Merge branch 'frost' of https://github.com/Aevann1/rDrama into frost

master
Aevann1 2022-08-05 21:50:40 +00:00
commit db6edad48a
14 changed files with 120 additions and 213 deletions

View File

@ -5087,7 +5087,7 @@ html {
display: block; display: block;
} }
.comment-anchor:target, .unread { .comment-anchor:target, .unread {
background: #ffffff22; background: #ffffff22 !important;
padding: 12px; padding: 12px;
padding-bottom: 4px; padding-bottom: 4px;
} }

View File

@ -128,6 +128,7 @@ class User(Base):
total_held_lottery_tickets = Column(Integer, default=0) total_held_lottery_tickets = Column(Integer, default=0)
total_lottery_winnings = Column(Integer, default=0) total_lottery_winnings = Column(Integer, default=0)
last_viewed_post_notifs = Column(Integer, default=0) last_viewed_post_notifs = Column(Integer, default=0)
last_viewed_log_notifs = Column(Integer, default=0)
pronouns = Column(String, default='they/them') pronouns = Column(String, default='they/them')
badges = relationship("Badge", order_by="Badge.created_utc", back_populates="user") badges = relationship("Badge", order_by="Badge.created_utc", back_populates="user")
@ -151,6 +152,7 @@ class User(Base):
if "created_utc" not in kwargs: if "created_utc" not in kwargs:
kwargs["created_utc"] = int(time.time()) kwargs["created_utc"] = int(time.time())
kwargs["last_viewed_post_notifs"] = kwargs["created_utc"] kwargs["last_viewed_post_notifs"] = kwargs["created_utc"]
kwargs["last_viewed_log_notifs"] = kwargs["created_utc"]
super().__init__(**kwargs) super().__init__(**kwargs)
@ -461,7 +463,7 @@ class User(Base):
if not self.shadowbanned and self.admin_level < 3: if not self.shadowbanned and self.admin_level < 3:
notifs = notifs.join(Comment.author).filter(User.shadowbanned == None) notifs = notifs.join(Comment.author).filter(User.shadowbanned == None)
return notifs.count() + self.post_notifications_count return notifs.count() + self.post_notifications_count + self.modaction_notifications_count
@property @property
@lazy @lazy
@ -492,11 +494,10 @@ class User(Base):
@lazy @lazy
def modaction_notifications_count(self): def modaction_notifications_count(self):
if not self.admin_level: return 0 if not self.admin_level: return 0
return g.db.query(Notification).join(Comment).filter( return g.db.query(ModAction).filter(
Notification.user_id == self.id, Notification.read == False, ModAction.created_utc > self.last_viewed_log_notifs,
Comment.is_banned == False, Comment.deleted_utc == 0, ModAction.user_id != self.id,
Comment.body_html.like(f'%<p>{NOTIF_MODACTION_PREFIX}%'), ).count()
Comment.parent_submission == None, Comment.author_id == AUTOJANNY_ID).count()
@property @property
@lazy @lazy

View File

@ -109,26 +109,6 @@ def NOTIFY_USERS(text, v):
return notify_users - bots return notify_users - bots
def notify_mod_action(by_id, msg):
body_html = sanitize(NOTIF_MODACTION_PREFIX + msg)
new_comment = Comment(
author_id=AUTOJANNY_ID,
parent_submission=None,
level=1,
body_html=body_html,
distinguish_level=6,
is_bot=True)
g.db.add(new_comment)
g.db.flush()
new_comment.top_comment_id = new_comment.id
send_to = g.db.query(User).filter(
User.admin_level >= NOTIF_MODACTION_JL_MIN, User.id != by_id).all()
for admin in send_to:
notif = Notification(comment_id=new_comment.id, user_id=admin.id)
g.db.add(notif)
if PUSHER_ID != 'blahblahblah': if PUSHER_ID != 'blahblahblah':
beams_client = PushNotifications(instance_id=PUSHER_ID, secret_key=PUSHER_KEY) beams_client = PushNotifications(instance_id=PUSHER_ID, secret_key=PUSHER_KEY)

View File

