diff --git a/src/apps/components/acceleratoroverview/AcceleratorOverview.svelte b/src/apps/components/acceleratoroverview/AcceleratorOverview.svelte index 173b0d3df..a3e966f7d 100755 --- a/src/apps/components/acceleratoroverview/AcceleratorOverview.svelte +++ b/src/apps/components/acceleratoroverview/AcceleratorOverview.svelte @@ -6,9 +6,9 @@ {#if $store && $apps} -
-

Keyboard Shortcuts

-

Get more work done faster with these handy shortcuts!

+
+

%title%

+

%subtitle%

{#each $store as [name, shortcuts]} diff --git a/src/apps/components/appinfo/AppInfo.ts b/src/apps/components/appinfo/AppInfo.ts index 335a73a8f..94a83fceb 100644 --- a/src/apps/components/appinfo/AppInfo.ts +++ b/src/apps/components/appinfo/AppInfo.ts @@ -5,7 +5,7 @@ import { AppInfoRuntime } from "./runtime"; const AppInfoApp: App = { metadata: { - name: "App Info", + name: "%apps.AppInfo._name%", author: "Izaak Kuipers", version: "3.0.1", icon: "AppInfoIcon", diff --git a/src/apps/components/appinfo/AppInfo/Actions.svelte b/src/apps/components/appinfo/AppInfo/Actions.svelte index b66bfad9b..b611d4353 100755 --- a/src/apps/components/appinfo/AppInfo/Actions.svelte +++ b/src/apps/components/appinfo/AppInfo/Actions.svelte @@ -21,7 +21,7 @@

{appId}

- - + +
diff --git a/src/apps/components/appinfo/AppInfo/Header.svelte b/src/apps/components/appinfo/AppInfo/Header.svelte index f7f6ebeba..6f11e317c 100755 --- a/src/apps/components/appinfo/AppInfo/Header.svelte +++ b/src/apps/components/appinfo/AppInfo/Header.svelte @@ -45,26 +45,36 @@

- {target?.metadata?.name || "Unknown"} + {target?.metadata?.name || "%general.unknown%"} {#if disabled} {/if}

-

{target?.metadata?.author || "No author"}

+

{target?.metadata?.author || "%general.noAuthor%"}

- + {#if (target?.entrypoint || target?.workingDirectory) && installed} - + {/if} - +
diff --git a/src/apps/components/appinfo/AppInfo/IndepthInfo.svelte b/src/apps/components/appinfo/AppInfo/IndepthInfo.svelte index 727ac884a..1dded77f6 100755 --- a/src/apps/components/appinfo/AppInfo/IndepthInfo.svelte +++ b/src/apps/components/appinfo/AppInfo/IndepthInfo.svelte @@ -11,43 +11,45 @@ - + {Math.max(0, target.size?.w || 0) || "F"} x {Math.max(0, target.size?.h || 0) || "F"} - + {Math.max(0, target.minSize?.w || 0) || "F"} x {Math.max(0, target.minSize?.h || 0) || "F"} - + {Math.max(0, target.maxSize?.w || 0) || "F"} x {Math.max(0, target.maxSize?.h || 0) || "F"} - +
- - - + + +
- + {#if target?.position?.centered} - Centered + %indepthInfo.centered% {:else if target?.position?.x || target.position?.y} {target?.position?.x}, {target?.position?.y} {:else} - Corner of screen + %indepthInfo.cornerOfScreen% {/if} - + {AppOrigins[target?.originId || "injected"]} - - {target?.core ? "Yes" : "No"} + + {target?.core ? "%general.yes%" : "%general.no%"} - - {target?.hidden ? "Yes" : "No"} + + {target?.hidden ? "%general.yes%" : "%general.no%"}
diff --git a/src/apps/components/appinfo/AppInfo/InternalInfo.svelte b/src/apps/components/appinfo/AppInfo/InternalInfo.svelte index e9361e6ff..71ad9bcb3 100644 --- a/src/apps/components/appinfo/AppInfo/InternalInfo.svelte +++ b/src/apps/components/appinfo/AppInfo/InternalInfo.svelte @@ -10,18 +10,18 @@ - + {target._internalLoadTime?.toFixed(2) || 0}ms - + {target._internalSysVer} - + {target._internalMinVer || "-"} - + {target._internalOriginalPath} diff --git a/src/apps/components/appinfo/AppInfo/ProcessInfo.svelte b/src/apps/components/appinfo/AppInfo/ProcessInfo.svelte index 68812697d..ba306d2aa 100755 --- a/src/apps/components/appinfo/AppInfo/ProcessInfo.svelte +++ b/src/apps/components/appinfo/AppInfo/ProcessInfo.svelte @@ -31,12 +31,12 @@ - - {count} instance(s) + + %processInfo.instances({count})% - - {pid < 0 ? "None" : pid} + + {pid < 0 ? "%general.none%" : pid} - + diff --git a/src/apps/components/appinfo/AppInfo/ThirdPartyInfo.svelte b/src/apps/components/appinfo/AppInfo/ThirdPartyInfo.svelte index 19393bacc..4159c96f8 100755 --- a/src/apps/components/appinfo/AppInfo/ThirdPartyInfo.svelte +++ b/src/apps/components/appinfo/AppInfo/ThirdPartyInfo.svelte @@ -10,19 +10,19 @@ - Yes - - {target.fileSignatures ? Object.entries(target.fileSignatures).length : "None"} + %general.yes% + + {target.fileSignatures ? Object.entries(target.fileSignatures).length : "%general.none%"} - - {target.process ? "Yes" : "No"} + + {target.process ? "%general.yes%" : "%general.no%"} - + {target.workingDirectory} - + {target.entrypoint} diff --git a/src/apps/components/appinfo/runtime.ts b/src/apps/components/appinfo/runtime.ts index 0d38c851e..ccf7c5cfe 100755 --- a/src/apps/components/appinfo/runtime.ts +++ b/src/apps/components/appinfo/runtime.ts @@ -22,12 +22,13 @@ export class AppInfoRuntime extends AppProcess { } async render() { + this.getBody().setAttribute("data-prefix", "apps.AppInfo"); const targetApp = this.appStore()?.getAppSynchronous(this.targetAppId); if (!targetApp) { this.userDaemon?.sendNotification({ - title: "App not found", - message: `AppInfo couldn't find any information about "${this.targetAppId}". Is it installed?`, + title: "%apps.AppInfo.noTargetApp.title%", + message: `%apps.AppInfo.noTargetApp.message(${this.targetAppId})%`, image: "AppInfoIcon", timeout: 6000, }); @@ -44,7 +45,7 @@ export class AppInfoRuntime extends AppProcess { async killAll() { const elevated = await this.userDaemon?.manuallyElevate({ - what: `ArcOS needs your permission to kill all instances of an app`, + what: `%apps.AppInfo.killAll.what%`, image: this.userDaemon?.getAppIcon(this.targetApp()) || this.getIconCached("ComponentIcon"), title: this.targetApp().metadata.name, description: this.targetAppId, diff --git a/src/apps/components/appinstaller/AppInstaller/Actions.svelte b/src/apps/components/appinstaller/AppInstaller/Actions.svelte index d8207de62..16520b4b0 100755 --- a/src/apps/components/appinstaller/AppInstaller/Actions.svelte +++ b/src/apps/components/appinstaller/AppInstaller/Actions.svelte @@ -8,14 +8,14 @@
{#if $failReason} - + {:else if $installing || $completed} {#if !isLibrary} - + {/if} {:else} - - + + {/if}
diff --git a/src/apps/components/appinstaller/AppInstaller/Header.svelte b/src/apps/components/appinstaller/AppInstaller/Header.svelte index 86c2707dc..522c4f963 100755 --- a/src/apps/components/appinstaller/AppInstaller/Header.svelte +++ b/src/apps/components/appinstaller/AppInstaller/Header.svelte @@ -23,7 +23,7 @@ Installing package... {/if} {:else if $failReason} - Installation failed + %header.title.failed% {:else} {metadata?.name} {/if} @@ -36,11 +36,11 @@ Click Open now to launch the app {/if} {:else if $installing} - {metadata?.name} by {metadata?.author} + %header.subtitle.installing({metadata?.name}::{metadata?.author})% {:else if $failReason} {$failReason} {:else} - {metadata?.author} - {metadata?.version} + %header.subtitle.generic({metadata?.author}::{metadata?.version})% {/if}

diff --git a/src/apps/components/appinstaller/AppInstaller/Log.svelte b/src/apps/components/appinstaller/AppInstaller/Log.svelte index e517446ac..a59f0357e 100755 --- a/src/apps/components/appinstaller/AppInstaller/Log.svelte +++ b/src/apps/components/appinstaller/AppInstaller/Log.svelte @@ -18,21 +18,21 @@ {#if !Object.entries($status).length && !$installing}
-

Ready to install

-

Click Install to install this package.

+

%readyToInstall.title%

+

%readyToInstall.message%

{:else} {#each Object.entries($status) as [uuid, item] (uuid)}

{#if item.type === "file"} - Writing file + %logType.file% {:else if item.type === "mkdir"} - Creating directory + %logType.mkdir% {:else if item.type === "registration"} - Registering + %logType.registration% {:else} - Status + %logType.generic% {/if}

{item.content}

diff --git a/src/apps/components/appinstaller/runtime.ts b/src/apps/components/appinstaller/runtime.ts index 85ea44887..36b149604 100755 --- a/src/apps/components/appinstaller/runtime.ts +++ b/src/apps/components/appinstaller/runtime.ts @@ -35,9 +35,9 @@ export class AppInstallerRuntime extends AppProcess { // Should never happen unless nik fucked something up (yes, nik) MessageBox( { - title: "Can't install package", - message: "The Distribution Service isn't running anymore. Please restart ArcOS to fix this problem.", - buttons: [{ caption: "Okay", action: () => {}, suggested: true }], + title: "%apps.AppInstaller.noDistrib.title%", + message: "%apps.AppInstaller.noDistrib.message%", + buttons: [{ caption: "%general.okay%", action: () => {}, suggested: true }], image: "ErrorIcon", sound: "arcos.dialog.error", }, @@ -53,24 +53,25 @@ export class AppInstallerRuntime extends AppProcess { } async render() { + this.getBody().setAttribute("data-prefix", "apps.AppInstaller"); + if (!this.userPreferences().security.enableThirdParty) { // The user has to allow TPAs explicitly MessageBox( { - title: "Can't install app", - message: - "Third-party apps aren't enabled on your account. Please enable third-party apps in the Settings to install this app.", + title: "%apps.AppInstaller.noEnableThirdParty.title%", + message: "%apps.AppInstaller.noEnableThirdParty.message%", image: "AppsIcon", sound: "arcos.dialog.warning", buttons: [ { - caption: "Take me there", + caption: "%apps.AppInstaller.noEnableThirdParty.takeMeThere%", action: () => { this.userDaemon?.spawnApp("systemSettings", +this.env.get("shell_pid"), "apps"); }, }, { - caption: "Okay", + caption: "%general.okay%", action: () => {}, suggested: true, }, @@ -95,7 +96,7 @@ export class AppInstallerRuntime extends AppProcess { // TODO: change rollback for library installment if (!this.isLibrary) { - const gli = await this.userDaemon?.GlobalLoadIndicator("Rolling back changes...", this.pid); + const gli = await this.userDaemon?.GlobalLoadIndicator("%apps.AppInstaller.rollback%", this.pid); try { await this.fs.deleteItem(this.metadata!.installLocation); diff --git a/src/apps/components/apppreinstall/AppPreinstall.svelte b/src/apps/components/apppreinstall/AppPreinstall.svelte index 4248a7cf0..6240c8857 100755 --- a/src/apps/components/apppreinstall/AppPreinstall.svelte +++ b/src/apps/components/apppreinstall/AppPreinstall.svelte @@ -10,17 +10,17 @@

{$metadata.name}

-

Do you want to install this package?

+

%header.title%

{$metadata.description}

-

Author

+

%info.author%

{$metadata.author}

-

Version

+

%info.version%

{$metadata.version}

@@ -28,9 +28,9 @@
- +
{:else}
diff --git a/src/apps/components/apppreinstall/runtime.ts b/src/apps/components/apppreinstall/runtime.ts index 120dbc15e..b7bd3d003 100755 --- a/src/apps/components/apppreinstall/runtime.ts +++ b/src/apps/components/apppreinstall/runtime.ts @@ -29,23 +29,24 @@ export class AppPreInstallRuntime extends AppProcess { } async render() { + this.getBody().setAttribute("data-prefix", "apps.AppPreInstall"); + if (!this.userPreferences().security.enableThirdParty) { MessageBox( { - title: "Can't install app", - message: - "Third-party apps aren't enabled on your account. Please enable third-party apps in the Settings to install this app.", + title: "%apps.AppPreInstall.noEnableThirdParty.title%", + message: "%apps.AppPreInstall.noEnableThirdParty.message%", image: "AppsIcon", sound: "arcos.dialog.warning", buttons: [ { - caption: "Take me there", + caption: "%apps.AppPreInstall.noEnableThirdParty.takeMeThere%", action: () => { this.userDaemon?.spawnApp("systemSettings", +this.env.get("shell_pid"), "apps"); }, }, { - caption: "Okay", + caption: "%general.okay%", action: () => {}, suggested: true, }, @@ -63,7 +64,7 @@ export class AppPreInstallRuntime extends AppProcess { { type: "size", icon: "DownloadIcon", - caption: "Reading ArcOS package", + caption: "%apps.AppPreInstall.readingPackage%", subtitle: this.pkgPath, }, +this.env.get("shell_pid") @@ -85,16 +86,30 @@ export class AppPreInstallRuntime extends AppProcess { await prog?.stop(); if (!content) { - return this.fail("The package contents could not be read"); + return this.fail("%apps.AppPreInstall.errors.noContents%"); } this.zip = new JSZip(); const buffer = await this.zip.loadAsync(content, {}); + + if (!buffer.files["_metadata.json"] || !buffer.files["payload/_app.tpa"]) { + return this.fail("%apps.AppPreInstall.errors.missingFiles%"); + } + const metaBinary = await buffer.files["_metadata.json"].async("arraybuffer"); const metadata = tryJsonParse(arrayToText(metaBinary)); + + if (!metadata || typeof metadata === "string") { + return this.fail("%apps.AppPreInstall.errors.noMeta%"); + } + + if (metadata.appId.includes(".") || metadata.appId.includes("-")) { + return this.fail("%apps.AppPreInstall.errors.appIdMalformed%"); + } + this.metadata.set(metadata); } catch { - return this.fail("Filesystem error"); + return this.fail("%apps.AppPreInstall.errors.fsError%"); } } @@ -104,9 +119,9 @@ export class AppPreInstallRuntime extends AppProcess { fail(reason: string) { MessageBox( { - title: "Failed to open package", - message: `ArcOS failed to open the specified package. ${reason}`, - buttons: [{ caption: "Okay", action: () => {}, suggested: true }], + title: "%apps.AppPreInstall.fail.title%", + message: `%apps.AppPreInstall.fail.messagePartial% ${reason}`, + buttons: [{ caption: "%general.okay%", action: () => {}, suggested: true }], image: "ErrorIcon", sound: "arcos.dialog.error", }, @@ -119,9 +134,9 @@ export class AppPreInstallRuntime extends AppProcess { async install() { const meta = this.metadata(); const elevated = await this.userDaemon?.manuallyElevate({ - what: "ArcOS wants to install an application", + what: "%apps.AppPreInstall.elevation.what%", title: meta.name, - description: `${meta.author} - ${meta.version}`, + description: `%apps.AppPreInstall.elevation.description(${meta.author}::${meta.version})%`, image: "ArcAppMimeIcon", level: ElevationLevel.medium, }); diff --git a/src/apps/components/arcfind/runtime.ts b/src/apps/components/arcfind/runtime.ts index f96d4163c..51ce93b2e 100755 --- a/src/apps/components/arcfind/runtime.ts +++ b/src/apps/components/arcfind/runtime.ts @@ -1,5 +1,7 @@ import { AppProcess } from "$ts/apps/process"; import { isPopulatable } from "$ts/apps/util"; +import { getKMod } from "$ts/env"; +import { I18n } from "$ts/kernel/mods/i18n"; import { UserPaths } from "$ts/server/user/store"; import { UUID } from "$ts/uuid"; import { Store } from "$ts/writable"; @@ -65,24 +67,24 @@ export class ArcFindRuntime extends AppProcess { if (sources.power) items.push( { - caption: "Shut down", - description: "Leave the desktop and turn off ArcOS", + caption: "%apps.ArcFindProc.powerOptions.shutdown.caption%", + description: "%apps.ArcFindProc.powerOptions.shutdown.description%", image: this.getIconCached("ShutdownIcon"), action: () => { this.userDaemon?.shutdown(); }, }, { - caption: "Restart", - description: "Leave the desktop and restart ArcOS", + caption: "%apps.ArcFindProc.powerOptions.restart.caption%", + description: "%apps.ArcFindProc.powerOptions.restart.description%", image: this.getIconCached("RestartIcon"), action: () => { this.userDaemon?.restart(); }, }, { - caption: "Log off", - description: "Leave the desktop and log out ArcOS", + caption: "%apps.ArcFindProc.powerOptions.logoff.caption%", + description: "%apps.ArcFindProc.powerOptions.logoff.description%", image: this.getIconCached("LogoutIcon"), action: () => { this.userDaemon?.logoff(); @@ -109,7 +111,7 @@ export class ArcFindRuntime extends AppProcess { if (preferences.searchOptions.excludeShortcuts && !!file.shortcut) continue; result.push({ caption: file.shortcut ? file.shortcut.name : file.name, - description: file.shortcut ? `Shortcut - ${file.path}` : file.path, + description: file.shortcut ? `%apps.ArcFindProc.fsSupplier.shortcut(${file.path})%` : file.path, action: () => { this.userDaemon?.openFile(file.path, file.shortcut); }, @@ -136,7 +138,7 @@ export class ArcFindRuntime extends AppProcess { ) { result.push({ caption: app.metadata.name, - description: `By ${app.metadata.author}`, + description: `%apps.ArcFindProc.appSupplier(${app.metadata.author})%`, image: this.getIconCached(`@app::${app.id}`), action: () => { this.spawnApp(app.id, this.pid); @@ -185,7 +187,14 @@ export class ArcFindRuntime extends AppProcess { keys: ["caption", "description"], }; - const fuse = new Fuse(this.searchItems, options); + const fuse = new Fuse( + this.searchItems.map((v) => ({ + ...v, + caption: getKMod("i18n").translateString(v.caption) || v.caption, + description: getKMod("i18n").translateString(v.description || "") || v.description, + })), + options + ); const result = fuse.search(query); return result.map((r) => ({ ...r, id: UUID() })); // Add a UUID to each search result diff --git a/src/apps/components/contextmenu/system.ts b/src/apps/components/contextmenu/system.ts index a30646e12..48154b258 100755 --- a/src/apps/components/contextmenu/system.ts +++ b/src/apps/components/contextmenu/system.ts @@ -12,14 +12,14 @@ export function WindowSystemContextMenu(runtime: ContextMenuRuntime): AppContext return { "_window-titlebar": [ { - caption: "App Info", + caption: "%apps.contextMenu.system.windowTitlebar.appInfo%", icon: "info", action: (proc: AppProcess) => { proc.spawnOverlayApp("AppInfo", +proc.env.get("shell_pid"), proc?.app.id); }, }, { - caption: "Process info", + caption: "%apps.contextMenu.system.windowTitlebar.processInfo%", icon: "cog", action: (proc: AppProcess) => { proc.spawnOverlayApp("ProcessInfoApp", +proc.env.get("shell_pid"), proc); @@ -28,7 +28,7 @@ export function WindowSystemContextMenu(runtime: ContextMenuRuntime): AppContext { sep: true }, { - caption: "Minimize", + caption: "%general.minimize%", action: (proc: AppProcess) => { KernelStack().renderer?.toggleMinimize(proc?.pid); }, @@ -37,7 +37,7 @@ export function WindowSystemContextMenu(runtime: ContextMenuRuntime): AppContext isActive: (proc: AppProcess) => !!proc?.getWindow()?.classList.contains("minimized"), }, { - caption: "Maximize", + caption: "%general.maximize%", action: (proc: AppProcess) => { KernelStack().renderer?.unsnapWindow(proc?.pid); KernelStack().renderer?.toggleMaximize(proc?.pid); @@ -48,64 +48,64 @@ export function WindowSystemContextMenu(runtime: ContextMenuRuntime): AppContext }, { sep: true }, { - caption: "Window snapping", + caption: "%apps.contextMenu.system.windowTitlebar.windowSnapping%", icon: "fullscreen", disabled: (proc: AppProcess) => !proc?.app.data.controls.maximize, isActive: (proc: AppProcess) => !!proc?.getWindow()?.classList.contains("snapped"), subItems: [ { - caption: "None", + caption: "%general.none%", icon: "x", action: (proc: AppProcess) => KernelStack().renderer?.unsnapWindow(proc?.pid), }, { sep: true }, { - caption: "Left", + caption: "%apps.contextMenu.system.windowTitlebar.snappingLeft%", icon: "arrow-left", action: (proc: AppProcess) => KernelStack().renderer?.snapWindow(proc?.pid, "left"), isActive: (proc: AppProcess) => proc?.getWindow()?.dataset.snapstate === "left", }, { - caption: "Right", + caption: "%apps.contextMenu.system.windowTitlebar.snappingRight%", icon: "arrow-right", action: (proc: AppProcess) => KernelStack().renderer?.snapWindow(proc?.pid, "right"), isActive: (proc: AppProcess) => proc?.getWindow()?.dataset.snapstate === "right", }, { sep: true }, { - caption: "Top", + caption: "%apps.contextMenu.system.windowTitlebar.snappingTop%", icon: "arrow-up", action: (proc: AppProcess) => KernelStack().renderer?.snapWindow(proc?.pid, "top"), isActive: (proc: AppProcess) => proc?.getWindow()?.dataset.snapstate === "top", }, { - caption: "Bottom", + caption: "%apps.contextMenu.system.windowTitlebar.snappingBottom%", icon: "arrow-down", action: (proc: AppProcess) => KernelStack().renderer?.snapWindow(proc?.pid, "bottom"), isActive: (proc: AppProcess) => proc?.getWindow()?.dataset.snapstate === "bottom", }, { sep: true }, { - caption: "Top Left", + caption: "%apps.contextMenu.system.windowTitlebar.snappingTopLeft%", icon: "arrow-up-left", action: (proc: AppProcess) => KernelStack().renderer?.snapWindow(proc?.pid, "top-left"), isActive: (proc: AppProcess) => proc?.getWindow()?.dataset.snapstate === "top-left", }, { - caption: "Top Right", + caption: "%apps.contextMenu.system.windowTitlebar.snappingTopRight%", icon: "arrow-up-right", action: (proc: AppProcess) => KernelStack().renderer?.snapWindow(proc?.pid, "top-right"), isActive: (proc: AppProcess) => proc?.getWindow()?.dataset.snapstate === "top-right", }, { sep: true }, { - caption: "Bottom Left", + caption: "%apps.contextMenu.system.windowTitlebar.snappingBottomLeft%", icon: "arrow-down-left", action: (proc: AppProcess) => KernelStack().renderer?.snapWindow(proc?.pid, "bottom-left"), isActive: (proc: AppProcess) => proc?.getWindow()?.dataset.snapstate === "bottom-left", }, { - caption: "Bottom Right", + caption: "%apps.contextMenu.system.windowTitlebar.snappingBottomRight%", icon: "arrow-down-right", action: (proc: AppProcess) => KernelStack().renderer?.snapWindow(proc?.pid, "bottom-right"), isActive: (proc: AppProcess) => proc?.getWindow()?.dataset.snapstate === "bottom-right", @@ -113,11 +113,11 @@ export function WindowSystemContextMenu(runtime: ContextMenuRuntime): AppContext ], }, { - caption: "Move to workspace", + caption: "%apps.contextMenu.system.windowTitlebar.moveWorkspace%", icon: "rotate-ccw-square", subItems: [ { - caption: "Left workspace", + caption: "%apps.contextMenu.system.windowTitlebar.moveWorkspaceLeft%", icon: "arrow-left", action: (proc: AppProcess) => { if (!proc?.pid) return; @@ -131,7 +131,7 @@ export function WindowSystemContextMenu(runtime: ContextMenuRuntime): AppContext }, }, { - caption: "Right workspace", + caption: "%apps.contextMenu.system.windowTitlebar.moveWorkspaceRight%", icon: "arrow-right", action: (proc: AppProcess) => { if (!proc?.pid) return; @@ -148,7 +148,7 @@ export function WindowSystemContextMenu(runtime: ContextMenuRuntime): AppContext }, { sep: true }, { - caption: "Close", + caption: "%general.close%", action: (proc: AppProcess) => { proc.closeWindow(); }, diff --git a/src/apps/components/driveinfo/DriveInfo.svelte b/src/apps/components/driveinfo/DriveInfo.svelte index 16eaa8577..f75059ab0 100755 --- a/src/apps/components/driveinfo/DriveInfo.svelte +++ b/src/apps/components/driveinfo/DriveInfo.svelte @@ -30,7 +30,8 @@ {/if}
{#if isUserFs} - + {/if} - +
diff --git a/src/apps/components/driveinfo/DriveInfo.ts b/src/apps/components/driveinfo/DriveInfo.ts index 980336371..78b6e85cf 100644 --- a/src/apps/components/driveinfo/DriveInfo.ts +++ b/src/apps/components/driveinfo/DriveInfo.ts @@ -5,7 +5,7 @@ import { DriveInfoRuntime } from "./runtime"; const DriveInfoApp: App = { metadata: { - name: "Drive Info", + name: "%apps.DriveInfo._name%", version: "1.0.0", author: "Izaak Kuipers", icon: "DriveIcon", diff --git a/src/apps/components/driveinfo/DriveInfo/AdvancedInfo.svelte b/src/apps/components/driveinfo/DriveInfo/AdvancedInfo.svelte index 09e722545..4b9370dce 100755 --- a/src/apps/components/driveinfo/DriveInfo/AdvancedInfo.svelte +++ b/src/apps/components/driveinfo/DriveInfo/AdvancedInfo.svelte @@ -6,25 +6,25 @@
-

ID

+

%advanced.id%

{drive.uuid}

-

Mountpoint

+

%advanced.mountpoint%

{drive.driveLetter || drive.uuid}:/

-

Label

+

%advanced.label%

{drive.label}

-

Identifies As

+

%advanced.identifiesAs%

{drive.IDENTIFIES_AS}

-

Flags

+

%advanced.flags%

- {`${drive.BUSY ? "Busy" : ""} ${drive.FIXED ? "Fixed" : ""} ${drive.READONLY ? "Readonly" : ""} ${drive.REMOVABLE ? "Removable" : ""}`.trim()} + {`${drive.BUSY ? "%advanced.busy%" : ""} ${drive.FIXED ? "%advanced.fixed%" : ""} ${drive.READONLY ? "%advanced.readonly%" : ""} ${drive.REMOVABLE ? "%advanced.removable%" : ""}`.trim()}

diff --git a/src/apps/components/driveinfo/DriveInfo/Quota.svelte b/src/apps/components/driveinfo/DriveInfo/Quota.svelte index 022b99bd3..c03cc83fb 100755 --- a/src/apps/components/driveinfo/DriveInfo/Quota.svelte +++ b/src/apps/components/driveinfo/DriveInfo/Quota.svelte @@ -10,7 +10,7 @@

- Used ({quota.percentage.toFixed(0)}%) + %quota.used({quota.percentage.toFixed(0)})%

{formatBytes(quota.used)}

@@ -19,7 +19,7 @@

- Free ({(100 - quota.percentage).toFixed(0)}%) + %quota.free({(100 - quota.percentage).toFixed(0)})%

{formatBytes(quota.free)}

diff --git a/src/apps/components/driveinfo/DriveInfo/Usage.svelte b/src/apps/components/driveinfo/DriveInfo/Usage.svelte index 18742cf83..7f655d21f 100755 --- a/src/apps/components/driveinfo/DriveInfo/Usage.svelte +++ b/src/apps/components/driveinfo/DriveInfo/Usage.svelte @@ -18,7 +18,7 @@

- {id.replace(id[0], id[0].toUpperCase())} ({percentage.toFixed(1)}%) + %legend.{id}({percentage.toFixed(1)})%

{formatBytes((usage.sizes as any)[id] || 0)}

diff --git a/src/apps/components/driveinfo/runtime.ts b/src/apps/components/driveinfo/runtime.ts index 72cf2c089..d2ee06fa1 100755 --- a/src/apps/components/driveinfo/runtime.ts +++ b/src/apps/components/driveinfo/runtime.ts @@ -4,6 +4,7 @@ import { ServerDrive } from "$ts/drives/server"; import { USERFS_UUID } from "$ts/env"; import type { AppProcessData } from "$types/app"; import type { UserQuota } from "$types/fs"; +import type { RenderArgs } from "$types/process"; import type { CategorizedDiskUsage } from "$types/user"; export class DriveInfoRuntime extends AppProcess { @@ -31,5 +32,9 @@ export class DriveInfoRuntime extends AppProcess { if (this.isUserFs) this.usage = await this.userDaemon?.determineCategorizedDiskUsage(); } + render(args: RenderArgs) { + this.getBody().setAttribute("data-prefix", "apps.DriveInfo"); + } + //#endregion } diff --git a/src/apps/components/exit/Exit.svelte b/src/apps/components/exit/Exit.svelte index c70c01fe2..64e5184f3 100755 --- a/src/apps/components/exit/Exit.svelte +++ b/src/apps/components/exit/Exit.svelte @@ -7,8 +7,8 @@
-

Exit ArcOS

-

What's your escape route?

+

%header.title%

+

%header.message%

@@ -26,7 +26,7 @@
- +
diff --git a/src/apps/components/exit/ExitApp.ts b/src/apps/components/exit/ExitApp.ts index 4d9edc7ef..342d3af8c 100644 --- a/src/apps/components/exit/ExitApp.ts +++ b/src/apps/components/exit/ExitApp.ts @@ -5,7 +5,7 @@ import { ExitRuntime } from "./runtime"; const ExitApp: App = { metadata: { - name: "Exit", + name: "%apps.ExitApp._name%", author: "Izaak Kuipers", version: "6.0.0", icon: "ShutdownIcon", diff --git a/src/apps/components/exit/runtime.ts b/src/apps/components/exit/runtime.ts index efb4a0bf2..6f1c22ffc 100755 --- a/src/apps/components/exit/runtime.ts +++ b/src/apps/components/exit/runtime.ts @@ -1,6 +1,7 @@ import { AppProcess } from "$ts/apps/process"; import { Store } from "$ts/writable"; import type { AppProcessData } from "$types/app"; +import type { RenderArgs } from "$types/process"; import { ExitActions } from "./store"; import type { ExitAction } from "./types"; @@ -30,4 +31,8 @@ export class ExitRuntime extends AppProcess { option.alternateAction(this.userDaemon!); // Alternate: when shift key is pressed else option.action(this.userDaemon!); } + + render(args: RenderArgs) { + this.getBody().setAttribute("data-prefix", "apps.ExitApp"); + } } diff --git a/src/apps/components/exit/store.ts b/src/apps/components/exit/store.ts index 422d44aad..4166ff25c 100755 --- a/src/apps/components/exit/store.ts +++ b/src/apps/components/exit/store.ts @@ -4,18 +4,18 @@ import type { ExitAction } from "./types"; export const ExitActions: Record = { restart: { action: (daemon: UserDaemon) => daemon.restart(), - caption: "Restart", + caption: "%exitActions.restart%", icon: "RestartIcon", }, shutdown: { action: (daemon: UserDaemon) => daemon.shutdown(), - caption: "Shut down", + caption: "%exitActions.shutdown%", icon: "ShutdownIcon", }, logoff: { action: (daemon: UserDaemon) => daemon.logoff(), alternateAction: (daemon: UserDaemon) => daemon.logoffSafeMode(), - caption: "Log off", + caption: "%exitActions.logoff%", icon: "LogoutIcon", }, }; diff --git a/src/apps/components/firstrun/ChooseProfilePicture/ChooseProfilePicture.svelte b/src/apps/components/firstrun/ChooseProfilePicture/ChooseProfilePicture.svelte index c3c3a2765..ac7ef6c77 100755 --- a/src/apps/components/firstrun/ChooseProfilePicture/ChooseProfilePicture.svelte +++ b/src/apps/components/firstrun/ChooseProfilePicture/ChooseProfilePicture.svelte @@ -8,8 +8,8 @@
-

Choose profile picture

-

What do you want to be?

+

%apps.FirstRun.ChooseProfilePicture.title%

+

%apps.FirstRun.ChooseProfilePicture.subtitle%

{#each Object.values(ProfilePictures) as pfp, i}
- +
diff --git a/src/apps/components/firstrun/ChooseProfilePicture/metadata.ts b/src/apps/components/firstrun/ChooseProfilePicture/metadata.ts index 6323cbf49..7f9f09140 100755 --- a/src/apps/components/firstrun/ChooseProfilePicture/metadata.ts +++ b/src/apps/components/firstrun/ChooseProfilePicture/metadata.ts @@ -4,7 +4,7 @@ import ChooseProfilePicture from "./ChooseProfilePicture.svelte"; export const ChooseProfilePictureApp: App = { metadata: { - name: "Choose Profile Picture", + name: "%apps.FirstRun.ChooseProfilePicture._name%", author: "Izaak Kuipers", version: "1.0.0", icon: "AccountIcon", diff --git a/src/apps/components/firstrun/FirstRun.svelte b/src/apps/components/firstrun/FirstRun.svelte index f61f2cee3..37b7ac7fe 100755 --- a/src/apps/components/firstrun/FirstRun.svelte +++ b/src/apps/components/firstrun/FirstRun.svelte @@ -15,7 +15,7 @@ }); -
+
{#if Component} {:else} @@ -24,7 +24,7 @@
{/if}
-
+
{#each $currentPage?.actions.left as button} - + +
diff --git a/src/apps/components/fsnewfolder/FsNewFolder.ts b/src/apps/components/fsnewfolder/FsNewFolder.ts index 5a525b74d..65eb3f513 100644 --- a/src/apps/components/fsnewfolder/FsNewFolder.ts +++ b/src/apps/components/fsnewfolder/FsNewFolder.ts @@ -5,7 +5,7 @@ import { NewFolderRuntime } from "./runtime"; export const FsNewFolderApp: App = { metadata: { - name: "New Folder", + name: "%apps.FsNewFolder.title%", version: "4.0.0", author: "Izaak Kuipers", icon: "ComponentIcon", diff --git a/src/apps/components/fsnewfolder/NewFolder.svelte b/src/apps/components/fsnewfolder/NewFolder.svelte index 855ba6c65..2e4e0f89a 100755 --- a/src/apps/components/fsnewfolder/NewFolder.svelte +++ b/src/apps/components/fsnewfolder/NewFolder.svelte @@ -8,12 +8,12 @@
-

New folder

-

Think of a wonderful name for this new folder:

+

%apps.FsNewFolder.title%

+

%apps.FsNewFile.subtitle%

- - + +
diff --git a/src/apps/components/fsprogress/FsProgress.ts b/src/apps/components/fsprogress/FsProgress.ts index 5deb6fef8..dcb11d3f4 100644 --- a/src/apps/components/fsprogress/FsProgress.ts +++ b/src/apps/components/fsprogress/FsProgress.ts @@ -6,7 +6,7 @@ import { FsProgressRuntime } from "./runtime"; export const FsProgressApp: App = { metadata: { name: "FsProgress", - author: "The ArcOS Team", + author: "%general.ArcOSTeam%", version: "1.0.0", icon: "ComponentIcon", appGroup: "components", diff --git a/src/apps/components/fsprogress/FsProgress/Bottom.svelte b/src/apps/components/fsprogress/FsProgress/Bottom.svelte index f1bd7b304..b1d46784c 100755 --- a/src/apps/components/fsprogress/FsProgress/Bottom.svelte +++ b/src/apps/components/fsprogress/FsProgress/Bottom.svelte @@ -20,11 +20,11 @@ {#if $Progress.max > 0}

{#if $Progress.type == "quantity"} - {$Progress.done} / {$Progress.max} done + %apps.FsProgress.quantity({$Progress.done}::{$Progress.max})% {:else if $Progress.type == "size"} - {formatBytes($Progress.done)} / {formatBytes($Progress.max)} done + %apps.FsProgress.size({formatBytes($Progress.done)}::{formatBytes($Progress.max)})% {/if}

{/if} - +
diff --git a/src/apps/components/fsprogressfail/FsProgressFail.svelte b/src/apps/components/fsprogressfail/FsProgressFail.svelte index 1065a447b..24698b5ca 100755 --- a/src/apps/components/fsprogressfail/FsProgressFail.svelte +++ b/src/apps/components/fsprogressfail/FsProgressFail.svelte @@ -8,7 +8,7 @@

{title}

-

This file operation encountered an error.

+

%apps.FsProgressFail.subtitle%

{#each errors as error} @@ -18,4 +18,4 @@
{/each}
- + diff --git a/src/apps/components/fsrenameitem/RenameItem.svelte b/src/apps/components/fsrenameitem/RenameItem.svelte index d2e6e43be..404271bb0 100755 --- a/src/apps/components/fsrenameitem/RenameItem.svelte +++ b/src/apps/components/fsrenameitem/RenameItem.svelte @@ -8,12 +8,12 @@
-

Rename file or folder

-

Enter a new name for the item:

+

%apps.FsRenameItem.title%

+

%apps.FsRenameItem.subtitle%

- - + +
diff --git a/src/apps/components/globalloadindicator/runtime.ts b/src/apps/components/globalloadindicator/runtime.ts index 74c3ce89e..31cd81a09 100755 --- a/src/apps/components/globalloadindicator/runtime.ts +++ b/src/apps/components/globalloadindicator/runtime.ts @@ -3,7 +3,7 @@ import { Store } from "$ts/writable"; import type { AppProcessData } from "$types/app"; export class GlobalLoadIndicatorRuntime extends AppProcess { - caption = Store("Just a moment..."); + caption = Store("%general.genericStatus%"); //#region LIFECYCLE diff --git a/src/apps/components/iconeditdialog/IconEditDialog.svelte b/src/apps/components/iconeditdialog/IconEditDialog.svelte index 6705959d6..7128fa1b0 100644 --- a/src/apps/components/iconeditdialog/IconEditDialog.svelte +++ b/src/apps/components/iconeditdialog/IconEditDialog.svelte @@ -11,7 +11,7 @@
-

Change {id}

+

%title({id})%

{#if $type === "@fs"} @@ -23,10 +23,10 @@
- - + +
diff --git a/src/apps/components/iconeditdialog/IconEditDialog.ts b/src/apps/components/iconeditdialog/IconEditDialog.ts index cdb9ab822..d43ff3180 100644 --- a/src/apps/components/iconeditdialog/IconEditDialog.ts +++ b/src/apps/components/iconeditdialog/IconEditDialog.ts @@ -5,7 +5,7 @@ import { IconEditDialogRuntime } from "./runtime"; export const IconEditDialogApp: App = { metadata: { - name: "Change Icon", + name: "%apps.IconEditDialog._name%", version: "1.0.0", author: "Izaak Kuipers", icon: "ComponentIcon", diff --git a/src/apps/components/iconeditdialog/IconEditDialog/AppType.svelte b/src/apps/components/iconeditdialog/IconEditDialog/AppType.svelte index 4fbf8680a..5e4b572bc 100644 --- a/src/apps/components/iconeditdialog/IconEditDialog/AppType.svelte +++ b/src/apps/components/iconeditdialog/IconEditDialog/AppType.svelte @@ -7,11 +7,11 @@
-

App:

+

%appType.title%

diff --git a/src/apps/components/iconeditdialog/IconEditDialog/BuiltinType.svelte b/src/apps/components/iconeditdialog/IconEditDialog/BuiltinType.svelte index 40dc5c730..d9ac66849 100644 --- a/src/apps/components/iconeditdialog/IconEditDialog/BuiltinType.svelte +++ b/src/apps/components/iconeditdialog/IconEditDialog/BuiltinType.svelte @@ -14,7 +14,7 @@
-

Icon ID:

+

%builtinType.title%

{#if $values[$type]} @@ -22,6 +22,6 @@ {/if} {$values[$type]}
- +
diff --git a/src/apps/components/iconeditdialog/IconEditDialog/FileType.svelte b/src/apps/components/iconeditdialog/IconEditDialog/FileType.svelte index 2627c90a3..6109cf24f 100644 --- a/src/apps/components/iconeditdialog/IconEditDialog/FileType.svelte +++ b/src/apps/components/iconeditdialog/IconEditDialog/FileType.svelte @@ -8,7 +8,7 @@ async function browse() { const [path] = await process.userDaemon!.LoadSaveDialog({ - title: "Choose an icon to load", + title: "%apps.IconEditDialog.fileType.loadSaveTitle%", extensions: [".svg", ".png", ".jpg", ".bmp", ".gif", ".jpeg"], icon: UploadIcon, startDir: UserPaths.Pictures, @@ -19,9 +19,9 @@
-

File path:

+

%fileType.title%

- +
diff --git a/src/apps/components/iconeditdialog/IconEditDialog/ModeToggle.svelte b/src/apps/components/iconeditdialog/IconEditDialog/ModeToggle.svelte index 821ef4488..00aee12cf 100644 --- a/src/apps/components/iconeditdialog/IconEditDialog/ModeToggle.svelte +++ b/src/apps/components/iconeditdialog/IconEditDialog/ModeToggle.svelte @@ -6,7 +6,7 @@
- - - + + +
diff --git a/src/apps/components/iconeditdialog/runtime.ts b/src/apps/components/iconeditdialog/runtime.ts index b33dfd474..ed2b9e8ad 100644 --- a/src/apps/components/iconeditdialog/runtime.ts +++ b/src/apps/components/iconeditdialog/runtime.ts @@ -31,6 +31,10 @@ export class IconEditDialogRuntime extends AppProcess { this.values.subscribe((v) => this.updateCurrentIcon(this.type(), v)); } + async render() { + this.getBody().setAttribute("data-prefix", "apps.IconEditDialog"); + } + //#endregion async updateCurrentIcon(type: string = this.type(), values: Record = this.values()) { diff --git a/src/apps/components/iconpicker/IconPicker.svelte b/src/apps/components/iconpicker/IconPicker.svelte index 14729c9da..621538460 100755 --- a/src/apps/components/iconpicker/IconPicker.svelte +++ b/src/apps/components/iconpicker/IconPicker.svelte @@ -28,12 +28,12 @@ %reset% - +
- - + +
diff --git a/src/apps/components/iconpicker/IconPicker.ts b/src/apps/components/iconpicker/IconPicker.ts index a1aecf36f..3624c525a 100644 --- a/src/apps/components/iconpicker/IconPicker.ts +++ b/src/apps/components/iconpicker/IconPicker.ts @@ -5,7 +5,7 @@ import { IconPickerRuntime } from "./runtime"; export const IconPickerApp: App = { metadata: { - name: "Icon Picker", + name: "%apps.IconPicker._name%", version: "3.0.0", author: "Izaak Kuipers", icon: "IconLibraryIcon", diff --git a/src/apps/components/iconpicker/IconPicker/Header.svelte b/src/apps/components/iconpicker/IconPicker/Header.svelte index f9abc8be2..2b8db9a85 100755 --- a/src/apps/components/iconpicker/IconPicker/Header.svelte +++ b/src/apps/components/iconpicker/IconPicker/Header.svelte @@ -6,7 +6,7 @@
-

Pick an icon for {forWhat}

+

%title({forWhat})%

{forWhat} diff --git a/src/apps/components/iconpicker/runtime.ts b/src/apps/components/iconpicker/runtime.ts index 5bcf4c39d..c6bcfa3cf 100755 --- a/src/apps/components/iconpicker/runtime.ts +++ b/src/apps/components/iconpicker/runtime.ts @@ -39,6 +39,10 @@ export class IconPickerRuntime extends AppProcess { this.groups = iconService.getGroupedIcons(); } + async render() { + this.getBody().setAttribute("data-prefix", "apps.IconPicker"); + } + //#endregion async confirm() { diff --git a/src/apps/components/iconpicker/store.ts b/src/apps/components/iconpicker/store.ts index eb442f0f6..ea4e4b445 100755 --- a/src/apps/components/iconpicker/store.ts +++ b/src/apps/components/iconpicker/store.ts @@ -1,10 +1,10 @@ export const ICON_GROUP_CAPTIONS = { - Branding: "ArcOS logos", - General: "General icons", - Apps: "Application icons", - Filesystem: "Filesystem-related icons", - Power: "Power icons", - Dialog: "Dialog icons", - Status: "Status indicators", - Mimetypes: "File mimetypes", + Branding: "%groups.Branding%", + General: "%groups.General%", + Apps: "%groups.Apps%", + Filesystem: "%groups.Filesystem%", + Power: "%groups.Power%", + Dialog: "%groups.Dialog%", + Status: "%groups.Status%", + Mimetypes: "%groups.Mimetypes%", }; diff --git a/src/apps/components/iteminfo/ItemInfo.ts b/src/apps/components/iteminfo/ItemInfo.ts index 935017ed1..2f76b26c1 100644 --- a/src/apps/components/iteminfo/ItemInfo.ts +++ b/src/apps/components/iteminfo/ItemInfo.ts @@ -5,7 +5,7 @@ import { ItemInfoRuntime } from "./runtime"; export const ItemInfoApp: App = { metadata: { - name: "Item Info", + name: "%apps.ItemInfo._name%", version: "1.0.0", author: "Izaak Kuipers", icon: "ComponentIcon", diff --git a/src/apps/components/iteminfo/ItemInfo/Actions.svelte b/src/apps/components/iteminfo/ItemInfo/Actions.svelte index 44e2723cb..0ccc293fb 100755 --- a/src/apps/components/iteminfo/ItemInfo/Actions.svelte +++ b/src/apps/components/iteminfo/ItemInfo/Actions.svelte @@ -14,10 +14,10 @@ {/if} - - + + diff --git a/src/apps/components/iteminfo/ItemInfo/Header.svelte b/src/apps/components/iteminfo/ItemInfo/Header.svelte index 87fa4ccda..6d3503d6b 100755 --- a/src/apps/components/iteminfo/ItemInfo/Header.svelte +++ b/src/apps/components/iteminfo/ItemInfo/Header.svelte @@ -19,10 +19,10 @@

{$info.name || $info.location.parent || $info.location.drive}

{#if $info.name && ($info.location.parent || $info.location.drive)} -

in {$info.location.parent || $info.location.drive}

+

%subtitle({$info.location.parent || $info.location.drive})%

{/if}
{#if $info.name} - + {/if}
diff --git a/src/apps/components/iteminfo/ItemInfo/Location.svelte b/src/apps/components/iteminfo/ItemInfo/Location.svelte index d414127b2..55b30919a 100755 --- a/src/apps/components/iteminfo/ItemInfo/Location.svelte +++ b/src/apps/components/iteminfo/ItemInfo/Location.svelte @@ -11,21 +11,21 @@ - + {$info.location.fullPath} - + {$info.location.extension ? "." + $info.location.extension : "-"} - + {$info.location.parent || "-"} - + {$info.location.drive || "-"} - + {$info.location.driveFs || "GFS"} diff --git a/src/apps/components/iteminfo/ItemInfo/Meta.svelte b/src/apps/components/iteminfo/ItemInfo/Meta.svelte index 1049d79cf..4b152c053 100755 --- a/src/apps/components/iteminfo/ItemInfo/Meta.svelte +++ b/src/apps/components/iteminfo/ItemInfo/Meta.svelte @@ -24,21 +24,21 @@ - + {$info.name ? $info.meta.sort : "drive"} - + {$info.meta.mimetype || "-"} - + {$info.meta.size ? formatBytes($info.meta.size) : "-"} - + {created} - + {modified} diff --git a/src/apps/components/iteminfo/runtime.ts b/src/apps/components/iteminfo/runtime.ts index a176df840..2e9d72154 100755 --- a/src/apps/components/iteminfo/runtime.ts +++ b/src/apps/components/iteminfo/runtime.ts @@ -27,6 +27,8 @@ export class ItemInfoRuntime extends AppProcess { } async render({ path, file }: RenderArgs) { + this.getBody().setAttribute("data-prefix", "apps.ItemInfo"); + file = file as FileEntry | FolderEntry; try { diff --git a/src/apps/components/messagecomposer/MessageComposer.ts b/src/apps/components/messagecomposer/MessageComposer.ts index cffdc5e56..d348f76a3 100644 --- a/src/apps/components/messagecomposer/MessageComposer.ts +++ b/src/apps/components/messagecomposer/MessageComposer.ts @@ -5,7 +5,7 @@ import { MessageComposerRuntime } from "./runtime"; export const MessageComposerApp: App = { metadata: { - name: "New Message", + name: "%apps.MessageComposer._name%", author: "Izaak Kuipers", version: "1.0.0", icon: "MessagingIcon", diff --git a/src/apps/components/messagecomposer/MessageComposer/ActionBar.svelte b/src/apps/components/messagecomposer/MessageComposer/ActionBar.svelte index aa9b2ec37..580c2ebbd 100755 --- a/src/apps/components/messagecomposer/MessageComposer/ActionBar.svelte +++ b/src/apps/components/messagecomposer/MessageComposer/ActionBar.svelte @@ -9,31 +9,31 @@
-

Body

+

%actionBar.body%

{formatBytes($body.length)}

-

Attachments

+

%actionBar.attachments%

{formatBytes($attachments.map((a) => a.data.size).reduce((partialSum, a) => partialSum + a, 0))}

%actionBar.send%
diff --git a/src/apps/components/messagecomposer/MessageComposer/AttachmentBar.svelte b/src/apps/components/messagecomposer/MessageComposer/AttachmentBar.svelte index 6560312e6..3fec16b12 100755 --- a/src/apps/components/messagecomposer/MessageComposer/AttachmentBar.svelte +++ b/src/apps/components/messagecomposer/MessageComposer/AttachmentBar.svelte @@ -19,10 +19,10 @@ ({formatBytes(attachment.data.size)})
diff --git a/src/apps/components/messagecomposer/MessageComposer/SubjectField.svelte b/src/apps/components/messagecomposer/MessageComposer/SubjectField.svelte index 1c4c0cf0c..5aaec102f 100755 --- a/src/apps/components/messagecomposer/MessageComposer/SubjectField.svelte +++ b/src/apps/components/messagecomposer/MessageComposer/SubjectField.svelte @@ -6,7 +6,7 @@
-

Subject:

+

%subjectField.subject%

diff --git a/src/apps/components/messagecomposer/MessageComposer/ToField.svelte b/src/apps/components/messagecomposer/MessageComposer/ToField.svelte index d39bb7d75..ef1dcfb81 100755 --- a/src/apps/components/messagecomposer/MessageComposer/ToField.svelte +++ b/src/apps/components/messagecomposer/MessageComposer/ToField.svelte @@ -26,7 +26,7 @@
-

To:

+

%toField.to%

{#each $recipients as recipient}
@@ -34,12 +34,12 @@
{/each} - +
diff --git a/src/apps/components/messagecomposer/runtime.ts b/src/apps/components/messagecomposer/runtime.ts index 2680655aa..d22f4c5d4 100755 --- a/src/apps/components/messagecomposer/runtime.ts +++ b/src/apps/components/messagecomposer/runtime.ts @@ -38,6 +38,10 @@ export class MessageComposerRuntime extends AppProcess { this.setSource(__SOURCE__); } + async render() { + this.getBody().setAttribute("data-prefix", "apps.MessageComposer"); + } + //#endregion //#region SENDING @@ -49,8 +53,8 @@ export class MessageComposerRuntime extends AppProcess { const prog = await this.userDaemon?.FileProgress( { type: "none", - caption: "Sending message", - subtitle: "Preparing...", + caption: "%apps.MessageComposer.sendProg.caption%", + subtitle: "%apps.MessageComposer.sendProg.subtitleInitial%", icon: "MessagingIcon", }, this.pid @@ -67,7 +71,7 @@ export class MessageComposerRuntime extends AppProcess { prog?.setType("size"); prog?.setMax(progress.max); prog?.setDone(progress.value); - prog?.updSub("Uploading..."); + prog?.updSub("%apps.MessageComposer.sendProg.subtitleUploading%"); } ); @@ -83,11 +87,11 @@ export class MessageComposerRuntime extends AppProcess { if (!this.isModified()) return this.closeWindow(); MessageBox( { - title: "Discard message?", - message: "Are you sure you want to discard this message? This cannot be undone.", + title: "%apps.MessageComposer.discardMessage.title%", + message: "%apps.MessageComposer.discardMessage.title%", buttons: [ - { caption: "Cancel", action: () => {} }, - { caption: "Discard", action: () => this.closeWindow(), suggested: true }, + { caption: "%general.cancel%", action: () => {} }, + { caption: "%general.discard%", action: () => this.closeWindow(), suggested: true }, ], image: "WarningIcon", sound: "arcos.dialog.warning", @@ -101,12 +105,11 @@ export class MessageComposerRuntime extends AppProcess { this.sending.set(false); MessageBox( { - title: "Failed to send message", - message: - "ArcOS failed to send the message! It might be too large, or none of the recipients exist. Please check the recipients or try shrinking it down, and then resend it. If it still doesn't work, contact an ArcOS administrator.", + title: "%apps.MessageComposer.sendFailed.title%", + message: "%apps.MessageComposer.sendFailed.message%", image: "WarningIcon", sound: "arcos.dialog.warning", - buttons: [{ caption: "Okay", action: () => {}, suggested: true }], + buttons: [{ caption: "%general.okay%", action: () => {}, suggested: true }], }, this.pid, true @@ -119,7 +122,7 @@ export class MessageComposerRuntime extends AppProcess { async addAttachment() { const attachments: Attachment[] = []; const paths = await this.userDaemon!.LoadSaveDialog({ - title: "Choose one or more files to attach", + title: "%apps.MessageComposer.addAttachment.title%", icon: "UploadIcon", startDir: UserPaths.Documents, multiple: true, @@ -129,7 +132,7 @@ export class MessageComposerRuntime extends AppProcess { { max: 100, type: "none", - caption: "Just a moment...", + caption: "%general.genericStatus%", icon: "MemoryIcon", }, this.pid @@ -143,7 +146,11 @@ export class MessageComposerRuntime extends AppProcess { try { const contents = await this.fs.readFile(path, (progress) => { prog.show(); - prog.updateCaption(progress.what ? `Reading ${progress.what}` : "Reading file..."); + prog.updateCaption( + progress.what + ? `%apps.MessageComposer.fileProgress.readingFileKnown(${progress.what})%` + : "%apps.MessageComposer.fileProgress.readingFileUnknown%" + ); prog.updSub(path); prog.setType("size"); prog.setDone(0); diff --git a/src/apps/components/multiupdategui/MultiUpdateGui.svelte b/src/apps/components/multiupdategui/MultiUpdateGui.svelte index be6d0e0a7..52a5c074c 100755 --- a/src/apps/components/multiupdategui/MultiUpdateGui.svelte +++ b/src/apps/components/multiupdategui/MultiUpdateGui.svelte @@ -24,40 +24,40 @@ ? StoreItemIcon($currentPackage) : $done ? process.getIconCached("GoodStatusIcon") - : "UpdateIcon"} + : process.getIconCached("UpdateIcon")} alt="" />

{#if $working} {#if $currentPackage} - Updating {$currentPackage.pkg.name} + %title.updating({$currentPackage.pkg.name})% {:else} - Just a moment + %title.loading% {/if} {:else if $done} - Finished updating + %title.done% {:else} - Ready to update + %title.ready% {/if}

{#if $working} {#if $currentPackage && $currentPackage.user} - By + %generic.by% {:else} - Loading... + %generic.loading% {/if} {:else if $done} {#if $errored.length} {$errored.length} {Plural("error", $errored.length)} occurred {:else} - All packages were updated. + %allPackagesUpdated% {/if} {:else} - Click Update to begin + %clickUpdate% {/if}

@@ -88,13 +88,13 @@

{#if item.type === "file"} - Writing file + %itemType.file% {:else if item.type === "mkdir"} - Creating directory + %itemType.mkdir% {:else if item.type === "registration"} - Registering + %itemType.registration% {:else} - Status + %itemType.generic% {/if}

{item.content}

@@ -111,10 +111,10 @@
{#if $showLog}%hideLog%{:else}%showLog%{/if} - + {#if $done}%finish%{:else}%startUpdate%{/if}
diff --git a/src/apps/components/multiupdategui/MultiUpdateGui.ts b/src/apps/components/multiupdategui/MultiUpdateGui.ts index 83c1a25db..651ed4b63 100644 --- a/src/apps/components/multiupdategui/MultiUpdateGui.ts +++ b/src/apps/components/multiupdategui/MultiUpdateGui.ts @@ -5,7 +5,7 @@ import { MultiUpdateGuiRuntime } from "./runtime"; export const MultiUpdateGuiApp: App = { metadata: { - name: "App Updater", + name: "%apps.MultiUpdateGui._name%", author: "Izaak Kuipers", version: "1.0.0", icon: "UpdateIcon", diff --git a/src/apps/components/multiupdategui/runtime.ts b/src/apps/components/multiupdategui/runtime.ts index e87a818c6..5b19585ab 100755 --- a/src/apps/components/multiupdategui/runtime.ts +++ b/src/apps/components/multiupdategui/runtime.ts @@ -50,6 +50,8 @@ export class MultiUpdateGuiRuntime extends AppProcess { } async render() { + this.getBody().setAttribute("data-prefix", "apps.MultiUpdateGui"); + this.win = this.getWindow(); if (this.updates.length > 15) { @@ -87,7 +89,7 @@ export class MultiUpdateGuiRuntime extends AppProcess { this.working.set(true); const elevated = await this.userDaemon!.manuallyElevate({ - what: `ArcOS needs your permission to update ${this.updates.length} ${Plural("app", this.updates.length)}.`, + what: `%apps.MultiUpdateGui.elevation(${this.updates.length}::${Plural("app", this.updates.length)})%`, title: this.app.data.metadata.name, description: this.app.data.metadata.author, image: "UpdateIcon", diff --git a/src/apps/core/bootscreen/bootScreen.ts b/src/apps/core/bootscreen/bootScreen.ts index c12f6c6a1..cdad1923d 100644 --- a/src/apps/core/bootscreen/bootScreen.ts +++ b/src/apps/core/bootscreen/bootScreen.ts @@ -5,7 +5,7 @@ import { BootScreenRuntime } from "./runtime"; export const BootScreen: App = { metadata: { - name: "Boot App", + name: "%apps.bootScreen._name%", author: "Izaak Kuipers", version: "9.0.0", icon: "ComponentIcon", diff --git a/src/apps/core/bootscreen/runtime.ts b/src/apps/core/bootscreen/runtime.ts index b0c8dc935..ccf145747 100755 --- a/src/apps/core/bootscreen/runtime.ts +++ b/src/apps/core/bootscreen/runtime.ts @@ -21,7 +21,7 @@ export class BootScreenRuntime extends AppProcess { async begin() { this.Log("Initializing boot"); - this.status.set("Press a key or click to start"); + this.status.set("%apps.bootScreen.pressAnyKey%"); document.addEventListener("click", () => this.startBooting(), { once: true, @@ -42,11 +42,11 @@ export class BootScreenRuntime extends AppProcess { this.progress.set(true); if (e?.key === "F8") { - this.status.set("Entering Safe Mode"); + this.status.set("%apps.bootScreen.safeMode%"); await Sleep(2000); KernelStateHandler()?.loadState("login", { safeMode: true }); } else if (e?.key.toLowerCase() === "a") { - this.status.set("Starting ArcTerm"); + this.status.set("%apps.bootScreen.arcTerm%"); KernelStateHandler()?.loadState("arcterm"); } else { this.status.set(" "); diff --git a/src/apps/core/initialsetup/InitialSetup.svelte b/src/apps/core/initialsetup/InitialSetup.svelte index 2cfc3885d..3c1fa65f7 100755 --- a/src/apps/core/initialsetup/InitialSetup.svelte +++ b/src/apps/core/initialsetup/InitialSetup.svelte @@ -26,7 +26,7 @@
-
+
{#if PageComponent} {/if} diff --git a/src/apps/core/initialsetup/InitialSetup/Page/CheckInbox.svelte b/src/apps/core/initialsetup/InitialSetup/Page/CheckInbox.svelte index 85bbdbd0b..2fc51e5d3 100755 --- a/src/apps/core/initialsetup/InitialSetup/Page/CheckInbox.svelte +++ b/src/apps/core/initialsetup/InitialSetup/Page/CheckInbox.svelte @@ -4,9 +4,7 @@
-

Check your inbox

-

You've got mail!

-

- We sent you a link to activate your account. Open it to continue. Be sure to check your spam if you can’t find it. -

+

%checkInbox.title%

+

%checkInbox.subtitle%

+

%checkInbox.message%

diff --git a/src/apps/core/initialsetup/InitialSetup/Page/Finish.svelte b/src/apps/core/initialsetup/InitialSetup/Page/Finish.svelte index 7cf2fa97a..d26fbb42c 100755 --- a/src/apps/core/initialsetup/InitialSetup/Page/Finish.svelte +++ b/src/apps/core/initialsetup/InitialSetup/Page/Finish.svelte @@ -4,9 +4,7 @@
-

All finished!

-

You're all set.

-

- Your account has been set up successfully. Click Finish to start using ArcOS. -

+

%finish.title%

+

%finish.subtitle%

+

%finish.message%

diff --git a/src/apps/core/initialsetup/InitialSetup/Page/FreshDeployment.svelte b/src/apps/core/initialsetup/InitialSetup/Page/FreshDeployment.svelte index d060d84bd..5bfa8870c 100644 --- a/src/apps/core/initialsetup/InitialSetup/Page/FreshDeployment.svelte +++ b/src/apps/core/initialsetup/InitialSetup/Page/FreshDeployment.svelte @@ -5,19 +5,12 @@
-

Fresh deployment

-

- It appears this ReArc deployment is fresh. Before continuing, please make sure that that's supposed to be the case. If it is, - click Next. The user you're about to create is considered user #0, and will be set up as a God Admin by default. The - owner of this account is then automatically seen as the owner of the server. Also, please check the server configuration: -

+

%freshDeployment.title%

+

%freshDeployment.message%

    {#each Object.entries(process.server?.serverInfo!) as [key, value]}
  • {key}: {JSON.stringify(value)}
  • {/each}
-

- Note: disableRegistration is ignored for the first user. This configuration option will be retained once the - first user has been created. -

+

%freshDeployment.note%

diff --git a/src/apps/core/initialsetup/InitialSetup/Page/Identity.svelte b/src/apps/core/initialsetup/InitialSetup/Page/Identity.svelte index 843084a2f..c85b625b6 100755 --- a/src/apps/core/initialsetup/InitialSetup/Page/Identity.svelte +++ b/src/apps/core/initialsetup/InitialSetup/Page/Identity.svelte @@ -2,7 +2,7 @@ import HtmlSpinner from "$lib/HtmlSpinner.svelte"; import { Sleep } from "$ts/sleep"; import { checkPasswordStrength, validateEmail, validateUsername } from "$ts/util"; - import { PasswordStrengthCaptions, type PasswordStrength } from "$types/user"; + import { type PasswordStrength } from "$types/user"; import type { InitialSetupRuntime } from "../../runtime"; const { process }: { process: InitialSetupRuntime } = $props(); @@ -120,15 +120,15 @@
-

Your ArcOS Identity

-

We'll use this information to create your ArcOS account.

+

%identity.title%

+

%identity.subtitle%

-

Display Name

+

%identity.fields.displayName%

-

Username

+

%identity.fields.username%

-

Password

+

%identity.fields.password%

- +
{#if usernameTaken && emailTaken} -

Username and email address are both taken!

+

%identity.errors.usernameAndEmailTaken%

{:else if usernameTaken} -

Username is already taken!

+

%identity.errors.usernameTaken%

{:else if emailTaken} -

Email is already taken!

+

%identity.errors.emailTaken%

{/if} {#if emailInvalid && usernameInvalid} -

Username and email address are both invalid!

+

%identity.errors.usernameAndEmailInvalid%

{:else if usernameInvalid} -

Username is invalid!

+

%identity.errors.usernameInvalid%

{:else if emailInvalid} -

Email address is invalid!

+

%identity.errors.emailInvalid%

{/if} {#if passwordInvalid} -

- Password is {PasswordStrengthCaptions[passwordStrength]}! -

+

%identity.errors.password{passwordStrength}%

{/if}
-

- * You will receive an email with a link to activate your account. Your display name, username and password can be changed - later on. To change your email, contact an administrator. -

+

%identity.disclaimer%

diff --git a/src/apps/core/initialsetup/InitialSetup/Page/License.svelte b/src/apps/core/initialsetup/InitialSetup/Page/License.svelte index 9bc150097..5ffd1fa71 100755 --- a/src/apps/core/initialsetup/InitialSetup/Page/License.svelte +++ b/src/apps/core/initialsetup/InitialSetup/Page/License.svelte @@ -4,7 +4,7 @@
-

License Agreement

-

Scary stuff, I know

-

By using ArcOS, you agree to the GPLv3 license.

+

%license.title%

+

%license.subtitle%

+

%license.message%

diff --git a/src/apps/core/initialsetup/InitialSetup/Page/Welcome.svelte b/src/apps/core/initialsetup/InitialSetup/Page/Welcome.svelte index 84d3393a9..4233e295f 100755 --- a/src/apps/core/initialsetup/InitialSetup/Page/Welcome.svelte +++ b/src/apps/core/initialsetup/InitialSetup/Page/Welcome.svelte @@ -4,10 +4,7 @@
-

Welcome

-

We're happy to have you

-

- Let's get you an ArcOS account. Click Next to get started, or - Cancel to go back to the login screen. -

+

%welcome.title%

+

%welcome.subtitle%

+

%welcome.message%

diff --git a/src/apps/core/initialsetup/initialSetupWizard.ts b/src/apps/core/initialsetup/initialSetupWizard.ts index 1ff53062d..7f37054e8 100644 --- a/src/apps/core/initialsetup/initialSetupWizard.ts +++ b/src/apps/core/initialsetup/initialSetupWizard.ts @@ -6,7 +6,7 @@ import { InitialSetupRuntime } from "./runtime"; export const InitialSetupWizard: App = { metadata: { - name: "Initial Setup Wizard", + name: "%apps.initialSetupWizard._name%", author: "Izaak Kuipers", version: "7.0.0", icon: WaveIcon, diff --git a/src/apps/core/initialsetup/runtime.ts b/src/apps/core/initialsetup/runtime.ts index 7e679a1a4..69bc8e5dc 100755 --- a/src/apps/core/initialsetup/runtime.ts +++ b/src/apps/core/initialsetup/runtime.ts @@ -39,7 +39,7 @@ export class InitialSetupRuntime extends AppProcess { public readonly pageButtons: PageButtons = [ { left: { - caption: "Cancel", + caption: "%general.cancel%", action: async () => { KernelStateHandler()?.loadState("login"); }, @@ -47,37 +47,37 @@ export class InitialSetupRuntime extends AppProcess { }, previous: { disabled: () => true, - caption: "Previous", + caption: "%general.previous%", to: 0, }, next: { suggested: true, - caption: "Next", + caption: "%general.next%", to: 1, }, }, { left: { - caption: "View License", + caption: "%apps.initialSetupWizard.buttons.viewLicense%", action: () => this.viewLicense(), }, previous: { - caption: "Previous", + caption: "%general.previous%", to: 0, }, next: { - caption: "I agree", + caption: "%general.iAgree%", suggested: true, action: () => this.licenseConfirmation(), }, }, { previous: { - caption: "Previous", + caption: "%general.previous%", to: 1, }, next: { - caption: "Continue", + caption: "%general.continue%", disabled: () => !this.identityInfoValid(), action: () => this.createAccount(), suggested: true, @@ -87,10 +87,10 @@ export class InitialSetupRuntime extends AppProcess { previous: { disabled: () => true, to: 3, - caption: "Previous", + caption: "%general.previous%", }, next: { - caption: "I clicked it", + caption: "%apps.initialSetupWizard.buttons.iClickedIt%", suggested: true, action: () => this.checkAccountActivation(), }, @@ -99,25 +99,25 @@ export class InitialSetupRuntime extends AppProcess { previous: { disabled: () => true, to: 4, - caption: "Previous", + caption: "%general.previous%", }, next: { - caption: "Let's begin", + caption: "%apps.initialSetupWizard.buttons.letsBegin%", action: () => this.finish(), suggested: true, }, }, { left: { - caption: "Cancel", + caption: "%general.cancel%", disabled: () => true, }, previous: { - caption: "Previous", + caption: "%general.previous%", disabled: () => true, }, next: { - caption: "Server's all good", + caption: "%apps.initialSetupWizard.serverAllGood%", to: 0, suggested: true, }, @@ -182,18 +182,17 @@ export class InitialSetupRuntime extends AppProcess { MessageBox( { - title: "Just making sure...", - message: - "By using ArcOS, you agree to the License Agreement. You may not violate any of the rules contained within this license. Continue?", + title: "%apps.initialSetupWizard.licenseConfirmation.title%", + message: "%apps.initialSetupWizard.licenseConfirmation.message%", buttons: [ { - caption: "Decline", + caption: "%general.decline%", action: () => { this.actionsDisabled.set(false); }, }, { - caption: "I agree", + caption: "%general.iAgree%", suggested: true, action: () => { this.pageNumber.set(this.pageNumber() + 1); @@ -213,19 +212,17 @@ export class InitialSetupRuntime extends AppProcess { MessageBox( { image: SecurityMediumIcon, - title: "ArcOS License - GPLv3", - message: `By using ArcOS, you agree to the GPLv3 License contained within: ${htmlspecialchars( - ArcLicense() - )}`, + title: "%apps.initialSetupWizard.viewLicense.title%", + message: `%apps.initialSetupWizard.viewLicense.message%: ${htmlspecialchars(ArcLicense())}`, buttons: [ { - caption: "Decline", + caption: "%general.decline%", action: () => { KernelStateHandler()?.loadState("licenseDeclined"); }, }, { - caption: "I agree", + caption: "%general.iAgree%", action: () => { this.actionsDisabled.set(false); }, @@ -253,11 +250,11 @@ export class InitialSetupRuntime extends AppProcess { MessageBox( { image: WarningIcon, - title: "You made a typo!", - message: "The passwords you entered don't match. Please re-enter them, and then try again.", + title: "%apps.initialSetupWizard.createAccount.passwordMismatch.title%", + message: "%apps.initialSetupWizard.createAccount.passwordMismatch.message%", buttons: [ { - caption: "Okay", + caption: "%general.okay%", suggested: true, action: () => { this.actionsDisabled.set(false); @@ -278,12 +275,11 @@ export class InitialSetupRuntime extends AppProcess { MessageBox( { image: ErrorIcon, - title: "Something went wrong", - message: - "An error occurred while creating your account. We might be experiencing some technical difficulties, please try again later.", + title: "%apps.initialSetupWizard.createAccount.genericError.title%", + message: "%apps.initialSetupWizard.createAccount.genericError.message%", buttons: [ { - caption: "Okay", + caption: "%generic.okay%", suggested: true, action: () => { this.actionsDisabled.set(false); @@ -309,12 +305,11 @@ export class InitialSetupRuntime extends AppProcess { if (!token) { MessageBox( { - title: "Did you click the link?", - message: - "Our systems tell me that your account hasn't been activated yet. Are you sure you clicked the link? If you did, and you're still seeing this, please contact support.", + title: "%apps.initialSetupWizard.checkAccountActivationError.title%", + message: "%apps.initialSetupWizard.checkAccountActivationError.message%", buttons: [ { - caption: "Okay", + caption: "%generic.okay%", action: () => { this.actionsDisabled.set(false); }, diff --git a/src/apps/core/loginapp/ErrorMessage.svelte b/src/apps/core/loginapp/ErrorMessage.svelte index abdd3cbfd..9257c27a4 100755 --- a/src/apps/core/loginapp/ErrorMessage.svelte +++ b/src/apps/core/loginapp/ErrorMessage.svelte @@ -7,4 +7,4 @@

{@html $errorMessage}

- + diff --git a/src/apps/core/loginapp/Loading.svelte b/src/apps/core/loginapp/Loading.svelte index 9ce31d65a..c767498eb 100755 --- a/src/apps/core/loginapp/Loading.svelte +++ b/src/apps/core/loginapp/Loading.svelte @@ -7,5 +7,5 @@

- {@html $loadingStatus} + {$loadingStatus}

diff --git a/src/apps/core/loginapp/LoginForm.svelte b/src/apps/core/loginapp/LoginForm.svelte index e64151d74..fe1b412eb 100755 --- a/src/apps/core/loginapp/LoginForm.svelte +++ b/src/apps/core/loginapp/LoginForm.svelte @@ -28,9 +28,9 @@