diff --git a/src-tauri/src/backend.rs b/src-tauri/src/backend.rs index 5886def..65a042e 100644 --- a/src-tauri/src/backend.rs +++ b/src-tauri/src/backend.rs @@ -4422,10 +4422,29 @@ fn get_mod_cache_status() -> Result { } #[tauri::command] -fn show_log_window() { - if let Err(error) = open::that(crate::logging::path()) { - crate::logging::error(format_args!("Failed to open CeleMod log: {error}")); - } +fn show_log_window() -> Result<(), String> { + let path = crate::logging::path(); + #[cfg(windows)] + let result = match open::that(path) { + Ok(()) => Ok(()), + Err(default_error) => std::process::Command::new("notepad.exe") + .arg(path) + .spawn() + .map(|_| ()) + .map_err(|notepad_error| { + format!( + "default opener failed: {default_error}; Notepad fallback failed: {notepad_error}" + ) + }), + }; + #[cfg(not(windows))] + let result = open::that(path).map_err(|error| error.to_string()); + + result.map_err(|error| { + let message = format!("Failed to open CeleMod log {}: {error}", path.display()); + crate::logging::error(format_args!("{message}")); + message + }) } #[tauri::command] diff --git a/src/celemod-ui/locales/de-DE.json b/src/celemod-ui/locales/de-DE.json index 12b062b..8492a44 100644 --- a/src/celemod-ui/locales/de-DE.json +++ b/src/celemod-ui/locales/de-DE.json @@ -79,6 +79,7 @@ "神烦的狗": "Frustrierender Hund", "狐狸": "Fuchs", "加载中...": "Wird geladen...", + "左键检查更新,右键打开日志 / Left click to check updates, right click to open the log": "Linksklick prüft auf Updates, Rechtsklick öffnet das Protokoll", "无数据": "Keine Daten", "安装": "Installation", "当前安装的 Everest 版本": "Aktuell installierte Everest-Version", @@ -309,9 +310,9 @@ "小时": "小时", "当前来源": "当前来源", "记录数": "记录数", - "缓存尚未建立": "缓存尚未建立", - "刷新中…": "刷新中…", - "立即刷新": "立即刷新", + "缓存尚未建立": "Cache noch nicht erstellt", + "刷新中…": "Wird aktualisiert…", + "立即刷新": "Jetzt aktualisieren", "界面": "界面", "使用系统窗口模糊和半透明背景": "使用系统窗口模糊和半透明背景", "语言/Language": "语言/Language", @@ -351,12 +352,16 @@ "删除损坏文件": "删除损坏文件", "完成": "完成", "检查中…": "检查中…", + "检查更新": "Nach Updates suchen", + "检查完成": "Prüfung abgeschlossen", + "检查失败": "Prüfung fehlgeschlagen", "{visible} / {total} 个 Mod": "{visible} / {total} 个 Mod", "搜索名称、备注、作者或文件…": "搜索名称、备注、作者或文件…", "筛选已下载 Mod": "筛选已下载 Mod", "重置": "重置", "启用状态": "启用状态", "依赖状态": "依赖状态", + "仅显示重复 Mod": "Nur doppelte Mods anzeigen", "正常": "正常", "有问题": "有问题", "缺失依赖": "缺失依赖", diff --git a/src/celemod-ui/locales/en-US.json b/src/celemod-ui/locales/en-US.json index f7a6e0a..122d70c 100644 --- a/src/celemod-ui/locales/en-US.json +++ b/src/celemod-ui/locales/en-US.json @@ -252,6 +252,9 @@ "小时": "hours", "当前来源": "Current source", "记录数": "Record count", + "缓存尚未建立": "Cache not created yet", + "刷新中…": "Refreshing…", + "立即刷新": "Refresh now", "界面": "Interface", "使用系统窗口模糊和半透明背景": "Use system window blur and semi-transparent background", "切换界面显示语言": "Switch interface display language", @@ -284,6 +287,9 @@ "删除损坏文件": "Delete corrupted files", "完成": "Done", "检查中…": "Checking…", + "检查更新": "Check for updates", + "检查完成": "Check complete", + "检查失败": "Check failed", "{visible} / {total} 个 Mod": "{visible} / {total} Mods", "搜索名称、备注、作者或文件…": "Search by name, note, author, or file...", "筛选已下载 Mod": "Filter Downloaded Mods", @@ -294,6 +300,7 @@ "有问题": "Something went wrong", "缺失依赖": "Missing dependencies", "仅显示可更新": "Show updatable only", + "仅显示重复 Mod": "Show duplicate Mods only", "显示设置中隐藏的类型": "Types hidden in display settings", "操作": "Actions", "展开全部": "Expand all", @@ -335,7 +342,7 @@ "undefined": "undefined", "更多": "More", "加载中": "Loading", - "左键检查更新,右键切换控制台 / Left click to check updates, right click to toggle console": "Left click to check updates, right click to toggle console", + "左键检查更新,右键打开日志 / Left click to check updates, right click to open the log": "Left click to check updates, right click to open the log", "发现无效 Mod 压缩包": "Found invalid Mod archive", "以下文件不是有效的 zip,继续保留可能导致游戏崩溃:": "The following files are not valid zips; keeping them may cause the game to crash:", "暂不处理": "Not now", diff --git a/src/celemod-ui/locales/fr-FR.json b/src/celemod-ui/locales/fr-FR.json index d9772a3..ba5f51d 100644 --- a/src/celemod-ui/locales/fr-FR.json +++ b/src/celemod-ui/locales/fr-FR.json @@ -79,6 +79,7 @@ "神烦的狗": "Chien de Dieu", "狐狸": "renard", "加载中...": "chargement...", + "左键检查更新,右键打开日志 / Left click to check updates, right click to open the log": "Clic gauche pour vérifier les mises à jour, clic droit pour ouvrir le journal", "无数据": "pas de données", "安装": "Installer", "当前安装的 Everest 版本": "La version everest actuellement installée", @@ -309,9 +310,9 @@ "小时": "小时", "当前来源": "当前来源", "记录数": "记录数", - "缓存尚未建立": "缓存尚未建立", - "刷新中…": "刷新中…", - "立即刷新": "立即刷新", + "缓存尚未建立": "Cache non créé", + "刷新中…": "Actualisation…", + "立即刷新": "Actualiser maintenant", "界面": "界面", "使用系统窗口模糊和半透明背景": "使用系统窗口模糊和半透明背景", "语言/Language": "语言/Language", @@ -351,12 +352,16 @@ "删除损坏文件": "删除损坏文件", "完成": "完成", "检查中…": "检查中…", + "检查更新": "Vérifier les mises à jour", + "检查完成": "Vérification terminée", + "检查失败": "Échec de la vérification", "{visible} / {total} 个 Mod": "{visible} / {total} 个 Mod", "搜索名称、备注、作者或文件…": "搜索名称、备注、作者或文件…", "筛选已下载 Mod": "筛选已下载 Mod", "重置": "重置", "启用状态": "启用状态", "依赖状态": "依赖状态", + "仅显示重复 Mod": "Afficher uniquement les mods en double", "正常": "正常", "有问题": "有问题", "缺失依赖": "缺失依赖", diff --git a/src/celemod-ui/locales/pt-BR.json b/src/celemod-ui/locales/pt-BR.json index 350aad5..17d2dc0 100644 --- a/src/celemod-ui/locales/pt-BR.json +++ b/src/celemod-ui/locales/pt-BR.json @@ -246,6 +246,9 @@ "小时": "horas", "当前来源": "Fonte atual", "记录数": "Número de registros", + "缓存尚未建立": "O cache ainda não foi criado", + "刷新中…": "Atualizando…", + "立即刷新": "Atualizar agora", "界面": "Interface", "使用系统窗口模糊和半透明背景": "Use system window blur and semi-transparent background", "切换界面显示语言": "Alternar o idioma da interface", @@ -276,6 +279,9 @@ "删除损坏文件": "Excluir arquivos corrompidos", "完成": "Concluído", "检查中…": "Verificando…", + "检查更新": "Verificar atualizações", + "检查完成": "Verificação concluída", + "检查失败": "Falha na verificação", "{visible} / {total} 个 Mod": "{visible} / {total} mods", "搜索名称、备注、作者或文件…": "Pesquisar por nome, nota, autor ou arquivo…", "筛选已下载 Mod": "Filtrar mods baixados", @@ -286,6 +292,7 @@ "有问题": "Tem problema", "缺失依赖": "Dependência ausente", "仅显示可更新": "Mostrar apenas atualizáveis", + "仅显示重复 Mod": "Mostrar apenas mods duplicados", "显示设置中隐藏的类型": "Tipos ocultos nas configurações de exibição", "操作": "Ações", "展开全部": "Expandir tudo", @@ -327,7 +334,7 @@ "undefined": "undefined", "更多": "Mais", "加载中": "Carregando", - "左键检查更新,右键切换控制台 / Left click to check updates, right click to toggle console": "Clique esquerdo para verificar atualizações, clique direito para alternar o console", + "左键检查更新,右键打开日志 / Left click to check updates, right click to open the log": "Clique esquerdo para verificar atualizações; clique direito para abrir o log", "发现无效 Mod 压缩包": "Arquivo de Mod inválido encontrado", "以下文件不是有效的 zip,继续保留可能导致游戏崩溃:": "Os seguintes arquivos não são um zip válido, mantê-los pode causar falhas no jogo:", "暂不处理": "Não processar agora", diff --git a/src/celemod-ui/locales/ru-RU.json b/src/celemod-ui/locales/ru-RU.json index 930bfec..ea30775 100644 --- a/src/celemod-ui/locales/ru-RU.json +++ b/src/celemod-ui/locales/ru-RU.json @@ -246,6 +246,9 @@ "小时": "часы", "当前来源": "Текущий источник", "记录数": "Количество записей", + "缓存尚未建立": "Кэш ещё не создан", + "刷新中…": "Обновление…", + "立即刷新": "Обновить сейчас", "界面": "Интерфейс", "使用系统窗口模糊和半透明背景": "Использовать системное размытие окна и полупрозрачный фон", "切换界面显示语言": "Переключить язык интерфейса", @@ -276,6 +279,9 @@ "删除损坏文件": "Удалить поврежденные файлы", "完成": "Готово", "检查中…": "Проверка…", + "检查更新": "Проверить обновления", + "检查完成": "Проверка завершена", + "检查失败": "Проверка не удалась", "{visible} / {total} 个 Mod": "{visible} / {total} модов", "搜索名称、备注、作者或文件…": "Поиск по названию, описанию, автору или файлу…", "筛选已下载 Mod": "Фильтровать загруженные моды", @@ -286,6 +292,7 @@ "有问题": "Есть проблема", "缺失依赖": "Отсутствующая зависимость", "仅显示可更新": "Показывать только обновляемые", + "仅显示重复 Mod": "Показывать только дублирующиеся моды", "显示设置中隐藏的类型": "Типы, скрытые в настройках", "操作": "Действия", "展开全部": "Развернуть все", @@ -327,7 +334,7 @@ "undefined": "undefined", "更多": "Ещё", "加载中": "Загрузка", - "左键检查更新,右键切换控制台 / Left click to check updates, right click to toggle console": "ЛКМ — проверить обновления, ПКМ — переключить консоль", + "左键检查更新,右键打开日志 / Left click to check updates, right click to open the log": "ЛКМ — проверить обновления, ПКМ — открыть журнал", "发现无效 Mod 压缩包": "Обнаружен недействительный архив мода", "以下文件不是有效的 zip,继续保留可能导致游戏崩溃:": "Следующие файлы не являются допустимыми zip-архивами, их сохранение может привести к сбою игры:", "暂不处理": "Не обрабатывать", diff --git a/src/celemod-ui/locales/zh-CN.json b/src/celemod-ui/locales/zh-CN.json index c8427ef..798c2ea 100644 --- a/src/celemod-ui/locales/zh-CN.json +++ b/src/celemod-ui/locales/zh-CN.json @@ -252,6 +252,9 @@ "小时": "小时", "当前来源": "当前来源", "记录数": "记录数", + "缓存尚未建立": "缓存尚未建立", + "刷新中…": "刷新中…", + "立即刷新": "立即刷新", "界面": "界面", "使用系统窗口模糊和半透明背景": "使用系统窗口模糊和半透明背景", "切换界面显示语言": "切换界面显示语言", @@ -284,6 +287,9 @@ "删除损坏文件": "删除损坏文件", "完成": "完成", "检查中…": "检查中…", + "检查更新": "检查更新", + "检查完成": "检查完成", + "检查失败": "检查失败", "{visible} / {total} 个 Mod": "{visible} / {total} 个 Mod", "搜索名称、备注、作者或文件…": "搜索名称、备注、作者或文件…", "筛选已下载 Mod": "筛选已下载 Mod", @@ -294,6 +300,7 @@ "有问题": "有问题", "缺失依赖": "缺失依赖", "仅显示可更新": "仅显示可更新", + "仅显示重复 Mod": "仅显示重复 Mod", "显示设置中隐藏的类型": "显示设置中隐藏的类型", "操作": "操作", "展开全部": "展开全部", @@ -335,7 +342,7 @@ "undefined": "undefined", "更多": "更多", "加载中": "加载中", - "左键检查更新,右键切换控制台 / Left click to check updates, right click to toggle console": "左键检查更新,右键切换控制台 / Left click to check updates, right click to toggle console", + "左键检查更新,右键打开日志 / Left click to check updates, right click to open the log": "左键检查更新,右键打开日志 / Left click to check updates, right click to open the log", "发现无效 Mod 压缩包": "发现无效 Mod 压缩包", "以下文件不是有效的 zip,继续保留可能导致游戏崩溃:": "以下文件不是有效的 zip,继续保留可能导致游戏崩溃:", "暂不处理": "暂不处理", diff --git a/src/celemod-ui/src/api/modCatalog.ts b/src/celemod-ui/src/api/modCatalog.ts index 9983994..0052da0 100644 --- a/src/celemod-ui/src/api/modCatalog.ts +++ b/src/celemod-ui/src/api/modCatalog.ts @@ -79,6 +79,7 @@ export interface LocalSubmission extends Content { let catalog: CatalogMod[] | null = null; let catalogPromise: Promise | null = null; +let catalogRequestId = 0; export const loadModCatalog = async ( ttlHours = 1, @@ -88,20 +89,25 @@ export const loadModCatalog = async ( if (catalog && !forceRefresh) return catalog; if (catalogPromise && !forceRefresh) return catalogPromise; - catalogPromise = callRemote("get_mod_catalog", forceRefresh) + const requestId = ++catalogRequestId; + let request: Promise; + request = callRemote("get_mod_catalog", forceRefresh) .then((raw) => { const parsed = JSON.parse(raw) as CatalogResponse; - catalog = Array.isArray(parsed.data) ? parsed.data : []; - return catalog; + const nextCatalog = Array.isArray(parsed.data) ? parsed.data : []; + if (requestId === catalogRequestId) catalog = nextCatalog; + return nextCatalog; }) .finally(() => { - catalogPromise = null; + if (catalogPromise === request) catalogPromise = null; }); - return catalogPromise; + catalogPromise = request; + return request; }; export const clearInMemoryModCatalog = () => { catalog = null; + catalogRequestId += 1; catalogPromise = null; }; diff --git a/src/celemod-ui/src/api/updateInfo.ts b/src/celemod-ui/src/api/updateInfo.ts index 43b5cc0..73c5d6e 100644 --- a/src/celemod-ui/src/api/updateInfo.ts +++ b/src/celemod-ui/src/api/updateInfo.ts @@ -82,6 +82,22 @@ const UPDATE_INFO_URL = "https://ganbei-hot-update-1258625969.file.myqcloud.com/celemod/updateInfo.json"; let cachedUpdateInfo: Promise | null = null; +let cachedUpdateInfoRequestId = 0; +let forcedUpdateInfoRequest: Promise | null = null; +let lastForcedUpdateAt = 0; +const MANUAL_REFRESH_COOLDOWN_MS = 10_000; +type UpdateInfoListener = (value: UpdateInfo) => void; +const updateInfoListeners = new Set(); + +const notifyUpdateInfo = (value: UpdateInfo) => { + for (const listener of updateInfoListeners) { + try { + listener(value); + } catch (error) { + console.error("Failed to notify update info listener", error); + } + } +}; const parseUpdateInfo = (text: string) => JSON.parse( @@ -93,7 +109,11 @@ const parseUpdateInfo = (text: string) => export const getLatestUpdateInfo = (forceRefresh = false) => { if (!cachedUpdateInfo || forceRefresh) { - cachedUpdateInfo = fetch(`${UPDATE_INFO_URL}?${Date.now()}`) + const requestId = ++cachedUpdateInfoRequestId; + console.info( + `[update-info] Fetching latest version information (${forceRefresh ? "forced refresh" : "cache miss"}, request ${requestId})`, + ); + const request = fetch(`${UPDATE_INFO_URL}?${Date.now()}-${requestId}`) .then((response) => { if (!response.ok) throw new Error( @@ -102,19 +122,66 @@ export const getLatestUpdateInfo = (forceRefresh = false) => { return response.text(); }) .then(parseUpdateInfo) - .catch((error) => { - cachedUpdateInfo = null; - throw error; + .then((value) => { + console.info( + `[update-info] Latest version information loaded: ${value.version} (request ${requestId})`, + ); + return value; }); + cachedUpdateInfo = request; + void request.then( + (value) => { + if ( + cachedUpdateInfo === request && + cachedUpdateInfoRequestId === requestId + ) { + notifyUpdateInfo(value); + } + }, + () => { + if ( + cachedUpdateInfo === request && + cachedUpdateInfoRequestId === requestId + ) { + cachedUpdateInfo = null; + } + }, + ); + } else { + console.info( + `[update-info] Using cached latest version information (request ${cachedUpdateInfoRequestId})`, + ); } return cachedUpdateInfo; }; -export const featureVisible = ( - feature: { enabled: boolean; only_zh_cn?: boolean } | null | undefined, - currentLang: string, -) => - Boolean(feature?.enabled && (!feature.only_zh_cn || currentLang === "zh-CN")); +export const refreshLatestUpdateInfo = () => { + if (forcedUpdateInfoRequest) return forcedUpdateInfoRequest; + const now = Date.now(); + if (cachedUpdateInfo && now - lastForcedUpdateAt < MANUAL_REFRESH_COOLDOWN_MS) { + console.info( + `[update-info] Manual refresh throttled; using cached request ${cachedUpdateInfoRequestId}`, + ); + return cachedUpdateInfo; + } + lastForcedUpdateAt = now; + const request = getLatestUpdateInfo(true); + forcedUpdateInfoRequest = request; + void request.then( + () => { + if (forcedUpdateInfoRequest === request) forcedUpdateInfoRequest = null; + }, + () => { + if (forcedUpdateInfoRequest === request) forcedUpdateInfoRequest = null; + }, + ); + return request; +}; + +export const subscribeToUpdateInfo = (listener: UpdateInfoListener) => { + updateInfoListeners.add(listener); + return () => updateInfoListeners.delete(listener); +}; export const useUpdateInfo = () => { const [data, setData] = useState(null); @@ -122,13 +189,37 @@ export const useUpdateInfo = () => { useEffect(() => { let active = true; - getLatestUpdateInfo() - .then((value) => active && setData(value)) - .catch((reason) => active && setError(reason)); + const unsubscribe = subscribeToUpdateInfo((value) => { + if (!active) return; + setData(value); + setError(null); + }); + const request = getLatestUpdateInfo(); + const requestId = cachedUpdateInfoRequestId; + void request.then( + (value) => { + if (active && requestId === cachedUpdateInfoRequestId) { + setData(value); + setError(null); + } + }, + (reason) => { + if (active && requestId === cachedUpdateInfoRequestId) + setError(reason); + }, + ); return () => { active = false; + unsubscribe(); }; }, []); return { data, error }; }; + +export const featureVisible = ( + feature: { enabled: boolean; only_zh_cn?: boolean } | null | undefined, + currentLang: string, +) => + Boolean(feature?.enabled && (!feature.only_zh_cn || currentLang === "zh-CN")); + diff --git a/src/celemod-ui/src/components/SelfUpdate.tsx b/src/celemod-ui/src/components/SelfUpdate.tsx index 84e461b..7ebdf74 100644 --- a/src/celemod-ui/src/components/SelfUpdate.tsx +++ b/src/celemod-ui/src/components/SelfUpdate.tsx @@ -4,14 +4,20 @@ import { callRemote, compareVersion } from "../utils"; import "./SelfUpdate.scss"; import { useState } from "react"; import { ProgressIndicator } from "./Progress"; -import { getLatestUpdateInfo } from "../api/updateInfo"; +import { + getLatestUpdateInfo, + refreshLatestUpdateInfo, +} from "../api/updateInfo"; -export const checkUpdate = async () => { +export const checkUpdate = async (forceRefresh = false) => { const currentVersion = (await callRemote("celemod_version")) .split("") .filter((v) => v === "." || !isNaN(parseInt(v))) .join(""); - const info = await getLatestUpdateInfo(); + const info = await (forceRefresh + ? refreshLatestUpdateInfo() + : getLatestUpdateInfo()); + const latestVersion = info.version .split("") .filter((v) => v === "." || !isNaN(parseInt(v))) diff --git a/src/celemod-ui/src/components/WindowTitlebar.tsx b/src/celemod-ui/src/components/WindowTitlebar.tsx index 4d8bf3d..1294e0e 100644 --- a/src/celemod-ui/src/components/WindowTitlebar.tsx +++ b/src/celemod-ui/src/components/WindowTitlebar.tsx @@ -59,15 +59,16 @@ export function WindowTitlebar() { + {gamePath && newKeyboardInputEnabled === true ? ( diff --git a/src/celemod-ui/src/routes/Manage.tsx b/src/celemod-ui/src/routes/Manage.tsx index 0e4067b..90ad8e5 100644 --- a/src/celemod-ui/src/routes/Manage.tsx +++ b/src/celemod-ui/src/routes/Manage.tsx @@ -1134,6 +1134,10 @@ export const Manage = () => { const setEnabledFilter = useManageStore((state) => state.setEnabledFilter); const setHealthFilter = useManageStore((state) => state.setHealthFilter); const toggleType = useManageStore((state) => state.toggleType); + const setUpdateOnly = useManageStore((state) => state.setUpdateOnly); + const setDuplicateOnly = useManageStore( + (state) => state.setDuplicateOnly, + ); const setShowHiddenTypes = useManageStore( (state) => state.setShowHiddenTypes, ); @@ -1297,6 +1301,7 @@ export const Manage = () => { health: "all" as const, types: [], updateOnly: false, + duplicateOnly: false, showHiddenTypes: true, }), [filters], @@ -2021,6 +2026,7 @@ export const Manage = () => { Number(filters.enabled !== "all") + Number(filters.health !== "all") + Number(filters.updateOnly) + + Number(filters.duplicateOnly) + Number(filters.showHiddenTypes) + Number(rootOnly) + Number(fullTree); @@ -2112,6 +2118,26 @@ export const Manage = () => {
+ +
+
+ + {cacheStatus?.path || _i18n.t("缓存尚未建立")} + + +
{cacheError &&
{cacheError}
} diff --git a/src/celemod-ui/src/stores/manage.ts b/src/celemod-ui/src/stores/manage.ts index d2b3628..33b47c2 100644 --- a/src/celemod-ui/src/stores/manage.ts +++ b/src/celemod-ui/src/stores/manage.ts @@ -106,6 +106,7 @@ interface ManageFilters { health: ManageHealthFilter; types: string[]; updateOnly: boolean; + duplicateOnly: boolean; showHiddenTypes: boolean; } @@ -132,6 +133,7 @@ interface ManageTreeState { setHealthFilter: (health: ManageHealthFilter) => void; toggleType: (type: string) => void; setUpdateOnly: (value: boolean) => void; + setDuplicateOnly: (value: boolean) => void; setShowHiddenTypes: (value: boolean) => void; resetFilters: () => void; setFilterOpen: (value: boolean) => void; @@ -146,6 +148,7 @@ const defaultFilters: ManageFilters = { health: "all", types: [], updateOnly: false, + duplicateOnly: false, showHiddenTypes: false, }; @@ -267,6 +270,11 @@ export const useManageStore = create()( state.filters.updateOnly = value; }); }, + setDuplicateOnly(value) { + set((state) => { + state.filters.duplicateOnly = value; + }); + }, setShowHiddenTypes(value) { set((state) => { state.filters.showHiddenTypes = value; @@ -536,6 +544,7 @@ export const selectVisibleRootNames = ({ if (filters.enabled === "enabled" && !node.enabled) return false; if (filters.enabled === "disabled" && node.enabled) return false; if (filters.updateOnly && !updateNames.has(node.name)) return false; + if (filters.duplicateOnly && node.duplicateFiles.length < 2) return false; const health = getDependencyHealth(node.name, nodes, includeOptional); if (filters.health === "healthy" && health.status !== "healthy") return false; diff --git a/src/celemod-ui/src/vite-env.d.ts b/src/celemod-ui/src/vite-env.d.ts index dfcd921..cd944ae 100644 --- a/src/celemod-ui/src/vite-env.d.ts +++ b/src/celemod-ui/src/vite-env.d.ts @@ -1,7 +1,7 @@ /// interface Window { - _checkUpdate(): Promise; + _checkUpdate(forceRefresh?: boolean): Promise; env: any; isMaximizable: boolean; storage: any;