@ -852,7 +852,6 @@ EIGHTBALL_REPLIES = ('<b style="color:#7FEC11">The 8-Ball Says: It is certain.</
if SITE_NAME == 'rDrama': patron = 'Paypig' if SITE_NAME == 'rDrama': patron = 'Paypig'
else: patron = 'Patron' else: patron = 'Patron'
NOTIF_MODACTION_PREFIX = '[Modaction] '
NOTIF_MODACTION_JL_MIN = 2 NOTIF_MODACTION_JL_MIN = 2
REDDIT_NOTIFS_JL_MIN = 1 REDDIT_NOTIFS_JL_MIN = 1

View File

@ -450,8 +450,6 @@ def change_settings(v, setting):
if site_settings[setting]: word = 'enable' if site_settings[setting]: word = 'enable'
else: word = 'disable' else: word = 'disable'
notify_mod_action(v.id, f"@{v.username} has {word}d `{setting}` in the [admin dashboard](/admin)!")
ma = ModAction( ma = ModAction(
kind=f"{word}_{setting}", kind=f"{word}_{setting}",
user_id=v.id, user_id=v.id,
@ -490,7 +488,7 @@ def under_attack(v):
) )
g.db.add(ma) g.db.add(ma)
response = str(requests.patch(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/settings/security_level', headers=CF_HEADERS, data='{"value":"medium"}', timeout=5)) response = str(requests.patch(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/settings/security_level', headers=CF_HEADERS, data='{"value":"high"}', timeout=5))
if response == "<Response [200]>": return {"message": "Under attack mode disabled!"} if response == "<Response [200]>": return {"message": "Under attack mode disabled!"}
return {"error": "Failed to disable under attack mode."} return {"error": "Failed to disable under attack mode."}
else: else:
@ -922,7 +920,6 @@ def shadowban(user_id, v):
g.db.add(ma) g.db.add(ma)
cache.delete_memoized(frontlist) cache.delete_memoized(frontlist)
notify_mod_action(v.id, f"@{v.username} has shadowbanned @{user.username}")
return {"message": "User shadowbanned!"} return {"message": "User shadowbanned!"}
@ -947,7 +944,6 @@ def unshadowban(user_id, v):
g.db.add(ma) g.db.add(ma)
cache.delete_memoized(frontlist) cache.delete_memoized(frontlist)
notify_mod_action(v.id, f"@{v.username} has unshadowbanned @{user.username}")
return {"message": "User unshadowbanned!"} return {"message": "User unshadowbanned!"}
@ -1049,8 +1045,6 @@ def ban_user(user_id, v):
comment.bannedfor = f'{duration} by @{v.username}' comment.bannedfor = f'{duration} by @{v.username}'
g.db.add(comment) g.db.add(comment)
notify_mod_action(v.id, f"@{v.username} has banned @{user.username} ({note})")
if 'redir' in request.values: return redirect(user.url) if 'redir' in request.values: return redirect(user.url)
else: return {"message": f"@{user.username} was banned!"} else: return {"message": f"@{user.username} was banned!"}
@ -1086,8 +1080,6 @@ def unban_user(user_id, v):
) )
g.db.add(ma) g.db.add(ma)
notify_mod_action(v.id, f"@{v.username} has unbanned @{user.username}")
if "@" in request.referrer: return redirect(user.url) if "@" in request.referrer: return redirect(user.url)
else: return {"message": f"@{user.username} was unbanned!"} else: return {"message": f"@{user.username} was unbanned!"}
@ -1123,9 +1115,6 @@ def ban_post(post_id, v):
v.coins += 1 v.coins += 1
g.db.add(v) g.db.add(v)
if v.id != post.author_id:
notify_mod_action(v.id, f"@{v.username} has removed [{post.title}]({post.shortlink}) by @{post.author.username}")
requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache',
headers=CF_HEADERS, json={'files': [f"{SITE_FULL}/logged_out/"]}, timeout=5) headers=CF_HEADERS, json={'files': [f"{SITE_FULL}/logged_out/"]}, timeout=5)
@ -1164,10 +1153,6 @@ def unban_post(post_id, v):
v.coins -= 1 v.coins -= 1
g.db.add(v) g.db.add(v)
if v.id != post.author_id:
notify_mod_action(v.id, f"@{v.username} has approved [{post.title}]({post.shortlink}) by @{post.author.username}")
return {"message": "Post approved!"} return {"message": "Post approved!"}
@ -1327,9 +1312,6 @@ def api_ban_comment(c_id, v):
) )
g.db.add(ma) g.db.add(ma)
if v.id != comment.author_id:
notify_mod_action(v.id, f"@{v.username} has removed [comment]({comment.shortlink}) by @{comment.author.username}")
return {"message": "Comment removed!"} return {"message": "Comment removed!"}
@ -1358,10 +1340,6 @@ def api_unban_comment(c_id, v):
g.db.add(comment) g.db.add(comment)
if v.id != comment.author_id:
notify_mod_action(v.id, f"@{v.username} has approved [comment]({comment.shortlink}) by @{comment.author.username}")
return {"message": "Comment approved!"} return {"message": "Comment approved!"}
@ -1479,9 +1457,6 @@ def admin_nuke_user(v):
) )
g.db.add(ma) g.db.add(ma)
notify_mod_action(v.id, f"@{v.username} has has removed all content of @{user.username}")
return redirect(user.url) return redirect(user.url)
@ -1517,7 +1492,4 @@ def admin_nunuke_user(v):
) )
g.db.add(ma) g.db.add(ma)
notify_mod_action(v.id, f"@{v.username} has approved all of content of @{user.username}")
return redirect(user.url) return redirect(user.url)

View File

@ -176,9 +176,17 @@ def award_thing(v, thing_type, id):
send_repeatable_notification(author.id, f"Your account has been banned for **yet another day** for {link}. Seriously man?") send_repeatable_notification(author.id, f"Your account has been banned for **yet another day** for {link}. Seriously man?")
if v.admin_level > 2: if v.admin_level > 2:
text = f"@{v.username} has banned @{author.username} for 1 day for {link}." log_link = f'/{thing_type}/{thing.id}'
if note: text += f" ({note})" reason = f'<a href="{log_link}">{log_link}</a>'
notify_mod_action(v.id, text)
note = f'reason: "{reason}", duration: for 1 day'
ma=ModAction(
kind="ban_user",
user_id=v.id,
target_user_id=author.id,
_note=note
)
g.db.add(ma)
elif kind == "unban": elif kind == "unban":
if not author.is_suspended or not author.unban_utc or time.time() > author.unban_utc: abort(403) if not author.is_suspended or not author.unban_utc or time.time() > author.unban_utc: abort(403)
@ -193,9 +201,12 @@ def award_thing(v, thing_type, id):
send_repeatable_notification(author.id, "You have been unbanned!") send_repeatable_notification(author.id, "You have been unbanned!")
if v.admin_level > 2: if v.admin_level > 2:
text = f"@{v.username} has unbanned @{author.username} for {link}." ma=ModAction(
if note: text += f" ({note})" kind="unban_user",
notify_mod_action(v.id, text) user_id=v.id,
target_user_id=author.id,
)
g.db.add(ma)
elif kind == "grass": elif kind == "grass":
author.is_banned = AUTOJANNY_ID author.is_banned = AUTOJANNY_ID
author.ban_reason = f"grass award used by @{v.username} on /{thing_type}/{thing.id}" author.ban_reason = f"grass award used by @{v.username} on /{thing_type}/{thing.id}"
@ -203,9 +214,17 @@ def award_thing(v, thing_type, id):
send_repeatable_notification(author.id, f"Your account has been banned permanently for {link}. You must [provide the admins](/contact) a timestamped picture of you touching grass/snow/sand/ass to get unbanned!") send_repeatable_notification(author.id, f"Your account has been banned permanently for {link}. You must [provide the admins](/contact) a timestamped picture of you touching grass/snow/sand/ass to get unbanned!")
if v.admin_level > 2: if v.admin_level > 2:
text = f"@{v.username} has grassed @{author.username} for {link}." log_link = f'/{thing_type}/{thing.id}'
if note: text += f" ({note})" reason = f'<a href="{log_link}">{log_link}</a>'
notify_mod_action(v.id, text)
note = f'reason: "{reason}", duration: for 30 days'
ma=ModAction(
kind="ban_user",
user_id=v.id,
target_user_id=author.id,
_note=note
)
g.db.add(ma)
elif kind == "pin": elif kind == "pin":
if not FEATURES['PINS']: if not FEATURES['PINS']:
abort(403) abort(403)

