safetwitch/src/views/VodView.vue

149 lines
4.3 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'
2023-09-10 15:21:55 -04:00
import AboutTab from '@/components/user/AboutTab.vue'
2023-09-16 18:13:28 -04:00
import ShareModal from '@/components/popups/ShareButtonPopup.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 rootBackendUrl = inject('rootBackendUrl')
const videoOptions = {
2023-09-16 18:13:28 -04:00
autoplay: getSetting('autoplay'),
2023-07-19 20:26:43 -04:00
controls: true,
sources: [
{
src: `${rootBackendUrl}/proxy/vod/${vodID}/video.m3u8`,
type: 'application/vnd.apple.mpegurl'
}
],
fluid: true
}
return {
2023-09-16 18:13:28 -04:00
data: ref<Video>(),
status: ref<'ok' | 'error'>(),
videoOptions,
time: ref(0),
shareModalVisible: ref(false)
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,
2023-09-16 18:13:28 -04:00
AboutTab,
ShareModal
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
2023-09-16 18:13:28 -04:00
this.time = time
2023-07-19 20:26:43 -04:00
chat.updateVodComments(time)
2023-08-16 13:48:44 -04:00
},
2023-09-08 22:23:33 -04:00
chatVisible,
2023-09-16 18:13:28 -04:00
getSetting,
toggleShareModal() {
this.shareModalVisible = !this.shareModalVisible
}
2023-07-19 20:26:43 -04:00
}
}
</script>
<template>
2023-09-16 18:13:28 -04:00
<share-modal v-if="shareModalVisible" :time="time" :useTime="true" @close="toggleShareModal"></share-modal>
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-09-24 11:47:48 -04:00
class="flex bg-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-09-16 18:13:28 -04:00
<div class="ml-3 content-between w-5/6">
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>
2023-09-16 18:13:28 -04:00
<div class="flex justify-between items-center">
<div class="pt-2 inline-flex">
<follow-button :username="data.streamer.login"></follow-button>
<p class="align-baseline font-bold ml-3">
{{ abbreviate(data.streamer.followers) }} {{ $t('main.followers') }}
</p>
</div>
<button @click="toggleShareModal" class="px-2 py-1.5 rounded-lg bg-purple-600">
<v-icon name="fa-share-alt"></v-icon>
</button>
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-16 18:13:28 -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>