doll active state
This commit is contained in:
@@ -5,6 +5,7 @@ use crate::{
|
|||||||
FriendRemote, FriendRequestResponseDto, FriendshipResponseDto, SendFriendRequestDto,
|
FriendRemote, FriendRequestResponseDto, FriendshipResponseDto, SendFriendRequestDto,
|
||||||
UserBasicDto,
|
UserBasicDto,
|
||||||
},
|
},
|
||||||
|
remotes::user::UserRemote,
|
||||||
services::cursor::start_cursor_tracking,
|
services::cursor::start_cursor_tracking,
|
||||||
state::{init_app_data, FDOLL},
|
state::{init_app_data, FDOLL},
|
||||||
};
|
};
|
||||||
@@ -192,6 +193,22 @@ async fn delete_doll(id: String) -> Result<(), String> {
|
|||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn set_active_doll(doll_id: String) -> Result<(), String> {
|
||||||
|
UserRemote::new()
|
||||||
|
.set_active_doll(&doll_id)
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn remove_active_doll() -> Result<(), String> {
|
||||||
|
UserRemote::new()
|
||||||
|
.remove_active_doll()
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn recolor_gif_base64(
|
fn recolor_gif_base64(
|
||||||
white_color_hex: String,
|
white_color_hex: String,
|
||||||
@@ -235,6 +252,8 @@ pub fn run() {
|
|||||||
create_doll,
|
create_doll,
|
||||||
update_doll,
|
update_doll,
|
||||||
delete_doll,
|
delete_doll,
|
||||||
|
set_active_doll,
|
||||||
|
remove_active_doll,
|
||||||
recolor_gif_base64,
|
recolor_gif_base64,
|
||||||
quit_app
|
quit_app
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ pub struct UserBasicDto {
|
|||||||
pub id: String,
|
pub id: String,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub username: Option<String>,
|
pub username: Option<String>,
|
||||||
|
pub active_doll_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ pub struct UserProfile {
|
|||||||
pub created_at: String,
|
pub created_at: String,
|
||||||
pub updated_at: String,
|
pub updated_at: String,
|
||||||
pub last_login_at: Option<String>,
|
pub last_login_at: Option<String>,
|
||||||
|
pub active_doll_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||||
@@ -79,4 +80,18 @@ impl UserRemote {
|
|||||||
resp.error_for_status()?;
|
resp.error_for_status()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn set_active_doll(&self, doll_id: &str) -> Result<(), Error> {
|
||||||
|
let url = format!("{}/users/me/active-doll/{}", self.base_url, doll_id);
|
||||||
|
let resp = with_auth(self.client.put(url)).await.send().await?;
|
||||||
|
resp.error_for_status()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn remove_active_doll(&self) -> Result<(), Error> {
|
||||||
|
let url = format!("{}/users/me/active-doll", self.base_url);
|
||||||
|
let resp = with_auth(self.client.delete(url)).await.send().await?;
|
||||||
|
resp.error_for_status()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,14 @@
|
|||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
import type { DollDto } from "../../../types/bindings/DollDto";
|
import type { DollDto } from "../../../types/bindings/DollDto";
|
||||||
|
import type { UserProfile } from "../../../types/bindings/UserProfile";
|
||||||
|
import type { AppData } from "../../../types/bindings/AppData";
|
||||||
import type { CreateDollDto } from "../../../types/bindings/CreateDollDto";
|
import type { CreateDollDto } from "../../../types/bindings/CreateDollDto";
|
||||||
import type { UpdateDollDto } from "../../../types/bindings/UpdateDollDto";
|
import type { UpdateDollDto } from "../../../types/bindings/UpdateDollDto";
|
||||||
import DollPreview from "./DollPreview.svelte";
|
import DollPreview from "./DollPreview.svelte";
|
||||||
|
|
||||||
let dolls: DollDto[] = [];
|
let dolls: DollDto[] = [];
|
||||||
|
let user: UserProfile | null = null;
|
||||||
let loading = false;
|
let loading = false;
|
||||||
let error: string | null = null;
|
let error: string | null = null;
|
||||||
let isCreateModalOpen = false;
|
let isCreateModalOpen = false;
|
||||||
@@ -29,6 +32,10 @@
|
|||||||
loading = true;
|
loading = true;
|
||||||
try {
|
try {
|
||||||
dolls = await invoke("get_dolls");
|
dolls = await invoke("get_dolls");
|
||||||
|
// Use refresh_app_data to ensure we get the latest user state (including activeDollId)
|
||||||
|
// from the server, as the local state might be stale after updates.
|
||||||
|
const appData: AppData = await invoke("refresh_app_data");
|
||||||
|
user = appData.user;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = (e as Error)?.message ?? String(e);
|
error = (e as Error)?.message ?? String(e);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -112,6 +119,24 @@
|
|||||||
error = (e as Error)?.message ?? String(e);
|
error = (e as Error)?.message ?? String(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleSetActiveDoll(dollId: string) {
|
||||||
|
try {
|
||||||
|
await invoke("set_active_doll", { dollId });
|
||||||
|
await refreshDolls();
|
||||||
|
} catch (e) {
|
||||||
|
error = (e as Error)?.message ?? String(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleRemoveActiveDoll() {
|
||||||
|
try {
|
||||||
|
await invoke("remove_active_doll");
|
||||||
|
await refreshDolls();
|
||||||
|
} catch (e) {
|
||||||
|
error = (e as Error)?.message ?? String(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="dolls-page flex flex-col gap-4 p-4">
|
<div class="dolls-page flex flex-col gap-4 p-4">
|
||||||
@@ -140,9 +165,16 @@
|
|||||||
<p>No dolls found. Create your first doll!</p>
|
<p>No dolls found. Create your first doll!</p>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
|
||||||
{#each dolls as doll (doll.id)}
|
{#each dolls as doll (doll.id)}
|
||||||
<div class="card border border-base-200 bg-base-100">
|
<div class="card border border-base-200 bg-base-100 relative">
|
||||||
|
{#if user?.activeDollId === doll.id}
|
||||||
|
<div
|
||||||
|
class="absolute top-2 right-2 badge badge-success badge-sm gap-1 z-10"
|
||||||
|
>
|
||||||
|
Active
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h3 class="card-title text-base">{doll.name}</h3>
|
<h3 class="card-title text-base">{doll.name}</h3>
|
||||||
<div class="flex justify-center mb-2">
|
<div class="flex justify-center mb-2">
|
||||||
@@ -170,6 +202,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions justify-end mt-2">
|
<div class="card-actions justify-end mt-2">
|
||||||
|
{#if user?.activeDollId === doll.id}
|
||||||
|
<button
|
||||||
|
class="btn btn-xs btn-ghost text-warning"
|
||||||
|
on:click={handleRemoveActiveDoll}>Deactivate</button
|
||||||
|
>
|
||||||
|
{:else}
|
||||||
|
<button
|
||||||
|
class="btn btn-xs btn-ghost text-success"
|
||||||
|
on:click={() => handleSetActiveDoll(doll.id)}>Activate</button
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
<button
|
<button
|
||||||
class="btn btn-xs btn-ghost"
|
class="btn btn-xs btn-ghost"
|
||||||
on:click={() => openEditModal(doll)}>Edit</button
|
on:click={() => openEditModal(doll)}>Edit</button
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
|
|
||||||
export type UserBasicDto = { id: string, name: string, username: string | null, };
|
export type UserBasicDto = { id: string, name: string, username: string | null, activeDollId: string | null, };
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
|
|
||||||
export type UserProfile = { id: string, keycloakSub: string, name: string, email: string, username: string | null, roles: Array<string>, createdAt: string, updatedAt: string, lastLoginAt: string | null, };
|
export type UserProfile = { id: string, keycloakSub: string, name: string, email: string, username: string | null, roles: Array<string>, createdAt: string, updatedAt: string, lastLoginAt: string | null, activeDollId: string | null, };
|
||||||
|
|||||||
Reference in New Issue
Block a user