View File

@ -12,6 +12,7 @@ def clear(v):
n.read = True n.read = True
g.db.add(n) g.db.add(n)
v.last_viewed_post_notifs = int(time.time()) v.last_viewed_post_notifs = int(time.time())
v.last_viewed_log_notifs = int(time.time())
g.db.add(v) g.db.add(v)
return {"message": "Notifications cleared!"} return {"message": "Notifications cleared!"}
@ -134,29 +135,16 @@ def notifications_modactions(v):
try: page = max(int(request.values.get("page", 1)), 1) try: page = max(int(request.values.get("page", 1)), 1)
except: page = 1 except: page = 1
notifications = g.db.query(Notification, Comment) \ listing = g.db.query(ModAction).filter(ModAction.user_id != v.id).order_by(ModAction.id.desc()).offset(25*(page-1)).limit(26).all()
.join(Notification.comment) \
.filter(Notification.user_id == v.id,
Comment.body_html.like(f'%<p>{NOTIF_MODACTION_PREFIX}%'),
Comment.parent_submission == None, Comment.author_id == AUTOJANNY_ID) \
.order_by(Notification.created_utc.desc()).offset(25 * (page - 1)).limit(101).all()
listing = []
for index, x in enumerate(notifications[:100]): next_exists = len(listing) > 25
n, c = x listing = listing[:25]
if n.read and index > 24: break
elif not n.read:
n.read = True
c.unread = True
g.db.add(n)
if n.created_utc > 1620391248: c.notif_utc = n.created_utc
listing.append(c)
next_exists = (len(notifications) > len(listing)) for ma in listing:
ma.unread = ma.created_utc > v.last_viewed_log_notifs
g.db.commit() v.last_viewed_log_notifs = int(time.time())
g.db.add(v)
if request.headers.get("Authorization"): return {"data":[x.json for x in listing]}
return render_template("notifications.html", return render_template("notifications.html",
v=v, v=v,
@ -225,7 +213,6 @@ def notifications(v):
Comment.is_banned == False, Comment.is_banned == False,
Comment.deleted_utc == 0, Comment.deleted_utc == 0,
Comment.body_html.notlike('%<p>New site mention%<a href="https://old.reddit.com/r/%'), Comment.body_html.notlike('%<p>New site mention%<a href="https://old.reddit.com/r/%'),
Comment.body_html.notlike(f'%<p>{NOTIF_MODACTION_PREFIX}%')
).order_by(Notification.created_utc.desc()) ).order_by(Notification.created_utc.desc())
if not (v and (v.shadowbanned or v.admin_level > 2)): if not (v and (v.shadowbanned or v.admin_level > 2)):

View File

