Skip to content

Commit

Permalink
add loading state
Browse files Browse the repository at this point in the history
  • Loading branch information
snazzyfox committed Nov 16, 2023
1 parent e0b4f2a commit 629ce9f
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
15 changes: 12 additions & 3 deletions src/api/twitch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ export function setTwitchAuth(clientId: string, bearerToken: string) {
}

/** For twitch endpoints that returns paginated data, a wrapper function that repeats the request while fetching more data until exhausted. */
async function getPaginatedData<T>(initialResponse: KyResponse): Promise<T[]> {
async function getPaginatedData<T>(
initialResponse: KyResponse,
callback?: (data: T[]) => void
): Promise<T[]> {
const responseJson = await initialResponse.json<TwitchResponse<T[]>>();
const result = responseJson.data;
const url = new URL(initialResponse.url);
Expand All @@ -102,6 +105,9 @@ async function getPaginatedData<T>(initialResponse: KyResponse): Promise<T[]> {
>();
result.push(...response.data);
cursor = response.pagination?.cursor;
if (callback) {
callback([...result]);
}
}
return result;
}
Expand All @@ -119,10 +125,13 @@ export async function getFollows(params: { from_id?: string; to_id?: string }) {
return await getPaginatedData<TwitchUser>(response);
}

export async function getClips(params: ClipID & { started_at?: string; ended_at?: string }) {
export async function getClips(
params: ClipID & { started_at?: string; ended_at?: string },
paginationCallback?: (data: TwitchClip[]) => void
) {
const searchParams = flattenParams({ ...params, first: 100 });
const response = await twitchApi.get('clips', { searchParams });
return await getPaginatedData<TwitchClip>(response);
return await getPaginatedData<TwitchClip>(response, paginationCallback);
}

export async function getGames(params: { id?: string[]; name?: string[] }) {
Expand Down
14 changes: 9 additions & 5 deletions src/pages/ClipSearch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
hint="YYYY-MM-DD format, UTC timezone." mask="####-##-##" clearable />
<q-input class="col-4" v-model="options.dateRange.to" label="Clip created before"
hint="YYYY-MM-DD format, UTC timezone." mask="####-##-##" clearable />
<q-btn class="q-my-lg" color="primary" :icon="ionDownloadOutline" :loading="loading"
@click="getClipsData">Download Clip Data</q-btn>
<q-btn class="q-my-lg" color="primary" :icon="ionDownloadOutline" :loading="loading" @click="getClipsData">
Download Clip Data
<template #loading><q-spinner-tail class="on-left" /> {{ loadingAmount }} clips loaded</template>
</q-btn>
</q-form>

<q-form class="q-gutter-sm q-mb-sm" v-if="clipData.length">
Expand Down Expand Up @@ -77,7 +79,7 @@
</div>
<q-pagination class="flex flex-center" v-model="currentPage" :max="Math.ceil(filteredClipData.length / PAGE_SIZE)"
boundary-numbers direction-links />
boundary-numbers direction-links max-pages="10" />
</div>
</q-page>
</template>
Expand Down Expand Up @@ -109,6 +111,7 @@ const options = useStorage('clipsearch.config', {
} as ClipSearchOptions);
const clipData = ref<TwitchClip[]>([]);
const loading = ref(false);
const loadingAmount = ref(0);
const clipSearch = ref({
author: {
search: '',
Expand All @@ -126,15 +129,16 @@ const games = ref<{ [key: string]: TwitchGame }>({});
async function getClipsData() {
try {
loading.value = true;
loadingAmount.value = 0;
clipData.value = [];
const dates = {
started_at: options.value.dateRange.from && new Date(options.value.dateRange.from).toISOString(),
ended_at: options.value.dateRange.to && new Date(options.value.dateRange.to).toISOString(),
}
if (options.value.channelId) {
clipData.value = await getClips({ broadcaster_id: options.value.channelId, ...dates })
clipData.value = await getClips({ broadcaster_id: options.value.channelId, ...dates }, (data) => loadingAmount.value = data.length)
} else if (options.value.gameId) {
clipData.value = await getClips({ game_id: options.value.gameId, ...dates })
clipData.value = await getClips({ game_id: options.value.gameId, ...dates }, (data) => loadingAmount.value = data.length)
} else {
quasar.notify({
message: 'You must provide at least a channel name or a game name to search. I cannot pull the list of all clips across all of twitch.',
Expand Down

0 comments on commit 629ce9f

Please sign in to comment.