Big chat improvements, adjusted mobile ui.

This commit is contained in:
Alois 2026-04-04 22:49:34 +02:00
commit 7a922a5978
15 changed files with 201 additions and 101 deletions

View file

@ -1,5 +1,5 @@
import { Button } from "@tensamin/ui/cmp/button";
import { House, Phone, User } from "lucide-react";
import { ArrowLeft, House, Phone, User } from "lucide-react";
import { useLocation, useNavigate, useSearch } from "@tanstack/react-router";
import { useCall } from "@tensamin/call/context";
import Wrapper from "@tensamin/user/wrapper";
@ -15,7 +15,7 @@ import { displayCallId } from "@tensamin/call/utils";
import { useState } from "react";
import { SidebarTrigger, useSidebar } from "@tensamin/ui/cmp/sidebar";
export default function Navbar() {
export default function Navbar({ forMobile }: { forMobile: boolean }) {
const navigate = useNavigate();
const { joinCall, state } = useCall();
const { conversations } = useConversation();
@ -29,14 +29,25 @@ export default function Navbar() {
const [selectOpen, setSelectOpen] = useState(false);
return (
<div className="w-full gap-2 h-13.5 flex items-center justify-center">
<Button
onClick={() => navigate({ to: "/" })}
className="w-9 h-9 aspect-square rounded-lg"
variant="outline"
>
<House className="size-4.5" />
</Button>
<div
className={`${forMobile && "border-b"} w-full gap-2 h-13.5 flex items-center justify-center`}
>
{forMobile ? (
<SidebarTrigger
className="w-9 h-9 aspect-square rounded-lg ml-2"
variant="outline"
>
<ArrowLeft className="size-4.5" />
</SidebarTrigger>
) : (
<Button
onClick={() => navigate({ to: "/" })}
className="w-9 h-9 aspect-square rounded-lg"
variant="outline"
>
<House className="size-4.5" />
</Button>
)}
{pathname === "/chat" && (
<Wrapper
userId={id}
@ -107,23 +118,25 @@ export function MobileNavbar() {
const { setOpenMobile } = useSidebar();
return (
<div className="z-100 w-full h-16 flex justify-center items-center gap-8 bg-card border-t">
<SidebarTrigger
className="text-foreground w-12! h-12! aspect-square rounded-xl"
variant="link"
>
<User className="size-5.5" />
</SidebarTrigger>
<Button
onClick={() => {
navigate({ to: "/" });
setOpenMobile(false);
}}
className="text-foreground w-12 h-12 aspect-square rounded-xl"
variant="link"
>
<House className="size-5.5" />
</Button>
<div className="z-100 w-full pb-[env(safe-area-inset-bottom)] bg-card border-t">
<div className="z-100 w-full h-14 flex justify-center items-center gap-8">
<SidebarTrigger
className="text-foreground w-12! h-12! aspect-square rounded-xl"
variant="link"
>
<User className="size-5.5" />
</SidebarTrigger>
<Button
onClick={() => {
navigate({ to: "/" });
setOpenMobile(false);
}}
className="text-foreground w-12 h-12 aspect-square rounded-xl"
variant="link"
>
<House className="size-5.5" />
</Button>
</div>
</div>
);
}

View file

@ -8,6 +8,7 @@ import {
Sidebar as SidebarRoot,
SidebarContent,
} from "@tensamin/ui/cmp/sidebar";
import { isTauri } from "@tauri-apps/api/core";
/**
* Renders the conversation sidebar with account summary and conversation list.
@ -23,8 +24,8 @@ export default function Sidebar() {
return (
<SidebarRoot>
<SidebarContent>
<div className="h-full w-full flex flex-col gap-3 p-2">
<SidebarContent className={isTauri() ? "pt-[env(safe-area-inset-top)]" : "pt-2"}>
<div className="h-full w-full flex flex-col gap-3 p-2 pt-0!">
<div>
<Wrapper
loading={<Loading />}

View file

@ -8,9 +8,11 @@ import {
ContextMenuTrigger,
} from "@tensamin/ui/cmp/context-menu";
import { useNavigate } from "@tanstack/react-router";
import { useSidebar } from "@tensamin/ui/cmp/sidebar";
export default function ConversationModal({ userId }: { userId: number }) {
const navigate = useNavigate();
const { setOpenMobile } = useSidebar();
return (
<ContextMenu>
@ -18,7 +20,10 @@ export default function ConversationModal({ userId }: { userId: number }) {
render={
<div
className="select-none cursor-pointer"
onClick={() => navigate({ to: "/chat", search: { id: userId } })}
onClick={() => {
navigate({ to: "/chat", search: { id: userId } });
setOpenMobile(false);
}}
>
<Wrapper
loading={<Loading />}

View file

@ -14,13 +14,17 @@ import { toast } from "@tensamin/shared/log";
import { useTTP } from "@tensamin/ttp/context";
import { useState } from "react";
import { Loader2 } from "lucide-react";
import { isTauri } from "@tauri-apps/api/core";
// The page
export default function Page() {
return (
<div className="p-3 flex gap-2">
<div className={`px-3 flex gap-2 ${!isTauri() && "pt-3"}`}>
<AddConversationButton />
<Button disabled>Add Community</Button>
<Button variant="outline" onClick={() => location.reload()}>
Reload
</Button>
</div>
);
}

View file

@ -7,6 +7,8 @@ import { SidebarProvider } from "@tensamin/ui/cmp/sidebar";
import { useIsMobile, cn } from "@tensamin/ui/utils";
import { motion } from "framer-motion";
import { isTauri } from "@tauri-apps/api/core";
import { useLocation } from "@tanstack/react-router";
/**
* Executes Layout.
@ -15,6 +17,7 @@ import { motion } from "framer-motion";
*/
export default function Layout(props: { children: ReactNode }) {
const isMobile = useIsMobile();
const location = useLocation();
return (
<motion.div
@ -33,8 +36,17 @@ export default function Layout(props: { children: ReactNode }) {
>
<SidebarProvider>
<Sidebar />
<div className="w-full h-full flex flex-col">
{!isMobile && <Navbar />}
<div
className={cn(
"w-full h-full flex flex-col",
isTauri() && "pt-[env(safe-area-inset-top)]",
)}
>
{!isMobile && <Navbar forMobile={false} />}
{isMobile && location.pathname === "/chat" && (
<Navbar forMobile={true} />
)}
<div
className={cn(
"bg-background h-full w-full",
@ -43,7 +55,7 @@ export default function Layout(props: { children: ReactNode }) {
>
{props.children}
</div>
{isMobile && <MobileNavbar />}
{isMobile && location.pathname !== "/chat" && <MobileNavbar />}
</div>
</SidebarProvider>
</motion.div>

View file

@ -12,6 +12,7 @@ import { TooltipProvider } from "@tensamin/ui/cmp/tooltip";
import { useStorage } from "@tensamin/storage/context";
import { useLocation, useNavigate } from "@tanstack/react-router";
import { useIsMobile } from "@tensamin/ui/utils";
import { isTauri } from "@tauri-apps/api/core";
/**
* Executes Layout.
@ -51,7 +52,16 @@ export default function Layout(props: { children: ReactNode }) {
</div>
)}
</div>
<Toaster position={isMobile ? "top-center" : "bottom-right"} />
<Toaster
position={isMobile ? "top-center" : "bottom-right"}
{...(isTauri()
? {
mobileOffset: {
top: "env(safe-area-inset-top)",
},
}
: {})}
/>
<TooltipProvider>
<Storage>
<LoginWrapper>