nodebb-theme-harmony 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/.eslintrc +3 -3
  2. package/README.md +22 -22
  3. package/lib/controllers.js +29 -29
  4. package/library.js +183 -183
  5. package/package.json +48 -48
  6. package/plugin.json +24 -24
  7. package/public/.eslintrc +3 -3
  8. package/public/admin.js +15 -15
  9. package/public/harmony.js +287 -287
  10. package/public/settings.js +31 -31
  11. package/renovate.json +6 -6
  12. package/scss/account.scss +27 -27
  13. package/scss/category.scss +3 -3
  14. package/scss/chats.scss +11 -11
  15. package/scss/common.scss +122 -122
  16. package/scss/fonts.scss +19 -19
  17. package/scss/groups.scss +22 -22
  18. package/scss/harmony.scss +24 -24
  19. package/scss/header.scss +15 -15
  20. package/scss/mixins.scss +183 -183
  21. package/scss/modals.scss +6 -6
  22. package/scss/modules/breadcrumbs.scss +15 -15
  23. package/scss/modules/cover.scss +102 -102
  24. package/scss/modules/filters.scss +7 -7
  25. package/scss/modules/nprogress.scss +80 -80
  26. package/scss/modules/paginator.scss +23 -23
  27. package/scss/modules/tags.scss +5 -5
  28. package/scss/modules/topic-navigator.scss +52 -52
  29. package/scss/modules/topics-list.scss +40 -40
  30. package/scss/modules/user-menu.scss +10 -10
  31. package/scss/overrides.scss +65 -65
  32. package/scss/sidebar.scss +188 -188
  33. package/scss/skins.scss +58 -58
  34. package/scss/status.scss +24 -24
  35. package/scss/topic.scss +130 -130
  36. package/templates/account/blocks.tpl +51 -51
  37. package/templates/account/categories.tpl +63 -63
  38. package/templates/account/consent.tpl +73 -73
  39. package/templates/account/edit/password.tpl +34 -34
  40. package/templates/account/edit/username.tpl +29 -29
  41. package/templates/account/edit.tpl +137 -137
  42. package/templates/account/followers.tpl +14 -14
  43. package/templates/account/following.tpl +15 -15
  44. package/templates/account/groups.tpl +15 -15
  45. package/templates/account/info.tpl +270 -270
  46. package/templates/account/posts.tpl +35 -35
  47. package/templates/account/profile.tpl +92 -92
  48. package/templates/account/sessions.tpl +8 -8
  49. package/templates/account/settings.tpl +236 -236
  50. package/templates/account/shares.tpl +19 -19
  51. package/templates/account/tags.tpl +12 -12
  52. package/templates/account/theme.tpl +63 -63
  53. package/templates/account/topics.tpl +44 -44
  54. package/templates/account/uploads.tpl +37 -37
  55. package/templates/admin/plugins/harmony.tpl +57 -57
  56. package/templates/categories.tpl +29 -29
  57. package/templates/category.tpl +72 -72
  58. package/templates/footer.tpl +17 -17
  59. package/templates/groups/details.tpl +86 -86
  60. package/templates/groups/list.tpl +58 -58
  61. package/templates/groups/members.tpl +9 -9
  62. package/templates/header.tpl +45 -45
  63. package/templates/notifications.tpl +32 -32
  64. package/templates/partials/account/admin-menu.tpl +36 -36
  65. package/templates/partials/account/category-item.tpl +22 -22
  66. package/templates/partials/account/footer.tpl +2 -2
  67. package/templates/partials/account/header.tpl +98 -98
  68. package/templates/partials/account/session-list.tpl +18 -18
  69. package/templates/partials/account/sidebar-left.tpl +116 -116
  70. package/templates/partials/breadcrumbs-json-ld.tpl +15 -15
  71. package/templates/partials/breadcrumbs.tpl +12 -12
  72. package/templates/partials/buttons/newTopic.tpl +22 -22
  73. package/templates/partials/categories/item.tpl +56 -56
  74. package/templates/partials/categories/lastpost.tpl +24 -24
  75. package/templates/partials/categories/link.tpl +4 -4
  76. package/templates/partials/category/subcategory.tpl +18 -18
  77. package/templates/partials/category/tags.tpl +3 -3
  78. package/templates/partials/cookie-consent.tpl +6 -6
  79. package/templates/partials/groups/admin.tpl +95 -95
  80. package/templates/partials/groups/invited.tpl +32 -32
  81. package/templates/partials/groups/list.tpl +15 -15
  82. package/templates/partials/groups/memberlist.tpl +46 -46
  83. package/templates/partials/groups/pending.tpl +29 -29
  84. package/templates/partials/groups/sidebar-left.tpl +27 -27
  85. package/templates/partials/header/brand.tpl +27 -27
  86. package/templates/partials/mobile-footer.tpl +95 -95
  87. package/templates/partials/notifications_list.tpl +44 -44
  88. package/templates/partials/paginator.tpl +46 -46
  89. package/templates/partials/post_bar.tpl +27 -27
  90. package/templates/partials/posts_list.tpl +7 -7
  91. package/templates/partials/posts_list_item.tpl +19 -19
  92. package/templates/partials/quick-search-results.tpl +46 -46
  93. package/templates/partials/search-filters.tpl +183 -183
  94. package/templates/partials/search-results.tpl +54 -54
  95. package/templates/partials/sidebar/chats.tpl +45 -45
  96. package/templates/partials/sidebar/drafts.tpl +63 -63
  97. package/templates/partials/sidebar/logged-in-menu.tpl +22 -22
  98. package/templates/partials/sidebar/logged-out-menu.tpl +44 -44
  99. package/templates/partials/sidebar/notifications.tpl +49 -49
  100. package/templates/partials/sidebar/search-mobile.tpl +28 -28
  101. package/templates/partials/sidebar/search.tpl +30 -30
  102. package/templates/partials/sidebar/user-menu.tpl +103 -103
  103. package/templates/partials/sidebar-left.tpl +39 -39
  104. package/templates/partials/sidebar-right.tpl +16 -16
  105. package/templates/partials/skin-switcher.tpl +50 -50
  106. package/templates/partials/tags_list.tpl +7 -7
  107. package/templates/partials/toast.tpl +19 -19
  108. package/templates/partials/topic/event.tpl +12 -12
  109. package/templates/partials/topic/navigation-post.tpl +9 -9
  110. package/templates/partials/topic/navigator-mobile.tpl +61 -61
  111. package/templates/partials/topic/navigator.tpl +26 -26
  112. package/templates/partials/topic/necro-post.tpl +5 -5
  113. package/templates/partials/topic/post-menu-list.tpl +156 -156
  114. package/templates/partials/topic/post-menu.tpl +4 -4
  115. package/templates/partials/topic/post-placeholder.tpl +14 -14
  116. package/templates/partials/topic/post.tpl +146 -146
  117. package/templates/partials/topic/quickreply.tpl +28 -28
  118. package/templates/partials/topic/reply-button.tpl +26 -26
  119. package/templates/partials/topic/selection-tooltip.tpl +2 -2
  120. package/templates/partials/topic/sort.tpl +27 -27
  121. package/templates/partials/topic/stats.tpl +14 -14
  122. package/templates/partials/topic/thumbs.tpl +4 -4
  123. package/templates/partials/topic/tools.tpl +8 -8
  124. package/templates/partials/topic/topic-menu-list.tpl +73 -73
  125. package/templates/partials/topic/watch.tpl +59 -59
  126. package/templates/partials/topic-filters.tpl +15 -15
  127. package/templates/partials/topic-list-bar.tpl +54 -54
  128. package/templates/partials/topic-terms.tpl +15 -15
  129. package/templates/partials/topics_list.tpl +131 -131
  130. package/templates/partials/users/item.tpl +39 -39
  131. package/templates/partials/users_list.tpl +4 -4
  132. package/templates/partials/users_list_menu.tpl +14 -14
  133. package/templates/popular.tpl +34 -34
  134. package/templates/post-queue.tpl +211 -211
  135. package/templates/recent.tpl +42 -42
  136. package/templates/search.tpl +46 -46
  137. package/templates/tag.tpl +34 -34
  138. package/templates/tags.tpl +49 -49
  139. package/templates/top.tpl +34 -34
  140. package/templates/topic.tpl +123 -123
  141. package/templates/unread.tpl +31 -31
  142. package/templates/users.tpl +39 -39
  143. package/templates/world.tpl +66 -66
  144. package/theme.json +6 -6
