forked from rDrama/rDrama
Merge branch 'master' of https://github.com/Aevann1/Drama
commit
6599d269ec
|
@ -112,3 +112,4 @@ package-lock.json
|
|||
local.txt
|
||||
*.scssc
|
||||
.idea/*
|
||||
disablesignups
|
||||
|
|
|
@ -3,18 +3,20 @@
|
|||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import relationship
|
||||
#from .mix_ins import *
|
||||
from drama.__main__ import Base
|
||||
from drama.__main__ import Base, app
|
||||
|
||||
AWARDS = {
|
||||
"ban": {
|
||||
"kind": "ban",
|
||||
"title": "1-Day Ban",
|
||||
"description": "Ban the author for a day.",
|
||||
"icon": "fas fa-gavel",
|
||||
"color": "text-danger"
|
||||
},
|
||||
"shit": {
|
||||
"kind": "shit",
|
||||
"title": "Literal Shitpost",
|
||||
"description": "Let OP know how much their post sucks ass.",
|
||||
"description": "Let OP know how much their post sucks ass. Flies will swarm their idiotic post. (flies only work on posts lol!!)",
|
||||
"icon": "fas fa-poop",
|
||||
"color": "text-black-50"
|
||||
}
|
||||
|
@ -28,8 +30,8 @@ class AwardRelationship(Base):
|
|||
id = Column(Integer, primary_key=True)
|
||||
|
||||
user_id = Column(Integer, ForeignKey("users.id"))
|
||||
submission_id = Column(Integer, ForeignKey("submissions.id"))
|
||||
comment_id = Column(Integer, ForeignKey("comments.id"))
|
||||
submission_id = Column(Integer, ForeignKey("submissions.id"), default=None)
|
||||
comment_id = Column(Integer, ForeignKey("comments.id"), default=None)
|
||||
kind = Column(String(20))
|
||||
|
||||
user = relationship("User", primaryjoin="AwardRelationship.user_id==User.id", lazy="joined")
|
||||
|
@ -44,6 +46,18 @@ class AwardRelationship(Base):
|
|||
lazy="joined"
|
||||
)
|
||||
|
||||
@property
|
||||
def given(self):
|
||||
return bool(self.submission_id) or bool(self.comment_id)
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return AWARDS[self.kind]
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
return self.type['title']
|
||||
|
||||
@property
|
||||
def class_list(self):
|
||||
return self.type['icon']+' '+self.type['color']
|
||||
|
|
|
@ -67,7 +67,7 @@ class Comment(Base, Age_times, Scores, Stndrd, Fuzzing):
|
|||
parent_comment = relationship("Comment", remote_side=[id])
|
||||
child_comments = relationship("Comment", remote_side=[parent_comment_id])
|
||||
|
||||
#awards = relationship("AwardRelationship", lazy="joined")
|
||||
awards = relationship("AwardRelationship", lazy="joined")
|
||||
|
||||
# These are virtual properties handled as postgres functions server-side
|
||||
# There is no difference to SQLAlchemy, but they cannot be written to
|
||||
|
|
|
@ -90,7 +90,7 @@ class Submission(Base, Stndrd, Age_times, Scores, Fuzzing):
|
|||
comment_count = Column(Integer, server_default=FetchedValue())
|
||||
score = deferred(Column(Float, server_default=FetchedValue()))
|
||||
|
||||
#awards = relationship("AwardRelationship", lazy="joined")
|
||||
awards = relationship("AwardRelationship", lazy="joined")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
|
@ -284,6 +284,9 @@ class Submission(Base, Stndrd, Age_times, Scores, Fuzzing):
|
|||
|
||||
return data
|
||||
|
||||
def has_award(self, kind):
|
||||
return bool(len([x for x in self.awards if x.kind == kind]))
|
||||
|
||||
@property
|
||||
def voted(self):
|
||||
return self._voted if "_voted" in self.__dict__ else 0
|
||||
|
|
|
@ -104,6 +104,12 @@ class User(Base, Stndrd, Age_times):
|
|||
lazy="dynamic",
|
||||
primaryjoin="User.id==SaveRelationship.user_id")
|
||||
|
||||
awards = relationship(
|
||||
"AwardRelationship",
|
||||
lazy="dynamic",
|
||||
primaryjoin="User.id==AwardRelationship.user_id"
|
||||
)
|
||||
|
||||
# properties defined as SQL server-side functions
|
||||
referral_count = deferred(Column(Integer, server_default=FetchedValue()))
|
||||
|
||||
|
|
|
@ -13,3 +13,4 @@ from .static import *
|
|||
from .users import *
|
||||
from .votes import *
|
||||
from .feeds import *
|
||||
from .awards import *
|
|
@ -0,0 +1,211 @@
|
|||
from drama.__main__ import app
|
||||
from drama.helpers.wrappers import *
|
||||
from drama.helpers.alerts import *
|
||||
from drama.helpers.get import *
|
||||
from drama.classes.award import *
|
||||
from flask import g, jsonify, request
|
||||
|
||||
|
||||
def banaward_trigger(post=None, comment=None):
|
||||
|
||||
author = post.author if post else comment.author
|
||||
link = f"[this post]({post.permalink})" if post else f"[this comment]({comment.permalink})"
|
||||
|
||||
if author.admin_level < 1:
|
||||
if not author.is_suspended:
|
||||
author.ban(reason="1-day ban award used", days=1)
|
||||
|
||||
send_notification(1046, author, f"Your Drama account has been suspended for a day for {link}. It sucked and you should feel bad.")
|
||||
elif author.unban_utc > 0:
|
||||
author.unban_utc += 24*60*60
|
||||
g.db.add(author)
|
||||
|
||||
send_notification(1046, author,
|
||||
f"Your Drama account has been suspended for yet another day for {link}. Seriously man?")
|
||||
|
||||
|
||||
ACTIONS = {
|
||||
"ban": banaward_trigger
|
||||
}
|
||||
|
||||
ALLOW_MULTIPLE = (
|
||||
"ban",
|
||||
)
|
||||
|
||||
|
||||
@app.get("/api/awards")
|
||||
@auth_required
|
||||
def get_awards(v):
|
||||
|
||||
return_value = list(AWARDS.values())
|
||||
|
||||
user_awards = v.awards
|
||||
for val in return_value:
|
||||
val['owned'] = len([x for x in user_awards if x.kind == val['kind'] and not x.given])
|
||||
|
||||
return jsonify(return_value)
|
||||
|
||||
|
||||
@app.put("/api/post/<pid>/awards")
|
||||
@auth_required
|
||||
@validate_formkey
|
||||
def award_post(pid, v):
|
||||
|
||||
if v.is_suspended and v.unban_utc == 0:
|
||||
return jsonify({"error": "forbidden"}), 403
|
||||
|
||||
kind = request.form.get("kind", "")
|
||||
|
||||
if kind not in AWARDS:
|
||||
return jsonify({"error": "That award doesn't exist."}), 404
|
||||
|
||||
post_award = g.db.query(AwardRelationship).filter(
|
||||
and_(
|
||||
AwardRelationship.kind == kind,
|
||||
AwardRelationship.user_id == v.id,
|
||||
AwardRelationship.submission_id == None,
|
||||
AwardRelationship.comment_id == None
|
||||
)
|
||||
).first()
|
||||
|
||||
if not post_award:
|
||||
return jsonify({"error": "You don't have that award."}), 404
|
||||
|
||||
post = g.db.query(Submission).filter_by(id=pid).first()
|
||||
|
||||
if not post or post.is_banned or post.deleted_utc > 0:
|
||||
return jsonify({"error": "That post doesn't exist or has been deleted or removed."}), 404
|
||||
|
||||
if post.author_id == v.id:
|
||||
return jsonify({"error": "You can't award yourself."}), 403
|
||||
|
||||
existing_award = g.db.query(AwardRelationship).filter(
|
||||
and_(
|
||||
AwardRelationship.submission_id == post.id,
|
||||
AwardRelationship.user_id == v.id,
|
||||
AwardRelationship.kind == kind
|
||||
)
|
||||
).first()
|
||||
|
||||
if existing_award and kind not in ALLOW_MULTIPLE:
|
||||
return jsonify({"error": "You can't give that award multiple times to the same post."}), 409
|
||||
|
||||
post_award.submission_id = post.id
|
||||
#print(f"give award to pid {post_award.submission_id} ({post.id})")
|
||||
g.db.add(post_award)
|
||||
|
||||
msg = f"@{v.username} has given your [post]({post.permalink}) the {AWARDS[kind]['title']} Award!"
|
||||
|
||||
note = request.form.get("note", "")
|
||||
if note:
|
||||
msg += f"\n\n> {note}"
|
||||
|
||||
send_notification(1046, post.author, msg)
|
||||
|
||||
if kind in ACTIONS:
|
||||
ACTIONS[kind](post=post)
|
||||
|
||||
return "", 204
|
||||
|
||||
|
||||
@app.put("/api/comment/<cid>/awards")
|
||||
@auth_required
|
||||
@validate_formkey
|
||||
def award_comment(cid, v):
|
||||
|
||||
if v.is_suspended and v.unban_utc == 0:
|
||||
return jsonify({"error": "forbidden"}), 403
|
||||
|
||||
kind = request.form.get("kind", "")
|
||||
|
||||
if kind not in AWARDS:
|
||||
return jsonify({"error": "That award doesn't exist."}), 404
|
||||
|
||||
comment_award = g.db.query(AwardRelationship).filter(
|
||||
and_(
|
||||
AwardRelationship.kind == kind,
|
||||
AwardRelationship.user_id == v.id,
|
||||
AwardRelationship.submission_id == None,
|
||||
AwardRelationship.comment_id == None
|
||||
)
|
||||
).first()
|
||||
|
||||
if not comment_award:
|
||||
return jsonify({"error": "You don't have that award."}), 404
|
||||
|
||||
c = g.db.query(Comment).filter_by(id=cid).first()
|
||||
|
||||
if not c or c.is_banned or c.deleted_utc > 0:
|
||||
return jsonify({"error": "That comment doesn't exist or has been deleted or removed."}), 404
|
||||
|
||||
if c.author_id == v.id:
|
||||
return jsonify({"error": "You can't award yourself."}), 403
|
||||
|
||||
existing_award = g.db.query(AwardRelationship).filter(
|
||||
and_(
|
||||
AwardRelationship.comment_id == c.id,
|
||||
AwardRelationship.user_id == v.id,
|
||||
AwardRelationship.kind == kind
|
||||
)
|
||||
).first()
|
||||
|
||||
if existing_award and kind not in ALLOW_MULTIPLE:
|
||||
return jsonify({"error": "You can't give that award multiple times to the same comment."}), 409
|
||||
|
||||
comment_award.comment_id = c.id
|
||||
g.db.add(comment_award)
|
||||
|
||||
msg = f"@{v.username} has given your [comment]({c.permalink}) the {AWARDS[kind]['title']} Award!"
|
||||
|
||||
note = request.form.get("note", "")
|
||||
if note:
|
||||
msg += f"\n\n> {note}"
|
||||
|
||||
send_notification(1046, c.author, msg)
|
||||
|
||||
if kind in ACTIONS:
|
||||
ACTIONS[kind](comment=c)
|
||||
|
||||
return "", 204
|
||||
|
||||
@app.get("/admin/user_award")
|
||||
@auth_required
|
||||
def admin_userawards_get(v):
|
||||
|
||||
if v.admin_level < 6:
|
||||
abort(403)
|
||||
|
||||
return render_template("admin/user_award.html", awards=list(AWARDS.values()), v=v)
|
||||
|
||||
@app.post("/admin/user_award")
|
||||
@auth_required
|
||||
@validate_formkey
|
||||
def admin_userawards_post(v):
|
||||
|
||||
if v.admin_level < 6:
|
||||
abort(403)
|
||||
|
||||
u = get_user(request.form.get("username", '1'), graceful=False, v=v)
|
||||
|
||||
awards = []
|
||||
|
||||
latest = g.db.query(AwardRelationship).order_by(AwardRelationship.id.desc()).first()
|
||||
thing = latest.id
|
||||
|
||||
for key, value in request.form.items():
|
||||
if key not in AWARDS:
|
||||
continue
|
||||
|
||||
if value:
|
||||
for x in range(int(value)):
|
||||
thing += 1
|
||||
|
||||
awards.append(AwardRelationship(
|
||||
id=thing,
|
||||
user_id=u.id,
|
||||
kind=key
|
||||
))
|
||||
|
||||
g.db.bulk_save_objects(awards)
|
||||
|
||||
return redirect(f'/@{u.username}')
|
|
@ -10,6 +10,7 @@
|
|||
<pre></pre>
|
||||
<h4> Admin Tools</h4>
|
||||
{% filter markdown %}
|
||||
* [Grant User Award](/admin/user_award)
|
||||
* [Advanced Stats](/api/user_stat_data)
|
||||
* [Ban Domain](/admin/domain/enter%20domain%20here)
|
||||
* [Shadowbanned Users](/admin/shadowbanned)
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
{% extends "default.html" %}
|
||||
|
||||
{% block title %}
|
||||
<title>Grant User Award</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block pagetype %}message{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if error %}
|
||||
<div class="alert alert-danger alert-dismissible fade show my-3" role="alert">
|
||||
<i class="fas fa-exclamation-circle my-auto"></i>
|
||||
<span>
|
||||
{{error}}
|
||||
</span>
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true"><i class="far fa-times"></i></span>
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if msg %}
|
||||
<div class="alert alert-success alert-dismissible fade show my-3" role="alert">
|
||||
<i class="fas fa-check-circle my-auto" aria-hidden="true"></i>
|
||||
<span>
|
||||
{{msg}}
|
||||
</span>
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true"><i class="far fa-times"></i></span>
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<pre></pre>
|
||||
<pre></pre>
|
||||
<h5>User Award Grant</h5>
|
||||
|
||||
<form action="/admin/user_award", method="post">
|
||||
<input type="hidden" name="formkey" value="{{v.formkey}}">
|
||||
|
||||
|
||||
<label for="input-username">Username</label><br>
|
||||
<input id="input-username" class="form-control mb-3" type="text" name="username" required>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead class="bg-primary text-white">
|
||||
<tr>
|
||||
<th scope="col">Icon</th>
|
||||
<th scope="col">Title</th>
|
||||
<th scope="col">Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for a in awards %}
|
||||
<tr>
|
||||
<td><i class="{{ a['icon'] }} {{ a['color'] }}" style="font-size: 30px"></i></td>
|
||||
<td style="font-weight: bold">{{ a['title'] }}</td>
|
||||
<td><input type="number" class="form-control" name="{{ a['kind'] }}" value="0" placeholder="enter amount" /></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<input class="btn btn-primary mt-3" type="submit" value="Grant Awards">
|
||||
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -0,0 +1,152 @@
|
|||
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
|
||||
|
||||
<input type="hidden" id="awardTarget" value="" />
|
||||
<div class="modal fade" id="awardModal" tabindex="-1" role="dialog" aria-labelledby="awardModalTitle" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Give Award</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true"><i class="far fa-times"></i></span>
|
||||
</button>
|
||||
</div>
|
||||
<div id="awardModalBody" class="modal-body">
|
||||
<form v-if="loaded" id="sex" class="pt-3 pb-0">
|
||||
<div class="card-columns awards-wrapper">
|
||||
<div v-for="(award, index) in awards" :key="index">
|
||||
<input type="radio" :id="index" :value="index" v-model="picked" :disabled="award.owned < 1">
|
||||
<label class="card" :for="index" :class="{ disabled: award.owned < 1 }">
|
||||
<i :class="award.icon+' '+award.color"></i><br />
|
||||
<span class="d-block pt-2" style="font-weight: bold; font-size: 14px;">[[ award.title ]]</span>
|
||||
<span class="text-muted">[[ award.owned ]] owned</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="picked !== null">
|
||||
<div class="award-desc p-3">
|
||||
<i style="font-size: 35px;" :class="pickedAward.icon+' '+pickedAward.color"></i>
|
||||
<div style="margin-left: 15px;">
|
||||
<strong>[[ pickedAward.title ]] Award</strong><br />
|
||||
<span class="text-muted">[[ pickedAward.description ]]</span>
|
||||
</div>
|
||||
</div>
|
||||
<label for="note" class="pt-4">Note (optional):</label>
|
||||
<textarea id="note" name="note" v-model="note" class="form-control" placeholder="Note to include in award notification"></textarea>
|
||||
</div>
|
||||
</form>
|
||||
<div v-else-if="error" class="p-5 text-center">
|
||||
<h4>Failed to fetch awards</h4>
|
||||
<button class="btn btn-primary">Retry</button>
|
||||
</div>
|
||||
<div v-else class="p-5 text-center">
|
||||
<h4>Loading...</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-link text-muted" data-dismiss="modal">Cancel</button>
|
||||
<button v-if="pending" class="btn btn-warning" type="button" disabled>
|
||||
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
||||
Gifting...
|
||||
</button>
|
||||
<button v-else type="submit" class="btn btn-warning" id="awardButton" @click="submit" :disabled="pickedAward === null">Give Award</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.awards-wrapper input[type="radio"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.awards-wrapper label {
|
||||
cursor: pointer;
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
text-transform: none!important;
|
||||
}
|
||||
|
||||
.awards-wrapper label i {
|
||||
font-size: 45px;
|
||||
}
|
||||
|
||||
.awards-wrapper label.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.awards-wrapper label:hover {
|
||||
/*background-color: rgba(173, 226, 255, 0.7)!important;*/
|
||||
background-color: var(--primary)!important;
|
||||
background-opacity: 0.4;
|
||||
}
|
||||
|
||||
.awards-wrapper input[type="radio"]:checked+label {
|
||||
/*background-color: rgba(173, 226, 255, 0.9)!important;*/
|
||||
background-color: var(--primary)!important;
|
||||
background-opacity: 0.9;
|
||||
}
|
||||
|
||||
.award-desc {
|
||||
border-radius: 5px;
|
||||
background-color: rgba(221, 221, 221, 0.23);
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
new Vue({
|
||||
el: "#awardModal",
|
||||
delimiters: ['[[', ']]'],
|
||||
data: {
|
||||
loaded: false,
|
||||
error: false,
|
||||
pending: false,
|
||||
awards: [],
|
||||
picked: null,
|
||||
note: ""
|
||||
},
|
||||
computed: {
|
||||
pickedAward: function() {
|
||||
if (this.picked !== null) {
|
||||
return this.awards[this.picked];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async submit() {
|
||||
this.pending = true;
|
||||
|
||||
const target = document.getElementById("awardTarget").value;
|
||||
|
||||
const f = new FormData();
|
||||
f.append("formkey", formkey());
|
||||
f.append("kind", this.pickedAward.kind || "");
|
||||
f.append("note", this.note)
|
||||
|
||||
let response = await fetch(target, {
|
||||
method: "PUT",
|
||||
body: f
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
location.reload();
|
||||
} else {
|
||||
this.pending = false;
|
||||
let s = await response.json();
|
||||
alert(s.error);
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
fetch('/api/awards')
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
this.awards = json;
|
||||
});
|
||||
|
||||
this.loaded = true;
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -131,6 +131,12 @@
|
|||
<span class="time-edited"><span>·</span> <span class="font-italic">Edited {{c.edited_string}}</span></span>
|
||||
{% endif %}
|
||||
|
||||
{% if c.awards %}
|
||||
{% for a in c.awards[:5] %}
|
||||
<i class="{{ a.class_list }} px-1" data-toggle="tooltip" data-placement="bottom" title="{{ a.title }} Award given by @{{a.user.username}}"></i>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
{% if c.is_banned and c.ban_reason %}
|
||||
|
@ -241,14 +247,6 @@
|
|||
|
||||
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="/votes?link=https://rdrama.net{{c.permalink}}"><i class="fas fa-arrows-v"></i>Votes</a></li>
|
||||
|
||||
{% if v and v.id!=c.author_id and v.admin_level == 0 %}
|
||||
{% if v.banawards > 0 %}
|
||||
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="javascript:void(0)" onclick="post_toast('/banaward/comment/{{c.id}}')"><i class="fas fa-user-slash text-danger"></i>Give ban award</a></li>
|
||||
{% else %}
|
||||
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="/banaward/comment/{{c.id}}"><i class="fas fa-user-slash text-danger"></i>Give ban award</a></li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if v and c.id in v.saved_comment_idlist() %}
|
||||
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="javascript:void(0)" onclick="post('/unsave_comment/{{c.base36id}}', function(){window.location.reload(true);})"><i class="fas fa-save"></i>Unsave</a></li>
|
||||
{% else %}
|
||||
|
@ -259,6 +257,11 @@
|
|||
<li class="list-inline-item text-muted"><a href="javascript:void(0)" onclick="document.getElementById('reply-to-{{c.base36id}}').classList.remove('d-none')"><i class="fas fa-reply"
|
||||
aria-hidden="true"></i><span class="d-none d-md-inline-block">Reply</span></a></li>
|
||||
|
||||
{% if v.id!=c.author_id %}
|
||||
<li class="list-inline-item text-muted"><a href="javascript:void(0)" data-toggle="modal" data-target="#awardModal" onclick="awardModal('/api/comment/{{c.id}}/awards')"><i class="fas fa-gift"
|
||||
aria-hidden="true"></i><span class="d-none d-md-inline-block">Give Award</span></a></li>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="{{c.permalink}}?context=99#context"{% if c.author.is_private %} rel="nofollow"{% endif %}><i class="fas fa-book-open"></i>Context</a></li>
|
||||
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="javascript:void(0);" role="button" class="copy-link" data-clipboard-text="{{c.permalink | full_link}}?context=99#context"><i class="fas fa-copy"></i>Copy link</a></li>
|
||||
|
|
|
@ -408,6 +408,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
// award modal
|
||||
|
||||
function awardModal(link) {
|
||||
var target = document.getElementById("awardTarget");
|
||||
|
||||
target.value = link;
|
||||
}
|
||||
|
||||
// Expand Images on Desktop
|
||||
|
||||
function expandDesktopImage(image, link) {
|
||||
|
@ -1072,6 +1080,7 @@
|
|||
</div>
|
||||
|
||||
{% if v %}
|
||||
{% include "award_modal.html" %}
|
||||
{% include "flag_post_modal.html" %}
|
||||
{% include "flag_comment_modal.html" %}
|
||||
{% include "gif_modal.html" %}
|
||||
|
|
|
@ -116,12 +116,8 @@
|
|||
|
||||
<button class="btn btn-link btn-block btn-lg text-left text-muted"><a href="/votes?link=https://rdrama.net{{p.permalink}}"><i class="fas fa-arrows-v text-center text-muted mr-3"></i>Votes</a></button>
|
||||
|
||||
{% if v and v.id!=p.author_id and v.admin_level == 0 %}
|
||||
{% if v.banawards > 0 %}
|
||||
<button class="btn btn-link btn-block btn-lg text-left text-muted"><a href="javascript:void(0)" onclick="post_toast('/banaward/post/{{p.id}}')"><i class="fas fa-user-slash text-danger mr-3"></i>Give ban award</a></button>
|
||||
{% else %}
|
||||
<button class="btn btn-link btn-block btn-lg text-left text-muted"><a href="/banaward/post/{{p.id}}"><i class="fas fa-user-slash text-danger mr-3"></i>Give ban award</a></button>
|
||||
{% endif %}
|
||||
{% if v and v.id!=p.author_id %}
|
||||
<button class="btn btn-link btn-block btn-lg text-left text-muted" data-toggle="modal" data-dismiss="modal" data-target="#awardModal" onclick="awardModal('/api/post/{{p.id}}/awards')"><i class="fas fa-gift text-center text-muted mr-3"></i>Give Award</button>
|
||||
{% endif %}
|
||||
|
||||
{% if v and p.id in v.subscribed_idlist() %}
|
||||
|
@ -189,6 +185,20 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if p.has_award("shit") %}
|
||||
<script src="/assets/js/bug-min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
new BugController({
|
||||
imageSprite: "/assets/js/fly-sprite.png",
|
||||
canDie: false,
|
||||
minBugs: 10,
|
||||
maxBugs: 20,
|
||||
mouseOver: "multiply"
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
<div class="row mb-3">
|
||||
|
||||
<div class="col-12">
|
||||
|
@ -224,6 +234,12 @@
|
|||
|
||||
{% if p.edited_utc %} Edited <span data-toggle="tooltip" data-placement="bottom" id="edited_timestamp" title="">{{p.edited_string}}</span>{% endif %}
|
||||
{{p.views}} views
|
||||
|
||||
{% if p.awards %}
|
||||
{% for a in p.awards[:5] %}
|
||||
<i class="{{ a.class_list }} px-1" data-toggle="tooltip" data-placement="bottom" title="{{ a.title }} Award given by @{{a.user.username}}"></i>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if p.realurl(v) %}
|
||||
|
@ -308,12 +324,8 @@
|
|||
|
||||
<li class="list-inline-item"><a href="/votes?link=https://rdrama.net{{p.permalink}}"><i class="fas fa-arrows-v"></i>Votes</a></li>
|
||||
|
||||
{% if v and v.id!=p.author_id and v.admin_level == 0 %}
|
||||
{% if v.banawards > 0 %}
|
||||
<li class="list-inline-item"><a href="javascript:void(0)" onclick="post_toast('/banaward/post/{{p.id}}')"><i class="fas fa-user-slash text-danger"></i>Give ban award</a></li>
|
||||
{% else %}
|
||||
<li class="list-inline-item"><a href="/banaward/post/{{p.id}}"><i class="fas fa-user-slash text-danger"></i>Give ban award</a></li>
|
||||
{% endif %}
|
||||
{% if v and v.id!=p.author_id %}
|
||||
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="javascript:void(0)" data-toggle="modal" data-target="#awardModal" onclick="awardModal('/api/post/{{p.id}}/awards')"><i class="fas fa-gift fa-fw"></i>Give Award</a></li>
|
||||
{% endif %}
|
||||
|
||||
<li class="list-inline-item"><a href="javascript:void(0);" role="button" class="copy-link" data-clipboard-text="{{p.permalink | full_link}}"><i class="fas fa-copy"></i>Copy link</a></li>
|
||||
|
|
|
@ -145,6 +145,12 @@
|
|||
{% if p.edited_utc %} Edited <span data-toggle="tooltip" data-placement="bottom" id="edited_timestamp-{{p.id}}" title="">{{p.edited_string}}</span>{% endif %}
|
||||
{{p.views}} views
|
||||
|
||||
{% if p.awards %}
|
||||
{% for a in p.awards[:5] %}
|
||||
<i class="{{ a.class_list }} px-1" data-toggle="tooltip" data-placement="bottom" title="{{ a.title }} Award given by @{{a.user.username}}"></i>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
<h5 class="card-title post-title text-left w-lg-75 mb-0 pb-0 pb-md-1"><a {% if v and v.newtab %}target="_blank"{% endif %} href="{{p.permalink}}" class="stretched-link" {% if p.author.is_private %} rel="nofollow"{% endif %}>
|
||||
|
@ -168,12 +174,8 @@
|
|||
|
||||
<li class="list-inline-item"><a href="/votes?link=https://rdrama.net{{p.permalink}}"><i class="fas fa-arrows-v"></i>Votes</a></li>
|
||||
|
||||
{% if v and v.id!=p.author_id and v.admin_level == 0 %}
|
||||
{% if v.banawards > 0 %}
|
||||
<li class="list-inline-item"><a href="javascript:void(0)" onclick="post_toast('/banaward/post/{{p.id}}')"><i class="fas fa-user-slash text-danger"></i>Give ban award</a></li>
|
||||
{% else %}
|
||||
<li class="list-inline-item"><a href="/banaward/post/{{p.id}}"><i class="fas fa-user-slash text-danger"></i>Give ban award</a></li>
|
||||
{% endif %}
|
||||
{% if v and v.id!=p.author_id %}
|
||||
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="javascript:void(0)" data-toggle="modal" data-target="#awardModal" onclick="awardModal('/api/post/{{p.id}}/awards')"><i class="fas fa-gift fa-fw"></i>Give Award</a></li>
|
||||
{% endif %}
|
||||
|
||||
<li class="list-inline-item"><a href="javascript:void(0);" role="button" class="copy-link" data-clipboard-text="{{p.permalink | full_link}}"><i class="fas fa-copy"></i>Copy link</a></li>
|
||||
|
@ -353,12 +355,8 @@
|
|||
<ul class="list-group post-actions">
|
||||
<button class="btn btn-link btn-block btn-lg text-left text-muted"><a href="/votes?link=https://rdrama.net{{p.permalink}}"><i class="fas fa-arrows-v text-center text-muted mr-3"></i>Votes</a></button>
|
||||
|
||||
{% if v and v.id!=p.author_id and v.admin_level == 0 %}
|
||||
{% if v.banawards > 0 %}
|
||||
<button class="btn btn-link btn-block btn-lg text-left text-muted"><a href="javascript:void(0)" onclick="post_toast('/banaward/post/{{p.id}}')"><i class="fas fa-user-slash text-danger mr-3"></i>Give ban award</a></button>
|
||||
{% else %}
|
||||
<button class="btn btn-link btn-block btn-lg text-left text-muted"><a href="/banaward/post/{{p.id}}"><i class="fas fa-user-slash text-danger mr-3"></i>Give ban award</a></button>
|
||||
{% endif %}
|
||||
{% if v and v.id!=p.author_id %}
|
||||
<li class="list-inline-item text-muted d-none d-md-inline-block"><a href="javascript:void(0)" data-toggle="modal" data-target="#awardModal" onclick="awardModal('/api/post/{{p.id}}/awards')"><i class="fas fa-gift fa-fw"></i>Give Award</a></li>
|
||||
{% endif %}
|
||||
|
||||
{% if v and p.id in v.subscribed_idlist() %}
|
||||
|
|
Loading…
Reference in New Issue