@okjavis/nodebb-theme-javis 3.0.2 → 3.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okjavis/nodebb-theme-javis",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
4
4
  "description": "Modern, premium NodeBB theme for JAVIS Community - Extends Harmony with custom styling",
5
5
  "main": "theme.js",
6
6
  "scripts": {
package/plugin.json CHANGED
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "templates": "templates",
24
24
  "screenshot": "screenshot.png",
25
- "version": "1.5.0",
25
+ "version": "3.0.3",
26
26
  "nbbpm": {
27
27
  "compatibility": "^4.0.0"
28
28
  }
package/scss/_base.scss CHANGED
@@ -30,8 +30,13 @@ nav[component="sidebar/left"] {
30
30
 
31
31
  // Sidebar toggle link padding
32
32
  .sidebar-toggle {
33
+ position: relative;
34
+ z-index: 10;
35
+
33
36
  [component="sidebar/toggle"] {
34
37
  padding: $jv-space-4 $jv-space-5 !important; // 16px vertical, 20px horizontal
38
+ pointer-events: auto !important;
39
+ cursor: pointer !important;
35
40
  }
36
41
  }
37
42
 
@@ -137,6 +137,11 @@
137
137
  margin-top: auto;
138
138
  }
139
139
 
140
+ // Ensure the dropup container has proper positioning context
141
+ .sidebar-user-section .dropup {
142
+ position: relative;
143
+ }
144
+
140
145
  // User dropdown menu styling
141
146
  .sidebar-user-section .dropdown-menu {
142
147
  min-width: 220px;
@@ -145,6 +150,18 @@
145
150
  border: 1px solid $jv-border-subtle;
146
151
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.12);
147
152
 
153
+ // Fix the shifting issue - disable Popper transforms and use fixed position
154
+ // Position dropdown to open upward from the bottom of the trigger
155
+ transform: none !important;
156
+ inset: auto auto 100% 0 !important; // bottom: 100%, left: 0
157
+ margin-bottom: $jv-space-2;
158
+ top: auto !important;
159
+ bottom: 100% !important;
160
+ left: 0 !important;
161
+
162
+ // Remove animation that could cause visual shifting
163
+ animation: none;
164
+
148
165
  .dropdown-item {
149
166
  padding: $jv-space-2 $jv-space-4;
150
167
  font-size: $jv-font-size-sm;
package/scss/_topic.scss CHANGED
@@ -382,10 +382,11 @@ body.template-topic {
382
382
  // ===========================================================
383
383
  [component="post/footer"],
384
384
  .post-footer {
385
- padding-top: 0 !important;
385
+ padding-top: $jv-space-3 !important;
386
386
  padding-bottom: 0 !important;
387
- margin-top: $jv-space-4;
387
+ margin-top: $jv-space-3;
388
388
  border-top: 1px solid $jv-border-subtle;
389
+ border-bottom: none !important; // Remove duplicate line from HTML class
389
390
  }
390
391
 
391
392
  [component="post/actions"] {
@@ -569,6 +570,9 @@ body.template-topic {
569
570
  align-self: flex-start;
570
571
  z-index: 100;
571
572
  pointer-events: auto;
573
+ // Match the top padding of posts list (py-3 = 1rem) + first post pt-4 (1.5rem)
574
+ // to align sidebar with post card
575
+ margin-top: calc(1rem + 1.5rem);
572
576
  }
573
577
 
574
578
  .topic-sidebar {
@@ -648,17 +652,60 @@ body.template-topic {
648
652
  }
649
653
  }
650
654
 
651
- .bottom-sheet {
655
+ // Each dropdown container gets stacking context
656
+ .bottom-sheet,
657
+ .thread-tools {
652
658
  width: 100%;
653
- .dropdown-menu { width: 100%; }
659
+ position: relative;
660
+ z-index: 1;
661
+
662
+ // When dropdown is open, raise z-index
663
+ &.show,
664
+ &:focus-within {
665
+ z-index: 100;
666
+ }
667
+
668
+ .dropdown-menu {
669
+ position: absolute;
670
+ top: 100%;
671
+ left: 0;
672
+ width: 100%;
673
+ min-width: 200px;
674
+ max-width: 280px;
675
+ z-index: 1050;
676
+ margin-top: $jv-space-1;
677
+ padding: $jv-space-2;
678
+ background: $jv-surface;
679
+ border: 1px solid $jv-border-subtle;
680
+ border-radius: $jv-radius-md;
681
+ box-shadow: $jv-shadow-lg;
682
+
683
+ // Dropdown items
684
+ .dropdown-item {
685
+ padding: $jv-space-2 $jv-space-3;
686
+ border-radius: $jv-radius-sm;
687
+ font-size: $jv-font-size-sm;
688
+ white-space: normal;
689
+
690
+ .help-text {
691
+ font-size: $jv-font-size-xs;
692
+ line-height: 1.3;
693
+ margin-top: 2px;
694
+ }
695
+ }
696
+ }
654
697
  }
655
698
 
656
- .thread-tools {
657
- .dropdown-menu { min-width: 100%; }
699
+ // Ensure pagination block stays below dropdowns
700
+ & + .pagination-block {
701
+ position: relative;
702
+ z-index: 0;
658
703
  }
659
704
  }
660
705
 
661
706
  .pagination-block {
707
+ position: relative;
708
+ z-index: 0;
662
709
  margin-top: $jv-space-4;
663
710
  padding-top: $jv-space-4;
664
711
  border-top: 1px solid $jv-border-subtle;
@@ -203,42 +203,13 @@
203
203
 
204
204
  /**
205
205
  * Initialize sidebar toggle click handler
206
- * Ensures the sidebar can be toggled and saves user preference
206
+ * We don't need our own handler - Harmony's handler works fine.
207
+ * This function is now a no-op to avoid conflicts.
207
208
  */
208
209
  function initSidebarToggle() {
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');
210
+ // Let Harmony's built-in handler manage the sidebar toggle
211
+ // We just ensure the sidebar auto-expands on desktop (handled by initSidebarAutoExpand)
212
+ console.log('JAVIS: Sidebar toggle - using Harmony default handler');
242
213
  }
243
214
 
244
215
  /**
@@ -38,7 +38,7 @@
38
38
  <!-- User Profile Section (only for logged-in users) -->
39
39
  {{{ if config.loggedIn }}}
40
40
  <div class="sidebar-user-section mx-2 mb-2">
41
- <div class="nav-item dropend usermenu">
41
+ <div class="nav-item dropup usermenu">
42
42
  <a component="header/avatar" id="sidebar_user_dropdown" href="#" role="button"
43
43
  class="nav-link d-flex gap-2 align-items-center text-truncate sidebar-user-trigger"
44
44
  data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
@@ -0,0 +1,20 @@
1
+ <div component="topic/reply/container" class="btn-group {{{ if !privileges.topics:reply }}}hidden{{{ end }}}">
2
+ <a href="{config.relative_path}/compose?tid={tid}" class="d-flex gap-2 align-items-center btn btn-sm btn-primary fw-semibold w-100 justify-content-center" component="topic/reply" data-ajaxify="false" role="button">
3
+ <i class="fa fa-fw fa-reply"></i>
4
+ <span>[[topic:reply]]</span>
5
+ </a>
6
+ <button type="button" class="btn btn-sm btn-primary dropdown-toggle flex-0" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="[[topic:reply-options]]">
7
+ <span class="caret"></span>
8
+ </button>
9
+ <ul class="dropdown-menu dropdown-menu-end p-1 text-sm" role="menu">
10
+ <li><a class="dropdown-item rounded-1" href="#" component="topic/reply-as-topic" role="menuitem">[[topic:reply-as-topic]]</a></li>
11
+ </ul>
12
+ </div>
13
+
14
+ {{{ if loggedIn }}}
15
+ <a href="#" component="topic/reply/locked" class="d-flex gap-2 align-items-center fw-semibold btn btn-sm btn-primary disabled hidden w-100 justify-content-center {{{ if (privileges.topics:reply || !locked) }}}hidden{{{ end }}}" disabled><i class="fa fa-fw fa-lock"></i> [[topic:locked]]</a>
16
+ {{{ else }}}
17
+ {{{ if !privileges.topics:reply }}}
18
+ <a component="topic/reply/guest" href="{config.relative_path}/login" class="d-flex gap-2 align-items-center fw-semibold btn btn-sm btn-primary w-100 justify-content-center"><i class="fa fa-fw fa-sign-in"></i><span>[[topic:guest-login-reply]]</span></a>
19
+ {{{ end }}}
20
+ {{{ end }}}
@@ -5,7 +5,7 @@
5
5
  <!-- IMPORT partials/topic/reply-button.tpl -->
6
6
 
7
7
  <!-- Mark Unread Button -->
8
- {{{ if loggedIn }}}
8
+ {{{ if config.loggedIn }}}
9
9
  <button component="topic/mark-unread" class="btn btn-ghost btn-sm d-flex gap-2 align-items-center w-100 justify-content-start">
10
10
  <i class="fa fa-fw fa-inbox"></i>
11
11
  <span class="fw-semibold text-nowrap">[[topic:mark-unread]]</span>
@@ -0,0 +1,27 @@
1
+ <div class="btn-group bottom-sheet w-100" component="thread/sort">
2
+ <button class="btn btn-ghost btn-sm d-flex gap-2 align-items-center dropdown-toggle w-100 justify-content-start" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="[[aria:post-sort-option, {sortOptionLabel}]]">
3
+ <i class="fa fa-fw fa-arrow-down-wide-short"></i>
4
+ <span class="fw-semibold text-nowrap">{sortOptionLabel}</span>
5
+ </button>
6
+
7
+ <ul class="dropdown-menu p-1 text-sm" role="menu">
8
+ <li>
9
+ <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" href="#" class="oldest_to_newest" data-sort="oldest_to_newest" role="menuitem">
10
+ <span class="flex-grow-1">[[topic:oldest-to-newest]]</span>
11
+ <i class="flex-shrink-0 fa fa-fw text-secondary"></i>
12
+ </a>
13
+ </li>
14
+ <li>
15
+ <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" href="#" class="newest_to_oldest" data-sort="newest_to_oldest" role="menuitem">
16
+ <span class="flex-grow-1">[[topic:newest-to-oldest]]</span>
17
+ <i class="flex-shrink-0 fa fa-fw text-secondary"></i>
18
+ </a>
19
+ </li>
20
+ <li>
21
+ <a class="dropdown-item rounded-1 d-flex align-items-center gap-2" href="#" class="most_votes" data-sort="most_votes" role="menuitem">
22
+ <span class="flex-grow-1">[[topic:most-votes]]</span>
23
+ <i class="flex-shrink-0 fa fa-fw text-secondary"></i>
24
+ </a>
25
+ </li>
26
+ </ul>
27
+ </div>
@@ -0,0 +1,9 @@
1
+ {{{ if privileges.view_thread_tools }}}
2
+ <div class="btn-group thread-tools bottom-sheet w-100">
3
+ <button class="btn btn-ghost btn-sm d-flex align-items-center gap-2 dropdown-toggle w-100 justify-content-start" data-bs-toggle="dropdown" type="button" aria-haspopup="true" aria-expanded="false">
4
+ <i class="fa fa-fw fa-gear"></i>
5
+ <span class="fw-semibold text-nowrap">[[topic:thread-tools.title]]</span>
6
+ </button>
7
+ <ul class="dropdown-menu p-1 text-sm" role="menu"></ul>
8
+ </div>
9
+ {{{ end }}}
@@ -0,0 +1,60 @@
1
+ {{{ if config.loggedIn }}}
2
+ <div class="btn-group bottom-sheet w-100" component="topic/watch">
3
+ <button class="btn btn-ghost btn-sm d-flex gap-2 align-items-center dropdown-toggle w-100 justify-content-start" data-bs-toggle="dropdown" type="button" aria-haspopup="true" aria-expanded="false">
4
+ <span component="topic/following/menu" class="d-flex gap-2 align-items-center{{{ if !isFollowing }}} hidden{{{ end }}}">
5
+ <i class="fa fa-fw fa-bell-o"></i>
6
+ <span class="fw-semibold text-nowrap">[[topic:watching]]</span>
7
+ </span>
8
+
9
+ <span component="topic/not-following/menu" class="d-flex gap-2 align-items-center{{{ if !isNotFollowing}}} hidden{{{ end }}}">
10
+ <i class="fa fa-fw fa-bell-slash-o"></i>
11
+ <span class="fw-semibold text-nowrap">[[topic:not-watching]]</span>
12
+ </span>
13
+
14
+ <span component="topic/ignoring/menu" class="d-flex gap-2 align-items-center{{{ if !isIgnoring }}} hidden{{{ end }}}">
15
+ <i class="fa fa-fw fa-eye-slash"></i>
16
+ <span class="fw-semibold text-nowrap">[[topic:ignoring]]</span>
17
+ </span>
18
+ </button>
19
+ <ul class="dropdown-menu p-1 text-sm" role="menu">
20
+ <li>
21
+ <a class="dropdown-item rounded-1 d-flex align-items-center gap-2 p-2" href="#" component="topic/following" role="menuitem">
22
+ <div class="flex-grow-1 d-flex flex-column">
23
+ <span class="d-flex align-items-center gap-2">
24
+ <i class="fa fa-fw fa-bell-o text-secondary"></i>
25
+ <span class="flex-grow-1 fw-semibold">[[topic:watching]]</span>
26
+ </span>
27
+ <div class="help-text text-secondary text-xs">[[topic:watching.description]]</div>
28
+ </div>
29
+ <span class="flex-shrink-0"><i component="topic/following/check" class="fa fa-fw {{{ if isFollowing }}}fa-check{{{ end }}}"></i></span>
30
+ </a>
31
+ </li>
32
+
33
+ <li>
34
+ <a class="dropdown-item rounded-1 d-flex align-items-center gap-2 p-2" href="#" component="topic/not-following" role="menuitem">
35
+ <div class="flex-grow-1 d-flex flex-column">
36
+ <span class="d-flex align-items-center gap-2">
37
+ <i class="fa fa-fw fa-bell-slash-o text-secondary"></i>
38
+ <span class="flex-grow-1 fw-semibold">[[topic:not-watching]]</span>
39
+ </span>
40
+ <div class="help-text text-secondary text-xs">[[topic:not-watching.description]]</div>
41
+ </div>
42
+ <span class="flex-shrink-0"><i component="topic/not-following/check" class="fa fa-fw {{{ if isNotFollowing }}}fa-check{{{ end }}}"></i></span>
43
+ </a>
44
+ </li>
45
+
46
+ <li>
47
+ <a class="dropdown-item rounded-1 d-flex align-items-center gap-2 p-2" href="#" component="topic/ignoring" role="menuitem">
48
+ <div class="flex-grow-1 d-flex flex-column">
49
+ <span class="d-flex align-items-center gap-2">
50
+ <i class="fa fa-fw fa-eye-slash text-secondary"></i>
51
+ <span class="flex-grow-1 fw-semibold">[[topic:ignoring]]</span>
52
+ </span>
53
+ <div class="help-text text-secondary text-xs">[[topic:ignoring.description]]</div>
54
+ </div>
55
+ <span class="flex-shrink-0"><i component="topic/ignoring/check" class="fa fa-fw {{{ if isIgnoring }}}fa-check{{{ end }}}"></i></span>
56
+ </a>
57
+ </li>
58
+ </ul>
59
+ </div>
60
+ {{{ end }}}
@@ -57,9 +57,9 @@
57
57
  <div class="d-flex gap-2 align-items-center mt-2 hidden-empty" component="topic/thumb/list"><!-- IMPORT partials/topic/thumbs.tpl --></div>
58
58
  </div>
59
59
 
60
- <div class="topic-layout d-flex gap-4 mb-4 mb-lg-0">
60
+ <div class="topic topic-layout d-flex gap-4 mb-4 mb-lg-0">
61
61
  <!-- Main Content Area -->
62
- <div class="topic flex-grow-1" style="min-width: 0;">
62
+ <div class="topic-main flex-grow-1" style="min-width: 0;">
63
63
  {{{ if merger }}}
64
64
  <!-- IMPORT partials/topic/merged-message.tpl -->
65
65
  {{{ end }}}