safetwitch/src/views/VodView.vue

140 lines
4.0 KiB
Vue
Raw Normal View History

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'
import VideoTab from '@/components/user/VideoTab.vue'
import type { Video, ApiResponse } from '@/types'
import { truncate, abbreviate, getEndpoint } from '@/mixins'
interface ChatComponent {
updateVodComments: (time: number) => void
}
export default {
inject: ["rootBackendUrl"],
async setup() {
const route = useRoute()
const vodID = route.params.vodID
const data = ref<Video>()
const status = ref<"ok" | "error">()
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,
videoOptions,
}
},
async mounted() {
const vodID = this.$route.params.vodID
await getEndpoint("api/vods/" + vodID)
.then((data) => {
this.data = data
})
.catch(() => {
this.status = "error"
})
},
components: {
VideoPlayer,
TwitchChat,
ErrorMessage,
FollowButton,
LoadingScreen,
VideoTab
},
methods: {
truncate, abbreviate,
handlePlayerTimeUpdate(time: number) {
const chat = this.$refs.chat as ChatComponent
chat.updateVodComments(time)
}
}
}
</script>
<template>
<loading-screen v-if="!data && status != 'error'"></loading-screen>
<error-message v-else-if="status == 'error'"></error-message>
<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
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"
>
<div class="w-full mx-auto rounded-lg mb-5">
<video-player :options="videoOptions" @PlayerTimeUpdate="handlePlayerTimeUpdate"> </video-player>
</div>
<div class="w-full flex-wrap md:p-3">
<div class="inline-flex md:w-full">
<img
:src="data.streamer.pfp"
class="rounded-full border-4 p-0.5 w-auto h-20"
:style="`border-color: ${data.streamer.colorHex};`"
/>
<div class="ml-3 content-between">
<h1 class="text-2xl md:text-4xl font-bold">{{ data.streamer.username }}</h1>
<p class="text-sm font-bold text-gray-200 self-end">
{{ truncate(data.title, 130) }}
</p>
</div>
</div>
<div class="pt-2 inline-flex">
<follow-button :username="data.streamer.username"></follow-button>
<p class="align-baseline font-bold ml-3">{{ abbreviate(data.streamer.followers) }} {{ $t("main.followers") }}</p>
</div>
</div>
<!-- VIDEOS TAB -->
<!-- <video-tab class="mb-4"></video-tab> -->
<!-- ABOUT TAB -->
<div class="bg-ctp-mantle mt-1 p-5 pt-3 rounded-lg w-full space-y-3">
<div class="inline-flex w-full">
<span class="pr-3 font-bold text-3xl">{{ $t("streamer.about") }}</span>
</div>
<p class="mb-5">{{ data.streamer.about }}</p>
<hr class="my-auto w-full bg-gray-200 rounded-full opacity-40" />
<ul class="flex font-semibold text-md justify-start flex-wrap flex-row">
<li v-for="link in data.streamer.socials">
<a :href="link.link" class="text-white hover:text-gray-400 mr-4">
<v-icon :name="`bi-${link.type}`" class="w-6 h-6 mr-1"></v-icon>
<span>{{ link.name }}</span>
</a>
</li>
</ul>
</div>
</div>
<twitch-chat :isVod="true" :channelName="data.streamer.login" ref="chat"></twitch-chat>
</div>
</template>