nodebb-theme-harmony 2.0.1 → 2.0.3

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
@@ -1,184 +1,184 @@
1
- <div class="d-flex flex-wrap gap-2 align-items-center" component="search/filters">
2
- <!-- category filter -->
3
- <div class="post-search-item">
4
- <div component="category/filter" class="dropdown" data-filter-name="category">
5
- <a component="category/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.categories.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
6
- <span class="filter-label">{{{ if filters.categories.active }}}{filters.categories.label}{{{ else }}}[[search:categories]]{{{ end }}}</span>
7
- <span class="caret text-primary opacity-75"></span>
8
- </a>
9
-
10
- <ul class="dropdown-menu p-1 text-sm" role="menu">
11
- <li class="px-3 py-1 mb-2 d-flex flex-column gap-2">
12
- <div component="category-selector-search">
13
- <input type="text" class="form-control" component="category/filter/search" placeholder="[[search:type-a-category]]">
14
- </div>
15
- </li>
16
- <div component="category/list" class="overflow-auto ghost-scrollbar" style="max-height: 350px;"></div>
17
- <div class="px-3 py-1">
18
- <div class="form-check">
19
- <input id="search-children" class="form-check-input" type="checkbox"/>
20
- <label class="form-check-label" for="search-children">[[search:search-child-categories]]</label>
21
- </div>
22
- </div>
23
- </ul>
24
- </div>
25
- </div>
26
-
27
-
28
- <!-- tag filter -->
29
- <div class="post-search-item">
30
- <div component="tag/filter" class="dropdown" data-filter-name="tag">
31
- <a component="tag/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.tags.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
32
- <span class="filter-label">{{{ if filters.tags.active }}}{filters.tags.label}{{{ else }}}[[search:tags]]{{{ end }}}</span>
33
- <span class="caret text-primary opacity-75"></span>
34
- </a>
35
-
36
- <ul class="dropdown-menu p-1 text-sm" style="width: 350px;" role="menu">
37
- <li class="px-3 py-1 d-flex flex-column gap-2">
38
- <input type="text" class="form-control" component="tag/filter/search" placeholder="[[search:type-a-tag]]">
39
- <div component="tag/filter/selected" class="d-flex flex-wrap gap-2">
40
- {{{ each tagFilterSelected }}}
41
- <div class="d-flex px-2 py-1 rounded-1 text-bg-primary gap-2 align-items-center text-sm">
42
- <div>{./valueEscaped}</div>
43
- <button component="tag/filter/delete" data-tag="{./valueEscaped}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
44
- </div>
45
- {{{ end }}}
46
- </div>
47
- <hr/>
48
- <div component="tag/filter/results" class="d-flex flex-wrap gap-2">
49
- {{{ each tagFilterResults }}}
50
- <button class="btn btn-light btn-sm border" data-tag="{./valueEscaped}">{./valueEscaped}</button>
51
- {{{ end }}}
52
- </div>
53
- </li>
54
- </ul>
55
- </div>
56
- </div>
57
-
58
- <!-- user name filter -->
59
- <div class="post-search-item">
60
- <div component="user/filter" class="dropdown" data-filter-name="user">
61
- <a component="user/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.users.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
62
- <span class="filter-label">{{{ if filters.users.active }}}{filters.users.label}{{{ else }}}[[search:posted-by]]{{{ end }}}</span>
63
- <span class="caret text-primary opacity-75"></span>
64
- </a>
65
-
66
- <ul class="dropdown-menu p-1 text-sm" style="width: 350px;" role="menu">
67
- <li class="px-3 py-1 d-flex flex-column gap-2">
68
- <input type="text" class="form-control" component="user/filter/search" placeholder="[[search:type-a-username]]">
69
- <div component="user/filter/selected" class="d-flex flex-wrap gap-2">
70
- {{{ each userFilterSelected }}}
71
- <div class="d-flex px-2 py-1 rounded-1 text-bg-primary gap-2 align-items-center text-sm">
72
- {buildAvatar(@value, "16px", true)} {./username}
73
- <button component="user/filter/delete" data-uid="{./uid}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
74
- </div>
75
- {{{ end }}}
76
- </div>
77
- <hr/>
78
- <div component="user/filter/results" class="d-flex flex-wrap gap-2">
79
- {{{ each userFilterResults }}}
80
- <button class="btn btn-light btn-sm border" data-uid="{./uid}" data-username="{./username}">{buildAvatar(@value, "16px", true)} {./username}</button>
81
- {{{ end }}}
82
- </div>
83
- </li>
84
- </ul>
85
- </div>
86
- </div>
87
-
88
-
89
- <!-- reply count filter -->
90
- <div class="post-search-item">
91
- <div class="dropdown" data-filter-name="replies">
92
- <a id="reply-count-button" class="filter-btn btn btn-light btn-sm border {{{ if filters.replies.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
93
- <span class="filter-label">{{{ if filters.replies.active }}}{filters.replies.label}{{{ else }}}[[search:replies]]{{{ end }}}</span>
94
- <span class="caret text-primary opacity-75"></span>
95
- </a>
96
-
97
- <ul class="dropdown-menu p-1 text-sm" style="width: 300px;" role="menu">
98
- <li class="px-3 py-1 d-flex flex-nowrap gap-2">
99
- <select id="reply-count-filter" class="form-select py-2 ps-2 pe-3">
100
- <option value="atleast">[[search:at-least]]</option>
101
- <option value="atmost">[[search:at-most]]</option>
102
- </select>
103
- <input id="reply-count" type="number" min="0" class="form-control py-2 ps-2 pe-3" />
104
- </li>
105
- </ul>
106
- </div>
107
- </div>
108
-
109
- <!-- time filter -->
110
- <div class="post-search-item">
111
- <div class="dropdown" data-filter-name="time">
112
- <a id="post-time-button" class="filter-btn btn btn-light btn-sm border {{{ if filters.time.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
113
- <span class="filter-label">{{{ if filters.time.active }}}{filters.time.label}{{{ else }}}[[search:time]]{{{ end }}}</span>
114
- <span class="caret text-primary opacity-75"></span>
115
- </a>
116
-
117
- <ul class="dropdown-menu p-1 text-sm" style="width: 350px;" role="menu">
118
- <li class="px-3 py-1 d-flex flex-nowrap gap-2">
119
- <select id="post-time-filter" class="form-select py-2 ps-2 pe-3">
120
- <option value="newer">[[search:newer-than]]</option>
121
- <option value="older">[[search:older-than]]</option>
122
- </select>
123
- <select id="post-time-range" class="form-select py-2 ps-2 pe-3">
124
- <option value="">[[search:any-date]]</option>
125
- <option value="86400">[[search:yesterday]]</option>
126
- <option value="604800">[[search:one-week]]</option>
127
- <option value="1209600">[[search:two-weeks]]</option>
128
- <option value="2592000">[[search:one-month]]</option>
129
- <option value="7776000">[[search:three-months]]</option>
130
- <option value="15552000">[[search:six-months]]</option>
131
- <option value="31104000">[[search:one-year]]</option>
132
- </select>
133
- </li>
134
- </ul>
135
- </div>
136
- </div>
137
-
138
- <!-- sort filter -->
139
- <div class="post-search-item">
140
- <div class="dropdown" data-filter-name="sort">
141
- <a id="sort-by-button" class="filter-btn btn btn-light btn-sm border {{{ if filters.sort.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
142
- <span class="filter-label">{{{ if filters.sort.active }}}{filters.sort.label}{{{ else }}}[[search:sort]]{{{ end }}}</span>
143
- <span class="caret text-primary opacity-75"></span>
144
- </a>
145
-
146
- <ul class="dropdown-menu p-1 text-sm" style="width: 250px;" role="menu">
147
- <li class="px-3 py-1 d-flex flex-column gap-2">
148
- <select id="post-sort-by" class="form-select py-2 ps-2 pe-3">
149
- <option value="relevance">[[search:relevance]]</option>
150
- <option value="timestamp">[[search:post-time]]</option>
151
- <option value="votes">[[search:votes]]</option>
152
- <option value="topic.lastposttime">[[search:last-reply-time]]</option>
153
- <option value="topic.title">[[search:topic-title]]</option>
154
- <option value="topic.postcount">[[search:number-of-replies]]</option>
155
- <option value="topic.viewcount">[[search:number-of-views]]</option>
156
- <option value="topic.votes">[[search:topic-votes]]</option>
157
- <option value="topic.timestamp">[[search:topic-start-date]]</option>
158
- <option value="user.username">[[search:username]]</option>
159
- <option value="category.name">[[search:category]]</option>
160
- </select>
161
- <select id="post-sort-direction" class="form-select py-2 ps-2 pe-3">
162
- <option value="desc">[[search:descending]]</option>
163
- <option value="asc">[[search:ascending]]</option>
164
- </select>
165
- </li>
166
- </ul>
167
- </div>
168
- </div>
169
-
170
- <!-- save & reset preferences -->
171
- <div class="post-search-item">
172
- <div class="dropdown">
173
- <a class="btn btn-light btn-sm border border-gray-300 dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">[[search:save]] <span class="caret text-primary opacity-75"></span>
174
- </a>
175
-
176
- <ul class="dropdown-menu p-1 text-sm" style="width: 300px;" role="menu">
177
- <li class="px-3 py-1 d-flex flex-column gap-2">
178
- <button id="save-preferences" class="btn btn-primary">[[search:save-preferences]]</button>
179
- <button id="clear-preferences" class="btn btn-ghost border">[[search:clear-preferences]]</button>
180
- </li>
181
- </ul>
182
- </div>
183
- </div>
1
+ <div class="d-flex flex-wrap gap-2 align-items-center" component="search/filters">
2
+ <!-- category filter -->
3
+ <div class="post-search-item">
4
+ <div component="category/filter" class="dropdown" data-filter-name="category">
5
+ <a component="category/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.categories.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
6
+ <span class="filter-label">{{{ if filters.categories.active }}}{filters.categories.label}{{{ else }}}[[search:categories]]{{{ end }}}</span>
7
+ <span class="caret text-primary opacity-75"></span>
8
+ </a>
9
+
10
+ <ul class="dropdown-menu p-1 text-sm" role="menu">
11
+ <li class="px-3 py-1 mb-2 d-flex flex-column gap-2">
12
+ <div component="category-selector-search">
13
+ <input type="text" class="form-control" component="category/filter/search" placeholder="[[search:type-a-category]]">
14
+ </div>
15
+ </li>
16
+ <div component="category/list" class="overflow-auto ghost-scrollbar" style="max-height: 350px;"></div>
17
+ <div class="px-3 py-1">
18
+ <div class="form-check">
19
+ <input id="search-children" class="form-check-input" type="checkbox"/>
20
+ <label class="form-check-label" for="search-children">[[search:search-child-categories]]</label>
21
+ </div>
22
+ </div>
23
+ </ul>
24
+ </div>
25
+ </div>
26
+
27
+
28
+ <!-- tag filter -->
29
+ <div class="post-search-item">
30
+ <div component="tag/filter" class="dropdown" data-filter-name="tag">
31
+ <a component="tag/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.tags.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
32
+ <span class="filter-label">{{{ if filters.tags.active }}}{filters.tags.label}{{{ else }}}[[search:tags]]{{{ end }}}</span>
33
+ <span class="caret text-primary opacity-75"></span>
34
+ </a>
35
+
36
+ <ul class="dropdown-menu p-1 text-sm" style="width: 350px;" role="menu">
37
+ <li class="px-3 py-1 d-flex flex-column gap-2">
38
+ <input type="text" class="form-control" component="tag/filter/search" placeholder="[[search:type-a-tag]]">
39
+ <div component="tag/filter/selected" class="d-flex flex-wrap gap-2">
40
+ {{{ each tagFilterSelected }}}
41
+ <div class="d-flex px-2 py-1 rounded-1 text-bg-primary gap-2 align-items-center text-sm">
42
+ <div>{./valueEscaped}</div>
43
+ <button component="tag/filter/delete" data-tag="{./valueEscaped}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
44
+ </div>
45
+ {{{ end }}}
46
+ </div>
47
+ <hr/>
48
+ <div component="tag/filter/results" class="d-flex flex-wrap gap-2">
49
+ {{{ each tagFilterResults }}}
50
+ <button class="btn btn-light btn-sm border" data-tag="{./valueEscaped}">{./valueEscaped}</button>
51
+ {{{ end }}}
52
+ </div>
53
+ </li>
54
+ </ul>
55
+ </div>
56
+ </div>
57
+
58
+ <!-- user name filter -->
59
+ <div class="post-search-item">
60
+ <div component="user/filter" class="dropdown" data-filter-name="user">
61
+ <a component="user/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.users.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
62
+ <span class="filter-label">{{{ if filters.users.active }}}{filters.users.label}{{{ else }}}[[search:posted-by]]{{{ end }}}</span>
63
+ <span class="caret text-primary opacity-75"></span>
64
+ </a>
65
+
66
+ <ul class="dropdown-menu p-1 text-sm" style="width: 350px;" role="menu">
67
+ <li class="px-3 py-1 d-flex flex-column gap-2">
68
+ <input type="text" class="form-control" component="user/filter/search" placeholder="[[search:type-a-username]]">
69
+ <div component="user/filter/selected" class="d-flex flex-wrap gap-2">
70
+ {{{ each userFilterSelected }}}
71
+ <div class="d-flex px-2 py-1 rounded-1 text-bg-primary gap-2 align-items-center text-sm">
72
+ {buildAvatar(@value, "16px", true)} {./username}
73
+ <button component="user/filter/delete" data-uid="{./uid}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
74
+ </div>
75
+ {{{ end }}}
76
+ </div>
77
+ <hr/>
78
+ <div component="user/filter/results" class="d-flex flex-wrap gap-2">
79
+ {{{ each userFilterResults }}}
80
+ <button class="btn btn-light btn-sm border" data-uid="{./uid}" data-username="{./username}">{buildAvatar(@value, "16px", true)} {./username}</button>
81
+ {{{ end }}}
82
+ </div>
83
+ </li>
84
+ </ul>
85
+ </div>
86
+ </div>
87
+
88
+
89
+ <!-- reply count filter -->
90
+ <div class="post-search-item">
91
+ <div class="dropdown" data-filter-name="replies">
92
+ <a id="reply-count-button" class="filter-btn btn btn-light btn-sm border {{{ if filters.replies.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
93
+ <span class="filter-label">{{{ if filters.replies.active }}}{filters.replies.label}{{{ else }}}[[search:replies]]{{{ end }}}</span>
94
+ <span class="caret text-primary opacity-75"></span>
95
+ </a>
96
+
97
+ <ul class="dropdown-menu p-1 text-sm" style="width: 300px;" role="menu">
98
+ <li class="px-3 py-1 d-flex flex-nowrap gap-2">
99
+ <select id="reply-count-filter" class="form-select py-2 ps-2 pe-3">
100
+ <option value="atleast">[[search:at-least]]</option>
101
+ <option value="atmost">[[search:at-most]]</option>
102
+ </select>
103
+ <input id="reply-count" type="number" min="0" class="form-control py-2 ps-2 pe-3" />
104
+ </li>
105
+ </ul>
106
+ </div>
107
+ </div>
108
+
109
+ <!-- time filter -->
110
+ <div class="post-search-item">
111
+ <div class="dropdown" data-filter-name="time">
112
+ <a id="post-time-button" class="filter-btn btn btn-light btn-sm border {{{ if filters.time.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
113
+ <span class="filter-label">{{{ if filters.time.active }}}{filters.time.label}{{{ else }}}[[search:time]]{{{ end }}}</span>
114
+ <span class="caret text-primary opacity-75"></span>
115
+ </a>
116
+
117
+ <ul class="dropdown-menu p-1 text-sm" style="width: 350px;" role="menu">
118
+ <li class="px-3 py-1 d-flex flex-nowrap gap-2">
119
+ <select id="post-time-filter" class="form-select py-2 ps-2 pe-3">
120
+ <option value="newer">[[search:newer-than]]</option>
121
+ <option value="older">[[search:older-than]]</option>
122
+ </select>
123
+ <select id="post-time-range" class="form-select py-2 ps-2 pe-3">
124
+ <option value="">[[search:any-date]]</option>
125
+ <option value="86400">[[search:yesterday]]</option>
126
+ <option value="604800">[[search:one-week]]</option>
127
+ <option value="1209600">[[search:two-weeks]]</option>
128
+ <option value="2592000">[[search:one-month]]</option>
129
+ <option value="7776000">[[search:three-months]]</option>
130
+ <option value="15552000">[[search:six-months]]</option>
131
+ <option value="31104000">[[search:one-year]]</option>
132
+ </select>
133
+ </li>
134
+ </ul>
135
+ </div>
136
+ </div>
137
+
138
+ <!-- sort filter -->
139
+ <div class="post-search-item">
140
+ <div class="dropdown" data-filter-name="sort">
141
+ <a id="sort-by-button" class="filter-btn btn btn-light btn-sm border {{{ if filters.sort.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
142
+ <span class="filter-label">{{{ if filters.sort.active }}}{filters.sort.label}{{{ else }}}[[search:sort]]{{{ end }}}</span>
143
+ <span class="caret text-primary opacity-75"></span>
144
+ </a>
145
+
146
+ <ul class="dropdown-menu p-1 text-sm" style="width: 250px;" role="menu">
147
+ <li class="px-3 py-1 d-flex flex-column gap-2">
148
+ <select id="post-sort-by" class="form-select py-2 ps-2 pe-3">
149
+ <option value="relevance">[[search:relevance]]</option>
150
+ <option value="timestamp">[[search:post-time]]</option>
151
+ <option value="votes">[[search:votes]]</option>
152
+ <option value="topic.lastposttime">[[search:last-reply-time]]</option>
153
+ <option value="topic.title">[[search:topic-title]]</option>
154
+ <option value="topic.postcount">[[search:number-of-replies]]</option>
155
+ <option value="topic.viewcount">[[search:number-of-views]]</option>
156
+ <option value="topic.votes">[[search:topic-votes]]</option>
157
+ <option value="topic.timestamp">[[search:topic-start-date]]</option>
158
+ <option value="user.username">[[search:username]]</option>
159
+ <option value="category.name">[[search:category]]</option>
160
+ </select>
161
+ <select id="post-sort-direction" class="form-select py-2 ps-2 pe-3">
162
+ <option value="desc">[[search:descending]]</option>
163
+ <option value="asc">[[search:ascending]]</option>
164
+ </select>
165
+ </li>
166
+ </ul>
167
+ </div>
168
+ </div>
169
+
170
+ <!-- save & reset preferences -->
171
+ <div class="post-search-item">
172
+ <div class="dropdown">
173
+ <a class="btn btn-light btn-sm border border-gray-300 dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">[[search:save]] <span class="caret text-primary opacity-75"></span>
174
+ </a>
175
+
176
+ <ul class="dropdown-menu p-1 text-sm" style="width: 300px;" role="menu">
177
+ <li class="px-3 py-1 d-flex flex-column gap-2">
178
+ <button id="save-preferences" class="btn btn-primary">[[search:save-preferences]]</button>
179
+ <button id="clear-preferences" class="btn btn-ghost border">[[search:clear-preferences]]</button>
180
+ </li>
181
+ </ul>
182
+ </div>
183
+ </div>
184
184
  </div>
@@ -1,55 +1,55 @@
1
- {{{ if matchCount }}}
2
- <div class="card card-header text-xs px-2 py-1 fw-semibold border-0 align-self-start">[[search:results-matching, {matchCount}, {search_query}, {time}]] </div>
3
- {{{ else }}}
4
- {{{ if search_query }}}
5
- <div class="badge text-bg-warning align-self-start">[[search:no-matches]]</div>
6
- {{{ end }}}
7
- {{{ end }}}
8
-
9
- <div id="results" class="search-results" data-search-query="{search_query}">
10
- {{{ if showAsPosts }}}
11
- {{{ if posts.length }}}
12
- <!-- IMPORT partials/posts_list.tpl -->
13
- {{{ end }}}
14
- {{{ end }}}
15
-
16
- {{{ if showAsTopics }}}
17
- {{{ each posts }}}
18
- <hr/>
19
- <div class="topic-row mb-3">
20
- <a class="topic-title fw-semibold fs-5 text-reset text-break" href="{config.relative_path}/post/{encodeURIComponent(./pid)}">
21
- {{{ if !./isMainPost }}}RE: {{{ end }}}{./topic.title}
22
- </a>
23
- <div class="post-body d-flex flex-column gap-1">
24
- <div class="d-flex gap-3 post-info">
25
- <div class="post-author d-flex gap-1">
26
- <a class="lh-1 text-decoration-none" href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(./user, "16px", true, "not-responsive")}</a>
27
- <a class="fw-semibold text-sm" href="{config.relative_path}/user/{./user.userslug}">{../user.displayname}</a>
28
- </div>
29
- <span class="timeago text-sm text-muted" title="{./timestampISO}"></span>
30
- </div>
31
- </div>
32
- </div>
33
- {{{ end }}}
34
- {{{ end }}}
35
-
36
- {{{ if users.length }}}
37
- <!-- IMPORT partials/users_list.tpl -->
38
- {{{ end }}}
39
-
40
- {{{ if tags.length }}}
41
- <div class="tag-list row row-cols-2 row-cols-lg-3 row-cols-xl-4 gx-3 gy-2">
42
- <!-- IMPORT partials/tags_list.tpl -->
43
- </div>
44
- {{{ end }}}
45
-
46
- {{{ if categories.length }}}
47
- <ul class="categories list-unstyled">
48
- {{{each categories}}}
49
- <!-- IMPORT partials/categories/item.tpl -->
50
- {{{end}}}
51
- </ul>
52
- {{{ end }}}
53
-
54
- <!-- IMPORT partials/paginator.tpl -->
1
+ {{{ if matchCount }}}
2
+ <div class="card card-header text-xs px-2 py-1 fw-semibold border-0 align-self-start">[[search:results-matching, {matchCount}, {search_query}, {time}]] </div>
3
+ {{{ else }}}
4
+ {{{ if search_query }}}
5
+ <div class="badge text-bg-warning align-self-start">[[search:no-matches]]</div>
6
+ {{{ end }}}
7
+ {{{ end }}}
8
+
9
+ <div id="results" class="search-results" data-search-query="{search_query}">
10
+ {{{ if showAsPosts }}}
11
+ {{{ if posts.length }}}
12
+ <!-- IMPORT partials/posts_list.tpl -->
13
+ {{{ end }}}
14
+ {{{ end }}}
15
+
16
+ {{{ if showAsTopics }}}
17
+ {{{ each posts }}}
18
+ <hr/>
19
+ <div class="topic-row mb-3">
20
+ <a class="topic-title fw-semibold fs-5 text-reset text-break" href="{config.relative_path}/post/{encodeURIComponent(./pid)}">
21
+ {{{ if !./isMainPost }}}RE: {{{ end }}}{./topic.title}
22
+ </a>
23
+ <div class="post-body d-flex flex-column gap-1">
24
+ <div class="d-flex gap-3 post-info">
25
+ <div class="post-author d-flex gap-1">
26
+ <a class="lh-1 text-decoration-none" href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(./user, "16px", true, "not-responsive")}</a>
27
+ <a class="fw-semibold text-sm" href="{config.relative_path}/user/{./user.userslug}">{../user.displayname}</a>
28
+ </div>
29
+ <span class="timeago text-sm text-muted" title="{./timestampISO}"></span>
30
+ </div>
31
+ </div>
32
+ </div>
33
+ {{{ end }}}
34
+ {{{ end }}}
35
+
36
+ {{{ if users.length }}}
37
+ <!-- IMPORT partials/users_list.tpl -->
38
+ {{{ end }}}
39
+
40
+ {{{ if tags.length }}}
41
+ <div class="tag-list row row-cols-2 row-cols-lg-3 row-cols-xl-4 gx-3 gy-2">
42
+ <!-- IMPORT partials/tags_list.tpl -->
43
+ </div>
44
+ {{{ end }}}
45
+
46
+ {{{ if categories.length }}}
47
+ <ul class="categories list-unstyled">
48
+ {{{each categories}}}
49
+ <!-- IMPORT partials/categories/item.tpl -->
50
+ {{{end}}}
51
+ </ul>
52
+ {{{ end }}}
53
+
54
+ <!-- IMPORT partials/paginator.tpl -->
55
55
  </div>
@@ -1,45 +1,45 @@
1
- <a data-bs-toggle="dropdown" href="#" role="button" class="nav-link d-flex gap-2 justify-content-between align-items-center position-relative" component="chat/dropdown" aria-haspopup="true" aria-expanded="false" aria-label="[[global:header.chats]]">
2
- <span class="d-flex gap-2 align-items-center text-nowrap truncate-open">
3
- <span class="position-relative">
4
- <i component="chat/icon" class="fa fa-fw {{{ if unreadCount.chat}}}fa-comment{{{ else }}}fa-comment-o{{{ end }}} unread-count" data-content="{unreadCount.chat}"></i>
5
- <span component="chat/count" class="visible-closed position-absolute top-0 start-100 translate-middle badge rounded-1 bg-primary {{{ if !unreadCount.chat }}}hidden{{{ end }}}">{unreadCount.chat}</span>
6
- </span>
7
- <span class="nav-text small visible-open fw-semibold">[[global:header.chats]]</span>
8
- </span>
9
- <span component="chat/count" class="visible-open badge rounded-1 bg-primary {{{ if !unreadCount.chat }}}hidden{{{ end }}}">{unreadCount.chat}</span>
10
- </a>
11
- <ul class="chats-dropdown dropdown-menu p-1 shadow" role="menu">
12
- <li>
13
- <div component="chat/list" class="list-container chats-list overscroll-behavior-contain p-0 pe-1 ff-base ghost-scrollbar">
14
- <div class="rounded-1">
15
- <div class="d-flex gap-1 justify-content-between">
16
- <div class="dropdown-item p-2 d-flex gap-2 placeholder-wave">
17
- <div class="main-avatar">
18
- <div class="placeholder" style="width: 32px; height: 32px;"></div>
19
- </div>
20
- <div class="d-flex flex-grow-1 flex-column w-100">
21
- <div class="text-xs"><div class="placeholder col-3"></div></div>
22
- <div class="text-sm"><div class="placeholder col-11"></div></div>
23
- <div class="text-xs"><div class="placeholder col-4"></div></div>
24
- </div>
25
- </div>
26
- <div>
27
- <button class="mark-read btn btn-ghost btn-sm d-flex align-items-center justify-content-center flex-grow-0 flex-shrink-0 p-1" style="width: 1.5rem; height: 1.5rem;">
28
- <i class="unread fa fa-2xs fa-circle text-primary"></i>
29
- </button>
30
- </div>
31
- </div>
32
- </div>
33
- </div>
34
- </li>
35
- <li class="dropdown-divider"></li>
36
- <li>
37
- <div class="d-flex justify-content-center gap-1 flex-wrap">
38
- <a component="chats/mark-all-read" role="button" href="#" class="btn btn-sm btn-light mark-all-read flex-fill text-nowrap text-truncate ff-secondary"><i class="fa fa-check-double"></i> [[modules:chat.mark-all-read]]</a>
39
- <!-- on md and up see all chats button goes to last room -->
40
- <a class="d-none d-md-inline btn btn-sm btn-primary flex-fill text-nowrap text-truncate ff-secondary" href="{relative_path}/user/{user.userslug}/chats{{{ if user.lastRoomId }}}/{user.lastRoomId}{{{ end }}}"><i class="fa fa-list"></i> [[modules:chat.see-all]]</a>
41
- <!-- on xs&sm the see all chats button goes to the list of chats -->
42
- <a class="d-inline d-md-none btn btn-sm btn-primary flex-fill text-nowrap text-truncate ff-secondary" href="{relative_path}/user/{user.userslug}/chats"><i class="fa fa-list"></i> [[modules:chat.see-all]]</a>
43
- </div>
44
- </li>
45
- </ul>
1
+ <a data-bs-toggle="dropdown" href="#" role="button" class="nav-link d-flex gap-2 justify-content-between align-items-center position-relative" component="chat/dropdown" aria-haspopup="true" aria-expanded="false" aria-label="[[global:header.chats]]">
2
+ <span class="d-flex gap-2 align-items-center text-nowrap truncate-open">
3
+ <span class="position-relative">
4
+ <i component="chat/icon" class="fa fa-fw {{{ if unreadCount.chat}}}fa-comment{{{ else }}}fa-comment-o{{{ end }}} unread-count" data-content="{unreadCount.chat}"></i>
5
+ <span component="chat/count" class="visible-closed position-absolute top-0 start-100 translate-middle badge rounded-1 bg-primary {{{ if !unreadCount.chat }}}hidden{{{ end }}}">{unreadCount.chat}</span>
6
+ </span>
7
+ <span class="nav-text small visible-open fw-semibold">[[global:header.chats]]</span>
8
+ </span>
9
+ <span component="chat/count" class="visible-open badge rounded-1 bg-primary {{{ if !unreadCount.chat }}}hidden{{{ end }}}">{unreadCount.chat}</span>
10
+ </a>
11
+ <ul class="chats-dropdown dropdown-menu p-1 shadow" role="menu">
12
+ <li>
13
+ <div component="chat/list" class="list-container chats-list overscroll-behavior-contain p-0 pe-1 ff-base ghost-scrollbar">
14
+ <div class="rounded-1">
15
+ <div class="d-flex gap-1 justify-content-between">
16
+ <div class="dropdown-item p-2 d-flex gap-2 placeholder-wave">
17
+ <div class="main-avatar">
18
+ <div class="placeholder" style="width: 32px; height: 32px;"></div>
19
+ </div>
20
+ <div class="d-flex flex-grow-1 flex-column w-100">
21
+ <div class="text-xs"><div class="placeholder col-3"></div></div>
22
+ <div class="text-sm"><div class="placeholder col-11"></div></div>
23
+ <div class="text-xs"><div class="placeholder col-4"></div></div>
24
+ </div>
25
+ </div>
26
+ <div>
27
+ <button class="mark-read btn btn-ghost btn-sm d-flex align-items-center justify-content-center flex-grow-0 flex-shrink-0 p-1" style="width: 1.5rem; height: 1.5rem;">
28
+ <i class="unread fa fa-2xs fa-circle text-primary"></i>
29
+ </button>
30
+ </div>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ </li>
35
+ <li class="dropdown-divider"></li>
36
+ <li>
37
+ <div class="d-flex justify-content-center gap-1 flex-wrap">
38
+ <a component="chats/mark-all-read" role="button" href="#" class="btn btn-sm btn-light mark-all-read flex-fill text-nowrap text-truncate ff-secondary"><i class="fa fa-check-double"></i> [[modules:chat.mark-all-read]]</a>
39
+ <!-- on md and up see all chats button goes to last room -->
40
+ <a class="d-none d-md-inline btn btn-sm btn-primary flex-fill text-nowrap text-truncate ff-secondary" href="{relative_path}/user/{user.userslug}/chats{{{ if user.lastRoomId }}}/{user.lastRoomId}{{{ end }}}"><i class="fa fa-list"></i> [[modules:chat.see-all]]</a>
41
+ <!-- on xs&sm the see all chats button goes to the list of chats -->
42
+ <a class="d-inline d-md-none btn btn-sm btn-primary flex-fill text-nowrap text-truncate ff-secondary" href="{relative_path}/user/{user.userslug}/chats"><i class="fa fa-list"></i> [[modules:chat.see-all]]</a>
43
+ </div>
44
+ </li>
45
+ </ul>