@okjavis/nodebb-theme-javis 3.0.1 → 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.1",
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;
@@ -12,6 +12,9 @@
12
12
  $(document).ready(function() {
13
13
  console.log('JAVIS Community Theme initialized');
14
14
 
15
+ // Initialize sidebar toggle handler
16
+ initSidebarToggle();
17
+
15
18
  // Auto-expand sidebar on desktop (Reddit-style default)
16
19
  initSidebarAutoExpand();
17
20
 
@@ -198,6 +201,17 @@
198
201
  console.log('JAVIS: Created carousel with ' + $images.length + ' images');
199
202
  }
200
203
 
204
+ /**
205
+ * Initialize sidebar toggle click handler
206
+ * We don't need our own handler - Harmony's handler works fine.
207
+ * This function is now a no-op to avoid conflicts.
208
+ */
209
+ function initSidebarToggle() {
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');
213
+ }
214
+
201
215
  /**
202
216
  * Auto-expand sidebar on desktop (Reddit-style default)
203
217
  * The sidebar will be expanded by default on desktop, but users can still toggle it.
@@ -0,0 +1,148 @@
1
+ <!--
2
+ JAVIS Community Theme - Feed Page
3
+ Overrides nodebb-plugin-feed/public/templates/feed.tpl
4
+ Structure: Content first, Image second, Action bar third (separated)
5
+ -->
6
+ <div data-widget-area="header">
7
+ {{{each widgets.header}}}
8
+ {{widgets.header.html}}
9
+ {{{end}}}
10
+ </div>
11
+ <style>.feed .post-body .content > p:last-child { margin-bottom: 0px; }</style>
12
+ <div class="feed">
13
+ <div class="row">
14
+ <div data-widget-area="left" class="col-lg-3 col-sm-12 {{{ if !widgets.left.length }}}hidden{{{ end }}}">
15
+ {{{each widgets.left}}}
16
+ {{widgets.left.html}}
17
+ {{{end}}}
18
+ </div>
19
+ {{{ if ((widgets.left.length && widgets.right.length) || (!widgets.left.length && !widgets.right.length))}}}
20
+ <div class="col-lg-6 col-sm-12 mx-auto">
21
+ {{{ end }}}
22
+ {{{ if (widgets.left.length && !widgets.right.length) }}}
23
+ <div class="col-lg-6 col-sm-12 me-auto">
24
+ {{{ end }}}
25
+ {{{ if (!widgets.left.length && widgets.right.length) }}}
26
+ <div class="col-lg-6 col-sm-12 ms-auto">
27
+ {{{ end }}}
28
+
29
+ <div class="d-flex justify-content-between py-2 mb-2 gap-1">
30
+ {{{ if canPost }}}
31
+ <button id="new_topic" class="btn btn-primary btn-sm">[[category:new-topic-button]]</button>
32
+ {{{ end }}}
33
+ {{{ if (!loggedIn && !canPost) }}}
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 -->
39
+
40
+ <div id="options-dropdown" class="btn-group dropdown dropdown-right bottom-sheet">
41
+ <button type="button" class="btn btn-ghost btn-sm d-flex align-items-center gap-2 ff-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
42
+ <i class="fa fa-fw fa-gear text-primary"></i>
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>
62
+ </div>
63
+
64
+ {{{ if !posts.length }}}
65
+ <div class="alert alert-warning text-center">[[feed:no-posts-found]] {{{ if !following.length }}}[[feed:are-you-following-anyone]] {{{ end }}}</div>
66
+ {{{ end }}}
67
+
68
+ <ul component="posts" class="list-unstyled" data-nextstart="{nextStart}">
69
+ {{{ each posts }}}
70
+ <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
+
72
+ <!-- 1. CONTENT (first) -->
73
+ <div class="d-flex gap-2 p-3">
74
+ <div class="d-none d-lg-block">
75
+ <a class="lh-1 text-decoration-none" href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(./user, "40px", true, "not-responsive")}</a>
76
+ </div>
77
+ <div class="post-body d-flex flex-column gap-2 flex-grow-1 hover-parent" style="min-width: 0px;">
78
+ {{{ if ./isMainPost }}}
79
+ <a class="lh-1 topic-title fw-semibold fs-5 text-reset text-break d-block" href="{config.relative_path}/topic/{./topic.slug}">
80
+ {./topic.title}
81
+ </a>
82
+ {{{ end }}}
83
+
84
+ <div class="d-flex gap-1 post-info text-sm align-items-center">
85
+ <div class="post-author d-flex align-items-center gap-1">
86
+ <a class="d-inline d-lg-none lh-1 text-decoration-none" href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(./user, "16px", true, "not-responsive")}</a>
87
+ <a class="lh-normal fw-semibold text-nowrap" href="{config.relative_path}/user/{./user.userslug}">{./user.displayname}</a>
88
+ </div>
89
+ {{{ if !./isMainPost}}}{./repliedString}{{{ else }}}<span class="timeago text-muted lh-normal" title="{./timestampISO}"></span>{{{ end}}}
90
+ </div>
91
+
92
+ <div component="post/content" class="content text-sm text-break position-relative truncate-post-content">
93
+ <a href="{config.relative_path}/post/{./pid}" class="stretched-link"></a>
94
+ {./content}
95
+ </div>
96
+ <div class="position-relative hover-visible">
97
+ <button component="show/more" class="btn btn-light btn-sm rounded-pill position-absolute start-50 translate-middle-x bottom-0 z-1 hidden ff-secondary">[[feed:see-more]]</button>
98
+ </div>
99
+ </div>
100
+ </div>
101
+
102
+ <!-- 2. IMAGE (second) -->
103
+ {{{ if (showThumbs && ./topic.thumbs.length)}}}
104
+ <div class="p-1 position-relative">
105
+ <div class="overflow-hidden rounded-1" style="max-height: 300px;">
106
+ <a href="{config.relative_path}/topic/{./topic.slug}">
107
+ <img class="w-100" src="{./topic.thumbs.0.url}">
108
+ </a>
109
+ </div>
110
+
111
+ <div class="position-absolute end-0 bottom-0 p-3 d-flex gap-2 align-items-center pe-none">
112
+ {{{ each ./topic.thumbs }}}
113
+ {{{ if (@index != 0) }}}
114
+ <img class="rounded-1" style="max-height: 64px; object-fit: contain;" src="{./url}">
115
+ {{{ end }}}
116
+ {{{ end }}}
117
+ </div>
118
+ </div>
119
+ {{{ end }}}
120
+
121
+ <!-- 3. ACTION BAR (third - separated from content) -->
122
+ <div class="feed-action-bar d-flex justify-content-between px-3 py-2 border-top">
123
+ <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>
124
+
125
+ <a href="#" data-pid="{./pid}" data-action="bookmark" data-bookmarked="{./bookmarked}" data-bookmarks="{./bookmarks}" class="btn btn-link btn-sm text-body"><i class="fa-fw fa-bookmark {{{ if ./bookmarked }}}fa text-primary{{{ else }}}fa-regular text-muted{{{ end }}}"></i> <span component="bookmark-count">{humanReadableNumber(./bookmarks)}</span></a>
126
+
127
+ <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>
128
+
129
+ <a href="#" data-pid="{./pid}" data-is-main="{./isMainPost}" data-tid="{./tid}" data-action="reply" class="btn btn-link btn-sm text-body"><i class="fa-fw fa fa-reply text-muted"></i> [[topic:reply]]</a>
130
+ </div>
131
+ </li>
132
+ {{{ end }}}
133
+ </ul>
134
+ </div>
135
+
136
+ <div data-widget-area="right" class="col-lg-3 col-sm-12 {{{ if !widgets.right.length }}}hidden{{{ end }}}">
137
+ {{{each widgets.right}}}
138
+ {{widgets.right.html}}
139
+ {{{end}}}
140
+ </div>
141
+ </div>
142
+ </div>
143
+
144
+ <div data-widget-area="footer">
145
+ {{{each widgets.footer}}}
146
+ {{widgets.footer.html}}
147
+ {{{end}}}
148
+ </div>
@@ -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 }}}