mirror of
https://github.com/open-goal/launcher.git
synced 2024-10-19 14:47:36 -04:00
i18n: make the app translatable (#196)
This commit is contained in:
parent
771286dd82
commit
8d7fe7c03f
3
crowdin.yml
Normal file
3
crowdin.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
files:
|
||||
- source: /src/assets/translations/en-US.json
|
||||
translation: /src/assets/translations/%locale%.json
|
|
@ -40,6 +40,7 @@
|
|||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-svelte": "^2.10.0",
|
||||
"svelte": "^3.58.0",
|
||||
"svelte-i18n": "^3.6.0",
|
||||
"svelte-preprocess": "^5.0.3",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"typescript": "^5.0.4",
|
||||
|
@ -47,6 +48,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^1.2.0",
|
||||
"country-flag-emoji-polyfill": "^0.1.4",
|
||||
"svelte-navigator": "^3.2.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -201,3 +201,23 @@ pub async fn get_active_tooling_version_folder(
|
|||
let config_lock = config.lock().await;
|
||||
Ok(config_lock.active_version_folder.clone())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_locale(
|
||||
config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>,
|
||||
) -> Result<Option<String>, CommandError> {
|
||||
let config_lock = config.lock().await;
|
||||
Ok(config_lock.locale.clone())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn set_locale(
|
||||
config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>,
|
||||
locale: String,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut config_lock = config.lock().await;
|
||||
config_lock
|
||||
.set_locale(locale)
|
||||
.map_err(|_| CommandError::Configuration(format!("Unable to persist locale change")))?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -117,6 +117,7 @@ pub struct LauncherConfig {
|
|||
pub installation_dir: Option<String>,
|
||||
pub active_version: Option<String>,
|
||||
pub active_version_folder: Option<String>,
|
||||
pub locale: Option<String>,
|
||||
}
|
||||
|
||||
fn default_version() -> Option<String> {
|
||||
|
@ -134,6 +135,7 @@ impl LauncherConfig {
|
|||
installation_dir: None,
|
||||
active_version: None,
|
||||
active_version_folder: Some("official".to_string()),
|
||||
locale: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,6 +273,12 @@ impl LauncherConfig {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_locale(&mut self, new_locale: String) -> Result<(), ConfigError> {
|
||||
self.locale = Some(new_locale);
|
||||
self.save_config()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TODO - this pattern isn't great. It's made awkward by trying to be backwards compatible
|
||||
// with the old format though
|
||||
//
|
||||
|
|
|
@ -155,6 +155,8 @@ fn main() {
|
|||
commands::config::set_opengl_requirement_met,
|
||||
commands::config::save_active_version_change,
|
||||
commands::config::set_install_directory,
|
||||
commands::config::get_locale,
|
||||
commands::config::set_locale,
|
||||
commands::game::reset_game_settings,
|
||||
commands::game::uninstall_game,
|
||||
commands::support::generate_support_package,
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
import Settings from "./routes/Settings.svelte";
|
||||
import Sidebar from "./components/sidebar/Sidebar.svelte";
|
||||
import Background from "./components/background/Background.svelte";
|
||||
import { appWindow } from "@tauri-apps/api/window";
|
||||
import Header from "./components/header/Header.svelte";
|
||||
import Textures from "./routes/Textures.svelte";
|
||||
import Update from "./routes/Update.svelte";
|
||||
|
@ -15,6 +14,7 @@
|
|||
import { Toast } from "flowbite-svelte";
|
||||
import Help from "./routes/Help.svelte";
|
||||
import { toastStore } from "$lib/stores/ToastStore";
|
||||
import { isLoading } from "svelte-i18n";
|
||||
|
||||
let revokeSpecificActions = false;
|
||||
|
||||
|
@ -59,14 +59,20 @@
|
|||
</script>
|
||||
|
||||
<Router>
|
||||
<div class="container h-screen max-w-none flex flex-col">
|
||||
<div class={`container h-screen max-w-none flex flex-col bg-black`}>
|
||||
{#if !$isLoading}
|
||||
<Background />
|
||||
<Header />
|
||||
<div class="flex h-full">
|
||||
<div class="flex h-full z-10">
|
||||
<Sidebar />
|
||||
<div id="content" class="basis-9/10">
|
||||
<Route path="/" component={Game} primary={false} let:params />
|
||||
<Route path="/:game_name" component={Game} primary={false} let:params />
|
||||
<Route
|
||||
path="/:game_name"
|
||||
component={Game}
|
||||
primary={false}
|
||||
let:params
|
||||
/>
|
||||
<Route
|
||||
path="/jak2"
|
||||
component={GameInProgress}
|
||||
|
@ -95,5 +101,6 @@
|
|||
{$toastStore.msg}
|
||||
</Toast>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</Router>
|
||||
|
|
118
src/assets/translations/en-US.json
Normal file
118
src/assets/translations/en-US.json
Normal file
|
@ -0,0 +1,118 @@
|
|||
{
|
||||
"header_updateAvailable": "Update Available!",
|
||||
"setup_extractAndVerify": "Extract and Verify",
|
||||
"setup_copyFiles": "Copy Files",
|
||||
"setup_decompile": "Decompile",
|
||||
"setup_compile": "Compile",
|
||||
"setup_done": "Done",
|
||||
"setup_button_continue": "Continue",
|
||||
"setup_installationFailed": "Installation has Failed!",
|
||||
"setup_button_getSupportPackage": "Get Support Package",
|
||||
"setup_button_installViaISO": "Install via ISO",
|
||||
"setup_logs_header": "Logs",
|
||||
"setup_logs_truncation": "Last 250 Lines",
|
||||
"gameUpdate_versionMismatch_title": "Version Mismatch Detected!",
|
||||
"gameUpdate_versionMismatch_currentlyInstalled": "The game is already installed with",
|
||||
"gameUpdate_versionMismatch_version": "Version",
|
||||
"gameUpdate_versionMismatch_type": "Type",
|
||||
"gameUpdate_versionMismatch_currentlySelected": "but you currently have selected",
|
||||
"gameUpdate_versionMismatch_nextSteps": "You can either update the game to this new version (no save data will be lost) or you can rollback your active version to match",
|
||||
"gameUpdate_versionMismatch_button_updateGame": "Update Game",
|
||||
"gameUpdate_versionMismatch_button_changeVersion": "Change Version",
|
||||
"requirements_notMet_header": "Unfortunately, your system does not meet all the minimum requirements or we were unable to check them",
|
||||
"requirements_cpu_supportsAVX": "Your CPU supports AVX",
|
||||
"requirements_cpu_unableToCheckAVX": "Unable to verify if your CPU supports AVX",
|
||||
"requirements_cpu_doesNotSupportAVX": "Your CPU does not support AVX",
|
||||
"requirements_cpu_avxExplanation_1": "This cannot be fixed without upgrading to a newer CPU",
|
||||
"requirements_cpu_avxExplanation_2": "AVX support has been fairly standard since 2011",
|
||||
"requirements_cpu_avxExplanation_3": "Click here for more information",
|
||||
"requirements_gpu_supportsOpenGL": "Your GPU supports OpenGL 4.3",
|
||||
"requirements_gpu_unableToCheckOpenGL": "Unable to verify if your GPU supports OpenGL 4.3",
|
||||
"requirements_gpu_doesNotSupportOpenGL": "Your GPU does not support OpenGL 4.3",
|
||||
"requirements_gpu_avxExplanation_1_preLink": "Lookup your GPU",
|
||||
"requirements_gpu_avxExplanation_1_link": "here",
|
||||
"requirements_gpu_avxExplanation_1_postLink": "to see if it should be supported",
|
||||
"requirements_gpu_avxExplanation_2": "You can attempt to upgrade your GPU drivers",
|
||||
"requirements_gpu_avxExplanation_3": "Otherwise, you will need to upgrade your GPU, most GPUs since 2012 support it",
|
||||
"gameControls_button_play": "Play",
|
||||
"gameControls_button_advanced": "Advanced",
|
||||
"gameControls_button_playInDebug": "Play in Debug Mode",
|
||||
"gameControls_button_openREPL": "Open REPL",
|
||||
"gameControls_button_decompile": "Decompile",
|
||||
"gameControls_button_decompile_helpText": "Extracts game assets (ie. to apply texture replacements)",
|
||||
"gameControls_button_compile": "Compile",
|
||||
"gameControls_button_compile_helpText": "Rebuild the game. (ie. after modifying OpenGOAL source code)",
|
||||
"gameControls_button_openSettingsFolder": "Open Settings Folder",
|
||||
"gameControls_button_openSavesFolder": "Open Saves Folder",
|
||||
"gameControls_button_resetSettings": "Reset Settings",
|
||||
"gameControls_button_uninstall_confirmation": "Are you sure you want to uninstall?",
|
||||
"gameControls_button_uninstall": "Uninstall",
|
||||
"gameControls_button_uninstall_helpText": "This will not delete any saves or settings",
|
||||
"gameName_jak1": "Jak & Daxter: The Precursor Legacy",
|
||||
"gameName_jak2": "Jak II",
|
||||
"temp_jak2_indev_header": "Jak II is Currently in Development",
|
||||
"temp_jak2_indev_subheader": "In the meantime, check out our latest progress reports showcasing what we've accomplished so far",
|
||||
"temp_jak2_indev_progressReports": "Progress Reports",
|
||||
"gameControls_noToolingSet_header": "No Tooling Version Configured!",
|
||||
"gameControls_noToolingSet_subheader": "Head over to the following settings page to download the latest release",
|
||||
"gameControls_noToolingSet_button_setVersion": "Set Version",
|
||||
"sidebar_settings": "Settings",
|
||||
"sidebar_help": "Help",
|
||||
"settings_general_localeChange": "Change Locale",
|
||||
"settings_general_localeChange_helper_1": "Consider ",
|
||||
"settings_general_localeChange_helper_link": "contributing translations",
|
||||
"settings_general_localeChange_helper_2": "if you can!",
|
||||
"settings_general_button_resetSettings": "Reset Launcher Settings",
|
||||
"settings_general_button_resetSettings_confirmation": "Are you sure you want to reset your launcher settings? This will reset your installation directory and any other settings you have changed. This will not affect your game files.",
|
||||
"settings_folders_installationDir": "Installation Directory",
|
||||
"settings_folders_installationDir_prompt": "Pick an Installation Folder",
|
||||
"settings_versions_devel_tabName": "Development",
|
||||
"settings_versions_devel_description": "This list serves as a convenient area to stage, manage and test new releases (either official or unofficial) This list will always require manual management via it's respective folder",
|
||||
"settings_versions_official_tabName": "Official",
|
||||
"settings_versions_official_description": "Official versions are from the `jak-project` GitHub repository",
|
||||
"settings_versions_unofficial_tabName": "Unofficial",
|
||||
"settings_versions_unofficial_description": "Unofficial versions are typically modified `jak-project` releases to enable changes or new content. These are not supported by the OpenGOAL team and will have to be manually added to the folder at this time",
|
||||
"settings_versions_icon_save_altText": "save version change",
|
||||
"settings_versions_icon_refresh_altText": "refresh version list",
|
||||
"settings_versions_icon_openFolder_altText": "open version folder",
|
||||
"settings_versions_icon_removeVersion_altText": "remove version",
|
||||
"settings_versions_icon_downloadVersion_altText": "download version",
|
||||
"settings_versions_icon_githubRelease_altText": "github release notes",
|
||||
"settings_versions_table_header_version": "Version",
|
||||
"settings_versions_table_header_date": "Date",
|
||||
"settings_versions_table_header_changes": "Changes",
|
||||
"settings_versions_header": "Configure your active tooling version",
|
||||
"help_header": "Support & FAQ",
|
||||
"help_foreword": "If you are reporting an issue or asking for help, download the following support package and attach it in your Discord thread or GitHub issue.",
|
||||
"help_button_downloadPackage": "Download Support Package",
|
||||
"help_button_openLogFolder": "Open Log Folder",
|
||||
"help_description_createAnIssue": "You can either ask a question on our Discord, or create a GitHub issue with as much detail as possible.",
|
||||
"help_description_duplicateReminder": "In either location, please do a quick search to see if the question has already been answered before",
|
||||
"help_button_reportLauncherIssue": "Report Launcher Issue",
|
||||
"help_button_reportGameIssue": "Report Game Issue",
|
||||
"settings_tabs_general": "General",
|
||||
"settings_tabs_folders": "General",
|
||||
"settings_tabs_versions": "General",
|
||||
"update_header": "Launcher Update Available",
|
||||
"update_versionLabel": "Version",
|
||||
"update_description": "View the changes below and click the button to update to the latest version. The launcher will restart when finished.",
|
||||
"update_button_doUpdate": "Update Launcher",
|
||||
"update_button_viewChangelog": "View Changelog",
|
||||
"update_button_hideDependencyChanges": "Dependency Changes",
|
||||
"update_changelog_header_contributor": "Contributor",
|
||||
"update_changelog_header_description": "Description",
|
||||
"update_changelog_header_pullRequest": "Pull Request",
|
||||
"update_alreadyUpToDate": "You're Up to Date!",
|
||||
"splash_selectLocale": "Select Locale",
|
||||
"splash_deleteOldInstallDir": "The old installation folder is no longer needed, delete it?",
|
||||
"splash_button_deleteOldInstallDir_yes": "Yes",
|
||||
"splash_button_deleteOldInstallDir_no": "No",
|
||||
"splash_noInstallDirSet": "No installation folder set!",
|
||||
"splash_button_setInstallFolder": "Set Install Folder",
|
||||
"splash_button_setInstallFolder_prompt": "Pick an Installation Folder",
|
||||
"splash_step_readingSettings": "Reading Settings",
|
||||
"splash_step_checkingDirectories": "Checking Directories",
|
||||
"splash_step_pickInstallFolder": "Pick an Installation Folder",
|
||||
"splash_step_finishingUp": "Finishing Up",
|
||||
"splash_step_errorOpening": "Problem opening Launcher"
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"jak1_gameName": "Jak & Daxter: The Precursor Legacy"
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
const location = useLocation();
|
||||
$: $location.pathname, updateStyle();
|
||||
|
||||
let style = "absolute -z-50 object-fill h-screen";
|
||||
let style = "absolute object-fill h-screen";
|
||||
|
||||
onMount(async () => {
|
||||
const unlistenInstalled = await listen("gameInstalled", (event) => {
|
||||
|
@ -23,7 +23,7 @@
|
|||
});
|
||||
|
||||
async function updateStyle(): Promise<void> {
|
||||
let newStyle = "absolute -z-50 object-fill h-screen";
|
||||
let newStyle = "absolute object-fill h-screen";
|
||||
let pathname = $location.pathname;
|
||||
if (pathname === "/jak1" || pathname === "/") {
|
||||
if (!(await isGameInstalled("jak1"))) {
|
||||
|
|
9
src/components/background/BackgroundLoading.svelte
Normal file
9
src/components/background/BackgroundLoading.svelte
Normal file
|
@ -0,0 +1,9 @@
|
|||
<script lang="ts">
|
||||
import logo from "$assets/images/icon.webp";
|
||||
import { Spinner } from "flowbite-svelte";
|
||||
</script>
|
||||
|
||||
<div class="h-screen flex flex-col items-center justify-center bg-black">
|
||||
<img data-tauri-drag-region src={logo} alt="" srcset="" class="w-48" />
|
||||
<Spinner color="yellow" size={"12"} class="mt-5" />
|
||||
</div>
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { getGameTitle, getInternalName, SupportedGame } from "$lib/constants";
|
||||
import { getInternalName, SupportedGame } from "$lib/constants";
|
||||
import { openDir } from "$lib/rpc/window";
|
||||
import Icon from "@iconify/svelte";
|
||||
import { configDir, join } from "@tauri-apps/api/path";
|
||||
|
@ -15,6 +15,7 @@
|
|||
import { resetGameSettings, uninstallGame } from "$lib/rpc/game";
|
||||
import { platform } from "@tauri-apps/api/os";
|
||||
import { launchGame, openREPL } from "$lib/rpc/binaries";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
export let activeGame: SupportedGame;
|
||||
|
||||
|
@ -45,14 +46,14 @@
|
|||
<h1
|
||||
class="tracking-tighter text-2xl font-bold pb-3 text-orange-500 text-outline pointer-events-none"
|
||||
>
|
||||
{getGameTitle(activeGame)}
|
||||
{$_(`gameName_${getInternalName(activeGame)}`)}
|
||||
</h1>
|
||||
<div class="flex flex-row gap-2">
|
||||
<Button
|
||||
btnClass="border-solid border-2 border-slate-900 rounded bg-slate-900 hover:bg-slate-800 text-sm text-white font-semibold px-5 py-2"
|
||||
on:click={async () => {
|
||||
launchGame(getInternalName(activeGame), false);
|
||||
}}>Play</Button
|
||||
}}>{$_("gameControls_button_play")}</Button
|
||||
>
|
||||
<!-- TODO - texture replacements left out for now, get everything else working end-to-end first -->
|
||||
<!-- <Button
|
||||
|
@ -65,19 +66,19 @@
|
|||
<Button
|
||||
btnClass="text-center font-semibold focus:ring-0 focus:outline-none inline-flex items-center justify-center px-2 py-2 text-sm text-white border-solid border-2 border-slate-900 rounded bg-slate-900 hover:bg-slate-800"
|
||||
>
|
||||
Advanced
|
||||
{$_("gameControls_button_advanced")}
|
||||
</Button>
|
||||
<Dropdown placement="top-end" frameClass="!bg-slate-900">
|
||||
<DropdownItem
|
||||
on:click={async () => {
|
||||
launchGame(getInternalName(activeGame), true);
|
||||
}}>Play in Debug Mode</DropdownItem
|
||||
}}>{$_("gameControls_button_playInDebug")}</DropdownItem
|
||||
>
|
||||
{#if !isLinux}
|
||||
<DropdownItem
|
||||
on:click={async () => {
|
||||
openREPL(getInternalName(activeGame));
|
||||
}}>Open REPL</DropdownItem
|
||||
}}>{$_("gameControls_button_openREPL")}</DropdownItem
|
||||
>
|
||||
{/if}
|
||||
<DropdownDivider />
|
||||
|
@ -87,10 +88,10 @@
|
|||
type: "decompile",
|
||||
});
|
||||
}}
|
||||
>Decompile
|
||||
>{$_("gameControls_button_decompile")}
|
||||
<!-- NOTE - this is a bug in flowbite-svelte, it's not replacing the default class but just appending -->
|
||||
<Helper helperClass="!text-neutral-400 !text-xs"
|
||||
>Extracts game assets (ie. to apply texture replacements)</Helper
|
||||
>{$_("gameControls_button_decompile_helpText")}</Helper
|
||||
></DropdownItem
|
||||
>
|
||||
<DropdownItem
|
||||
|
@ -99,10 +100,10 @@
|
|||
type: "compile",
|
||||
});
|
||||
}}
|
||||
>Compile
|
||||
>{$_("gameControls_button_compile")}
|
||||
<!-- NOTE - this is a bug in flowbite-svelte, it's not replacing the default class but just appending -->
|
||||
<Helper helperClass="!text-neutral-400 !text-xs"
|
||||
>Rebuild the game. (ie. after modifying OpenGOAL source code)
|
||||
>{$_("gameControls_button_compile_helpText")}
|
||||
</Helper></DropdownItem
|
||||
>
|
||||
</Dropdown>
|
||||
|
@ -116,12 +117,12 @@
|
|||
<DropdownItem
|
||||
on:click={async () => {
|
||||
await openDir(settingsDir);
|
||||
}}>Open Settings Folder</DropdownItem
|
||||
}}>{$_("gameControls_button_openSettingsFolder")}</DropdownItem
|
||||
>
|
||||
<DropdownItem
|
||||
on:click={async () => {
|
||||
await openDir(savesDir);
|
||||
}}>Open Saves Folder</DropdownItem
|
||||
}}>{$_("gameControls_button_openSavesFolder")}</DropdownItem
|
||||
>
|
||||
<DropdownDivider />
|
||||
<!-- TODO - verify installation -->
|
||||
|
@ -129,14 +130,14 @@
|
|||
<DropdownItem
|
||||
on:click={async () => {
|
||||
await resetGameSettings(getInternalName(activeGame));
|
||||
}}>Reset Settings</DropdownItem
|
||||
}}>{$_("gameControls_button_resetSettings")}</DropdownItem
|
||||
>
|
||||
<DropdownItem
|
||||
on:click={async () => {
|
||||
// Get confirmation
|
||||
// TODO - probably move these confirms into the actual launcher itself
|
||||
const confirmed = await confirm(
|
||||
"Are you sure you want to uninstall?",
|
||||
$_("gameControls_button_uninstall_confirmation"),
|
||||
{ title: "OpenGOAL Launcher", type: "warning" }
|
||||
);
|
||||
if (confirmed) {
|
||||
|
@ -144,8 +145,9 @@
|
|||
dispatch("change");
|
||||
}
|
||||
}}
|
||||
>Uninstall<Helper helperClass="!text-neutral-400 !text-xs"
|
||||
>This will not delete any saves or settings</Helper
|
||||
>{$_("gameControls_button_uninstall")}<Helper
|
||||
helperClass="!text-neutral-400 !text-xs"
|
||||
>{$_("gameControls_button_uninstall_helpText")}</Helper
|
||||
></DropdownItem
|
||||
>
|
||||
</Dropdown>
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
<script lang="ts">
|
||||
import { _ } from "svelte-i18n";
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col h-full justify-center items-center p-5 text-center">
|
||||
<h1 class="text-2xl font-black mb-5 text-outline">
|
||||
Jak 2 is Currently in Development
|
||||
{$_("temp_jak2_indev_header")}
|
||||
</h1>
|
||||
<p class="mb-10">
|
||||
In the meantime, check out our latest progress reports showcasing what we've
|
||||
accomplished so far
|
||||
{$_("temp_jak2_indev_subheader")}
|
||||
</p>
|
||||
<a
|
||||
class="font-bold text-orange-400 hover:text-orange-600"
|
||||
href="https://opengoal.dev/blog/tags/progress-report"
|
||||
target="_blank"
|
||||
rel="noreferrer">Progress Reports</a
|
||||
rel="noreferrer">{$_("temp_jak2_indev_progressReports")}</a
|
||||
>
|
||||
</div>
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
<script>
|
||||
import { Button } from "flowbite-svelte";
|
||||
import { _ } from "svelte-i18n";
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col h-full justify-center items-center p-5 text-center">
|
||||
<h1 class="text-2xl font-black mb-5 text-outline">
|
||||
No Tooling Version Configured!
|
||||
{$_("gameControls_noToolingSet_header")}
|
||||
</h1>
|
||||
<p class="mb-10">
|
||||
Head over to the following settings page to download the latest release
|
||||
{$_("gameControls_noToolingSet_subheader")}
|
||||
</p>
|
||||
<Button
|
||||
btnClass="border-solid border-2 border-slate-500 rounded bg-slate-900 hover:bg-slate-800 text-sm text-white font-semibold px-5 py-2"
|
||||
href="/settings/versions">Set Version</Button
|
||||
href="/settings/versions"
|
||||
>{$_("gameControls_noToolingSet_button_setVersion")}</Button
|
||||
>
|
||||
</div>
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
} from "$lib/rpc/binaries";
|
||||
import { finalizeInstallation } from "$lib/rpc/config";
|
||||
import { generateSupportPackage } from "$lib/rpc/support";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
export let activeGame: SupportedGame;
|
||||
export let jobType: Job;
|
||||
|
@ -32,11 +33,11 @@
|
|||
progressTracker.init([
|
||||
{
|
||||
status: "queued",
|
||||
label: "Decompile",
|
||||
label: $_("setup_decompile"),
|
||||
},
|
||||
{
|
||||
status: "queued",
|
||||
label: "Done",
|
||||
label: $_("setup_done"),
|
||||
},
|
||||
]);
|
||||
progressTracker.start();
|
||||
|
@ -54,11 +55,11 @@
|
|||
progressTracker.init([
|
||||
{
|
||||
status: "queued",
|
||||
label: "Compile",
|
||||
label: $_("setup_compile"),
|
||||
},
|
||||
{
|
||||
status: "queued",
|
||||
label: "Done",
|
||||
label: $_("setup_done"),
|
||||
},
|
||||
]);
|
||||
progressTracker.start();
|
||||
|
@ -76,19 +77,19 @@
|
|||
progressTracker.init([
|
||||
{
|
||||
status: "queued",
|
||||
label: "Copy Files",
|
||||
label: $_("setup_copyFiles"),
|
||||
},
|
||||
{
|
||||
status: "queued",
|
||||
label: "Decompile",
|
||||
label: $_("setup_decompile"),
|
||||
},
|
||||
{
|
||||
status: "queued",
|
||||
label: "Compile",
|
||||
label: $_("setup_compile"),
|
||||
},
|
||||
{
|
||||
status: "queued",
|
||||
label: "Done",
|
||||
label: $_("setup_done"),
|
||||
},
|
||||
]);
|
||||
progressTracker.start();
|
||||
|
@ -137,7 +138,8 @@
|
|||
<div class="flex flex-row gap-2">
|
||||
<Button
|
||||
btnClass="border-solid border-2 border-slate-900 rounded bg-slate-900 hover:bg-slate-800 text-sm text-white font-semibold px-5 py-2"
|
||||
on:click={async () => dispatchCompleteJob()}>Continue</Button
|
||||
on:click={async () => dispatchCompleteJob()}
|
||||
>{$_("setup_button_continue")}</Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -146,13 +148,13 @@
|
|||
<div class="flex flex-row gap-2">
|
||||
<Alert color="red" class="dark:bg-slate-900 flex-grow" accent={true}>
|
||||
<span class="font-medium text-red-500"
|
||||
>Installation has failed!
|
||||
>{$_("setup_installationFailed")}
|
||||
</span><span class="text-white"> {installationError}</span>
|
||||
</Alert>
|
||||
<Button
|
||||
btnClass="border-solid border-2 border-slate-900 rounded bg-slate-900 hover:bg-slate-800 text-sm text-white font-semibold px-5 py-2"
|
||||
on:click={async () => await generateSupportPackage()}
|
||||
>Get Support Package</Button
|
||||
>{$_("setup_button_getSupportPackage")}</Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
<script lang="ts">
|
||||
import Progress from "./Progress.svelte";
|
||||
import {
|
||||
getGameTitle,
|
||||
getInternalName,
|
||||
type SupportedGame,
|
||||
} from "$lib/constants";
|
||||
import { getInternalName, type SupportedGame } from "$lib/constants";
|
||||
import LogViewer from "./LogViewer.svelte";
|
||||
import Requirements from "./Requirements.svelte";
|
||||
import { createEventDispatcher, onMount } from "svelte";
|
||||
|
@ -25,6 +21,7 @@
|
|||
import { progressTracker } from "$lib/stores/ProgressStore";
|
||||
import { generateSupportPackage } from "$lib/rpc/support";
|
||||
import { isOpenGLVersionSupported } from "$lib/sidecars/glewinfo";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
export let activeGame: SupportedGame;
|
||||
|
||||
|
@ -61,19 +58,19 @@
|
|||
progressTracker.init([
|
||||
{
|
||||
status: "queued",
|
||||
label: "Extract and Verify",
|
||||
label: $_("setup_extractAndVerify"),
|
||||
},
|
||||
{
|
||||
status: "queued",
|
||||
label: "Decompile",
|
||||
label: $_("setup_decompile"),
|
||||
},
|
||||
{
|
||||
status: "queued",
|
||||
label: "Compile",
|
||||
label: $_("setup_compile"),
|
||||
},
|
||||
{
|
||||
status: "queued",
|
||||
label: "Done",
|
||||
label: $_("setup_done"),
|
||||
},
|
||||
]);
|
||||
// TODO - make this cleaner
|
||||
|
@ -130,7 +127,8 @@
|
|||
<div class="flex flex-row gap-2">
|
||||
<Button
|
||||
btnClass="border-solid border-2 border-slate-900 rounded bg-slate-900 hover:bg-slate-800 text-sm text-white font-semibold px-5 py-2"
|
||||
on:click={async () => await dispatchSetupEvent()}>Continue</Button
|
||||
on:click={async () => await dispatchSetupEvent()}
|
||||
>{$_("setup_button_continue")}</Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -139,13 +137,13 @@
|
|||
<div class="flex flex-row gap-2">
|
||||
<Alert color="red" class="dark:bg-slate-900 flex-grow" accent={true}>
|
||||
<span class="font-medium text-red-500"
|
||||
>Installation has failed!
|
||||
>{$_("setup_installationFailed")}
|
||||
</span><span class="text-white"> {installationError}</span>
|
||||
</Alert>
|
||||
<Button
|
||||
btnClass="border-solid border-2 border-slate-900 rounded bg-slate-900 hover:bg-slate-800 text-sm text-white font-semibold px-5 py-2"
|
||||
on:click={async () => await generateSupportPackage()}
|
||||
>Get Support Package</Button
|
||||
>{$_("setup_button_getSupportPackage")}</Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -155,12 +153,13 @@
|
|||
<h1
|
||||
class="tracking-tighter text-2xl font-bold pb-3 text-orange-500 text-outline"
|
||||
>
|
||||
{getGameTitle(activeGame)}
|
||||
{$_(`gameName_${getInternalName(activeGame)}`)}
|
||||
</h1>
|
||||
<div class="flex flex-row gap-2">
|
||||
<Button
|
||||
btnClass="border-solid border-2 border-slate-900 rounded bg-slate-900 hover:bg-slate-800 text-sm text-white font-semibold px-5 py-2"
|
||||
on:click={async () => await install(false)}>Install via ISO</Button
|
||||
on:click={async () => await install(false)}
|
||||
>{$_("setup_button_installViaISO")}</Button
|
||||
>
|
||||
<!-- TODO - disabled for now, needs fixes in the extractor -->
|
||||
<!-- <Button
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import { VersionStore } from "$lib/stores/VersionStore";
|
||||
import { Button, Card } from "flowbite-svelte";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
export let activeGame: SupportedGame;
|
||||
|
||||
|
@ -17,25 +18,36 @@
|
|||
<h5
|
||||
class="mb-2 text-xl font-bold text-gray-900 dark:text-white text-center"
|
||||
>
|
||||
Version Mismatch Detected!
|
||||
{$_("gameUpdate_versionMismatch_title")}
|
||||
</h5>
|
||||
<p class="text-base text-gray-500 dark:text-gray-400 mb-1">
|
||||
The game is already installed with...
|
||||
{$_("gameUpdate_versionMismatch_currentlyInstalled")}...
|
||||
</p>
|
||||
<ul class="list-disc list-inside mb-2">
|
||||
<li>Version: <strong>{installedVersion}</strong></li>
|
||||
<li>Type: <strong>{installedVersionFolder}</strong></li>
|
||||
<li>
|
||||
{$_("gameUpdate_versionMismatch_version")}:
|
||||
<strong>{installedVersion}</strong>
|
||||
</li>
|
||||
<li>
|
||||
{$_("gameUpdate_versionMismatch_type")}:
|
||||
<strong>{installedVersionFolder}</strong>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="text-base text-gray-500 dark:text-gray-400 mb-1">
|
||||
...but you currently have selected
|
||||
...{$_("gameUpdate_versionMismatch_currentlySelected")}
|
||||
</p>
|
||||
<ul class="list-disc list-inside mb-5">
|
||||
<li>Version: <strong>{$VersionStore.activeVersionName}</strong></li>
|
||||
<li>Type: <strong>{$VersionStore.activeVersionType}</strong></li>
|
||||
<li>
|
||||
{$_("gameUpdate_versionMismatch_version")}:
|
||||
<strong>{$VersionStore.activeVersionName}</strong>
|
||||
</li>
|
||||
<li>
|
||||
{$_("gameUpdate_versionMismatch_type")}:
|
||||
<strong>{$VersionStore.activeVersionType}</strong>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="mb-3">
|
||||
You can either update the game to this new version (no save data will be
|
||||
lost) or you can rollback your active version to match
|
||||
{$_("gameUpdate_versionMismatch_nextSteps")}
|
||||
</p>
|
||||
<div
|
||||
class="justify-center items-center space-y-4 sm:flex sm:space-y-0 sm:space-x-4"
|
||||
|
@ -46,11 +58,12 @@
|
|||
dispatch("job", {
|
||||
type: "updateGame",
|
||||
});
|
||||
}}>Update Game</Button
|
||||
}}>{$_("gameUpdate_versionMismatch_button_updateGame")}</Button
|
||||
>
|
||||
<Button
|
||||
btnClass="border-solid border-2 border-slate-500 rounded bg-slate-900 hover:bg-slate-800 text-sm text-white font-semibold px-5 py-2"
|
||||
href="/settings/versions">Change Version</Button
|
||||
href="/settings/versions"
|
||||
>{$_("gameUpdate_versionMismatch_button_changeVersion")}</Button
|
||||
>
|
||||
</div>
|
||||
</Card>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import { Accordion, AccordionItem } from "flowbite-svelte";
|
||||
import { ansiSpan } from "ansi-to-span";
|
||||
import escapeHtml from "escape-html";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
function convertLogColors(text) {
|
||||
return ansiSpan(escapeHtml(text)).replaceAll("\n", "<br/>");
|
||||
|
@ -14,14 +15,14 @@
|
|||
<AccordionItem class="bg-slate-900 rounded p-[1rem]">
|
||||
<span slot="header" class="text-sm font-semibold text-white flex gap-2">
|
||||
<Icon icon="mdi:file-document-outline" width={18} />
|
||||
<span>Logs</span>
|
||||
<span>{$_("setup_logs_header")}</span>
|
||||
</span>
|
||||
<div
|
||||
slot="default"
|
||||
class="bg-slate-900 px-4 max-h-60 overflow-y-scroll scrollbar"
|
||||
>
|
||||
<p class="py-4 text-clip overflow-hidden font-mono log-output">
|
||||
...Last 250 Lines:
|
||||
...{$_("setup_logs_truncation")}:
|
||||
<br />
|
||||
{@html convertLogColors($progressTracker.logs)}
|
||||
</p>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
type ProgressStatus,
|
||||
} from "$lib/stores/ProgressStore";
|
||||
import Icon from "@iconify/svelte";
|
||||
|
||||
$: progress = $progressTracker;
|
||||
|
||||
const iconContainerStyle =
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { onMount } from "svelte";
|
||||
import { Alert } from "flowbite-svelte";
|
||||
import { isAVXRequirementMet, isOpenGLRequirementMet } from "$lib/rpc/config";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
let isAVXMet = false;
|
||||
let isOpenGLMet = false;
|
||||
|
@ -23,8 +24,7 @@
|
|||
class="flex flex-col h-full justify-center items-center p-5 text-center gap-3"
|
||||
>
|
||||
<h1 class="text-xl font-black mb-5 text-outline">
|
||||
Unfortunately, your system does not meet all the minimum requirements or we
|
||||
were unable to check them
|
||||
{$_("requirements_notMet_header")}
|
||||
</h1>
|
||||
<Alert
|
||||
class="w-full text-start"
|
||||
|
@ -33,21 +33,21 @@
|
|||
color={alertColor(isAVXMet)}
|
||||
>
|
||||
{#if isAVXMet}
|
||||
<span class="font-bold">Your CPU supports AVX</span>
|
||||
<span class="font-bold">{$_("requirements_cpu_supportsAVX")}</span>
|
||||
{:else if isAVXMet === undefined}
|
||||
<span class="font-bold">Unable to verify if your CPU supports AVX</span>
|
||||
<span class="font-bold">{$_("requirements_cpu_unableToCheckAVX")}</span>
|
||||
{:else}
|
||||
<span class="font-bold">Your CPU does not support AVX</span>
|
||||
<span class="font-bold">{$_("requirements_cpu_doesNotSupportAVX")}</span>
|
||||
<ul class="font-medium list-disc list-inside">
|
||||
<li>This cannot be fixed without upgrading to a newer CPU</li>
|
||||
<li>AVX support has been fairly standard since 2011</li>
|
||||
<li>{$_("requirements_cpu_avxExplanation_1")}</li>
|
||||
<li>{$_("requirements_cpu_avxExplanation_2")}</li>
|
||||
<li>
|
||||
<a
|
||||
class="font-bold text-blue-500"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href="https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#CPUs_with_AVX"
|
||||
>Click here for more information</a
|
||||
>{$_("requirements_cpu_avxExplanation_3")}</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -60,26 +60,29 @@
|
|||
color={alertColor(isOpenGLMet)}
|
||||
>
|
||||
{#if isOpenGLMet}
|
||||
<span class="font-bold">Your GPU supports OpenGL 4.3</span>
|
||||
<span class="font-bold">{$_("requirements_gpu_supportsOpenGL")}</span>
|
||||
{:else if isOpenGLMet === undefined}
|
||||
<span class="font-bold"
|
||||
>Unable to verify if your GPU supports OpenGL 4.3</span
|
||||
<span class="font-bold">{$_("requirements_gpu_unableToCheckOpenGL")}</span
|
||||
>
|
||||
{:else}
|
||||
<span class="font-bold">Your GPU does not support OpenGL 4.3</span>
|
||||
<span class="font-bold"
|
||||
>{$_("requirements_gpu_doesNotSupportOpenGL")}</span
|
||||
>
|
||||
<ul class="font-medium list-disc list-inside">
|
||||
<li>
|
||||
Lookup your GPU <a
|
||||
{$_("requirements_gpu_avxExplanation_1_preLink")}
|
||||
<a
|
||||
class="font-bold text-blue-500"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href="https://www.techpowerup.com/gpu-specs/">here</a
|
||||
> to see if it should be supported
|
||||
href="https://www.techpowerup.com/gpu-specs/"
|
||||
>{$_("requirements_gpu_avxExplanation_1_link")}</a
|
||||
>
|
||||
{$_("requirements_gpu_avxExplanation_1_postLink")}
|
||||
</li>
|
||||
<li>You can attempt to upgrade your GPU drivers</li>
|
||||
<li>{$_("requirements_gpu_avxExplanation_2")}</li>
|
||||
<li>
|
||||
Otherwise, you will need to upgrade your GPU, most GPUs since 2012
|
||||
support it
|
||||
{$_("requirements_gpu_avxExplanation_3")}
|
||||
</li>
|
||||
</ul>
|
||||
{/if}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { appWindow } from "@tauri-apps/api/window";
|
||||
import logo from "$assets/images/icon.png";
|
||||
import logo from "$assets/images/icon.webp";
|
||||
import { onMount } from "svelte";
|
||||
import { getVersion } from "@tauri-apps/api/app";
|
||||
import { Link } from "svelte-navigator";
|
||||
|
@ -16,6 +16,7 @@
|
|||
import { getLatestOfficialRelease } from "$lib/utils/github";
|
||||
import { VersionStore } from "$lib/stores/VersionStore";
|
||||
import { exceptionLog } from "$lib/rpc/logging";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
let launcherVerison = null;
|
||||
|
||||
|
@ -94,7 +95,7 @@
|
|||
</script>
|
||||
|
||||
<header
|
||||
class="flex flex-row basis-1/10 bg-[#101010] pl-2 pr-4 pt-1 pb-1 items-center"
|
||||
class="flex flex-row basis-1/10 bg-[#101010] pl-2 pr-4 pt-1 pb-1 items-center z-10"
|
||||
data-tauri-drag-region
|
||||
>
|
||||
<div class="flex flex-row items-center space-x-2 pointer-events-none">
|
||||
|
@ -132,7 +133,9 @@
|
|||
? 'pointer-events-auto'
|
||||
: 'invisible pointer-events-none'}"
|
||||
>
|
||||
<Link class="font-mono" to="/update">> Update Available!</Link>
|
||||
<Link class="font-mono" to="/update"
|
||||
>> {$_("header_updateAvailable")}</Link
|
||||
>
|
||||
</p>
|
||||
<p
|
||||
class="font-mono text-sm hover:text-orange-300 {$UpdateStore
|
||||
|
@ -140,7 +143,8 @@
|
|||
? 'pointer-events-auto'
|
||||
: 'invisible pointer-events-none'}"
|
||||
>
|
||||
<Link class="font-mono " to="/settings/versions">> Update Available!</Link
|
||||
<Link class="font-mono " to="/settings/versions"
|
||||
>> {$_("header_updateAvailable")}</Link
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
import Icon from "@iconify/svelte";
|
||||
import { link, useLocation } from "svelte-navigator";
|
||||
import { Tooltip } from "flowbite-svelte";
|
||||
import { SupportedGame, getInternalName } from "$lib/constants";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
const location = useLocation();
|
||||
$: $location.pathname;
|
||||
|
@ -50,7 +52,7 @@
|
|||
>
|
||||
<img src={logoJak1} alt="Jak - The Precursor Legacy" />
|
||||
<Tooltip placement="right"
|
||||
>Jak and Daxter: The Precursor Legacy</Tooltip
|
||||
>{$_(`gameName_${getInternalName(SupportedGame.Jak1)}`)}</Tooltip
|
||||
>
|
||||
</a>
|
||||
</li>
|
||||
|
@ -61,7 +63,9 @@
|
|||
use:link
|
||||
>
|
||||
<img src={logoJak2} alt="Jak 2" />
|
||||
<Tooltip placement="right" style="dark">Jak 2</Tooltip>
|
||||
<Tooltip placement="right" style="dark"
|
||||
>{$_(`gameName_${getInternalName(SupportedGame.Jak2)}`)}</Tooltip
|
||||
>
|
||||
</a>
|
||||
</li>
|
||||
<li class="fixed bottom-24 left-6">
|
||||
|
@ -71,7 +75,9 @@
|
|||
use:link
|
||||
>
|
||||
<Icon icon="material-symbols:settings" width={36} height={36} />
|
||||
<Tooltip placement="right" style="dark">Settings</Tooltip>
|
||||
<Tooltip placement="right" style="dark"
|
||||
>{$_("sidebar_settings")}</Tooltip
|
||||
>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
@ -82,8 +88,7 @@
|
|||
use:link
|
||||
>
|
||||
<Icon icon="material-symbols:contact-support" width={36} height={36} />
|
||||
<Tooltip placement="right" style="dark">Support & FAQ</Tooltip
|
||||
>
|
||||
<Tooltip placement="right" style="dark">{$_("sidebar_help")}</Tooltip>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
* {
|
||||
-webkit-user-drag: none;
|
||||
font-family: "Inter", sans-serif;
|
||||
font-family: "Twemoji Country Flags", "Inter", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { TranslatedStrings } from "./translations/translations";
|
||||
|
||||
export const enum SupportedGame {
|
||||
Jak1 = "Jak 1",
|
||||
Jak2 = "Jak 2",
|
||||
|
@ -7,17 +5,6 @@ export const enum SupportedGame {
|
|||
JakX = "Jak X",
|
||||
}
|
||||
|
||||
// TODO - we should really just have `SupportedGame` be a class instead of an enum
|
||||
// then these could just be methods
|
||||
export function getGameTitle(game: SupportedGame) {
|
||||
switch (game) {
|
||||
case SupportedGame.Jak1:
|
||||
return TranslatedStrings.jak1_gameName;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
export function fromRoute(gameName: string): SupportedGame {
|
||||
switch (gameName) {
|
||||
case "jak1":
|
||||
|
|
40
src/lib/i18n/i18n.ts
Normal file
40
src/lib/i18n/i18n.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
import { addMessages, init, register } from "svelte-i18n";
|
||||
|
||||
interface Locale {
|
||||
id: string;
|
||||
flag: string;
|
||||
localizedName: string;
|
||||
}
|
||||
|
||||
export const AVAILABLE_LOCALES: Locale[] = [
|
||||
{
|
||||
id: "en-US",
|
||||
flag: "🇺🇸",
|
||||
localizedName: "English",
|
||||
},
|
||||
];
|
||||
|
||||
export async function initLocales(async: boolean) {
|
||||
if (async) {
|
||||
for (const locale of AVAILABLE_LOCALES) {
|
||||
register(
|
||||
locale.id,
|
||||
() => import(`../../assets/translations/${locale.id}.json`)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (const locale of AVAILABLE_LOCALES) {
|
||||
addMessages(
|
||||
locale.id,
|
||||
await import(`../../assets/translations/${locale.id}.json`)
|
||||
);
|
||||
}
|
||||
}
|
||||
const initPromise = init({
|
||||
fallbackLocale: "en-US",
|
||||
initialLocale: "en-US",
|
||||
});
|
||||
if (!async) {
|
||||
await initPromise;
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ import { toastStore } from "$lib/stores/ToastStore";
|
|||
import { invoke } from "@tauri-apps/api/tauri";
|
||||
import { errorLog, exceptionLog } from "./logging";
|
||||
import type { VersionFolders } from "./versions";
|
||||
import { locale } from "svelte-i18n";
|
||||
|
||||
export async function oldDataDirectoryExists(): Promise<boolean> {
|
||||
try {
|
||||
|
@ -147,3 +148,21 @@ export async function saveActiveVersionChange(
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getLocale(): Promise<String | null> {
|
||||
try {
|
||||
return await invoke("get_locale", {});
|
||||
} catch (e) {
|
||||
exceptionLog("Unable to get locale", e);
|
||||
return "en-US";
|
||||
}
|
||||
}
|
||||
|
||||
export async function setLocale(locale_string: string): Promise<void> {
|
||||
try {
|
||||
await invoke("set_locale", { locale: locale_string });
|
||||
locale.set(locale_string);
|
||||
} catch (e) {
|
||||
exceptionLog("Unable to set locale", e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,181 +0,0 @@
|
|||
// Code Generated from - https://app.quicktype.io/
|
||||
// Don't Hand Modify!
|
||||
|
||||
// To parse this data:
|
||||
//
|
||||
// import { Convert, TranslationSchema } from "./file";
|
||||
//
|
||||
// const translationSchema = Convert.toTranslationSchema(json);
|
||||
//
|
||||
// These functions will throw an error if the JSON doesn't
|
||||
// match the expected interface, even if the JSON is valid.
|
||||
|
||||
export interface TranslationSchema {
|
||||
jak1_gameName: string;
|
||||
}
|
||||
|
||||
// Converts JSON strings to/from your types
|
||||
// and asserts the results of JSON.parse at runtime
|
||||
export class Convert {
|
||||
public static toTranslationSchema(json: string): TranslationSchema {
|
||||
return cast(JSON.parse(json), r("TranslationSchema"));
|
||||
}
|
||||
|
||||
public static translationSchemaToJson(value: TranslationSchema): string {
|
||||
return JSON.stringify(uncast(value, r("TranslationSchema")), null, 2);
|
||||
}
|
||||
}
|
||||
|
||||
function invalidValue(typ: any, val: any, key: any = ""): never {
|
||||
if (key) {
|
||||
throw Error(
|
||||
`Invalid value for key "${key}". Expected type ${JSON.stringify(
|
||||
typ
|
||||
)} but got ${JSON.stringify(val)}`
|
||||
);
|
||||
}
|
||||
throw Error(
|
||||
`Invalid value ${JSON.stringify(val)} for type ${JSON.stringify(typ)}`
|
||||
);
|
||||
}
|
||||
|
||||
function jsonToJSProps(typ: any): any {
|
||||
if (typ.jsonToJS === undefined) {
|
||||
const map: any = {};
|
||||
typ.props.forEach((p: any) => (map[p.json] = { key: p.js, typ: p.typ }));
|
||||
typ.jsonToJS = map;
|
||||
}
|
||||
return typ.jsonToJS;
|
||||
}
|
||||
|
||||
function jsToJSONProps(typ: any): any {
|
||||
if (typ.jsToJSON === undefined) {
|
||||
const map: any = {};
|
||||
typ.props.forEach((p: any) => (map[p.js] = { key: p.json, typ: p.typ }));
|
||||
typ.jsToJSON = map;
|
||||
}
|
||||
return typ.jsToJSON;
|
||||
}
|
||||
|
||||
function transform(val: any, typ: any, getProps: any, key: any = ""): any {
|
||||
function transformPrimitive(typ: string, val: any): any {
|
||||
if (typeof typ === typeof val) return val;
|
||||
return invalidValue(typ, val, key);
|
||||
}
|
||||
|
||||
function transformUnion(typs: any[], val: any): any {
|
||||
// val must validate against one typ in typs
|
||||
const l = typs.length;
|
||||
for (let i = 0; i < l; i++) {
|
||||
const typ = typs[i];
|
||||
try {
|
||||
return transform(val, typ, getProps);
|
||||
} catch (_) {}
|
||||
}
|
||||
return invalidValue(typs, val);
|
||||
}
|
||||
|
||||
function transformEnum(cases: string[], val: any): any {
|
||||
if (cases.indexOf(val) !== -1) return val;
|
||||
return invalidValue(cases, val);
|
||||
}
|
||||
|
||||
function transformArray(typ: any, val: any): any {
|
||||
// val must be an array with no invalid elements
|
||||
if (!Array.isArray(val)) return invalidValue("array", val);
|
||||
return val.map((el) => transform(el, typ, getProps));
|
||||
}
|
||||
|
||||
function transformDate(val: any): any {
|
||||
if (val === null) {
|
||||
return null;
|
||||
}
|
||||
const d = new Date(val);
|
||||
if (isNaN(d.valueOf())) {
|
||||
return invalidValue("Date", val);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
function transformObject(
|
||||
props: { [k: string]: any },
|
||||
additional: any,
|
||||
val: any
|
||||
): any {
|
||||
if (val === null || typeof val !== "object" || Array.isArray(val)) {
|
||||
return invalidValue("object", val);
|
||||
}
|
||||
const result: any = {};
|
||||
Object.getOwnPropertyNames(props).forEach((key) => {
|
||||
const prop = props[key];
|
||||
const v = Object.prototype.hasOwnProperty.call(val, key)
|
||||
? val[key]
|
||||
: undefined;
|
||||
result[prop.key] = transform(v, prop.typ, getProps, prop.key);
|
||||
});
|
||||
Object.getOwnPropertyNames(val).forEach((key) => {
|
||||
if (!Object.prototype.hasOwnProperty.call(props, key)) {
|
||||
result[key] = transform(val[key], additional, getProps, key);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
if (typ === "any") return val;
|
||||
if (typ === null) {
|
||||
if (val === null) return val;
|
||||
return invalidValue(typ, val);
|
||||
}
|
||||
if (typ === false) return invalidValue(typ, val);
|
||||
while (typeof typ === "object" && typ.ref !== undefined) {
|
||||
typ = typeMap[typ.ref];
|
||||
}
|
||||
if (Array.isArray(typ)) return transformEnum(typ, val);
|
||||
if (typeof typ === "object") {
|
||||
return typ.hasOwnProperty("unionMembers")
|
||||
? transformUnion(typ.unionMembers, val)
|
||||
: typ.hasOwnProperty("arrayItems")
|
||||
? transformArray(typ.arrayItems, val)
|
||||
: typ.hasOwnProperty("props")
|
||||
? transformObject(getProps(typ), typ.additional, val)
|
||||
: invalidValue(typ, val);
|
||||
}
|
||||
// Numbers can be parsed by Date but shouldn't be.
|
||||
if (typ === Date && typeof val !== "number") return transformDate(val);
|
||||
return transformPrimitive(typ, val);
|
||||
}
|
||||
|
||||
function cast<T>(val: any, typ: any): T {
|
||||
return transform(val, typ, jsonToJSProps);
|
||||
}
|
||||
|
||||
function uncast<T>(val: T, typ: any): any {
|
||||
return transform(val, typ, jsToJSONProps);
|
||||
}
|
||||
|
||||
function a(typ: any) {
|
||||
return { arrayItems: typ };
|
||||
}
|
||||
|
||||
function u(...typs: any[]) {
|
||||
return { unionMembers: typs };
|
||||
}
|
||||
|
||||
function o(props: any[], additional: any) {
|
||||
return { props, additional };
|
||||
}
|
||||
|
||||
function m(additional: any) {
|
||||
return { props: [], additional };
|
||||
}
|
||||
|
||||
function r(name: string) {
|
||||
return { ref: name };
|
||||
}
|
||||
|
||||
const typeMap: any = {
|
||||
TranslationSchema: o(
|
||||
[{ json: "jak1_gameName", js: "jak1_gameName", typ: "" }],
|
||||
false
|
||||
),
|
||||
};
|
|
@ -1,17 +0,0 @@
|
|||
import { Convert } from "./translation_schema";
|
||||
import type { TranslationSchema } from "./translation_schema";
|
||||
import english from "$assets/translations/english.json";
|
||||
|
||||
let supportedTranslations = ["english"];
|
||||
|
||||
export let TranslatedStrings: TranslationSchema;
|
||||
|
||||
export function loadTranslations(language: string) {
|
||||
if (!supportedTranslations.includes(language)) {
|
||||
}
|
||||
// TODO - would prefer to import this by a raw path but have to import
|
||||
// for vite reasons -- maybe there is a different way to ensure they are bundled?
|
||||
if (language === "english") {
|
||||
TranslatedStrings = Convert.toTranslationSchema(JSON.stringify(english));
|
||||
}
|
||||
}
|
|
@ -1,8 +1,12 @@
|
|||
import { initLocales } from "$lib/i18n/i18n";
|
||||
import "./app.postcss";
|
||||
import { loadTranslations } from "$lib/translations/translations";
|
||||
import App from "./App.svelte";
|
||||
import { polyfillCountryFlagEmojis } from "country-flag-emoji-polyfill";
|
||||
|
||||
loadTranslations("english");
|
||||
polyfillCountryFlagEmojis();
|
||||
|
||||
// Register Translations
|
||||
initLocales(true);
|
||||
|
||||
const app = new App({
|
||||
target: document.getElementById("app"),
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import { openDir } from "$lib/rpc/window";
|
||||
import { onMount } from "svelte";
|
||||
import { appConfigDir } from "@tauri-apps/api/path";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
let appDir = undefined;
|
||||
let downloadingPackage = false;
|
||||
|
@ -15,10 +16,9 @@
|
|||
</script>
|
||||
|
||||
<div class="flex flex-col h-full bg-slate-900 p-4 gap-3">
|
||||
<h1 class="font-semibold text-xl text-orange-500">Support & FAQ</h1>
|
||||
<h1 class="font-semibold text-xl text-orange-500">{$_("help_header")}</h1>
|
||||
<p class="text-sm">
|
||||
If you are reporting an issue or asking for help, download the following
|
||||
support package and attach it in your Discord thread or GitHub issue.
|
||||
{$_("help_header")}
|
||||
</p>
|
||||
<div class="flex flex-row mt-1 gap-2">
|
||||
<Button
|
||||
|
@ -32,25 +32,22 @@
|
|||
{#if downloadingPackage}
|
||||
<Spinner class="text-sm mb-0.5 mr-1" size="4" color="white" />
|
||||
{/if}
|
||||
|
||||
Download Support Package</Button
|
||||
{$_("help_button_downloadPackage")}</Button
|
||||
>
|
||||
{#if appDir !== undefined}
|
||||
<Button
|
||||
btnClass="flex items-center border-solid rounded bg-white hover:bg-orange-400 text-sm text-slate-900 font-semibold px-4 py-2"
|
||||
on:click={() => {
|
||||
openDir(appDir);
|
||||
}}>Open Log Folder</Button
|
||||
}}>{$_("help_button_openLogFolder")}</Button
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
<p class="mt-3 text-sm">
|
||||
You can either ask a question on our Discord, or create a GitHub issue with
|
||||
as much detail as possible.
|
||||
{$_("help_description_createAnIssue")}
|
||||
</p>
|
||||
<p class="text-sm">
|
||||
In either location, please do a quick search to see if the question has
|
||||
already been answered before
|
||||
{$_("help_description_duplicateReminder")}
|
||||
</p>
|
||||
<div class="flex flex-row gap-2">
|
||||
<Button
|
||||
|
@ -69,16 +66,18 @@
|
|||
href="https://github.com/open-goal/launcher/issues/new/choose"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
><Icon class="inline-block" icon="mdi:github" width={20} /> Report
|
||||
Launcher Issue</Button
|
||||
><Icon class="inline-block" icon="mdi:github" width={20} /> {$_(
|
||||
"help_button_reportLauncherIssue"
|
||||
)}</Button
|
||||
>
|
||||
<Button
|
||||
btnClass="flex items-center border-solid rounded bg-white hover:bg-orange-400 text-sm text-slate-900 font-semibold px-4 py-2"
|
||||
href="https://github.com/open-goal/jak-project/issues/new/choose"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
><Icon class="inline-block" icon="mdi:github" width={20} /> Report
|
||||
Game Issue</Button
|
||||
><Icon class="inline-block" icon="mdi:github" width={20} /> {$_(
|
||||
"help_button_reportGameIssue"
|
||||
)}</Button
|
||||
>
|
||||
</div>
|
||||
<div class="flex mt-auto justify-end">
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import Folders from "./settings/Folders.svelte";
|
||||
import Versions from "./settings/Versions.svelte";
|
||||
import General from "./settings/General.svelte";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
const params = useParams();
|
||||
$: activeTab = $params["tab"];
|
||||
|
@ -24,7 +25,7 @@
|
|||
>
|
||||
<TabItem
|
||||
open={!activeTab || activeTab === "general"}
|
||||
title="General"
|
||||
title={$_("settings_tabs_general")}
|
||||
activeClasses={tabItemActiveClasses}
|
||||
inactiveClasses={tabItemInactiveClasses}
|
||||
>
|
||||
|
@ -32,7 +33,7 @@
|
|||
</TabItem>
|
||||
<TabItem
|
||||
open={!activeTab || activeTab === "folders"}
|
||||
title="Folders"
|
||||
title={$_("settings_tabs_folders")}
|
||||
activeClasses={tabItemActiveClasses}
|
||||
inactiveClasses={tabItemInactiveClasses}
|
||||
>
|
||||
|
@ -40,7 +41,7 @@
|
|||
</TabItem>
|
||||
<TabItem
|
||||
open={activeTab === "versions"}
|
||||
title="Version Management"
|
||||
title={$_("settings_tabs_versions")}
|
||||
activeClasses={tabItemActiveClasses}
|
||||
inactiveClasses={tabItemInactiveClasses}
|
||||
>
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
} from "flowbite-svelte";
|
||||
import { UpdateStore } from "$lib/stores/AppStore";
|
||||
import Icon from "@iconify/svelte";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
$: launcherUpdateInfo = $UpdateStore?.launcher;
|
||||
|
||||
|
@ -34,14 +35,15 @@
|
|||
<div class="flex flex-col h-full bg-slate-900 p-4 gap-3 overflow-y-auto pb-20">
|
||||
{#if $UpdateStore.launcher.updateAvailable}
|
||||
<h1 class="font-semibold text-xl text-orange-500">
|
||||
Launcher Update Available
|
||||
{$_("settings_tabs_general")}
|
||||
</h1>
|
||||
<p>
|
||||
Version: <strong>{launcherUpdateInfo.versionNumber}</strong>
|
||||
{$_("update_versionLabel")}: <strong
|
||||
>{launcherUpdateInfo.versionNumber}</strong
|
||||
>
|
||||
</p>
|
||||
<p class="text-sm">
|
||||
View the changes below and click the button to update to the latest
|
||||
version. The launcher will restart when finished.
|
||||
{$_("update_description")}
|
||||
</p>
|
||||
<div class="flex flex-row mt-1 gap-3">
|
||||
<Button
|
||||
|
@ -52,13 +54,16 @@
|
|||
{#if updating}
|
||||
<Spinner class="mr-3" size="4" color="white" />
|
||||
{/if}
|
||||
Update Launcher
|
||||
{$_("update_button_doUpdate")}
|
||||
</Button>
|
||||
<Button
|
||||
btnClass="flex-shrink border-solid rounded bg-white hover:bg-orange-400 text-sm text-slate-900 font-semibold px-5 py-2"
|
||||
on:click={() => (showChanges = !showChanges)}>View Changelog</Button
|
||||
on:click={() => (showChanges = !showChanges)}
|
||||
>{$_("update_button_viewChangelog")}g</Button
|
||||
>
|
||||
<Toggle checked={showDependencyChanges}
|
||||
>{$_("update_button_hideDependencyChanges")}</Toggle
|
||||
>
|
||||
<Toggle checked={showDependencyChanges}>Dependency Changes</Toggle>
|
||||
</div>
|
||||
{#if showChanges}
|
||||
<Table hoverable={true}>
|
||||
|
@ -66,9 +71,15 @@
|
|||
class="p-2 font-semibold text-right text-gray-900 bg-white dark:text-white dark:bg-gray-800"
|
||||
/>
|
||||
<TableHead>
|
||||
<TableHeadCell>Contributor</TableHeadCell>
|
||||
<TableHeadCell>Description</TableHeadCell>
|
||||
<TableHeadCell>Pull Request</TableHeadCell>
|
||||
<TableHeadCell
|
||||
>{$_("update_changelog_header_contributor")}</TableHeadCell
|
||||
>
|
||||
<TableHeadCell
|
||||
>{$_("update_changelog_header_description")}</TableHeadCell
|
||||
>
|
||||
<TableHeadCell
|
||||
>{$_("update_changelog_header_pullRequest")}</TableHeadCell
|
||||
>
|
||||
</TableHead>
|
||||
<TableBody tableBodyClass="divide-y">
|
||||
{#each launcherUpdateInfo.changeLog["changes"].filter((note) => {
|
||||
|
@ -105,6 +116,8 @@
|
|||
</Table>
|
||||
{/if}
|
||||
{:else}
|
||||
<h1 class="font-semibold text-xl text-orange-500">You're Up to Date!</h1>
|
||||
<h1 class="font-semibold text-xl text-orange-500">
|
||||
{$_("update_alreadyUpToDate")}
|
||||
</h1>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import { folderPrompt } from "$lib/utils/file";
|
||||
import { Label, Input } from "flowbite-svelte";
|
||||
import { onMount } from "svelte";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
let currentInstallationDirectory = "";
|
||||
|
||||
|
@ -17,12 +18,16 @@
|
|||
|
||||
<div class="flex flex-col gap-2 mt-2">
|
||||
<div>
|
||||
<Label for="default-input" class="block mb-2">Installation Directory</Label>
|
||||
<Label for="default-input" class="block mb-2"
|
||||
>{$_("settings_folders_installationDir")}</Label
|
||||
>
|
||||
<Input
|
||||
id="default-input"
|
||||
placeholder={currentInstallationDirectory}
|
||||
on:click={async () => {
|
||||
const newInstallDir = await folderPrompt("Pick an Installation Folder");
|
||||
const newInstallDir = await folderPrompt(
|
||||
$_("settings_folders_installationDir_prompt")
|
||||
);
|
||||
if (
|
||||
newInstallDir !== undefined &&
|
||||
newInstallDir !== currentInstallationDirectory
|
||||
|
|
|
@ -1,27 +1,66 @@
|
|||
<script lang="ts">
|
||||
import { AVAILABLE_LOCALES } from "$lib/i18n/i18n";
|
||||
import {
|
||||
getInstallationDirectory,
|
||||
getLocale,
|
||||
resetLauncherSettingsToDefaults,
|
||||
setLocale,
|
||||
} from "$lib/rpc/config";
|
||||
import { getActiveVersion, getActiveVersionFolder } from "$lib/rpc/versions";
|
||||
import { VersionStore } from "$lib/stores/VersionStore";
|
||||
import { Button } from "flowbite-svelte";
|
||||
import { Button, Helper, Label, Select } from "flowbite-svelte";
|
||||
import { onMount } from "svelte";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
let currentInstallationDirectory = "";
|
||||
let currentLocale;
|
||||
let availableLocales = [];
|
||||
|
||||
onMount(async () => {
|
||||
currentInstallationDirectory = await getInstallationDirectory();
|
||||
for (const locale of AVAILABLE_LOCALES) {
|
||||
availableLocales = [
|
||||
...availableLocales,
|
||||
{
|
||||
value: locale.id,
|
||||
name: `${locale.flag} ${locale.localizedName}`,
|
||||
},
|
||||
];
|
||||
}
|
||||
currentLocale = await getLocale();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-2 mt-2">
|
||||
<div class="flex flex-col gap-5 mt-2">
|
||||
<div>
|
||||
<Label
|
||||
>{$_("settings_general_localeChange")}
|
||||
<Select
|
||||
class="mt-2"
|
||||
items={availableLocales}
|
||||
bind:value={currentLocale}
|
||||
on:change={async (evt) => {
|
||||
setLocale(evt.target.value);
|
||||
}}
|
||||
/>
|
||||
</Label>
|
||||
<Helper class="text-sm mt-2"
|
||||
>{$_("settings_general_localeChange_helper_1")}
|
||||
<a
|
||||
class=" text-orange-400 hover:text-orange-600"
|
||||
href="https://crowdin.com/project/opengoal-launcher"
|
||||
target="_blank"
|
||||
rel="noreferrer">{$_("settings_general_localeChange_helper_link")}</a
|
||||
>
|
||||
{$_("settings_general_localeChange_helper_2")}</Helper
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
btnClass="flex-shrink border-solid rounded bg-white hover:bg-orange-400 text-sm text-slate-900 font-semibold px-5 py-2"
|
||||
on:click={async () => {
|
||||
const confirmed = await confirm(
|
||||
"Are you sure you want to reset your launcher settings? This will reset your installation directory and any other settings you have changed. This will not affect your game files."
|
||||
$_("settings_general_button_resetSettings_confirmation")
|
||||
);
|
||||
if (confirmed) {
|
||||
const result = resetLauncherSettingsToDefaults();
|
||||
|
@ -31,7 +70,7 @@
|
|||
$VersionStore.activeVersionName = await getActiveVersion();
|
||||
}
|
||||
}
|
||||
}}>Reset Launcher Settings</Button
|
||||
}}>{$_("settings_general_button_resetSettings")}</Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
import OfficialVersions from "./versions/OfficialVersions.svelte";
|
||||
import UnofficialVersions from "./versions/UnofficialVersions.svelte";
|
||||
import DevelVersions from "./versions/DevelVersions.svelte";
|
||||
import { _ } from "svelte-i18n";
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<p class="text-sm mt-2 mb-2">Configure your active tooling version</p>
|
||||
<p class="text-sm mt-2 mb-2">{$_("settings_versions_header")}</p>
|
||||
<Tabs style="pill" contentClass="p-4 rounded-lg mt-0 pb-20 overflow-y-auto">
|
||||
<OfficialVersions />
|
||||
<UnofficialVersions />
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
import type { ReleaseInfo } from "$lib/utils/github";
|
||||
import { VersionStore } from "$lib/stores/VersionStore";
|
||||
import { saveActiveVersionChange } from "$lib/rpc/config";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
let versionsLoaded = false;
|
||||
|
||||
|
@ -80,8 +81,8 @@
|
|||
|
||||
<VersionList
|
||||
initiallyOpen={false}
|
||||
name="Development"
|
||||
description="This list serves as a convenient area to stage, manage and test new releases (either official or unofficial) This list will always require manual management via it's respective folder"
|
||||
name={$_("settings_versions_devel_tabName")}
|
||||
description={$_("settings_versions_devel_description")}
|
||||
releaseList={releases}
|
||||
loaded={versionsLoaded}
|
||||
releaseType="devel"
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
import { VersionStore } from "$lib/stores/VersionStore";
|
||||
import { UpdateStore } from "$lib/stores/AppStore";
|
||||
import { saveActiveVersionChange } from "$lib/rpc/config";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
let versionsLoaded = false;
|
||||
let releases: ReleaseInfo[] = [];
|
||||
|
@ -159,8 +160,8 @@
|
|||
|
||||
<VersionList
|
||||
initiallyOpen={true}
|
||||
name="Official"
|
||||
description="Official versions are from the `jak-project` GitHub repository"
|
||||
name={$_("settings_versions_official_tabName")}
|
||||
description={$_("settings_versions_official_description")}
|
||||
releaseList={releases}
|
||||
loaded={versionsLoaded}
|
||||
releaseType="official"
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
import type { ReleaseInfo } from "$lib/utils/github";
|
||||
import { VersionStore } from "$lib/stores/VersionStore";
|
||||
import { saveActiveVersionChange } from "$lib/rpc/config";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
let versionsLoaded = false;
|
||||
|
||||
|
@ -83,9 +84,8 @@
|
|||
|
||||
<VersionList
|
||||
initiallyOpen={false}
|
||||
name="Unofficial"
|
||||
description="Unofficial versions are typically modified `jak-project` releases to enable changes or new content. These are not supported by the OpenGOAL team and will have to be
|
||||
manually added to the folder at this time"
|
||||
name={$_("settings_versions_unofficial_tabName")}
|
||||
description={$_("settings_versions_unofficial_description")}
|
||||
releaseList={releases}
|
||||
loaded={versionsLoaded}
|
||||
releaseType="unofficial"
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
TableHeadCell,
|
||||
} from "flowbite-svelte";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
export let name: string;
|
||||
export let description: string;
|
||||
|
@ -71,7 +72,7 @@
|
|||
icon="material-symbols:save"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="save version change"
|
||||
alt={$_("settings_versions_icon_save_altText")}
|
||||
/>
|
||||
</Button>
|
||||
{/if}
|
||||
|
@ -83,7 +84,7 @@
|
|||
icon="material-symbols:refresh"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="refresh version list"
|
||||
alt={$_("settings_versions_icon_refresh_altText")}
|
||||
/>
|
||||
</Button>
|
||||
<Button
|
||||
|
@ -94,7 +95,7 @@
|
|||
icon="material-symbols:folder-open-rounded"
|
||||
width="20"
|
||||
height="20"
|
||||
alt="open version folder"
|
||||
alt={$_("settings_versions_icon_openFolder_altText")}
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -107,9 +108,15 @@
|
|||
<TableHeadCell>
|
||||
<span class="sr-only">Controls</span>
|
||||
</TableHeadCell>
|
||||
<TableHeadCell>Version</TableHeadCell>
|
||||
<TableHeadCell>Date</TableHeadCell>
|
||||
<TableHeadCell>Changes</TableHeadCell>
|
||||
<TableHeadCell
|
||||
>{$_("settings_versions_table_header_version")}</TableHeadCell
|
||||
>
|
||||
<TableHeadCell
|
||||
>{$_("settings_versions_table_header_date")}</TableHeadCell
|
||||
>
|
||||
<TableHeadCell
|
||||
>{$_("settings_versions_table_header_changes")}</TableHeadCell
|
||||
>
|
||||
</TableHead>
|
||||
<TableBody tableBodyClass="divide-y">
|
||||
{#each releaseList as release (release.version)}
|
||||
|
@ -154,6 +161,7 @@
|
|||
width="24"
|
||||
height="24"
|
||||
color="red"
|
||||
alt={$_("settings_versions_icon_removeVersion_altText")}
|
||||
/>
|
||||
{:else if release.pendingAction}
|
||||
<Spinner color="yellow" size={"6"} />
|
||||
|
@ -163,6 +171,7 @@
|
|||
color="#00d500"
|
||||
width="24"
|
||||
height="24"
|
||||
alt={$_("settings_versions_icon_downloadVersion_altText")}
|
||||
/>
|
||||
{/if}
|
||||
</Button>
|
||||
|
@ -187,6 +196,7 @@
|
|||
icon="mdi:github"
|
||||
width="24"
|
||||
height="24"
|
||||
alt={$_("settings_versions_icon_githubRelease_altText")}
|
||||
/></a
|
||||
>
|
||||
{/if}
|
||||
|
|
|
@ -6,63 +6,70 @@
|
|||
import {
|
||||
deleteOldDataDirectory,
|
||||
getInstallationDirectory,
|
||||
getLocale,
|
||||
oldDataDirectoryExists,
|
||||
setInstallationDirectory,
|
||||
setLocale,
|
||||
} from "$lib/rpc/config";
|
||||
import { AVAILABLE_LOCALES } from "$lib/i18n/i18n";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
let currentProgress = 10;
|
||||
let currentStatusText = "Reading Settings";
|
||||
let currentStatusText = $_("splash_step_readingSettings");
|
||||
|
||||
let selectLocale = false;
|
||||
let installationDirSet = true;
|
||||
let stepError = undefined;
|
||||
let oldDataDirToClean = false;
|
||||
|
||||
// Events
|
||||
onMount(async () => {
|
||||
currentStatusText = "Checking Directories";
|
||||
// First, see if the user has selected a locale
|
||||
await checkLocale();
|
||||
});
|
||||
|
||||
// TODO - cleanup this code and make it easier to add steps like with
|
||||
// the game setup
|
||||
|
||||
async function checkLocale() {
|
||||
const locale = await getLocale();
|
||||
if (locale === null) {
|
||||
// Prompt the user to select a locale
|
||||
selectLocale = true;
|
||||
} else {
|
||||
await checkDirectories();
|
||||
}
|
||||
}
|
||||
|
||||
async function checkDirectories() {
|
||||
currentStatusText = $_("splash_step_checkingDirectories");
|
||||
currentProgress = 15;
|
||||
// Check to see if the install dir has been setup or not
|
||||
const install_dir = await getInstallationDirectory();
|
||||
if (install_dir === null) {
|
||||
// Check to see if they have the old data directory, ask them if they'd like us to
|
||||
// remove it
|
||||
currentProgress = 25;
|
||||
const hasOldDataDir = await oldDataDirectoryExists();
|
||||
if (hasOldDataDir) {
|
||||
oldDataDirToClean = true;
|
||||
}
|
||||
// If not -- let's ask the user to set one up
|
||||
installationDirSet = false;
|
||||
} else {
|
||||
currentProgress = 25;
|
||||
finishSplash();
|
||||
}
|
||||
});
|
||||
|
||||
async function selectInstallationFolder() {
|
||||
// If not -- let's ask the user to set one up
|
||||
// This is part of what allows for the user to install the games and such wherever they want
|
||||
currentStatusText = "Pick an Installation Folder";
|
||||
currentProgress = 25;
|
||||
const newInstallDir = await folderPrompt("Pick an Installation Folder");
|
||||
if (newInstallDir !== undefined) {
|
||||
const result = await setInstallationDirectory(newInstallDir);
|
||||
if (result !== null) {
|
||||
stepError = result;
|
||||
} else {
|
||||
installationDirSet = true;
|
||||
finishSplash();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function finishSplash() {
|
||||
currentProgress = 50;
|
||||
currentStatusText = "Finishing Up";
|
||||
currentStatusText = $_("splash_step_finishingUp");
|
||||
await new Promise((res) => setTimeout(res, 1000));
|
||||
currentProgress = 100;
|
||||
await new Promise((res) => setTimeout(res, 500));
|
||||
const errorClosing = await openMainWindow();
|
||||
if (!errorClosing) {
|
||||
currentStatusText = "Problem opening Launcher";
|
||||
currentStatusText = $_("splash_step_errorOpening");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -72,8 +79,29 @@
|
|||
<img src={logo} alt="" draggable="false" />
|
||||
</div>
|
||||
<div class="splash-contents no-pointer-events">
|
||||
{#if oldDataDirToClean}
|
||||
The old installation folder is no longer needed, delete it?
|
||||
{#if selectLocale}
|
||||
<span class="mb-1">{$_("splash_selectLocale")}</span>
|
||||
<div class="splash-select">
|
||||
<select
|
||||
name="cars"
|
||||
id="cars"
|
||||
class="pointer-events emoji-font"
|
||||
on:change={async (evt) => {
|
||||
setLocale(evt.target.value);
|
||||
selectLocale = false;
|
||||
await checkDirectories();
|
||||
}}
|
||||
>
|
||||
<option disabled selected value hidden />
|
||||
{#each AVAILABLE_LOCALES as locale}
|
||||
<option class="emoji-font" value={locale.id}
|
||||
>{locale.flag} {locale.localizedName}</option
|
||||
>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
{:else if oldDataDirToClean}
|
||||
{$_("splash_deleteOldInstallDir")}
|
||||
<br />
|
||||
<span>
|
||||
<button
|
||||
|
@ -81,33 +109,53 @@
|
|||
on:click={() => {
|
||||
oldDataDirToClean = false;
|
||||
deleteOldDataDirectory();
|
||||
}}>Yes</button
|
||||
}}>{$_("splash_button_deleteOldInstallDir_yes")}</button
|
||||
>
|
||||
<button
|
||||
class="splash-button pointer-events"
|
||||
on:click={() => {
|
||||
oldDataDirToClean = false;
|
||||
}}>No</button
|
||||
}}>{$_("splash_button_deleteOldInstallDir_no")}</button
|
||||
>
|
||||
</span>
|
||||
{:else if !installationDirSet}
|
||||
{#if stepError !== undefined}
|
||||
{stepError}
|
||||
{:else}
|
||||
No installation directory set!
|
||||
{$_("splash_noInstallDirSet")}
|
||||
{/if}
|
||||
<br />
|
||||
<button
|
||||
class="splash-button pointer-events"
|
||||
on:click={selectInstallationFolder}>Set Install Folder</button
|
||||
on:click={async () => {
|
||||
// This is part of what allows for the user to install the games and such wherever they want
|
||||
currentStatusText = $_("splash_step_pickInstallFolder");
|
||||
currentProgress = 25;
|
||||
const newInstallDir = await folderPrompt(
|
||||
$_("splash_button_setInstallFolder_prompt")
|
||||
);
|
||||
if (newInstallDir !== undefined) {
|
||||
const result = await setInstallationDirectory(newInstallDir);
|
||||
if (result !== null) {
|
||||
stepError = result;
|
||||
} else {
|
||||
installationDirSet = true;
|
||||
finishSplash();
|
||||
}
|
||||
}
|
||||
}}>{$_("splash_button_setInstallFolder")}</button
|
||||
>
|
||||
{:else}
|
||||
<div class="splash-status-text">{currentStatusText}</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="splash-bar">
|
||||
<div class="splash-status-bar fg" style="width: {currentProgress}%" />
|
||||
<div class="splash-status-bar bg" />
|
||||
<div
|
||||
data-tauri-drag-region
|
||||
class="splash-status-bar fg"
|
||||
style="width: {currentProgress}%"
|
||||
/>
|
||||
<div data-tauri-drag-region class="splash-status-bar bg" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -133,7 +181,7 @@
|
|||
height: 35%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: "Roboto Mono", monospace;
|
||||
font-family: "Twemoji Country Flags", "Roboto Mono", monospace;
|
||||
font-size: 10pt;
|
||||
text-align: center;
|
||||
padding-left: 10px;
|
||||
|
@ -218,4 +266,12 @@
|
|||
.pointer-events {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.mb-1 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.emoji-font {
|
||||
font-family: "Twemoji Country Flags", "Roboto Mono";
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
import { initLocales } from "$lib/i18n/i18n";
|
||||
import App from "./Splash.svelte";
|
||||
import { polyfillCountryFlagEmojis } from "country-flag-emoji-polyfill";
|
||||
|
||||
const app = new App({
|
||||
// Register Translations
|
||||
export default (async () => {
|
||||
polyfillCountryFlagEmojis();
|
||||
await initLocales(false);
|
||||
return new App({
|
||||
target: document.getElementById("app"),
|
||||
});
|
||||
|
||||
export default app;
|
||||
});
|
||||
})();
|
||||
|
|
229
yarn.lock
229
yarn.lock
|
@ -137,6 +137,45 @@
|
|||
resolved "https://registry.yarnpkg.com/@fiahfy/packbits/-/packbits-0.0.6.tgz#d93146683fa59f476c6ccb988eb1cf9d7c16e489"
|
||||
integrity sha512-XuhF/edg+iIvXjkCWgfj6fWtRi/KrEPg2ILXj1l86EN4EssuOiPcLKgkMDr9cL8jTGtVd/MKUWW6Y0/ZVf1PGA==
|
||||
|
||||
"@formatjs/ecma402-abstract@1.11.4":
|
||||
version "1.11.4"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz#b962dfc4ae84361f9f08fbce411b4e4340930eda"
|
||||
integrity sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==
|
||||
dependencies:
|
||||
"@formatjs/intl-localematcher" "0.2.25"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@formatjs/fast-memoize@1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz#e6f5aee2e4fd0ca5edba6eba7668e2d855e0fc21"
|
||||
integrity sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==
|
||||
dependencies:
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@formatjs/icu-messageformat-parser@2.1.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.0.tgz#a54293dd7f098d6a6f6a084ab08b6d54a3e8c12d"
|
||||
integrity sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==
|
||||
dependencies:
|
||||
"@formatjs/ecma402-abstract" "1.11.4"
|
||||
"@formatjs/icu-skeleton-parser" "1.3.6"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@formatjs/icu-skeleton-parser@1.3.6":
|
||||
version "1.3.6"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.6.tgz#4ce8c0737d6f07b735288177049e97acbf2e8964"
|
||||
integrity sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==
|
||||
dependencies:
|
||||
"@formatjs/ecma402-abstract" "1.11.4"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@formatjs/intl-localematcher@0.2.25":
|
||||
version "0.2.25"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz#60892fe1b271ec35ba07a2eb018a2dd7bca6ea3a"
|
||||
integrity sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==
|
||||
dependencies:
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@fullhuman/postcss-purgecss@^5.0.0":
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@fullhuman/postcss-purgecss/-/postcss-purgecss-5.0.0.tgz#70db9a537c73750fbcf745b49573db758daba1d8"
|
||||
|
@ -1255,6 +1294,17 @@ cli-boxes@^2.2.1:
|
|||
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
|
||||
integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
|
||||
|
||||
cli-color@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-2.0.3.tgz#73769ba969080629670f3f2ef69a4bf4e7cc1879"
|
||||
integrity sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==
|
||||
dependencies:
|
||||
d "^1.0.1"
|
||||
es5-ext "^0.10.61"
|
||||
es6-iterator "^2.0.3"
|
||||
memoizee "^0.4.15"
|
||||
timers-ext "^0.1.7"
|
||||
|
||||
cli-cursor@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
|
||||
|
@ -1376,6 +1426,13 @@ core-util-is@~1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
|
||||
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
|
||||
|
||||
country-flag-emoji-polyfill@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/country-flag-emoji-polyfill/-/country-flag-emoji-polyfill-0.1.4.tgz#54b7ca61220c124b11d3091c46d16bd7f3ba0016"
|
||||
integrity sha512-e20azlb9yHb3mpL3lAlhkidmJgB5TELpA8oe0DPlyIfnqXhAGBmgLDpC+mm+Envh57n1xPrOfkJtXq2CrpvoGQ==
|
||||
dependencies:
|
||||
is-emoji-supported "^0.0.5"
|
||||
|
||||
cross-env@7.0.3:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
|
||||
|
@ -1429,6 +1486,14 @@ currently-unhandled@^0.4.1:
|
|||
dependencies:
|
||||
array-find-index "^1.0.1"
|
||||
|
||||
d@1, d@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
|
||||
integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
|
||||
dependencies:
|
||||
es5-ext "^0.10.50"
|
||||
type "^1.0.1"
|
||||
|
||||
debug@^4.3.4:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||
|
@ -1523,7 +1588,7 @@ deep-extend@^0.6.0:
|
|||
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
|
||||
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
|
||||
|
||||
deepmerge@^4.3.1:
|
||||
deepmerge@^4.2.2, deepmerge@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
|
||||
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
|
||||
|
@ -1666,16 +1731,52 @@ error-ex@^1.2.0:
|
|||
dependencies:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
|
||||
version "0.10.62"
|
||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
|
||||
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
|
||||
dependencies:
|
||||
es6-iterator "^2.0.3"
|
||||
es6-symbol "^3.1.3"
|
||||
next-tick "^1.1.0"
|
||||
|
||||
es6-error@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
|
||||
integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
|
||||
|
||||
es6-iterator@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
|
||||
integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "^0.10.35"
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
es6-promise@^3.1.2:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613"
|
||||
integrity sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==
|
||||
|
||||
es6-symbol@^3.1.1, es6-symbol@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
|
||||
integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==
|
||||
dependencies:
|
||||
d "^1.0.1"
|
||||
ext "^1.1.2"
|
||||
|
||||
es6-weak-map@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53"
|
||||
integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "^0.10.46"
|
||||
es6-iterator "^2.0.3"
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
esbuild@^0.17.5:
|
||||
version "0.17.18"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.18.tgz#f4f8eb6d77384d68cd71c53eb6601c7efe05e746"
|
||||
|
@ -1729,6 +1830,19 @@ escape-string-regexp@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
estree-walker@^2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
|
||||
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
|
||||
|
||||
event-emitter@^0.3.5:
|
||||
version "0.3.5"
|
||||
resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
|
||||
integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "~0.10.14"
|
||||
|
||||
exec-buffer@^3.0.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/exec-buffer/-/exec-buffer-3.2.0.tgz#b1686dbd904c7cf982e652c1f5a79b1e5573082b"
|
||||
|
@ -1813,6 +1927,13 @@ ext-name@^5.0.0:
|
|||
ext-list "^2.0.0"
|
||||
sort-keys-length "^1.0.0"
|
||||
|
||||
ext@^1.1.2:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
|
||||
integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==
|
||||
dependencies:
|
||||
type "^2.7.2"
|
||||
|
||||
external-editor@^3.0.3:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495"
|
||||
|
@ -2164,6 +2285,11 @@ globalthis@^1.0.1:
|
|||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
|
||||
globalyzer@0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/globalyzer/-/globalyzer-0.1.0.tgz#cb76da79555669a1519d5a8edf093afaa0bf1465"
|
||||
integrity sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==
|
||||
|
||||
globby@^12.0.0:
|
||||
version "12.2.0"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-12.2.0.tgz#2ab8046b4fba4ff6eede835b29f678f90e3d3c22"
|
||||
|
@ -2176,6 +2302,11 @@ globby@^12.0.0:
|
|||
merge2 "^1.4.1"
|
||||
slash "^4.0.0"
|
||||
|
||||
globrex@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
|
||||
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
|
||||
|
||||
got@12.1.0:
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/got/-/got-12.1.0.tgz#099f3815305c682be4fd6b0ee0726d8e4c6b0af4"
|
||||
|
@ -2457,6 +2588,16 @@ inquirer@8.2.4:
|
|||
through "^2.3.6"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
intl-messageformat@^9.13.0:
|
||||
version "9.13.0"
|
||||
resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-9.13.0.tgz#97360b73bd82212e4f6005c712a4a16053165468"
|
||||
integrity sha512-7sGC7QnSQGa5LZP7bXLDhVDtQOeKGeBFGHF2Y8LVBwYZoQZCgWeKoPGTa5GMG8g/TzDgeXuYJQis7Ggiw2xTOw==
|
||||
dependencies:
|
||||
"@formatjs/ecma402-abstract" "1.11.4"
|
||||
"@formatjs/fast-memoize" "1.2.1"
|
||||
"@formatjs/icu-messageformat-parser" "2.1.0"
|
||||
tslib "^2.1.0"
|
||||
|
||||
into-stream@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6"
|
||||
|
@ -2496,6 +2637,11 @@ is-core-module@^2.11.0:
|
|||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
is-emoji-supported@^0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/is-emoji-supported/-/is-emoji-supported-0.0.5.tgz#f22301b22c63d6322935e829f39dfa59d03a7fe2"
|
||||
integrity sha512-WOlXUhDDHxYqcSmFZis+xWhhqXiK2SU0iYiqmth5Ip0FHLZQAt9rKL5ahnilE8/86WH8tZ3bmNNNC+bTzamqlw==
|
||||
|
||||
is-extglob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
|
@ -2586,6 +2732,11 @@ is-png@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/is-png/-/is-png-2.0.0.tgz#ee8cbc9e9b050425cedeeb4a6fb74a649b0a4a8d"
|
||||
integrity sha512-4KPGizaVGj2LK7xwJIz8o5B2ubu1D/vcQsgOGFEDlpcvgZHto4gBnyd0ig7Ws+67ixmwKoNmu0hYnpo6AaKb5g==
|
||||
|
||||
is-promise@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1"
|
||||
integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
|
||||
|
||||
is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
|
||||
|
@ -2850,6 +3001,13 @@ lru-cache@^6.0.0:
|
|||
dependencies:
|
||||
yallist "^4.0.0"
|
||||
|
||||
lru-queue@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3"
|
||||
integrity sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==
|
||||
dependencies:
|
||||
es5-ext "~0.10.2"
|
||||
|
||||
magic-string@^0.27.0:
|
||||
version "0.27.0"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3"
|
||||
|
@ -2890,6 +3048,20 @@ matcher@^3.0.0:
|
|||
dependencies:
|
||||
escape-string-regexp "^4.0.0"
|
||||
|
||||
memoizee@^0.4.15:
|
||||
version "0.4.15"
|
||||
resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72"
|
||||
integrity sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==
|
||||
dependencies:
|
||||
d "^1.0.1"
|
||||
es5-ext "^0.10.53"
|
||||
es6-weak-map "^2.0.3"
|
||||
event-emitter "^0.3.5"
|
||||
is-promise "^2.2.2"
|
||||
lru-queue "^0.1.0"
|
||||
next-tick "^1.1.0"
|
||||
timers-ext "^0.1.7"
|
||||
|
||||
meow@^3.3.0:
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb"
|
||||
|
@ -3007,6 +3179,11 @@ mkdirp@^0.5.1:
|
|||
dependencies:
|
||||
minimist "^1.2.6"
|
||||
|
||||
mri@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
|
||||
integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
|
||||
|
||||
ms@2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
|
@ -3041,6 +3218,11 @@ napi-build-utils@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
|
||||
integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==
|
||||
|
||||
next-tick@1, next-tick@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
|
||||
integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
|
||||
|
||||
nice-try@^1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
|
@ -3853,6 +4035,13 @@ rxjs@^7.5.5:
|
|||
dependencies:
|
||||
tslib "^2.1.0"
|
||||
|
||||
sade@^1.8.1:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701"
|
||||
integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==
|
||||
dependencies:
|
||||
mri "^1.1.0"
|
||||
|
||||
safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
|
@ -4230,6 +4419,18 @@ svelte-hmr@^0.15.1:
|
|||
resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.15.1.tgz#d11d878a0bbb12ec1cba030f580cd2049f4ec86b"
|
||||
integrity sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA==
|
||||
|
||||
svelte-i18n@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/svelte-i18n/-/svelte-i18n-3.6.0.tgz#0f345d066662dd8f46efefc0e867fb05b71c9dbd"
|
||||
integrity sha512-qvvcMqHVCXJ5pHoQR5uGzWAW5vS3qB9mBq+W6veLZ6jkrzZGOziR+wyOUJsc59BupMh+Ae30qjOndFrRU6v5jA==
|
||||
dependencies:
|
||||
cli-color "^2.0.3"
|
||||
deepmerge "^4.2.2"
|
||||
estree-walker "^2"
|
||||
intl-messageformat "^9.13.0"
|
||||
sade "^1.8.1"
|
||||
tiny-glob "^0.2.9"
|
||||
|
||||
svelte-navigator@^3.2.2:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/svelte-navigator/-/svelte-navigator-3.2.2.tgz#4156c2388226e7c42b766ca4def63444ec58a8d2"
|
||||
|
@ -4361,11 +4562,27 @@ timed-out@^4.0.0, timed-out@^4.0.1:
|
|||
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
|
||||
integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==
|
||||
|
||||
timers-ext@^0.1.7:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6"
|
||||
integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==
|
||||
dependencies:
|
||||
es5-ext "~0.10.46"
|
||||
next-tick "1"
|
||||
|
||||
timm@^1.6.1:
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/timm/-/timm-1.7.1.tgz#96bab60c7d45b5a10a8a4d0f0117c6b7e5aff76f"
|
||||
integrity sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==
|
||||
|
||||
tiny-glob@^0.2.9:
|
||||
version "0.2.9"
|
||||
resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.9.tgz#2212d441ac17928033b110f8b3640683129d31e2"
|
||||
integrity sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==
|
||||
dependencies:
|
||||
globalyzer "0.1.0"
|
||||
globrex "^0.1.2"
|
||||
|
||||
tinycolor2@^1.4.1:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.6.0.tgz#f98007460169b0263b97072c5ae92484ce02d09e"
|
||||
|
@ -4452,6 +4669,16 @@ type-fest@^0.21.3:
|
|||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
|
||||
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
|
||||
|
||||
type@^1.0.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
|
||||
integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
|
||||
|
||||
type@^2.7.2:
|
||||
version "2.7.2"
|
||||
resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0"
|
||||
integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==
|
||||
|
||||
typedarray-to-buffer@^3.1.5:
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
|
||||
|
|
Loading…
Reference in a new issue