refactor: app conf

This commit is contained in:
lencx
2023-01-27 00:23:05 +08:00
parent f0ff062b21
commit f9f173407e
14 changed files with 388 additions and 396 deletions

View File

@@ -1,10 +1,7 @@
use crate::{ use crate::utils;
conf::ChatConfJson,
utils::{self, chat_root, create_file},
};
use log::info; use log::info;
use std::{fs, path::PathBuf}; use std::{fs, path::PathBuf};
use tauri::{api, command, AppHandle, Manager, Theme}; use tauri::{api, command, AppHandle, Manager};
#[command] #[command]
pub fn drag_window(app: AppHandle) { pub fn drag_window(app: AppHandle) {
@@ -23,16 +20,16 @@ pub fn fullscreen(app: AppHandle) {
#[command] #[command]
pub fn download(_app: AppHandle, name: String, blob: Vec<u8>) { pub fn download(_app: AppHandle, name: String, blob: Vec<u8>) {
let path = chat_root().join(PathBuf::from(name)); let path = utils::app_root().join(PathBuf::from(name));
create_file(&path).unwrap(); utils::create_file(&path).unwrap();
fs::write(&path, blob).unwrap(); fs::write(&path, blob).unwrap();
utils::open_file(path); utils::open_file(path);
} }
#[command] #[command]
pub fn save_file(_app: AppHandle, name: String, content: String) { pub fn save_file(_app: AppHandle, name: String, content: String) {
let path = chat_root().join(PathBuf::from(name)); let path = utils::app_root().join(PathBuf::from(name));
create_file(&path).unwrap(); utils::create_file(&path).unwrap();
fs::write(&path, content).unwrap(); fs::write(&path, content).unwrap();
utils::open_file(path); utils::open_file(path);
} }
@@ -42,52 +39,11 @@ pub fn open_link(app: AppHandle, url: String) {
api::shell::open(&app.shell_scope(), url, None).unwrap(); api::shell::open(&app.shell_scope(), url, None).unwrap();
} }
#[command]
pub fn get_chat_conf() -> ChatConfJson {
ChatConfJson::get_chat_conf()
}
#[command]
pub fn reset_chat_conf() -> ChatConfJson {
ChatConfJson::reset_chat_conf()
}
#[command]
pub fn get_theme() -> String {
ChatConfJson::theme().unwrap_or(Theme::Light).to_string()
}
#[command] #[command]
pub fn run_check_update(app: AppHandle, silent: bool, has_msg: Option<bool>) { pub fn run_check_update(app: AppHandle, silent: bool, has_msg: Option<bool>) {
utils::run_check_update(app, silent, has_msg); utils::run_check_update(app, silent, has_msg);
} }
#[command]
pub fn form_confirm(_app: AppHandle, data: serde_json::Value) {
ChatConfJson::amend(&serde_json::json!(data), None).unwrap();
}
#[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);
}
#[command] #[command]
pub fn open_file(path: PathBuf) { pub fn open_file(path: PathBuf) {
utils::open_file(path); utils::open_file(path);

View File

@@ -1,7 +1,7 @@
use crate::{ use crate::{
app::{fs_extra, window}, app::{fs_extra, window},
conf::GITHUB_PROMPTS_CSV_URL, conf::GITHUB_PROMPTS_CSV_URL,
utils::{self, chat_root}, utils,
}; };
use log::info; use log::info;
use regex::Regex; use regex::Regex;
@@ -11,7 +11,7 @@ use walkdir::WalkDir;
#[command] #[command]
pub fn get_chat_model_cmd() -> serde_json::Value { pub fn get_chat_model_cmd() -> serde_json::Value {
let path = utils::chat_root().join("chat.model.cmd.json"); let path = utils::app_root().join("chat.model.cmd.json");
let content = fs::read_to_string(path).unwrap_or_else(|_| r#"{"data":[]}"#.to_string()); let content = fs::read_to_string(path).unwrap_or_else(|_| r#"{"data":[]}"#.to_string());
serde_json::from_str(&content).unwrap() serde_json::from_str(&content).unwrap()
} }
@@ -55,7 +55,7 @@ pub struct ModelRecord {
#[command] #[command]
pub fn cmd_list() -> Vec<ModelRecord> { pub fn cmd_list() -> Vec<ModelRecord> {
let mut list = vec![]; let mut list = vec![];
for entry in WalkDir::new(utils::chat_root().join("cache_model")) for entry in WalkDir::new(utils::app_root().join("cache_model"))
.into_iter() .into_iter()
.filter_map(|e| e.ok()) .filter_map(|e| e.ok())
{ {
@@ -82,7 +82,7 @@ pub struct FileMetadata {
#[tauri::command] #[tauri::command]
pub fn get_download_list(pathname: &str) -> (Vec<serde_json::Value>, PathBuf) { pub fn get_download_list(pathname: &str) -> (Vec<serde_json::Value>, PathBuf) {
info!("get_download_list: {}", pathname); info!("get_download_list: {}", pathname);
let download_path = chat_root().join(PathBuf::from(pathname)); let download_path = utils::app_root().join(PathBuf::from(pathname));
let content = fs::read_to_string(&download_path).unwrap_or_else(|err| { let content = fs::read_to_string(&download_path).unwrap_or_else(|err| {
info!("download_list_error: {}", err); info!("download_list_error: {}", err);
fs::write(&download_path, "[]").unwrap(); fs::write(&download_path, "[]").unwrap();
@@ -104,7 +104,7 @@ pub fn download_list(pathname: &str, dir: &str, filename: Option<String>, id: Op
let mut idmap = HashMap::new(); let mut idmap = HashMap::new();
utils::vec_to_hashmap(data.0.into_iter(), "id", &mut idmap); utils::vec_to_hashmap(data.0.into_iter(), "id", &mut idmap);
for entry in WalkDir::new(utils::chat_root().join(dir)) for entry in WalkDir::new(utils::app_root().join(dir))
.into_iter() .into_iter()
.filter_entry(|e| !utils::is_hidden(e)) .filter_entry(|e| !utils::is_hidden(e))
.filter_map(|e| e.ok()) .filter_map(|e| e.ok())
@@ -182,9 +182,9 @@ pub async fn sync_prompts(app: AppHandle, time: u64) -> Option<Vec<ModelRecord>>
let data2 = data.clone(); let data2 = data.clone();
let model = utils::chat_root().join("chat.model.json"); let model = utils::app_root().join("chat.model.json");
let model_cmd = utils::chat_root().join("chat.model.cmd.json"); let model_cmd = utils::app_root().join("chat.model.cmd.json");
let chatgpt_prompts = utils::chat_root() let chatgpt_prompts = utils::app_root()
.join("cache_model") .join("cache_model")
.join("chatgpt_prompts.json"); .join("chatgpt_prompts.json");
@@ -238,8 +238,8 @@ pub async fn sync_prompts(app: AppHandle, time: u64) -> Option<Vec<ModelRecord>>
"Sync Prompts", "Sync Prompts",
"ChatGPT Prompts data has been synchronized!", "ChatGPT Prompts data has been synchronized!",
); );
window::window_reload(app.clone(), "core"); window::cmd::window_reload(app.clone(), "core");
window::window_reload(app, "tray"); window::cmd::window_reload(app, "tray");
return Some(data2); return Some(data2);
} }

View File

@@ -1,6 +1,6 @@
use crate::{ use crate::{
app::window, app::window,
conf::{self, ChatConfJson}, conf::{self, AppConf},
utils, utils,
}; };
use tauri::{ use tauri::{
@@ -14,7 +14,7 @@ use tauri::AboutMetadata;
// --- Menu // --- Menu
pub fn init() -> Menu { pub fn init() -> Menu {
let chat_conf = ChatConfJson::get_chat_conf(); let app_conf = AppConf::read();
let name = "ChatGPT"; let name = "ChatGPT";
let app_menu = Submenu::new( let app_menu = Submenu::new(
name, name,
@@ -35,7 +35,7 @@ pub fn init() -> Menu {
let stay_on_top = let stay_on_top =
CustomMenuItem::new("stay_on_top".to_string(), "Stay On Top").accelerator("CmdOrCtrl+T"); CustomMenuItem::new("stay_on_top".to_string(), "Stay On Top").accelerator("CmdOrCtrl+T");
let stay_on_top_menu = if chat_conf.stay_on_top { let stay_on_top_menu = if app_conf.stay_on_top {
stay_on_top.selected() stay_on_top.selected()
} else { } else {
stay_on_top stay_on_top
@@ -44,15 +44,15 @@ pub fn init() -> Menu {
let theme_light = CustomMenuItem::new("theme_light".to_string(), "Light"); let theme_light = CustomMenuItem::new("theme_light".to_string(), "Light");
let theme_dark = CustomMenuItem::new("theme_dark".to_string(), "Dark"); let theme_dark = CustomMenuItem::new("theme_dark".to_string(), "Dark");
let theme_system = CustomMenuItem::new("theme_system".to_string(), "System"); let theme_system = CustomMenuItem::new("theme_system".to_string(), "System");
let is_dark = chat_conf.theme == "Dark"; let is_dark = app_conf.clone().theme_check("dark");
let is_system = chat_conf.theme == "System"; let is_system = app_conf.clone().theme_check("system");
let update_prompt = CustomMenuItem::new("update_prompt".to_string(), "Prompt"); let update_prompt = CustomMenuItem::new("update_prompt".to_string(), "Prompt");
let update_silent = CustomMenuItem::new("update_silent".to_string(), "Silent"); let update_silent = CustomMenuItem::new("update_silent".to_string(), "Silent");
let _update_disable = CustomMenuItem::new("update_disable".to_string(), "Disable"); let _update_disable = CustomMenuItem::new("update_disable".to_string(), "Disable");
let popup_search = CustomMenuItem::new("popup_search".to_string(), "Pop-up Search"); let popup_search = CustomMenuItem::new("popup_search".to_string(), "Pop-up Search");
let popup_search_menu = if chat_conf.popup_search { let popup_search_menu = if app_conf.popup_search {
popup_search.selected() popup_search.selected()
} else { } else {
popup_search popup_search
@@ -61,14 +61,14 @@ pub fn init() -> Menu {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
let titlebar = CustomMenuItem::new("titlebar".to_string(), "Titlebar").accelerator("CmdOrCtrl+B"); let titlebar = CustomMenuItem::new("titlebar".to_string(), "Titlebar").accelerator("CmdOrCtrl+B");
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
let titlebar_menu = if chat_conf.titlebar { let titlebar_menu = if app_conf.titlebar {
titlebar.selected() titlebar.selected()
} else { } else {
titlebar titlebar
}; };
let system_tray = CustomMenuItem::new("system_tray".to_string(), "System Tray"); let system_tray = CustomMenuItem::new("system_tray".to_string(), "System Tray");
let system_tray_menu = if chat_conf.tray { let system_tray_menu = if app_conf.tray {
system_tray.selected() system_tray.selected()
} else { } else {
system_tray system_tray
@@ -114,16 +114,16 @@ pub fn init() -> Menu {
Submenu::new( Submenu::new(
"Auto Update", "Auto Update",
Menu::new() Menu::new()
.add_item(if chat_conf.auto_update == "Prompt" { .add_item(if app_conf.auto_update == "Prompt" {
update_prompt.selected() update_prompt.selected()
} else { } else {
update_prompt update_prompt
}) })
.add_item(if chat_conf.auto_update == "Silent" { .add_item(if app_conf.auto_update == "Silent" {
update_silent.selected() update_silent.selected()
} else { } else {
update_silent update_silent
}), // .add_item(if chat_conf.auto_update == "Disable" { }), // .add_item(if app_conf.auto_update == "Disable" {
// update_disable.selected() // update_disable.selected()
// } else { // } else {
// update_disable // update_disable
@@ -241,23 +241,25 @@ pub fn menu_handler(event: WindowMenuEvent<tauri::Wry>) {
utils::run_check_update(app, false, None); utils::run_check_update(app, false, None);
} }
// Preferences // Preferences
"control_center" => window::control_window(app), "control_center" => window::cmd::control_window(app),
"restart" => tauri::api::process::restart(&app.env()), "restart" => tauri::api::process::restart(&app.env()),
"inject_script" => open(&app, script_path), "inject_script" => open(&app, script_path),
"go_conf" => utils::open_file(utils::chat_root()), "go_conf" => utils::open_file(utils::app_root()),
"clear_conf" => utils::clear_conf(&app), "clear_conf" => utils::clear_conf(&app),
"awesome" => open(&app, conf::AWESOME_URL.to_string()), "awesome" => open(&app, conf::AWESOME_URL.to_string()),
"buy_coffee" => open(&app, conf::BUY_COFFEE.to_string()), "buy_coffee" => open(&app, conf::BUY_COFFEE.to_string()),
"popup_search" => { "popup_search" => {
let chat_conf = conf::ChatConfJson::get_chat_conf(); let app_conf = AppConf::read();
let popup_search = !chat_conf.popup_search; let popup_search = !app_conf.popup_search;
menu_handle menu_handle
.get_item(menu_id) .get_item(menu_id)
.set_selected(popup_search) .set_selected(popup_search)
.unwrap(); .unwrap();
ChatConfJson::amend(&serde_json::json!({ "popup_search": popup_search }), None).unwrap(); app_conf
window::window_reload(app.clone(), "core"); .amend(serde_json::json!({ "popup_search": popup_search }))
window::window_reload(app, "tray"); .write();
window::cmd::window_reload(app.clone(), "core");
window::cmd::window_reload(app, "tray");
} }
"sync_prompts" => { "sync_prompts" => {
tauri::api::dialog::ask( tauri::api::dialog::ask(
@@ -276,29 +278,37 @@ pub fn menu_handler(event: WindowMenuEvent<tauri::Wry>) {
); );
} }
"hide_dock_icon" => { "hide_dock_icon" => {
ChatConfJson::amend(&serde_json::json!({ "hide_dock_icon": true }), Some(app)).unwrap() AppConf::read()
.amend(serde_json::json!({ "hide_dock_icon": true }))
.write()
.restart(app);
} }
"titlebar" => { "titlebar" => {
let chat_conf = conf::ChatConfJson::get_chat_conf(); let app_conf = AppConf::read();
ChatConfJson::amend( app_conf
&serde_json::json!({ "titlebar": !chat_conf.titlebar }), .clone()
None, .amend(serde_json::json!({ "titlebar": !app_conf.titlebar }))
) .write()
.unwrap(); .restart(app);
tauri::api::process::restart(&app.env());
} }
"system_tray" => { "system_tray" => {
let chat_conf = conf::ChatConfJson::get_chat_conf(); let app_conf = AppConf::read();
ChatConfJson::amend(&serde_json::json!({ "tray": !chat_conf.tray }), None).unwrap(); app_conf
tauri::api::process::restart(&app.env()); .clone()
.amend(serde_json::json!({ "tray": !app_conf.tray }))
.write()
.restart(app);
} }
"theme_light" | "theme_dark" | "theme_system" => { "theme_light" | "theme_dark" | "theme_system" => {
let theme = match menu_id { let theme = match menu_id {
"theme_dark" => "Dark", "theme_dark" => "dark",
"theme_system" => "System", "theme_system" => "system",
_ => "Light", _ => "light",
}; };
ChatConfJson::amend(&serde_json::json!({ "theme": theme }), Some(app)).unwrap(); AppConf::read()
.amend(serde_json::json!({ "theme": theme }))
.write()
.restart(app);
} }
"update_prompt" | "update_silent" | "update_disable" => { "update_prompt" | "update_silent" | "update_disable" => {
// for id in ["update_prompt", "update_silent", "update_disable"] { // for id in ["update_prompt", "update_silent", "update_disable"] {
@@ -328,17 +338,21 @@ pub fn menu_handler(event: WindowMenuEvent<tauri::Wry>) {
"Prompt" "Prompt"
} }
}; };
ChatConfJson::amend(&serde_json::json!({ "auto_update": auto_update }), None).unwrap(); AppConf::read()
.amend(serde_json::json!({ "auto_update": auto_update }))
.write();
} }
"stay_on_top" => { "stay_on_top" => {
let chat_conf = conf::ChatConfJson::get_chat_conf(); let app_conf = AppConf::read();
let stay_on_top = !chat_conf.stay_on_top; let stay_on_top = !app_conf.stay_on_top;
menu_handle menu_handle
.get_item(menu_id) .get_item(menu_id)
.set_selected(stay_on_top) .set_selected(stay_on_top)
.unwrap(); .unwrap();
win.set_always_on_top(stay_on_top).unwrap(); win.set_always_on_top(stay_on_top).unwrap();
ChatConfJson::amend(&serde_json::json!({ "stay_on_top": stay_on_top }), None).unwrap(); app_conf
.amend(serde_json::json!({ "stay_on_top": stay_on_top }))
.write();
} }
// Window // Window
"dalle2" => window::dalle2_window(&app, None, None, Some(false)), "dalle2" => window::dalle2_window(&app, None, None, Some(false)),
@@ -367,7 +381,7 @@ pub fn menu_handler(event: WindowMenuEvent<tauri::Wry>) {
) )
.unwrap(), .unwrap(),
// Help // Help
"chatgpt_log" => utils::open_file(utils::chat_root().join("chatgpt.log")), "chatgpt_log" => utils::open_file(utils::app_root().join("chatgpt.log")),
"update_log" => open(&app, conf::UPDATE_LOG_URL.to_string()), "update_log" => open(&app, conf::UPDATE_LOG_URL.to_string()),
"report_bug" => open(&app, conf::ISSUES_URL.to_string()), "report_bug" => open(&app, conf::ISSUES_URL.to_string()),
"dev_tools" => { "dev_tools" => {
@@ -422,9 +436,9 @@ pub fn tray_handler(handle: &AppHandle, event: SystemTrayEvent) {
match event { match event {
SystemTrayEvent::LeftClick { .. } => { SystemTrayEvent::LeftClick { .. } => {
let chat_conf = conf::ChatConfJson::get_chat_conf(); let app_conf = AppConf::read();
if !chat_conf.hide_dock_icon { if !app_conf.hide_dock_icon {
let core_win = handle.get_window("core").unwrap(); let core_win = handle.get_window("core").unwrap();
core_win.minimize().unwrap(); core_win.minimize().unwrap();
} }
@@ -439,15 +453,21 @@ pub fn tray_handler(handle: &AppHandle, event: SystemTrayEvent) {
} }
} }
SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() { SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
"control_center" => window::control_window(app), "control_center" => window::cmd::control_window(app),
"restart" => tauri::api::process::restart(&handle.env()), "restart" => tauri::api::process::restart(&handle.env()),
"show_dock_icon" => { "show_dock_icon" => {
ChatConfJson::amend(&serde_json::json!({ "hide_dock_icon": false }), Some(app)).unwrap(); AppConf::read()
.amend(serde_json::json!({ "hide_dock_icon": false }))
.write()
.restart(app);
} }
"hide_dock_icon" => { "hide_dock_icon" => {
let chat_conf = conf::ChatConfJson::get_chat_conf(); let app_conf = AppConf::read();
if !chat_conf.hide_dock_icon { if !app_conf.hide_dock_icon {
ChatConfJson::amend(&serde_json::json!({ "hide_dock_icon": true }), Some(app)).unwrap(); app_conf
.amend(serde_json::json!({ "hide_dock_icon": true }))
.write()
.restart(app);
} }
} }
"show_core" => { "show_core" => {

View File

@@ -1,20 +1,20 @@
use crate::{app::window, conf::ChatConfJson, utils}; use crate::{app::window, conf::AppConf, utils};
use log::info; use log::info;
use tauri::{utils::config::WindowUrl, window::WindowBuilder, App, GlobalShortcutManager, Manager}; use tauri::{utils::config::WindowUrl, window::WindowBuilder, App, GlobalShortcutManager, Manager};
use wry::application::accelerator::Accelerator; use wry::application::accelerator::Accelerator;
pub fn init(app: &mut App) -> std::result::Result<(), Box<dyn std::error::Error>> { pub fn init(app: &mut App) -> std::result::Result<(), Box<dyn std::error::Error>> {
info!("stepup"); info!("stepup");
let chat_conf = ChatConfJson::get_chat_conf(); let app_conf = AppConf::read();
let url = chat_conf.main_origin.to_string(); let url = app_conf.main_origin.to_string();
let theme = ChatConfJson::theme(); let theme = AppConf::theme_mode();
let handle = app.app_handle(); let handle = app.app_handle();
tauri::async_runtime::spawn(async move { tauri::async_runtime::spawn(async move {
window::tray_window(&handle); window::tray_window(&handle);
}); });
if let Some(v) = chat_conf.global_shortcut { if let Some(v) = app_conf.clone().global_shortcut {
info!("global_shortcut: `{}`", v); info!("global_shortcut: `{}`", v);
match v.parse::<Accelerator>() { match v.parse::<Accelerator>() {
Ok(_) => { Ok(_) => {
@@ -44,13 +44,14 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box<dyn std::error::Error>
info!("global_shortcut_unregister"); info!("global_shortcut_unregister");
}; };
if chat_conf.hide_dock_icon { let app_conf2 = app_conf.clone();
if app_conf.hide_dock_icon {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
app.set_activation_policy(tauri::ActivationPolicy::Accessory); app.set_activation_policy(tauri::ActivationPolicy::Accessory);
} else { } else {
let app = app.handle(); let app = app.handle();
tauri::async_runtime::spawn(async move { tauri::async_runtime::spawn(async move {
let link = if chat_conf.main_dashboard { let link = if app_conf2.main_dashboard {
"index.html" "index.html"
} else { } else {
&url &url
@@ -60,20 +61,20 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box<dyn std::error::Error>
.resizable(true) .resizable(true)
.fullscreen(false) .fullscreen(false)
.inner_size(800.0, 600.0) .inner_size(800.0, 600.0)
.theme(theme) .theme(Some(theme))
.always_on_top(chat_conf.stay_on_top) .always_on_top(app_conf2.stay_on_top)
.initialization_script(&utils::user_script()) .initialization_script(&utils::user_script())
.initialization_script(include_str!("../scripts/core.js")) .initialization_script(include_str!("../scripts/core.js"))
.user_agent(&chat_conf.ua_window); .user_agent(&app_conf2.ua_window);
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
main_win = main_win main_win = main_win
.title_bar_style(ChatConfJson::titlebar()) .title_bar_style(app_conf2.clone().titlebar())
.hidden_title(true); .hidden_title(true);
} }
if url == "https://chat.openai.com" && !chat_conf.main_dashboard { if url == "https://chat.openai.com" && !app_conf2.main_dashboard {
main_win = main_win main_win = main_win
.initialization_script(include_str!("../vendors/floating-ui-core.js")) .initialization_script(include_str!("../vendors/floating-ui-core.js"))
.initialization_script(include_str!("../vendors/floating-ui-dom.js")) .initialization_script(include_str!("../vendors/floating-ui-dom.js"))
@@ -92,10 +93,10 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box<dyn std::error::Error>
} }
// auto_update // auto_update
if chat_conf.auto_update != "Disable" { if app_conf.auto_update != "Disable" {
info!("stepup::run_check_update"); info!("stepup::run_check_update");
let app = app.handle(); let app = app.handle();
utils::run_check_update(app, chat_conf.auto_update == "Silent", None); utils::run_check_update(app, app_conf.auto_update == "Silent", None);
} }
Ok(()) Ok(())

View File

@@ -1,18 +1,18 @@
use crate::{conf, utils}; use crate::{conf::AppConf, utils};
use log::info; use log::info;
use std::time::SystemTime; use std::time::SystemTime;
use tauri::{utils::config::WindowUrl, window::WindowBuilder, Manager}; use tauri::{utils::config::WindowUrl, window::WindowBuilder, Manager};
pub fn tray_window(handle: &tauri::AppHandle) { pub fn tray_window(handle: &tauri::AppHandle) {
let chat_conf = conf::ChatConfJson::get_chat_conf(); let app_conf = AppConf::read();
let theme = conf::ChatConfJson::theme(); let theme = AppConf::theme_mode();
let app = handle.clone(); let app = handle.clone();
tauri::async_runtime::spawn(async move { tauri::async_runtime::spawn(async move {
let link = if chat_conf.tray_dashboard { let link = if app_conf.tray_dashboard {
"index.html" "index.html"
} else { } else {
&chat_conf.tray_origin &app_conf.tray_origin
}; };
let mut tray_win = WindowBuilder::new(&app, "tray", WindowUrl::App(link.into())) let mut tray_win = WindowBuilder::new(&app, "tray", WindowUrl::App(link.into()))
.title("ChatGPT") .title("ChatGPT")
@@ -21,12 +21,12 @@ pub fn tray_window(handle: &tauri::AppHandle) {
.inner_size(360.0, 540.0) .inner_size(360.0, 540.0)
.decorations(false) .decorations(false)
.always_on_top(true) .always_on_top(true)
.theme(theme) .theme(Some(theme))
.initialization_script(&utils::user_script()) .initialization_script(&utils::user_script())
.initialization_script(include_str!("../scripts/core.js")) .initialization_script(include_str!("../scripts/core.js"))
.user_agent(&chat_conf.ua_tray); .user_agent(&app_conf.ua_tray);
if chat_conf.tray_origin == "https://chat.openai.com" && !chat_conf.tray_dashboard { if app_conf.tray_origin == "https://chat.openai.com" && !app_conf.tray_dashboard {
tray_win = tray_win tray_win = tray_win
.initialization_script(include_str!("../vendors/floating-ui-core.js")) .initialization_script(include_str!("../vendors/floating-ui-core.js"))
.initialization_script(include_str!("../vendors/floating-ui-dom.js")) .initialization_script(include_str!("../vendors/floating-ui-dom.js"))
@@ -45,7 +45,7 @@ pub fn dalle2_window(
is_new: Option<bool>, is_new: Option<bool>,
) { ) {
info!("dalle2_query: {:?}", query); info!("dalle2_query: {:?}", query);
let theme = conf::ChatConfJson::theme(); let theme = AppConf::theme_mode();
let app = handle.clone(); let app = handle.clone();
let query = if query.is_some() { let query = if query.is_some() {
@@ -76,7 +76,7 @@ pub fn dalle2_window(
.fullscreen(false) .fullscreen(false)
.inner_size(800.0, 600.0) .inner_size(800.0, 600.0)
.always_on_top(false) .always_on_top(false)
.theme(theme) .theme(Some(theme))
.initialization_script(include_str!("../scripts/core.js")) .initialization_script(include_str!("../scripts/core.js"))
.initialization_script(&query) .initialization_script(&query)
.initialization_script(include_str!("../scripts/dalle2.js")) .initialization_script(include_str!("../scripts/dalle2.js"))
@@ -90,78 +90,84 @@ pub fn dalle2_window(
} }
} }
#[tauri::command] pub mod cmd {
pub fn dalle2_search_window(app: tauri::AppHandle, query: String) { use super::*;
dalle2_window( use log::info;
&app.app_handle(), use tauri::{command, utils::config::WindowUrl, window::WindowBuilder, Manager};
Some(query),
Some("ChatGPT & DALL·E 2".to_string()),
None,
);
}
#[tauri::command] #[tauri::command]
pub fn control_window(handle: tauri::AppHandle) { pub fn dalle2_search_window(app: tauri::AppHandle, query: String) {
tauri::async_runtime::spawn(async move { dalle2_window(
if handle.get_window("main").is_none() { &app.app_handle(),
WindowBuilder::new( Some(query),
&handle, Some("ChatGPT & DALL·E 2".to_string()),
"main", None,
WindowUrl::App("index.html?type=control".into()), );
) }
.title("Control Center")
.resizable(true)
.fullscreen(false)
.inner_size(1200.0, 700.0)
.min_inner_size(1000.0, 600.0)
.build()
.unwrap();
} else {
let main_win = handle.get_window("main").unwrap();
main_win.show().unwrap();
main_win.set_focus().unwrap();
}
});
}
#[tauri::command] #[tauri::command]
pub async fn wa_window( pub fn control_window(handle: tauri::AppHandle) {
app: tauri::AppHandle,
label: String,
title: String,
url: String,
script: Option<String>,
) {
info!("wa_window: {} :=> {}", title, url);
let win = app.get_window(&label);
if win.is_none() {
tauri::async_runtime::spawn(async move { tauri::async_runtime::spawn(async move {
tauri::WindowBuilder::new(&app, label, tauri::WindowUrl::App(url.parse().unwrap())) if handle.get_window("main").is_none() {
.initialization_script(&script.unwrap_or_default()) WindowBuilder::new(
.initialization_script(include_str!("../scripts/core.js")) &handle,
.title(title) "main",
WindowUrl::App("index.html?type=control".into()),
)
.title("Control Center")
.resizable(true)
.fullscreen(false)
.inner_size(1200.0, 700.0)
.min_inner_size(1000.0, 600.0)
.build() .build()
.unwrap(); .unwrap();
} else {
let main_win = handle.get_window("main").unwrap();
main_win.show().unwrap();
main_win.set_focus().unwrap();
}
}); });
} else { }
if !win.clone().unwrap().is_visible().unwrap() {
win.clone().unwrap().show().unwrap(); #[command]
pub async fn wa_window(
app: tauri::AppHandle,
label: String,
title: String,
url: String,
script: Option<String>,
) {
info!("wa_window: {} :=> {}", title, url);
let win = app.get_window(&label);
if win.is_none() {
tauri::async_runtime::spawn(async move {
tauri::WindowBuilder::new(&app, label, tauri::WindowUrl::App(url.parse().unwrap()))
.initialization_script(&script.unwrap_or_default())
.initialization_script(include_str!("../scripts/core.js"))
.title(title)
.build()
.unwrap();
});
} else {
if !win.clone().unwrap().is_visible().unwrap() {
win.clone().unwrap().show().unwrap();
}
win
.clone()
.unwrap()
.eval("window.location.reload()")
.unwrap();
win.unwrap().set_focus().unwrap();
} }
win }
.clone()
#[command]
pub fn window_reload(app: tauri::AppHandle, label: &str) {
app
.app_handle()
.get_window(label)
.unwrap() .unwrap()
.eval("window.location.reload()") .eval("window.location.reload()")
.unwrap(); .unwrap();
win.unwrap().set_focus().unwrap();
} }
} }
#[tauri::command]
pub fn window_reload(app: tauri::AppHandle, label: &str) {
app
.app_handle()
.get_window(label)
.unwrap()
.eval("window.location.reload()")
.unwrap();
}

View File

@@ -1,15 +1,12 @@
use crate::utils::{chat_root, create_file, exists}; use log::{error, info};
use anyhow::Result;
use log::info;
use serde_json::Value; use serde_json::Value;
use std::{collections::BTreeMap, fs, path::PathBuf}; use std::{collections::BTreeMap, path::PathBuf};
use tauri::{Manager, Theme}; use tauri::{Manager, Theme};
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
use tauri::TitleBarStyle; use tauri::TitleBarStyle;
// pub const USER_AGENT: &str = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15"; use crate::utils::{app_root, create_file, exists};
// pub const PHONE_USER_AGENT: &str = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1";
pub const ISSUES_URL: &str = "https://github.com/lencx/ChatGPT/issues"; pub const ISSUES_URL: &str = "https://github.com/lencx/ChatGPT/issues";
pub const UPDATE_LOG_URL: &str = "https://github.com/lencx/ChatGPT/blob/main/UPDATE_LOG.md"; pub const UPDATE_LOG_URL: &str = "https://github.com/lencx/ChatGPT/blob/main/UPDATE_LOG.md";
@@ -17,163 +14,129 @@ pub const AWESOME_URL: &str = "https://github.com/lencx/ChatGPT/blob/main/AWESOM
pub const BUY_COFFEE: &str = "https://www.buymeacoffee.com/lencx"; pub const BUY_COFFEE: &str = "https://www.buymeacoffee.com/lencx";
pub const GITHUB_PROMPTS_CSV_URL: &str = pub const GITHUB_PROMPTS_CSV_URL: &str =
"https://raw.githubusercontent.com/f/awesome-chatgpt-prompts/main/prompts.csv"; "https://raw.githubusercontent.com/f/awesome-chatgpt-prompts/main/prompts.csv";
pub const DEFAULT_CHAT_CONF: &str = r#"{
"stay_on_top": false,
"auto_update": "Prompt",
"theme": "Light",
"tray": true,
"titlebar": true,
"popup_search": false,
"global_shortcut": "",
"hide_dock_icon": false,
"main_dashboard": false,
"tray_dashboard": false,
"main_origin": "https://chat.openai.com",
"tray_origin": "https://chat.openai.com",
"default_origin": "https://chat.openai.com",
"ua_window": "",
"ua_tray": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1"
}"#;
pub const DEFAULT_CHAT_CONF_MAC: &str = r#"{
"stay_on_top": false,
"auto_update": "Prompt",
"theme": "Light",
"tray": true,
"titlebar": false,
"popup_search": false,
"global_shortcut": "",
"hide_dock_icon": false,
"main_dashboard": false,
"tray_dashboard": false,
"main_origin": "https://chat.openai.com",
"tray_origin": "https://chat.openai.com",
"default_origin": "https://chat.openai.com",
"ua_window": "",
"ua_tray": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1"
}"#;
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] pub const APP_CONF_PATH: &str = "chat.conf.json";
pub struct ChatConfJson { pub const CHATGPT_URL: &str = "https://chat.openai.com";
// support macOS only pub const UA_MOBILE: &str = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1";
pub titlebar: bool,
pub hide_dock_icon: bool,
// macOS and Windows, Light/Dark/System macro_rules! pub_struct {
pub theme: String, ($name:ident {$($field:ident: $t:ty,)*}) => {
// auto update policy, Prompt/Silent/Disable #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub auto_update: String, pub struct $name {
pub tray: bool, $(pub $field: $t),*
pub popup_search: bool, }
pub stay_on_top: bool, }
pub main_dashboard: bool,
pub tray_dashboard: bool,
pub main_origin: String,
pub tray_origin: String,
pub default_origin: String,
pub ua_window: String,
pub ua_tray: String,
pub global_shortcut: Option<String>,
} }
impl ChatConfJson { pub_struct!(AppConf {
/// init chat.conf.json titlebar: bool,
/// path: ~/.chatgpt/chat.conf.json hide_dock_icon: bool,
pub fn init() -> PathBuf { // macOS and Windows: Light / Dark / System
info!("chat_conf_init"); theme: String,
let conf_file = ChatConfJson::conf_path(); // auto update policy: Prompt / Silent / Disable
let content = if cfg!(target_os = "macos") { auto_update: String,
DEFAULT_CHAT_CONF_MAC tray: bool,
} else { popup_search: bool,
DEFAULT_CHAT_CONF stay_on_top: bool,
}; main_dashboard: bool,
tray_dashboard: bool,
main_origin: String,
tray_origin: String,
default_origin: String,
ua_window: String,
ua_tray: String,
global_shortcut: Option<String>,
});
if !exists(&conf_file) { impl AppConf {
create_file(&conf_file).unwrap(); pub fn new() -> Self {
fs::write(&conf_file, content).unwrap(); info!("conf_init");
return conf_file; Self {
titlebar: !cfg!(target_os = "macos"),
hide_dock_icon: false,
theme: "Light".into(),
auto_update: "Prompt".into(),
tray: true,
popup_search: false,
stay_on_top: false,
main_dashboard: false,
tray_dashboard: false,
main_origin: CHATGPT_URL.into(),
tray_origin: CHATGPT_URL.into(),
default_origin: CHATGPT_URL.into(),
ua_tray: UA_MOBILE.into(),
ua_window: "".into(),
global_shortcut: None,
} }
}
let conf_file = ChatConfJson::conf_path(); pub fn file_path() -> PathBuf {
let file_content = fs::read_to_string(&conf_file).unwrap(); app_root().join(APP_CONF_PATH)
match serde_json::from_str(&file_content) { }
Ok(v) => v,
pub fn read() -> Self {
match std::fs::read_to_string(Self::file_path()) {
Ok(v) => serde_json::from_str::<AppConf>(&v).unwrap(),
Err(err) => { Err(err) => {
if err.to_string() == "invalid type: map, expected unit at line 1 column 0" { error!("conf_read_error: {}", err);
return conf_file; Self::default()
}
fs::write(&conf_file, content).unwrap();
}
};
conf_file
}
pub fn conf_path() -> PathBuf {
chat_root().join("chat.conf.json")
}
pub fn get_chat_conf() -> Self {
let conf_file = ChatConfJson::conf_path();
let file_content = fs::read_to_string(&conf_file).unwrap();
let content = if cfg!(target_os = "macos") {
DEFAULT_CHAT_CONF_MAC
} else {
DEFAULT_CHAT_CONF
};
match serde_json::from_value(match serde_json::from_str(&file_content) {
Ok(v) => v,
Err(_) => {
fs::write(&conf_file, content).unwrap();
serde_json::from_str(content).unwrap()
}
}) {
Ok(v) => v,
Err(_) => {
fs::write(&conf_file, content).unwrap();
serde_json::from_value(serde_json::from_str(content).unwrap()).unwrap()
} }
} }
} }
pub fn reset_chat_conf() -> Self { pub fn write(self) -> Self {
let conf_file = ChatConfJson::conf_path(); let path = &Self::file_path();
let content = if cfg!(target_os = "macos") { if !exists(path) {
DEFAULT_CHAT_CONF_MAC create_file(path).unwrap();
info!("conf_init")
}
if let Ok(v) = serde_json::to_string_pretty(&self) {
std::fs::write(path, v).unwrap_or_else(|err| {
error!("conf_write_error: {}", err);
Self::default().write();
});
} else { } else {
DEFAULT_CHAT_CONF error!("conf_ser_error");
}; }
fs::write(&conf_file, content).unwrap(); self
serde_json::from_str(content).unwrap()
} }
// https://users.rust-lang.org/t/updating-object-fields-given-dynamic-json/39049/3 pub fn amend(self, json: Value) -> Self {
pub fn amend(new_rules: &Value, app: Option<tauri::AppHandle>) -> Result<()> { let val = serde_json::to_value(&self).unwrap();
let config = ChatConfJson::get_chat_conf(); let mut config: BTreeMap<String, Value> = serde_json::from_value(val).unwrap();
let config: Value = serde_json::to_value(&config)?; let new_json: BTreeMap<String, Value> = serde_json::from_value(json).unwrap();
let mut config: BTreeMap<String, Value> = serde_json::from_value(config)?;
let new_rules: BTreeMap<String, Value> = serde_json::from_value(new_rules.clone())?;
for (k, v) in new_rules { for (k, v) in new_json {
config.insert(k, v); config.insert(k, v);
} }
fs::write( match serde_json::to_string_pretty(&config) {
ChatConfJson::conf_path(), Ok(v) => match serde_json::from_str::<AppConf>(&v) {
serde_json::to_string_pretty(&config)?, Ok(v) => v,
)?; Err(err) => {
error!("conf_amend_parse_error: {}", err);
if let Some(handle) = app { self
tauri::api::process::restart(&handle.env()); }
},
Err(err) => {
error!("conf_amend_str_error: {}", err);
self
}
} }
Ok(())
} }
pub fn theme() -> Option<Theme> { #[cfg(target_os = "macos")]
let conf = ChatConfJson::get_chat_conf(); pub fn titlebar(self) -> TitleBarStyle {
let theme = match conf.theme.as_str() { if self.titlebar {
"System" => match dark_light::detect() { TitleBarStyle::Transparent
} else {
TitleBarStyle::Overlay
}
}
pub fn theme_mode() -> Theme {
match cmd::get_theme().to_lowercase().as_str() {
"system" => match dark_light::detect() {
// Dark mode // Dark mode
dark_light::Mode::Dark => Theme::Dark, dark_light::Mode::Dark => Theme::Dark,
// Light mode // Light mode
@@ -181,20 +144,68 @@ impl ChatConfJson {
// Unspecified // Unspecified
dark_light::Mode::Default => Theme::Light, dark_light::Mode::Default => Theme::Light,
}, },
"Dark" => Theme::Dark, "dark" => Theme::Dark,
_ => Theme::Light, _ => Theme::Light,
};
Some(theme)
}
#[cfg(target_os = "macos")]
pub fn titlebar() -> TitleBarStyle {
let conf = ChatConfJson::get_chat_conf();
if conf.titlebar {
TitleBarStyle::Transparent
} else {
TitleBarStyle::Overlay
} }
} }
pub fn theme_check(self, mode: &str) -> bool {
self.theme.to_lowercase() == mode
}
pub fn restart(self, app: tauri::AppHandle) {
tauri::api::process::restart(&app.env());
}
}
impl Default for AppConf {
fn default() -> Self {
Self::new()
}
}
pub mod cmd {
use super::AppConf;
use tauri::{command, AppHandle, Manager};
#[command]
pub fn get_app_conf() -> AppConf {
AppConf::read()
}
#[command]
pub fn reset_app_conf() -> AppConf {
AppConf::default().write()
}
#[command]
pub fn get_theme() -> String {
AppConf::read().theme
}
#[command]
pub fn form_confirm(_app: AppHandle, data: serde_json::Value) {
AppConf::read().amend(serde_json::json!(data)).write();
}
#[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);
}
} }

View File

@@ -8,8 +8,7 @@ mod conf;
mod utils; mod utils;
use app::{cmd, fs_extra, gpt, menu, setup, window}; use app::{cmd, fs_extra, gpt, menu, setup, window};
use conf::ChatConfJson; use conf::AppConf;
use tauri::api::path;
use tauri_plugin_autostart::MacosLauncher; use tauri_plugin_autostart::MacosLauncher;
use tauri_plugin_log::{ use tauri_plugin_log::{
fern::colors::{Color, ColoredLevelConfig}, fern::colors::{Color, ColoredLevelConfig},
@@ -18,56 +17,59 @@ use tauri_plugin_log::{
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
ChatConfJson::init(); let app_conf = AppConf::read().write();
// If the file does not exist, creating the file will block menu synchronization // If the file does not exist, creating the file will block menu synchronization
utils::create_chatgpt_prompts(); utils::create_chatgpt_prompts();
let context = tauri::generate_context!(); let context = tauri::generate_context!();
let colors = ColoredLevelConfig {
error: Color::Red,
warn: Color::Yellow,
debug: Color::Blue,
info: Color::BrightGreen,
trace: Color::Cyan,
};
gpt::download_list("chat.download.json", "download", None, None); gpt::download_list("chat.download.json", "download", None, None);
gpt::download_list("chat.notes.json", "notes", None, None); gpt::download_list("chat.notes.json", "notes", None, None);
let chat_conf = ChatConfJson::get_chat_conf(); let mut log = tauri_plugin_log::Builder::default()
.targets([
// LogTarget::LogDir,
// LOG PATH: ~/.chatgpt/ChatGPT.log
LogTarget::Folder(utils::app_root()),
LogTarget::Stdout,
LogTarget::Webview,
])
.level(log::LevelFilter::Debug);
if cfg!(debug_assertions) {
log = log.with_colors(ColoredLevelConfig {
error: Color::Red,
warn: Color::Yellow,
debug: Color::Blue,
info: Color::BrightGreen,
trace: Color::Cyan,
});
}
let mut builder = tauri::Builder::default() let mut builder = tauri::Builder::default()
// https://github.com/tauri-apps/tauri/pull/2736 // https://github.com/tauri-apps/tauri/pull/2736
.plugin( .plugin(log.build())
tauri_plugin_log::Builder::default()
.targets([
// LogTarget::LogDir,
// LOG PATH: ~/.chatgpt/ChatGPT.log
LogTarget::Folder(path::home_dir().unwrap().join(".chatgpt")),
LogTarget::Stdout,
LogTarget::Webview,
])
.level(log::LevelFilter::Debug)
.with_colors(colors)
.build(),
)
.plugin(tauri_plugin_positioner::init()) .plugin(tauri_plugin_positioner::init())
.plugin(tauri_plugin_autostart::init( .plugin(tauri_plugin_autostart::init(
MacosLauncher::LaunchAgent, MacosLauncher::LaunchAgent,
None, None,
)) ))
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
conf::cmd::get_app_conf,
conf::cmd::reset_app_conf,
conf::cmd::get_theme,
conf::cmd::form_confirm,
conf::cmd::form_cancel,
conf::cmd::form_msg,
window::cmd::wa_window,
window::cmd::control_window,
window::cmd::window_reload,
window::cmd::dalle2_search_window,
cmd::drag_window, cmd::drag_window,
cmd::fullscreen, cmd::fullscreen,
cmd::download, cmd::download,
cmd::save_file, cmd::save_file,
cmd::open_link, cmd::open_link,
cmd::get_chat_conf,
cmd::get_theme,
cmd::reset_chat_conf,
cmd::run_check_update, cmd::run_check_update,
cmd::form_cancel,
cmd::form_confirm,
cmd::form_msg,
cmd::open_file, cmd::open_file,
cmd::get_data, cmd::get_data,
gpt::get_chat_model_cmd, gpt::get_chat_model_cmd,
@@ -77,16 +79,12 @@ async fn main() {
gpt::cmd_list, gpt::cmd_list,
gpt::download_list, gpt::download_list,
gpt::get_download_list, gpt::get_download_list,
window::wa_window,
window::control_window,
window::window_reload,
window::dalle2_search_window,
fs_extra::metadata, fs_extra::metadata,
]) ])
.setup(setup::init) .setup(setup::init)
.menu(menu::init()); .menu(menu::init());
if chat_conf.tray { if app_conf.tray {
builder = builder.system_tray(menu::tray_menu()); builder = builder.system_tray(menu::tray_menu());
} }

View File

@@ -54,7 +54,7 @@ async function init() {
if (__TAURI_METADATA__.__currentWindow.label !== 'tray') { if (__TAURI_METADATA__.__currentWindow.label !== 'tray') {
const _platform = await platform(); const _platform = await platform();
const chatConf = await invoke('get_chat_conf') || {}; const chatConf = await invoke('get_app_conf') || {};
if (/darwin/.test(_platform) && !chatConf.titlebar) { if (/darwin/.test(_platform) && !chatConf.titlebar) {
const topStyleDom = document.createElement("style"); 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;}`; 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;}`;

View File

@@ -3,7 +3,7 @@
async function init() { async function init() {
const buttonOuterHTMLFallback = `<button class="btn flex justify-center gap-2 btn-neutral" id="download-png-button">Try Again</button>`; const buttonOuterHTMLFallback = `<button class="btn flex justify-center gap-2 btn-neutral" id="download-png-button">Try Again</button>`;
if (window.innerWidth < 767) return; if (window.innerWidth < 767) return;
const chatConf = await invoke('get_chat_conf') || {}; const chatConf = await invoke('get_app_conf') || {};
if (window.buttonsInterval) { if (window.buttonsInterval) {
clearInterval(window.buttonsInterval); clearInterval(window.buttonsInterval);
} }

View File

@@ -1,7 +1,7 @@
// *** Core Script - DALL·E 2 Core *** // *** Core Script - DALL·E 2 Core ***
async function init() { async function init() {
const chatConf = await invoke('get_chat_conf') || {}; const chatConf = await invoke('get_app_conf') || {};
if (!chatConf.popup_search) return; if (!chatConf.popup_search) return;
if (!window.FloatingUIDOM) return; if (!window.FloatingUIDOM) return;

View File

@@ -11,7 +11,7 @@ use std::{
use tauri::updater::UpdateResponse; use tauri::updater::UpdateResponse;
use tauri::{utils::config::Config, AppHandle, Manager, Wry}; use tauri::{utils::config::Config, AppHandle, Manager, Wry};
pub fn chat_root() -> PathBuf { pub fn app_root() -> PathBuf {
tauri::api::path::home_dir().unwrap().join(".chatgpt") tauri::api::path::home_dir().unwrap().join(".chatgpt")
} }
@@ -33,7 +33,7 @@ pub fn create_file(path: &Path) -> Result<File> {
} }
pub fn create_chatgpt_prompts() { pub fn create_chatgpt_prompts() {
let sync_file = chat_root().join("cache_model").join("chatgpt_prompts.json"); let sync_file = app_root().join("cache_model").join("chatgpt_prompts.json");
if !exists(&sync_file) { if !exists(&sync_file) {
create_file(&sync_file).unwrap(); create_file(&sync_file).unwrap();
fs::write(&sync_file, "[]").unwrap(); fs::write(&sync_file, "[]").unwrap();
@@ -41,7 +41,7 @@ pub fn create_chatgpt_prompts() {
} }
pub fn script_path() -> PathBuf { pub fn script_path() -> PathBuf {
let script_file = chat_root().join("main.js"); let script_file = app_root().join("main.js");
if !exists(&script_file) { if !exists(&script_file) {
create_file(&script_file).unwrap(); create_file(&script_file).unwrap();
fs::write( fs::write(
@@ -96,7 +96,7 @@ pub fn convert_path(path_str: &str) -> String {
} }
pub fn clear_conf(app: &tauri::AppHandle) { pub fn clear_conf(app: &tauri::AppHandle) {
let root = chat_root(); let root = app_root();
let msg = format!( let msg = format!(
"Path: {}\n "Path: {}\n
Are you sure you want to clear all ChatGPT configurations? Performing this operation data can not be restored, please back up in advance.\n Are you sure you want to clear all ChatGPT configurations? Performing this operation data can not be restored, please back up in advance.\n

2
src/utils.ts vendored
View File

@@ -2,7 +2,7 @@ import { readTextFile, writeTextFile, exists, createDir } from '@tauri-apps/api/
import { homeDir, join, dirname } from '@tauri-apps/api/path'; import { homeDir, join, dirname } from '@tauri-apps/api/path';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
export const CHAT_CONF_JSON = 'chat.conf.json'; export const APP_CONF_JSON = 'chat.conf.json';
export const CHAT_MODEL_JSON = 'chat.model.json'; export const CHAT_MODEL_JSON = 'chat.model.json';
export const CHAT_MODEL_CMD_JSON = 'chat.model.cmd.json'; export const CHAT_MODEL_CMD_JSON = 'chat.model.cmd.json';
export const CHAT_DOWNLOAD_JSON = 'chat.download.json'; export const CHAT_DOWNLOAD_JSON = 'chat.download.json';

View File

@@ -7,7 +7,7 @@ import { os, invoke } from '@tauri-apps/api';
import useInit from '@/hooks/useInit'; import useInit from '@/hooks/useInit';
import useJson from '@/hooks/useJson'; import useJson from '@/hooks/useJson';
import { CHAT_AWESOME_JSON, CHAT_CONF_JSON, readJSON } from '@/utils'; import { CHAT_AWESOME_JSON, APP_CONF_JSON, readJSON } from '@/utils';
import './index.scss'; import './index.scss';
export default function Dashboard() { export default function Dashboard() {
@@ -19,7 +19,7 @@ export default function Dashboard() {
useInit(async () => { useInit(async () => {
const getOS = await os.platform(); const getOS = await os.platform();
const conf = await readJSON(CHAT_CONF_JSON); const conf = await readJSON(APP_CONF_JSON);
const appTheme = await invoke('get_theme'); const appTheme = await invoke('get_theme');
setTheme(appTheme as string); setTheme(appTheme as string);
setClass(!conf?.titlebar && getOS === 'darwin'); setClass(!conf?.titlebar && getOS === 'darwin');

View File

@@ -6,7 +6,7 @@ import { clone, omit, isEqual } from 'lodash';
import useInit from '@/hooks/useInit'; import useInit from '@/hooks/useInit';
import FilePath from '@/components/FilePath'; import FilePath from '@/components/FilePath';
import { chatRoot, CHAT_CONF_JSON } from '@/utils'; import { chatRoot, APP_CONF_JSON } from '@/utils';
import General from './General'; import General from './General';
import MainWindow from './MainWindow'; import MainWindow from './MainWindow';
import TrayWindow from './TrayWindow'; import TrayWindow from './TrayWindow';
@@ -24,8 +24,8 @@ export default function Settings() {
}, [key]); }, [key]);
useInit(async () => { useInit(async () => {
setChatConf(await invoke('get_chat_conf')); setChatConf(await invoke('get_app_conf'));
setPath(await path.join(await chatRoot(), CHAT_CONF_JSON)); setPath(await path.join(await chatRoot(), APP_CONF_JSON));
}); });
useEffect(() => { useEffect(() => {
@@ -37,7 +37,7 @@ export default function Settings() {
}; };
const onReset = async () => { const onReset = async () => {
const chatData = await invoke('reset_chat_conf'); const chatData = await invoke('reset_app_conf');
setChatConf(chatData); setChatConf(chatData);
const isOk = await dialog.ask(`Configuration reset successfully, whether to restart?`, { const isOk = await dialog.ask(`Configuration reset successfully, whether to restart?`, {
title: 'ChatGPT Preferences', title: 'ChatGPT Preferences',
@@ -69,7 +69,7 @@ export default function Settings() {
return ( return (
<div> <div>
<FilePath paths={CHAT_CONF_JSON} /> <FilePath paths={APP_CONF_JSON} />
<Form <Form
form={form} form={form}
style={{ maxWidth: 500 }} style={{ maxWidth: 500 }}