Skip to content
Open
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
13 changes: 13 additions & 0 deletions packages/app/dist-mirror/assets/ghostty-web-DZEGc9xA.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/app/dist-mirror/assets/home-_mSBvk4G.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2,160 changes: 2,160 additions & 0 deletions packages/app/dist-mirror/assets/mirror-00ORfTCH.js

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions packages/app/dist-mirror/assets/session-BtM9eZfI.js

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions packages/app/src/components/settings-general.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useTheme, type ColorScheme } from "@opencode-ai/ui/theme"
import { showToast } from "@opencode-ai/ui/toast"
import { useLanguage } from "@/context/language"
import { usePlatform } from "@/context/platform"
import { useServer } from "@/context/server"
import { useSettings, monoFontFamily } from "@/context/settings"
import { playSound, SOUND_OPTIONS } from "@/utils/sound"
import { Link } from "./link"
Expand Down Expand Up @@ -42,6 +43,7 @@ export const SettingsGeneral: Component = () => {
const language = useLanguage()
const platform = usePlatform()
const settings = useSettings()
const server = useServer()

const [store, setStore] = createStore({
checking: false,
Expand Down Expand Up @@ -538,6 +540,27 @@ export const SettingsGeneral: Component = () => {
)
}}
</Show>

{/* Desktop Section - Desktop only */}
<Show when={platform.platform === "desktop"}>
<div class="flex flex-col gap-1">
<h3 class="text-14-medium text-text-strong pb-2">{language.t("settings.general.section.desktop")}</h3>

<div class="bg-surface-raised-base px-4 rounded-lg">
<SettingsRow
title={language.t("settings.general.desktop.dynamicSort.title")}
description={language.t("settings.general.desktop.dynamicSort.description")}
>
<div data-action="settings-dynamic-sort">
<Switch
checked={server.dynamicSort.enabled()}
onChange={(checked) => server.dynamicSort.set(checked)}
/>
</div>
</SettingsRow>
</div>
</div>
</Show>
</div>
</div>
)
Expand Down
7 changes: 7 additions & 0 deletions packages/app/src/context/global-sync.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import type { ProjectMeta } from "./global-sync/types"
import { SESSION_RECENT_LIMIT } from "./global-sync/types"
import { sanitizeProject } from "./global-sync/utils"
import { formatServerError } from "@/utils/server-errors"
import { useServer } from "./server"

type GlobalStore = {
ready: boolean
Expand All @@ -53,6 +54,7 @@ type GlobalStore = {
function createGlobalSync() {
const globalSDK = useGlobalSDK()
const language = useLanguage()
const server = useServer()
const owner = getOwner()
if (!owner) throw new Error("GlobalSync must be created within owner")

Expand Down Expand Up @@ -306,6 +308,11 @@ function createGlobalSync() {
.lsp.status()
.then((x) => setStore("lsp", x.data ?? []))
},
onSessionBusy: (sessionID) => {
if (!server.dynamicSort.enabled()) return
server.projects.bringToTop(directory)
setStore("session_active", sessionID, Date.now())
},
})
})

