Skip to content

Commit 78599c8

Browse files
committed
Adds a page progress indicator and optional page looping when pagination enabled.
1 parent 24525f2 commit 78599c8

File tree

5 files changed

+277
-97
lines changed

5 files changed

+277
-97
lines changed

common/common.scss

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,34 @@ html.homepage-featured-topics {
240240
}
241241
}
242242
}
243+
244+
.page-progress-container {
245+
display: flex;
246+
justify-content: center;
247+
align-items: center;
248+
gap: var(--progress-bar-circle-size);
249+
margin-bottom: 1.2rem;
250+
251+
.page-progress-marker {
252+
width: var(--progress-bar-circle-size);
253+
height: var(--progress-bar-circle-size);
254+
border: var(--progress-bar-line-width) solid var(--primary-low-mid);
255+
background-color: var(--secondary);
256+
border-radius: 50%;
257+
258+
&.--previous-page {
259+
background-color: var(--primary-medium);
260+
border-color: var(--primary-medium);
261+
}
262+
263+
&.--current-page {
264+
background-color: var(--primary-medium);
265+
border-color: var(--primary-medium);
266+
box-shadow: 0 0 1px calc(var(--progress-bar-circle-size) / 2)
267+
var(--primary-low);
268+
}
269+
}
270+
}
243271
}
244272

245273
body:not(.staff) {

javascripts/discourse/components/featured-homepage-topics.gjs

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export default class FeaturedHomepageTopics extends Component {
2828
toggleTopics =
2929
this.keyValueStore.getItem("toggleTopicsState") === "true" || false;
3030

31-
@tracked currentFeaturedTopic = 0;
31+
@tracked currentPageIndex = 0;
3232
@tracked featuredTopicsAvailable = 0;
3333
@tracked actualTopicsDisplayed = 0;
3434

@@ -160,48 +160,82 @@ export default class FeaturedHomepageTopics extends Component {
160160

161161
this.featuredTopicsAvailable = filteredTopics.length;
162162

163+
const firstFeaturedTopicIndex = this.currentPageIndex * this.actualTopicsDisplayed;
164+
const lastFeaturedTopicIndex = firstFeaturedTopicIndex + this.actualTopicsDisplayed;
165+
163166
this.featuredTagTopics = filteredTopics.slice(
164-
this.currentFeaturedTopic,
165-
this.currentFeaturedTopic + this.actualTopicsDisplayed
167+
firstFeaturedTopicIndex,
168+
lastFeaturedTopicIndex
166169
);
167170
}
168171

169-
get showPageArrows() {
172+
get paginationEnabled() {
170173
return (
171174
settings.max_number_of_topics > settings.number_of_topics &&
172175
this.featuredTopicsAvailable > settings.number_of_topics
173176
);
174177
}
175178

179+
get numberOfPages() {
180+
return Math.ceil(this.featuredTopicsAvailable / this.actualTopicsDisplayed);
181+
}
182+
183+
get currentPageNumber() {
184+
return this.currentPageIndex + 1;
185+
}
186+
187+
176188
get showLeftArrow() {
177-
return this.currentFeaturedTopic > 0;
189+
return settings.pages_loop || this.currentPageIndex > 0;
178190
}
179191

180192
get showRightArrow() {
181193
return (
182-
this.currentFeaturedTopic <
183-
this.featuredTopicsAvailable - this.actualTopicsDisplayed
194+
settings.pages_loop ||
195+
this.currentPageIndex < this.numberOfPages - 1
184196
);
185197
}
186198

187199
@action
188200
pageLeft() {
189-
this.currentFeaturedTopic = Math.max(
190-
this.currentFeaturedTopic - this.actualTopicsDisplayed,
191-
0
192-
);
201+
if (this.currentPageIndex === 0) {
202+
if (settings.pages_loop) {
203+
this.currentPageIndex = this.numberOfPages - 1;
204+
}
205+
} else {
206+
this.currentPageIndex -= 1;
207+
}
208+
193209
this.getBannerTopics();
194210
}
195211

196212
@action
197213
pageRight() {
198-
this.currentFeaturedTopic = Math.min(
199-
this.currentFeaturedTopic + this.actualTopicsDisplayed,
200-
this.featuredTopicsAvailable - 1
201-
);
214+
if (this.currentPageIndex === this.numberOfPages - 1) {
215+
if (settings.pages_loop) {
216+
this.currentPageIndex = 0;
217+
}
218+
} else {
219+
this.currentPageIndex += 1;
220+
}
221+
202222
this.getBannerTopics();
203223
}
204224

225+
get pageProgressArray() {
226+
let pageProgressArray = [];
227+
for (let i = 0; i < this.numberOfPages; ++i) {
228+
if (i === this.currentPageIndex) {
229+
pageProgressArray.push("--current-page");
230+
} else if (i < this.currentPageIndex) {
231+
pageProgressArray.push("--previous-page");
232+
} else {
233+
pageProgressArray.push("");
234+
}
235+
}
236+
return pageProgressArray;
237+
}
238+
205239
<template>
206240
{{#if (and this.showFor this.showHere)}}
207241
<div
@@ -242,7 +276,7 @@ export default class FeaturedHomepageTopics extends Component {
242276
{{/if}}
243277

244278
<div class="featured-topics-controls">
245-
{{#if this.showPageArrows}}
279+
{{#if this.paginationEnabled}}
246280
<div class="page-button-container">
247281
{{#if this.showLeftArrow}}
248282
<DButton
@@ -278,7 +312,7 @@ export default class FeaturedHomepageTopics extends Component {
278312
</div>
279313
{{/each}}
280314
</div>
281-
{{#if this.showPageArrows}}
315+
{{#if this.paginationEnabled}}
282316
<div class="page-button-container">
283317
{{#if this.showRightArrow}}
284318
<DButton
@@ -290,6 +324,14 @@ export default class FeaturedHomepageTopics extends Component {
290324
</div>
291325
{{/if}}
292326
</div>
327+
328+
{{#if this.paginationEnabled}}
329+
<div class="page-progress-container">
330+
{{#each this.pageProgressArray as |pageProgressClass|}}
331+
<div class="page-progress-marker {{pageProgressClass}}"/>
332+
{{/each}}
333+
</div>
334+
{{/if}}
293335
</div>
294336
</div>
295337
{{/if}}

locales/en.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ en:
44
settings:
55
number_of_topics: Display up to 5 topics at max-width
66
max_number_of_topics: Maximum number of featured topics. If set higher than number_of_topics then arrows will be displayed for paging through the topics.
7+
pages_loop: If pagination is enabled (max_number_of_topics > number_of_topics), pages continue back to the first page after the last.
78
hide_featured_tag: When enabled the tag "featured tag" set above will be invisible to normal users when viewing topics.
89
show_on: top_menu refers to pages set in the <a href="%{base_path}/admin/site_settings/category/all_results?filter=top_menu">top menu site setting</a>
910
make_collapsible: Make the entire component collapsible

settings.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ max_number_of_topics:
1111
min: 0
1212
max: 25
1313

14+
pages_loop:
15+
default: false
16+
1417
hide_featured_tag:
1518
default: false
1619

0 commit comments

Comments
 (0)