mirror of
https://codeberg.org/SafeTwitch/safetwitch.git
synced 2025-04-12 21:31:19 -05:00
fix following page & add suspended account handle
This commit is contained in:
parent
f274ba527d
commit
ad0f79b889
2 changed files with 49 additions and 20 deletions
|
@ -126,18 +126,16 @@ export async function followersStreaming(streamers: string[], cursor: number): P
|
|||
* @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<FollowingStreamer[]> {
|
||||
export async function getParsedFollowing(streamers: string[], cursor: number): Promise<FollowingStreamer[]> {
|
||||
// do not make request if no followers
|
||||
if (streamers.length == 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
let res: FollowingStreamer[] = []
|
||||
|
||||
const payloadData = streamers.slice(cursor, cursor + 35)
|
||||
const start = cursor * 35
|
||||
const end = (cursor + 1) * 35
|
||||
const payloadData = streamers.slice(start, end)
|
||||
|
||||
const payload = {
|
||||
streamers: payloadData
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
<script lang="ts">
|
||||
import { ref, inject } from 'vue'
|
||||
|
||||
import FollowButton from '@/components/FollowButton.vue'
|
||||
import LoadingScreen from '@/components/LoadingScreen.vue'
|
||||
import ErrorMessage from '@/components/ErrorMessage.vue'
|
||||
import VueTitle from '@/components/VueTitle.vue'
|
||||
|
||||
import { getFollows } from '@/settingsManager'
|
||||
import { postEndpoint, abbreviate, getParsedFollowing } from '@/mixins'
|
||||
import { abbreviate, getParsedFollowing } from '@/mixins'
|
||||
import type { FollowingStreamer } from '@/types'
|
||||
|
||||
export default {
|
||||
|
@ -15,10 +13,11 @@ export default {
|
|||
setup() {
|
||||
let data = ref<FollowingStreamer[]>([])
|
||||
let status = ref<'ok' | 'error'>()
|
||||
|
||||
let loadedImages = ref<Set<string>>(new Set())
|
||||
return {
|
||||
data,
|
||||
status,
|
||||
loadedImages,
|
||||
rootBackendUrl: inject('rootBackendUrl')
|
||||
}
|
||||
},
|
||||
|
@ -38,20 +37,29 @@ export default {
|
|||
this.data = []
|
||||
return
|
||||
}
|
||||
|
||||
let cursor = this.data.length / 35
|
||||
let maxCursor = follows.length / 35
|
||||
let cursor = Math.floor(this.data.length / 35)
|
||||
let maxCursor = Math.floor(follows.length / 35)
|
||||
if (cursor > maxCursor) return
|
||||
|
||||
let chunk = await getParsedFollowing(follows, cursor)
|
||||
this.data = [...this.data, ...chunk]
|
||||
// Filter out the users that are already in the list
|
||||
const newItems = chunk.filter(item => !this.data.some(existingItem => existingItem.login === item.login))
|
||||
this.data = [...this.data, ...newItems]
|
||||
},
|
||||
onImageLoad(login: string) {
|
||||
this.loadedImages.add(login)
|
||||
},
|
||||
onImageError(login: string) {
|
||||
// Remove from loadedImages if it was there
|
||||
this.loadedImages.delete(login)
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
const follows = getFollows()
|
||||
|
||||
window.onscroll = this.getNextFollowingStage
|
||||
this.data = await getParsedFollowing(follows, 0)
|
||||
const initialChunk = await getParsedFollowing(follows, 0)
|
||||
this.data = initialChunk
|
||||
},
|
||||
components: {
|
||||
LoadingScreen,
|
||||
|
@ -61,6 +69,7 @@ export default {
|
|||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<loading-screen v-if="!data && status != 'error'"></loading-screen>
|
||||
<error-message v-else-if="status == 'error'"></error-message>
|
||||
|
@ -81,12 +90,34 @@ export default {
|
|||
|
||||
<ul class="m-2 flex flex-wrap justify-center">
|
||||
<li v-for="streamer in data" :key="streamer.login" class="">
|
||||
<div class="inline-flex bg-overlay0 p-2.5 m-1 rounded-md w-[22rem]">
|
||||
<img :src="streamer.pfp" class="w-16 rounded-full" />
|
||||
<div class="justify-between flex flex-col ml-2 truncate text-ellipsis w-[8rem]">
|
||||
<h1 class="text-2xl font-bold"><router-link :to="streamer.login">{{ streamer.username }}</router-link></h1>
|
||||
<span>{{ abbreviate(streamer.followers) }} Followers</span>
|
||||
<div class="inline-flex bg-overlay0 p-2.5 m-1 rounded-md w-[24rem]">
|
||||
<div class="w-16 h-16 rounded-full overflow-hidden flex items-center justify-center bg-gray-200 relative">
|
||||
<svg class="w-full h-full text-gray-400" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M24 20.993V24H0v-2.996A14.977 14.977 0 0112.004 15c4.904 0 9.26 2.354 11.996 5.993zM16.002 8.999a4 4 0 11-8 0 4 4 0 018 0z" />
|
||||
</svg>
|
||||
<img
|
||||
v-if="streamer.username && streamer.followers > 0"
|
||||
:src="streamer.pfp"
|
||||
:class="{'opacity-0': !loadedImages.has(streamer.login), 'opacity-100': loadedImages.has(streamer.login)}"
|
||||
class="absolute inset-0 w-full h-full object-cover transition-opacity duration-300"
|
||||
@load="onImageLoad(streamer.login)"
|
||||
@error="onImageError(streamer.login)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="justify-between flex flex-col ml-2 truncate text-ellipsis w-[12rem]">
|
||||
<h1 class="text-2xl font-bold">
|
||||
<template v-if="streamer.username && streamer.followers > 0">
|
||||
<router-link :to="streamer.login">{{ streamer.username }}</router-link>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>{{ streamer.login }}</span>
|
||||
</template>
|
||||
</h1>
|
||||
<span v-if="streamer.followers > 0">{{ abbreviate(streamer.followers) }} Followers</span>
|
||||
<span v-else class="text-red">Account Suspended</span>
|
||||
</div>
|
||||
|
||||
<div class="m-auto">
|
||||
<follow-button :username="streamer.login"></follow-button>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue