##// END OF EJS Templates
Update reply and image count after thread update
neko259 -
r391:0a2454a1 default
parent child Browse files
Show More
@@ -1,116 +1,127 b''
1 1 /*
2 2 @licstart The following is the entire license notice for the
3 3 JavaScript code in this page.
4 4
5 5
6 6 Copyright (C) 2013 neko259
7 7
8 8 The JavaScript code in this page is free software: you can
9 9 redistribute it and/or modify it under the terms of the GNU
10 10 General Public License (GNU GPL) as published by the Free Software
11 11 Foundation, either version 3 of the License, or (at your option)
12 12 any later version. The code is distributed WITHOUT ANY WARRANTY;
13 13 without even the implied warranty of MERCHANTABILITY or FITNESS
14 14 FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
15 15
16 16 As additional permission under GNU GPL version 3 section 7, you
17 17 may distribute non-source (e.g., minimized or compacted) forms of
18 18 that code without the copy of the GNU GPL normally required by
19 19 section 4, provided you include this license notice and a URL
20 20 through which recipients can access the Corresponding Source.
21 21
22 22 @licend The above is the entire license notice
23 23 for the JavaScript code in this page.
24 24 */
25 25
26 26 var THREAD_UPDATE_DELAY = 10000;
27 27
28 28 var loading = false;
29 29 var lastUpdateTime = null;
30 30
31 31 function blink(node) {
32 32 var blinkCount = 2;
33 33 var blinkDelay = 250;
34 34
35 35 var nodeToAnimate = node;
36 36 for (var i = 0; i < blinkCount; i++) {
37 37 nodeToAnimate = nodeToAnimate.fadeOut(blinkDelay).fadeIn(blinkDelay);
38 38 }
39 39 }
40 40
41 41 function updateThread() {
42 42 if (loading) {
43 43 return;
44 44 }
45 45
46 46 loading = true;
47 47
48 48 var threadPosts = $('div.thread').children('.post');
49 49
50 50 var lastPost = threadPosts.last();
51 51 var threadId = threadPosts.first().attr('id');
52 52
53 53 var diffUrl = '/api/diff_thread/' + threadId + '/' + lastUpdateTime + '/';
54 54 $.getJSON(diffUrl)
55 55 .success(function(data) {
56 56 var bottom = isPageBottom();
57 57
58 58 var addedPosts = data.added;
59 59
60 60 for (var i = 0; i < addedPosts.length; i++) {
61 61 var postText = addedPosts[i];
62 62
63 63 var post = $(postText);
64 64 post.appendTo(lastPost.parent());
65 65 addRefLinkPreview(post[0]);
66 66
67 67 lastPost = post;
68 68 blink(post);
69 69 }
70 70
71 71 var updatedPosts = data.updated;
72 72 for (var i = 0; i < updatedPosts.length; i++) {
73 73 var postText = updatedPosts[i];
74 74
75 75 var post = $(postText);
76 76 var postId = post.attr('id');
77 77
78 78 var oldPost = $('div.thread').children('.post[id=' + postId + ']');
79 79
80 80 oldPost.replaceWith(post);
81 81 addRefLinkPreview(post[0]);
82 82
83 83 blink(post);
84 84 }
85 85
86 86 // TODO Process deleted posts
87 87
88 88 lastUpdateTime = data.last_update;
89 89 loading = false;
90 90
91 91 if (bottom) {
92 92 var $target = $('html,body');
93 93 $target.animate({scrollTop: $target.height()}, 1000);
94 94 }
95
96 $('#reply-count').text(getReplyCount());
97 $('#image-count').text(getImageCount());
95 98 })
96 99 .error(function(data) {
97 100 // TODO Show error message that server is unavailable?
98 101
99 102 loading = false;
100 103 });
101 104 }
102 105
103 106 function isPageBottom() {
104 107 var scroll = $(window).scrollTop() / ($(document).height()
105 108 - $(window).height())
106 109
107 110 return scroll == 1
108 111 }
109 112
110 113 function initAutoupdate() {
111 114 loading = false;
112 115
113 116 lastUpdateTime = $('.metapanel').attr('data-last-update');
114 117
115 118 setInterval(updateThread, THREAD_UPDATE_DELAY);
116 119 }
120
121 function getReplyCount() {
122 return $('.thread').children('.post').length - 1
123 }
124
125 function getImageCount() {
126 return $('.thread').find('img').length
127 }
@@ -1,164 +1,164 b''
1 1 {% extends "boards/base.html" %}
2 2
3 3 {% load i18n %}
4 4 {% load markup %}
5 5 {% load cache %}
6 6 {% load static from staticfiles %}
7 7 {% load board %}
8 8
9 9 {% block head %}
10 10 <title>Neboard - {{ posts.0.get_title }}</title>
11 11 {% endblock %}
12 12
13 13 {% block content %}
14 14 {% get_current_language as LANGUAGE_CODE %}
15 15
16 16 <script src="{% static 'js/thread_update.js' %}"></script>
17 17 <script src="{% static 'js/thread.js' %}"></script>
18 18
19 19 {% if posts %}
20 20 {% cache 600 thread_view posts.0.last_edit_time moderator LANGUAGE_CODE %}
21 21 {% if bumpable %}
22 22 <div class="bar-bg">
23 23 <div class="bar-value" style="width:{{ bumplimit_progress }}%">
24 24 </div>
25 25 <div class="bar-text">
26 26 {{ posts_left }} {% trans 'posts to bumplimit' %}
27 27 </div>
28 28 </div>
29 29 {% endif %}
30 30 <div class="thread">
31 31 {% for post in posts %}
32 32 {% if bumpable %}
33 33 <div class="post" id="{{ post.id }}">
34 34 {% else %}
35 35 <div class="post dead_post" id="{{ post.id }}">
36 36 {% endif %}
37 37 {% if post.image %}
38 38 <div class="image">
39 39 <a
40 40 class="thumb"
41 41 href="{{ post.image.url }}"><img
42 42 src="{{ post.image.url_200x150 }}"
43 43 alt="{{ post.id }}"
44 44 data-width="{{ post.image_width }}"
45 45 data-height="{{ post.image_height }}"/>
46 46 </a>
47 47 </div>
48 48 {% endif %}
49 49 <div class="message">
50 50 <div class="post-info">
51 51 <span class="title">{{ post.title }}</span>
52 52 <a class="post_id" href="#{{ post.id }}">
53 53 ({{ post.id }})</a>
54 54 [{{ post.pub_time }}]
55 55 [<a href="#" onclick="javascript:addQuickReply('{{ post.id }}')
56 56 ; return false;">&gt;&gt;</a>]
57 57
58 58 {% if moderator %}
59 59 <span class="moderator_info">
60 60 [<a href="{% url 'delete' post_id=post.id %}"
61 61 >{% trans 'Delete' %}</a>]
62 62 ({{ post.poster_ip }})
63 63 [<a href="{% url 'ban' post_id=post.id %}?next={{ request.path }}"
64 64 >{% trans 'Ban IP' %}</a>]
65 65 </span>
66 66 {% endif %}
67 67 </div>
68 68 {% autoescape off %}
69 69 {{ post.text.rendered }}
70 70 {% endautoescape %}
71 71 {% if post.is_referenced %}
72 72 <div class="refmap">
73 73 {% trans "Replies" %}:
74 74 {% for ref_post in post.get_sorted_referenced_posts %}
75 75 <a href="{% post_url ref_post.id %}">&gt;&gt;{{ ref_post.id }}</a
76 76 >{% if not forloop.last %},{% endif %}
77 77 {% endfor %}
78 78 </div>
79 79 {% endif %}
80 80 </div>
81 81 {% if forloop.first %}
82 82 <div class="metadata">
83 83 <span class="tags">
84 84 {% for tag in post.get_tags %}
85 85 <a class="tag" href="{% url 'tag' tag.name %}">
86 86 #{{ tag.name }}</a
87 87 >{% if not forloop.last %},{% endif %}
88 88 {% endfor %}
89 89 </span>
90 90 </div>
91 91 {% endif %}
92 92 </div>
93 93 {% endfor %}
94 94 </div>
95 95 {% endcache %}
96 96 {% endif %}
97 97
98 98 <form id="form" enctype="multipart/form-data" method="post"
99 99 >{% csrf_token %}
100 100 <div class="post-form-w">
101 101 <div class="form-title">{% trans "Reply to thread" %} #{{ posts.0.id }}</div>
102 102 <div class="post-form">
103 103 <div class="form-row">
104 104 <div class="form-label">{% trans 'Title' %}</div>
105 105 <div class="form-input">{{ form.title }}</div>
106 106 <div class="form-errors">{{ form.title.errors }}</div>
107 107 </div>
108 108 <div class="form-row">
109 109 <div class="form-label">{% trans 'Formatting' %}</div>
110 110 <div class="form-input" id="mark_panel">
111 111 <span class="mark_btn" id="quote"><span class="quote">&gt;{% trans 'quote' %}</span></span>
112 112 <span class="mark_btn" id="italic"><i>{% trans 'italic' %}</i></span>
113 113 <span class="mark_btn" id="bold"><b>{% trans 'bold' %}</b></span>
114 114 <span class="mark_btn" id="spoiler"><span class="spoiler">{% trans 'spoiler' %}</span></span>
115 115 <span class="mark_btn" id="comment"><span class="comment">// {% trans 'comment' %}</span></span>
116 116 </div>
117 117 </div>
118 118 <div class="form-row">
119 119 <div class="form-label">{% trans 'Text' %}</div>
120 120 <div class="form-input">{{ form.text }}</div>
121 121 <div class="form-errors">{{ form.text.errors }}</div>
122 122 </div>
123 123 <div class="form-row">
124 124 <div class="form-label">{% trans 'Image' %}</div>
125 125 <div class="form-input">{{ form.image }}</div>
126 126 <div class="form-errors">{{ form.image.errors }}</div>
127 127 </div>
128 128 <div class="form-row form-email">
129 129 <div class="form-label">{% trans 'e-mail' %}</div>
130 130 <div class="form-input">{{ form.email }}</div>
131 131 <div class="form-errors">{{ form.email.errors }}</div>
132 132 </div>
133 133 <div class="form-row">
134 134 {{ form.captcha }}
135 135 <div class="form-errors">{{ form.captcha.errors }}</div>
136 136 </div>
137 137 <div class="form-row">
138 138 <div class="form-errors">{{ form.other.errors }}</div>
139 139 </div>
140 140 </div>
141 141
142 142 <div class="form-submit"><input type="submit"
143 143 value="{% trans "Post" %}"/></div>
144 144 <div><a href="{% url "staticpage" name="help" %}">
145 145 {% trans 'Text syntax' %}</a></div>
146 146 </div>
147 147 </form>
148 148
149 149 {% endblock %}
150 150
151 151 {% block metapanel %}
152 152
153 153 {% get_current_language as LANGUAGE_CODE %}
154 154
155 155 <span class="metapanel" data-last-update="{{ last_update }}">
156 156 {% cache 600 thread_meta posts.0.last_edit_time moderator LANGUAGE_CODE %}
157 {{ posts.0.get_reply_count }} {% trans 'replies' %},
158 {{ posts.0.get_images_count }} {% trans 'images' %}.
157 <span id="reply-count">{{ posts.0.get_reply_count }}</span> {% trans 'replies' %},
158 <span id="image-count">{{ posts.0.get_images_count }}</span> {% trans 'images' %}.
159 159 {% trans 'Last update: ' %}{{ posts.0.last_edit_time }}
160 160 [<a href="rss/">RSS</a>]
161 161 {% endcache %}
162 162 </span>
163 163
164 164 {% endblock %}
@@ -1,48 +1,48 b''
1 1 = Features =
2 2 [DONE] Connecting tags to each other
3 3 [DONE] Connect posts to the replies (in messages), get rid of the JS reply map
4 4 [DONE] Better django admin pages to simplify admin operations
5 5 [DONE] Regen script to update all posts
6 6 [DONE] Remove jump links from refmaps
7 7 [DONE] Ban reasons. Split bans into 2 types "read-only" and "read
8 8 denied". Use second only for autoban for spam
9 9 [DONE] Clean up tests and make them run ALWAYS
10 10 [DONE] Use transactions in tests
11 11 [DONE] Thread autoupdate (JS + API)
12 12
13 13 [NOT STARTED] Tree view (JS)
14 14 [NOT STARTED] Adding tags to images filename
15 15 [NOT STARTED] Federative network for s2s communication
16 16 [NOT STARTED] XMPP gate
17 17 [NOT STARTED] Bitmessage gate
18 18 [NOT STARTED] Notification engine
19 19 [NOT STARTED] Javascript disabling engine
20 20 [NOT STARTED] Group tags by first letter in all tags list
21 21 [NOT STARTED] Show board speed in the lower panel (posts per day)
22 22 [NOT STARTED] Character counter in the post field
23 23 [NOT STARTED] Save image thumbnails size to the separate field
24 24 [NOT STARTED] Whitelist functionality. Permin autoban of an address
25 25 [NOT STARTED] Split up post model into post and thread,
26 26 and move everything that is used only in 1st post to thread model.
27 27 [NOT STARTED] Statistics module. Count views (optional, may result in bad
28 28 performance), posts per day/week/month, users (or IPs)
29 29 [NOT STARTED] Quote button next to "reply" for posts in thread to include full
30 30 post or its part (delimited by N characters) into quote of the new post.
31 31 [NOT STARTED] Ban confirmation page with reason
32 32 [NOT STARTED] Post deletion confirmation page
33 33 [NOT STARTED] Moderating page. Tags editing and adding
34 34 [NOT STARTED] Get thread graph image using pygraphviz
35 35 [NOT STARTED] Creating post via AJAX without reloading page
36 36 [NOT STARTED] Subscribing to tag via AJAX
37 37
38 38 = Bugs =
39 39 [DONE] Fix bug with creating threads from tag view
40 40 [DONE] Quote characters within quote causes quote parsing to fail
41 41
42 [NOT STARTED] Replies, images, last update time in bottom panel doesn't change when
42 [IN PROGRESS] Replies, images, last update time in bottom panel doesn't change when
43 43 thread updates
44 44
45 45 = Testing =
46 46 [NOT STARTED] Make tests for every view
47 47 [NOT STARTED] Make tests for every model
48 48 [NOT STARTED] Make tests for every form
General Comments 0
You need to be logged in to leave comments. Login now