Expand Down
1 change: 1 addition & 0 deletions packages/app/src/context/global-sync/child-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export function createChildStoreManager(input: {
session: [],
sessionTotal: 0,
session_status: {},
session_active: {},
session_diff: {},
todo: {},
permission: {},
Expand Down
2 changes: 2 additions & 0 deletions packages/app/src/context/global-sync/event-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export function applyDirectoryEvent(input: {
loadLsp: () => void
vcsCache?: VcsCache
setSessionTodo?: (sessionID: string, todos: Todo[] | undefined) => void
onSessionBusy?: (sessionID: string) => void
}) {
const event = input.event
switch (event.type) {
Expand Down Expand Up @@ -162,6 +163,7 @@ export function applyDirectoryEvent(input: {
case "session.status": {
const props = event.properties as { sessionID: string; status: SessionStatus }
input.setStore("session_status", props.sessionID, reconcile(props.status))
if (props.status.type === "busy") input.onSessionBusy?.(props.sessionID)
break
}
case "message.updated": {
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/context/global-sync/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ export type State = {
session_status: {
[sessionID: string]: SessionStatus
}
session_active: {
[sessionID: string]: number
}
session_diff: {
[sessionID: string]: FileDiff[]
}
Expand Down
49 changes: 48 additions & 1 deletion packages/app/src/context/server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { usePlatform } from "@/context/platform"
import { Persist, persisted } from "@/utils/persist"
import { checkServerHealth } from "@/utils/server-health"

type StoredProject = { worktree: string; expanded: boolean }
type StoredProject = { worktree: string; expanded: boolean; lastUsed?: number; pinned?: boolean }
type StoredServer = string | ServerConnection.HttpBase | ServerConnection.Http
const HEALTH_POLL_INTERVAL_MS = 10_000

Expand Down Expand Up @@ -104,6 +104,7 @@ export const { use: useServer, provider: ServerProvider } = createSimpleContext(
list: [] as StoredServer[],
projects: {} as Record<string, StoredProject[]>,
lastProject: {} as Record<string, string>,
dynamicSort: true,
}),
)

Expand Down Expand Up @@ -291,6 +292,52 @@ export const { use: useServer, provider: ServerProvider } = createSimpleContext(
if (!key) return
setStore("lastProject", key, directory)
},
bringToTop(directory: string) {
if (!(store.dynamicSort ?? true)) return
const key = origin()
if (!key) return
const current = store.projects[key] ?? []
const index = current.findIndex((x) => x.worktree === directory)
if (index <= 0) return
if (current[index].pinned) return
const project = { ...current[index], lastUsed: Date.now() }
const rest = current.filter((_, i) => i !== index)
const insertAt = rest.findIndex((x) => !x.pinned)
const result = [...rest]
result.splice(insertAt === -1 ? rest.length : insertAt, 0, project)
setStore("projects", key, result)
},
pin(directory: string) {
const key = origin()
if (!key) return
const current = store.projects[key] ?? []
const index = current.findIndex((x) => x.worktree === directory)
if (index === -1) return
const project = { ...current[index], pinned: true }
const rest = current.filter((_, i) => i !== index)
const lastPinned = rest.findLastIndex((x) => x.pinned)
const result = [...rest]
result.splice(lastPinned + 1, 0, project)
setStore("projects", key, result)
},
unpin(directory: string) {
const key = origin()
if (!key) return
const current = store.projects[key] ?? []
const index = current.findIndex((x) => x.worktree === directory)
if (index === -1) return
setStore("projects", key, index, "pinned", false)
},
isPinned(directory: string) {
const current = store.projects[origin()] ?? []
return current.find((x) => x.worktree === directory)?.pinned ?? false
},
},
dynamicSort: {
enabled: createMemo(() => store.dynamicSort ?? true),
set(value: boolean) {
setStore("dynamicSort", value)
},
},
}
},
Expand Down
7 changes: 7 additions & 0 deletions packages/app/src/i18n/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,8 @@ export const dict = {
"sidebar.nav.projectsAndSessions": "المشاريع والجلسات",
"sidebar.settings": "الإعدادات",
"sidebar.help": "مساعدة",
"sidebar.project.pin": "تثبيت في الأعلى",
"sidebar.project.unpin": "إلغاء التثبيت",
"sidebar.workspaces.enable": "تمكين مساحات العمل",
"sidebar.workspaces.disable": "تعطيل مساحات العمل",
"sidebar.gettingStarted.title": "البدء",
Expand All @@ -533,6 +535,11 @@ export const dict = {
"settings.general.section.sounds": "المؤثرات الصوتية",
"settings.general.section.feed": "الخلاصة",
"settings.general.section.display": "شاشة العرض",
"settings.general.section.desktop": "سطح المكتب",

"settings.general.desktop.dynamicSort.title": "ترتيب ديناميكي للشريط الجانبي",
"settings.general.desktop.dynamicSort.description": "نقل المشاريع النشطة مؤخراً إلى الأعلى",

"settings.general.row.language.title": "اللغة",
"settings.general.row.language.description": "تغيير لغة العرض لـ OpenCode",
"settings.general.row.appearance.title": "المظهر",
Expand Down
7 changes: 7 additions & 0 deletions packages/app/src/i18n/br.ts
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,8 @@ export const dict = {
"sidebar.nav.projectsAndSessions": "Projetos e sessões",
"sidebar.settings": "Configurações",
"sidebar.help": "Ajuda",
"sidebar.project.pin": "Fixar no topo",
"sidebar.project.unpin": "Desafixar",
"sidebar.workspaces.enable": "Habilitar espaços de trabalho",
"sidebar.workspaces.disable": "Desabilitar espaços de trabalho",
"sidebar.gettingStarted.title": "Começando",
Expand All @@ -539,6 +541,11 @@ export const dict = {
"settings.general.section.sounds": "Efeitos sonoros",
"settings.general.section.feed": "Feed",
"settings.general.section.display": "Tela",
"settings.general.section.desktop": "Desktop",

"settings.general.desktop.dynamicSort.title": "Ordenação dinâmica da barra lateral",
"settings.general.desktop.dynamicSort.description": "Mover projetos recentemente ativos para o topo",

"settings.general.row.language.title": "Idioma",
"settings.general.row.language.description": "Alterar o idioma de exibição do OpenCode",
"settings.general.row.appearance.title": "Aparência",
Expand Down
6 changes: 6 additions & 0 deletions packages/app/src/i18n/da.ts
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,8 @@ export const dict = {
"sidebar.nav.projectsAndSessions": "Projekter og sessioner",
"sidebar.settings": "Indstillinger",
"sidebar.help": "Hjælp",
"sidebar.project.pin": "Fastgør øverst",
"sidebar.project.unpin": "Frigør",
"sidebar.workspaces.enable": "Aktiver arbejdsområder",
"sidebar.workspaces.disable": "Deaktiver arbejdsområder",
"sidebar.gettingStarted.title": "Kom i gang",
Expand All @@ -598,6 +600,10 @@ export const dict = {
"settings.general.section.sounds": "Lydeffekter",
"settings.general.section.feed": "Feed",
"settings.general.section.display": "Skærm",
"settings.general.section.desktop": "Skrivebord",

"settings.general.desktop.dynamicSort.title": "Dynamisk sidebjælkesortering",
"settings.general.desktop.dynamicSort.description": "Flyt nyligt aktive projekter til toppen",

"settings.general.row.language.title": "Sprog",
"settings.general.row.language.description": "Ændr visningssproget for OpenCode",
Expand Down
7 changes: 7 additions & 0 deletions packages/app/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,8 @@ export const dict = {
"sidebar.nav.projectsAndSessions": "Projekte und Sitzungen",
"sidebar.settings": "Einstellungen",
"sidebar.help": "Hilfe",
"sidebar.project.pin": "Oben anheften",
"sidebar.project.unpin": "Loslösen",
"sidebar.workspaces.enable": "Arbeitsbereiche aktivieren",
"sidebar.workspaces.disable": "Arbeitsbereiche deaktivieren",
"sidebar.gettingStarted.title": "Erste Schritte",
Expand All @@ -548,6 +550,11 @@ export const dict = {
"settings.general.section.sounds": "Soundeffekte",
"settings.general.section.feed": "Feed",
"settings.general.section.display": "Anzeige",
"settings.general.section.desktop": "Desktop",

"settings.general.desktop.dynamicSort.title": "Dynamische Seitenleisten-Sortierung",
"settings.general.desktop.dynamicSort.description": "Kürzlich aktive Projekte nach oben verschieben",

"settings.general.row.language.title": "Sprache",
"settings.general.row.language.description": "Die Anzeigesprache für OpenCode ändern",
"settings.general.row.appearance.title": "Erscheinungsbild",
Expand Down
6 changes: 6 additions & 0 deletions packages/app/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,8 @@ export const dict = {
"sidebar.nav.projectsAndSessions": "Projects and sessions",
"sidebar.settings": "Settings",
"sidebar.help": "Help",
"sidebar.project.pin": "Pin to top",
"sidebar.project.unpin": "Unpin",
"sidebar.workspaces.enable": "Enable workspaces",
"sidebar.workspaces.disable": "Disable workspaces",
"sidebar.gettingStarted.title": "Getting started",
Expand All @@ -625,6 +627,10 @@ export const dict = {
"settings.general.section.sounds": "Sound effects",
"settings.general.section.feed": "Feed",
"settings.general.section.display": "Display",
"settings.general.section.desktop": "Desktop",

"settings.general.desktop.dynamicSort.title": "Dynamic sidebar sorting",
"settings.general.desktop.dynamicSort.description": "Move recently active projects to the top",

"settings.general.row.language.title": "Language",
"settings.general.row.language.description": "Change the display language for OpenCode",
Expand Down
6 changes: 6 additions & 0 deletions packages/app/src/i18n/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,8 @@ export const dict = {
"sidebar.nav.projectsAndSessions": "Proyectos y sesiones",
"sidebar.settings": "Ajustes",
"sidebar.help": "Ayuda",
"sidebar.project.pin": "Fijar arriba",
"sidebar.project.unpin": "Desfijar",
"sidebar.workspaces.enable": "Habilitar espacios de trabajo",
"sidebar.workspaces.disable": "Deshabilitar espacios de trabajo",
"sidebar.gettingStarted.title": "Empezando",
Expand All @@ -606,6 +608,10 @@ export const dict = {
"settings.general.section.sounds": "Efectos de sonido",
"settings.general.section.feed": "Feed",
"settings.general.section.display": "Pantalla",
"settings.general.section.desktop": "Escritorio",

"settings.general.desktop.dynamicSort.title": "Ordenación dinámica de la barra lateral",
"settings.general.desktop.dynamicSort.description": "Mover proyectos recientemente activos a la parte superior",

"settings.general.row.language.title": "Idioma",
"settings.general.row.language.description": "Cambiar el idioma de visualización para OpenCode",
Expand Down
7 changes: 7 additions & 0 deletions packages/app/src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,8 @@ export const dict = {
"sidebar.nav.projectsAndSessions": "Projets et sessions",
"sidebar.settings": "Paramètres",
"sidebar.help": "Aide",
"sidebar.project.pin": "Épingler en haut",
"sidebar.project.unpin": "Désépingler",
"sidebar.workspaces.enable": "Activer les espaces de travail",
"sidebar.workspaces.disable": "Désactiver les espaces de travail",
"sidebar.gettingStarted.title": "Commencer",
Expand All @@ -545,6 +547,11 @@ export const dict = {
"settings.general.section.sounds": "Effets sonores",
"settings.general.section.feed": "Flux",
"settings.general.section.display": "Affichage",
"settings.general.section.desktop": "Bureau",

"settings.general.desktop.dynamicSort.title": "Tri dynamique de la barre latérale",
"settings.general.desktop.dynamicSort.description": "Déplacer les projets récemment actifs vers le haut",

"settings.general.row.language.title": "Langue",
"settings.general.row.language.description": "Changer la langue d'affichage pour OpenCode",
"settings.general.row.appearance.title": "Apparence",
Expand Down
7 changes: 7 additions & 0 deletions packages/app/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,8 @@ export const dict = {
"sidebar.nav.projectsAndSessions": "プロジェクトとセッション",
"sidebar.settings": "設定",
"sidebar.help": "ヘルプ",
"sidebar.project.pin": "上部に固定",
"sidebar.project.unpin": "固定を解除",
"sidebar.workspaces.enable": "ワークスペースを有効化",
"sidebar.workspaces.disable": "ワークスペースを無効化",
"sidebar.gettingStarted.title": "はじめに",
Expand All @@ -537,6 +539,11 @@ export const dict = {
"settings.general.section.sounds": "効果音",
"settings.general.section.feed": "フィード",
"settings.general.section.display": "ディスプレイ",
"settings.general.section.desktop": "デスクトップ",

"settings.general.desktop.dynamicSort.title": "サイドバーの動的ソート",
"settings.general.desktop.dynamicSort.description": "最近アクティブなプロジェクトを上部に移動",

"settings.general.row.language.title": "言語",
"settings.general.row.language.description": "OpenCodeの表示言語を変更します",
"settings.general.row.appearance.title": "外観",
Expand Down
7 changes: 7 additions & 0 deletions packages/app/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,8 @@ export const dict = {
"sidebar.nav.projectsAndSessions": "프로젝트 및 세션",
"sidebar.settings": "설정",
"sidebar.help": "도움말",
"sidebar.project.pin": "상단에 고정",
"sidebar.project.unpin": "고정 해제",
"sidebar.workspaces.enable": "작업 공간 활성화",
"sidebar.workspaces.disable": "작업 공간 비활성화",
"sidebar.gettingStarted.title": "시작하기",
Expand All @@ -538,6 +540,11 @@ export const dict = {
"settings.general.section.sounds": "효과음",
"settings.general.section.feed": "피드",
"settings.general.section.display": "디스플레이",
"settings.general.section.desktop": "데스크톱",

"settings.general.desktop.dynamicSort.title": "사이드바 동적 정렬",
"settings.general.desktop.dynamicSort.description": "최근 활성 프로젝트를 상단으로 이동",

"settings.general.row.language.title": "언어",
"settings.general.row.language.description": "OpenCode 표시 언어 변경",
"settings.general.row.appearance.title": "모양",
Expand Down
Loading
Loading