nodebb-theme-harmony 1.0.0-beta.61 → 1.0.0-beta.63

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-theme-harmony",
3
- "version": "1.0.0-beta.61",
3
+ "version": "1.0.0-beta.63",
4
4
  "nbbpm": {
5
5
  "compatibility": "^3.0.0"
6
6
  },
package/scss/chats.scss CHANGED
@@ -3,6 +3,7 @@
3
3
  .page-user-chats #content {
4
4
  max-width: 100%;
5
5
  }
6
+
6
7
  body.page-user-chats {
7
8
  overflow: hidden;
8
9
  [data-widget-area="footer"] {
@@ -19,9 +20,17 @@ body.page-user-chats {
19
20
  }
20
21
  }
21
22
  }
23
+
24
+ [component="chat/recent"] {
25
+ .active {
26
+ background-color: $btn-ghost-hover-color;
27
+ }
28
+ }
29
+
22
30
  [component="chat/nav-wrapper"] {
23
31
  width: 300px;
24
32
  }
33
+
25
34
  .expanded-chat {
26
35
  // no taskbar so hide minimize button
27
36
  [data-action="minimize"] {
package/scss/common.scss CHANGED
@@ -61,7 +61,8 @@ body:not(.page-user) {
61
61
  .sticky-tools {
62
62
  position: sticky;
63
63
  z-index: 3;
64
- top: calc($spacer * 0.5);
64
+ top: 0;
65
+ padding: 0.25rem 0;
65
66
  background-color: $body-bg;
66
67
  }
67
68
  // quartz doesn't need body-bg for tool background
@@ -95,7 +96,7 @@ body:not(.page-user) {
95
96
  text-align: left;
96
97
  --bs-text-opacity: 1;
97
98
  color: inherit !important;
98
-
99
+ font-family: $font-family-secondary;
99
100
  cursor: pointer;
100
101
  &:hover, &.active {
101
102
  background-color: $btn-ghost-hover-color;
package/scss/harmony.scss CHANGED
@@ -9,7 +9,6 @@
9
9
  @import "status";
10
10
  @import "account";
11
11
  @import "groups";
12
- @import "search";
13
12
  @import "modals";
14
13
 
15
14
  @import "modules/breadcrumbs";
@@ -22,5 +21,6 @@
22
21
  @import "modules/cover";
23
22
  @import "modules/nprogress";
24
23
  @import "modules/paginator";
24
+ @import "modules/filters";
25
25
 
26
26
  @import "skins";
@@ -0,0 +1,8 @@
1
+ [component="search/filters"], [component="flags/filters"] {
2
+ .filter-btn {
3
+ border-color: $gray-300!important;
4
+ &.active-filter {
5
+ border-color: $primary!important;
6
+ }
7
+ }
8
+ }
@@ -57,6 +57,7 @@ $link-hover-decoration: underline;
57
57
  $font-family-sans-serif: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
58
58
  $font-family-secondary: "Poppins", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default;
59
59
  $font-weight-semibold: 500 !default;
60
+ $small-font-size: 0.875rem !default;
60
61
 
61
62
  $breadcrumb-divider: quote("→");
62
63
  $breadcrumb-divider-color: $gray-500 !default;
package/scss/search.scss CHANGED
@@ -1,8 +0,0 @@
1
- [component="search/filters"] {
2
- .filter-btn {
3
- border-color: $gray-300!important;
4
- &.active-filter {
5
- border-color: $primary!important;
6
- }
7
- }
8
- }
package/scss/sidebar.scss CHANGED
@@ -87,7 +87,8 @@
87
87
  line-height: 12px;
88
88
  &.visible-open {
89
89
  font-size:12px;
90
- line-height: 16px;
90
+ line-height: 12px;
91
+ font-weight: normal;
91
92
  }
92
93
  }
93
94
 
@@ -14,7 +14,7 @@
14
14
  </div>
15
15
  </div>
16
16
  <hr class="text-muted opacity-25 my-1">
17
- <ul component="chat/recent" class="chats-list list-unstyled overflow-auto mb-0 pe-2" data-nextstart="{nextStart}">
17
+ <ul component="chat/recent" class="chats-list list-unstyled overflow-auto mb-0" data-nextstart="{nextStart}">
18
18
  {{{each rooms}}}
19
19
  <!-- IMPORT partials/chats/recent_room.tpl -->
20
20
  {{{end}}}
@@ -2,72 +2,8 @@
2
2
 
3
3
  <!-- IMPORT partials/breadcrumbs.tpl -->
4
4
 
5
- <div class="row">
6
- <div class="col-sm-4 col-md-3">
7
- <!-- IMPORT partials/flags/filters.tpl -->
8
- </div>
9
- <div class="col-sm-8 col-md-9">
10
- {{{ if hasFilter }}}
11
- <div class="alert alert-warning">
12
- <p class="float-end">
13
- <a href="{config.relative_path}/flags">[[flags:filter-reset]]</a>
14
- </p>
15
- [[flags:filter-active]]
16
- </div>
17
- {{{ end }}}
18
-
19
- <div class="btn-group float-end" component="flags/bulk-actions">
20
- <button type="button" class="btn btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown" autocomplete="off" aria-haspopup="true" aria-expanded="false" disabled="disabled">
21
- <i class="fa fa-clone"></i> <span class="fw-semibold">[[flags:bulk-actions]]</span>
22
- </button>
23
- <ul class="dropdown-menu">
24
- <li><a href="#" class="dropdown-item" data-action="bulk-assign">[[flags:assign-to-me]]</a></li>
25
- <li><a href="#" class="dropdown-item" data-action="bulk-mark-resolved">[[flags:bulk-resolve]]</a></li>
26
- </ul>
27
- </div>
28
-
29
- <table class="table table-striped table-hover" component="flags/list">
30
- <thead>
31
- <tr>
32
- <th>
33
- <input type="checkbox" data-action="toggle-all" autocomplete="off" />
34
- </th>
35
- <th></th>
36
- <th><span class="hidden-xs">[[flags:reports]] </span><i class="fa fa-user-plus"></i></th>
37
- <th><span class="hidden-xs">[[flags:first-reported]] </span><i class="fa fa-clock-o"></i></th>
38
- <th>[[flags:state]]</th>
39
- </tr>
40
- </thead>
41
- <tbody>
42
- {{{ if !flags.length }}}
43
- <tr>
44
- <td colspan="5">
45
- <div class="alert alert-success text-center">
46
- [[flags:no-flags]]
47
- </div>
48
- </td>
49
- </tr>
50
- {{{ end }}}
51
- {{{ each flags }}}
52
- <tr data-flag-id="{./flagId}">
53
- <td>
54
- <input type="checkbox" autocomplete="off" />
55
- </td>
56
- <td>
57
- <a href="{config.relative_path}/flags/{./flagId}">
58
- <strong>{./target_readable}</strong>
59
- </a>
60
- </td>
61
- <td>
62
- {./heat}
63
- </td>
64
- <td><span class="timeago" title="{./datetimeISO}"></span></td>
65
- <td><span class="badge bg-{./labelClass}">[[flags:state-{./state}]]</span></td>
66
- </tr>
67
- {{{end}}}
68
- </tbody>
69
- </table>
70
-
71
- <!-- IMPORT partials/paginator.tpl -->
72
- </div>
5
+ <div class="d-flex flex-column gap-3">
6
+ <!-- IMPORT partials/flags/filters.tpl -->
7
+ <!-- IMPORT partials/flags/results.tpl -->
8
+ <!-- IMPORT partials/flags/bulk-actions.tpl -->
73
9
  </div>
@@ -16,7 +16,7 @@
16
16
  <div class="d-flex flex-column flex-md-row justify-content-md-between pb-4 mb-4 mt-2 border-bottom">
17
17
  <div class="d-flex flex-column mt-1">
18
18
  <div class="d-flex align-items-center gap-2">
19
- <h2 class="mb-0">{group.displayName}</h2>
19
+ <h3 class="mb-0">{group.displayName}</h3>
20
20
  </div>
21
21
  <div class="d-flex gap-2">
22
22
  {group.descriptionParsed}
@@ -4,7 +4,7 @@
4
4
  {{{end}}}
5
5
  </div>
6
6
  <div class="groups list">
7
- <h2 class="fw-semibold">[[pages:groups]]</h2>
7
+ <h3 class="fw-semibold">[[pages:groups]]</h3>
8
8
  <div class="d-flex flex-wrap justify-content-between">
9
9
  <div class="mb-2 mb-md-0">
10
10
  <div class="text-sm d-flex flex-wrap align-items-center gap-2">
@@ -1,37 +1,45 @@
1
- <a class="text-decoration-none text-reset" href="{config.relative_path}/me/chats/{./roomId}">
2
- <li component="chat/recent/room" data-roomid="{./roomId}" data-full="1" class="{{{ if ./unread }}}unread{{{ end }}} btn-ghost-sm gap-2 justify-content-start align-items-start">
3
- <div class="main-avatar">
4
- {{{ if ./users.length }}}
5
- {{{ if ./groupChat}}}
6
- <div class="position-relative" style="width:32px; height:32px;">
7
- <span class="text-decoration-none position-absolute top-0" style="left: 8px;" href="{config.relative_path}/user/{./users.1.userslug}">{buildAvatar(./users.1, "24px", true)}</span>
8
- <span class="text-decoration-none position-absolute start-0" style="top: 8px;" href="{config.relative_path}/user/{./users.0.userslug}" >{buildAvatar(./users.0, "24px", true)}</span>
9
- </div>
10
- {{{ else }}}
11
- <span href="{config.relative_path}/user/{./users.0.userslug}" class="text-decoration-none">{buildAvatar(./users.0, "32px", true)}</span>
12
- {{{ end }}}
13
- {{{ else }}}
14
- <span class="avatar avatar-rounded text-bg-warning" component="avatar/icon" style="--avatar-size: 32px;">?</span>
15
- {{{ end }}}
16
- </div>
17
-
18
- <div class="d-flex flex-grow-1 flex-column w-100">
19
- <div class="room-name fw-semibold text-xs">
20
- {{{ if !./lastUser.uid }}}
21
- <span>[[modules:chat.no-users-in-room]]</span>
1
+ <li component="chat/recent/room" data-roomid="{./roomId}" data-full="1" class="{{{ if !@last }}}border-bottom mb-1{{{ end }}} rounded-1 {{{ if ./unread }}}unread{{{ end }}}">
2
+ <div class="d-flex gap-1 justify-content-between p-1">
3
+ <div class="position-relative d-flex flex-grow-1 gap-2 justify-content-start align-items-start">
4
+ <div class="main-avatar">
5
+ <a class="stretched-link" href="{config.relative_path}/me/chats/{./roomId}"></a>
6
+ {{{ if ./users.length }}}
7
+ {{{ if ./groupChat}}}
8
+ <div class="position-relative" style="width:32px; height:32px;">
9
+ <span class="text-decoration-none position-absolute top-0" style="left: 8px;" href="{config.relative_path}/user/{./users.1.userslug}">{buildAvatar(./users.1, "24px", true)}</span>
10
+ <span class="text-decoration-none position-absolute start-0" style="top: 8px;" href="{config.relative_path}/user/{./users.0.userslug}" >{buildAvatar(./users.0, "24px", true)}</span>
11
+ </div>
12
+ {{{ else }}}
13
+ <span href="{config.relative_path}/user/{./users.0.userslug}" class="text-decoration-none">{buildAvatar(./users.0, "32px", true)}</span>
14
+ {{{ end }}}
22
15
  {{{ else }}}
23
- {{{ if ./roomName }}}{./roomName}{{{ else }}}{./usernames}{{{ end }}}
16
+ <span class="avatar avatar-rounded text-bg-warning" component="avatar/icon" style="--avatar-size: 32px;">?</span>
24
17
  {{{ end }}}
25
18
  </div>
26
- {{{ if ./teaser }}}
27
- <div class="teaser-content text-sm line-clamp-3 text-break">
28
- <span href="#" class="text-decoration-none">{buildAvatar(./teaser.user, "14px", true)}</span>
29
- <strong class="text-xs fw-semibold teaser-username">{./teaser.user.username}:</strong>
30
- {./teaser.content}
19
+
20
+ <div class="d-flex flex-grow-1 flex-column w-100">
21
+ <div class="room-name fw-semibold text-xs">
22
+ {{{ if !./lastUser.uid }}}
23
+ <span>[[modules:chat.no-users-in-room]]</span>
24
+ {{{ else }}}
25
+ {{{ if ./roomName }}}{./roomName}{{{ else }}}{./usernames}{{{ end }}}
26
+ {{{ end }}}
27
+ </div>
28
+ {{{ if ./teaser }}}
29
+ <div class="teaser-content text-sm line-clamp-3 text-break">
30
+ <span href="#" class="text-decoration-none">{buildAvatar(./teaser.user, "14px", true)}</span>
31
+ <strong class="text-xs fw-semibold teaser-username">{./teaser.user.username}:</strong>
32
+ {./teaser.content}
33
+ </div>
34
+ <div class="teaser-timestamp text-muted text-xs">{./teaser.timeagoLong}</div>
35
+ {{{ end }}}
31
36
  </div>
32
- <div class="teaser-timestamp text-muted text-xs">{./teaser.timeagoLong}</div>
33
- {{{ end }}}
34
37
  </div>
35
- </li>
36
- </a>
37
- <hr class="text-muted opacity-25 my-1"/>
38
+ <div>
39
+ <button class="mark-read btn-ghost-sm" style="width: 1.5rem; height: 1.5rem;">
40
+ <i class="unread fa fa-2xs fa-circle text-primary {{{ if !./unread }}}hidden{{{ end }}}"></i>
41
+ <i class="read fa fa-2xs fa-circle-o text-secondary {{{ if ./unread }}}hidden{{{ end }}}"></i>
42
+ </button>
43
+ </div>
44
+ </div>
45
+ </li>
@@ -1,99 +1,156 @@
1
1
  <!-- THIS FILE IS STILL PERSONA -->
2
2
 
3
- <div class="text-center">
4
- <div class="card mb-3">
5
- <div class="card-body collapse" id="flags-daily-wrapper" aria-expanded="false">
6
- <div><canvas id="flags:daily" height="150"></canvas></div>
7
- </div>
8
- <div class="card-footer" data-bs-toggle="collapse" data-bs-target="#flags-daily-wrapper" aria-controls="#flags-daily-wrapper"><small>[[flags:graph-label]]</small>&nbsp;<i class="fa fa-sort"></i></div>
9
- </div>
10
- </div>
3
+ <div class="d-flex align-items-start gap-2 pb-3 border-bottom">
4
+ <a class="filter-btn btn btn-light btn-sm border {{{ if filters.quick }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
5
+ <span class="filter-label">{{{ if filters.quick }}}[[flags:filter-quick-{./filters.quick}]]{{{ else }}}[[flags:quick-filters]]{{{ end }}}</span>
6
+ <span class="caret"></span>
7
+ </a>
8
+ <ul class="dropdown-menu">
9
+ <li>
10
+ <a class="dropdown-item" href="{config.relative_path}/flags?quick=mine">[[flags:filter-quick-mine]]</a>
11
+ </li>
12
+ </ul>
11
13
 
12
- <div class="card mb-3">
13
- <div class="card-header">
14
- [[flags:quick-filters]]
15
- </div>
16
- <div class="card-body">
17
- <ul>
18
- <li><a href="{config.relative_path}/flags?quick=mine">[[flags:filter-quick-mine]]</a></li>
14
+ <div component="flags/filters" class="ps-2 ms-2 border-start d-flex gap-2 me-auto">
15
+ <!-- IMPORT partials/category/filter-dropdown-left.tpl -->
16
+
17
+ <a class="filter-btn btn btn-light btn-sm border {{{ if (sort != "newest") }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
18
+ <span class="filter-label">{{{ if (sort != "newest") }}}[[flags:sort-{./sort}]]{{{ else }}}[[flags:sort]]{{{ end }}}</span>
19
+ <span class="caret"></span>
20
+ </a>
21
+ <ul class="dropdown-menu">
22
+ <li><h6 class="dropdown-header">[[flags:sort-all]]</h6></li>
23
+ <li class="dropdown-item" data-name="sort" data-value="newest">[[flags:sort-newest]]</li>
24
+ <li class="dropdown-item" data-name="sort" data-value="oldest">[[flags:sort-oldest]]</li>
25
+ <li class="dropdown-item" data-name="sort" data-value="reports">[[flags:sort-reports]]</li>
26
+ <li><h6 class="dropdown-header">[[flags:sort-posts-only]]</h6></li>
27
+ <li class="dropdown-item" data-name="sort" data-value="downvotes">[[flags:sort-downvotes]]</li>
28
+ <li class="dropdown-item" data-name="sort" data-value="upvotes">[[flags:sort-upvotes]]</li>
29
+ <li class="dropdown-item" data-name="sort" data-value="replies">[[flags:sort-replies]]</li>
19
30
  </ul>
20
- </div>
21
- </div>
22
31
 
23
- <div class="card mb-3">
24
- <div class="card-header">
25
- [[flags:filters]]
26
- </div>
27
- <div class="card-body">
28
- <form role="form" component="flags/filters">
29
- <fieldset>
30
- <div class="mb-3">
31
- <label class="form-label" for="filter-cid">[[flags:filter-cid]]</label>
32
- <div class="input-group">
33
- <!-- IMPORT partials/category/filter-dropdown-left.tpl -->
32
+ <a class="filter-btn btn btn-light btn-sm border {{{ if filters.state }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
33
+ <span class="filter-label">{{{ if filters.state }}}[[flags:state-{./filters.state}]]{{{ else }}}[[flags:filter-state]]{{{ end }}}</span>
34
+ <span class="caret"></span>
35
+ </a>
36
+ <ul class="dropdown-menu">
37
+ <li class="dropdown-item" data-name="state" data-value="open">[[flags:state-open]]</li>
38
+ <li class="dropdown-item" data-name="state" data-value="wip">[[flags:state-wip]]</li>
39
+ <li class="dropdown-item" data-name="state" data-value="resolved">[[flags:state-resolved]]</li>
40
+ <li class="dropdown-item" data-name="state" data-value="rejected">[[flags:state-rejected]]</li>
41
+ </ul>
42
+
43
+ <a class="filter-btn btn btn-light btn-sm border {{{ if filters.type }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
44
+ <span class="filter-label">{{{ if filters.type }}}[[flags:filter-type-{./filters.type}]]{{{ else }}}[[flags:filter-type]]{{{ end }}}</span>
45
+ <span class="caret"></span>
46
+ </a>
47
+ <ul class="dropdown-menu">
48
+ <li class="dropdown-item" data-name="type" data-value="all">[[flags:filter-type-all]]</li>
49
+ <li class="dropdown-item" data-name="type" data-value="post">[[flags:filter-type-post]]</li>
50
+ <li class="dropdown-item" data-name="type" data-value="user">[[flags:filter-type-user]]</li>
51
+ </ul>
52
+
53
+ <div component="flags/filter/assignee" class="dropdown" data-filter-name="assignee">
54
+ <a component="user/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.assignee }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
55
+ <span class="filter-label">[[flags:filter-assignee]]</span>
56
+ <span class="caret"></span>
57
+ </a>
58
+
59
+ <ul class="dropdown-menu" style="width: 350px;">
60
+ <li class="px-3 py-1 d-flex flex-column gap-2">
61
+ <input type="text" class="form-control" component="user/filter/search" placeholder="[[search:type-a-username]]">
62
+ <div component="user/filter/selected" class="d-flex flex-wrap gap-2">
63
+ {{{ each selected.assignee }}}
64
+ <div class="d-flex px-2 py-1 rounded-1 text-bg-primary gap-2 align-items-center text-sm">
65
+ {buildAvatar(@value, "16px", true)} {./username}
66
+ <button component="user/filter/delete" data-uid="{./uid}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
67
+ </div>
68
+ {{{ end }}}
69
+ </div>
70
+ <hr/>
71
+ <div component="user/filter/results" class="d-flex flex-wrap gap-2">
72
+ {{{ each userFilterResults }}}
73
+ <button class="btn btn-light btn-sm border" data-uid="{./uid}" data-username="{./username}">{buildAvatar(@value, "16px", true)} {./username}</button>
74
+ {{{ end }}}
34
75
  </div>
35
- </div>
36
- <div class="mb-3">
37
- <label class="form-label" for="sort">[[flags:sort]]</label>
38
- <select class="form-control" id="sort" name="sort">
39
- <optgroup label="[[flags:sort-all]]">
40
- <option value="newest">[[flags:sort-newest]]</option>
41
- <option value="oldest">[[flags:sort-oldest]]</option>
42
- <option value="reports">[[flags:sort-reports]]</option>
43
- </optgroup>
44
- <optgroup label="[[flags:sort-posts-only]]">
45
- <option value="downvotes">[[flags:sort-downvotes]]</option>
46
- <option value="upvotes">[[flags:sort-upvotes]]</option>
47
- <option value="replies">[[flags:sort-replies]]</option>
48
- </optgroup>
49
- </select>
50
- </div>
51
- <div class="mb-3">
52
- <label class="form-label" for="filter-state">[[flags:filter-state]]</label>
53
- <select class="form-control" id="filter-state" name="state">
54
- <option value="">[[flags:state-all]]</option>
55
- <option value="open">[[flags:state-open]]</option>
56
- <option value="wip">[[flags:state-wip]]</option>
57
- <option value="resolved">[[flags:state-resolved]]</option>
58
- <option value="rejected">[[flags:state-rejected]]</option>
59
- </select>
60
- </div>
76
+ </li>
77
+ </ul>
78
+ </div>
61
79
 
62
- <div class="mb-3">
63
- <label class="form-label" for="filter-type">[[flags:filter-type]]</label>
64
- <select class="form-control" id="filter-type" name="type">
65
- <option value="">[[flags:filter-type-all]]</option>
66
- <option value="post">[[flags:filter-type-post]]</option>
67
- <option value="user">[[flags:filter-type-user]]</option>
68
- </select>
69
- </div>
70
- </fieldset>
80
+ <div component="flags/filter/reporterId" class="dropdown" data-filter-name="reporterId">
81
+ <a component="user/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.reporterId }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
82
+ <span class="filter-label">[[flags:filter-reporterId]]</span>
83
+ <span class="caret"></span>
84
+ </a>
71
85
 
72
- <fieldset class="collapse{{{ if expanded }}} show{{{ end }}}" id="more-filters" aria-expanded="{expanded}">
73
- <div class="mb-3">
74
- <label class="form-label" for="filter-assignee">[[flags:filter-assignee]]</label>
75
- <input type="text" class="form-control" id="filter-assignee" name="assignee" />
76
- </div>
86
+ <ul class="dropdown-menu" style="width: 350px;">
87
+ <li class="px-3 py-1 d-flex flex-column gap-2">
88
+ <input type="text" class="form-control" component="user/filter/search" placeholder="[[search:type-a-username]]">
89
+ <div component="user/filter/selected" class="d-flex flex-wrap gap-2">
90
+ {{{ each selected.reporterId }}}
91
+ <div class="d-flex px-2 py-1 rounded-1 text-bg-primary gap-2 align-items-center text-sm">
92
+ {buildAvatar(@value, "16px", true)} {./username}
93
+ <button component="user/filter/delete" data-uid="{./uid}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
94
+ </div>
95
+ {{{ end }}}
96
+ </div>
97
+ <hr/>
98
+ <div component="user/filter/results" class="d-flex flex-wrap gap-2">
99
+ {{{ each userFilterResults }}}
100
+ <button class="btn btn-light btn-sm border" data-uid="{./uid}" data-username="{./username}">{buildAvatar(@value, "16px", true)} {./username}</button>
101
+ {{{ end }}}
102
+ </div>
103
+ </li>
104
+ </ul>
105
+ </div>
77
106
 
78
- <div class="mb-3">
79
- <label class="form-label" for="filter-targetUid">[[flags:filter-targetUid]]</label>
80
- <input type="text" class="form-control" id="filter-targetUid" name="targetUid" />
81
- </div>
107
+ <div component="flags/filter/targetUid" class="dropdown" data-filter-name="targetUid">
108
+ <a component="user/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.targetUid }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
109
+ <span class="filter-label">[[flags:filter-targetUid]]</span>
110
+ <span class="caret"></span>
111
+ </a>
82
112
 
83
- <div class="mb-3">
84
- <label class="form-label" for="filter-reporterId">[[flags:filter-reporterId]]</label>
85
- <input type="text" class="form-control" id="filter-reporterId" name="reporterId" />
86
- </div>
87
- </fieldset>
113
+ <ul class="dropdown-menu" style="width: 350px;">
114
+ <li class="px-3 py-1 d-flex flex-column gap-2">
115
+ <input type="text" class="form-control" component="user/filter/search" placeholder="[[search:type-a-username]]">
116
+ <div component="user/filter/selected" class="d-flex flex-wrap gap-2">
117
+ {{{ each selected.targetUid }}}
118
+ <div class="d-flex px-2 py-1 rounded-1 text-bg-primary gap-2 align-items-center text-sm">
119
+ {buildAvatar(@value, "16px", true)} {./username}
120
+ <button component="user/filter/delete" data-uid="{./uid}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
121
+ </div>
122
+ {{{ end }}}
123
+ </div>
124
+ <hr/>
125
+ <div component="user/filter/results" class="d-flex flex-wrap gap-2">
126
+ {{{ each userFilterResults }}}
127
+ <button class="btn btn-light btn-sm border" data-uid="{./uid}" data-username="{./username}">{buildAvatar(@value, "16px", true)} {./username}</button>
128
+ {{{ end }}}
129
+ </div>
130
+ </li>
131
+ </ul>
132
+ </div>
88
133
 
89
- <div class="d-grid gap-2">
90
- {{{ if expanded }}}
91
- <button type="button" class="btn btn-link" data-bs-toggle="collapse" data-bs-target="#more-filters" aria-controls="#more-filters" data-text-variant="[[flags:more-filters]] ">[[flags:fewer-filters]]&nbsp;<i class="fa fa-sort"></i></button>
92
- {{{ else }}}
93
- <button type="button" class="btn btn-link" data-bs-toggle="collapse" data-bs-target="#more-filters" aria-controls="#more-filters" data-text-variant="[[flags:fewer-filters]] ">[[flags:more-filters]]&nbsp;<i class="fa fa-sort"></i></button>
94
- {{{ end }}}
95
- <button type="button" id="apply-filters" class="btn btn-primary">[[flags:apply-filters]]</button>
96
- </div>
134
+ <form role="form">
135
+ <input type="hidden" name="sort" value="{./sort}" />
136
+ <input type="hidden" name="state" value="{./filters.state}" />
137
+ <input type="hidden" name="type" value="{./filters.type}" />
97
138
  </form>
98
139
  </div>
140
+
141
+ <div component="flags/filters/reset">
142
+ <a class="filter-btn btn btn-warning btn-sm border {{{ if !hasFilter }}}btn-light disabled{{{ end }}}" href="{config.relative_path}/flags" role="button">
143
+ <span class="filter-label">[[flags:filter-reset]]</span>
144
+ </a>
145
+ </div>
146
+
147
+ <div class="btn-group float-end" component="flags/bulk-actions">
148
+ <button class="filter-btn btn btn-light btn-sm border" data-bs-toggle="dropdown" autocomplete="off" aria-haspopup="true" aria-expanded="false" disabled="disabled">
149
+ <span class="filter-label">[[flags:bulk-actions]]</span>
150
+ </button>
151
+ <ul class="dropdown-menu">
152
+ <li><a href="#" class="dropdown-item" data-action="bulk-assign">[[flags:assign-to-me]]</a></li>
153
+ <li><a href="#" class="dropdown-item" data-action="bulk-mark-resolved">[[flags:bulk-resolve]]</a></li>
154
+ </ul>
155
+ </div>
99
156
  </div>
@@ -0,0 +1,38 @@
1
+ <div class="card card-header text-xs px-2 py-1 fw-semibold border-0 align-self-start">
2
+ [[flags:x-flags-found, {count}]]
3
+ </div>
4
+
5
+ <table class="table table-striped table-hover" component="flags/list">
6
+ <thead>
7
+ <tr>
8
+ <th></th>
9
+ <th class="text-xs text-muted">[[flags:reports]]</th>
10
+ <th class="text-xs text-muted">[[flags:first-reported]]</th>
11
+ <th class="text-xs text-muted">[[flags:state]]</th>
12
+ <th>
13
+ <input type="checkbox" data-action="toggle-all" autocomplete="off" />
14
+ </th>
15
+ </tr>
16
+ </thead>
17
+ <tbody>
18
+ {{{ each flags }}}
19
+ <tr data-flag-id="{./flagId}">
20
+ <td>
21
+ <a class="text-reset text-decoration-underline" href="{config.relative_path}/flags/{./flagId}">
22
+ {./target_readable}
23
+ </a>
24
+ </td>
25
+ <td>
26
+ {./heat}
27
+ </td>
28
+ <td><span class="timeago" title="{./datetimeISO}"></span></td>
29
+ <td><span class="badge bg-{./labelClass}">[[flags:state-{./state}]]</span></td>
30
+ <td>
31
+ <input type="checkbox" autocomplete="off" />
32
+ </td>
33
+ </tr>
34
+ {{{end}}}
35
+ </tbody>
36
+ </table>
37
+
38
+ <!-- IMPORT partials/paginator.tpl -->
@@ -20,7 +20,7 @@
20
20
  <div class="text-xs text-muted">{{{ if ./timeagoLong }}}{./timeagoLong}{{{ else }}}<span class="timeago" title="{./datetimeISO}"></span>{{{ end }}}</div>
21
21
  </div>
22
22
  </div>
23
- <div class="">
23
+ <div>
24
24
  {{{ if ./nid }}}
25
25
  <button class="mark-read btn-ghost-sm" style="width: 1.5rem; height: 1.5rem;">
26
26
  <i class="unread fa fa-2xs fa-circle text-primary {{{ if ./read }}}hidden{{{ end }}}"></i>
@@ -1,28 +1,29 @@
1
- <nav class="{{{ if config.theme.stickyToolbar }}}sticky-tools{{{ end }}} navbar navbar-expand mt-4 p-0 border-0 rounded topic-main-buttons">
2
- <div class="card card-header flex-row p-2 border rounded ff-secondary w-100">
3
- <ul class="navbar-nav me-auto gap-2 align-items-center">
4
- {{{ if loggedIn }}}
5
- <button component="topic/mark-unread" class="btn-ghost-sm d-flex gap-2 align-items-center">
6
- <i class="fa fa-fw fa-inbox text-primary"></i>
7
- <span class="d-none d-md-inline fw-semibold">[[topic:mark_unread]]</span>
8
- </button>
9
- {{{ end }}}
1
+ <div class="{{{ if config.theme.stickyToolbar }}}sticky-tools{{{ end }}}">
2
+ <nav class="navbar navbar-expand my-2 p-0 border-0 rounded topic-main-buttons">
3
+ <div class="card card-header flex-row p-2 border rounded w-100">
4
+ <ul class="navbar-nav me-auto gap-2 align-items-center">
5
+ {{{ if loggedIn }}}
6
+ <button component="topic/mark-unread" class="btn-ghost-sm d-flex gap-2 align-items-center">
7
+ <i class="fa fa-fw fa-inbox text-primary"></i>
8
+ <span class="d-none d-md-inline fw-semibold">[[topic:mark_unread]]</span>
9
+ </button>
10
+ {{{ end }}}
10
11
 
11
- <!-- IMPORT partials/topic/watch.tpl -->
12
- <!-- IMPORT partials/topic/sort.tpl -->
13
- <!-- IMPORT partials/topic/tools.tpl -->
12
+ <!-- IMPORT partials/topic/watch.tpl -->
13
+ <!-- IMPORT partials/topic/sort.tpl -->
14
+ <!-- IMPORT partials/topic/tools.tpl -->
14
15
 
15
- {{{ if (!feeds:disableRSS && rssFeedUrl) }}}
16
- <a class="btn-ghost-sm d-none d-lg-flex align-self-stretch" target="_blank" href="{rssFeedUrl}" itemprop="item"><i class="fa fa-rss text-primary"></i></a>
17
- {{{ end }}}
16
+ {{{ if (!feeds:disableRSS && rssFeedUrl) }}}
17
+ <a class="btn-ghost-sm d-none d-lg-flex align-self-stretch" target="_blank" href="{rssFeedUrl}" itemprop="item"><i class="fa fa-rss text-primary"></i></a>
18
+ {{{ end }}}
18
19
 
19
- {{{ if browsingUsers }}}
20
- <div class="hidden-xs">
21
- <!-- IMPORT partials/topic/browsing-users.tpl -->
22
- </div>
23
- {{{ end }}}
24
- </ul>
25
- <!-- IMPORT partials/topic/reply-button.tpl -->
26
- </div>
27
-
28
- </nav>
20
+ {{{ if browsingUsers }}}
21
+ <div class="hidden-xs">
22
+ <!-- IMPORT partials/topic/browsing-users.tpl -->
23
+ </div>
24
+ {{{ end }}}
25
+ </ul>
26
+ <!-- IMPORT partials/topic/reply-button.tpl -->
27
+ </div>
28
+ </nav>
29
+ </div>
@@ -9,7 +9,7 @@
9
9
  </div>
10
10
  {{{ end }}}
11
11
 
12
- <ul id="quick-search-results" class="quick-search-results list-unstyled mb-0 p-0 pe-1 overflow-auto overscroll-behavior-contain" style="max-width: 400px; max-height: 500px;">
12
+ <ul id="quick-search-results" class="quick-search-results list-unstyled mb-0 p-0 pe-1 overflow-auto overscroll-behavior-contain ff-base" style="max-width: 400px; max-height: 500px;">
13
13
  <li role="separator" class="dropdown-divider d-none d-md-block"></li>
14
14
  {{{ each posts }}}
15
15
  <li data-tid="{posts.topic.tid}" data-pid="{posts.pid}" class="d-flex flex-column gap-1">
@@ -22,7 +22,7 @@
22
22
  </p>
23
23
  </a>
24
24
  <div class="d-flex gap-1 post-info px-2 text-xs">
25
- <div class="category-item d-inline-block">
25
+ <div class="category-item d-inline-block ff-secondary">
26
26
  <span>{function.buildCategoryLabel, posts.category}</span>
27
27
  </div>
28
28
  <span class="timeago text-muted" title="{posts.timestampISO}"></span>
@@ -10,15 +10,24 @@
10
10
  </a>
11
11
  <ul class="chats-dropdown dropdown-menu p-1 shadow">
12
12
  <li>
13
- <ul component="chat/list" class="chat-list chats-list list-unstyled overscroll-behavior-contain p-0 pe-1">
14
- <li class="dropdown-item rounded-1 p-2 d-flex gap-2 placeholder-wave">
15
- <div class="main-avatar">
16
- <div class="placeholder" style="width: 32px; height: 32px;"></div>
17
- </div>
18
- <div class="d-flex flex-grow-1 flex-column w-100">
19
- <div class="text-xs"><div class="placeholder col-3"></div></div>
20
- <div class="text-sm"><div class="placeholder col-11"></div></div>
21
- <div class="text-xs"><div class="placeholder col-4"></div></div>
13
+ <ul component="chat/list" class="chat-list chats-list list-unstyled overscroll-behavior-contain p-0 ff-base">
14
+ <li class="rounded-1">
15
+ <div class="d-flex gap-1 justify-content-between">
16
+ <div class="dropdown-item p-2 d-flex gap-2 placeholder-wave">
17
+ <div class="main-avatar">
18
+ <div class="placeholder" style="width: 32px; height: 32px;"></div>
19
+ </div>
20
+ <div class="d-flex flex-grow-1 flex-column w-100">
21
+ <div class="text-xs"><div class="placeholder col-3"></div></div>
22
+ <div class="text-sm"><div class="placeholder col-11"></div></div>
23
+ <div class="text-xs"><div class="placeholder col-4"></div></div>
24
+ </div>
25
+ </div>
26
+ <div>
27
+ <button class="mark-read btn-ghost-sm" style="width: 1.5rem; height: 1.5rem;">
28
+ <i class="unread fa fa-2xs fa-circle text-primary"></i>
29
+ </button>
30
+ </div>
22
31
  </div>
23
32
  </li>
24
33
  </ul>
@@ -10,7 +10,7 @@
10
10
  </a>
11
11
  <ul class="notifications-dropdown dropdown-menu p-1 shadow">
12
12
  <li>
13
- <ul component="notifications/list" class="notification-list list-unstyled overscroll-behavior-contain">
13
+ <ul component="notifications/list" class="notification-list list-unstyled overscroll-behavior-contain ff-base">
14
14
  <li class="mb-2 p-1 placeholder-wave">
15
15
  <div class="d-flex gap-1 justify-content-between">
16
16
  <div class="d-flex gap-2 flex-grow-1">
@@ -30,7 +30,7 @@
30
30
  </div>
31
31
  </div>
32
32
  </div>
33
- <div class="">
33
+ <div>
34
34
  <button class="mark-read btn-ghost-sm" style="width: 1.5rem; height: 1.5rem;">
35
35
  <i class="unread fa fa-2xs fa-circle text-primary"></i>
36
36
  </button>
@@ -2,10 +2,10 @@
2
2
  {buildAvatar(user, "20px", true)}
3
3
  <span id="user-header-name" class="nav-text small visible-open fw-semibold">{user.username}</span>
4
4
  </label>
5
- <ul id="user-control-list" component="header/usercontrol" class="overscroll-behavior-contain user-dropdown dropdown-menu shadow p-1 text-sm" aria-labelledby="user_dropdown">
5
+ <ul id="user-control-list" component="header/usercontrol" class="overscroll-behavior-contain user-dropdown dropdown-menu shadow p-1 text-sm ff-base" aria-labelledby="user_dropdown">
6
6
  <li>
7
7
  <a class="dropdown-item rounded-1 d-flex align-items-center gap-1" component="header/profilelink" href="{relative_path}/user/{user.userslug}">
8
- <div class="text-center"><span component="user/status" class="badge border border-white border-2 rounded-circle status {user.status}"><span class="visually-hidden">[[global:{user.status}]]</span></span></div>
8
+ <span component="user/status" class="badge border border-white border-2 rounded-circle status {user.status}"><span class="visually-hidden">[[global:{user.status}]]</span></span>
9
9
  <span class="fw-semibold" component="header/username">{user.username}</span>
10
10
  </a>
11
11
  </li>
@@ -13,25 +13,25 @@
13
13
  <li><h6 class="dropdown-header text-xs">[[global:status]]</h6></li>
14
14
  <li>
15
15
  <a href="#" class="dropdown-item rounded-1 user-status d-flex align-items-center gap-1" data-status="online">
16
- <div class="text-center"><span component="user/status" class="badge border border-white border-2 rounded-circle status online"><span class="visually-hidden">[[global:online]]</span></span></div>
16
+ <span component="user/status" class="badge border border-white border-2 rounded-circle status online"><span class="visually-hidden">[[global:online]]</span></span>
17
17
  <span{{{ if user.online }}} class="fw-semibold"{{{ end }}}> [[global:online]]</span>
18
18
  </a>
19
19
  </li>
20
20
  <li>
21
21
  <a href="#" class="dropdown-item rounded-1 user-status d-flex align-items-center gap-1" data-status="away">
22
- <div class="text-center"><span component="user/status" class="badge border border-white border-2 rounded-circle status away"><span class="visually-hidden">[[global:away]]</span></span></div>
22
+ <span component="user/status" class="badge border border-white border-2 rounded-circle status away"><span class="visually-hidden">[[global:away]]</span></span>
23
23
  <span{{{ if user.away}}} class="fw-semibold"{{{ end }}}> [[global:away]]</span>
24
24
  </a>
25
25
  </li>
26
26
  <li>
27
27
  <a href="#" class="dropdown-item rounded-1 user-status d-flex align-items-center gap-1" data-status="dnd">
28
- <div class="text-center"><span component="user/status" class="badge border border-white border-2 rounded-circle status dnd"><span class="visually-hidden">[[global:dnd]]</span></span></div>
28
+ <span component="user/status" class="badge border border-white border-2 rounded-circle status dnd"><span class="visually-hidden">[[global:dnd]]</span></span>
29
29
  <span{{{ if user.dnd}}} class="fw-semibold"{{{ end }}}> [[global:dnd]]</span>
30
30
  </a>
31
31
  </li>
32
32
  <li>
33
33
  <a href="#" class="dropdown-item rounded-1 user-status d-flex align-items-center gap-1" data-status="offline">
34
- <div class="text-center"><span component="user/status" class="badge border border-white border-2 rounded-circle status offline"><span class="visually-hidden">[[global:invisible]]</span></span></div>
34
+ <span component="user/status" class="badge border border-white border-2 rounded-circle status offline"><span class="visually-hidden">[[global:invisible]]</span></span>
35
35
  <span{{{ if user.offline}}} class="fw-semibold"{{{ end }}}> [[global:invisible]]</span>
36
36
  </a>
37
37
  </li>
@@ -1,8 +1,6 @@
1
1
  {{{each tags}}}
2
- <div class="tag-container d-flex">
3
- <div class="d-flex gap-2 align-items-center text-truncate">
4
- <a class="fs-5 badge border text-bg-light text-truncate text-decoration-none" href="{config.relative_path}/tags/{tags.valueEncoded}" data-tag="{tags.valueEscaped}"><span class="tag-item text-muted text-uppercase text-nowrap tag-class-{tags.class}" data-tag="{tags.valueEscaped}">{tags.valueEscaped}</span></a>
5
- <span class="tag-topic-count text-secondary fw-semibold text-nowrap human-readable-number" title="{tags.score}">{tags.score}</span>
6
- </div>
7
- </div>
2
+ <a href="{config.relative_path}/tags/{./valueEncoded}" data-tag="{./valueEscaped}" class="btn-ghost flex-column gap-1 align-items-start justify-content-start text-truncate">
3
+ <div class="fw-semibold text-nowrap tag-item w-100 text-truncate">{./valueEscaped}</div>
4
+ <div class="text-xs text-muted text-nowrap tag-topic-count">[[global:x-topics, {./score}]]</div>
5
+ </a>
8
6
  {{{end}}}
@@ -1,50 +1,52 @@
1
- <nav class="topic-list-header {{{ if config.theme.stickyToolbar }}} sticky-tools{{{ end }}} navbar navbar-expand p-0 border-0 rounded mb-3">
2
- <div class="card card-header flex-row p-2 gap-1 border rounded ff-secondary w-100">
3
- <ul component="category/controls" class="navbar-nav me-auto gap-2 align-items-center">
4
- {{{ if template.category }}}
5
- <!-- IMPORT partials/category/watch.tpl -->
6
- <!-- IMPORT partials/category/sort.tpl -->
7
- {{{ end }}}
8
- {{{ if (template.popular || template.top)}}}
9
- <!-- IMPORT partials/topic-terms.tpl -->
10
- {{{ end }}}
11
- {{{ if (template.unread || (template.recent || (template.popular || template.top))) }}}
12
- <!-- IMPORT partials/topic-filters.tpl -->
13
- <!-- IMPORT partials/category/filter-dropdown-left.tpl -->
14
- {{{ end }}}
15
- {{{ if template.unread }}}
16
- <div class="markread btn-group {{{ if !topics.length }}}hidden{{{ end }}}">
17
- <!-- IMPORT partials/category/selector-dropdown-left.tpl -->
18
- </div>
19
- {{{ end }}}
20
- {{{ if template.tag }}}
21
- <!-- IMPORT partials/category/filter-dropdown-left.tpl -->
22
- {{{ end }}}
23
- <!-- IMPORT partials/category/tools.tpl -->
1
+ <div class="{{{ if config.theme.stickyToolbar }}}sticky-tools{{{ end }}}">
2
+ <nav class="topic-list-header navbar navbar-expand p-0 border-0 rounded my-2">
3
+ <div class="card card-header flex-row p-2 gap-1 border rounded w-100">
4
+ <ul component="category/controls" class="navbar-nav me-auto gap-2 align-items-center">
5
+ {{{ if template.category }}}
6
+ <!-- IMPORT partials/category/watch.tpl -->
7
+ <!-- IMPORT partials/category/sort.tpl -->
8
+ {{{ end }}}
9
+ {{{ if (template.popular || template.top)}}}
10
+ <!-- IMPORT partials/topic-terms.tpl -->
11
+ {{{ end }}}
12
+ {{{ if (template.unread || (template.recent || (template.popular || template.top))) }}}
13
+ <!-- IMPORT partials/topic-filters.tpl -->
14
+ <!-- IMPORT partials/category/filter-dropdown-left.tpl -->
15
+ {{{ end }}}
16
+ {{{ if template.unread }}}
17
+ <div class="markread btn-group {{{ if !topics.length }}}hidden{{{ end }}}">
18
+ <!-- IMPORT partials/category/selector-dropdown-left.tpl -->
19
+ </div>
20
+ {{{ end }}}
21
+ {{{ if template.tag }}}
22
+ <!-- IMPORT partials/category/filter-dropdown-left.tpl -->
23
+ {{{ end }}}
24
+ <!-- IMPORT partials/category/tools.tpl -->
24
25
 
25
- {{{ if (!feeds:disableRSS && rssFeedUrl) }}}
26
- <a class="btn-ghost-sm d-none d-lg-flex align-self-stretch" target="_blank" href="{rssFeedUrl}" itemprop="item"><i class="fa fa-rss text-primary"></i></a>
27
- {{{ end }}}
26
+ {{{ if (!feeds:disableRSS && rssFeedUrl) }}}
27
+ <a class="btn-ghost-sm d-none d-lg-flex align-self-stretch" target="_blank" href="{rssFeedUrl}" itemprop="item"><i class="fa fa-rss text-primary"></i></a>
28
+ {{{ end }}}
28
29
 
29
- <a href="{config.relative_path}{{{ if template.category }}}{url}{{{ else }}}/{selectedFilter.url}{querystring}{{{ end }}}" class="d-inline-block text-decoration-none">
30
- <div class="d-md-block alert alert-warning h-100 m-0 px-2 py-1 line-clamp-2 text-sm text-break hide" id="new-topics-alert">There is a new post. Click here to reload.</div>
31
- </a>
32
- </ul>
30
+ <a href="{config.relative_path}{{{ if template.category }}}{url}{{{ else }}}/{selectedFilter.url}{querystring}{{{ end }}}" class="d-inline-block text-decoration-none">
31
+ <div class="d-md-block alert alert-warning h-100 m-0 px-2 py-1 line-clamp-2 text-sm text-break hide" id="new-topics-alert">There is a new post. Click here to reload.</div>
32
+ </a>
33
+ </ul>
33
34
 
34
- <div class="d-flex gap-1 align-items-center">
35
- {{{ if template.category }}}
36
- {{{ if privileges.topics:create }}}
37
- <a href="{config.relative_path}/compose?cid={cid}" component="category/post" id="new_topic" class="btn btn-primary btn-sm text-nowrap" data-ajaxify="false" role="button">[[category:new_topic_button]]</a>
38
- {{{ end }}}
39
- {{{ else }}}
40
- {{{ if canPost }}}
41
- <!-- IMPORT partials/buttons/newTopic.tpl -->
42
- {{{ end }}}
43
- {{{ end }}}
44
- <!-- only show login button if not logged in and doesn't have any posting privilege -->
45
- {{{ if (!loggedIn && (!privileges.topics:create && !canPost))}}}
46
- <a component="category/post/guest" href="{config.relative_path}/login" class="btn btn-primary">[[category:guest-login-post]]</a>
47
- {{{ end }}}
35
+ <div class="d-flex gap-1 align-items-center">
36
+ {{{ if template.category }}}
37
+ {{{ if privileges.topics:create }}}
38
+ <a href="{config.relative_path}/compose?cid={cid}" component="category/post" id="new_topic" class="btn btn-primary btn-sm text-nowrap" data-ajaxify="false" role="button">[[category:new_topic_button]]</a>
39
+ {{{ end }}}
40
+ {{{ else }}}
41
+ {{{ if canPost }}}
42
+ <!-- IMPORT partials/buttons/newTopic.tpl -->
43
+ {{{ end }}}
44
+ {{{ end }}}
45
+ <!-- only show login button if not logged in and doesn't have any posting privilege -->
46
+ {{{ if (!loggedIn && (!privileges.topics:create && !canPost))}}}
47
+ <a component="category/post/guest" href="{config.relative_path}/login" class="btn btn-primary">[[category:guest-login-post]]</a>
48
+ {{{ end }}}
49
+ </div>
48
50
  </div>
49
- </div>
50
- </nav>
51
+ </nav>
52
+ </div>
@@ -4,36 +4,34 @@
4
4
  <div class="fw-semibold text-truncate" title="{./displayname}">{./displayname}</div>
5
5
  <div class="text-xs text-muted text-truncate">@{./username}</div>
6
6
 
7
- <div class="align-self-start">
8
- {{{ if section_online }}}
9
- <div class="card card-header border rounded-1 py-0 px-1 text-xs">
10
- <span class="timeago" title="{./lastonlineISO}"></span>
11
- </div>
12
- {{{ end }}}
7
+ {{{ if section_online }}}
8
+ <div class="text-xs text-muted text-truncate">
9
+ <span class="timeago" title="{./lastonlineISO}"></span>
10
+ </div>
11
+ {{{ end }}}
13
12
 
14
- {{{ if section_joindate }}}
15
- <div class="card card-header border rounded-1 py-0 px-1 text-xs">
16
- <span class="timeago" title="{./joindateISO}"></span>
17
- </div>
18
- {{{ end }}}
13
+ {{{ if section_joindate }}}
14
+ <div class="text-xs text-muted text-truncate">
15
+ <span class="timeago" title="{./joindateISO}"></span>
16
+ </div>
17
+ {{{ end }}}
19
18
 
20
- {{{ if section_sort-reputation }}}
21
- <div class="card card-header border rounded-1 py-0 px-1 text-xs">
22
- <span class="formatted-number">{./reputation}</span>
23
- </div>
24
- {{{ end }}}
19
+ {{{ if section_sort-reputation }}}
20
+ <div class="text-xs text-muted text-truncate">
21
+ <span class="formatted-number">{./reputation}</span>
22
+ </div>
23
+ {{{ end }}}
25
24
 
26
- {{{ if section_sort-posts }}}
27
- <div class="card card-header border rounded-1 py-0 px-1 text-xs">
28
- <span class="formatted-number">{./postcount}</span>
29
- </div>
30
- {{{ end }}}
25
+ {{{ if section_sort-posts }}}
26
+ <div class="text-xs text-muted text-truncate">
27
+ <span class="formatted-number">{./postcount}</span>
28
+ </div>
29
+ {{{ end }}}
31
30
 
32
- {{{ if section_flagged }}}
33
- <div class="card card-header border rounded-1 py-0 px-1 text-xs">
34
- <span class="formatted-number">{./flags}</span>
35
- </div>
36
- {{{ end }}}
31
+ {{{ if section_flagged }}}
32
+ <div class="text-xs text-muted text-truncate">
33
+ <span class="formatted-number">{./flags}</span>
37
34
  </div>
35
+ {{{ end }}}
38
36
  </div>
39
37
  </a>
@@ -1,4 +1,4 @@
1
- <div id="users-container" class="users-container row row-cols-2 row-cols-md-3 row-cols-lg-4 row-cols-xl-5 g-2">
1
+ <div id="users-container" class="users-container row row-cols-2 row-cols-md-3 row-cols-lg-4 row-cols-xl-5 g-4">
2
2
  {{{ each users }}}
3
3
  <!-- IMPORT partials/users/item.tpl -->
4
4
  {{{ end }}}
@@ -33,7 +33,7 @@
33
33
  {{{ if (!posts.length && isAdmin) }}}
34
34
  {{{ if !singlePost }}}
35
35
  <div class="alert alert-info">
36
- <p>[[post-queue:no-queued-posts]]</p>
36
+ [[post-queue:no-queued-posts]]
37
37
  {{{ if !enabled }}}<p>[[post-queue:enabling-help, {config.relative_path}/admin/settings/post#post-queue]]</p>{{{ end }}}
38
38
  </div>
39
39
  {{{ else }}}
@@ -4,7 +4,7 @@
4
4
  {{{end}}}
5
5
  </div>
6
6
  <div class="tags">
7
- <h2 class="fw-semibold">[[pages:tags]]</h2>
7
+ <h3 class="fw-semibold">[[pages:tags]]</h3>
8
8
  {{{ if displayTagSearch }}}
9
9
  {{{ if tags.length }}}
10
10
  <div class="row justify-content-end mb-3">
@@ -29,7 +29,7 @@
29
29
  {{{ end }}}
30
30
 
31
31
  <div class="category">
32
- <div class="tag-list row row-cols-2 row-cols-lg-3 row-cols-xl-4 row-cols-xxl-5 gx-3 gy-2" data-nextstart="{nextStart}">
32
+ <div class="tag-list row row-cols-2 row-cols-lg-4 row-cols-xl-5 gx-3 gy-2" data-nextstart="{nextStart}">
33
33
  <!-- IMPORT partials/tags_list.tpl -->
34
34
  </div>
35
35
  </div>
@@ -49,7 +49,7 @@
49
49
  <!-- IMPORT partials/topic/deleted-message.tpl -->
50
50
  {{{ end }}}
51
51
 
52
- <ul component="topic" class="posts timeline mt-sm-4 p-0 py-3" data-tid="{tid}" data-cid="{cid}">
52
+ <ul component="topic" class="posts timeline mt-sm-2 p-0 py-3" data-tid="{tid}" data-cid="{cid}">
53
53
  {{{each posts}}}
54
54
  <li component="post" class="pt-4 {{{ if posts.deleted }}}deleted{{{ end }}} {{{ if posts.selfPost }}}self-post{{{ end }}} {{{ if posts.topicOwnerPost }}}topic-owner-post{{{ end }}}" <!-- IMPORT partials/data/topic.tpl -->>
55
55
  <a component="post/anchor" data-index="{./index}" id="{increment(./index, "1")}"></a>
@@ -4,7 +4,7 @@
4
4
  {{{end}}}
5
5
  </div>
6
6
  <div class="users">
7
- <h2 class="fw-semibold">[[global:users]]</h2>
7
+ <h3 class="fw-semibold">[[global:users]]</h3>
8
8
  <div class="d-flex flex-wrap justify-content-between">
9
9
  <div class="mb-2 mb-md-0">
10
10
  <!-- IMPORT partials/users_list_menu.tpl -->