@ -22,8 +22,8 @@
<a href="#leaderboard-blocked">Blocked</a> <a href="#leaderboard-blocked">Blocked</a>
</div> </div>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-coins">Top 25 by coins</a></h5> <h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-coins">Top 25 by coins</a></h5>
<pre></pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>
@ -48,16 +48,8 @@
{% endif %} {% endif %}
</table> </table>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-spent">Top 25 by coins spent in shop</a></h5>
<pre>
</pre>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-spent">Top 25 by coins spent in shop</a></h5>
<pre>
</pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>
@ -83,16 +75,8 @@
{% endif %} {% endif %}
</table> </table>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-truescore">Top 25 by truescore</a></h5>
<pre>
</pre>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-truescore">Top 25 by truescore</a></h5>
<pre>
</pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>
@ -119,15 +103,8 @@
</tbody> </tbody>
</table> </table>
<pre> <h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-followers">Top 25 by followers</a></h5>
</pre>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-followers">Top 25 by followers</a></h5>
<pre>
</pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>
@ -151,15 +128,9 @@
</tr> </tr>
{% endif %} {% endif %}
</table> </table>
<pre>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-posts">Top 25 by post count</a></h5>
</pre>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-posts">Top 25 by post count</a></h5>
<pre>
</pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>
@ -183,15 +154,9 @@
</tr> </tr>
{% endif %} {% endif %}
</table> </table>
<pre>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-comments">Top 25 by comment count</a></h5>
</pre>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-comments">Top 25 by comment count</a></h5>
<pre>
</pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>
@ -216,16 +181,8 @@
{% endif %} {% endif %}
</table> </table>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-awards">Top 25 by received awards</a></h5>
<pre>
</pre>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-awards">Top 25 by received awards</a></h5>
<pre>
</pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>
@ -250,16 +207,7 @@
{% endif %} {% endif %}
</table> </table>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-downvotes">Top 25 by received downvotes</a></h5>
<pre>
</pre>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-downvotes">Top 25 by received downvotes</a></h5>
<pre>
</pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
@ -287,16 +235,7 @@
</tbody> </tbody>
</table> </table>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-badges">Top 25 by badges</a></h5>
<pre>
</pre>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-badges">Top 25 by badges</a></h5>
<pre>
</pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
@ -327,15 +266,9 @@
{% if users6 %} {% if users6 %}
<pre>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-based">Top 25 by based count</a></h5>
</pre>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-based">Top 25 by based count</a></h5>
<pre>
</pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>
@ -362,15 +295,8 @@
{% endif %} {% endif %}
{% if users12 %} {% if users12 %}
<pre>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-marseys">Top 25 by marseys made</a></h5>
</pre>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-marseys">Top 25 by marseys made</a></h5>
<pre>
</pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
@ -400,15 +326,8 @@
{% endif %} {% endif %}
{% if users13 %} {% if users13 %}
<pre>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-upgiven">Top 25 by upvotes given</a></h5>
</pre>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-upgiven">Top 25 by upvotes given</a></h5>
<pre>
</pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
@ -437,8 +356,8 @@
</table> </table>
{% endif %} {% endif %}
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-winnings">Top 25 by winnings</a></h5> <h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-winnings">Top 25 by winnings</a></h5>
<pre></pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>
@ -463,13 +382,8 @@
{% endif %} {% endif %}
</table> </table>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-losses">Bottom 25 by winnings</a></h5>
<pre>
</pre>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-losses">Bottom 25 by winnings</a></h5>
<pre></pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>
@ -494,13 +408,8 @@
{% endif %} {% endif %}
</table> </table>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-blocked">Top 25 Most Blocked</a></h5>
<pre>
</pre>
<h5 style="font-weight:bold;text-align: center"><a id="leaderboard-blocked">Top 25 Most Blocked</a></h5>
<pre></pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>
@ -518,11 +427,6 @@
{% endfor %} {% endfor %}
</table> </table>
<pre>
</pre>
<a id="leader--top-btn" href="#leaderboard-contents" role="button" <a id="leader--top-btn" href="#leaderboard-contents" role="button"
style="position: fixed; bottom: 5rem; right: 2rem; font-size: 3rem;"> style="position: fixed; bottom: 5rem; right: 2rem; font-size: 3rem;">
<i class="fas fa-arrow-alt-circle-up"></i> <i class="fas fa-arrow-alt-circle-up"></i>

View File

@ -93,7 +93,7 @@
<div class="rounded border bg-white mx-auto"> <div class="rounded border bg-white mx-auto">
{% for ma in actions %} {% for ma in actions %}
<div id="action-{{ma.id}}" class="position-relative d-flex justify-content-between flex-wrap align-items-center h-min-16 px-3 py-3 mb-3 mb-md-2 bg-white{% if loop.index > 1 %} border-top{% endif %}"> <div id="action-{{ma.id}}" class="{% if ma.unread %}unread{% endif %} position-relative d-flex justify-content-between flex-wrap align-items-center h-min-16 px-3 py-3 bg-white{% if loop.index > 1 %} border-top{% endif %}">
<div class="d-flex flex-grow-1 align-items-center"> <div class="d-flex flex-grow-1 align-items-center">
<div class="d-flex align-items-center justify-content-center {{ma.color}} mr-3 rounded-lg flex-shrink-0" style="width: 32px;height: 32px;"><i class="far text-center {{ma.icon}} text-lg text-white fa-fw"></i></div> <div class="d-flex align-items-center justify-content-center {{ma.color}} mr-3 rounded-lg flex-shrink-0" style="width: 32px;height: 32px;"><i class="far text-center {{ma.icon}} text-lg text-white fa-fw"></i></div>

