2023-07-19 20:26:43 -04:00
|
|
|
<script lang="ts">
|
|
|
|
import { ref, inject } from 'vue'
|
|
|
|
import { useRoute } from 'vue-router'
|
|
|
|
|
|
|
|
import VideoPlayer from '@/components/VideoPlayer.vue'
|
|
|
|
import TwitchChat from '@/components/TwitchChat.vue'
|
|
|
|
import ErrorMessage from '@/components/ErrorMessage.vue'
|
|
|
|
import FollowButton from '@/components/FollowButton.vue'
|
|
|
|
import LoadingScreen from '@/components/LoadingScreen.vue'
|
2023-09-10 15:21:55 -04:00
|
|
|
import AboutTab from '@/components/user/AboutTab.vue'
|
2023-07-19 20:26:43 -04:00
|
|
|
|
2023-07-20 13:57:01 -04:00
|
|
|
import type { Video } from '@/types'
|
2023-08-18 14:23:59 -04:00
|
|
|
import { truncate, abbreviate, getEndpoint } from '@/mixins'
|
2023-09-08 22:23:33 -04:00
|
|
|
import { chatVisible, getSetting } from '@/settingsManager'
|
2023-07-19 20:26:43 -04:00
|
|
|
|
|
|
|
interface ChatComponent {
|
|
|
|
updateVodComments: (time: number) => void
|
|
|
|
}
|
|
|
|
|
|
|
|
export default {
|
2023-07-20 13:57:01 -04:00
|
|
|
inject: ['rootBackendUrl'],
|
2023-07-19 20:26:43 -04:00
|
|
|
async setup() {
|
|
|
|
const route = useRoute()
|
|
|
|
const vodID = route.params.vodID
|
|
|
|
const data = ref<Video>()
|
2023-07-20 13:57:01 -04:00
|
|
|
const status = ref<'ok' | 'error'>()
|
2023-07-19 20:26:43 -04:00
|
|
|
const rootBackendUrl = inject('rootBackendUrl')
|
|
|
|
const videoOptions = {
|
|
|
|
autoplay: true,
|
|
|
|
controls: true,
|
|
|
|
sources: [
|
|
|
|
{
|
|
|
|
src: `${rootBackendUrl}/proxy/vod/${vodID}/video.m3u8`,
|
|
|
|
type: 'application/vnd.apple.mpegurl'
|
|
|
|
}
|
|
|
|
],
|
|
|
|
fluid: true
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
data,
|
|
|
|
status,
|
2023-07-20 13:57:01 -04:00
|
|
|
videoOptions
|
2023-07-19 20:26:43 -04:00
|
|
|
}
|
|
|
|
},
|
|
|
|
async mounted() {
|
|
|
|
const vodID = this.$route.params.vodID
|
|
|
|
|
2023-07-20 13:57:01 -04:00
|
|
|
await getEndpoint('api/vods/' + vodID)
|
|
|
|
.then((data) => {
|
|
|
|
this.data = data
|
|
|
|
})
|
|
|
|
.catch(() => {
|
|
|
|
this.status = 'error'
|
|
|
|
})
|
2023-07-19 20:26:43 -04:00
|
|
|
},
|
|
|
|
components: {
|
|
|
|
VideoPlayer,
|
|
|
|
TwitchChat,
|
|
|
|
ErrorMessage,
|
|
|
|
FollowButton,
|
2023-09-10 15:21:55 -04:00
|
|
|
LoadingScreen,
|
|
|
|
AboutTab
|
2023-07-19 20:26:43 -04:00
|
|
|
},
|
|
|
|
methods: {
|
2023-07-20 13:57:01 -04:00
|
|
|
truncate,
|
|
|
|
abbreviate,
|
2023-07-19 20:26:43 -04:00
|
|
|
handlePlayerTimeUpdate(time: number) {
|
2023-08-16 13:48:44 -04:00
|
|
|
if (!chatVisible()) return
|
2023-07-19 20:26:43 -04:00
|
|
|
const chat = this.$refs.chat as ChatComponent
|
|
|
|
chat.updateVodComments(time)
|
2023-08-16 13:48:44 -04:00
|
|
|
},
|
2023-09-08 22:23:33 -04:00
|
|
|
chatVisible,
|
|
|
|
getSetting
|
2023-07-19 20:26:43 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
2023-07-20 13:57:01 -04:00
|
|
|
<loading-screen v-if="!data && status != 'error'"></loading-screen>
|
|
|
|
<error-message v-else-if="status == 'error'"></error-message>
|
2023-07-19 20:26:43 -04:00
|
|
|
|
|
|
|
<div
|
|
|
|
v-else-if="data"
|
|
|
|
class="w-full justify-center md:inline-flex space-y-4 md:space-y-0 md:space-x-4 md:p-4"
|
|
|
|
>
|
|
|
|
<div
|
2023-07-20 13:57:01 -04:00
|
|
|
class="flex bg-ctp-crust flex-col p-6 rounded-lg w-[99vw] md:max-w-prose md:min-w-[65ch] lg:max-w-[70rem] text-white"
|
2023-07-19 20:26:43 -04:00
|
|
|
>
|
|
|
|
<div class="w-full mx-auto rounded-lg mb-5">
|
2023-07-20 13:57:01 -04:00
|
|
|
<video-player :options="videoOptions" @PlayerTimeUpdate="handlePlayerTimeUpdate">
|
|
|
|
</video-player>
|
2023-07-19 20:26:43 -04:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="w-full flex-wrap md:p-3">
|
|
|
|
<div class="inline-flex md:w-full">
|
2023-07-20 13:57:01 -04:00
|
|
|
<router-link :to="'/' + data.streamer.login">
|
|
|
|
<img
|
|
|
|
:src="data.streamer.pfp"
|
|
|
|
class="rounded-full border-4 p-0.5 w-auto h-20"
|
|
|
|
:style="`border-color: ${data.streamer.colorHex};`"
|
|
|
|
/>
|
|
|
|
</router-link>
|
|
|
|
|
2023-07-19 20:26:43 -04:00
|
|
|
<div class="ml-3 content-between">
|
2023-07-20 13:57:01 -04:00
|
|
|
<router-link :to="'/' + data.streamer.login">
|
|
|
|
<h1 class="text-2xl md:text-4xl font-bold">{{ data.streamer.username }}</h1>
|
|
|
|
</router-link>
|
2023-07-19 20:26:43 -04:00
|
|
|
<p class="text-sm font-bold text-gray-200 self-end">
|
|
|
|
{{ truncate(data.title, 130) }}
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="pt-2 inline-flex">
|
2023-09-08 21:46:19 -04:00
|
|
|
<follow-button :username="data.streamer.login"></follow-button>
|
2023-07-20 13:57:01 -04:00
|
|
|
<p class="align-baseline font-bold ml-3">
|
|
|
|
{{ abbreviate(data.streamer.followers) }} {{ $t('main.followers') }}
|
|
|
|
</p>
|
2023-07-19 20:26:43 -04:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- ABOUT TAB -->
|
2023-09-10 15:21:55 -04:00
|
|
|
<about-tab :socials="data.streamer.socials" :about="data.streamer.about"></about-tab>
|
2023-07-19 20:26:43 -04:00
|
|
|
</div>
|
|
|
|
|
2023-08-18 13:39:26 -04:00
|
|
|
<twitch-chat
|
2023-09-08 22:23:33 -04:00
|
|
|
v-if="getSetting('chatVisible')"
|
2023-08-18 13:39:26 -04:00
|
|
|
:isVod="true"
|
|
|
|
:channelName="data.streamer.login"
|
|
|
|
ref="chat"
|
|
|
|
></twitch-chat>
|
2023-07-19 20:26:43 -04:00
|
|
|
</div>
|
|
|
|
</template>
|