import { ChevronDown, ChevronRight, Plus, Trash2, Undo2 } from 'lucide-react'; import { getLanguage } from 'obsidian'; import React, { useEffect, useMemo, useState } from 'react'; import { PREVIEW_VIEW_TYPE } from '../../constants'; import { useApp } from '../../contexts/AppContext'; import { useDiffStrategy } from '../../contexts/DiffStrategyContext'; import { useRAG } from '../../contexts/RAGContext'; import { useSettings } from '../../contexts/SettingsContext'; import { CustomMode, GroupEntry, ToolGroup } from '../../database/json/custom-mode/types'; import { useCustomModes } from '../../hooks/use-custom-mode'; import { t } from '../../lang/helpers'; import { PreviewView, PreviewViewState } from '../../PreviewView'; import { defaultModes as buildinModes } from '../../utils/modes'; import { openOrCreateMarkdownFile } from '../../utils/obsidian'; import { PromptGenerator, getFullLanguageName } from '../../utils/prompt-generator'; const CustomModeView = () => { const app = useApp() const { createCustomMode, deleteCustomMode, updateCustomMode, customModeList, customModePrompts } = useCustomModes() const { settings } = useSettings() const { getRAGEngine } = useRAG() const diffStrategy = useDiffStrategy() const promptGenerator = useMemo(() => { // @ts-expect-error PromptGenerator constructor parameter types need to be reviewed return new PromptGenerator(getRAGEngine, app, settings, diffStrategy, customModePrompts, customModeList) }, [app, settings, diffStrategy, customModePrompts, customModeList]) // Currently selected mode const [selectedMode, setSelectedMode] = useState('ask') const [isBuiltinMode, setIsBuiltinMode] = useState(true) const [isAdvancedCollapsed, setIsAdvancedCollapsed] = useState(true); const isNewMode = React.useMemo(() => selectedMode === "add_new_mode", [selectedMode]) // New mode configuration const [newMode, setNewMode] = useState({ id: '', slug: '', name: '', roleDefinition: '', customInstructions: '', groups: [], source: 'global', updatedAt: 0, }) // Custom mode ID const [customModeId, setCustomModeId] = useState('') // Mode name const [modeName, setModeName] = useState('') // Role definition const [roleDefinition, setRoleDefinition] = useState('') // Selected tool groups const [selectedTools, setSelectedTools] = useState([]); // Custom instructions const [customInstructions, setCustomInstructions] = useState('') // Update form data when mode changes useEffect(() => { // new mode if (isNewMode) { setIsBuiltinMode(false); setModeName(newMode.name); setRoleDefinition(newMode.roleDefinition); setCustomInstructions(newMode.customInstructions || ''); setSelectedTools(newMode.groups); setCustomModeId(''); return; } const builtinMode = buildinModes.find(m => m.slug === selectedMode); if (builtinMode) { setIsBuiltinMode(true); setModeName(builtinMode.slug); setRoleDefinition(builtinMode.roleDefinition); setCustomInstructions(builtinMode.customInstructions || ''); setSelectedTools(builtinMode.groups as GroupEntry[]); setCustomModeId(''); // Built-in modes don't have custom IDs } else { setIsBuiltinMode(false); const customMode = customModeList.find(m => m.slug === selectedMode); if (customMode) { setCustomModeId(customMode.id || ''); setModeName(customMode.name); setRoleDefinition(customMode.roleDefinition); setCustomInstructions(customMode.customInstructions || ''); setSelectedTools(customMode.groups); } else { console.error("custom mode not found") } } }, [selectedMode, customModeList]); // Handle tool group selection change const handleToolChange = React.useCallback((tool: ToolGroup) => { if (isNewMode) { setNewMode((prev) => ({ ...prev, groups: prev.groups.includes(tool) ? prev.groups.filter(t => t !== tool) : [...prev.groups, tool] })) } setSelectedTools(prev => { if (prev.includes(tool)) { return prev.filter(t => t !== tool); } else { return [...prev, tool]; } }); }, [isNewMode]) // Update mode configuration const handleUpdateMode = React.useCallback(async () => { if (!isBuiltinMode) { await updateCustomMode( customModeId, modeName, roleDefinition, customInstructions, selectedTools ); } }, [isBuiltinMode, customModeId, modeName, roleDefinition, customInstructions, selectedTools]) // Create new mode const createNewMode = React.useCallback(async () => { if (!isNewMode) return; await createCustomMode( modeName, roleDefinition, customInstructions, selectedTools ); // reset setNewMode({ id: '', slug: '', name: '', roleDefinition: '', customInstructions: '', groups: [], source: 'global', updatedAt: 0, }) setSelectedMode("add_new_mode") }, [isNewMode, modeName, roleDefinition, customInstructions, selectedTools]) // Delete mode const deleteMode = React.useCallback(async () => { if (isNewMode || isBuiltinMode) return; await deleteCustomMode(customModeId); setModeName('') setRoleDefinition('') setCustomInstructions('') setSelectedTools([]) setSelectedMode('add_new_mode') }, [isNewMode, isBuiltinMode, customModeId]) return (
{/* Mode configuration title and buttons */}

{t('prompt.title')}

{/*
*/}
{/* Create mode tip */}
{t('prompt.description')}
{/* Mode selection area */}
{[...buildinModes, ...customModeList].map(mode => ( ))}
{/* Mode name */}

{t('prompt.modeName')}

{!isBuiltinMode && !isNewMode && ( )}
{ isBuiltinMode ? (

{t('prompt.builtinModeNameWarning')}

) : (

{t('prompt.modeNameRequirements')}

) } { if (isNewMode) { setNewMode((prev) => ({ ...prev, name: e.target.value })) } setModeName(e.target.value) }} className="infio-custom-modes-input" placeholder={t('prompt.modeNamePlaceholder')} disabled={isBuiltinMode} />
{/* Role definition */}

{t('prompt.roleDefinition')}

{isBuiltinMode && ( )}

{t('prompt.roleDefinitionDescription')}