nodebb-theme-harmony 0.0.1 → 0.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 (139) hide show
  1. package/languages/en-GB/harmony.json +5 -0
  2. package/library.js +101 -26
  3. package/package.json +5 -2
  4. package/plugin.json +14 -2
  5. package/public/harmony.js +101 -0
  6. package/scss/account.scss +38 -0
  7. package/scss/chats.scss +72 -0
  8. package/scss/common.scss +65 -0
  9. package/scss/fonts.scss +17 -0
  10. package/scss/groups.scss +30 -0
  11. package/scss/harmony.scss +23 -3
  12. package/scss/header.scss +16 -0
  13. package/scss/mixins.scss +183 -0
  14. package/scss/modals.scss +4 -0
  15. package/scss/modules/bottom-sheet.scss +52 -0
  16. package/scss/modules/breadcrumbs.scss +16 -0
  17. package/scss/modules/composer.scss +21 -0
  18. package/scss/modules/cover.scss +115 -0
  19. package/scss/modules/tags.scss +6 -0
  20. package/scss/modules/topic-navigator.scss +61 -0
  21. package/scss/modules/topics-list.scss +20 -0
  22. package/scss/modules/user-menu.scss +5 -0
  23. package/scss/overrides.scss +65 -0
  24. package/scss/sidebar.scss +125 -0
  25. package/scss/skins.scss +13 -0
  26. package/scss/status.scss +25 -0
  27. package/scss/topic.scss +128 -0
  28. package/templates/account/best.tpl +0 -2
  29. package/templates/account/blocks.tpl +31 -26
  30. package/templates/account/bookmarks.tpl +0 -2
  31. package/templates/account/categories.tpl +1 -3
  32. package/templates/account/controversial.tpl +0 -2
  33. package/templates/account/downvoted.tpl +0 -2
  34. package/templates/account/followers.tpl +14 -10
  35. package/templates/account/following.tpl +14 -10
  36. package/templates/account/groups.tpl +13 -11
  37. package/templates/account/ignored.tpl +0 -2
  38. package/templates/account/posts.tpl +29 -10
  39. package/templates/account/profile.tpl +76 -159
  40. package/templates/account/topics.tpl +32 -21
  41. package/templates/account/uploads.tpl +38 -35
  42. package/templates/account/upvoted.tpl +0 -2
  43. package/templates/account/watched.tpl +0 -2
  44. package/templates/admin/plugins/harmony.tpl +17 -0
  45. package/templates/categories.tpl +5 -5
  46. package/templates/category.tpl +26 -26
  47. package/templates/chat.tpl +9 -9
  48. package/templates/chats.tpl +5 -7
  49. package/templates/footer.tpl +11 -7
  50. package/templates/groups/details.tpl +74 -64
  51. package/templates/groups/list.tpl +19 -14
  52. package/templates/header.tpl +34 -21
  53. package/templates/login.tpl +51 -45
  54. package/templates/partials/account/admin-menu.tpl +36 -0
  55. package/templates/partials/account/category-item.tpl +17 -17
  56. package/templates/partials/account/header.tpl +77 -35
  57. package/templates/partials/account/sidebar-left.tpl +82 -0
  58. package/templates/partials/breadcrumbs.tpl +4 -12
  59. package/templates/partials/categories/item.tpl +48 -44
  60. package/templates/partials/categories/lastpost.tpl +17 -19
  61. package/templates/partials/categories/link.tpl +5 -13
  62. package/templates/partials/category/sort.tpl +4 -7
  63. package/templates/partials/category/subcategory.tpl +4 -4
  64. package/templates/partials/category/tools.tpl +6 -9
  65. package/templates/partials/category/watch.tpl +7 -11
  66. package/templates/partials/category-filter-content.tpl +5 -6
  67. package/templates/partials/category-filter.tpl +0 -2
  68. package/templates/partials/category-selector-content.tpl +4 -5
  69. package/templates/partials/category-selector.tpl +0 -2
  70. package/templates/partials/chats/dropdown.tpl +24 -32
  71. package/templates/partials/chats/message-window.tpl +7 -7
  72. package/templates/partials/chats/message.tpl +34 -34
  73. package/templates/partials/chats/recent_room.tpl +16 -29
  74. package/templates/partials/chats/system-message.tpl +4 -4
  75. package/templates/partials/chats/user.tpl +1 -3
  76. package/templates/partials/groups/admin.tpl +82 -183
  77. package/templates/partials/groups/badge.tpl +1 -3
  78. package/templates/partials/groups/invited.tpl +33 -0
  79. package/templates/partials/groups/list.tpl +14 -21
  80. package/templates/partials/groups/memberlist.tpl +28 -24
  81. package/templates/partials/groups/pending.tpl +30 -0
  82. package/templates/partials/groups/sidebar-left.tpl +27 -0
  83. package/templates/partials/mobile-footer.tpl +70 -0
  84. package/templates/partials/notifications_list.tpl +19 -27
  85. package/templates/partials/paginator.tpl +22 -24
  86. package/templates/partials/post_bar.tpl +23 -18
  87. package/templates/partials/posts_list.tpl +0 -2
  88. package/templates/partials/posts_list_item.tpl +14 -29
  89. package/templates/partials/quick-search-results.tpl +36 -25
  90. package/templates/partials/search-results.tpl +4 -1
  91. package/templates/partials/sidebar/chats.tpl +53 -0
  92. package/templates/partials/sidebar/drafts.tpl +41 -0
  93. package/templates/partials/sidebar/logged-out-menu.tpl +38 -0
  94. package/templates/partials/sidebar/notifications.tpl +28 -0
  95. package/templates/partials/sidebar/search-mobile.tpl +29 -0
  96. package/templates/partials/sidebar/search.tpl +30 -0
  97. package/templates/partials/sidebar/user-menu.tpl +87 -0
  98. package/templates/partials/sidebar-left.tpl +40 -0
  99. package/templates/partials/sidebar-right.tpl +41 -0
  100. package/templates/partials/skin-switcher.tpl +35 -0
  101. package/templates/partials/tags_list.tpl +0 -2
  102. package/templates/partials/toast.tpl +6 -8
  103. package/templates/partials/topic/event.tpl +4 -20
  104. package/templates/partials/topic/navigator.tpl +20 -41
  105. package/templates/partials/topic/necro-post.tpl +5 -4
  106. package/templates/partials/topic/post-menu.tpl +23 -2
  107. package/templates/partials/topic/post-placeholder.tpl +15 -0
  108. package/templates/partials/topic/post.tpl +67 -64
  109. package/templates/partials/topic/quickreply.tpl +12 -14
  110. package/templates/partials/topic/reactions.tpl +0 -2
  111. package/templates/partials/topic/reply-button.tpl +16 -20
  112. package/templates/partials/topic/selection-tooltip.tpl +0 -2
  113. package/templates/partials/topic/sort.tpl +8 -6
  114. package/templates/partials/topic/stats.tpl +15 -14
  115. package/templates/partials/topic/tag.tpl +1 -3
  116. package/templates/partials/topic/tags.tpl +1 -5
  117. package/templates/partials/topic/tools.tpl +13 -0
  118. package/templates/partials/topic/watch.tpl +15 -13
  119. package/templates/partials/topic-filters.tpl +4 -5
  120. package/templates/partials/topic-list-bar.tpl +54 -0
  121. package/templates/partials/topic-terms.tpl +4 -5
  122. package/templates/partials/topics_list.tpl +109 -100
  123. package/templates/partials/users/item.tpl +7 -0
  124. package/templates/partials/users_list.tpl +11 -60
  125. package/templates/partials/users_list_menu.tpl +10 -18
  126. package/templates/popular.tpl +1 -18
  127. package/templates/recent.tpl +8 -24
  128. package/templates/register.tpl +74 -60
  129. package/templates/tag.tpl +3 -15
  130. package/templates/tags.tpl +3 -4
  131. package/templates/top.tpl +1 -18
  132. package/templates/topic.tpl +39 -43
  133. package/templates/unread.tpl +1 -22
  134. package/templates/users.tpl +17 -17
  135. package/templates/admin/plugins/persona.tpl +0 -29
  136. package/templates/partials/account/menu.tpl +0 -103
  137. package/templates/partials/header/user-menu.tpl +0 -87
  138. package/templates/partials/menu.tpl +0 -188
  139. package/templates/partials/thread_tools.tpl +0 -10
@@ -1,36 +1,36 @@
1
- <!-- THIS FILE IS STILL PERSONA -->
1
+ <li component="chat/message" class="chat-message mx-2 pe-2 fw-light clear<!-- IF ../deleted --> deleted<!-- END -->" data-index="{messages.index}" data-mid="{messages.messageId}" data-uid="{messages.fromuid}" data-self="{messages.self}" data-break="{messages.newSet}" data-timestamp="{messages.timestamp}">
2
+ <div class="message-header {{{ if !messages.newSet }}}hidden{{{ end }}} pb-2">
3
+ <a href="{config.relative_path}/user/{messages.fromUser.userslug}" class="text-decoration-none">{buildAvatar(messages.fromUser, "24px", false, "not-responsive rounded")}</a>
4
+ <span class="chat-user fw-bold"><a href="{config.relative_path}/user/{messages.fromUser.userslug}">{messages.fromUser.displayname}</a></span>
5
+ <!-- IF ../fromUser.banned -->
6
+ <span class="badge bg-danger">[[user:banned]]</span>
7
+ <!-- END -->
8
+ <!-- IF ../fromUser.deleted -->
9
+ <span class="badge bg-danger">[[user:deleted]]</span>
10
+ <!-- END -->
11
+ <small class="chat-timestamp text-muted ms-2 timeago" title="{messages.timestampISO}"></small>
12
+ <!-- IF messages.edited -->
13
+ <div class="text-muted float-end" title="[[global:edited]] {messages.editedISO}"><i class="fa fa-edit"></i></span></div>
14
+ <!-- ENDIF messages.edited -->
15
+ </div>
16
+ <div class="message-body-wrapper hover-parent">
17
+ <div component="chat/message/body" class="message-body ps-0 py-0 overflow-auto">
18
+ {messages.content}
19
+ </div>
2
20
 
3
- <li component="chat/message" class="chat-message mx-2 pe-2 fw-light clear<!-- IF ../deleted --> deleted<!-- END -->" data-index="{messages.index}" data-mid="{messages.messageId}" data-uid="{messages.fromuid}" data-self="{messages.self}" data-break="{messages.newSet}" data-timestamp="{messages.timestamp}">
4
- <div class="message-header">
5
- <a href="{config.relative_path}/user/{messages.fromUser.userslug}">{buildAvatar(messages.fromUser, "32px", true, "not-responsive")}</a>
6
- <span class="chat-user fw-bold"><a href="{config.relative_path}/user/{messages.fromUser.userslug}">{messages.fromUser.displayname}</a></span>
7
- <!-- IF ../fromUser.banned -->
8
- <span class="badge bg-danger">[[user:banned]]</span>
9
- <!-- END -->
10
- <!-- IF ../fromUser.deleted -->
11
- <span class="badge bg-danger">[[user:deleted]]</span>
12
- <!-- END -->
13
- <small class="chat-timestamp text-muted ms-2 timeago" title="{messages.timestampISO}"></small>
14
- <!-- IF messages.edited -->
15
- <div class="text-muted float-end" title="[[global:edited]] {messages.editedISO}"><i class="fa fa-edit"></i></span></div>
16
- <!-- ENDIF messages.edited -->
17
- </div>
18
- <div class="message-body-wrapper">
19
- <div component="chat/message/body" class="message-body">
20
- {messages.content}
21
- </div>
22
-
23
- <!-- IF !config.disableChatMessageEditing -->
24
- <!-- IF messages.self -->
25
- <div class="btn-group controls">
26
- <button class="btn btn-sm btn-link" data-action="edit"><i class="fa fa-pencil"></i></button>
27
- <button class="btn btn-sm btn-link" data-action="delete"><i class="fa fa-times"></i></button>
28
- <button class="btn btn-sm btn-link" data-action="restore"><i class="fa fa-repeat"></i></button>
29
- <!-- IF isAdminOrGlobalMod -->
30
- <button class="btn btn-sm btn-link chat-ip" title="[[modules:chat.show-ip]]"><i class="fa fa-info-circle chat-ip-button"></i></button>
31
- <!-- ENDIF isAdminOrGlobalMod -->
32
- </div>
33
- <!-- ENDIF messages.self -->
34
- <!-- ENDIF !config.disableChatMessageEditing -->
35
- </div>
21
+ <!-- IF !config.disableChatMessageEditing -->
22
+ <!-- IF messages.self -->
23
+ <div class="position-relative">
24
+ <div class="btn-group border shadow-sm controls position-absolute small hover-d-block" style="bottom:5px; right:30px; display:none;">
25
+ <button class="btn btn-sm btn-link" data-action="edit"><i class="fa fa-pencil"></i></button>
26
+ <button class="btn btn-sm btn-link" data-action="delete"><i class="fa fa-trash"></i></button>
27
+ <button class="btn btn-sm btn-link" data-action="restore"><i class="fa fa-repeat"></i></button>
28
+ <!-- IF isAdminOrGlobalMod -->
29
+ <button class="btn btn-sm btn-link chat-ip" title="[[modules:chat.show-ip]]"><i class="fa fa-info-circle chat-ip-button"></i></button>
30
+ <!-- ENDIF isAdminOrGlobalMod -->
31
+ </div>
32
+ </div>
33
+ <!-- ENDIF messages.self -->
34
+ <!-- ENDIF !config.disableChatMessageEditing -->
35
+ </div>
36
36
  </li>
@@ -1,33 +1,20 @@
1
- <!-- THIS FILE IS STILL PERSONA -->
2
-
3
- <li component="chat/recent/room" data-roomid="{rooms.roomId}" class="<!-- IF rooms.unread -->unread<!-- ENDIF rooms.unread -->">
4
- {{{each rooms.users}}}
5
- <!-- IF @first -->
6
- <div class="main-avatar me-2">
7
- <!-- IMPORT partials/chats/user.tpl -->
1
+ <li component="chat/recent/room" data-roomid="{rooms.roomId}" class="{{{ if rooms.unread }}}unread{{{ end }}} card card-body p-1 mb-1 border-0 pointer">
2
+ <div class="members">
3
+ {{{ each rooms.users}}}
4
+ {{{ if @first }}}
5
+ <div class="main-avatar">
6
+ <a href="{config.relative_path}/user/{rooms.users.userslug}" class="text-decoration-none">{buildAvatar(rooms.users, "24px", true)}</a>
7
+ <span component="chat/title">{{{ if rooms.roomName }}}{rooms.roomName}{{{ else }}}{rooms.usernames}{{{ end }}}</span>
8
8
  </div>
9
- <!-- ENDIF @first -->
10
- {{{end}}}
11
-
12
- {{{ if rooms.users.length }}}
13
- <ul class="members">
14
- {{{each rooms.users}}}
15
- <li>
16
- <!-- IMPORT partials/chats/user.tpl -->
17
- </li>
18
- {{{end}}}
19
- </ul>
9
+ {{{ else }}}
10
+ <a href="{config.relative_path}/user/{rooms.users.userslug}" class="text-decoration-none">{buildAvatar(rooms.users, "24px", true)}</a>
11
+ {{{ end }}}
12
+ {{{ end }}}
13
+ {{{ if !./users.length}}}
14
+ <span class="avatar avatar-rounded text-bg-warning" component="avatar/icon" style="--avatar-size: 24px;">?</span>
15
+ {{{ if !rooms.lastUser.uid }}}
16
+ <span class="text-muted">[[modules:chat.no-users-in-room]]</span>
17
+ {{{ end }}}
20
18
  {{{ end }}}
21
-
22
- <div class="notification-chat-content flex-grow-1">
23
- <!-- IF !rooms.lastUser.uid -->
24
- <div class="p-3 text-center h-100">
25
- <span>[[modules:chat.no-users-in-room]]</span>
26
- </div>
27
- <!-- ELSE -->
28
- <strong class="room-name">
29
- <span component="chat/title"><!-- IF rooms.roomName -->{rooms.roomName}<!-- ELSE -->{rooms.usernames}<!-- ENDIF rooms.roomName --></span>
30
- </strong>
31
- <!-- ENDIF !rooms.lastUser.uid -->
32
19
  </div>
33
20
  </li>
@@ -1,5 +1,5 @@
1
- <!-- THIS FILE IS STILL PERSONA -->
2
-
3
- <li component="chat/system-message" class="system-message fs-6 py-3 clear" data-index="{messages.index}" data-mid="{messages.messageId}" data-uid="{messages.fromuid}" data-self="{messages.self}" data-break="0" data-timestamp="{messages.timestamp}">
4
- [[modules:chat.system.{messages.content}, {messages.fromUser.username}]]
1
+ <li component="chat/system-message" class="system-message text-muted small py-2 gap-3 d-flex align-items-center justify-content-center" data-index="{messages.index}" data-mid="{messages.messageId}" data-uid="{messages.fromuid}" data-self="{messages.self}" data-break="0" data-timestamp="{messages.timestamp}">
2
+ <hr class="d-inline-block my-1" style="width: 10%;"/>
3
+ [[modules:chat.system.{messages.content}, {messages.fromUser.username}]]
4
+ <hr class="d-inline-block my-1" style="width: 10%;"/>
5
5
  </li>
@@ -1,3 +1 @@
1
- <!-- THIS FILE IS STILL PERSONA -->
2
-
3
- <a href="{config.relative_path}/user/{rooms.users.userslug}">{buildAvatar(rooms.users, "28px", true)}</a>
1
+ <a href="{config.relative_path}/user/{rooms.users.userslug}" class="text-decoration-none">{buildAvatar(rooms.users, "32px", true)}</a>
@@ -1,197 +1,96 @@
1
- <!-- THIS FILE IS STILL PERSONA -->
2
-
3
- <div class="card mb-3">
4
- <div class="card-header">
5
- <div class="fs-5">
6
- <i class="fa fa-clock-o"></i> [[groups:details.pending]]
7
- <!-- IF group.pending.length -->
8
- <div class="btn-group float-end">
9
- <button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
10
- [[global:more]] <span class="caret"></span>
11
- </button>
12
- <ul class="dropdown-menu" role="menu">
13
- <li><a class="dropdown-item" href="#" data-ajaxify="false" data-action="acceptAll">[[groups:pending.accept_all]]</a></li>
14
- <li><a class="dropdown-item" href="#" data-ajaxify="false" data-action="rejectAll">[[groups:pending.reject_all]]</a></li>
15
- </ul>
16
- </div>
17
- <!-- ENDIF group.pending.length -->
18
- </div>
19
- </div>
20
- <div class="card-body">
21
- <table component="groups/pending" class="table table-striped table-hover">
22
- <!-- IF !group.pending.length -->
23
- <div class="alert alert-info">[[groups:pending.none]]</div>
24
- <!-- ENDIF !group.pending.length -->
25
- {{{each group.pending}}}
26
- <tr data-uid="{group.pending.uid}">
27
- <td class="p-2">
28
- <a href="{config.relative_path}/user/{group.pending.userslug}">{buildAvatar(group.pending, "24px", true)}</a>
29
- </td>
30
- <td class="member-name p-2">
31
- <a href="{config.relative_path}/user/{group.pending.userslug}">{group.pending.username}</a>
32
- </td>
33
- <td class="p-2">
34
- <div class="btn-group float-end">
35
- <button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
36
- [[global:more]] <span class="caret"></span>
37
- </button>
38
- <ul class="dropdown-menu" role="menu">
39
- <li><a class="dropdown-item" href="#" data-ajaxify="false" data-action="accept">[[groups:pending.accept]]</a></li>
40
- <li><a class="dropdown-item" href="#" data-ajaxify="false" data-action="reject">[[groups:pending.reject]]</a></li>
41
- </ul>
42
- </div>
43
- </td>
44
- </tr>
45
- {{{end}}}
46
- </table>
47
- </div>
48
- </div>
49
- <div class="card mb-3">
50
- <div class="card-header">
51
- <span class="fs-5">
52
- <i class="fa fa-gift"></i> [[groups:details.invited]]
53
- </span>
54
- </div>
55
- <div class="card-body">
56
- <div class="input-group mb-2">
57
- <input class="form-control" type="text" component="groups/members/invite" placeholder="[[groups:invited.search]]"/>
58
- <span class="input-group-text search-button"><i class="fa fa-search"></i></span>
59
- </div>
60
-
61
- <div class="mb-2">
62
- <textarea class="form-control" component="groups/members/bulk-invite" placeholder="[[groups:bulk-invite-instructions]]"></textarea>
63
- </div>
64
-
65
- <div class="mb-2 clearfix">
66
- <button class="btn btn-outline-secondary btn-sm float-end" component="groups/members/bulk-invite-button">[[groups:bulk-invite]]</button>
67
- </div>
68
-
69
- <table component="groups/invited" class="table table-striped table-hover">
70
- <!-- IF !group.invited.length -->
71
- <div class="alert alert-info">[[groups:invited.none]]</div>
72
- <!-- ENDIF !group.invited.length -->
73
- {{{each group.invited}}}
74
- <tr data-uid="{group.invited.uid}">
75
- <td class="p-2">
76
- <a href="{config.relative_path}/user/{group.invited.userslug}">{buildAvatar(group.invited, "24px", true)}</a>
77
- </td>
78
- <td class="member-name p-2">
79
- <a href="{config.relative_path}/user/{group.invited.userslug}">{group.invited.username}</a>
80
- </td>
81
- <td class="p-2">
82
- <div class="btn-group float-end">
83
- <button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
84
- [[global:more]] <span class="caret"></span>
85
- </button>
86
- <ul class="dropdown-menu" role="menu">
87
- <li><a class="dropdown-item" href="#" data-ajaxify="false" data-action="rescindInvite">[[groups:invited.uninvite]]</a></li>
88
- </ul>
89
- </div>
90
- </td>
91
- </tr>
92
- {{{end}}}
93
- </table>
94
- </div>
95
- </div>
1
+ <div class="options">
2
+ <form component="groups/settings" role="form">
3
+ <div class="row">
4
+ <div class="col-12 col-lg-6">
5
+ <div class="mb-3">
6
+ <label class="form-label" for="name">[[groups:details.group_name]]</label>
7
+ <input <!-- IF group.system -->readonly<!-- ENDIF group.system --> class="form-control" name="name" id="name" type="text" value="{group.displayName}" />
8
+ </div>
9
+ <div class="mb-3">
10
+ <label class="form-label" for="name">[[groups:details.description]]</label>
11
+ <textarea class="form-control" name="description" id="description" type="text" maxlength="255">{group.description}</textarea>
12
+ </div>
96
13
 
97
- <div class="card mb-3">
98
- <div class="card-header pointer" data-bs-toggle="collapse" data-bs-target=".options">
99
- <span class="fs-5">
100
- <i class="fa fa-caret-down float-end"></i>
101
- <i class="fa fa-cogs"></i> [[groups:details.owner_options]]
102
- </span>
103
- </div>
14
+ <div class="form-check">
15
+ <label class="form-check-label">[[groups:details.private]]</label>
16
+ <input class="form-check-input" name="private" type="checkbox"<!-- IF group.private --> checked<!-- ENDIF group.private -->>
17
+ {{{ if !allowPrivateGroups }}}
18
+ <p class="form-text">
19
+ [[groups:details.private_system_help]]
20
+ </p>
21
+ {{{ end }}}
22
+ <p class="form-text text-xs m-0">
23
+ [[groups:details.private_help]]
24
+ </p>
25
+ </div>
26
+ <div class="form-check">
27
+ <label class="form-check-label">[[groups:details.hidden]]</label>
28
+ <input class="form-check-input" name="hidden" type="checkbox"<!-- IF group.hidden --> checked<!-- ENDIF group.hidden -->>
29
+ <p class="form-text text-xs m-0">
30
+ [[groups:details.hidden_help]]
31
+ </p>
32
+ </div>
104
33
 
105
- <div class="card-body options collapse">
106
- <form component="groups/settings" role="form">
107
- <div class="mb-3">
108
- <label class="form-label" for="name">[[groups:details.group_name]]</label>
109
- <input <!-- IF group.system -->readonly<!-- ENDIF group.system --> class="form-control" name="name" id="name" type="text" value="{group.displayName}" />
110
- </div>
111
- <div class="mb-3">
112
- <label class="form-label" for="name">[[groups:details.description]]</label>
113
- <textarea class="form-control" name="description" id="description" type="text" maxlength="255">{group.description}</textarea>
34
+ <div class="form-check">
35
+ <label class="form-check-label">[[groups:details.disableJoinRequests]]</label>
36
+ <input class="form-check-input" name="disableJoinRequests" type="checkbox"{{{ if group.disableJoinRequests }}} checked{{{ end }}}>
37
+ </div>
38
+ <div class="form-check">
39
+ <label class="form-check-label">[[groups:details.disableLeave]]</label>
40
+ <input class="form-check-input" name="disableLeave" type="checkbox"{{{if group.disableLeave}}} checked{{{end}}}>
41
+ </div>
114
42
  </div>
115
-
116
- <hr />
117
- <div class="mb-3">
118
- <label class="form-label" for="memberPostCids">[[groups:details.member-post-cids]]</label>
119
- <div class="row">
120
- <div class="col-md-6">
121
- <input id="memberPostCids" type="text" class="form-control" value="{group.memberPostCids}">
122
- </div>
123
- <div class="col-md-6 member-post-cids-selector">
124
- <!-- IMPORT partials/category-selector.tpl -->
43
+ <div class="col-12 col-lg-6">
44
+ <div class="d-flex gap-2 align-items-center">
45
+ <div class="form-check">
46
+ <label class="form-check-label">[[groups:details.userTitleEnabled]]</label>
47
+ <input class="form-check-input" name="userTitleEnabled" type="checkbox"{{{ if group.userTitleEnabled }}} checked{{{ end }}}>
125
48
  </div>
49
+ <span class="badge rounded-1 text-uppercase text-truncate rounded-1 {{{ if !group.userTitleEnabled }}} hide{{{ end }}}" style="max-width:150px; color: {group.textColor}; background-color: {group.labelColor}"><i class="fa {{{ if group.icon }}} {group.icon}{{{ if group.userTitle}}} me-1{{{ end }}}{{{ end }}}"></i><span class="badge-text">{{{ if group.userTitle }}}{group.userTitle}{{{ end }}}</span></span>
126
50
  </div>
127
- </div>
128
51
 
129
- <hr />
130
52
 
131
- <div class="mb-3 user-title-option">
132
- <label class="form-label" for="userTitle">[[groups:details.badge_text]]</label>
133
- <input component="groups/userTitleOption" class="form-control" name="userTitle" id="userTitle" type="text" maxlength="40" value="{group.userTitleEscaped}"<!-- IF !group.userTitleEnabled --> disabled<!-- ENDIF !group.userTitleEnabled --> />
53
+ <div class="mb-2">
54
+ <label class="form-label text-xs text-muted" for="userTitle">[[groups:details.badge_text]]</label>
55
+ <div class="d-flex gap-1">
56
+ <input component="groups/userTitleOption" class="form-control" name="userTitle" id="userTitle" type="text" maxlength="40" value="{group.userTitleEscaped}"{{{ if !group.userTitleEnabled }}} disabled{{{ end }}} />
57
+ <button component="groups/userTitleOption" type="button" class="btn btn-outline-secondary text-nowrap" data-action="icon-select"{{{ if !group.userTitleEnabled }}} disabled{{{ end }}}>[[groups:details.change_icon]]</button>
58
+ <input type="hidden" name="icon" value="{{{ if group.icon }}}{group.icon}{{{ end }}}" />
59
+ <div id="icons" class="hidden">
60
+ <div class="icon-container">
61
+ <div class="row nbb-fa-icons">
62
+ <!-- IMPORT partials/fontawesome.tpl -->
63
+ </div>
64
+ </div>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ <div class="mb-2">
69
+ <label class="form-label text-xs text-muted" for="labelColor" class="badge-color-label">[[groups:details.change_label_colour]]</label>
70
+ <input class="form-control" component="groups/userTitleOption" type="color" name="labelColor" value="{{{ if group.labelColor }}}{group.labelColor}{{{ end }}}" />
71
+ </div>
72
+ <div class="mb-2">
73
+ <label class="form-label text-xs text-muted" for="color" class="badge-color-label">[[groups:details.change_text_colour]]</label>
74
+ <input class="form-control" component="groups/userTitleOption" type="color" name="textColor" value="{{{ if group.textColor }}}{group.textColor}{{{ end }}}" />
75
+ </div>
134
76
  </div>
77
+ </div>
135
78
 
136
- <div class="mb-3 user-title-option">
137
- <label>[[groups:details.badge_preview]]</label><br />
138
- <span class="badge rounded-1 text-uppercase text-truncate rounded-1 {{{ if !group.userTitleEnabled }}} hide{{{ end }}}" style="max-width:150px; color: {group.textColor}; background-color: {group.labelColor}"><i class="fa{{{ if group.icon }}} {group.icon}{{{ if ./userTitle}}}me-1{{{ end }}}{{{ end }}}"></i><span class="badge-text">{{{ if group.userTitle }}}{group.userTitle}{{{ end }}}</span></span>
79
+ <hr />
139
80
 
140
- <hr/>
141
- <button component="groups/userTitleOption" type="button" class="btn btn-outline-secondary btn-sm" data-action="icon-select"<!-- IF !group.userTitleEnabled --> disabled<!-- ENDIF !group.userTitleEnabled -->>[[groups:details.change_icon]]</button>
142
- <div>
143
- <label class="form-label" for="labelColor" class="badge-color-label">[[groups:details.change_label_colour]]</label>
144
- <input component="groups/userTitleOption" type="color" name="labelColor" value="<!-- IF group.labelColor -->{group.labelColor}<!-- ENDIF group.labelColor -->" />
145
- </div>
146
- <div>
147
- <label class="form-label" for="color" class="badge-color-label">[[groups:details.change_text_colour]]</label>
148
- <input component="groups/userTitleOption" type="color" name="textColor" value="<!-- IF group.textColor -->{group.textColor}<!-- ENDIF group.textColor -->" />
81
+ <div class="mb-3">
82
+ <label class="form-label" for="memberPostCids">[[groups:details.member-post-cids]]</label>
83
+ <div class="row">
84
+ <div class="col-md-6">
85
+ <input id="memberPostCids" type="text" class="form-control" value="{group.memberPostCids}">
149
86
  </div>
150
- <input type="hidden" name="icon" value="<!-- IF group.icon -->{group.icon}<!-- ENDIF group.icon -->" />
151
-
152
- <div id="icons" class="hidden">
153
- <div class="icon-container">
154
- <div class="row nbb-fa-icons">
155
- <!-- IMPORT partials/fontawesome.tpl -->
156
- </div>
157
- </div>
87
+ <div class="col-md-6 member-post-cids-selector">
88
+ <!-- IMPORT partials/category-selector.tpl -->
158
89
  </div>
159
90
  </div>
160
- <hr />
161
- <div class="form-check">
162
- <label class="form-check-label">[[groups:details.userTitleEnabled]]</label>
163
- <input class="form-check-input" name="userTitleEnabled" type="checkbox"<!-- IF group.userTitleEnabled --> checked<!-- ENDIF group.userTitleEnabled -->>
164
- </div>
165
- <div class="form-check">
166
- <label class="form-check-label">[[groups:details.private]]</label>
167
- <input class="form-check-input" name="private" type="checkbox"<!-- IF group.private --> checked<!-- ENDIF group.private -->>
168
- <!-- IF !allowPrivateGroups -->
169
- <p class="form-text">
170
- [[groups:details.private_system_help]]
171
- </p>
172
- <!-- ENDIF !allowPrivateGroups -->
173
- <p class="form-text">
174
- [[groups:details.private_help]]
175
- </p>
176
- </div>
177
- <div class="form-check">
178
- <label class="form-check-label">[[groups:details.disableJoinRequests]]</label>
179
- <input class="form-check-input" name="disableJoinRequests" type="checkbox"<!-- IF group.disableJoinRequests --> checked<!-- ENDIF group.disableJoinRequests -->>
180
- </div>
181
- <div class="form-check">
182
- <label class="form-check-label">[[groups:details.disableLeave]]</label>
183
- <input class="form-check-input" name="disableLeave" type="checkbox"{{{if group.disableLeave}}} checked{{{end}}}>
184
- </div>
185
- <div class="form-check">
186
- <label class="form-check-label">[[groups:details.hidden]]</label>
187
- <input class="form-check-input" name="hidden" type="checkbox"<!-- IF group.hidden --> checked<!-- ENDIF group.hidden -->>
188
- <p class="form-text">
189
- [[groups:details.hidden_help]]
190
- </p>
191
- </div>
91
+ </div>
192
92
 
193
- <button class="btn btn-link text-danger float-end" type="button" data-action="delete">[[groups:details.delete_group]]</button>
194
- <button class="btn btn-primary" type="button" data-action="update">[[global:save_changes]]</button>
195
- </form>
196
- </div>
197
- </div>
93
+ <button class="btn btn-link text-danger float-end" type="button" data-action="delete">[[groups:details.delete_group]]</button>
94
+ <button class="btn btn-primary" type="button" data-action="update">[[global:save_changes]]</button>
95
+ </form>
96
+ </div>
@@ -1,3 +1 @@
1
- <!-- THIS FILE IS STILL PERSONA -->
2
-
3
- <a href="{config.relative_path}/groups/{./slug}" class="badge rounded-1 text-uppercase text-truncate" style="max-width: 150px;color:{./textColor};background-color: {./labelColor};"><i class="fa {{{ if ./icon }}}{./icon}{{{ if ./userTitle}}} me-1{{{ end }}}{{{else}}}hidden{{{ end }}}"></i><span class="badge-text">{{{ if ./userTitle }}}{./userTitle}{{{ end }}}</span></a>
1
+ <a href="{config.relative_path}/groups/{./slug}" class="badge rounded-1 text-uppercase text-truncate text-decoration-none" style="max-width: 150px;color:{./textColor};background-color: {./labelColor};"><i class="fa {{{ if ./icon }}}{./icon}{{{ if ./userTitle}}} me-1{{{ end }}}{{{else}}}hidden{{{ end }}}"></i><span class="badge-text">{{{ if ./userTitle }}}{./userTitle}{{{ end }}}</span></a>
@@ -0,0 +1,33 @@
1
+ <label class="text-xs text-muted">[[groups:invited.search]]</label>
2
+ <div class="input-group mb-2">
3
+ <input class="form-control" type="text" component="groups/members/invite"/>
4
+ <span class="input-group-text search-button"><i class="fa fa-search"></i></span>
5
+ </div>
6
+
7
+ <div class="mb-2">
8
+ <label class="text-xs text-muted">[[groups:bulk-invite-instructions]]</label>
9
+ <textarea class="form-control" component="groups/members/bulk-invite"></textarea>
10
+ </div>
11
+
12
+ <div class="mb-2 clearfix">
13
+ <button class="btn btn-primary btn-sm float-end" component="groups/members/bulk-invite-button">[[groups:bulk-invite]]</button>
14
+ </div>
15
+
16
+ <table component="groups/invited" class="table table-hover">
17
+ {{{ if !group.invited.length }}}
18
+ <div class="alert alert-info">[[groups:invited.none]]</div>
19
+ {{{ end }}}
20
+ {{{each group.invited}}}
21
+ <tr data-uid="{group.invited.uid}" class="align-middle">
22
+ <td class="p-2">
23
+ <a class="text-decoration-none" href="{config.relative_path}/user/{group.invited.userslug}">{buildAvatar(group.invited, "24px", true)}</a>
24
+ </td>
25
+ <td class="member-name p-2 w-100">
26
+ <a href="{config.relative_path}/user/{group.invited.userslug}">{group.invited.username}</a>
27
+ </td>
28
+ <td class="p-2">
29
+ <button class="btn btn-outline-secondary btn-sm text-nowrap" data-action="rescindInvite">[[groups:invited.uninvite]]</button>
30
+ </td>
31
+ </tr>
32
+ {{{end}}}
33
+ </table>
@@ -1,23 +1,16 @@
1
- <!-- THIS FILE IS STILL PERSONA -->
2
-
3
- {{{each groups}}}
4
- <div class="col-lg-4 col-md-6 col-sm-12 mb-3" component="groups/summary" data-slug="{groups.slug}">
5
- <div class="card h-100">
6
- <a href="{config.relative_path}/groups/{groups.slug}" class="card-header list-cover" style="<!-- IF groups.cover:thumb:url -->background-image: url({groups.cover:thumb:url});<!-- ENDIF groups.cover:thumb:url -->">
7
- <h5 class="card-title">{groups.displayName} <small>{groups.memberCount}</small></h5>
8
- </a>
9
- <div class="card-body">
10
- <ul class="members">
11
- {{{each groups.members}}}
12
- <li>
13
- <a href="{config.relative_path}/user/{groups.members.userslug}">{buildAvatar(groups.members, "24px", true)}</a>
14
- </li>
15
- {{{end}}}
16
- <!-- IF groups.truncated -->
17
- <li class="truncated"><i class="fa fa-ellipsis-h"></i></li>
18
- <!-- ENDIF groups.truncated -->
19
- </ul>
1
+ {{{ each groups }}}
2
+ <div class="col-xl-4 col-lg-6 col-sm-12 mb-3" component="groups/summary" data-slug="{./slug}">
3
+ <div class="card h-100 group-hover-bg border-0">
4
+ <a href="{config.relative_path}/groups/{./slug}" class="card-header border-bottom-0 pointer d-block list-cover" style="{{{ if ./cover:thumb:url }}}background-image: url({./cover:thumb:url});background-size: cover; min-height: 125px; background-position: {./cover:position}{{{ end }}}"></a>
5
+ <a href="{config.relative_path}/groups/{./slug}" class="d-block h-100 text-reset text-decoration-none">
6
+ <div class="card-body d-flex flex-column gap-1 border border-top-0 rounded-bottom h-100">
7
+ <div class="d-flex">
8
+ <div class="flex-1 fs-6 fw-semibold">{./displayName}</div>
9
+ <div class="text-sm"><i class="text-muted fa-solid fa-user"></i> {./memberCount}</div>
10
+ </div>
11
+ <div class="text-sm">{./description}</div>
20
12
  </div>
21
- </div>
13
+ </a>
22
14
  </div>
23
- {{{end}}}
15
+ </div>
16
+ {{{ end }}}
@@ -1,41 +1,45 @@
1
- <!-- THIS FILE IS STILL PERSONA -->
2
-
3
- <div class="d-flex mb-3">
4
- <!-- IF group.isOwner -->
1
+ <div class="d-flex {{{ if group.isOwner }}}justify-content-between{{{ else }}}justify-content-end{{{ end }}} mb-3">
2
+ {{{ if group.isOwner }}}
5
3
  <div class="flex-shrink-0">
