@okjavis/nodebb-theme-javis 4.0.1 → 4.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
package/scss/_base.scss
CHANGED
|
@@ -144,6 +144,55 @@ a {
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
+
// ===========================================================
|
|
148
|
+
// PROFILE PAGE - Hide Push Notifications link
|
|
149
|
+
// ===========================================================
|
|
150
|
+
#web-push {
|
|
151
|
+
display: none !important;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// ===========================================================
|
|
155
|
+
// PROFILE EDIT PAGE - Right side options alignment
|
|
156
|
+
// ===========================================================
|
|
157
|
+
.account .col-xl-6:last-child {
|
|
158
|
+
// Remove text-center, align left
|
|
159
|
+
text-align: left !important;
|
|
160
|
+
|
|
161
|
+
// The list group for Change Picture, Username, etc.
|
|
162
|
+
.list-group {
|
|
163
|
+
border-radius: $jv-radius-sm;
|
|
164
|
+
overflow: hidden;
|
|
165
|
+
|
|
166
|
+
.list-group-item {
|
|
167
|
+
text-align: left;
|
|
168
|
+
padding: $jv-space-4 $jv-space-6;
|
|
169
|
+
border-left: none;
|
|
170
|
+
border-right: none;
|
|
171
|
+
|
|
172
|
+
&:first-child {
|
|
173
|
+
border-top: none;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
a {
|
|
177
|
+
display: block;
|
|
178
|
+
font-weight: 500;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// SSO section label - align with list items above
|
|
184
|
+
> label.form-label {
|
|
185
|
+
margin-top: $jv-space-6;
|
|
186
|
+
padding-left: $jv-space-6; // Match list-group-item padding
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Delete account button container
|
|
190
|
+
.d-flex.justify-content-center {
|
|
191
|
+
justify-content: flex-start !important;
|
|
192
|
+
margin-top: $jv-space-6;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
147
196
|
// ===========================================================
|
|
148
197
|
// LOGIN PAGE ONLY - Hide search bar
|
|
149
198
|
// ===========================================================
|
package/scss/_forms.scss
CHANGED
|
@@ -30,9 +30,11 @@ textarea,
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
// Textarea specific
|
|
34
|
-
textarea
|
|
35
|
-
|
|
33
|
+
// Textarea specific - override pill shape for multi-line inputs
|
|
34
|
+
textarea,
|
|
35
|
+
textarea.form-control,
|
|
36
|
+
.form-control[type="textarea"] {
|
|
37
|
+
border-radius: $jv-radius-sm !important; // 8px rounded rectangle, not pill
|
|
36
38
|
resize: vertical;
|
|
37
39
|
min-height: 100px;
|
|
38
40
|
}
|
package/templates/feed.tpl
CHANGED
|
@@ -94,13 +94,13 @@
|
|
|
94
94
|
{{{ end }}}
|
|
95
95
|
|
|
96
96
|
<!-- 3. ACTION BAR (third - separated from content) -->
|
|
97
|
-
<!-- Order: Likes, Comments,
|
|
97
|
+
<!-- Order: Likes, Comments, Share -->
|
|
98
98
|
<div class="feed-action-bar d-flex justify-content-between px-3 py-2 border-top">
|
|
99
99
|
<a href="#" data-pid="{./pid}" data-action="upvote" data-upvoted="{./upvoted}" data-upvotes="{./upvotes}" class="btn btn-link btn-sm text-body"><i class="fa-fw fa-heart {{{ if ./upvoted }}}fa text-danger{{{ else }}}fa-regular text-muted{{{ end }}}"></i> <span component="upvote-count">{humanReadableNumber(./upvotes)}</span></a>
|
|
100
100
|
|
|
101
101
|
<a href="{config.relative_path}/post/{{{ if ./topic.teaserPid }}}{./topic.teaserPid}{{{ else }}}{./pid}{{{ end }}}" class="btn btn-link btn-sm text-body {{{ if !./isMainPost }}}invisible{{{ end }}}"><i class="fa-fw fa-regular fa-message text-muted"></i> {humanReadableNumber(./topic.postcount)}</a>
|
|
102
102
|
|
|
103
|
-
<a href="#" data-pid="{./pid}"
|
|
103
|
+
<a href="#" data-pid="{./pid}" component="share/linkedin" class="btn btn-link btn-sm text-body"><i class="fa-fw fa-brands fa-linkedin text-muted"></i> [[topic:share]]</a>
|
|
104
104
|
</div>
|
|
105
105
|
</li>
|
|
106
106
|
{{{ end }}}
|
|
@@ -120,3 +120,99 @@
|
|
|
120
120
|
{{widgets.footer.html}}
|
|
121
121
|
{{{end}}}
|
|
122
122
|
</div>
|
|
123
|
+
|
|
124
|
+
<script>
|
|
125
|
+
$(document).ready(function() {
|
|
126
|
+
require(['share'], function(share) {
|
|
127
|
+
share.addShareHandlers('{title}');
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
</script>
|
|
131
|
+
|
|
132
|
+
<script>
|
|
133
|
+
// Embed videos on feed page - runs independently
|
|
134
|
+
(function() {
|
|
135
|
+
function embedFeedVideos() {
|
|
136
|
+
// Find all MP4 links in feed posts
|
|
137
|
+
var $links = $('a[href*=".mp4"]').not('.stretched-link');
|
|
138
|
+
|
|
139
|
+
$links.each(function() {
|
|
140
|
+
var $link = $(this);
|
|
141
|
+
|
|
142
|
+
// Avoid double-processing
|
|
143
|
+
if ($link.data('javisVideoEmbedded')) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
var href = $link.attr('href');
|
|
148
|
+
if (!href || href.indexOf('.mp4') === -1) return;
|
|
149
|
+
|
|
150
|
+
// Normalise relative URLs
|
|
151
|
+
var src = href;
|
|
152
|
+
if (href.indexOf('http') !== 0) {
|
|
153
|
+
src = window.location.origin + href;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Find the parent post content div and feed-content-section
|
|
157
|
+
var $contentDiv = $link.closest('[component="post/content"]');
|
|
158
|
+
var $feedContentSection = $link.closest('.feed-content-section');
|
|
159
|
+
|
|
160
|
+
// Remove the stretched-link overlay so video controls work
|
|
161
|
+
if ($contentDiv.length) {
|
|
162
|
+
$contentDiv.find('.stretched-link').remove();
|
|
163
|
+
$contentDiv.removeClass('position-relative');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Create the inline video player
|
|
167
|
+
var $video = $('<video />', {
|
|
168
|
+
src: src,
|
|
169
|
+
controls: true,
|
|
170
|
+
preload: 'metadata',
|
|
171
|
+
class: 'javis-feed-video'
|
|
172
|
+
}).css({
|
|
173
|
+
width: '100%',
|
|
174
|
+
maxWidth: '100%',
|
|
175
|
+
borderRadius: '8px',
|
|
176
|
+
backgroundColor: '#000'
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Wrap video in a container
|
|
180
|
+
var $videoContainer = $('<div class="feed-video-section px-3 pb-3"></div>').append($video);
|
|
181
|
+
|
|
182
|
+
// Insert video container after the feed-content-section (outside of it)
|
|
183
|
+
if ($feedContentSection.length) {
|
|
184
|
+
$feedContentSection.after($videoContainer);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Hide the link/paragraph containing the MP4 link
|
|
188
|
+
var $parent = $link.closest('p');
|
|
189
|
+
if ($parent.length) {
|
|
190
|
+
$parent.hide();
|
|
191
|
+
} else {
|
|
192
|
+
$link.hide();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
$link.data('javisVideoEmbedded', true);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Run when DOM is ready
|
|
200
|
+
if (document.readyState === 'loading') {
|
|
201
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
202
|
+
setTimeout(embedFeedVideos, 200);
|
|
203
|
+
});
|
|
204
|
+
} else {
|
|
205
|
+
setTimeout(embedFeedVideos, 200);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Also run on ajaxify (SPA navigation)
|
|
209
|
+
$(window).on('action:ajaxify.end', function() {
|
|
210
|
+
setTimeout(embedFeedVideos, 200);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// Run when new posts are loaded (infinite scroll)
|
|
214
|
+
$(window).on('action:posts.loaded', function() {
|
|
215
|
+
setTimeout(embedFeedVideos, 200);
|
|
216
|
+
});
|
|
217
|
+
})();
|
|
218
|
+
</script>
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<div class="flex-shrink-0 pe-2 border-end-md text-sm mb-3 flex-basis-md-200">
|
|
2
|
+
<div class="sticky-md-top d-flex flex-row flex-md-column flex-wrap gap-1" style="top: 1rem;z-index: 1;">
|
|
3
|
+
<a href="{config.relative_path}/user/{userslug}" class="btn btn-ghost btn-sm text-start ff-secondary fw-semibold {{{ if template.account/profile }}}active{{{ end }}}">
|
|
4
|
+
<div class="flex-grow-1">[[global:about]]</div>
|
|
5
|
+
</a>
|
|
6
|
+
|
|
7
|
+
<a href="{config.relative_path}/user/{userslug}/posts"class="btn btn-ghost btn-sm text-start ff-secondary fw-semibold d-flex gap-2 align-items-center
|
|
8
|
+
{{{ if template.account/posts }}}active{{{ end }}}
|
|
9
|
+
{{{ if template.account/best }}}active{{{ end }}}
|
|
10
|
+
{{{ if template.account/controversial }}}active{{{ end }}}
|
|
11
|
+
{{{ if template.account/upvoted }}}active{{{ end }}}
|
|
12
|
+
{{{ if template.account/downvoted }}}active{{{ end }}}
|
|
13
|
+
{{{ if template.account/bookmarks }}}active{{{ end }}}">
|
|
14
|
+
<div class="flex-grow-1">[[global:posts]]</div>
|
|
15
|
+
<span class="flex-shrink-0 text-xs" title="{counts.posts}">{humanReadableNumber(counts.posts)}</span>
|
|
16
|
+
</a>
|
|
17
|
+
|
|
18
|
+
<a href="{config.relative_path}/user/{userslug}/topics" class="btn btn-ghost btn-sm text-start ff-secondary fw-semibold d-flex gap-2 align-items-center
|
|
19
|
+
{{{ if template.account/topics }}}active{{{ end }}}
|
|
20
|
+
{{{ if template.account/watched }}}active{{{ end }}}
|
|
21
|
+
{{{ if template.account/ignored }}}active{{{ end }}}">
|
|
22
|
+
<div class="flex-grow-1">[[global:topics]]</div>
|
|
23
|
+
<span class="flex-shrink-0 text-xs" title="{counts.topics}">{humanReadableNumber(counts.topics)}</span>
|
|
24
|
+
</a>
|
|
25
|
+
|
|
26
|
+
<a href="{config.relative_path}/user/{userslug}/shares" class="btn btn-ghost btn-sm text-start ff-secondary fw-semibold d-flex gap-2 align-items-center
|
|
27
|
+
{{{ if template.account/shares }}}active{{{ end }}}">
|
|
28
|
+
<div class="flex-grow-1">[[user:shares]]</div>
|
|
29
|
+
<span class="flex-shrink-0 text-xs" title="{counts.shares}">{humanReadableNumber(counts.shares)}</span>
|
|
30
|
+
</a>
|
|
31
|
+
|
|
32
|
+
<a href="{config.relative_path}/user/{userslug}/groups" class="btn btn-ghost btn-sm text-start ff-secondary fw-semibold d-flex gap-2 align-items-center
|
|
33
|
+
{{{ if template.account/groups }}}active{{{ end }}}">
|
|
34
|
+
<div class="flex-grow-1">[[global:header.groups]]</div>
|
|
35
|
+
<span class="flex-shrink-0 text-xs" title="{counts.groups}">{humanReadableNumber(counts.groups)}</span>
|
|
36
|
+
</a>
|
|
37
|
+
|
|
38
|
+
<a href="{config.relative_path}/user/{userslug}/followers" class="btn btn-ghost btn-sm text-start ff-secondary fw-semibold d-flex gap-2 align-items-center
|
|
39
|
+
{{{ if template.account/followers }}}active{{{ end }}}">
|
|
40
|
+
<div class="flex-grow-1">[[user:followers]]</div>
|
|
41
|
+
<span class="flex-shrink-0 text-xs" title="{counts.followers}">{humanReadableNumber(counts.followers)}</span>
|
|
42
|
+
</a>
|
|
43
|
+
|
|
44
|
+
<a href="{config.relative_path}/user/{userslug}/following" class="btn btn-ghost btn-sm text-start ff-secondary fw-semibold d-flex gap-2 align-items-center
|
|
45
|
+
{{{ if template.account/following }}}active{{{ end }}}">
|
|
46
|
+
<div class="flex-grow-1">[[user:following]]</div>
|
|
47
|
+
<span class="flex-shrink-0 text-xs" title="{counts.following}">{humanReadableNumber(counts.following)}</span>
|
|
48
|
+
</a>
|
|
49
|
+
|
|
50
|
+
{{{ if canEdit }}}
|
|
51
|
+
<a href="{config.relative_path}/user/{userslug}/categories" class="btn btn-ghost btn-sm text-start ff-secondary fw-semibold d-flex gap-2 align-items-center
|
|
52
|
+
{{{ if template.account/categories }}}active{{{ end }}}">
|
|
53
|
+
<div class="flex-grow-1">[[user:watched-categories]]</div>
|
|
54
|
+
<span class="flex-shrink-0 text-xs" title="{counts.categoriesWatched}">{counts.categoriesWatched}</span>
|
|
55
|
+
</a>
|
|
56
|
+
{{{ if isSelf }}}
|
|
57
|
+
<a href="{config.relative_path}/user/{userslug}/tags" class="btn btn-ghost btn-sm text-start ff-secondary fw-semibold d-flex gap-2 align-items-center
|
|
58
|
+
{{{ if template.account/tags }}}active{{{ end }}}">
|
|
59
|
+
<div class="flex-grow-1">[[user:watched-tags]]</div>
|
|
60
|
+
<span class="flex-shrink-0 text-xs" title="{counts.tagsWatched}">{counts.tagsWatched}</span>
|
|
61
|
+
</a>
|
|
62
|
+
{{{ end }}}
|
|
63
|
+
|
|
64
|
+
<a href="{config.relative_path}/user/{userslug}/blocks" class="btn btn-ghost btn-sm text-start ff-secondary fw-semibold d-flex gap-2 align-items-center
|
|
65
|
+
{{{ if template.account/blocks }}}active{{{ end }}}">
|
|
66
|
+
<div class="flex-grow-1">[[user:blocked-users]]</div>
|
|
67
|
+
<span class="flex-shrink-0 text-xs" title="{counts.blocks}">{humanReadableNumber(counts.blocks)}</span>
|
|
68
|
+
</a>
|
|
69
|
+
|
|
70
|
+
<a href="{config.relative_path}/user/{userslug}/uploads" class="btn btn-ghost btn-sm text-start ff-secondary fw-semibold d-flex gap-2 align-items-center
|
|
71
|
+
{{{ if template.account/uploads }}}active{{{ end }}}">
|
|
72
|
+
<div class="flex-grow-1">[[global:uploads]]</div>
|
|
73
|
+
<span class="flex-shrink-0 text-xs" title="{counts.uploaded}">{humanReadableNumber(counts.uploaded)}</span>
|
|
74
|
+
</a>
|
|
75
|
+
{{{ end }}}
|
|
76
|
+
|
|
77
|
+
{{{ if remoteUrl }}}
|
|
78
|
+
<hr class="w-100 my-2"/>
|
|
79
|
+
|
|
80
|
+
<a href="{remoteUrl}" target="_self" component="account/view-remote" class="btn btn-ghost btn-sm ff-secondary d-flex align-items-center gap-2 text-start">
|
|
81
|
+
<i class="flex-shrink-0 fa-solid fa-globe"></i>
|
|
82
|
+
<div class="flex-grow-1 text-nowrap">[[user:view-remote]]</div>
|
|
83
|
+
</a>
|
|
84
|
+
{{{ end }}}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
{{{ if (loggedIn && (!isSelf && !banned)) }}}
|
|
88
|
+
<hr class="w-100 my-2"/>
|
|
89
|
+
|
|
90
|
+
<a href="#" component="account/flag" class="btn btn-ghost btn-sm ff-secondary d-flex align-items-center gap-2 text-start {{{if flagId }}}hidden{{{end}}}">
|
|
91
|
+
<i class="flex-shrink-0 fa-solid fa-flag text-danger"></i>
|
|
92
|
+
<div class="flex-grow-1 text-nowrap">[[user:flag-profile]]</div>
|
|
93
|
+
</a>
|
|
94
|
+
<a href="#" component="account/already-flagged" class="btn btn-ghost btn-sm ff-secondary d-flex align-items-center gap-2 text-start {{{if !flagId }}}hidden{{{end}}}" data-flag-id="{flagId}">
|
|
95
|
+
<i class="flex-shrink-0 fa-solid fa-flag text-danger"></i>
|
|
96
|
+
<div class="flex-grow-1 text-nowrap">[[user:profile-flagged]]</div>
|
|
97
|
+
</a>
|
|
98
|
+
<a href="#" component="account/block" class="btn btn-ghost btn-sm ff-secondary d-flex align-items-center gap-2 text-start {{{ if isBlocked }}}hidden{{{ end }}}">
|
|
99
|
+
<i class="flex-shrink-0 fa-solid fa-ban text-danger"></i>
|
|
100
|
+
<div class="flex-grow-1 text-nowrap">[[user:block-user]]</div>
|
|
101
|
+
</a>
|
|
102
|
+
<a href="#" component="account/unblock" class="btn btn-ghost btn-sm ff-secondary d-flex align-items-center gap-2 text-start {{{ if !isBlocked }}}hidden{{{ end }}}">
|
|
103
|
+
<i class="flex-shrink-0 fa-solid fa-ban text-danger"></i>
|
|
104
|
+
<div class="flex-grow-1 text-nowrap">[[user:unblock-user]]</div>
|
|
105
|
+
</a>
|
|
106
|
+
{{{ end }}}
|
|
107
|
+
|
|
108
|
+
{{{ if canEdit }}}
|
|
109
|
+
<hr class="w-100 my-2"/>
|
|
110
|
+
<a href="{config.relative_path}/user/{userslug}/edit" class="btn btn-ghost btn-sm ff-secondary text-xs text-start
|
|
111
|
+
{{{ if template.account/edit }}}active{{{ end }}}">
|
|
112
|
+
<div class="flex-grow-1">[[user:edit-profile]]</div>
|
|
113
|
+
</a>
|
|
114
|
+
{{{ end }}}
|
|
115
|
+
|
|
116
|
+
{{{ each profile_links }}}
|
|
117
|
+
<a href="{config.relative_path}/user/{userslug}/{./route}" class="btn btn-ghost btn-sm ff-secondary text-xs text-start plugin-link {{{ if ./public }}}public{{{ else }}}private{{{ end }}} {{{ if (url == ./url) }}}active{{{ end }}}" id="{./id}">
|
|
118
|
+
<div class="flex-grow-1">{./name}</div>
|
|
119
|
+
</a>
|
|
120
|
+
{{{end}}}
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
@@ -46,11 +46,6 @@
|
|
|
46
46
|
<i class="fa fa-fw fa-edit text-secondary"></i> <span>[[user:edit-profile]]</span>
|
|
47
47
|
</a>
|
|
48
48
|
</li>
|
|
49
|
-
<li>
|
|
50
|
-
<a class="dropdown-item rounded-1 d-flex align-items-center gap-2" component="header/profilelink/settings" href="{relative_path}/user/{user.userslug}/settings" role="menuitem">
|
|
51
|
-
<i class="fa fa-fw fa-gear text-secondary"></i> <span>[[user:settings]]</span>
|
|
52
|
-
</a>
|
|
53
|
-
</li>
|
|
54
49
|
{{{ if showModMenu }}}
|
|
55
50
|
<li role="presentation" class="dropdown-divider"></li>
|
|
56
51
|
<li><h6 class="dropdown-header text-xs">[[pages:moderator-tools]]</h6></li>
|