pins logic rework

This commit is contained in:
Aevann1 2021-12-26 03:03:21 +02:00
parent f8f285bcee
commit 1a43b0dedc
27 changed files with 300 additions and 310 deletions

View file

@ -4671,4 +4671,8 @@ input[type=radio] ~ .custom-control-label::before {
} }
.preview-edit img { .preview-edit img {
max-width: 20%; max-width: 20%;
}
.twitter-tweet {
margin-bottom: 9.8px;
padding-bottom: 7px;
} }

View file

@ -6,7 +6,8 @@ function timestamp(str, ti) {
function pinned_timestamp(id) { function pinned_timestamp(id) {
const el = document.getElementById(id) const el = document.getElementById(id)
const time = new Date(parseInt(el.dataset.timestamp)*1000) const time = new Date(parseInt(el.dataset.timestamp)*1000)
el.setAttribute("data-bs-original-title", `Pinned until ${time}`) const pintooltip = el.getAttribute("data-bs-original-title")
if (!pintooltip.includes('until')) el.setAttribute("data-bs-original-title", `${pintooltip} until ${time}`)
} }
function expandDesktopImage(image) { function expandDesktopImage(image) {

View file

@ -11,9 +11,8 @@ function collapse_comment(comment_id) {
}; };
function poll_vote_no_v() { function poll_vote_no_v() {
var myToast = new bootstrap.Toast(document.getElementById('toast-post-error'));
myToast.show();
document.getElementById('toast-post-error-text').innerText = "Only logged-in users can vote!"; document.getElementById('toast-post-error-text').innerText = "Only logged-in users can vote!";
new bootstrap.Toast(document.getElementById('toast-post-error')).show();
} }
function morecomments(cid) { function morecomments(cid) {

View file

@ -24,35 +24,20 @@ function post_toast3(url, button1, button2) {
xhr.withCredentials=true; xhr.withCredentials=true;
xhr.onload = function() { xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) { let data = JSON.parse(xhr.response)
var myToast = new bootstrap.Toast(document.getElementById('toast-post-success')); if (xhr.status >= 200 && xhr.status < 300 && !data['error']) {
myToast.show(); document.getElementById('toast-post-success-text').innerText = data["message"];
try { new bootstrap.Toast(document.getElementById('toast-post-success')).show();
document.getElementById('toast-post-success-text').innerText = JSON.parse(xhr.response)["message"]; document.getElementById(button1).classList.toggle("d-md-inline-block");
} catch(e) { document.getElementById(button2).classList.toggle("d-md-inline-block");
}
return true
} else if (xhr.status >= 300 && xhr.status < 400) {
window.location.href = JSON.parse(xhr.response)["redirect"]
} else { } else {
if (data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"];
try { new bootstrap.Toast(document.getElementById('toast-post-error')).show();
data=JSON.parse(xhr.response);
} catch(e) {}
var myToast = new bootstrap.Toast(document.getElementById('toast-post-success'));
myToast.hide();
var myToast = new bootstrap.Toast(document.getElementById('toast-post-error'));
myToast.show();
return false
} }
}; };
xhr.send(form); xhr.send(form);
document.getElementById(button1).classList.toggle("d-md-inline-block");
document.getElementById(button2).classList.toggle("d-md-inline-block");
} }
function report_commentModal(id, author) { function report_commentModal(id, author) {
@ -136,12 +121,7 @@ function post_reply(id){
commentForm.innerHTML = xhr.response.replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, ''); commentForm.innerHTML = xhr.response.replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, '');
} }
else { else {
var myToast = new bootstrap.Toast(document.getElementById('toast-post-success')); new bootstrap.Toast(document.getElementById('toast-post-error')).show();
myToast.hide();
var myToast = new bootstrap.Toast(document.getElementById('toast-post-error'));
myToast.show();
try {document.getElementById('toast-post-error-text').innerText = JSON.parse(xhr.response)["error"];}
catch {}
} }
} }
xhr.send(form) xhr.send(form)
@ -165,12 +145,7 @@ function comment_edit(id){
document.getElementById('cancel-edit-'+id).click() document.getElementById('cancel-edit-'+id).click()
} }
else { else {
var myToast = new bootstrap.Toast(document.getElementById('toast-post-success')); new bootstrap.Toast(document.getElementById('toast-post-error')).show();
myToast.hide();
var myToast = new bootstrap.Toast(document.getElementById('toast-post-error'));
myToast.show();
try {document.getElementById('toast-post-error-text').innerText = JSON.parse(xhr.response)["error"];}
catch {}
} }
} }
xhr.send(form) xhr.send(form)
@ -197,12 +172,7 @@ function post_comment(fullname){
commentForm.innerHTML = xhr.response.replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, ''); commentForm.innerHTML = xhr.response.replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, '');
} }
else { else {
var myToast = new bootstrap.Toast(document.getElementById('toast-post-success')); new bootstrap.Toast(document.getElementById('toast-post-error')).show();
myToast.hide();
var myToast = new bootstrap.Toast(document.getElementById('toast-post-error'));
myToast.show();
try {document.getElementById('toast-post-error-text').innerText = JSON.parse(xhr.response)["error"];}
catch {}
btn.classList.remove('disabled'); btn.classList.remove('disabled');
} }
} }

View file

