@okjavis/nodebb-theme-javis 6.0.2 → 6.0.3
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 +98 -0
- package/templates/feed.tpl +90 -1
package/package.json
CHANGED
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
|
package/templates/feed.tpl
CHANGED
|
@@ -44,7 +44,13 @@
|
|
|
44
44
|
|
|
45
45
|
{{{ if !posts.length }}}
|
|
46
46
|
{{{ if showFollowed }}}
|
|
47
|
-
<div class="alert alert-info text-center">Follow
|
|
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() {
|