User profile

This commit is contained in:
2026-08-02 09:54:28 +08:00
parent 0f5ded4cd9
commit 5c5f4dbf01
9 changed files with 299 additions and 40 deletions
+18 -5
View File
@@ -5,13 +5,13 @@
export const commands = {
async createFriend(friend: Friend) : Promise<Friend> {
async createFriend(friend: User) : Promise<User> {
return await TAURI_INVOKE("create_friend", { friend });
},
async listFriends() : Promise<Friend[]> {
async listFriends() : Promise<User[]> {
return await TAURI_INVOKE("list_friends");
},
async getFriend(id: string) : Promise<Friend | null> {
async getFriend(id: string) : Promise<User | null> {
return await TAURI_INVOKE("get_friend", { id });
},
async deleteFriend(id: string) : Promise<boolean> {
@@ -32,6 +32,12 @@ async updateRemote(id: string, remote: RemoteInput) : Promise<Remote | null> {
async deleteRemote(id: string) : Promise<boolean> {
return await TAURI_INVOKE("delete_remote", { id });
},
async getProfile() : Promise<User> {
return await TAURI_INVOKE("get_profile");
},
async updateProfile(displayName: string) : Promise<User> {
return await TAURI_INVOKE("update_profile", { displayName });
},
async getPublicKey() : Promise<string> {
return await TAURI_INVOKE("get_public_key");
}
@@ -42,9 +48,11 @@ async getPublicKey() : Promise<string> {
export const events = __makeEvents__<{
friendsChanged: FriendsChanged,
profileChanged: ProfileChanged,
remotesChanged: RemotesChanged
}>({
friendsChanged: "friends-changed",
profileChanged: "profile-changed",
remotesChanged: "remotes-changed"
})
@@ -54,11 +62,16 @@ remotesChanged: "remotes-changed"
/** user-defined types **/
export type Friend = { id: string; displayName: string }
export type FriendsChanged = { friends: Friend[] }
export type FriendsChanged = { friends: User[] }
export type ProfileChanged = { profile: User }
export type Remote = { id: string; address: string; name: string | null; port: number | null }
export type RemoteInput = { address: string; name: string | null; port: number | null }
export type RemotesChanged = { remotes: Remote[] }
/**
* Public user identity exchanged with peers and remote servers. `id` is the
* user's Ed25519 public key and is not persisted as local profile metadata.
*/
export type User = { id: string; displayName: string }
/** tauri-specta globals **/
+2 -2
View File
@@ -1,8 +1,8 @@
<script lang="ts">
import { onMount } from "svelte";
import { commands, events, type Friend } from "$lib/bindings";
import { commands, events, type User } from "$lib/bindings";
let friends: Friend[] = [];
let friends: User[] = [];
let error = "";
onMount(() => {
+70
View File
@@ -0,0 +1,70 @@
<script lang="ts">
import { onMount } from "svelte";
import { commands, events, type User } from "$lib/bindings";
let profile: User | null = null;
let displayName = "";
let error = "";
onMount(() => {
let stop: (() => void) | undefined;
let disposed = false;
async function initialize() {
const unlisten = await events.profileChanged.listen((event) => {
profile = event.payload.profile;
displayName = event.payload.profile.displayName;
});
if (disposed) {
unlisten();
return;
}
stop = unlisten;
await commands.getProfile();
}
initialize().catch((err) => {
error = String(err);
});
return () => {
disposed = true;
stop?.();
};
});
async function updateProfile(event: SubmitEvent) {
event.preventDefault();
error = "";
try {
await commands.updateProfile(displayName);
} catch (err) {
error = String(err);
}
}
</script>
<section>
<h1>Profile</h1>
{#if profile}
<p>Public key: {profile.id}</p>
{:else}
<p>Loading profile...</p>
{/if}
<form onsubmit={updateProfile}>
<label>
Display name
<input name="displayName" bind:value={displayName} required />
</label>
<button type="submit">Save profile</button>
</form>
{#if error}
<p>{error}</p>
{/if}
</section>
+4
View File
@@ -1,9 +1,13 @@
<script>
import FriendsList from "$lib/components/friends-list.svelte";
import Profile from "$lib/components/profile.svelte";
import RemotesList from "$lib/components/remotes-list.svelte";
</script>
<main>
<div>
<Profile />
</div>
<div>
<FriendsList />
</div>