mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
feat: add search functionality to mode selector and reorganize layout
- Add search input with clear button to filter modes - Move marketplace and settings buttons to bottom of popup - Replace instruction text with info icon tooltip - Update all localization files with new translation keys - Maintain consistent UI pattern with model selector Fixes #6128
This commit is contained in:
parent
4042fb0fd0
commit
0482256a6e
19 changed files with 205 additions and 91 deletions
|
|
@ -1,8 +1,19 @@
|
|||
import React from "react"
|
||||
import { ChevronUp, Check } from "lucide-react"
|
||||
import React, { useState, useRef, useCallback } from "react"
|
||||
import { ChevronUp, Check, X } from "lucide-react"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { useRooPortal } from "@/components/ui/hooks/useRooPortal"
|
||||
import { Popover, PopoverContent, PopoverTrigger, StandardTooltip } from "@/components/ui"
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
StandardTooltip,
|
||||
Command,
|
||||
CommandInput,
|
||||
CommandList,
|
||||
CommandEmpty,
|
||||
CommandItem,
|
||||
CommandGroup,
|
||||
} from "@/components/ui"
|
||||
import { IconButton } from "./IconButton"
|
||||
import { vscode } from "@/utils/vscode"
|
||||
import { useExtensionState } from "@/context/ExtensionStateContext"
|
||||
|
|
@ -33,7 +44,9 @@ export const ModeSelector = ({
|
|||
customModes,
|
||||
customModePrompts,
|
||||
}: ModeSelectorProps) => {
|
||||
const [open, setOpen] = React.useState(false)
|
||||
const [open, setOpen] = useState(false)
|
||||
const [searchValue, setSearchValue] = useState("")
|
||||
const searchInputRef = useRef<HTMLInputElement>(null)
|
||||
const portalContainer = useRooPortal("roo-portal")
|
||||
const { hasOpenedModeSelector, setHasOpenedModeSelector } = useExtensionState()
|
||||
const { t } = useAppTranslation()
|
||||
|
|
@ -61,6 +74,32 @@ export const ModeSelector = ({
|
|||
// Find the selected mode
|
||||
const selectedMode = React.useMemo(() => modes.find((mode) => mode.slug === value), [modes, value])
|
||||
|
||||
// Filter modes based on search
|
||||
const filteredModes = React.useMemo(() => {
|
||||
if (!searchValue) return modes
|
||||
const searchLower = searchValue.toLowerCase()
|
||||
return modes.filter(
|
||||
(mode) => mode.name.toLowerCase().includes(searchLower) || mode.slug.toLowerCase().includes(searchLower),
|
||||
)
|
||||
}, [modes, searchValue])
|
||||
|
||||
// Handler for clearing search input
|
||||
const onClearSearch = useCallback(() => {
|
||||
setSearchValue("")
|
||||
searchInputRef.current?.focus()
|
||||
}, [])
|
||||
|
||||
// Handler for mode selection
|
||||
const handleModeSelect = useCallback(
|
||||
(modeSlug: string) => {
|
||||
onChange(modeSlug as Mode)
|
||||
setOpen(false)
|
||||
// Clear search after selection
|
||||
setTimeout(() => setSearchValue(""), 100)
|
||||
},
|
||||
[onChange],
|
||||
)
|
||||
|
||||
const trigger = (
|
||||
<PopoverTrigger
|
||||
disabled={disabled}
|
||||
|
|
@ -88,6 +127,10 @@ export const ModeSelector = ({
|
|||
onOpenChange={(isOpen) => {
|
||||
if (isOpen) trackModeSelectorOpened()
|
||||
setOpen(isOpen)
|
||||
// Clear search when closing
|
||||
if (!isOpen) {
|
||||
setTimeout(() => setSearchValue(""), 100)
|
||||
}
|
||||
}}
|
||||
data-testid="mode-selector-root">
|
||||
{title ? <StandardTooltip content={title}>{trigger}</StandardTooltip> : trigger}
|
||||
|
|
@ -97,81 +140,116 @@ export const ModeSelector = ({
|
|||
sideOffset={4}
|
||||
container={portalContainer}
|
||||
className="p-0 overflow-hidden min-w-80 max-w-9/10">
|
||||
<div className="flex flex-col w-full">
|
||||
<div className="p-3 border-b border-vscode-dropdown-border cursor-default">
|
||||
<div className="flex flex-row items-center gap-1 p-0 mt-0 mb-1 w-full">
|
||||
<h4 className="m-0 pb-2 flex-1">{t("chat:modeSelector.title")}</h4>
|
||||
<div className="flex flex-row gap-1 ml-auto mb-1">
|
||||
<IconButton
|
||||
iconClass="codicon-extensions"
|
||||
title={t("chat:modeSelector.marketplace")}
|
||||
onClick={() => {
|
||||
window.postMessage(
|
||||
{
|
||||
type: "action",
|
||||
action: "marketplaceButtonClicked",
|
||||
values: { marketplaceTab: "mode" },
|
||||
},
|
||||
"*",
|
||||
)
|
||||
|
||||
setOpen(false)
|
||||
}}
|
||||
/>
|
||||
<IconButton
|
||||
iconClass="codicon-settings-gear"
|
||||
title={t("chat:modeSelector.settings")}
|
||||
onClick={() => {
|
||||
vscode.postMessage({
|
||||
type: "switchTab",
|
||||
tab: "modes",
|
||||
})
|
||||
setOpen(false)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Command className="flex flex-col h-full">
|
||||
{/* Header with title and info icon */}
|
||||
<div className="p-3 border-b border-vscode-dropdown-border">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<h4 className="m-0">{t("chat:modeSelector.title")}</h4>
|
||||
<StandardTooltip
|
||||
content={
|
||||
<div>
|
||||
{t("chat:modeSelector.description")}
|
||||
<br />
|
||||
{modeShortcutText}
|
||||
</div>
|
||||
}
|
||||
side="left"
|
||||
maxWidth={300}>
|
||||
<span className="codicon codicon-info text-vscode-descriptionForeground cursor-help" />
|
||||
</StandardTooltip>
|
||||
</div>
|
||||
|
||||
{/* Search input */}
|
||||
<div className="relative">
|
||||
<CommandInput
|
||||
ref={searchInputRef}
|
||||
value={searchValue}
|
||||
onValueChange={setSearchValue}
|
||||
placeholder={t("chat:modeSelector.searchPlaceholder")}
|
||||
className="h-9 pr-8"
|
||||
data-testid="mode-search-input"
|
||||
/>
|
||||
{searchValue.length > 0 && (
|
||||
<div className="absolute right-2 top-0 bottom-0 flex items-center justify-center">
|
||||
<X
|
||||
className="text-vscode-input-foreground opacity-50 hover:opacity-100 size-4 p-0.5 cursor-pointer"
|
||||
onClick={onClearSearch}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<p className="my-0 pr-4 text-sm w-full">
|
||||
{t("chat:modeSelector.description")}
|
||||
<br />
|
||||
{modeShortcutText}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Mode List */}
|
||||
<div className="max-h-[400px] overflow-y-auto py-0">
|
||||
{modes.map((mode) => (
|
||||
<div
|
||||
className={cn(
|
||||
"p-2 text-sm cursor-pointer flex flex-row gap-4 items-center",
|
||||
"hover:bg-vscode-list-hoverBackground",
|
||||
mode.slug === value
|
||||
? "bg-vscode-list-activeSelectionBackground text-vscode-list-activeSelectionForeground"
|
||||
: "",
|
||||
)}
|
||||
key={mode.slug}
|
||||
onClick={() => {
|
||||
onChange(mode.slug as Mode)
|
||||
setOpen(false)
|
||||
}}
|
||||
data-testid="mode-selector-item">
|
||||
<div className="flex-grow">
|
||||
<p className="m-0 mb-0 font-bold">{mode.name}</p>
|
||||
{mode.description && (
|
||||
<p className="m-0 py-0 pl-4 h-4 flex-1 text-xs overflow-hidden">
|
||||
{mode.description}
|
||||
</p>
|
||||
)}
|
||||
<CommandList className="flex-1 overflow-y-auto">
|
||||
<CommandEmpty>
|
||||
{searchValue && (
|
||||
<div className="py-4 px-3 text-sm text-vscode-descriptionForeground text-center">
|
||||
{t("chat:modeSelector.noMatchFound")}
|
||||
</div>
|
||||
{mode.slug === value ? (
|
||||
<Check className="m-0 size-4 p-0.5" />
|
||||
) : (
|
||||
<div className="size-4" />
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
)}
|
||||
</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{filteredModes.map((mode) => (
|
||||
<CommandItem
|
||||
key={mode.slug}
|
||||
value={mode.slug}
|
||||
onSelect={() => handleModeSelect(mode.slug)}
|
||||
className={cn(
|
||||
"p-2 cursor-pointer",
|
||||
mode.slug === value && "bg-vscode-list-activeSelectionBackground",
|
||||
)}
|
||||
data-testid="mode-selector-item">
|
||||
<div className="flex items-center gap-4 w-full">
|
||||
<div className="flex-grow min-w-0">
|
||||
<p className="m-0 font-bold">{mode.name}</p>
|
||||
{mode.description && (
|
||||
<p className="m-0 mt-0.5 text-xs text-vscode-descriptionForeground truncate">
|
||||
{mode.description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
{mode.slug === value ? (
|
||||
<Check className="size-4 flex-shrink-0" />
|
||||
) : (
|
||||
<div className="size-4 flex-shrink-0" />
|
||||
)}
|
||||
</div>
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
|
||||
{/* Footer with marketplace and settings buttons */}
|
||||
<div className="p-3 border-t border-vscode-dropdown-border flex justify-end gap-2">
|
||||
<IconButton
|
||||
iconClass="codicon-extensions"
|
||||
title={t("chat:modeSelector.marketplace")}
|
||||
onClick={() => {
|
||||
window.postMessage(
|
||||
{
|
||||
type: "action",
|
||||
action: "marketplaceButtonClicked",
|
||||
values: { marketplaceTab: "mode" },
|
||||
},
|
||||
"*",
|
||||
)
|
||||
setOpen(false)
|
||||
}}
|
||||
/>
|
||||
<IconButton
|
||||
iconClass="codicon-settings-gear"
|
||||
title={t("chat:modeSelector.settings")}
|
||||
onClick={() => {
|
||||
vscode.postMessage({
|
||||
type: "switchTab",
|
||||
tab: "modes",
|
||||
})
|
||||
setOpen(false)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/ca/chat.json
generated
4
webview-ui/src/i18n/locales/ca/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "Modes",
|
||||
"marketplace": "Marketplace de Modes",
|
||||
"settings": "Configuració de Modes",
|
||||
"description": "Personalitats especialitzades que adapten el comportament de Roo."
|
||||
"description": "Personalitats especialitzades que adapten el comportament de Roo.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "Error en llegir el fitxer:",
|
||||
"noValidImages": "No s'ha processat cap imatge vàlida",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/de/chat.json
generated
4
webview-ui/src/i18n/locales/de/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "Modi",
|
||||
"marketplace": "Modus-Marketplace",
|
||||
"settings": "Modus-Einstellungen",
|
||||
"description": "Spezialisierte Personas, die Roos Verhalten anpassen."
|
||||
"description": "Spezialisierte Personas, die Roos Verhalten anpassen.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "Fehler beim Lesen der Datei:",
|
||||
"noValidImages": "Keine gültigen Bilder wurden verarbeitet",
|
||||
|
|
|
|||
|
|
@ -118,7 +118,9 @@
|
|||
"title": "Modes",
|
||||
"marketplace": "Mode Marketplace",
|
||||
"settings": "Mode Settings",
|
||||
"description": "Specialized personas that tailor Roo's behavior."
|
||||
"description": "Specialized personas that tailor Roo's behavior.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"enhancePromptDescription": "The 'Enhance Prompt' button helps improve your prompt by providing additional context, clarification, or rephrasing. Try typing a prompt in here and clicking the button again to see how it works.",
|
||||
"addImages": "Add images to message",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/es/chat.json
generated
4
webview-ui/src/i18n/locales/es/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "Modos",
|
||||
"marketplace": "Marketplace de Modos",
|
||||
"settings": "Configuración de Modos",
|
||||
"description": "Personalidades especializadas que adaptan el comportamiento de Roo."
|
||||
"description": "Personalidades especializadas que adaptan el comportamiento de Roo.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "Error al leer el archivo:",
|
||||
"noValidImages": "No se procesaron imágenes válidas",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/fr/chat.json
generated
4
webview-ui/src/i18n/locales/fr/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "Modes",
|
||||
"marketplace": "Marketplace de Modes",
|
||||
"settings": "Paramètres des Modes",
|
||||
"description": "Personas spécialisés qui adaptent le comportement de Roo."
|
||||
"description": "Personas spécialisés qui adaptent le comportement de Roo.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "Erreur lors de la lecture du fichier :",
|
||||
"noValidImages": "Aucune image valide n'a été traitée",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/hi/chat.json
generated
4
webview-ui/src/i18n/locales/hi/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "मोड्स",
|
||||
"marketplace": "मोड मार्केटप्लेस",
|
||||
"settings": "मोड सेटिंग्स",
|
||||
"description": "विशेष व्यक्तित्व जो Roo के व्यवहार को अनुकूलित करते हैं।"
|
||||
"description": "विशेष व्यक्तित्व जो Roo के व्यवहार को अनुकूलित करते हैं।",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "फ़ाइल पढ़ने में त्रुटि:",
|
||||
"noValidImages": "कोई मान्य चित्र प्रोसेस नहीं किया गया",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/id/chat.json
generated
4
webview-ui/src/i18n/locales/id/chat.json
generated
|
|
@ -122,7 +122,9 @@
|
|||
"title": "Mode",
|
||||
"marketplace": "Marketplace Mode",
|
||||
"settings": "Pengaturan Mode",
|
||||
"description": "Persona khusus yang menyesuaikan perilaku Roo."
|
||||
"description": "Persona khusus yang menyesuaikan perilaku Roo.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"addImages": "Tambahkan gambar ke pesan",
|
||||
"sendMessage": "Kirim pesan",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/it/chat.json
generated
4
webview-ui/src/i18n/locales/it/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "Modalità",
|
||||
"marketplace": "Marketplace delle Modalità",
|
||||
"settings": "Impostazioni Modalità",
|
||||
"description": "Personalità specializzate che adattano il comportamento di Roo."
|
||||
"description": "Personalità specializzate che adattano il comportamento di Roo.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "Errore nella lettura del file:",
|
||||
"noValidImages": "Nessuna immagine valida è stata elaborata",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/ja/chat.json
generated
4
webview-ui/src/i18n/locales/ja/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "モード",
|
||||
"marketplace": "モードマーケットプレイス",
|
||||
"settings": "モード設定",
|
||||
"description": "Rooの動作をカスタマイズする専門的なペルソナ。"
|
||||
"description": "Rooの動作をカスタマイズする専門的なペルソナ。",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "ファイル読み込みエラー:",
|
||||
"noValidImages": "有効な画像が処理されませんでした",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/ko/chat.json
generated
4
webview-ui/src/i18n/locales/ko/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "모드",
|
||||
"marketplace": "모드 마켓플레이스",
|
||||
"settings": "모드 설정",
|
||||
"description": "Roo의 행동을 맞춤화하는 전문화된 페르소나."
|
||||
"description": "Roo의 행동을 맞춤화하는 전문화된 페르소나.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "파일 읽기 오류:",
|
||||
"noValidImages": "처리된 유효한 이미지가 없습니다",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/nl/chat.json
generated
4
webview-ui/src/i18n/locales/nl/chat.json
generated
|
|
@ -108,7 +108,9 @@
|
|||
"title": "Modi",
|
||||
"marketplace": "Modus Marktplaats",
|
||||
"settings": "Modus Instellingen",
|
||||
"description": "Gespecialiseerde persona's die het gedrag van Roo aanpassen."
|
||||
"description": "Gespecialiseerde persona's die het gedrag van Roo aanpassen.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"addImages": "Afbeeldingen toevoegen aan bericht",
|
||||
"sendMessage": "Bericht verzenden",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/pl/chat.json
generated
4
webview-ui/src/i18n/locales/pl/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "Tryby",
|
||||
"marketplace": "Marketplace Trybów",
|
||||
"settings": "Ustawienia Trybów",
|
||||
"description": "Wyspecjalizowane persony, które dostosowują zachowanie Roo."
|
||||
"description": "Wyspecjalizowane persony, które dostosowują zachowanie Roo.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "Błąd odczytu pliku:",
|
||||
"noValidImages": "Nie przetworzono żadnych prawidłowych obrazów",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/pt-BR/chat.json
generated
4
webview-ui/src/i18n/locales/pt-BR/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "Modos",
|
||||
"marketplace": "Marketplace de Modos",
|
||||
"settings": "Configurações de Modos",
|
||||
"description": "Personas especializadas que adaptam o comportamento do Roo."
|
||||
"description": "Personas especializadas que adaptam o comportamento do Roo.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "Erro ao ler arquivo:",
|
||||
"noValidImages": "Nenhuma imagem válida foi processada",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/ru/chat.json
generated
4
webview-ui/src/i18n/locales/ru/chat.json
generated
|
|
@ -108,7 +108,9 @@
|
|||
"title": "Режимы",
|
||||
"marketplace": "Маркетплейс режимов",
|
||||
"settings": "Настройки режимов",
|
||||
"description": "Специализированные персоны, которые настраивают поведение Roo."
|
||||
"description": "Специализированные персоны, которые настраивают поведение Roo.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"addImages": "Добавить изображения к сообщению",
|
||||
"sendMessage": "Отправить сообщение",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/tr/chat.json
generated
4
webview-ui/src/i18n/locales/tr/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "Modlar",
|
||||
"marketplace": "Mod Pazaryeri",
|
||||
"settings": "Mod Ayarları",
|
||||
"description": "Roo'nun davranışını özelleştiren uzmanlaşmış kişilikler."
|
||||
"description": "Roo'nun davranışını özelleştiren uzmanlaşmış kişilikler.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "Dosya okuma hatası:",
|
||||
"noValidImages": "Hiçbir geçerli resim işlenmedi",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/vi/chat.json
generated
4
webview-ui/src/i18n/locales/vi/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "Chế độ",
|
||||
"marketplace": "Chợ Chế độ",
|
||||
"settings": "Cài đặt Chế độ",
|
||||
"description": "Các nhân cách chuyên biệt điều chỉnh hành vi của Roo."
|
||||
"description": "Các nhân cách chuyên biệt điều chỉnh hành vi của Roo.",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "Lỗi khi đọc tệp:",
|
||||
"noValidImages": "Không có hình ảnh hợp lệ nào được xử lý",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/zh-CN/chat.json
generated
4
webview-ui/src/i18n/locales/zh-CN/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "模式",
|
||||
"marketplace": "模式市场",
|
||||
"settings": "模式设置",
|
||||
"description": "专门定制Roo行为的角色。"
|
||||
"description": "专门定制Roo行为的角色。",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "读取文件时出错:",
|
||||
"noValidImages": "没有处理有效图片",
|
||||
|
|
|
|||
4
webview-ui/src/i18n/locales/zh-TW/chat.json
generated
4
webview-ui/src/i18n/locales/zh-TW/chat.json
generated
|
|
@ -116,7 +116,9 @@
|
|||
"title": "模式",
|
||||
"marketplace": "模式市集",
|
||||
"settings": "模式設定",
|
||||
"description": "專門定制Roo行為的角色。"
|
||||
"description": "專門定制Roo行為的角色。",
|
||||
"searchPlaceholder": "Search modes...",
|
||||
"noMatchFound": "No modes found"
|
||||
},
|
||||
"errorReadingFile": "讀取檔案時發生錯誤:",
|
||||
"noValidImages": "未處理到任何有效圖片",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue