@@ -15,6 +15,8 @@ import CustomTrans from "@App/pages/components/CustomTrans";
1515import { useSystemConfig } from "./utils" ;
1616import { subscribeMessage } from "@App/pages/store/global" ;
1717import { SystemConfigChange , type SystemConfigKey } from "@App/pkg/config/config" ;
18+ import { FaviconDAO } from "@App/app/repo/favicon" ;
19+ import { clearFaviconMemoryCache } from "@App/pages/store/favicons" ;
1820import { type TKeyValue } from "@Packages/message/message_queue" ;
1921import { useEffect , useMemo } from "react" ;
2022import { systemConfig } from "@App/pages/store/global" ;
@@ -41,6 +43,7 @@ function Setting() {
4143 const [ badgeTextColor , setBadgeTextColor , submitBadgeTextColor ] = useSystemConfig ( "badge_text_color" ) ;
4244 const [ scriptMenuDisplayType , setScriptMenuDisplayType , submitScriptMenuDisplayType ] =
4345 useSystemConfig ( "script_menu_display_type" ) ;
46+ const [ faviconService , setFaviconService , submitFaviconService ] = useSystemConfig ( "favicon_service" ) ;
4447
4548 const [ editorTypeDefinition , setEditorTypeDefinition , submitEditorTypeDefinition ] =
4649 useSystemConfig ( "editor_type_definition" ) ;
@@ -81,6 +84,7 @@ function Setting() {
8184 badge_background_color : setBadgeBackgroundColor ,
8285 badge_text_color : setBadgeTextColor ,
8386 script_menu_display_type : setScriptMenuDisplayType ,
87+ favicon_service : setFaviconService ,
8488 editor_type_definition : setEditorTypeDefinition ,
8589 } as const ;
8690 const hookMgr = new HookManager ( ) ;
@@ -306,6 +310,39 @@ function Setting() {
306310 </ div >
307311 </ Space >
308312 </ div >
313+
314+ { /* Favicon 服务 */ }
315+ < div className = "tw-flex tw-items-center tw-justify-between tw-min-h-9" >
316+ < div className = "tw-flex tw-items-center tw-gap-4 tw-flex-1" >
317+ < span className = "tw-min-w-20" > { t ( "favicon_service" ) } </ span >
318+ < Select
319+ value = { faviconService }
320+ className = "tw-w-40 tw-max-w-50"
321+ onChange = { async ( value ) => {
322+ submitFaviconService ( value ) ;
323+ // 清除 favicon 缓存
324+ try {
325+ const faviconDAO = new FaviconDAO ( ) ;
326+ const allFavicons = await faviconDAO . find ( ) ;
327+ await faviconDAO . deletes ( allFavicons . map ( ( f ) => f . uuid ) ) ;
328+ // 清除 OPFS 缓存:删除并重建目录
329+ const opfsRoot = await navigator . storage . getDirectory ( ) ;
330+ await opfsRoot . removeEntry ( "cached_favicons" , { recursive : true } ) . catch ( ( ) => { } ) ;
331+ // 清除内存中的 blob URL 缓存
332+ clearFaviconMemoryCache ( ) ;
333+ } catch {
334+ // 忽略清除缓存的错误
335+ }
336+ Message . success ( t ( "save_success" ) ! ) ;
337+ } }
338+ >
339+ < Select . Option value = "scriptcat" > { t ( "favicon_service_scriptcat" ) } </ Select . Option >
340+ < Select . Option value = "google" > { t ( "favicon_service_google" ) } </ Select . Option >
341+ < Select . Option value = "local" > { t ( "favicon_service_local" ) } </ Select . Option >
342+ </ Select >
343+ </ div >
344+ < span className = "tw-text-xs tw-ml-6 tw-flex-shrink-0" > { t ( "favicon_service_desc" ) } </ span >
345+ </ div >
309346 </ Space >
310347 </ Card >
311348
0 commit comments