@okjavis/nodebb-theme-javis 6.0.2 → 6.0.4

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": "@okjavis/nodebb-theme-javis",
3
- "version": "6.0.2",
3
+ "version": "6.0.4",
4
4
  "description": "Modern, premium NodeBB theme for JAVIS Community - Extends Harmony with custom styling",
5
5
  "main": "theme.js",
6
6
  "scripts": {
package/scss/_feed.scss CHANGED
@@ -1138,6 +1138,104 @@ ul.categories-list {
1138
1138
  }
1139
1139
  }
1140
1140
 
1141
+ // ===========================================================
1142
+ // SUGGESTED USERS – Following Empty State
1143
+ // ===========================================================
1144
+ .javis-suggested-users {
1145
+ background: $jv-surface;
1146
+ border: 1px solid $jv-border-subtle;
1147
+ border-radius: $jv-radius-lg;
1148
+ padding: $jv-space-4 $jv-space-6;
1149
+ margin-bottom: $jv-space-4;
1150
+ box-shadow: $jv-shadow-sm;
1151
+ }
1152
+
1153
+ .javis-suggested-users-title {
1154
+ font-size: $jv-font-size-xs;
1155
+ font-weight: 700;
1156
+ text-transform: uppercase;
1157
+ letter-spacing: 0.6px;
1158
+ color: $jv-text-muted;
1159
+ padding: $jv-space-3 0 $jv-space-2;
1160
+ margin: 0;
1161
+ }
1162
+
1163
+ .javis-sug-card {
1164
+ display: flex !important;
1165
+ flex-direction: row !important;
1166
+ align-items: center !important;
1167
+ gap: $jv-space-3;
1168
+ padding: $jv-space-3 0;
1169
+ border-bottom: 1px solid $jv-border-subtle;
1170
+
1171
+ &:last-child {
1172
+ border-bottom: none;
1173
+ padding-bottom: $jv-space-2;
1174
+ }
1175
+
1176
+ &:first-child {
1177
+ padding-top: $jv-space-2;
1178
+ }
1179
+
1180
+ // Anchor wrapping the avatar — must be inline-flex
1181
+ > a:first-child {
1182
+ display: inline-flex !important;
1183
+ flex-shrink: 0;
1184
+ line-height: 0;
1185
+ }
1186
+ }
1187
+
1188
+ .javis-sug-avatar {
1189
+ width: 40px !important;
1190
+ height: 40px !important;
1191
+ min-width: 40px;
1192
+ min-height: 40px;
1193
+ border-radius: 50% !important;
1194
+ flex-shrink: 0;
1195
+ display: block;
1196
+ object-fit: cover;
1197
+ }
1198
+
1199
+ .javis-sug-avatar-icon {
1200
+ color: #fff;
1201
+ display: inline-flex !important;
1202
+ align-items: center !important;
1203
+ justify-content: center !important;
1204
+ font-size: 16px;
1205
+ font-weight: 700;
1206
+ font-family: $jv-font-sans;
1207
+ line-height: 1;
1208
+ }
1209
+
1210
+ .javis-sug-info {
1211
+ flex: 1 1 0;
1212
+ min-width: 0;
1213
+ display: flex;
1214
+ flex-direction: column;
1215
+ gap: 2px;
1216
+ overflow: hidden;
1217
+ }
1218
+
1219
+ .javis-sug-name {
1220
+ font-size: $jv-font-size-sm;
1221
+ font-weight: 600;
1222
+ color: $jv-text-main;
1223
+ text-decoration: none;
1224
+ white-space: nowrap;
1225
+ overflow: hidden;
1226
+ text-overflow: ellipsis;
1227
+ display: block;
1228
+
1229
+ &:hover {
1230
+ color: $jv-primary;
1231
+ }
1232
+ }
1233
+
1234
+ .javis-sug-meta {
1235
+ font-size: $jv-font-size-xs;
1236
+ color: $jv-text-soft;
1237
+ }
1238
+
1141
1239
  // ===========================================================
1142
1240
  // MOBILE FIX - Category dropdown positioning
1143
1241
  // Fix dropdown opening from bottom left corner on mobile
@@ -11,10 +11,10 @@
11
11
  display: flex;
12
12
  align-items: center;
13
13
  justify-content: center;
14
- height: 56px; // Match header height (8px + 36px + 8px + border)
14
+ height: 56px;
15
15
  min-height: 56px;
16
- padding: 0 $jv-space-4; // Only horizontal padding
17
- margin-bottom: $jv-space-3; // 12px space below border before nav items
16
+ padding: 0 $jv-space-4;
17
+ margin-bottom: $jv-space-3;
18
18
  border-bottom: 1px solid $jv-border-subtle;
19
19
  flex-shrink: 0;
20
20
  box-sizing: border-box;
@@ -26,17 +26,16 @@
26
26
  text-decoration: none;
27
27
  }
28
28
 
29
- // Icon logo (collapsed state) - 36px for better visibility
29
+ // Icon logo (collapsed state)
30
30
  .javis-logo-icon {
31
31
  width: 36px;
32
32
  height: 36px;
33
33
  object-fit: contain;
34
34
  }
35
35
 
36
- // Full logo (expanded state) - max 140px width, 36px height
36
+ // Full logo (expanded state) size controlled via inline style on the img tag
37
37
  .javis-logo-full {
38
- max-width: 140px;
39
- height: 36px;
38
+ max-width: 200px;
40
39
  object-fit: contain;
41
40
  }
42
41
  }
@@ -44,7 +44,13 @@
44
44
 
45
45
  {{{ if !posts.length }}}
46
46
  {{{ if showFollowed }}}
47
- <div class="alert alert-info text-center">Follow some members to see their posts here.</div>
47
+ <div class="alert alert-info text-center mb-3">Follow new members to see their posts here.</div>
48
+ <div class="javis-suggested-users">
49
+ <p style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:0.6px;color:#6b7280;margin:0 0 4px;">People you should follow</p>
50
+ <div id="javis-suggested-users-list">
51
+ <div class="text-center text-muted py-4"><i class="fa fa-spinner fa-spin me-2"></i></div>
52
+ </div>
53
+ </div>
48
54
  {{{ else }}}
49
55
  <div class="alert alert-warning text-center">[[feed:no-posts-found]]</div>
50
56
  {{{ end }}}
@@ -134,9 +140,92 @@ $(document).ready(function() {
134
140
  require(['share'], function(share) {
135
141
  share.addShareHandlers('{title}');
136
142
  });
143
+
137
144
  });
138
145
  </script>
139
146
 
147
+ <script>
148
+ // Suggested users – standalone, same pattern as video embed
149
+ (function() {
150
+ function loadSuggestedUsers() {
151
+ var $list = $('#javis-suggested-users-list');
152
+ if (!$list.length) return;
153
+
154
+ fetch((config.relative_path || '') + '/api/users?section=top', {
155
+ credentials: 'same-origin',
156
+ headers: { 'Accept': 'application/json' }
157
+ })
158
+ .then(function(r) { return r.json(); })
159
+ .then(function(data) {
160
+ var users = (data.users || []).filter(function(u) {
161
+ return u.uid && String(u.uid) !== String(config.uid);
162
+ }).slice(0, 6);
163
+
164
+ if (!users.length) {
165
+ $list.html('<p class="text-muted text-center py-2 mb-0">No members to suggest yet.</p>');
166
+ return;
167
+ }
168
+
169
+ $list.html(users.map(function(u, i) {
170
+ var bg = u['icon:bgColor'] || '#0051ff';
171
+ var icon = u['icon:text'] || (u.displayname || 'U')[0].toUpperCase();
172
+ var isLast = i === users.length - 1;
173
+ var avatarHtml = u.picture
174
+ ? '<img src="' + u.picture + '" style="width:40px;height:40px;min-width:40px;border-radius:50%;object-fit:cover;display:block;" data-bg="' + bg + '" data-icon="' + icon + '" class="javis-sug-avatar-img">'
175
+ : '<span style="width:40px;height:40px;min-width:40px;border-radius:50%;background:' + bg + ';color:#fff;display:inline-flex;align-items:center;justify-content:center;font-size:15px;font-weight:700;font-family:system-ui,sans-serif;flex-shrink:0;">' + icon + '</span>';
176
+ return '<div style="display:flex;align-items:center;gap:12px;padding:10px 0;' + (isLast ? '' : 'border-bottom:1px solid rgba(0,0,0,0.07);') + '">' +
177
+ '<a href="' + (config.relative_path || '') + '/user/' + u.userslug + '" style="flex-shrink:0;display:inline-flex;line-height:0;">' + avatarHtml + '</a>' +
178
+ '<div style="flex:1;min-width:0;">' +
179
+ '<a href="' + (config.relative_path || '') + '/user/' + u.userslug + '" style="font-size:13px;font-weight:600;color:#111;text-decoration:none;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">' + (u.displayname || u.username) + '</a>' +
180
+ '<span style="font-size:12px;color:#9ca3af;">' + (u.postcount || 0) + ' posts</span>' +
181
+ '</div>' +
182
+ '<button class="btn btn-sm rounded-pill javis-follow-btn" style="flex-shrink:0;font-size:12px;font-weight:600;padding:4px 14px;border:1.5px solid #0051ff;color:#0051ff;background:transparent;white-space:nowrap;" data-userslug="' + u.userslug + '">Follow</button>' +
183
+ '</div>';
184
+ }).join(''));
185
+
186
+ $list.find('img.javis-sug-avatar-img').on('error', function() {
187
+ var $img = $(this);
188
+ $img.replaceWith('<span class="javis-sug-avatar javis-sug-avatar-icon" style="background:' + ($img.data('bg') || '#0051ff') + '">' + ($img.data('icon') || 'U') + '</span>');
189
+ });
190
+ })
191
+ .catch(function() {
192
+ $list.closest('.javis-suggested-users').remove();
193
+ });
194
+ }
195
+
196
+ // Initial load
197
+ if (document.readyState === 'loading') {
198
+ document.addEventListener('DOMContentLoaded', function() { setTimeout(loadSuggestedUsers, 100); });
199
+ } else {
200
+ setTimeout(loadSuggestedUsers, 100);
201
+ }
202
+
203
+ // SPA navigation
204
+ $(window).on('action:ajaxify.end', function() {
205
+ setTimeout(loadSuggestedUsers, 100);
206
+ });
207
+
208
+ // Follow button
209
+ $(document).on('click', '.javis-follow-btn', function() {
210
+ var $btn = $(this);
211
+ var userslug = $btn.data('userslug');
212
+ $btn.prop('disabled', true).text('...');
213
+ fetch((config.relative_path || '') + '/api/v3/users/' + userslug + '/follow', {
214
+ method: 'PUT',
215
+ credentials: 'same-origin',
216
+ headers: { 'Content-Type': 'application/json', 'x-csrf-token': config.csrf_token },
217
+ body: JSON.stringify({})
218
+ }).then(function(r) {
219
+ if (r.ok) {
220
+ $btn.text('Following').css({'background':'#0051ff','color':'#fff','border-color':'#0051ff'}).prop('disabled',true);
221
+ } else { throw new Error(); }
222
+ }).catch(function() {
223
+ $btn.prop('disabled', false).text('Follow');
224
+ });
225
+ });
226
+ })();
227
+ </script>
228
+
140
229
  <script>
141
230
  // Embed videos on feed page - runs independently
142
231
  (function() {
@@ -5,7 +5,7 @@
5
5
  <!-- Icon logo (shown when collapsed) -->
6
6
  <img src="{relative_path}/plugins/@okjavis/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/@okjavis/nodebb-theme-javis/static/images/logo-full.png" alt="JAVIS Community" class="javis-logo-full visible-open" />
8
+ <img src="{relative_path}/plugins/@okjavis/nodebb-theme-javis/static/images/logo-full.png" alt="JAVIS Community" class="javis-logo-full visible-open" style="height:44px;width:auto;" />
9
9
  </a>
10
10
  </div>
11
11