Implement picking game dir

This commit is contained in:
2025-01-11 23:28:25 +01:00
parent 156c5770e8
commit e0f3361efe
8 changed files with 147 additions and 20 deletions

32
app.go
View File

@@ -2,6 +2,8 @@ package main
import ( import (
"context" "context"
"os"
"path/filepath"
"github.com/wailsapp/wails/v2/pkg/runtime" "github.com/wailsapp/wails/v2/pkg/runtime"
) )
@@ -90,12 +92,36 @@ func (a *App) GetGamePath() (res StringResponse) {
func (a *App) SetGamePath(path string) (res StringResponse) { func (a *App) SetGamePath(path string) (res StringResponse) {
settings.GamePath = path settings.GamePath = path
SaveSettings(*settings) err := SaveSettings(*settings)
res.Data = path if err != nil {
res.Error = err.Error()
}
return res return res
} }
func (a *App) IsGamePathValid() (res BoolResponse) { func (a *App) IsGamePathValid() (res BoolResponse) {
res.Data = settings.GamePath != "" if settings.GamePath == "" {
res.Data = false
return res return res
} }
// Check if the path exists and contains the Interface/AddOns directory
addonPath := filepath.Join(settings.GamePath, "Interface", "AddOns")
if _, err := os.Stat(addonPath); os.IsNotExist(err) {
res.Data = false
return res
}
res.Data = true
return res
}
func (a *App) SelectDirectory() (res StringResponse) {
path, err := runtime.OpenDirectoryDialog(a.ctx, runtime.OpenDialogOptions{
Title: "Select World of Warcraft Directory",
})
if err != nil {
res.Error = err.Error()
return
}
res.Data = path
return
}

View File

@@ -1,17 +1,62 @@
<script> <script>
import { GetGamePath, IsGamePathValid, SelectDirectory, SetGamePath } from "$wails/main/App";
let name = "Yggdrasil"; let name = "Yggdrasil";
let description = "The wow addon manager"; let description = "The wow addon manager";
let gamePathValid = false;
IsGamePathValid().then((res) => {
if (res.error) {
console.error(res.error);
} else {
gamePathValid = res.data;
}
});
async function handleSelectDirectory() {
try {
const result = await SelectDirectory();
if (result.error) {
console.error("Error selecting directory:", result.error);
return;
}
if (result.data) {
const response = await SetGamePath(result.data);
if (response.error) {
console.error("Error setting game path:", response.error);
} else {
window.location.reload();
}
}
} catch (error) {
console.error("Error selecting directory:", error);
}
}
</script> </script>
<header class="bg-gray-900 text-white py-4"> <header class="bg-gray-900 text-white py-4">
<div class="container mx-auto px-4 relative"> <div class="container mx-auto px-4 relative">
<div class="flex justify-center"> <div class="flex justify-between items-center">
<h1 class="text-3xl font-bold text-center relative"> <div class="flex-1"></div>
<h1 class="text-3xl font-bold text-center relative flex-1">
{name} {name}
<p class="text-base text-gray-300 absolute left-full ml-4 whitespace-nowrap bottom-0">
{description}
</p>
</h1> </h1>
<div class="flex-1 flex justify-end">
<button
class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg flex items-center gap-2 transition-colors"
on:click={handleSelectDirectory}
>
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path
fill-rule="evenodd"
d="M2 6a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1H8a3 3 0 00-3 3v1.5a1.5 1.5 0 01-3 0V6z"
clip-rule="evenodd"
/>
<path d="M6 12a2 2 0 012-2h8a2 2 0 012 2v2a2 2 0 01-2 2H8a2 2 0 01-2-2v-2z" />
</svg>
{gamePathValid ? "Change Game Path" : "Set Game Path"}
</button>
</div>
</div> </div>
</div> </div>
</header> </header>

View File

@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import AddonCard from "$lib/components/AddonCard.svelte"; import AddonCard from "$lib/components/AddonCard.svelte";
import { GetAddons } from "$wails/main/App"; import { GetAddons, IsGamePathValid } from "$wails/main/App";
import { type main } from "$wails/models"; import { type main } from "$wails/models";
let addons: { [key: string]: main.Addon } = {}; let addons: { [key: string]: main.Addon } = {};
@@ -11,12 +11,29 @@
addons = res.data; addons = res.data;
} }
}); });
let gamePath = "";
let gamePathValid = false;
IsGamePathValid().then((res) => {
if (res.error) {
console.error(res.error);
} else {
gamePathValid = res.data;
}
});
</script> </script>
<template> <template>
{#if gamePathValid}
<div class="grid grid-cols-3 gap-4"> <div class="grid grid-cols-3 gap-4">
{#each Object.values(addons) as addon} {#each Object.values(addons) as addon}
<AddonCard {addon} /> <AddonCard {addon} />
{/each} {/each}
</div> </div>
{:else}
<div class="flex flex-col items-center justify-center h-full">
<p class="text-gray-300">Game path is not valid</p>
<button class="bg-blue-500 text-white p-2 my-2 rounded-lg">Set Game Path</button>
</div>
{/if}
</template> </template>

View File

@@ -12,6 +12,7 @@ export default defineConfig({
$components: join(__dirname, "src/lib/components"), $components: join(__dirname, "src/lib/components"),
$router: join(__dirname, "src/lib/router"), $router: join(__dirname, "src/lib/router"),
$wails: join(__dirname, "wailsjs/go"), $wails: join(__dirname, "wailsjs/go"),
$runtime: join(__dirname, "wailsjs/runtime"),
}, },
}, },

View File

@@ -12,4 +12,12 @@ export function GetAddonRemoteVersion(arg1:string):Promise<main.StringResponse>;
export function GetAddons():Promise<main.AddonsResponse>; export function GetAddons():Promise<main.AddonsResponse>;
export function GetGamePath():Promise<main.StringResponse>;
export function IsGamePathValid():Promise<main.BoolResponse>;
export function SelectDirectory():Promise<main.StringResponse>;
export function SetGamePath(arg1:string):Promise<main.StringResponse>;
export function UpdateAddon(arg1:string):Promise<main.AddonResponse>; export function UpdateAddon(arg1:string):Promise<main.AddonResponse>;

View File

@@ -22,6 +22,22 @@ export function GetAddons() {
return window['go']['main']['App']['GetAddons'](); return window['go']['main']['App']['GetAddons']();
} }
export function GetGamePath() {
return window['go']['main']['App']['GetGamePath']();
}
export function IsGamePathValid() {
return window['go']['main']['App']['IsGamePathValid']();
}
export function SelectDirectory() {
return window['go']['main']['App']['SelectDirectory']();
}
export function SetGamePath(arg1) {
return window['go']['main']['App']['SetGamePath'](arg1);
}
export function UpdateAddon(arg1) { export function UpdateAddon(arg1) {
return window['go']['main']['App']['UpdateAddon'](arg1); return window['go']['main']['App']['UpdateAddon'](arg1);
} }

View File

@@ -78,6 +78,20 @@ export namespace main {
return a; return a;
} }
} }
export class BoolResponse {
data: boolean;
error?: string;
static createFrom(source: any = {}) {
return new BoolResponse(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.data = source["data"];
this.error = source["error"];
}
}
export class StringResponse { export class StringResponse {
data: string; data: string;
error?: string; error?: string;

View File

@@ -1 +1 @@
{"gamePath":"","addons":{"Channeler":{"name":"Channeler","url":"https://git.site.quack-lab.dev/dave/wow_channeler"},"Dechickenator":{"name":"Dechickenator","url":"https://git.site.quack-lab.dev/dave/wow_dechickenator"},"Heimdall":{"name":"Heimdall","url":"https://git.site.quack-lab.dev/dave/wow-Heimdall"}}} {"gamePath":"C:\\Games\\WoWRuski","addons":{"Channeler":{"name":"Channeler","url":"https://git.site.quack-lab.dev/dave/wow_channeler"},"Dechickenator":{"name":"Dechickenator","url":"https://git.site.quack-lab.dev/dave/wow_dechickenator"},"Heimdall":{"name":"Heimdall","url":"https://git.site.quack-lab.dev/dave/wow-Heimdall"}}}