Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: handle long thread title without space #3107

Merged
merged 2 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions web/containers/ModelDropdown/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, useMemo, useEffect, useCallback } from 'react'
import { useState, useMemo, useEffect, useCallback, useRef } from 'react'

import { InferenceEngine } from '@janhq/core'
import { Badge, Input, ScrollArea, Select, useClickOutside } from '@janhq/joi'
Expand Down Expand Up @@ -70,7 +70,7 @@ const ModelDropdown = ({
const downloadStates = useAtomValue(modelDownloadStateAtom)
const setThreadModelParams = useSetAtom(setThreadModelParamsAtom)
const { updateModelParameter } = useUpdateModelParameters()

const searchInputRef = useRef<HTMLInputElement>(null)
const configuredModels = useAtomValue(configuredModelsAtom)
const featuredModel = configuredModels.filter((x) =>
x.metadata.tags.includes('Featured')
Expand Down Expand Up @@ -108,6 +108,12 @@ const ModelDropdown = ({
[configuredModels, searchText, searchFilter]
)

useEffect(() => {
if (open && searchInputRef.current) {
searchInputRef.current.focus()
}
}, [open])

useEffect(() => {
if (!activeThread) return
let model = downloadedModels.find(
Expand Down Expand Up @@ -258,6 +264,7 @@ const ModelDropdown = ({
<Input
placeholder="Search"
value={searchText}
ref={searchInputRef}
className="rounded-none border-x-0 border-t-0 focus-within:ring-0 hover:border-b-[hsla(var(--app-border))]"
onChange={(e) => setSearchText(e.target.value)}
suffixIcon={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import useDeleteThread from '@/hooks/useDeleteThread'

type Props = {
threadId: string
closeContextMenu?: () => void
}

const ModalCleanThread = ({ threadId }: Props) => {
const ModalCleanThread = ({ threadId, closeContextMenu }: Props) => {
const { cleanThread } = useDeleteThread()
const onCleanThreadClick = useCallback(
(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
Expand All @@ -22,6 +23,11 @@ const ModalCleanThread = ({ threadId }: Props) => {
return (
<Modal
title="Clean Thread"
onOpenChange={(open) => {
if (open && closeContextMenu) {
closeContextMenu()
}
}}
trigger={
<div
className="flex cursor-pointer items-center space-x-2 px-4 py-2 hover:bg-[hsla(var(--dropdown-menu-hover-bg))]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import useDeleteThread from '@/hooks/useDeleteThread'

type Props = {
threadId: string
closeContextMenu?: () => void
}

const ModalDeleteThread = ({ threadId }: Props) => {
const ModalDeleteThread = ({ threadId, closeContextMenu }: Props) => {
const { deleteThread } = useDeleteThread()

const onDeleteThreadClick = useCallback(
(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.stopPropagation()
Expand All @@ -22,6 +24,11 @@ const ModalDeleteThread = ({ threadId }: Props) => {
return (
<Modal
title="Delete Thread"
onOpenChange={(open) => {
if (open && closeContextMenu) {
closeContextMenu()
}
}}
trigger={
<div
className="flex cursor-pointer items-center space-x-2 px-4 py-2 hover:bg-[hsla(var(--dropdown-menu-hover-bg))]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import { useCreateNewThread } from '@/hooks/useCreateNewThread'

type Props = {
thread: Thread
closeContextMenu?: () => void
}

const ModalEditTitleThread = ({ thread }: Props) => {
const ModalEditTitleThread = ({ thread, closeContextMenu }: Props) => {
const [title, setTitle] = useState(thread.title)

const { updateThreadMetadata } = useCreateNewThread()
Expand All @@ -30,6 +31,11 @@ const ModalEditTitleThread = ({ thread }: Props) => {
return (
<Modal
title="Edit title thread"
onOpenChange={(open) => {
if (open && closeContextMenu) {
closeContextMenu()
}
}}
trigger={
<div
className="flex cursor-pointer items-center space-x-2 px-4 py-2 hover:bg-[hsla(var(--dropdown-menu-hover-bg))]"
Expand Down
53 changes: 47 additions & 6 deletions web/screens/Thread/ThreadLeftPanel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useEffect } from 'react'
import { useCallback, useEffect, useState } from 'react'

import { Thread } from '@janhq/core'

Expand Down Expand Up @@ -43,6 +43,14 @@ const ThreadLeftPanel = () => {
const setEditMessage = useSetAtom(editMessageAtom)
const { recommendedModel, downloadedModels } = useRecommendedModel()

const [contextMenu, setContextMenu] = useState<{
visible: boolean
thread?: Thread
}>({
visible: false,
thread: undefined,
})

const onThreadClick = useCallback(
(thread: Thread) => {
setActiveThread(thread)
Expand Down Expand Up @@ -91,6 +99,21 @@ const ThreadLeftPanel = () => {
}
}

const onContextMenu = (event: React.MouseEvent, thread: Thread) => {
event.preventDefault()
setContextMenu({
visible: true,
thread,
})
}

const closeContextMenu = () => {
setContextMenu({
visible: false,
thread: undefined,
})
}

return (
<LeftPanelContainer>
{threads.length === 0 ? (
Expand Down Expand Up @@ -124,8 +147,10 @@ const ThreadLeftPanel = () => {
onClick={() => {
onThreadClick(thread)
}}
onContextMenu={(e) => onContextMenu(e, thread)}
onMouseLeave={closeContextMenu}
>
<div className="relative z-10 p-2">
<div className="relative z-10 break-all p-2">
<h1
className={twMerge(
'line-clamp-1 pr-2 font-medium group-hover/message:pr-6',
Expand All @@ -143,10 +168,26 @@ const ThreadLeftPanel = () => {
<Button theme="icon" className="mt-2">
<MoreHorizontalIcon />
</Button>
<div className="invisible absolute -right-1 z-50 w-40 overflow-hidden rounded-lg border border-[hsla(var(--app-border))] bg-[hsla(var(--app-bg))] shadow-lg group-hover/icon:visible">
<ModalEditTitleThread thread={thread} />
<ModalCleanThread threadId={thread.id} />
<ModalDeleteThread threadId={thread.id} />
<div
className={twMerge(
'invisible absolute -right-1 z-50 w-40 overflow-hidden rounded-lg border border-[hsla(var(--app-border))] bg-[hsla(var(--app-bg))] shadow-lg group-hover/icon:visible',
contextMenu.visible &&
contextMenu.thread?.id === thread.id &&
'visible'
)}
>
<ModalEditTitleThread
thread={thread}
closeContextMenu={closeContextMenu}
/>
<ModalCleanThread
threadId={thread.id}
closeContextMenu={closeContextMenu}
/>
<ModalDeleteThread
threadId={thread.id}
closeContextMenu={closeContextMenu}
/>
</div>
</div>
{activeThreadId === thread.id && (
Expand Down
2 changes: 1 addition & 1 deletion web/screens/Thread/ThreadRightPanel/Tools/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ const Tools = () => {
<div className="mb-2 flex items-center">
<label
id="vector-database"
className="inline-block font-medium"
className="inline-flex items-center font-medium"
>
Vector Database
<Tooltip
Expand Down
Loading