Skip to content

Commit

Permalink
feat(message-settings): add copy, show raw code, delete message btns
Browse files Browse the repository at this point in the history
  • Loading branch information
yzh990918 committed May 6, 2023
1 parent cbd8da0 commit 441023a
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/components/Main.astro
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Conversation from './main/Conversation'
<main class="flex-1 mt-14 flex flex-col overflow-hidden">
<!-- <ConversationConfiguration /> -->
<div class="flex-1 relative overflow-hidden">
<Conversation client:only />
<Conversation client:load />
</div>
</main>
<Send client:load />
Expand Down
5 changes: 3 additions & 2 deletions src/components/Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'katex/dist/katex.min.css'
interface Props {
class?: string
text: string
showRawCode?: boolean
}

const parseMarkdown = (raw: string) => {
Expand All @@ -27,11 +28,11 @@ const parseMarkdown = (raw: string) => {
}

export default (props: Props) => {
const htmlString = () => parseMarkdown(props.text)
const htmlString = () => props.showRawCode ? props.text : parseMarkdown(props.text)

return (
<div
class={props.class ?? ''}
class={`${props.class ?? ''} ${props.showRawCode ? 'whitespace-pre-wrap overflow-auto my-0' : ''}`}
innerHTML={htmlString()}
/>
)
Expand Down
2 changes: 2 additions & 0 deletions src/components/StreamableText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Markdown from './Markdown'
interface Props {
class?: string
text: string
showRawCode?: boolean
streamInfo?: () => {
conversationId: string
messageId: string
Expand Down Expand Up @@ -47,6 +48,7 @@ export default (props: Props) => {
<Markdown
class={`prose prose-neutral dark:prose-invert fg-base! max-w-3xl -my-4 ${props.class ?? ''}`}
text={localText()}
showRawCode={props.showRawCode}
/>
)
}
46 changes: 34 additions & 12 deletions src/components/main/MessageItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { For } from 'solid-js/web'
import { createSignal } from 'solid-js'
import { useClipboardCopy } from '@/hooks'
import { deleteMessageByConversationId } from '@/stores/messages'
import StreamableText from '../StreamableText'
import { DropDownMenu, Tooltip } from '../ui/base'
import { Tooltip } from '../ui/base'
import type { MenuItem } from '../ui/base'
import type { MessageInstance } from '@/types/message'

Expand All @@ -18,18 +21,29 @@ export default (props: Props) => {
assistant: 'bg-gradient-to-b from-[#fccb90] to-[#d57eeb]',
}

const handleCopyMessage = () => {
const [copied, copy] = useClipboardCopy(props.message.content)
const [showRawCode, setShowRawCode] = createSignal(false)

const handleDeleteMessageItem = () => {
deleteMessageByConversationId(props.conversationId, props.message)
}

const menuList: MenuItem[] = [
{ id: 'retry', label: 'Retry message', icon: 'i-ion:refresh-outline' },
{ id: 'show', label: 'Show raw code', icon: 'i-carbon-code' },
{ id: 'share', label: 'Share message', icon: 'i-ion:ios-share-alt' },
{ id: 'edit', label: 'Edit message', icon: 'i-ion:md-create' },
{ id: 'copy', label: 'Copy message', icon: 'i-carbon-copy' },
{ id: 'delete', label: 'Delete message', icon: 'i-carbon-trash-can' },
]
const [menuList, setMenuList] = createSignal<MenuItem[]>([
// TODO: Retry send message
// { id: 'retry', label: 'Retry send', icon: 'i-ion:refresh-outline', role: 'all' },
{ id: 'raw', label: 'Show raw code', icon: 'i-carbon-code', role: 'system', action: () => setShowRawCode(!showRawCode()) },
// TODO: Share message
// { id: 'share', label: 'Share message', icon: 'i-ion:ios-share-alt' },
// TODO: Edit message
// { id: 'edit', label: 'Edit message', icon: 'i-ion:md-create', role: 'user' },
{ id: 'copy', label: 'Copy message', icon: 'i-carbon-copy', role: 'all', action: copy },
{ id: 'delete', label: 'Delete message', icon: 'i-carbon-trash-can', role: 'all', action: handleDeleteMessageItem },
])

if (props.message.role === 'user')
setMenuList(menuList().filter(item => ['all', 'user'].includes(item.role!)))
else
setMenuList(menuList().filter(item => ['all', 'system'].includes(item.role!)))

return (
<div
Expand All @@ -48,8 +62,15 @@ export default (props: Props) => {
</div>
<div class={`hidden sm:block absolute right-6 -top-4 ${!props.index && 'top-0'}`}>
<div class="op-0 group-hover:op-80 fcc space-x-2 !bg-base px-4 py-1 rounded-xl b border-base transition-opacity duration-400">
<For each={menuList}>
{item => (<Tooltip tip={item.label}><div class={`${item.icon} menu-icon`} /></Tooltip>)}
<For each={menuList()}>
{item => (
<Tooltip tip={item.label} handleChildClick={item.action}>
{
item.id === 'copy'
? <div class={`menu-icon ${copied() ? 'i-carbon-checkmark !text-emerald-400' : 'i-carbon-copy'}`} />
: <div class={`${item.icon} menu-icon`} />
}
</Tooltip>)}
</For>
</div>
</div>
Expand All @@ -63,6 +84,7 @@ export default (props: Props) => {
handleStreaming: props.handleStreaming,
})
: undefined}
showRawCode={showRawCode()}
/>
</div>

Expand Down
2 changes: 2 additions & 0 deletions src/components/ui/base/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export interface MenuItem {
icon?: string
// TODO: nested menu
children?: MenuItem[]
role?: string
action?: (params?: any) => void
}

interface Props {
Expand Down
5 changes: 3 additions & 2 deletions src/components/ui/base/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface Props {
children: JSX.Element
openDelay?: number
closeDelay?: number
handleChildClick?: () => void
placement?: 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end' | 'right-start' | 'right-end'
}

Expand All @@ -30,9 +31,9 @@ export const Tooltip = (props: Props) => {
const resolvedChild = () => {
const child = children(() => props.children)
createEffect(() => {
spread(child() as Element, { ...api().triggerProps })
spread(child() as Element, { ...api().triggerProps, onClick: props.handleChildClick })
})
return child
return child()
}

return (
Expand Down
13 changes: 13 additions & 0 deletions src/stores/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,16 @@ export const clearMessagesByConversationId = action(
})
},
)

export const deleteMessageByConversationId = action(
conversationMessagesMap,
'deleteMessageByConversationId',
(map, id: string, payload: MessageInstance) => {
const oldMessages = map.get()[id] || []
map.setKey(id, [...oldMessages.filter(message => message.id !== payload.id)])
db.setItem(id, [...oldMessages.filter(message => message.id !== payload.id)])
updateConversationById(id, {
lastUseTime: Date.now(),
})
},
)

0 comments on commit 441023a

Please sign in to comment.