View File

@ -65,6 +65,48 @@
{% include "submission_listing.html" %} {% include "submission_listing.html" %}
</div> </div>
{% endwith %} {% endwith %}
{% elif request.path == '/notifications/modactions' %}
<div class="rounded border bg-white mx-auto mt-4">
{% for ma in notifications %}
<div id="action-{{ma.id}}" class="{% if ma.unread %}unread{% endif %} position-relative d-flex justify-content-between flex-wrap align-items-center h-min-16 px-3 py-3 bg-white{% if loop.index > 1 %} border-top{% endif %}">
<div class="d-flex flex-grow-1 align-items-center">
<div class="d-flex align-items-center justify-content-center {{ma.color}} mr-3 rounded-lg flex-shrink-0" style="width: 32px;height: 32px;"><i class="far text-center {{ma.icon}} text-lg text-white fa-fw"></i></div>
<div class="d-flex align-items-center">
<span class="rounded">
<img loading="lazy" src="{{ma.user.profile_url}}" alt="avatar" class="profile-pic-35">
</span>
<div class="text-muted pl-3">
<div>
<a href="{{ma.user.url}}" class="font-weight-bold text-black" target="_self">@{{ma.user.username}}</a>
<span>{{ma.string | safe}}</span>
</div>
<div class="text-gray-500">
<span class="log--item-age" id="{{ma.id}}-age" data-bs-toggle="tooltip" data-bs-placement="bottom" onmouseover="timestamp('{{ma.id}}-age','{{ma.created_utc}}')">{{ma.age_string}}</span>
<a href="{{ma.permalink}}"><i class="far fa-link ml-1 text-muted"></i></a>
<a role="button" class="copy-link" role="button" data-clipboard-text="{{ma.permalink}}"><i class="far fa-copy ml-1 text-muted"></i></a>
</div>
</div>
</div>
</div>
</div>
{% else %}
<div>There's nothing here right now.</div>
{% endfor %}
</div>
<div class="toast clipboard" id="toast-success" role="alert" aria-live="assertive" aria-atomic="true" data-bs-animation="true" data-bs-autohide="true" data-bs-delay="5000">
<div class="toast-body text-center">
<i class="fas fa-check-circle text-success mr-2"></i>Link copied to clipboard
</div>
</div>
<script src="/assets/js/clipboard.js?v=240"></script>
{% else %} {% else %}
{% with comments=notifications %} {% with comments=notifications %}
{% include "comments.html" %} {% include "comments.html" %}

View File

