@okjavis/nodebb-theme-javis 3.0.3 → 3.0.5
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 +1 -1
- package/scss/_feed.scss +141 -7
- package/scss/_topic.scss +99 -22
- package/static/lib/theme.js +42 -6
- package/templates/feed.tpl +16 -41
- package/templates/partials/sidebar-left.tpl +2 -2
- package/templates/partials/topic/post.tpl +102 -0
- package/theme.json +2 -1
package/package.json
CHANGED
package/scss/_feed.scss
CHANGED
|
@@ -58,11 +58,8 @@
|
|
|
58
58
|
display: none !important;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
> .row > div > .d-flex.justify-content-between.py-2.mb-2 {
|
|
64
|
-
display: none !important;
|
|
65
|
-
}
|
|
61
|
+
// The controls row is now visible but the new_topic button is hidden
|
|
62
|
+
// JS injects the composer prompt card before this row
|
|
66
63
|
}
|
|
67
64
|
|
|
68
65
|
// ===========================================================
|
|
@@ -74,7 +71,7 @@
|
|
|
74
71
|
border-radius: $jv-radius-lg;
|
|
75
72
|
padding: $jv-space-4 $jv-space-6; // 16px top/bottom, 24px left/right
|
|
76
73
|
margin-top: $jv-space-4; // Align with trending tags padding-top
|
|
77
|
-
margin-bottom: $jv-space-
|
|
74
|
+
margin-bottom: $jv-space-2; // Reduced bottom margin for tighter spacing
|
|
78
75
|
box-shadow: $jv-shadow-sm;
|
|
79
76
|
transition: box-shadow $jv-transition-fast, border-color $jv-transition-fast;
|
|
80
77
|
|
|
@@ -486,7 +483,7 @@
|
|
|
486
483
|
.content[component="post/content"] {
|
|
487
484
|
font-size: 15px !important; // Slightly larger for better readability
|
|
488
485
|
line-height: 1.6 !important;
|
|
489
|
-
color:
|
|
486
|
+
color: #000000 !important; // Black text for feed body copy
|
|
490
487
|
margin-top: $jv-space-3; // Better spacing from meta
|
|
491
488
|
|
|
492
489
|
// Truncation styles (from plugin)
|
|
@@ -1001,3 +998,140 @@ ul.categories-list {
|
|
|
1001
998
|
}
|
|
1002
999
|
}
|
|
1003
1000
|
}
|
|
1001
|
+
|
|
1002
|
+
// ===========================================================
|
|
1003
|
+
// FEED CATEGORY FILTER - LinkedIn Style
|
|
1004
|
+
// Minimal text-based dropdown like "Sort by: Top"
|
|
1005
|
+
// ===========================================================
|
|
1006
|
+
|
|
1007
|
+
// Ultra-specific override to remove pill button styling
|
|
1008
|
+
.feed .feed-category-filter .btn-group .btn.btn-ghost.btn-sm.dropdown-toggle,
|
|
1009
|
+
.feed .feed-category-filter .category-dropdown-container .btn.btn-ghost.btn-sm,
|
|
1010
|
+
.feed .feed-category-filter button.btn.btn-ghost.btn-sm {
|
|
1011
|
+
border: none !important;
|
|
1012
|
+
border-width: 0 !important;
|
|
1013
|
+
border-color: transparent !important;
|
|
1014
|
+
border-radius: 4px !important;
|
|
1015
|
+
background: transparent !important;
|
|
1016
|
+
box-shadow: none !important;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
.feed-category-filter {
|
|
1020
|
+
.category-dropdown-container,
|
|
1021
|
+
[component="category/dropdown"] {
|
|
1022
|
+
// Override the btn-group styling
|
|
1023
|
+
&.btn-group {
|
|
1024
|
+
border: none !important;
|
|
1025
|
+
box-shadow: none !important;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
// Target the specific button with all its classes
|
|
1029
|
+
.dropdown-toggle,
|
|
1030
|
+
.btn.btn-ghost.btn-sm.dropdown-toggle,
|
|
1031
|
+
button.dropdown-toggle {
|
|
1032
|
+
// LinkedIn style - minimal, text-based, NO border
|
|
1033
|
+
padding: 4px 8px !important;
|
|
1034
|
+
font-size: 12px !important;
|
|
1035
|
+
font-weight: 400 !important;
|
|
1036
|
+
color: $jv-text-muted !important;
|
|
1037
|
+
background: transparent !important;
|
|
1038
|
+
background-color: transparent !important;
|
|
1039
|
+
border: none !important;
|
|
1040
|
+
border-width: 0 !important;
|
|
1041
|
+
border-color: transparent !important;
|
|
1042
|
+
box-shadow: none !important;
|
|
1043
|
+
border-radius: 4px !important;
|
|
1044
|
+
min-width: auto !important;
|
|
1045
|
+
gap: 4px !important;
|
|
1046
|
+
|
|
1047
|
+
// Hide the category icon, show only name
|
|
1048
|
+
.category-item {
|
|
1049
|
+
gap: 4px !important;
|
|
1050
|
+
|
|
1051
|
+
// Hide category icon on compact view
|
|
1052
|
+
.rounded-circle,
|
|
1053
|
+
[component="category/icon"],
|
|
1054
|
+
span[style*="background"] {
|
|
1055
|
+
display: none !important;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
// Show category name - smaller text
|
|
1059
|
+
span.d-none.d-md-inline,
|
|
1060
|
+
.fw-semibold {
|
|
1061
|
+
display: inline !important;
|
|
1062
|
+
font-size: 12px !important;
|
|
1063
|
+
font-weight: 600 !important;
|
|
1064
|
+
color: $jv-text-main !important;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
// "All Categories" state
|
|
1069
|
+
> i.fa-list {
|
|
1070
|
+
font-size: 12px !important;
|
|
1071
|
+
color: $jv-text-muted !important;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
// Show "All Categories" text
|
|
1075
|
+
> span.d-none.d-md-inline,
|
|
1076
|
+
> .fw-semibold {
|
|
1077
|
+
display: inline !important;
|
|
1078
|
+
font-size: 12px !important;
|
|
1079
|
+
font-weight: 600 !important;
|
|
1080
|
+
color: $jv-text-main !important;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
// Dropdown arrow - smaller
|
|
1084
|
+
&::after {
|
|
1085
|
+
font-size: 8px !important;
|
|
1086
|
+
margin-left: 4px !important;
|
|
1087
|
+
color: $jv-text-muted !important;
|
|
1088
|
+
border-top-width: 4px !important;
|
|
1089
|
+
border-right-width: 4px !important;
|
|
1090
|
+
border-left-width: 4px !important;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
&:hover {
|
|
1094
|
+
background: rgba(0, 0, 0, 0.04) !important;
|
|
1095
|
+
background-color: rgba(0, 0, 0, 0.04) !important;
|
|
1096
|
+
color: $jv-text-main !important;
|
|
1097
|
+
border: none !important;
|
|
1098
|
+
box-shadow: none !important;
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
&:focus,
|
|
1102
|
+
&:active {
|
|
1103
|
+
background: transparent !important;
|
|
1104
|
+
border: none !important;
|
|
1105
|
+
box-shadow: none !important;
|
|
1106
|
+
outline: none !important;
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
// Dropdown menu styling
|
|
1111
|
+
.dropdown-menu {
|
|
1112
|
+
min-width: 180px;
|
|
1113
|
+
max-width: 240px;
|
|
1114
|
+
border-radius: $jv-radius-md !important;
|
|
1115
|
+
border: 1px solid $jv-border-subtle !important;
|
|
1116
|
+
box-shadow: $jv-shadow-card !important;
|
|
1117
|
+
padding: $jv-space-1 !important;
|
|
1118
|
+
margin-top: 4px !important;
|
|
1119
|
+
|
|
1120
|
+
.category-dropdown-menu {
|
|
1121
|
+
max-height: 280px;
|
|
1122
|
+
overflow-y: auto;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
.dropdown-item {
|
|
1126
|
+
font-size: 13px !important;
|
|
1127
|
+
padding: 6px 12px !important;
|
|
1128
|
+
border-radius: $jv-radius-xs !important;
|
|
1129
|
+
color: $jv-text-main !important;
|
|
1130
|
+
|
|
1131
|
+
&:hover {
|
|
1132
|
+
background: $jv-hover-bg !important;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
}
|
package/scss/_topic.scss
CHANGED
|
@@ -32,9 +32,32 @@ body.template-topic {
|
|
|
32
32
|
[component="post/header"].fs-3 {
|
|
33
33
|
margin-bottom: 0;
|
|
34
34
|
display: flex;
|
|
35
|
-
align-items:
|
|
35
|
+
align-items: center; // Center align items vertically
|
|
36
36
|
gap: $jv-space-3;
|
|
37
37
|
|
|
38
|
+
// Back button styling
|
|
39
|
+
.topic-back-btn {
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
justify-content: center;
|
|
43
|
+
width: 36px;
|
|
44
|
+
height: 36px;
|
|
45
|
+
border-radius: $jv-radius-sm;
|
|
46
|
+
color: $jv-text-muted;
|
|
47
|
+
text-decoration: none;
|
|
48
|
+
transition: background-color $jv-transition-fast, color $jv-transition-fast;
|
|
49
|
+
flex-shrink: 0;
|
|
50
|
+
|
|
51
|
+
&:hover {
|
|
52
|
+
background: $jv-hover-bg;
|
|
53
|
+
color: $jv-text-main;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
i {
|
|
57
|
+
font-size: 18px;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
38
61
|
h1,
|
|
39
62
|
[component="topic/title"],
|
|
40
63
|
.topic-title {
|
|
@@ -142,33 +165,71 @@ body.template-topic {
|
|
|
142
165
|
display: none !important;
|
|
143
166
|
}
|
|
144
167
|
|
|
145
|
-
// Card styling
|
|
168
|
+
// Card styling - vertical stack layout (like feed page)
|
|
146
169
|
.post-container-parent {
|
|
147
170
|
background: $jv-surface;
|
|
148
171
|
border-radius: $jv-radius-md;
|
|
149
172
|
border: 1px solid $jv-border-subtle;
|
|
150
|
-
padding: $jv-space-
|
|
151
|
-
gap: $jv-space-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
173
|
+
padding: $jv-space-4;
|
|
174
|
+
gap: $jv-space-3 !important;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Author row - avatar + username + timestamp inline
|
|
178
|
+
.post-author-row {
|
|
179
|
+
display: flex;
|
|
180
|
+
align-items: center;
|
|
181
|
+
gap: $jv-space-2;
|
|
182
|
+
|
|
183
|
+
// Avatar size 32px
|
|
184
|
+
[component="user/picture"],
|
|
185
|
+
.avatar {
|
|
186
|
+
width: 32px !important;
|
|
187
|
+
height: 32px !important;
|
|
188
|
+
min-width: 32px !important;
|
|
189
|
+
min-height: 32px !important;
|
|
190
|
+
font-size: $jv-font-size-sm !important;
|
|
191
|
+
line-height: 32px !important;
|
|
192
|
+
border-radius: 50% !important;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Author name
|
|
196
|
+
.post-author-name {
|
|
197
|
+
font-weight: 600;
|
|
198
|
+
font-size: $jv-font-size-sm;
|
|
199
|
+
color: $jv-text-main;
|
|
200
|
+
text-decoration: none;
|
|
201
|
+
|
|
202
|
+
&:hover {
|
|
203
|
+
color: $jv-primary;
|
|
165
204
|
}
|
|
166
205
|
}
|
|
167
|
-
}
|
|
168
206
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
207
|
+
// Timestamp
|
|
208
|
+
.post-timestamp {
|
|
209
|
+
font-size: $jv-font-size-xs;
|
|
210
|
+
color: $jv-text-soft;
|
|
211
|
+
|
|
212
|
+
&::before {
|
|
213
|
+
content: "• ";
|
|
214
|
+
margin-right: 2px;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Edit indicator
|
|
219
|
+
.edit-icon {
|
|
220
|
+
font-size: $jv-font-size-xs;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Post index
|
|
224
|
+
.post-index {
|
|
225
|
+
font-size: $jv-font-size-xs;
|
|
226
|
+
color: $jv-text-soft;
|
|
227
|
+
opacity: 0.6;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.bookmarked {
|
|
231
|
+
color: $jv-warning;
|
|
232
|
+
}
|
|
172
233
|
}
|
|
173
234
|
|
|
174
235
|
.post-container {
|
|
@@ -185,7 +246,7 @@ body.template-topic {
|
|
|
185
246
|
}
|
|
186
247
|
|
|
187
248
|
// ===========================================================
|
|
188
|
-
// POST HEADER
|
|
249
|
+
// POST HEADER (legacy support for any remaining old structure)
|
|
189
250
|
// ===========================================================
|
|
190
251
|
.post-header {
|
|
191
252
|
display: flex;
|
|
@@ -777,6 +838,22 @@ body.template-topic {
|
|
|
777
838
|
margin-top: $jv-space-6;
|
|
778
839
|
border: 1px solid $jv-border-subtle;
|
|
779
840
|
|
|
841
|
+
// Reduce avatar size to 32px (matching post author avatars)
|
|
842
|
+
[component="user/picture"],
|
|
843
|
+
.avatar {
|
|
844
|
+
width: 32px !important;
|
|
845
|
+
height: 32px !important;
|
|
846
|
+
min-width: 32px !important;
|
|
847
|
+
min-height: 32px !important;
|
|
848
|
+
font-size: $jv-font-size-sm !important;
|
|
849
|
+
line-height: 32px !important;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
// Hide user status indicator (green dot)
|
|
853
|
+
[component="user/status"] {
|
|
854
|
+
display: none !important;
|
|
855
|
+
}
|
|
856
|
+
|
|
780
857
|
.quick-reply-header {
|
|
781
858
|
margin-bottom: $jv-space-4;
|
|
782
859
|
font-weight: 600;
|
package/static/lib/theme.js
CHANGED
|
@@ -203,13 +203,42 @@
|
|
|
203
203
|
|
|
204
204
|
/**
|
|
205
205
|
* Initialize sidebar toggle click handler
|
|
206
|
-
*
|
|
207
|
-
* This function is now a no-op to avoid conflicts.
|
|
206
|
+
* Custom handler needed because Harmony's handler targets .sidebar but JAVIS uses .sidebar-left
|
|
208
207
|
*/
|
|
209
208
|
function initSidebarToggle() {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
209
|
+
var $toggle = $('[component="sidebar/toggle"]');
|
|
210
|
+
if (!$toggle.length) {
|
|
211
|
+
console.log('JAVIS: Sidebar toggle element not found');
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Remove any existing handlers to avoid duplicates, then add our handler
|
|
216
|
+
$toggle.off('click.javis').on('click.javis', function(e) {
|
|
217
|
+
e.preventDefault();
|
|
218
|
+
e.stopPropagation();
|
|
219
|
+
|
|
220
|
+
var $sidebar = $('.sidebar-left');
|
|
221
|
+
$sidebar.toggleClass('open');
|
|
222
|
+
|
|
223
|
+
console.log('JAVIS: Sidebar toggled, open:', $sidebar.hasClass('open'));
|
|
224
|
+
|
|
225
|
+
// Save preference if user is logged in
|
|
226
|
+
if (typeof app !== 'undefined' && app.user && app.user.uid) {
|
|
227
|
+
require(['api'], function(api) {
|
|
228
|
+
api.put('/users/' + app.user.uid + '/settings', {
|
|
229
|
+
settings: {
|
|
230
|
+
openSidebars: $sidebar.hasClass('open') ? 'on' : 'off',
|
|
231
|
+
},
|
|
232
|
+
}).catch(function(err) {
|
|
233
|
+
console.warn('JAVIS: Could not save sidebar preference', err);
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
$(window).trigger('action:sidebar.toggle');
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
console.log('JAVIS: Sidebar toggle initialized');
|
|
213
242
|
}
|
|
214
243
|
|
|
215
244
|
/**
|
|
@@ -402,7 +431,14 @@
|
|
|
402
431
|
}
|
|
403
432
|
|
|
404
433
|
// Find the existing controls row (contains New Topic button)
|
|
405
|
-
|
|
434
|
+
// Try mb-0, mb-1 and mb-2 for compatibility
|
|
435
|
+
var $controlsRow = $('.feed .d-flex.justify-content-between.py-2.mb-0').first();
|
|
436
|
+
if (!$controlsRow.length) {
|
|
437
|
+
$controlsRow = $('.feed .d-flex.justify-content-between.py-2.mb-1').first();
|
|
438
|
+
}
|
|
439
|
+
if (!$controlsRow.length) {
|
|
440
|
+
$controlsRow = $('.feed .d-flex.justify-content-between.py-2.mb-2').first();
|
|
441
|
+
}
|
|
406
442
|
if (!$controlsRow.length) {
|
|
407
443
|
return;
|
|
408
444
|
}
|
package/templates/feed.tpl
CHANGED
|
@@ -26,39 +26,16 @@
|
|
|
26
26
|
<div class="col-lg-6 col-sm-12 ms-auto">
|
|
27
27
|
{{{ end }}}
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
<!-- Controls row for composer prompt injection -->
|
|
30
|
+
<div class="d-flex justify-content-between py-2 mb-0 gap-1">
|
|
30
31
|
{{{ if canPost }}}
|
|
31
|
-
<button id="new_topic" class="btn btn-primary btn-sm">[[category:new-topic-button]]</button>
|
|
32
|
+
<button id="new_topic" class="btn btn-primary btn-sm d-none">[[category:new-topic-button]]</button>
|
|
32
33
|
{{{ end }}}
|
|
33
|
-
|
|
34
|
-
<a href="{config.relative_path}/login" class="btn btn-primary btn-sm">[[category:guest-login-post]]</a>
|
|
35
|
-
{{{ end }}}
|
|
36
|
-
|
|
37
|
-
<div class="d-flex justify-content-end gap-1">
|
|
38
|
-
<!-- IMPORT partials/category/filter-dropdown-right.tpl -->
|
|
34
|
+
</div>
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
</button>
|
|
44
|
-
<ul class="dropdown-menu p-1 text-sm" role="menu">
|
|
45
|
-
<li class="py-1 px-3">
|
|
46
|
-
<div class="form-check form-switch d-flex px-0 align-items-center justify-content-between gap-3">
|
|
47
|
-
<label class="form-check-label text-nowrap" for="showAllPosts">[[feed:show-all-posts]]</label>
|
|
48
|
-
<input class="form-check-input float-none m-0 pointer" type="checkbox" role="switch" id="showAllPosts" {{{ if showAllPosts }}}checked{{{ end }}}>
|
|
49
|
-
</div>
|
|
50
|
-
</li>
|
|
51
|
-
{{{ if loggedIn }}}
|
|
52
|
-
<li class="py-1 px-3">
|
|
53
|
-
<div class="form-check form-switch d-flex px-0 align-items-center justify-content-between gap-3">
|
|
54
|
-
<label class="form-check-label text-nowrap" for="showFollowedUsers">[[feed:followed-users-only]]</label>
|
|
55
|
-
<input class="form-check-input float-none m-0 pointer" type="checkbox" role="switch" id="showFollowedUsers" {{{ if showFollowed }}}checked{{{ end }}}>
|
|
56
|
-
</div>
|
|
57
|
-
</li>
|
|
58
|
-
{{{ end }}}
|
|
59
|
-
</ul>
|
|
60
|
-
</div>
|
|
61
|
-
</div>
|
|
36
|
+
<!-- Category filter - LinkedIn style, right aligned, tight spacing -->
|
|
37
|
+
<div class="d-flex justify-content-end py-1 feed-category-filter">
|
|
38
|
+
<!-- IMPORT partials/category/filter-dropdown-right.tpl -->
|
|
62
39
|
</div>
|
|
63
40
|
|
|
64
41
|
{{{ if !posts.length }}}
|
|
@@ -70,25 +47,23 @@
|
|
|
70
47
|
<li component="post" class="shadow-sm mb-3 rounded-2 border posts-list-item {{{ if ./deleted }}} deleted{{{ else }}}{{{ if ./topic.deleted }}} deleted{{{ end }}}{{{ end }}}{{{ if ./topic.scheduled }}} scheduled{{{ end }}}" data-pid="{./pid}" data-uid="{./uid}">
|
|
71
48
|
|
|
72
49
|
<!-- 1. CONTENT (first) -->
|
|
73
|
-
<div class="
|
|
74
|
-
<div class="
|
|
75
|
-
|
|
76
|
-
</div>
|
|
77
|
-
<div class="post-body d-flex flex-column gap-2 flex-grow-1 hover-parent" style="min-width: 0px;">
|
|
50
|
+
<div class="p-3 feed-content-section">
|
|
51
|
+
<div class="post-body d-flex flex-column gap-2 flex-grow-1" style="min-width: 0px;">
|
|
52
|
+
<!-- Topic title (first) -->
|
|
78
53
|
{{{ if ./isMainPost }}}
|
|
79
54
|
<a class="lh-1 topic-title fw-semibold fs-5 text-reset text-break d-block" href="{config.relative_path}/topic/{./topic.slug}">
|
|
80
55
|
{./topic.title}
|
|
81
56
|
</a>
|
|
82
57
|
{{{ end }}}
|
|
83
58
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
</div>
|
|
59
|
+
<!-- Author info row (second) -->
|
|
60
|
+
<div class="d-flex gap-2 post-info text-sm align-items-center">
|
|
61
|
+
<a class="lh-1 text-decoration-none" href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(./user, "24px", true, "not-responsive")}</a>
|
|
62
|
+
<a class="lh-normal fw-semibold text-nowrap" href="{config.relative_path}/user/{./user.userslug}">{./user.displayname}</a>
|
|
89
63
|
{{{ if !./isMainPost}}}{./repliedString}{{{ else }}}<span class="timeago text-muted lh-normal" title="{./timestampISO}"></span>{{{ end}}}
|
|
90
64
|
</div>
|
|
91
65
|
|
|
66
|
+
<!-- Post content text (third) -->
|
|
92
67
|
<div component="post/content" class="content text-sm text-break position-relative truncate-post-content">
|
|
93
68
|
<a href="{config.relative_path}/post/{./pid}" class="stretched-link"></a>
|
|
94
69
|
{./content}
|
|
@@ -101,7 +76,7 @@
|
|
|
101
76
|
|
|
102
77
|
<!-- 2. IMAGE (second) -->
|
|
103
78
|
{{{ if (showThumbs && ./topic.thumbs.length)}}}
|
|
104
|
-
<div class="p-1 position-relative">
|
|
79
|
+
<div class="p-1 position-relative feed-image-section">
|
|
105
80
|
<div class="overflow-hidden rounded-1" style="max-height: 300px;">
|
|
106
81
|
<a href="{config.relative_path}/topic/{./topic.slug}">
|
|
107
82
|
<img class="w-100" src="{./topic.thumbs.0.url}">
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
<div class="javis-sidebar-logo">
|
|
4
4
|
<a href="{relative_path}/" class="javis-logo-link" title="JAVIS Community">
|
|
5
5
|
<!-- Icon logo (shown when collapsed) -->
|
|
6
|
-
<img src="{relative_path}/plugins
|
|
6
|
+
<img src="{relative_path}/plugins/nodebb-theme-javis/static/images/logo-icon.png" alt="JAVIS" class="javis-logo-icon visible-closed" />
|
|
7
7
|
<!-- Full logo (shown when expanded) -->
|
|
8
|
-
<img src="{relative_path}/plugins
|
|
8
|
+
<img src="{relative_path}/plugins/nodebb-theme-javis/static/images/logo-full.png" alt="JAVIS Community" class="javis-logo-full visible-open" />
|
|
9
9
|
</a>
|
|
10
10
|
</div>
|
|
11
11
|
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{{{ if (!./index && widgets.mainpost-header.length) }}}
|
|
2
|
+
<div data-widget-area="mainpost-header">
|
|
3
|
+
{{{ each widgets.mainpost-header }}}
|
|
4
|
+
{widgets.mainpost-header.html}
|
|
5
|
+
{{{ end }}}
|
|
6
|
+
</div>
|
|
7
|
+
{{{ end }}}
|
|
8
|
+
{{{ if (./parent && !hideParent) }}}
|
|
9
|
+
<!-- IMPORT partials/topic/post-parent.tpl -->
|
|
10
|
+
{{{ end }}}
|
|
11
|
+
<div class="d-flex flex-column gap-2 post-container-parent">
|
|
12
|
+
<!-- Author row: Avatar + Username + Timestamp -->
|
|
13
|
+
<div class="d-flex align-items-center gap-2 post-author-row">
|
|
14
|
+
<a class="d-inline-block position-relative text-decoration-none flex-shrink-0" href="{{{ if ./user.userslug }}}{config.relative_path}/user/{./user.userslug}{{{ else }}}#{{{ end }}}" aria-label="[[aria:profile-page-for, {./user.displayname}]]">
|
|
15
|
+
{buildAvatar(posts.user, "32px", true, "", "user/picture")}
|
|
16
|
+
</a>
|
|
17
|
+
<div class="d-flex flex-wrap align-items-center gap-1" itemprop="author" itemscope itemtype="https://schema.org/Person">
|
|
18
|
+
<meta itemprop="name" content="{./user.displayname}">
|
|
19
|
+
{{{ if ./user.userslug }}}<meta itemprop="url" content="{config.relative_path}/user/{./user.userslug}">{{{ end }}}
|
|
20
|
+
<a class="fw-semibold text-nowrap post-author-name" href="{{{ if ./user.userslug }}}{config.relative_path}/user/{./user.userslug}{{{ else }}}#{{{ end }}}" data-username="{posts.user.username}" data-uid="{posts.user.uid}">{posts.user.displayname}</a>
|
|
21
|
+
<span class="text-muted post-timestamp">{generateWrote(@value, config.timeagoCutoff)}</span>
|
|
22
|
+
<i component="post/edit-indicator" class="fa fa-edit text-muted{{{ if privileges.posts:history }}} pointer{{{ end }}} edit-icon {{{ if !posts.editor.username }}}hidden{{{ end }}}" title="[[global:edited-timestamp, {isoTimeToLocaleString(./editedISO, config.userLang)}]]"></i>
|
|
23
|
+
<span data-editor="{posts.editor.userslug}" component="post/editor" class="visually-hidden">[[global:last-edited-by, {posts.editor.username}]] <span class="timeago" title="{isoTimeToLocaleString(posts.editedISO, config.userLang)}"></span></span>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="d-flex align-items-center gap-1 ms-auto">
|
|
26
|
+
<span class="bookmarked opacity-0 text-primary"><i class="fa fa-bookmark-o"></i></span>
|
|
27
|
+
<a href="{config.relative_path}/post/{encodeURIComponent(./pid)}" class="post-index text-muted d-none d-md-inline">#{increment(./index, "1")}</a>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<!-- Post content - full width below author row -->
|
|
32
|
+
<div class="post-container d-flex flex-column w-100" style="min-width:0;">
|
|
33
|
+
<div class="content text-break" component="post/content" itemprop="text">
|
|
34
|
+
{posts.content}
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div component="post/footer" class="post-footer border-bottom pb-2">
|
|
38
|
+
{{{ if posts.user.signature }}}
|
|
39
|
+
<div component="post/signature" data-uid="{posts.user.uid}" class="text-xs text-muted mt-2">{posts.user.signature}</div>
|
|
40
|
+
{{{ end }}}
|
|
41
|
+
|
|
42
|
+
<div class="d-flex flex-wrap-reverse gap-2 {{{ if (hideReplies || !posts.replies.count) }}}justify-content-end{{{ else }}}justify-content-between{{{ end }}}">
|
|
43
|
+
{{{ if !hideReplies }}}
|
|
44
|
+
<a component="post/reply-count" data-target-component="post/replies/container" href="#" class="d-flex gap-2 align-items-center btn btn-ghost ff-secondary border rounded-1 p-1 text-muted text-decoration-none text-xs {{{ if (!./replies || shouldHideReplyContainer(@value)) }}}hidden{{{ end }}}">
|
|
45
|
+
<span component="post/reply-count/avatars" class="d-flex gap-1 {{{ if posts.replies.hasMore }}}hasMore{{{ end }}}">
|
|
46
|
+
{{{each posts.replies.users}}}
|
|
47
|
+
<span>{buildAvatar(posts.replies.users, "20px", true, "avatar-tooltip")}</span>
|
|
48
|
+
{{{end}}}
|
|
49
|
+
{{{ if posts.replies.hasMore}}}
|
|
50
|
+
<span style="height: 20px; line-height: 20px;"><i class="fa fa-ellipsis"></i></span>
|
|
51
|
+
{{{ end }}}
|
|
52
|
+
</span>
|
|
53
|
+
|
|
54
|
+
<span class="ms-2 replies-count fw-semibold text-nowrap" component="post/reply-count/text" data-replies="{posts.replies.count}">{posts.replies.text}</span>
|
|
55
|
+
<span class="ms-2 replies-last hidden-xs fw-semibold">[[topic:last-reply-time]] <span class="timeago" title="{posts.replies.timestampISO}"></span></span>
|
|
56
|
+
|
|
57
|
+
<i class="fa fa-fw fa-chevron-down" component="post/replies/open"></i>
|
|
58
|
+
</a>
|
|
59
|
+
{{{ end }}}
|
|
60
|
+
<div component="post/actions" class="d-flex flex-grow-1 align-items-center justify-content-end gap-1 post-tools">
|
|
61
|
+
<!-- IMPORT partials/topic/reactions.tpl -->
|
|
62
|
+
<a component="post/reply" href="#" class="btn btn-ghost btn-sm {{{ if !privileges.topics:reply }}}hidden{{{ end }}}" title="[[topic:reply]]"><i class="fa fa-fw fa-reply text-primary"></i></a>
|
|
63
|
+
<a component="post/quote" href="#" class="btn btn-ghost btn-sm {{{ if !privileges.topics:reply }}}hidden{{{ end }}}" title="[[topic:quote]]"><i class="fa fa-fw fa-quote-right text-primary"></i></a>
|
|
64
|
+
|
|
65
|
+
{{{ if ./announces }}}
|
|
66
|
+
<a component="post/announce-count" href="#" class="btn btn-ghost btn-sm d-flex gap-2 align-items-center" title="[[topic:announcers]]"><i class="fa fa-share-alt text-primary"></i> {./announces}</a>
|
|
67
|
+
{{{ end }}}
|
|
68
|
+
|
|
69
|
+
{{{ if !reputation:disabled }}}
|
|
70
|
+
<div class="d-flex votes align-items-center">
|
|
71
|
+
<a component="post/upvote" href="#" class="btn btn-ghost btn-sm{{{ if posts.upvoted }}} upvoted{{{ end }}}" title="[[topic:upvote-post]]">
|
|
72
|
+
<i class="fa fa-fw fa-chevron-up text-primary"></i>
|
|
73
|
+
</a>
|
|
74
|
+
|
|
75
|
+
<meta itemprop="upvoteCount" content="{posts.upvotes}">
|
|
76
|
+
<meta itemprop="downvoteCount" content="{posts.downvotes}">
|
|
77
|
+
<a href="#" class="px-2 mx-1 btn btn-ghost btn-sm" component="post/vote-count" data-votes="{posts.votes}" title="[[global:voters]]">{posts.votes}</a>
|
|
78
|
+
|
|
79
|
+
{{{ if !downvote:disabled }}}
|
|
80
|
+
<a component="post/downvote" href="#" class="btn btn-ghost btn-sm{{{ if posts.downvoted }}} downvoted{{{ end }}}" title="[[topic:downvote-post]]">
|
|
81
|
+
<i class="fa fa-fw fa-chevron-down text-primary"></i>
|
|
82
|
+
</a>
|
|
83
|
+
{{{ end }}}
|
|
84
|
+
</div>
|
|
85
|
+
{{{ end }}}
|
|
86
|
+
|
|
87
|
+
<!-- IMPORT partials/topic/post-menu.tpl -->
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<div component="post/replies/container" class="my-2 col-11 border rounded-1 p-3 hidden-empty"></div>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
{{{ if (!./index && widgets.mainpost-footer.length) }}}
|
|
97
|
+
<div data-widget-area="mainpost-footer">
|
|
98
|
+
{{{ each widgets.mainpost-footer }}}
|
|
99
|
+
{widgets.mainpost-footer.html}
|
|
100
|
+
{{{ end }}}
|
|
101
|
+
</div>
|
|
102
|
+
{{{ end }}}
|
package/theme.json
CHANGED
|
@@ -4,5 +4,6 @@
|
|
|
4
4
|
"description": "Modern, premium NodeBB theme for JAVIS Community",
|
|
5
5
|
"url": "https://github.com/javis-admin/nodebb-community-theme",
|
|
6
6
|
"screenshot": "screenshot.png",
|
|
7
|
-
"baseTheme": "nodebb-theme-harmony"
|
|
7
|
+
"baseTheme": "nodebb-theme-harmony",
|
|
8
|
+
"templates": "templates"
|
|
8
9
|
}
|