feat: add "Load more" button to paginator for better well-being

This commit is contained in:
TAKAHASHI Shuuji 2025-08-14 00:25:24 +09:00
parent 78fd25ac10
commit c23e2cb8e2
3 changed files with 28 additions and 2 deletions

View file

@ -45,7 +45,15 @@ defineSlots<{
const { t } = useI18n() const { t } = useI18n()
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
const { items, prevItems, update, state, endAnchor, error } = usePaginator(paginator, toRef(() => stream), eventType, preprocess) const {
items,
prevItems,
update,
state,
endAnchor,
error,
canLoadMore,
} = usePaginator(paginator, toRef(() => stream), eventType, preprocess)
nuxtApp.hook('elk-logo:click', () => { nuxtApp.hook('elk-logo:click', () => {
update() update()
@ -117,5 +125,18 @@ defineExpose({ createEntry, removeEntry, updateEntry })
<div v-else-if="state === 'error'" p5 text-secondary> <div v-else-if="state === 'error'" p5 text-secondary>
{{ t('common.error') }}: {{ error }} {{ t('common.error') }}: {{ error }}
</div> </div>
<!-- TODO: debug -->
<div flex="~ center col">
<button
flex btn-solid mt-1
:title="$t('settings.notifications.push_notifications.warning.enable_close')"
@click="canLoadMore = true"
>
Load more
</button>
<p m-y-4>
debug: canLoadMore="{{ canLoadMore }}" / state="{{ state }}"
</p>
</div>
</div> </div>
</template> </template>

View file

@ -18,6 +18,7 @@ export function usePaginator<T, P, U = T>(
const items = ref<U[]>([]) const items = ref<U[]>([])
const nextItems = ref<U[]>([]) const nextItems = ref<U[]>([])
const prevItems = ref<T[]>([]) const prevItems = ref<T[]>([])
const canLoadMore = ref<boolean>(false)
const endAnchor = ref<HTMLDivElement>() const endAnchor = ref<HTMLDivElement>()
const bound = useElementBounding(endAnchor) const bound = useElementBounding(endAnchor)
@ -70,7 +71,7 @@ export function usePaginator<T, P, U = T>(
}, { immediate: true }) }, { immediate: true })
async function loadNext() { async function loadNext() {
if (state.value !== 'idle') if (state.value !== 'idle' || !canLoadMore.value)
return return
state.value = 'loading' state.value = 'loading'
@ -99,6 +100,7 @@ export function usePaginator<T, P, U = T>(
error.value = e error.value = e
state.value = 'error' state.value = 'error'
} }
canLoadMore.value = false
await nextTick() await nextTick()
bound.update() bound.update()
@ -123,6 +125,7 @@ export function usePaginator<T, P, U = T>(
&& state.value === 'idle' && state.value === 'idle'
// No new content is loaded when the keepAlive page enters the background // No new content is loaded when the keepAlive page enters the background
&& deactivated.value === false && deactivated.value === false
&& canLoadMore.value
) { ) {
loadNext() loadNext()
} }
@ -137,5 +140,6 @@ export function usePaginator<T, P, U = T>(
state, state,
error, error,
endAnchor, endAnchor,
canLoadMore,
} }
} }

View file

@ -720,6 +720,7 @@
"year_past": "0 years ago|last year|{n} years ago" "year_past": "0 years ago|last year|{n} years ago"
}, },
"timeline": { "timeline": {
"load_more": "Load more posts",
"no_posts": "No posts here!", "no_posts": "No posts here!",
"show_new_items": "Show {v} new items|Show {v} new item|Show {v} new items", "show_new_items": "Show {v} new items|Show {v} new item|Show {v} new items",
"view_older_posts": "Older posts from other instances may not be displayed." "view_older_posts": "Older posts from other instances may not be displayed."