redesigned UI logic
This commit is contained in:
parent
72b09cc383
commit
c58130f2db
8 changed files with 190 additions and 145 deletions
|
@ -1,17 +1,17 @@
|
|||
<script lang="ts">
|
||||
export let activated: boolean
|
||||
export let active: boolean
|
||||
</script>
|
||||
|
||||
<div class="spinner">
|
||||
<img alt="WBM back" src="/img/WBM-back.png" />
|
||||
<img
|
||||
alt="WBM left gear"
|
||||
class="rotateL {activated && 'activated'}"
|
||||
class="rotateL {active && 'activated'}"
|
||||
src="/img/WBM-Lgear.png"
|
||||
/>
|
||||
<img
|
||||
alt="WBM right gear"
|
||||
class="rotateR {activated && 'activated'}"
|
||||
class="rotateR {active && 'activated'}"
|
||||
src="/img/WBM-Rgear.png"
|
||||
/>
|
||||
<img alt="WBM ftont" src="/img/WBM-front.png" />
|
||||
|
|
|
@ -1,31 +1,45 @@
|
|||
<script lang="ts">
|
||||
import { open as shellOpen } from "@tauri-apps/api/shell"
|
||||
|
||||
import { OperationType } from "./types"
|
||||
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
|
||||
export let operationType: OperationType
|
||||
</script>
|
||||
|
||||
<p>
|
||||
You can also optionally setup
|
||||
<!-- svelte-ignore a11y-invalid-attribute -->
|
||||
<a
|
||||
href="javascript:;"
|
||||
on:click={() => {
|
||||
shellOpen("https://github.com/War-Brokers-Mods/WBM#3-set-up-obs-optional")
|
||||
}}
|
||||
>
|
||||
OBS overlays
|
||||
</a>
|
||||
for WB statistics.
|
||||
</p>
|
||||
{#if operationType == OperationType.Install}
|
||||
<p>
|
||||
You can also optionally setup
|
||||
<!-- svelte-ignore a11y-invalid-attribute -->
|
||||
<a
|
||||
href="javascript:;"
|
||||
on:click={() => {
|
||||
shellOpen(
|
||||
"https://github.com/War-Brokers-Mods/WBM#3-set-up-obs-optional"
|
||||
)
|
||||
}}
|
||||
>
|
||||
OBS overlays
|
||||
</a>
|
||||
for WB statistics.
|
||||
</p>
|
||||
{:else}
|
||||
<p>Remove launch option if you're using macOS or linux.</p>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
p {
|
||||
@apply text-center;
|
||||
}
|
||||
|
||||
a {
|
||||
@apply text-blue-400;
|
||||
a {
|
||||
@apply text-blue-400;
|
||||
|
||||
&:hover {
|
||||
@apply text-blue-500;
|
||||
}
|
||||
&:hover {
|
||||
@apply text-blue-500;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
5
src/pages/Operation/Install.svelte
Normal file
5
src/pages/Operation/Install.svelte
Normal file
|
@ -0,0 +1,5 @@
|
|||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
<!-- Handle lastInstallErr change -->
|
||||
<!-- On install complete -->
|
5
src/pages/Operation/Remove.svelte
Normal file
5
src/pages/Operation/Remove.svelte
Normal file
|
@ -0,0 +1,5 @@
|
|||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
<!-- Handle lastRemoveErr change -->
|
||||
<!-- On remove complete -->
|
|
@ -1,31 +1,21 @@
|
|||
<script lang="ts">
|
||||
// components only used here
|
||||
import Install from "./Install.svelte"
|
||||
import Remove from "./Remove.svelte"
|
||||
|
||||
// components also used outside
|
||||
import HomeButton from "../../components/HomeButton.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
|
||||
import { querystring } from "svelte-spa-router"
|
||||
|
||||
// etc
|
||||
import { install, remove } from "./logic"
|
||||
import store from "./store"
|
||||
|
||||
// types
|
||||
import { COMMANDS } from "../../constants"
|
||||
import { InstallErr, RemoveErr } from "./types"
|
||||
|
||||
interface InstallArgs {
|
||||
gamePath: string
|
||||
}
|
||||
|
||||
enum OperationType {
|
||||
Install,
|
||||
Remove,
|
||||
}
|
||||
import { OperationType } from "./types"
|
||||
|
||||
//
|
||||
// variables
|
||||
|
@ -34,73 +24,21 @@
|
|||
const operationType: OperationType = $querystring.includes("install")
|
||||
? OperationType.Install
|
||||
: 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 spinCog = false
|
||||
|
||||
let installSuccess = false
|
||||
let removeSuccess = false
|
||||
|
||||
//
|
||||
// functions
|
||||
//
|
||||
//
|
||||
|
||||
/**
|
||||
* only used inside other install functions.
|
||||
* Is never called directly.
|
||||
*
|
||||
* @param {InstallArgs} args
|
||||
*/
|
||||
function _install(args: InstallArgs) {
|
||||
wasButtonClicked = true
|
||||
spinCog = true
|
||||
store.wasButtonClicked.subscribe((value) => {
|
||||
wasButtonClicked = value
|
||||
})
|
||||
|
||||
invoke<InstallErr>(COMMANDS.INSTALL, args as any)
|
||||
.then((res) => {
|
||||
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,
|
||||
})
|
||||
}
|
||||
store.spinCog.subscribe((value) => {
|
||||
spinCog = value
|
||||
})
|
||||
</script>
|
||||
|
||||
<!-- Allow user to go back to home until they click the install button -->
|
||||
|
@ -108,58 +46,30 @@
|
|||
<HomeButton />
|
||||
{/if}
|
||||
|
||||
{#if operationType == OperationType.Install}
|
||||
<div class="install-page">
|
||||
<Spinner activated={spinCog} />
|
||||
<div class="page">
|
||||
<Spinner active={spinCog} />
|
||||
|
||||
{#if !wasButtonClicked}
|
||||
<button on:click={install}>Install!</button>
|
||||
{#if !wasButtonClicked}
|
||||
<!-- 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}
|
||||
|
||||
<!-- show only when the install button is clicked -->
|
||||
{#if wasButtonClicked}
|
||||
<Interrupts
|
||||
lastErrStaus={lastInstallErrStaus}
|
||||
{selectGamePathAndInstall}
|
||||
{setSteamLaunchOptionAndInstall}
|
||||
/>
|
||||
|
||||
{#if installSuccess}
|
||||
<Complete />
|
||||
{/if}
|
||||
{:else}
|
||||
<!-- Show only when the button is clicked -->
|
||||
{#if operationType == OperationType.Install}
|
||||
<Install />
|
||||
{:else}
|
||||
<Remove />
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<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}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import "./styles/button.scss";
|
||||
|
||||
.install-page {
|
||||
@apply flex flex-col items-center;
|
||||
}
|
||||
|
||||
.remove-page {
|
||||
.page {
|
||||
@apply flex flex-col items-center;
|
||||
}
|
||||
</style>
|
||||
|
|
78
src/pages/Operation/logic.ts
Normal file
78
src/pages/Operation/logic.ts
Normal 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)
|
||||
})
|
||||
}
|
26
src/pages/Operation/store.ts
Normal file
26
src/pages/Operation/store.ts
Normal 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,
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
/**
|
||||
* Must be synced with `src-tauri/src/commands/install/types.rs`
|
||||
*/
|
||||
|
||||
export enum InstallErr {
|
||||
UnsupportedOS,
|
||||
FailedToGetGamePath,
|
||||
|
@ -16,7 +15,15 @@ export enum InstallErr {
|
|||
LaunchOptionNotSet,
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be synced with `src-tauri/src/commands/remove/types.rs`
|
||||
*/
|
||||
export enum RemoveErr {
|
||||
FailedToGetGamePath,
|
||||
GamePathNotValid,
|
||||
}
|
||||
|
||||
export enum OperationType {
|
||||
Install,
|
||||
Remove,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue