nodebb-theme-harmony 1.0.0 → 1.0.1

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 (155) hide show
  1. package/README.md +12 -1
  2. package/languages/en-GB/harmony.json +6 -1
  3. package/library.js +56 -25
  4. package/package.json +1 -1
  5. package/plugin.json +0 -1
  6. package/public/harmony.js +165 -41
  7. package/public/settings.js +1 -0
  8. package/screenshots/categories.png +0 -0
  9. package/screenshots/recent.png +0 -0
  10. package/screenshots/topic.png +0 -0
  11. package/scss/account.scss +1 -1
  12. package/scss/chats.scss +81 -26
  13. package/scss/common.scss +84 -10
  14. package/scss/flags.scss +5 -0
  15. package/scss/groups.scss +2 -2
  16. package/scss/harmony.scss +3 -0
  17. package/scss/mixins.scss +7 -3
  18. package/scss/modals.scss +5 -3
  19. package/scss/modules/bottom-sheet.scss +1 -1
  20. package/scss/modules/composer.scss +0 -4
  21. package/scss/modules/cover.scss +1 -11
  22. package/scss/modules/filters.scss +8 -0
  23. package/scss/modules/paginator.scss +24 -0
  24. package/scss/modules/tags.scss +2 -2
  25. package/scss/modules/topic-navigator.scss +18 -42
  26. package/scss/modules/topics-list.scss +32 -17
  27. package/scss/modules/user-menu.scss +6 -0
  28. package/scss/overrides.scss +4 -1
  29. package/scss/sidebar.scss +61 -8
  30. package/scss/topic.scss +36 -13
  31. package/templates/account/blocks.tpl +35 -40
  32. package/templates/account/categories.tpl +47 -29
  33. package/templates/account/consent.tpl +66 -10
  34. package/templates/account/edit/password.tpl +25 -30
  35. package/templates/account/edit/username.tpl +21 -26
  36. package/templates/account/edit.tpl +105 -116
  37. package/templates/account/followers.tpl +12 -19
  38. package/templates/account/following.tpl +12 -18
  39. package/templates/account/groups.tpl +12 -17
  40. package/templates/account/info.tpl +178 -206
  41. package/templates/account/posts.tpl +31 -36
  42. package/templates/account/profile.tpl +82 -72
  43. package/templates/account/sessions.tpl +8 -30
  44. package/templates/account/settings.tpl +222 -203
  45. package/templates/account/theme.tpl +39 -25
  46. package/templates/account/topics.tpl +36 -38
  47. package/templates/account/uploads.tpl +33 -40
  48. package/templates/admin/plugins/harmony.tpl +21 -3
  49. package/templates/categories.tpl +3 -6
  50. package/templates/category.tpl +13 -14
  51. package/templates/chats.tpl +9 -10
  52. package/templates/flags/detail.tpl +160 -193
  53. package/templates/flags/list.tpl +3 -70
  54. package/templates/footer.tpl +2 -2
  55. package/templates/groups/details.tpl +22 -19
  56. package/templates/groups/list.tpl +1 -1
  57. package/templates/groups/members.tpl +0 -2
  58. package/templates/header.tpl +2 -2
  59. package/templates/login.tpl +4 -4
  60. package/templates/notifications.tpl +5 -5
  61. package/templates/partials/account/admin-menu.tpl +9 -9
  62. package/templates/partials/account/category-item.tpl +14 -17
  63. package/templates/partials/account/footer.tpl +3 -0
  64. package/templates/partials/account/header.tpl +78 -81
  65. package/templates/partials/account/session-list.tpl +18 -0
  66. package/templates/partials/account/sidebar-left.tpl +31 -25
  67. package/templates/partials/breadcrumbs.tpl +6 -6
  68. package/templates/partials/buttons/newTopic.tpl +1 -1
  69. package/templates/partials/categories/item.tpl +31 -27
  70. package/templates/partials/categories/lastpost.tpl +7 -7
  71. package/templates/partials/category/filter-dropdown-content.tpl +37 -0
  72. package/templates/partials/{category-selector-content.tpl → category/selector-dropdown-content.tpl} +7 -7
  73. package/templates/partials/category/sort.tpl +22 -7
  74. package/templates/partials/category/subcategory.tpl +2 -3
  75. package/templates/partials/category/tags.tpl +0 -2
  76. package/templates/partials/category/tools.tpl +28 -25
  77. package/templates/partials/category/watch.tpl +39 -6
  78. package/templates/partials/chats/dropdown.tpl +4 -1
  79. package/templates/partials/chats/message-window.tpl +12 -8
  80. package/templates/partials/chats/message.tpl +8 -10
  81. package/templates/partials/chats/options.tpl +14 -6
  82. package/templates/partials/chats/recent_room.tpl +41 -32
  83. package/templates/partials/cookie-consent.tpl +5 -5
  84. package/templates/partials/flags/bulk-actions.tpl +9 -0
  85. package/templates/partials/flags/filters.tpl +165 -78
  86. package/templates/partials/flags/results.tpl +38 -0
  87. package/templates/partials/groups/admin.tpl +4 -4
  88. package/templates/partials/groups/badge.tpl +1 -1
  89. package/templates/partials/groups/invited.tpl +1 -1
  90. package/templates/partials/groups/list.tpl +2 -2
  91. package/templates/partials/groups/memberlist.tpl +2 -2
  92. package/templates/partials/groups/sidebar-left.tpl +10 -10
  93. package/templates/partials/header/brand.tpl +9 -2
  94. package/templates/partials/mobile-footer.tpl +69 -61
  95. package/templates/partials/notifications_list.tpl +11 -8
  96. package/templates/partials/paginator.tpl +11 -9
  97. package/templates/partials/post_bar.tpl +26 -24
  98. package/templates/partials/posts_list_item.tpl +5 -5
  99. package/templates/partials/quick-search-results.tpl +3 -3
  100. package/templates/partials/search-filters.tpl +184 -0
  101. package/templates/partials/search-results.tpl +28 -35
  102. package/templates/partials/sidebar/chats.tpl +26 -34
  103. package/templates/partials/sidebar/drafts.tpl +45 -34
  104. package/templates/partials/sidebar/logged-in-menu.tpl +5 -5
  105. package/templates/partials/sidebar/logged-out-menu.tpl +1 -1
  106. package/templates/partials/sidebar/notifications.tpl +30 -9
  107. package/templates/partials/sidebar/search-mobile.tpl +1 -1
  108. package/templates/partials/sidebar/search.tpl +1 -1
  109. package/templates/partials/sidebar/user-menu.tpl +38 -29
  110. package/templates/partials/sidebar-left.tpl +14 -11
  111. package/templates/partials/sidebar-right.tpl +1 -3
  112. package/templates/partials/skin-switcher.tpl +3 -3
  113. package/templates/partials/tags/filter-dropdown-content.tpl +34 -0
  114. package/templates/partials/tags_list.tpl +4 -4
  115. package/templates/partials/topic/browsing-users.tpl +0 -2
  116. package/templates/partials/topic/event.tpl +1 -1
  117. package/templates/partials/topic/navigation-post.tpl +5 -9
  118. package/templates/partials/topic/navigator-mobile.tpl +62 -0
  119. package/templates/partials/topic/navigator.tpl +23 -17
  120. package/templates/partials/topic/post-editor.tpl +0 -2
  121. package/templates/partials/topic/post-menu-list.tpl +60 -62
  122. package/templates/partials/topic/post-menu.tpl +16 -11
  123. package/templates/partials/topic/post.tpl +45 -27
  124. package/templates/partials/topic/quickreply.tpl +8 -8
  125. package/templates/partials/topic/reply-button.tpl +7 -7
  126. package/templates/partials/topic/sort.tpl +17 -5
  127. package/templates/partials/topic/tools.tpl +2 -2
  128. package/templates/partials/topic/topic-menu-list.tpl +22 -24
  129. package/templates/partials/topic/watch.tpl +42 -9
  130. package/templates/partials/topic-filters.tpl +6 -3
  131. package/templates/partials/topic-list-bar.tpl +50 -46
  132. package/templates/partials/topic-terms.tpl +6 -3
  133. package/templates/partials/topics_list.tpl +88 -93
  134. package/templates/partials/userFilter-placeholders.tpl +5 -0
  135. package/templates/partials/users/filter-dropdown-content.tpl +23 -0
  136. package/templates/partials/users/item.tpl +25 -27
  137. package/templates/partials/users_list.tpl +1 -1
  138. package/templates/popular.tpl +3 -1
  139. package/templates/post-queue.tpl +166 -0
  140. package/templates/recent.tpl +3 -2
  141. package/templates/register.tpl +4 -4
  142. package/templates/search.tpl +39 -177
  143. package/templates/tags.tpl +3 -3
  144. package/templates/top.tpl +3 -1
  145. package/templates/topic.tpl +74 -68
  146. package/templates/unread.tpl +3 -1
  147. package/templates/users.tpl +7 -3
  148. package/templates/modules/usercard.tpl +0 -39
  149. package/templates/partials/acceptTos.tpl +0 -11
  150. package/templates/partials/category-filter-content.tpl +0 -30
  151. package/templates/partials/category-filter-right.tpl +0 -5
  152. package/templates/partials/category-filter.tpl +0 -3
  153. package/templates/partials/category-selector-right.tpl +0 -5
  154. package/templates/partials/category-selector.tpl +0 -3
  155. package/templates/partials/slideout-menu.tpl +0 -6
