feat: flux to logos

This commit is contained in:
2026-03-15 23:41:10 +01:00
parent 45c387c9e6
commit f67c491deb
6 changed files with 289 additions and 7 deletions

View File

@@ -5,11 +5,13 @@
import React, { useCallback, useEffect, useMemo, useRef, useState, forwardRef } from 'react'
import { useParams } from 'react-router-dom'
import { useCreateBlockNote } from '@blocknote/react'
import { FluxIcon } from '@/lib/icons'
import { useCreateBlockNote, getDefaultReactSlashMenuItems, SuggestionMenuController } from '@blocknote/react'
import { BlockNoteView } from '@blocknote/shadcn'
import { useTheme } from '@/lib/themeContext'
import { useRecollectionActions } from '../RecollectionActionsContext'
import { getLogosContent, setLogosContent, type StoredLogosContent } from '../recollectionStore'
import { logosSchema } from './logosSchema'
import { toast } from 'sonner'
/** Wraps BlockNoteView so refs go to a div, not the function component (avoids ref warning). */
@@ -58,7 +60,10 @@ export function LogosPage() {
[recollectionId, reloadKey]
)
const editor = useCreateBlockNote({ initialContent }, [recollectionId, reloadKey])
const editor = useCreateBlockNote(
{ schema: logosSchema, initialContent },
[recollectionId, reloadKey]
)
const persistContent = useCallback(() => {
if (!recollectionId || !editor) return
@@ -137,14 +142,43 @@ export function LogosPage() {
patchBlockNoteRefWarning()
const getSlashMenuItems = useCallback(
async (query: string) => {
const defaultItems = getDefaultReactSlashMenuItems(editor)
const fluxItem = {
title: 'Insert from Flux',
subtext: 'Insert output from a Flux rendering node',
icon: <FluxIcon className="size-4" />,
onItemClick: () => {
const pos = editor.getTextCursorPosition()
editor.replaceBlocks([pos.block.id], [{ type: 'fluxOutput', props: {} }])
},
aliases: ['flux', 'output', 'render'] as const,
group: 'Flux',
}
const all = [...defaultItems, fluxItem]
const q = query.trim().toLowerCase()
if (!q) return all
return all.filter(
(item) =>
item.title.toLowerCase().includes(q) ||
(item.aliases && item.aliases.some((a: string) => a.toLowerCase().includes(q)))
)
},
[editor]
)
return (
<div className="flex h-full min-h-0 flex-1 flex-col overflow-auto bg-background">
<div className="mx-auto w-full max-w-3xl p-4">
<BlockNoteViewWrapper
editor={editor}
editor={editor as any}
theme={theme}
className="min-h-full w-full"
/>
slashMenu={false}
>
<SuggestionMenuController triggerCharacter="/" getItems={getSlashMenuItems} />
</BlockNoteViewWrapper>
</div>
</div>
)