@@ -83,6 +83,7 @@ const DocumentEditor: React.FC<DocumentEditorProps> = ({ documentNode, onSave, o
8383 const [ isDirty , setIsDirty ] = useState ( false ) ;
8484 const [ isSaving , setIsSaving ] = useState ( false ) ;
8585 const [ isGeneratingTitle , setIsGeneratingTitle ] = useState ( false ) ;
86+ const [ isGeneratingEmoji , setIsGeneratingEmoji ] = useState ( false ) ;
8687 const [ isCopied , setIsCopied ] = useState ( false ) ;
8788 const [ viewMode , setViewMode ] = useState < ViewMode > ( resolveDefaultViewMode ( documentNode . default_view_mode , documentNode . language_hint ) ) ;
8889 const [ splitSize , setSplitSize ] = useState ( 50 ) ;
@@ -389,6 +390,31 @@ const DocumentEditor: React.FC<DocumentEditorProps> = ({ documentNode, onSave, o
389390 }
390391 } ;
391392
393+ const handleAddEmojiToTitle = async ( ) => {
394+ if ( ! settings . llmProviderUrl || ! settings . llmModelName || ! title . trim ( ) ) return ;
395+ setIsGeneratingEmoji ( true ) ;
396+ setError ( null ) ;
397+ addLog ( 'INFO' , `Attempting to generate emoji for title "${ title } ".` ) ;
398+ try {
399+ const emoji = await llmService . generateEmojiForTitle ( title , settings , addLog ) ;
400+ setTitle ( ( currentTitle ) => {
401+ const baseTitle = currentTitle . trim ( ) ;
402+ const emojiPrefixRegex = / ^ [ \p{ Extended_Pictographic} \p{ Emoji_Presentation} \p{ Emoji} \ufe0f ] + \s * / u;
403+ const strippedTitle = baseTitle . replace ( emojiPrefixRegex , '' ) . trim ( ) ;
404+ if ( ! strippedTitle ) {
405+ return `${ emoji } ` ;
406+ }
407+ return `${ emoji } ${ strippedTitle } ` ;
408+ } ) ;
409+ } catch ( err ) {
410+ const message = err instanceof Error ? err . message : 'Unknown error' ;
411+ setError ( `Could not generate emoji: ${ message } ` ) ;
412+ addLog ( 'ERROR' , `Could not generate emoji: ${ message } ` ) ;
413+ } finally {
414+ setIsGeneratingEmoji ( false ) ;
415+ }
416+ } ;
417+
392418 const acceptRefinement = ( ) => {
393419 if ( refinedContent ) {
394420 setContent ( refinedContent ) ;
@@ -527,6 +553,23 @@ const DocumentEditor: React.FC<DocumentEditorProps> = ({ documentNode, onSave, o
527553 < div className = "flex justify-between items-center px-4 h-7 gap-4 border-b border-border-color flex-shrink-0 bg-secondary" >
528554 < div className = "flex items-center gap-3 flex-1 min-w-0" >
529555 < input type = "text" value = { title } onChange = { ( e ) => setTitle ( e . target . value ) } placeholder = "Document Title" disabled = { isGeneratingTitle } className = "bg-transparent text-base font-semibold text-text-main focus:outline-none w-full truncate" />
556+ { supportsAiTools && (
557+ < IconButton
558+ onClick = { handleAddEmojiToTitle }
559+ disabled = {
560+ isGeneratingEmoji ||
561+ ! title . trim ( ) ||
562+ ! settings . llmProviderUrl ||
563+ ! settings . llmModelName
564+ }
565+ tooltip = "Add Emoji to Title"
566+ size = "xs"
567+ variant = "ghost"
568+ className = "flex-shrink-0"
569+ >
570+ { isGeneratingEmoji ? < Spinner /> : < span className = "text-base" > 😊</ span > }
571+ </ IconButton >
572+ ) }
530573 { supportsAiTools && (
531574 < IconButton onClick = { handleGenerateTitle } disabled = { isGeneratingTitle || ! content . trim ( ) || ! settings . llmProviderUrl } tooltip = "Regenerate Title with AI" size = "xs" variant = "ghost" className = "flex-shrink-0" >
532575 { isGeneratingTitle ? < Spinner /> : < RefreshIcon className = "w-4 h-4 text-primary" /> }
0 commit comments