Skip to content

Commit

Permalink
feat: move chat item to separate file ChatItem. Hide titles if ther…
Browse files Browse the repository at this point in the history
…e is no pinned chats
  • Loading branch information
OctopBP committed Aug 18, 2023
1 parent 96de7e3 commit dfc8492
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 98 deletions.
88 changes: 88 additions & 0 deletions src/components/ChatItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 1,88 @@
import { ActionIcon, Flex, Menu } from "@mantine/core";
import {
IconDotsVertical,
IconMessages,
IconPencil,
IconPin,
IconPinned,
IconPinnedOff,
IconTrash
} from "@tabler/icons-react";
import { Link } from "@tanstack/react-location";
import { Chat, db } from "../db";
import { DeleteChatModal } from "./DeleteChatModal";
import { EditChatModal } from "./EditChatModal";
import { MainLink } from "./MainLink";
import { notifications } from "@mantine/notifications";

export function ChatItem({ chat, isActive }: { chat: Chat, isActive: boolean }) {
const toggleChatPin = async (chatId: string, event: React.UIEvent) => {
try {
event.preventDefault();
await db.chats.where({ id: chatId }).modify((chat) => {
chat.pinned = !chat.pinned;
});
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
message: "No internet connection.",
});
}
const message = error.response?.data?.error?.message;
if (message) {
notifications.show({
title: "Error",
color: "red",
message,
});
}
}
};

return (
<Flex
key={chat.id}
className={isActive ? "active" : undefined}
sx={(theme) => ({
marginTop: 1,
"&:hover, &.active": {
backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.colors.gray[1],
},
})}
>
<Link to={`/chats/${chat.id}`} style={{ flex: 1 }}>
<MainLink
icon={chat.pinned ? <IconPinned size="1rem" /> : <IconMessages size="1rem" />}
color="teal"
chat={chat}
label={chat.description}
/>
</Link>
<Menu shadow="md" width={200} keepMounted>
<Menu.Target>
<ActionIcon sx={{ height: "auto" }}>
<IconDotsVertical size={20} />
</ActionIcon>
</Menu.Target>
<Menu.Dropdown>
<Menu.Item
icon={chat.pinned ? <IconPinnedOff size="1rem" /> : <IconPin size="1rem" />}
onClick={(event) => toggleChatPin(chat.id, event)}
>
{chat.pinned ? "Remove pin" : "Pin chat"}
</Menu.Item>
<EditChatModal chat={chat}>
<Menu.Item icon={<IconPencil size="1rem" />}>Edit</Menu.Item>
</EditChatModal>
<DeleteChatModal chat={chat}>
<Menu.Item color="red" icon={<IconTrash size="1rem" />}>
Delete
</Menu.Item>
</DeleteChatModal>
</Menu.Dropdown>
</Menu>
</Flex>
)
}
117 changes: 19 additions & 98 deletions src/components/Chats.tsx
Original file line number Diff line number Diff line change
@@ -1,22 1,9 @@
import { ActionIcon, Flex, Menu, Text } from "@mantine/core";
import {
IconDotsVertical,
IconMessages,
IconPencil,
IconPin,
IconPinned,
IconPinnedOff,
IconTrash
} from "@tabler/icons-react";
import { Link } from "@tanstack/react-location";
import { Text } from "@mantine/core";
import { useLiveQuery } from "dexie-react-hooks";
import { useMemo } from "react";
import { Chat, db } from "../db";
import { db } from "../db";
import { useChatId } from "../hooks/useChatId";
import { DeleteChatModal } from "./DeleteChatModal";
import { EditChatModal } from "./EditChatModal";
import { MainLink } from "./MainLink";
import { notifications } from "@mantine/notifications";
import { ChatItem } from "./ChatItem";

export function Chats({ search }: { search: string }) {
const chatId = useChatId();
Expand All @@ -32,91 19,25 @@ export function Chats({ search }: { search: string }) {
[chats, search]
);

const toggleChatPin = async (chatId: string, event: React.UIEvent) => {
try {
event.preventDefault();
await db.chats.where({ id: chatId }).modify((chat) => {
chat.pinned = !chat.pinned;
});
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
message: "No internet connection.",
});
}
const message = error.response?.data?.error?.message;
if (message) {
notifications.show({
title: "Error",
color: "red",
message,
});
}
}
};

const ChatItem = ({ chat }: { chat: Chat }) => (
<Flex
key={chat.id}
className={chatId === chat.id ? "active" : undefined}
sx={(theme) => ({
marginTop: 1,
"&:hover, &.active": {
backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.colors.gray[1],
},
})}
>
<Link to={`/chats/${chat.id}`} style={{ flex: 1 }}>
<MainLink
icon={chat.pinned ? <IconPinned size="1rem" /> : <IconMessages size="1rem" />}
color="teal"
chat={chat}
label={chat.description}
/>
</Link>
<Menu shadow="md" width={200} keepMounted>
<Menu.Target>
<ActionIcon sx={{ height: "auto" }}>
<IconDotsVertical size={20} />
</ActionIcon>
</Menu.Target>
<Menu.Dropdown>
<Menu.Item
icon={chat.pinned ? <IconPinnedOff size="1rem" /> : <IconPin size="1rem" />}
onClick={(event) => toggleChatPin(chat.id, event)}
>
{chat.pinned ? "Remove pin" : "Pin chat"}
</Menu.Item>
<EditChatModal chat={chat}>
<Menu.Item icon={<IconPencil size="1rem" />}>Edit</Menu.Item>
</EditChatModal>
<DeleteChatModal chat={chat}>
<Menu.Item color="red" icon={<IconTrash size="1rem" />}>
Delete
</Menu.Item>
</DeleteChatModal>
</Menu.Dropdown>
</Menu>
</Flex>
);
const pinnedChats = useMemo(() => filteredChats.filter((chat) => chat.pinned), [filteredChats]);
const unpinnedChats = useMemo(() => filteredChats.filter((chat) => !chat.pinned), [filteredChats]);

return (
<>
<Text p="xs" fz="xs" fw={700} color="gray" children={"Pinned"} />
{filteredChats
.filter((chat) => chat.pinned)
.map((chat) => (
<ChatItem chat={chat} />
))}
{pinnedChats.length > 0 ? (
<>
<Text p="xs" fz="xs" fw={700} color="gray" children={"Pinned"} />
{pinnedChats.map((chat) => (
<ChatItem chat={chat} isActive={chatId === chat.id} />
))}

<Text p="xs" fz="xs" fw={700} color="gray" children={"Unpinned"} />
{filteredChats
.filter((chat) => !chat.pinned)
.map((chat) => (
<ChatItem chat={chat} />
))}
{unpinnedChats.length > 0 ? <Text p="xs" fz="xs" fw={700} color="gray" children={"Unpinned"} /> : null}
</>
) : null}

{unpinnedChats.map((chat) => (
<ChatItem chat={chat} isActive={chatId === chat.id} />
))}
</>
);
)
}

0 comments on commit dfc8492

Please sign in to comment.