feat: replace infinite scroll with load more button for footer access

This commit is contained in:
2026-02-04 11:45:30 +01:00
parent de0f3628ce
commit 2ffbfdf3e1
4 changed files with 24 additions and 27 deletions

View File

@@ -14,7 +14,6 @@ class PageHome extends HTMLElement {
this.error = null this.error = null
this.page = 1 this.page = 1
this.hasMore = true this.hasMore = true
this.observer = null
// Filter state // Filter state
this.query = '' this.query = ''
@@ -44,7 +43,6 @@ class PageHome extends HTMLElement {
disconnectedCallback() { disconnectedCallback() {
if (this.unsubscribe) this.unsubscribe() if (this.unsubscribe) this.unsubscribe()
if (this.observer) this.observer.disconnect()
window.removeEventListener('hashchange', this.handleHashChange.bind(this)) window.removeEventListener('hashchange', this.handleHashChange.bind(this))
} }
@@ -226,7 +224,7 @@ class PageHome extends HTMLElement {
this.loading = false this.loading = false
this.loadingMore = false this.loadingMore = false
this.updateListingsSection() this.updateListingsSection()
this.setupInfiniteScroll() this.setupLoadMoreButton()
} catch (err) { } catch (err) {
console.error('Failed to load listings:', err) console.error('Failed to load listings:', err)
this.error = err.message this.error = err.message
@@ -255,27 +253,19 @@ class PageHome extends HTMLElement {
.sort((a, b) => a._distance - b._distance) .sort((a, b) => a._distance - b._distance)
} }
setupInfiniteScroll() { setupLoadMoreButton() {
if (this.observer) this.observer.disconnect() const btn = this.querySelector('#load-more-btn')
btn?.addEventListener('click', () => {
const sentinel = this.querySelector('#scroll-sentinel') this.page++
if (!sentinel || !this.hasMore) return this.loadListings()
})
this.observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && !this.loadingMore && this.hasMore) {
this.page++
this.loadListings()
}
}, { rootMargin: '100px' })
this.observer.observe(sentinel)
} }
updateListingsSection() { updateListingsSection() {
const listingsContainer = this.querySelector('#listings-container') const listingsContainer = this.querySelector('#listings-container')
if (listingsContainer) { if (listingsContainer) {
listingsContainer.innerHTML = this.renderListings() listingsContainer.innerHTML = this.renderListings()
this.setupInfiniteScroll() this.setupLoadMoreButton()
} }
const titleEl = this.querySelector('.listings-title') const titleEl = this.querySelector('.listings-title')
@@ -413,16 +403,20 @@ class PageHome extends HTMLElement {
` `
}).join('') }).join('')
const sentinelHtml = this.hasMore ? ` const loadMoreHtml = this.hasMore ? `
<div id="scroll-sentinel" class="scroll-sentinel"> <div class="load-more-container">
${this.loadingMore ? ` ${this.loadingMore ? `
<div class="spinner"></div> <div class="spinner"></div>
<p>${t('common.loading')}</p> <p>${t('common.loading')}</p>
` : ''} ` : `
<button id="load-more-btn" class="btn btn-outline">
${t('home.loadMore')}
</button>
`}
</div> </div>
` : '' ` : ''
return listingsHtml + sentinelHtml return listingsHtml + loadMoreHtml
} }
escapeHtml(text) { escapeHtml(text) {
@@ -583,7 +577,7 @@ style.textContent = /* css */`
to { transform: rotate(360deg); } to { transform: rotate(360deg); }
} }
page-home .scroll-sentinel { page-home .load-more-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@@ -593,7 +587,7 @@ style.textContent = /* css */`
grid-column: 1 / -1; grid-column: 1 / -1;
} }
page-home .scroll-sentinel .spinner { page-home .load-more-container .spinner {
width: 30px; width: 30px;
height: 30px; height: 30px;
margin-bottom: var(--space-sm); margin-bottom: var(--space-sm);

View File

@@ -24,7 +24,8 @@
"placeholderLocation": "Standort", "placeholderLocation": "Standort",
"addFavorite": "Zu Favoriten hinzufügen", "addFavorite": "Zu Favoriten hinzufügen",
"removeFavorite": "Aus Favoriten entfernen", "removeFavorite": "Aus Favoriten entfernen",
"noListings": "Keine Anzeigen gefunden" "noListings": "Keine Anzeigen gefunden",
"loadMore": "Mehr laden"
}, },
"common": { "common": {
"loading": "Laden...", "loading": "Laden...",

View File

@@ -24,7 +24,8 @@
"placeholderLocation": "Location", "placeholderLocation": "Location",
"addFavorite": "Add to favorites", "addFavorite": "Add to favorites",
"removeFavorite": "Remove from favorites", "removeFavorite": "Remove from favorites",
"noListings": "No listings found" "noListings": "No listings found",
"loadMore": "Load more"
}, },
"common": { "common": {
"loading": "Loading...", "loading": "Loading...",

View File

@@ -24,7 +24,8 @@
"placeholderLocation": "Emplacement", "placeholderLocation": "Emplacement",
"addFavorite": "Ajouter aux favoris", "addFavorite": "Ajouter aux favoris",
"removeFavorite": "Retirer des favoris", "removeFavorite": "Retirer des favoris",
"noListings": "Aucune annonce trouvée" "noListings": "Aucune annonce trouvée",
"loadMore": "Charger plus"
}, },
"common": { "common": {
"loading": "Chargement...", "loading": "Chargement...",