diff --git a/README-ZH_CN.md b/README-ZH_CN.md index 74c93fd..a3486a4 100644 --- a/README-ZH_CN.md +++ b/README-ZH_CN.md @@ -12,47 +12,49 @@ [![chat](https://img.shields.io/badge/chat-discord-blue?style=flat&logo=discord)](https://discord.gg/aPhCRf4zZr) [![lencx](https://img.shields.io/twitter/follow/lencx_.svg?style=social)](https://twitter.com/lencx_) -[Awesome ChatGPT](./AWESOME.md) +Buy Me A Coffee -## 📦 下载 +## 📦 安装 [📝 更新日志](./UPDATE_LOG.md) -**最新版:** +### Windows -- `Mac`: [ChatGPT_0.7.4_x64.dmg](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/ChatGPT_0.7.4_x64.dmg) -- `Windows`: [ChatGPT_0.7.4_x64_en-US.msi](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/ChatGPT_0.7.4_x64_en-US.msi) -- `Linux`: - - [chat-gpt_0.7.4_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/chat-gpt_0.7.4_amd64.deb) - - [chat-gpt_0.7.4_amd64.AppImage](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/chat-gpt_0.7.4_amd64.AppImage): **工作可靠,`.deb` 运行失败时可以尝试它** +- [ChatGPT_0.7.4_x64_en-US.msi](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/ChatGPT_0.7.4_x64_en-US.msi) +- 或者使用 [winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/): + - `winget install --id=lencx.ChatGPT -e` + - `winget install --id=lencx.ChatGPT -e --version 0.7.4` -[其他版本...](https://github.com/lencx/ChatGPT/releases) +**注意:如果安装路径和应用名称相同,会导致冲突 ([#142](https://github.com/lencx/ChatGPT/issues/142#issuecomment-1371166972))** + +### Mac + +- [ChatGPT_0.7.4_x64.dmg](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/ChatGPT_0.7.4_x64.dmg) +- 如果你偏爱 `.app` 的安装包,你同样可以在我们的 github releases 里找到 [ChatGPT.app.tar.gz](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/ChatGPT.app.tar.gz) +- Homebrew \ + _[Homebrew 快捷安装](https://brew.sh) ([Cask](https://docs.brew.sh/Cask-Cookbook)):_ + ```sh + brew tap lencx/chatgpt https://github.com/lencx/ChatGPT.git + brew install --cask chatgpt --no-quarantine + ``` + 如果你坚持使用 _[Brewfile](https://github.com/Homebrew/homebrew-bundle#usage)_ ,你需要添加以下配置: + ```rb + repo = "lencx/chatgpt" + tap repo, "https://github.com/#{repo}.git" + cask "chatgpt", args: { "no-quarantine": true } + ``` + +### Linux + +- [chat-gpt_0.7.4_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/chat-gpt_0.7.4_amd64.deb) +- [chat-gpt_0.7.4_amd64.AppImage](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/chat-gpt_0.7.4_amd64.AppImage): **工作可靠,`.deb` 运行失败时可以尝试它** -Buy Me A Coffee - --- -### brew 安装 - -_[Homebrew快捷安装](https://brew.sh) ([Cask](https://docs.brew.sh/Cask-Cookbook)):_ - -```sh -brew tap lencx/chatgpt https://github.com/lencx/ChatGPT.git -brew install --cask chatgpt --no-quarantine -``` - -如果你坚持使用 _[Brewfile](https://github.com/Homebrew/homebrew-bundle#usage)_ ,你需要添加以下配置: - -```rb -repo = "lencx/chatgpt" -tap repo, "https://github.com/#{repo}.git" -cask "chatgpt", args: { "no-quarantine": true } -``` - ## 📢 公告 这是一个令人兴奋的重大更新。像 `Telegram 机器人指令` 那样工作,帮助你快速填充自定模型,来让 ChatGPT 按照你想要的方式去工作。这个项目倾注了我大量业余时间,如果它对你有所帮助,宣传转发,或者 star 都是对我的巨大鼓励。我希望我可以持续更新下去,加入更多有趣的功能。 diff --git a/README.md b/README.md index fbf4bfa..ccbc88a 100644 --- a/README.md +++ b/README.md @@ -15,48 +15,55 @@ -## 📦 Downloads +Buy Me A Coffee + +## 📦 Install [📝 Update Log](./UPDATE_LOG.md) -**Latest:** +### Windows -- `Mac`: [ChatGPT_0.7.4_x64.dmg](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/ChatGPT_0.7.4_x64.dmg) -- `Windows`: [ChatGPT_0.7.4_x64_en-US.msi](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/ChatGPT_0.7.4_x64_en-US.msi) -- `Linux`: - - [chat-gpt_0.7.4_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/chat-gpt_0.7.4_amd64.deb) - - [chat-gpt_0.7.4_amd64.AppImage](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/chat-gpt_0.7.4_amd64.AppImage): **works reliably, you can try it if `.deb` fails to run** +- From our github releases: [ChatGPT_0.7.4_x64_en-US.msi](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/ChatGPT_0.7.4_x64_en-US.msi) +- Or install with [winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/): + - `winget install --id=lencx.ChatGPT -e` + - `winget install --id=lencx.ChatGPT -e --version 0.7.4` -[Other version...](https://github.com/lencx/ChatGPT/releases) +**Note: If the installation path and application name are the same, it will lead to conflict ([#142](https://github.com/lencx/ChatGPT/issues/142#issuecomment-1371166972))** + +### Mac + +- From our github releases: [ChatGPT_0.7.4_x64.dmg](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/ChatGPT_0.7.4_x64.dmg) +- If you prefer `.app` installation, you can also download it from our github releases: [ChatGPT.app.tar.gz](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/ChatGPT.app.tar.gz) +- Homebrew \ + Or you can install with _[Homebrew](https://brew.sh) ([Cask](https://docs.brew.sh/Cask-Cookbook)):_ + ```sh + brew tap lencx/chatgpt https://github.com/lencx/ChatGPT.git + brew install --cask chatgpt --no-quarantine + ``` + Also, if you keep a _[Brewfile](https://github.com/Homebrew/homebrew-bundle#usage)_, you can add something like this: + ```rb + repo = "lencx/chatgpt" + tap repo, "https://github.com/#{repo}.git" + cask "chatgpt", args: { "no-quarantine": true } + ``` + +### Linux + +- [chat-gpt_0.7.4_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/chat-gpt_0.7.4_amd64.deb) +- [chat-gpt_0.7.4_amd64.AppImage](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/chat-gpt_0.7.4_amd64.AppImage): **works reliably, you can try it if `.deb` fails to run** + +[History versions...](https://github.com/lencx/ChatGPT/releases) -Buy Me A Coffee - --- -### Install - -Easily install with _[Homebrew](https://brew.sh) ([Cask](https://docs.brew.sh/Cask-Cookbook)):_ - -```sh -brew tap lencx/chatgpt https://github.com/lencx/ChatGPT.git -brew install --cask chatgpt --no-quarantine -``` - -Also, if you keep a _[Brewfile](https://github.com/Homebrew/homebrew-bundle#usage)_, you can add something like this: - -```rb -repo = "lencx/chatgpt" -tap repo, "https://github.com/#{repo}.git" -cask "chatgpt", args: { "no-quarantine": true } -``` - ## 📢 Announcement ### ChatGPT Prompts! + This is a major and exciting update. It works like a `Telegram bot command` and helps you quickly populate custom models to make chatgpt work the way you want it to. This project has taken a lot of my spare time, so if it helps you, please help spread the word or star it would be a great encouragement to me. I hope I can keep updating it and adding more interesting features. ### How does it work? @@ -140,7 +147,7 @@ You can look at **[awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt Currently, only json and csv are supported for synchronizing custom files, and the following formats need to be met, otherwise the application will be abnormal: -> JSON format: +`JSON format:` ```json [ @@ -157,7 +164,7 @@ Currently, only json and csv are supported for synchronizing custom files, and t ] ``` -> CSV format +`CSV format` ```csv "cmd","act","prompt" diff --git a/src-tauri/src/app/cmd.rs b/src-tauri/src/app/cmd.rs index 52248f0..81657b8 100644 --- a/src-tauri/src/app/cmd.rs +++ b/src-tauri/src/app/cmd.rs @@ -51,8 +51,8 @@ pub fn reset_chat_conf() -> ChatConfJson { } #[command] -pub fn run_check_update(app: AppHandle) -> () { - utils::run_check_update(app).unwrap(); +pub fn run_check_update(app: AppHandle, silent: bool) { + utils::run_check_update(app, silent).unwrap(); } #[command] diff --git a/src-tauri/src/app/menu.rs b/src-tauri/src/app/menu.rs index 617f4da..285d84b 100644 --- a/src-tauri/src/app/menu.rs +++ b/src-tauri/src/app/menu.rs @@ -36,20 +36,27 @@ pub fn init() -> Menu { let stay_on_top = CustomMenuItem::new("stay_on_top".to_string(), "Stay On Top").accelerator("CmdOrCtrl+T"); + #[cfg(target_os = "macos")] 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 theme_system = CustomMenuItem::new("theme_system".to_string(), "System"); let is_dark = chat_conf.theme == "Dark"; let is_system = chat_conf.theme == "System"; + let update_prompt = CustomMenuItem::new("update_prompt".to_string(), "Prompt"); + let update_silent = CustomMenuItem::new("update_silent".to_string(), "Silent"); + let _update_disable = CustomMenuItem::new("update_disable".to_string(), "Disable"); + let stay_on_top_menu = if chat_conf.stay_on_top { stay_on_top.selected() } else { stay_on_top }; + #[cfg(target_os = "macos")] let titlebar_menu = if chat_conf.titlebar { titlebar.selected() @@ -84,6 +91,26 @@ pub fn init() -> Menu { }), ) .into(), + Submenu::new( + "Auto Update", + Menu::new() + .add_item(if chat_conf.auto_update == "Prompt" { + update_prompt.selected() + } else { + update_prompt + }) + .add_item(if chat_conf.auto_update == "Silent" { + update_silent.selected() + } else { + update_silent + }) + // .add_item(if chat_conf.auto_update == "Disable" { + // update_disable.selected() + // } else { + // update_disable + // }) + , + ).into(), stay_on_top_menu.into(), #[cfg(target_os = "macos")] titlebar_menu.into(), @@ -201,7 +228,7 @@ pub fn menu_handler(event: WindowMenuEvent) { ); } "check_update" => { - utils::run_check_update(app).unwrap(); + utils::run_check_update(app, false).unwrap(); } // Preferences "control_center" => window::control_window(&app), @@ -237,16 +264,34 @@ pub fn menu_handler(event: WindowMenuEvent) { .unwrap(); tauri::api::process::restart(&app.env()); } - "theme_light" | "theme_dark" | "theme_system" => { - let theme = if menu_id == "theme_dark" { - "Dark" - } else if menu_id == "theme_system" { - "System" - } else { - "Light" + "theme_light" | "theme_dark" | "theme_system" => { + let theme = match menu_id { + "theme_dark" => "Dark", + "theme_system" => "System", + _ => "Light", }; ChatConfJson::amend(&serde_json::json!({ "theme": theme }), Some(app)).unwrap(); } + "update_prompt" | "update_silent" | "update_disable" => { + for id in ["update_prompt" , "update_silent" , "update_disable"] { + menu_handle.get_item(id).set_selected(false).unwrap(); + } + let auto_update = match menu_id { + "update_silent" => { + menu_handle.get_item("update_silent").set_selected(true).unwrap(); + "Silent" + }, + "update_disable" => { + menu_handle.get_item("update_disable").set_selected(true).unwrap(); + "Disable" + }, + _ => { + menu_handle.get_item("update_prompt").set_selected(true).unwrap(); + "Prompt" + }, + }; + ChatConfJson::amend(&serde_json::json!({ "auto_update": auto_update }), None).unwrap(); + } "stay_on_top" => { let mut stay_on_top = state.stay_on_top.lock().unwrap(); *stay_on_top = !*stay_on_top; diff --git a/src-tauri/src/app/setup.rs b/src-tauri/src/app/setup.rs index d555404..4ddb5b6 100644 --- a/src-tauri/src/app/setup.rs +++ b/src-tauri/src/app/setup.rs @@ -95,10 +95,10 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box .unwrap(); }); } - // auto_check_update - if chat_conf.auto_check_update { + // auto_update + if chat_conf.auto_update != "Disable" { let app = app.handle(); - utils::run_check_update(app).unwrap(); + utils::run_check_update(app, chat_conf.auto_update == "Silent").unwrap(); } Ok(()) diff --git a/src-tauri/src/conf.rs b/src-tauri/src/conf.rs index 7153908..f71a188 100644 --- a/src-tauri/src/conf.rs +++ b/src-tauri/src/conf.rs @@ -18,7 +18,7 @@ pub const GITHUB_PROMPTS_CSV_URL: &str = "https://raw.githubusercontent.com/f/awesome-chatgpt-prompts/main/prompts.csv"; pub const DEFAULT_CHAT_CONF: &str = r#"{ "stay_on_top": false, - "auto_check_update": true, + "auto_update": "Prompt", "theme": "Light", "titlebar": true, "global_shortcut": "", @@ -30,7 +30,7 @@ pub const DEFAULT_CHAT_CONF: &str = r#"{ }"#; pub const DEFAULT_CHAT_CONF_MAC: &str = r#"{ "stay_on_top": false, - "auto_check_update": true, + "auto_update": "Prompt", "theme": "Light", "titlebar": false, "global_shortcut": "", @@ -59,10 +59,10 @@ pub struct ChatConfJson { pub titlebar: bool, pub hide_dock_icon: bool, - // macOS and Windows + // macOS and Windows, Light/Dark/System pub theme: String, - - pub auto_check_update: bool, + // auto update policy, Prompt/Silent/Disable + pub auto_update: String, pub stay_on_top: bool, pub default_origin: String, pub origin: String, @@ -177,21 +177,20 @@ impl ChatConfJson { pub fn theme() -> Option { let conf = ChatConfJson::get_chat_conf(); - if conf.theme == "System" { - let mode = dark_light::detect(); - return match mode { + let theme = match conf.theme.as_str() { + "System" => match dark_light::detect() { // Dark mode - dark_light::Mode::Dark => Some(Theme::Dark), + dark_light::Mode::Dark => Theme::Dark, // Light mode - dark_light::Mode::Light => Some(Theme::Light), + dark_light::Mode::Light => Theme::Light, // Unspecified - dark_light::Mode::Default => Some(Theme::Light), - } - } if conf.theme == "Dark" { - Some(Theme::Dark) - } else { - Some(Theme::Light) - } + dark_light::Mode::Default => Theme::Light, + }, + "Dark" => Theme::Dark, + _ => Theme::Light, + }; + + Some(theme) } #[cfg(target_os = "macos")] diff --git a/src-tauri/src/utils.rs b/src-tauri/src/utils.rs index c7a1732..a23c668 100644 --- a/src-tauri/src/utils.rs +++ b/src-tauri/src/utils.rs @@ -8,8 +8,8 @@ use std::{ path::{Path, PathBuf}, process::Command, }; -use tauri::{utils::config::Config, Manager, AppHandle, Wry}; use tauri::updater::UpdateResponse; +use tauri::{utils::config::Config, AppHandle, Manager, Wry}; pub fn chat_root() -> PathBuf { tauri::api::path::home_dir().unwrap().join(".chatgpt") @@ -130,14 +130,20 @@ pub async fn get_data( } } -pub fn run_check_update(app: AppHandle) -> Result<()> { +pub fn run_check_update(app: AppHandle, silent: bool) -> Result<()> { tauri::async_runtime::spawn(async move { let result = app.updater().check().await; let update_resp = result.unwrap(); if update_resp.is_update_available() { - tauri::async_runtime::spawn(async move { - prompt_for_install(app, update_resp).await.unwrap(); - }); + if silent { + tauri::async_runtime::spawn(async move { + silent_install(app, update_resp).await.unwrap(); + }); + } else { + tauri::async_runtime::spawn(async move { + prompt_for_install(app, update_resp).await.unwrap(); + }); + } } }); Ok(()) @@ -146,10 +152,7 @@ pub fn run_check_update(app: AppHandle) -> Result<()> { // Copy private api in tauri/updater/mod.rs. TODO: refactor to public api // Prompt a dialog asking if the user want to install the new version // Maybe we should add an option to customize it in future versions. -pub async fn prompt_for_install ( - app: AppHandle, - update: UpdateResponse -) -> Result<()> { +pub async fn prompt_for_install(app: AppHandle, update: UpdateResponse) -> Result<()> { let windows = app.windows(); let parent_window = windows.values().next(); let package_info = app.package_info().clone(); @@ -167,7 +170,11 @@ Would you like to install it now? Release Notes: {}"#, - package_info.name, update.latest_version(), package_info.version, body), + package_info.name, + update.latest_version(), + package_info.version, + body + ), ); if should_install { @@ -190,3 +197,26 @@ Release Notes: Ok(()) } + +pub async fn silent_install(app: AppHandle, update: UpdateResponse) -> Result<()> { + let windows = app.windows(); + let parent_window = windows.values().next(); + + // Launch updater download process + // macOS we display the `Ready to restart dialog` asking to restart + // Windows is closing the current App and launch the downloaded MSI when ready (the process stop here) + // Linux we replace the AppImage by launching a new install, it start a new AppImage instance, so we're closing the previous. (the process stop here) + update.download_and_install().await?; + + // Ask user if we need to restart the application + let should_exit = tauri::api::dialog::blocking::ask( + parent_window, + "Ready to Restart", + "The silent installation was successful, do you want to restart the application now?", + ); + if should_exit { + app.restart(); + } + + Ok(()) +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index c6611f7..406486b 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -68,7 +68,7 @@ }, "updater": { "active": true, - "dialog": true, + "dialog": false, "endpoints": [ "https://lencx.github.io/ChatGPT/install.json" ], diff --git a/src/layout/index.tsx b/src/layout/index.tsx index 667792a..82cf74a 100644 --- a/src/layout/index.tsx +++ b/src/layout/index.tsx @@ -23,7 +23,7 @@ const ChatLayout: FC = ({ children }) => { const go = useNavigate(); const checkAppUpdate = async () => { - await invoke('run_check_update'); + await invoke('run_check_update', {silent: false}); } return ( diff --git a/src/view/General.tsx b/src/view/General.tsx index 084c947..1291baf 100644 --- a/src/view/General.tsx +++ b/src/view/General.tsx @@ -10,10 +10,17 @@ import { clone, omit, isEqual } from 'lodash'; import useInit from '@/hooks/useInit'; import { DISABLE_AUTO_COMPLETE, chatRoot } from '@/utils'; -const CheckUpdateLabel = () => { +const AutoUpdateLabel = () => { return ( - Auto Check Update + Auto Update +
Auto Update Policy
+ Prompt: prompt to install
+ Silent: install silently
+ {/*Disable: disable auto update
*/} + + )}>
) } @@ -121,8 +128,12 @@ export default function General() { - } name="auto_check_update" valuePropName="checked"> - + } name="auto_update"> + + Prompt + Silent + {/*Disable*/} + } name="global_shortcut">