1+ import type { SetRequired } from 'type-fest' ;
2+
13import { createEffect , on } from 'solid-js' ;
4+ import { unwrap } from 'solid-js/store' ;
25
36import {
47 assign ,
@@ -8,14 +11,16 @@ import {
811 throttle ,
912} from 'helper' ;
1013
11- import type { MangaProps } from '..' ;
14+ import type { ComicImgData , MangaProps } from '..' ;
1215import type { State } from '../store' ;
1316import type { ComicImg } from '../store/image' ;
1417import type { Option } from '../store/option' ;
1518
1619import {
1720 defaultHotkeys ,
1821 focus ,
22+ getImgDisplaySize ,
23+ getImgType ,
1924 placeholderSize ,
2025 resetImgState ,
2126 resumeReadProgress ,
@@ -30,13 +35,6 @@ import classes from '../index.module.css';
3035import { refs , setState } from '../store' ;
3136import { defaultOption } from '../store/option' ;
3237
33- const createComicImg = ( src : string ) : ComicImg => ( {
34- src,
35- loadType : 'wait' ,
36- size : placeholderSize ( ) ,
37- blobUrl : src . startsWith ( 'blob:' ) ? src : undefined ,
38- } ) ;
39-
4038export const useInit = ( props : MangaProps ) => {
4139 watchDomSize ( 'rootSize' , refs . root ) ;
4240
@@ -134,8 +132,36 @@ export const useInit = (props: MangaProps) => {
134132
135133 const handleImgList = ( ) => {
136134 setState ( ( state ) => {
137- // 使用相对协议路径,防止 Mixed Content 报错
138- const imgList = props . imgList . map ( ( url ) => url ?. replace ( / ^ h t t p : / , '' ) ) ;
135+ const newImgMap : State [ 'imgMap' ] = { } ;
136+ const newImgList : string [ ] = [ ] ; // 因为会有相同 url 的图片,所以不能用 Set
137+ for ( const img of unwrap ( props . imgList ) ) {
138+ // 使用相对协议路径,防止 Mixed Content 报错
139+ const url =
140+ ( typeof img === 'object' ? img . src : img ) ?. replace ( / ^ h t t p : / , '' ) ??
141+ '' ;
142+ newImgList . push ( url ) ;
143+
144+ if ( Reflect . has ( newImgMap , url ) ) continue ;
145+ if ( Reflect . has ( state . imgMap , url ) ) {
146+ newImgMap [ url ] = state . imgMap [ url ] ;
147+ continue ;
148+ }
149+
150+ const imgItem : ComicImgData =
151+ typeof img === 'string' ? { src : url } : img ;
152+ imgItem . loadType ??= 'wait' ;
153+ if ( imgItem . width && imgItem . height ) {
154+ imgItem . size = getImgDisplaySize ( state , imgItem ) ;
155+ imgItem . type = getImgType (
156+ imgItem as SetRequired < ComicImg , 'width' | 'height' > ,
157+ ) ;
158+ }
159+ imgItem . size ??= placeholderSize ( ) ;
160+ if ( ! imgItem . blobUrl && url . startsWith ( 'blob:' ) )
161+ imgItem . blobUrl = imgItem . src ;
162+
163+ newImgMap [ url ] = imgItem as ComicImg ;
164+ }
139165
140166 /** 修改前的当前显示图片 */
141167 const oldActiveImg =
@@ -147,21 +173,22 @@ export const useInit = (props: MangaProps) => {
147173 const fillEffectList = Object . keys ( state . fillEffect ) . map ( Number ) ;
148174 for ( const pageIndex of fillEffectList ) {
149175 if ( pageIndex === - 1 ) continue ;
150- if ( state . imgList [ pageIndex ] === imgList [ pageIndex ] ) continue ;
176+ if ( state . imgList [ pageIndex ] === newImgList [ pageIndex ] ) continue ;
151177 needResetFillEffect = true ;
152178 break ;
153179 }
154180
155- const newImgList = new Set ( imgList ) ;
156181 const oldImgList = new Set ( state . imgList ) ;
157182
158- if ( oldImgList . size === 0 && newImgList . size > 0 ) {
183+ if ( oldImgList . size === 0 && newImgList . length > 0 ) {
159184 resumeReadProgress ( state ) ;
160185 updateSelfhostedOptions ( true ) ;
161186 }
162187
163188 /** 被删除的图片 */
164- const deleteList = [ ...oldImgList ] . filter ( ( url ) => ! newImgList . has ( url ) ) ;
189+ const deleteList = [ ...oldImgList ] . filter (
190+ ( url ) => ! newImgList . includes ( url ) ,
191+ ) ;
165192 for ( const url of deleteList )
166193 if ( state . imgMap [ url ] . blobUrl && state . imgMap [ url ] . blobUrl !== url )
167194 URL . revokeObjectURL ( state . imgMap [ url ] . blobUrl ) ;
@@ -175,15 +202,11 @@ export const useInit = (props: MangaProps) => {
175202 /** 是否需要更新页面 */
176203 const needUpdatePageData =
177204 needResetFillEffect ||
178- state . imgList . length !== imgList . length ||
205+ state . imgList . length !== newImgList . length ||
179206 deleteNum > 0 ;
180207
181- const newImgMap : State [ 'imgMap' ] = { } ;
182- for ( const url of imgList )
183- newImgMap [ url ] = state . imgMap [ url ] ?? createComicImg ( url ) ;
184-
185208 state . imgMap = newImgMap ;
186- state . imgList = imgList ;
209+ state . imgList = [ ... newImgList ] ;
187210
188211 state . prop . onLoading ?.( state . imgList . map ( ( url ) => state . imgMap [ url ] ) ) ;
189212
@@ -211,7 +234,7 @@ export const useInit = (props: MangaProps) => {
211234 // 尽量使当前显示的图片在修改后依然不变
212235 oldActiveImg . some ( ( url ) => {
213236 // 跳过填充页和已被删除的图片
214- if ( ! url || imgList . includes ( url ) ) return false ;
237+ if ( ! url || newImgList . includes ( url ) ) return false ;
215238
216239 const newPageIndex = state . pageList . findIndex ( ( page ) =>
217240 page . some ( ( index ) => state . imgList ?. [ index ] === url ) ,
0 commit comments