nodebb-theme-harmony 2.0.0-pre.9 → 2.0.0

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 (94) hide show
  1. package/README.md +3 -0
  2. package/library.js +1 -7
  3. package/package-lock.json +372 -402
  4. package/package.json +2 -2
  5. package/plugin.json +1 -2
  6. package/public/harmony.js +15 -15
  7. package/scss/common.scss +2 -8
  8. package/scss/harmony.scss +0 -1
  9. package/scss/header.scss +1 -1
  10. package/scss/mixins.scss +12 -5
  11. package/scss/modules/cover.scss +2 -4
  12. package/scss/modules/topics-list.scss +1 -1
  13. package/scss/overrides.scss +4 -0
  14. package/scss/sidebar.scss +18 -19
  15. package/scss/skins.scss +9 -0
  16. package/scss/topic.scss +4 -12
  17. package/templates/account/blocks.tpl +18 -7
  18. package/templates/account/categories.tpl +1 -1
  19. package/templates/account/consent.tpl +2 -2
  20. package/templates/account/edit/password.tpl +8 -8
  21. package/templates/account/edit/username.tpl +2 -3
  22. package/templates/account/edit.tpl +30 -15
  23. package/templates/account/info.tpl +142 -73
  24. package/templates/account/posts.tpl +7 -7
  25. package/templates/account/profile.tpl +19 -22
  26. package/templates/account/read.tpl +1 -0
  27. package/templates/account/settings.tpl +5 -5
  28. package/templates/account/shares.tpl +20 -0
  29. package/templates/account/topics.tpl +6 -5
  30. package/templates/admin/plugins/harmony.tpl +1 -0
  31. package/templates/footer.tpl +1 -1
  32. package/templates/groups/list.tpl +9 -7
  33. package/templates/notifications.tpl +1 -1
  34. package/templates/partials/account/header.tpl +15 -15
  35. package/templates/partials/account/sidebar-left.tpl +30 -16
  36. package/templates/partials/breadcrumbs-json-ld.tpl +15 -25
  37. package/templates/partials/categories/item.tpl +8 -8
  38. package/templates/partials/categories/lastpost.tpl +1 -1
  39. package/templates/partials/category/subcategory.tpl +1 -1
  40. package/templates/partials/groups/list.tpl +1 -1
  41. package/templates/partials/groups/memberlist.tpl +1 -1
  42. package/templates/partials/groups/sidebar-left.tpl +8 -8
  43. package/templates/partials/header/brand.tpl +3 -1
  44. package/templates/partials/mobile-footer.tpl +3 -6
  45. package/templates/partials/notifications_list.tpl +2 -2
  46. package/templates/partials/post_bar.tpl +3 -5
  47. package/templates/partials/posts_list_item.tpl +1 -1
  48. package/templates/partials/quick-search-results.tpl +5 -5
  49. package/templates/partials/search-filters.tpl +1 -1
  50. package/templates/partials/search-results.tpl +1 -1
  51. package/templates/partials/sidebar/chats.tpl +1 -1
  52. package/templates/partials/sidebar/notifications.tpl +1 -1
  53. package/templates/partials/sidebar/search.tpl +2 -2
  54. package/templates/partials/sidebar-left.tpl +2 -5
  55. package/templates/partials/tags_list.tpl +6 -4
  56. package/templates/partials/topic/event.tpl +1 -1
  57. package/templates/partials/topic/navigator.tpl +2 -2
  58. package/templates/partials/topic/post-menu-list.tpl +20 -4
  59. package/templates/partials/topic/post-menu.tpl +3 -29
  60. package/templates/partials/topic/post.tpl +108 -101
  61. package/templates/partials/topic/quickreply.tpl +2 -2
  62. package/templates/partials/topic/reply-button.tpl +4 -2
  63. package/templates/partials/topic/sort.tpl +1 -1
  64. package/templates/partials/topic/thumbs.tpl +1 -1
  65. package/templates/partials/topic/tools.tpl +2 -6
  66. package/templates/partials/topic/watch.tpl +1 -1
  67. package/templates/partials/topic-filters.tpl +1 -1
  68. package/templates/partials/topic-list-bar.tpl +6 -6
  69. package/templates/partials/topic-terms.tpl +1 -1
  70. package/templates/partials/topics_list.tpl +12 -4
  71. package/templates/partials/users/item.tpl +33 -31
  72. package/templates/partials/users_list_menu.tpl +5 -5
  73. package/templates/post-queue.tpl +6 -2
  74. package/templates/recent.tpl +7 -0
  75. package/templates/topic.tpl +81 -88
  76. package/templates/users.tpl +2 -2
  77. package/templates/world.tpl +32 -1
  78. package/scss/modules/bottom-sheet.scss +0 -52
  79. package/templates/flags/detail.tpl +0 -179
  80. package/templates/flags/list.tpl +0 -6
  81. package/templates/login.tpl +0 -102
  82. package/templates/partials/category/filter-dropdown-content.tpl +0 -41
  83. package/templates/partials/category/selector-dropdown-content.tpl +0 -39
  84. package/templates/partials/category/sort.tpl +0 -39
  85. package/templates/partials/category/tools.tpl +0 -89
  86. package/templates/partials/category/watch.tpl +0 -67
  87. package/templates/partials/flags/bulk-actions.tpl +0 -9
  88. package/templates/partials/flags/filters.tpl +0 -189
  89. package/templates/partials/flags/results.tpl +0 -38
  90. package/templates/partials/groups/filter-dropdown-content.tpl +0 -25
  91. package/templates/partials/tags/filter-dropdown-content.tpl +0 -38
  92. package/templates/partials/tags/watch.tpl +0 -42
  93. package/templates/partials/users/filter-dropdown-content.tpl +0 -23
  94. package/templates/register.tpl +0 -104
@@ -2,7 +2,7 @@
2
2
  <div class="d-flex justify-content-end sticky-top mt-4" style="top:6rem;z-index:1;">
3
3
  <div class="ps-1 ps-md-0 d-inline-block">
4
4
  <div class="scroller-content d-flex gap-2 flex-column align-items-start">
5
- <div class="pointer pagetop btn-ghost-sm ff-secondary d-inline-flex" style="padding: 4px;"><i class="fa fa-chevron-up"></i> <span class="timeago text-xs text-muted text-nowrap" title="{./timestampISO}"></span></div>
5
+ <button class="pagetop btn btn-ghost btn-sm ff-secondary d-inline-flex border-0 align-items-center gap-2" style="padding: 4px;"><i class="fa fa-chevron-up"></i> <span class="timeago text-xs text-muted text-nowrap" title="{./timestampISO}"></span></button>
6
6
  <div class="scroller-container position-relative">
7
7
  <div class="scroller-thumb d-flex gap-2 text-nowrap position-relative" style="height: 40px;">
8
8
  <div class="scroller-thumb-icon bg-primary rounded d-inline-block" style="width:9px; height: 40px;"></div>
@@ -18,7 +18,7 @@
18
18
  </div>
19
19
  </div>
20
20
  </div>
21
- <div class="pointer pagebottom btn-ghost-sm ff-secondary d-inline-flex" style="padding: 4px;"><i class="fa fa-chevron-down"></i> <span class="timeago text-xs text-muted text-nowrap" title="{./lastposttimeISO}"></span></div>
21
+ <button class="pagebottom btn btn-ghost btn-sm ff-secondary d-inline-flex border-0 align-items-center gap-2" style="padding: 4px;"><i class="fa fa-chevron-down"></i> <span class="timeago text-xs text-muted text-nowrap" title="{./lastposttimeISO}"></span></button>
22
22
  </div>
23
23
  </div>
24
24
  </div>
@@ -4,6 +4,7 @@
4
4
  <span class="menu-icon"><i class="fa fa-fw text-secondary fa-pencil"></i></span> [[topic:edit]]
5
5
  </a>
6
6
  </li>
7
+ {{{ if posts.display_delete_tools }}}
7
8
  <li {{{ if posts.deleted }}}hidden{{{ end }}}>
8
9
  <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" component="post/delete" role="menuitem" href="#" class="{{{ if posts.deleted }}}hidden{{{ end }}}">
9
10
  <span class="menu-icon"><i class="fa fa-fw text-secondary fa-trash-o"></i></span> [[topic:delete]]
@@ -14,6 +15,7 @@
14
15
  <span class="menu-icon"><i class="fa fa-fw text-secondary fa-history"></i></span> [[topic:restore]]
15
16
  </a>
16
17
  </li>
18
+ {{{ end }}}
17
19
  {{{ if posts.display_purge_tools }}}
18
20
  <li {{{ if !posts.deleted }}}hidden{{{ end }}}>
19
21
  <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" component="post/purge" role="menuitem" href="#" class="{{{ if !posts.deleted }}}hidden{{{ end }}}">
@@ -38,6 +40,14 @@
38
40
  </li>
39
41
  {{{ end }}}
40
42
 
43
+ {{{ if posts.display_manage_editors_tools }}}
44
+ <li>
45
+ <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" component="post/manage-editors" role="menuitem" href="#">
46
+ <span class="menu-icon"><i class="fa fa-fw text-secondary fa-user-pen"></i></span> [[topic:manage-editors]]
47
+ </a>
48
+ </li>
49
+ {{{ end }}}
50
+
41
51
  {{{ if posts.ip }}}
42
52
  <li>
43
53
  <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" component="post/copy-ip" role="menuitem" href="#" data-clipboard-text="{posts.ip}">
@@ -84,15 +94,21 @@
84
94
  </li>
85
95
  {{{ end }}}
86
96
 
97
+
98
+ {{{ if !posts.display_original_url }}}
87
99
  <li>
88
100
  <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" role="menuitem" href="#" data-clipboard-text="{posts.absolute_url}">
89
101
  <i class="fa fa-fw text-secondary fa-link"></i> [[topic:copy-permalink]]
90
102
  </a>
91
103
  </li>
92
-
93
- {{{ if posts.display_original_url }}}
104
+ {{{ else }}}
105
+ <li>
106
+ <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" role="menuitem" href="#" data-clipboard-text="{{{ if posts.url }}}{posts.url}{{{ else }}}{posts.pid}{{{ end }}}">
107
+ <i class="fa fa-fw text-secondary fa-link"></i> [[topic:copy-permalink]]
108
+ </a>
109
+ </li>
94
110
  <li>
95
- <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" role="menuitem" href="{posts.pid}">
111
+ <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" role="menuitem" target="_self" href="{{{ if posts.url }}}{posts.url}{{{ else }}}{posts.pid}{{{ end }}}">
96
112
  <i class="fa fa-fw text-secondary fa-external-link"></i> [[topic:go-to-original]]
97
113
  </a>
98
114
  </li>
@@ -116,7 +132,7 @@
116
132
  <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" component="post/flag" role="menuitem" href="#"><i class="fa fa-fw text-secondary fa-flag"></i> [[topic:flag-post]]</a>
117
133
  </li>
118
134
  <li {{{ if !posts.flags.flagged }}}hidden{{{ end }}} class="disabled text-secondary">
119
- <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" component="post/already-flagged" role="menuitem" href="#"><i class="fa fa-fw text-secondary fa-flag"></i> [[topic:already-flagged]]</a>
135
+ <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" component="post/already-flagged" role="menuitem" href="#" data-flag-id="{posts.flagId}"><i class="fa fa-fw text-secondary fa-flag"></i> [[topic:already-flagged]]</a>
120
136
  </li>
121
137
 
122
138
  {{{ if (!posts.selfPost && posts.uid) }}}
