Updated a lot of stuff, trying out radix ui
This commit is contained in:
parent
9778e7dc71
commit
2862060439
24 changed files with 525 additions and 437 deletions
|
|
@ -7,11 +7,12 @@ import { Skeleton } from "@tensamin/ui/cmp/skeleton";
|
|||
import { useConversation } from "@/features/conversation/context";
|
||||
import {
|
||||
Select,
|
||||
SelectTrigger,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
} from "@tensamin/ui/cmp/select";
|
||||
import { displayCallId } from "@tensamin/call/utils";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function Navbar() {
|
||||
const navigate = useNavigate();
|
||||
|
|
@ -22,6 +23,9 @@ export default function Navbar() {
|
|||
const { id } = useSearch({ strict: false });
|
||||
|
||||
const currentCalls = id ? conversations?.[id]?.calls || [] : [];
|
||||
//const currentCalls = ["leck", "schleck", "und", "eck"];
|
||||
|
||||
const [selectOpen, setSelectOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="w-full h-13.5 flex items-center justify-center">
|
||||
|
|
@ -32,7 +36,7 @@ export default function Navbar() {
|
|||
>
|
||||
<House className="size-4.5" />
|
||||
</Button>
|
||||
{pathname === "/app/chat" && (
|
||||
{pathname === "/chat" && (
|
||||
<Wrapper
|
||||
userId={id}
|
||||
component={(user) => (
|
||||
|
|
@ -42,9 +46,9 @@ export default function Navbar() {
|
|||
/>
|
||||
)}
|
||||
<div className="w-full" />
|
||||
{pathname === "/app/chat" && id && (
|
||||
{pathname === "/chat" && id && (
|
||||
<>
|
||||
{currentCalls.length > 0 ? (
|
||||
{currentCalls.length === 0 ? (
|
||||
<Button
|
||||
disabled={state !== "closed"}
|
||||
onClick={() => {
|
||||
|
|
@ -66,27 +70,30 @@ export default function Navbar() {
|
|||
<Phone />
|
||||
</Button>
|
||||
) : (
|
||||
<Select>
|
||||
<SelectTrigger
|
||||
render={
|
||||
<Button className="w-9 h-9 aspect-square rounded-lg mr-2">
|
||||
<Phone />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<SelectContent>
|
||||
{currentCalls.map((callId) => (
|
||||
<SelectItem
|
||||
key={callId}
|
||||
onSelect={() => {
|
||||
joinCall(id, callId);
|
||||
}}
|
||||
>
|
||||
{displayCallId(callId)}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<>
|
||||
<Button
|
||||
onClick={() => setSelectOpen((prev) => !prev)}
|
||||
className="w-9! h-9! aspect-square rounded-lg mr-2"
|
||||
>
|
||||
<Phone />
|
||||
</Button>
|
||||
<Select onOpenChange={setSelectOpen} open={selectOpen}>
|
||||
<SelectTrigger hidden />
|
||||
<SelectContent>
|
||||
{currentCalls.map((callId) => (
|
||||
<SelectItem
|
||||
value={callId}
|
||||
key={callId}
|
||||
onSelect={() => {
|
||||
joinCall(id, callId);
|
||||
}}
|
||||
>
|
||||
{displayCallId(callId)}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
import * as React from "react";
|
||||
import { useSocket } from "@tensamin/ttp/context";
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
type ReactNode,
|
||||
} from "react";
|
||||
|
||||
import { toast } from "@tensamin/shared/log";
|
||||
import type {
|
||||
|
|
@ -12,28 +18,22 @@ interface contextValue {
|
|||
communities: Community[] | null;
|
||||
}
|
||||
|
||||
const ConversationContext = React.createContext<contextValue | undefined>(
|
||||
undefined,
|
||||
);
|
||||
const ConversationContext = createContext<contextValue | undefined>(undefined);
|
||||
|
||||
/**
|
||||
* Executes ConversationProvider.
|
||||
* @param props Parameter props.
|
||||
* @returns unknown.
|
||||
*/
|
||||
export default function ConversationProvider(props: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const [conversations, setConversations] = React.useState<
|
||||
Conversation[] | null
|
||||
>(null);
|
||||
const [communities, setCommunities] = React.useState<Community[] | null>(
|
||||
export default function ConversationProvider(props: { children: ReactNode }) {
|
||||
const [conversations, setConversations] = useState<Conversation[] | null>(
|
||||
null,
|
||||
);
|
||||
const [communities, setCommunities] = useState<Community[] | null>(null);
|
||||
|
||||
const { send } = useSocket();
|
||||
|
||||
React.useEffect(() => {
|
||||
useEffect(() => {
|
||||
let active = true;
|
||||
|
||||
send("get_conversations", {})
|
||||
|
|
@ -92,7 +92,7 @@ export default function ConversationProvider(props: {
|
|||
* @returns contextValue.
|
||||
*/
|
||||
export function useConversation(): contextValue {
|
||||
const context = React.useContext(ConversationContext);
|
||||
const context = useContext(ConversationContext);
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useConversation must be used within a ConversationProvider",
|
||||
|
|
|
|||
|
|
@ -38,21 +38,20 @@ export default function List() {
|
|||
id="conversation-list"
|
||||
className="overflow-y-auto flex-1 h-full"
|
||||
>
|
||||
{communities === null || conversations === null ? (
|
||||
<div className="flex items-center justify-center pt-5">
|
||||
<p className="text-foreground/45 flex gap-1 items-center justify-center">
|
||||
<Loader2 size={18} className="animate-spin" />
|
||||
Loading...
|
||||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
<div
|
||||
className="relative w-full flex flex-col"
|
||||
style={{
|
||||
height: `${virtualizer.getTotalSize()}px`,
|
||||
}}
|
||||
>
|
||||
{communities === null || conversations === null ? (
|
||||
<div className="flex items-center justify-center h-full pt-5">
|
||||
<p className="text-foreground/45 flex gap-1 items-center justify-center">
|
||||
<Loader2 size={18} className="animate-spin" />
|
||||
Loading...
|
||||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{communities &&
|
||||
conversations &&
|
||||
virtualizer.getVirtualItems().map((virtualItem) => {
|
||||
|
|
|
|||
|
|
@ -14,20 +14,18 @@ export default function ConversationModal({ userId }: { userId: number }) {
|
|||
|
||||
return (
|
||||
<ContextMenu>
|
||||
<ContextMenuTrigger
|
||||
render={
|
||||
<div
|
||||
className="select-none cursor-pointer"
|
||||
onClick={() => navigate({ to: "/chat", search: { id: userId } })}
|
||||
>
|
||||
<Wrapper
|
||||
loading={<Loading />}
|
||||
userId={userId}
|
||||
component={(user) => <Basic user={user} />}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
></ContextMenuTrigger>
|
||||
<ContextMenuTrigger asChild>
|
||||
<div
|
||||
className="select-none cursor-pointer"
|
||||
onClick={() => navigate({ to: "/chat", search: { id: userId } })}
|
||||
>
|
||||
<Wrapper
|
||||
loading={<Loading />}
|
||||
userId={userId}
|
||||
component={(user) => <Basic user={user} />}
|
||||
/>
|
||||
</div>
|
||||
</ContextMenuTrigger>
|
||||
<ContextMenuContent>
|
||||
<ContextMenuGroup>
|
||||
<ContextMenuItem>Test</ContextMenuItem>
|
||||
|
|
|
|||
|
|
@ -70,7 +70,9 @@ function AddConversationButton() {
|
|||
|
||||
return (
|
||||
<Dialog>
|
||||
<DialogTrigger render={<Button>Add Conversation</Button>} />
|
||||
<DialogTrigger asChild>
|
||||
<Button>Add Conversation</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>New Conversation</DialogTitle>
|
||||
|
|
@ -96,7 +98,9 @@ function AddConversationButton() {
|
|||
placeholder="Enter username..."
|
||||
/>
|
||||
<div className="flex w-full justify-end gap-1">
|
||||
<DialogClose render={<Button variant="outline">Cancel</Button>} />
|
||||
<DialogClose asChild>
|
||||
<Button variant="outline">Cancel</Button>
|
||||
</DialogClose>
|
||||
<Button disabled={loading} type="submit">
|
||||
{loading && <Loader2 className="animate-spin" />} Continue
|
||||
</Button>
|
||||
|
|
|
|||
Loading…
Reference in a new issue