bring back reactions
This commit is contained in:
@@ -1,10 +1,21 @@
|
||||
from flask import Blueprint, request
|
||||
from ..auth import is_logged_in, hard_login_required, get_active_user
|
||||
from ..lib.babycode import babycode_to_html
|
||||
from ..models import APIRateLimits
|
||||
from ..models import APIRateLimits, Posts, Threads, Reactions
|
||||
from ..constants import REACTION_EMOJI
|
||||
|
||||
bp = Blueprint('api', __name__, url_prefix='/api/')
|
||||
|
||||
@bp.before_request
|
||||
def ensure_json():
|
||||
if request.method == 'POST':
|
||||
if not request.is_json:
|
||||
return {'error': 'unsupported media type'}, 415
|
||||
elif not request.content_length:
|
||||
return {'error': 'body expected'}, 400
|
||||
elif not isinstance(request.json, dict):
|
||||
return {'error': 'body must be an object'}, 400
|
||||
|
||||
@bp.post('/babycode-preview/')
|
||||
@hard_login_required
|
||||
def babycode_preview():
|
||||
@@ -31,3 +42,48 @@ def whoami():
|
||||
'username': user.username,
|
||||
'display_name': user.display_name,
|
||||
}
|
||||
|
||||
@bp.post('/toggle-reaction/')
|
||||
@hard_login_required
|
||||
def toggle_reaction():
|
||||
user = get_active_user()
|
||||
emoji = request.json.get('reaction')
|
||||
if emoji not in REACTION_EMOJI:
|
||||
return {'error': f'invalid reaction string, given: {emoji}'}, 400
|
||||
|
||||
post_id = request.json.get('post', -1)
|
||||
post = Posts.find({'id': post_id})
|
||||
if not post:
|
||||
return {'error': 'post not found'}, 404
|
||||
|
||||
thread = Threads.find({'id': post.thread_id})
|
||||
|
||||
if not user.can_post_to_thread_or_topic(thread):
|
||||
return {'error': 'thread is locked'}, 403
|
||||
|
||||
reaction_obj = {
|
||||
'user_id': int(user.id),
|
||||
'post_id': int(post_id),
|
||||
'reaction_text': emoji,
|
||||
}
|
||||
r = Reactions.find(reaction_obj)
|
||||
if r:
|
||||
# remove
|
||||
r.delete()
|
||||
return {'status': 'ok', 'added': False}
|
||||
else:
|
||||
# add
|
||||
r = Reactions.create(reaction_obj)
|
||||
return {'status': 'ok', 'added': True}
|
||||
|
||||
@bp.get('/thread-permission/<int:thread_id>')
|
||||
def thread_permission(thread_id):
|
||||
user = get_active_user()
|
||||
if not user:
|
||||
return {'can_post': False}
|
||||
|
||||
thread = Threads.find({'id': thread_id})
|
||||
if not thread:
|
||||
return {'can_post': False}
|
||||
|
||||
return {'can_post': user.can_post_to_thread_or_topic(thread)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from flask import Blueprint, render_template, request, url_for
|
||||
from ..auth import get_active_user, is_logged_in, hard_login_required
|
||||
from ..models import BookmarkCollections, BookmarkedPosts, BookmarkedThreads, Threads, Posts, Badges, BadgeUploads
|
||||
from ..models import BookmarkCollections, BookmarkedPosts, BookmarkedThreads, Threads, Posts, Badges, BadgeUploads, Reactions
|
||||
from functools import wraps
|
||||
|
||||
bp = Blueprint('hyperapi', __name__, url_prefix='/hyperapi/')
|
||||
@@ -133,3 +133,7 @@ def badge_editor():
|
||||
badges = Badges.get_for_user(user.id)
|
||||
badge_uploads = BadgeUploads.get_for_user(user.id)
|
||||
return render_template('hyper/badge_editor.html', badges=badges, badge_uploads=badge_uploads)
|
||||
|
||||
@bp.get('/reactions/<int:post_id>')
|
||||
def get_reaction_buttons(post_id):
|
||||
return render_template('hyper/reaction_buttons.html', Reactions=Reactions, post_id=post_id)
|
||||
|
||||
@@ -35,6 +35,13 @@ def ownership_or_mod_required(view_func):
|
||||
return view_func(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
@bp.get('/<int:post_id>/')
|
||||
def post_by_id(post_id):
|
||||
post = get_post_url(post_id, _anchor=True)
|
||||
if not post:
|
||||
abort(404)
|
||||
return redirect(post)
|
||||
|
||||
@bp.get('/<int:post_id>/edit/')
|
||||
@login_required
|
||||
@ownership_required
|
||||
|
||||
@@ -658,7 +658,6 @@ def save_badges(username):
|
||||
('id', 'NOT IN', ids),
|
||||
('user_id', '=', user.id),
|
||||
])
|
||||
print(list(map(lambda x: x.id, deleted_badges)))
|
||||
|
||||
with db.transaction():
|
||||
for b in deleted_badges:
|
||||
|
||||
@@ -140,6 +140,19 @@
|
||||
<button autocomplete='off' data-r="enhance" data-s="showBookmarkMenu" disabled title="This feature requires JavaScript to be enabled." data-concept-kind="{{kind}}" data-concept-id="{{id}}">{{icn_bookmark(24)}}{{text}}…</button>
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro reaction_buttons(post_id) -%}
|
||||
{%- for reaction in Reactions.for_post(post_id) -%}
|
||||
{% set reactors = Reactions.get_users(post_id, reaction.reaction_text) | map(attribute='username') | list %}
|
||||
{% set reactors_trimmed = reactors[:10] %}
|
||||
{% set reactors_str = reactors_trimmed | join (',\n') %}
|
||||
{% if reactors | count > 10 %}
|
||||
{% set reactors_str = reactors_str + '\n...and many others' %}
|
||||
{% endif %}
|
||||
{% set has_reacted = get_active_user() is not none and get_active_user().username in reactors %}
|
||||
<button autocomplete="off" type="button" title="{{reactors_str}}" class="minimal {{'alt' if has_reacted else ''}}" data-emoji="{{reaction.reaction_text}}" data-s="toggleReaction" data-r="enableReactionButtons" disabled><img src="/static/emoji/{{reaction.reaction_text}}.png">{{reaction.c}}</button>
|
||||
{%- endfor -%}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro full_post(
|
||||
post, render_sig=true, is_latest=false,
|
||||
show_toolbar=true, is_editing=false, thread=none,
|
||||
@@ -218,19 +231,10 @@
|
||||
</div>
|
||||
<div class="plank even secondary-bg minimal no-shadow">
|
||||
{%- if show_reactions -%}
|
||||
<span class="button-row">
|
||||
{%- for reaction in Reactions.for_post(post.id) -%}
|
||||
{% set reactors = Reactions.get_users(post.id, reaction.reaction_text) | map(attribute='username') | list %}
|
||||
{% set reactors_trimmed = reactors[:10] %}
|
||||
{% set reactors_str = reactors_trimmed | join (',\n') %}
|
||||
{% if reactors | count > 10 %}
|
||||
{% set reactors_str = reactors_str + '\n...and many others' %}
|
||||
{% endif %}
|
||||
{% set has_reacted = get_active_user() is not none and get_active_user().username in reactors %}
|
||||
<button data-r="enhance" type="button" disabled title="{{reactors_str}}" class="minimal {{'alt' if has_reacted else ''}}"><img src="/static/emoji/{{reaction.reaction_text}}.png">{{reaction.c}}</button>
|
||||
{%- endfor -%}
|
||||
<span class="button-row" data-r="replaceReactionButtons">
|
||||
{{- reaction_buttons(post.id) -}}
|
||||
</span>
|
||||
{%- if is_logged_in() and allow_reacting -%}<button autocomplete='off' data-r="enhance" disabled title="This feature requires JavaScript to be enabled.">Add reaction</button>{%- endif -%}
|
||||
{%- if is_logged_in() and allow_reacting -%}<button autocomplete='off' data-r="disableReactionMenuButton enableReactionMenuButton" disabled title="This feature requires JavaScript to be enabled." data-s="openReactionMenu">Add reaction</button>{%- endif -%}
|
||||
{%- elif is_editing -%}
|
||||
<input type="submit" value="Save">
|
||||
<a href="{{get_post_url(post.id, _anchor=true)}}" class="linkbutton warn">Cancel</a>
|
||||
|
||||
2
app/templates/hyper/reaction_buttons.html
Normal file
2
app/templates/hyper/reaction_buttons.html
Normal file
@@ -0,0 +1,2 @@
|
||||
{%- from 'common/macros.html' import reaction_buttons with context -%}
|
||||
{{- reaction_buttons(post_id) -}}
|
||||
@@ -65,7 +65,7 @@
|
||||
{%- endcall -%}
|
||||
<main>
|
||||
{%- for post in posts -%}
|
||||
<article id="post-{{post.id}}" class="post plank">
|
||||
<article id="post-{{post.id}}" class="post plank" data-postid="{{post.id}}">
|
||||
{{full_post(post)}}
|
||||
</article>
|
||||
{%- endfor -%}
|
||||
@@ -98,6 +98,13 @@
|
||||
</div>
|
||||
</dialog>
|
||||
{%- if is_logged_in() and get_active_user().can_post_to_thread_or_topic(thread) -%}
|
||||
<div class="plank even" id="reaction-popover" popover data-r="openReactionMenu closeReactionMenu">
|
||||
{%- for emoji in REACTION_EMOJI -%}
|
||||
<button class="minimal emoji-button" title=":{{emoji}}:" data-emoji="{{emoji}}" data-s="toggleReaction"><img src="/static/emoji/{{emoji}}.png"></button>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
{%- endif -%}
|
||||
{%- if is_logged_in() and get_active_user().can_post_to_thread_or_topic(thread) -%}
|
||||
<form action="{{url_for('threads.reply', thread_id=thread.id)}}" method="POST" class="plank post-edit-form" data-listen="submit" data-r="clearThreadDraft" data-s="clearThreadDraft">
|
||||
<h2 class="info">Reply to "{{thread.title}}"</h2>
|
||||
{{- babycode_editor_component() -}}
|
||||
|
||||
Reference in New Issue
Block a user