Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

splash: cleanup splash implementation, allow changing locale during installation dir step #552

Merged
merged 4 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<!doctype html>
<!-- TODO - perhaps eventually add a lightmode toggle -->
<html lang="en" class="dark">
<head>
<meta charset="UTF-8" />
Expand Down
6 changes: 1 addition & 5 deletions src/assets/translations/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,14 @@
"setup_prompt_selectISO": "Select your legitimately obtained ISO File",
"sidebar_help": "Help",
"sidebar_settings": "Settings",
"splash_button_deleteOldInstallDir_no": "No",
"splash_button_deleteOldInstallDir_yes": "Yes",
"splash_button_setInstallFolder_prompt": "Pick an Installation Folder",
"splash_button_setInstallFolder": "Set Install Folder",
"splash_deleteOldInstallDir": "The old installation folder is no longer needed, delete it?",
"splash_noInstallDirSet": "No installation folder set!",
"splash_selectLocale": "Select Locale",
"splash_step_loadingTranslations": "Loading Translations",
"splash_step_checkingDirectories": "Checking Directories",
"splash_step_errorOpening": "Problem opening Launcher",
"splash_step_finishingUp": "Finishing Up",
"splash_step_pickInstallFolder": "Pick an Installation Folder",
"splash_step_readingSettings": "Reading Settings",
"temp_jak2_indev_header": "Jak II is Currently in Development",
"temp_jak2_indev_progressReports": "Progress Reports",
"temp_jak2_indev_subheader": "In the meantime, check out our latest progress reports showcasing what we've accomplished so far",
Expand Down
317 changes: 128 additions & 189 deletions src/splash/Splash.svelte
Original file line number Diff line number Diff line change
@@ -1,179 +1,172 @@
<script lang="ts">
import { openMainWindow } from "$lib/rpc/window";
import { onMount } from "svelte";
import logo from "$assets/images/icon.webp";
import { folderPrompt } from "$lib/utils/file-dialogs";
import {
deleteOldDataDirectory,
getInstallationDirectory,
getLocale,
oldDataDirectoryExists,
setInstallationDirectory,
setLocale,
} from "$lib/rpc/config";
import { AVAILABLE_LOCALES } from "$lib/i18n/i18n";
import { locale as svelteLocale, _ } from "svelte-i18n";
import SelectLocale from "./components/SelectLocale.svelte";
import ChooseInstallFolder from "./components/ChooseInstallFolder.svelte";
import LocaleQuickChanger from "./components/LocaleQuickChanger.svelte";
import { openMainWindow } from "$lib/rpc/window";

let currentProgress = 10;
let currentStatusText = "Loading Locales...";

let selectLocale = false;
let installationDirSet = true;
let stepError = undefined;
let oldDataDirToClean = false;
let loaded = false;
let timeStartedAt = 0;
let minimumTime = 500;
let stepsToDo = [
{
statusText: "splash_step_loadingTranslations",
func: async () => {
await checkLocale();
},
waitingForInteraction: false,
},
{
statusText: "splash_step_checkingDirectories",
func: async () => {
await checkDirectories();
},
waitingForInteraction: false,
},
];
let currentStepIndex = 0;
let errorText = "";

// Events
onMount(async () => {
// First, see if the user has selected a locale
await checkLocale();
currentStatusText = $_("splash_step_readingSettings");
// Ensure a default locale is set
await svelteLocale.set("en-US");
timeStartedAt = Date.now();
stepsToDo.push({
statusText: "splash_step_finishingUp",
func: async () => {
let currentTime = Date.now();
if (currentTime - timeStartedAt < minimumTime) {
await new Promise((res) =>
setTimeout(res, minimumTime - (currentTime - timeStartedAt)),
);
}
const errorClosing = await openMainWindow();
if (!errorClosing) {
errorText = $_("splash_step_errorOpening");
}
},
waitingForInteraction: false,
});
loaded = true;
await proceedInSteps(false, false);
});

// TODO - cleanup this code and make it easier to add steps like with
// the game setup
async function proceedInSteps(stepForward: boolean, stepBackward: boolean) {
if (stepForward) {
currentStepIndex++;
if (currentStepIndex >= stepsToDo.length) {
currentStepIndex = stepsToDo.length - 1;
}
}
if (stepBackward) {
currentStepIndex--;
if (currentStepIndex < 0) {
currentStepIndex = 0;
}
}
// Process as many steps as we can
while (
currentStepIndex < stepsToDo.length &&
!stepsToDo[currentStepIndex].waitingForInteraction
) {
await new Promise((res) => setTimeout(res, 125));
await stepsToDo[currentStepIndex].func();
currentStepIndex++;
}
if (currentStepIndex >= stepsToDo.length) {
currentStepIndex = stepsToDo.length - 1;
}
}

async function checkLocale() {
const locale = await getLocale();
if (locale === null) {
// Prompt the user to select a locale
selectLocale = true;
svelteLocale.set("en-US");
stepsToDo.splice(currentStepIndex + 1, 0, {
statusText: "splash_selectLocale",
waitingForInteraction: true,
func: async () => {},
});
} else {
// Set locale and continue
setLocale(locale);
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 {
finishSplash();
stepsToDo.splice(currentStepIndex + 1, 0, {
statusText: "splash_noInstallDirSet",
waitingForInteraction: true,
func: async () => {},
});
}
}

async function finishSplash() {
currentProgress = 50;
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 = $_("splash_step_errorOpening");
async function handleLocaleChange(event: any, forStep: boolean) {
await setLocale(event.detail.newLocale);
if (forStep) {
await proceedInSteps(true, false);
}
}

async function handleLocaleChange(evt: Event) {
const selectElement = evt.target as HTMLSelectElement;
setLocale(selectElement.value);
selectLocale = false;
await checkDirectories();
}
</script>

<div class="content" data-tauri-drag-region>
<div class="splash-logo no-pointer-events">
<img
src={logo}
data-testId="splash-logo"
alt="OpenGOAL logo"
aria-label="OpenGOAL logo"
draggable="false"
/>
</div>
<div class="splash-contents no-pointer-events">
{#if selectLocale}
<span class="mb-1">{$_("splash_selectLocale")}</span>
<div class="splash-select">
<select
data-testId="locale-select"
name="locales"
id="locales"
class="pointer-events emoji-font"
on:change={handleLocaleChange}
>
<option disabled selected value hidden />
{#each AVAILABLE_LOCALES as locale}
<option class="emoji-font" value={locale.id}
>{locale.flag}&nbsp;{locale.localizedName}</option
>
{/each}
</select>
</div>
{:else if oldDataDirToClean}
{$_("splash_deleteOldInstallDir")}
<br />
<span>
<button
data-testId="delete-old-data-dir-button"
class="splash-button pointer-events"
on:click={() => {
oldDataDirToClean = false;
deleteOldDataDirectory();
}}>{$_("splash_button_deleteOldInstallDir_yes")}</button
>
<button
data-testId="dont-delete-old-data-dir-button"
class="splash-button pointer-events"
on:click={() => {
oldDataDirToClean = false;
}}>{$_("splash_button_deleteOldInstallDir_no")}</button
>
</span>
{:else if !installationDirSet}
{#if stepError !== undefined}
{stepError}
{#if loaded}
<div class="splash-logo pointer-events-none">
<img
src={logo}
data-testId="splash-logo"
alt="OpenGOAL logo"
aria-label="OpenGOAL logo"
draggable="false"
/>
</div>
<div class="splash-contents pointer-events-none">
{#if errorText !== ""}
<div class="splash-status-text">
{errorText}
</div>
{:else if stepsToDo[currentStepIndex].statusText === "splash_selectLocale"}
<div class="splash-status-text">
{$_(stepsToDo[currentStepIndex].statusText)}
</div>
<SelectLocale on:change={(evt) => handleLocaleChange(evt, true)} />
{:else if stepsToDo[currentStepIndex].statusText === "splash_noInstallDirSet"}
<ChooseInstallFolder
on:complete={async () => {
await proceedInSteps(true, false);
}}
/>
{:else}
{$_("splash_noInstallDirSet")}
<div class="splash-status-text">
{$_(stepsToDo[currentStepIndex].statusText)}
</div>
{/if}
<br />
<button
data-testId="pick-install-folder-button"
class="splash-button pointer-events"
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>
</div>
<div class="splash-bar">
<div
data-tauri-drag-region
class="splash-status-bar fg"
style="width: {((currentStepIndex + 1) / stepsToDo.length) * 100}%"
/>
<div data-tauri-drag-region class="splash-status-bar bg" />
</div>
{#if stepsToDo[currentStepIndex].statusText === "splash_noInstallDirSet"}
<LocaleQuickChanger on:change={(evt) => handleLocaleChange(evt, false)} />
{/if}
</div>
<div class="splash-bar">
<div
data-tauri-drag-region
class="splash-status-bar fg"
style="width: {currentProgress}%"
/>
<div data-tauri-drag-region class="splash-status-bar bg" />
</div>
{/if}
</div>

<style>
Expand Down Expand Up @@ -221,64 +214,10 @@
background-color: #775500;
position: absolute;
}

.splash-status-bar.fg {
background-color: #ffb807;
position: absolute;
z-index: 999;
}

.splash-button {
margin-top: 5px;
appearance: none;
background-color: #ffb807;
border-radius: 6px;
box-sizing: border-box;
color: #000;
cursor: pointer;
display: inline-block;
font-family: "Roboto Mono", monospace;
font-size: 8pt;
font-weight: 700;
position: relative;
text-align: center;
text-decoration: none;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
vertical-align: middle;
white-space: nowrap;
}

.splash-button:focus:not(:focus-visible):not(.focus-visible) {
box-shadow: none;
outline: none;
}

.splash-button:hover {
background-color: #775500;
}

.splash-button:focus {
outline: none;
}

.splash-button:active {
background-color: #775500;
}

.no-pointer-events {
pointer-events: none;
}

.pointer-events {
pointer-events: auto;
}

.mb-1 {
margin-bottom: 1rem;
}

.emoji-font {
font-family: "Twemoji Country Flags", "Roboto Mono";
}
</style>
Loading
Loading