@@ -1,30 +1,4 @@
1
- <span component="post/tools" class="dropdown moderator-tools bottom-sheet d-inline-block {{{ if !./display_post_menu }}}hidden{{{ end }}}">
2
- <a class="btn-ghost-sm ff-secondary dropdown-toggle d-block" href="#" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="[[topic:post-tools]]"><i class="fa fa-fw fa-ellipsis-v text-primary"></i></a>
3
- <ul class="dropdown-menu dropdown-menu-end p-1 text-sm" role="menu">
4
- <li class="dropdown-item placeholder-wave">
5
- <div class="placeholder" style="width: 20px;"></div>
6
- <div class="placeholder col-3"></div>
7
- </li>
8
- <li class="dropdown-item placeholder-wave">
9
- <div class="placeholder" style="width: 20px;"></div>
10
- <div class="placeholder col-5"></div>
11
- </li>
12
- <li class="dropdown-item placeholder-wave">
13
- <div class="placeholder" style="width: 20px;"></div>
14
- <div class="placeholder col-9"></div>
15
- </li>
16
- <li class="dropdown-item placeholder-wave">
17
- <div class="placeholder" style="width: 20px;"></div>
18
- <div class="placeholder col-7"></div>
19
- </li>
20
- <li class="dropdown-item placeholder-wave">
21
- <div class="placeholder" style="width: 20px;"></div>
22
- <div class="placeholder col-10"></div>
23
- </li>
24
- <li class="dropdown-divider"></li>
25
- <li class="dropdown-item placeholder-wave">
26
- <div class="placeholder" style="width: 20px;"></div>
27
- <div class="placeholder col-10"></div>
28
- </li>
29
- </ul>
1
+ <span component="post/tools" class="dropdown bottom-sheet {{{ if !./display_post_menu }}}hidden{{{ end }}}">
2
+ <a class="btn btn-ghost btn-sm ff-secondary dropdown-toggle" href="#" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="[[topic:post-tools]]"><i class="fa fa-fw fa-ellipsis-v text-primary"></i></a>
3
+ <ul class="dropdown-menu dropdown-menu-end p-1 text-sm" role="menu"></ul>
30
4
  </span>
@@ -5,129 +5,136 @@
5
5
  {{{ end }}}
6
6
  </div>
7
7
  {{{ end }}}
8
-
9
8
  <div class="d-flex align-items-start gap-3">
10
- <div class="icon bg-body d-none d-sm-block rounded-circle" style="outline: 2px solid var(--bs-body-bg);">
11
- <a class="d-inline-block position-relative text-decoration-none" href="{{{ if ./user.userslug }}}{config.relative_path}/user/{./user.userslug}{{{ else }}}#{{{ end }}}">
9
+ <div class="bg-body d-none d-sm-block rounded-circle" style="outline: 2px solid var(--bs-body-bg);">
10
+ <a class="d-inline-block position-relative text-decoration-none" href="{{{ if ./user.userslug }}}{config.relative_path}/user/{./user.userslug}{{{ else }}}#{{{ end }}}" aria-label="[[aria:profile-page-for, {./user.displayname}]]">
12
11
  {buildAvatar(posts.user, "48px", true, "", "user/picture")}
13
- <span component="user/status" class="position-absolute translate-middle-y border border-white border-2 rounded-circle status {posts.user.status}"><span class="visually-hidden">[[global:{posts.user.status}]]</span></span>
14
- </a>
15
- </div>
16
-
17
- <div class="post-container d-flex flex-grow-1 flex-column w-100" style="min-width: 0;">
18
- <div class="d-flex align-items-center gap-1 flex-wrap w-100 post-header mt-1" itemprop="author" itemscope itemtype="https://schema.org/Person">
19
- <meta itemprop="name" content="{./user.username}">
20
- {{{ if ./user.userslug }}}<meta itemprop="url" content="{config.relative_path}/user/{./user.userslug}">{{{ end }}}
21
-
22
- <div class="icon bg-body d-sm-none">
23
- <a class="d-inline-block position-relative text-decoration-none" href="{{{ if ./user.userslug }}}{config.relative_path}/user/{./user.userslug}{{{ else }}}#{{{ end }}}">
24
- {buildAvatar(posts.user, "20px", true, "", "user/picture")}
25
- <span component="user/status" class="position-absolute translate-middle-y border border-white border-2 rounded-circle status {posts.user.status}"><span class="visually-hidden">[[global:{posts.user.status}]]</span></span>
26
- </a>
27
- </div>
28
-
29
- <span class="text-nowrap">
30
- <a class="fw-bold" href="{{{ if ./user.userslug }}}{config.relative_path}/user/{./user.userslug}{{{ else }}}#{{{ end }}}" data-username="{posts.user.username}" data-uid="{posts.user.uid}">{posts.user.displayname}</a>
12
+ {{{ if ./user.isLocal }}}
13
+ <span component="user/status" class="position-absolute top-100 start-100 border border-white border-2 rounded-circle status {posts.user.status}"><span class="visually-hidden">[[global:{posts.user.status}]]</span></span>
14
+ {{{ else }}}
15
+ <span component="user/locality" class="position-absolute top-100 start-100 lh-1 border border-white border-2 rounded-circle small" title="[[global:remote-user]]">
16
+ <span class="visually-hidden">[[global:remote-user]]</span>
17
+ <i class="fa fa-globe"></i>
31
18
  </span>
32
-
33
- {{{ each posts.user.selectedGroups }}}
34
- {{{ if posts.user.selectedGroups.slug }}}
35
- <!-- IMPORT partials/groups/badge.tpl -->
36
- {{{ end }}}
37
19
  {{{ end }}}
