nodebb-theme-harmony 1.0.0-beta.83 → 1.0.0-beta.85

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/library.js CHANGED
@@ -93,6 +93,11 @@ library.defineWidgetAreas = async function (areas) {
93
93
  template: 'global',
94
94
  location: 'sidebar-footer',
95
95
  },
96
+ {
97
+ name: 'Brand Header',
98
+ template: 'global',
99
+ location: 'brand-header',
100
+ },
96
101
  ]);
97
102
 
98
103
  return areas;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-theme-harmony",
3
- "version": "1.0.0-beta.83",
3
+ "version": "1.0.0-beta.85",
4
4
  "nbbpm": {
5
5
  "compatibility": "^3.0.0"
6
6
  },
package/scss/common.scss CHANGED
@@ -2,20 +2,23 @@
2
2
  body {
3
3
  overflow-y: scroll;
4
4
  -webkit-font-smoothing: antialiased;
5
- -moz-osx-font-smoothing: grayscale;
6
- text-rendering: optimizeLegibility;
5
+ -moz-osx-font-smoothing: grayscale;
6
+ text-rendering: optimizeLegibility;
7
7
  }
8
8
 
9
9
  // fixes chrome font boosting :/ https://stackoverflow.com/questions/13430897/how-to-override-font-boosting-in-mobile-chrome
10
10
  body * {
11
- max-height:1000000px;
12
- text-size-adjust: none;
13
- -webkit-text-size-adjust: none;
14
- -moz-text-size-adjust: none;
11
+ max-height:1000000px;
12
+ text-size-adjust: none;
13
+ -webkit-text-size-adjust: none;
14
+ -moz-text-size-adjust: none;
15
15
  }
16
16
 
17
17
  .ff-base {
18
- font-family: $font-family-base;
18
+ font-family: $font-family-base !important;
19
+ }
20
+ .ff-sans {
21
+ font-family: $font-family-sans-serif !important;
19
22
  }
20
23
  .ff-secondary {
21
24
  font-family: $font-family-secondary;
@@ -1,32 +1,164 @@
1
- .topic-list {
2
- overflow-x: hidden!important;
3
- }
1
+ ul.topics-list {
2
+ position: relative;
4
3
 
5
- [component="category/topic"] {
6
- &.deleted {
7
- opacity: 0.6;
8
- .meta { display: none!important; }
9
- }
4
+ li {
5
+ display: flex;
6
+ gap: 1rem;
7
+ border-bottom: 1px solid $border-color;
8
+ padding: 0.75rem 0;
9
+
10
+ @include media-breakpoint-up(sm) { padding: 1.5rem 0; }
10
11
 
11
- &.selected {
12
- [component="topic/select"] {
13
- color: $success!important;
12
+ &.deleted {
13
+ opacity: 0.6;
14
+ .meta { display: none!important; }
14
15
  }
15
- }
16
- .lastpost .post-content {
17
- p { margin-bottom: 0; }
18
- }
19
16
 
20
- // &.unread .title {
21
- // color: $link-color;
22
- // }
17
+ &.selected {
18
+ background-color: $light;
19
+
20
+ [component="topic/select"] {
21
+ color: $primary!important;
22
+ }
23
+ }
24
+
25
+ > .thumb-avatar-box {
26
+ flex: none;
27
+ display: none;
28
+ @include media-breakpoint-up(sm) { display: flex; }
29
+ }
30
+
31
+ > .wrapper {
32
+ flex: 1 1 auto;
33
+ display: grid;
34
+ align-items: start;
35
+ gap: 0.5rem;
36
+
37
+ @include media-breakpoint-up(sm) { gap: 1rem; }
38
+ @include media-breakpoint-up(xl) { display: flex; }
39
+ // @container (min-width: 799px) { display: flex; }
40
+
41
+ > .wrapper2 {
42
+ flex: 1 1 auto;
43
+ display: flex;
44
+ gap: 0.5rem;
45
+
46
+ @include media-breakpoint-up(sm) { gap: 1rem; }
47
+
48
+ > .title_badges {
49
+ flex: 1 1 auto;
50
+ display: flex;
51
+ flex-direction: column;
52
+ gap: 0.25rem;
53
+
54
+ @include media-breakpoint-up(sm) { gap: 0.5rem; }
55
+
56
+ > h2 {
57
+ font-size: 1rem !important;
58
+ @include media-breakpoint-up(sm) {
59
+ font-size: 1.125rem !important;
60
+ }
61
+ }
62
+
63
+ > .info {
64
+ display: flex;
65
+ flex-wrap: wrap;
66
+ gap: 0.25rem;
67
+ align-items: center;
68
+ }
69
+ }
23
70
 
24
- .ui-sortable-handle {
25
- cursor: move;
71
+ > .stats {
72
+ flex: none;
73
+ display: none;
74
+ gap: 0.25rem;
75
+ align-items: start;
76
+ grid-auto-rows: min-content;
77
+ @include media-breakpoint-up(md) { display: grid; }
78
+ @include media-breakpoint-up(xl) { display: flex; }
79
+
80
+ > .card {
81
+ display: flex;
82
+ flex-direction: row;
83
+ gap: 0.5rem;
84
+ flex-wrap: nowrap;
85
+ align-items: center;
86
+ padding: 0.25rem 0.5rem;
87
+ border: none;
88
+ border-radius: 4px;
89
+ color: $text-muted;
90
+ @include media-breakpoint-up(xl) {
91
+ flex-direction: column;
92
+ padding: 0.5rem 1rem;
93
+ gap: 0;
94
+ min-height:3.4rem;
95
+ }
96
+
97
+ > i.fa {
98
+ display: flex;
99
+ font-size: 0.75rem;
100
+ @include media-breakpoint-up(xl) { display: none; }
101
+ }
102
+ > .human-readable-number {
103
+ line-height: 1;
104
+ font-size: 0.875rem;
105
+ @include media-breakpoint-up(xl) { font-size: 1.25rem; }
106
+ }
107
+ > .text-lowercase {
108
+ display: none;
109
+ @include media-breakpoint-up(xl) { display: flex; }
110
+ }
111
+ }
112
+ }
113
+ }
114
+
115
+ > .teaser {
116
+ flex: none;
117
+ overflow: hidden;
118
+
119
+ @include media-breakpoint-up(xl) {
120
+ width:12rem;
121
+ }
122
+
123
+ > .lastpost {
124
+ @include media-breakpoint-up(xl) {
125
+ min-height: 3.4rem;
126
+ }
127
+ }
128
+
129
+ .post-content {
130
+ @include line-clamp(1);
131
+ @include media-breakpoint-up(xl) {
132
+ @include line-clamp(2);
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ > .checkbox {
139
+ flex: none;
140
+ }
141
+
142
+ .ui-sortable-handle {
143
+ cursor: move;
144
+ }
26
145
  }
27
146
 
28
- .topic-thumb img {
29
- width: 80px;
30
- height: auto;
147
+ &.narrow {
148
+ li {
149
+ .wrapper {
150
+ display: grid !important;
151
+
152
+ .teaser {
153
+ width: auto !important;
154
+
155
+ .post-content {
156
+ -webkit-line-clamp: 1 !important;
157
+ }
158
+ }
159
+ }
160
+ }
31
161
  }
32
- }
162
+
163
+
164
+ }
package/scss/topic.scss CHANGED
@@ -128,6 +128,10 @@
128
128
  [component="post/actions"] {
129
129
  opacity: 0;
130
130
  transition: $transition-fade;
131
+
132
+ &:has([aria-expanded="true"]) {
133
+ opacity: 1;
134
+ }
131
135
  }
132
136
 
133
137
  &:hover {
@@ -5,7 +5,7 @@
5
5
  <div class="alert alert-warning text-center">[[user:has_no_follower]]</div>
6
6
  {{{ end }}}
7
7
 
8
- <div class="row row-cols-2 row-cols-lg-3 row-cols-xl-4 g-2">
8
+ <div class="row row-cols-2 row-cols-lg-3 row-cols-xl-4 g-4">
9
9
  {{{ each users }}}
10
10
  <!-- IMPORT partials/users/item.tpl -->
11
11
  {{{end}}}
@@ -6,7 +6,7 @@
6
6
  <div class="alert alert-warning text-center">[[user:follows_no_one]]</div>
7
7
  {{{ end }}}
8
8
 
9
- <div class="row row-cols-2 row-cols-lg-3 row-cols-xl-4 g-2">
9
+ <div class="row row-cols-2 row-cols-lg-3 row-cols-xl-4 g-4">
10
10
  {{{ each users }}}
11
11
  <!-- IMPORT partials/users/item.tpl -->
12
12
  {{{end}}}
@@ -83,8 +83,8 @@
83
83
  {{{ end }}}
84
84
  {{{ each history }}}
85
85
  <div class="d-flex flex-column gap-1">
86
- <div class="d-flex gap-2">
87
- <a href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(./user, "16px", true)}</a>
86
+ <div class="d-flex gap-2 align-items-center">
87
+ <a class="d-flex text-decoration-none" href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(./user, "16px", true)}</a>
88
88
  <a href="{config.relative_path}/user/{./user.userslug}">{./user.username}</a>
89
89
  <span class="timeago text-muted" title="{./datetimeISO}"></span>
90
90
  </div>
@@ -113,9 +113,9 @@
113
113
  </h2>
114
114
  <div component="flag/content" class="d-flex flex-column gap-1 pb-3 border-bottom">
115
115
  {{{ if type_bool.post }}}
116
- <div class="d-flex gap-2">
117
- <a href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(target.user, "16px", true)}</a>
118
- <a href="{config.relative_path}/user/{./user.userslug}">{target.user.username}</a>
116
+ <div class="d-flex gap-2 align-items-center">
117
+ <a class="d-flex text-decoration-none" href="{config.relative_path}/user/{target.user.userslug}">{buildAvatar(target.user, "16px", true)}</a>
118
+ <a href="{config.relative_path}/user/{target.user.userslug}">{target.user.username}</a>
119
119
  <span class="timeago text-muted" title="{target.timestampISO}"></span>
120
120
  </div>
121
121
  <blockquote>{target.content}</blockquote>
@@ -138,8 +138,8 @@
138
138
  <ul class="list-unstyled mt-4">
139
139
  {{{ each reports }}}
140
140
  <li class="d-flex flex-column gap-1" component="flag/report" data-timestamp="{./timestamp}">
141
- <div class="d-flex gap-2">
142
- <a href="{config.relative_path}/user/{./reporter.userslug}">{buildAvatar(./reporter, "16px", true)}</a>
141
+ <div class="d-flex gap-2 align-items-center">
142
+ <a class="d-flex text-decoration-none" href="{config.relative_path}/user/{./reporter.userslug}">{buildAvatar(./reporter, "16px", true)}</a>
143
143
  <a href="{config.relative_path}/user/{./reporter.userslug}">{./reporter.username}</a>
144
144
  <span class="timeago text-muted" title="{./timestampISO}"></span>
145
145
  </div>
@@ -6,7 +6,7 @@
6
6
  <!-- IMPORT partials/mobile-footer.tpl -->
7
7
  {{{ if !isSpider }}}
8
8
  <div class="">
9
- <div component="toaster/tray" class="alert-window fixed-bottom mb-5 mb-md-2 me-2 me-md-5 ms-auto" style="width:300px;">
9
+ <div component="toaster/tray" class="alert-window fixed-bottom mb-5 mb-md-2 me-2 me-md-5 ms-auto" style="width:300px; z-index: 1090;">
10
10
  <div id="reconnect-alert" class="alert alert-dismissible alert-warning clearfix hide" component="toaster/toast">
11
11
  <button type="button" class="btn-close float-end" data-bs-dismiss="alert" aria-hidden="true"></button>
12
12
  <p>[[global:reconnecting-message, {config.siteTitle}]]</p>
@@ -1,14 +1,14 @@
1
1
  <li component="categories/category" data-cid="{./cid}" data-parent-cid="{../parentCid}" class="category-{./cid}">
2
2
  <meta itemprop="name" content="{./name}">
3
- <div class="content depth-{./depth} d-flex gap-3 py-3">
4
- <div class="flex-1 d-flex gap-2">
5
- <div class="fs-5">
3
+ <div class="content depth-{./depth} d-flex gap-2">
4
+ <div class="flex-1 align-items-start d-flex gap-2">
5
+ <div>
6
6
  {buildCategoryIcon(@value, "24px", "rounded-1")}
7
7
  </div>
8
- <div>
9
- <h2 class="title fw-semibold fs-5 m-0 tracking-tight">
8
+ <div class="d-grid gap-0">
9
+ <div class="title fw-semibold">
10
10
  <!-- IMPORT partials/categories/link.tpl -->
11
- </h2>
11
+ </div>
12
12
  {{{ if ./descriptionParsed }}}
13
13
  <div class="description text-muted text-xs">{./descriptionParsed}</div>
14
14
  {{{ end }}}
@@ -18,5 +18,5 @@
18
18
  <!-- IMPORT partials/category/watch.tpl -->
19
19
  </div>
20
20
  </div>
21
- <hr class="text-muted opacity-25 m-0"/>
21
+ <hr class="text-muted opacity-25"/>
22
22
  </li>
@@ -94,5 +94,5 @@
94
94
 
95
95
  <div class="d-flex flex-column flex-md-row">
96
96
  <!-- IMPORT partials/account/sidebar-left.tpl -->
97
- <div class="account-content flex-1 ps-md-2 ps-lg-5" style="min-width: 0;">
97
+ <div class="account-content flex-1 ps-md-2 ps-lg-3 ps-xl-4" style="min-width: 0;">
98
98
 
@@ -21,9 +21,15 @@
21
21
  {{{ if !./isSection }}}
22
22
  <span class="category-children-item small">
23
23
  {{{ if ./link }}}
24
- <div class="d-flex align-items-center gap-1"><i class="fa fa-fw fa-caret-right text-primary"></i><a href="{./link}" class="text-reset fw-semibold">{./name}</a></div>
24
+ <div class="d-flex align-items-start gap-1">
25
+ <i class="fa fa-fw fa-caret-right text-primary mt-1"></i>
26
+ <a href="{./link}" class="text-reset fw-semibold">{./name}</a>
27
+ </div>
25
28
  {{{ else }}}
26
- <div class="d-flex align-items-center gap-1"><i class="fa fa-fw fa-caret-right text-primary"></i><a href="{config.relative_path}/category/{./slug}" class="text-reset fw-semibold">{./name}</a></div>
29
+ <div class="d-flex align-items-start gap-1">
30
+ <i class="fa fa-fw fa-caret-right text-primary mt-1"></i>
31
+ <a href="{config.relative_path}/category/{./slug}" class="text-reset fw-semibold">{./name}</a>
32
+ </div>
27
33
  {{{ end }}}
28
34
  </span>
29
35
  {{{ end }}}
@@ -9,7 +9,7 @@
9
9
  <span class="visible-md-inline visible-lg-inline fw-semibold">[[unread:all_categories]]</span>{{{ end }}}
10
10
  </button>
11
11
  <div component="category-selector-search" class="hidden position-absolute">
12
- <input type="text" class="form-control form-control-sm" autocomplete="off">
12
+ <input type="text" class="form-control form-control-sm" placeholder="[[search:type-to-search]]" autocomplete="off">
13
13
  </div>
14
14
  <ul component="category/list" class="dropdown-menu p-1 text-sm category-dropdown-menu" role="menu">
15
15
  <li role="presentation" class="category" data-cid="all">
@@ -12,7 +12,7 @@
12
12
  </span>
13
13
  </button>
14
14
  <div component="category-selector-search" class="hidden position-absolute">
15
- <input type="text" class="form-control form-control-sm" autocomplete="off">
15
+ <input type="text" class="form-control form-control-sm" placeholder="[[search:type-to-search]]" autocomplete="off">
16
16
  </div>
17
17
  <ul component="category/list" class="dropdown-menu p-1 text-sm category-dropdown-menu" role="menu">
18
18
  <li component="category/no-matches" role="presentation" class="category hidden">
@@ -3,6 +3,7 @@
3
3
  <button class="btn-ghost-sm d-flex gap-2 dropdown-toggle" data-bs-toggle="dropdown" type="button">
4
4
  <i class="fa fa-fw fa-gear text-primary"></i>
5
5
  <span class="visible-md-inline visible-lg-inline fw-semibold">[[topic:thread_tools.title]]</span>
6
+ <span component="topic/selected/badge" class="badge rounded-pill bg-secondary"></span>
6
7
  </button>
7
8
  <ul class="dropdown-menu p-1 text-sm">
8
9
  <li>
@@ -72,7 +73,9 @@
72
73
 
73
74
  {{{each thread_tools}}}
74
75
  <li>
75
- <a href="#" class="dropdown-item rounded-1 d-flex align-items-center gap-2 {thread_tools.class}"><i class="fa fa-fw {thread_tools.icon}"></i> {thread_tools.title}</a>
76
+ <a href="#" class="dropdown-item rounded-1 d-flex align-items-center gap-2 {thread_tools.class}">
77
+ <i class="fa fa-fw {thread_tools.icon}"></i>
78
+ {thread_tools.title}</a>
76
79
  </li>
77
80
  {{{end}}}
78
81
  </ul>
@@ -1,6 +1,6 @@
1
1
  <div component="chat/recent/room" data-roomid="{./roomId}" data-full="1" class="rounded-1 {{{ if ./unread }}}unread{{{ end }}}">
2
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">
3
+ <div class="position-relative d-flex flex-grow-1 gap-2 justify-content-start align-items-start btn-ghost-sm ff-sans">
4
4
  <div class="main-avatar">
5
5
  <a class="stretched-link" href="{config.relative_path}/me/chats/{./roomId}"></a>
6
6
  {{{ if ./users.length }}}
@@ -11,7 +11,41 @@
11
11
  </ul>
12
12
  </div>
13
13
 
14
- <!-- IMPORT partials/category/filter-dropdown-left.tpl -->
14
+
15
+ <div component="category/dropdown" class="btn-group category-dropdown-container bottom-sheet">
16
+ <button type="button" class="filter-btn btn btn-light btn-sm border d-flex gap-2 dropdown-toggle {{{ if filters.cid }}}active-filter{{{ end }}}" data-bs-toggle="dropdown">
17
+ {{{ if selectedCategory }}}
18
+ <span class="category-item d-inline-flex align-items-center gap-1">
19
+ {buildCategoryIcon(selectedCategory, "18px", "rounded-circle")}
20
+ <span class="visible-md-inline visible-lg-inline">{selectedCategory.name}</span>
21
+ </span>
22
+ {{{ else }}}
23
+ <span class="visible-md-inline visible-lg-inline">[[unread:all_categories]]</span>
24
+ {{{ end }}}
25
+ <span class="caret"></span>
26
+ </button>
27
+ <div component="category-selector-search" class="hidden position-absolute">
28
+ <input type="text" class="form-control form-control-sm" placeholder="[[search:type-to-search]]" autocomplete="off">
29
+ </div>
30
+ <ul component="category/list" class="dropdown-menu p-1 text-sm category-dropdown-menu" role="menu">
31
+ {{{each categoryItems}}}
32
+ <li role="presentation" class="category {{{ if ../disabledClass }}}disabled{{{ end }}}" data-cid="{../cid}" data-parent-cid="{../parentCid}" data-name="{../name}">
33
+ <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" role="menu-item" href="#">
34
+ {../level}
35
+ <span component="category-markup" class="flex-1" style="{{{ if ../match }}}font-weight: bold;{{{end}}}">
36
+ <div class="category-item d-inline-flex align-items-center gap-1">
37
+ {{{ if ./icon }}}
38
+ {buildCategoryIcon(@value, "24px", "rounded-circle")}
39
+ {{{ end }}}
40
+ {./name}
41
+ </div>
42
+ </span>
43
+ <i component="category/select/icon" class="fa fa-fw fa-check {{{ if !../selected }}}invisible{{{ end }}}"></i>
44
+ </a>
45
+ </li>
46
+ {{{end}}}
47
+ </ul>
48
+ </div>
15
49
 
16
50
  <div class="btn-group bottom-sheet">
17
51
  <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">
@@ -14,6 +14,13 @@
14
14
  </a>
15
15
  {{{ end }}}
16
16
  </div>
17
+ {{{ if widgets.brand-header.length }}}
18
+ <div data-widget-area="brand-header" class="ms-auto gap-3 p-2 align-self-center">
19
+ {{{each widgets.brand-header}}}
20
+ {{./html}}
21
+ {{{end}}}
22
+ </div>
23
+ {{{ end }}}
17
24
  </div>
18
25
  </div>
19
26
  {{{ end }}}
@@ -8,16 +8,16 @@
8
8
  {{{ each notifications }}}
9
9
  <li class="{./readClass} mb-2 p-1" data-nid="{./nid}" data-path="{./path}" {{{ if ./pid }}}data-pid="{./pid}"{{{ end }}}{{{ if ./tid }}}data-tid="{./tid}"{{{ end }}}>
10
10
  <div class="d-flex gap-1 justify-content-between">
11
- <div class="d-flex gap-2 flex-grow-1">
11
+ <div class="d-flex gap-0 flex-grow-1 align-items-start">
12
12
  {{{ if ./image }}}
13
13
  {{{ if ./from }}}
14
- <a class="text-decoration-none" href="{config.relative_path}/user/{./user.userslug}"><img class="avatar avatar-rounded" style="--avatar-size: 32px;" src="{./image}" /></a>
14
+ <a class="btn-ghost-sm p-1 flex-grow-0 flex-shrink-0" href="{config.relative_path}/user/{./user.userslug}"><img class="avatar avatar-rounded" style="--avatar-size: 32px;" src="{./image}" /></a>
15
15
  {{{ end }}}
16
16
  {{{ else }}}
17
- <a class="text-decoration-none" href="{config.relative_path}/user/{./user.userslug}"><div class="avatar avatar-rounded" style="--avatar-size: 32px; background-color: {./user.icon:bgColor};">{./user.icon:text}</div></a>
17
+ <a class="btn-ghost-sm p-1 flex-grow-0 flex-shrink-0" href="{config.relative_path}/user/{./user.userslug}"><div class="avatar avatar-rounded" style="--avatar-size: 32px; background-color: {./user.icon:bgColor};">{./user.icon:text}</div></a>
18
18
  {{{ end }}}
19
- <div class=" d-flex flex-grow-1 flex-column position-relative">
20
- <a href="{./path}" class="text-decoration-none text-reset text-break text-sm stretched-link">
19
+ <div class="d-flex flex-grow-1 flex-column align-items-start position-relative">
20
+ <a href="{./path}" class="btn-ghost-sm d-inline-block text-reset text-break text-sm ff-sans stretched-link">
21
21
  {./bodyShort}
22
22
  </a>
23
23
  <div class="text-xs text-muted">{{{ if ./timeagoLong }}}{./timeagoLong}{{{ else }}}<span class="timeago" title="{./datetimeISO}"></span>{{{ end }}}</div>
@@ -25,7 +25,7 @@
25
25
  </div>
26
26
  <div>
27
27
  {{{ if ./nid }}}
28
- <button class="mark-read btn-ghost-sm" style="width: 1.5rem; height: 1.5rem;">
28
+ <button class="mark-read btn-ghost-sm flex-grow-0 flex-shrink-0 p-1" style="width: 1.5rem; height: 1.5rem;">
29
29
  <i class="unread fa fa-2xs fa-circle text-primary {{{ if ./read }}}hidden{{{ end }}}"></i>
30
30
  <i class="read fa fa-2xs fa-circle-o text-secondary {{{ if !./read }}}hidden{{{ end }}}"></i>
31
31
  </button>
@@ -1,7 +1,7 @@
1
1
  <div class="{{{ if config.theme.stickyToolbar }}}sticky-tools{{{ end }}}">
2
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">
3
+ <div class="card card-header flex-row p-2 border rounded w-100 align-items-center">
4
+ <ul class="navbar-nav me-auto gap-2 align-items-center flex-wrap">
5
5
  {{{ if loggedIn }}}
6
6
  <button component="topic/mark-unread" class="btn-ghost-sm d-flex gap-2 align-items-center">
7
7
  <i class="fa fa-fw fa-inbox text-primary"></i>
@@ -40,6 +40,11 @@
40
40
  </a>
41
41
  </li>
42
42
  <li role="presentation" class="dropdown-divider"></li>
43
+ <li>
44
+ <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" href="{relative_path}/user/{user.userslug}/bookmarks">
45
+ <i class="fa fa-fw fa-bookmark text-muted"></i> <span>[[user:bookmarks]]</span>
46
+ </a>
47
+ </li>
43
48
  <li>
44
49
  <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" component="header/profilelink/edit" href="{relative_path}/user/{user.userslug}/edit">
45
50
  <i class="fa fa-fw fa-edit text-muted"></i> <span>[[user:edit-profile]]</span>
@@ -10,7 +10,7 @@
10
10
  {{{ end }}}
11
11
  </button>
12
12
  <div component="tag/filter/search" class="hidden position-absolute top-0">
13
- <input type="text" class="form-control form-control-sm" autocomplete="off">
13
+ <input type="text" class="form-control form-control-sm" placeholder="[[search:type-to-search]]" autocomplete="off">
14
14
  </div>
15
15
  <ul component="tag/filter/list" class="dropdown-menu p-1 text-sm overflow-auto" role="menu" style="max-height: 500px;">
16
16
  <li role="presentation" data-tag="">
@@ -1,5 +1,5 @@
1
1
  {{{each tags}}}
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">
2
+ <a href="{config.relative_path}/tags/{./valueEncoded}" data-tag="{./valueEscaped}" class="btn-ghost flex-column gap-0 align-items-start justify-content-start text-truncate p-2 ff-base">
3
3
  <div class="fw-semibold text-nowrap tag-item w-100 text-truncate">{./valueEscaped}</div>
4
4
  <div class="text-xs text-muted text-nowrap tag-topic-count">[[global:x-topics, {./score}]]</div>
5
5
  </a>
@@ -1,7 +1,7 @@
1
1
  <div class="{{{ if config.theme.stickyToolbar }}}sticky-tools{{{ end }}} mb-3">
2
2
  <nav class="topic-list-header navbar navbar-expand p-0 border-0 rounded">
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">
3
+ <div class="card card-header flex-row p-2 gap-1 border rounded w-100 align-items-center">
4
+ <ul component="category/controls" class="navbar-nav me-auto gap-2 align-items-start flex-wrap">
5
5
  {{{ if template.category }}}
6
6
  <!-- IMPORT partials/category/watch.tpl -->
7
7
  <!-- IMPORT partials/tags/filter-dropdown-left.tpl -->
@@ -29,9 +29,8 @@
29
29
  <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>
30
30
  {{{ end }}}
31
31
 
32
- <a href="{config.relative_path}{{{ if template.category }}}{url}{{{ else }}}/{selectedFilter.url}{querystring}{{{ end }}}" class="btn-ghost-sm fw-semibold text-nowrap d-flex align-items-baseline gap-2 flex-nowrap hide" id="new-topics-alert">
33
- <i class="fa fa-solid fa-rotate-right text-primary"></i>
34
- Load new posts
32
+ <a href="{config.relative_path}{{{ if template.category }}}{url}{{{ else }}}/{selectedFilter.url}{querystring}{{{ end }}}" class="btn btn-secondary fw-semibold position-absolute top-100 translate-middle-x start-50 mt-1 hide" style="--bs-btn-padding-y: .25rem; --bs-btn-padding-x: .5rem; --bs-btn-font-size: .75rem;" id="new-topics-alert">
33
+ <i class="fa fa-fw fa-arrow-up"></i> [[recent:load-new-posts]]
35
34
  </a>
36
35
  </ul>
37
36
 
@@ -1,4 +1,4 @@
1
- <ul component="category" class="list-unstyled topic-list overflow-auto position-relative" itemscope itemtype="http://www.schema.org/ItemList" data-nextstart="{nextStart}" data-set="{set}">
1
+ <ul component="category" class="topics-list list-unstyled {{{ if template.account/topics }}}narrow{{{ end}}}" itemscope itemtype="http://www.schema.org/ItemList" data-nextstart="{nextStart}" data-set="{set}">
2
2
 
3
3
  {{{ each topics }}}
4
4
  <li component="category/topic" class="category-item position-relative {function.generateTopicClass}" <!-- IMPORT partials/data/category.tpl -->>
@@ -8,129 +8,113 @@
8
8
  <meta itemprop="position" content="{./index}" />
9
9
  <a id="{./index}" data-index="{./index}" component="topic/anchor"></a>
10
10
 
11
- <div class="row py-2">
12
- <div class="col-md-7 col-sm-9 col-12 content d-flex">
13
- <div class="me-3">
14
- {{{ if ./thumbs.length }}}
15
- <div class="topic-thumb">
16
- <a href="{./thumbs.0.url}">
17
- <img class="topic-thumb rounded-1" src="{./thumbs.0.url}" class="not-responsive" />
18
- </a>
19
- </div>
20
- {{{ else }}}
21
- <div class="avatar">
22
- <a href="{{{ if ./user.userslug }}}{config.relative_path}/user/{./user.userslug}{{{ else }}}#{{{ end }}}" class="text-decoration-none">
23
- {buildAvatar(./user, "40px", true, "avatar-tooltip not-responsive")}
24
- </a>
25
- </div>
26
- {{{ end }}}
27
- </div>
28
- <div class="d-flex flex-column gap-1">
29
- <div class="d-flex align-items-center gap-1 mb-1 {{{ if showSelect }}}me-4{{{ end }}} me-md-0">
30
- {{{ if ./unread }}}<span class="text-primary text-xs">&#9679;</span>{{{ end }}}
31
- <h2 component="topic/header" class="tracking-tight text-break title text-md fw-semibold m-0">
32
- {{{ if topics.noAnchor }}}
33
- <span>{./title}</span>
34
- {{{ else }}}
35
- <a class="text-reset" href="{config.relative_path}/topic/{./slug}{{{ if ./bookmark }}}/{./bookmark}{{{ end }}}">{./title}</a>
36
- {{{ end }}}
37
- </h2>
38
- </div>
39
- <div class="info d-flex align-items-center flex-wrap">
40
- <span component="topic/labels" class="d-flex mb-1">
41
- <span component="topic/scheduled" class="me-2 badge border border-gray-300 text-primary {{{ if !./scheduled }}}hidden{{{ end }}}">
11
+
12
+ <div class="thumb-avatar-box">
13
+ {{{ if ./thumbs.length }}}
14
+ <a class="text-decoration-none" href="{./thumbs.0.url}" target="_blank">
15
+ <img class="topic-thumb rounded-1" width="40" style="height: auto;" src="{./thumbs.0.url}"/>
16
+ </a>
17
+ {{{ else }}}
18
+ <a class="text-decoration-none" href="{{{ if ./user.userslug }}}{config.relative_path}/user/{./user.userslug}{{{ else }}}#{{{ end }}}">
19
+ {buildAvatar(./user, "40px", true, "avatar avatar-tooltip")}
20
+ </a>
21
+ {{{ end }}}
22
+ </div>
23
+
24
+ <div class="wrapper">
25
+ <div class="wrapper2">
26
+ <div class="title_badges">
27
+ <h2 component="topic/header" class="text-break title text-md fw-semibold m-0">
28
+ {{{ if topics.noAnchor }}}
29
+ <span>{./title}</span>
30
+ {{{ else }}}
31
+ <a class="{{{ if ./unread }}}text-primary{{{ else }}}text-reset{{{ end }}}" href="{config.relative_path}/topic/{./slug}{{{ if ./bookmark }}}/{./bookmark}{{{ end }}}">{./title}</a>
32
+ {{{ end }}}
33
+ </h2>
34
+ <div class="info">
35
+ <span component="topic/labels" class="d-flex flex-wrap gap-1">
36
+ <span component="topic/scheduled" class="badge border border-gray-300 text-primary {{{ if !./scheduled }}}hidden{{{ end }}}">
42
37
  <i class="fa fa-clock-o"></i>
43
38
  [[topic:scheduled]]
44
39
  </span>
45
- <span component="topic/pinned" class="me-2 badge border border-gray-300 text-primary {{{ if (./scheduled || !./pinned) }}}hidden{{{ end }}}">
40
+ <span component="topic/pinned" class="badge border border-gray-300 text-primary {{{ if (./scheduled || !./pinned) }}}hidden{{{ end }}}">
46
41
  <i class="fa fa-thumb-tack"></i>
47
42
  {{{ if !./pinExpiry }}}[[topic:pinned]]{{{ else }}}[[topic:pinned-with-expiry, {./pinExpiryISO}]]{{{ end }}}
48
43
  </span>
49
- <span component="topic/locked" class="me-2 badge border border-gray-300 text-primary {{{ if !./locked }}}hidden{{{ end }}}">
44
+ <span component="topic/locked" class="badge border border-gray-300 text-primary {{{ if !./locked }}}hidden{{{ end }}}">
50
45
  <i class="fa fa-lock"></i>
51
46
  [[topic:locked]]
52
47
  </span>
53
- <span class="me-2 badge border border-gray-300 text-primary {{{ if !./oldCid }}}hidden{{{ end }}}">
48
+ <span class="badge border border-gray-300 text-primary {{{ if !./oldCid }}}hidden{{{ end }}}">
54
49
  <i class="fa fa-arrow-circle-right"></i>
55
50
  [[topic:moved]]
56
51
  </span>
57
- {{{each ./icons}}}<span class="me-2">{@value}</span>{{{end}}}
52
+ {{{each ./icons}}}<span class="lh-1 me-2">{@value}</span>{{{end}}}
58
53
  </span>
59
-
60
-
61
54
  {{{ if !template.category }}}
62
- <a class="lh-1 me-2 mb-1" href="{config.relative_path}/category/{./category.slug}">{function.buildCategoryLabel, ./category, "border"}</a>
55
+ <a class="lh-1" href="{config.relative_path}/category/{./category.slug}">{function.buildCategoryLabel, ./category, "border"}</a>
63
56
  {{{ end }}}
64
-
65
57
  {{{ if ./tags.length }}}
66
- <span class="lh-1 tag-list hidden-xs d-flex flex-wrap gap-2 me-2 mb-1 ">
58
+ <span class="lh-1 tag-list hidden-xs d-flex flex-wrap gap-1">
67
59
  {{{ each ./tags }}}
68
60
  <a href="{config.relative_path}/tags/{./valueEncoded}"><span class="badge border border-gray-300 text-xs fw-normal tag tag-class-{./class}" data-tag="{./value}">{./valueEscaped}</span></a>
69
61
  {{{ end }}}
70
62
  </span>
71
63
  {{{ end }}}
72
-
73
- <span class="hidden-xs text-xs timeago text-muted me-2 mb-1" title="{./timestampISO}"></span>
74
-
75
- <span class="visible-xs-inline timeago text-muted text-xs" title="{{{ if ./teaser.timestampISO }}}{./teaser.timestampISO}{{{ else }}}{./timestampISO}{{{ end }}}"></span>
64
+ <span class="hidden-xs text-xs timeago text-muted" title="{./timestampISO}"></span>
76
65
  </div>
77
66
  </div>
78
- </div>
79
-
80
- <div class="meta row col-md-5 col-sm-3 d-none d-md-flex align-self-stretch align-self-lg-start">
81
- <div class="col-lg-5 d-none d-lg-flex stats text-muted gap-2 px-0">
67
+ <div class="meta stats">
82
68
  {{{ if !reputation:disabled }}}
83
- <div class="stats-votes flex-1">
84
- <div class="align-items-center card card-header px-0 py-2 border-0 rounded-1">
85
- <span class="human-readable-number fs-5 ff-secondary lh-1" title="{./votes}" data-toFixed="0">{./votes}</span>
86
- <span class="text-lowercase text-xs">[[global:votes]]</span>
87
- </div>
69
+ <div class="stats-votes card card-header">
70
+ <i class="fa fa-fw fa-thumbs-up"></i>
71
+ <span class="human-readable-number ff-secondary" title="{./votes}" data-toFixed="0">{./votes}</span>
72
+ <span class="text-lowercase text-xs">[[global:votes]]</span>
88
73
  </div>
89
74
  {{{ end }}}
90
- <div class="stats-postcount flex-1">
91
- <div class="align-items-center card card-header px-0 py-2 border-0 rounded-1">
92
- <span class="human-readable-number fs-5 ff-secondary lh-1" title="{./postcount}" data-toFixed="0">{./postcount}</span>
93
- <span class="text-lowercase text-xs">[[global:posts]]</span>
94
- </div>
75
+ <div class="stats-postcount card card-header">
76
+ <i class="fa fa-fw fa-bars"></i>
77
+ <span class="human-readable-number ff-secondary" title="{./postcount}" data-toFixed="0">{./postcount}</span>
78
+ <span class="text-lowercase text-xs">[[global:posts]]</span>
95
79
  </div>
96
- <div class="stats-viewcount flex-1">
97
- <div class="align-items-center card card-header px-0 py-2 border-0 rounded-1">
98
- <span class="human-readable-number fs-5 ff-secondary lh-1" title="{./viewcount}" data-toFixed="0">{./viewcount}</span>
99
- <span class="text-lowercase text-xs">[[global:views]]</span>
100
- </div>
80
+ <div class="stats-viewcount card card-header">
81
+ <i class="fa fa-fw fa-eye"></i>
82
+ <span class="human-readable-number ff-secondary" title="{./viewcount}" data-toFixed="0">{./viewcount}</span>
83
+ <span class="text-lowercase text-xs">[[global:views]]</span>
101
84
  </div>
102
85
  </div>
86
+ </div>
103
87
 
104
- <div class="col-lg-7 col-md-12 teaser d-none d-md-block overflow-hidden" component="topic/teaser">
105
- <div class="lastpost background-link-container border-start border-2 h-100" style="border-color: {./category.bgColor}!important;">
106
- <a class="background-link" href="{config.relative_path}/topic/{./slug}/{./teaser.index}"></a>
107
- {{{ if ./unreplied }}}
108
- <p class="ps-3 text-xs lh-1">
109
- [[category:no_replies]]
110
- </p>
111
- {{{ else }}}
112
- {{{ if ./teaser.pid }}}
113
- <p class="ps-3 mb-0 lh-1">
114
- <a href="{config.relative_path}/user/{./teaser.user.userslug}" class="text-decoration-none">{buildAvatar(./teaser.user, "18px", true, "avatar-tooltip not-responsive")}</a>
115
- <a class="permalink text-muted timeago text-xs" href="{config.relative_path}/topic/{./slug}/{./teaser.index}" title="{./teaser.timestampISO}">
116
- </a>
117
- </p>
118
- <div class="post-content overflow-hidden text-xs line-clamp-2 ps-3">
119
- {./teaser.content}
120
- </div>
121
- {{{ end }}}
122
- {{{ end }}}
88
+ <div class="meta teaser" component="topic/teaser">
89
+ <div class="lastpost background-link-container border-start border-2" style="border-color: {./category.bgColor}!important;">
90
+ <a class="background-link" href="{config.relative_path}/topic/{./slug}/{./teaser.index}"></a>
91
+ {{{ if ./unreplied }}}
92
+ <p class="ps-2 text-xs lh-1">
93
+ [[category:no_replies]]
94
+ </p>
95
+ {{{ else }}}
96
+ {{{ if ./teaser.pid }}}
97
+ <p class="ps-2 mb-0 lh-1">
98
+ <a href="{config.relative_path}/user/{./teaser.user.userslug}" class="text-decoration-none">{buildAvatar(./teaser.user, "18px", true, "avatar-tooltip not-responsive")}</a>
99
+ <a class="permalink text-muted timeago text-xs" href="{config.relative_path}/topic/{./slug}/{./teaser.index}" title="{./teaser.timestampISO}">
100
+ </a>
101
+ </p>
102
+ <div class="post-content text-xs ps-2">
103
+ {./teaser.content}
123
104
  </div>
105
+ {{{ end }}}
106
+ {{{ end }}}
124
107
  </div>
125
108
  </div>
126
109
 
127
- {{{ if showSelect }}}
128
- <div class="position-absolute top-0 end-0 w-auto p-0">
129
- <i component="topic/select" class="fa fa-square-o fs-5 text-muted pointer"></i>
130
- </div>
131
- {{{ end }}}
110
+ </div><!-- /wrapper -->
111
+
112
+ {{{ if showSelect }}}
113
+ <div class="checkbox">
114
+ <i component="topic/select" class="fa fa-square-o fs-5 text-muted pointer"></i>
132
115
  </div>
133
- <hr class="text-muted opacity-25"/>
116
+ {{{ end }}}
134
117
  </li>
135
118
  {{{end}}}
119
+
136
120
  </ul>
@@ -1,4 +1,4 @@
1
- <a href="{config.relative_path}/user/{./userslug}" class="btn-ghost align-items-start justify-content-start">
1
+ <a href="{config.relative_path}/user/{./userslug}" class="btn-ghost align-items-start justify-content-start p-2 ff-base">
2
2
  {buildAvatar(@value, "48px", true, "flex-shrink-0")}
3
3
  <div class="d-flex flex-column text-truncate">
4
4
  <div class="fw-semibold text-truncate" title="{./displayname}">{./displayname}</div>
@@ -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-4">
1
+ <div id="users-container" class="users-container row row-cols-2 row-cols-lg-3 row-cols-xl-4 g-4">
2
2
  {{{ each users }}}
3
3
  <!-- IMPORT partials/users/item.tpl -->
4
4
  {{{ end }}}
@@ -33,9 +33,11 @@
33
33
  {{{ if !enabled }}}<p>[[post-queue:enabling-help, {config.relative_path}/admin/settings/post#post-queue]]</p>{{{ end }}}
34
34
  </div>
35
35
  {{{ else }}}
36
- <div class="alert alert-info d-flex align-items-center">
37
- <p class="mb-0 me-auto">[[post-queue:no-single-post]]</p>
38
- <a class="btn btn-sm btn-primary" href=".">[[post-queue:back-to-list]]</a>
36
+ <div class="alert alert-info d-flex align-items-md-center d-flex flex-column flex-md-row">
37
+ <p class="mb-md-0">[[post-queue:no-single-post]]</p>
38
+ <div class="d-grid ms-md-auto">
39
+ <a class="btn btn-sm btn-primary flex-shrink text-nowrap" href=".">[[post-queue:back-to-list]]</a>
40
+ </div>
39
41
  </div>
40
42
  {{{ end }}}
41
43
  {{{ end }}}
@@ -91,7 +93,7 @@
91
93
  </li>
92
94
  <li class="card-body border-bottom">
93
95
  <div class="text-xs fw-semibold mb-1">
94
- {{{ if posts.data.tid }}}[[post-queue:topic]]{{{ else }}}[[post-queue:title]] <i class="fa fa-fw fa-edit" data-bs-toggle="tooltip" title="[[post-queue:title-editable]]"></i>{{{ end }}}
96
+ {{{ if posts.data.tid }}}[[post-queue:topic]]{{{ else }}}[[post-queue:title]]{{{ end }}}
95
97
  </div>
96
98
  <span class="small topic-title text-break">
97
99
  {{{ if posts.data.tid }}}
@@ -107,9 +109,9 @@
107
109
  </li>
108
110
  <li class="card-body border-bottom">
109
111
  <div class="text-xs fw-semibold mb-1">
110
- [[post-queue:category]]{{{ if posts.data.cid}}} <i class="fa fa-fw fa-edit" data-bs-toggle="tooltip" title="[[post-queue:category-editable]]"></i>{{{ end }}}
112
+ [[post-queue:category]]
111
113
  </div>
112
- <div class="topic-category small" {{{if posts.data.cid}}}data-editable="editable"{{{end}}}">
114
+ <div class="topic-category small">
113
115
  <a href="{config.relative_path}/category/{posts.category.slug}">
114
116
  <div class="category-item d-inline-block">
115
117
  {buildCategoryIcon(./category, "24px", "rounded-circle")}
@@ -118,11 +120,32 @@
118
120
  </a>
119
121
  </div>
120
122
  </li>
121
- <li class="card-body d-grid d-lg-flex gap-2">
123
+ <li class="card-body">
122
124
  {{{ if canAccept }}}
123
- <button class="btn btn-success btn-sm" data-action="accept"><i class="fa fa-fw fa-check"></i> [[post-queue:accept]] </button>
124
- <button class="btn btn-info btn-sm" data-action="notify"><i class="fa fa-fw fa-bell-o"></i> [[post-queue:notify]]</button>
125
- <button class="btn btn-danger btn-sm" data-action="reject"><i class="fa fa-fw fa-times"></i> [[post-queue:reject]]</button>
125
+ <div class="row row-cols-2 g-1">
126
+ <div class="col d-grid">
127
+ <button class="btn btn-success btn-sm" data-action="accept"><i class="fa fa-fw fa-check"></i> [[post-queue:accept]] </button>
128
+ </div>
129
+ <div class="col d-grid">
130
+ <button class="btn btn-danger btn-sm" data-action="reject"><i class="fa fa-fw fa-times"></i> [[post-queue:reject]]</button>
131
+ </div>
132
+ {{{ if !posts.data.tid }}}
133
+ <div class="col d-grid">
134
+ <button class="btn btn-light btn-sm" data-action="editTitle"><i class="fa fa-fw fa-edit"></i> [[post-queue:title]]</button>
135
+ </div>
136
+ {{{ end }}}
137
+ <div class="col d-grid">
138
+ <button class="btn btn-light btn-sm" data-action="editContent"><i class="fa fa-fw fa-edit"></i> [[post-queue:content]]</button>
139
+ </div>
140
+ {{{if posts.data.cid}}}
141
+ <div class="col d-grid">
142
+ <button class="btn btn-light btn-sm" data-action="editCategory"><i class="fa fa-fw fa-edit"></i> [[post-queue:category]]</button>
143
+ </div>
144
+ {{{ end }}}
145
+ <div class="col d-grid">
146
+ <button class="btn btn-light btn-sm" data-action="notify"><i class="fa fa-fw fa-bell-o"></i> [[post-queue:notify]]</button>
147
+ </div>
148
+ </div>
126
149
  {{{ else }}}
127
150
  <button class="btn btn-danger btn-sm" data-action="reject"><i class="fa fa-fw fa-times"></i> [[post-queue:remove]]</button>
128
151
  {{{ end }}}
@@ -134,7 +157,6 @@
134
157
  <div class="post-content-editable flex-grow-1 hidden">
135
158
  <textarea class="form-control w-100 h-100 p-3">{posts.data.rawContent}</textarea>
136
159
  </div>
137
- <div class="border-top p-2 d-none d-md-block text-xs fw-semibold text-end">[[post-queue:content-editable]]</div>
138
160
  </div>
139
161
  </div>
140
162
  </div>
@@ -29,7 +29,7 @@
29
29
  <i class="fa fa-arrow-circle-right"></i>
30
30
  {{{ if privileges.isAdminOrMod }}}[[topic:moved-from, {oldCategory.name}]]{{{ else }}}[[topic:moved]]{{{ end }}}
31
31
  </span>
32
- {{{each icons}}}<span>{@value}</span>{{{end}}}
32
+ {{{each icons}}}<span class="lh-1">{@value}</span>{{{end}}}
33
33
  </span>
34
34
  <a class="lh-1" href="{config.relative_path}/category/{category.slug}">{function.buildCategoryLabel, category, "border"}</a>
35
35
  <div class="lh-1 tags tag-list d-flex hidden-xs gap-2"><!-- IMPORT partials/topic/tags.tpl --></div>