package/public/harmony.js CHANGED
@@ -1,287 +1,287 @@
1
- 'use strict';
2
-
3
- $(document).ready(function () {
4
- setupSkinSwitcher();
5
- setupNProgress();
6
- setupMobileMenu();
7
- setupSearch();
8
- setupDrafts();
9
- handleMobileNavigator();
10
- setupNavTooltips();
11
- fixPlaceholders();
12
- fixSidebarOverflow();
13
-
14
- function setupSkinSwitcher() {
15
- $('[component="skinSwitcher"]').on('click', '.dropdown-item', function () {
16
- const skin = $(this).attr('data-value');
17
- $('[component="skinSwitcher"] .dropdown-item .fa-check').addClass('invisible');
18
- $(this).find('.fa-check').removeClass('invisible');
19
- require(['forum/account/settings', 'hooks'], function (accountSettings, hooks) {
20
- hooks.one('action:skin.change', function () {
21
- $('[component="skinSwitcher"] [component="skinSwitcher/icon"]').removeClass('fa-fade');
22
- });
23
- $('[component="skinSwitcher"] [component="skinSwitcher/icon"]').addClass('fa-fade');
24
- accountSettings.changeSkin(skin);
25
- });
26
- });
27
- }
28
-
29
- require(['hooks'], function (hooks) {
30
- $(window).on('action:composer.resize action:sidebar.toggle', function () {
31
- const isRtl = $('html').attr('data-dir') === 'rtl';
32
- const css = {
33
- width: $('#panel').width(),
34
- };
35
- const sidebarEl = $('.sidebar-left');
36
- css[isRtl ? 'right' : 'left'] = sidebarEl.is(':visible') ? sidebarEl.outerWidth(true) : 0;
37
- $('[component="composer"]').css(css);
38
- });
39
-
40
- hooks.on('filter:chat.openChat', function (hookData) {
41
- // disables chat modals & goes straight to chat page based on user setting
42
- hookData.modal = config.theme.chatModals && !utils.isMobile();
43
- return hookData;
44
- });
45
- });
46
-
47
- function setupMobileMenu() {
48
- require(['hooks', 'api', 'navigator'], function (hooks, api, navigator) {
49
- $('[component="sidebar/toggle"]').on('click', async function () {
50
- const sidebarEl = $('.sidebar');
51
- sidebarEl.toggleClass('open');
52
- if (app.user.uid) {
53
- await api.put(`/users/${app.user.uid}/settings`, {
54
- settings: {
55
- openSidebars: sidebarEl.hasClass('open') ? 'on' : 'off',
56
- },
57
- });
58
- }
59
- $(window).trigger('action:sidebar.toggle');
60
- if (ajaxify.data.template.topic) {
61
- hooks.fire('action:navigator.update', { newIndex: navigator.getIndex() });
62
- }
63
- });
64
-
65
- const bottomBar = $('[component="bottombar"]');
66
- const $body = $('body');
67
- const $window = $(window);
68
- $body.on('shown.bs.dropdown hidden.bs.dropdown', '.sticky-tools', function () {
69
- bottomBar.toggleClass('hidden', $(this).find('.dropdown-menu.show').length);
70
- });
71
- function isSearchVisible() {
72
- return !!$('[component="bottombar"] [component="sidebar/search"] .search-dropdown.show').length;
73
- }
74
-
75
- let lastScrollTop = $window.scrollTop();
76
- let newPostsLoaded = false;
77
-
78
- function onWindowScroll() {
79
- const st = $window.scrollTop();
80
- if (newPostsLoaded) {
81
- newPostsLoaded = false;
82
- lastScrollTop = st;
83
- return;
84
- }
85
- if (st !== lastScrollTop && !navigator.scrollActive && !isSearchVisible()) {
86
- const diff = Math.abs(st - lastScrollTop);
87
- const scrolledDown = st > lastScrollTop;
88
- const scrolledUp = st < lastScrollTop;
89
- if (diff > 10) {
90
- bottomBar.css({
91
- bottom: !scrolledUp && scrolledDown ?
92
- -bottomBar.find('.bottombar-nav').outerHeight(true) :
93
- 0,
94
- });
95
- }
96
- }
97
- lastScrollTop = st;
98
- }
99
-
100
- const delayedScroll = utils.throttle(onWindowScroll, 250);
101
- function enableAutohide() {
102
- $window.off('scroll', delayedScroll);
103
- if (config.theme.autohideBottombar) {
104
- lastScrollTop = $window.scrollTop();
105
- $window.on('scroll', delayedScroll);
106
- }
107
- }
108
-
109
- hooks.on('action:posts.loading', function () {
110
- $window.off('scroll', delayedScroll);
111
- });
112
- hooks.on('action:posts.loaded', function () {
113
- newPostsLoaded = true;
114
- setTimeout(enableAutohide, 250);
115
- });
116
- hooks.on('action:ajaxify.end', function () {
117
- $window.off('scroll', delayedScroll);
118
- if (config.theme.autohideBottombar) {
119
- bottomBar.css({ bottom: 0 });
120
- setTimeout(enableAutohide, 250);
121
- }
122
- });
123
- });
124
- }
125
-
126
- function setupSearch() {
127
- $('[component="sidebar/search"]').on('shown.bs.dropdown', function () {
128
- $(this).find('[component="search/fields"] input[name="query"]').trigger('focus');
129
- });
130
- }
131
-
132
- function setupDrafts() {
133
- require(['composer/drafts', 'bootbox'], function (drafts, bootbox) {
134
- const draftsEl = $('[component="sidebar/drafts"]');
135
-
136
- function updateBadgeCount() {
137
- const count = drafts.getAvailableCount();
138
- if (count > 0) {
139
- draftsEl.removeClass('hidden');
140
- }
141
- $('[component="drafts/count"]').toggleClass('hidden', count <= 0).text(count);
142
- }
143
-
144
- async function renderDraftList() {
145
- const draftListEl = $('[component="drafts/list"]');
146
- const draftItems = drafts.listAvailable();
147
- if (!draftItems.length) {
148
- draftListEl.find('.no-drafts').removeClass('hidden');
149
- draftListEl.find('.placeholder-wave').addClass('hidden');
150
- draftListEl.find('.draft-item-container').html('');
151
- return;
152
- }
153
- draftItems.reverse().forEach((draft) => {
154
- if (draft) {
155
- if (draft.title) {
156
- draft.title = utils.escapeHTML(String(draft.title));
157
- }
158
- draft.text = utils.escapeHTML(
159
- draft.text
160
- ).replace(/(?:\r\n|\r|\n)/g, '<br>');
161
- }
162
- });
163
-
164
- const html = await app.parseAndTranslate('partials/sidebar/drafts', 'drafts', { drafts: draftItems });
165
- draftListEl.find('.no-drafts').addClass('hidden');
166
- draftListEl.find('.placeholder-wave').addClass('hidden');
167
- draftListEl.find('.draft-item-container').html(html).find('.timeago').timeago();
168
- }
169
-
170
-
171
- draftsEl.on('shown.bs.dropdown', renderDraftList);
172
-
173
- draftsEl.on('click', '[component="drafts/open"]', function () {
174
- drafts.open($(this).attr('data-save-id'));
175
- });
176
-
177
- draftsEl.on('click', '[component="drafts/delete"]', function () {
178
- const save_id = $(this).attr('data-save-id');
179
- bootbox.confirm('[[modules:composer.discard-draft-confirm]]', function (ok) {
180
- if (ok) {
181
- drafts.removeDraft(save_id);
182
- renderDraftList();
183
- }
184
- });
185
- return false;
186
- });
187
-
188
- $(window).on('action:composer.drafts.save', updateBadgeCount);
189
- $(window).on('action:composer.drafts.remove', updateBadgeCount);
190
- updateBadgeCount();
191
- });
192
- }
193
-
194
- function setupNProgress() {
195
- require(['nprogress'], function (NProgress) {
196
- window.nprogress = NProgress;
197
- if (NProgress) {
198
- $(window).on('action:ajaxify.start', function () {
199
- NProgress.set(0.7);
200
- });
201
-
202
- $(window).on('action:ajaxify.end', function () {
203
- NProgress.done(true);
204
- });
205
- }
206
- });
207
- }
208
-
209
- function handleMobileNavigator() {
210
- const paginationBlockEl = $('.pagination-block');
211
- require(['hooks'], function (hooks) {
212
- hooks.on('action:ajaxify.end', function () {
213
- paginationBlockEl.find('.dropdown-menu.show').removeClass('show');
214
- });
215
- hooks.on('filter:navigator.scroll', function (hookData) {
216
- paginationBlockEl.find('.dropdown-menu.show').removeClass('show');
217
- return hookData;
218
- });
219
- });
220
- }
221
-
222
- function setupNavTooltips() {
223
- // remove title from user icon in sidebar to prevent double tooltip
224
- $('.sidebar [component="header/avatar"] .avatar').removeAttr('title');
225
- const tooltipEls = $('.sidebar [title]');
226
- const lefttooltipEls = $('.sidebar-left [title]');
227
- const rightooltipEls = $('.sidebar-right [title]');
228
- const isRtl = $('html').attr('data-dir') === 'rtl';
229
- lefttooltipEls.tooltip({
230
- trigger: 'manual',
231
- animation: false,
232
- placement: isRtl ? 'left' : 'right',
233
- });
234
- rightooltipEls.tooltip({
235
- trigger: 'manual',
236
- animation: false,
237
- placement: isRtl ? 'right' : 'left',
238
- });
239
-
240
- tooltipEls.on('mouseenter', function (ev) {
241
- const target = $(ev.target);
242
- const isDropdown = target.hasClass('dropdown-menu') || !!target.parents('.dropdown-menu').length;
243
- if (!$('.sidebar').hasClass('open') && !isDropdown) {
244
- $(this).tooltip('show');
245
- }
246
- });
247
- tooltipEls.on('click mouseleave', function () {
248
- $(this).tooltip('hide');
249
- });
250
- }
251
-
252
- function fixPlaceholders() {
253
- if (!config.loggedIn) {
254
- return;
255
- }
256
- ['notifications', 'chat'].forEach((type) => {
257
- const countEl = $(`nav.sidebar [component="${type}/count"]`).first();
258
- if (!countEl.length) {
259
- return;
260
- }
261
- const count = parseInt(countEl.text(), 10);
262
- if (count > 1) {
263
- const listEls = $(`.dropdown-menu [component="${type}/list"]`);
264
- listEls.each((index, el) => {
265
- const placeholder = $(el).children().first();
266
- for (let x = 0; x < count - 1; x++) {
267
- const cloneEl = placeholder.clone(true);
268
- cloneEl.insertAfter(placeholder);
269
- }
270
- });
271
- }
272
- });
273
- }
274
-
275
- function fixSidebarOverflow() {
276
- // overflow-y-auto needs to be removed on main-nav when dropdowns are opened
277
- const mainNavEl = $('#main-nav');
278
- function toggleOverflow() {
279
- mainNavEl.toggleClass(
280
- 'overflow-y-auto',
281
- !mainNavEl.find('.dropdown-menu.show').length
282
- );
283
- }
284
- mainNavEl.on('shown.bs.dropdown', toggleOverflow)
285
- .on('hidden.bs.dropdown', toggleOverflow);
286
- }
287
- });
1
+ 'use strict';
2
+
3
+ $(document).ready(function () {
4
+ setupSkinSwitcher();
5
+ setupNProgress();
6
+ setupMobileMenu();
7
+ setupSearch();
8
+ setupDrafts();
9
+ handleMobileNavigator();
10
+ setupNavTooltips();
11
+ fixPlaceholders();
12
+ fixSidebarOverflow();
13
+
14
+ function setupSkinSwitcher() {
15
+ $('[component="skinSwitcher"]').on('click', '.dropdown-item', function () {
16
+ const skin = $(this).attr('data-value');
17
+ $('[component="skinSwitcher"] .dropdown-item .fa-check').addClass('invisible');
18
+ $(this).find('.fa-check').removeClass('invisible');
19
+ require(['forum/account/settings', 'hooks'], function (accountSettings, hooks) {
20
+ hooks.one('action:skin.change', function () {
21
+ $('[component="skinSwitcher"] [component="skinSwitcher/icon"]').removeClass('fa-fade');
22
+ });
23
+ $('[component="skinSwitcher"] [component="skinSwitcher/icon"]').addClass('fa-fade');
24
+ accountSettings.changeSkin(skin);
25
+ });
26
+ });
27
+ }
28
+
29
+ require(['hooks'], function (hooks) {
30
+ $(window).on('action:composer.resize action:sidebar.toggle', function () {
31
+ const isRtl = $('html').attr('data-dir') === 'rtl';
32
+ const css = {
33
+ width: $('#panel').width(),
34
+ };
35
+ const sidebarEl = $('.sidebar-left');
36
+ css[isRtl ? 'right' : 'left'] = sidebarEl.is(':visible') ? sidebarEl.outerWidth(true) : 0;
37
+ $('[component="composer"]').css(css);
38
+ });
39
+
40
+ hooks.on('filter:chat.openChat', function (hookData) {
41
+ // disables chat modals & goes straight to chat page based on user setting
42
+ hookData.modal = config.theme.chatModals && !utils.isMobile();
43
+ return hookData;
44
+ });
45
+ });
46
+
47
+ function setupMobileMenu() {
48
+ require(['hooks', 'api', 'navigator'], function (hooks, api, navigator) {
49
+ $('[component="sidebar/toggle"]').on('click', async function () {
50
+ const sidebarEl = $('.sidebar');
51
+ sidebarEl.toggleClass('open');
52
+ if (app.user.uid) {
53
+ await api.put(`/users/${app.user.uid}/settings`, {
54
+ settings: {
55
+ openSidebars: sidebarEl.hasClass('open') ? 'on' : 'off',
56
+ },
57
+ });
58
+ }
59
+ $(window).trigger('action:sidebar.toggle');
60
+ if (ajaxify.data.template.topic) {
61
+ hooks.fire('action:navigator.update', { newIndex: navigator.getIndex() });
62
+ }
63
+ });
64
+
65
+ const bottomBar = $('[component="bottombar"]');
66
+ const $body = $('body');
67
+ const $window = $(window);
68
+ $body.on('shown.bs.dropdown hidden.bs.dropdown', '.sticky-tools', function () {
69
+ bottomBar.toggleClass('hidden', $(this).find('.dropdown-menu.show').length);
70
+ });
71
+ function isSearchVisible() {
72
+ return !!$('[component="bottombar"] [component="sidebar/search"] .search-dropdown.show').length;
73
+ }
74
+
75
+ let lastScrollTop = $window.scrollTop();
76
+ let newPostsLoaded = false;
77
+
78
+ function onWindowScroll() {
79
+ const st = $window.scrollTop();
80
+ if (newPostsLoaded) {
81
+ newPostsLoaded = false;
82
+ lastScrollTop = st;
83
+ return;
84
+ }
85
+ if (st !== lastScrollTop && !navigator.scrollActive && !isSearchVisible()) {
86
+ const diff = Math.abs(st - lastScrollTop);
87
+ const scrolledDown = st > lastScrollTop;
88
+ const scrolledUp = st < lastScrollTop;
89
+ if (diff > 10) {
90
+ bottomBar.css({
91
+ bottom: !scrolledUp && scrolledDown ?
92
+ -bottomBar.find('.bottombar-nav').outerHeight(true) :
93
+ 0,
94
+ });
95
+ }
96
+ }
97
+ lastScrollTop = st;
98
+ }
99
+
100
+ const delayedScroll = utils.throttle(onWindowScroll, 250);
101
+ function enableAutohide() {
102
+ $window.off('scroll', delayedScroll);
103
+ if (config.theme.autohideBottombar) {
104
+ lastScrollTop = $window.scrollTop();
105
+ $window.on('scroll', delayedScroll);
106
+ }
107
+ }
108
+
109
+ hooks.on('action:posts.loading', function () {
110
+ $window.off('scroll', delayedScroll);
111
+ });
112
+ hooks.on('action:posts.loaded', function () {
113
+ newPostsLoaded = true;
114
+ setTimeout(enableAutohide, 250);
115
+ });
116
+ hooks.on('action:ajaxify.end', function () {
117
+ $window.off('scroll', delayedScroll);
118
+ if (config.theme.autohideBottombar) {
119
+ bottomBar.css({ bottom: 0 });
120
+ setTimeout(enableAutohide, 250);
121
+ }
122
+ });
123
+ });
124
+ }
125
+
126
+ function setupSearch() {
127
+ $('[component="sidebar/search"]').on('shown.bs.dropdown', function () {
128
+ $(this).find('[component="search/fields"] input[name="query"]').trigger('focus');
129
+ });
130
+ }
131
+
132
+ function setupDrafts() {
133
+ require(['composer/drafts', 'bootbox'], function (drafts, bootbox) {
134
+ const draftsEl = $('[component="sidebar/drafts"]');
135
+
136
+ function updateBadgeCount() {
137
+ const count = drafts.getAvailableCount();
138
+ if (count > 0) {
139
+ draftsEl.removeClass('hidden');
140
+ }
141
+ $('[component="drafts/count"]').toggleClass('hidden', count <= 0).text(count);
142
+ }
143
+
144
+ async function renderDraftList() {
145
+ const draftListEl = $('[component="drafts/list"]');
146
+ const draftItems = drafts.listAvailable();
147
+ if (!draftItems.length) {
148
+ draftListEl.find('.no-drafts').removeClass('hidden');
149
+ draftListEl.find('.placeholder-wave').addClass('hidden');
150
+ draftListEl.find('.draft-item-container').html('');
151
+ return;
152
+ }
153
+ draftItems.reverse().forEach((draft) => {
154
+ if (draft) {
155
+ if (draft.title) {
156
+ draft.title = utils.escapeHTML(String(draft.title));
157
+ }
158
+ draft.text = utils.escapeHTML(
159
+ draft.text
160
+ ).replace(/(?:\r\n|\r|\n)/g, '<br>');
161
+ }
162
+ });
163
+
164
+ const html = await app.parseAndTranslate('partials/sidebar/drafts', 'drafts', { drafts: draftItems });
165
+ draftListEl.find('.no-drafts').addClass('hidden');
166
+ draftListEl.find('.placeholder-wave').addClass('hidden');
167
+ draftListEl.find('.draft-item-container').html(html).find('.timeago').timeago();
168
+ }
169
+
170
+
171
+ draftsEl.on('shown.bs.dropdown', renderDraftList);
172
+
173
+ draftsEl.on('click', '[component="drafts/open"]', function () {
174
+ drafts.open($(this).attr('data-save-id'));
175
+ });
176
+
177
+ draftsEl.on('click', '[component="drafts/delete"]', function () {
178
+ const save_id = $(this).attr('data-save-id');
179
+ bootbox.confirm('[[modules:composer.discard-draft-confirm]]', function (ok) {
180
+ if (ok) {
181
+ drafts.removeDraft(save_id);
182
+ renderDraftList();
183
+ }
184
+ });
185
+ return false;
186
+ });
187
+
188
+ $(window).on('action:composer.drafts.save', updateBadgeCount);
189
+ $(window).on('action:composer.drafts.remove', updateBadgeCount);
190
+ updateBadgeCount();
191
+ });
192
+ }
193
+
194
+ function setupNProgress() {
195
+ require(['nprogress'], function (NProgress) {
196
+ window.nprogress = NProgress;
197
+ if (NProgress) {
198
+ $(window).on('action:ajaxify.start', function () {
199
+ NProgress.set(0.7);
200
+ });
201
+
202
+ $(window).on('action:ajaxify.end', function () {
203
+ NProgress.done(true);
204
+ });
205
+ }
206
+ });
207
+ }
208
+
209
+ function handleMobileNavigator() {
210
+ const paginationBlockEl = $('.pagination-block');
211
+ require(['hooks'], function (hooks) {
212
+ hooks.on('action:ajaxify.end', function () {
213
+ paginationBlockEl.find('.dropdown-menu.show').removeClass('show');
214
+ });
215
+ hooks.on('filter:navigator.scroll', function (hookData) {
216
+ paginationBlockEl.find('.dropdown-menu.show').removeClass('show');
217
+ return hookData;
218
+ });
219
+ });
220
+ }
221
+
222
+ function setupNavTooltips() {
223
+ // remove title from user icon in sidebar to prevent double tooltip
224
+ $('.sidebar [component="header/avatar"] .avatar').removeAttr('title');
225
+ const tooltipEls = $('.sidebar [title]');
226
+ const lefttooltipEls = $('.sidebar-left [title]');
227
+ const rightooltipEls = $('.sidebar-right [title]');
228
+ const isRtl = $('html').attr('data-dir') === 'rtl';
229
+ lefttooltipEls.tooltip({
230
+ trigger: 'manual',
231
+ animation: false,
232
+ placement: isRtl ? 'left' : 'right',
233
+ });
234
+ rightooltipEls.tooltip({
235
+ trigger: 'manual',
236
+ animation: false,
237
+ placement: isRtl ? 'right' : 'left',
238
+ });
239
+
240
+ tooltipEls.on('mouseenter', function (ev) {
241
+ const target = $(ev.target);
242
+ const isDropdown = target.hasClass('dropdown-menu') || !!target.parents('.dropdown-menu').length;
243
+ if (!$('.sidebar').hasClass('open') && !isDropdown) {
244
+ $(this).tooltip('show');
245
+ }
246
+ });
247
+ tooltipEls.on('click mouseleave', function () {
248
+ $(this).tooltip('hide');
249
+ });
250
+ }
251
+
252
+ function fixPlaceholders() {
253
+ if (!config.loggedIn) {
254
+ return;
255
+ }
256
+ ['notifications', 'chat'].forEach((type) => {
257
+ const countEl = $(`nav.sidebar [component="${type}/count"]`).first();
258
+ if (!countEl.length) {
259
+ return;
260
+ }
261
+ const count = parseInt(countEl.text(), 10);
262
+ if (count > 1) {
263
+ const listEls = $(`.dropdown-menu [component="${type}/list"]`);
264
+ listEls.each((index, el) => {
265
+ const placeholder = $(el).children().first();
266
+ for (let x = 0; x < count - 1; x++) {
267
+ const cloneEl = placeholder.clone(true);
268
+ cloneEl.insertAfter(placeholder);
269
+ }
270
+ });
271
+ }
272
+ });
273
+ }
274
+
275
+ function fixSidebarOverflow() {
276
+ // overflow-y-auto needs to be removed on main-nav when dropdowns are opened
277
+ const mainNavEl = $('#main-nav');
278
+ function toggleOverflow() {
279
+ mainNavEl.toggleClass(
280
+ 'overflow-y-auto',
281
+ !mainNavEl.find('.dropdown-menu.show').length
282
+ );
283
+ }
284
+ mainNavEl.on('shown.bs.dropdown', toggleOverflow)
285
+ .on('hidden.bs.dropdown', toggleOverflow);
286
+ }
287
+ });
@@ -1,31 +1,31 @@
1
- 'use strict';
2
-
3
- define('forum/account/theme', ['forum/account/header', 'api', 'settings', 'alerts'], function (header, api, settings, alerts) {
4
- const Theme = {};
5
-
6
- Theme.init = () => {
7
- header.init();
8
- Theme.setupForm();
9
- };
10
-
11
- Theme.setupForm = () => {
12
- const saveEl = document.getElementById('save');
13
- if (saveEl) {
14
- const formEl = document.getElementById('theme-settings');
15
- saveEl.addEventListener('click', async () => {
16
- const themeSettings = settings.helper.serializeForm($(formEl));
17
- await api.put(`/users/${ajaxify.data.uid}/settings`, {
18
- settings: {
19
- ...themeSettings,
20
- },
21
- });
22
- if (ajaxify.data.isSelf) {
23
- config.theme = (await api.get('/api/config')).theme;
24
- }
25
- alerts.success('[[success:settings-saved]]');
26
- });
27
- }
28
- };
29
-
30
- return Theme;
31
- });
1
+ 'use strict';
2
+
3
+ define('forum/account/theme', ['forum/account/header', 'api', 'settings', 'alerts'], function (header, api, settings, alerts) {
4
+ const Theme = {};
5
+
6
+ Theme.init = () => {
7
+ header.init();
8
+ Theme.setupForm();
9
+ };
10
+
11
+ Theme.setupForm = () => {
12
+ const saveEl = document.getElementById('save');
13
+ if (saveEl) {
14
+ const formEl = document.getElementById('theme-settings');
15
+ saveEl.addEventListener('click', async () => {
16
+ const themeSettings = settings.helper.serializeForm($(formEl));
17
+ await api.put(`/users/${ajaxify.data.uid}/settings`, {
18
+ settings: {
19
+ ...themeSettings,
20
+ },
21
+ });
22
+ if (ajaxify.data.isSelf) {
23
+ config.theme = (await api.get('/api/config')).theme;
24
+ }
25
+ alerts.success('[[success:settings-saved]]');
26
+ });
27
+ }
28
+ };
29
+
30
+ return Theme;
31
+ });
package/renovate.json CHANGED
@@ -1,6 +1,6 @@
1
- {
2
- "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
- "extends": [
4
- "config:base"
5
- ]
6
- }
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": [
4
+ "config:base"
5
+ ]
6
+ }