20
+ </a>
21
+ </div>
22
+ <div class="post-container d-flex gap-2 flex-grow-1 flex-column w-100" style="min-width:0;">
23
+ <div class="d-flex align-items-start justify-content-between gap-1 flex-nowrap w-100 post-header" itemprop="author" itemscope itemtype="https://schema.org/Person">
24
+ <div class="d-flex gap-1 flex-wrap align-items-center">
25
+ <meta itemprop="name" content="{./user.displayname}">
26
+ {{{ if ./user.userslug }}}<meta itemprop="url" content="{config.relative_path}/user/{./user.userslug}">{{{ end }}}
27
+
28
+ <div class="bg-body d-sm-none">
29
+ <a class="d-inline-block position-relative text-decoration-none" href="{{{ if ./user.userslug }}}{config.relative_path}/user/{./user.userslug}{{{ else }}}#{{{ end }}}">
30
+ {buildAvatar(posts.user, "20px", true, "", "user/picture")}
31
+ {{{ if ./user.isLocal }}}
32
+ <span component="user/status" class="position-absolute top-100 start-100 border border-white border-2 rounded-circle status {posts.user.status}"><span class="visually-hidden">[[global:{posts.user.status}]]</span></span>
33
+ {{{ else }}}
34
+ <span component="user/locality" class="position-absolute top-100 start-100 lh-1 border border-white border-2 rounded-circle small" title="[[global:remote-user]]">
35
+ <span class="visually-hidden">[[global:remote-user]]</span>
36
+ <i class="fa fa-globe"></i>
37
+ </span>
38
+ {{{ end }}}
39
+ </a>
40
+ </div>
41
+
42
+ <a class="fw-bold text-nowrap" href="{{{ if ./user.userslug }}}{config.relative_path}/user/{./user.userslug}{{{ else }}}#{{{ end }}}" data-username="{posts.user.username}" data-uid="{posts.user.uid}">{posts.user.displayname}</a>
43
+
44
+ {{{ each posts.user.selectedGroups }}}
45
+ {{{ if posts.user.selectedGroups.slug }}}
46
+ <!-- IMPORT partials/groups/badge.tpl -->
47
+ {{{ end }}}
48
+ {{{ end }}}
38
49
 
39
- {{{ if posts.user.banned }}}
40
- <span class="badge bg-danger rounded-1">[[user:banned]]</span>
41
- {{{ end }}}
42
-
43
- <div class="d-flex gap-1 align-items-center">
44
- <span class="text-muted">
45
- {{{ if posts.toPid }}}
46
- {generateRepliedTo(@value, config.timeagoCutoff)}
47
- {{{ else }}}
48
- {generateWrote(@value, config.timeagoCutoff)}
49
- {{{ end }}}
50
- </span>
51
-
52
- <i component="post/edit-indicator" class="fa fa-edit text-muted{{{ if privileges.posts:history }}} pointer{{{ end }}} edit-icon {{{ if !posts.editor.username }}}hidden{{{ end }}}" title="[[global:edited-timestamp, {isoTimeToLocaleString(./editedISO, config.userLang)}]]"></i>
53
- <span data-editor="{posts.editor.userslug}" component="post/editor" class="visually-hidden">[[global:last-edited-by, {posts.editor.username}]] <span class="timeago" title="{isoTimeToLocaleString(posts.editedISO, config.userLang)}"></span></span>
54
- </div>
50
+ {{{ if posts.user.banned }}}
51
+ <span class="badge bg-danger rounded-1">[[user:banned]]</span>
52
+ {{{ end }}}
55
53
 
56
- <div>
57
- <span>
58
- {{{ if posts.user.custom_profile_info.length }}}
59
- &#124;
60
- {{{ each posts.user.custom_profile_info }}}
61
- {posts.user.custom_profile_info.content}
62
- {{{ end }}}
63
- {{{ end }}}
64
- </span>
54
+ <div class="d-flex gap-1 align-items-center">
55
+ <span class="text-muted">{generateWroteReplied(@value, config.timeagoCutoff)}</span>
56
+
57
+ <i component="post/edit-indicator" class="fa fa-edit text-muted{{{ if privileges.posts:history }}} pointer{{{ end }}} edit-icon {{{ if !posts.editor.username }}}hidden{{{ end }}}" title="[[global:edited-timestamp, {isoTimeToLocaleString(./editedISO, config.userLang)}]]"></i>
58
+ <span data-editor="{posts.editor.userslug}" component="post/editor" class="visually-hidden">[[global:last-edited-by, {posts.editor.username}]] <span class="timeago" title="{isoTimeToLocaleString(posts.editedISO, config.userLang)}"></span></span>
59
+ </div>
60
+
61
+ {{{ if posts.user.custom_profile_info.length }}}
62
+ <div>
63
+ <span>
64
+ &#124;
65
+ {{{ each posts.user.custom_profile_info }}}
66
+ {posts.user.custom_profile_info.content}
67
+ {{{ end }}}
68
+ </span>
69
+ </div>
70
+ {{{ end }}}
65
71
  </div>
66
- <div class="d-flex align-items-center gap-1 flex-grow-1 justify-content-end">
72
+ <div class="d-flex align-items-center gap-1 justify-content-end">
67
73
  <span class="bookmarked opacity-0 text-primary"><i class="fa fa-bookmark-o"></i></span>
68
74
  <a href="{config.relative_path}/post/{encodeURIComponent(./pid)}" class="post-index text-muted d-none d-md-inline">#{increment(./index, "1")}</a>
69
75
  </div>
70
76
  </div>
71
77
 
72
- <div class="content mt-2 text-break" component="post/content" itemprop="text">
78
+ <div class="content text-break" component="post/content" itemprop="text">
73
79
  {posts.content}
74
80
  </div>
75
- </div>
76
- </div>
77
81
 
78
- <div component="post/footer" class="post-footer border-bottom pb-2">
79
- {{{ if posts.user.signature }}}
80
- <div component="post/signature" data-uid="{posts.user.uid}" class="text-xs text-muted mt-2">{posts.user.signature}</div>
81
- {{{ end }}}
82
+ <div component="post/footer" class="post-footer border-bottom pb-2">
83
+ {{{ if posts.user.signature }}}
84
+ <div component="post/signature" data-uid="{posts.user.uid}" class="text-xs text-muted mt-2">{posts.user.signature}</div>
85
+ {{{ end }}}
82
86
 
83
- <div class="d-flex">
84
- {{{ if !hideReplies }}}
85
- <a component="post/reply-count" data-target-component="post/replies/container" href="#" class="d-flex gap-2 align-items-center mt-2 btn-ghost ff-secondary border rounded-1 p-1 threaded-replies user-select-none text-muted text-decoration-none text-xs {{{ if (!./replies || shouldHideReplyContainer(@value)) }}}hidden{{{ end }}}">
86
- <span component="post/reply-count/avatars" class="avatars d-inline-flex gap-1 align-items-top {{{ if posts.replies.hasMore }}}hasMore{{{ end }}}">
87
- {{{each posts.replies.users}}}
88
- <span>{buildAvatar(posts.replies.users, "20px", true, "avatar-tooltip")}</span>
89
- {{{end}}}
90
- {{{ if posts.replies.hasMore}}}
91
- <span><i class="fa fa-ellipsis"></i></span>
87
+ <div class="d-flex flex-wrap {{{ if (hideReplies || !posts.replies.count) }}}justify-content-end{{{ else }}}justify-content-between{{{ end }}}">
88
+ {{{ if !hideReplies }}}
89
+ <a component="post/reply-count" data-target-component="post/replies/container" href="#" class="d-flex gap-2 align-items-center btn btn-ghost ff-secondary border rounded-1 p-1 text-muted text-decoration-none text-xs {{{ if (!./replies || shouldHideReplyContainer(@value)) }}}hidden{{{ end }}}">
90
+ <span component="post/reply-count/avatars" class="d-flex gap-1 {{{ if posts.replies.hasMore }}}hasMore{{{ end }}}">
91
+ {{{each posts.replies.users}}}
92
+ <span>{buildAvatar(posts.replies.users, "20px", true, "avatar-tooltip")}</span>
93
+ {{{end}}}
94
+ {{{ if posts.replies.hasMore}}}
95
+ <span style="height: 20px; line-height: 20px;"><i class="fa fa-ellipsis"></i></span>
96
+ {{{ end }}}
97
+ </span>
98
+
99
+ <span class="ms-2 replies-count fw-semibold text-nowrap" component="post/reply-count/text" data-replies="{posts.replies.count}">{posts.replies.text}</span>
100
+ <span class="ms-2 replies-last hidden-xs fw-semibold">[[topic:last-reply-time]] <span class="timeago" title="{posts.replies.timestampISO}"></span></span>
101
+
102
+ <i class="fa fa-fw fa-chevron-down" component="post/replies/open"></i>
103
+ </a>
92
104
  {{{ end }}}
93
- </span>
94
-
95
- <span class="ms-2 replies-count fw-semibold" component="post/reply-count/text" data-replies="{posts.replies.count}">{posts.replies.text}</span>
96
- <span class="ms-2 replies-last hidden-xs fw-semibold">[[topic:last-reply-time]] <span class="timeago" title="{posts.replies.timestampISO}"></span></span>
105
+ <div component="post/actions" class="d-flex flex-grow-1 justify-content-end gap-1 post-tools">
106
+ <!-- IMPORT partials/topic/reactions.tpl -->
107
+ <a component="post/reply" href="#" class="btn btn-ghost btn-sm {{{ if !privileges.topics:reply }}}hidden{{{ end }}}" title="[[topic:reply]]"><i class="fa fa-fw fa-reply text-primary"></i></a>
108
+ <a component="post/quote" href="#" class="btn btn-ghost btn-sm {{{ if !privileges.topics:reply }}}hidden{{{ end }}}" title="[[topic:quote]]"><i class="fa fa-fw fa-quote-right text-primary"></i></a>
97
109
 
98
- <i class="fa fa-fw fa-chevron-down" component="post/replies/open"></i>
99
- <i class="fa fa-fw fa-chevron-up hidden" component="post/replies/close"></i>
100
- <i class="fa fa-fw fa-spin fa-spinner hidden" component="post/replies/loading"></i>
101
- </a>
102
- {{{ end }}}
103
- </div>
104
-
105
- <div component="post/replies/container" class="my-2 col-11 border rounded-1 p-3 hidden-empty"></div>
106
-
107
- <div component="post/actions" class="d-flex justify-content-end gap-1 post-tools">
108
- <!-- IMPORT partials/topic/reactions.tpl -->
109
- <a component="post/reply" href="#" class="btn-ghost-sm user-select-none {{{ if !privileges.topics:reply }}}hidden{{{ end }}}" title="[[topic:reply]]"><i class="fa fa-fw fa-reply text-primary"></i></a>
110
- <a component="post/quote" href="#" class="btn-ghost-sm user-select-none {{{ if !privileges.topics:reply }}}hidden{{{ end }}}" title="[[topic:quote]]"><i class="fa fa-fw fa-quote-right text-primary"></i></a>
110
+ {{{ if ./announces }}}
111
+ <a component="post/announce-count" href="#" class="btn btn-ghost btn-sm d-flex gap-2 align-items-center" title="[[topic:announcers]]"><i class="fa fa-share-alt text-primary"></i> {./announces}</a>
112
+ {{{ end }}}
111
113
 
112
- {{{ if !reputation:disabled }}}
113
- <div class="d-flex votes align-items-center">
114
- <a component="post/upvote" href="#" class="btn-ghost-sm {{{ if posts.upvoted }}}upvoted{{{ end }}}" title="[[topic:upvote-post]]">
115
- <i class="fa fa-fw fa-chevron-up text-primary"></i>
116
- </a>
114
+ {{{ if !reputation:disabled }}}
115
+ <div class="d-flex votes align-items-center">
116
+ <a component="post/upvote" href="#" class="btn btn-ghost btn-sm{{{ if posts.upvoted }}} upvoted{{{ end }}}" title="[[topic:upvote-post]]">
117
+ <i class="fa fa-fw fa-chevron-up text-primary"></i>
118
+ </a>
119
+
120
+ <meta itemprop="upvoteCount" content="{posts.upvotes}">
121
+ <meta itemprop="downvoteCount" content="{posts.downvotes}">
122
+ <a href="#" class="px-2 mx-1 btn btn-ghost btn-sm" component="post/vote-count" data-votes="{posts.votes}" title="[[global:voters]]">{posts.votes}</a>
123
+
124
+ {{{ if !downvote:disabled }}}
125
+ <a component="post/downvote" href="#" class="btn btn-ghost btn-sm{{{ if posts.downvoted }}} downvoted{{{ end }}}" title="[[topic:downvote-post]]">
126
+ <i class="fa fa-fw fa-chevron-down text-primary"></i>
127
+ </a>
128
+ {{{ end }}}
129
+ </div>
130
+ {{{ end }}}
117
131
 
118
- <meta itemprop="upvoteCount" content="{posts.upvotes}">
119
- <meta itemprop="downvoteCount" content="{posts.downvotes}">
120
- <a href="#" class="d-inline-block px-2 mx-1 btn-ghost-sm ff-secondary" component="post/vote-count" data-votes="{posts.votes}" title="[[global:voters]]">{posts.votes}</a>
132
+ <!-- IMPORT partials/topic/post-menu.tpl -->
133
+ </div>
134
+ </div>
121
135
 
122
- {{{ if !downvote:disabled }}}
123
- <a component="post/downvote" href="#" class="btn-ghost-sm {{{ if posts.downvoted }}}downvoted{{{ end }}}" title="[[topic:downvote-post]]">
124
- <i class="fa fa-fw fa-chevron-down text-primary"></i>
125
- </a>
126
- {{{ end }}}
136
+ <div component="post/replies/container" class="my-2 col-11 border rounded-1 p-3 hidden-empty"></div>
127
137
  </div>
128
- {{{ end }}}
129
-
130
- <!-- IMPORT partials/topic/post-menu.tpl -->
131
138
  </div>
132
139
  </div>
133
140
 
@@ -3,7 +3,7 @@
3
3
  <div class="icon hidden-xs">
4
4
  <a class="d-inline-block position-relative" href="{{{ if loggedInUser.userslug }}}{config.relative_path}/user/{loggedInUser.userslug}{{{ else }}}#{{{ end }}}">
5
5
  {buildAvatar(loggedInUser, "48px", true, "", "user/picture")}
6
- {{{ if loggedInUser.status }}}<span component="user/status" class="position-absolute translate-middle-y border border-white border-2 rounded-circle status {loggedInUser.status}"><span class="visually-hidden">[[global:{loggedInUser.status}]]</span></span>{{{ end }}}
6
+ {{{ if loggedInUser.status }}}<span component="user/status" class="position-absolute top-100 start-100 border border-white border-2 rounded-circle status {loggedInUser.status}"><span class="visually-hidden">[[global:{loggedInUser.status}]]</span></span>{{{ end }}}
7
7
  </a>
8
8
  </div>
9
9
  <form class="flex-grow-1 d-flex flex-column gap-2" method="post" action="{config.relative_path}/compose">
@@ -15,7 +15,7 @@
15
15
  </div>
16
16
  <div>
17
17
  <div class="d-flex justify-content-end gap-2">
18
- <button type="submit" component="topic/quickreply/expand" class="btn-ghost-sm border" title="[[topic:open-composer]]"><i class="fa fa-expand"></i></button>
18
+ <button type="submit" component="topic/quickreply/expand" class="btn btn-ghost btn-sm border" title="[[topic:open-composer]]"><i class="fa fa-expand"></i></button>
19
19
  <button type="submit" component="topic/quickreply/button" class="btn btn-sm btn-primary">[[topic:post-quick-reply]]</button>
20
20
  </div>
21
21
  </div>
@@ -1,5 +1,6 @@
1
- <div component="topic/reply/container" class="btn-group action-bar {{{ if !privileges.topics:reply }}}hidden{{{ end }}}">
2
- <a href="{config.relative_path}/compose?tid={tid}" class="d-flex align-items-center btn btn-sm btn-primary px-3 fw-semibold " component="topic/reply" data-ajaxify="false" role="button"><i class="fa fa-reply d-sm-block d-md-none"></i><span class="d-none d-md-block"> [[topic:reply]]</span></a>
1
+ {{{ if privileges.topics:reply }}}
2
+ <div component="topic/reply/container" class="btn-group">
3
+ <a href="{config.relative_path}/compose?tid={tid}" class="d-flex align-items-center btn btn-sm btn-primary px-3 fw-semibold" component="topic/reply" data-ajaxify="false" role="button"><i class="fa fa-reply d-sm-block d-md-none"></i><span class="d-none d-md-block"> [[topic:reply]]</span></a>
3
4
  <button type="button" class="btn btn-sm btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="[[topic:reply-options]]">
4
5
  <span class="caret"></span>
5
6
  </button>
@@ -7,6 +8,7 @@
7
8
  <li><a class="dropdown-item rounded-1" href="#" component="topic/reply-as-topic" role="menuitem">[[topic:reply-as-topic]]</a></li>
8
9
  </ul>
9
10
  </div>
11
+ {{{ end }}}
10
12
 
11
13
  {{{ if loggedIn }}}
12
14
  {{{ if !privileges.topics:reply }}}
@@ -1,5 +1,5 @@
1
1
  <div class="btn-group bottom-sheet" component="thread/sort">
2
- <button class="btn-ghost-sm ff-secondary d-flex gap-2 align-items-center dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="[[aria:post-sort-option, {sortOptionLabel}]]">
2
+ <button class="btn btn-ghost btn-sm ff-secondary d-flex gap-2 align-items-center dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="[[aria:post-sort-option, {sortOptionLabel}]]">
3
3
  <i class="fa fa-fw fa-arrow-down-wide-short text-primary"></i>
