nodebb-theme-harmony 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +76 -62
  51. package/templates/groups/list.tpl +16 -11
  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 -175
  77. package/templates/partials/groups/badge.tpl +1 -3
  78. package/templates/partials/groups/invited.tpl +31 -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 +28 -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,104 @@
1
- <!-- THIS FILE IS STILL PERSONA -->
1
+ <div class="options">
2
+ <form component="groups/settings" role="form">
3
+ <div class="mb-3">
4
+ <label class="form-label" for="name">[[groups:details.group_name]]</label>
5
+ <input <!-- IF group.system -->readonly<!-- ENDIF group.system --> class="form-control" name="name" id="name" type="text" value="{group.displayName}" />
6
+ </div>
7
+ <div class="mb-3">
8
+ <label class="form-label" for="name">[[groups:details.description]]</label>
9
+ <textarea class="form-control" name="description" id="description" type="text" maxlength="255">{group.description}</textarea>
10
+ </div>
2
11
 
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 -->
12
+
13
+ <div class="form-check">
14
+ <label class="form-check-label">[[groups:details.private]]</label>
15
+ <input class="form-check-input" name="private" type="checkbox"<!-- IF group.private --> checked<!-- ENDIF group.private -->>
16
+ <!-- IF !allowPrivateGroups -->
17
+ <p class="form-text">
18
+ [[groups:details.private_system_help]]
19
+ </p>
20
+ <!-- ENDIF !allowPrivateGroups -->
21
+ <p class="form-text text-xs m-0">
22
+ [[groups:details.private_help]]
23
+ </p>
18
24
  </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>
25
+ <div class="form-check">
26
+ <label class="form-check-label">[[groups:details.hidden]]</label>
27
+ <input class="form-check-input" name="hidden" type="checkbox"<!-- IF group.hidden --> checked<!-- ENDIF group.hidden -->>
28
+ <p class="form-text text-xs m-0">
29
+ [[groups:details.hidden_help]]
30
+ </p>
59
31
  </div>
60
32
 
61
- <div class="mb-2">
62
- <textarea class="form-control" component="groups/members/bulk-invite" placeholder="[[groups:bulk-invite-instructions]]"></textarea>
33
+ <div class="form-check">
34
+ <label class="form-check-label">[[groups:details.disableJoinRequests]]</label>
35
+ <input class="form-check-input" name="disableJoinRequests" type="checkbox"<!-- IF group.disableJoinRequests --> checked<!-- ENDIF group.disableJoinRequests -->>
36
+ </div>
37
+ <div class="form-check">
38
+ <label class="form-check-label">[[groups:details.disableLeave]]</label>
39
+ <input class="form-check-input" name="disableLeave" type="checkbox"{{{if group.disableLeave}}} checked{{{end}}}>
63
40
  </div>
64
41
 
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>
42
+ <div class="form-check">
43
+ <label class="form-check-label">[[groups:details.userTitleEnabled]]</label>
44
+ <input class="form-check-input" name="userTitleEnabled" type="checkbox"<!-- IF group.userTitleEnabled --> checked<!-- ENDIF group.userTitleEnabled -->>
67
45
  </div>
68
46
 
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>
47
+ <div class="row mb-3">
48
+ <div class="col-6">
49
+ <div class="user-title-option">
50
+ <label class="form-label" for="userTitle">[[groups:details.badge_text]]</label>
51
+ <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 --> />
52
+ </div>
53
+ </div>
54
+ <div class="col-6 d-flex flex-column">
55
+ <label class="form-label">[[groups:details.badge_preview]]</label>
56
+ <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>
57
+ </div>
58
+ </div>
59
+
60
+
61
+
96
62
 
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>
104
63
 
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}" />
64
+ <div class="row mb-3 user-title-option">
65
+ <div class="col-4">
66
+ <button component="groups/userTitleOption" type="button" class="btn btn-outline-secondary btn-sm" data-action="icon-select"{{{ if !group.userTitleEnabled }}} disabled{{{ end }}}>[[groups:details.change_icon]]</button>
110
67
  </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>
68
+ <div class="col-4">
69
+ <label class="form-label" for="labelColor" class="badge-color-label">[[groups:details.change_label_colour]]</label>
70
+ <input component="groups/userTitleOption" type="color" name="labelColor" value="{{{ if group.labelColor }}}{group.labelColor}{{{ end }}}" />
114
71
  </div>
72
+ <div class="col-4">
73
+ <label class="form-label" for="color" class="badge-color-label">[[groups:details.change_text_colour]]</label>
74
+ <input component="groups/userTitleOption" type="color" name="textColor" value="{{{ if group.textColor }}}{group.textColor}{{{ end }}}" />
75
+ </div>
76
+ <input type="hidden" name="icon" value="{{{ if group.icon }}}{group.icon}{{{ end }}}" />
115
77
 
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 -->
78
+ <div id="icons" class="hidden">
79
+ <div class="icon-container">
80
+ <div class="row nbb-fa-icons">
81
+ <!-- IMPORT partials/fontawesome.tpl -->
125
82
  </div>
126
83
  </div>
127
84
  </div>
85
+ </div>
128
86
 
129
- <hr />
130
-
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 --> />
134
- </div>
135
-
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>
87
+ <hr />
139
88
 
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 -->" />
89
+ <div class="mb-3">
90
+ <label class="form-label" for="memberPostCids">[[groups:details.member-post-cids]]</label>
91
+ <div class="row">
92
+ <div class="col-md-6">
93
+ <input id="memberPostCids" type="text" class="form-control" value="{group.memberPostCids}">
145
94
  </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 -->" />
95
+ <div class="col-md-6 member-post-cids-selector">
96
+ <!-- IMPORT partials/category-selector.tpl -->
149
97
  </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>
158
- </div>
159
- </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
98
  </div>
99
+ </div>
192
100
 
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>
101
+ <button class="btn btn-link text-danger float-end" type="button" data-action="delete">[[groups:details.delete_group]]</button>
102
+ <button class="btn btn-primary" type="button" data-action="update">[[global:save_changes]]</button>
103
+ </form>
104
+ </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,31 @@
1
+ <div class="input-group mb-2">
2
+ <input class="form-control" type="text" component="groups/members/invite" placeholder="[[groups:invited.search]]"/>
3
+ <span class="input-group-text search-button"><i class="fa fa-search"></i></span>
4
+ </div>
5
+
6
+ <div class="mb-2">
7
+ <textarea class="form-control" component="groups/members/bulk-invite" placeholder="[[groups:bulk-invite-instructions]]"></textarea>
8
+ </div>
9
+
10
+ <div class="mb-2 clearfix">
11
+ <button class="btn btn-outline-secondary btn-sm float-end" component="groups/members/bulk-invite-button">[[groups:bulk-invite]]</button>
12
+ </div>
13
+
14
+ <table component="groups/invited" class="table table-hover">
15
+ {{{ if !group.invited.length }}}
16
+ <div class="alert alert-info">[[groups:invited.none]]</div>
17
+ {{{ end }}}
18
+ {{{each group.invited}}}
19
+ <tr data-uid="{group.invited.uid}">
20
+ <td class="p-2">
21
+ <a class="text-decoration-none" href="{config.relative_path}/user/{group.invited.userslug}">{buildAvatar(group.invited, "24px", true)}</a>
22
+ </td>
23
+ <td class="member-name p-2 w-100">
24
+ <a href="{config.relative_path}/user/{group.invited.userslug}">{group.invited.username}</a>
25
+ </td>
26
+ <td class="p-2">
27
+ <button class="btn btn-outline-secondary btn-sm text-nowrap" data-action="rescindInvite">[[groups:invited.uninvite]]</button>
28
+ </td>
29
+ </tr>
30
+ {{{end}}}
31
+ </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-xxl-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,28 @@
1
+ {{{ if group.pending.length }}}
2
+ <div class="d-flex justify-content-end gap-2 mb-3">
3
+ <button class="btn btn-outline-secondary btn-sm" data-action="acceptAll">[[groups:pending.accept_all]]</button>
4
+ <button class="btn btn-outline-secondary btn-sm" data-action="rejectAll">[[groups:pending.reject_all]]</button>
5
+ </div>
6
+ {{{ end }}}
7
+
8
+ <table component="groups/pending" class="table table-hover">
9
+ {{{ if !group.pending.length }}}
10
+ <div class="alert alert-info">[[groups:pending.none]]</div>
11
+ {{{ end }}}
12
+ {{{each group.pending}}}
13
+ <tr data-uid="{group.pending.uid}">
14
+ <td class="p-2">
15
+ <a class="text-decoration-none" href="{config.relative_path}/user/{group.pending.userslug}">{buildAvatar(group.pending, "24px", true)}</a>
16
+ </td>
17
+ <td class="member-name p-2 w-100">
18
+ <a href="{config.relative_path}/user/{group.pending.userslug}">{group.pending.username}</a>
19
+ </td>
20
+ <td class="p-2">
21
+ <div class="d-flex gap-2">
22
+ <button class="btn btn-outline-secondary btn-sm" data-action="accept">[[groups:pending.accept]]</a></li>
23
+ <button class="btn btn-outline-secondary btn-sm" data-action="reject">[[groups:pending.reject]]</a></li>
24
+ </div>
25
+ </td>
26
+ </tr>
27
+ {{{end}}}
28
+ </table>