@@ -6,8 +6,7 @@ import 'swiper/css/zoom'
66import ' swiper/css/free-mode'
77import { uni } from ' @delta-comic/model'
88import { Inject , useConfig } from ' @delta-comic/plugin'
9- import { SmartAbortController } from ' @delta-comic/request'
10- import { useQuery } from ' @pinia/colada'
9+ import { useInfiniteQuery , useQuery } from ' @pinia/colada'
1110import { LikeOutlined } from ' @vicons/antd'
1211import { ArrowBackIosNewRound , FullscreenExitRound } from ' @vicons/material'
1312import { computedWithControl , useResizeObserver } from ' @vueuse/core'
@@ -24,20 +23,27 @@ import { useRoute } from 'vue-router'
2423import ButtonPopup from ' @/components/ButtonPopup.vue'
2524import Settings from ' @/components/Settings.vue'
2625import { imageViewConfig } from ' @/config'
26+ import { createPageQueryKey } from ' @/layout/default'
2727import type { ContentImagePage } from ' @/model'
28+ import { useLike } from ' @/utils/content'
2829import { useSwipeDbClick } from ' @/utils/ui'
2930
30- import type * as ImageViewInject from ' ./image'
31- const $props = defineProps <{ page: ContentImagePage }>()
31+ import * as LayoutInject from ' ../layout/default'
32+ import * as ImageViewInject from ' ./image'
33+
34+ const $props = defineProps <{ page: ContentImagePage ; union? : uni .item .Item }>()
3235
3336const config = useConfig ().$load (imageViewConfig )
3437
3538const swiper = shallowRef <SwiperClass >()
3639
3740const { isFullscreen } = useFullscreen ()
3841
39- const images = useQuery ({})
40- // const images = computed(() => $props.page.images.content.data.value ?? [])
42+ const imagesQuery = useQuery ({
43+ key : () => [ImageViewInject .QueryKey .Images , createPageQueryKey ($props .page )],
44+ query : async ({ signal }) => await $props .page .fetchImages (signal )
45+ })
46+ const images = computed (() => imagesQuery .data .value ?? [])
4147
4248const pageOnIndex = shallowRef (0 )
4349const selectPage = shallowRef (pageOnIndex .value )
@@ -59,22 +65,26 @@ const goToSlide = (offset: 1 | -1) => {
5965 offset < 0 ? swiper .value ?.slidePrev () : swiper .value ?.slideNext ()
6066 }
6167}
62- const goPrev = () => goToSlide (- 1 )
63- const goNext = () => goToSlide (1 )
6468
6569const isShowMenu = shallowRef (true )
6670
6771const { handleTouchend, handleTouchmove, handleTouchstart, handleDbTap } = useSwipeDbClick (() => {
6872 isShowMenu .value = ! isShowMenu .value
6973})
7074
71- const nowEp = computed (() =>
72- $props .page .eps .content .data .value ?.find (v => v .index === $props .page .ep )
73- )
75+ const { likeItem } = useLike ()
7476
77+ const queryEps = useInfiniteQuery ({
78+ key : () => [LayoutInject .QueryKey .Ep , LayoutInject .createPageQueryKey ($props .page )],
79+ query : async ({ signal , pageParam }) => await $props .page .fetchEps (pageParam , signal ),
80+ initialPageParam: $props .page .fetchEps .initialPageParam ,
81+ getNextPageParam : lp => lp .nextPage
82+ })
83+ const eps = computed (() => queryEps .data .value ?.pages .flat () ?? [])
84+ const nowEp = computed (() => eps .value ?.find (v => v .id === $props .page .ep ))
7585const $route = useRoute ()
7686const nowEpId = $route .params .ep .toString ()
77- const handleEpSelect = (preload : uni .item .RawItem ) =>
87+ const routeToContent = (preload : uni .item .RawItem ) =>
7888 SharedFunction .call (
7989 ' routeToContent' ,
8090 preload .contentType ,
@@ -83,23 +93,6 @@ const handleEpSelect = (preload: uni.item.RawItem) =>
8393 uni .item .Item .create (preload )
8494 )
8595
86- const { data : detail } = useQuery ({
87- query : ({ signal }) => $props .page .fetchDetail (signal ),
88- key : () => [LayoutInject .QueryKey .Detail , LayoutInject .createPageQueryKey ($props .page )]
89- })
90- const union = computed (() => detail .value ?? $props .page .preload )
91-
92- const isLiked = shallowRef (union .value ?.isLiked ?? false )
93- const likeSignal = new SmartAbortController ()
94- const handleLike = async () => {
95- likeSignal .abort ()
96- try {
97- union .value .like (likeSignal .signal ).then (v => (isLiked .value = v ))
98- } catch (error ) {
99- console .error (' liked fail' )
100- }
101- }
102-
10396const slides = shallowReactive <InstanceType <typeof SwiperSlide >[]>([])
10497const freeModeHeightCache = shallowReactive (new Array <number >())
10598const virtualShowIndex = computedWithControl <number []>([swiper ], () =>
@@ -205,14 +198,14 @@ defineSlots<{
205198 ref="imgIns"
206199 class="absolute top-0 size-full"
207200 fit="contain"
208- :src =" comic .$cover "
201+ :src =" union ? .$cover "
209202 v-if =" isEmpty (images )"
210203 />
211204 <div
212205 class =" pointer-events-none absolute top-0 left-0 z-2 h-full w-full *:pointer-events-auto *:absolute *:top-0 *:h-full *:w-10"
213206 >
214- <div class =" left-0" @click.stop =" goPrev " />
215- <div class =" right-0" @click.stop =" goNext " />
207+ <div class =" left-0" @click.stop =" goToSlide(-1) " />
208+ <div class =" right-0" @click.stop =" goToSlide(1) " />
216209 </div >
217210 <AnimatePresence >
218211 <motion .div
@@ -229,7 +222,7 @@ defineSlots<{
229222 </NIcon >
230223 </NButton >
231224 <div class =" flex w-1/2 flex-col text-nowrap" >
232- <span class =" van-ellipsis text-[1rem]" >{{ comic .title }}</span >
225+ <span class =" van-ellipsis text-[1rem]" >{{ union? .title }}</span >
233226 <span class =" van-ellipsis ml-1 text-xs" >{{ nowEp?.name }}</span >
234227 </div >
235228 <div class =" flex h-full w-full items-center justify-around" >
@@ -239,13 +232,14 @@ defineSlots<{
239232 :args =" { page , images , swiper , index: pageOnIndex } "
240233 />
241234 <DcToggleIcon
235+ v-if =" union "
242236 padding
243237 size="30px"
244- v-model =" isLiked "
245- @click =" handleLike "
238+ v-model =" union . isLiked "
239+ @click =" likeItem ( union ) "
246240 :icon =" LikeOutlined "
247241 />
248- <FavouriteSelect :item =" page . union . value " v-if =" page . union . value " plain />
242+ <FavouriteSelect :item =" union " v-if =" union " plain />
249243 </div >
250244 </motion .div >
251245 <motion .div
@@ -299,7 +293,7 @@ defineSlots<{
299293 <Settings />
300294 </ButtonPopup >
301295 <ButtonPopup
302- v-if =" (page . eps . content . data . value ? .length ?? 1 ) > 1 "
296+ v-if =" (eps .length ?? 1 ) > 1 "
303297 class="flex h-[70vh] flex-col bg-black/50! backdrop-blur"
304298 >
305299 <template #button >
@@ -310,17 +304,17 @@ defineSlots<{
310304 </div >
311305 <DcList
312306 class="h-full w-full"
313- :source =" { data: page . eps . content , isEnd: true } "
307+ :source =" { type: ' infinite ' , value: queryEps } "
314308 :itemHeight =" 40 "
315309 v-slot =" { data: { item: ep , index }, height } "
316310 :data-processor =" v => v .toReversed ()"
317311 ref="epSelList"
318312 >
319313 <VanCell
320314 clickable
321- @click =" handleEpSelect ({ ... page . union . value ! .toJSON (), thisEp: ep .toJSON () })"
322- :title =" ep .name || ` 第${page . eps . content . data . value ! .length - index }话 ` "
323- :title-class =" [' text-white' , nowEpId === ep .index && ' font-bold !text-(--p-color)' ] "
315+ @click =" union && routeToContent ({ ... union .toJSON (), thisEp: ep .toJSON () })"
316+ :title =" ep .name || ` 第${eps .length - index }话 ` "
317+ :title-class =" [' text-white' , nowEpId === ep .id && ' font-bold !text-(--p-color)' ] "
324318 class="flex w-full items-center bg-transparent!"
325319 :style =" { height: ` ${height }px !important ` } "
326320 >
0 commit comments