diff --git a/boards/abstracts/settingsmanager.py b/boards/abstracts/settingsmanager.py --- a/boards/abstracts/settingsmanager.py +++ b/boards/abstracts/settingsmanager.py @@ -11,6 +11,7 @@ PERMISSION_MODERATE = 'moderator' SETTING_THEME = 'theme' SETTING_FAVORITE_TAGS = 'favorite_tags' +SETTING_FAVORITE_THREADS = 'favorite_threads' SETTING_HIDDEN_TAGS = 'hidden_tags' SETTING_PERMISSIONS = 'permissions' SETTING_USERNAME = 'username' @@ -118,6 +119,23 @@ class SettingsManager: tags.remove(tag.name) self.set_setting(SETTING_HIDDEN_TAGS, tags) + def get_fav_threads(self) -> dict: + return self.get_setting(SETTING_FAVORITE_THREADS, default=dict()) + + def add_or_read_fav_thread(self, opening_post): + threads = self.get_fav_threads() + threads[str(opening_post.id)] = opening_post.get_thread().get_replies()\ + .last().id + self.set_setting(SETTING_FAVORITE_THREADS, threads) + + def del_fav_thread(self, opening_post): + threads = self.get_fav_threads() + if self.thread_is_fav(opening_post): + del threads[str(opening_post.id)] + self.set_setting(SETTING_FAVORITE_THREADS, threads) + + def thread_is_fav(self, opening_post): + return str(opening_post.id) in self.get_fav_threads() class SessionSettingsManager(SettingsManager): """ diff --git a/boards/context_processors.py b/boards/context_processors.py --- a/boards/context_processors.py +++ b/boards/context_processors.py @@ -19,6 +19,7 @@ CONTEXT_NEW_NOTIFICATIONS_COUNT = 'new_n CONTEXT_USERNAME = 'username' CONTEXT_TAGS_STR = 'tags_str' CONTEXT_IMAGE_VIEWER = 'image_viewer' +CONTEXT_FAV_THREADS = 'fav_threads' def get_notifications(context, request): @@ -43,6 +44,9 @@ def user_and_ui_processor(request): settings_manager = get_settings_manager(request) fav_tags = settings_manager.get_fav_tags() context[CONTEXT_TAGS] = fav_tags + + _get_fav_threads(context, settings_manager) + context[CONTEXT_TAGS_STR] = Tag.objects.get_tag_url_list(fav_tags) theme = settings_manager.get_theme() context[CONTEXT_THEME] = theme @@ -61,3 +65,15 @@ def user_and_ui_processor(request): get_notifications(context, request) return context + + +def _get_fav_threads(context, settings_manager): + fav_threads_setting = settings_manager.get_fav_threads() + if fav_threads_setting: + fav_threads = Post.objects.filter( + id__in=fav_threads_setting.keys()).only('url', 'id', 'thread')\ + .select_related('thread') + context[CONTEXT_FAV_THREADS] = [ + (post, post.get_thread().get_replies_newer( + fav_threads_setting[str(post.id)]).count()) + for post in fav_threads] diff --git a/boards/models/post/__init__.py b/boards/models/post/__init__.py --- a/boards/models/post/__init__.py +++ b/boards/models/post/__init__.py @@ -253,7 +253,6 @@ class Post(models.Model, Viewable): post_url += '#' + str(self.id) return post_url - def get_thread(self): return self.thread @@ -449,7 +448,7 @@ class Post(models.Model, Viewable): """ result = '>>{}'.format(self.get_absolute_url(), - self.id) + self.id) if self.is_opening(): result = '{}'.format(result) diff --git a/boards/models/thread.py b/boards/models/thread.py --- a/boards/models/thread.py +++ b/boards/models/thread.py @@ -228,3 +228,7 @@ class Thread(models.Model): def get_required_tags(self): return self.get_tags().filter(required=True) + + def get_replies_newer(self, post_id): + return self.get_replies().filter(id__gt=post_id) + diff --git a/boards/static/css/md/base_page.css b/boards/static/css/md/base_page.css --- a/boards/static/css/md/base_page.css +++ b/boards/static/css/md/base_page.css @@ -510,6 +510,11 @@ ul { border: 1px solid #777; background: #000; padding: 4px; + opacity: 0.3; +} + +#up:hover { + opacity: 1; } .user-cast { diff --git a/boards/static/js/thread_update.js b/boards/static/js/thread_update.js --- a/boards/static/js/thread_update.js +++ b/boards/static/js/thread_update.js @@ -439,11 +439,11 @@ function updateNodeAttr(oldNode, newNode if (form.length > 0) { var options = { beforeSubmit: function(arr, $form, options) { - showAsErrors($('form'), gettext('Sending message...')); + showAsErrors($('#form'), gettext('Sending message...')); }, success: updateOnPost, error: function() { - showAsErrors($('form'), gettext('Server error!')); + showAsErrors($('#form'), gettext('Server error!')); }, url: '/api/add_post/' + threadId + '/' }; diff --git a/boards/templates/boards/base.html b/boards/templates/boards/base.html --- a/boards/templates/boards/base.html +++ b/boards/templates/boards/base.html @@ -28,6 +28,7 @@ {% block content %}{% endblock %} diff --git a/boards/templates/boards/thread_normal.html b/boards/templates/boards/thread_normal.html --- a/boards/templates/boards/thread_normal.html +++ b/boards/templates/boards/thread_normal.html @@ -9,6 +9,19 @@ {% get_current_language as LANGUAGE_CODE %} {% get_current_timezone as TIME_ZONE %} +
+

+
+ {% if is_favorite %} + + {% else %} + + {% endif %} +
+ {{ opening_post.get_title|striptags|truncatewords:10 }} +

+
+ {% if bumpable and thread.has_post_limit %}
diff --git a/boards/views/api.py b/boards/views/api.py --- a/boards/views/api.py +++ b/boards/views/api.py @@ -5,6 +5,7 @@ from django.db import transaction from django.http import HttpResponse from django.shortcuts import get_object_or_404 from django.core import serializers +from boards.abstracts.settingsmanager import get_settings_manager from boards.forms import PostForm, PlainErrorList from boards.models import Post, Thread, Tag @@ -45,7 +46,8 @@ def api_get_threaddiff(request): uids_str = request.POST.get(PARAMETER_UIDS).strip() uids = uids_str.split(' ') - thread = get_object_or_404(Post, id=thread_id).get_thread() + opening_post = get_object_or_404(Post, id=thread_id) + thread = opening_post.get_thread() json_data = { PARAMETER_UPDATED: [], @@ -60,6 +62,12 @@ def api_get_threaddiff(request): request)) json_data[PARAMETER_LAST_UPDATE] = str(thread.last_edit_time) + # If the tag is favorite, update the counter + settings_manager = get_settings_manager(request) + favorite = settings_manager.thread_is_fav(opening_post) + if favorite: + settings_manager.add_or_read_fav_thread(opening_post) + return HttpResponse(content=json.dumps(json_data)) diff --git a/boards/views/thread/thread.py b/boards/views/thread/thread.py --- a/boards/views/thread/thread.py +++ b/boards/views/thread/thread.py @@ -7,9 +7,11 @@ from django.utils import timezone from django.utils.dateformat import format from boards import utils, settings +from boards.abstracts.settingsmanager import get_settings_manager from boards.forms import PostForm, PlainErrorList from boards.models import Post from boards.views.base import BaseBoardView, CONTEXT_FORM +from boards.views.mixins import DispatcherMixin from boards.views.posting_mixin import PostMixin import neboard @@ -24,6 +26,7 @@ CONTEXT_WS_PORT = 'ws_port' CONTEXT_WS_TIME = 'ws_token_time' CONTEXT_MODE = 'mode' CONTEXT_OP = 'opening_post' +CONTEXT_FAVORITE = 'is_favorite' FORM_TITLE = 'title' FORM_TEXT = 'text' @@ -31,7 +34,7 @@ FORM_IMAGE = 'image' FORM_THREADS = 'threads' -class ThreadView(BaseBoardView, PostMixin, FormMixin): +class ThreadView(BaseBoardView, PostMixin, FormMixin, DispatcherMixin): def get(self, request, post_id, form: PostForm=None): try: @@ -39,10 +42,21 @@ class ThreadView(BaseBoardView, PostMixi except ObjectDoesNotExist: raise Http404 + if 'method' in request.POST: + self.dispatch_method(request, opening_post) + + return redirect('thread', post_id) # FIXME Different for different modes + + # If the tag is favorite, update the counter + settings_manager = get_settings_manager(request) + favorite = settings_manager.thread_is_fav(opening_post) + if favorite: + settings_manager.add_or_read_fav_thread(opening_post) + # If this is not OP, don't show it as it is if not opening_post.is_opening(): return redirect(opening_post.get_thread().get_opening_post() - .get_absolute_url()) + .get_absolute_url()) if not form: form = PostForm(error_class=PlainErrorList) @@ -56,6 +70,7 @@ class ThreadView(BaseBoardView, PostMixi params[CONTEXT_THREAD] = thread_to_show params[CONTEXT_MODE] = self.get_mode() params[CONTEXT_OP] = opening_post + params[CONTEXT_FAVORITE] = favorite if settings.get_bool('External', 'WebsocketsEnabled'): token_time = format(timezone.now(), u'U') @@ -138,3 +153,11 @@ class ThreadView(BaseBoardView, PostMixi def get_mode(self) -> str: pass + + def subscribe(self, request, opening_post): + settings_manager = get_settings_manager(request) + settings_manager.add_or_read_fav_thread(opening_post) + + def unsubscribe(self, request, opening_post): + settings_manager = get_settings_manager(request) + settings_manager.del_fav_thread(opening_post)