disable sharing

This commit is contained in:
BetaHuhn 2023-09-05 16:09:12 +02:00
parent f4dd6d38c5
commit 550a23af9b
4 changed files with 73 additions and 34 deletions

View file

@ -1,5 +1,5 @@
import { ActionIcon, Box, Flex, Header, TextInput, Tooltip, useMantineTheme } from "@mantine/core";
import { IconAdjustments, IconInfoCircle } from "@tabler/icons-react";
import { IconAdjustments, IconInfoCircle, IconShare2, IconWorld } from "@tabler/icons-react";
import { EditChatModal } from "./EditChatModal";
import { Chat, detaDB } from "../db";
import { useEffect, useRef, useState } from "react";
@ -93,7 +93,20 @@ export function ChatHeader({ readOnly = false }: { readOnly?: boolean}) {
},
})}
>
<ShareChatModal chat={chat!} />
<ShareChatModal chat={chat!} readOnly={readOnly}>
<Tooltip label={chat!.shared && !readOnly ? "Shared Chat" : "Share Chat"}>
<ActionIcon size="xl" loaderProps={{ size: 20 }} pos="relative">
{chat!.shared && !readOnly ? (
<>
<IconWorld size={20} />
<Box w={10} h={10} sx={(theme) => ({ background: theme.colors.blue[6], borderRadius: '100%' })} pos="absolute" top={8} right={8}></Box>
</>
) : (
<IconShare2 size={20} />
)}
</ActionIcon>
</Tooltip>
</ShareChatModal>
{!readOnly ? (
<>

View file

@ -1,5 +1,5 @@
import { ActionIcon, Flex, Menu, useMantineTheme } from "@mantine/core";
import { IconDotsVertical, IconMessages } from "@tabler/icons-react";
import { IconDotsVertical, IconMessages, IconWorld } from "@tabler/icons-react";
import { Link } from "@tanstack/react-location";
import { DeleteChatModal } from "./DeleteChatModal";
import { EditChatModal } from "./EditChatModal";
@ -7,6 +7,7 @@ import { MainLink } from "./MainLink";
import { useHover } from "@mantine/hooks";
import { Chat } from "../db";
import { useIncognitoMode } from "../hooks/contexts";
import { ShareChatModal } from "./ShareChatModal";
export function ChatItem({ chat, active = false }: { chat: Chat, active?: boolean }) {
const { hovered, ref } = useHover();
@ -18,6 +19,7 @@ export function ChatItem({ chat, active = false }: { chat: Chat, active?: boolea
ref={ref}
key={chat.key}
className={active ? "active" : undefined}
align='center'
sx={(theme) => ({
marginTop: 1,
"&:hover, &.active": {
@ -42,6 +44,12 @@ export function ChatItem({ chat, active = false }: { chat: Chat, active?: boolea
label={chat.description}
/>
</Link>
{chat.shared && !hovered && (
<ActionIcon mr={5}>
<IconWorld size={18} />
</ActionIcon>
)}
<Menu shadow="md" width={200} keepMounted>
{hovered && (
@ -52,6 +60,11 @@ export function ChatItem({ chat, active = false }: { chat: Chat, active?: boolea
</Menu.Target>
)}
<Menu.Dropdown>
{chat.shared && (
<ShareChatModal chat={chat}>
<Menu.Item>Share</Menu.Item>
</ShareChatModal>
)}
<EditChatModal chat={chat}>
<Menu.Item>Edit</Menu.Item>
</EditChatModal>

View file

@ -1,24 +1,28 @@
import { ActionIcon, Button, Input, Modal, Stack, Text, Tooltip } from "@mantine/core";
import { Button, Input, Modal, Stack, Text } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { notifications } from "@mantine/notifications";
import { IconShare2 } from "@tabler/icons-react";
import { useState } from "react";
import { ReactElement, cloneElement, useState } from "react";
import { Chat, detaDB } from "../db";
import { useChat } from "../hooks/contexts";
import { useChat, useChats } from "../hooks/contexts";
export function ShareChatModal({ chat }: { chat: Chat }) {
export function ShareChatModal({ children, chat, readOnly }: { children: ReactElement, chat: Chat, readOnly?: boolean }) {
const [opened, { open, close }] = useDisclosure(false);
const [submitting, setSubmitting] = useState(false);
const [url, setUrl] = useState<string | null>(null);
const { setChat } = useChat()
const { setChats } = useChats()
const handleClick = async () => {
if (!chat.shared) {
setSubmitting(true)
await detaDB.chats.update({ shared: true }, chat.key)
setChat(current => ({ ...(current as unknown as Chat), shared: true }))
setSubmitting(false)
setChats(current => (current || []).map(item => {
if (item.key === chat.key) {
return { ...item, shared: true };
}
return item;
}))
notifications.show({
title: "Shared!",
@ -43,23 +47,45 @@ export function ShareChatModal({ chat }: { chat: Chat }) {
close()
}
const handleDisable = async () => {
await detaDB.chats.update({ shared: false }, chat.key)
setChat(current => ({ ...(current as unknown as Chat), shared: false }))
setChats(current => (current || []).map(item => {
if (item.key === chat.key) {
return { ...item, shared: false };
}
return item;
}))
notifications.show({
title: "Disabled!",
color: "green",
message: "Chat is now private.",
})
close()
}
return (
<>
<Modal opened={opened} onClose={close} title="Share Chat" size="md">
{cloneElement(children, { onClick: handleClick })}
<Modal opened={opened} onClose={close} title={chat.shared && !readOnly ? "Shared Chat" : "Share Chat"} size="md">
<Stack>
<Text size="sm">Use this URL to share this chat with others:</Text>
<Input readOnly value={url ?? ''} />
<Button type="submit" onClick={handleCopy}>
Copy URL
</Button>
<Stack spacing="xs">
<Button type="submit" onClick={handleCopy}>
Copy URL
</Button>
{!readOnly && (
<Button variant="light" color="red" onClick={handleDisable}>
Disable Sharing
</Button>
)}
</Stack>
</Stack>
</Modal>
<Tooltip label="Share Chat">
<ActionIcon size="xl" onClick={handleClick} loading={submitting} loaderProps={{ size: 20 }}>
<IconShare2 size={20} />
</ActionIcon>
</Tooltip>
</>
);
}

View file

@ -1,11 +1,7 @@
import {
AppShell,
Burger,
MediaQuery,
useMantineColorScheme,
useMantineTheme,
} from "@mantine/core";
import { useRouter } from "@tanstack/react-location";
import { useEffect, useState } from "react";
import { Chat } from "../db";
import { usePublicChatId } from "../hooks/useChatId";
@ -14,14 +10,9 @@ import { ChatHeader } from "../components/ChatHeader";
import { useLocalStorage } from "@mantine/hooks";
export function PublicLayout({ children }: { children: React.ReactNode }) {
const theme = useMantineTheme();
const router = useRouter();
const { colorScheme } = useMantineColorScheme();
const chatId = usePublicChatId();
const [opened, setOpened] = useState(false);
const [incognitoMode, setIncognitoMode] = useLocalStorage({
key: 'incognito-mode', defaultValue: false, getInitialValueInEffect: false
});
@ -49,10 +40,6 @@ export function PublicLayout({ children }: { children: React.ReactNode }) {
}
}, [chatId]);
useEffect(() => {
setOpened(false);
}, [router.state.location]);
return (
<ChatContext.Provider value={{ chat: chat, setChat: setChat }}>
<IncognitoModeContext.Provider value={{ incognitoMode: incognitoMode, setIncognitoMode: setIncognitoMode }}>