@@ -1,44 +1,37 @@
1
- <div class="account">
2
- <!-- IMPORT partials/account/header.tpl -->
3
- <div class="d-flex flex-column flex-md-row">
4
- <!-- IMPORT partials/account/sidebar-left.tpl -->
5
- <div class="flex-1 ps-md-2 ps-lg-5" style="min-width: 0;">
6
- <h3 class="fw-semibold fs-5">{title}</h3>
1
+ <!-- IMPORT partials/account/header.tpl -->
7
2
 
8
- <!-- IF privateUploads -->
9
- <div class="alert alert-info text-center">[[uploads:private-uploads-info]]</div>
10
- <!-- ELSE -->
11
- <div class="alert alert-info text-center">[[uploads:public-uploads-info]]</div>
12
- <!-- ENDIF privateUploads -->
3
+ <h3 class="fw-semibold fs-5">{title}</h3>
13
4
 
14
- <!-- IF !uploads.length -->
15
- <div class="alert alert-warning text-center">[[uploads:no-uploads-found]]</div>
16
- <!-- ENDIF !uploads.length -->
5
+ <div class="alert alert-info text-center">
6
+ {{{ if privateUploads }}}[[uploads:private-uploads-info]]{{{ else }}}[[uploads:public-uploads-info]]{{{ end }}}
7
+ </div>
17
8
 
18
- <table class="table table-striped table-responsive">
19
- <thead>
20
- <tr>
21
- <th></th>
22
- <th></th>
23
- </tr>
24
- </thead>
25
- <tbody>
26
- {{{each uploads}}}
27
- <tr data-name="{uploads.name}">
28
- <td>
29
- <a class="text-break" href="{config.relative_path}{uploads.url}">{uploads.url}</a>
30
- </td>
31
- <td>
32
- <div class="btn-group ">
33
- <button class="btn btn-danger btn-sm" data-action="delete"><i class="fa fa-trash"></i></button>
34
- </div>
35
- </td>
36
- </tr>
37
- {{{end}}}
38
- </tbody>
39
- </table>
9
+ {{{ if !uploads.length }}}
10
+ <div class="alert alert-warning text-center">[[uploads:no-uploads-found]]</div>
11
+ {{{ end }}}
40
12
 
41
- <!-- IMPORT partials/paginator.tpl -->
42
- </div>
43
- </div>
44
- </div>
13
+ <table class="table table-striped table-responsive">
14
+ <thead>
15
+ <tr>
16
+ <th></th>
17
+ <th></th>
18
+ </tr>
19
+ </thead>
20
+ <tbody>
21
+ {{{ each uploads }}}
22
+ <tr data-name="{./name}">
23
+ <td>
24
+ <a class="text-break" href="{config.relative_path}{./url}">{./url}</a>
25
+ </td>
26
+ <td>
27
+ <div class="btn-group ">
28
+ <button class="btn btn-danger btn-sm" data-action="delete"><i class="fa fa-trash"></i></button>
29
+ </div>
30
+ </td>
31
+ </tr>
32
+ {{{ end }}}
33
+ </tbody>
34
+ </table>
35
+
36
+ <!-- IMPORT partials/paginator.tpl -->
37
+ <!-- IMPORT partials/account/footer.tpl -->
@@ -4,15 +4,33 @@
4
4
  <form role="form" class="harmony-settings">
5
5
  <div class="form-check form-switch">
6
6
  <input type="checkbox" class="form-check-input" id="enableQuickReply" name="enableQuickReply" />
7
- <label for="enableQuickReply" class="form-check-label">Enable quick reply</label>
7
+ <label for="enableQuickReply" class="form-check-label">[[harmony:settings.enableQuickReply]]</label>
8
8
  </div>
9
9
  <div class="form-check form-switch">
10
10
  <input type="checkbox" class="form-check-input" id="centerHeaderElements" name="centerHeaderElements" />
11
- <label for="centerHeaderElements" class="form-check-label">Center header elements</label>
11
+ <label for="centerHeaderElements" class="form-check-label">[[harmony:settings.centerHeaderElements]]</label>
12
+ </div>
13
+ <div class="form-check form-switch">
14
+ <input type="checkbox" class="form-check-input" id="mobileTopicTeasers" name="mobileTopicTeasers" />
15
+ <label for="mobileTopicTeasers" class="form-check-label">[[harmony:settings.mobileTopicTeasers]]</label>
12
16
  </div>
13
17
  <div class="form-check form-switch">
14
18
  <input type="checkbox" class="form-check-input" id="stickyToolbar" name="stickyToolbar" />
15
- <label for="stickyToolbar" class="form-check-label">Sticky toolbar on topic and category pages</label>
19
+ <div for="stickyToolbar" class="form-check-label">
20
+ [[harmony:settings.stickyToolbar]]
21
+ <p class="form-text">
22
+ [[harmony:settings.stickyToolbar.help]]
23
+ </p>
24
+ </div>
25
+ </div>
26
+ <div class="form-check form-switch">
27
+ <input type="checkbox" class="form-check-input" id="autohideBottombar" name="autohideBottombar" />
28
+ <div for="autohideBottombar" class="form-check-label">
29
+ [[harmony:settings.autohideBottombar]]
30
+ <p class="form-text">
31
+ [[harmony:settings.autohideBottombar.help]]
32
+ </p>
33
+ </div>
16
34
  </div>
17
35
  </form>
18
36
  </div>
@@ -3,16 +3,13 @@
3
3
  {{widgets.header.html}}
4
4
  {{{ end }}}
5
5
  </div>
6
- <div class="row">
6
+ <div class="row py-2">
7
7
  <div class="{{{ if widgets.sidebar.length }}}col-lg-9 col-sm-12{{{ else }}}col-lg-12{{{ end }}}">
8
8
  {{{ if pagination.pages.length }}}
9
- <div><!-- IMPORT partials/category-selector.tpl --></div>
9
+ <div><!-- IMPORT partials/category/selector-dropdown-left.tpl --></div>
10
10
  {{{ end }}}
11
- <ul class="categories list-unstyled" itemscope itemtype="http://www.schema.org/ItemList">
11
+ <ul class="categories-list list-unstyled" itemscope itemtype="http://www.schema.org/ItemList">
12
12
  {{{ each categories }}}
13
- {{{ if !@first }}}
14
- <hr class="text-muted opacity-25"/>
15
- {{{ end }}}
16
13
  <!-- IMPORT partials/categories/item.tpl -->
17
14
  {{{ end }}}
18
15
  </ul>
@@ -1,19 +1,10 @@
1
1
  <!-- IMPORT partials/breadcrumbs.tpl -->
2
-
3
- {{{ if widgets.header.length }}}
4
- <div data-widget-area="header">
5
- {{{ each widgets.header }}}
6
- {{widgets.header.html}}
7
- {{{ end }}}
8
- </div>
9
- {{{ end }}}
10
-
11
2
  <div class="d-flex flex-column gap-2">
12
- <div class="d-flex gap-2 align-items-center mb-1 {{{ if config.centerHeaderElements }}}justify-content-center{{{ end }}}">
3
+ <div class="d-flex gap-2 align-items-center mb-1 {{{ if config.theme.centerHeaderElements }}}justify-content-center{{{ end }}}">
13
4
  {buildCategoryIcon(@value, "40px", "rounded-1 flex-shrink-0")}
14
- <h2 class="fs-2 fw-semibold mb-0 text-center">{./name}</h2>
5
+ <h2 class="tracking-tight fs-2 fw-semibold mb-0 text-center">{./name}</h2>
15
6
  </div>
16
- <div class="d-flex flex-wrap gap-2 {{{ if config.centerHeaderElements }}}justify-content-center{{{ end }}}">
7
+ <div class="d-flex flex-wrap gap-2 {{{ if config.theme.centerHeaderElements }}}justify-content-center{{{ end }}}">
17
8
  <span class="badge text-body border border-gray-300 stats text-xs">
18
9
  <span title="{totalTopicCount}" class="human-readable-number fw-bold">{totalTopicCount}</span>
19
10
  <span class="text-lowercase fw-normal">[[global:topics]]</span>
@@ -25,6 +16,15 @@
25
16
  </div>
26
17
  </div>
27
18
 
19
+ {{{ if widgets.header.length }}}
20
+ <div data-widget-area="header">
21
+ {{{ each widgets.header }}}
22
+ {{widgets.header.html}}
23
+ {{{ end }}}
24
+ </div>
25
+ {{{ end }}}
26
+
27
+
28
28
  <div class="row mt-3">
29
29
  <div class="category d-flex flex-column {{{if widgets.sidebar.length }}}col-lg-9 col-sm-12{{{ else }}}col-lg-12{{{ end }}}">
30
30
  <!-- IMPORT partials/category/subcategory.tpl -->
@@ -33,8 +33,7 @@
33
33
 
34
34
  {{{ if !topics.length }}}
35
35
  {{{ if privileges.topics:create }}}
36
- <hr class="visible-xs" />
37
- <div class="alert alert-warning" id="category-no-topics">
36
+ <div class="alert alert-info" id="category-no-topics">
38
37
  [[category:no_topics]]
39
38
  </div>
40
39
  {{{ end }}}
@@ -1,27 +1,26 @@
1
- <div class="chats-full d-flex gap-1 vh-100 py-3">
2
- <div class="d-flex flex-column h-100" style="width:300px;" component="chat/nav-wrapper" data-loaded="{{{ if roomId }}}1{{{ else }}}0{{{ end }}}">
1
+ <div class="chats-full d-flex gap-1 h-100 mt-3 mt-md-0 py-md-3">
2
+ <div class="flex-shrink-0 d-flex flex-column h-100" component="chat/nav-wrapper" data-loaded="{{{ if roomId }}}1{{{ else }}}0{{{ end }}}">
3
3
  <div class="chat-search dropdown mb-2">
4
4
  <label class="text-xs text-muted">[[users:search-user-for-chat]]</label>
5
5
 
6
6
  <div class="input-group">
7
7
  <input class="form-control" type="text" component="chat/search" data-bs-toggle="dropdown" />
8
+ <ul component="chat/search/list" class="dropdown-menu">
9
+ <li><a href="#" class="dropdown-item rounded-1">[[admin/menu:search.start-typing]]</a></li>
10
+ </ul>
8
11
  <button class="btn btn-primary" type="button">
9
12
  <i class="fa fa-search"></i>
10
13
  </button>
11
14
  </div>
12
-
13
- <ul component="chat/search/list" class="dropdown-menu">
14
- <li><a href="#" class="dropdown-item">[[admin/menu:search.start-typing]]</a></li>
15
- </ul>
16
15
  </div>
17
- <hr class="text-muted opacity-25 my-1">
18
- <ul component="chat/recent" class="chats-list list-unstyled overflow-auto mb-0 pe-2" data-nextstart="{nextStart}">
16
+ <hr class="my-1">
17
+ <div component="chat/recent" class="chats-list overflow-auto mb-0 pe-1" data-nextstart="{nextStart}">
19
18
  {{{each rooms}}}
20
19
  <!-- IMPORT partials/chats/recent_room.tpl -->
21
20
  {{{end}}}
22
- </ul>
21
+ </div>
23
22
  </div>
24
- <div class="flex-1 ms-md-2 ps-md-2 border-1 border-start-md" component="chat/main-wrapper">
23
+ <div class="flex-grow-1 ms-md-2 ps-md-2 border-1 border-start-md h-100" component="chat/main-wrapper" style="min-width: 0;">
25
24
  <!-- IMPORT partials/chats/message-window.tpl -->
26
25
  </div>
27
26
  <div class="imagedrop"><div>[[topic:composer.drag_and_drop_images]]</div></div>
@@ -1,210 +1,177 @@
1
- <!-- THIS FILE IS STILL PERSONA -->
2
-
3
1
  <!-- IMPORT partials/breadcrumbs.tpl -->
4
2
 
5
- <div class="row">
6
- <div class="col-12">
7
- <h2 class="h4">
8
- {target_readable}
9
- <small><span class="text-muted timeago" title="{datetimeISO}"></span></small>
10
- </h2>
11
-
12
- <hr />
13
-
14
- <!-- IF type_bool.post -->
15
- <div class="d-flex">
16
- <div class="flex-shrink-0">
17
- <a href="{config.relative_path}/user/{target.user.userslug}">{buildAvatar(target.user, "64px", true, "media-object")}</a>
18
- </div>
19
- <div class="flex-grow-1 ms-3">
20
- <h4 class="media-heading"><a href="{config.relative_path}/user/{target.user.userslug}">{target.user.username}</a></h4>
21
- {target.content}
3
+ <div class="d-flex flex-column flex-md-row">
4
+ <div class="flex-shrink-0 d-flex flex-column gap-3 border-end-md text-sm mb-3 pe-4" style="flex-basis: 240px !important;">
5
+ <div class="d-grid gap-1">
6
+ <a class="btn btn-ghost border btn-sm justify-content-start" href="{config.relative_path}/{type_path}/{targetId}">
7
+ <i class="fa fa-fw fa-external-link text-primary"></i>
8
+ [[flags:go-to-target]]
9
+ </a>
10
+
11
+ {{{ if target.uid }}}
12
+ <div class="btn-group dropend" data-uid="{target.uid}">
13
+ <button type="button" class="btn btn-ghost border btn-sm justify-content-start dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
14
+ <i class="fa fa-fw fa-street-view text-primary"></i>
15
+ [[flags:flagged-user]]
16
+ </button>
17
+ <ul class="dropdown-menu p-1 text-sm">
18
+ <li><a class="dropdown-item rounded-1" href="{config.relative_path}/uid/{target.uid}">[[flags:view-profile]]</a></li>
19
+ {{{ if !config.disableChat }}}
20
+ <li><a class="dropdown-item rounded-1" href="#" data-action="chat">[[flags:start-new-chat]]</a></li>
21
+ {{{ end }}}
22
+ <li class="dropdown-divider"></li>
23
+ {{{ if privileges.ban }}}
24
+ <li class="{{{ if target.user.banned }}}hidden{{{ end }}}"><a class="dropdown-item rounded-1" href="#" data-action="ban">[[user:ban_account]]</a></li>
25
+ <li class="{{{ if !target.user.banned }}}hidden{{{ end }}}"><a class="dropdown-item rounded-1" href="#" data-action="unban">[[user:unban_account]]</a></li>
26
+ {{{ end }}}
27
+ {{{ if privileges.mute}}}
28
+ <li class="{{{ if target.user.muted }}}hidden{{{ end }}}"><a class="dropdown-item rounded-1" href="#" data-action="mute">[[user:mute_account]]</a></li>
29
+ <li class="{{{ if !target.user.muted }}}hidden{{{ end }}}"><a class="dropdown-item rounded-1" href="#" data-action="unmute">[[user:unmute_account]]</a></li>
30
+ {{{ end }}}
31
+ {{{ if privileges.admin:users }}}
32
+ <li><a class="dropdown-item rounded-1" href="#" data-action="delete-account">[[user:delete_account_as_admin]]</a></li>
33
+ <li><a class="dropdown-item rounded-1" href="#" data-action="delete-content">[[user:delete_content]]</a></li>
34
+ <li><a class="dropdown-item rounded-1" href="#" data-action="delete-all">[[user:delete_all]]</a></li>
35
+ {{{ end }}}
36
+ </ul>
22
37
  </div>
38
+ {{{ end }}}
39
+
40
+ <a class="btn btn-ghost border btn-sm justify-content-start" href="#" data-action="assign">
41
+ <i class="fa fa-fw fa-id-card-o text-primary"></i>
42
+ [[flags:assign-to-me]]
43
+ </a>
44
+
45
+ {{{ if type_bool.post }}}
46
+ {{{ if !target.deleted}}}
47
+ <a class="d-flex gap-2 align-items-center btn btn-sm btn-outline-danger border border-secondary-subtle text-start" href="#" data-action="delete-post"><i class="fa fa-fw fa-trash"></i> [[flags:delete-post]]</a>
48
+ {{{ else }}}
49
+ <a class="d-flex gap-2 align-items-center btn btn-sm btn-danger border border-secondary-subtle text-start" href="#" data-action="purge-post"><i class="fa fa-fw fa-trash"></i> [[flags:purge-post]]</a>
50
+ <a class="d-flex gap-2 align-items-center btn btn-sm btn-outline-success border border-secondary-subtle text-start" href="#" data-action="restore-post"><i class="fa fa-fw fa-reply"></i><i class="fa fa-trash"></i> [[flags:restore-post]]</a>
51
+ {{{ end }}}
52
+ {{{ end }}}
23
53
  </div>
24
- <!-- ENDIF type_bool.post -->
25
54
 
26
- <!-- IF type_bool.user -->
27
- <div class="d-flex">
28
- <div class="flex-shrink-0">
29
- <a href="{config.relative_path}/user/{target.userslug}">{buildAvatar(target, "64px", true, "media-object")}</a>
30
- </div>
31
- <div class="flex-grow-1 ms-3">
32
- <h4 class="media-heading"><a href="{config.relative_path}/user/{target.userslug}">{target.username}</a></h4>
33
- <p class="lead">
34
- <a href="{config.relative_path}/uid/{target.uid}">[[flags:user-view]]</a> |
35
- <a href="{config.relative_path}/uid/{target.uid}/edit">[[flags:user-edit]]</a>
36
- </p>
55
+ <form class="d-flex flex-column gap-3" id="attributes">
56
+ <div>
57
+ <label class="text-muted fw-semibold" for="state">[[flags:state]]</label>
58
+ <select class="form-select form-select-sm" id="state" name="state" disabled>
59
+ <option value="open">[[flags:state-open]]</option>
60
+ <option value="wip">[[flags:state-wip]]</option>
61
+ <option value="resolved">[[flags:state-resolved]]</option>
62
+ <option value="rejected">[[flags:state-rejected]]</option>
63
+ </select>
37
64
  </div>
38
- </div>
39
- <!-- ENDIF type_bool.user -->
40
-
41
- <!-- IF type_bool.empty -->
42
- <div class="alert alert-warning" role="alert">[[flags:target-purged]]</div>
43
- <!-- ENDIF type_bool.empty -->
44
-
45
- <hr />
46
-
47
- <div class="row">
48
- <div class="col-sm-6">
49
- <form role="form" id="attributes">
50
- <div class="mb-3">
51
- <h2 class="h4">[[flags:reports]]</h2>
52
- <ul class="list-group" component="flag/reports">
53
- {{{ each reports }}}
54
- <li class="list-group-item">
55
- <a href="{config.relative_path}/user/{./reporter.userslug}">{buildAvatar(./reporter, "24px", true)}</a>
56
- &ndash; <span class="timeago" title="{./timestampISO}"></span>
57
- <blockquote><em>{./value}</em></blockquote>
58
- </li>
59
- {{{ end }}}
60
- </ul>
61
- </div>
62
- <div class="mb-3">
63
- <h2 class="h4" for="state">[[flags:state]]</h2>
64
- <select class="form-select" id="state" name="state" disabled>
65
- <option value="open">[[flags:state-open]]</option>
66
- <option value="wip">[[flags:state-wip]]</option>
67
- <option value="resolved">[[flags:state-resolved]]</option>
68
- <option value="rejected">[[flags:state-rejected]]</option>
69
- </select>
70
- </div>
71
- <div class="mb-3">
72
- <h2 class="h4" for="assignee">[[flags:assignee]]</h2>
73
- <select class="form-control" id="assignee" name="assignee" disabled>
74
- <option value="">[[flags:no-assignee]]</option>
75
- {{{each assignees}}}
76
- <option value="{../uid}">{../username}</option>
77
- {{{end}}}
78
- </select>
79
- </div>
80
- <div class="d-grid">
81
- <button type="button" class="btn btn-primary" data-action="update">[[flags:update]]</button>
82
- </div>
83
- </form>
84
-
85
- <hr />
86
-
87
- <form role="form">
88
- <div class="mb-3">
89
- <h2 class="h4" for="note">[[flags:notes]]</h2>
90
- <textarea id="note" class="form-control"></textarea>
91
- <div class="d-grid">
92
- <button type="button" class="btn btn-block btn-primary" data-action="appendNote">[[flags:add-note]]</button>
93
- </div>
94
- </div>
95
- </form>
96
-
97
- <div component="flag/notes">
98
- <!-- IF !notes.length -->
99
- <div class="alert alert-success text-center">[[flags:no-notes]]</div>
100
- <!-- ENDIF !notes.length -->
101
- {{{each notes}}}
102
- <div class="d-flex mb-3">
103
- <div class="flex-shrink-0">
104
- <a href="{config.relative_path}/user/{../user.userslug}">{buildAvatar(notes.user, "32px", true, "media-object")}</a>
105
- </div>
106
- <div class="flex-grow-1 mx-3">
107
- <h2 class="h5">
108
- <a href="{config.relative_path}/user/{../user.userslug}">{../user.username}</a>
109
- <small><span class="timeago" title="{../datetimeISO}"></span></small>
110
- </h4>
111
- {../content}
112
- </div>
113
- <div class="flex-shrink-0">
114
- <a href="#" class="btn btn-sm btn-link" data-action="prepare-edit"><i class="fa fa-pencil"></i></a>
115
- <a href="#" class="btn btn-sm btn-link" data-action="delete-note"><i class="fa fa-trash text-danger"></i></a>
116
- </div>
117
- </div>
65
+ <div>
66
+ <label class="text-muted fw-semibold" for="assignee">[[flags:assignee]]</label>
67
+ <select class="form-control form-control-sm" id="assignee" name="assignee" disabled>
68
+ <option value="">[[flags:no-assignee]]</option>
69
+ {{{each assignees}}}
70
+ <option value="{../uid}">{../username}</option>
118
71
  {{{end}}}
