feat: Introduce shader cache cleaning options ('Keep Latest', 'Clean All') via a new dialog and refactor cleaning logic with new localization.

close: https://github.com/StarCitizenToolBox/app/issues/173
This commit is contained in:
xkeyC 2025-12-23 17:54:15 +08:00
parent 1a1f72a596
commit 66ead87d47
12 changed files with 208 additions and 13 deletions

View File

@ -2406,6 +2406,13 @@ class MessageLookup extends MessageLookupByLibrary {
"tools_rsi_launcher_enhance_working_msg2": MessageLookupByLibrary.simpleMessage( "tools_rsi_launcher_enhance_working_msg2": MessageLookupByLibrary.simpleMessage(
"Installing patch, this will take some time depending on your computer\'s performance...", "Installing patch, this will take some time depending on your computer\'s performance...",
), ),
"tools_shader_clean_all": MessageLookupByLibrary.simpleMessage("Clean All"),
"tools_shader_clean_dialog_title": MessageLookupByLibrary.simpleMessage(
"Clear Shader Cache",
),
"tools_shader_clean_keep_latest": MessageLookupByLibrary.simpleMessage(
"Keep Latest",
),
"tools_unp4k_action_cancel_multi_select": "tools_unp4k_action_cancel_multi_select":
MessageLookupByLibrary.simpleMessage("Cancel Multi-Select"), MessageLookupByLibrary.simpleMessage("Cancel Multi-Select"),
"tools_unp4k_action_deselect_all": MessageLookupByLibrary.simpleMessage( "tools_unp4k_action_deselect_all": MessageLookupByLibrary.simpleMessage(

View File

@ -2036,6 +2036,13 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage( MessageLookupByLibrary.simpleMessage(
"パッチをインストール中、これはコンピュータのパフォーマンスによって時間がかかります...", "パッチをインストール中、これはコンピュータのパフォーマンスによって時間がかかります...",
), ),
"tools_shader_clean_all": MessageLookupByLibrary.simpleMessage("すべてクリア"),
"tools_shader_clean_dialog_title": MessageLookupByLibrary.simpleMessage(
"シェーダーキャッシュをクリア",
),
"tools_shader_clean_keep_latest": MessageLookupByLibrary.simpleMessage(
"最新を保持",
),
"tools_unp4k_missing_runtime": MessageLookupByLibrary.simpleMessage( "tools_unp4k_missing_runtime": MessageLookupByLibrary.simpleMessage(
"ランタイムがありません", "ランタイムがありません",
), ),

View File

@ -2293,6 +2293,15 @@ class MessageLookup extends MessageLookupByLibrary {
"tools_rsi_launcher_enhance_working_msg2": MessageLookupByLibrary.simpleMessage( "tools_rsi_launcher_enhance_working_msg2": MessageLookupByLibrary.simpleMessage(
"Установка патча, это займет некоторое время в зависимости от производительности вашего компьютера...", "Установка патча, это займет некоторое время в зависимости от производительности вашего компьютера...",
), ),
"tools_shader_clean_all": MessageLookupByLibrary.simpleMessage(
"Очистить всё",
),
"tools_shader_clean_dialog_title": MessageLookupByLibrary.simpleMessage(
"Очистить кеш шейдеров",
),
"tools_shader_clean_keep_latest": MessageLookupByLibrary.simpleMessage(
"Сохранить последнее",
),
"tools_unp4k_missing_runtime": MessageLookupByLibrary.simpleMessage( "tools_unp4k_missing_runtime": MessageLookupByLibrary.simpleMessage(
"Отсутствует среда выполнения", "Отсутствует среда выполнения",
), ),

View File

@ -2044,6 +2044,13 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("生成补丁 ..."), MessageLookupByLibrary.simpleMessage("生成补丁 ..."),
"tools_rsi_launcher_enhance_working_msg2": "tools_rsi_launcher_enhance_working_msg2":
MessageLookupByLibrary.simpleMessage("安装补丁,这需要一点时间,取决于您的计算机性能 ..."), MessageLookupByLibrary.simpleMessage("安装补丁,这需要一点时间,取决于您的计算机性能 ..."),
"tools_shader_clean_all": MessageLookupByLibrary.simpleMessage("全部清理"),
"tools_shader_clean_dialog_title": MessageLookupByLibrary.simpleMessage(
"清理着色器缓存",
),
"tools_shader_clean_keep_latest": MessageLookupByLibrary.simpleMessage(
"保留最新",
),
"tools_unp4k_action_cancel_multi_select": "tools_unp4k_action_cancel_multi_select":
MessageLookupByLibrary.simpleMessage("取消多选"), MessageLookupByLibrary.simpleMessage("取消多选"),
"tools_unp4k_action_deselect_all": MessageLookupByLibrary.simpleMessage( "tools_unp4k_action_deselect_all": MessageLookupByLibrary.simpleMessage(

View File

@ -1907,6 +1907,13 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("生成補丁 ..."), MessageLookupByLibrary.simpleMessage("生成補丁 ..."),
"tools_rsi_launcher_enhance_working_msg2": "tools_rsi_launcher_enhance_working_msg2":
MessageLookupByLibrary.simpleMessage("安裝補丁,這需要一點時間,取決於您的電腦性能 ..."), MessageLookupByLibrary.simpleMessage("安裝補丁,這需要一點時間,取決於您的電腦性能 ..."),
"tools_shader_clean_all": MessageLookupByLibrary.simpleMessage("全部清理"),
"tools_shader_clean_dialog_title": MessageLookupByLibrary.simpleMessage(
"清理著色器緩存",
),
"tools_shader_clean_keep_latest": MessageLookupByLibrary.simpleMessage(
"保留最新",
),
"tools_unp4k_missing_runtime": MessageLookupByLibrary.simpleMessage( "tools_unp4k_missing_runtime": MessageLookupByLibrary.simpleMessage(
"缺少運行庫", "缺少運行庫",
), ),

View File

@ -9546,6 +9546,36 @@ class S {
args: [year], args: [year],
); );
} }
/// `Clear Shader Cache`
String get tools_shader_clean_dialog_title {
return Intl.message(
'Clear Shader Cache',
name: 'tools_shader_clean_dialog_title',
desc: '',
args: [],
);
}
/// `Keep Latest`
String get tools_shader_clean_keep_latest {
return Intl.message(
'Keep Latest',
name: 'tools_shader_clean_keep_latest',
desc: '',
args: [],
);
}
/// `Clean All`
String get tools_shader_clean_all {
return Intl.message(
'Clean All',
name: 'tools_shader_clean_all',
desc: '',
args: [],
);
}
} }
class AppLocalizationDelegate extends LocalizationsDelegate<S> { class AppLocalizationDelegate extends LocalizationsDelegate<S> {

View File

@ -1912,5 +1912,11 @@
"yearly_report_card_title": "{year} Yearly Report (Limited Time)", "yearly_report_card_title": "{year} Yearly Report (Limited Time)",
"@yearly_report_card_title": {}, "@yearly_report_card_title": {},
"yearly_report_card_desc": "View your Star Citizen gameplay statistics for {year}. Data is from local logs, please check on your main computer.", "yearly_report_card_desc": "View your Star Citizen gameplay statistics for {year}. Data is from local logs, please check on your main computer.",
"@yearly_report_card_desc": {} "@yearly_report_card_desc": {},
"tools_shader_clean_dialog_title": "Clear Shader Cache",
"@tools_shader_clean_dialog_title": {},
"tools_shader_clean_keep_latest": "Keep Latest",
"@tools_shader_clean_keep_latest": {},
"tools_shader_clean_all": "Clean All",
"@tools_shader_clean_all": {}
} }

View File

@ -1734,5 +1734,11 @@
"yearly_report_card_title": "{year} 年間レポート(期間限定)", "yearly_report_card_title": "{year} 年間レポート(期間限定)",
"@yearly_report_card_title": {}, "@yearly_report_card_title": {},
"yearly_report_card_desc": "{year}年のStar Citizenプレイ統計を表示します。データはローカルログからのものです。メインのコンピュータで確認してください。", "yearly_report_card_desc": "{year}年のStar Citizenプレイ統計を表示します。データはローカルログからのものです。メインのコンピュータで確認してください。",
"@yearly_report_card_desc": {} "@yearly_report_card_desc": {},
"tools_shader_clean_dialog_title": "シェーダーキャッシュをクリア",
"@tools_shader_clean_dialog_title": {},
"tools_shader_clean_keep_latest": "最新を保持",
"@tools_shader_clean_keep_latest": {},
"tools_shader_clean_all": "すべてクリア",
"@tools_shader_clean_all": {}
} }

View File

@ -1734,5 +1734,11 @@
"yearly_report_card_title": "Ежегодный отчет {year} (Ограниченное время)", "yearly_report_card_title": "Ежегодный отчет {year} (Ограниченное время)",
"@yearly_report_card_title": {}, "@yearly_report_card_title": {},
"yearly_report_card_desc": "Посмотрите статистику вашей игры в Star Citizen за {year} год. Данные из локальных логов, пожалуйста, проверяйте на основном компьютере.", "yearly_report_card_desc": "Посмотрите статистику вашей игры в Star Citizen за {year} год. Данные из локальных логов, пожалуйста, проверяйте на основном компьютере.",
"@yearly_report_card_desc": {} "@yearly_report_card_desc": {},
"tools_shader_clean_dialog_title": "Очистить кеш шейдеров",
"@tools_shader_clean_dialog_title": {},
"tools_shader_clean_keep_latest": "Сохранить последнее",
"@tools_shader_clean_keep_latest": {},
"tools_shader_clean_all": "Очистить всё",
"@tools_shader_clean_all": {}
} }

View File

@ -1328,5 +1328,8 @@
"yearly_report_powered_by": "由 SC 汉化盒子为您呈现", "yearly_report_powered_by": "由 SC 汉化盒子为您呈现",
"yearly_report_disclaimer": "数据使用您的本地日志生成,不会发送到任何第三方。因跨版本 Log 改动较大,数据可能不完整,仅供娱乐。", "yearly_report_disclaimer": "数据使用您的本地日志生成,不会发送到任何第三方。因跨版本 Log 改动较大,数据可能不完整,仅供娱乐。",
"yearly_report_card_title": "{year} 年度报告(限时)", "yearly_report_card_title": "{year} 年度报告(限时)",
"yearly_report_card_desc": "查看您在{year}年的星际公民游玩统计,数据来自本地 log ,请确保在常用电脑上查看。" "yearly_report_card_desc": "查看您在{year}年的星际公民游玩统计,数据来自本地 log ,请确保在常用电脑上查看。",
"tools_shader_clean_dialog_title": "清理着色器缓存",
"tools_shader_clean_keep_latest": "保留最新",
"tools_shader_clean_all": "全部清理"
} }

View File

@ -1670,5 +1670,8 @@
"yearly_report_powered_by": "由 SC工具箱為您呈現", "yearly_report_powered_by": "由 SC工具箱為您呈現",
"yearly_report_disclaimer": "數據使用您的本地日誌生成,不會發送到任何第三方。因跨版本 Log 改動較大,數據可能不完整,僅供娛樂。", "yearly_report_disclaimer": "數據使用您的本地日誌生成,不會發送到任何第三方。因跨版本 Log 改動較大,數據可能不完整,僅供娛樂。",
"yearly_report_card_title": "{year} 年度報告(限時)", "yearly_report_card_title": "{year} 年度報告(限時)",
"yearly_report_card_desc": "查看您在{year}年的星際公民遊玩統計,數據來自本地 log ,請確保在常用電腦上查看。" "yearly_report_card_desc": "查看您在{year}年的星際公民遊玩統計,數據來自本地 log ,請確保在常用電腦上查看。",
"tools_shader_clean_dialog_title": "清理著色器緩存",
"tools_shader_clean_keep_latest": "保留最新",
"tools_shader_clean_all": "全部清理"
} }

View File

@ -544,27 +544,131 @@ class ToolsUIModel extends _$ToolsUIModel {
state = state.copyWith(working: false); state = state.copyWith(working: false);
} }
/// GraphicsSettings
static Future<void> cleanShaderCache() async { static Future<void> cleanShaderCache() async {
await _cleanShaderCacheWithMode(keepLatest: false);
}
///
/// GraphicsSettings
static Future<void> cleanShaderCacheKeepLatest() async {
await _cleanShaderCacheWithMode(keepLatest: true);
}
///
/// [keepLatest] true: false:
static Future<void> _cleanShaderCacheWithMode({required bool keepLatest}) async {
final gameShaderCachePath = await SCLoggerHelper.getShaderCachePath(); final gameShaderCachePath = await SCLoggerHelper.getShaderCachePath();
final l = await Directory(gameShaderCachePath!).list(recursive: false).toList(); if (gameShaderCachePath == null) return;
for (var value in l) {
if (value is Directory) { final dir = Directory(gameShaderCachePath);
final dirName = value.path.split(Platform.pathSeparator).last; if (!await dir.exists()) return;
// starcitizen_*
final scDirs = <Directory>[];
final otherDirs = <Directory>[];
await for (var entity in dir.list(recursive: false)) {
if (entity is Directory) {
final dirName = entity.path.split(Platform.pathSeparator).last;
if (dirName == "Crashes") continue; if (dirName == "Crashes") continue;
// starcitizen_* GraphicsSettings
if (dirName.startsWith("starcitizen_")) { if (dirName.startsWith("starcitizen_")) {
await _cleanShaderCacheDirectory(value); scDirs.add(entity);
} else { } else {
await value.delete(recursive: true); otherDirs.add(entity);
} }
} }
} }
//
scDirs.sort((a, b) {
final aName = a.path.split(Platform.pathSeparator).last;
final bName = b.path.split(Platform.pathSeparator).last;
return bName.compareTo(aName);
});
// starcitizen_*
for (var d in otherDirs) {
try {
await d.delete(recursive: true);
} catch (e) {
dPrint("_cleanShaderCacheWithMode delete other dir error: $e");
}
}
// starcitizen_*
for (var i = 0; i < scDirs.length; i++) {
final scDir = scDirs[i];
if (keepLatest) {
//
//
// GraphicsSettings
// GraphicsSettings
if (i == 0) {
//
continue;
} else {
// GraphicsSettings
await _cleanShaderCacheDirectory(scDir);
}
} else {
//
// GraphicsSettings
// GraphicsSettings
await _cleanShaderCacheDirectory(scDir);
}
}
} }
Future<void> _cleanShaderCache(BuildContext context) async { Future<void> _cleanShaderCache(BuildContext context) async {
//
final result = await showDialog<String>(
context: context,
builder: (dialogContext) => ContentDialog(
title: Text(S.current.tools_shader_clean_dialog_title),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(height: 12),
SizedBox(
width: double.infinity,
child: FilledButton(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Text(S.current.tools_shader_clean_keep_latest),
),
onPressed: () => Navigator.pop(dialogContext, "keep_latest"),
),
),
const SizedBox(height: 12),
SizedBox(
width: double.infinity,
child: Button(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Text(S.current.tools_shader_clean_all),
),
onPressed: () => Navigator.pop(dialogContext, "clean_all"),
),
),
],
),
actions: [Button(child: Text(S.current.app_common_tip_cancel), onPressed: () => Navigator.pop(dialogContext))],
),
);
if (result == null || !context.mounted) return;
state = state.copyWith(working: true); state = state.copyWith(working: true);
await cleanShaderCache();
if (result == "keep_latest") {
await cleanShaderCacheKeepLatest();
} else {
await cleanShaderCache();
}
if (!context.mounted) return; if (!context.mounted) return;
loadToolsCard(context, skipPathScan: true); loadToolsCard(context, skipPathScan: true);
state = state.copyWith(working: false); state = state.copyWith(working: false);