1
0
Fork 0

redesigned UI logic

This commit is contained in:
Kim, Jimin 2022-01-31 15:41:14 +09:00
parent 72b09cc383
commit c58130f2db
8 changed files with 190 additions and 145 deletions

View file

@ -1,17 +1,17 @@
<script lang="ts"> <script lang="ts">
export let activated: boolean export let active: boolean
</script> </script>
<div class="spinner"> <div class="spinner">
<img alt="WBM back" src="/img/WBM-back.png" /> <img alt="WBM back" src="/img/WBM-back.png" />
<img <img
alt="WBM left gear" alt="WBM left gear"
class="rotateL {activated && 'activated'}" class="rotateL {active && 'activated'}"
src="/img/WBM-Lgear.png" src="/img/WBM-Lgear.png"
/> />
<img <img
alt="WBM right gear" alt="WBM right gear"
class="rotateR {activated && 'activated'}" class="rotateR {active && 'activated'}"
src="/img/WBM-Rgear.png" src="/img/WBM-Rgear.png"
/> />
<img alt="WBM ftont" src="/img/WBM-front.png" /> <img alt="WBM ftont" src="/img/WBM-front.png" />

View file

@ -1,31 +1,45 @@
<script lang="ts"> <script lang="ts">
import { open as shellOpen } from "@tauri-apps/api/shell" import { open as shellOpen } from "@tauri-apps/api/shell"
import { OperationType } from "./types"
//
// Variables
//
export let operationType: OperationType
</script> </script>
<p> {#if operationType == OperationType.Install}
You can also optionally setup <p>
<!-- svelte-ignore a11y-invalid-attribute --> You can also optionally setup
<a <!-- svelte-ignore a11y-invalid-attribute -->
href="javascript:;" <a
on:click={() => { href="javascript:;"
shellOpen("https://github.com/War-Brokers-Mods/WBM#3-set-up-obs-optional") on:click={() => {
}} shellOpen(
> "https://github.com/War-Brokers-Mods/WBM#3-set-up-obs-optional"
OBS overlays )
</a> }}
for WB statistics. >
</p> OBS overlays
</a>
for WB statistics.
</p>
{:else}
<p>Remove launch option if you're using macOS or linux.</p>
{/if}
<style lang="scss"> <style lang="scss">
p { p {
@apply text-center; @apply text-center;
}
a { a {
@apply text-blue-400; @apply text-blue-400;
&:hover { &:hover {
@apply text-blue-500; @apply text-blue-500;
}
} }
} }
</style> </style>

View file

@ -0,0 +1,5 @@
<script lang="ts">
</script>
<!-- Handle lastInstallErr change -->
<!-- On install complete -->

View file

@ -0,0 +1,5 @@
<script lang="ts">
</script>
<!-- Handle lastRemoveErr change -->
<!-- On remove complete -->

View file

@ -1,31 +1,21 @@
<script lang="ts"> <script lang="ts">
// components only used here
import Install from "./Install.svelte"
import Remove from "./Remove.svelte"
// components also used outside // components also used outside
import HomeButton from "../../components/HomeButton.svelte" import HomeButton from "../../components/HomeButton.svelte"
import Spinner from "../../components/Spinner.svelte" import Spinner from "../../components/Spinner.svelte"
// components only used here
import Interrupts from "./Interrupts.svelte"
import Complete from "./Complete.svelte"
// tauri stuff
import { invoke } from "@tauri-apps/api/tauri"
import { open as dialogOpen } from "@tauri-apps/api/dialog"
// svelte stuff // svelte stuff
import { querystring } from "svelte-spa-router" import { querystring } from "svelte-spa-router"
// etc
import { install, remove } from "./logic"
import store from "./store"
// types // types
import { COMMANDS } from "../../constants" import { OperationType } from "./types"
import { InstallErr, RemoveErr } from "./types"
interface InstallArgs {
gamePath: string
}
enum OperationType {
Install,
Remove,
}
// //
// variables // variables
@ -34,73 +24,21 @@
const operationType: OperationType = $querystring.includes("install") const operationType: OperationType = $querystring.includes("install")
? OperationType.Install ? OperationType.Install
: OperationType.Remove : OperationType.Remove
let _gamePath = "" // not used directly
let lastInstallErrStaus: InstallErr = undefined
let lastRemoveErrStatus: RemoveErr = undefined
let wasButtonClicked = false // if the install/remove button was clicked or not let wasButtonClicked = false // if the install/remove button was clicked or not
let spinCog = false let spinCog = false
let installSuccess = false
let removeSuccess = false
// //
// functions //
// //
/** store.wasButtonClicked.subscribe((value) => {
* only used inside other install functions. wasButtonClicked = value
* Is never called directly. })
*
* @param {InstallArgs} args
*/
function _install(args: InstallArgs) {
wasButtonClicked = true
spinCog = true
invoke<InstallErr>(COMMANDS.INSTALL, args as any) store.spinCog.subscribe((value) => {
.then((res) => { spinCog = value
switch (res) { })
case InstallErr.FailedToGetGamePath: {
break
}
}
})
.catch((err: InstallErr) => {
console.log(typeof err, err)
})
}
/**
* entry point
*/
function install() {
_install({
gamePath: _gamePath,
})
}
/**
* called when default game path was not found.
*/
function selectGamePathAndInstall() {
dialogOpen({ directory: true, multiple: false }).then((value) => {
_gamePath = value as string
_install({
gamePath: _gamePath,
})
})
}
/**
* called after setting the steam launch option.
*/
function setSteamLaunchOptionAndInstall() {
_install({
gamePath: _gamePath,
})
}
</script> </script>
<!-- Allow user to go back to home until they click the install button --> <!-- Allow user to go back to home until they click the install button -->
@ -108,58 +46,30 @@
<HomeButton /> <HomeButton />
{/if} {/if}
{#if operationType == OperationType.Install} <div class="page">
<div class="install-page"> <Spinner active={spinCog} />
<Spinner activated={spinCog} />
{#if !wasButtonClicked} {#if !wasButtonClicked}
<button on:click={install}>Install!</button> <!-- Hide after clicking the button -->
{#if operationType == OperationType.Install}
<button on:click|once={() => install()}>Install/Update!</button>
{:else}
<button on:click|once={() => remove()}>Remove!</button>
{/if} {/if}
{:else}
<!-- show only when the install button is clicked --> <!-- Show only when the button is clicked -->
{#if wasButtonClicked} {#if operationType == OperationType.Install}
<Interrupts <Install />
lastErrStaus={lastInstallErrStaus} {:else}
{selectGamePathAndInstall} <Remove />
{setSteamLaunchOptionAndInstall}
/>
{#if installSuccess}
<Complete />
{/if}
{/if} {/if}
</div> {/if}
{:else} </div>
<div class="remove-page">
<Spinner activated={spinCog} />
{#if !wasButtonClicked}
<button on:click={install}>Remove!</button>
{/if}
<!-- show only when the install button is clicked -->
{#if wasButtonClicked}
<Interrupts
lastErrStaus={lastInstallErrStaus}
{selectGamePathAndInstall}
{setSteamLaunchOptionAndInstall}
/>
{#if installSuccess}
<Complete />
{/if}
{/if}
</div>
{/if}
<style lang="scss"> <style lang="scss">
@import "./styles/button.scss"; @import "./styles/button.scss";
.install-page { .page {
@apply flex flex-col items-center;
}
.remove-page {
@apply flex flex-col items-center; @apply flex flex-col items-center;
} }
</style> </style>

View file

@ -0,0 +1,78 @@
import { invoke } from "@tauri-apps/api/tauri"
import { open as dialogOpen } from "@tauri-apps/api/dialog"
import { COMMANDS } from "../../constants"
import store from "./store"
import type { InstallErr, RemoveErr } from "./types"
function buttonClicked() {
store.wasButtonClicked.set(true)
store.spinCog.set(true)
}
/**
* Calls the install command in the backend.
*
* @param {string} gamePath - Absolute path to the game directory in the steam library. Leave it empty to use default location.
*/
export function install(gamePath: string = "") {
buttonClicked()
if (!gamePath) {
store.gamePath.update((value) => {
gamePath = value
return value
})
}
invoke(COMMANDS.INSTALL, { gamePath })
.then(() => {
store.wasInstallSuccessful.set(true)
})
.catch((err: InstallErr) => {
console.error(err)
store.lastInstallErr.set(err)
})
}
/**
* Calls the remove command in the backend.
*
* @param {string} gamePath - Absolute path to the game directory in the steam library. Leave it empty to use default location.
*/
export function remove(gamePath: string = "") {
buttonClicked()
if (gamePath) {
store.gamePath.update((value) => {
gamePath = value
return value
})
}
invoke(COMMANDS.REMOVE, { gamePath })
.then(() => {
store.wasRemoveSuccessful.set(true)
})
.catch((err: RemoveErr) => {
console.error(err)
store.lastRemoveErr.set(err)
})
}
/**
* Opens a file selection dialog for the user to manually select the game directory.
* Called when the default game location was not found.
*
* @param {(gamePath?: string) => void} f - Function that will run after selecting a directory. Expected to be either the {@link install} function or the {@link remove} function.
*/
export function selectGamePathAndRun(f: (gamePath?: string) => void) {
dialogOpen({ directory: true, multiple: false }).then((value: string) => {
store.gamePath.set(value)
f(value)
})
}

View file

@ -0,0 +1,26 @@
import { writable } from "svelte/store"
import type { InstallErr, RemoveErr } from "./types"
const wasButtonClicked = writable(false)
const spinCog = writable(false)
const gamePath = writable("")
const lastInstallErr = writable<InstallErr>(undefined)
const lastRemoveErr = writable<RemoveErr>(undefined)
const wasInstallSuccessful = writable(false)
const wasRemoveSuccessful = writable(false)
export default {
wasButtonClicked,
spinCog,
gamePath,
lastInstallErr,
lastRemoveErr,
wasInstallSuccessful,
wasRemoveSuccessful,
}

View file

@ -1,7 +1,6 @@
/** /**
* Must be synced with `src-tauri/src/commands/install/types.rs` * Must be synced with `src-tauri/src/commands/install/types.rs`
*/ */
export enum InstallErr { export enum InstallErr {
UnsupportedOS, UnsupportedOS,
FailedToGetGamePath, FailedToGetGamePath,
@ -16,7 +15,15 @@ export enum InstallErr {
LaunchOptionNotSet, LaunchOptionNotSet,
} }
/**
* Must be synced with `src-tauri/src/commands/remove/types.rs`
*/
export enum RemoveErr { export enum RemoveErr {
FailedToGetGamePath, FailedToGetGamePath,
GamePathNotValid, GamePathNotValid,
} }
export enum OperationType {
Install,
Remove,
}