mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 12:44:18 +08:00
feat: add lightweight mode (#1739)
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
#[tauri::command]
|
||||
pub fn enter_lightweight_mode(app: tauri::AppHandle) -> Result<(), String> {
|
||||
crate::lightweight::enter_lightweight_mode(&app)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn exit_lightweight_mode(app: tauri::AppHandle) -> Result<(), String> {
|
||||
crate::lightweight::exit_lightweight_mode(&app)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn is_lightweight_mode() -> bool {
|
||||
crate::lightweight::is_lightweight_mode()
|
||||
}
|
||||
@@ -25,6 +25,7 @@ mod sync_support;
|
||||
mod usage;
|
||||
mod webdav_sync;
|
||||
mod workspace;
|
||||
mod lightweight;
|
||||
|
||||
pub use auth::*;
|
||||
pub use config::*;
|
||||
@@ -50,3 +51,4 @@ pub use stream_check::*;
|
||||
pub use usage::*;
|
||||
pub use webdav_sync::*;
|
||||
pub use workspace::*;
|
||||
pub use lightweight::*;
|
||||
|
||||
@@ -12,6 +12,7 @@ mod error;
|
||||
mod gemini_config;
|
||||
mod gemini_mcp;
|
||||
mod init_status;
|
||||
mod lightweight;
|
||||
mod mcp;
|
||||
mod openclaw_config;
|
||||
mod opencode_config;
|
||||
@@ -204,6 +205,12 @@ pub fn run() {
|
||||
log::debug!(" arg[{i}]: {}", redact_url_for_log(arg));
|
||||
}
|
||||
|
||||
if crate::lightweight::is_lightweight_mode() {
|
||||
if let Err(e) = crate::lightweight::exit_lightweight_mode(app) {
|
||||
log::error!("退出轻量模式重建窗口失败: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
// Check for deep link URL in args (mainly for Windows/Linux command line)
|
||||
let mut found_deeplink = false;
|
||||
for arg in &args {
|
||||
@@ -615,6 +622,12 @@ pub fn run() {
|
||||
let urls = event.urls();
|
||||
log::info!("Received {} URL(s)", urls.len());
|
||||
|
||||
if crate::lightweight::is_lightweight_mode() {
|
||||
if let Err(e) = crate::lightweight::exit_lightweight_mode(&app_handle) {
|
||||
log::error!("退出轻量模式重建窗口失败: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
for (i, url) in urls.iter().enumerate() {
|
||||
let url_str = url.as_str();
|
||||
log::debug!(" URL[{i}]: {}", redact_url_for_log(url_str));
|
||||
@@ -1085,6 +1098,10 @@ pub fn run() {
|
||||
commands::delete_daily_memory_file,
|
||||
commands::search_daily_memory_files,
|
||||
commands::open_workspace_directory,
|
||||
// lightweight mode (for testing or low-resource environments)
|
||||
commands::enter_lightweight_mode,
|
||||
commands::exit_lightweight_mode,
|
||||
commands::is_lightweight_mode,
|
||||
]);
|
||||
|
||||
let app = builder
|
||||
@@ -1135,6 +1152,10 @@ pub fn run() {
|
||||
let _ = window.show();
|
||||
let _ = window.set_focus();
|
||||
tray::apply_tray_policy(app_handle, true);
|
||||
} else if crate::lightweight::is_lightweight_mode() {
|
||||
if let Err(e) = crate::lightweight::exit_lightweight_mode(app_handle) {
|
||||
log::error!("退出轻量模式重建窗口失败: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
// 处理通过自定义 URL 协议触发的打开事件(例如 ccswitch://...)
|
||||
@@ -1144,6 +1165,13 @@ pub fn run() {
|
||||
log::info!("RunEvent::Opened with URL: {url_str}");
|
||||
|
||||
if url_str.starts_with("ccswitch://") {
|
||||
if crate::lightweight::is_lightweight_mode() {
|
||||
if let Err(e) = crate::lightweight::exit_lightweight_mode(app_handle)
|
||||
{
|
||||
log::error!("退出轻量模式重建窗口失败: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
// 解析并广播深链接事件,复用与 single_instance 相同的逻辑
|
||||
match crate::deeplink::parse_deeplink_url(&url_str) {
|
||||
Ok(request) => {
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use tauri::Manager;
|
||||
|
||||
static LIGHTWEIGHT_MODE: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
pub fn enter_lightweight_mode(app: &tauri::AppHandle) -> Result<(), String> {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.set_skip_taskbar(true);
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
crate::tray::apply_tray_policy(app, false);
|
||||
}
|
||||
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
window
|
||||
.destroy()
|
||||
.map_err(|e| format!("销毁主窗口失败: {e}"))?;
|
||||
}
|
||||
// else: already in lightweight mode or window not found, just set the flag
|
||||
|
||||
LIGHTWEIGHT_MODE.store(true, Ordering::Release);
|
||||
crate::tray::refresh_tray_menu(app);
|
||||
log::info!("进入轻量模式");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn exit_lightweight_mode(app: &tauri::AppHandle) -> Result<(), String> {
|
||||
use tauri::WebviewWindowBuilder;
|
||||
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.unminimize();
|
||||
let _ = window.show();
|
||||
let _ = window.set_focus();
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let _ = window.set_skip_taskbar(false);
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
crate::tray::apply_tray_policy(app, true);
|
||||
}
|
||||
LIGHTWEIGHT_MODE.store(false, Ordering::Release);
|
||||
crate::tray::refresh_tray_menu(app);
|
||||
log::info!("退出轻量模式");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let window_config = app
|
||||
.config()
|
||||
.app
|
||||
.windows
|
||||
.iter()
|
||||
.find(|w| w.label == "main")
|
||||
.ok_or("主窗口配置未找到")?;
|
||||
|
||||
WebviewWindowBuilder::from_config(app, window_config)
|
||||
.map_err(|e| format!("加载主窗口配置失败: {e}"))?
|
||||
.visible(true)
|
||||
.build()
|
||||
.map_err(|e| format!("创建主窗口失败: {e}"))?;
|
||||
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.set_focus();
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.set_skip_taskbar(false);
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
crate::tray::apply_tray_policy(app, true);
|
||||
}
|
||||
|
||||
LIGHTWEIGHT_MODE.store(false, Ordering::Release);
|
||||
crate::tray::refresh_tray_menu(app);
|
||||
log::info!("退出轻量模式");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_lightweight_mode() -> bool {
|
||||
LIGHTWEIGHT_MODE.load(Ordering::Acquire)
|
||||
}
|
||||
@@ -14,6 +14,7 @@ use crate::store::AppState;
|
||||
pub struct TrayTexts {
|
||||
pub show_main: &'static str,
|
||||
pub no_provider_hint: &'static str,
|
||||
pub lightweight_mode: &'static str,
|
||||
pub quit: &'static str,
|
||||
pub _auto_label: &'static str,
|
||||
}
|
||||
@@ -24,6 +25,7 @@ impl TrayTexts {
|
||||
"en" => Self {
|
||||
show_main: "Open main window",
|
||||
no_provider_hint: " (No providers yet, please add them from the main window)",
|
||||
lightweight_mode: "Lightweight Mode",
|
||||
quit: "Quit",
|
||||
_auto_label: "Auto (Failover)",
|
||||
},
|
||||
@@ -31,12 +33,14 @@ impl TrayTexts {
|
||||
show_main: "メインウィンドウを開く",
|
||||
no_provider_hint:
|
||||
" (プロバイダーがまだありません。メイン画面から追加してください)",
|
||||
lightweight_mode: "軽量モード",
|
||||
quit: "終了",
|
||||
_auto_label: "自動 (フェイルオーバー)",
|
||||
},
|
||||
_ => Self {
|
||||
show_main: "打开主界面",
|
||||
no_provider_hint: " (无供应商,请在主界面添加)",
|
||||
lightweight_mode: "轻量模式",
|
||||
quit: "退出",
|
||||
_auto_label: "自动 (故障转移)",
|
||||
},
|
||||
@@ -382,6 +386,19 @@ pub fn create_tray_menu(
|
||||
menu_builder = menu_builder.separator();
|
||||
}
|
||||
|
||||
let lightweight_item = CheckMenuItem::with_id(
|
||||
app,
|
||||
"lightweight_mode",
|
||||
tray_texts.lightweight_mode,
|
||||
true,
|
||||
crate::lightweight::is_lightweight_mode(),
|
||||
None::<&str>,
|
||||
).map_err(|e| AppError::Message(format!("创建轻量模式菜单失败: {e}")))?;
|
||||
|
||||
menu_builder = menu_builder
|
||||
.item(&lightweight_item)
|
||||
.separator();
|
||||
|
||||
// 退出菜单(分隔符已在上面的 section 循环中添加)
|
||||
let quit_item = MenuItem::with_id(app, "quit", tray_texts.quit, true, None::<&str>)
|
||||
.map_err(|e| AppError::Message(format!("创建退出菜单失败: {e}")))?;
|
||||
@@ -393,6 +410,20 @@ pub fn create_tray_menu(
|
||||
.map_err(|e| AppError::Message(format!("构建菜单失败: {e}")))
|
||||
}
|
||||
|
||||
pub fn refresh_tray_menu(app: &tauri::AppHandle) {
|
||||
use crate::store::AppState;
|
||||
|
||||
if let Some(state) = app.try_state::<AppState>() {
|
||||
if let Ok(new_menu) = create_tray_menu(app, state.inner()) {
|
||||
if let Some(tray) = app.tray_by_id("main") {
|
||||
if let Err(e) = tray.set_menu(Some(new_menu)) {
|
||||
log::error!("刷新托盘菜单失败: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn apply_tray_policy(app: &tauri::AppHandle, dock_visible: bool) {
|
||||
use tauri::ActivationPolicy;
|
||||
@@ -430,6 +461,21 @@ pub fn handle_tray_menu_event(app: &tauri::AppHandle, event_id: &str) {
|
||||
{
|
||||
apply_tray_policy(app, true);
|
||||
}
|
||||
} else if crate::lightweight::is_lightweight_mode() {
|
||||
if let Err(e) = crate::lightweight::exit_lightweight_mode(app) {
|
||||
log::error!("退出轻量模式重建窗口失败: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
"lightweight_mode" => {
|
||||
if crate::lightweight::is_lightweight_mode() {
|
||||
if let Err(e) = crate::lightweight::exit_lightweight_mode(app) {
|
||||
log::error!("退出轻量模式失败: {e}");
|
||||
}
|
||||
} else {
|
||||
if let Err(e) = crate::lightweight::enter_lightweight_mode(app) {
|
||||
log::error!("进入轻量模式失败: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
"quit" => {
|
||||
|
||||
Reference in New Issue
Block a user