mirror of
https://github.com/FranP-code/ChatGPT.git
synced 2025-10-13 00:13:25 +00:00
Merge pull request #144 from tk103331/main
This commit is contained in:
@@ -43,6 +43,11 @@ pub fn reset_chat_conf() -> ChatConfJson {
|
|||||||
ChatConfJson::reset_chat_conf()
|
ChatConfJson::reset_chat_conf()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
pub fn run_check_update(app: AppHandle) -> () {
|
||||||
|
utils::run_check_update(app).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
pub fn form_confirm(_app: AppHandle, data: serde_json::Value) {
|
pub fn form_confirm(_app: AppHandle, data: serde_json::Value) {
|
||||||
ChatConfJson::amend(&serde_json::json!(data), None).unwrap();
|
ChatConfJson::amend(&serde_json::json!(data), None).unwrap();
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ pub fn init() -> Menu {
|
|||||||
MenuItem::About(name.into(), AboutMetadata::default()).into(),
|
MenuItem::About(name.into(), AboutMetadata::default()).into(),
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
CustomMenuItem::new("about".to_string(), "About ChatGPT").into(),
|
CustomMenuItem::new("about".to_string(), "About ChatGPT").into(),
|
||||||
|
CustomMenuItem::new("check_update".to_string(), "Check for Updates").into(),
|
||||||
MenuItem::Services.into(),
|
MenuItem::Services.into(),
|
||||||
MenuItem::Hide.into(),
|
MenuItem::Hide.into(),
|
||||||
MenuItem::HideOthers.into(),
|
MenuItem::HideOthers.into(),
|
||||||
@@ -192,6 +193,9 @@ pub fn menu_handler(event: WindowMenuEvent<tauri::Wry>) {
|
|||||||
format!("Version {}", tauri_conf.package.version.unwrap()),
|
format!("Version {}", tauri_conf.package.version.unwrap()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
"check_update" => {
|
||||||
|
utils::run_check_update(app).unwrap();
|
||||||
|
}
|
||||||
// Preferences
|
// Preferences
|
||||||
"control_center" => window::control_window(&app),
|
"control_center" => window::control_window(&app),
|
||||||
"restart" => tauri::api::process::restart(&app.env()),
|
"restart" => tauri::api::process::restart(&app.env()),
|
||||||
|
|||||||
@@ -89,6 +89,11 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box<dyn std::error::Error>
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// auto_check_update
|
||||||
|
if chat_conf.auto_check_update {
|
||||||
|
let app = app.handle();
|
||||||
|
utils::run_check_update(app).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ 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#"{
|
pub const DEFAULT_CHAT_CONF: &str = r#"{
|
||||||
"stay_on_top": false,
|
"stay_on_top": false,
|
||||||
|
"auto_check_update": true,
|
||||||
"theme": "Light",
|
"theme": "Light",
|
||||||
"titlebar": true,
|
"titlebar": true,
|
||||||
"global_shortcut": "",
|
"global_shortcut": "",
|
||||||
@@ -29,6 +30,7 @@ pub const DEFAULT_CHAT_CONF: &str = r#"{
|
|||||||
}"#;
|
}"#;
|
||||||
pub const DEFAULT_CHAT_CONF_MAC: &str = r#"{
|
pub const DEFAULT_CHAT_CONF_MAC: &str = r#"{
|
||||||
"stay_on_top": false,
|
"stay_on_top": false,
|
||||||
|
"auto_check_update": true,
|
||||||
"theme": "Light",
|
"theme": "Light",
|
||||||
"titlebar": false,
|
"titlebar": false,
|
||||||
"global_shortcut": "",
|
"global_shortcut": "",
|
||||||
@@ -60,6 +62,7 @@ pub struct ChatConfJson {
|
|||||||
// macOS and Windows
|
// macOS and Windows
|
||||||
pub theme: String,
|
pub theme: String,
|
||||||
|
|
||||||
|
pub auto_check_update: bool,
|
||||||
pub stay_on_top: bool,
|
pub stay_on_top: bool,
|
||||||
pub default_origin: String,
|
pub default_origin: String,
|
||||||
pub origin: String,
|
pub origin: String,
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ async fn main() {
|
|||||||
cmd::open_link,
|
cmd::open_link,
|
||||||
cmd::get_chat_conf,
|
cmd::get_chat_conf,
|
||||||
cmd::reset_chat_conf,
|
cmd::reset_chat_conf,
|
||||||
|
cmd::run_check_update,
|
||||||
cmd::form_cancel,
|
cmd::form_cancel,
|
||||||
cmd::form_confirm,
|
cmd::form_confirm,
|
||||||
cmd::form_msg,
|
cmd::form_msg,
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ use std::{
|
|||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::Command,
|
process::Command,
|
||||||
};
|
};
|
||||||
use tauri::{utils::config::Config, Manager};
|
use tauri::{utils::config::Config, Manager, AppHandle, Wry};
|
||||||
|
use tauri::updater::UpdateResponse;
|
||||||
pub fn chat_root() -> PathBuf {
|
pub fn chat_root() -> PathBuf {
|
||||||
tauri::api::path::home_dir().unwrap().join(".chatgpt")
|
tauri::api::path::home_dir().unwrap().join(".chatgpt")
|
||||||
}
|
}
|
||||||
@@ -128,3 +128,64 @@ pub async fn get_data(
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn run_check_update(app: AppHandle<Wry>) -> 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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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<Wry>,
|
||||||
|
update: UpdateResponse<Wry>
|
||||||
|
) -> Result<()> {
|
||||||
|
let windows = app.windows();
|
||||||
|
let parent_window = windows.values().next();
|
||||||
|
let package_info = app.package_info().clone();
|
||||||
|
|
||||||
|
let body = update.body().unwrap();
|
||||||
|
// todo(lemarier): We should review this and make sure we have
|
||||||
|
// something more conventional.
|
||||||
|
let should_install = tauri::api::dialog::blocking::ask(
|
||||||
|
parent_window,
|
||||||
|
format!(r#"A new version of {} is available! "#, package_info.name),
|
||||||
|
format!(
|
||||||
|
r#"{} {} is now available -- you have {}.
|
||||||
|
|
||||||
|
Would you like to install it now?
|
||||||
|
|
||||||
|
Release Notes:
|
||||||
|
{}"#,
|
||||||
|
package_info.name, update.latest_version(), package_info.version, body),
|
||||||
|
);
|
||||||
|
|
||||||
|
if should_install {
|
||||||
|
// 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 installation was successful, do you want to restart the application now?",
|
||||||
|
);
|
||||||
|
if should_exit {
|
||||||
|
app.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
"csp": null
|
"csp": null
|
||||||
},
|
},
|
||||||
"updater": {
|
"updater": {
|
||||||
"active": true,
|
"active": false,
|
||||||
"dialog": true,
|
"dialog": true,
|
||||||
"endpoints": [
|
"endpoints": [
|
||||||
"https://lencx.github.io/ChatGPT/install.json"
|
"https://lencx.github.io/ChatGPT/install.json"
|
||||||
@@ -75,4 +75,4 @@
|
|||||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEIxMjY4OUI5MTVFNjBEMDUKUldRRkRlWVZ1WWttc1NGWEE0RFNSb0RqdnhsekRJZTkwK2hVLzhBZTZnaHExSEZ1ZEdzWkpXTHkK"
|
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEIxMjY4OUI5MTVFNjBEMDUKUldRRkRlWVZ1WWttc1NGWEE0RFNSb0RqdnhsekRJZTkwK2hVLzhBZTZnaHExSEZ1ZEdzWkpXTHkK"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
src/layout/index.scss
vendored
5
src/layout/index.scss
vendored
@@ -7,7 +7,10 @@
|
|||||||
height: 48px;
|
height: 48px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.chat-info {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
.ant-layout-sider-trigger {
|
.ant-layout-sider-trigger {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
|
|||||||
25
src/layout/index.tsx
vendored
25
src/layout/index.tsx
vendored
@@ -1,12 +1,18 @@
|
|||||||
import { FC, useState } from 'react';
|
import { FC, useState } from 'react';
|
||||||
import { Layout, Menu } from 'antd';
|
import {Layout, Menu, Button, Tooltip, message} from 'antd';
|
||||||
|
import { SyncOutlined } from '@ant-design/icons';
|
||||||
import { useNavigate, useLocation } from 'react-router-dom';
|
import { useNavigate, useLocation } from 'react-router-dom';
|
||||||
|
import { getName, getVersion } from '@tauri-apps/api/app';
|
||||||
|
import { invoke } from '@tauri-apps/api';
|
||||||
|
|
||||||
import Routes, { menuItems } from '@/routes';
|
import Routes, { menuItems } from '@/routes';
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
const { Content, Footer, Sider } = Layout;
|
const { Content, Footer, Sider } = Layout;
|
||||||
|
|
||||||
|
const appName = await getName();
|
||||||
|
const appVersion = await getVersion();
|
||||||
|
|
||||||
interface ChatLayoutProps {
|
interface ChatLayoutProps {
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}
|
}
|
||||||
@@ -16,6 +22,10 @@ const ChatLayout: FC<ChatLayoutProps> = ({ children }) => {
|
|||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const go = useNavigate();
|
const go = useNavigate();
|
||||||
|
|
||||||
|
const checkAppUpdate = async () => {
|
||||||
|
await invoke('run_check_update');
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout style={{ minHeight: '100vh' }} hasSider>
|
<Layout style={{ minHeight: '100vh' }} hasSider>
|
||||||
<Sider
|
<Sider
|
||||||
@@ -34,6 +44,19 @@ const ChatLayout: FC<ChatLayoutProps> = ({ children }) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="chat-logo"><img src="/logo.png" /></div>
|
<div className="chat-logo"><img src="/logo.png" /></div>
|
||||||
|
<div className="chat-info">
|
||||||
|
<span>{appName}</span>
|
||||||
|
</div>
|
||||||
|
<div className="chat-info">
|
||||||
|
<span>{appVersion}</span>
|
||||||
|
<span> </span>
|
||||||
|
{
|
||||||
|
<Tooltip title="click to check update">
|
||||||
|
<a onClick={checkAppUpdate}><SyncOutlined /></a>
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
<Menu
|
<Menu
|
||||||
defaultSelectedKeys={[location.pathname]}
|
defaultSelectedKeys={[location.pathname]}
|
||||||
mode="inline"
|
mode="inline"
|
||||||
|
|||||||
11
src/view/General.tsx
vendored
11
src/view/General.tsx
vendored
@@ -10,6 +10,14 @@ import { clone, omit, isEqual } from 'lodash';
|
|||||||
import useInit from '@/hooks/useInit';
|
import useInit from '@/hooks/useInit';
|
||||||
import { DISABLE_AUTO_COMPLETE, chatRoot } from '@/utils';
|
import { DISABLE_AUTO_COMPLETE, chatRoot } from '@/utils';
|
||||||
|
|
||||||
|
const CheckUpdateLabel = () => {
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
Auto Check Update <Tooltip title={`check update on start`}><QuestionCircleOutlined style={{ color: '#1677ff' }} /></Tooltip>
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const OriginLabel = ({ url }: { url: string }) => {
|
const OriginLabel = ({ url }: { url: string }) => {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
@@ -108,6 +116,9 @@ export default function General() {
|
|||||||
<Form.Item label="Stay On Top" name="stay_on_top" valuePropName="checked">
|
<Form.Item label="Stay On Top" name="stay_on_top" valuePropName="checked">
|
||||||
<Switch />
|
<Switch />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item label={<CheckUpdateLabel />} name="auto_check_update" valuePropName="checked">
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
<Form.Item label={<GlobalShortcut />} name="global_shortcut">
|
<Form.Item label={<GlobalShortcut />} name="global_shortcut">
|
||||||
<Input placeholder="CmdOrCtrl+Shift+O" {...DISABLE_AUTO_COMPLETE} />
|
<Input placeholder="CmdOrCtrl+Shift+O" {...DISABLE_AUTO_COMPLETE} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
Reference in New Issue
Block a user