Skip to content

Commit db9fa3a

Browse files
authored
Merge pull request #1077 from oraios/manual_banner_rotation
Dashboard: Replace automatic banner rotation with random initial display and manual rotation
2 parents 0c95433 + a35ba3a commit db9fa3a

File tree

3 files changed

+118
-19
lines changed

3 files changed

+118
-19
lines changed

src/serena/resources/dashboard/dashboard.css

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ body {
207207
top: 0;
208208
left: 0;
209209
order: 2;
210+
height: var(--header-height);
210211
max-height: var(--header-height);
211212
}
212213

@@ -311,17 +312,13 @@ body {
311312
}
312313

313314
.platinum-banner-slide {
314-
position: absolute;
315-
top: 0;
316-
left: 0;
315+
display: none;
317316
pointer-events: none;
318317
height: 100%;
319-
opacity: 0;
320-
transition: opacity 0.5s ease-in-out;
321318
}
322319

323320
.platinum-banner-slide.active {
324-
opacity: 1;
321+
display: block;
325322
pointer-events: auto;
326323
}
327324

@@ -351,19 +348,16 @@ body {
351348
.gold-banner {
352349
position: relative;
353350
width: 100%;
354-
height: 60px;
355351
overflow: hidden;
356352
}
357353

358354
.gold-banner-slide {
359-
position: absolute;
355+
display: none;
360356
pointer-events: none;
361-
opacity: 0;
362-
transition: opacity 0.5s ease-in-out;
363357
}
364358

365359
.gold-banner-slide.active {
366-
opacity: 1;
360+
display: block;
367361
pointer-events: auto;
368362
}
369363

@@ -372,6 +366,43 @@ body {
372366
object-fit: contain;
373367
}
374368

369+
/* Banner Arrow Navigation */
370+
.banner-arrow {
371+
position: absolute;
372+
top: 50%;
373+
transform: translateY(-50%);
374+
z-index: 10;
375+
background: rgba(128, 128, 128, 0.15);
376+
color: var(--text-muted);
377+
border: none;
378+
font-size: 18px;
379+
line-height: 1;
380+
width: 24px;
381+
height: 32px;
382+
display: flex;
383+
align-items: center;
384+
justify-content: center;
385+
cursor: pointer;
386+
border-radius: 4px;
387+
opacity: 0.3;
388+
transition: opacity 0.2s ease, background-color 0.2s ease, color 0.2s ease;
389+
padding: 0;
390+
}
391+
392+
.banner-arrow:hover {
393+
opacity: 0.8;
394+
background: rgba(128, 128, 128, 0.4);
395+
color: var(--text-primary);
396+
}
397+
398+
.banner-arrow-left {
399+
left: 0;
400+
}
401+
402+
.banner-arrow-right {
403+
right: 0;
404+
}
405+
375406
.page-view {
376407
/*max-width: 1600px;*/
377408
margin: 0 auto;

src/serena/resources/dashboard/dashboard.js

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,17 @@ function updateThemeAwareImage($img, theme=null) {
5252
}
5353
}
5454

55+
/**
56+
* Manages banner loading, display, and navigation.
57+
*
58+
* When automaticRotationEnabled is true, banners rotate on a timer and arrow
59+
* buttons are hidden. When false (the current default), a random initial
60+
* banner is shown and the user navigates manually via arrow buttons.
61+
*/
5562
class BannerRotation {
5663
constructor() {
64+
this.automaticRotationEnabled = false;
65+
5766
this.platinumIndex = 0;
5867
this.goldIndex = 0;
5968
this.platinumTimer = null;
@@ -67,8 +76,18 @@ class BannerRotation {
6776
init() {
6877
let self = this;
6978
this.loadBanners(function() {
70-
self.startPlatinumRotation();
71-
self.startGoldRotation();
79+
self.randomizeInitialBanner('platinum');
80+
self.randomizeInitialBanner('gold');
81+
82+
if (self.automaticRotationEnabled) {
83+
self.startPlatinumRotation();
84+
self.startGoldRotation();
85+
// Hide arrows entirely when rotation is automatic
86+
$('.banner-arrow').hide();
87+
} else {
88+
self.hideArrowsIfSingle();
89+
self.bindArrowButtons();
90+
}
7291
});
7392
}
7493

@@ -119,13 +138,54 @@ class BannerRotation {
119138
}, this.platinumInterval);
120139
}
121140

141+
randomizeInitialBanner(type) {
142+
const slideClass = type === 'platinum' ? '.platinum-banner-slide' : '.gold-banner-slide';
143+
const $slides = $(slideClass);
144+
const total = $slides.length;
145+
146+
if (total === 0) return;
147+
148+
const randomIndex = Math.floor(Math.random() * total);
149+
if (type === 'platinum') {
150+
this.platinumIndex = randomIndex;
151+
} else {
152+
this.goldIndex = randomIndex;
153+
}
154+
$slides.removeClass('active');
155+
$slides.eq(randomIndex).addClass('active');
156+
}
157+
122158
startGoldRotation() {
123159
const self = this;
124160
this.goldTimer = setInterval(() => {
125161
self.rotateGold('next');
126162
}, this.goldInterval);
127163
}
128164

165+
hideArrowsIfSingle() {
166+
if ($('.platinum-banner-slide').length <= 1) {
167+
$('#platinum-banners .banner-arrow').hide();
168+
}
169+
if ($('.gold-banner-slide').length <= 1) {
170+
$('#gold-banners .banner-arrow').hide();
171+
}
172+
}
173+
174+
bindArrowButtons() {
175+
let self = this;
176+
$('.banner-arrow').on('click', function(e) {
177+
e.preventDefault();
178+
e.stopPropagation();
179+
const target = $(this).data('target');
180+
const direction = $(this).hasClass('banner-arrow-right') ? 'next' : 'prev';
181+
if (target === 'platinum') {
182+
self.rotatePlatinum(direction);
183+
} else {
184+
self.rotateGold(direction);
185+
}
186+
});
187+
}
188+
129189
rotatePlatinum(direction) {
130190
const $slides = $('.platinum-banner-slide');
131191
const total = $slides.length;
@@ -145,9 +205,11 @@ class BannerRotation {
145205
// Add active class to new slide
146206
$slides.eq(this.platinumIndex).addClass('active');
147207

148-
// Reset timer
149-
clearInterval(this.platinumTimer);
150-
this.startPlatinumRotation();
208+
// Reset timer when in automatic rotation mode
209+
if (this.automaticRotationEnabled) {
210+
clearInterval(this.platinumTimer);
211+
this.startPlatinumRotation();
212+
}
151213
}
152214

153215
rotateGold(direction) {
@@ -169,9 +231,11 @@ class BannerRotation {
169231
// Add active class to new group
170232
$groups.eq(this.goldIndex).addClass('active');
171233

172-
// Reset timer
173-
clearInterval(this.goldTimer);
174-
this.startGoldRotation();
234+
// Reset timer when in automatic rotation mode
235+
if (this.automaticRotationEnabled) {
236+
clearInterval(this.goldTimer);
237+
this.startGoldRotation();
238+
}
175239
}
176240
}
177241

src/serena/resources/dashboard/index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
<!-- Platinum Banners in Header -->
2828
<div id="platinum-banners" class="header-banner">
29+
<button class="banner-arrow banner-arrow-left" data-target="platinum" aria-label="Previous banner">&#8249;</button>
30+
<button class="banner-arrow banner-arrow-right" data-target="platinum" aria-label="Next banner">&#8250;</button>
2931
</div>
3032
</div>
3133

@@ -147,6 +149,8 @@ <h2 class="collapsible-header" id="available-contexts-header">
147149

148150
<!-- Gold Banners -->
149151
<section id="gold-banners" class="gold-banners-section">
152+
<button class="banner-arrow banner-arrow-left" data-target="gold" aria-label="Previous banner">&#8249;</button>
153+
<button class="banner-arrow banner-arrow-right" data-target="gold" aria-label="Next banner">&#8250;</button>
150154
</section>
151155
</div>
152156
</div>

0 commit comments

Comments
 (0)