mirror of
https://github.com/EthanMarti/infio-copilot.git
synced 2026-05-08 16:10:09 +00:00
add chat view & edit line local lang
This commit is contained in:
@@ -2,6 +2,7 @@ import { Check, Diff, Loader2, X } from 'lucide-react'
|
||||
import { PropsWithChildren, useState } from 'react'
|
||||
|
||||
import { useDarkModeContext } from "../../../contexts/DarkModeContext"
|
||||
import { t } from '../../../lang/helpers'
|
||||
import { ApplyStatus, ToolArgs } from "../../../types/apply"
|
||||
|
||||
import { MemoizedSyntaxHighlighterWrapper } from "./SyntaxHighlighterWrapper"
|
||||
@@ -55,23 +56,23 @@ export default function MarkdownApplyDiffBlock({
|
||||
{
|
||||
!finish ? (
|
||||
<>
|
||||
<Loader2 className="spinner" size={14} /> Loading...
|
||||
<Loader2 className="spinner" size={14} /> {t('chat.reactMarkdown.loading')}
|
||||
</>
|
||||
) : applyStatus === ApplyStatus.Idle ? (
|
||||
applying ? (
|
||||
<>
|
||||
<Loader2 className="spinner" size={14} /> Applying...
|
||||
<Loader2 className="spinner" size={14} /> {t('chat.reactMarkdown.applying')}
|
||||
</>
|
||||
) : (
|
||||
'Apply'
|
||||
t('chat.reactMarkdown.apply')
|
||||
)
|
||||
) : applyStatus === ApplyStatus.Applied ? (
|
||||
<>
|
||||
<Check size={14} /> Success
|
||||
<Check size={14} /> {t('chat.reactMarkdown.success')}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<X size={14} /> Failed
|
||||
<X size={14} /> {t('chat.reactMarkdown.failed')}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Check, CopyIcon, Edit, Loader2, X } from 'lucide-react'
|
||||
import { PropsWithChildren, useMemo, useState } from 'react'
|
||||
|
||||
import { useDarkModeContext } from "../../../contexts/DarkModeContext"
|
||||
import { t } from '../../../lang/helpers'
|
||||
import { ApplyStatus, ToolArgs } from "../../../types/apply"
|
||||
|
||||
import { MemoizedSyntaxHighlighterWrapper } from "./SyntaxHighlighterWrapper"
|
||||
@@ -63,7 +64,7 @@ export default function MarkdownEditFileBlock({
|
||||
{path && (
|
||||
<div className={'infio-chat-code-block-header-filename'}>
|
||||
<Edit size={10} className="infio-chat-code-block-header-icon" />
|
||||
{mode}: {path}
|
||||
{t('chat.reactMarkdown.editOrApplyDiff').replace('{mode}', mode).replace('{path}', path)}
|
||||
</div>
|
||||
)}
|
||||
<div className={'infio-chat-code-block-header-button'}>
|
||||
@@ -74,34 +75,34 @@ export default function MarkdownEditFileBlock({
|
||||
>
|
||||
{copied ? (
|
||||
<>
|
||||
<Check size={10} /> Copied
|
||||
<Check size={10} /> {t('chat.reactMarkdown.copied')}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<CopyIcon size={10} /> Copy
|
||||
<CopyIcon size={10} /> {t('chat.reactMarkdown.copy')}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleApply}
|
||||
style={{ color: '#008000' }}
|
||||
className="infio-apply-button"
|
||||
disabled={applyStatus !== ApplyStatus.Idle || applying}
|
||||
>
|
||||
{applyStatus === ApplyStatus.Idle ? (
|
||||
applying ? (
|
||||
<>
|
||||
<Loader2 className="spinner" size={14} /> Applying...
|
||||
<Loader2 className="spinner" size={14} /> {t('chat.reactMarkdown.applying')}
|
||||
</>
|
||||
) : (
|
||||
'Apply'
|
||||
t('chat.reactMarkdown.apply')
|
||||
)
|
||||
) : applyStatus === ApplyStatus.Applied ? (
|
||||
<>
|
||||
<Check size={14} /> Success
|
||||
<Check size={14} /> {t('chat.reactMarkdown.success')}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<X size={14} /> Failed
|
||||
<X size={14} /> {t('chat.reactMarkdown.failed')}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Check, ChevronDown, ChevronRight, Globe, Loader2, X } from 'lucide-react'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
|
||||
import { t } from '../../../lang/helpers'
|
||||
import { ApplyStatus, FetchUrlsContentToolArgs } from "../../../types/apply"
|
||||
|
||||
export default function MarkdownFetchUrlsContentBlock({
|
||||
@@ -38,7 +39,7 @@ export default function MarkdownFetchUrlsContentBlock({
|
||||
<div className="infio-chat-code-block-header">
|
||||
<div className="infio-chat-code-block-header-filename">
|
||||
<Globe size={10} className="infio-chat-code-block-header-icon" />
|
||||
Fetch URLs Content
|
||||
{t('chat.reactMarkdown.fetchUrlsContent')}
|
||||
</div>
|
||||
<div className="infio-chat-code-block-header-button">
|
||||
<button
|
||||
@@ -48,15 +49,15 @@ export default function MarkdownFetchUrlsContentBlock({
|
||||
{
|
||||
!finish || applyStatus === ApplyStatus.Idle ? (
|
||||
<>
|
||||
<Loader2 className="spinner" size={14} /> Fetching...
|
||||
<Loader2 className="spinner" size={14} /> {t('chat.reactMarkdown.fetching')}
|
||||
</>
|
||||
) : applyStatus === ApplyStatus.Applied ? (
|
||||
<>
|
||||
<Check size={14} /> Done
|
||||
<Check size={14} /> {t('chat.reactMarkdown.done')}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<X size={14} /> Failed
|
||||
<X size={14} /> {t('chat.reactMarkdown.failed')}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { FolderOpen } from 'lucide-react'
|
||||
import React from 'react'
|
||||
|
||||
import { useApp } from "../../../contexts/AppContext"
|
||||
import { t } from '../../../lang/helpers'
|
||||
import { ApplyStatus, ListFilesToolArgs } from "../../../types/apply"
|
||||
import { openMarkdownFile } from "../../../utils/obsidian"
|
||||
|
||||
@@ -42,7 +43,7 @@ export default function MarkdownListFilesBlock({
|
||||
<div className={'infio-chat-code-block-header'}>
|
||||
<div className={'infio-chat-code-block-header-filename'}>
|
||||
<FolderOpen size={14} className="infio-chat-code-block-header-icon" />
|
||||
List files: {path}
|
||||
{t('chat.reactMarkdown.listFiles').replace('{path}', path)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { ExternalLink } from 'lucide-react'
|
||||
import React from 'react'
|
||||
|
||||
import { useApp } from "../../../contexts/AppContext"
|
||||
import { t } from '../../../lang/helpers'
|
||||
import { ApplyStatus, ReadFileToolArgs } from "../../../types/apply"
|
||||
import { openMarkdownFile } from "../../../utils/obsidian"
|
||||
|
||||
@@ -39,7 +40,7 @@ export default function MarkdownReadFileBlock({
|
||||
<div className={'infio-chat-code-block-header'}>
|
||||
<div className={'infio-chat-code-block-header-filename'}>
|
||||
<ExternalLink size={10} className="infio-chat-code-block-header-icon" />
|
||||
Read file: {path}
|
||||
{t('chat.reactMarkdown.readFile').replace('{path}', path)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { ChevronDown, ChevronRight, Brain } from 'lucide-react'
|
||||
import { PropsWithChildren, useEffect, useRef, useState } from 'react'
|
||||
|
||||
import { useDarkModeContext } from "../../../contexts/DarkModeContext"
|
||||
import { t } from '../../../lang/helpers'
|
||||
|
||||
import { MemoizedSyntaxHighlighterWrapper } from "./SyntaxHighlighterWrapper"
|
||||
|
||||
@@ -28,7 +29,7 @@ export default function MarkdownReasoningBlock({
|
||||
<div className={'infio-chat-code-block-header'}>
|
||||
<div className={'infio-chat-code-block-header-filename'}>
|
||||
<Brain size={10} className="infio-chat-code-block-header-icon" />
|
||||
Reasoning
|
||||
{t('chat.reactMarkdown.reasoning')}
|
||||
</div>
|
||||
<button
|
||||
className="clickable-icon infio-chat-list-dropdown"
|
||||
|
||||
@@ -2,6 +2,7 @@ import { FileSearch } from 'lucide-react'
|
||||
import React from 'react'
|
||||
|
||||
import { useApp } from "../../../contexts/AppContext"
|
||||
import { t } from '../../../lang/helpers'
|
||||
import { ApplyStatus, RegexSearchFilesToolArgs } from "../../../types/apply"
|
||||
import { openMarkdownFile } from "../../../utils/obsidian"
|
||||
|
||||
@@ -43,7 +44,7 @@ export default function MarkdownRegexSearchFilesBlock({
|
||||
<div className={'infio-chat-code-block-header'}>
|
||||
<div className={'infio-chat-code-block-header-filename'}>
|
||||
<FileSearch size={14} className="infio-chat-code-block-header-icon" />
|
||||
<span>regex search files "{regex}" in {path}</span>
|
||||
<span>{t('chat.reactMarkdown.regexSearchInPath').replace('{regex}', regex).replace('{path}', path)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ import React from 'react'
|
||||
|
||||
import { useApp } from '../../../contexts/AppContext'
|
||||
import { useDarkModeContext } from '../../../contexts/DarkModeContext'
|
||||
import { t } from '../../../lang/helpers'
|
||||
import { ApplyStatus, SearchAndReplaceToolArgs } from '../../../types/apply'
|
||||
import { openMarkdownFile } from '../../../utils/obsidian'
|
||||
|
||||
@@ -52,7 +53,7 @@ export default function MarkdownSearchAndReplace({
|
||||
<div className={'infio-chat-code-block-header'}>
|
||||
<div className={'infio-chat-code-block-header-filename'}>
|
||||
<Replace size={10} className="infio-chat-code-block-header-icon" />
|
||||
Search and replace in {path}
|
||||
{t('chat.reactMarkdown.searchAndReplaceInPath').replace('{path}', path)}
|
||||
</div>
|
||||
<div className={'infio-chat-code-block-header-button'}>
|
||||
<button
|
||||
@@ -66,18 +67,18 @@ export default function MarkdownSearchAndReplace({
|
||||
) : applyStatus === ApplyStatus.Idle ? (
|
||||
applying ? (
|
||||
<>
|
||||
<Loader2 className="spinner" size={14} /> Applying...
|
||||
<Loader2 className="spinner" size={14} /> {t('chat.reactMarkdown.applying')}
|
||||
</>
|
||||
) : (
|
||||
'Apply'
|
||||
t('chat.reactMarkdown.apply')
|
||||
)
|
||||
) : applyStatus === ApplyStatus.Applied ? (
|
||||
<>
|
||||
<Check size={14} /> Success
|
||||
<Check size={14} /> {t('chat.reactMarkdown.success')}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<X size={14} /> Failed
|
||||
<X size={14} /> {t('chat.reactMarkdown.failed')}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Check, Loader2, Search, X } from 'lucide-react'
|
||||
import React from 'react'
|
||||
|
||||
import { useSettings } from "../../../contexts/SettingsContext"
|
||||
import { t } from '../../../lang/helpers'
|
||||
import { ApplyStatus, SearchWebToolArgs } from "../../../types/apply"
|
||||
|
||||
export default function MarkdownWebSearchBlock({
|
||||
@@ -46,7 +47,7 @@ export default function MarkdownWebSearchBlock({
|
||||
<div className={'infio-chat-code-block-header'}>
|
||||
<div className={'infio-chat-code-block-header-filename'}>
|
||||
<Search size={14} className="infio-chat-code-block-header-icon" />
|
||||
Web search: {query}
|
||||
{t('chat.reactMarkdown.webSearch').replace('{query}', query)}
|
||||
</div>
|
||||
<div className={'infio-chat-code-block-header-button'}>
|
||||
<button
|
||||
@@ -56,15 +57,15 @@ export default function MarkdownWebSearchBlock({
|
||||
{
|
||||
!finish || applyStatus === ApplyStatus.Idle ? (
|
||||
<>
|
||||
<Loader2 className="spinner" size={14} /> Searching...
|
||||
<Loader2 className="spinner" size={14} /> {t('chat.reactMarkdown.searching')}
|
||||
</>
|
||||
) : applyStatus === ApplyStatus.Applied ? (
|
||||
<>
|
||||
<Check size={14} /> Done
|
||||
<Check size={14} /> {t('chat.reactMarkdown.done')}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<X size={14} /> Failed
|
||||
<X size={14} /> {t('chat.reactMarkdown.failed')}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { FileSearch } from 'lucide-react'
|
||||
import React from 'react'
|
||||
|
||||
import { useApp } from "../../../contexts/AppContext"
|
||||
import { t } from '../../../lang/helpers'
|
||||
import { ApplyStatus, SemanticSearchFilesToolArgs } from "../../../types/apply"
|
||||
import { openMarkdownFile } from "../../../utils/obsidian"
|
||||
|
||||
@@ -42,7 +43,7 @@ export default function MarkdownSemanticSearchFilesBlock({
|
||||
<div className={'infio-chat-code-block-header'}>
|
||||
<div className={'infio-chat-code-block-header-filename'}>
|
||||
<FileSearch size={14} className="infio-chat-code-block-header-icon" />
|
||||
<span>semantic search files "{query}" in {path}</span>
|
||||
<span>{t('chat.reactMarkdown.semanticSearchInPath').replace('{query}', query).replace('{path}', path)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Check, Loader2, Settings2, X } from 'lucide-react'
|
||||
import { PropsWithChildren, useState } from 'react'
|
||||
|
||||
import { useDarkModeContext } from "../../../contexts/DarkModeContext"
|
||||
import { t } from '../../../lang/helpers'
|
||||
import { ApplyStatus, ToolArgs } from "../../../types/apply"
|
||||
|
||||
import { MemoizedSyntaxHighlighterWrapper } from "./SyntaxHighlighterWrapper"
|
||||
@@ -40,7 +41,7 @@ export default function MarkdownSwitchModeBlock({
|
||||
<div className={'infio-chat-code-block-header'}>
|
||||
<div className={'infio-chat-code-block-header-filename'}>
|
||||
<Settings2 size={10} className="infio-chat-code-block-header-icon" />
|
||||
Switch to "{mode.charAt(0).toUpperCase() + mode.slice(1)}" mode
|
||||
{t('chat.reactMarkdown.switchToMode').replace('{mode}', mode.charAt(0).toUpperCase() + mode.slice(1))}
|
||||
</div>
|
||||
<div className={'infio-chat-code-block-header-button'}>
|
||||
<button
|
||||
@@ -51,18 +52,18 @@ export default function MarkdownSwitchModeBlock({
|
||||
{applyStatus === ApplyStatus.Idle ? (
|
||||
applying ? (
|
||||
<>
|
||||
<Loader2 className="spinner" size={14} /> Allowing...
|
||||
<Loader2 className="spinner" size={14} /> {t('chat.reactMarkdown.allowing')}
|
||||
</>
|
||||
) : (
|
||||
'Allow'
|
||||
t('chat.reactMarkdown.allow')
|
||||
)
|
||||
) : applyStatus === ApplyStatus.Applied ? (
|
||||
<>
|
||||
<Check size={14} /> Success
|
||||
<Check size={14} /> {t('chat.reactMarkdown.success')}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<X size={14} /> Failed
|
||||
<X size={14} /> {t('chat.reactMarkdown.failed')}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
|
||||
@@ -5,6 +5,8 @@ import ReactMarkdown from 'react-markdown';
|
||||
import rehypeRaw from 'rehype-raw';
|
||||
import { useApp } from 'src/contexts/AppContext';
|
||||
|
||||
import { t } from '../../../lang/helpers'
|
||||
|
||||
function CopyButton({ message }: { message: string }) {
|
||||
const [copied, setCopied] = useState(false)
|
||||
|
||||
@@ -33,7 +35,7 @@ function CopyButton({ message }: { message: string }) {
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Portal>
|
||||
<Tooltip.Content className="infio-tooltip-content">
|
||||
Copy message
|
||||
{t('chat.reactMarkdown.copyMsg')}
|
||||
</Tooltip.Content>
|
||||
</Tooltip.Portal>
|
||||
</Tooltip.Root>
|
||||
@@ -77,7 +79,7 @@ function CreateNewFileButton({ message }: { message: string }) {
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Portal>
|
||||
<Tooltip.Content className="infio-tooltip-content">
|
||||
Create new note
|
||||
{t('chat.reactMarkdown.createNewNote')}
|
||||
</Tooltip.Content>
|
||||
</Tooltip.Portal>
|
||||
</Tooltip.Root>
|
||||
@@ -123,9 +125,9 @@ const MarkdownWithIcons = ({
|
||||
|
||||
switch (iconName) {
|
||||
case 'ask_followup_question':
|
||||
return 'Ask Followup Question:';
|
||||
return t('chat.reactMarkdown.askFollowupQuestion');
|
||||
case 'attempt_completion':
|
||||
return 'Task Completion';
|
||||
return t('chat.reactMarkdown.taskCompletion');
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user