mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-04-26 17:06:23 +02:00
remove faulty undo/redo and replaced with back/forward buttons
This commit is contained in:
parent
4d2fc01f88
commit
d05344861a
3 changed files with 97 additions and 17 deletions
|
|
@ -382,6 +382,8 @@ function ChatInputWithMentions({
|
|||
function App() {
|
||||
// File browser state (for Knowledge section)
|
||||
const [selectedPath, setSelectedPath] = useState<string | null>(null)
|
||||
const [fileHistoryBack, setFileHistoryBack] = useState<string[]>([])
|
||||
const [fileHistoryForward, setFileHistoryForward] = useState<string[]>([])
|
||||
const [fileContent, setFileContent] = useState<string>('')
|
||||
const [editorContent, setEditorContent] = useState<string>('')
|
||||
const [tree, setTree] = useState<TreeNode[]>([])
|
||||
|
|
@ -1075,6 +1077,52 @@ function App() {
|
|||
setIsGraphOpen(false)
|
||||
}, [])
|
||||
|
||||
// File navigation with history tracking
|
||||
const navigateToFile = useCallback((path: string | null) => {
|
||||
if (path === selectedPath) return
|
||||
|
||||
// Push current path to back history (if we have one)
|
||||
if (selectedPath) {
|
||||
setFileHistoryBack(prev => [...prev, selectedPath])
|
||||
}
|
||||
// Clear forward history when navigating to a new file
|
||||
setFileHistoryForward([])
|
||||
setSelectedPath(path)
|
||||
}, [selectedPath])
|
||||
|
||||
const navigateBack = useCallback(() => {
|
||||
if (fileHistoryBack.length === 0) return
|
||||
|
||||
const newBack = [...fileHistoryBack]
|
||||
const previousPath = newBack.pop()!
|
||||
|
||||
// Push current path to forward history
|
||||
if (selectedPath) {
|
||||
setFileHistoryForward(prev => [...prev, selectedPath])
|
||||
}
|
||||
|
||||
setFileHistoryBack(newBack)
|
||||
setSelectedPath(previousPath)
|
||||
}, [fileHistoryBack, selectedPath])
|
||||
|
||||
const navigateForward = useCallback(() => {
|
||||
if (fileHistoryForward.length === 0) return
|
||||
|
||||
const newForward = [...fileHistoryForward]
|
||||
const nextPath = newForward.pop()!
|
||||
|
||||
// Push current path to back history
|
||||
if (selectedPath) {
|
||||
setFileHistoryBack(prev => [...prev, selectedPath])
|
||||
}
|
||||
|
||||
setFileHistoryForward(newForward)
|
||||
setSelectedPath(nextPath)
|
||||
}, [fileHistoryForward, selectedPath])
|
||||
|
||||
const canNavigateBack = fileHistoryBack.length > 0
|
||||
const canNavigateForward = fileHistoryForward.length > 0
|
||||
|
||||
// Handle image upload for the markdown editor
|
||||
const handleImageUpload = useCallback(async (file: File): Promise<string | null> => {
|
||||
try {
|
||||
|
|
@ -1128,7 +1176,7 @@ function App() {
|
|||
|
||||
const toggleExpand = (path: string, kind: 'file' | 'dir') => {
|
||||
if (kind === 'file') {
|
||||
setSelectedPath(path)
|
||||
navigateToFile(path)
|
||||
setIsGraphOpen(false)
|
||||
return
|
||||
}
|
||||
|
|
@ -1312,9 +1360,9 @@ function App() {
|
|||
const openWikiLink = useCallback(async (wikiPath: string) => {
|
||||
const resolvedPath = await ensureWikiFile(wikiPath)
|
||||
if (resolvedPath) {
|
||||
setSelectedPath(resolvedPath)
|
||||
navigateToFile(resolvedPath)
|
||||
}
|
||||
}, [ensureWikiFile, setSelectedPath])
|
||||
}, [ensureWikiFile, navigateToFile])
|
||||
|
||||
const wikiLinkConfig = React.useMemo(() => ({
|
||||
files: knowledgeFiles,
|
||||
|
|
@ -1616,7 +1664,7 @@ function App() {
|
|||
error={graphStatus === 'error' ? (graphError ?? 'Failed to build graph') : null}
|
||||
onSelectNode={(path) => {
|
||||
setIsGraphOpen(false)
|
||||
setSelectedPath(path)
|
||||
navigateToFile(path)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -1629,6 +1677,10 @@ function App() {
|
|||
placeholder="Start writing..."
|
||||
wikiLinks={wikiLinkConfig}
|
||||
onImageUpload={handleImageUpload}
|
||||
onNavigateBack={navigateBack}
|
||||
onNavigateForward={navigateForward}
|
||||
canNavigateBack={canNavigateBack}
|
||||
canNavigateForward={canNavigateForward}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ import {
|
|||
MinusIcon,
|
||||
LinkIcon,
|
||||
CodeSquareIcon,
|
||||
Undo2Icon,
|
||||
Redo2Icon,
|
||||
ChevronLeftIcon,
|
||||
ChevronRightIcon,
|
||||
ExternalLinkIcon,
|
||||
Trash2Icon,
|
||||
ImageIcon,
|
||||
|
|
@ -33,9 +33,21 @@ interface EditorToolbarProps {
|
|||
editor: Editor | null
|
||||
onSelectionHighlight?: (range: { from: number; to: number } | null) => void
|
||||
onImageUpload?: (file: File) => Promise<void> | void
|
||||
onNavigateBack?: () => void
|
||||
onNavigateForward?: () => void
|
||||
canNavigateBack?: boolean
|
||||
canNavigateForward?: boolean
|
||||
}
|
||||
|
||||
export function EditorToolbar({ editor, onSelectionHighlight, onImageUpload }: EditorToolbarProps) {
|
||||
export function EditorToolbar({
|
||||
editor,
|
||||
onSelectionHighlight,
|
||||
onImageUpload,
|
||||
onNavigateBack,
|
||||
onNavigateForward,
|
||||
canNavigateBack,
|
||||
canNavigateForward,
|
||||
}: EditorToolbarProps) {
|
||||
const [linkUrl, setLinkUrl] = useState('')
|
||||
const [isLinkPopoverOpen, setIsLinkPopoverOpen] = useState(false)
|
||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
|
|
@ -105,24 +117,24 @@ export function EditorToolbar({ editor, onSelectionHighlight, onImageUpload }: E
|
|||
|
||||
return (
|
||||
<div className="editor-toolbar">
|
||||
{/* Undo / Redo */}
|
||||
{/* Back / Forward Navigation */}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
onClick={() => editor.chain().focus().undo().run()}
|
||||
disabled={!editor.can().undo()}
|
||||
title="Undo (Ctrl+Z)"
|
||||
onClick={onNavigateBack}
|
||||
disabled={!canNavigateBack}
|
||||
title="Go back"
|
||||
>
|
||||
<Undo2Icon className="size-4" />
|
||||
<ChevronLeftIcon className="size-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
onClick={() => editor.chain().focus().redo().run()}
|
||||
disabled={!editor.can().redo()}
|
||||
title="Redo (Ctrl+Shift+Z)"
|
||||
onClick={onNavigateForward}
|
||||
disabled={!canNavigateForward}
|
||||
title="Go forward"
|
||||
>
|
||||
<Redo2Icon className="size-4" />
|
||||
<ChevronRightIcon className="size-4" />
|
||||
</Button>
|
||||
|
||||
<div className="separator" />
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ interface MarkdownEditorProps {
|
|||
placeholder?: string
|
||||
wikiLinks?: WikiLinkConfig
|
||||
onImageUpload?: (file: File) => Promise<string | null>
|
||||
onNavigateBack?: () => void
|
||||
onNavigateForward?: () => void
|
||||
canNavigateBack?: boolean
|
||||
canNavigateForward?: boolean
|
||||
}
|
||||
|
||||
type WikiLinkMatch = {
|
||||
|
|
@ -78,6 +82,10 @@ export function MarkdownEditor({
|
|||
placeholder = 'Start writing...',
|
||||
wikiLinks,
|
||||
onImageUpload,
|
||||
onNavigateBack,
|
||||
onNavigateForward,
|
||||
canNavigateBack,
|
||||
canNavigateForward,
|
||||
}: MarkdownEditorProps) {
|
||||
const isInternalUpdate = useRef(false)
|
||||
const wrapperRef = useRef<HTMLDivElement>(null)
|
||||
|
|
@ -318,7 +326,15 @@ export function MarkdownEditor({
|
|||
|
||||
return (
|
||||
<div className="tiptap-editor" onKeyDown={handleKeyDown}>
|
||||
<EditorToolbar editor={editor} onSelectionHighlight={setSelectionHighlight} onImageUpload={handleImageUploadWithPlaceholder} />
|
||||
<EditorToolbar
|
||||
editor={editor}
|
||||
onSelectionHighlight={setSelectionHighlight}
|
||||
onImageUpload={handleImageUploadWithPlaceholder}
|
||||
onNavigateBack={onNavigateBack}
|
||||
onNavigateForward={onNavigateForward}
|
||||
canNavigateBack={canNavigateBack}
|
||||
canNavigateForward={canNavigateForward}
|
||||
/>
|
||||
<div className="editor-content-wrapper" ref={wrapperRef} onScroll={handleScroll}>
|
||||
<EditorContent editor={editor} />
|
||||
{wikiLinks ? (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue