UI to show modules

This commit is contained in:
2026-02-17 18:19:12 +08:00
parent dcb9012ff6
commit 68c42b34a1
13 changed files with 134 additions and 43 deletions

View File

@@ -1,9 +1,9 @@
import { writable } from "svelte/store";
import { type AppData } from "../types/bindings/AppData";
import { type UserData } from "../types/bindings/UserData";
import { listen, type UnlistenFn } from "@tauri-apps/api/event";
import { invoke } from "@tauri-apps/api/core";
export let appData = writable<AppData | null>(null);
export let appData = writable<UserData | null>(null);
let unlisten: UnlistenFn | null = null;
let isListening = false;
@@ -12,7 +12,7 @@ export async function initAppDataListener() {
try {
if (isListening) return;
appData.set(await invoke("get_app_data"));
unlisten = await listen<AppData>("app-data-refreshed", (event) => {
unlisten = await listen<UserData>("app-data-refreshed", (event) => {
console.log("app-data-refreshed", event.payload);
appData.set(event.payload);
});

View File

@@ -1,6 +1,7 @@
<script lang="ts">
import Friends from "./tabs/friends.svelte";
import Preferences from "./tabs/preferences.svelte";
import Modules from "./tabs/modules.svelte";
import YourDolls from "./tabs/your-dolls/index.svelte";
import { listen } from "@tauri-apps/api/event";
import { onMount } from "svelte";
@@ -67,6 +68,16 @@
<div class="tab-content bg-base-100 border-base-300 p-4">
<Preferences />
</div>
<input
type="radio"
name="app_menu_tabs"
class="tab"
aria-label="Modules"
/>
<div class="tab-content bg-base-100 border-base-300 p-4">
<Modules />
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,62 @@
<script lang="ts">
import { onMount } from "svelte";
import { invoke } from "@tauri-apps/api/core";
import type { ModuleMetadata } from "../../../types/bindings/ModuleMetadata";
let modules: ModuleMetadata[] = [];
let loading = false;
let error: string | null = null;
onMount(async () => {
loading = true;
try {
modules = await invoke("get_modules");
} catch (e) {
error = (e as Error)?.message ?? String(e);
} finally {
loading = false;
}
});
</script>
<div class="modules-page flex flex-col gap-2">
{#if error}
<div class="text-error text-sm">{error}</div>
{/if}
<section class="flex flex-col gap-2">
<div class="collapse bg-base-100 border-base-300 border">
<input type="checkbox" checked />
<div class="collapse-title text-sm opacity-70 py-2">
Loaded Presence Modules
</div>
<div class="collapse-content px-2 -mb-2">
<div class="flex flex-col gap-3">
{#if loading}
<p class="text-sm text-base-content/70">Loading modules...</p>
{:else if modules.length === 0}
<p class="text-sm text-base-content/70">No modules loaded.</p>
{:else}
<div class="flex flex-col gap-2">
{#each modules as module (module.name)}
<div class="card px-3 py-2 bg-base-200/50">
<div class="flex flex-col gap-1">
<div class="font-medium">{module.name}</div>
<div class="text-xs text-base-content/70">
Version: {module.version}
</div>
{#if module.description}
<div class="text-xs text-base-content/60">
{module.description}
</div>
{/if}
</div>
</div>
{/each}
</div>
{/if}
</div>
</div>
</div>
</section>
</div>

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type ModuleMetadata = { name: string, version: string, description: string | null, };

View File

@@ -4,4 +4,4 @@ import type { FriendshipResponseDto } from "./FriendshipResponseDto";
import type { SceneData } from "./SceneData";
import type { UserProfile } from "./UserProfile";
export type AppData = { user: UserProfile | null, friends: Array<FriendshipResponseDto> | null, dolls: Array<DollDto> | null, scene: SceneData, };
export type UserData = { user: UserProfile | null, friends: Array<FriendshipResponseDto> | null, dolls: Array<DollDto> | null, scene: SceneData, };