-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #132 from miurla/share
Enable sharing of search results
- Loading branch information
Showing
11 changed files
with
225 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { notFound } from 'next/navigation' | ||
import { Chat } from '@/components/chat' | ||
import { getSharedChat } from '@/lib/actions/chat' | ||
import { AI } from '@/app/actions' | ||
|
||
export interface SharePageProps { | ||
params: { | ||
id: string | ||
} | ||
} | ||
|
||
export async function generateMetadata({ params }: SharePageProps) { | ||
const chat = await getSharedChat(params.id) | ||
|
||
if (!chat || !chat.sharePath) { | ||
return notFound() | ||
} | ||
|
||
return { | ||
title: chat?.title.toString().slice(0, 50) || 'Search' | ||
} | ||
} | ||
|
||
export default async function SharePage({ params }: SharePageProps) { | ||
const chat = await getSharedChat(params.id) | ||
|
||
if (!chat || !chat.sharePath) { | ||
notFound() | ||
} | ||
|
||
return ( | ||
<AI | ||
initialAIState={{ | ||
chatId: chat.id, | ||
messages: chat.messages, | ||
isSharePage: true | ||
}} | ||
> | ||
<Chat id={params.id} /> | ||
</AI> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
'use client' | ||
|
||
import { useState, useTransition } from 'react' | ||
import { Button } from './ui/button' | ||
import { Share } from 'lucide-react' | ||
import { | ||
Dialog, | ||
DialogContent, | ||
DialogFooter, | ||
DialogHeader, | ||
DialogTrigger, | ||
DialogDescription, | ||
DialogTitle | ||
} from './ui/dialog' | ||
import { shareChat } from '@/lib/actions/chat' | ||
import { toast } from 'sonner' | ||
import { useCopyToClipboard } from '@/lib/hooks/use-copy-to-clipboard' | ||
import { Spinner } from './ui/spinner' | ||
|
||
interface ChatShareProps { | ||
chatId: string | ||
className?: string | ||
} | ||
|
||
export function ChatShare({ chatId, className }: ChatShareProps) { | ||
const [open, setOpen] = useState(false) | ||
const [pending, startTransition] = useTransition() | ||
const { copyToClipboard } = useCopyToClipboard({ timeout: 1000 }) | ||
|
||
const handleClick = async () => { | ||
startTransition(async () => { | ||
const result = await shareChat(chatId) | ||
if (!result) { | ||
toast.error('Failed to share chat') | ||
} | ||
|
||
if (!result?.sharePath) { | ||
toast.error('Could not copy link to clipboard') | ||
return | ||
} | ||
|
||
const url = new URL(result.sharePath, window.location.origin) | ||
copyToClipboard(url.toString()) | ||
toast.success('Link copied to clipboard') | ||
setOpen(false) | ||
}) | ||
} | ||
|
||
return ( | ||
<div className={className}> | ||
<Dialog | ||
open={open} | ||
onOpenChange={open => setOpen(open)} | ||
aria-labelledby="share-dialog-title" | ||
aria-describedby="share-dialog-description" | ||
> | ||
<DialogTrigger asChild> | ||
<Button | ||
className="rounded-full" | ||
size="icon" | ||
variant={'ghost'} | ||
onClick={() => setOpen(true)} | ||
> | ||
<Share size={14} /> | ||
</Button> | ||
</DialogTrigger> | ||
<DialogContent> | ||
<DialogHeader> | ||
<DialogTitle>Share link to search result</DialogTitle> | ||
<DialogDescription> | ||
Anyone with the link will be able to view this search result. | ||
</DialogDescription> | ||
</DialogHeader> | ||
<DialogFooter className="items-center"> | ||
<Button onClick={handleClick} disabled={pending} size="sm"> | ||
{pending ? <Spinner /> : 'Copy link'} | ||
</Button> | ||
</DialogFooter> | ||
</DialogContent> | ||
</Dialog> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,21 @@ | ||
import React from 'react' | ||
import { ChatShare } from './chat-share' | ||
|
||
type UserMessageProps = { | ||
message: string | ||
chatId?: string | ||
showShare?: boolean | ||
} | ||
|
||
export const UserMessage: React.FC<UserMessageProps> = ({ message }) => { | ||
export const UserMessage: React.FC<UserMessageProps> = ({ | ||
message, | ||
chatId, | ||
showShare = false | ||
}) => { | ||
return ( | ||
<div className="mt-6"> | ||
<div className="text-xl">{message}</div> | ||
<div className="flex items-center w-full space-x-1 mt-2 min-h-10"> | ||
<div className="text-xl flex-1">{message}</div> | ||
{showShare && chatId && <ChatShare chatId={chatId} />} | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
'use client' | ||
|
||
import { useState } from 'react' | ||
|
||
export interface useCopyToClipboardProps { | ||
timeout?: number | ||
} | ||
|
||
export function useCopyToClipboard({ | ||
timeout = 2000 | ||
}: useCopyToClipboardProps) { | ||
const [isCopied, setIsCopied] = useState<Boolean>(false) | ||
|
||
const copyToClipboard = (value: string) => { | ||
if (typeof window === 'undefined' || !navigator.clipboard?.writeText) { | ||
return | ||
} | ||
|
||
if (!value) { | ||
return | ||
} | ||
|
||
navigator.clipboard.writeText(value).then(() => { | ||
setIsCopied(true) | ||
|
||
setTimeout(() => { | ||
setIsCopied(false) | ||
}, timeout) | ||
}) | ||
} | ||
|
||
return { isCopied, copyToClipboard } | ||
} |