|
1 | 1 | <script setup lang="ts"> |
2 | | -import { computed, onBeforeUnmount, shallowRef, useTemplateRef } from 'vue' |
3 | | -import { watch } from 'vue' |
4 | | -import type { MediaPlayerElement } from 'vidstack/elements' |
5 | | -import 'vidstack/icons' |
| 2 | +import { useFullscreen } from '@delta-comic/core' |
| 3 | +import type { uni } from '@delta-comic/model' |
| 4 | +import { Inject } from '@delta-comic/plugin' |
6 | 5 | import 'vidstack/bundle' |
| 6 | +import 'vidstack/icons' |
7 | 7 | import 'hls.js' |
8 | | -import { ArrowBackIosRound, PauseRound, PlayArrowRound } from '@vicons/material' |
| 8 | +import { useQuery } from '@pinia/colada' |
9 | 9 | import { LikeOutlined } from '@vicons/antd' |
| 10 | +import { ArrowBackIosRound, PauseRound, PlayArrowRound } from '@vicons/material' |
| 11 | +import type { MediaPlayerElement } from 'vidstack/elements' |
| 12 | +import { computed, onBeforeUnmount, shallowRef, useTemplateRef } from 'vue' |
| 13 | +import { watch } from 'vue' |
10 | 14 | import { useRouter } from 'vue-router' |
11 | | -import { useFullscreen } from '@delta-comic/core' |
12 | | -import type { ContentVideoPage, VideoConfig } from '@/model' |
13 | | -import { SmartAbortController } from '@delta-comic/request' |
14 | | -import type * as VideoViewInject from './video' |
15 | | -import { Inject } from '@delta-comic/plugin' |
| 15 | +
|
16 | 16 | import ButtonPopup from '@/components/ButtonPopup.vue' |
17 | 17 | import Settings from '@/components/Settings.vue' |
| 18 | +import { createPageQueryKey } from '@/layout/default' |
| 19 | +import type { ContentVideoPage, VideoConfig } from '@/model' |
| 20 | +import { useLike } from '@/utils/content' |
| 21 | +
|
| 22 | +import * as VideoViewInject from './video' |
18 | 23 |
|
19 | | -const $props = defineProps<{ page: ContentVideoPage }>() |
| 24 | +const $props = defineProps<{ page: ContentVideoPage; union?: uni.item.Item }>() |
20 | 25 |
|
21 | 26 | const { isFullscreen, ...fc } = useFullscreen() |
22 | 27 | const setFullscreen = async (isFull: boolean) => (isFull ? fc.entry() : fc.exit()) |
23 | 28 |
|
24 | 29 | const player = useTemplateRef<MediaPlayerElement>('player') |
25 | | -const union = computed(() => $props.page.union.value) |
26 | | -const videos = computed(() => $props.page.videos.content.data.value ?? []) |
| 30 | +
|
| 31 | +const videosQuery = useQuery({ |
| 32 | + key: () => [VideoViewInject.QueryKey.Videos, createPageQueryKey($props.page)], |
| 33 | + query: async ({ signal }) => await $props.page.fetchVideo(signal) |
| 34 | +}) |
| 35 | +const videos = computed(() => videosQuery.data.value ?? []) |
27 | 36 |
|
28 | 37 | watch( |
29 | 38 | player, |
@@ -84,16 +93,7 @@ watch( |
84 | 93 | { immediate: true } |
85 | 94 | ) |
86 | 95 |
|
87 | | -const isLiked = shallowRef(union.value?.isLiked ?? false) |
88 | | -const likeSignal = new SmartAbortController() |
89 | | -const handleLike = async () => { |
90 | | - likeSignal.abort() |
91 | | - try { |
92 | | - union.value?.like(likeSignal.signal).then(v => (isLiked.value = v)) |
93 | | - } catch (error) { |
94 | | - console.error('liked fail') |
95 | | - } |
96 | | -} |
| 96 | +const { likeItem } = useLike() |
97 | 97 |
|
98 | 98 | defineSlots<{ |
99 | 99 | topBar(args: VideoViewInject.BarProps): any |
@@ -142,9 +142,15 @@ defineSlots<{ |
142 | 142 | <slot name="topBar" :="{ player, page, isFullscreen }"></slot> |
143 | 143 | <Inject key="layout::view::video.top-bar" :args="{ player, page, isFullscreen }" /> |
144 | 144 |
|
145 | | - <DcToggleIcon size="23px" v-model="isLiked" @click="handleLike" :icon="LikeOutlined" /> |
| 145 | + <DcToggleIcon |
| 146 | + size="23px" |
| 147 | + v-model="union.isLiked" |
| 148 | + @click="likeItem(union)" |
| 149 | + v-if="union" |
| 150 | + :icon="LikeOutlined" |
| 151 | + /> |
146 | 152 |
|
147 | | - <FavouriteSelect :item="page.union.value" v-if="page.union.value" plain /> |
| 153 | + <FavouriteSelect :item="union" v-if="union" plain /> |
148 | 154 |
|
149 | 155 | <media-pip-button> |
150 | 156 | <media-icon |
|
0 commit comments