72
+ </select>
73
+ </div>
74
+ <div class="d-grid">
75
+ <button type="button" class="btn btn-primary" data-action="update">[[flags:update]]</button>
76
+ </div>
77
+ </form>
78
+
79
+ <div class="overflow-auto" component="flag/history">
80
+ <h2 class="h6 fw-bold">[[flags:history]]</h2>
81
+ {{{ if !history.length }}}
82
+ <div class="alert alert-success text-center">[[flags:no-history]]</div>
83
+ {{{ end }}}
84
+ {{{ each history }}}
85
+ <div class="d-flex flex-column gap-1">
86
+ <div class="d-flex gap-2 align-items-center">
87
+ <a class="d-flex text-decoration-none" href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(./user, "16px", true)}</a>
88
+ <a href="{config.relative_path}/user/{./user.userslug}">{./user.username}</a>
89
+ <span class="timeago text-muted" title="{./datetimeISO}"></span>
90
+ </div>
91
+ <div>
92
+ <ul class="list-unstyled">
93
+ {{{ each ./fields }}}
94
+ <li>
95
+ [[flags:{@key}]]{{{ if @value }}} &rarr; <span class="fw-semibold">{@value}</span>{{{ end }}}
96
+ </li>
97
+ {{{ end }}}
98
+ {{{ each ./meta }}}
99
+ <li>
100
+ {{./key}}{{{ if ./value }}} &rarr; <span class="fw-semibold">{./value}</span>{{{ end }}}
101
+ </li>
102
+ {{{ end }}}
103
+ </ul>
119
104
  </div>
120
105
  </div>
121
- <div class="col-sm-6">
122
- <h2 class="h4">[[flags:quick-actions]]</h2>
123
-
124
- <div class="d-grid gap-1">
125
- <a class="btn btn-light" href="{config.relative_path}/{type_path}/{targetId}">
126
- <i class="fa fa-external-link"></i>
127
- [[flags:go-to-target]]
128
- </a>
129
-
130
- <a class="btn btn-light" href="#" data-action="assign">
131
- <i class="fa fa-id-card-o"></i>
132
- [[flags:assign-to-me]]
133
- </a>
134
-
135
- {{{ if type_bool.post }}}
136
- {{{ if !target.deleted}}}
137
- <a class="btn btn-outline-danger" href="#" data-action="delete-post"><i class="fa fa-trash"></i> [[flags:delete-post]]</a>
138
- {{{ else }}}
139
- <a class="btn btn-danger" href="#" data-action="purge-post"><i class="fa fa-trash"></i> [[flags:purge-post]]</a>
140
- <a class="btn btn-outline-success" href="#" data-action="restore-post"><i class="fa fa-reply"></i><i class="fa fa-trash"></i> [[flags:restore-post]]</a>
141
- {{{ end }}}
142
- {{{ end }}}
143
-
144
- {{{ if target.uid }}}
145
- <div class="btn-group" data-uid="{target.uid}">
146
- <button type="button" class="btn btn-light dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
147
- <i class="fa fa-street-view"></i>
148
- [[flags:flagged-user]]
149
- <span class="caret"></span>
150
- </button>
151
- <ul class="dropdown-menu">
152
- <li><a class="dropdown-item" href="{config.relative_path}/uid/{target.uid}">[[flags:view-profile]]</a></li>
153
- {{{ if !config.disableChat }}}
154
- <li><a class="dropdown-item" href="#" data-action="chat">[[flags:start-new-chat]]</a></li>
155
- {{{ end }}}
156
- <li class="dropdown-divider"></li>
157
- {{{ if privileges.ban }}}
158
- <li class="{{{ if target.user.banned }}}hidden{{{ end }}}"><a class="dropdown-item" href="#" data-action="ban">[[user:ban_account]]</a></li>
159
- <li class="{{{ if !target.user.banned }}}hidden{{{ end }}}"><a class="dropdown-item" href="#" data-action="unban">[[user:unban_account]]</a></li>
160
- {{{ end }}}
161
- {{{ if privileges.mute}}}
162
- <li class="{{{ if target.user.muted }}}hidden{{{ end }}}"><a class="dropdown-item" href="#" data-action="mute">[[user:mute_account]]</a></li>
163
- <li class="{{{ if !target.user.muted }}}hidden{{{ end }}}"><a class="dropdown-item" href="#" data-action="unmute">[[user:unmute_account]]</a></li>
164
- {{{ end }}}
165
- {{{ if privileges.admin:users }}}
166
- <li><a class="dropdown-item" href="#" data-action="delete-account">[[user:delete_account_as_admin]]</a></li>
167
- <li><a class="dropdown-item" href="#" data-action="delete-content">[[user:delete_content]]</a></li>
168
- <li><a class="dropdown-item" href="#" data-action="delete-all">[[user:delete_all]]</a></li>
169
- {{{ end }}}
170
- </ul>
171
- </div>
172
- {{{ end }}}
106
+ {{{ end }}}
107
+ </div>
108
+ </div>
109
+ <div class="flex-grow-1 ps-md-2 ps-lg-5" style="min-width:0;">
110
+ <div class="d-flex flex-column gap-4">
111
+ <h2 class="h6 fw-bold">
112
+ {target_readable}
113
+ </h2>
114
+ <div component="flag/content" class="d-flex flex-column gap-1 pb-3 border-bottom">
115
+ {{{ if type_bool.post }}}
116
+ <div class="d-flex gap-2 align-items-center">
117
+ <a class="d-flex text-decoration-none" href="{config.relative_path}/user/{target.user.userslug}">{buildAvatar(target.user, "16px", true)}</a>
118
+ <a href="{config.relative_path}/user/{target.user.userslug}">{target.user.username}</a>
119
+ <span class="timeago text-muted" title="{target.timestampISO}"></span>
173
120
  </div>
121
+ <blockquote>{target.content}</blockquote>
122
+ {{{ end }}}
174
123
 
175
- <hr />
124
+ {{{ if type_bool.user }}}
125
+ <div class="d-flex gap-2">
126
+ <a href="{config.relative_path}/user/{./target.userslug}">{buildAvatar(target, "16px", true)}</a>
127
+ <a href="{config.relative_path}/user/{./target.userslug}">{target.username}</a>
128
+ </div>
129
+ <blockquote>{{{ if target.aboutme }}}{target.aboutme}{{{ else }}}<em>[[flags:target-aboutme-empty]]</em>{{{ end }}}</blockquote>
130
+ {{{ end }}}
176
131
 
177
- <h2 class="h4">[[flags:history]]</h2>
178
- <div component="flag/history">
179
- <!-- IF !history.length -->
180
- <div class="alert alert-success text-center">[[flags:no-history]]</div>
181
- <!-- ENDIF !history.length -->
182
- {{{each history}}}
183
- <div class="d-flex">
184
- <div class="flex-shrink-0">
185
- <a href="{config.relative_path}/user/{../user.userslug}">{buildAvatar(history.user, "32px", true, "media-object")}</a>
186
- </div>
187
- <div class="flex-grow-1 ms-3">
188
- <h4 class="media-heading">
189
- <a href="{config.relative_path}/user/{../user.userslug}">{../user.username}</a>
190
- <small><span class="timeago" title="{../datetimeISO}"></span></small>
191
- </h4>
192
- <ul>
193
- {{{each ./fields}}}
194
- <li>
195
- <span class="badge bg-primary">[[flags:{@key}]]</span><!-- IF @value --> &rarr; <span class="badge bg-light text-dark">{@value}</span><!-- ENDIF @value -->
196
- </li>
197
- {{{end}}}
198
- {{{ each ./meta }}}
199
- <li>
200
- <span class="badge bg-{{./labelClass}}">{{./key}}</span>{{{ if ./value }}} &rarr; <span class="badge bg-light text-dark">{{ ./value }}</span>{{{ end }}}
201
- </li>
202
- {{{ end }}}
203
- </ul>
132
+ {{{ if type_bool.empty }}}
133
+ <div class="alert alert-warning" role="alert">[[flags:target-purged]]</div>
134
+ {{{ end }}}
135
+ </div>
136
+ <div class="flag/reports" class="pb-4 border-bottom">
137
+ <h2 class="h6 fw-bold">[[flags:reports]]</h2>
138
+ <ul class="list-unstyled mt-4">
139
+ {{{ each reports }}}
140
+ <li class="d-flex flex-column gap-1" component="flag/report" data-timestamp="{./timestamp}">
141
+ <div class="d-flex gap-2 align-items-center">
142
+ <a class="d-flex text-decoration-none" href="{config.relative_path}/user/{./reporter.userslug}">{buildAvatar(./reporter, "16px", true)}</a>
143
+ <a href="{config.relative_path}/user/{./reporter.userslug}">{./reporter.username}</a>
144
+ <span class="timeago text-muted" title="{./timestampISO}"></span>
204
145
  </div>
205
- </div>
206
- {{{end}}}
146
+ <p>{./value}</p>
147
+ </li>
148
+ {{{ end }}}
149
+ </ul>
150
+ </div>
151
+ <div class="pb-4 border-bottom">
152
+ <div class="d-flex align-items-center">
153
+ <h2 class="h6 fw-bold me-auto mb-0">[[flags:notes]]</h2>
154
+ <button class="btn btn-ghost border" data-action="addEditNote">[[flags:add-note]]</button>
207
155
  </div>
156
+ <ul component="flag/notes" class="list-unstyled mt-4">
157
+ {{{ if !notes.length }}}
158
+ <em>[[flags:no-notes]]</em>
159
+ {{{ end }}}
160
+ {{{ each notes }}}
161
+ <li class="d-flex flex-column gap-1" component="flag/note" data-datetime="{./datetime}" data-index="{@index}">
162
+ <div class="d-flex gap-2 align-items-center">
163
+ <a href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(./user, "16px", true)}</a>
164
+ <a href="{config.relative_path}/user/{./user.userslug}">{./user.username}</a>
165
+ <span class="timeago text-muted" title="{./datetimeISO}"></span>
166
+ <div class=" ms-auto flex-shrink-0">
167
+ <a href="#" class="btn btn-sm btn-link" data-action="addEditNote"><i class="fa fa-pencil"></i></a>
168
+ <a href="#" class="btn btn-sm btn-link" data-action="delete-note"><i class="fa fa-trash text-danger"></i></a>
169
+ </div>
170
+ </div>
171
+ <p>{./content}</p>
172
+ </li>
173
+ {{{ end }}}
174
+ </ul>
208
175
  </div>
209
176
  </div>
210
177
  </div>