diff --git a/README.md b/README.md index 66452c0..3ad9501 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ **Latest:** -- `Mac`: [ChatGPT_0.1.7_x64.dmg](https://github.com/lencx/ChatGPT/releases/download/v0.1.7/ChatGPT_0.1.7_x64.dmg) -- `Linux`: [chat-gpt_0.1.7_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.1.7/chat-gpt_0.1.7_amd64.deb) -- `Windows`: [ChatGPT_0.1.7_x64_en-US.msi](https://github.com/lencx/ChatGPT/releases/download/v0.1.7/ChatGPT_0.1.7_x64_en-US.msi) +- `Mac`: [ChatGPT_0.1.8_x64.dmg](https://github.com/lencx/ChatGPT/releases/download/v0.1.8/ChatGPT_0.1.8_x64.dmg) +- `Linux`: [chat-gpt_0.1.8_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.1.8/chat-gpt_0.1.8_amd64.deb) +- `Windows`: [ChatGPT_0.1.8_x64_en-US.msi](https://github.com/lencx/ChatGPT/releases/download/v0.1.8/ChatGPT_0.1.8_x64_en-US.msi) [Other version...](https://github.com/lencx/ChatGPT/releases) @@ -52,6 +52,23 @@ cask "popcorn-time", args: { "no-quarantine": true } - tray window - shortcut +### Menu + +- **ChatGPT** + - `Restart ChatGPT`: After editing the injection script file, you can restart the application through this menu item to make the script take effect. +- **Preferences** + - `Theme` - `Light`, `Dark` (Only macOS and Windows are supported). + - `Always On Top`: Window is always on top of other windows. + - `Titlebar`: Only supports macOS. + - `Switch Origin` ([#14](https://github.com/lencx/ChatGPT/issues/14)): Modify website address, the default is `https://chat.openai.com`. Please ensure that the mirror address is consistent with the UI of the original URL, otherwise the export function will fail. + - `Inject Script`: User scripts that can modify web pages. + - `Awesome ChatGPT`: Related resources recommended. +- **Edit** - `Undo`, `Redo`, `Cut`, `Copy`, `SelectAll`, ... +- **View** - `Go Back`, `Go Forward`, `Scroll to Top of Screen`, `Scroll to Bottom of Screen`, `Refresh the Screen`, ... +- **Help** + - `Report Bug`: Defects and Suggestions Feedback. + - `Toggle Developer Tools`: Developer tools for debugging web pages. + ## Preview install chat diff --git a/UPDATE_LOG.md b/UPDATE_LOG.md index faccfd8..d077fcf 100644 --- a/UPDATE_LOG.md +++ b/UPDATE_LOG.md @@ -1,5 +1,11 @@ # UPDATE LOG +## v0.1.8 + +feat: +- menu enhancement: theme, titlebar +- modify website address + ## v0.1.7 feat: tray window diff --git a/package.json b/package.json index a3651b0..79f4083 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,15 @@ }, "license": "MIT", "author": "lencx ", - "keywords": ["chatgpt", "app", "desktop", "tauri", "macos", "linux", "windows"], + "keywords": [ + "chatgpt", + "app", + "desktop", + "tauri", + "macos", + "linux", + "windows" + ], "homepage": "https://github.com/lencx/ChatGPT", "bugs": "https://github.com/lencx/ChatGPT/issues", "repository": { diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 47bb13b..1e861a8 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -14,11 +14,11 @@ rust-version = "1.57" tauri-build = {version = "1.2.1", features = [] } [dependencies] +anyhow = "1.0.66" serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } -tauri = { version = "1.2.1", features = ["api-all", "devtools", "system-tray", "updater"] } +tauri = { version = "1.2.2", features = ["api-all", "devtools", "system-tray", "updater"] } tauri-plugin-positioner = { version = "1.0.4", features = ["system-tray"] } -anyhow = "1.0.66" [features] # by default Tauri runs in production mode diff --git a/src-tauri/icons/tray-icon.png b/src-tauri/icons/tray-icon.png new file mode 100644 index 0000000..81d2aeb Binary files /dev/null and b/src-tauri/icons/tray-icon.png differ diff --git a/src-tauri/src/app/cmd.rs b/src-tauri/src/app/cmd.rs index 1003ce1..4c883c7 100644 --- a/src-tauri/src/app/cmd.rs +++ b/src-tauri/src/app/cmd.rs @@ -1,4 +1,4 @@ -use crate::utils; +use crate::{conf::ChatConfJson, utils}; use std::fs; use tauri::{api, command, AppHandle, Manager}; @@ -28,3 +28,35 @@ pub fn download(_app: AppHandle, name: String, blob: Vec) { pub fn open_link(app: AppHandle, url: String) { api::shell::open(&app.shell_scope(), url, None).unwrap(); } + +#[command] +pub fn get_chat_conf() -> ChatConfJson { + ChatConfJson::get_chat_conf() +} + +#[command] +pub fn form_confirm(app: AppHandle, data: serde_json::Value) { + ChatConfJson::amend(&serde_json::json!(data)).unwrap(); + tauri::api::process::restart(&app.env()); +} + +#[command] +pub fn form_cancel(app: AppHandle, label: &str, title: &str, msg: &str) { + let win = app.app_handle().get_window(label).unwrap(); + tauri::api::dialog::ask( + app.app_handle().get_window(label).as_ref(), + title, + msg, + move |is_cancel| { + if is_cancel { + win.close().unwrap(); + } + }, + ); +} + +#[command] +pub fn form_msg(app: AppHandle, label: &str, title: &str, msg: &str) { + let win = app.app_handle().get_window(label); + tauri::api::dialog::message(win.as_ref(), title, msg); +} diff --git a/src-tauri/src/app/menu.rs b/src-tauri/src/app/menu.rs index ef88c3f..bc23916 100644 --- a/src-tauri/src/app/menu.rs +++ b/src-tauri/src/app/menu.rs @@ -1,4 +1,8 @@ -use crate::{conf, utils}; +use crate::{ + app::window, + conf::{self, ChatConfJson}, + utils, +}; use tauri::{ utils::assets::EmbeddedAssets, AboutMetadata, AppHandle, Context, CustomMenuItem, Manager, Menu, MenuItem, Submenu, SystemTray, SystemTrayEvent, SystemTrayMenu, WindowMenuEvent, @@ -6,13 +10,19 @@ use tauri::{ use tauri_plugin_positioner::{on_tray_event, Position, WindowExt}; // --- Menu -pub fn init(chat_conf: &conf::ChatConfJson, context: &Context) -> Menu { +pub fn init(context: &Context) -> Menu { + let chat_conf = ChatConfJson::get_chat_conf(); let name = &context.package_info().name; let app_menu = Submenu::new( name, Menu::new() .add_native_item(MenuItem::About(name.into(), AboutMetadata::default())) .add_native_item(MenuItem::Separator) + .add_item( + CustomMenuItem::new("restart".to_string(), "Restart ChatGPT") + .accelerator("CmdOrCtrl+Shift+R"), + ) + .add_native_item(MenuItem::Services) .add_native_item(MenuItem::Separator) .add_native_item(MenuItem::Hide) .add_native_item(MenuItem::HideOthers) @@ -23,24 +33,55 @@ pub fn init(chat_conf: &conf::ChatConfJson, context: &Context) - let always_on_top = CustomMenuItem::new("always_on_top".to_string(), "Always On Top") .accelerator("CmdOrCtrl+T"); + let titlebar = + CustomMenuItem::new("titlebar".to_string(), "Titlebar").accelerator("CmdOrCtrl+B"); + let theme_light = CustomMenuItem::new("theme_light".to_string(), "Light"); + let theme_dark = CustomMenuItem::new("theme_dark".to_string(), "Dark"); + let is_dark = chat_conf.theme == "Dark"; + + let always_on_top_menu = if chat_conf.always_on_top { + always_on_top.selected() + } else { + always_on_top + }; + let titlebar_menu = if chat_conf.titlebar { + titlebar.selected() + } else { + titlebar + }; let preferences_menu = Submenu::new( "Preferences", - Menu::new() - .add_item( - CustomMenuItem::new("inject_script".to_string(), "Inject Script") - .accelerator("CmdOrCtrl+J"), + Menu::with_items([ + Submenu::new( + "Theme", + Menu::new() + .add_item(if is_dark { + theme_light + } else { + theme_light.selected() + }) + .add_item(if is_dark { + theme_dark.selected() + } else { + theme_dark + }), ) - .add_item(if chat_conf.always_on_top { - always_on_top.selected() - } else { - always_on_top - }) - .add_native_item(MenuItem::Separator) - .add_item( - CustomMenuItem::new("awesome".to_string(), "Awesome ChatGPT") - .accelerator("CmdOrCtrl+Z"), - ), + .into(), + always_on_top_menu.into(), + #[cfg(target_os = "macos")] + titlebar_menu.into(), + CustomMenuItem::new("switch_origin".to_string(), "Switch Origin") + .accelerator("CmdOrCtrl+O") + .into(), + CustomMenuItem::new("inject_script".to_string(), "Inject Script") + .accelerator("CmdOrCtrl+J") + .into(), + MenuItem::Separator.into(), + CustomMenuItem::new("awesome".to_string(), "Awesome ChatGPT") + .accelerator("CmdOrCtrl+Z") + .into(), + ]), ); let edit_menu = Submenu::new( @@ -73,6 +114,7 @@ pub fn init(chat_conf: &conf::ChatConfJson, context: &Context) - CustomMenuItem::new("scroll_bottom".to_string(), "Scroll to Bottom of Screen") .accelerator("CmdOrCtrl+Down"), ) + .add_native_item(MenuItem::Zoom) .add_native_item(MenuItem::Separator) .add_item( CustomMenuItem::new("reload".to_string(), "Refresh the Screen") @@ -110,9 +152,29 @@ pub fn menu_handler(event: WindowMenuEvent) { let menu_handle = core_window.menu_handle(); match menu_id { + // App + "restart" => tauri::api::process::restart(&app.env()), // Preferences "inject_script" => open(&app, script_path), "awesome" => open(&app, conf::AWESOME_URL.to_string()), + "switch_origin" => { + window::origin_window(&app); + // app.get_window("origin").unwrap().show(); + } + "titlebar" => { + let chat_conf = conf::ChatConfJson::get_chat_conf(); + ChatConfJson::amend(&serde_json::json!({ "titlebar": !chat_conf.titlebar })).unwrap(); + tauri::api::process::restart(&app.env()); + } + "theme_light" | "theme_dark" => { + let theme = if menu_id == "theme_dark" { + "Dark" + } else { + "Light" + }; + ChatConfJson::amend(&serde_json::json!({ "theme": theme })).unwrap(); + tauri::api::process::restart(&app.env()); + } "always_on_top" => { let mut always_on_top = state.always_on_top.lock().unwrap(); *always_on_top = !*always_on_top; @@ -121,7 +183,7 @@ pub fn menu_handler(event: WindowMenuEvent) { .set_selected(*always_on_top) .unwrap(); win.set_always_on_top(*always_on_top).unwrap(); - conf::ChatConfJson::update_chat_conf(*always_on_top); + ChatConfJson::amend(&serde_json::json!({ "always_on_top": *always_on_top })).unwrap(); } // View "reload" => win.eval("window.location.reload()").unwrap(), diff --git a/src-tauri/src/app/setup.rs b/src-tauri/src/app/setup.rs index 84cdc5a..3418a8f 100644 --- a/src-tauri/src/app/setup.rs +++ b/src-tauri/src/app/setup.rs @@ -1,15 +1,14 @@ -use crate::{app::window, conf, utils}; +use crate::{ + app::window, + conf::{ChatConfJson, USER_AGENT}, + utils, +}; use tauri::{utils::config::WindowUrl, window::WindowBuilder, App, Manager}; -#[cfg(target_os = "macos")] -use tauri::TitleBarStyle; - -pub fn init( - app: &mut App, - chat_conf: conf::ChatConfJson, -) -> std::result::Result<(), Box> { - let conf = utils::get_tauri_conf().unwrap(); - let url = conf.build.dev_path.to_string(); +pub fn init(app: &mut App) -> std::result::Result<(), Box> { + let chat_conf = ChatConfJson::get_chat_conf(); + let url = chat_conf.origin.to_string(); + let theme = ChatConfJson::theme(); window::mini_window(&app.app_handle()); #[cfg(target_os = "macos")] @@ -18,14 +17,15 @@ pub fn init( .fullscreen(false) .inner_size(800.0, 600.0) .hidden_title(true) - .title_bar_style(TitleBarStyle::Overlay) + .theme(theme) .always_on_top(chat_conf.always_on_top) + .title_bar_style(ChatConfJson::titlebar()) .initialization_script(&utils::user_script()) .initialization_script(include_str!("../assets/html2canvas.js")) .initialization_script(include_str!("../assets/jspdf.js")) .initialization_script(include_str!("../assets/core.js")) .initialization_script(include_str!("../assets/export.js")) - .user_agent(conf::USER_AGENT) + .user_agent(USER_AGENT) .build()?; #[cfg(not(target_os = "macos"))] @@ -34,13 +34,14 @@ pub fn init( .resizable(true) .fullscreen(false) .inner_size(800.0, 600.0) + .theme(theme) .always_on_top(chat_conf.always_on_top) .initialization_script(&utils::user_script()) .initialization_script(include_str!("../assets/html2canvas.js")) .initialization_script(include_str!("../assets/jspdf.js")) .initialization_script(include_str!("../assets/core.js")) .initialization_script(include_str!("../assets/export.js")) - .user_agent(conf::USER_AGENT) + .user_agent(USER_AGENT) .build()?; Ok(()) diff --git a/src-tauri/src/app/window.rs b/src-tauri/src/app/window.rs index e969d71..2fc6af3 100644 --- a/src-tauri/src/app/window.rs +++ b/src-tauri/src/app/window.rs @@ -2,24 +2,40 @@ use crate::{conf, utils}; use tauri::{utils::config::WindowUrl, window::WindowBuilder}; pub fn mini_window(handle: &tauri::AppHandle) { - let conf = utils::get_tauri_conf().unwrap(); - let url = conf.build.dev_path.to_string(); + let chat_conf = conf::ChatConfJson::get_chat_conf(); + let theme = conf::ChatConfJson::theme(); - WindowBuilder::new(handle, "mini", WindowUrl::App(url.into())) + WindowBuilder::new(handle, "mini", WindowUrl::App(chat_conf.origin.into())) .resizable(false) .fullscreen(false) .inner_size(360.0, 540.0) .decorations(false) .always_on_top(true) + .theme(theme) .initialization_script(&utils::user_script()) .initialization_script(include_str!("../assets/html2canvas.js")) .initialization_script(include_str!("../assets/jspdf.js")) .initialization_script(include_str!("../assets/core.js")) .initialization_script(include_str!("../assets/export.js")) .user_agent(conf::PHONE_USER_AGENT) - .menu(tauri::Menu::new()) .build() .unwrap() .hide() .unwrap(); } + +pub fn origin_window(handle: &tauri::AppHandle) { + let chat_conf = conf::ChatConfJson::get_chat_conf(); + // tauri://localhost/origin + // let url = chat_conf.origin; + WindowBuilder::new(handle, "origin", WindowUrl::App(chat_conf.origin.into())) + .resizable(false) + .fullscreen(false) + .inner_size(400.0, 300.0) + .always_on_top(true) + .decorations(false) + .initialization_script(include_str!("../assets/core.js")) + .initialization_script(include_str!("../assets/origin.js")) + .build() + .unwrap(); +} diff --git a/src-tauri/src/assets/core.js b/src-tauri/src/assets/core.js index fe79a00..854b1aa 100644 --- a/src-tauri/src/assets/core.js +++ b/src-tauri/src/assets/core.js @@ -54,7 +54,8 @@ async function init() { } const _platform = await platform(); - if (/darwin/.test(_platform)) { + const chatConf = await invoke('get_chat_conf') || {}; + if (/darwin/.test(_platform) && !chatConf.titlebar) { const topStyleDom = document.createElement("style"); topStyleDom.innerHTML = `#chatgpt-app-window-top{position:fixed;top:0;z-index:999999999;width:100%;height:24px;background:transparent;cursor:grab;cursor:-webkit-grab;user-select:none;-webkit-user-select:none;}#chatgpt-app-window-top:active {cursor:grabbing;cursor:-webkit-grabbing;}`; document.head.appendChild(topStyleDom); @@ -70,7 +71,7 @@ async function init() { document.addEventListener("click", (e) => { const origin = e.target.closest("a"); if (origin && origin.href && origin.target !== '_self') { - origin.target = "_self"; + invoke('open_link', { url: origin.href }); } }); diff --git a/src-tauri/src/assets/export.js b/src-tauri/src/assets/export.js index 819675a..41a1851 100644 --- a/src-tauri/src/assets/export.js +++ b/src-tauri/src/assets/export.js @@ -2,6 +2,7 @@ // @ref: https://github.com/liady/ChatGPT-pdf/blob/main/src/content_script.js async function init() { + const chatConf = await invoke('get_chat_conf') || {}; if (window.buttonsInterval) { clearInterval(window.buttonsInterval); } @@ -16,7 +17,7 @@ async function init() { }); if (hasTryAgainButton && buttons.length === 1) { const TryAgainButton = actionsArea.querySelector("button"); - addActionsButtons(actionsArea, TryAgainButton); + addActionsButtons(actionsArea, TryAgainButton, chatConf); } else if (!hasTryAgainButton) { removeButtons(); } @@ -28,7 +29,7 @@ const Format = { PDF: "pdf", }; -function addActionsButtons(actionsArea, TryAgainButton) { +function addActionsButtons(actionsArea, TryAgainButton, chatConf) { const downloadButton = TryAgainButton.cloneNode(true); downloadButton.id = "download-png-button"; downloadButton.innerText = "Generate PNG"; @@ -36,6 +37,7 @@ function addActionsButtons(actionsArea, TryAgainButton) { downloadThread(); }; actionsArea.appendChild(downloadButton); + const downloadPdfButton = TryAgainButton.cloneNode(true); downloadPdfButton.id = "download-pdf-button"; downloadPdfButton.innerText = "Download PDF"; @@ -43,13 +45,16 @@ function addActionsButtons(actionsArea, TryAgainButton) { downloadThread({ as: Format.PDF }); }; actionsArea.appendChild(downloadPdfButton); - const exportHtml = TryAgainButton.cloneNode(true); - exportHtml.id = "download-html-button"; - exportHtml.innerText = "Share Link"; - exportHtml.onclick = () => { - sendRequest(); - }; - actionsArea.appendChild(exportHtml); + + if (new RegExp('//chat.openai.com').test(chatConf.origin)) { + const exportHtml = TryAgainButton.cloneNode(true); + exportHtml.id = "download-html-button"; + exportHtml.innerText = "Share Link"; + exportHtml.onclick = () => { + sendRequest(); + }; + actionsArea.appendChild(exportHtml); + } } function removeButtons() { diff --git a/src-tauri/src/assets/origin.js b/src-tauri/src/assets/origin.js new file mode 100644 index 0000000..4220086 --- /dev/null +++ b/src-tauri/src/assets/origin.js @@ -0,0 +1,77 @@ +function init() { + document.body.innerHTML = ` +

Switch Origin

+ +
+ + +
`; + + const srcipt = document.createElement('script'); + srcipt.innerHTML = `const input = document.getElementById('input'); + const cancelBtn = document.getElementById('cancel'); + const confirmBtn = document.getElementById('confirm'); + cancelBtn.addEventListener('click', () => { + window.invoke('form_cancel', { label: 'origin', title: 'Switch Origin', msg: 'Sure you want to give up the switch?' }); + }) + confirmBtn.addEventListener('click', () => { + if (/^https?:\\/\\//.test(input.value)) { + window.invoke('form_confirm', { data: { origin: input.value } }); + } else { + window.invoke('form_msg', { label: 'origin', title: 'Switch Origin', msg: 'Invalid URL!' }); + } + })`; + document.head.appendChild(srcipt); +} + +// run init +if ( + document.readyState === "complete" || + document.readyState === "interactive" +) { + init(); +} else { + document.addEventListener("DOMContentLoaded", init); +} \ No newline at end of file diff --git a/src-tauri/src/conf.rs b/src-tauri/src/conf.rs index 8486d05..12e5179 100644 --- a/src-tauri/src/conf.rs +++ b/src-tauri/src/conf.rs @@ -1,19 +1,30 @@ use crate::utils::{chat_root, create_file, exists}; -use std::fs; -use std::path::PathBuf; -use std::sync::Mutex; +use anyhow::Result; +use serde_json::Value; +use std::{collections::BTreeMap, fs, path::PathBuf, sync::Mutex}; +use tauri::Theme; + +#[cfg(target_os = "macos")] +use tauri::TitleBarStyle; pub const USER_AGENT: &str = "5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"; pub const PHONE_USER_AGENT: &str = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"; pub const ISSUES_URL: &str = "https://github.com/lencx/ChatGPT/issues"; pub const AWESOME_URL: &str = "https://github.com/lencx/ChatGPT/blob/main/AWESOME.md"; +pub const DEFAULT_CHAT_CONF: &str = r#"{ + "always_on_top": false, + "theme": "Light", + "titlebar": true, + "default_origin": "https://chat.openai.com", + "origin": "https://chat.openai.com" +}"#; pub struct ChatState { pub always_on_top: Mutex, } impl ChatState { - pub fn default(chat_conf: &ChatConfJson) -> Self { + pub fn default(chat_conf: ChatConfJson) -> Self { ChatState { always_on_top: Mutex::new(chat_conf.always_on_top), } @@ -23,6 +34,10 @@ impl ChatState { #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] pub struct ChatConfJson { pub always_on_top: bool, + pub theme: String, + pub titlebar: bool, + pub default_origin: String, + pub origin: String, } impl ChatConfJson { @@ -32,7 +47,22 @@ impl ChatConfJson { let conf_file = ChatConfJson::conf_path(); if !exists(&conf_file) { create_file(&conf_file).unwrap(); - fs::write(&conf_file, r#"{"always_on_top": false}"#).unwrap(); + + #[cfg(target_os = "macos")] + fs::write( + &conf_file, + r#"{ + "always_on_top": false, + "theme": "Light", + "titlebar": false, + "default_origin": "https://chat.openai.com", + "origin": "https://chat.openai.com" + }"#, + ) + .unwrap(); + + #[cfg(not(target_os = "macos"))] + fs::write(&conf_file, DEFAULT_CHAT_CONF).unwrap(); } conf_file } @@ -43,25 +73,49 @@ impl ChatConfJson { pub fn get_chat_conf() -> Self { let config_file = fs::read_to_string(ChatConfJson::conf_path()).unwrap(); - let config: serde_json::Value = + let config: Value = serde_json::from_str(&config_file).expect("failed to parse chat.conf.json"); serde_json::from_value(config).unwrap_or_else(|_| ChatConfJson::chat_conf_default()) } - pub fn update_chat_conf(always_on_top: bool) { - let mut conf = ChatConfJson::get_chat_conf(); - conf.always_on_top = always_on_top; + // https://users.rust-lang.org/t/updating-object-fields-given-dynamic-json/39049/3 + pub fn amend(new_rules: &Value) -> Result<()> { + let config = ChatConfJson::get_chat_conf(); + let config: Value = serde_json::to_value(&config)?; + let mut config: BTreeMap = serde_json::from_value(config)?; + let new_rules: BTreeMap = serde_json::from_value(new_rules.clone())?; + + for (k, v) in new_rules { + config.insert(k, v); + } + fs::write( ChatConfJson::conf_path(), - serde_json::to_string(&conf).unwrap(), - ) - .unwrap(); + serde_json::to_string_pretty(&config)?, + )?; + Ok(()) + } + + pub fn theme() -> Option { + let conf = ChatConfJson::get_chat_conf(); + if conf.theme == "Dark" { + Some(Theme::Dark) + } else { + Some(Theme::Light) + } + } + + #[cfg(target_os = "macos")] + pub fn titlebar() -> TitleBarStyle { + let conf = ChatConfJson::get_chat_conf(); + if conf.titlebar { + TitleBarStyle::Transparent + } else { + TitleBarStyle::Overlay + } } pub fn chat_conf_default() -> Self { - serde_json::from_value(serde_json::json!({ - "always_on_top": false, - })) - .unwrap() + serde_json::from_value(serde_json::json!(DEFAULT_CHAT_CONF)).unwrap() } } diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 57b55e0..ce3ad3e 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -8,25 +8,28 @@ mod conf; mod utils; use app::{cmd, menu, setup}; -use conf::ChatConfJson; +use conf::{ChatConfJson, ChatState}; fn main() { ChatConfJson::init(); - let context = tauri::generate_context!(); let chat_conf = ChatConfJson::get_chat_conf(); - let chat_conf2 = chat_conf.clone(); + let context = tauri::generate_context!(); tauri::Builder::default() - .manage(conf::ChatState::default(&chat_conf)) + .manage(ChatState::default(chat_conf)) .invoke_handler(tauri::generate_handler![ cmd::drag_window, cmd::fullscreen, cmd::download, - cmd::open_link + cmd::open_link, + cmd::get_chat_conf, + cmd::form_cancel, + cmd::form_confirm, + cmd::form_msg, ]) - .setup(|app| setup::init(app, chat_conf2)) + .setup(setup::init) .plugin(tauri_plugin_positioner::init()) - .menu(menu::init(&chat_conf, &context)) + .menu(menu::init(&context)) .system_tray(menu::tray_menu()) .on_menu_event(menu::menu_handler) .on_system_tray_event(menu::tray_handler) diff --git a/src-tauri/src/utils.rs b/src-tauri/src/utils.rs index 15e80a8..58f37fe 100644 --- a/src-tauri/src/utils.rs +++ b/src-tauri/src/utils.rs @@ -4,18 +4,18 @@ use std::{ path::{Path, PathBuf}, process::Command, }; -use tauri::utils::config::Config; +// use tauri::utils::config::Config; pub fn chat_root() -> PathBuf { tauri::api::path::home_dir().unwrap().join(".chatgpt") } -pub fn get_tauri_conf() -> Option { - let config_file = include_str!("../tauri.conf.json"); - let config: Config = - serde_json::from_str(config_file).expect("failed to parse tauri.conf.json"); - Some(config) -} +// pub fn get_tauri_conf() -> Option { +// let config_file = include_str!("../tauri.conf.json"); +// let config: Config = +// serde_json::from_str(config_file).expect("failed to parse tauri.conf.json"); +// Some(config) +// } pub fn exists(path: &Path) -> bool { Path::new(path).exists() diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index ef29397..bbf63ce 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -2,20 +2,20 @@ "build": { "beforeDevCommand": "", "beforeBuildCommand": "", - "devPath": "https://chat.openai.com/", + "devPath": "../dist", "distDir": "../dist" }, "package": { "productName": "ChatGPT", - "version": "0.1.7" + "version": "0.1.8" }, "tauri": { "allowlist": { "all": true }, "systemTray": { - "iconPath": "icons/icon.png", - "iconAsTemplate": false + "iconPath": "icons/tray-icon.png", + "iconAsTemplate": true }, "bundle": { "active": true,