@ -1,6 +1,6 @@
{%- {%-
set CACHE_VER = { set CACHE_VER = {
'css/main.css': 434, 'css/main.css': 435,
'css/catalog.css': 2, 'css/catalog.css': 2,
'css/4chan.css': 61, 'css/4chan.css': 61,

View File

@ -809,6 +809,7 @@ CREATE TABLE public.users (
last_active integer DEFAULT 0 NOT NULL, last_active integer DEFAULT 0 NOT NULL,
poorcel boolean DEFAULT false NOT NULL, poorcel boolean DEFAULT false NOT NULL,
last_viewed_post_notifs integer NOT NULL, last_viewed_post_notifs integer NOT NULL,
last_viewed_log_notifs integer NOT NULL,
pronouns character varying(11) NOT NULL pronouns character varying(11) NOT NULL
); );

View File

@ -1,23 +1,23 @@
INSERT INTO public.users (username, passhash, created_utc, admin_level, over_18, is_activated, bio, bio_html, login_nonce, is_private, INSERT INTO public.users (username, passhash, created_utc, admin_level, over_18, is_activated, bio, bio_html, login_nonce, is_private,
unban_utc, original_username, customtitle, defaultsorting, defaultsortingcomments, defaulttime, namecolor, titlecolor, unban_utc, original_username, customtitle, defaultsorting, defaultsortingcomments, defaulttime, namecolor, titlecolor,
customtitleplain, theme, themecolor, reddit, css, profilecss, coins, agendaposter, customtitleplain, theme, themecolor, reddit, css, profilecss, coins, agendaposter,
post_count, comment_count, background, verified, truecoins, cardview, profileurl, highres, last_viewed_post_notifs, pronouns post_count, comment_count, background, verified, truecoins, cardview, profileurl, highres, last_viewed_post_notifs, last_viewed_log_notifs, pronouns
) VALUES ('AutoJanny', '', extract(epoch from now()), 0, true, true, '', '', 0, false, ) VALUES ('AutoJanny', '', extract(epoch from now()), 0, true, true, '', '', 0, false,
0, 'AutoJanny', '', 'hot', 'top', 'day', 'ff66ac', 'ff66ac', 0, 'AutoJanny', '', 'hot', 'top', 'day', 'ff66ac', 'ff66ac',
'', 'dark', 'ff66ac', 'old.reddit.com', '', '', 0, 0, '', 'dark', 'ff66ac', 'old.reddit.com', '', '', 0, 0,
0, 0, '', 'Verified', 0, false, '/i/pfps/1.webp', '/i/pfps/1.webp', 0, 'clean/itup'), 0, 0, '', 'Verified', 0, false, '/i/pfps/1.webp', '/i/pfps/1.webp', 0, 0, 'clean/itup'),
('Snappy', '', extract(epoch from now()), 0, true, true, '', '', 0, false, ('Snappy', '', extract(epoch from now()), 0, true, true, '', '', 0, false,
0, 'Snappy', '', 'hot', 'top', 'day', '62ca56', 'e4432d', 0, 'Snappy', '', 'hot', 'top', 'day', '62ca56', 'e4432d',
'', 'dark', '30409f', 'old.reddit.com', '', '', 0, 0, '', 'dark', '30409f', 'old.reddit.com', '', '', 0, 0,
0, 0, '', 'Verified', 0, false, '/i/pfps/2.webp', '/i/pfps/2.webp', 0, 'beep/boop'), 0, 0, '', 'Verified', 0, false, '/i/pfps/2.webp', '/i/pfps/2.webp', 0, 0,'beep/boop'),
('longpostbot', '', extract(epoch from now()), 0, true, true, '', '', 0, false, ('longpostbot', '', extract(epoch from now()), 0, true, true, '', '', 0, false,
0, 'longpostbot', '', 'hot', 'top', 'day', '62ca56', 'e4432d', 0, 'longpostbot', '', 'hot', 'top', 'day', '62ca56', 'e4432d',
'', 'dark', '30409f', 'old.reddit.com', '', '', 0, 0, '', 'dark', '30409f', 'old.reddit.com', '', '', 0, 0,
0, 0, '', 'Verified', 0, false, '/i/pfps/3.webp', '/i/pfps/3.webp', 0, 'tl/dr'), 0, 0, '', 'Verified', 0, false, '/i/pfps/3.webp', '/i/pfps/3.webp', 0, 0, 'tl/dr'),
('zozbot', '', extract(epoch from now()), 0, true, true, '', '', 0, false, ('zozbot', '', extract(epoch from now()), 0, true, true, '', '', 0, false,
0, 'zozbot', '', 'hot', 'top', 'day', '62ca56', 'e4432d', 0, 'zozbot', '', 'hot', 'top', 'day', '62ca56', 'e4432d',
'', 'dark', '30409f', 'old.reddit.com', '', '', 0, 0, '', 'dark', '30409f', 'old.reddit.com', '', '', 0, 0,
0, 0, '', 'Verified', 0, false, '/i/pfps/4.webp', '/i/pfps/4.webp', 0, 'zoz/zle'); 0, 0, '', 'Verified', 0, false, '/i/pfps/4.webp', '/i/pfps/4.webp', 0, 0,'zoz/zle');
INSERT INTO public.marseys VALUES INSERT INTO public.marseys VALUES
('marseyvirus', 1, 'phage infect infection plagued', 0), ('marseyvirus', 1, 'phage infect infection plagued', 0),

View File

@ -0,0 +1,2 @@
alter table users add column last_viewed_log_notifs int not null default 0;
alter table users alter column last_viewed_log_notifs drop default;