mirror of
https://github.com/FranP-code/ChatGPT.git
synced 2025-10-13 00:13:25 +00:00
feat: switch origin
This commit is contained in:
@@ -14,11 +14,11 @@ rust-version = "1.57"
|
|||||||
tauri-build = {version = "1.2.1", features = [] }
|
tauri-build = {version = "1.2.1", features = [] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow = "1.0.66"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
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"] }
|
tauri-plugin-positioner = { version = "1.0.4", features = ["system-tray"] }
|
||||||
anyhow = "1.0.66"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# by default Tauri runs in production mode
|
# by default Tauri runs in production mode
|
||||||
|
|||||||
@@ -33,3 +33,30 @@ pub fn open_link(app: AppHandle, url: String) {
|
|||||||
pub fn get_chat_conf() -> ChatConfJson {
|
pub fn get_chat_conf() -> ChatConfJson {
|
||||||
ChatConfJson::get_chat_conf()
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ use tauri::{
|
|||||||
use tauri_plugin_positioner::{on_tray_event, Position, WindowExt};
|
use tauri_plugin_positioner::{on_tray_event, Position, WindowExt};
|
||||||
|
|
||||||
// --- Menu
|
// --- Menu
|
||||||
pub fn init(chat_conf: &conf::ChatConfJson, context: &Context<EmbeddedAssets>) -> Menu {
|
pub fn init(context: &Context<EmbeddedAssets>) -> Menu {
|
||||||
|
let chat_conf = ChatConfJson::get_chat_conf();
|
||||||
let name = &context.package_info().name;
|
let name = &context.package_info().name;
|
||||||
let app_menu = Submenu::new(
|
let app_menu = Submenu::new(
|
||||||
name,
|
name,
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use tauri::{utils::config::WindowUrl, window::WindowBuilder, App, Manager};
|
use tauri::{utils::config::WindowUrl, window::WindowBuilder, App, Manager};
|
||||||
|
|
||||||
pub fn init(
|
pub fn init(app: &mut App) -> std::result::Result<(), Box<dyn std::error::Error>> {
|
||||||
app: &mut App,
|
let chat_conf = ChatConfJson::get_chat_conf();
|
||||||
chat_conf: ChatConfJson,
|
|
||||||
) -> std::result::Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let url = chat_conf.origin.to_string();
|
let url = chat_conf.origin.to_string();
|
||||||
let theme = ChatConfJson::theme();
|
let theme = ChatConfJson::theme();
|
||||||
window::mini_window(&app.app_handle());
|
window::mini_window(&app.app_handle());
|
||||||
|
|||||||
@@ -25,14 +25,17 @@ pub fn mini_window(handle: &tauri::AppHandle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn origin_window(handle: &tauri::AppHandle) {
|
pub fn origin_window(handle: &tauri::AppHandle) {
|
||||||
let theme = conf::ChatConfJson::theme();
|
let chat_conf = conf::ChatConfJson::get_chat_conf();
|
||||||
|
// tauri://localhost/origin
|
||||||
WindowBuilder::new(handle, "main", WindowUrl::External("/".parse().unwrap()))
|
// let url = chat_conf.origin;
|
||||||
|
WindowBuilder::new(handle, "origin", WindowUrl::App(chat_conf.origin.into()))
|
||||||
.resizable(false)
|
.resizable(false)
|
||||||
.fullscreen(false)
|
.fullscreen(false)
|
||||||
.inner_size(400.0, 300.0)
|
.inner_size(400.0, 300.0)
|
||||||
.always_on_top(true)
|
.always_on_top(true)
|
||||||
.theme(theme)
|
.decorations(false)
|
||||||
|
.initialization_script(include_str!("../assets/core.js"))
|
||||||
|
.initialization_script(include_str!("../assets/origin.js"))
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
23
src-tauri/src/assets/export.js
vendored
23
src-tauri/src/assets/export.js
vendored
@@ -2,6 +2,7 @@
|
|||||||
// @ref: https://github.com/liady/ChatGPT-pdf/blob/main/src/content_script.js
|
// @ref: https://github.com/liady/ChatGPT-pdf/blob/main/src/content_script.js
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
|
const chatConf = await invoke('get_chat_conf') || {};
|
||||||
if (window.buttonsInterval) {
|
if (window.buttonsInterval) {
|
||||||
clearInterval(window.buttonsInterval);
|
clearInterval(window.buttonsInterval);
|
||||||
}
|
}
|
||||||
@@ -16,7 +17,7 @@ async function init() {
|
|||||||
});
|
});
|
||||||
if (hasTryAgainButton && buttons.length === 1) {
|
if (hasTryAgainButton && buttons.length === 1) {
|
||||||
const TryAgainButton = actionsArea.querySelector("button");
|
const TryAgainButton = actionsArea.querySelector("button");
|
||||||
addActionsButtons(actionsArea, TryAgainButton);
|
addActionsButtons(actionsArea, TryAgainButton, chatConf);
|
||||||
} else if (!hasTryAgainButton) {
|
} else if (!hasTryAgainButton) {
|
||||||
removeButtons();
|
removeButtons();
|
||||||
}
|
}
|
||||||
@@ -28,7 +29,7 @@ const Format = {
|
|||||||
PDF: "pdf",
|
PDF: "pdf",
|
||||||
};
|
};
|
||||||
|
|
||||||
function addActionsButtons(actionsArea, TryAgainButton) {
|
function addActionsButtons(actionsArea, TryAgainButton, chatConf) {
|
||||||
const downloadButton = TryAgainButton.cloneNode(true);
|
const downloadButton = TryAgainButton.cloneNode(true);
|
||||||
downloadButton.id = "download-png-button";
|
downloadButton.id = "download-png-button";
|
||||||
downloadButton.innerText = "Generate PNG";
|
downloadButton.innerText = "Generate PNG";
|
||||||
@@ -36,6 +37,7 @@ function addActionsButtons(actionsArea, TryAgainButton) {
|
|||||||
downloadThread();
|
downloadThread();
|
||||||
};
|
};
|
||||||
actionsArea.appendChild(downloadButton);
|
actionsArea.appendChild(downloadButton);
|
||||||
|
|
||||||
const downloadPdfButton = TryAgainButton.cloneNode(true);
|
const downloadPdfButton = TryAgainButton.cloneNode(true);
|
||||||
downloadPdfButton.id = "download-pdf-button";
|
downloadPdfButton.id = "download-pdf-button";
|
||||||
downloadPdfButton.innerText = "Download PDF";
|
downloadPdfButton.innerText = "Download PDF";
|
||||||
@@ -43,13 +45,16 @@ function addActionsButtons(actionsArea, TryAgainButton) {
|
|||||||
downloadThread({ as: Format.PDF });
|
downloadThread({ as: Format.PDF });
|
||||||
};
|
};
|
||||||
actionsArea.appendChild(downloadPdfButton);
|
actionsArea.appendChild(downloadPdfButton);
|
||||||
const exportHtml = TryAgainButton.cloneNode(true);
|
|
||||||
exportHtml.id = "download-html-button";
|
if (new RegExp('//chat.openai.com').test(chatConf.origin)) {
|
||||||
exportHtml.innerText = "Share Link";
|
const exportHtml = TryAgainButton.cloneNode(true);
|
||||||
exportHtml.onclick = () => {
|
exportHtml.id = "download-html-button";
|
||||||
sendRequest();
|
exportHtml.innerText = "Share Link";
|
||||||
};
|
exportHtml.onclick = () => {
|
||||||
actionsArea.appendChild(exportHtml);
|
sendRequest();
|
||||||
|
};
|
||||||
|
actionsArea.appendChild(exportHtml);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeButtons() {
|
function removeButtons() {
|
||||||
|
|||||||
71
src-tauri/src/assets/origin.js
vendored
71
src-tauri/src/assets/origin.js
vendored
@@ -0,0 +1,71 @@
|
|||||||
|
function init() {
|
||||||
|
document.body.innerHTML = `<style>
|
||||||
|
body {
|
||||||
|
height: 100vh;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-family: Söhne,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,Helvetica Neue,Arial,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
all: unset;
|
||||||
|
width: 280px;
|
||||||
|
height: 30px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 0 5px;
|
||||||
|
border: solid 2px #d8d8d8;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
all: unset;
|
||||||
|
height: 30px;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 0 10px;
|
||||||
|
line-height: 30px;
|
||||||
|
margin: 0 5px;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
#cancel {
|
||||||
|
background-color: #999;
|
||||||
|
}
|
||||||
|
#confirm {
|
||||||
|
background-color: #10a37f;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<h3>Switch Origin</h3>
|
||||||
|
<input id="input" type="text" />
|
||||||
|
<div class="btns">
|
||||||
|
<button id="cancel">Cancel</button>
|
||||||
|
<button id="confirm">Confirm</button>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
@@ -12,7 +12,8 @@ pub const DEFAULT_CHAT_CONF: &str = r#"{
|
|||||||
"always_on_top": false,
|
"always_on_top": false,
|
||||||
"theme": "Light",
|
"theme": "Light",
|
||||||
"titlebar": true,
|
"titlebar": true,
|
||||||
"origin": "https://chat.openai.com/"
|
"default_origin": "https://chat.openai.com",
|
||||||
|
"origin": "https://chat.openai.com"
|
||||||
}"#;
|
}"#;
|
||||||
|
|
||||||
pub struct ChatState {
|
pub struct ChatState {
|
||||||
@@ -32,6 +33,7 @@ pub struct ChatConfJson {
|
|||||||
pub always_on_top: bool,
|
pub always_on_top: bool,
|
||||||
pub theme: String,
|
pub theme: String,
|
||||||
pub titlebar: bool,
|
pub titlebar: bool,
|
||||||
|
pub default_origin: String,
|
||||||
pub origin: String,
|
pub origin: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,10 +44,22 @@ impl ChatConfJson {
|
|||||||
let conf_file = ChatConfJson::conf_path();
|
let conf_file = ChatConfJson::conf_path();
|
||||||
if !exists(&conf_file) {
|
if !exists(&conf_file) {
|
||||||
create_file(&conf_file).unwrap();
|
create_file(&conf_file).unwrap();
|
||||||
fs::write(&conf_file, DEFAULT_CHAT_CONF).unwrap();
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
ChatConfJson::amend(&serde_json::json!({ "titlebar": false })).unwrap();
|
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
|
conf_file
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,26 +8,28 @@ mod conf;
|
|||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use app::{cmd, menu, setup};
|
use app::{cmd, menu, setup};
|
||||||
use conf::ChatConfJson;
|
use conf::{ChatConfJson, ChatState};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
ChatConfJson::init();
|
ChatConfJson::init();
|
||||||
let context = tauri::generate_context!();
|
|
||||||
let chat_conf = ChatConfJson::get_chat_conf();
|
let chat_conf = ChatConfJson::get_chat_conf();
|
||||||
let chat_conf2 = chat_conf.clone();
|
let context = tauri::generate_context!();
|
||||||
|
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.manage(conf::ChatState::default(chat_conf.clone()))
|
.manage(ChatState::default(chat_conf))
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
cmd::drag_window,
|
cmd::drag_window,
|
||||||
cmd::fullscreen,
|
cmd::fullscreen,
|
||||||
cmd::download,
|
cmd::download,
|
||||||
cmd::open_link,
|
cmd::open_link,
|
||||||
cmd::get_chat_conf,
|
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())
|
.plugin(tauri_plugin_positioner::init())
|
||||||
.menu(menu::init(&chat_conf, &context))
|
.menu(menu::init(&context))
|
||||||
.system_tray(menu::tray_menu())
|
.system_tray(menu::tray_menu())
|
||||||
.on_menu_event(menu::menu_handler)
|
.on_menu_event(menu::menu_handler)
|
||||||
.on_system_tray_event(menu::tray_handler)
|
.on_system_tray_event(menu::tray_handler)
|
||||||
|
|||||||
Reference in New Issue
Block a user