@ -315,7 +315,6 @@ const EMOJIS_STRINGS = [
marseydynamite: 'dynomite black afro gun', marseydynamite: 'dynomite black afro gun',
marseyeggirl: 'troomer tranny transgender lgbt groomer troid transsexual', marseyeggirl: 'troomer tranny transgender lgbt groomer troid transsexual',
marseyeldritch: 'lovecraft horror halloween tentacles holiday scary monster', marseyeldritch: 'lovecraft horror halloween tentacles holiday scary monster',
marseyeldritch2: 'horror halloween lovecraftian holiday scary',
marseyelephant: 'oliphant dumbo', marseyelephant: 'oliphant dumbo',
marseyemo: 'girl goth scene', marseyemo: 'girl goth scene',
marseyemperor: 'gold', marseyemperor: 'gold',
@ -471,7 +470,7 @@ const EMOJIS_STRINGS = [
marseymcarthur: 'nuke missile nuclear bomb history', marseymcarthur: 'nuke missile nuclear bomb history',
marseymeds: 'mentally ill rightoid doctor psycho crazy mental illness reaction risperidone schizo nurse', marseymeds: 'mentally ill rightoid doctor psycho crazy mental illness reaction risperidone schizo nurse',
marseymermaid: 'merman merfolk', marseymermaid: 'merman merfolk',
marseymexican: 'latina latino hispanic fiesta sombrero latinx hombre', marseymexican: 'latina latino hispanic fiesta sombrero latinx hombre mexico',
marseymini: 'annihilate minigun machine gun kill destroy murder animated', marseymini: 'annihilate minigun machine gun kill destroy murder animated',
marseyminimalism: 'orange minimalist square art', marseyminimalism: 'orange minimalist square art',
marseyminimalism2: 'minimalist polygons polygonal art', marseyminimalism2: 'minimalist polygons polygonal art',
@ -668,7 +667,6 @@ const EMOJIS_STRINGS = [
marseysnoo: 'shaking redditor scared reaction nervous schizo reddit', marseysnoo: 'shaking redditor scared reaction nervous schizo reddit',
marseysob: 'tear crying depressed reaction sobbing depression sad cry animated tears', marseysob: 'tear crying depressed reaction sobbing depression sad cry animated tears',
marseysociety: 'batman joker capeshit jared leto', marseysociety: 'batman joker capeshit jared leto',
marseysombrero: 'mexican mexico',
marseysonic: 'hedgehog blue', marseysonic: 'hedgehog blue',
marseysoypoint: 'soyboy soy boy beard reaction pointing', marseysoypoint: 'soyboy soy boy beard reaction pointing',
marseyspecial: 'retard reaction slow special needs sped', marseyspecial: 'retard reaction slow special needs sped',
@ -677,7 +675,7 @@ const EMOJIS_STRINGS = [
marseyspider2: 'insect halloween spiderweb arachnid holiday bug', marseyspider2: 'insect halloween spiderweb arachnid holiday bug',
marseyspirit: 'ghost halloween holiday', marseyspirit: 'ghost halloween holiday',
marseyspit: 'surprising reaction shocking water surprised shocked', marseyspit: 'surprising reaction shocking water surprised shocked',
marseyspooky: 'art horror halloween holiday evil scary monster', marseyspooky: 'art horror halloween holiday evil scary monster lovecraftian eldritch',
marseyspookysmile: 'horror halloween holiday evil scary monster', marseyspookysmile: 'horror halloween holiday evil scary monster',
marseysrdine: 'fisherman reaction fish canned fishing', marseysrdine: 'fisherman reaction fish canned fishing',
marseysrdine2: 'can animated reaction fish knife chop sardine', marseysrdine2: 'can animated reaction fish knife chop sardine',

View file

@ -26,33 +26,14 @@ function post_toast(url, reload, data) {
xhr.withCredentials=true; xhr.withCredentials=true;
xhr.onload = function() { xhr.onload = function() {
let data=JSON.parse(xhr.response); let data = JSON.parse(xhr.response)
if (xhr.status >= 200 && xhr.status < 300 && !data["error"]) { if (xhr.status >= 200 && xhr.status < 300 && !data['error']) {
var myToast = new bootstrap.Toast(document.getElementById('toast-post-success')); document.getElementById('toast-post-success-text').innerText = data["message"];
myToast.show(); new bootstrap.Toast(document.getElementById('toast-post-success')).show();
try {
document.getElementById('toast-post-success-text').innerText = data["message"];
} catch(e) {
}
if (reload == 1) {location.reload(true)} if (reload == 1) {location.reload(true)}
return true
} else if (xhr.status >= 300 && xhr.status < 400) {
window.location.href = data["redirect"]
} else { } else {
try { if (data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"];
var myToast = new bootstrap.Toast(document.getElementById('toast-post-error')); new bootstrap.Toast(document.getElementById('toast-post-error')).show();
myToast.show();
document.getElementById('toast-post-error-text').innerText = data["error"];
return false
} catch(e) {
var myToast = new bootstrap.Toast(document.getElementById('toast-post-success'));
myToast.hide();
var myToast = new bootstrap.Toast(document.getElementById('toast-post-error'));
myToast.show();
return false
}
} }
}; };

View file

@ -15,29 +15,19 @@ function post_toast2(url, button1, button2) {
xhr.withCredentials=true; xhr.withCredentials=true;
xhr.onload = function() { xhr.onload = function() {
data = JSON.parse(xhr.response) let data = JSON.parse(xhr.response)
if (xhr.status >= 200 && xhr.status < 300 && !data["error"]) { if (xhr.status >= 200 && xhr.status < 300 && !data['error']) {
try { document.getElementById('toast-post-success-text').innerText = data["message"];
document.getElementById('toast-post-success-text').innerText = data["message"]; new bootstrap.Toast(document.getElementById('toast-post-success')).show();
} catch(e) {}
var myToast = new bootstrap.Toast(document.getElementById('toast-post-success'));
myToast.show();
return true
} else if (xhr.status >= 300 && xhr.status < 400) { document.getElementById(button1).classList.toggle("d-none");
window.location.href = data["redirect"] document.getElementById(button2).classList.toggle("d-none");
} else { } else {
try { if (data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"];
document.getElementById('toast-post-error-text').innerText = data["error"]; new bootstrap.Toast(document.getElementById('toast-post-error')).show();
} catch(e) {}
var myToast = new bootstrap.Toast(document.getElementById('toast-post-error'));
myToast.show();
return false
} }
}; };
xhr.send(form); xhr.send(form);
document.getElementById(button1).classList.toggle("d-none");
document.getElementById(button2).classList.toggle("d-none");
} }

View file

@ -36,6 +36,7 @@ class Comment(Base):
over_18 = Column(Boolean, default=False) over_18 = Column(Boolean, default=False)
is_bot = Column(Boolean, default=False) is_bot = Column(Boolean, default=False)
is_pinned = Column(String) is_pinned = Column(String)
is_pinned_utc = Column(Integer)
sentto=Column(Integer, ForeignKey("users.id")) sentto=Column(Integer, ForeignKey("users.id"))
app_id = Column(Integer, ForeignKey("oauth_apps.id")) app_id = Column(Integer, ForeignKey("oauth_apps.id"))
oauth_app = relationship("OauthApp", viewonly=True) oauth_app = relationship("OauthApp", viewonly=True)

View file

@ -32,6 +32,7 @@ class Submission(Base):
deleted_utc = Column(Integer, default=0) deleted_utc = Column(Integer, default=0)
distinguish_level = Column(Integer, default=0) distinguish_level = Column(Integer, default=0)
stickied = Column(String) stickied = Column(String)
stickied_utc = Column(Integer)
is_pinned = Column(Boolean, default=False) is_pinned = Column(Boolean, default=False)
private = Column(Boolean, default=False) private = Column(Boolean, default=False)
club = Column(Boolean, default=False) club = Column(Boolean, default=False)

View file

@ -88,7 +88,7 @@ SLURS = {
" elon ": " rocket daddy ", " elon ": " rocket daddy ",
} }
LONGPOST_REPLIES = ['Wow, you must be a JP fan.', 'This is one of the worst posts I have EVER seen. Delete it.', "No, don't reply like this, please do another wall of unhinged rant please.", '# 😴😴😴', "Ma'am we've been over this before. You need to stop.", "I've known more coherent downies.", "Your pulitzer's in the mail", "That's great and all, but I asked for my burger without cheese.", 'That degree finally paying off', "That's nice sweaty. Why don't you have a seat in the time out corner with Pizzashill until you calm down, then you can have your Capri Sun.", "All them words won't bring your pa back.", "You had a chance to not be completely worthless, but it looks like you threw it away. At least you're consistent.", 'Some people are able to display their intelligence by going on at length on a subject and never actually saying anything. This ability is most common in trades such as politics, public relations, and law. You have impressed me by being able to best them all, while still coming off as an absolute idiot.', "You can type 10,000 characters and you decided that these were the one's that you wanted.", 'Have you owned the libs yet?', "I don't know what you said, because I've seen another human naked.", 'Impressive. Normally people with such severe developmental disabilities struggle to write much more than a sentence or two. He really has exceded our expectations for the writing portion. Sadly the coherency of his writing, along with his abilities in the social skills and reading portions, are far behind his peers with similar disabilities.', "This is a really long way of saying you don't fuck.", "Sorry ma'am, looks like his delusions have gotten worse. We'll have to admit him,", ':#marseywoah:', 'If only you could put that energy into your relationships', 'Posts like this is why I do Heroine.', 'still unemployed then?', 'K', 'look im gunna have 2 ask u 2 keep ur giant dumps in the toilet not in my replys 😷😷😷', "Mommy is soooo proud of you, sweaty. Let's put this sperg out up on the fridge with all your other failures.", "Good job bobby, here's a star", "That was a mistake. You're about to find out the hard way why.", 'You sat down and wrote all this shit. You could have done so many other things with your life. What happened to your life that made you decide writing novels of bullshit on rdrama.net was the best option?', "I don't have enough spoons to read this shit", "All those words won't bring daddy back.", 'OUT!'] LONGPOST_REPLIES = ['Wow, you must be a JP fan.', 'This is one of the worst posts I have EVER seen. Delete it.', "No, don't reply like this, please do another wall of unhinged rant please.", '# 😴😴😴', "Ma'am we've been over this before. You need to stop.", "I've known more coherent downies.", "Your pulitzer's in the mail", "That's great and all, but I asked for my burger without cheese.", 'That degree finally paying off', "That's nice sweaty. Why don't you have a seat in the time out corner with Pizzashill until you calm down, then you can have your Capri Sun.", "All them words won't bring your pa back.", "You had a chance to not be completely worthless, but it looks like you threw it away. At least you're consistent.", 'Some people are able to display their intelligence by going on at length on a subject and never actually saying anything. This ability is most common in trades such as politics, public relations, and law. You have impressed me by being able to best them all, while still coming off as an absolute idiot.', "You can type 10,000 characters and you decided that these were the one's that you wanted.", 'Have you owned the libs yet?', "I don't know what you said, because I've seen another human naked.", 'Impressive. Normally people with such severe developmental disabilities struggle to write much more than a sentence or two. He really has exceded our expectations for the writing portion. Sadly the coherency of his writing, along with his abilities in the social skills and reading portions, are far behind his peers with similar disabilities.', "This is a really long way of saying you don't fuck.", "Sorry ma'am, looks like his delusions have gotten worse. We'll have to admit him.", ':#marseywoah:', 'If only you could put that energy into your relationships', 'Posts like this is why I do Heroine.', 'still unemployed then?', 'K', 'look im gunna have 2 ask u 2 keep ur giant dumps in the toilet not in my replys 😷😷😷', "Mommy is soooo proud of you, sweaty. Let's put this sperg out up on the fridge with all your other failures.", "Good job bobby, here's a star", "That was a mistake. You're about to find out the hard way why.", 'You sat down and wrote all this shit. You could have done so many other things with your life. What happened to your life that made you decide writing novels of bullshit on rdrama.net was the best option?', "I don't have enough spoons to read this shit", "All those words won't bring daddy back.", 'OUT!']
AGENDAPOSTER_MSG = """Hi @{username},\n\nYour comment has been automatically removed because you forgot AGENDAPOSTER_MSG = """Hi @{username},\n\nYour comment has been automatically removed because you forgot
to include `trans lives matter`.\n\nDon't worry, we're here to help! We to include `trans lives matter`.\n\nDon't worry, we're here to help! We

View file

@ -187,7 +187,7 @@ def get_comment(i, v=None, graceful=False):
if v: if v:
comment=g.db.query(Comment).filter(Comment.id == i).first() comment=g.db.query(Comment).filter(Comment.id == i).one_or_none()
if not comment and not graceful: abort(404) if not comment and not graceful: abort(404)

View file

@ -214,17 +214,31 @@ def monthly(v):
if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host): if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host):
thing = g.db.query(AwardRelationship).order_by(AwardRelationship.id.desc()).first().id thing = g.db.query(AwardRelationship).order_by(AwardRelationship.id.desc()).first().id
data = {'access_token': GUMROAD_TOKEN}
response = [x['email'] for x in requests.get('https://api.gumroad.com/v2/products/tfcvri/subscribers', data=data, timeout=5).json()["subscribers"]]
emails = []
for email in response:
if email.endswith("@gmail.com"):
email=email.split('@')[0]
email=email.split('+')[0]
email=email.replace('.','').replace('_','')
email=f"{email}@gmail.com"
emails.append(email.lower())
for u in g.db.query(User).filter(User.patron > 0).all(): for u in g.db.query(User).filter(User.patron > 0).all():
if u.patron == 1: procoins = 2500 if u.patron == 5 or u.email and u.email.lower() in emails or u.id == 1379:
elif u.patron == 2: procoins = 5000 if u.patron == 1: procoins = 2500
elif u.patron == 3: procoins = 10000 elif u.patron == 2: procoins = 5000
elif u.patron == 4: procoins = 25000 elif u.patron == 3: procoins = 10000
elif u.patron == 5: procoins = 50000 elif u.patron == 4: procoins = 25000
u.procoins += procoins elif u.patron == 5: procoins = 50000
g.db.add(u) u.procoins += procoins
g.db.add(u)
cid = notif_comment(f"You were given {procoins} Marseybux for the month of {month}! You can use them to buy awards in the [shop](/shop).")
add_notif(cid, u.id) cid = notif_comment(f"You were given {procoins} Marseybux for the month of {month}! You can use them to buy awards in the [shop](/shop).")
add_notif(cid, u.id)
g.db.commit() g.db.commit()
return {"message": "Monthly coins granted"} return {"message": "Monthly coins granted"}
@ -1024,44 +1038,95 @@ def api_distinguish_post(post_id, v):
@app.post("/sticky/<post_id>") @app.post("/sticky/<post_id>")
@admin_level_required(2) @admin_level_required(2)
@validate_formkey @validate_formkey
def api_sticky_post(post_id, v): def sticky_post(post_id, v):
post = g.db.query(Submission).filter_by(id=post_id).first() post = g.db.query(Submission).filter_by(id=post_id).one_or_none()
if post: if post and not post.stickied:
if post.stickied: pins = g.db.query(Submission.id).filter(Submission.stickied != None, Submission.is_banned == False).count()
if post.stickied.startswith("t:"): return {"error": "Can't unpin award pins!"}, 403 if pins > 2:
else: post.stickied = None if v.admin_level > 2:
else: post.stickied = v.username
pins = g.db.query(Submission.id).filter(Submission.stickied != None, Submission.is_banned == False).count() post.stickied_utc = int(time.time()) + 3600
if pins > 2: else: return {"error": "Can't exceed 3 pinned posts limit!"}, 403
if v.admin_level > 2: else: post.stickied = v.username
t = int(time.time()) + 3600 g.db.add(post)
post.stickied = f"j:{t}"
else: return {"error": "Can't exceed 3 pinned posts limit!"}, 403 if v.id != post.author_id:
else: post.stickied = v.username send_repeatable_notification(post.author_id, f"@{v.username} has pinned your [post](/post/{post_id})!")
cache.delete_memoized(frontlist)
g.db.commit()
return {"message": "Post pinned!"}
@app.post("/unsticky/<post_id>")
@admin_level_required(2)
@validate_formkey
def unsticky_post(post_id, v):
post = g.db.query(Submission).filter_by(id=post_id).one_or_none()
if post and post.stickied:
if post.stickied.endswith('(pin award)'): return {"error": "Can't unpin award pins!"}, 403
post.stickied = None
post.stickied_utc = None
g.db.add(post) g.db.add(post)
ma=ModAction( ma=ModAction(
kind="pin_post" if post.stickied else "unpin_post", kind="unpin_post",
user_id=v.id, user_id=v.id,
target_submission_id=post.id target_submission_id=post.id
) )
g.db.add(ma) g.db.add(ma)
cache.delete_memoized(frontlist) if v.id != post.author_id:
send_repeatable_notification(post.author_id, f"@{v.username} has unpinned your [post](/post/{post_id})!")
cache.delete_memoized(frontlist)
g.db.commit()
return {"message": "Post unpinned!"}
@app.post("/sticky_comment/<cid>")
@admin_level_required(2)
@validate_formkey
def sticky_comment(cid, v):
comment = get_comment(cid, v=v)
comment.is_pinned = v.username
g.db.add(comment)
if v.id != comment.author_id:
message = f"@{v.username} has pinned your [comment]({comment.permalink})!"
send_repeatable_notification(comment.author_id, message)
g.db.commit()
return {"message": "Comment pinned!"}
@app.post("/unsticky_comment/<cid>")
@admin_level_required(2)
@validate_formkey
def unsticky_comment(cid, v):
comment = get_comment(cid, v=v)
if comment.is_pinned.endswith("(pin award)"): return {"error": "Can't unpin award pins!"}, 403
g.db.add(comment)
ma=ModAction(
kind="unpin_comment",
user_id=v.id,
target_comment_id=comment.id
)
g.db.add(ma)
if v.id != comment.author_id:
message = f"@{v.username} has unpinned your [comment]({comment.permalink})!"
send_repeatable_notification(comment.author_id, message)
g.db.commit()
return {"message": "Comment unpinned!"}
if post.stickied:
if v.id != post.author_id:
message = f"@{v.username} has pinned your [post](/post/{post_id})!"
send_repeatable_notification(post.author_id, message)
g.db.commit()
return {"message": "Post pinned!"}
else:
if v.id != post.author_id:
message = f"@{v.username} has unpinned your [post](/post/{post_id})!"
send_repeatable_notification(post.author_id, message)
g.db.commit()
return {"message": "Post unpinned!"}
@app.post("/ban_comment/<c_id>") @app.post("/ban_comment/<c_id>")
@limiter.limit("1/second") @limiter.limit("1/second")

View file

@ -18,14 +18,6 @@ discounts = {
} }
AWARDS3 = { AWARDS3 = {
"ban": {
"kind": "ban",
"title": "1-Day Ban",
"description": "Bans the recipient for a day.",
"icon": "fas fa-gavel",
"color": "text-danger",
"price": 3000
},
"fireflies": { "fireflies": {
"kind": "fireflies", "kind": "fireflies",
"title": "Fireflies", "title": "Fireflies",
@ -243,18 +235,21 @@ def award_post(pid, v):
send_repeatable_notification(CARP_ID, f"@{v.username} used {kind} award on [{post.shortlink}]({post.shortlink})") send_repeatable_notification(CARP_ID, f"@{v.username} used {kind} award on [{post.shortlink}]({post.shortlink})")
send_repeatable_notification(DAD_ID, f"@{v.username} used {kind} award on [{post.shortlink}]({post.shortlink})") send_repeatable_notification(DAD_ID, f"@{v.username} used {kind} award on [{post.shortlink}]({post.shortlink})")
elif kind == "pin": elif kind == "pin":
if post.stickied and post.stickied.startswith("t:"): t = int(post.stickied[2:]) + 3600 if post.stickied and post.stickied_utc:
else: t = int(time.time()) + 3600 post.stickied_utc += 3600
post.stickied = f"t:{t}" else:
post.stickied = f'{v.username} (pin award)'
post.stickied_utc = int(time.time()) + 3600
g.db.add(post) g.db.add(post)
cache.delete_memoized(frontlist) cache.delete_memoized(frontlist)
elif kind == "unpin": elif kind == "unpin":
if not (post.stickied and post.stickied.startswith("t:")): abort(403) if not post.stickied_utc: abort(403)
t = int(post.stickied[2:]) - 3600 t = post.stickied_utc - 3600
if time.time() > t: if time.time() > t:
post.stickied = None post.stickied = None
post.stickied_utc = None
cache.delete_memoized(frontlist) cache.delete_memoized(frontlist)
else: post.stickied = f"t:{t}" else: post.stickied_utc = t
g.db.add(post) g.db.add(post)
elif kind == "agendaposter" and not (author.agendaposter and author.agendaposter_expires_utc == 0): elif kind == "agendaposter" and not (author.agendaposter and author.agendaposter_expires_utc == 0):
if author.agendaposter_expires_utc and time.time() < author.agendaposter_expires_utc: author.agendaposter_expires_utc += 86400 if author.agendaposter_expires_utc and time.time() < author.agendaposter_expires_utc: author.agendaposter_expires_utc += 86400
@ -416,15 +411,18 @@ def award_comment(cid, v):
send_repeatable_notification(CARP_ID, f"@{v.username} used {kind} award on [{c.shortlink}]({c.shortlink})") send_repeatable_notification(CARP_ID, f"@{v.username} used {kind} award on [{c.shortlink}]({c.shortlink})")
send_repeatable_notification(DAD_ID, f"@{v.username} used {kind} award on [{c.shortlink}]({c.shortlink})") send_repeatable_notification(DAD_ID, f"@{v.username} used {kind} award on [{c.shortlink}]({c.shortlink})")
elif kind == "pin": elif kind == "pin":
if c.is_pinned and c.is_pinned.startswith("t:"): t = int(c.is_pinned[2:]) + 3600 if c.is_pinned and c.is_pinned_utc: c.is_pinned_utc += 3600
else: t = int(time.time()) + 3600 else:
c.is_pinned = f"t:{t}" c.is_pinned = f'{v.username} (pin award)'
c.is_pinned_utc = int(time.time()) + 3600
g.db.add(c) g.db.add(c)
elif kind == "unpin": elif kind == "unpin":
if not (c.is_pinned and c.is_pinned.startswith("t:")): abort(403) if not c.is_pinned_utc: abort(403)
t = int(c.is_pinned[2:]) - 3600 t = c.is_pinned_utc - 3600
if time.time() > t: c.is_pinned = None if time.time() > t:
else: c.is_pinned = f"t:{t}" c.is_pinned = None
c.is_pinned_utc = None
else: c.is_pinned_utc = t
g.db.add(c) g.db.add(c)
elif kind == "agendaposter" and not (author.agendaposter and author.agendaposter_expires_utc == 0): elif kind == "agendaposter" and not (author.agendaposter and author.agendaposter_expires_utc == 0):
if author.agendaposter_expires_utc and time.time() < author.agendaposter_expires_utc: author.agendaposter_expires_utc += 86400 if author.agendaposter_expires_utc and time.time() < author.agendaposter_expires_utc: author.agendaposter_expires_utc += 86400

View file

@ -899,48 +899,45 @@ def undelete_comment(cid, v):
@app.post("/pin_comment/<cid>") @app.post("/pin_comment/<cid>")
@auth_required @auth_required
@validate_formkey @validate_formkey
def toggle_pin_comment(cid, v): def pin_comment(cid, v):
comment = get_comment(cid, v=v) comment = get_comment(cid, v=v)
if v.admin_level < 1 and v.id != comment.post.author_id: abort(403) if v.id != comment.post.author_id: abort(403)
if comment.is_pinned: comment.is_pinned = v.username + " (OP)"
if comment.is_pinned.startswith("t:"): abort(403)
else:
if v.admin_level > 1 or comment.is_pinned.endswith(" (OP)"): comment.is_pinned = None
else: abort(403)
else:
if v.admin_level > 1: comment.is_pinned = v.username
else: comment.is_pinned = v.username + " (OP)"
g.db.add(comment) g.db.add(comment)
g.db.flush()
if v.admin_level > 1: if v.id != comment.author_id:
ma=ModAction( message = f"@{v.username} (OP) has pinned your [comment]({comment.permalink})!"
kind="pin_comment" if comment.is_pinned else "unpin_comment", send_repeatable_notification(comment.author_id, message)
user_id=v.id,
target_comment_id=comment.id
)
g.db.add(ma)
g.db.commit() g.db.commit()
return {"message": "Comment pinned!"}
if comment.is_pinned: @app.post("/unpin_comment/<cid>")
if v.id != comment.author_id: @auth_required
message = f"@{v.username} has pinned your [comment]({comment.permalink})!" @validate_formkey
send_repeatable_notification(comment.author_id, message) def unpin_comment(cid, v):
g.db.commit()
return {"message": "Comment pinned!"}
else:
if v.id != comment.author_id:
message = f"@{v.username} has unpinned your [comment]({comment.permalink})!"
send_repeatable_notification(comment.author_id, message)
g.db.commit()
return {"message": "Comment unpinned!"}
comment = get_comment(cid, v=v)
if v.id != comment.post.author_id: abort(403)
if not comment.is_pinned.endswith(" (OP)"):
return {"error": "You can only unpin comments you have pinned!"}
comment.is_pinned = None
g.db.add(comment)
if v.id != comment.author_id:
message = f"@{v.username} (OP) has unpinned your [comment]({comment.permalink})!"
send_repeatable_notification(comment.author_id, message)
g.db.commit()
return {"message": "Comment unpinned!"}
@app.post("/save_comment/<cid>") @app.post("/save_comment/<cid>")
@limiter.limit("1/second") @limiter.limit("1/second")
@auth_required @auth_required

View file

@ -279,8 +279,9 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, filter_words='
pins = pins.all() pins = pins.all()
for pin in pins: for pin in pins:
if (pin.stickied.startswith("t:") or pin.stickied.startswith("j:")) and int(time.time()) > int(pin.stickied[2:]): if pin.stickied_utc and int(time.time()) > pin.stickied_utc:
pin.stickied = None pin.stickied = None
pin.stickied_utc = None
g.db.add(pin) g.db.add(pin)
pins.remove(pin) pins.remove(pin)

View file

@ -218,8 +218,9 @@ def post_id(pid, anything=None, v=None):
comments = comments2 comments = comments2
for pin in pinned: for pin in pinned:
if pin.is_pinned.startswith("t:") and int(time.time()) > int(pin.is_pinned[2:]): if pin.is_pinned_utc and int(time.time()) > pin.is_pinned_utc:
pin.is_pinned = None pin.is_pinned = None
pin.is_pinned_utc = None
g.db.add(pin) g.db.add(pin)
pinned.remove(pin) pinned.remove(pin)

View file

@ -32,32 +32,6 @@ tiers={
"(Rich Bich)": 5, "(Rich Bich)": 5,
} }
@app.get("/sex")
@admin_level_required(3)
def sex(v):
data = {'access_token': GUMROAD_TOKEN}
response = [x['email'] for x in requests.get('https://api.gumroad.com/v2/products/tfcvri/subscribers', data=data, timeout=5).json()["subscribers"]]
emails = []
for email in response:
if email.endswith("@gmail.com"):
email=email.split('@')[0]
email=email.split('+')[0]
email=email.replace('.','').replace('_','')
email=f"{email}@gmail.com"
emails.append(email.lower())
users = g.db.query(User).filter(User.patron > 0, User.patron < 5).all()
for u in users:
if not u.email or u.email.lower() not in emails: print(f'{u.username} - {u.email}')
return "sex"
@app.post("/settings/removebackground") @app.post("/settings/removebackground")
@limiter.limit("1/second") @limiter.limit("1/second")
@auth_required @auth_required

View file

@ -169,7 +169,10 @@ def patrons(v):
@app.get("/badmins") @app.get("/badmins")
@auth_desired @auth_desired
def admins(v): def admins(v):
admins = g.db.query(User).filter(User.admin_level>0).order_by(User.truecoins.desc()).all() if v and v.admin_level > 2:
admins = g.db.query(User).filter(User.admin_level>1).order_by(User.truecoins.desc()).all()
admins += g.db.query(User).filter(User.admin_level==1).order_by(User.truecoins.desc()).all()
else: admins = g.db.query(User).filter(User.admin_level>0).order_by(User.truecoins.desc()).all()
if not v or v.oldsite: template = '' if not v or v.oldsite: template = ''
else: template = 'CHRISTMAS/' else: template = 'CHRISTMAS/'
return render_template(f"{template}admins.html", v=v, admins=admins) return render_template(f"{template}admins.html", v=v, admins=admins)

View file

@ -118,7 +118,7 @@ def api_vote_post(post_id, new, v):
g.db.flush() g.db.flush()
post.upvotes = g.db.query(Vote.id).filter_by(submission_id=post.id, vote_type=1).count() post.upvotes = g.db.query(Vote.id).filter_by(submission_id=post.id, vote_type=1).count()
post.downvotes = g.db.query(Vote.id).filter_by(submission_id=post.id, vote_type=-1).count() post.downvotes = g.db.query(Vote.id).filter_by(submission_id=post.id, vote_type=-1).count()
post.realupvotes = g.db.query(Vote.id).filter_by(submission_id=post.id, vote_type=1, real=True).count() - g.db.query(Vote.id).filter_by(submission_id=post.id, vote_type=1, real=False).count() - g.db.query(Vote.id).filter_by(submission_id=post.id, vote_type=-1, real=True).count() + g.db.query(Vote.id).filter_by(submission_id=post.id, vote_type=-1, real=False).count() post.realupvotes = g.db.query(Vote.id).filter_by(submission_id=post.id, vote_type=1, real=True).count() - g.db.query(Vote.id).filter_by(submission_id=post.id, vote_type=1, real=False).count() + g.db.query(Vote.id).filter_by(submission_id=post.id, vote_type=-1).count()
g.db.add(post) g.db.add(post)
g.db.commit() g.db.commit()
except: g.db.rollback() except: g.db.rollback()
@ -185,7 +185,7 @@ def api_vote_comment(comment_id, new, v):
g.db.flush() g.db.flush()
comment.upvotes = g.db.query(CommentVote.id).filter_by(comment_id=comment.id, vote_type=1).count() comment.upvotes = g.db.query(CommentVote.id).filter_by(comment_id=comment.id, vote_type=1).count()
comment.downvotes = g.db.query(CommentVote.id).filter_by(comment_id=comment.id, vote_type=-1).count() comment.downvotes = g.db.query(CommentVote.id).filter_by(comment_id=comment.id, vote_type=-1).count()
comment.realupvotes = g.db.query(CommentVote.id).filter_by(comment_id=comment.id, vote_type=1, real=True).count() - g.db.query(CommentVote.id).filter_by(comment_id=comment.id, vote_type=1, real=False).count() - g.db.query(CommentVote.id).filter_by(comment_id=comment.id, vote_type=-1, real=True).count() + g.db.query(CommentVote.id).filter_by(comment_id=comment.id, vote_type=-1, real=False).count() comment.realupvotes = g.db.query(CommentVote.id).filter_by(comment_id=comment.id, vote_type=1, real=True).count() - g.db.query(CommentVote.id).filter_by(comment_id=comment.id, vote_type=1, real=False).count() + g.db.query(CommentVote.id).filter_by(comment_id=comment.id, vote_type=-1).count()
g.db.add(comment) g.db.add(comment)
g.db.commit() g.db.commit()
except: g.db.rollback() except: g.db.rollback()

View file

@ -104,6 +104,6 @@
</nav> </nav>
{% endif %} {% endif %}
<script src="/static/assets/js/post_toast2.js?a=3"></script> <script src="/static/assets/js/post_toast2.js?a=4"></script>
{% endblock %} {% endblock %}

View file

@ -191,10 +191,8 @@
{% if c.active_flags %}<a class="btn btn-primary" style="padding:1px 5px; font-size:10px;" href="javascript:void(0)" onclick="document.getElementById('flaggers-{{c.id}}').classList.toggle('d-none')">{{c.active_flags}} Reports</a>{% endif %} {% if c.active_flags %}<a class="btn btn-primary" style="padding:1px 5px; font-size:10px;" href="javascript:void(0)" onclick="document.getElementById('flaggers-{{c.id}}').classList.toggle('d-none')">{{c.active_flags}} Reports</a>{% endif %}
{% if c.over_18 %}<span class="badge badge-danger text-small-extra mr-1">+18</span>{% endif %} {% if c.over_18 %}<span class="badge badge-danger text-small-extra mr-1">+18</span>{% endif %}
{% if v and v.admin_level > 1 and c.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Shadowbanned by @{{c.author.shadowbanned}}"></i>{% endif %} {% if v and v.admin_level > 1 and c.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Shadowbanned by @{{c.author.shadowbanned}}"></i>{% endif %}
{% if c.is_pinned and c.is_pinned.startswith('t:') %} {% if c.is_pinned %}
<i id='pinned-{{c.id}}' onmouseover="pinned_timestamp('pinned-{{c.id}}')" class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-timestamp={{c.is_pinned[2:]}}></i> <i id='pinned-{{c.id}}'class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Pinned by @{{c.is_pinned}}" {% if c.is_pinned_utc %}onmouseover="pinned_timestamp('pinned-{{c.id}}')" data-timestamp={{c.is_pinned_utc}} {% endif %}></i>
{% elif c.is_pinned %}
<i id='pinned-{{c.id}}' class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Pinned by @{{c.is_pinned}}"></i>
{% endif %} {% endif %}
{% if c.distinguish_level %}<i class="fas fa-broom text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="{{'SITE_NAME' | app_config}} Admin, speaking officially"></i>{% endif %} {% if c.distinguish_level %}<i class="fas fa-broom text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="{{'SITE_NAME' | app_config}} Admin, speaking officially"></i>{% endif %}
{% if c.is_op %}<i class="fas fa-microphone-stand text-info" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="OP"></i>{% endif %} {% if c.is_op %}<i class="fas fa-microphone-stand text-info" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="OP"></i>{% endif %}
@ -303,43 +301,76 @@
{% endif %} {% endif %}
<div id="comment-{{c.id}}-actions" class="comment-actions{% if voted==1 %} upvoted{% elif voted==-1 %} downvoted{% endif %}"> <div id="comment-{{c.id}}-actions" class="comment-actions{% if voted==1 %} upvoted{% elif voted==-1 %} downvoted{% endif %}">
<ul class="d-md-none list-inline text-right text-md-left {% if v and v.admin_level > 1 %}d-flex{% endif %}">
{% if v and v.admin_level > 1 %}
<button class="btn caction p-0 m-0 nobackground mr-auto d-md-none" href="javascript:void(0)" data-bs-toggle="modal" data-bs-target="#adminModal-{{c.id}}">
<i class="fas fa-broom"></i>
</button>
{% endif %}
<li class="pt-1">
{% if v %}
<button class="btn caction py-0 px-1 m-0 nobackground text-muted" href="javascript:void(0)" onclick="openReplyBox('reply-to-{{c.id}}')"><i class="fas fa-reply" aria-hidden="true"></i></button>
{% endif %}
<button class="btn caction p-0 m-0 nobackground" href="javascript:void(0)" data-bs-toggle="modal" data-bs-target="#actionsModal-{{c.id}}" data-bs-focus="false"><i class="fas fa-ellipsis-h"></i></button>
<div class="d-md-none mt-2">
<div class="post-actions">
<ul class="list-inline text-right d-flex">
<li class="list-inline-item mr-auto">
{% if v and v.admin_level > 1 %}
<a href="javascript:void(0)" data-bs-toggle="modal" data-bs-target="#adminModal-{{c.id}}">
<i class="fas fa-broom"></i>
</a>
{% endif %}
</li>
{% if v %}
<a class="list-inline-item" href="javascript:void(0)" onclick="openReplyBox('reply-to-{{c.id}}')"><i class="fas fa-reply"></i></a>
{% endif %}
{% if v and request.path.startswith('/@') and v.admin_level == 0 %} <li class="list-inline-item">
{% if voted==1 %} <a href="javascript:void(0)" data-bs-toggle="modal" data-bs-target="#actionsModal-{{c.id}}">
<button class="btn caction m-0 py-0 pr-1 pl-2 nobackground arrow-up comment-{{c.id}}-up active"></button> <i class="fas fa-ellipsis-h"></i>
</a>
</li>
{% if v and request.path.startswith('/@') and not v.admin_level %}
<li id="voting-{{c.id}}-mobile" class="voting list-inline-item d-md-none">
{% if voted==1 %}
<span class="mr-2 arrow-up comment-{{c.id}}-up active"></span>
{% endif %}
<span id="comment-mobile-score-{{c.id}}" class="score comment-score-{{c.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}"{% if not c.is_banned %} data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
{% if voted==-1 %}
<span class="ml-2 my-0 arrow-down comment-{{c.id}}-down active"></span>
{% endif %}
</li>
{% elif v %}
<li id="voting-{{c.id}}-mobile" class="voting list-inline-item d-md-none">
<span id="comment-mobile-{{c.id}}-up" tabindex="0" href="javascript:void(0)" onclick="vote('comment-mobile', '{{c.id}}', '1')" class="mx-0 pr-1 arrow-up upvote-button comment-{{c.id}}-up {% if voted==1 %}active{% endif %}">
</span>
<span id="comment-mobile-score-{{c.id}}" class="score comment-score-{{c.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}"{% if not c.is_banned %} data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<span {% if environ.get('DISABLE_DOWNVOTES') == '1' %}style="display:None!important"{% endif %} id="comment-mobile-{{c.id}}-down" tabindex="0" href="javascript:void(0)" onclick="vote('comment-mobile', '{{c.id}}', '-1')" class="mx-0 pl-1 my-0 arrow-down downvote-button comment-{{c.id}}-down {% if voted==-1 %}active{% endif %}">
</span>
</li>
{% else %}
<li id="voting-{{c.id}}-mobile" class="voting list-inline-item d-md-none">
<span id="arrow-{{c.id}}-mobile-up" tabindex="0" class="mx-0 pr-1 arrow-mobile-up" onclick="location.href='/login';">
<i class="fas fa-arrow-alt-up mx-0" aria-hidden="true"></i>
</span>
<span id="comment-mobile-score-{{c.id}}" class="score"{% if not c.is_banned %} data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<span id="arrow-{{c.id}}-mobile-down" tabindex="0" class="arrow-mobile-down mx-0 pl-1 my-0" onclick="location.href='/login';">
<i class="fas fa-arrow-alt-down mx-0" aria-hidden="true"></i>
</span>
</li>
{% endif %} {% endif %}
{% elif v %} </ul>
<button id="comment-mobile-{{c.id}}-up" tabindex="0" onclick="vote('comment-mobile', '{{c.id}}', '1')" class="btn caction m-0 py-0 pr-1 pl-2 nobackground arrow-up upvote-button comment-{{c.id}}-up {% if voted==1 %}active{% endif %}"></button> </div>
{% else %} </div>
<button id="comment-{{c.id}}-up" tabindex="0" onclick="vote('comment', '{{c.id}}', '1')" class="btn caction m-0 py-0 pr-1 pl-2 nobackground arrow-up" onclick="location.href='/login';"></button>
{% endif %}
<span style="font-size:14px" class="score caction btn m-0 p-0 nobackground comment-score-{{c.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-original-title="+{{ups}} | -{{downs}}" id="comment-mobile-score-{{c.id}}">{{score}}</span>
{% if v and request.path.startswith('/@') and v.admin_level == 0 %}
{% if voted==-1 %}
<button class="btn caction m-0 p-0 pl-1 nobackground arrow-down comment-{{c.id}}-up active"></button>
{% endif %}
{% elif v %}
<button {% if environ.get('DISABLE_DOWNVOTES') == '1' %}style="display:None!important"{% endif %} id="comment-mobile-{{c.id}}-down" tabindex="0" onclick="vote('comment-mobile', '{{c.id}}', '-1')" class="btn caction m-0 p-0 pl-1 nobackground arrow-down downvote-button comment-{{c.id}}-down {% if voted==-1 %}active{% endif %}"></button>
{% else %}
<a {% if environ.get('DISABLE_DOWNVOTES') == '1' %}style="display:None!important"{% endif %} id="comment-{{c.id}}-down" tabindex="0" onclick="vote('comment', '{{c.id}}', '-1')" class="arrow-down m-0 p-0 pl-1" onclick="location.href='/login';"></a>
{% endif %}
</li>
</ul>
@ -419,10 +450,16 @@
<button id="block-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if not c.is_blocking %}d-md-inline-block{% endif %} d-none text-danger" onclick="document.getElementById('block-{{c.id}}').classList.toggle('d-md-inline-block');document.getElementById('prompt-{{c.id}}').classList.toggle('d-md-inline-block');"><i class="fas fa-eye-slash fa-fw text-danger"></i>Block user</button> <button id="block-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if not c.is_blocking %}d-md-inline-block{% endif %} d-none text-danger" onclick="document.getElementById('block-{{c.id}}').classList.toggle('d-md-inline-block');document.getElementById('prompt-{{c.id}}').classList.toggle('d-md-inline-block');"><i class="fas fa-eye-slash fa-fw text-danger"></i>Block user</button>
{% endif %} {% endif %}
{% if v and c.post and (v.admin_level > 1 or v.id == c.post.author_id) %} {% if v and c.post %}
<button id="unpin-{{c.id}}" class="btn caction py-0 nobackground {% if c.is_pinned %}d-md-inline-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/pin_comment/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Unpin</button> {% if v.admin_level > 1 %}
<button id="unpin-{{c.id}}" class="btn caction py-0 nobackground {% if c.is_pinned %}d-md-inline-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/unsticky_comment/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Unpin</button>
<button id="pin-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if not c.is_pinned %}d-md-inline-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/pin_comment/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Pin</button>
<button id="pin-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if not c.is_pinned %}d-md-inline-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/sticky_comment/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Pin</button>
{% elif v.id == c.post.author_id and v.admin_level %}
<button id="unpin-{{c.id}}" class="btn caction py-0 nobackground {% if c.is_pinned %}d-md-inline-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/unpin_comment/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Unpin</button>
<button id="pin-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if not c.is_pinned %}d-md-inline-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/pin_comment/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Pin</button>
{% endif %}
{% endif %} {% endif %}
@ -566,9 +603,9 @@
{% endif %} {% endif %}
{% if c.post and v.id == c.post.author_id %} {% if c.post and v.id == c.post.author_id and not v.admin_level %}
<a id="pin2-{{c.id}}" class="list-group-item {% if c.is_pinned %}d-none{% endif %} text-info" href="javascript:void(0)" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast2('/pin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Pin</a> <a id="pin2-{{c.id}}" class="list-group-item {% if c.is_pinned %}d-none{% endif %} text-info" href="javascript:void(0)" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast2('/pin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Pin</a>
<a id="unpin2-{{c.id}}" class="list-group-item {% if not c.is_pinned %}d-none{% endif %} text-info" href="javascript:void(0)" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast2('/pin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Unpin</a> <a id="unpin2-{{c.id}}" class="list-group-item {% if not c.is_pinned %}d-none{% endif %} text-info" href="javascript:void(0)" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast2('/unpin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Unpin</a>
{% endif %} {% endif %}
{% endif %} {% endif %}
</ul> </ul>
@ -595,8 +632,8 @@
<div class="modal-body"> <div class="modal-body">
<ul class="list-group comment-actions"> <ul class="list-group comment-actions">
{% if c.parent_submission %} {% if c.parent_submission %}
<a id="pin2-{{c.id}}" class="list-group-item {% if c.is_pinned %}d-none{% endif %} text-info" href="javascript:void(0)" data-bs-target="#adminModal-{{c.id}}" onclick="post_toast2('/pin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Pin</a> <a id="pin2-{{c.id}}" class="list-group-item {% if c.is_pinned %}d-none{% endif %} text-info" href="javascript:void(0)" data-bs-target="#adminModal-{{c.id}}" onclick="post_toast2('/sticky_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Pin</a>
<a id="unpin2-{{c.id}}" class="list-group-item {% if not c.is_pinned %}d-none{% endif %} text-info" href="javascript:void(0)" data-bs-target="#adminModal-{{c.id}}" onclick="post_toast2('/pin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Unpin</a> <a id="unpin2-{{c.id}}" class="list-group-item {% if not c.is_pinned %}d-none{% endif %} text-info" href="javascript:void(0)" data-bs-target="#adminModal-{{c.id}}" onclick="post_toast2('/unsticky_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Unpin</a>
<a id="mark2-{{c.id}}" class="{% if c.over_18 %}d-none{% endif %} list-group-item text-danger" href="javascript:void(0)" onclick="post_toast2('/toggle_comment_nsfw/{{c.id}}','mark2-{{c.id}}','unmark2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-eye-evil text-danger"></i>Mark +18</a> <a id="mark2-{{c.id}}" class="{% if c.over_18 %}d-none{% endif %} list-group-item text-danger" href="javascript:void(0)" onclick="post_toast2('/toggle_comment_nsfw/{{c.id}}','mark2-{{c.id}}','unmark2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-eye-evil text-danger"></i>Mark +18</a>
<a id="unmark2-{{c.id}}" class="{% if not c.over_18 %}d-none{% endif %} list-group-item text-danger" href="javascript:void(0)" onclick="post_toast2('/toggle_comment_nsfw/{{c.id}}','mark2-{{c.id}}','unmark2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-eye-evil text-danger"></i>Unmark +18</a> <a id="unmark2-{{c.id}}" class="{% if not c.over_18 %}d-none{% endif %} list-group-item text-danger" href="javascript:void(0)" onclick="post_toast2('/toggle_comment_nsfw/{{c.id}}','mark2-{{c.id}}','unmark2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-eye-evil text-danger"></i>Unmark +18</a>
@ -807,7 +844,7 @@
{% if v %} {% if v %}
<script src="/static/assets/js/marked.js?a=3"></script> <script src="/static/assets/js/marked.js?a=3"></script>
<script src="/static/assets/js/comments_v.js?a=3"></script> <script src="/static/assets/js/comments_v.js?a=4"></script>
{% endif %} {% endif %}
<script src="/static/assets/js/clipboard.js?a=3"></script> <script src="/static/assets/js/clipboard.js?a=3"></script>
@ -818,8 +855,8 @@
{% include "expanded_image_modal.html" %} {% include "expanded_image_modal.html" %}
<script src="/static/assets/js/comments+submission_listing.js?a=3"></script> <script src="/static/assets/js/comments+submission_listing.js?a=5"></script>
<script src="/static/assets/js/comments.js?a=3"></script> <script src="/static/assets/js/comments.js?a=4"></script>
<script> <script>
{% if p and (not v or v.highlightcomments) %} {% if p and (not v or v.highlightcomments) %}

View file

@ -287,7 +287,7 @@
<script src="/static/assets/js/lozad.js?a=3"></script> <script src="/static/assets/js/lozad.js?a=3"></script>
{% if v %} {% if v %}
<script src="/static/assets/js/post_toast2.js?a=3"></script> <script src="/static/assets/js/post_toast2.js?a=4"></script>
<script src="/static/assets/js/formatting.js?a=3"></script> <script src="/static/assets/js/formatting.js?a=3"></script>
<script src="/static/assets/js/default.js?a=3"></script> <script src="/static/assets/js/default.js?a=3"></script>
{% endif %} {% endif %}

View file

@ -81,7 +81,7 @@
</div> </div>
</div> </div>
<script src="/static/assets/js/emoji_modal.js?a=3"></script> <script src="/static/assets/js/emoji_modal.js?a=4"></script>
<style> <style>
a.emojitab { a.emojitab {

View file

@ -214,7 +214,7 @@
</div> </div>
</nav> </nav>
<script src="/static/assets/js/header.js?a=3"></script> <script src="/static/assets/js/header.js?a=4"></script>
<style> <style>
.notif-count { .notif-count {

View file

@ -252,7 +252,7 @@
<button id="unclub2-{{p.id}}" class="{% if not p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-info text-left" href="javascript:void(0)" onclick="post_toast2('/toggle_club/{{p.id}}','club2-{{p.id}}','unclub2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-eye mr-3"></i>Unmark club</button> <button id="unclub2-{{p.id}}" class="{% if not p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-info text-left" href="javascript:void(0)" onclick="post_toast2('/toggle_club/{{p.id}}','club2-{{p.id}}','unclub2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-eye mr-3"></i>Unmark club</button>
<button id="pin2-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Pin</button> <button id="pin2-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Pin</button>
<button id="unpin2-{{p.id}}" class="{% if not p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Unpin</button> <button id="unpin2-{{p.id}}" class="{% if not p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/unsticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Unpin</button>
{% if v==p.author %} {% if v==p.author %}
<button id="distinguish2-{{p.id}}" class="{% if p.distinguish_level %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-crown text-center mr-3"></i>Distinguish</button> <button id="distinguish2-{{p.id}}" class="{% if p.distinguish_level %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-crown text-center mr-3"></i>Distinguish</button>
@ -323,10 +323,8 @@
{% endif %} {% endif %}
{% if v and v.admin_level > 1 and p.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Shadowbanned by @{{p.author.shadowbanned}}"></i>{% endif %} {% if v and v.admin_level > 1 and p.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Shadowbanned by @{{p.author.shadowbanned}}"></i>{% endif %}
{% if p.stickied and (p.stickied.startswith('t:') or p.stickied.startswith('j:')) %} {% if p.stickied %}
<i id='pinned-{{p.id}}' onmouseover="pinned_timestamp('pinned-{{p.id}}')" class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-timestamp={{p.stickied[2:]}}></i> <i id='pinned-{{p.id}}' class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Pinned by @{{p.stickied}}" {% if p.stickied_utc %}onmouseover="pinned_timestamp('pinned-{{p.id}}')" data-timestamp={{p.stickied_utc}} {% endif %}></i>
{% elif p.stickied %}
<i id='pinned-{{p.id}}' class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Pinned by @{{p.stickied}}"></i>
{% endif %} {% endif %}
{% if p.is_pinned %}<i class="fas fa-thumbtack fa-rotate--45 fa-fw text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Pinned to profile"></i>{% endif %} {% if p.is_pinned %}<i class="fas fa-thumbtack fa-rotate--45 fa-fw text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Pinned to profile"></i>{% endif %}
@ -547,7 +545,7 @@
{% endif %} {% endif %}
{% if v and v.admin_level > 0 %} {% if v and v.admin_level > 0 %}
<a id="pin-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Pin</a> <a id="pin-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Pin</a>
<a id="unpin-{{p.id}}" class="{% if not p.stickied %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Unpin</a> <a id="unpin-{{p.id}}" class="{% if not p.stickied %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/unsticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Unpin</a>
{% if v==p.author %} {% if v==p.author %}
<a id="distinguish-{{p.id}}" class="{% if p.distinguish_level %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}')"><i class="fas fa-crown"></i>Distinguish</a> <a id="distinguish-{{p.id}}" class="{% if p.distinguish_level %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}')"><i class="fas fa-crown"></i>Distinguish</a>
<a id="undistinguish-{{p.id}}" class="{% if not p.distinguish_level %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}')"><i class="fas fa-crown"></i>Undistinguish</a> <a id="undistinguish-{{p.id}}" class="{% if not p.distinguish_level %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}')"><i class="fas fa-crown"></i>Undistinguish</a>

View file

@ -18,35 +18,6 @@
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block adminpanel %}
{% if v.admin_level > 1 %}
<form action="/sticky/{{p.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="submit" value="{% if p.stickied %}Un-sticky{% else %}Pin{% endif %}">
</form>
{% endif %}
{% if v.admin_level > 0 and v.id==p.author_id %}
<form action="/distinguish/{{p.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="submit" value="{% if p.distinguish_level %}Un-distinguish{% else %}Distinguish{% endif %}">
</form>
{% endif %}
{% if v.admin_level > 1 and v.admin_level > p.author.admin_level %}
{% if p.is_banned %}
<form action="/unban_post/{{p.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="submit" value="Approve Post">
</form>
{% else %}
<form action="/ban_post/{{p.id}}", method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="submit" value="Remove Post">
</form>
{% endif %}
{% endif %}
<p>Score: +{{p.upvotes}}/-{{p.downvotes}}</p>
{% endblock %}
{% block content %} {% block content %}
<div class="mb-2 p-3"> <div class="mb-2 p-3">

View file

@ -164,12 +164,12 @@
<i class="{{a.class_list}} px-1" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="{{a.title}} Award given by @{{a.user.username}}"></i> <i class="{{a.class_list}} px-1" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="{{a.title}} Award given by @{{a.user.username}}"></i>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if v and v.admin_level > 1 and p.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Shadowbanned by @{{p.author.shadowbanned}}"></i>{% endif %} {% if v and v.admin_level > 1 and p.author.shadowbanned %}
<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Shadowbanned by @{{p.author.shadowbanned}}"></i>
{% endif %}
{% if p.stickied and (p.stickied.startswith('t:') or p.stickied.startswith('j:')) %} {% if p.stickied %}
<i id='pinned-{{p.id}}' onmouseover="pinned_timestamp('pinned-{{p.id}}')" class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-timestamp={{p.stickied[2:]}}*1000></i> <i id='pinned-{{p.id}}' class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Pinned by @{{p.stickied}}" {% if p.stickied_utc %}onmouseover="pinned_timestamp('pinned-{{p.id}}')" data-timestamp={{p.stickied_utc}} {% endif %}></i>
{% elif p.stickied %}
<i id='pinned-{{p.id}}' class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="Pinned by @{{p.stickied}}"></i>
{% endif %} {% endif %}
{% if p.distinguish_level %}<i class="fas fa-broom text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="{{'SITE_NAME' | app_config}} Admin, speaking officially"></i>{% endif %} {% if p.distinguish_level %}<i class="fas fa-broom text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="{{'SITE_NAME' | app_config}} Admin, speaking officially"></i>{% endif %}
@ -242,7 +242,7 @@
{% if v and v.admin_level > 0 %} {% if v and v.admin_level > 0 %}
<a id="pin-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Pin</a> <a id="pin-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Pin</a>
<a id="unpin-{{p.id}}" class="{% if not p.stickied %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Unpin</a> <a id="unpin-{{p.id}}" class="{% if not p.stickied %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/unsticky/{{p.id}}','pin-{{p.id}}','unpin-{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Unpin</a>
{% if v==p.author %} {% if v==p.author %}
<a id="distinguish-{{p.id}}" class="{% if p.distinguish_level %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}')"><i class="fas fa-crown"></i>Distinguish</a> <a id="distinguish-{{p.id}}" class="{% if p.distinguish_level %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}')"><i class="fas fa-crown"></i>Distinguish</a>
<a id="undistinguish-{{p.id}}" class="{% if not p.distinguish_level %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}')"><i class="fas fa-crown"></i>Undistinguish</a> <a id="undistinguish-{{p.id}}" class="{% if not p.distinguish_level %}d-none{% endif %} list-inline-item text-info" href="javascript:void(0)" onclick="post_toast2('/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}')"><i class="fas fa-crown"></i>Undistinguish</a>
@ -447,7 +447,7 @@
<button id="unclub2-{{p.id}}" class="{% if not p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-info text-left" href="javascript:void(0)" onclick="post_toast2('/toggle_club/{{p.id}}','club2-{{p.id}}','unclub2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-eye mr-3"></i>Unmark club</button> <button id="unclub2-{{p.id}}" class="{% if not p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-info text-left" href="javascript:void(0)" onclick="post_toast2('/toggle_club/{{p.id}}','club2-{{p.id}}','unclub2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-eye mr-3"></i>Unmark club</button>
<button id="pin2-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Pin</button> <button id="pin2-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Pin</button>
<button id="unpin2-{{p.id}}" class="{% if not p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/sticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Unpin</button> <button id="unpin2-{{p.id}}" class="{% if not p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/unsticky/{{p.id}}','pin2-{{p.id}}','unpin2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Unpin</button>
{% if v==p.author %} {% if v==p.author %}
<button id="distinguish2-{{p.id}}" class="{% if p.distinguish_level %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-crown text-center mr-3"></i>Distinguish</button> <button id="distinguish2-{{p.id}}" class="{% if p.distinguish_level %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" href="javascript:void(0)" onclick="post_toast2('/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-crown text-center mr-3"></i>Distinguish</button>
@ -676,5 +676,5 @@
</style> </style>
<script src="/static/assets/js/clipboard.js?a=3"></script> <script src="/static/assets/js/clipboard.js?a=3"></script>
<script src="/static/assets/js/comments+submission_listing.js?a=3"></script> <script src="/static/assets/js/comments+submission_listing.js?a=5"></script>
<script src="/static/assets/js/submission_listing.js?a=3"></script> <script src="/static/assets/js/submission_listing.js?a=3"></script>