mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-12 16:15:33 +00:00
Merge pull request #1077 from oraios/manual_banner_rotation
Dashboard: Replace automatic banner rotation with random initial display and manual rotation
This commit is contained in:
3 files changed
+118
-19
No files matched your search
@@ -207,6 +207,7 @@ body {
|
||||
top: 0;
|
||||
left: 0;
|
||||
order: 2;
|
||||
height: var(--header-height);
|
||||
max-height: var(--header-height);
|
||||
}
|
||||
|
||||
@@ -311,17 +312,13 @@ body {
|
||||
}
|
||||
|
||||
.platinum-banner-slide {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: none;
|
||||
pointer-events: none;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
transition: opacity 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.platinum-banner-slide.active {
|
||||
opacity: 1;
|
||||
display: block;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
@@ -351,19 +348,16 @@ body {
|
||||
.gold-banner {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.gold-banner-slide {
|
||||
position: absolute;
|
||||
display: none;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.gold-banner-slide.active {
|
||||
opacity: 1;
|
||||
display: block;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
@@ -372,6 +366,43 @@ body {
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* Banner Arrow Navigation */
|
||||
.banner-arrow {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 10;
|
||||
background: rgba(128, 128, 128, 0.15);
|
||||
color: var(--text-muted);
|
||||
border: none;
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
width: 24px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
opacity: 0.3;
|
||||
transition: opacity 0.2s ease, background-color 0.2s ease, color 0.2s ease;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.banner-arrow:hover {
|
||||
opacity: 0.8;
|
||||
background: rgba(128, 128, 128, 0.4);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.banner-arrow-left {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.banner-arrow-right {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.page-view {
|
||||
/*max-width: 1600px;*/
|
||||
margin: 0 auto;
|
||||
|
||||
@@ -52,8 +52,17 @@ function updateThemeAwareImage($img, theme=null) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages banner loading, display, and navigation.
|
||||
*
|
||||
* When automaticRotationEnabled is true, banners rotate on a timer and arrow
|
||||
* buttons are hidden. When false (the current default), a random initial
|
||||
* banner is shown and the user navigates manually via arrow buttons.
|
||||
*/
|
||||
class BannerRotation {
|
||||
constructor() {
|
||||
this.automaticRotationEnabled = false;
|
||||
|
||||
this.platinumIndex = 0;
|
||||
this.goldIndex = 0;
|
||||
this.platinumTimer = null;
|
||||
@@ -67,8 +76,18 @@ class BannerRotation {
|
||||
init() {
|
||||
let self = this;
|
||||
this.loadBanners(function() {
|
||||
self.startPlatinumRotation();
|
||||
self.startGoldRotation();
|
||||
self.randomizeInitialBanner('platinum');
|
||||
self.randomizeInitialBanner('gold');
|
||||
|
||||
if (self.automaticRotationEnabled) {
|
||||
self.startPlatinumRotation();
|
||||
self.startGoldRotation();
|
||||
// Hide arrows entirely when rotation is automatic
|
||||
$('.banner-arrow').hide();
|
||||
} else {
|
||||
self.hideArrowsIfSingle();
|
||||
self.bindArrowButtons();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -119,6 +138,23 @@ class BannerRotation {
|
||||
}, this.platinumInterval);
|
||||
}
|
||||
|
||||
randomizeInitialBanner(type) {
|
||||
const slideClass = type === 'platinum' ? '.platinum-banner-slide' : '.gold-banner-slide';
|
||||
const $slides = $(slideClass);
|
||||
const total = $slides.length;
|
||||
|
||||
if (total === 0) return;
|
||||
|
||||
const randomIndex = Math.floor(Math.random() * total);
|
||||
if (type === 'platinum') {
|
||||
this.platinumIndex = randomIndex;
|
||||
} else {
|
||||
this.goldIndex = randomIndex;
|
||||
}
|
||||
$slides.removeClass('active');
|
||||
$slides.eq(randomIndex).addClass('active');
|
||||
}
|
||||
|
||||
startGoldRotation() {
|
||||
const self = this;
|
||||
this.goldTimer = setInterval(() => {
|
||||
@@ -126,6 +162,30 @@ class BannerRotation {
|
||||
}, this.goldInterval);
|
||||
}
|
||||
|
||||
hideArrowsIfSingle() {
|
||||
if ($('.platinum-banner-slide').length <= 1) {
|
||||
$('#platinum-banners .banner-arrow').hide();
|
||||
}
|
||||
if ($('.gold-banner-slide').length <= 1) {
|
||||
$('#gold-banners .banner-arrow').hide();
|
||||
}
|
||||
}
|
||||
|
||||
bindArrowButtons() {
|
||||
let self = this;
|
||||
$('.banner-arrow').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const target = $(this).data('target');
|
||||
const direction = $(this).hasClass('banner-arrow-right') ? 'next' : 'prev';
|
||||
if (target === 'platinum') {
|
||||
self.rotatePlatinum(direction);
|
||||
} else {
|
||||
self.rotateGold(direction);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
rotatePlatinum(direction) {
|
||||
const $slides = $('.platinum-banner-slide');
|
||||
const total = $slides.length;
|
||||
@@ -145,9 +205,11 @@ class BannerRotation {
|
||||
// Add active class to new slide
|
||||
$slides.eq(this.platinumIndex).addClass('active');
|
||||
|
||||
// Reset timer
|
||||
clearInterval(this.platinumTimer);
|
||||
this.startPlatinumRotation();
|
||||
// Reset timer when in automatic rotation mode
|
||||
if (this.automaticRotationEnabled) {
|
||||
clearInterval(this.platinumTimer);
|
||||
this.startPlatinumRotation();
|
||||
}
|
||||
}
|
||||
|
||||
rotateGold(direction) {
|
||||
@@ -169,9 +231,11 @@ class BannerRotation {
|
||||
// Add active class to new group
|
||||
$groups.eq(this.goldIndex).addClass('active');
|
||||
|
||||
// Reset timer
|
||||
clearInterval(this.goldTimer);
|
||||
this.startGoldRotation();
|
||||
// Reset timer when in automatic rotation mode
|
||||
if (this.automaticRotationEnabled) {
|
||||
clearInterval(this.goldTimer);
|
||||
this.startGoldRotation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
<!-- Platinum Banners in Header -->
|
||||
<div id="platinum-banners" class="header-banner">
|
||||
<button class="banner-arrow banner-arrow-left" data-target="platinum" aria-label="Previous banner">‹</button>
|
||||
<button class="banner-arrow banner-arrow-right" data-target="platinum" aria-label="Next banner">›</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -147,6 +149,8 @@
|
||||
|
||||
<!-- Gold Banners -->
|
||||
<section id="gold-banners" class="gold-banners-section">
|
||||
<button class="banner-arrow banner-arrow-left" data-target="gold" aria-label="Previous banner">‹</button>
|
||||
<button class="banner-arrow banner-arrow-right" data-target="gold" aria-label="Next banner">›</button>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user