6
- <button component="groups/members/add" type="button" class="btn btn-primary me-3" title="[[groups:details.add-member]]"><i class="fa fa-user-plus"></i></button>
4
+ <button component="groups/members/add" type="button" class="btn btn-primary btn-sm me-3" title="[[groups:details.add-member]]"><i class="fa fa-user-plus"></i> [[groups:details.add-member]]</button>
7
5
  </div>
8
- <!-- ENDIF group.isOwner -->
9
- <div class="flex-grow-1">
6
+ {{{ end }}}
7
+ <div class="">
10
8
  <div class="input-group">
11
- <input class="form-control" type="text" component="groups/members/search" placeholder="[[global:search]]"/>
12
- <span class="input-group-text search-button"><i class="fa fa-search"></i></span>
9
+ <input class="form-control form-control-sm" type="text" component="groups/members/search" placeholder="[[global:search]]"/>
10
+ <button class="btn btn-primary btn-sm search-button" type="button">
11
+ <i class="fa fa-search"></i>
12
+ </button>
13
13
  </div>
14
14
  </div>
15
15
  </div>
16
16
 
17
- <table component="groups/members" class="table table-striped table-hover" data-nextstart="{group.membersNextStart}">
17
+ <table component="groups/members" class="table table-hover" data-nextstart="{group.membersNextStart}">
18
18
  <tbody>
19
19
  {{{each group.members}}}
20
- <tr data-uid="{group.members.uid}">
20
+ <tr data-uid="{group.members.uid}" data-isowner="{{{ if group.members.isOwner }}}1{{{ else }}}0{{{ end }}}">
21
21
  <td class="p-2">
22
- <a href="{config.relative_path}/user/{group.members.userslug}">{buildAvatar(group.members, "24px", true)}</a>
22
+ <a class="text-decoration-none" href="{config.relative_path}/user/{group.members.userslug}">{buildAvatar(group.members, "24px", true)}</a>
23
23
  </td>
24
- <td class="member-name p-2">
25
- <a class="align-text-top" href="{config.relative_path}/user/{group.members.userslug}">{group.members.username}</a>
26
- <i title="[[groups:owner]]" class="user-owner-icon fa fa-star align-text-top text-warning <!-- IF !group.members.isOwner -->invisible<!-- ENDIF !group.members.isOwner -->"></i>
24
+ <td class="member-name p-2 w-100 ">
25
+ <div class="d-flex align-items-center justify-content-between">
26
+ <div class="d-flex align-items-center gap-2">
27
+ <a class="align-text-top" href="{config.relative_path}/user/{group.members.userslug}">{group.members.username}</a>
28
+ <i component="groups/owner/icon" title="[[groups:owner]]" class="user-owner-icon fa fa-star align-text-top text-warning <!-- IF !group.members.isOwner -->invisible<!-- ENDIF !group.members.isOwner -->"></i>
29
+ </div>
27
30
 
28
- <!-- IF group.isOwner -->
29
- <div class="owner-controls btn-group float-end">
30
- <a class="btn btn-sm" href="#" data-ajaxify="false" data-action="toggleOwnership" title="[[groups:details.grant]]">
31
- <i class="fa fa-star"></i>
32
- </a>
31
+ {{{ if group.isOwner }}}
32
+ <div class="owner-controls btn-group">
33
+ <a class="btn btn-sm" href="#" data-ajaxify="false" data-action="toggleOwnership" title="[[groups:details.grant]]">
34
+ <i class="fa fa-star"></i>
35
+ </a>
33
36
 
34
- <a class="btn btn-sm" href="#" data-ajaxify="false" data-action="kick" title="[[groups:details.kick]]">
35
- <i class="fa fa-ban"></i>
36
- </a>
37
+ <a class="btn btn-sm" href="#" data-ajaxify="false" data-action="kick" title="[[groups:details.kick]]">
38
+ <i class="fa fa-ban"></i>
39
+ </a>
40
+ </div>
41
+ {{{ end }}}
37
42
  </div>
38
- <!-- ENDIF group.isOwner -->
39
43
  </td>
40
44
  </tr>
41
45
  {{{end}}}
@@ -0,0 +1,30 @@
1
+ {{{ if group.pending.length }}}
2
+ <div class="d-flex justify-content-end gap-2 mb-3">
3
+ <button class="btn btn-danger btn-sm" data-action="rejectAll">[[groups:pending.reject_all]]</button>
4
+ <button class="btn btn-success btn-sm" data-action="acceptAll">[[groups:pending.accept_all]]</button>
5
+
6
+ </div>
7
+ {{{ end }}}
8
+
9
+ <table component="groups/pending" class="table table-hover">
10
+ {{{ if !group.pending.length }}}
11
+ <div class="alert alert-info">[[groups:pending.none]]</div>
12
+ {{{ end }}}
13
+ {{{each group.pending}}}
14
+ <tr data-uid="{group.pending.uid}" class="align-middle">
15
+ <td class="p-2">
16
+ <a class="text-decoration-none" href="{config.relative_path}/user/{group.pending.userslug}">{buildAvatar(group.pending, "24px", true)}</a>
17
+ </td>
18
+ <td class="member-name p-2 w-100">
19
+ <a href="{config.relative_path}/user/{group.pending.userslug}">{group.pending.username}</a>
20
+ </td>
21
+ <td class="p-2">
22
+ <div class="d-flex gap-2">
23
+ <button class="btn btn-danger btn-sm" data-action="reject">[[groups:pending.reject]]</a></li>
24
+ <button class="btn btn-success btn-sm" data-action="accept">[[groups:pending.accept]]</a></li>
25
+
26
+ </div>
27
+ </td>
28
+ </tr>
29
+ {{{end}}}
30
+ </table>