diff --git a/src/mixins.ts b/src/mixins.ts index 7c2101c..8039e48 100644 --- a/src/mixins.ts +++ b/src/mixins.ts @@ -1,4 +1,4 @@ -import type { StreamerData } from '@/types' +import type { FollowingStreamer } from '@/types' const language = localStorage.getItem('language') || 'en-us' const https = import.meta.env.SAFETWITCH_HTTPS.slice() === 'true' @@ -108,15 +108,42 @@ export async function followersStreaming(streamers: string[], cursor: number): P const payloadData = streamers.slice(cursor, cursor + 35) - const payload = { - streamers: payloadData - } - - await postEndpoint('api/users/isLive/bulk', payload) - .then((data: string[]) => { - res = [...res, ...data] - }) + const payload = { + streamers: payloadData + } + await postEndpoint('api/users/isLive/bulk', payload) + .then((data: string[]) => { + res = [...res, ...data] + }) return res } + +/** + * Returns an array of FollowingStreamers + * @param streamers the array of streamers + * @param cursor which 35 streamer chunk to fetch + * @returns the streamers in that list that are online + */ +export async function getParsedFollowing(streamers: string[], cursor: number): Promise { + // do not make request if no followers + if (streamers.length == 0) { + return [] + } + + let res: FollowingStreamer[] = [] + + const payloadData = streamers.slice(cursor, cursor + 35) + + const payload = { + streamers: payloadData + } + + await postEndpoint('api/users/followingStreamer/bulk', payload) + .then((data: FollowingStreamer[]) => { + res = [...res, ...data] + }) + + return res +} \ No newline at end of file diff --git a/src/types/Streamer.ts b/src/types/Streamer.ts index f77fd0a..6c58dfa 100644 --- a/src/types/Streamer.ts +++ b/src/types/Streamer.ts @@ -28,3 +28,10 @@ export interface StreamerData { colorHex: string id: number } + +export interface FollowingStreamer { + username: string + login: string + pfp: string + followers: number +} diff --git a/src/views/FollowingView.vue b/src/views/FollowingView.vue index 687a167..3633c5f 100644 --- a/src/views/FollowingView.vue +++ b/src/views/FollowingView.vue @@ -6,13 +6,13 @@ import LoadingScreen from '@/components/LoadingScreen.vue' import ErrorMessage from '@/components/ErrorMessage.vue' import { getFollows } from '@/settingsManager' -import { postEndpoint, abbreviate } from '@/mixins' -import type { StreamerData } from '@/types' +import { postEndpoint, abbreviate, getParsedFollowing } from '@/mixins' +import type { FollowingStreamer } from '@/types' export default { inject: ['rootBackendUrl'], setup() { - let data = ref([]) + let data = ref([]) let status = ref<'ok' | 'error'>() return { @@ -22,39 +22,35 @@ export default { } }, methods: { - abbreviate + abbreviate, + async getNextFollowingStage() { + let bottomOfWindow = + document.documentElement.scrollTop + window.innerHeight === + document.documentElement.offsetHeight + + if (!bottomOfWindow) return; + + const follows = getFollows() + + // do not make request if no followers + if (follows.length == 0) { + this.data = [] + return + } + + let cursor = this.data.length / 35 + let maxCursor = follows.length / 35 + if (cursor > maxCursor) return; + + let chunk = await getParsedFollowing(follows, cursor) + this.data = [...this.data, ...chunk] + } }, async mounted() { const follows = getFollows() - // do not make request if no followers - if (follows.length == 0) { - this.data = [] - return - } - - // split follows into 35 person segments - // the endpoint can only handle 35 at a time - let payloads: string[][] = [] - for (let i = 0; i < follows.length; i += 35) { - const chunk = follows.slice(i, i + 35) - payloads.push(chunk) - } - - - for (let i = 0; i < payloads.length; i++) { - const payload = { - streamers: payloads[i] - } - - await postEndpoint('api/users/followingStreamer/bulk', payload) - .catch(() => { - this.status = 'error' - }) - .then((data: StreamerData[]) => { - this.data = [...this.data, ...data] - }) - } + window.onscroll = this.getNextFollowingStage + this.data = await getParsedFollowing(follows, 0); }, components: { LoadingScreen,