Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 59 additions & 33 deletions packages/app/src/components/file-tree.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useFile } from "@/context/file"
import { useLanguage } from "@/context/language"
import { Collapsible } from "@opencode-ai/ui/collapsible"
import { ContextMenu } from "@opencode-ai/ui/context-menu"
import { FileIcon } from "@opencode-ai/ui/file-icon"
import { Icon } from "@opencode-ai/ui/icon"
import { Tooltip } from "@opencode-ai/ui/tooltip"
Expand Down Expand Up @@ -81,10 +83,15 @@ export default function FileTree(props: {
_kinds?: ReadonlyMap<string, Kind>
}) {
const file = useFile()
const language = useLanguage()
const level = props.level ?? 0
const draggable = () => props.draggable ?? true
const tooltip = () => props.tooltip ?? true

const copyToClipboard = (text: string) => {
navigator.clipboard.writeText(text).catch(() => {})
}

const filter = createMemo(() => {
if (props._filter) return props._filter

Expand Down Expand Up @@ -349,8 +356,6 @@ export default function FileTree(props: {
const expanded = () => file.tree.state(node.path)?.expanded ?? false
const deep = () => deeps().get(node.path) ?? -1
const Wrapper = (p: ParentProps) => {
if (!tooltip()) return p.children

const parts = node.path.split("/")
const leaf = parts[parts.length - 1] ?? node.path
const head = parts.slice(0, -1).join("/")
Expand All @@ -367,40 +372,61 @@ export default function FileTree(props: {

const ignored = () => node.type === "directory" && node.ignored

return (
<Tooltip
openDelay={2000}
placement="bottom-start"
class="w-full"
contentStyle={{ "max-width": "480px", width: "fit-content" }}
value={
<div class="flex items-center min-w-0 whitespace-nowrap text-12-regular">
<span
class="min-w-0 truncate text-text-invert-base"
style={{ direction: "rtl", "unicode-bidi": "plaintext" }}
>
{prefix}
</span>
<span class="shrink-0 text-text-invert-strong">{leaf}</span>
<Show when={label()}>
{(t: () => string) => (
const TooltipWrapper = (tp: ParentProps) => {
if (!tooltip()) return tp.children
return (
<Tooltip
openDelay={2000}
placement="bottom-start"
class="w-full"
contentStyle={{ "max-width": "480px", width: "fit-content" }}
value={
<div class="flex items-center min-w-0 whitespace-nowrap text-12-regular">
<span
class="min-w-0 truncate text-text-invert-base"
style={{ direction: "rtl", "unicode-bidi": "plaintext" }}
>
{prefix}
</span>
<span class="shrink-0 text-text-invert-strong">{leaf}</span>
<Show when={label()}>
{(t: () => string) => (
<>
<span class="mx-1 font-bold text-text-invert-strong">•</span>
<span class="shrink-0 text-text-invert-strong">{t()}</span>
</>
)}
</Show>
<Show when={ignored()}>
<>
<span class="mx-1 font-bold text-text-invert-strong">•</span>
<span class="shrink-0 text-text-invert-strong">{t()}</span>
<span class="shrink-0 text-text-invert-strong">Ignored</span>
</>
)}
</Show>
<Show when={ignored()}>
<>
<span class="mx-1 font-bold text-text-invert-strong">•</span>
<span class="shrink-0 text-text-invert-strong">Ignored</span>
</>
</Show>
</div>
}
>
{p.children}
</Tooltip>
</Show>
</div>
}
>
{tp.children}
</Tooltip>
)
}

return (
<ContextMenu>
<ContextMenu.Trigger class="w-full">
<TooltipWrapper>{p.children}</TooltipWrapper>
</ContextMenu.Trigger>
<ContextMenu.Portal>
<ContextMenu.Content>
<ContextMenu.Item onSelect={() => copyToClipboard(node.path)}>
<ContextMenu.ItemLabel>{language.t("filetree.copyRelativePath")}</ContextMenu.ItemLabel>
</ContextMenu.Item>
<ContextMenu.Item onSelect={() => copyToClipboard(node.absolute)}>
<ContextMenu.ItemLabel>{language.t("filetree.copyAbsolutePath")}</ContextMenu.ItemLabel>
</ContextMenu.Item>
</ContextMenu.Content>
</ContextMenu.Portal>
</ContextMenu>
)
}

Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/i18n/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ export const dict = {
"command.input.focus": "التركيز على حقل الإدخال",
"command.terminal.toggle": "تبديل المحطة الطرفية",
"command.fileTree.toggle": "تبديل شجرة الملفات",

"filetree.copyRelativePath": "نسخ المسار النسبي",
"filetree.copyAbsolutePath": "نسخ المسار المطلق",
"command.review.toggle": "تبديل المراجعة",
"command.terminal.new": "محطة طرفية جديدة",
"command.terminal.new.description": "إنشاء علامة تبويب جديدة للمحطة الطرفية",
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ export const dict = {
"command.input.focus": "Eingabefeld fokussieren",
"command.terminal.toggle": "Terminal umschalten",
"command.fileTree.toggle": "Dateibaum umschalten",

"filetree.copyRelativePath": "Relativen Pfad kopieren",
"filetree.copyAbsolutePath": "Absoluten Pfad kopieren",
"command.review.toggle": "Überprüfung umschalten",
"command.terminal.new": "Neues Terminal",
"command.terminal.new.description": "Neuen Terminal-Tab erstellen",
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ export const dict = {
"command.input.focus": "Focus input",
"command.terminal.toggle": "Toggle terminal",
"command.fileTree.toggle": "Toggle file tree",

"filetree.copyRelativePath": "Copy Relative Path",
"filetree.copyAbsolutePath": "Copy Absolute Path",
"command.review.toggle": "Toggle review",
"command.terminal.new": "New terminal",
"command.terminal.new.description": "Create a new terminal tab",
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/i18n/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ export const dict = {
"command.input.focus": "Enfocar entrada",
"command.terminal.toggle": "Alternar terminal",
"command.fileTree.toggle": "Alternar árbol de archivos",

"filetree.copyRelativePath": "Copiar ruta relativa",
"filetree.copyAbsolutePath": "Copiar ruta absoluta",
"command.review.toggle": "Alternar revisión",
"command.terminal.new": "Nueva terminal",
"command.terminal.new.description": "Crear una nueva pestaña de terminal",
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ export const dict = {
"command.input.focus": "Focus input",
"command.terminal.toggle": "Basculer le terminal",
"command.fileTree.toggle": "Basculer l'arborescence des fichiers",

"filetree.copyRelativePath": "Copier le chemin relatif",
"filetree.copyAbsolutePath": "Copier le chemin absolu",
"command.review.toggle": "Basculer la revue",
"command.terminal.new": "Nouveau terminal",
"command.terminal.new.description": "Créer un nouvel onglet de terminal",
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ export const dict = {
"command.input.focus": "入力欄にフォーカス",
"command.terminal.toggle": "ターミナルの切り替え",
"command.fileTree.toggle": "ファイルツリーを切り替え",

"filetree.copyRelativePath": "相対パスをコピー",
"filetree.copyAbsolutePath": "絶対パスをコピー",
"command.review.toggle": "レビューの切り替え",
"command.terminal.new": "新しいターミナル",
"command.terminal.new.description": "新しいターミナルタブを作成",
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ export const dict = {
"command.input.focus": "입력창 포커스",
"command.terminal.toggle": "터미널 토글",
"command.fileTree.toggle": "파일 트리 토글",

"filetree.copyRelativePath": "상대 경로 복사",
"filetree.copyAbsolutePath": "절대 경로 복사",
"command.review.toggle": "검토 토글",
"command.terminal.new": "새 터미널",
"command.terminal.new.description": "새 터미널 탭 생성",
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ export const dict = {
"command.input.focus": "Фокус на поле ввода",
"command.terminal.toggle": "Переключить терминал",
"command.fileTree.toggle": "Переключить дерево файлов",

"filetree.copyRelativePath": "Копировать относительный путь",
"filetree.copyAbsolutePath": "Копировать абсолютный путь",
"command.review.toggle": "Переключить обзор",
"command.terminal.new": "Новый терминал",
"command.terminal.new.description": "Создать новую вкладку терминала",
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ export const dict = {
"command.input.focus": "聚焦输入框",
"command.terminal.toggle": "切换终端",
"command.fileTree.toggle": "切换文件树",

"filetree.copyRelativePath": "复制相对路径",
"filetree.copyAbsolutePath": "复制绝对路径",
"command.review.toggle": "切换审查",
"command.terminal.new": "新建终端",
"command.terminal.new.description": "创建新的终端标签页",
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/i18n/zht.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ export const dict = {
"command.input.focus": "聚焦輸入框",
"command.terminal.toggle": "切換終端機",
"command.fileTree.toggle": "切換檔案樹",

"filetree.copyRelativePath": "複製相對路徑",
"filetree.copyAbsolutePath": "複製絕對路徑",
"command.review.toggle": "切換審查",
"command.terminal.new": "新增終端機",
"command.terminal.new.description": "建立新的終端機標籤頁",
Expand Down
Loading