Revert "feat(desktop): add WSL backend mode (#12914)"
This reverts commit 213a87234d.
This commit is contained in:
@@ -43,7 +43,7 @@ function UiI18nBridge(props: ParentProps) {
|
|||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
__OPENCODE__?: { updaterEnabled?: boolean; serverPassword?: string; deepLinks?: string[]; wsl?: boolean }
|
__OPENCODE__?: { updaterEnabled?: boolean; serverPassword?: string; deepLinks?: string[] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -367,34 +367,6 @@ export const SettingsGeneral: Component = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Show when={platform.platform === "desktop" && platform.os === "windows" && platform.getWslEnabled}>
|
|
||||||
{(_) => {
|
|
||||||
const [enabledResource, actions] = createResource(() => platform.getWslEnabled?.())
|
|
||||||
const enabled = () => (enabledResource.state === "pending" ? undefined : enabledResource.latest)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div class="flex flex-col gap-1">
|
|
||||||
<h3 class="text-14-medium text-text-strong pb-2">{language.t("settings.desktop.section.wsl")}</h3>
|
|
||||||
|
|
||||||
<div class="bg-surface-raised-base px-4 rounded-lg">
|
|
||||||
<SettingsRow
|
|
||||||
title={language.t("settings.desktop.wsl.title")}
|
|
||||||
description={language.t("settings.desktop.wsl.description")}
|
|
||||||
>
|
|
||||||
<div data-action="settings-wsl">
|
|
||||||
<Switch
|
|
||||||
checked={enabled() ?? false}
|
|
||||||
disabled={enabledResource.state === "pending"}
|
|
||||||
onChange={(checked) => platform.setWslEnabled?.(checked)?.finally(() => actions.refetch())}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</SettingsRow>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</Show>
|
|
||||||
|
|
||||||
{/* Updates Section */}
|
{/* Updates Section */}
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1">
|
||||||
<h3 class="text-14-medium text-text-strong pb-2">{language.t("settings.general.section.updates")}</h3>
|
<h3 class="text-14-medium text-text-strong pb-2">{language.t("settings.general.section.updates")}</h3>
|
||||||
|
|||||||
@@ -57,12 +57,6 @@ export type Platform = {
|
|||||||
/** Set the default server URL to use on app startup (platform-specific) */
|
/** Set the default server URL to use on app startup (platform-specific) */
|
||||||
setDefaultServerUrl?(url: string | null): Promise<void> | void
|
setDefaultServerUrl?(url: string | null): Promise<void> | void
|
||||||
|
|
||||||
/** Get the configured WSL integration (desktop only) */
|
|
||||||
getWslEnabled?(): Promise<boolean>
|
|
||||||
|
|
||||||
/** Set the configured WSL integration (desktop only) */
|
|
||||||
setWslEnabled?(config: boolean): Promise<void> | void
|
|
||||||
|
|
||||||
/** Get the preferred display backend (desktop only) */
|
/** Get the preferred display backend (desktop only) */
|
||||||
getDisplayBackend?(): Promise<DisplayBackend | null> | DisplayBackend | null
|
getDisplayBackend?(): Promise<DisplayBackend | null> | DisplayBackend | null
|
||||||
|
|
||||||
|
|||||||
@@ -508,9 +508,6 @@ export const dict = {
|
|||||||
"settings.section.server": "الخادم",
|
"settings.section.server": "الخادم",
|
||||||
"settings.tab.general": "عام",
|
"settings.tab.general": "عام",
|
||||||
"settings.tab.shortcuts": "اختصارات",
|
"settings.tab.shortcuts": "اختصارات",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "المظهر",
|
"settings.general.section.appearance": "المظهر",
|
||||||
"settings.general.section.notifications": "إشعارات النظام",
|
"settings.general.section.notifications": "إشعارات النظام",
|
||||||
|
|||||||
@@ -512,9 +512,6 @@ export const dict = {
|
|||||||
"settings.section.server": "Servidor",
|
"settings.section.server": "Servidor",
|
||||||
"settings.tab.general": "Geral",
|
"settings.tab.general": "Geral",
|
||||||
"settings.tab.shortcuts": "Atalhos",
|
"settings.tab.shortcuts": "Atalhos",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "Aparência",
|
"settings.general.section.appearance": "Aparência",
|
||||||
"settings.general.section.notifications": "Notificações do sistema",
|
"settings.general.section.notifications": "Notificações do sistema",
|
||||||
|
|||||||
@@ -539,9 +539,6 @@ export const dict = {
|
|||||||
"settings.section.server": "Server",
|
"settings.section.server": "Server",
|
||||||
"settings.tab.general": "Opšte",
|
"settings.tab.general": "Opšte",
|
||||||
"settings.tab.shortcuts": "Prečice",
|
"settings.tab.shortcuts": "Prečice",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "Izgled",
|
"settings.general.section.appearance": "Izgled",
|
||||||
"settings.general.section.notifications": "Sistemske obavijesti",
|
"settings.general.section.notifications": "Sistemske obavijesti",
|
||||||
|
|||||||
@@ -512,9 +512,6 @@ export const dict = {
|
|||||||
"settings.section.server": "Server",
|
"settings.section.server": "Server",
|
||||||
"settings.tab.general": "Generelt",
|
"settings.tab.general": "Generelt",
|
||||||
"settings.tab.shortcuts": "Genveje",
|
"settings.tab.shortcuts": "Genveje",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "Udseende",
|
"settings.general.section.appearance": "Udseende",
|
||||||
"settings.general.section.notifications": "Systemmeddelelser",
|
"settings.general.section.notifications": "Systemmeddelelser",
|
||||||
|
|||||||
@@ -556,9 +556,6 @@ export const dict = {
|
|||||||
"settings.section.server": "Server",
|
"settings.section.server": "Server",
|
||||||
"settings.tab.general": "Allgemein",
|
"settings.tab.general": "Allgemein",
|
||||||
"settings.tab.shortcuts": "Tastenkombinationen",
|
"settings.tab.shortcuts": "Tastenkombinationen",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "Erscheinungsbild",
|
"settings.general.section.appearance": "Erscheinungsbild",
|
||||||
"settings.general.section.notifications": "Systembenachrichtigungen",
|
"settings.general.section.notifications": "Systembenachrichtigungen",
|
||||||
|
|||||||
@@ -583,9 +583,6 @@ export const dict = {
|
|||||||
"settings.section.server": "Server",
|
"settings.section.server": "Server",
|
||||||
"settings.tab.general": "General",
|
"settings.tab.general": "General",
|
||||||
"settings.tab.shortcuts": "Shortcuts",
|
"settings.tab.shortcuts": "Shortcuts",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "Appearance",
|
"settings.general.section.appearance": "Appearance",
|
||||||
"settings.general.section.notifications": "System notifications",
|
"settings.general.section.notifications": "System notifications",
|
||||||
|
|||||||
@@ -515,9 +515,6 @@ export const dict = {
|
|||||||
"settings.section.server": "Servidor",
|
"settings.section.server": "Servidor",
|
||||||
"settings.tab.general": "General",
|
"settings.tab.general": "General",
|
||||||
"settings.tab.shortcuts": "Atajos",
|
"settings.tab.shortcuts": "Atajos",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "Apariencia",
|
"settings.general.section.appearance": "Apariencia",
|
||||||
"settings.general.section.notifications": "Notificaciones del sistema",
|
"settings.general.section.notifications": "Notificaciones del sistema",
|
||||||
|
|||||||
@@ -522,9 +522,6 @@ export const dict = {
|
|||||||
"settings.section.server": "Serveur",
|
"settings.section.server": "Serveur",
|
||||||
"settings.tab.general": "Général",
|
"settings.tab.general": "Général",
|
||||||
"settings.tab.shortcuts": "Raccourcis",
|
"settings.tab.shortcuts": "Raccourcis",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "Apparence",
|
"settings.general.section.appearance": "Apparence",
|
||||||
"settings.general.section.notifications": "Notifications système",
|
"settings.general.section.notifications": "Notifications système",
|
||||||
|
|||||||
@@ -507,9 +507,6 @@ export const dict = {
|
|||||||
"settings.section.server": "サーバー",
|
"settings.section.server": "サーバー",
|
||||||
"settings.tab.general": "一般",
|
"settings.tab.general": "一般",
|
||||||
"settings.tab.shortcuts": "ショートカット",
|
"settings.tab.shortcuts": "ショートカット",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "外観",
|
"settings.general.section.appearance": "外観",
|
||||||
"settings.general.section.notifications": "システム通知",
|
"settings.general.section.notifications": "システム通知",
|
||||||
|
|||||||
@@ -513,9 +513,6 @@ export const dict = {
|
|||||||
"settings.section.server": "서버",
|
"settings.section.server": "서버",
|
||||||
"settings.tab.general": "일반",
|
"settings.tab.general": "일반",
|
||||||
"settings.tab.shortcuts": "단축키",
|
"settings.tab.shortcuts": "단축키",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "모양",
|
"settings.general.section.appearance": "모양",
|
||||||
"settings.general.section.notifications": "시스템 알림",
|
"settings.general.section.notifications": "시스템 알림",
|
||||||
|
|||||||
@@ -515,9 +515,6 @@ export const dict = {
|
|||||||
"settings.section.server": "Server",
|
"settings.section.server": "Server",
|
||||||
"settings.tab.general": "Generelt",
|
"settings.tab.general": "Generelt",
|
||||||
"settings.tab.shortcuts": "Snarveier",
|
"settings.tab.shortcuts": "Snarveier",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "Utseende",
|
"settings.general.section.appearance": "Utseende",
|
||||||
"settings.general.section.notifications": "Systemvarsler",
|
"settings.general.section.notifications": "Systemvarsler",
|
||||||
|
|||||||
@@ -514,9 +514,6 @@ export const dict = {
|
|||||||
"settings.section.server": "Serwer",
|
"settings.section.server": "Serwer",
|
||||||
"settings.tab.general": "Ogólne",
|
"settings.tab.general": "Ogólne",
|
||||||
"settings.tab.shortcuts": "Skróty",
|
"settings.tab.shortcuts": "Skróty",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "Wygląd",
|
"settings.general.section.appearance": "Wygląd",
|
||||||
"settings.general.section.notifications": "Powiadomienia systemowe",
|
"settings.general.section.notifications": "Powiadomienia systemowe",
|
||||||
|
|||||||
@@ -517,9 +517,6 @@ export const dict = {
|
|||||||
"settings.section.server": "Сервер",
|
"settings.section.server": "Сервер",
|
||||||
"settings.tab.general": "Основные",
|
"settings.tab.general": "Основные",
|
||||||
"settings.tab.shortcuts": "Горячие клавиши",
|
"settings.tab.shortcuts": "Горячие клавиши",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "Внешний вид",
|
"settings.general.section.appearance": "Внешний вид",
|
||||||
"settings.general.section.notifications": "Системные уведомления",
|
"settings.general.section.notifications": "Системные уведомления",
|
||||||
|
|||||||
@@ -516,9 +516,6 @@ export const dict = {
|
|||||||
"settings.section.server": "เซิร์ฟเวอร์",
|
"settings.section.server": "เซิร์ฟเวอร์",
|
||||||
"settings.tab.general": "ทั่วไป",
|
"settings.tab.general": "ทั่วไป",
|
||||||
"settings.tab.shortcuts": "ทางลัด",
|
"settings.tab.shortcuts": "ทางลัด",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "รูปลักษณ์",
|
"settings.general.section.appearance": "รูปลักษณ์",
|
||||||
"settings.general.section.notifications": "การแจ้งเตือนระบบ",
|
"settings.general.section.notifications": "การแจ้งเตือนระบบ",
|
||||||
|
|||||||
@@ -548,9 +548,6 @@ export const dict = {
|
|||||||
"settings.section.server": "服务器",
|
"settings.section.server": "服务器",
|
||||||
"settings.tab.general": "通用",
|
"settings.tab.general": "通用",
|
||||||
"settings.tab.shortcuts": "快捷键",
|
"settings.tab.shortcuts": "快捷键",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "外观",
|
"settings.general.section.appearance": "外观",
|
||||||
"settings.general.section.notifications": "系统通知",
|
"settings.general.section.notifications": "系统通知",
|
||||||
|
|||||||
@@ -545,9 +545,6 @@ export const dict = {
|
|||||||
"settings.section.server": "伺服器",
|
"settings.section.server": "伺服器",
|
||||||
"settings.tab.general": "一般",
|
"settings.tab.general": "一般",
|
||||||
"settings.tab.shortcuts": "快速鍵",
|
"settings.tab.shortcuts": "快速鍵",
|
||||||
"settings.desktop.section.wsl": "WSL",
|
|
||||||
"settings.desktop.wsl.title": "WSL integration",
|
|
||||||
"settings.desktop.wsl.description": "Run the OpenCode server inside WSL on Windows.",
|
|
||||||
|
|
||||||
"settings.general.section.appearance": "外觀",
|
"settings.general.section.appearance": "外觀",
|
||||||
"settings.general.section.notifications": "系統通知",
|
"settings.general.section.notifications": "系統通知",
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
# Desktop package notes
|
|
||||||
|
|
||||||
- Never call `invoke` manually in this package.
|
|
||||||
- Use the generated bindings in `packages/desktop/src/bindings.ts` for core commands/events.
|
|
||||||
@@ -3,11 +3,8 @@ use tauri_plugin_shell::{
|
|||||||
ShellExt,
|
ShellExt,
|
||||||
process::{Command, CommandChild, CommandEvent, TerminatedPayload},
|
process::{Command, CommandChild, CommandEvent, TerminatedPayload},
|
||||||
};
|
};
|
||||||
use tauri_plugin_store::StoreExt;
|
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
|
|
||||||
use crate::constants::{SETTINGS_STORE, WSL_ENABLED_KEY};
|
|
||||||
|
|
||||||
const CLI_INSTALL_DIR: &str = ".opencode/bin";
|
const CLI_INSTALL_DIR: &str = ".opencode/bin";
|
||||||
const CLI_BINARY_NAME: &str = "opencode";
|
const CLI_BINARY_NAME: &str = "opencode";
|
||||||
|
|
||||||
@@ -23,7 +20,7 @@ pub struct Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_config(app: &AppHandle) -> Option<Config> {
|
pub async fn get_config(app: &AppHandle) -> Option<Config> {
|
||||||
create_command(app, "debug config", &[])
|
create_command(app, "debug config")
|
||||||
.output()
|
.output()
|
||||||
.await
|
.await
|
||||||
.inspect_err(|e| tracing::warn!("Failed to read OC config: {e}"))
|
.inspect_err(|e| tracing::warn!("Failed to read OC config: {e}"))
|
||||||
@@ -152,106 +149,25 @@ fn get_user_shell() -> String {
|
|||||||
std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string())
|
std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_wsl_enabled(app: &tauri::AppHandle) -> bool {
|
pub fn create_command(app: &tauri::AppHandle, args: &str) -> Command {
|
||||||
let Ok(store) = app.store(SETTINGS_STORE) else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
store
|
|
||||||
.get(WSL_ENABLED_KEY)
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|value| value.as_bool())
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shell_escape(input: &str) -> String {
|
|
||||||
if input.is_empty() {
|
|
||||||
return "''".to_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut escaped = String::from("'");
|
|
||||||
escaped.push_str(&input.replace("'", "'\"'\"'"));
|
|
||||||
escaped.push('\'');
|
|
||||||
escaped
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_command(app: &tauri::AppHandle, args: &str, extra_env: &[(&str, String)]) -> Command {
|
|
||||||
let state_dir = app
|
let state_dir = app
|
||||||
.path()
|
.path()
|
||||||
.resolve("", BaseDirectory::AppLocalData)
|
.resolve("", BaseDirectory::AppLocalData)
|
||||||
.expect("Failed to resolve app local data dir");
|
.expect("Failed to resolve app local data dir");
|
||||||
|
|
||||||
let mut envs = vec![
|
#[cfg(target_os = "windows")]
|
||||||
(
|
|
||||||
"OPENCODE_EXPERIMENTAL_ICON_DISCOVERY".to_string(),
|
|
||||||
"true".to_string(),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"OPENCODE_EXPERIMENTAL_FILEWATCHER".to_string(),
|
|
||||||
"true".to_string(),
|
|
||||||
),
|
|
||||||
("OPENCODE_CLIENT".to_string(), "desktop".to_string()),
|
|
||||||
(
|
|
||||||
"XDG_STATE_HOME".to_string(),
|
|
||||||
state_dir.to_string_lossy().to_string(),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
envs.extend(
|
|
||||||
extra_env
|
|
||||||
.iter()
|
|
||||||
.map(|(key, value)| (key.to_string(), value.clone())),
|
|
||||||
);
|
|
||||||
|
|
||||||
if cfg!(windows) {
|
|
||||||
if is_wsl_enabled(app) {
|
|
||||||
tracing::info!("WSL is enabled, spawning CLI server in WSL");
|
|
||||||
let version = app.package_info().version.to_string();
|
|
||||||
let mut script = vec![
|
|
||||||
"set -e".to_string(),
|
|
||||||
"BIN=\"$HOME/.opencode/bin/opencode\"".to_string(),
|
|
||||||
"if [ ! -x \"$BIN\" ]; then".to_string(),
|
|
||||||
format!(
|
|
||||||
" curl -fsSL https://opencode.ai/install | bash -s -- --version {} --no-modify-path",
|
|
||||||
shell_escape(&version)
|
|
||||||
),
|
|
||||||
"fi".to_string(),
|
|
||||||
];
|
|
||||||
|
|
||||||
let mut env_prefix = vec![
|
|
||||||
"OPENCODE_EXPERIMENTAL_ICON_DISCOVERY=true".to_string(),
|
|
||||||
"OPENCODE_EXPERIMENTAL_FILEWATCHER=true".to_string(),
|
|
||||||
"OPENCODE_CLIENT=desktop".to_string(),
|
|
||||||
"XDG_STATE_HOME=\"$HOME/.local/state\"".to_string(),
|
|
||||||
];
|
|
||||||
env_prefix.extend(
|
|
||||||
envs.iter()
|
|
||||||
.filter(|(key, _)| key != "OPENCODE_EXPERIMENTAL_ICON_DISCOVERY")
|
|
||||||
.filter(|(key, _)| key != "OPENCODE_EXPERIMENTAL_FILEWATCHER")
|
|
||||||
.filter(|(key, _)| key != "OPENCODE_CLIENT")
|
|
||||||
.filter(|(key, _)| key != "XDG_STATE_HOME")
|
|
||||||
.map(|(key, value)| format!("{}={}", key, shell_escape(value))),
|
|
||||||
);
|
|
||||||
|
|
||||||
script.push(format!("{} exec \"$BIN\" {}", env_prefix.join(" "), args));
|
|
||||||
|
|
||||||
return app
|
return app
|
||||||
.shell()
|
|
||||||
.command("wsl")
|
|
||||||
.args(["-e", "bash", "-lc", &script.join("\n")]);
|
|
||||||
} else {
|
|
||||||
let mut cmd = app
|
|
||||||
.shell()
|
.shell()
|
||||||
.sidecar("opencode-cli")
|
.sidecar("opencode-cli")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(args.split_whitespace());
|
.args(args.split_whitespace())
|
||||||
|
.env("OPENCODE_EXPERIMENTAL_ICON_DISCOVERY", "true")
|
||||||
|
.env("OPENCODE_EXPERIMENTAL_FILEWATCHER", "true")
|
||||||
|
.env("OPENCODE_CLIENT", "desktop")
|
||||||
|
.env("XDG_STATE_HOME", &state_dir);
|
||||||
|
|
||||||
for (key, value) in envs {
|
#[cfg(not(target_os = "windows"))]
|
||||||
cmd = cmd.env(key, value);
|
return {
|
||||||
}
|
|
||||||
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let sidecar = get_sidecar_path(app);
|
let sidecar = get_sidecar_path(app);
|
||||||
let shell = get_user_shell();
|
let shell = get_user_shell();
|
||||||
|
|
||||||
@@ -261,14 +177,14 @@ pub fn create_command(app: &tauri::AppHandle, args: &str, extra_env: &[(&str, St
|
|||||||
format!("\"{}\" {}", sidecar.display(), args)
|
format!("\"{}\" {}", sidecar.display(), args)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut cmd = app.shell().command(&shell).args(["-il", "-c", &cmd]);
|
app.shell()
|
||||||
|
.command(&shell)
|
||||||
for (key, value) in envs {
|
.env("OPENCODE_EXPERIMENTAL_ICON_DISCOVERY", "true")
|
||||||
cmd = cmd.env(key, value);
|
.env("OPENCODE_EXPERIMENTAL_FILEWATCHER", "true")
|
||||||
}
|
.env("OPENCODE_CLIENT", "desktop")
|
||||||
|
.env("XDG_STATE_HOME", &state_dir)
|
||||||
cmd
|
.args(["-il", "-c", &cmd])
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serve(
|
pub fn serve(
|
||||||
@@ -281,16 +197,12 @@ pub fn serve(
|
|||||||
|
|
||||||
tracing::info!(port, "Spawning sidecar");
|
tracing::info!(port, "Spawning sidecar");
|
||||||
|
|
||||||
let envs = [
|
|
||||||
("OPENCODE_SERVER_USERNAME", "opencode".to_string()),
|
|
||||||
("OPENCODE_SERVER_PASSWORD", password.to_string()),
|
|
||||||
];
|
|
||||||
|
|
||||||
let (mut rx, child) = create_command(
|
let (mut rx, child) = create_command(
|
||||||
app,
|
app,
|
||||||
format!("--print-logs --log-level WARN serve --hostname {hostname} --port {port}").as_str(),
|
format!("--print-logs --log-level WARN serve --hostname {hostname} --port {port}").as_str(),
|
||||||
&envs,
|
|
||||||
)
|
)
|
||||||
|
.env("OPENCODE_SERVER_USERNAME", "opencode")
|
||||||
|
.env("OPENCODE_SERVER_PASSWORD", password)
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("Failed to spawn opencode");
|
.expect("Failed to spawn opencode");
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ use tauri_plugin_window_state::StateFlags;
|
|||||||
|
|
||||||
pub const SETTINGS_STORE: &str = "opencode.settings.dat";
|
pub const SETTINGS_STORE: &str = "opencode.settings.dat";
|
||||||
pub const DEFAULT_SERVER_URL_KEY: &str = "defaultServerUrl";
|
pub const DEFAULT_SERVER_URL_KEY: &str = "defaultServerUrl";
|
||||||
pub const WSL_ENABLED_KEY: &str = "wslEnabled";
|
|
||||||
pub const UPDATER_ENABLED: bool = option_env!("TAURI_SIGNING_PRIVATE_KEY").is_some();
|
pub const UPDATER_ENABLED: bool = option_env!("TAURI_SIGNING_PRIVATE_KEY").is_some();
|
||||||
|
|
||||||
pub fn window_state_flags() -> StateFlags {
|
pub fn window_state_flags() -> StateFlags {
|
||||||
|
|||||||
@@ -52,13 +52,6 @@ enum InitStep {
|
|||||||
Done,
|
Done,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, specta::Type)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
enum WslPathMode {
|
|
||||||
Windows,
|
|
||||||
Linux,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct InitState {
|
struct InitState {
|
||||||
current: watch::Receiver<InitStep>,
|
current: watch::Receiver<InitStep>,
|
||||||
}
|
}
|
||||||
@@ -627,50 +620,32 @@ fn check_linux_app(app_name: &str) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
#[specta::specta]
|
|
||||||
fn wsl_path(path: String, mode: Option<WslPathMode>) -> Result<String, String> {
|
|
||||||
if !cfg!(windows) {
|
|
||||||
return Ok(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
let flag = match mode.unwrap_or(WslPathMode::Linux) {
|
|
||||||
WslPathMode::Windows => "-w",
|
|
||||||
WslPathMode::Linux => "-u",
|
|
||||||
};
|
|
||||||
|
|
||||||
let output = if path.starts_with('~') {
|
|
||||||
let suffix = path.strip_prefix('~').unwrap_or("");
|
|
||||||
let escaped = suffix.replace('"', "\\\"");
|
|
||||||
let cmd = format!("wslpath {flag} \"$HOME{escaped}\"");
|
|
||||||
Command::new("wsl")
|
|
||||||
.args(["-e", "sh", "-lc", &cmd])
|
|
||||||
.output()
|
|
||||||
.map_err(|e| format!("Failed to run wslpath: {e}"))?
|
|
||||||
} else {
|
|
||||||
Command::new("wsl")
|
|
||||||
.args(["-e", "wslpath", flag, &path])
|
|
||||||
.output()
|
|
||||||
.map_err(|e| format!("Failed to run wslpath: {e}"))?
|
|
||||||
};
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
|
|
||||||
if stderr.is_empty() {
|
|
||||||
return Err("wslpath failed".to_string());
|
|
||||||
}
|
|
||||||
return Err(stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
let builder = make_specta_builder();
|
let builder = tauri_specta::Builder::<tauri::Wry>::new()
|
||||||
|
// Then register them (separated by a comma)
|
||||||
|
.commands(tauri_specta::collect_commands![
|
||||||
|
kill_sidecar,
|
||||||
|
cli::install_cli,
|
||||||
|
await_initialization,
|
||||||
|
server::get_default_server_url,
|
||||||
|
server::set_default_server_url,
|
||||||
|
get_display_backend,
|
||||||
|
set_display_backend,
|
||||||
|
markdown::parse_markdown_command,
|
||||||
|
check_app_exists,
|
||||||
|
resolve_app_path
|
||||||
|
])
|
||||||
|
.events(tauri_specta::collect_events![LoadingWindowComplete])
|
||||||
|
.error_handling(tauri_specta::ErrorHandlingMode::Throw);
|
||||||
|
|
||||||
#[cfg(debug_assertions)] // <- Only export on non-release builds
|
#[cfg(debug_assertions)] // <- Only export on non-release builds
|
||||||
export_types(&builder);
|
builder
|
||||||
|
.export(
|
||||||
|
specta_typescript::Typescript::default(),
|
||||||
|
"../src/bindings.ts",
|
||||||
|
)
|
||||||
|
.expect("Failed to export typescript bindings");
|
||||||
|
|
||||||
#[cfg(all(target_os = "macos", not(debug_assertions)))]
|
#[cfg(all(target_os = "macos", not(debug_assertions)))]
|
||||||
let _ = std::process::Command::new("killall")
|
let _ = std::process::Command::new("killall")
|
||||||
@@ -737,44 +712,6 @@ pub fn run() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_specta_builder() -> tauri_specta::Builder<tauri::Wry> {
|
|
||||||
tauri_specta::Builder::<tauri::Wry>::new()
|
|
||||||
// Then register them (separated by a comma)
|
|
||||||
.commands(tauri_specta::collect_commands![
|
|
||||||
kill_sidecar,
|
|
||||||
cli::install_cli,
|
|
||||||
await_initialization,
|
|
||||||
server::get_default_server_url,
|
|
||||||
server::set_default_server_url,
|
|
||||||
server::get_wsl_config,
|
|
||||||
server::set_wsl_config,
|
|
||||||
get_display_backend,
|
|
||||||
set_display_backend,
|
|
||||||
markdown::parse_markdown_command,
|
|
||||||
check_app_exists,
|
|
||||||
wsl_path,
|
|
||||||
resolve_app_path
|
|
||||||
])
|
|
||||||
.events(tauri_specta::collect_events![LoadingWindowComplete])
|
|
||||||
.error_handling(tauri_specta::ErrorHandlingMode::Throw)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn export_types(builder: &tauri_specta::Builder<tauri::Wry>) {
|
|
||||||
builder
|
|
||||||
.export(
|
|
||||||
specta_typescript::Typescript::default(),
|
|
||||||
"../src/bindings.ts",
|
|
||||||
)
|
|
||||||
.expect("Failed to export typescript bindings");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[test]
|
|
||||||
fn test_export_types() {
|
|
||||||
let builder = make_specta_builder();
|
|
||||||
export_types(&builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(tauri_specta::Event, serde::Deserialize, specta::Type)]
|
#[derive(tauri_specta::Event, serde::Deserialize, specta::Type)]
|
||||||
struct LoadingWindowComplete;
|
struct LoadingWindowComplete;
|
||||||
|
|
||||||
|
|||||||
@@ -8,20 +8,9 @@ use tokio::task::JoinHandle;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cli,
|
cli,
|
||||||
constants::{DEFAULT_SERVER_URL_KEY, SETTINGS_STORE, WSL_ENABLED_KEY},
|
constants::{DEFAULT_SERVER_URL_KEY, SETTINGS_STORE},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, serde::Serialize, serde::Deserialize, specta::Type, Debug)]
|
|
||||||
pub struct WslConfig {
|
|
||||||
pub enabled: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for WslConfig {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self { enabled: false }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
#[specta::specta]
|
#[specta::specta]
|
||||||
pub fn get_default_server_url(app: AppHandle) -> Result<Option<String>, String> {
|
pub fn get_default_server_url(app: AppHandle) -> Result<Option<String>, String> {
|
||||||
@@ -59,38 +48,6 @@ pub async fn set_default_server_url(app: AppHandle, url: Option<String>) -> Resu
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
#[specta::specta]
|
|
||||||
pub fn get_wsl_config(app: AppHandle) -> Result<WslConfig, String> {
|
|
||||||
let store = app
|
|
||||||
.store(SETTINGS_STORE)
|
|
||||||
.map_err(|e| format!("Failed to open settings store: {}", e))?;
|
|
||||||
|
|
||||||
let enabled = store
|
|
||||||
.get(WSL_ENABLED_KEY)
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|v| v.as_bool())
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
Ok(WslConfig { enabled })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
#[specta::specta]
|
|
||||||
pub fn set_wsl_config(app: AppHandle, config: WslConfig) -> Result<(), String> {
|
|
||||||
let store = app
|
|
||||||
.store(SETTINGS_STORE)
|
|
||||||
.map_err(|e| format!("Failed to open settings store: {}", e))?;
|
|
||||||
|
|
||||||
store.set(WSL_ENABLED_KEY, serde_json::Value::Bool(config.enabled));
|
|
||||||
|
|
||||||
store
|
|
||||||
.save()
|
|
||||||
.map_err(|e| format!("Failed to save settings: {}", e))?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_saved_server_url(app: &tauri::AppHandle) -> Option<String> {
|
pub async fn get_saved_server_url(app: &tauri::AppHandle) -> Option<String> {
|
||||||
if let Some(url) = get_default_server_url(app.clone()).ok().flatten() {
|
if let Some(url) = get_default_server_url(app.clone()).ok().flatten() {
|
||||||
tracing::info!(%url, "Using desktop-specific custom URL");
|
tracing::info!(%url, "Using desktop-specific custom URL");
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
use crate::{
|
use crate::constants::{UPDATER_ENABLED, window_state_flags};
|
||||||
constants::{UPDATER_ENABLED, window_state_flags},
|
|
||||||
server::get_wsl_config,
|
|
||||||
};
|
|
||||||
use std::{ops::Deref, time::Duration};
|
use std::{ops::Deref, time::Duration};
|
||||||
use tauri::{AppHandle, Manager, Runtime, WebviewUrl, WebviewWindow, WebviewWindowBuilder};
|
use tauri::{AppHandle, Manager, Runtime, WebviewUrl, WebviewWindow, WebviewWindowBuilder};
|
||||||
use tauri_plugin_window_state::AppHandleExt;
|
use tauri_plugin_window_state::AppHandleExt;
|
||||||
@@ -25,11 +22,6 @@ impl MainWindow {
|
|||||||
return Ok(Self(window));
|
return Ok(Self(window));
|
||||||
}
|
}
|
||||||
|
|
||||||
let wsl_enabled = get_wsl_config(app.clone())
|
|
||||||
.ok()
|
|
||||||
.map(|v| v.enabled)
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
let window_builder = base_window_config(
|
let window_builder = base_window_config(
|
||||||
WebviewWindowBuilder::new(app, Self::LABEL, WebviewUrl::App("/".into())),
|
WebviewWindowBuilder::new(app, Self::LABEL, WebviewUrl::App("/".into())),
|
||||||
app,
|
app,
|
||||||
@@ -44,7 +36,6 @@ impl MainWindow {
|
|||||||
r#"
|
r#"
|
||||||
window.__OPENCODE__ ??= {{}};
|
window.__OPENCODE__ ??= {{}};
|
||||||
window.__OPENCODE__.updaterEnabled = {UPDATER_ENABLED};
|
window.__OPENCODE__.updaterEnabled = {UPDATER_ENABLED};
|
||||||
window.__OPENCODE__.wsl = {wsl_enabled};
|
|
||||||
"#
|
"#
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,10 @@ export const commands = {
|
|||||||
awaitInitialization: (events: Channel) => __TAURI_INVOKE<ServerReadyData>("await_initialization", { events }),
|
awaitInitialization: (events: Channel) => __TAURI_INVOKE<ServerReadyData>("await_initialization", { events }),
|
||||||
getDefaultServerUrl: () => __TAURI_INVOKE<string | null>("get_default_server_url"),
|
getDefaultServerUrl: () => __TAURI_INVOKE<string | null>("get_default_server_url"),
|
||||||
setDefaultServerUrl: (url: string | null) => __TAURI_INVOKE<null>("set_default_server_url", { url }),
|
setDefaultServerUrl: (url: string | null) => __TAURI_INVOKE<null>("set_default_server_url", { url }),
|
||||||
getWslConfig: () => __TAURI_INVOKE<WslConfig>("get_wsl_config"),
|
|
||||||
setWslConfig: (config: WslConfig) => __TAURI_INVOKE<null>("set_wsl_config", { config }),
|
|
||||||
getDisplayBackend: () => __TAURI_INVOKE<"wayland" | "auto" | null>("get_display_backend"),
|
getDisplayBackend: () => __TAURI_INVOKE<"wayland" | "auto" | null>("get_display_backend"),
|
||||||
setDisplayBackend: (backend: LinuxDisplayBackend) => __TAURI_INVOKE<null>("set_display_backend", { backend }),
|
setDisplayBackend: (backend: LinuxDisplayBackend) => __TAURI_INVOKE<null>("set_display_backend", { backend }),
|
||||||
parseMarkdownCommand: (markdown: string) => __TAURI_INVOKE<string>("parse_markdown_command", { markdown }),
|
parseMarkdownCommand: (markdown: string) => __TAURI_INVOKE<string>("parse_markdown_command", { markdown }),
|
||||||
checkAppExists: (appName: string) => __TAURI_INVOKE<boolean>("check_app_exists", { appName }),
|
checkAppExists: (appName: string) => __TAURI_INVOKE<boolean>("check_app_exists", { appName }),
|
||||||
wslPath: (path: string, mode: "windows" | "linux" | null) => __TAURI_INVOKE<string>("wsl_path", { path, mode }),
|
|
||||||
resolveAppPath: (appName: string) => __TAURI_INVOKE<string | null>("resolve_app_path", { appName }),
|
resolveAppPath: (appName: string) => __TAURI_INVOKE<string | null>("resolve_app_path", { appName }),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,12 +34,6 @@ export type ServerReadyData = {
|
|||||||
password: string | null,
|
password: string | null,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WslConfig = {
|
|
||||||
enabled: boolean,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type WslPathMode = "windows" | "linux";
|
|
||||||
|
|
||||||
/* Tauri Specta runtime */
|
/* Tauri Specta runtime */
|
||||||
function makeEvent<T>(name: string) {
|
function makeEvent<T>(name: string) {
|
||||||
const base = {
|
const base = {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { open as shellOpen } from "@tauri-apps/plugin-shell"
|
|||||||
import { type as ostype } from "@tauri-apps/plugin-os"
|
import { type as ostype } from "@tauri-apps/plugin-os"
|
||||||
import { check, Update } from "@tauri-apps/plugin-updater"
|
import { check, Update } from "@tauri-apps/plugin-updater"
|
||||||
import { getCurrentWindow } from "@tauri-apps/api/window"
|
import { getCurrentWindow } from "@tauri-apps/api/window"
|
||||||
|
import { invoke } from "@tauri-apps/api/core"
|
||||||
import { isPermissionGranted, requestPermission } from "@tauri-apps/plugin-notification"
|
import { isPermissionGranted, requestPermission } from "@tauri-apps/plugin-notification"
|
||||||
import { relaunch } from "@tauri-apps/plugin-process"
|
import { relaunch } from "@tauri-apps/plugin-process"
|
||||||
import { AsyncStorage } from "@solid-primitives/storage"
|
import { AsyncStorage } from "@solid-primitives/storage"
|
||||||
@@ -29,7 +30,7 @@ import { UPDATER_ENABLED } from "./updater"
|
|||||||
import { initI18n, t } from "./i18n"
|
import { initI18n, t } from "./i18n"
|
||||||
import pkg from "../package.json"
|
import pkg from "../package.json"
|
||||||
import "./styles.css"
|
import "./styles.css"
|
||||||
import { commands, InitStep, type WslConfig } from "./bindings"
|
import { commands, InitStep } from "./bindings"
|
||||||
import { Channel } from "@tauri-apps/api/core"
|
import { Channel } from "@tauri-apps/api/core"
|
||||||
import { createMenu } from "./menu"
|
import { createMenu } from "./menu"
|
||||||
|
|
||||||
@@ -58,40 +59,22 @@ const listenForDeepLinks = async () => {
|
|||||||
await onOpenUrl((urls) => emitDeepLinks(urls)).catch(() => undefined)
|
await onOpenUrl((urls) => emitDeepLinks(urls)).catch(() => undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
const createPlatform = (password: Accessor<string | null>): Platform => {
|
const createPlatform = (password: Accessor<string | null>): Platform => ({
|
||||||
const os = (() => {
|
platform: "desktop",
|
||||||
|
os: (() => {
|
||||||
const type = ostype()
|
const type = ostype()
|
||||||
if (type === "macos" || type === "windows" || type === "linux") return type
|
if (type === "macos" || type === "windows" || type === "linux") return type
|
||||||
return undefined
|
return undefined
|
||||||
})()
|
})(),
|
||||||
|
|
||||||
const wslHome = async () => {
|
|
||||||
if (os !== "windows" || !window.__OPENCODE__?.wsl) return undefined
|
|
||||||
return commands.wslPath("~", "windows").catch(() => undefined)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleWslPicker = async <T extends string | string[]>(result: T | null): Promise<T | null> => {
|
|
||||||
if (!result || !window.__OPENCODE__?.wsl) return result
|
|
||||||
if (Array.isArray(result)) {
|
|
||||||
return Promise.all(result.map((path) => commands.wslPath(path, "linux").catch(() => path))) as any
|
|
||||||
}
|
|
||||||
return commands.wslPath(result, "linux").catch(() => result) as any
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
platform: "desktop",
|
|
||||||
os,
|
|
||||||
version: pkg.version,
|
version: pkg.version,
|
||||||
|
|
||||||
async openDirectoryPickerDialog(opts) {
|
async openDirectoryPickerDialog(opts) {
|
||||||
const defaultPath = await wslHome()
|
|
||||||
const result = await open({
|
const result = await open({
|
||||||
directory: true,
|
directory: true,
|
||||||
multiple: opts?.multiple ?? false,
|
multiple: opts?.multiple ?? false,
|
||||||
title: opts?.title ?? t("desktop.dialog.chooseFolder"),
|
title: opts?.title ?? t("desktop.dialog.chooseFolder"),
|
||||||
defaultPath,
|
|
||||||
})
|
})
|
||||||
return await handleWslPicker(result)
|
return result
|
||||||
},
|
},
|
||||||
|
|
||||||
async openFilePickerDialog(opts) {
|
async openFilePickerDialog(opts) {
|
||||||
@@ -100,7 +83,7 @@ const createPlatform = (password: Accessor<string | null>): Platform => {
|
|||||||
multiple: opts?.multiple ?? false,
|
multiple: opts?.multiple ?? false,
|
||||||
title: opts?.title ?? t("desktop.dialog.chooseFile"),
|
title: opts?.title ?? t("desktop.dialog.chooseFile"),
|
||||||
})
|
})
|
||||||
return handleWslPicker(result)
|
return result
|
||||||
},
|
},
|
||||||
|
|
||||||
async saveFilePickerDialog(opts) {
|
async saveFilePickerDialog(opts) {
|
||||||
@@ -108,25 +91,18 @@ const createPlatform = (password: Accessor<string | null>): Platform => {
|
|||||||
title: opts?.title ?? t("desktop.dialog.saveFile"),
|
title: opts?.title ?? t("desktop.dialog.saveFile"),
|
||||||
defaultPath: opts?.defaultPath,
|
defaultPath: opts?.defaultPath,
|
||||||
})
|
})
|
||||||
return handleWslPicker(result)
|
return result
|
||||||
},
|
},
|
||||||
|
|
||||||
openLink(url: string) {
|
openLink(url: string) {
|
||||||
void shellOpen(url).catch(() => undefined)
|
void shellOpen(url).catch(() => undefined)
|
||||||
},
|
},
|
||||||
|
|
||||||
async openPath(path: string, app?: string) {
|
async openPath(path: string, app?: string) {
|
||||||
const os = ostype()
|
const os = ostype()
|
||||||
if (os === "windows") {
|
if (os === "windows" && app) {
|
||||||
const resolvedApp = (app && (await commands.resolveAppPath(app))) || app
|
const resolvedApp = await commands.resolveAppPath(app)
|
||||||
const resolvedPath = await (async () => {
|
return openerOpenPath(path, resolvedApp || app)
|
||||||
if (window.__OPENCODE__?.wsl) {
|
|
||||||
const converted = await commands.wslPath(path, "windows").catch(() => null)
|
|
||||||
if (converted) return converted
|
|
||||||
}
|
|
||||||
|
|
||||||
return path
|
|
||||||
})()
|
|
||||||
return openerOpenPath(resolvedPath, resolvedApp)
|
|
||||||
}
|
}
|
||||||
return openerOpenPath(path, app)
|
return openerOpenPath(path, app)
|
||||||
},
|
},
|
||||||
@@ -366,16 +342,6 @@ const createPlatform = (password: Accessor<string | null>): Platform => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getWslEnabled: async () => {
|
|
||||||
const next = await commands.getWslConfig().catch(() => null)
|
|
||||||
if (next) return next.enabled
|
|
||||||
return window.__OPENCODE__!.wsl ?? false
|
|
||||||
},
|
|
||||||
|
|
||||||
setWslEnabled: async (enabled) => {
|
|
||||||
await commands.setWslConfig({ enabled })
|
|
||||||
},
|
|
||||||
|
|
||||||
getDefaultServerUrl: async () => {
|
getDefaultServerUrl: async () => {
|
||||||
const result = await commands.getDefaultServerUrl().catch(() => null)
|
const result = await commands.getDefaultServerUrl().catch(() => null)
|
||||||
return result
|
return result
|
||||||
@@ -386,12 +352,12 @@ const createPlatform = (password: Accessor<string | null>): Platform => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getDisplayBackend: async () => {
|
getDisplayBackend: async () => {
|
||||||
const result = await commands.getDisplayBackend().catch(() => null)
|
const result = await invoke<DisplayBackend | null>("get_display_backend").catch(() => null)
|
||||||
return result
|
return result
|
||||||
},
|
},
|
||||||
|
|
||||||
setDisplayBackend: async (backend) => {
|
setDisplayBackend: async (backend) => {
|
||||||
await commands.setDisplayBackend(backend)
|
await invoke("set_display_backend", { backend }).catch(() => undefined)
|
||||||
},
|
},
|
||||||
|
|
||||||
parseMarkdown: (markdown: string) => commands.parseMarkdownCommand(markdown),
|
parseMarkdown: (markdown: string) => commands.parseMarkdownCommand(markdown),
|
||||||
@@ -424,8 +390,7 @@ const createPlatform = (password: Accessor<string | null>): Platform => {
|
|||||||
}, "image/png")
|
}, "image/png")
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
}
|
|
||||||
|
|
||||||
let menuTrigger = null as null | ((id: string) => void)
|
let menuTrigger = null as null | ((id: string) => void)
|
||||||
createMenu((id) => {
|
createMenu((id) => {
|
||||||
@@ -435,7 +400,6 @@ void listenForDeepLinks()
|
|||||||
|
|
||||||
render(() => {
|
render(() => {
|
||||||
const [serverPassword, setServerPassword] = createSignal<string | null>(null)
|
const [serverPassword, setServerPassword] = createSignal<string | null>(null)
|
||||||
|
|
||||||
const platform = createPlatform(() => serverPassword())
|
const platform = createPlatform(() => serverPassword())
|
||||||
|
|
||||||
function handleClick(e: MouseEvent) {
|
function handleClick(e: MouseEvent) {
|
||||||
|
|||||||
Reference in New Issue
Block a user