From ba59a49f98f92bb054d3da3e1c8a394fd89e4c35 Mon Sep 17 00:00:00 2001 From: Alois Date: Thu, 21 May 2026 12:15:37 +0200 Subject: [PATCH] (feat): improved conversation adding flow (feat): visual tweaks for user modal (feat): now using full width for profile settings page on mobile (fix): profile not saving with empty avatar (chore): bump version due to prod release not getting created (chore): update licenses --- apps/web/src/components/modals/basic.tsx | 6 +- apps/web/src/components/navbar.tsx | 1 - apps/web/src/components/sidebar.tsx | 2 +- .../src/features/conversation/list/body.tsx | 10 ++++ apps/web/src/routes/app/home.tsx | 58 ++++++++++++++++--- apps/web/src/routes/settings/profile.tsx | 23 +++++--- .../LICENSE | 0 licenses/THIRD_PARTY_NOTICES.md | 18 ++++-- licenses/sbom.cyclonedx.json | 53 ++++++++++++++--- .../tauri-plugin-app-events-api@0.2.0/LICENSE | 21 +++++++ licenses/third-party-credits.json | 25 ++++++-- package.json | 2 +- packages/shared/src/data.ts | 3 +- packages/storage/src/session.tsx | 25 +++++++- 14 files changed, 203 insertions(+), 44 deletions(-) rename licenses/{@tensamin_ttp-core@0.0.15 => @tensamin_ttp-core@0.0.19}/LICENSE (100%) create mode 100644 licenses/tauri-plugin-app-events-api@0.2.0/LICENSE diff --git a/apps/web/src/components/modals/basic.tsx b/apps/web/src/components/modals/basic.tsx index be3e967..8a7df3b 100644 --- a/apps/web/src/components/modals/basic.tsx +++ b/apps/web/src/components/modals/basic.tsx @@ -31,12 +31,12 @@ export function Basic({ +
} @@ -52,7 +52,7 @@ export function Basic({

{user.display}

-
{extra}
+
{extra}
); diff --git a/apps/web/src/components/navbar.tsx b/apps/web/src/components/navbar.tsx index 162a057..1c9e3a7 100644 --- a/apps/web/src/components/navbar.tsx +++ b/apps/web/src/components/navbar.tsx @@ -23,7 +23,6 @@ export default function Navbar({ forMobile }: { forMobile: boolean }) { const currentCalls = calls.filter((call) => call.call_members.some((member) => member === id), ); - //const currentCalls = ["leck", "schleck", "und", "eck"]; const [selectOpen, setSelectOpen] = useState(false); diff --git a/apps/web/src/components/sidebar.tsx b/apps/web/src/components/sidebar.tsx index f8ce056..054aff7 100644 --- a/apps/web/src/components/sidebar.tsx +++ b/apps/web/src/components/sidebar.tsx @@ -220,7 +220,7 @@ export default function Sidebar() { diff --git a/apps/web/src/features/conversation/list/body.tsx b/apps/web/src/features/conversation/list/body.tsx index 7092b6f..d240655 100644 --- a/apps/web/src/features/conversation/list/body.tsx +++ b/apps/web/src/features/conversation/list/body.tsx @@ -76,6 +76,16 @@ export default function List() {
); })} + diff --git a/apps/web/src/routes/app/home.tsx b/apps/web/src/routes/app/home.tsx index 90f6a26..3e2c477 100644 --- a/apps/web/src/routes/app/home.tsx +++ b/apps/web/src/routes/app/home.tsx @@ -11,12 +11,12 @@ import { useIsMobile, } from "@tensamin/ui"; import z from "zod"; -import { toast } from "@tensamin/shared/log"; import { useTTP } from "@tensamin/ttp"; import { useState } from "react"; import { Loader2 } from "lucide-react"; import { isTauri } from "@tauri-apps/api/core"; import { useStorage } from "@tensamin/storage/context"; +import { useSession } from "@tensamin/storage/session"; // The page export default function Page() { @@ -43,11 +43,16 @@ export default function Page() { // Add Conversation Button Component function AddConversationButton() { const { send } = useTTP(); + const { contacts, insertContact } = useSession(); const [loading, setLoading] = useState(false); + const [open, setOpen] = useState(false); + const [error, setError] = useState(null); - function submit(username: string | null) { + async function submit(username: string | null) { if (loading) return; + setError(null); + // username check const schema = z .string() .min(1, "Username is too short") @@ -56,26 +61,50 @@ function AddConversationButton() { const result = schema.safeParse(username?.toLowerCase().trim()); if (!result.success) { - toast("error", result.error.issues[0].message); + setError(result.error.issues[0].message); return; } + // user existence check + const user = await send("get_user_data", { + username: result.data, + }) + .then((data) => { + if (data.data.user_id === 0) { + throw new Error(); + } + + return data; + }) + .catch(() => { + setError("User not found"); + return; + }); + if (!user) return; + + // alrady added check + if (contacts.some((contact) => contact.user_id === user.data.user_id)) { + setError("Conversation already exists"); + return; + } + + // add the conv const timeout = setTimeout(() => setLoading(true), 500); send("add_conversation", { chat_partner_name: result.data, }) .then(() => { - toast("success", "Conversation added"); + insertContact(user.data.user_id); + setOpen(false); }) .catch((error) => { if (String(error).includes("error_not_found")) { - toast("error", "User not found"); + setError("User not found"); return; } - toast("error", "Failed to add conversation, check console for details"); - console.error("Failed to add conversation", error); + setError(String(error)); }) .finally(() => { clearTimeout(timeout); @@ -84,7 +113,15 @@ function AddConversationButton() { } return ( - + { + if (value) { + setError(null); + } + setOpen(value); + }} + > Add Conversation} /> @@ -110,7 +147,10 @@ function AddConversationButton() { name="username" placeholder="Enter username..." /> -
+
+ {error && ( +

{error}

+ )} Cancel} />

- GIFs are supported in decentralised mode or with Tensamin Premium + GIFs are supported in decentralised mode or with Tensamin Premium.
Maximum file size is 16mb.

@@ -162,13 +166,16 @@ export default function Page() { />