@okjavis/nodebb-theme-javis 2.5.3 → 3.0.1
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/_base.scss +114 -0
- package/scss/_categories.scss +424 -39
- package/scss/_composer.scss +140 -41
- package/scss/_feed.scss +121 -64
- package/scss/_header.scss +12 -9
- package/scss/_sidebar-user.scss +25 -5
- package/scss/_sidebar.scss +128 -74
- package/scss/_topic.scss +1 -1
- package/static/lib/theme.js +29 -32
- package/templates/partials/categories/item.tpl +67 -0
- package/templates/partials/categories/lastpost.tpl +30 -0
- package/templates/partials/categories/link.tpl +5 -0
- package/templates/partials/header/brand.tpl +53 -0
package/scss/_sidebar.scss
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
// ===========================================================
|
|
7
7
|
// JAVIS SIDEBAR LOGO
|
|
8
8
|
// ===========================================================
|
|
9
|
-
// Height should match the sticky header (
|
|
9
|
+
// Height should match the sticky header (56px) for visual alignment
|
|
10
10
|
.javis-sidebar-logo {
|
|
11
11
|
display: flex;
|
|
12
12
|
align-items: center;
|
|
13
13
|
justify-content: center;
|
|
14
|
-
height:
|
|
15
|
-
min-height:
|
|
14
|
+
height: 56px; // Match header height (8px + 36px + 8px + border)
|
|
15
|
+
min-height: 56px;
|
|
16
16
|
padding: 0 $jv-space-4; // Only horizontal padding
|
|
17
17
|
margin-bottom: $jv-space-3; // 12px space below border before nav items
|
|
18
18
|
border-bottom: 1px solid $jv-border-subtle;
|
|
@@ -26,17 +26,17 @@
|
|
|
26
26
|
text-decoration: none;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
// Icon logo (collapsed state) -
|
|
29
|
+
// Icon logo (collapsed state) - 36px for better visibility
|
|
30
30
|
.javis-logo-icon {
|
|
31
|
-
width:
|
|
32
|
-
height:
|
|
31
|
+
width: 36px;
|
|
32
|
+
height: 36px;
|
|
33
33
|
object-fit: contain;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
// Full logo (expanded state) - max 140px width,
|
|
36
|
+
// Full logo (expanded state) - max 140px width, 36px height
|
|
37
37
|
.javis-logo-full {
|
|
38
38
|
max-width: 140px;
|
|
39
|
-
height:
|
|
39
|
+
height: 36px;
|
|
40
40
|
object-fit: contain;
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
// ===========================================================
|
|
51
51
|
// LEFT SIDEBAR (Main Navigation)
|
|
52
52
|
// ===========================================================
|
|
53
|
+
// Reddit-style wider sidebar (200px) with expanded state as default
|
|
53
54
|
|
|
54
55
|
// Override Bootstrap's bg-light class on sidebar
|
|
55
56
|
.sidebar.bg-light,
|
|
@@ -59,9 +60,18 @@ nav.sidebar.bg-light {
|
|
|
59
60
|
|
|
60
61
|
.sidebar {
|
|
61
62
|
background: $jv-surface !important; // Pure white - cohesive with header
|
|
62
|
-
border-right:
|
|
63
|
+
border-right: none !important; // Clean look - no vertical divider
|
|
63
64
|
padding-top: 0 !important; // Remove top padding so logo sits at top edge
|
|
64
65
|
|
|
66
|
+
// Desktop: Use 270px width when expanded (Reddit-style)
|
|
67
|
+
@media (min-width: 992px) {
|
|
68
|
+
&.open {
|
|
69
|
+
min-width: 270px !important;
|
|
70
|
+
max-width: 270px !important;
|
|
71
|
+
width: 270px !important;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
65
75
|
// Nav items - proper spacing between items
|
|
66
76
|
.nav-item {
|
|
67
77
|
margin-bottom: $jv-space-2; // 4px between nav items - compact like Slack/Discord
|
|
@@ -498,7 +508,8 @@ div[data-widget-area] {
|
|
|
498
508
|
// RIGHT SIDEBAR WIDGET AREA (Reddit-style)
|
|
499
509
|
// ===========================================================
|
|
500
510
|
div[data-widget-area="right"],
|
|
501
|
-
.col-lg-3.col-sm-12
|
|
511
|
+
div[data-widget-area="right"].col-lg-3.col-sm-12,
|
|
512
|
+
.col-lg-3.col-sm-12[data-widget-area="right"] {
|
|
502
513
|
display: flex;
|
|
503
514
|
flex-direction: column;
|
|
504
515
|
|
|
@@ -506,33 +517,49 @@ div[data-widget-area="right"],
|
|
|
506
517
|
position: sticky;
|
|
507
518
|
top: 72px; // Adjust based on your header height
|
|
508
519
|
align-self: flex-start;
|
|
509
|
-
max-height: calc(100vh - 100px); // Account for header + padding
|
|
510
|
-
overflow-y: auto; // Allow scrolling if content is too tall
|
|
511
|
-
|
|
512
|
-
// Smooth scrollbar styling (webkit browsers)
|
|
513
|
-
&::-webkit-scrollbar {
|
|
514
|
-
width: 6px;
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
&::-webkit-scrollbar-track {
|
|
518
|
-
background: transparent;
|
|
519
|
-
}
|
|
520
520
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
&:hover {
|
|
526
|
-
background: rgba(0, 0, 0, 0.25);
|
|
527
|
-
}
|
|
528
|
-
}
|
|
521
|
+
// CRITICAL: Remove all overflow/scroll from sidebar and ALL descendants
|
|
522
|
+
overflow: visible !important;
|
|
523
|
+
max-height: none !important;
|
|
529
524
|
|
|
530
525
|
// Widget card container
|
|
531
526
|
> div {
|
|
532
527
|
background: $jv-surface;
|
|
533
528
|
border: 1px solid $jv-border-subtle;
|
|
534
529
|
border-radius: $jv-radius-lg;
|
|
535
|
-
overflow: hidden;
|
|
530
|
+
overflow: hidden; // Hide overflow on card itself
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Trending Now widget - needs scrollable content
|
|
534
|
+
> div:has(#recent_posts),
|
|
535
|
+
> div:has(ul[id*="recent"]),
|
|
536
|
+
> div:has(.widget-posts) {
|
|
537
|
+
overflow: hidden !important; // Card clips content
|
|
538
|
+
|
|
539
|
+
// Inner scrollable container
|
|
540
|
+
> div {
|
|
541
|
+
max-height: 500px !important;
|
|
542
|
+
overflow-y: auto !important;
|
|
543
|
+
overflow-x: hidden !important;
|
|
544
|
+
|
|
545
|
+
// Scrollbar styling
|
|
546
|
+
&::-webkit-scrollbar {
|
|
547
|
+
width: 6px;
|
|
548
|
+
}
|
|
549
|
+
&::-webkit-scrollbar-track {
|
|
550
|
+
background: rgba(0, 0, 0, 0.03);
|
|
551
|
+
border-radius: 3px;
|
|
552
|
+
}
|
|
553
|
+
&::-webkit-scrollbar-thumb {
|
|
554
|
+
background: rgba(0, 0, 0, 0.15);
|
|
555
|
+
border-radius: 3px;
|
|
556
|
+
&:hover {
|
|
557
|
+
background: rgba(0, 0, 0, 0.25);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
scrollbar-width: thin;
|
|
561
|
+
scrollbar-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.03);
|
|
562
|
+
}
|
|
536
563
|
}
|
|
537
564
|
|
|
538
565
|
// Widget header/title - clean and simple
|
|
@@ -542,14 +569,19 @@ div[data-widget-area="right"],
|
|
|
542
569
|
text-transform: uppercase;
|
|
543
570
|
letter-spacing: 0.5px;
|
|
544
571
|
color: $jv-text-soft;
|
|
545
|
-
padding: $jv-space-4 $jv-space-
|
|
572
|
+
padding: $jv-space-4 0 $jv-space-3 0 !important; // top right bottom left - no horizontal padding (body handles it)
|
|
546
573
|
margin: 0 !important;
|
|
547
574
|
border-bottom: none !important; // Removed border
|
|
548
575
|
}
|
|
549
576
|
|
|
577
|
+
// Remove hr dividers after widget headers
|
|
578
|
+
hr {
|
|
579
|
+
display: none !important;
|
|
580
|
+
}
|
|
581
|
+
|
|
550
582
|
// Add spacing between widgets
|
|
551
583
|
> div + div {
|
|
552
|
-
margin-top: $jv-space-
|
|
584
|
+
margin-top: $jv-space-3; // Reduced from 16px to 12px
|
|
553
585
|
}
|
|
554
586
|
}
|
|
555
587
|
|
|
@@ -563,30 +595,35 @@ div[data-widget-area="right"] {
|
|
|
563
595
|
border: none !important;
|
|
564
596
|
border-radius: 0 !important;
|
|
565
597
|
overflow: visible !important;
|
|
566
|
-
|
|
567
|
-
//
|
|
568
|
-
h5 {
|
|
569
|
-
padding: $jv-space-3 0 !important;
|
|
570
|
-
border-bottom: none !important;
|
|
571
|
-
}
|
|
598
|
+
padding: 0 $jv-space-4 !important; // Horizontal padding for alignment
|
|
599
|
+
margin-bottom: 0 !important; // Remove extra margin
|
|
572
600
|
}
|
|
573
601
|
|
|
574
602
|
.popular-tags {
|
|
575
603
|
padding: 0 !important;
|
|
576
|
-
margin: 0;
|
|
604
|
+
margin: 0 !important; // Reset all margins
|
|
605
|
+
|
|
606
|
+
// Override Bootstrap mb-3 class
|
|
607
|
+
&.mb-3 {
|
|
608
|
+
margin-bottom: $jv-space-2 !important; // Space between widgets (reduced to 8px)
|
|
609
|
+
}
|
|
577
610
|
}
|
|
578
611
|
|
|
579
612
|
// Override Bootstrap's grid - make it a flowing wrap layout
|
|
580
|
-
.tag-list
|
|
613
|
+
.tag-list,
|
|
614
|
+
.tag-list.row {
|
|
581
615
|
display: flex !important;
|
|
582
616
|
flex-wrap: wrap !important;
|
|
583
617
|
gap: $jv-space-2 !important; // 8px gap between pills
|
|
584
618
|
padding: 0 !important;
|
|
585
619
|
margin: 0 !important;
|
|
620
|
+
margin-left: -$jv-space-3 !important; // Offset to align first pill's text with header (compensate for pill padding)
|
|
621
|
+
margin-bottom: $jv-space-2 !important; // Space between widgets (8px)
|
|
586
622
|
|
|
587
623
|
// Reset Bootstrap row/column styles
|
|
588
624
|
&.row {
|
|
589
|
-
margin:
|
|
625
|
+
margin-left: -$jv-space-3 !important;
|
|
626
|
+
margin-bottom: $jv-space-2 !important;
|
|
590
627
|
display: flex !important;
|
|
591
628
|
flex-wrap: wrap !important;
|
|
592
629
|
}
|
|
@@ -672,43 +709,13 @@ div[data-widget-area="right"] {
|
|
|
672
709
|
}
|
|
673
710
|
|
|
674
711
|
// ===========================================================
|
|
675
|
-
// TRENDING POSTS WIDGET - Widget Essentials
|
|
712
|
+
// TRENDING POSTS WIDGET - Widget Essentials / Recent Posts
|
|
676
713
|
// ===========================================================
|
|
677
714
|
|
|
678
|
-
//
|
|
679
|
-
.overflow-hidden {
|
|
680
|
-
overflow: visible !important;
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
// The wrapper div after h5 (Trending Posts header) - make it scrollable
|
|
684
|
-
h5 + div {
|
|
685
|
-
max-height: 420px;
|
|
686
|
-
overflow-y: auto !important;
|
|
687
|
-
overflow-x: hidden !important;
|
|
688
|
-
|
|
689
|
-
// Scrollbar styling
|
|
690
|
-
&::-webkit-scrollbar {
|
|
691
|
-
width: 6px;
|
|
692
|
-
}
|
|
693
|
-
&::-webkit-scrollbar-track {
|
|
694
|
-
background: transparent;
|
|
695
|
-
}
|
|
696
|
-
&::-webkit-scrollbar-thumb {
|
|
697
|
-
background: rgba(0, 0, 0, 0.15);
|
|
698
|
-
border-radius: 3px;
|
|
699
|
-
&:hover {
|
|
700
|
-
background: rgba(0, 0, 0, 0.25);
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
// Recent posts container - no scroll here, parent wrapper handles it
|
|
715
|
+
// Recent posts container styling
|
|
706
716
|
#recent_posts,
|
|
707
717
|
ul[id*="recent"] {
|
|
708
|
-
|
|
709
|
-
overflow: visible !important;
|
|
710
|
-
padding: $jv-space-3 !important;
|
|
711
|
-
padding-bottom: $jv-space-5 !important;
|
|
718
|
+
padding: $jv-space-3 $jv-space-4 $jv-space-4 $jv-space-4 !important;
|
|
712
719
|
margin: 0;
|
|
713
720
|
list-style: none;
|
|
714
721
|
display: flex !important;
|
|
@@ -829,4 +836,51 @@ div[data-widget-area="right"] {
|
|
|
829
836
|
}
|
|
830
837
|
}
|
|
831
838
|
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// ===========================================================
|
|
842
|
+
// CRITICAL: Override ALL overflow rules on right sidebar
|
|
843
|
+
// This MUST be at the end to have highest specificity
|
|
844
|
+
// The selector [data-widget-area=right] gets overflow-y:auto from somewhere
|
|
845
|
+
// ===========================================================
|
|
846
|
+
|
|
847
|
+
// Override the base selector that has overflow-y: auto
|
|
848
|
+
[data-widget-area="right"] {
|
|
849
|
+
overflow: visible !important;
|
|
850
|
+
overflow-y: visible !important;
|
|
851
|
+
overflow-x: visible !important;
|
|
852
|
+
max-height: none !important;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// More specific selectors to ensure override
|
|
856
|
+
div[data-widget-area="right"],
|
|
857
|
+
.col-lg-3[data-widget-area="right"],
|
|
858
|
+
.col-sm-12[data-widget-area="right"] {
|
|
859
|
+
overflow: visible !important;
|
|
860
|
+
overflow-y: visible !important;
|
|
861
|
+
overflow-x: visible !important;
|
|
862
|
+
max-height: none !important;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
// Override Bootstrap's overflow-hidden utility
|
|
866
|
+
div[data-widget-area="right"] .overflow-hidden,
|
|
867
|
+
[data-widget-area="right"] .overflow-hidden {
|
|
868
|
+
overflow: visible !important;
|
|
869
|
+
overflow-x: visible !important;
|
|
870
|
+
overflow-y: visible !important;
|
|
871
|
+
max-height: none !important;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// Hide any scrollbar that might appear (as backup)
|
|
875
|
+
[data-widget-area="right"]::-webkit-scrollbar,
|
|
876
|
+
div[data-widget-area="right"]::-webkit-scrollbar {
|
|
877
|
+
display: none !important;
|
|
878
|
+
width: 0 !important;
|
|
879
|
+
height: 0 !important;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
[data-widget-area="right"],
|
|
883
|
+
div[data-widget-area="right"] {
|
|
884
|
+
scrollbar-width: none !important;
|
|
885
|
+
-ms-overflow-style: none !important;
|
|
832
886
|
}
|
package/scss/_topic.scss
CHANGED
package/static/lib/theme.js
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
$(document).ready(function() {
|
|
13
13
|
console.log('JAVIS Community Theme initialized');
|
|
14
14
|
|
|
15
|
-
//
|
|
16
|
-
|
|
15
|
+
// Auto-expand sidebar on desktop (Reddit-style default)
|
|
16
|
+
initSidebarAutoExpand();
|
|
17
17
|
|
|
18
18
|
// Initialize image carousels for posts with multiple images
|
|
19
19
|
initPostImageCarousels();
|
|
@@ -198,41 +198,38 @@
|
|
|
198
198
|
console.log('JAVIS: Created carousel with ' + $images.length + ' images');
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
201
|
+
/**
|
|
202
|
+
* Auto-expand sidebar on desktop (Reddit-style default)
|
|
203
|
+
* The sidebar will be expanded by default on desktop, but users can still toggle it.
|
|
204
|
+
* Their preference is saved and respected on subsequent visits.
|
|
205
|
+
*/
|
|
206
|
+
function initSidebarAutoExpand() {
|
|
207
|
+
// Only run on desktop (min-width: 992px)
|
|
208
|
+
if ($(window).width() < 992) {
|
|
206
209
|
return;
|
|
207
210
|
}
|
|
208
211
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
212
|
+
var $sidebar = $('.sidebar-left');
|
|
213
|
+
if (!$sidebar.length) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
213
216
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
});
|
|
229
|
-
});
|
|
217
|
+
// Check if user has a saved preference (via config.theme.openSidebars)
|
|
218
|
+
// If they've explicitly closed the sidebar before, respect that
|
|
219
|
+
var hasUserPreference = typeof config !== 'undefined' &&
|
|
220
|
+
config.theme &&
|
|
221
|
+
typeof config.theme.openSidebars !== 'undefined';
|
|
222
|
+
|
|
223
|
+
// If sidebar is not already open and user hasn't explicitly closed it, expand it
|
|
224
|
+
if (!$sidebar.hasClass('open')) {
|
|
225
|
+
// If no user preference set, auto-expand (first-time visitors)
|
|
226
|
+
// If user preference is 'on', also expand
|
|
227
|
+
if (!hasUserPreference || config.theme.openSidebars === 'on' || config.theme.openSidebars === true) {
|
|
228
|
+
$sidebar.addClass('open');
|
|
229
|
+
$(window).trigger('action:sidebar.toggle');
|
|
230
|
+
console.log('JAVIS: Auto-expanded sidebar (Reddit-style default)');
|
|
230
231
|
}
|
|
231
|
-
|
|
232
|
-
$(window).trigger('action:sidebar.toggle');
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
console.log('JAVIS: Sidebar toggle initialized');
|
|
232
|
+
}
|
|
236
233
|
}
|
|
237
234
|
|
|
238
235
|
/**
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<li component="categories/category" data-cid="{./cid}" class="category-card w-100 py-3 py-lg-4 gap-lg-0 gap-2 d-flex flex-column flex-lg-row align-items-start category-{./cid} {./unread-class}">
|
|
2
|
+
<meta itemprop="name" content="{./name}">
|
|
3
|
+
|
|
4
|
+
<div class="d-flex col-lg-7 gap-2 gap-lg-3">
|
|
5
|
+
<div class="flex-shrink-0">
|
|
6
|
+
{buildCategoryIcon(@value, "48px", "rounded-1 category-icon-enhanced")}
|
|
7
|
+
</div>
|
|
8
|
+
<div class="flex-grow-1 d-flex flex-wrap gap-1 me-0 me-lg-2">
|
|
9
|
+
<h2 class="title text-break fs-5 fw-semibold m-0 tracking-tight w-100">
|
|
10
|
+
<!-- IMPORT partials/categories/link.tpl -->
|
|
11
|
+
</h2>
|
|
12
|
+
{{{ if ./descriptionParsed }}}
|
|
13
|
+
<div class="description text-muted text-sm w-100">
|
|
14
|
+
{./descriptionParsed}
|
|
15
|
+
</div>
|
|
16
|
+
{{{ end }}}
|
|
17
|
+
|
|
18
|
+
<!-- Activity Badge Row -->
|
|
19
|
+
<div class="category-activity-row d-flex align-items-center gap-2 w-100 mt-1">
|
|
20
|
+
{{{ each ./posts }}}
|
|
21
|
+
{{{ if @first }}}
|
|
22
|
+
<span class="activity-badge" title="Last activity">
|
|
23
|
+
<i class="fa fa-clock-o"></i>
|
|
24
|
+
<span class="timeago" title="{./timestampISO}"></span>
|
|
25
|
+
</span>
|
|
26
|
+
{{{ end }}}
|
|
27
|
+
{{{ end }}}
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
{{{ if !config.hideSubCategories }}}
|
|
31
|
+
{{{ if ./children.length }}}
|
|
32
|
+
<div class="subcategory-pills d-flex flex-wrap gap-2 mt-2 w-100">
|
|
33
|
+
{{{ each ./children }}}
|
|
34
|
+
{{{ if !./isSection }}}
|
|
35
|
+
<a href="{{{ if ./link }}}{./link}{{{ else }}}{config.relative_path}/category/{./slug}{{{ end }}}" class="subcategory-pill" style="--pill-color: {./bgColor};">
|
|
36
|
+
<span class="pill-icon" style="background-color: {./bgColor};">
|
|
37
|
+
<i class="{./icon}"></i>
|
|
38
|
+
</span>
|
|
39
|
+
<span class="pill-name">{./name}</span>
|
|
40
|
+
</a>
|
|
41
|
+
{{{ end }}}
|
|
42
|
+
{{{ end }}}
|
|
43
|
+
</div>
|
|
44
|
+
{{{ end }}}
|
|
45
|
+
{{{ end }}}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
{{{ if !./link }}}
|
|
49
|
+
<div class="d-flex col-lg-5 col-12 align-content-stretch">
|
|
50
|
+
<div class="meta stats-minimal d-none d-lg-flex col-4 gap-3 pe-3 text-muted align-items-center justify-content-end">
|
|
51
|
+
<div class="stat-item text-center">
|
|
52
|
+
<span class="stat-number" title="{./totalTopicCount}">{humanReadableNumber(./totalTopicCount, 0)}</span>
|
|
53
|
+
<span class="stat-label">topics</span>
|
|
54
|
+
</div>
|
|
55
|
+
<div class="stat-item text-center">
|
|
56
|
+
<span class="stat-number" title="{./totalPostCount}">{humanReadableNumber(./totalPostCount, 0)}</span>
|
|
57
|
+
<span class="stat-label">posts</span>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
{{{ if !config.hideCategoryLastPost }}}
|
|
61
|
+
<div component="topic/teaser" class="teaser col-lg-8 col-12 {{{ if !config.theme.mobileTopicTeasers }}}d-none d-lg-block{{{ end }}}">
|
|
62
|
+
<!-- IMPORT partials/categories/lastpost.tpl -->
|
|
63
|
+
</div>
|
|
64
|
+
{{{ end }}}
|
|
65
|
+
</div>
|
|
66
|
+
{{{ end }}}
|
|
67
|
+
</li>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<div class="lastpost teaser-enhanced lh-sm h-100" style="--teaser-color: {./bgColor};">
|
|
2
|
+
{{{ each ./posts }}}
|
|
3
|
+
{{{ if @first }}}
|
|
4
|
+
<div component="category/posts" class="d-flex flex-column h-100 gap-2">
|
|
5
|
+
<div class="teaser-header d-flex align-items-center gap-2">
|
|
6
|
+
<a class="text-decoration-none avatar-tooltip" title="{./user.displayname}" href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(posts.user, "24px", true)}</a>
|
|
7
|
+
<div class="teaser-meta">
|
|
8
|
+
<span class="teaser-user">{./user.displayname}</span>
|
|
9
|
+
<a class="permalink timeago teaser-time" href="{config.relative_path}/topic/{./topic.slug}{{{ if ./index }}}/{./index}{{{ end }}}" title="{./timestampISO}" aria-label="[[global:lastpost]]"></a>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="teaser-content-wrapper position-relative flex-fill">
|
|
13
|
+
<div class="teaser-content text-break line-clamp-2">
|
|
14
|
+
{./content}
|
|
15
|
+
</div>
|
|
16
|
+
<a class="teaser-read-more" href="{config.relative_path}/topic/{./topic.slug}{{{ if ./index }}}/{./index}{{{ end }}}">Read more →</a>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
{{{ end }}}
|
|
20
|
+
{{{ end }}}
|
|
21
|
+
|
|
22
|
+
{{{ if !./posts.length }}}
|
|
23
|
+
<div component="category/posts" class="ps-2 empty-category-state">
|
|
24
|
+
<div class="d-flex flex-column align-items-start gap-1">
|
|
25
|
+
<span class="empty-icon"><i class="fa fa-inbox"></i></span>
|
|
26
|
+
<span class="empty-text">Be the first to post</span>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
{{{ end }}}
|
|
30
|
+
</div>
|
|
@@ -1,11 +1,64 @@
|
|
|
1
1
|
{{{ if widgets.brand-header.length }}}
|
|
2
2
|
<div class="container-lg px-md-4 brand-container">
|
|
3
3
|
<div class="col-12 d-flex border-bottom pb-3 {{{ if config.theme.centerHeaderElements }}}justify-content-center{{{ end }}}">
|
|
4
|
+
<!-- Search widget area (left/center) -->
|
|
4
5
|
<div data-widget-area="brand-header" class="flex-fill gap-3 p-2 align-self-center">
|
|
5
6
|
{{{each widgets.brand-header}}}
|
|
6
7
|
{{./html}}
|
|
7
8
|
{{{end}}}
|
|
8
9
|
</div>
|
|
10
|
+
|
|
11
|
+
<!-- Right side: Notifications -->
|
|
12
|
+
<div class="header-right-actions d-flex align-items-center gap-2 ms-auto">
|
|
13
|
+
{{{ if config.loggedIn }}}
|
|
14
|
+
<!-- Notifications dropdown (logged-in users) -->
|
|
15
|
+
<div class="dropdown" component="notifications">
|
|
16
|
+
<a data-bs-toggle="dropdown" href="#" role="button" class="nav-link d-flex align-items-center position-relative p-2 rounded-circle" aria-haspopup="true" aria-expanded="false" aria-label="[[global:header.notifications]]" style="width: 40px; height: 40px; justify-content: center;">
|
|
17
|
+
<span class="position-relative">
|
|
18
|
+
<i component="notifications/icon" class="fa fa-fw fa-lg {{{ if unreadCount.notification}}}fa-bell{{{ else }}}fa-bell-o{{{ end }}}" style="color: #6b7280;"></i>
|
|
19
|
+
<span component="notifications/count" class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger {{{ if !unreadCount.notification }}}hidden{{{ end }}}" style="font-size: 10px; min-width: 18px;">{unreadCount.notification}</span>
|
|
20
|
+
</span>
|
|
21
|
+
</a>
|
|
22
|
+
<ul class="notifications-dropdown dropdown-menu dropdown-menu-end p-1 shadow" role="menu" style="min-width: 320px;">
|
|
23
|
+
<li>
|
|
24
|
+
<div component="notifications/list" class="list-container notification-list overscroll-behavior-contain pe-1 ff-base ghost-scrollbar" style="max-height: 400px; overflow-y: auto;">
|
|
25
|
+
<div class="mb-2 p-1">
|
|
26
|
+
<div class="d-flex gap-1 justify-content-between">
|
|
27
|
+
<div class="d-flex gap-2 flex-grow-1 placeholder-wave">
|
|
28
|
+
<div class="placeholder rounded-circle" style="width: 32px; height: 32px;"></div>
|
|
29
|
+
<div class="flex-grow-1">
|
|
30
|
+
<div class="d-flex flex-column">
|
|
31
|
+
<div class="text-sm">
|
|
32
|
+
<span class="placeholder placeholder-sm col-4"></span>
|
|
33
|
+
<span class="placeholder placeholder-sm col-6"></span>
|
|
34
|
+
<span class="placeholder placeholder-sm col-7"></span>
|
|
35
|
+
</div>
|
|
36
|
+
<div class="text-xs">
|
|
37
|
+
<div class="placeholder placeholder-xs col-6"></div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</li>
|
|
46
|
+
<li class="dropdown-divider"></li>
|
|
47
|
+
<li>
|
|
48
|
+
<div class="d-flex justify-content-center gap-1 flex-wrap p-1">
|
|
49
|
+
<a role="button" href="#" class="btn btn-sm btn-light mark-all-read flex-fill text-nowrap text-truncate"><i class="fa fa-check-double"></i> [[notifications:mark-all-read]]</a>
|
|
50
|
+
<a class="btn btn-sm btn-primary flex-fill text-nowrap text-truncate" href="{relative_path}/notifications"><i class="fa fa-list"></i> [[notifications:see-all]]</a>
|
|
51
|
+
</div>
|
|
52
|
+
</li>
|
|
53
|
+
</ul>
|
|
54
|
+
</div>
|
|
55
|
+
{{{ else }}}
|
|
56
|
+
<!-- Notification icon for guests (redirects to login) -->
|
|
57
|
+
<a href="{relative_path}/login" class="nav-link d-flex align-items-center position-relative p-2 rounded-circle guest-notification-btn" aria-label="[[global:header.notifications]]" title="Sign in to view notifications" style="width: 40px; height: 40px; justify-content: center;">
|
|
58
|
+
<i class="fa fa-fw fa-lg fa-bell-o" style="color: #6b7280;"></i>
|
|
59
|
+
</a>
|
|
60
|
+
{{{ end }}}
|
|
61
|
+
</div>
|
|
9
62
|
</div>
|
|
10
63
|
</div>
|
|
11
64
|
{{{ end }}}
|