##// END OF EJS Templates
Favorite threads with new posts counter
neko259 -
r1323:46a185c5 default
parent child Browse files
Show More
@@ -11,6 +11,7 b" PERMISSION_MODERATE = 'moderator'"
11
11
12 SETTING_THEME = 'theme'
12 SETTING_THEME = 'theme'
13 SETTING_FAVORITE_TAGS = 'favorite_tags'
13 SETTING_FAVORITE_TAGS = 'favorite_tags'
14 SETTING_FAVORITE_THREADS = 'favorite_threads'
14 SETTING_HIDDEN_TAGS = 'hidden_tags'
15 SETTING_HIDDEN_TAGS = 'hidden_tags'
15 SETTING_PERMISSIONS = 'permissions'
16 SETTING_PERMISSIONS = 'permissions'
16 SETTING_USERNAME = 'username'
17 SETTING_USERNAME = 'username'
@@ -118,6 +119,23 b' class SettingsManager:'
118 tags.remove(tag.name)
119 tags.remove(tag.name)
119 self.set_setting(SETTING_HIDDEN_TAGS, tags)
120 self.set_setting(SETTING_HIDDEN_TAGS, tags)
120
121
122 def get_fav_threads(self) -> dict:
123 return self.get_setting(SETTING_FAVORITE_THREADS, default=dict())
124
125 def add_or_read_fav_thread(self, opening_post):
126 threads = self.get_fav_threads()
127 threads[str(opening_post.id)] = opening_post.get_thread().get_replies()\
128 .last().id
129 self.set_setting(SETTING_FAVORITE_THREADS, threads)
130
131 def del_fav_thread(self, opening_post):
132 threads = self.get_fav_threads()
133 if self.thread_is_fav(opening_post):
134 del threads[str(opening_post.id)]
135 self.set_setting(SETTING_FAVORITE_THREADS, threads)
136
137 def thread_is_fav(self, opening_post):
138 return str(opening_post.id) in self.get_fav_threads()
121
139
122 class SessionSettingsManager(SettingsManager):
140 class SessionSettingsManager(SettingsManager):
123 """
141 """
@@ -19,6 +19,7 b" CONTEXT_NEW_NOTIFICATIONS_COUNT = 'new_n"
19 CONTEXT_USERNAME = 'username'
19 CONTEXT_USERNAME = 'username'
20 CONTEXT_TAGS_STR = 'tags_str'
20 CONTEXT_TAGS_STR = 'tags_str'
21 CONTEXT_IMAGE_VIEWER = 'image_viewer'
21 CONTEXT_IMAGE_VIEWER = 'image_viewer'
22 CONTEXT_FAV_THREADS = 'fav_threads'
22
23
23
24
24 def get_notifications(context, request):
25 def get_notifications(context, request):
@@ -43,6 +44,9 b' def user_and_ui_processor(request):'
43 settings_manager = get_settings_manager(request)
44 settings_manager = get_settings_manager(request)
44 fav_tags = settings_manager.get_fav_tags()
45 fav_tags = settings_manager.get_fav_tags()
45 context[CONTEXT_TAGS] = fav_tags
46 context[CONTEXT_TAGS] = fav_tags
47
48 _get_fav_threads(context, settings_manager)
49
46 context[CONTEXT_TAGS_STR] = Tag.objects.get_tag_url_list(fav_tags)
50 context[CONTEXT_TAGS_STR] = Tag.objects.get_tag_url_list(fav_tags)
47 theme = settings_manager.get_theme()
51 theme = settings_manager.get_theme()
48 context[CONTEXT_THEME] = theme
52 context[CONTEXT_THEME] = theme
@@ -61,3 +65,15 b' def user_and_ui_processor(request):'
61 get_notifications(context, request)
65 get_notifications(context, request)
62
66
63 return context
67 return context
68
69
70 def _get_fav_threads(context, settings_manager):
71 fav_threads_setting = settings_manager.get_fav_threads()
72 if fav_threads_setting:
73 fav_threads = Post.objects.filter(
74 id__in=fav_threads_setting.keys()).only('url', 'id', 'thread')\
75 .select_related('thread')
76 context[CONTEXT_FAV_THREADS] = [
77 (post, post.get_thread().get_replies_newer(
78 fav_threads_setting[str(post.id)]).count())
79 for post in fav_threads]
@@ -253,7 +253,6 b' class Post(models.Model, Viewable):'
253 post_url += '#' + str(self.id)
253 post_url += '#' + str(self.id)
254 return post_url
254 return post_url
255
255
256
257 def get_thread(self):
256 def get_thread(self):
258 return self.thread
257 return self.thread
259
258
@@ -449,7 +448,7 b' class Post(models.Model, Viewable):'
449 """
448 """
450
449
451 result = '<a href="{}">&gt;&gt;{}</a>'.format(self.get_absolute_url(),
450 result = '<a href="{}">&gt;&gt;{}</a>'.format(self.get_absolute_url(),
452 self.id)
451 self.id)
453 if self.is_opening():
452 if self.is_opening():
454 result = '<b>{}</b>'.format(result)
453 result = '<b>{}</b>'.format(result)
455
454
@@ -228,3 +228,7 b' class Thread(models.Model):'
228
228
229 def get_required_tags(self):
229 def get_required_tags(self):
230 return self.get_tags().filter(required=True)
230 return self.get_tags().filter(required=True)
231
232 def get_replies_newer(self, post_id):
233 return self.get_replies().filter(id__gt=post_id)
234
@@ -510,6 +510,11 b' ul {'
510 border: 1px solid #777;
510 border: 1px solid #777;
511 background: #000;
511 background: #000;
512 padding: 4px;
512 padding: 4px;
513 opacity: 0.3;
514 }
515
516 #up:hover {
517 opacity: 1;
513 }
518 }
514
519
515 .user-cast {
520 .user-cast {
@@ -439,11 +439,11 b' function updateNodeAttr(oldNode, newNode'
439 if (form.length > 0) {
439 if (form.length > 0) {
440 var options = {
440 var options = {
441 beforeSubmit: function(arr, $form, options) {
441 beforeSubmit: function(arr, $form, options) {
442 showAsErrors($('form'), gettext('Sending message...'));
442 showAsErrors($('#form'), gettext('Sending message...'));
443 },
443 },
444 success: updateOnPost,
444 success: updateOnPost,
445 error: function() {
445 error: function() {
446 showAsErrors($('form'), gettext('Server error!'));
446 showAsErrors($('#form'), gettext('Server error!'));
447 },
447 },
448 url: '/api/add_post/' + threadId + '/'
448 url: '/api/add_post/' + threadId + '/'
449 };
449 };
@@ -28,6 +28,7 b''
28 <script src="{% url 'js_info_dict' %}"></script>
28 <script src="{% url 'js_info_dict' %}"></script>
29
29
30 <div class="navigation_panel header">
30 <div class="navigation_panel header">
31 <div>
31 <a class="link" href="{% url 'index' %}">{% trans "All threads" %}</a>
32 <a class="link" href="{% url 'index' %}">{% trans "All threads" %}</a>
32 {% if tags_str %}
33 {% if tags_str %}
33 {% autoescape off %}
34 {% autoescape off %}
@@ -51,6 +52,18 b''
51 {% endif %}
52 {% endif %}
52
53
53 <a class="right-link link" href="{% url 'settings' %}">{% trans 'Settings' %}</a>
54 <a class="right-link link" href="{% url 'settings' %}">{% trans 'Settings' %}</a>
55 </div>
56 {% if fav_threads %}
57 <div>
58 <span class="fav">β˜…</span>
59 {% for thread in fav_threads %}
60 {% comment %}
61 If there are new posts in the thread, show their count.
62 {% endcomment %}
63 {{ thread.0.get_link_view|safe }}{% if thread.1 %} (+{{ thread.1 }}){% endif %}{% if not forloop.last %}, {% endif %}
64 {% endfor %}
65 </div>
66 {% endif %}
54 </div>
67 </div>
55
68
56 {% block content %}{% endblock %}
69 {% block content %}{% endblock %}
@@ -9,6 +9,19 b''
9 {% get_current_language as LANGUAGE_CODE %}
9 {% get_current_language as LANGUAGE_CODE %}
10 {% get_current_timezone as TIME_ZONE %}
10 {% get_current_timezone as TIME_ZONE %}
11
11
12 <div class="tag_info">
13 <h2>
14 <form action="{% url 'thread' opening_post.id %}" method="post" class="post-button-form">
15 {% if is_favorite %}
16 <button name="method" value="unsubscribe" class="fav">β˜…</button>
17 {% else %}
18 <button name="method" value="subscribe" class="not_fav">β˜…</button>
19 {% endif %}
20 </form>
21 {{ opening_post.get_title|striptags|truncatewords:10 }}
22 </h2>
23 </div>
24
12 {% if bumpable and thread.has_post_limit %}
25 {% if bumpable and thread.has_post_limit %}
13 <div class="bar-bg">
26 <div class="bar-bg">
14 <div class="bar-value" style="width:{{ bumplimit_progress }}%" id="bumplimit_progress">
27 <div class="bar-value" style="width:{{ bumplimit_progress }}%" id="bumplimit_progress">
@@ -5,6 +5,7 b' from django.db import transaction'
5 from django.http import HttpResponse
5 from django.http import HttpResponse
6 from django.shortcuts import get_object_or_404
6 from django.shortcuts import get_object_or_404
7 from django.core import serializers
7 from django.core import serializers
8 from boards.abstracts.settingsmanager import get_settings_manager
8
9
9 from boards.forms import PostForm, PlainErrorList
10 from boards.forms import PostForm, PlainErrorList
10 from boards.models import Post, Thread, Tag
11 from boards.models import Post, Thread, Tag
@@ -45,7 +46,8 b' def api_get_threaddiff(request):'
45 uids_str = request.POST.get(PARAMETER_UIDS).strip()
46 uids_str = request.POST.get(PARAMETER_UIDS).strip()
46 uids = uids_str.split(' ')
47 uids = uids_str.split(' ')
47
48
48 thread = get_object_or_404(Post, id=thread_id).get_thread()
49 opening_post = get_object_or_404(Post, id=thread_id)
50 thread = opening_post.get_thread()
49
51
50 json_data = {
52 json_data = {
51 PARAMETER_UPDATED: [],
53 PARAMETER_UPDATED: [],
@@ -60,6 +62,12 b' def api_get_threaddiff(request):'
60 request))
62 request))
61 json_data[PARAMETER_LAST_UPDATE] = str(thread.last_edit_time)
63 json_data[PARAMETER_LAST_UPDATE] = str(thread.last_edit_time)
62
64
65 # If the tag is favorite, update the counter
66 settings_manager = get_settings_manager(request)
67 favorite = settings_manager.thread_is_fav(opening_post)
68 if favorite:
69 settings_manager.add_or_read_fav_thread(opening_post)
70
63 return HttpResponse(content=json.dumps(json_data))
71 return HttpResponse(content=json.dumps(json_data))
64
72
65
73
@@ -7,9 +7,11 b' from django.utils import timezone'
7 from django.utils.dateformat import format
7 from django.utils.dateformat import format
8
8
9 from boards import utils, settings
9 from boards import utils, settings
10 from boards.abstracts.settingsmanager import get_settings_manager
10 from boards.forms import PostForm, PlainErrorList
11 from boards.forms import PostForm, PlainErrorList
11 from boards.models import Post
12 from boards.models import Post
12 from boards.views.base import BaseBoardView, CONTEXT_FORM
13 from boards.views.base import BaseBoardView, CONTEXT_FORM
14 from boards.views.mixins import DispatcherMixin
13 from boards.views.posting_mixin import PostMixin
15 from boards.views.posting_mixin import PostMixin
14
16
15 import neboard
17 import neboard
@@ -24,6 +26,7 b" CONTEXT_WS_PORT = 'ws_port'"
24 CONTEXT_WS_TIME = 'ws_token_time'
26 CONTEXT_WS_TIME = 'ws_token_time'
25 CONTEXT_MODE = 'mode'
27 CONTEXT_MODE = 'mode'
26 CONTEXT_OP = 'opening_post'
28 CONTEXT_OP = 'opening_post'
29 CONTEXT_FAVORITE = 'is_favorite'
27
30
28 FORM_TITLE = 'title'
31 FORM_TITLE = 'title'
29 FORM_TEXT = 'text'
32 FORM_TEXT = 'text'
@@ -31,7 +34,7 b" FORM_IMAGE = 'image'"
31 FORM_THREADS = 'threads'
34 FORM_THREADS = 'threads'
32
35
33
36
34 class ThreadView(BaseBoardView, PostMixin, FormMixin):
37 class ThreadView(BaseBoardView, PostMixin, FormMixin, DispatcherMixin):
35
38
36 def get(self, request, post_id, form: PostForm=None):
39 def get(self, request, post_id, form: PostForm=None):
37 try:
40 try:
@@ -39,10 +42,21 b' class ThreadView(BaseBoardView, PostMixi'
39 except ObjectDoesNotExist:
42 except ObjectDoesNotExist:
40 raise Http404
43 raise Http404
41
44
45 if 'method' in request.POST:
46 self.dispatch_method(request, opening_post)
47
48 return redirect('thread', post_id) # FIXME Different for different modes
49
50 # If the tag is favorite, update the counter
51 settings_manager = get_settings_manager(request)
52 favorite = settings_manager.thread_is_fav(opening_post)
53 if favorite:
54 settings_manager.add_or_read_fav_thread(opening_post)
55
42 # If this is not OP, don't show it as it is
56 # If this is not OP, don't show it as it is
43 if not opening_post.is_opening():
57 if not opening_post.is_opening():
44 return redirect(opening_post.get_thread().get_opening_post()
58 return redirect(opening_post.get_thread().get_opening_post()
45 .get_absolute_url())
59 .get_absolute_url())
46
60
47 if not form:
61 if not form:
48 form = PostForm(error_class=PlainErrorList)
62 form = PostForm(error_class=PlainErrorList)
@@ -56,6 +70,7 b' class ThreadView(BaseBoardView, PostMixi'
56 params[CONTEXT_THREAD] = thread_to_show
70 params[CONTEXT_THREAD] = thread_to_show
57 params[CONTEXT_MODE] = self.get_mode()
71 params[CONTEXT_MODE] = self.get_mode()
58 params[CONTEXT_OP] = opening_post
72 params[CONTEXT_OP] = opening_post
73 params[CONTEXT_FAVORITE] = favorite
59
74
60 if settings.get_bool('External', 'WebsocketsEnabled'):
75 if settings.get_bool('External', 'WebsocketsEnabled'):
61 token_time = format(timezone.now(), u'U')
76 token_time = format(timezone.now(), u'U')
@@ -138,3 +153,11 b' class ThreadView(BaseBoardView, PostMixi'
138
153
139 def get_mode(self) -> str:
154 def get_mode(self) -> str:
140 pass
155 pass
156
157 def subscribe(self, request, opening_post):
158 settings_manager = get_settings_manager(request)
159 settings_manager.add_or_read_fav_thread(opening_post)
160
161 def unsubscribe(self, request, opening_post):
162 settings_manager = get_settings_manager(request)
163 settings_manager.del_fav_thread(opening_post)
General Comments 0
You need to be logged in to leave comments. Login now