##// END OF EJS Templates
Setting for image view mode: in post (simple) or in popup
neko259 -
r1122:2ec94187 default
parent child Browse files
Show More
@@ -14,6 +14,7 b" SETTING_HIDDEN_TAGS = 'hidden_tags'"
14 SETTING_PERMISSIONS = 'permissions'
14 SETTING_PERMISSIONS = 'permissions'
15 SETTING_USERNAME = 'username'
15 SETTING_USERNAME = 'username'
16 SETTING_LAST_NOTIFICATION_ID = 'last_notification'
16 SETTING_LAST_NOTIFICATION_ID = 'last_notification'
17 SETTING_IMAGE_VIEWER = 'image_viewer'
17
18
18 DEFAULT_THEME = 'md'
19 DEFAULT_THEME = 'md'
19
20
@@ -44,7 +45,7 b' class SettingsManager:'
44 else:
45 else:
45 return False
46 return False
46
47
47 def get_setting(self, setting):
48 def get_setting(self, setting, default=None):
48 pass
49 pass
49
50
50 def set_setting(self, setting, value):
51 def set_setting(self, setting, value):
@@ -127,11 +128,11 b' class SessionSettingsManager(SettingsMan'
127 SettingsManager.__init__(self)
128 SettingsManager.__init__(self)
128 self.session = session
129 self.session = session
129
130
130 def get_setting(self, setting):
131 def get_setting(self, setting, default=None):
131 if setting in self.session:
132 if setting in self.session:
132 return self.session[setting]
133 return self.session[setting]
133 else:
134 else:
134 return None
135 return default
135
136
136 def set_setting(self, setting, value):
137 def set_setting(self, setting, value):
137 self.session[setting] = value
138 self.session[setting] = value
@@ -1,5 +1,5 b''
1 from boards.abstracts.settingsmanager import get_settings_manager, \
1 from boards.abstracts.settingsmanager import get_settings_manager, \
2 SETTING_USERNAME, SETTING_LAST_NOTIFICATION_ID
2 SETTING_USERNAME, SETTING_LAST_NOTIFICATION_ID, SETTING_IMAGE_VIEWER
3 from boards.models.user import Notification
3 from boards.models.user import Notification
4
4
5 __author__ = 'neko259'
5 __author__ = 'neko259'
@@ -18,7 +18,7 b" CONTEXT_USER = 'user'"
18 CONTEXT_NEW_NOTIFICATIONS_COUNT = 'new_notifications_count'
18 CONTEXT_NEW_NOTIFICATIONS_COUNT = 'new_notifications_count'
19 CONTEXT_USERNAME = 'username'
19 CONTEXT_USERNAME = 'username'
20 CONTEXT_TAGS_STR = 'tags_str'
20 CONTEXT_TAGS_STR = 'tags_str'
21
21 CONTEXT_IMAGE_VIEWER = 'image_viewer'
22
22
23
23
24 def get_notifications(context, request):
24 def get_notifications(context, request):
@@ -54,6 +54,9 b' def user_and_ui_processor(request):'
54 context[CONTEXT_VERSION] = settings.VERSION
54 context[CONTEXT_VERSION] = settings.VERSION
55 context[CONTEXT_SITE_NAME] = settings.SITE_NAME
55 context[CONTEXT_SITE_NAME] = settings.SITE_NAME
56
56
57 context[CONTEXT_IMAGE_VIEWER] = settings_manager.get_setting(
58 SETTING_IMAGE_VIEWER, default=settings.DEFAULT_IMAGE_VIEWER)
59
57 get_notifications(context, request)
60 get_notifications(context, request)
58
61
59 return context
62 return context
@@ -12,6 +12,7 b' MAX_POSTS_PER_THREAD = 10'
12 MAX_THREAD_COUNT = 5
12 MAX_THREAD_COUNT = 5
13 THREADS_PER_PAGE = 3
13 THREADS_PER_PAGE = 3
14 DEFAULT_THEME = 'md'
14 DEFAULT_THEME = 'md'
15 DEFAULT_IMAGE_VIEWER = 'simple'
15 LAST_REPLIES_COUNT = 3
16 LAST_REPLIES_COUNT = 3
16
17
17 # Enable archiving threads instead of deletion when the thread limit is reached
18 # Enable archiving threads instead of deletion when the thread limit is reached
@@ -365,6 +365,7 b' class ThreadForm(PostForm):'
365 class SettingsForm(NeboardForm):
365 class SettingsForm(NeboardForm):
366
366
367 theme = forms.ChoiceField(choices=settings.THEMES, label=_('Theme'))
367 theme = forms.ChoiceField(choices=settings.THEMES, label=_('Theme'))
368 image_viewer = forms.ChoiceField(choices=settings.IMAGE_VIEWERS, label=_('Image view mode'))
368 username = forms.CharField(label=_('User name'), required=False)
369 username = forms.CharField(label=_('User name'), required=False)
369 timezone = forms.ChoiceField(choices=get_timezones(), label=_('Time zone'))
370 timezone = forms.ChoiceField(choices=get_timezones(), label=_('Time zone'))
370
371
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -7,7 +7,7 b' msgid ""'
7 msgstr ""
7 msgstr ""
8 "Project-Id-Version: PACKAGE VERSION\n"
8 "Project-Id-Version: PACKAGE VERSION\n"
9 "Report-Msgid-Bugs-To: \n"
9 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2015-04-17 15:12+0300\n"
10 "POT-Creation-Date: 2015-04-21 21:10+0300\n"
11 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
11 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 "Language-Team: LANGUAGE <LL@li.org>\n"
13 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -59,7 +59,7 b' msgstr "\xd0\xa2\xd0\xb5\xd0\xba\xd1\x81\xd1\x82"'
59 msgid "Tag"
59 msgid "Tag"
60 msgstr "Метка"
60 msgstr "Метка"
61
61
62 #: forms.py:41 templates/boards/base.html:40 templates/search/search.html:7
62 #: forms.py:41 templates/boards/base.html:41 templates/search/search.html:7
63 msgid "Search"
63 msgid "Search"
64 msgstr "Поиск"
64 msgstr "Поиск"
65
65
@@ -129,14 +129,18 b' msgid "Theme"'
129 msgstr "Тема"
129 msgstr "Тема"
130
130
131 #: forms.py:368
131 #: forms.py:368
132 msgid "Image view mode"
133 msgstr "Режим просмотра изображений"
134
135 #: forms.py:369
132 msgid "User name"
136 msgid "User name"
133 msgstr "Имя пользователя"
137 msgstr "Имя пользователя"
134
138
135 #: forms.py:369
139 #: forms.py:370
136 msgid "Time zone"
140 msgid "Time zone"
137 msgstr "Часовой пояс"
141 msgstr "Часовой пояс"
138
142
139 #: forms.py:375
143 #: forms.py:376
140 msgid "Inappropriate characters."
144 msgid "Inappropriate characters."
141 msgstr "Недопустимые символы."
145 msgstr "Недопустимые символы."
142
146
@@ -164,41 +168,41 b' msgstr "\xd0\xbb\xd0\xb8\xd1\x86\xd0\xb5\xd0\xbd\xd0\xb7\xd0\xb8\xd0\xb5\xd0\xb9"'
164 msgid "Repository"
168 msgid "Repository"
165 msgstr "Репозиторий"
169 msgstr "Репозиторий"
166
170
167 #: templates/boards/base.html:13
171 #: templates/boards/base.html:14
168 msgid "Feed"
172 msgid "Feed"
169 msgstr "Лента"
173 msgstr "Лента"
170
174
171 #: templates/boards/base.html:30
175 #: templates/boards/base.html:31
172 msgid "All threads"
176 msgid "All threads"
173 msgstr "Все темы"
177 msgstr "Все темы"
174
178
175 #: templates/boards/base.html:36
179 #: templates/boards/base.html:37
176 msgid "Add tags"
180 msgid "Add tags"
177 msgstr "Добавить метки"
181 msgstr "Добавить метки"
178
182
179 #: templates/boards/base.html:38
183 #: templates/boards/base.html:39
180 msgid "Tag management"
184 msgid "Tag management"
181 msgstr "Управление метками"
185 msgstr "Управление метками"
182
186
183 #: templates/boards/base.html:43 templates/boards/base.html.py:44
187 #: templates/boards/base.html:44 templates/boards/base.html.py:45
184 #: templates/boards/notifications.html:8
188 #: templates/boards/notifications.html:8
185 msgid "Notifications"
189 msgid "Notifications"
186 msgstr "Уведомления"
190 msgstr "Уведомления"
187
191
188 #: templates/boards/base.html:51 templates/boards/settings.html:9
192 #: templates/boards/base.html:52 templates/boards/settings.html:9
189 msgid "Settings"
193 msgid "Settings"
190 msgstr "Настройки"
194 msgstr "Настройки"
191
195
192 #: templates/boards/base.html:64
196 #: templates/boards/base.html:65
193 msgid "Admin"
197 msgid "Admin"
194 msgstr "Администрирование"
198 msgstr "Администрирование"
195
199
196 #: templates/boards/base.html:66
200 #: templates/boards/base.html:67
197 #, python-format
201 #, python-format
198 msgid "Speed: %(ppd)s posts per day"
202 msgid "Speed: %(ppd)s posts per day"
199 msgstr "Скорость: %(ppd)s сообщений в день"
203 msgstr "Скорость: %(ppd)s сообщений в день"
200
204
201 #: templates/boards/base.html:68
205 #: templates/boards/base.html:69
202 msgid "Up"
206 msgid "Up"
203 msgstr "Вверх"
207 msgstr "Вверх"
204
208
@@ -232,11 +236,11 b' msgstr "\xd0\x98\xd0\xb7\xd0\xbc\xd0\xb5\xd0\xbd\xd0\xb8\xd1\x82\xd1\x8c \xd1\x82\xd0\xb5\xd0\xbc\xd1\x83"'
232 msgid "Replies"
236 msgid "Replies"
233 msgstr "Ответы"
237 msgstr "Ответы"
234
238
235 #: templates/boards/post.html:81 templates/boards/thread.html:31
239 #: templates/boards/post.html:81 templates/boards/thread.html:26
236 msgid "messages"
240 msgid "messages"
237 msgstr "сообщений"
241 msgstr "сообщений"
238
242
239 #: templates/boards/post.html:82 templates/boards/thread.html:32
243 #: templates/boards/post.html:82 templates/boards/thread.html:27
240 msgid "images"
244 msgid "images"
241 msgstr "изображений"
245 msgstr "изображений"
242
246
@@ -277,7 +281,7 b' msgstr ""'
277 msgid "Text syntax"
281 msgid "Text syntax"
278 msgstr "Синтаксис текста"
282 msgstr "Синтаксис текста"
279
283
280 #: templates/boards/posting_general.html:158
284 #: templates/boards/posting_general.html:159
281 msgid "Pages:"
285 msgid "Pages:"
282 msgstr "Страницы: "
286 msgstr "Страницы: "
283
287
@@ -359,7 +363,7 b' msgstr "\xd0\x9c\xd0\xb5\xd1\x82\xd0\xba\xd0\xb8 \xd0\xbd\xd0\xb5 \xd0\xbd\xd0\xb0\xd0\xb9\xd0\xb4\xd0\xb5\xd0\xbd\xd1\x8b."'
359 msgid "All tags"
363 msgid "All tags"
360 msgstr "Все метки"
364 msgstr "Все метки"
361
365
362 #: templates/boards/thread.html:33
366 #: templates/boards/thread.html:28
363 msgid "Last update: "
367 msgid "Last update: "
364 msgstr "Последнее обновление: "
368 msgstr "Последнее обновление: "
365
369
@@ -89,17 +89,19 b' class PostImage(models.Model, Viewable):'
89
89
90 def get_view(self):
90 def get_view(self):
91 return '<div class="{}">' \
91 return '<div class="{}">' \
92 '<a class="{}" href="{}">' \
92 '<a class="{}" href="{full}">' \
93 '<img' \
93 '<img class="post-image-preview"' \
94 ' src="{}"' \
94 ' src="{}"' \
95 ' alt="{}"' \
95 ' alt="{}"' \
96 ' width="{}"' \
96 ' width="{}"' \
97 ' height="{}"' \
97 ' height="{}"' \
98 ' data-width="{}"' \
98 ' data-width="{}"' \
99 ' data-height="{}" />' \
99 ' data-height="{}" />' \
100 '<img class="post-image-full"' \
101 ' src="{full}" />' \
100 '</a>' \
102 '</a>' \
101 '</div>'\
103 '</div>'\
102 .format(CSS_CLASS_IMAGE, CSS_CLASS_THUMB, self.image.url,
104 .format(CSS_CLASS_IMAGE, CSS_CLASS_THUMB,
103 self.image.url_200x150,
105 self.image.url_200x150,
104 str(self.hash), str(self.pre_width),
106 str(self.hash), str(self.pre_width),
105 str(self.pre_height), str(self.width), str(self.height))
107 str(self.pre_height), str(self.width), str(self.height), full=self.image.url)
@@ -95,3 +95,8 b' textarea, input {'
95 #form-close-button {
95 #form-close-button {
96 display: none;
96 display: none;
97 }
97 }
98
99 .post-image-full {
100 display: none;
101 width: 100%;
102 }
@@ -23,8 +23,100 b''
23 for the JavaScript code in this page.
23 for the JavaScript code in this page.
24 */
24 */
25
25
26
27 var IMAGE_VIEWERS = [
28 ['simple', new SimpleImageViewer()],
29 ['popup', new PopupImageViewer()]
30 ];
31
32
33 function ImageViewer() {}
34 ImageViewer.prototype.view = function (post) {};
35
36 function SimpleImageViewer() {}
37 SimpleImageViewer.prototype.view = function (post) {
38 post.find('img').toggle();
39 };
40
41 function PopupImageViewer() {}
42 PopupImageViewer.prototype.view = function (post) {
43 var margin = 20; //..change
44
45 var el = post;
46 var thumb_id = 'full' + el.find('img').attr('alt');
47
48 var existingPopups = $('#' + thumb_id);
49 if(!existingPopups.length) {
50 var imgElement= el.find('img');
51
52 var img_w = imgElement.attr('data-width');
53 var img_h = imgElement.attr('data-height');
54
55 var win = $(window);
56
57 var win_w = win.width();
58 var win_h = win.height();
59 //new image size
60 if (img_w > win_w) {
61 img_h = img_h * (win_w/img_w) - margin;
62 img_w = win_w - margin;
63 }
64 if (img_h > win_h) {
65 img_w = img_w * (win_h/img_h) - margin;
66 img_h = win_h - margin;
67 }
68
69 var img_pv = new Image();
70 var newImage = $(img_pv);
71 newImage.addClass('img-full')
72 .attr('id', thumb_id)
73 .attr('src', $(el).attr('href'))
74 .appendTo($(el))
75 .css({
76 'width': img_w,
77 'height': img_h,
78 'left': (win_w - img_w) / 2,
79 'top': ((win_h - img_h) / 2)
80 })
81 //scaling preview
82 .mousewheel(function(event, delta) {
83 var cx = event.originalEvent.clientX,
84 cy = event.originalEvent.clientY,
85 i_w = parseFloat(newImage.width()),
86 i_h = parseFloat(newImage.height()),
87 newIW = i_w * (delta > 0 ? 1.25 : 0.8),
88 newIH = i_h * (delta > 0 ? 1.25 : 0.8);
89
90 newImage.width(newIW);
91 newImage.height(newIH);
92 //set position
93 newImage.css({
94 left: parseInt(cx - (newIW/i_w) * (cx - parseInt($(img_pv).position().left, 10)), 10),
95 top: parseInt(cy - (newIH/i_h) * (cy - parseInt($(img_pv).position().top, 10)), 10)
96 });
97
98 return false;
99 }
100 )
101 .draggable({
102 addClasses: false,
103 stack: '.img-full'
104 });
105 } else {
106 existingPopups.remove();
107 }
108 };
109
26 function addImgPreview() {
110 function addImgPreview() {
27 var margin = 20; //..change
111 var viewerName = $('body').attr('data-image-viewer');
112 var viewer = ImageViewer();
113 for (var i = 0; i < IMAGE_VIEWERS.length; i++) {
114 var item = IMAGE_VIEWERS[i];
115 if (item[0] === viewerName) {
116 viewer = item[1];
117 break;
118 }
119 }
28
120
29 //keybind
121 //keybind
30 $(document).on('keyup.removepic', function(e) {
122 $(document).on('keyup.removepic', function(e) {
@@ -34,70 +126,8 b' function addImgPreview() {'
34 });
126 });
35
127
36 $('body').on('click', '.thumb', function() {
128 $('body').on('click', '.thumb', function() {
37 var el = $(this);
129 viewer.view($(this));
38 var thumb_id = 'full' + el.find('img').attr('alt');
39
40 var existingPopups = $('#' + thumb_id);
41 if(!existingPopups.length) {
42 var imgElement= el.find('img');
43
44 var img_w = imgElement.attr('data-width');
45 var img_h = imgElement.attr('data-height');
46
47 var win = $(window);
48
49 var win_w = win.width();
50 var win_h = win.height();
51 //new image size
52 if (img_w > win_w) {
53 img_h = img_h * (win_w/img_w) - margin;
54 img_w = win_w - margin;
55 }
56 if (img_h > win_h) {
57 img_w = img_w * (win_h/img_h) - margin;
58 img_h = win_h - margin;
59 }
60
130
61 var img_pv = new Image();
62 var newImage = $(img_pv);
63 newImage.addClass('img-full')
64 .attr('id', thumb_id)
65 .attr('src', $(el).attr('href'))
66 .appendTo($(el))
67 .css({
68 'width': img_w,
69 'height': img_h,
70 'left': (win_w - img_w) / 2,
71 'top': ((win_h - img_h) / 2)
72 })
73 //scaling preview
74 .mousewheel(function(event, delta) {
75 var cx = event.originalEvent.clientX,
76 cy = event.originalEvent.clientY,
77 i_w = parseFloat(newImage.width()),
78 i_h = parseFloat(newImage.height()),
79 newIW = i_w * (delta > 0 ? 1.25 : 0.8),
80 newIH = i_h * (delta > 0 ? 1.25 : 0.8);
81
82 newImage.width(newIW);
83 newImage.height(newIH);
84 //set position
85 newImage.css({
86 left: parseInt(cx - (newIW/i_w) * (cx - parseInt($(img_pv).position().left, 10)), 10),
87 top: parseInt(cy - (newIH/i_h) * (cy - parseInt($(img_pv).position().top, 10)), 10)
88 });
89
90 return false;
91 }
92 )
93 .draggable({
94 addClasses: false,
95 stack: '.img-full'
96 });
97 } else {
98 existingPopups.remove();
99 }
100 //prevent default
101 return false;
131 return false;
102 });
132 });
103 }
133 }
@@ -21,7 +21,7 b''
21
21
22 {% block head %}{% endblock %}
22 {% block head %}{% endblock %}
23 </head>
23 </head>
24 <body>
24 <body data-image-viewer="{{ image_viewer }}">
25 <script src="{% static 'js/jquery-2.0.1.min.js' %}"></script>
25 <script src="{% static 'js/jquery-2.0.1.min.js' %}"></script>
26 <script src="{% static 'js/3party/jquery-ui.min.js' %}"></script>
26 <script src="{% static 'js/3party/jquery-ui.min.js' %}"></script>
27 <script src="{% static 'js/jquery.mousewheel.js' %}"></script>
27 <script src="{% static 'js/jquery.mousewheel.js' %}"></script>
@@ -3,15 +3,17 b' from django.shortcuts import render, red'
3 from django.utils import timezone
3 from django.utils import timezone
4
4
5 from boards.abstracts.settingsmanager import get_settings_manager, \
5 from boards.abstracts.settingsmanager import get_settings_manager, \
6 SETTING_USERNAME, SETTING_LAST_NOTIFICATION_ID
6 SETTING_USERNAME, SETTING_LAST_NOTIFICATION_ID, SETTING_IMAGE_VIEWER
7 from boards.middlewares import SESSION_TIMEZONE
7 from boards.middlewares import SESSION_TIMEZONE
8 from boards.views.base import BaseBoardView, CONTEXT_FORM
8 from boards.views.base import BaseBoardView, CONTEXT_FORM
9 from boards.forms import SettingsForm, PlainErrorList
9 from boards.forms import SettingsForm, PlainErrorList
10 from boards import settings
10
11
11
12
12 FORM_THEME = 'theme'
13 FORM_THEME = 'theme'
13 FORM_USERNAME = 'username'
14 FORM_USERNAME = 'username'
14 FORM_TIMEZONE = 'timezone'
15 FORM_TIMEZONE = 'timezone'
16 FORM_IMAGE_VIEWER = 'image_viewer'
15
17
16 CONTEXT_HIDDEN_TAGS = 'hidden_tags'
18 CONTEXT_HIDDEN_TAGS = 'hidden_tags'
17
19
@@ -29,6 +31,8 b' class SettingsView(BaseBoardView):'
29 form = SettingsForm(
31 form = SettingsForm(
30 initial={
32 initial={
31 FORM_THEME: selected_theme,
33 FORM_THEME: selected_theme,
34 FORM_IMAGE_VIEWER: settings_manager.get_setting(
35 SETTING_IMAGE_VIEWER, default=settings.DEFAULT_IMAGE_VIEWER),
32 FORM_USERNAME: settings_manager.get_setting(SETTING_USERNAME),
36 FORM_USERNAME: settings_manager.get_setting(SETTING_USERNAME),
33 FORM_TIMEZONE: request.session.get(
37 FORM_TIMEZONE: request.session.get(
34 SESSION_TIMEZONE, timezone.get_current_timezone()),
38 SESSION_TIMEZONE, timezone.get_current_timezone()),
@@ -51,6 +55,8 b' class SettingsView(BaseBoardView):'
51 username = form.cleaned_data[FORM_USERNAME].lower()
55 username = form.cleaned_data[FORM_USERNAME].lower()
52
56
53 settings_manager.set_theme(selected_theme)
57 settings_manager.set_theme(selected_theme)
58 settings_manager.set_setting(SETTING_IMAGE_VIEWER,
59 form.cleaned_data[FORM_IMAGE_VIEWER])
54
60
55 old_username = settings_manager.get_setting(SETTING_USERNAME)
61 old_username = settings_manager.get_setting(SETTING_USERNAME)
56 if username != old_username:
62 if username != old_username:
@@ -202,6 +202,11 b' THEMES = ['
202 ('pg', 'Photon Gray'),
202 ('pg', 'Photon Gray'),
203 ]
203 ]
204
204
205 IMAGE_VIEWERS = [
206 ('simple', 'Simple'),
207 ('popup', 'Popup'),
208 ]
209
205 POSTING_DELAY = 20 # seconds
210 POSTING_DELAY = 20 # seconds
206
211
207 # Websocket settins
212 # Websocket settins
General Comments 0
You need to be logged in to leave comments. Login now