From ce3d1f404b443e7957049f3af33635b0040c2160 Mon Sep 17 00:00:00 2001 From: Kalami Date: Sun, 15 Feb 2026 01:59:27 +0000 Subject: [PATCH 1/3] feat(app): add preview and source view options for markdown files in file tabs --- packages/app/src/i18n/de.ts | 2 + packages/app/src/i18n/en.ts | 2 + packages/app/src/i18n/es.ts | 2 + packages/app/src/i18n/fr.ts | 2 + packages/app/src/i18n/ja.ts | 2 + packages/app/src/pages/session/file-tabs.tsx | 43 +++++++++++++++++++- 6 files changed, 52 insertions(+), 1 deletion(-) diff --git a/packages/app/src/i18n/de.ts b/packages/app/src/i18n/de.ts index 4b6b43a57c00..4b6e978d6f4e 100644 --- a/packages/app/src/i18n/de.ts +++ b/packages/app/src/i18n/de.ts @@ -452,6 +452,8 @@ export const dict = { "session.files.selectToOpen": "Datei zum Öffnen auswählen", "session.files.all": "Alle Dateien", "session.files.binaryContent": "Binärdatei (Inhalt kann nicht angezeigt werden)", + "session.files.viewPreview": "Vorschau", + "session.files.viewSource": "Quelltext", "session.messages.renderEarlier": "Frühere Nachrichten rendern", "session.messages.loadingEarlier": "Lade frühere Nachrichten...", "session.messages.loadEarlier": "Frühere Nachrichten laden", diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts index fd70f389ecfc..f7c52eedbe28 100644 --- a/packages/app/src/i18n/en.ts +++ b/packages/app/src/i18n/en.ts @@ -496,6 +496,8 @@ export const dict = { "session.files.selectToOpen": "Select a file to open", "session.files.all": "All files", "session.files.binaryContent": "Binary file (content cannot be displayed)", + "session.files.viewPreview": "Preview", + "session.files.viewSource": "Source", "session.messages.renderEarlier": "Render earlier messages", "session.messages.loadingEarlier": "Loading earlier messages...", diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts index 135a63fef742..5895557d8d69 100644 --- a/packages/app/src/i18n/es.ts +++ b/packages/app/src/i18n/es.ts @@ -498,6 +498,8 @@ export const dict = { "session.files.selectToOpen": "Selecciona un archivo para abrir", "session.files.all": "Todos los archivos", "session.files.binaryContent": "Archivo binario (el contenido no puede ser mostrado)", + "session.files.viewPreview": "Vista previa", + "session.files.viewSource": "Código fuente", "session.messages.renderEarlier": "Renderizar mensajes anteriores", "session.messages.loadingEarlier": "Cargando mensajes anteriores...", diff --git a/packages/app/src/i18n/fr.ts b/packages/app/src/i18n/fr.ts index 1ab0c72d53a5..52c684cb5ea7 100644 --- a/packages/app/src/i18n/fr.ts +++ b/packages/app/src/i18n/fr.ts @@ -450,6 +450,8 @@ export const dict = { "session.files.selectToOpen": "Sélectionnez un fichier à ouvrir", "session.files.all": "Tous les fichiers", "session.files.binaryContent": "Fichier binaire (le contenu ne peut pas être affiché)", + "session.files.viewPreview": "Aperçu", + "session.files.viewSource": "Source", "session.messages.renderEarlier": "Afficher les messages précédents", "session.messages.loadingEarlier": "Chargement des messages précédents...", "session.messages.loadEarlier": "Charger les messages précédents", diff --git a/packages/app/src/i18n/ja.ts b/packages/app/src/i18n/ja.ts index 6f092a60f683..3d909b944099 100644 --- a/packages/app/src/i18n/ja.ts +++ b/packages/app/src/i18n/ja.ts @@ -442,6 +442,8 @@ export const dict = { "session.files.selectToOpen": "開くファイルを選択", "session.files.all": "すべてのファイル", "session.files.binaryContent": "バイナリファイル(内容を表示できません)", + "session.files.viewPreview": "プレビュー", + "session.files.viewSource": "ソース", "session.messages.renderEarlier": "以前のメッセージを表示", "session.messages.loadingEarlier": "以前のメッセージを読み込み中...", "session.messages.loadEarlier": "以前のメッセージを読み込む", diff --git a/packages/app/src/pages/session/file-tabs.tsx b/packages/app/src/pages/session/file-tabs.tsx index d22fa358b028..0f53f5b6d2fd 100644 --- a/packages/app/src/pages/session/file-tabs.tsx +++ b/packages/app/src/pages/session/file-tabs.tsx @@ -1,4 +1,4 @@ -import { type ValidComponent, createEffect, createMemo, For, Match, on, onCleanup, Show, Switch } from "solid-js" +import { type ValidComponent, createEffect, createMemo, createSignal, For, Match, on, onCleanup, Show, Switch } from "solid-js" import { createStore, produce } from "solid-js/store" import { Dynamic } from "solid-js/web" import { sampledChecksum } from "@opencode-ai/util/encode" @@ -7,6 +7,8 @@ import { showToast } from "@opencode-ai/ui/toast" import { LineComment as LineCommentView, LineCommentEditor } from "@opencode-ai/ui/line-comment" import { Mark } from "@opencode-ai/ui/logo" import { Tabs } from "@opencode-ai/ui/tabs" +import { IconButton } from "@opencode-ai/ui/icon-button" +import { Markdown } from "@opencode-ai/ui/markdown" import { useLayout } from "@/context/layout" import { useFile, type SelectedLineRange } from "@/context/file" import { useComments } from "@/context/comments" @@ -59,6 +61,18 @@ export function FileTabContent(props: { return c?.mimeType === "image/svg+xml" }) const isBinary = createMemo(() => state()?.content?.type === "binary") + const isMarkdown = createMemo(() => { + const p = path() + return p?.toLowerCase().endsWith(".md") || p?.toLowerCase().endsWith(".markdown") + }) + const [previewMode, setPreviewMode] = createSignal(true) + + createEffect(() => { + const isMarkdownFile = isMarkdown() + if (isMarkdownFile) { + setPreviewMode(true) + } + }) const svgContent = createMemo(() => { if (!isSvg()) return const c = state()?.content @@ -483,6 +497,28 @@ export function FileTabContent(props: { }} onScroll={handleScroll} > + +
+
+ setPreviewMode(false)} + aria-label={props.language.t("session.files.viewSource")} + title={props.language.t("session.files.viewSource")} + /> + setPreviewMode(true)} + aria-label={props.language.t("session.files.viewPreview")} + title={props.language.t("session.files.viewPreview")} + /> +
+
+
@@ -513,6 +549,11 @@ export function FileTabContent(props: {
+ +
+ +
+
{renderCode(contents(), "pb-40")}
{props.language.t("common.loading")}...
From 98897be2a02169f4166bff5e3e080553de1876cd Mon Sep 17 00:00:00 2001 From: Kimi Chen Date: Sun, 15 Feb 2026 19:48:41 +1100 Subject: [PATCH 2/3] feat(i18n): add translations for view preview and view source options in multiple languages --- packages/app/src/i18n/ar.ts | 2 ++ packages/app/src/i18n/br.ts | 2 ++ packages/app/src/i18n/bs.ts | 2 ++ packages/app/src/i18n/da.ts | 2 ++ packages/app/src/i18n/ko.ts | 2 ++ packages/app/src/i18n/no.ts | 2 ++ packages/app/src/i18n/pl.ts | 2 ++ packages/app/src/i18n/ru.ts | 2 ++ packages/app/src/i18n/th.ts | 2 ++ packages/app/src/i18n/zh.ts | 2 ++ packages/app/src/i18n/zht.ts | 2 ++ 11 files changed, 22 insertions(+) diff --git a/packages/app/src/i18n/ar.ts b/packages/app/src/i18n/ar.ts index 81cc92bf6de2..94ea7d55c27f 100644 --- a/packages/app/src/i18n/ar.ts +++ b/packages/app/src/i18n/ar.ts @@ -441,6 +441,8 @@ export const dict = { "session.files.selectToOpen": "اختر ملفًا لفتحه", "session.files.all": "كل الملفات", "session.files.binaryContent": "ملف ثنائي (لا يمكن عرض المحتوى)", + "session.files.viewPreview": "استعراض", + "session.files.viewSource": "مصدر", "session.messages.renderEarlier": "عرض الرسائل السابقة", "session.messages.loadingEarlier": "جارٍ تحميل الرسائل السابقة...", "session.messages.loadEarlier": "تحميل الرسائل السابقة", diff --git a/packages/app/src/i18n/br.ts b/packages/app/src/i18n/br.ts index 9ed3a9fc6fc1..7c4ebfd30c68 100644 --- a/packages/app/src/i18n/br.ts +++ b/packages/app/src/i18n/br.ts @@ -444,6 +444,8 @@ export const dict = { "session.files.selectToOpen": "Selecione um arquivo para abrir", "session.files.all": "Todos os arquivos", "session.files.binaryContent": "Arquivo binário (conteúdo não pode ser exibido)", + "session.files.viewPreview": "Pré-visualização", + "session.files.viewSource": "Código-fonte", "session.messages.renderEarlier": "Renderizar mensagens anteriores", "session.messages.loadingEarlier": "Carregando mensagens anteriores...", "session.messages.loadEarlier": "Carregar mensagens anteriores", diff --git a/packages/app/src/i18n/bs.ts b/packages/app/src/i18n/bs.ts index 206aae3729da..f460cd93bc23 100644 --- a/packages/app/src/i18n/bs.ts +++ b/packages/app/src/i18n/bs.ts @@ -497,6 +497,8 @@ export const dict = { "session.files.selectToOpen": "Odaberi datoteku za otvaranje", "session.files.all": "Sve datoteke", "session.files.binaryContent": "Binarna datoteka (sadržaj se ne može prikazati)", + "session.files.viewPreview": "Pregled", + "session.files.viewSource": "Izvorni kod", "session.messages.renderEarlier": "Prikaži ranije poruke", "session.messages.loadingEarlier": "Učitavanje ranijih poruka...", diff --git a/packages/app/src/i18n/da.ts b/packages/app/src/i18n/da.ts index 6bf67168fb08..f818143740f3 100644 --- a/packages/app/src/i18n/da.ts +++ b/packages/app/src/i18n/da.ts @@ -493,6 +493,8 @@ export const dict = { "session.files.selectToOpen": "Vælg en fil at åbne", "session.files.all": "Alle filer", "session.files.binaryContent": "Binær fil (indhold kan ikke vises)", + "session.files.viewPreview": "Forhåndsvisning", + "session.files.viewSource": "Kilde", "session.messages.renderEarlier": "Vis tidligere beskeder", "session.messages.loadingEarlier": "Indlæser tidligere beskeder...", "session.messages.loadEarlier": "Indlæs tidligere beskeder", diff --git a/packages/app/src/i18n/ko.ts b/packages/app/src/i18n/ko.ts index 4d814d43d0a3..85903a56b707 100644 --- a/packages/app/src/i18n/ko.ts +++ b/packages/app/src/i18n/ko.ts @@ -444,6 +444,8 @@ export const dict = { "session.files.selectToOpen": "열 파일을 선택하세요", "session.files.all": "모든 파일", "session.files.binaryContent": "바이너리 파일 (내용을 표시할 수 없음)", + "session.files.viewPreview": "미리보기", + "session.files.viewSource": "소스", "session.messages.renderEarlier": "이전 메시지 렌더링", "session.messages.loadingEarlier": "이전 메시지 로드 중...", "session.messages.loadEarlier": "이전 메시지 로드", diff --git a/packages/app/src/i18n/no.ts b/packages/app/src/i18n/no.ts index 63bc66acfcd2..bfc811f5d27b 100644 --- a/packages/app/src/i18n/no.ts +++ b/packages/app/src/i18n/no.ts @@ -498,6 +498,8 @@ export const dict = { "session.files.selectToOpen": "Velg en fil å åpne", "session.files.all": "Alle filer", "session.files.binaryContent": "Binær fil (innhold kan ikke vises)", + "session.files.viewPreview": "Forhåndsvisning", + "session.files.viewSource": "Kilde", "session.messages.renderEarlier": "Vis tidligere meldinger", "session.messages.loadingEarlier": "Laster inn tidligere meldinger...", diff --git a/packages/app/src/i18n/pl.ts b/packages/app/src/i18n/pl.ts index 2a3ea7bfb183..5f988e2d84aa 100644 --- a/packages/app/src/i18n/pl.ts +++ b/packages/app/src/i18n/pl.ts @@ -443,6 +443,8 @@ export const dict = { "session.files.selectToOpen": "Wybierz plik do otwarcia", "session.files.all": "Wszystkie pliki", "session.files.binaryContent": "Plik binarny (zawartość nie może być wyświetlona)", + "session.files.viewPreview": "Podgląd", + "session.files.viewSource": "Źródło", "session.messages.renderEarlier": "Renderuj wcześniejsze wiadomości", "session.messages.loadingEarlier": "Ładowanie wcześniejszych wiadomości...", "session.messages.loadEarlier": "Załaduj wcześniejsze wiadomości", diff --git a/packages/app/src/i18n/ru.ts b/packages/app/src/i18n/ru.ts index 93e5b274253c..58270483667b 100644 --- a/packages/app/src/i18n/ru.ts +++ b/packages/app/src/i18n/ru.ts @@ -497,6 +497,8 @@ export const dict = { "session.files.selectToOpen": "Выберите файл, чтобы открыть", "session.files.all": "Все файлы", "session.files.binaryContent": "Двоичный файл (содержимое не может быть отображено)", + "session.files.viewPreview": "Предпросмотр", + "session.files.viewSource": "Исходный код", "session.messages.renderEarlier": "Показать предыдущие сообщения", "session.messages.loadingEarlier": "Загрузка предыдущих сообщений...", "session.messages.loadEarlier": "Загрузить предыдущие сообщения", diff --git a/packages/app/src/i18n/th.ts b/packages/app/src/i18n/th.ts index 3b3486b5c700..8ddd48135951 100644 --- a/packages/app/src/i18n/th.ts +++ b/packages/app/src/i18n/th.ts @@ -493,6 +493,8 @@ export const dict = { "session.files.selectToOpen": "เลือกไฟล์เพื่อเปิด", "session.files.all": "ไฟล์ทั้งหมด", "session.files.binaryContent": "ไฟล์ไบนารี (ไม่สามารถแสดงเนื้อหาได้)", + "session.files.viewPreview": "ดูตัวอย่าง", + "session.files.viewSource": "ซอร์สโค้ด", "session.messages.renderEarlier": "แสดงข้อความก่อนหน้า", "session.messages.loadingEarlier": "กำลังโหลดข้อความก่อนหน้า...", diff --git a/packages/app/src/i18n/zh.ts b/packages/app/src/i18n/zh.ts index 6489b7025425..c2aca87130c9 100644 --- a/packages/app/src/i18n/zh.ts +++ b/packages/app/src/i18n/zh.ts @@ -494,6 +494,8 @@ export const dict = { "session.files.selectToOpen": "选择要打开的文件", "session.files.all": "所有文件", "session.files.binaryContent": "二进制文件(无法显示内容)", + "session.files.viewPreview": "预览", + "session.files.viewSource": "源代码", "session.messages.renderEarlier": "显示更早的消息", "session.messages.loadingEarlier": "正在加载更早的消息...", "session.messages.loadEarlier": "加载更早的消息", diff --git a/packages/app/src/i18n/zht.ts b/packages/app/src/i18n/zht.ts index a01b76c0521b..a100e0718a43 100644 --- a/packages/app/src/i18n/zht.ts +++ b/packages/app/src/i18n/zht.ts @@ -490,6 +490,8 @@ export const dict = { "session.files.selectToOpen": "選取要開啟的檔案", "session.files.all": "所有檔案", "session.files.binaryContent": "二進位檔案(無法顯示內容)", + "session.files.viewPreview": "預覽", + "session.files.viewSource": "原始碼", "session.messages.renderEarlier": "顯示更早的訊息", "session.messages.loadingEarlier": "正在載入更早的訊息...", "session.messages.loadEarlier": "載入更早的訊息", From d5f4095ad42bdf1b7692bb438537d64e79779028 Mon Sep 17 00:00:00 2001 From: Kalami Date: Sun, 15 Feb 2026 20:07:45 +1100 Subject: [PATCH 3/3] Update packages/app/src/pages/session/file-tabs.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- packages/app/src/pages/session/file-tabs.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/src/pages/session/file-tabs.tsx b/packages/app/src/pages/session/file-tabs.tsx index 0f53f5b6d2fd..c5499ef295ab 100644 --- a/packages/app/src/pages/session/file-tabs.tsx +++ b/packages/app/src/pages/session/file-tabs.tsx @@ -497,7 +497,7 @@ export function FileTabContent(props: { }} onScroll={handleScroll} > - +