4
4
  <span class="d-none d-md-inline fw-semibold">{sortOptionLabel}</span>
5
5
  </button>
@@ -1,5 +1,5 @@
1
1
  {{{ each thumbs }}}
2
- <a class="d-inline-block h-100" href="{./url}">
2
+ <a class="d-inline-block" href="{./url}">
3
3
  <img class="rounded-1 h-100 bg-light" style="max-width: 5.33rem; object-fit: contain;" src="{./url}" />
4
4
  </a>
5
5
  {{{ end }}}
@@ -1,13 +1,9 @@
1
1
  {{{ if privileges.view_thread_tools }}}
2
2
  <div class="btn-group thread-tools bottom-sheet">
3
- <button class="btn-ghost-sm ff-secondary d-flex gap-2 dropdown-toggle" data-bs-toggle="dropdown" type="button" aria-haspopup="true" aria-expanded="false">
3
+ <button class="btn btn-ghost btn-sm ff-secondary d-flex align-items-center gap-2 dropdown-toggle" data-bs-toggle="dropdown" type="button" aria-haspopup="true" aria-expanded="false">
4
4
  <i class="fa fa-fw fa-gear text-primary"></i>
5
5
  <span class="d-none d-md-inline fw-semibold">[[topic:thread-tools.title]]</span>
6
6
  </button>
7
- <ul class="dropdown-menu p-1 text-sm" role="menu">
8
- <li class="placeholder-wave"><a class="dropdown-item d-flex gap-2" href="#"><div class="placeholder bg-secondary rounded-1" style="width: 1em;"></div><div class="placeholder bg-secondary rounded-1 col-8"></div></a></li>
9
- <li class="placeholder-wave"><a class="dropdown-item d-flex gap-2" href="#"><div class="placeholder bg-secondary rounded-1" style="width: 1em;"></div><div class="placeholder bg-secondary rounded-1 col-8"></div></a></li>
10
- <li class="placeholder-wave"><a class="dropdown-item d-flex gap-2" href="#"><div class="placeholder bg-secondary rounded-1" style="width: 1em;"></div><div class="placeholder bg-secondary rounded-1 col-8"></div></a></li>
11
- </ul>
7
+ <ul class="dropdown-menu p-1 text-sm" role="menu"></ul>
12
8
  </div>
13
9
  {{{ end }}}
@@ -1,6 +1,6 @@
1
1
  {{{ if config.loggedIn }}}
2
2
  <div class="btn-group bottom-sheet" component="topic/watch">
3
- <button class="btn-ghost-sm ff-secondary d-flex gap-2 dropdown-toggle" data-bs-toggle="dropdown" type="button" aria-haspopup="true" aria-expanded="false">
3
+ <button class="btn btn-ghost btn-sm ff-secondary d-flex gap-2 dropdown-toggle" data-bs-toggle="dropdown" type="button" aria-haspopup="true" aria-expanded="false">
4
4
  <span component="topic/following/menu" class="d-flex gap-2 align-items-center{{{ if !isFollowing }}} hidden{{{ end }}}">
5
5
  <i class="flex-shrink-0 fa fa-fw fa-bell-o text-primary"></i>
6
6
  <span class="d-none d-md-inline fw-semibold">[[topic:watching]]</span>
@@ -1,5 +1,5 @@
1
1
  <div class="btn-group bottom-sheet{{{ if !filters.length }}} hidden{{{ end }}}">
2
- <button type="button" class="btn-ghost-sm ff-secondary d-flex gap-2 dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
2
+ <button type="button" class="btn btn-ghost btn-sm ff-secondary d-flex gap-2 align-items-center dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
3
3
  <i class="fa fa-fw fa-filter text-primary"></i>
4
4
  <span class="visible-md-inline visible-lg-inline fw-semibold">{selectedFilter.name}</span>
5
5
  </button>
@@ -1,8 +1,8 @@
1
1
  <div class="{{{ if config.theme.stickyToolbar }}}sticky-tools{{{ end }}} mb-3">
2
2
  <nav class="topic-list-header d-flex flex-nowrap my-2 p-0 border-0 rounded">
3
- <div class="d-flex flex-row p-2 text-bg-light gap-1 border rounded w-100 align-items-center">
3
+ <div class="d-flex flex-row p-2 text-bg-light gap-1 border rounded w-100">
4
4
  <div component="category/controls" class="d-flex me-auto mb-0 gap-2 flex-wrap">
5
- {{{ if template.category }}}
5
+ {{{ if (template.category || template.world) }}}
6
6
  <!-- IMPORT partials/category/watch.tpl -->
7
7
  <!-- IMPORT partials/tags/filter-dropdown-left.tpl -->
8
8
  <!-- IMPORT partials/category/sort.tpl -->
@@ -24,19 +24,19 @@
24
24
  <!-- IMPORT partials/category/filter-dropdown-left.tpl -->
25
25
  <!-- IMPORT partials/tags/watch.tpl -->
26
26
  {{{ end }}}
27
- <!-- IMPORT partials/category/tools.tpl -->
27
+ <!-- IMPORT partials/category/tools-dropdown-left.tpl -->
28
28
 
29
29
  {{{ if (!feeds:disableRSS && rssFeedUrl) }}}
30
- <a class="btn-ghost-sm d-none d-lg-flex align-self-stretch" target="_blank" href="{rssFeedUrl}" itemprop="item" title="[[global:rss-feed]]"><i class="fa fa-rss text-primary"></i></a>
30
+ <a class="btn btn-ghost btn-sm d-none d-lg-flex align-items-center align-self-stretch" target="_blank" href="{rssFeedUrl}" itemprop="item" title="[[global:rss-feed]]"><i class="fa fa-rss text-primary"></i></a>
31
31
  {{{ end }}}
32
32
 
33
- <a href="{config.relative_path}{{{ if template.category }}}{url}{{{ else }}}/{selectedFilter.url}{querystring}{{{ end }}}" class="btn btn-secondary fw-semibold position-absolute top-100 translate-middle-x start-50 mt-1 hide" style="--bs-btn-padding-y: .25rem; --bs-btn-padding-x: .5rem; --bs-btn-font-size: .75rem;" id="new-topics-alert">
33
+ <a href="{{{ if (template.category || template.world) }}}{url}{{{ else }}}{config.relative_path}/{selectedFilter.url}{querystring}{{{ end }}}" class="btn btn-secondary fw-semibold position-absolute top-100 translate-middle-x start-50 mt-1 hide" style="--bs-btn-padding-y: .25rem; --bs-btn-padding-x: .5rem; --bs-btn-font-size: .75rem;" id="new-topics-alert">
34
34
  <i class="fa fa-fw fa-arrow-up"></i> [[recent:load-new-posts]]
35
35
  </a>
36
36
  </div>
37
37
 
38
38
  <div class="d-flex gap-1 align-items-center">
39
- {{{ if template.category }}}
39
+ {{{ if (template.category || template.world) }}}
40
40
  {{{ if privileges.topics:create }}}
41
41
  <a href="{config.relative_path}/compose?cid={cid}" component="category/post" id="new_topic" class="btn btn-primary btn-sm text-nowrap" data-ajaxify="false" role="button">[[category:new-topic-button]]</a>
42
42
  {{{ end }}}
@@ -1,5 +1,5 @@
1
1
  <div class="btn-group bottom-sheet {{{ if !terms.length }}}hidden{{{ end }}}">
2
- <button type="button" class="btn-ghost-sm ff-secondary d-flex gap-2 dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
2
+ <button type="button" class="btn btn-ghost btn-sm ff-secondary d-flex align-items-center gap-2 dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
3
3
  <i class="fa fa-fw fa-clock text-primary"></i>
4
4
  <span class="visible-md-inline visible-lg-inline fw-semibold">{selectedTerm.name}</span>
5
5
  </button>
@@ -10,8 +10,8 @@
10
10
 
11
11
  <div class="d-flex p-0 col-12 col-lg-7 gap-2 gap-lg-3 pe-1 align-items-start {{{ if config.theme.mobileTopicTeasers }}}mb-2 mb-lg-0{{{ end }}}">
12
12
  <div class="flex-shrink-0 position-relative">
13
- <a class="text-decoration-none" href="{{{ if ./user.userslug }}}{config.relative_path}/user/{./user.userslug}{{{ else }}}#{{{ end }}}">
14
- {buildAvatar(./user, "40px", true, "avatar avatar-tooltip")}
13
+ <a class="d-inline-block text-decoration-none avatar-tooltip" title="{./user.displayname}" href="{{{ if ./user.userslug }}}{config.relative_path}/user/{./user.userslug}{{{ else }}}#{{{ end }}}">
14
+ {buildAvatar(./user, "40px", true)}
15
15
  </a>
16
16
  {{{ if showSelect }}}
17
17
  <div class="checkbox position-absolute top-100 start-50 translate-middle-x pt-2 m-0 d-none d-lg-flex" style="max-width:max-content">
@@ -24,6 +24,14 @@
24
24
  <a class="text-reset" href="{{{ if topics.noAnchor }}}#{{{ else }}}{config.relative_path}/topic/{./slug}{{{ if ./bookmark }}}/{./bookmark}{{{ end }}}{{{ end }}}">{./title}</a>
25
25
  </h3>
26
26
  <span component="topic/labels" class="d-flex flex-wrap gap-1 w-100">
27
+ <span component="topic/watched" class="badge border border-gray-300 text-body {{{ if !./followed }}}hidden{{{ end }}}">
28
+ <i class="fa fa-bell-o"></i>
29
+ <span>[[topic:watching]]</span>
30
+ </span>
31
+ <span component="topic/ignored" class="badge border border-gray-300 text-body {{{ if !./ignored }}}hidden{{{ end }}}">
32
+ <i class="fa fa-eye-slash"></i>
33
+ <span>[[topic:ignoring]]</span>
34
+ </span>
27
35
  <span component="topic/scheduled" class="badge border border-gray-300 text-body {{{ if !./scheduled }}}hidden{{{ end }}}">
28
36
  <i class="fa fa-clock-o"></i>
29
37
  <span>[[topic:scheduled]]</span>
@@ -36,7 +44,7 @@
36
44
  <i class="fa fa-lock"></i>
37
45
  <span>[[topic:locked]]</span>
38
46
  </span>
39
- <span class="badge border border-gray-300 text-body {{{ if !./oldCid }}}hidden{{{ end }}}">
47
+ <span component="topic/moved" class="badge border border-gray-300 text-body {{{ if (!./oldCid || (./oldCid == "-1")) }}}hidden{{{ end }}}">
40
48
  <i class="fa fa-arrow-circle-right"></i>
41
49
  <span>[[topic:moved]]</span>
42
50
  </span>
@@ -106,7 +114,7 @@
106
114
  {{{ else }}}
107
115
  {{{ if ./teaser.pid }}}
108
116
  <div class="ps-2">
109
- <a href="{config.relative_path}/user/{./teaser.user.userslug}" class="text-decoration-none">{buildAvatar(./teaser.user, "18px", true, "avatar-tooltip not-responsive")}</a>
117
+ <a href="{{{ if ./teaser.user.userslug }}}{config.relative_path}/user/{./teaser.user.userslug}{{{ else }}}#{{{ end }}}" class="text-decoration-none avatar-tooltip" title="{./teaser.user.displayname}">{buildAvatar(./teaser.user, "18px", true)}</a>
110
118
  <a class="permalink text-muted timeago text-xs" href="{config.relative_path}/topic/{./slug}/{./teaser.index}" title="{./teaser.timestampISO}" aria-label="[[global:lastpost]]"></a>
111
119
  </div>
112
120
  <div class="post-content text-xs ps-2 line-clamp-sm-2 lh-sm text-break position-relative flex-fill">