Clean this mess
This commit is contained in:
parent
cf71bf6fa7
commit
b7464e84aa
@ -1,10 +1,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ref, type Ref, inject } from 'vue'
|
import { ref, inject } from 'vue'
|
||||||
|
|
||||||
import BadgeVue from './ChatBadge.vue'
|
import BadgeVue from './ChatBadge.vue'
|
||||||
import { getBadges } from '@/assets/badges'
|
import { getBadges } from '@/assets/badges'
|
||||||
import { parseMessage } from '@/assets/messageParser'
|
import { parseMessage } from '@/assets/messageParser'
|
||||||
|
|
||||||
import type { Badge, ParsedMessage } from '@/assets/types'
|
import type { Badge, ParsedMessage } from '@/assets/types'
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
isLive: {
|
isLive: {
|
||||||
@ -18,23 +21,20 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async setup(props) {
|
async setup(props) {
|
||||||
let messages: Ref<ParsedMessage[]> = ref([])
|
let messages = ref<ParsedMessage[]>([])
|
||||||
const protocol = inject('protocol')
|
let badges = ref<Badge[]>([])
|
||||||
const wsProtocol = protocol === 'https://' ? 'wss://' : 'ws://'
|
let wsLink = inject('wsLink') as string
|
||||||
const badgesFetch = await fetch(`${protocol}${import.meta.env.SAFETWITCH_BACKEND_DOMAIN}/api/badges?channelName=${props.channelName}`)
|
|
||||||
let badges: Badge[] = (await badgesFetch.json()).data
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ws: new WebSocket(`${wsProtocol}${import.meta.env.SAFETWITCH_BACKEND_DOMAIN}`),
|
ws: new WebSocket(wsLink),
|
||||||
messages,
|
messages,
|
||||||
badges,
|
badges,
|
||||||
props,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
const chatList = this.$refs.chatList as Element
|
const chatList = this.$refs.chatList as Element
|
||||||
const chatStatusMessage = this.$refs.initConnectingStatus as Element
|
const chatStatusMessage = this.$refs.initConnectingStatus as Element
|
||||||
|
|
||||||
this.ws.onmessage = (message) => {
|
this.ws.onmessage = (message) => {
|
||||||
if (message.data == 'OK') {
|
if (message.data == 'OK') {
|
||||||
chatStatusMessage.textContent = this.$t("chat.connected", {username: this.channelName})
|
chatStatusMessage.textContent = this.$t("chat.connected", {username: this.channelName})
|
||||||
@ -46,7 +46,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.ws.onopen = () => {
|
this.ws.onopen = () => {
|
||||||
this.ws.send('JOIN ' + this.props.channelName?.toLowerCase())
|
this.ws.send('JOIN ' + this.$props.channelName?.toLowerCase())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -13,11 +13,11 @@ const app = createApp(App).use(i18n)
|
|||||||
const https = (import.meta.env.SAFETWITCH_HTTPS.slice() === "true")
|
const https = (import.meta.env.SAFETWITCH_HTTPS.slice() === "true")
|
||||||
|
|
||||||
const protocol = https ? 'https://' : 'http://'
|
const protocol = https ? 'https://' : 'http://'
|
||||||
|
const wsProtocol = https ? 'wss://' : 'ws://'
|
||||||
app.provide('protocol', protocol)
|
app.provide('protocol', protocol)
|
||||||
app.provide('rootUrl', `${protocol}${import.meta.env.SAFETWITCH_INSTANCE_DOMAIN}`)
|
app.provide('rootUrl', `${protocol}${import.meta.env.SAFETWITCH_INSTANCE_DOMAIN}`)
|
||||||
app.provide('rootBackendUrl', `${protocol}${import.meta.env.SAFETWITCH_BACKEND_DOMAIN}`)
|
app.provide('rootBackendUrl', `${protocol}${import.meta.env.SAFETWITCH_BACKEND_DOMAIN}`)
|
||||||
|
app.provide('wsLink', `${wsProtocol}${import.meta.env.SAFETWITCH_BACKEND_DOMAIN}`)
|
||||||
|
|
||||||
|
|
||||||
import { OhVueIcon, addIcons } from 'oh-vue-icons'
|
import { OhVueIcon, addIcons } from 'oh-vue-icons'
|
||||||
import {
|
import {
|
||||||
|
@ -16,7 +16,7 @@ export function abbreviate(text: number) {
|
|||||||
|
|
||||||
const https = (import.meta.env.SAFETWITCH_HTTPS.slice() === "true")
|
const https = (import.meta.env.SAFETWITCH_HTTPS.slice() === "true")
|
||||||
const protocol = https ? 'https://' : 'http://'
|
const protocol = https ? 'https://' : 'http://'
|
||||||
const rootBackendUrl = `${protocol}${import.meta.env.SAFETWITCH_BACKEND_DOMAIN}`
|
const rootBackendUrl = `${protocol}${import.meta.env.SAFETWITCH_BACKEND_DOMAIN}/`
|
||||||
|
|
||||||
export async function getEndpoint(endpoint: string) {
|
export async function getEndpoint(endpoint: string) {
|
||||||
let data
|
let data
|
||||||
@ -25,15 +25,16 @@ export async function getEndpoint(endpoint: string) {
|
|||||||
const res = await fetch(rootBackendUrl + endpoint)
|
const res = await fetch(rootBackendUrl + endpoint)
|
||||||
const rawData = await res.json()
|
const rawData = await res.json()
|
||||||
|
|
||||||
if (rawData.status === 'ok') {
|
if (!res.ok) {
|
||||||
data = rawData.data
|
throw res
|
||||||
} else {
|
}
|
||||||
data = { status: 'error' }
|
if (rawData.status !== 'ok') {
|
||||||
|
throw rawData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data = rawData.data
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
throw error
|
||||||
data = { status: 'error' }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export type Tag = string
|
export type Tag = string
|
||||||
|
|
||||||
export interface Category {
|
export interface CategoryPreview {
|
||||||
name: string
|
name: string
|
||||||
displayName: string
|
displayName: string
|
||||||
viewers: number
|
viewers: number
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import type { StreamData, StreamerData } from "./"
|
import type { StreamData, StreamerData } from "./"
|
||||||
import type { Category } from "./"
|
import type { CategoryPreview } from "./"
|
||||||
|
|
||||||
export interface SearchResult {
|
export interface SearchResult {
|
||||||
channels: StreamerData[]
|
channels: StreamerData[]
|
||||||
categories: Category[]
|
categories: CategoryPreview[]
|
||||||
relatedChannels: StreamData[]
|
relatedChannels: StreamerData[]
|
||||||
channelsWithTag: StreamData[]
|
channelsWithTag: StreamerData[]
|
||||||
}
|
}
|
@ -16,6 +16,7 @@ export interface StreamData {
|
|||||||
|
|
||||||
export interface StreamerData {
|
export interface StreamerData {
|
||||||
username: string
|
username: string
|
||||||
|
login: string
|
||||||
followers: number
|
followers: number
|
||||||
isLive: boolean
|
isLive: boolean
|
||||||
about: string
|
about: string
|
||||||
|
@ -5,4 +5,3 @@ export * from './Chat'
|
|||||||
export * from './Category'
|
export * from './Category'
|
||||||
export * from './CategoryData'
|
export * from './CategoryData'
|
||||||
export * from './ApiResponse'
|
export * from './ApiResponse'
|
||||||
|
|
||||||
|
@ -1,37 +1,33 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ref, type Ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
import StreamPreviewVue from '@/components/StreamPreview.vue'
|
import StreamPreviewVue from '@/components/StreamPreview.vue'
|
||||||
import ErrorMessage from '@/components/ErrorMessage.vue'
|
import ErrorMessage from '@/components/ErrorMessage.vue'
|
||||||
import LoadingScreen from '@/components/LoadingScreen.vue'
|
import LoadingScreen from '@/components/LoadingScreen.vue'
|
||||||
|
|
||||||
|
import type { CategoryData } from '@/types'
|
||||||
|
import { getEndpoint, abbreviate } from '@/mixins'
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['protocol'],
|
inject: ['protocol'],
|
||||||
async setup() {
|
async setup() {
|
||||||
const route = useRoute()
|
let data = ref<CategoryData>()
|
||||||
const data: Ref<any | undefined> = ref()
|
let status = ref<"ok" | "error">()
|
||||||
const game: string = route.params.game.toString()
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data,
|
data,
|
||||||
game
|
status
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
try {
|
await getEndpoint("api/discover/" + this.$route.params.game)
|
||||||
const res = await fetch(
|
.catch(() => {
|
||||||
`${this.protocol}${import.meta.env.SAFETWITCH_BACKEND_DOMAIN}/api/discover/${this.game}`
|
this.status = "error"
|
||||||
)
|
})
|
||||||
const rawData = await res.json()
|
.then((data: CategoryData) => {
|
||||||
if (rawData.status === "ok") {
|
this.data = data
|
||||||
this.data = rawData.data
|
})
|
||||||
} else {
|
|
||||||
this.data = { status: 'error' }
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
this.data = { status: 'error' }
|
|
||||||
console.error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getMoreStreams()
|
this.getMoreStreams()
|
||||||
},
|
},
|
||||||
@ -41,31 +37,26 @@ export default {
|
|||||||
let bottomOfWindow =
|
let bottomOfWindow =
|
||||||
document.documentElement.scrollTop + window.innerHeight ===
|
document.documentElement.scrollTop + window.innerHeight ===
|
||||||
document.documentElement.offsetHeight
|
document.documentElement.offsetHeight
|
||||||
const streams = this.data.streams
|
const streams = this.data!.streams
|
||||||
|
|
||||||
if (bottomOfWindow && streams) {
|
if (bottomOfWindow && streams) {
|
||||||
|
// get cursor of the last stream rendered
|
||||||
const cursor = streams[streams.length - 1].cursor
|
const cursor = streams[streams.length - 1].cursor
|
||||||
if (!cursor) return
|
if (!cursor) return
|
||||||
const res = await fetch(
|
|
||||||
`${this.protocol}${import.meta.env.SAFETWITCH_BACKEND_DOMAIN}/api/discover/${this.game}/?cursor=${cursor}`
|
|
||||||
)
|
|
||||||
if (!res.ok) {
|
|
||||||
throw new Error('Failed to fetch data')
|
|
||||||
}
|
|
||||||
const resData = await res.json()
|
|
||||||
|
|
||||||
for (let stream of resData.data.streams) {
|
// get rest of streams from api
|
||||||
this.data.streams.push(stream)
|
const resData = await getEndpoint(`api/discover/${this.$route.params.game}/?cursor=${cursor}`)
|
||||||
|
.catch((err) => {
|
||||||
|
throw err
|
||||||
|
})
|
||||||
|
|
||||||
|
for (let stream of resData.streams) {
|
||||||
|
this.data!.streams.push(stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
abbreviate(text: number) {
|
abbreviate,
|
||||||
return Intl.NumberFormat('en-US', {
|
|
||||||
//@ts-ignore
|
|
||||||
notation: 'compact',
|
|
||||||
maximumFractionDigits: 1
|
|
||||||
}).format(text)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
StreamPreviewVue,
|
StreamPreviewVue,
|
||||||
@ -76,10 +67,10 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<loading-screen v-if="!data"></loading-screen>
|
<loading-screen v-if="!data && status != 'error'"></loading-screen>
|
||||||
<error-message v-else-if="data.status === 'error' || !data"></error-message>
|
<error-message v-else-if="status == 'error'"></error-message>
|
||||||
|
|
||||||
<div v-else class="flex flex-col max-w-5xl mx-auto">
|
<div v-else-if="data" class="flex flex-col max-w-5xl mx-auto">
|
||||||
<div class="flex p-3 flex-col">
|
<div class="flex p-3 flex-col">
|
||||||
<div class="inline-flex space-x-4">
|
<div class="inline-flex space-x-4">
|
||||||
<img :src="data.cover" class="self-start rounded-md" />
|
<img :src="data.cover" class="self-start rounded-md" />
|
||||||
@ -127,7 +118,7 @@ export default {
|
|||||||
|
|
||||||
<div class="max-w-[58rem] mx-auto">
|
<div class="max-w-[58rem] mx-auto">
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="stream in data.streams" :key="stream" class="inline-flex m-2 hover:scale-105 transition-transform">
|
<li v-for="stream in data.streams" class="inline-flex m-2 hover:scale-105 transition-transform">
|
||||||
<StreamPreviewVue :stream="stream"></StreamPreviewVue>
|
<StreamPreviewVue :stream="stream"></StreamPreviewVue>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ref, type Ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
import StreamPreviewVue from '@/components/StreamPreview.vue'
|
import StreamPreviewVue from '@/components/StreamPreview.vue'
|
||||||
import ErrorMessage from '@/components/ErrorMessage.vue'
|
import ErrorMessage from '@/components/ErrorMessage.vue'
|
||||||
import LoadingScreen from '@/components/LoadingScreen.vue'
|
import LoadingScreen from '@/components/LoadingScreen.vue'
|
||||||
import CategoryPreview from '@/components/CategoryPreview.vue'
|
import CategoryPreview from '@/components/CategoryPreview.vue'
|
||||||
|
|
||||||
|
import { getEndpoint } from '@/mixins'
|
||||||
|
import type { CategoryPreview as CategoryPreviewInterface } from '@/types'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['protocol'],
|
inject: ['protocol'],
|
||||||
async setup() {
|
async setup() {
|
||||||
let data: Ref<any | undefined> = ref()
|
let data = ref<CategoryPreviewInterface[]>()
|
||||||
|
let status = ref<"ok" | "error">()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data,
|
data,
|
||||||
|
status,
|
||||||
filterTags: '',
|
filterTags: '',
|
||||||
following: ref([])
|
following: ref([])
|
||||||
}
|
}
|
||||||
@ -75,19 +81,14 @@ export default {
|
|||||||
this.following = []
|
this.following = []
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
await getEndpoint("api/discover")
|
||||||
const res = await fetch(`${this.protocol}${import.meta.env.SAFETWITCH_BACKEND_DOMAIN}/api/discover`)
|
.catch(() => {
|
||||||
|
this.status = "error"
|
||||||
|
})
|
||||||
|
.then((data: CategoryPreviewInterface[]) => {
|
||||||
|
this.data = data
|
||||||
|
})
|
||||||
|
|
||||||
const rawData = await res.json()
|
|
||||||
if (rawData.status === 'ok') {
|
|
||||||
this.data = rawData.data
|
|
||||||
} else {
|
|
||||||
this.data = { status: 'error' }
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
this.data = { status: 'error' }
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
StreamPreviewVue,
|
StreamPreviewVue,
|
||||||
@ -99,10 +100,10 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<loading-screen v-if="!data"></loading-screen>
|
<loading-screen v-if="!data && status != 'error'"></loading-screen>
|
||||||
<error-message v-else-if="data.status === 'error'"></error-message>
|
<error-message v-else-if="status == 'error'"></error-message>
|
||||||
|
|
||||||
<div v-else class="max-w-5xl mx-auto">
|
<div v-else-if="data" class="max-w-5xl mx-auto">
|
||||||
<div v-if="following.length > 0" class="p-2 text-white">
|
<div v-if="following.length > 0" class="p-2 text-white">
|
||||||
<h1 class="font-bold text-5xl">Following</h1>
|
<h1 class="font-bold text-5xl">Following</h1>
|
||||||
<p class="text-xl">Streamers you follow</p>
|
<p class="text-xl">Streamers you follow</p>
|
||||||
@ -142,7 +143,6 @@ export default {
|
|||||||
<ul ref="categoryList">
|
<ul ref="categoryList">
|
||||||
<li
|
<li
|
||||||
v-for="category in data"
|
v-for="category in data"
|
||||||
:key="category"
|
|
||||||
ref="categoryItem"
|
ref="categoryItem"
|
||||||
class="inline-flex m-2 hover:scale-105 transition-transform"
|
class="inline-flex m-2 hover:scale-105 transition-transform"
|
||||||
>
|
>
|
||||||
|
@ -21,7 +21,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
|
|
||||||
await getEndpoint("api/search/?query=" + this.$route.query.query)
|
await getEndpoint("api/search/?query=" + this.$route.query.query)
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.status = "error"
|
this.status = "error"
|
||||||
|
@ -151,6 +151,6 @@ export default {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<twitch-chat :isLive="data.isLive" :channelName="data.username"></twitch-chat>
|
<twitch-chat :isLive="data.isLive" :channelName="data.login"></twitch-chat>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user