Fixed mobile infinite scrolling

This commit is contained in:
WardPearce
2024-04-03 04:24:14 +13:00
parent 23452118de
commit 232ed38e00
12 changed files with 79 additions and 75 deletions
+5 -5
View File
@@ -12,7 +12,7 @@
"human-number": "^2.0.4",
"media-icons": "^0.10.0",
"sponsorblock-api": "^0.2.4",
"svelte-infinite-scroll": "^2.0.1",
"svelte-infinite-loading": "^1.3.8",
"svelte-persisted-store": "^0.9.1",
"vidstack": "^1.11.4"
},
@@ -7143,10 +7143,10 @@
"svelte": "^3.19.0 || ^4.0.0"
}
},
"node_modules/svelte-infinite-scroll": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/svelte-infinite-scroll/-/svelte-infinite-scroll-2.0.1.tgz",
"integrity": "sha512-goTHCfOHRDCs8C5MeSuIc6LlAQ8zVQ+M4Y3LyvrDjx5rqSSxSrdCuQwIyWYNcO6j6/mnqRro3QB64ClBzfn+Wg=="
"node_modules/svelte-infinite-loading": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/svelte-infinite-loading/-/svelte-infinite-loading-1.3.8.tgz",
"integrity": "sha512-hn4o848LKd2Q+M11hiMWnfFxM1GHKVDi92HPZ1FYvfed4bEeRZL+QvFAQzhy1SACq6Si0CAJcQFUZpIYmAEnpQ=="
},
"node_modules/svelte-persisted-store": {
"version": "0.9.1",
+1 -1
View File
@@ -39,7 +39,7 @@
"human-number": "^2.0.4",
"media-icons": "^0.10.0",
"sponsorblock-api": "^0.2.4",
"svelte-infinite-scroll": "^2.0.1",
"svelte-infinite-loading": "^1.3.8",
"svelte-persisted-store": "^0.9.1",
"vidstack": "^1.11.4"
}
+1 -1
View File
@@ -535,7 +535,7 @@
{/each}
</dialog>
<main class="responsive max">
<main class="responsive max root">
<slot />
</main>
+1 -1
View File
@@ -1,6 +1,6 @@
<script lang="ts">
import VideoList from '$lib/VideoList.svelte';
import { activePage } from '../store.js';
import { activePage } from '../store';
export let data;
@@ -5,7 +5,8 @@
import PlaylistThumbnail from '$lib/PlaylistThumbnail.svelte';
import Thumbnail from '$lib/Thumbnail.svelte';
import { cleanNumber } from '$lib/misc';
import { onDestroy, onMount } from 'svelte';
import { onMount } from 'svelte';
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
import { get } from 'svelte/store';
import { activePage, auth } from '../../../store';
@@ -19,22 +20,29 @@
let displayContent: ChannelContentPlaylists | ChannelContentVideos | undefined = undefined;
async function handleScroll() {
async function loadMore(event: InfiniteEvent) {
if (typeof displayContent === 'undefined') return;
const { scrollTop, clientHeight, scrollHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 5) {
const newContent = await getChannelContent(data.channel.authorId, {
type: tab,
continuation: displayContent.continuation
});
if ('videos' in newContent && 'videos' in displayContent) {
displayContent.videos = [...displayContent.videos, ...newContent.videos];
} else if ('playlists' in displayContent && 'playlists' in newContent) {
displayContent.playlists = [...displayContent.playlists, ...newContent.playlists];
const newContent = await getChannelContent(data.channel.authorId, {
type: tab,
continuation: displayContent.continuation
});
if ('videos' in newContent && 'videos' in displayContent) {
if (displayContent.continuation === newContent.continuation) {
event.detail.complete();
} else {
event.detail.loaded();
}
displayContent.continuation = newContent.continuation;
displayContent.videos = [...displayContent.videos, ...newContent.videos];
} else if ('playlists' in displayContent && 'playlists' in newContent) {
if (displayContent.continuation === newContent.continuation) {
event.detail.complete();
} else {
event.detail.loaded();
}
displayContent.playlists = [...displayContent.playlists, ...newContent.playlists];
}
displayContent.continuation = newContent.continuation;
}
async function changeTab(newTab: 'videos' | 'playlists' | 'streams' | 'shorts') {
@@ -49,12 +57,6 @@
if (get(auth)) {
isSubscribed = await amSubscribed(data.channel.authorId);
}
window.addEventListener('scroll', handleScroll);
});
onDestroy(() => {
window.removeEventListener('scroll', handleScroll);
});
async function toggleSubscribed() {
@@ -144,6 +146,8 @@
{/if}
</div>
</div>
<InfiniteLoading on:infinite={loadMore} />
{:else}
<PageLoading />
{/if}
+13 -12
View File
@@ -3,7 +3,8 @@
import type { VideoPlay } from '$lib/Api/model';
import VideoList from '$lib/VideoList.svelte';
import { error } from '@sveltejs/kit';
import { onDestroy, onMount } from 'svelte';
import { onMount } from 'svelte';
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
import { activePage } from '../../store';
activePage.set('history');
@@ -28,23 +29,21 @@
}
}
async function handleScroll() {
const { scrollTop, clientHeight, scrollHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 5) {
currentPage += 1;
await loadPageHistory();
async function loadMore(event: InfiniteEvent) {
const pastHistoryLen = Number(history.length);
await loadPageHistory();
if (pastHistoryLen === history.length) {
event.detail.complete();
} else {
event.detail.loaded();
}
}
onMount(async () => {
await loadPageHistory();
loaded = true;
window.addEventListener('scroll', handleScroll);
});
onDestroy(() => {
window.removeEventListener('scroll', handleScroll);
});
</script>
@@ -66,3 +65,5 @@
</div>
<VideoList videos={history} />
<InfiniteLoading on:infinite={loadMore} />
@@ -4,7 +4,7 @@
import VideoList from '$lib/VideoList.svelte';
import { cleanNumber } from '$lib/misc.js';
import { onMount } from 'svelte';
import { activePage } from '../../../store.js';
import { activePage } from '../../../store';
export let data;
@@ -4,7 +4,7 @@
import ChannelThumbnail from '$lib/ChannelThumbnail.svelte';
import PlaylistThumbnail from '$lib/PlaylistThumbnail.svelte';
import Thumbnail from '$lib/Thumbnail.svelte';
import { onDestroy, onMount } from 'svelte';
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
import { activePage } from '../../../store';
export let data;
@@ -20,24 +20,20 @@
document.location.href = $page.url.href;
}
async function handleScroll() {
const { scrollTop, clientHeight, scrollHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 5) {
currentPage += 1;
search = [
...search,
...(await getSearch(data.slug, { page: currentPage.toString(), type: data.searchType }))
];
async function loadMore(event: InfiniteEvent) {
currentPage++;
const newSearch = await getSearch(data.slug, {
page: currentPage.toString(),
type: data.searchType
});
if (newSearch.length === 0) {
event.detail.complete();
} else {
search = [...search, ...newSearch];
event.detail.loaded();
}
}
onMount(() => {
window.addEventListener('scroll', handleScroll);
});
onDestroy(() => {
window.removeEventListener('scroll', handleScroll);
});
</script>
<div class="space" style="margin-bottom: 1em;">
@@ -91,3 +87,5 @@
{/each}
</div>
</div>
<InfiniteLoading on:infinite={loadMore} />
@@ -1,32 +1,28 @@
<script lang="ts">
import { getFeed } from '$lib/Api/index.js';
import VideoList from '$lib/VideoList.svelte';
import { onDestroy, onMount } from 'svelte';
import { activePage } from '../../store.js';
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
import { activePage } from '../../store';
export let data;
let currentPage = 1;
let videos = [...data.feed.videos, ...data.feed.notifications];
$: videos = [...data.feed.videos, ...data.feed.notifications];
activePage.set('subscriptions');
async function handleScroll() {
const { scrollTop, clientHeight, scrollHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 5) {
currentPage += 1;
const feed = await getFeed(100, currentPage);
async function loadMore(event: InfiniteEvent) {
currentPage++;
const feed = await getFeed(100, currentPage);
if (feed.notifications.length === 0) {
event.detail.complete();
} else {
videos = [...videos, ...feed.notifications];
event.detail.loaded();
}
}
onMount(() => {
window.addEventListener('scroll', handleScroll);
});
onDestroy(() => {
window.removeEventListener('scroll', handleScroll);
});
</script>
<VideoList bind:videos />
<InfiniteLoading on:infinite={loadMore} />
@@ -1,6 +1,6 @@
<script lang="ts">
import VideoList from '$lib/VideoList.svelte';
import { activePage } from '../../store.js';
import { activePage } from '../../store';
export let data;
@@ -15,7 +15,7 @@
import { cleanNumber, numberWithCommas } from '$lib/misc.js';
import { onMount } from 'svelte';
import { get } from 'svelte/store';
import { activePage, auth, playerListenByDefault } from '../../../store.js';
import { activePage, auth, playerListenByDefault } from '../../../store';
export let data;
+5
View File
@@ -7,4 +7,9 @@
padding-left: .1em !important;
padding-right: .1em !important;
}
}
main.root {
max-height: 100vh;
overflow-y: scroll;
}