@@ -2,42 +2,108 @@ import { computed } from 'vue';
2
2
3
3
import type { Ref } from 'vue' ;
4
4
5
- import type { ListScrollItem , ListScrollSourceItem , OnScroll , OnUpdated } from '~/components/common/list/ListScroll.model' ;
6
5
import type { TraktClientPagination } from '~/models/trakt/trakt-client.model' ;
7
6
7
+ import type { ImageQuery } from '~/stores/data/image.store' ;
8
+
9
+ import {
10
+ type ListScrollItem ,
11
+ ListScrollItemType ,
12
+ type ListScrollSourceItem ,
13
+ type OnScroll ,
14
+ type OnUpdated ,
15
+ } from '~/components/common/list/ListScroll.model' ;
16
+
8
17
export type ListScrollSourceItemWithDate < T extends string > = ListScrollSourceItem & Partial < Record < T , string | number | Date > > ;
9
18
19
+ export const getTitle = ( media : ListScrollSourceItem ) : ListScrollItem [ 'title' ] => {
20
+ if ( ! media ) return ;
21
+ if ( media . person ) return media . person . name ;
22
+ if ( media . movie ) return media . movie . title ;
23
+ if ( ! media . episode ) return media . show ?. title ;
24
+ const number = media . episode . number ?. toString ( ) . padStart ( 2 , '0' ) ;
25
+ return `${ media . episode . season } x${ number } - ${ media . episode . title } ` ;
26
+ } ;
27
+
28
+ export const getContent = ( media : ListScrollSourceItem ) : ListScrollItem [ 'content' ] => {
29
+ if ( ! media ) return ;
30
+ if ( media . movie ) return media . movie . year ?. toString ( ) ;
31
+ if ( ! media . episode ) return media . show ?. year ?. toString ( ) ;
32
+ return media . show ?. title ;
33
+ } ;
34
+
35
+ export const getType = ( media : ListScrollSourceItem ) : ListScrollItem [ 'type' ] => {
36
+ if ( ! media ) return ;
37
+ if ( 'movie' in media ) return ListScrollItemType . movie ;
38
+ if ( 'episode' in media ) return ListScrollItemType . episode ;
39
+ if ( 'season' in media ) return ListScrollItemType . season ;
40
+ if ( 'show' in media ) return ListScrollItemType . show ;
41
+ if ( 'person' in media ) return ListScrollItemType . person ;
42
+ } ;
43
+
44
+ export const getDate = < D extends string , T extends ListScrollSourceItemWithDate < D > > (
45
+ media : T ,
46
+ array : T [ ] ,
47
+ index : number ,
48
+ dateFn ?: D | ( ( item : T ) => ListScrollSourceItemWithDate < D > [ D ] ) ,
49
+ ) : ListScrollItem [ 'date' ] => {
50
+ if ( ! media || ! dateFn ) return ;
51
+ const _date = typeof dateFn === 'function' ? dateFn ( media ) : media [ dateFn ] ;
52
+ if ( ! _date ) return ;
53
+ const date : ListScrollItem [ 'date' ] = { current : new Date ( _date ) } ;
54
+ const previous = typeof dateFn === 'function' ? dateFn ( array [ index - 1 ] ) : array [ index - 1 ] ?. [ dateFn ] ;
55
+ if ( index > 0 && previous ) date . previous = new Date ( previous ) ;
56
+ const next = typeof dateFn === 'function' ? dateFn ( array [ index + 1 ] ) : array [ index + 1 ] ?. [ dateFn ] ;
57
+ if ( next ) date . next = new Date ( next ) ;
58
+ date . sameDayAsPrevious = date . previous ?. toLocaleDateString ( ) === date . current ?. toLocaleDateString ( ) ;
59
+ date . sameDayAsNext = date . next ?. toLocaleDateString ( ) === date . current ?. toLocaleDateString ( ) ;
60
+ return date ;
61
+ } ;
62
+
63
+ const isMediaType = ( type : ListScrollItem [ 'type' ] ) : type is 'movie' | 'show' | 'season' | 'episode' | 'person' =>
64
+ type === ListScrollItemType . movie ||
65
+ type === ListScrollItemType . show ||
66
+ type === ListScrollItemType . season ||
67
+ type === ListScrollItemType . episode ||
68
+ type === ListScrollItemType . person ;
69
+
70
+ export const getPosterQuery =
71
+ ( item : ListScrollSourceItem , type : ListScrollItem [ 'type' ] ) : ListScrollItem [ 'getPosterQuery' ] =>
72
+ ( ) => {
73
+ if ( ! item || ! type ) return ;
74
+ if ( type === ListScrollItemType . placeholder ) return ;
75
+ if ( ! isMediaType ( type ) ) return ;
76
+ const _type = [ 'show' , 'episode' , 'season' ] . includes ( type ) ? 'show' : type ;
77
+ const media = item [ _type ] ;
78
+ if ( ! media ?. ids . tmdb ) return ;
79
+ return {
80
+ type,
81
+ id : media . ids . tmdb ,
82
+ season : item ?. episode ?. season ?? item . season ?. number ,
83
+ episode : item ?. episode ?. number ,
84
+ } satisfies ImageQuery ;
85
+ } ;
86
+
10
87
export const useListScroll = < D extends string , T extends ListScrollSourceItemWithDate < D > > (
11
88
items : Ref < T [ ] > ,
12
89
dateFn ?: D | ( ( item : T ) => ListScrollSourceItemWithDate < D > [ D ] ) ,
13
- ) =>
14
- computed < ListScrollItem [ ] > ( ( ) => {
90
+ ) => {
91
+ return computed < ListScrollItem [ ] > ( ( ) => {
15
92
const array = items . value ;
16
93
if ( ! array . length ) return [ ] ;
17
94
return array . map ( ( item , index ) => {
18
95
const _item : ListScrollItem = { ...item , index, loading : typeof item . id === 'number' && item . id < 0 } ;
19
96
20
- if ( 'movie' in _item ) _item . type = 'movie' ;
21
- else if ( 'episode' in _item ) _item . type = 'episode' ;
22
- else if ( 'season' in _item ) _item . type = 'season' ;
23
- else if ( 'show' in _item ) _item . type = 'show' ;
24
- else if ( 'person' in _item ) _item . type = 'person' ;
25
-
26
- if ( ! _item || ! dateFn ) return _item ;
27
- const _date = typeof dateFn === 'function' ? dateFn ( item ) : item [ dateFn ] ;
28
- if ( ! _date ) return _item ;
29
-
30
- const date : ListScrollItem [ 'date' ] = { current : new Date ( _date ! ) } ;
31
- const previous = typeof dateFn === 'function' ? dateFn ( array [ index - 1 ] ) : array [ index - 1 ] ?. [ dateFn ] ;
32
- if ( index > 0 && previous ) date . previous = new Date ( previous ) ;
33
- const next = typeof dateFn === 'function' ? dateFn ( array [ index + 1 ] ) : array [ index + 1 ] ?. [ dateFn ] ;
34
- if ( next ) date . next = new Date ( next ) ;
35
- date . sameDayAsPrevious = date . previous ?. toLocaleDateString ( ) === date . current ?. toLocaleDateString ( ) ;
36
- date . sameDayAsNext = date . next ?. toLocaleDateString ( ) === date . current ?. toLocaleDateString ( ) ;
37
-
38
- return { ..._item , date } ;
97
+ if ( ! _item . type ) _item . type = getType ( item ) ;
98
+ if ( ! _item . title ) _item . title = getTitle ( item ) ;
99
+ if ( ! _item . content ) _item . content = getContent ( item ) ;
100
+ if ( ! _item . poster && ! _item . getPosterQuery ) _item . getPosterQuery = getPosterQuery ( item , _item . type ) ;
101
+ _item . date = getDate ( item , array , index , dateFn ) ;
102
+
103
+ return _item ;
39
104
} ) ;
40
105
} ) ;
106
+ } ;
41
107
42
108
export const useListScrollEvents = (
43
109
callback : ( query : { page : number } ) => Promise < unknown > ,
0 commit comments