From c4c875c6eff448af84f746ccc1f6d81bacced61c Mon Sep 17 00:00:00 2001 From: Caten Date: Fri, 12 Sep 2025 16:49:40 +0800 Subject: [PATCH] More English localization --- lib/l10n/intl_en.arb | 8 ++--- lib/l10n/intl_zh.arb | 2 +- lib/l10n/intl_zh_Hant.arb | 2 +- lib/main.dart | 34 ++++++++++++------ lib/workflow.dart | 74 +++++++++++++++++++++++++++++++++++---- 5 files changed, 96 insertions(+), 24 deletions(-) diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index eaf38d2..f0e7104 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -80,7 +80,7 @@ "openSourceLicenses": "Open Source Licenses", "permissionUsage": "Permission Usage", "privacyStatement": "\nThis app does not collect your private information.\n\nHowever, I cannot control behaviors of apps you install/use inside the container system (including via shortcut commands).\n\nRequested permissions are used for:\nFile permissions: accessing phone directories\nNotifications & accessibility: Required by Termux:X11", - "supportAuthor": "Support Author", + "supportAuthor": "Support Developers", "recommendApp": "If you find it useful, please recommend to others!", "projectUrl": "Project URL", "commandEdit": "Command Edit", @@ -98,15 +98,15 @@ "enterNumber": "Please enter a number", "enterValidNumber": "Please enter a valid number", "installingBootPackage": "Installing Boot Package", - "copyingContainerSystem": "Copying Container System", - "installingContainerSystem": "Installing Container System", + "copyingContainerSystem": "Copying System Files", + "installingContainerSystem": "Installing System Files", "installationComplete": "Installation Complete", "reinstallingBootPackage": "Reinstalling Boot Package", "issueUrl": "Issue Report", "faqUrl": "FAQ", "solutionUrl": "Usage Guide", "discussionUrl": "Discussion", - "firstLoadInstructions": "The first load may take about 5 to 10 minutes...\n\nNormally, the software will automatically redirect to the graphical interface after loading.\n\nIn the graphical interface:\n- Tap for left-click\n- Long press for right-click\n- Two-finger tap to open the keyboard\n- Two-finger swipe for mouse wheel\n\nPlease do not exit the software during installation.\n\nWhile waiting, you can click the button below to request permissions.\n\nMany folders in Tiny Computer (e.g., Downloads, Documents, Pictures) are bound to the corresponding device folders. Without these permissions, access to these folders will be denied.\n\nIf you don't need to access these folders, you can skip granting file permissions (but this may cause Firefox to fail when downloading files due to denied access to the Downloads folder).", + "firstLoadInstructions": "The first load takes about 5 to 10 minutes... and does not require an internet connection.\n\nNormally, the software will automatically redirect to the graphical interface after loading.\n\nIn the graphical interface:\n- Tap for left-click\n- Long press for right-click\n- Two-finger tap to open the keyboard\n- Two-finger swipe for mouse wheel\n\nPlease do not exit the software during installation.\n\nWhile waiting, you can click the button below to request permissions.\n\nMany folders in Tiny Computer (e.g., Downloads, Documents, Pictures) are bound to the corresponding device folders. Without these permissions, access to these folders will be denied.\n\nIf you don't need to access these folders, you can skip granting file permissions (but this may cause Firefox to fail when downloading files due to denied access to the Downloads folder).", "updateRequest": "Please try to use the latest version. Visit the project address to check for the latest version.", "avncScreenResize": "Adaptive Screen Size", "avncResizeFactor": "Screen Scaling Ratio", diff --git a/lib/l10n/intl_zh.arb b/lib/l10n/intl_zh.arb index 389e2e8..1c25799 100644 --- a/lib/l10n/intl_zh.arb +++ b/lib/l10n/intl_zh.arb @@ -106,7 +106,7 @@ "faqUrl": "常见问题", "solutionUrl": "典型场景使用指南", "discussionUrl": "论坛与讨论", - "firstLoadInstructions": "第一次加载大概需要5到10分钟...\n\n正常情况下,加载完成后软件会自动跳转到图形界面。\n\n在图形界面时:\n- 点击为鼠标左键\n- 长按为鼠标右键\n- 双指点击可弹出键盘\n- 双指划动为鼠标滚轮\n\n请不要在安装时退出软件。\n\n在等待时,可以点击下面的按钮申请一下权限。\n\n小小电脑的许多文件夹,比如下载、文档、图片等等都和设备的对应文件夹绑定,如果不授予这些权限会导致这些文件夹无权访问。\n\n但如果你不需要访问这些文件夹,也可以不授予文件权限(可能导致火狐浏览器下载文件失败,因为无权访问下载文件夹)。", + "firstLoadInstructions": "第一次加载大概需要5到10分钟...并且不需要网络。\n\n正常情况下,加载完成后软件会自动跳转到图形界面。\n\n在图形界面时:\n- 点击为鼠标左键\n- 长按为鼠标右键\n- 双指点击可弹出键盘\n- 双指划动为鼠标滚轮\n\n请不要在安装时退出软件。\n\n在等待时,可以点击下面的按钮申请一下权限。\n\n小小电脑的许多文件夹,比如下载、文档、图片等等都和设备的对应文件夹绑定,如果不授予这些权限会导致这些文件夹无权访问。\n\n但如果你不需要访问这些文件夹,也可以不授予文件权限(可能导致火狐浏览器下载文件失败,因为无权访问下载文件夹)。", "updateRequest": "请尽量使用最新版本。前往项目地址可查看最新版本。", "avncScreenResize": "自适应屏幕尺寸", "avncResizeFactor": "屏幕缩放比", diff --git a/lib/l10n/intl_zh_Hant.arb b/lib/l10n/intl_zh_Hant.arb index 6220f86..1fbfa5d 100644 --- a/lib/l10n/intl_zh_Hant.arb +++ b/lib/l10n/intl_zh_Hant.arb @@ -106,7 +106,7 @@ "faqUrl": "常見問題", "solutionUrl": "操作指南", "discussionUrl": "討論", - "firstLoadInstructions": "第一次載入大概需要5到10分鐘...\n\n正常情況下,載入完成後軟體會自動跳轉到圖形介面。\n\n在圖形介面時:\n- 點擊為滑鼠左鍵\n- 長按為滑鼠右鍵\n- 雙指點擊可彈出鍵盤\n- 雙指滑動為滑鼠滾輪\n\n請不要在安裝時退出軟體。\n\n在等待時,可以點擊下面的按鈕申請權限。\n\n小小電腦的許多資料夾,比如下載、文件、圖片等等都和裝置的這些資料夾綁定,如果不授予這些權限會導致這些資料夾無權存取。\n\n但如果你不需要存取這些資料夾,也可以不授予檔案權限(可能導致火狐瀏覽器下載檔案失敗,因為無權存取下載資料夾)。", + "firstLoadInstructions": "第一次加載大概需要5到10分鐘...並且不需要網絡。\n\n正常情況下,載入完成後軟體會自動跳轉到圖形介面。\n\n在圖形介面時:\n- 點擊為滑鼠左鍵\n- 長按為滑鼠右鍵\n- 雙指點擊可彈出鍵盤\n- 雙指滑動為滑鼠滾輪\n\n請不要在安裝時退出軟體。\n\n在等待時,可以點擊下面的按鈕申請權限。\n\n小小電腦的許多資料夾,比如下載、文件、圖片等等都和裝置的這些資料夾綁定,如果不授予這些權限會導致這些資料夾無權存取。\n\n但如果你不需要存取這些資料夾,也可以不授予檔案權限(可能導致火狐瀏覽器下載檔案失敗,因為無權存取下載資料夾)。", "updateRequest": "請盡量使用最新版本。前往專案網址查看最新版本。", "avncScreenResize": "自適應螢幕尺寸", "avncResizeFactor": "螢幕縮放比", diff --git a/lib/main.dart b/lib/main.dart index 850ec1f..2a4d8f3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -197,7 +197,7 @@ class _SettingPageState extends State { Navigator.of(context).pop(); }, child: Text(AppLocalizations.of(context)!.cancel)), TextButton(onPressed:() async { - await Util.setCurrentProp("boot", D.boot); + await Util.setCurrentProp("boot", Localizations.localeOf(context).languageCode == 'zh' ? D.boot : D.boot.replaceFirst('LANG=zh_CN.UTF-8', 'LANG=en_US.UTF-8').replaceFirst('公共', 'Public').replaceFirst('图片', 'Pictures').replaceFirst('音乐', 'Music').replaceFirst('视频', 'Videos').replaceFirst('下载', 'Downloads').replaceFirst('文档', 'Documents').replaceFirst('照片', 'Photos')); G.bootTextChange.value = !G.bootTextChange.value; if (!context.mounted) return; Navigator.of(context).pop(); @@ -579,14 +579,24 @@ sed -i -E "s@^(VNC_RESOLUTION)=.*@\\1=${w}x${h}@" \$(command -v startvnc)"""); const SizedBox.square(dimension: 16), Text(AppLocalizations.of(context)!.wineCommandsHint), const SizedBox.square(dimension: 8), - Wrap(alignment: WrapAlignment.center, spacing: 4.0, runSpacing: 4.0, children: D.wineCommands.asMap().entries.map( - (e) { - return OutlinedButton(style: D.commandButtonStyle, child: Text(e.value["name"]!), onPressed: () { - Util.termWrite("${e.value["command"]!} &"); - G.pageIndex.value = 0; - }); - } - ).toList()), + Wrap( + alignment: WrapAlignment.center, + spacing: 4.0, + runSpacing: 4.0, + children: (Localizations.localeOf(context).languageCode == 'zh' + ? D.wineCommands + : D.wineCommands4En + ).asMap().entries.map((e) { + return OutlinedButton( + style: D.commandButtonStyle, + child: Text(e.value["name"]!), + onPressed: () { + Util.termWrite("${e.value["command"]!} &"); + G.pageIndex.value = 0; + }, + ); + }).toList(), + ), const SizedBox.square(dimension: 16), const Divider(height: 2, indent: 8, endIndent: 8), const SizedBox.square(dimension: 16), @@ -1263,7 +1273,7 @@ class _FastCommandsState extends State { Navigator.of(context).pop(); }, child: Text(AppLocalizations.of(context)!.cancel)), TextButton(onPressed:() async { - await Util.setCurrentProp("commands", D.commands); + await Util.setCurrentProp("commands", Localizations.localeOf(context).languageCode == 'zh' ? D.commands : D.commands4En); setState(() {}); if (!context.mounted) return; Navigator.of(context).pop(); @@ -1290,7 +1300,9 @@ class _MyHomePageState extends State { @override void initState() { super.initState(); - _initializeWorkflow(); + Future.delayed(Duration.zero,() { + _initializeWorkflow(); + }); SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky, overlays: []); } diff --git a/lib/workflow.dart b/lib/workflow.dart index 33d6d66..7002ba7 100644 --- a/lib/workflow.dart +++ b/lib/workflow.dart @@ -384,6 +384,32 @@ class D { {"name":"???", "command":"timeout 8 cmatrix"} ]; + //默认快捷指令,英文版本 + static const commands4En = [{"name":"Update Packages", "command":"sudo dpkg --configure -a && sudo apt update && sudo apt full-upgrade -y && sudo apt autoremove -y"}, + {"name":"System Info", "command":"neofetch -L && neofetch --off"}, + {"name":"Clear", "command":"clear"}, + {"name":"Interrupt", "command":"\x03"}, + {"name":"Install Painting Program Krita", "command":"sudo apt update && sudo apt install -y krita krita-l10n"}, + {"name":"Uninstall Krita", "command":"sudo apt autoremove --purge -y krita krita-l10n"}, + {"name":"Install KDE Non-Linear Video Editor", "command":"sudo apt update && sudo apt install -y kdenlive"}, + {"name":"Uninstall Kdenlive", "command":"sudo apt autoremove --purge -y kdenlive"}, + {"name":"Install LibreOffice", "command":"sudo apt update && sudo apt install -y libreoffice"}, + {"name":"Uninstall LibreOffice", "command":"sudo apt autoremove --purge -y libreoffice"}, + {"name":"Install WPS", "command":r"""cat << 'EOF' | sh && sudo dpkg --configure -a && sudo apt update && sudo apt install -y /tmp/wps.deb +wget https://github.com/tiny-computer/third-party-archives/releases/download/archives/wps-office_11.1.0.11720_arm64.deb -O /tmp/wps.deb +EOF +rm /tmp/wps.deb"""}, + {"name":"Uninstall WPS", "command":"sudo apt autoremove --purge -y wps-office"}, + {"name":"Install CAJViewer", "command":"wget https://download.cnki.net/net.cnki.cajviewer_1.3.20-1_arm64.deb -O /tmp/caj.deb && sudo apt update && sudo apt install -y /tmp/caj.deb && bash /home/tiny/.local/share/tiny/caj/postinst; rm /tmp/caj.deb"}, + {"name":"Uninstall CAJViewer", "command":"sudo apt autoremove --purge -y net.cnki.cajviewer && bash /home/tiny/.local/share/tiny/caj/postrm"}, + {"name":"Install EdrawMax", "command":"wget https://cc-download.wondershare.cc/business/prd/edrawmax_13.1.0-1_arm64_binner.deb -O /tmp/edraw.deb && sudo apt update && sudo apt install -y /tmp/edraw.deb && bash /home/tiny/.local/share/tiny/edraw/postinst; rm /tmp/edraw.deb"}, + {"name":"Uninstall EdrawMax", "command":"sudo apt autoremove --purge -y edrawmax libldap-2.4-2"}, + {"name":"Enable Recycle Bin", "command":"sudo apt update && sudo apt install -y gvfs && echo 'Restart the app to use Recycle Bin.'"}, + {"name":"Clean Package Cache", "command":"sudo apt clean"}, + {"name":"Power Off", "command":"stopvnc\nexit\nexit"}, + {"name":"???", "command":"timeout 8 cmatrix"} + ]; + //默认wine快捷指令 static const wineCommands = [{"name":"Wine配置", "command":"winecfg"}, {"name":"修复方块字", "command":"regedit Z:\\\\home\\\\tiny\\\\.local\\\\share\\\\tiny\\\\extra\\\\chn_fonts.reg && wine reg delete \"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes\" /va /f"}, @@ -409,6 +435,31 @@ WINEDLLOVERRIDES="d3d8=b,d3d9=b,d3d10core=b,d3d11=b,dxgi=b" wine reg add 'HKEY_C {"name":"强制关闭Wine", "command":"wineserver -k"} ]; + //默认wine快捷指令,英文版本 + static const wineCommands4En = [{"name":"Wine Configuration", "command":"winecfg"}, + {"name":"Fix CJK Characters", "command":"regedit Z:\\\\home\\\\tiny\\\\.local\\\\share\\\\tiny\\\\extra\\\\chn_fonts.reg && wine reg delete \"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes\" /va /f"}, + {"name":"Start Menu Dir", "command":"wine explorer \"C:\\\\ProgramData\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\""}, + {"name":"Enable DXVK", "command":"""WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d8 /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d9 /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d10core /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d11 /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v dxgi /d native /f >/dev/null 2>&1"""}, + {"name":"Disable DXVK", "command":"""WINEDLLOVERRIDES="d3d8=b,d3d9=b,d3d10core=b,d3d11=b,dxgi=b" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d8 /d builtin /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=b,d3d9=b,d3d10core=b,d3d11=b,dxgi=b" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d9 /d builtin /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=b,d3d9=b,d3d10core=b,d3d11=b,dxgi=b" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d10core /d builtin /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=b,d3d9=b,d3d10core=b,d3d11=b,dxgi=b" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v d3d11 /d builtin /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=b,d3d9=b,d3d10core=b,d3d11=b,dxgi=b" wine reg add 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides' /v dxgi /d builtin /f >/dev/null 2>&1"""}, + {"name":"Explorer", "command":"wine explorer"}, + {"name":"Notepad", "command":"notepad"}, + {"name":"Minesweeper", "command":"winemine"}, + {"name":"Regedit", "command":"regedit"}, + {"name":"Control Panel", "command":"wine control"}, + {"name":"File Manager", "command":"winefile"}, + {"name":"Task Manager", "command":"wine taskmgr"}, + {"name":"IE Explorer", "command":"wine iexplore"}, + {"name":"Kill Wine Process", "command":"wineserver -k"} + ]; + //默认小键盘 static const termCommands = [ {"name": "Esc", "key": TerminalKey.escape}, @@ -554,10 +605,10 @@ chmod 1777 tmp //初次启动要做的事情 static Future initForFirstTime() async { //首先设置bootstrap - G.updateText.value = "正在安装引导包"; + G.updateText.value = AppLocalizations.of(G.homePageStateContext)!.installingBootPackage; await setupBootstrap(); - G.updateText.value = "正在复制容器系统"; + G.updateText.value = AppLocalizations.of(G.homePageStateContext)!.copyingContainerSystem; //存放容器的文件夹0和存放硬链接的文件夹.l2s Util.createDirFromString("${G.dataPath}/containers/0/.l2s"); //这个是容器rootfs,被split命令分成了xa*,放在assets里 @@ -566,7 +617,7 @@ chmod 1777 tmp await Util.copyAsset("assets/$name", "${G.dataPath}/$name"); } //-J - G.updateText.value = "正在安装容器系统"; + G.updateText.value = AppLocalizations.of(G.homePageStateContext)!.installingContainerSystem; await Util.execute( """ export DATA_DIR=${G.dataPath} @@ -596,18 +647,19 @@ cat tmp3 | while read -r group_name group_id; do fi done \$DATA_DIR/bin/busybox rm -rf xa* tmp1 tmp2 tmp3 +${Localizations.localeOf(G.homePageStateContext).languageCode == 'zh' ? "" : "echo 'LANG=en_US.UTF-8' > \$CONTAINER_DIR/usr/local/etc/tmoe-linux/locale.txt"} """); //一些数据初始化 //$DATA_DIR是数据文件夹, $CONTAINER_DIR是容器根目录 //Termux:X11的启动命令并不在这里面,而是写死了。这下成💩山代码了:P await G.prefs.setStringList("containersInfo", ["""{ "name":"GXDE OS", -"boot":"${D.boot}", +"boot":"${Localizations.localeOf(G.homePageStateContext).languageCode == 'zh' ? D.boot : D.boot.replaceFirst('LANG=zh_CN.UTF-8', 'LANG=en_US.UTF-8').replaceFirst('公共', 'Public').replaceFirst('图片', 'Pictures').replaceFirst('音乐', 'Music').replaceFirst('视频', 'Videos').replaceFirst('下载', 'Downloads').replaceFirst('文档', 'Documents').replaceFirst('照片', 'Photos')}", "vnc":"startnovnc &", "vncUrl":"http://localhost:36082/vnc.html?host=localhost&port=36082&autoconnect=true&resize=remote&password=12345678", -"commands":${jsonEncode(D.commands)} +"commands":${jsonEncode(Localizations.localeOf(G.homePageStateContext).languageCode == 'zh' ? D.commands : D.commands4En)} }"""]); - G.updateText.value = "安装完成"; + G.updateText.value = AppLocalizations.of(G.homePageStateContext)!.installationComplete; } static Future initData() async { @@ -631,13 +683,21 @@ done final String h = (min(s.width, s.height) * 0.75).round().toString(); G.postCommand = """sed -i -E "s@(geometry)=.*@\\1=${w}x${h}@" /etc/tigervnc/vncserver-config-tmoe sed -i -E "s@^(VNC_RESOLUTION)=.*@\\1=${w}x${h}@" \$(command -v startvnc)"""; + if (Localizations.localeOf(G.homePageStateContext).languageCode != 'zh') { + G.postCommand += "\nlocale-gen"; + // For English users, assume they need to enable terminal write + await G.prefs.setBool("isTerminalWriteEnabled", true); + await G.prefs.setBool("isTerminalCommandsEnabled", true); + await G.prefs.setBool("isStickyKey", false); + await G.prefs.setBool("wakelock", true); + } await G.prefs.setBool("getifaddrsBridge", (await DeviceInfoPlugin().androidInfo).version.sdkInt >= 31); } G.currentContainer = Util.getGlobal("defaultContainer") as int; //是否需要重新安装引导包? if (Util.getGlobal("reinstallBootstrap")) { - G.updateText.value = "正在重新安装引导包"; + G.updateText.value = AppLocalizations.of(G.homePageStateContext)!.reinstallingBootPackage; await setupBootstrap(); G.prefs.setBool("reinstallBootstrap", false); }