From e2235e706027c69869241add6e65dfc666939c5c Mon Sep 17 00:00:00 2001
From: lencx
Date: Sat, 31 Dec 2022 21:17:48 +0800
Subject: [PATCH 01/24] chore: log level
---
src-tauri/src/main.rs | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 05e9161..0db83a4 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -34,11 +34,7 @@ async fn main() {
// https://github.com/tauri-apps/tauri/pull/2736
.plugin(
LoggerBuilder::new()
- .level(if cfg!(debug_assertions) {
- log::LevelFilter::Debug
- } else {
- log::LevelFilter::Trace
- })
+ .level(log::LevelFilter::Debug)
.with_colors(colors)
.targets([
// LogTarget::LogDir,
From 4c86477d6f4d6b29f71b2943b4bde194c2c6f252 Mon Sep 17 00:00:00 2001
From: lencx
Date: Sun, 1 Jan 2023 16:21:20 +0800
Subject: [PATCH 02/24] chore: window
---
UPDATE_LOG.md | 5 +++++
src-tauri/src/app/menu.rs | 42 ++++++++++++++++++++++++++++-----------
src-tauri/src/main.rs | 5 +++++
3 files changed, 40 insertions(+), 12 deletions(-)
diff --git a/UPDATE_LOG.md b/UPDATE_LOG.md
index 8a6b166..0c12a73 100644
--- a/UPDATE_LOG.md
+++ b/UPDATE_LOG.md
@@ -1,5 +1,10 @@
# UPDATE LOG
+## v0.7.5
+
+fix:
+- close the main window and hide it in the tray (windows systems)
+
## v0.7.4
fix:
diff --git a/src-tauri/src/app/menu.rs b/src-tauri/src/app/menu.rs
index 7fe9b6e..0c948f1 100644
--- a/src-tauri/src/app/menu.rs
+++ b/src-tauri/src/app/menu.rs
@@ -293,12 +293,13 @@ pub fn menu_handler(event: WindowMenuEvent) {
// --- SystemTray Menu
pub fn tray_menu() -> SystemTray {
if cfg!(target_os = "macos") {
- return SystemTray::new().with_menu(
+ SystemTray::new().with_menu(
SystemTrayMenu::new()
.add_item(CustomMenuItem::new(
"control_center".to_string(),
"Control Center",
))
+ .add_native_item(SystemTrayMenuItem::Separator)
.add_item(CustomMenuItem::new(
"show_dock_icon".to_string(),
"Show Dock Icon",
@@ -307,20 +308,28 @@ pub fn tray_menu() -> SystemTray {
"hide_dock_icon".to_string(),
"Hide Dock Icon",
))
+ .add_item(CustomMenuItem::new(
+ "show_core".to_string(),
+ "Show ChatGPT",
+ ))
.add_native_item(SystemTrayMenuItem::Separator)
.add_item(CustomMenuItem::new("quit".to_string(), "Quit ChatGPT")),
- );
+ )
+ } else {
+ SystemTray::new().with_menu(
+ SystemTrayMenu::new()
+ .add_item(CustomMenuItem::new(
+ "control_center".to_string(),
+ "Control Center",
+ ))
+ .add_item(CustomMenuItem::new(
+ "show_core".to_string(),
+ "Show ChatGPT",
+ ))
+ .add_native_item(SystemTrayMenuItem::Separator)
+ .add_item(CustomMenuItem::new("quit".to_string(), "Quit ChatGPT")),
+ )
}
-
- SystemTray::new().with_menu(
- SystemTrayMenu::new()
- .add_item(CustomMenuItem::new(
- "control_center".to_string(),
- "Control Center",
- ))
- .add_native_item(SystemTrayMenuItem::Separator)
- .add_item(CustomMenuItem::new("quit".to_string(), "Quit ChatGPT")),
- )
}
// --- SystemTray Event
@@ -361,6 +370,15 @@ pub fn tray_handler(handle: &AppHandle, event: SystemTrayEvent) {
.unwrap();
}
}
+ "show_core" => {
+ let core_win = app.get_window("core").unwrap();
+ let tray_win = app.get_window("tray").unwrap();
+ if !core_win.is_visible().unwrap() {
+ core_win.show().unwrap();
+ core_win.set_focus().unwrap();
+ tray_win.hide().unwrap();
+ }
+ }
"quit" => std::process::exit(0),
_ => (),
},
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 0db83a4..82ebd8d 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -82,7 +82,12 @@ async fn main() {
// TODO: https://github.com/tauri-apps/tauri/issues/3084
// event.window().hide().unwrap();
// https://github.com/tauri-apps/tao/pull/517
+ #[cfg(target_os = "macos")]
event.window().minimize().unwrap();
+
+ // fix: https://github.com/lencx/ChatGPT/issues/93
+ #[cfg(not(target_os = "macos"))]
+ event.window().hide().unwrap();
}
api.prevent_close();
}
From 53a240953f795a4a2e813e1c2c7300071e7e6385 Mon Sep 17 00:00:00 2001
From: lencx
Date: Mon, 2 Jan 2023 17:40:33 +0800
Subject: [PATCH 03/24] chore: spawn
---
src-tauri/src/app/setup.rs | 4 ++--
src-tauri/src/app/window.rs | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src-tauri/src/app/setup.rs b/src-tauri/src/app/setup.rs
index b926a9f..22681a5 100644
--- a/src-tauri/src/app/setup.rs
+++ b/src-tauri/src/app/setup.rs
@@ -10,7 +10,7 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box
let theme = ChatConfJson::theme();
let handle = app.app_handle();
- tokio::spawn(async move {
+ tauri::async_runtime::spawn(async move {
window::tray_window(&handle);
});
@@ -49,7 +49,7 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box
app.set_activation_policy(tauri::ActivationPolicy::Accessory);
} else {
let app = app.handle();
- tokio::spawn(async move {
+ tauri::async_runtime::spawn(async move {
#[cfg(target_os = "macos")]
WindowBuilder::new(&app, "core", WindowUrl::App(url.into()))
.title("ChatGPT")
diff --git a/src-tauri/src/app/window.rs b/src-tauri/src/app/window.rs
index 546be04..e7a4294 100644
--- a/src-tauri/src/app/window.rs
+++ b/src-tauri/src/app/window.rs
@@ -6,7 +6,7 @@ pub fn tray_window(handle: &tauri::AppHandle) {
let theme = conf::ChatConfJson::theme();
let app = handle.clone();
- tokio::spawn(async move {
+ tauri::async_runtime::spawn(async move {
WindowBuilder::new(&app, "tray", WindowUrl::App(chat_conf.origin.into()))
.title("ChatGPT")
.resizable(false)
@@ -28,7 +28,7 @@ pub fn tray_window(handle: &tauri::AppHandle) {
pub fn control_window(handle: &tauri::AppHandle) {
let app = handle.clone();
- tokio::spawn(async move {
+ tauri::async_runtime::spawn(async move {
WindowBuilder::new(&app, "main", WindowUrl::App("index.html".into()))
.title("Control Center")
.resizable(true)
From 594260ce5d492f6827275afad0ed73acc8bdf822 Mon Sep 17 00:00:00 2001
From: lencx
Date: Wed, 4 Jan 2023 18:10:07 +0800
Subject: [PATCH 04/24] feat: dalle2 (#122)
---
src-tauri/src/app/cmd.rs | 24 +++--
src-tauri/src/app/menu.rs | 11 +--
src-tauri/src/app/setup.rs | 14 ++-
src-tauri/src/app/window.rs | 28 ++++++
src-tauri/src/assets/dalle2.core.js | 87 +++++++++++++++++++
src-tauri/src/assets/dalle2.js | 34 ++++++++
src-tauri/src/main.rs | 7 +-
src-tauri/src/vendors/floating-ui-core.js | 1 +
src-tauri/src/vendors/floating-ui-dom.js | 1 +
.../src/{assets => vendors}/html2canvas.js | 0
src-tauri/src/{assets => vendors}/jspdf.js | 0
11 files changed, 183 insertions(+), 24 deletions(-)
create mode 100644 src-tauri/src/assets/dalle2.core.js
create mode 100644 src-tauri/src/assets/dalle2.js
create mode 100644 src-tauri/src/vendors/floating-ui-core.js
create mode 100644 src-tauri/src/vendors/floating-ui-dom.js
rename src-tauri/src/{assets => vendors}/html2canvas.js (100%)
rename src-tauri/src/{assets => vendors}/jspdf.js (100%)
diff --git a/src-tauri/src/app/cmd.rs b/src-tauri/src/app/cmd.rs
index 104a93e..52248f0 100644
--- a/src-tauri/src/app/cmd.rs
+++ b/src-tauri/src/app/cmd.rs
@@ -1,16 +1,23 @@
use crate::{
+ app::window,
conf::{ChatConfJson, GITHUB_PROMPTS_CSV_URL},
- utils::{self, exists},
+ utils,
};
use log::info;
use std::{collections::HashMap, fs, path::PathBuf};
use tauri::{api, command, AppHandle, Manager};
+use walkdir::WalkDir;
#[command]
pub fn drag_window(app: AppHandle) {
app.get_window("core").unwrap().start_dragging().unwrap();
}
+#[command]
+pub fn dalle2_window(app: AppHandle, query: String) {
+ window::dalle2_window(&app.app_handle(), query);
+}
+
#[command]
pub fn fullscreen(app: AppHandle) {
let win = app.get_window("core").unwrap();
@@ -122,9 +129,6 @@ pub fn window_reload(app: AppHandle, label: &str) {
.unwrap();
}
-use utils::chat_root;
-use walkdir::WalkDir;
-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct ModelRecord {
pub cmd: String,
@@ -137,7 +141,7 @@ pub struct ModelRecord {
#[command]
pub fn cmd_list() -> Vec {
let mut list = vec![];
- for entry in WalkDir::new(chat_root().join("cache_model"))
+ for entry in WalkDir::new(utils::chat_root().join("cache_model"))
.into_iter()
.filter_map(|e| e.ok())
{
@@ -177,11 +181,13 @@ pub async fn sync_prompts(app: AppHandle, time: u64) -> Option>
let data2 = data.clone();
- let model = chat_root().join("chat.model.json");
- let model_cmd = chat_root().join("chat.model.cmd.json");
- let chatgpt_prompts = chat_root().join("cache_model").join("chatgpt_prompts.json");
+ let model = utils::chat_root().join("chat.model.json");
+ let model_cmd = utils::chat_root().join("chat.model.cmd.json");
+ let chatgpt_prompts = utils::chat_root()
+ .join("cache_model")
+ .join("chatgpt_prompts.json");
- if !exists(&model) {
+ if !utils::exists(&model) {
fs::write(
&model,
serde_json::json!({
diff --git a/src-tauri/src/app/menu.rs b/src-tauri/src/app/menu.rs
index 0c948f1..617f4da 100644
--- a/src-tauri/src/app/menu.rs
+++ b/src-tauri/src/app/menu.rs
@@ -261,6 +261,7 @@ pub fn menu_handler(event: WindowMenuEvent) {
"reload" => win.eval("window.location.reload()").unwrap(),
"go_back" => win.eval("window.history.go(-1)").unwrap(),
"go_forward" => win.eval("window.history.go(1)").unwrap(),
+ // core: document.querySelector('main .overflow-y-auto')
"scroll_top" => win
.eval(
r#"window.scroll({
@@ -308,10 +309,7 @@ pub fn tray_menu() -> SystemTray {
"hide_dock_icon".to_string(),
"Hide Dock Icon",
))
- .add_item(CustomMenuItem::new(
- "show_core".to_string(),
- "Show ChatGPT",
- ))
+ .add_item(CustomMenuItem::new("show_core".to_string(), "Show ChatGPT"))
.add_native_item(SystemTrayMenuItem::Separator)
.add_item(CustomMenuItem::new("quit".to_string(), "Quit ChatGPT")),
)
@@ -322,10 +320,7 @@ pub fn tray_menu() -> SystemTray {
"control_center".to_string(),
"Control Center",
))
- .add_item(CustomMenuItem::new(
- "show_core".to_string(),
- "Show ChatGPT",
- ))
+ .add_item(CustomMenuItem::new("show_core".to_string(), "Show ChatGPT"))
.add_native_item(SystemTrayMenuItem::Separator)
.add_item(CustomMenuItem::new("quit".to_string(), "Quit ChatGPT")),
)
diff --git a/src-tauri/src/app/setup.rs b/src-tauri/src/app/setup.rs
index 22681a5..d555404 100644
--- a/src-tauri/src/app/setup.rs
+++ b/src-tauri/src/app/setup.rs
@@ -61,9 +61,12 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box
.always_on_top(chat_conf.stay_on_top)
.title_bar_style(ChatConfJson::titlebar())
.initialization_script(&utils::user_script())
- .initialization_script(include_str!("../assets/html2canvas.js"))
- .initialization_script(include_str!("../assets/jspdf.js"))
+ .initialization_script(include_str!("../vendors/floating-ui-core.js"))
+ .initialization_script(include_str!("../vendors/floating-ui-dom.js"))
+ .initialization_script(include_str!("../vendors/html2canvas.js"))
+ .initialization_script(include_str!("../vendors/jspdf.js"))
.initialization_script(include_str!("../assets/core.js"))
+ .initialization_script(include_str!("../assets/dalle2.core.js"))
.initialization_script(include_str!("../assets/export.js"))
.initialization_script(include_str!("../assets/cmd.js"))
.user_agent(&chat_conf.ua_window)
@@ -79,9 +82,12 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box
.theme(theme)
.always_on_top(chat_conf.stay_on_top)
.initialization_script(&utils::user_script())
- .initialization_script(include_str!("../assets/html2canvas.js"))
- .initialization_script(include_str!("../assets/jspdf.js"))
+ .initialization_script(include_str!("../vendors/floating-ui-core.js"))
+ .initialization_script(include_str!("../vendors/floating-ui-dom.js"))
+ .initialization_script(include_str!("../vendors/html2canvas.js"))
+ .initialization_script(include_str!("../vendors/jspdf.js"))
.initialization_script(include_str!("../assets/core.js"))
+ .initialization_script(include_str!("../assets/dalle2.core.js"))
.initialization_script(include_str!("../assets/export.js"))
.initialization_script(include_str!("../assets/cmd.js"))
.user_agent(&chat_conf.ua_window)
diff --git a/src-tauri/src/app/window.rs b/src-tauri/src/app/window.rs
index e7a4294..8eade7a 100644
--- a/src-tauri/src/app/window.rs
+++ b/src-tauri/src/app/window.rs
@@ -1,4 +1,5 @@
use crate::{conf, utils};
+use std::time::SystemTime;
use tauri::{utils::config::WindowUrl, window::WindowBuilder};
pub fn tray_window(handle: &tauri::AppHandle) {
@@ -26,6 +27,33 @@ pub fn tray_window(handle: &tauri::AppHandle) {
});
}
+pub fn dalle2_window(handle: &tauri::AppHandle, query: String) {
+ let timestamp = SystemTime::now()
+ .duration_since(SystemTime::UNIX_EPOCH)
+ .unwrap()
+ .as_secs();
+ let theme = conf::ChatConfJson::theme();
+ let app = handle.clone();
+
+ tauri::async_runtime::spawn(async move {
+ WindowBuilder::new(&app, format!("dalle2_{}", timestamp), WindowUrl::App("https://labs.openai.com".into()))
+ .title("ChatGPT & DALL·E 2")
+ .resizable(true)
+ .fullscreen(false)
+ .inner_size(800.0, 600.0)
+ .always_on_top(false)
+ .theme(theme)
+ .initialization_script(include_str!("../assets/core.js"))
+ .initialization_script(&format!(
+ "window.addEventListener('DOMContentLoaded', function() {{\nwindow.__CHATGPT_QUERY__='{}';\n}})",
+ query
+ ))
+ .initialization_script(include_str!("../assets/dalle2.js"))
+ .build()
+ .unwrap();
+ });
+}
+
pub fn control_window(handle: &tauri::AppHandle) {
let app = handle.clone();
tauri::async_runtime::spawn(async move {
diff --git a/src-tauri/src/assets/dalle2.core.js b/src-tauri/src/assets/dalle2.core.js
new file mode 100644
index 0000000..bb28e10
--- /dev/null
+++ b/src-tauri/src/assets/dalle2.core.js
@@ -0,0 +1,87 @@
+// *** Core Script - DALL·E 2 Core ***
+
+async function init() {
+ if (!window.FloatingUIDOM) return;
+
+ const styleDom = document.createElement('style');
+ styleDom.innerHTML = `
+ #chagpt-selection-menu {
+ display: none;
+ width: max-content;
+ position: absolute;
+ top: 0;
+ left: 0;
+ background: #4a4a4a;
+ color: white;
+ font-weight: bold;
+ padding: 5px 8px;
+ border-radius: 4px;
+ font-size: 12px;
+ cursor: pointer;
+ }
+ `;
+ document.head.append(styleDom);
+
+ const selectionMenu = document.createElement('div');
+ selectionMenu.id = 'chagpt-selection-menu';
+ selectionMenu.innerHTML = 'DALL·E 2';
+ document.body.appendChild(selectionMenu);
+ const { computePosition, flip, offset, shift } = window.FloatingUIDOM;
+
+ document.body.addEventListener("mouseup", async (e) => {
+ const selection = window.getSelection();
+ if (window.__DALLE2_STATE__ !== 1) {
+ window.__DALLE2_CONTENT__ = selection.toString().trim();
+ }
+
+ if (e.target.id === 'chagpt-selection-menu') {
+ await invoke('dalle2_window', { query: encodeURIComponent(window.__DALLE2_CONTENT__) });
+ }
+
+ if (window.__DALLE2_STATE__ === 1) {
+ delete window.__DALLE2_STATE__;
+ delete window.__DALLE2_CONTENT__;
+ }
+
+ selectionMenu.style.display = 'none';
+ if (!window.__DALLE2_CONTENT__) return;
+
+ if (selection.rangeCount > 0) {
+ const range = selection.getRangeAt(0);
+ const rect = range.getClientRects()[0];
+
+ const rootEl = document.createElement('div');
+ rootEl.style.top = `${rect.top}px`;
+ rootEl.style.position = 'fixed';
+ rootEl.style.left = `${rect.left}px`;
+ document.body.appendChild(rootEl);
+
+ window.__DALLE2_STATE__ = 1;
+
+ selectionMenu.style.display = 'block';
+ computePosition(rootEl, selectionMenu, {
+ placement: 'top',
+ middleware: [
+ flip(),
+ offset(5),
+ shift({ padding: 5 })
+ ]
+ }).then(({x, y}) => {
+ Object.assign(selectionMenu.style, {
+ left: `${x}px`,
+ top: `${y}px`,
+ });
+ });
+ }
+ });
+
+}
+
+if (
+ document.readyState === "complete" ||
+ document.readyState === "interactive"
+) {
+ init();
+} else {
+ document.addEventListener("DOMContentLoaded", init);
+}
\ No newline at end of file
diff --git a/src-tauri/src/assets/dalle2.js b/src-tauri/src/assets/dalle2.js
new file mode 100644
index 0000000..0aa323b
--- /dev/null
+++ b/src-tauri/src/assets/dalle2.js
@@ -0,0 +1,34 @@
+// *** Core Script - DALL·E 2 ***
+
+async function init() {
+ if (window.searchInterval) {
+ clearInterval(window.searchInterval);
+ }
+
+ window.searchInterval = setInterval(() => {
+ // const searchForm = document.querySelector('.image-prompt-form-wrapper form');
+ // const searchBtn = document.querySelector('.image-prompt-form-wrapper form .image-prompt-btn');
+ const searchInput = document.querySelector('.image-prompt-form-wrapper form>.text-input');
+ if (searchInput) {
+ const query = decodeURIComponent(window.__CHATGPT_QUERY__);
+ searchInput.focus();
+ searchInput.value = query;
+ searchInput.setAttribute('value', query);
+ // searchInput.dispatchEvent(new CustomEvent('change'));
+ // searchForm.classList.add('focused');
+ // searchBtn.classList.add('active-style');
+ // searchBtn.removeAttribute('disabled');
+ // searchBtn.classList.remove('btn-disabled', 'btn-disabled-style');
+ clearInterval(window.searchInterval);
+ }
+ }, 200)
+}
+
+if (
+ document.readyState === "complete" ||
+ document.readyState === "interactive"
+) {
+ init();
+} else {
+ document.addEventListener("DOMContentLoaded", init);
+}
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 82ebd8d..6224712 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -63,6 +63,7 @@ async fn main() {
cmd::sync_prompts,
cmd::sync_user_prompts,
cmd::window_reload,
+ cmd::dalle2_window,
cmd::cmd_list,
fs_extra::metadata,
])
@@ -76,9 +77,7 @@ async fn main() {
// https://github.com/tauri-apps/tauri/discussions/2684
if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() {
let win = event.window();
- if win.label() == "main" {
- win.close().unwrap();
- } else {
+ if win.label() == "core" {
// TODO: https://github.com/tauri-apps/tauri/issues/3084
// event.window().hide().unwrap();
// https://github.com/tauri-apps/tao/pull/517
@@ -88,6 +87,8 @@ async fn main() {
// fix: https://github.com/lencx/ChatGPT/issues/93
#[cfg(not(target_os = "macos"))]
event.window().hide().unwrap();
+ } else {
+ win.close().unwrap();
}
api.prevent_close();
}
diff --git a/src-tauri/src/vendors/floating-ui-core.js b/src-tauri/src/vendors/floating-ui-core.js
new file mode 100644
index 0000000..a0f787b
--- /dev/null
+++ b/src-tauri/src/vendors/floating-ui-core.js
@@ -0,0 +1 @@
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).FloatingUICore={})}(this,(function(t){"use strict";function e(t){return t.split("-")[1]}function n(t){return"y"===t?"height":"width"}function i(t){return t.split("-")[0]}function o(t){return["top","bottom"].includes(i(t))?"x":"y"}function r(t,r,a){let{reference:l,floating:s}=t;const f=l.x+l.width/2-s.width/2,c=l.y+l.height/2-s.height/2,u=o(r),m=n(u),d=l[m]/2-s[m]/2,g="x"===u;let p;switch(i(r)){case"top":p={x:f,y:l.y-s.height};break;case"bottom":p={x:f,y:l.y+l.height};break;case"right":p={x:l.x+l.width,y:c};break;case"left":p={x:l.x-s.width,y:c};break;default:p={x:l.x,y:l.y}}switch(e(r)){case"start":p[u]-=d*(a&&g?-1:1);break;case"end":p[u]+=d*(a&&g?-1:1)}return p}function a(t){return"number"!=typeof t?function(t){return{top:0,right:0,bottom:0,left:0,...t}}(t):{top:t,right:t,bottom:t,left:t}}function l(t){return{...t,top:t.y,left:t.x,right:t.x+t.width,bottom:t.y+t.height}}async function s(t,e){var n;void 0===e&&(e={});const{x:i,y:o,platform:r,rects:s,elements:f,strategy:c}=t,{boundary:u="clippingAncestors",rootBoundary:m="viewport",elementContext:d="floating",altBoundary:g=!1,padding:p=0}=e,h=a(p),y=f[g?"floating"===d?"reference":"floating":d],x=l(await r.getClippingRect({element:null==(n=await(null==r.isElement?void 0:r.isElement(y)))||n?y:y.contextElement||await(null==r.getDocumentElement?void 0:r.getDocumentElement(f.floating)),boundary:u,rootBoundary:m,strategy:c})),w="floating"===d?{...s.floating,x:i,y:o}:s.reference,v=await(null==r.getOffsetParent?void 0:r.getOffsetParent(f.floating)),b=await(null==r.isElement?void 0:r.isElement(v))&&await(null==r.getScale?void 0:r.getScale(v))||{x:1,y:1},R=l(r.convertOffsetParentRelativeRectToViewportRelativeRect?await r.convertOffsetParentRelativeRectToViewportRelativeRect({rect:w,offsetParent:v,strategy:c}):w);return{top:(x.top-R.top+h.top)/b.y,bottom:(R.bottom-x.bottom+h.bottom)/b.y,left:(x.left-R.left+h.left)/b.x,right:(R.right-x.right+h.right)/b.x}}const f=Math.min,c=Math.max;function u(t,e,n){return c(t,f(e,n))}const m=["top","right","bottom","left"],d=m.reduce(((t,e)=>t.concat(e,e+"-start",e+"-end")),[]),g={left:"right",right:"left",bottom:"top",top:"bottom"};function p(t){return t.replace(/left|right|bottom|top/g,(t=>g[t]))}function h(t,i,r){void 0===r&&(r=!1);const a=e(t),l=o(t),s=n(l);let f="x"===l?a===(r?"end":"start")?"right":"left":"start"===a?"bottom":"top";return i.reference[s]>i.floating[s]&&(f=p(f)),{main:f,cross:p(f)}}const y={start:"end",end:"start"};function x(t){return t.replace(/start|end/g,(t=>y[t]))}function w(t,e){return{top:t.top-e.height,right:t.right-e.width,bottom:t.bottom-e.height,left:t.left-e.width}}function v(t){return m.some((e=>t[e]>=0))}function b(t){return"x"===t?"y":"x"}t.arrow=t=>({name:"arrow",options:t,async fn(i){const{element:r,padding:l=0}=t||{},{x:s,y:f,placement:c,rects:m,platform:d}=i;if(null==r)return{};const g=a(l),p={x:s,y:f},h=o(c),y=n(h),x=await d.getDimensions(r),w="y"===h?"top":"left",v="y"===h?"bottom":"right",b=m.reference[y]+m.reference[h]-p[h]-m.floating[y],R=p[h]-m.reference[h],A=await(null==d.getOffsetParent?void 0:d.getOffsetParent(r));let P=A?"y"===h?A.clientHeight||0:A.clientWidth||0:0;0===P&&(P=m.floating[y]);const T=b/2-R/2,O=g[w],D=P-x[y]-g[v],E=P/2-x[y]/2+T,L=u(O,E,D),k=null!=e(c)&&E!=L&&m.reference[y]/2-(Ee(n)===t)),...o.filter((n=>e(n)!==t))]:o.filter((t=>i(t)===t))).filter((i=>!t||e(i)===t||!!n&&x(i)!==i))}(g||null,y,p):p,b=await s(n,w),R=(null==(o=f.autoPlacement)?void 0:o.index)||0,A=v[R];if(null==A)return{};const{main:P,cross:T}=h(A,l,await(null==u.isRTL?void 0:u.isRTL(m.floating)));if(c!==A)return{reset:{placement:v[0]}};const O=[b[i(A)],b[P],b[T]],D=[...(null==(r=f.autoPlacement)?void 0:r.overflows)||[],{placement:A,overflows:O}],E=v[R+1];if(E)return{data:{index:R+1,overflows:D},reset:{placement:E}};const L=D.slice().sort(((t,e)=>t.overflows[0]-e.overflows[0])),k=null==(a=L.find((t=>{let{overflows:e}=t;return e.every((t=>t<=0))})))?void 0:a.placement,C=k||L[0].placement;return C!==c?{data:{index:R+1,overflows:D},reset:{placement:C}}:{}}}},t.computePosition=async(t,e,n)=>{const{placement:i="bottom",strategy:o="absolute",middleware:a=[],platform:l}=n,s=a.filter(Boolean),f=await(null==l.isRTL?void 0:l.isRTL(e));let c=await l.getElementRects({reference:t,floating:e,strategy:o}),{x:u,y:m}=r(c,i,f),d=i,g={},p=0;for(let n=0;nt+"-"+a)),n&&(l=l.concat(l.map(x)))),l}(f,v,w,P));const O=[f,...T],D=await s(n,b),E=[];let L=(null==(o=a.flip)?void 0:o.overflows)||[];if(m&&E.push(D[R]),d){const{main:t,cross:e}=h(r,l,P);E.push(D[t],D[e])}if(L=[...L,{placement:r,overflows:E}],!E.every((t=>t<=0))){var k;const t=((null==(k=a.flip)?void 0:k.index)||0)+1,e=O[t];if(e)return{data:{index:t,overflows:L},reset:{placement:e}};let n="bottom";switch(y){case"bestFit":{var C;const t=null==(C=L.map((t=>[t,t.overflows.filter((t=>t>0)).reduce(((t,e)=>t+e),0)])).sort(((t,e)=>t[1]-e[1]))[0])?void 0:C[0].placement;t&&(n=t);break}case"initialPlacement":n=f}if(r!==n)return{reset:{placement:n}}}return{}}}},t.hide=function(t){return void 0===t&&(t={}),{name:"hide",options:t,async fn(e){const{strategy:n="referenceHidden",...i}=t,{rects:o}=e;switch(n){case"referenceHidden":{const t=w(await s(e,{...i,elementContext:"reference"}),o.reference);return{data:{referenceHiddenOffsets:t,referenceHidden:v(t)}}}case"escaped":{const t=w(await s(e,{...i,altBoundary:!0}),o.floating);return{data:{escapedOffsets:t,escaped:v(t)}}}default:return{}}}}},t.inline=function(t){return void 0===t&&(t={}),{name:"inline",options:t,async fn(e){const{placement:n,elements:r,rects:s,platform:u,strategy:m}=e,{padding:d=2,x:g,y:p}=t,h=l(u.convertOffsetParentRelativeRectToViewportRelativeRect?await u.convertOffsetParentRelativeRectToViewportRelativeRect({rect:s.reference,offsetParent:await(null==u.getOffsetParent?void 0:u.getOffsetParent(r.floating)),strategy:m}):s.reference),y=await(null==u.getClientRects?void 0:u.getClientRects(r.reference))||[],x=a(d);const w=await u.getElementRects({reference:{getBoundingClientRect:function(){if(2===y.length&&y[0].left>y[1].right&&null!=g&&null!=p)return y.find((t=>g>t.left-x.left&>.top-x.top&&p=2){if("x"===o(n)){const t=y[0],e=y[y.length-1],o="top"===i(n),r=t.top,a=e.bottom,l=o?t.left:e.left,s=o?t.right:e.right;return{top:r,bottom:a,left:l,right:s,width:s-l,height:a-r,x:l,y:r}}const t="left"===i(n),e=c(...y.map((t=>t.right))),r=f(...y.map((t=>t.left))),a=y.filter((n=>t?n.left===r:n.right===e)),l=a[0].top,s=a[a.length-1].bottom;return{top:l,bottom:s,left:r,right:e,width:e-r,height:s-l,x:r,y:l}}return h}},floating:r.floating,strategy:m});return s.reference.x!==w.reference.x||s.reference.y!==w.reference.y||s.reference.width!==w.reference.width||s.reference.height!==w.reference.height?{reset:{rects:w}}:{}}}},t.limitShift=function(t){return void 0===t&&(t={}),{options:t,fn(e){const{x:n,y:r,placement:a,rects:l,middlewareData:s}=e,{offset:f=0,mainAxis:c=!0,crossAxis:u=!0}=t,m={x:n,y:r},d=o(a),g=b(d);let p=m[d],h=m[g];const y="function"==typeof f?f(e):f,x="number"==typeof y?{mainAxis:y,crossAxis:0}:{mainAxis:0,crossAxis:0,...y};if(c){const t="y"===d?"height":"width",e=l.reference[d]-l.floating[t]+x.mainAxis,n=l.reference[d]+l.reference[t]-x.mainAxis;pn&&(p=n)}if(u){var w,v;const t="y"===d?"width":"height",e=["top","left"].includes(i(a)),n=l.reference[g]-l.floating[t]+(e&&(null==(w=s.offset)?void 0:w[g])||0)+(e?0:x.crossAxis),o=l.reference[g]+l.reference[t]+(e?0:(null==(v=s.offset)?void 0:v[g])||0)-(e?x.crossAxis:0);ho&&(h=o)}return{[d]:p,[g]:h}}}},t.offset=function(t){return void 0===t&&(t=0),{name:"offset",options:t,async fn(n){const{x:r,y:a}=n,l=await async function(t,n){const{placement:r,platform:a,elements:l}=t,s=await(null==a.isRTL?void 0:a.isRTL(l.floating)),f=i(r),c=e(r),u="x"===o(r),m=["left","top"].includes(f)?-1:1,d=s&&u?-1:1,g="function"==typeof n?n(t):n;let{mainAxis:p,crossAxis:h,alignmentAxis:y}="number"==typeof g?{mainAxis:g,crossAxis:0,alignmentAxis:null}:{mainAxis:0,crossAxis:0,alignmentAxis:null,...g};return c&&"number"==typeof y&&(h="end"===c?-1*y:y),u?{x:h*d,y:p*m}:{x:p*m,y:h*d}}(n,t);return{x:r+l.x,y:a+l.y,data:l}}}},t.rectToClientRect=l,t.shift=function(t){return void 0===t&&(t={}),{name:"shift",options:t,async fn(e){const{x:n,y:r,placement:a}=e,{mainAxis:l=!0,crossAxis:f=!1,limiter:c={fn:t=>{let{x:e,y:n}=t;return{x:e,y:n}}},...m}=t,d={x:n,y:r},g=await s(e,m),p=o(i(a)),h=b(p);let y=d[p],x=d[h];if(l){const t="y"===p?"bottom":"right";y=u(y+g["y"===p?"top":"left"],y,y-g[t])}if(f){const t="y"===h?"bottom":"right";x=u(x+g["y"===h?"top":"left"],x,x-g[t])}const w=c.fn({...e,[p]:y,[h]:x});return{...w,data:{x:w.x-n,y:w.y-r}}}}},t.size=function(t){return void 0===t&&(t={}),{name:"size",options:t,async fn(n){const{placement:o,rects:r,platform:a,elements:l}=n,{apply:f=(()=>{}),...u}=t,m=await s(n,u),d=i(o),g=e(o);let p,h;"top"===d||"bottom"===d?(p=d,h=g===(await(null==a.isRTL?void 0:a.isRTL(l.floating))?"start":"end")?"left":"right"):(h=d,p="end"===g?"top":"bottom");const y=c(m.left,0),x=c(m.right,0),w=c(m.top,0),v=c(m.bottom,0),b={availableHeight:r.floating.height-(["left","right"].includes(o)?2*(0!==w||0!==v?w+v:c(m.top,m.bottom)):m[p]),availableWidth:r.floating.width-(["top","bottom"].includes(o)?2*(0!==y||0!==x?y+x:c(m.left,m.right)):m[h])};await f({...n,...b});const R=await a.getDimensions(l.floating);return r.floating.width!==R.width||r.floating.height!==R.height?{reset:{rects:!0}}:{}}}},Object.defineProperty(t,"__esModule",{value:!0})}));
\ No newline at end of file
diff --git a/src-tauri/src/vendors/floating-ui-dom.js b/src-tauri/src/vendors/floating-ui-dom.js
new file mode 100644
index 0000000..5c7c9a3
--- /dev/null
+++ b/src-tauri/src/vendors/floating-ui-dom.js
@@ -0,0 +1 @@
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@floating-ui/core")):"function"==typeof define&&define.amd?define(["exports","@floating-ui/core"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).FloatingUIDOM={},t.FloatingUICore)}(this,(function(t,e){"use strict";function n(t){var e;return(null==(e=t.ownerDocument)?void 0:e.defaultView)||window}function o(t){return n(t).getComputedStyle(t)}function i(t){return s(t)?(t.nodeName||"").toLowerCase():""}let r;function l(){if(r)return r;const t=navigator.userAgentData;return t&&Array.isArray(t.brands)?(r=t.brands.map((t=>t.brand+"/"+t.version)).join(" "),r):navigator.userAgent}function c(t){return t instanceof n(t).HTMLElement}function f(t){return t instanceof n(t).Element}function s(t){return t instanceof n(t).Node}function u(t){if("undefined"==typeof ShadowRoot)return!1;return t instanceof n(t).ShadowRoot||t instanceof ShadowRoot}function a(t){const{overflow:e,overflowX:n,overflowY:i,display:r}=o(t);return/auto|scroll|overlay|hidden|clip/.test(e+i+n)&&!["inline","contents"].includes(r)}function d(t){return["table","td","th"].includes(i(t))}function h(t){const e=/firefox/i.test(l()),n=o(t),i=n.backdropFilter||n.WebkitBackdropFilter;return"none"!==n.transform||"none"!==n.perspective||!!i&&"none"!==i||e&&"filter"===n.willChange||e&&!!n.filter&&"none"!==n.filter||["transform","perspective"].some((t=>n.willChange.includes(t)))||["paint","layout","strict","content"].some((t=>{const e=n.contain;return null!=e&&e.includes(t)}))}function p(){return!/^((?!chrome|android).)*safari/i.test(l())}function g(t){return["html","body","#document"].includes(i(t))}const m=Math.min,y=Math.max,b=Math.round;function w(t){const e=o(t);let n=parseFloat(e.width),i=parseFloat(e.height);const r=t.offsetWidth,l=t.offsetHeight,c=b(n)!==r||b(i)!==l;return c&&(n=r,i=l),{width:n,height:i,fallback:c}}function x(t){return f(t)?t:t.contextElement}const v={x:1,y:1};function L(t){const e=x(t);if(!c(e))return v;const n=e.getBoundingClientRect(),{width:o,height:i,fallback:r}=w(e);let l=(r?b(n.width):n.width)/o,f=(r?b(n.height):n.height)/i;return l&&Number.isFinite(l)||(l=1),f&&Number.isFinite(f)||(f=1),{x:l,y:f}}function T(t,e,o,i){var r,l;void 0===e&&(e=!1),void 0===o&&(o=!1);const c=t.getBoundingClientRect(),s=x(t);let u=v;e&&(i?f(i)&&(u=L(i)):u=L(t));const a=s?n(s):window,d=!p()&&o;let h=(c.left+(d&&(null==(r=a.visualViewport)?void 0:r.offsetLeft)||0))/u.x,g=(c.top+(d&&(null==(l=a.visualViewport)?void 0:l.offsetTop)||0))/u.y,m=c.width/u.x,y=c.height/u.y;if(s){const t=n(s),e=i&&f(i)?n(i):i;let o=t.frameElement;for(;o&&i&&e!==t;){const t=L(o),e=o.getBoundingClientRect(),i=getComputedStyle(o);e.x+=(o.clientLeft+parseFloat(i.paddingLeft))*t.x,e.y+=(o.clientTop+parseFloat(i.paddingTop))*t.y,h*=t.x,g*=t.y,m*=t.x,y*=t.y,h+=e.x,g+=e.y,o=n(o).frameElement}}return{width:m,height:y,top:g,right:h+m,bottom:g+y,left:h,x:h,y:g}}function O(t){return((s(t)?t.ownerDocument:t.document)||window.document).documentElement}function P(t){return f(t)?{scrollLeft:t.scrollLeft,scrollTop:t.scrollTop}:{scrollLeft:t.pageXOffset,scrollTop:t.pageYOffset}}function R(t){return T(O(t)).left+P(t).scrollLeft}function E(t,e,n){const o=c(e),r=O(e),l=T(t,!0,"fixed"===n,e);let f={scrollLeft:0,scrollTop:0};const s={x:0,y:0};if(o||!o&&"fixed"!==n)if(("body"!==i(e)||a(r))&&(f=P(e)),c(e)){const t=T(e,!0);s.x=t.x+e.clientLeft,s.y=t.y+e.clientTop}else r&&(s.x=R(r));return{x:l.left+f.scrollLeft-s.x,y:l.top+f.scrollTop-s.y,width:l.width,height:l.height}}function C(t){if("html"===i(t))return t;const e=t.assignedSlot||t.parentNode||(u(t)?t.host:null)||O(t);return u(e)?e.host:e}function j(t){return c(t)&&"fixed"!==o(t).position?t.offsetParent:null}function F(t){const e=n(t);let r=j(t);for(;r&&d(r)&&"static"===o(r).position;)r=j(r);return r&&("html"===i(r)||"body"===i(r)&&"static"===o(r).position&&!h(r))?e:r||function(t){let e=C(t);for(;c(e)&&!g(e);){if(h(e))return e;e=C(e)}return null}(t)||e}function D(t){const e=C(t);return g(e)?t.ownerDocument.body:c(e)&&a(e)?e:D(e)}function S(t,e){var o;void 0===e&&(e=[]);const i=D(t),r=i===(null==(o=t.ownerDocument)?void 0:o.body),l=n(i);return r?e.concat(l,l.visualViewport||[],a(i)?i:[]):e.concat(i,S(i))}function W(t,i,r){return"viewport"===i?e.rectToClientRect(function(t,e){const o=n(t),i=O(t),r=o.visualViewport;let l=i.clientWidth,c=i.clientHeight,f=0,s=0;if(r){l=r.width,c=r.height;const t=p();(t||!t&&"fixed"===e)&&(f=r.offsetLeft,s=r.offsetTop)}return{width:l,height:c,x:f,y:s}}(t,r)):f(i)?function(t,e){const n=T(t,!0,"fixed"===e),o=n.top+t.clientTop,i=n.left+t.clientLeft,r=c(t)?L(t):{x:1,y:1},l=t.clientWidth*r.x,f=t.clientHeight*r.y,s=i*r.x,u=o*r.y;return{top:u,left:s,right:s+l,bottom:u+f,x:s,y:u,width:l,height:f}}(i,r):e.rectToClientRect(function(t){var e;const n=O(t),i=P(t),r=null==(e=t.ownerDocument)?void 0:e.body,l=y(n.scrollWidth,n.clientWidth,r?r.scrollWidth:0,r?r.clientWidth:0),c=y(n.scrollHeight,n.clientHeight,r?r.scrollHeight:0,r?r.clientHeight:0);let f=-i.scrollLeft+R(t);const s=-i.scrollTop;return"rtl"===o(r||n).direction&&(f+=y(n.clientWidth,r?r.clientWidth:0)-l),{width:l,height:c,x:f,y:s}}(O(t)))}const A={getClippingRect:function(t){let{element:e,boundary:n,rootBoundary:r,strategy:l}=t;const c="clippingAncestors"===n?function(t,e){const n=e.get(t);if(n)return n;let r=S(t).filter((t=>f(t)&&"body"!==i(t))),l=null;const c="fixed"===o(t).position;let s=c?C(t):t;for(;f(s)&&!g(s);){const t=o(s),e=h(s);(c?e||l:e||"static"!==t.position||!l||!["absolute","fixed"].includes(l.position))?l=t:r=r.filter((t=>t!==s)),s=C(s)}return e.set(t,r),r}(e,this._c):[].concat(n),s=[...c,r],u=s[0],a=s.reduce(((t,n)=>{const o=W(e,n,l);return t.top=y(o.top,t.top),t.right=m(o.right,t.right),t.bottom=m(o.bottom,t.bottom),t.left=y(o.left,t.left),t}),W(e,u,l));return{width:a.right-a.left,height:a.bottom-a.top,x:a.left,y:a.top}},convertOffsetParentRelativeRectToViewportRelativeRect:function(t){let{rect:e,offsetParent:n,strategy:o}=t;const r=c(n),l=O(n);if(n===l)return e;let f={scrollLeft:0,scrollTop:0},s={x:1,y:1};const u={x:0,y:0};if((r||!r&&"fixed"!==o)&&(("body"!==i(n)||a(l))&&(f=P(n)),c(n))){const t=T(n);s=L(n),u.x=t.x+n.clientLeft,u.y=t.y+n.clientTop}return{width:e.width*s.x,height:e.height*s.y,x:e.x*s.x-f.scrollLeft*s.x+u.x,y:e.y*s.y-f.scrollTop*s.y+u.y}},isElement:f,getDimensions:function(t){return w(t)},getOffsetParent:F,getDocumentElement:O,getScale:L,async getElementRects(t){let{reference:e,floating:n,strategy:o}=t;const i=this.getOffsetParent||F,r=this.getDimensions;return{reference:E(e,await i(n),o),floating:{x:0,y:0,...await r(n)}}},getClientRects:t=>Array.from(t.getClientRects()),isRTL:t=>"rtl"===o(t).direction};Object.defineProperty(t,"arrow",{enumerable:!0,get:function(){return e.arrow}}),Object.defineProperty(t,"autoPlacement",{enumerable:!0,get:function(){return e.autoPlacement}}),Object.defineProperty(t,"detectOverflow",{enumerable:!0,get:function(){return e.detectOverflow}}),Object.defineProperty(t,"flip",{enumerable:!0,get:function(){return e.flip}}),Object.defineProperty(t,"hide",{enumerable:!0,get:function(){return e.hide}}),Object.defineProperty(t,"inline",{enumerable:!0,get:function(){return e.inline}}),Object.defineProperty(t,"limitShift",{enumerable:!0,get:function(){return e.limitShift}}),Object.defineProperty(t,"offset",{enumerable:!0,get:function(){return e.offset}}),Object.defineProperty(t,"shift",{enumerable:!0,get:function(){return e.shift}}),Object.defineProperty(t,"size",{enumerable:!0,get:function(){return e.size}}),t.autoUpdate=function(t,e,n,o){void 0===o&&(o={});const{ancestorScroll:i=!0,ancestorResize:r=!0,elementResize:l=!0,animationFrame:c=!1}=o,s=i&&!c,u=s||r?[...f(t)?S(t):t.contextElement?S(t.contextElement):[],...S(e)]:[];u.forEach((t=>{s&&t.addEventListener("scroll",n,{passive:!0}),r&&t.addEventListener("resize",n)}));let a,d=null;if(l){let o=!0;d=new ResizeObserver((()=>{o||n(),o=!1})),f(t)&&!c&&d.observe(t),f(t)||!t.contextElement||c||d.observe(t.contextElement),d.observe(e)}let h=c?T(t):null;return c&&function e(){const o=T(t);!h||o.x===h.x&&o.y===h.y&&o.width===h.width&&o.height===h.height||n();h=o,a=requestAnimationFrame(e)}(),n(),()=>{var t;u.forEach((t=>{s&&t.removeEventListener("scroll",n),r&&t.removeEventListener("resize",n)})),null==(t=d)||t.disconnect(),d=null,c&&cancelAnimationFrame(a)}},t.computePosition=(t,n,o)=>{const i=new Map,r={platform:A,...o},l={...r.platform,_c:i};return e.computePosition(t,n,{...r,platform:l})},t.getOverflowAncestors=S,t.platform=A,Object.defineProperty(t,"__esModule",{value:!0})}));
\ No newline at end of file
diff --git a/src-tauri/src/assets/html2canvas.js b/src-tauri/src/vendors/html2canvas.js
similarity index 100%
rename from src-tauri/src/assets/html2canvas.js
rename to src-tauri/src/vendors/html2canvas.js
diff --git a/src-tauri/src/assets/jspdf.js b/src-tauri/src/vendors/jspdf.js
similarity index 100%
rename from src-tauri/src/assets/jspdf.js
rename to src-tauri/src/vendors/jspdf.js
From a361ce52b562ddcc12316eaa039b2f8ce6a9bee0 Mon Sep 17 00:00:00 2001
From: lencx
Date: Wed, 4 Jan 2023 23:18:41 +0800
Subject: [PATCH 05/24] chore: dalle2
---
src-tauri/src/assets/dalle2.core.js | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/src-tauri/src/assets/dalle2.core.js b/src-tauri/src/assets/dalle2.core.js
index bb28e10..7478691 100644
--- a/src-tauri/src/assets/dalle2.core.js
+++ b/src-tauri/src/assets/dalle2.core.js
@@ -28,22 +28,19 @@ async function init() {
document.body.appendChild(selectionMenu);
const { computePosition, flip, offset, shift } = window.FloatingUIDOM;
- document.body.addEventListener("mouseup", async (e) => {
- const selection = window.getSelection();
- if (window.__DALLE2_STATE__ !== 1) {
- window.__DALLE2_CONTENT__ = selection.toString().trim();
- }
-
+ document.body.addEventListener('mousedown', async (e) => {
if (e.target.id === 'chagpt-selection-menu') {
await invoke('dalle2_window', { query: encodeURIComponent(window.__DALLE2_CONTENT__) });
- }
-
- if (window.__DALLE2_STATE__ === 1) {
- delete window.__DALLE2_STATE__;
+ } else {
delete window.__DALLE2_CONTENT__;
}
+ });
+ document.body.addEventListener("mouseup", async (e) => {
selectionMenu.style.display = 'none';
+ const selection = window.getSelection();
+ window.__DALLE2_CONTENT__ = selection.toString().trim();
+
if (!window.__DALLE2_CONTENT__) return;
if (selection.rangeCount > 0) {
@@ -56,8 +53,6 @@ async function init() {
rootEl.style.left = `${rect.left}px`;
document.body.appendChild(rootEl);
- window.__DALLE2_STATE__ = 1;
-
selectionMenu.style.display = 'block';
computePosition(rootEl, selectionMenu, {
placement: 'top',
From c2b0e02b75f2dccc46d04fe3836a4290ac0d71ad Mon Sep 17 00:00:00 2001
From: lencx
Date: Thu, 5 Jan 2023 17:21:18 +0800
Subject: [PATCH 06/24] merge
---
src-tauri/src/app/menu.rs | 1 +
1 file changed, 1 insertion(+)
diff --git a/src-tauri/src/app/menu.rs b/src-tauri/src/app/menu.rs
index abd4bc9..48fbf55 100644
--- a/src-tauri/src/app/menu.rs
+++ b/src-tauri/src/app/menu.rs
@@ -272,6 +272,7 @@ pub fn menu_handler(event: WindowMenuEvent) {
ChatConfJson::amend(&serde_json::json!({ "theme": theme }), Some(app)).unwrap();
}
"update_prompt" | "update_silent" | "update_disable" => {
+ dbg!(12);
for id in ["update_prompt", "update_silent", "update_disable"] {
menu_handle.get_item(id).set_selected(false).unwrap();
}
From 3919b24df8591834bb7e2b7102462b47e36e853c Mon Sep 17 00:00:00 2001
From: kirti purohit
Date: Thu, 5 Jan 2023 21:53:49 +0530
Subject: [PATCH 07/24] chore: dalle2(#122)
---
src-tauri/src/app/menu.rs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src-tauri/src/app/menu.rs b/src-tauri/src/app/menu.rs
index 617f4da..704686f 100644
--- a/src-tauri/src/app/menu.rs
+++ b/src-tauri/src/app/menu.rs
@@ -63,6 +63,7 @@ pub fn init() -> Menu {
CustomMenuItem::new("control_center".to_string(), "Control Center")
.accelerator("CmdOrCtrl+Shift+P")
.into(),
+ CustomMenuItem::new("dall_e2".to_string(), "Search DALLE-2").into(),
MenuItem::Separator.into(),
Submenu::new(
"Theme",
@@ -189,7 +190,7 @@ pub fn menu_handler(event: WindowMenuEvent) {
let core_window = app.get_window("core").unwrap();
let menu_handle = core_window.menu_handle();
-
+ let query = String::from("");
match menu_id {
// App
"about" => {
@@ -205,6 +206,7 @@ pub fn menu_handler(event: WindowMenuEvent) {
}
// Preferences
"control_center" => window::control_window(&app),
+ "dall_e2"=> window::dalle2_window(&app, query),
"restart" => tauri::api::process::restart(&app.env()),
"inject_script" => open(&app, script_path),
"go_conf" => utils::open_file(utils::chat_root()),
From 8c2303dec96fdd17cc24a686540357d9953e6f7a Mon Sep 17 00:00:00 2001
From: lencx
Date: Fri, 6 Jan 2023 14:39:25 +0800
Subject: [PATCH 08/24] chore: dalle2
---
src-tauri/Cargo.toml | 5 +++-
src-tauri/src/app/cmd.rs | 10 +++++---
src-tauri/src/app/menu.rs | 36 +++++++++++++++-------------
src-tauri/src/app/setup.rs | 4 +++-
src-tauri/src/app/window.rs | 44 +++++++++++++++++++++-------------
src-tauri/src/assets/dalle2.js | 11 ++++++++-
src-tauri/src/main.rs | 5 ++++
src-tauri/src/utils.rs | 10 +++++++-
src/layout/index.tsx | 2 +-
9 files changed, 86 insertions(+), 41 deletions(-)
diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index 3093a68..a25678f 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -29,9 +29,12 @@ reqwest = "0.11.13"
wry = "0.23.4"
dark-light = "1.0.0"
[dependencies.tauri-plugin-log]
-git = "https://github.com/tauri-apps/tauri-plugin-log"
+git = "https://github.com/lencx/tauri-plugin-log"
branch = "dev"
features = ["colored"]
+[dependencies.tauri-plugin-autostart]
+git = "https://github.com/lencx/tauri-plugin-autostart"
+branch = "dev"
[features]
# by default Tauri runs in production mode
diff --git a/src-tauri/src/app/cmd.rs b/src-tauri/src/app/cmd.rs
index fd92724..8755da4 100644
--- a/src-tauri/src/app/cmd.rs
+++ b/src-tauri/src/app/cmd.rs
@@ -15,7 +15,11 @@ pub fn drag_window(app: AppHandle) {
#[command]
pub fn dalle2_window(app: AppHandle, query: String) {
- window::dalle2_window(&app.app_handle(), query);
+ window::dalle2_window(
+ &app.app_handle(),
+ Some(query),
+ Some("ChatGPT & DALL·E 2".to_string()),
+ );
}
#[command]
@@ -56,8 +60,8 @@ pub fn reset_chat_conf() -> ChatConfJson {
}
#[command]
-pub fn run_check_update(app: AppHandle, silent: bool) {
- utils::run_check_update(app, silent).unwrap();
+pub fn run_check_update(app: AppHandle, silent: bool, has_msg: Option) {
+ utils::run_check_update(app, silent, has_msg).unwrap();
}
#[command]
diff --git a/src-tauri/src/app/menu.rs b/src-tauri/src/app/menu.rs
index ec8587a..8bf5cd8 100644
--- a/src-tauri/src/app/menu.rs
+++ b/src-tauri/src/app/menu.rs
@@ -1,4 +1,5 @@
use crate::{
+ app::window,
conf::{self, ChatConfJson},
utils,
};
@@ -11,8 +12,6 @@ use tauri_plugin_positioner::{on_tray_event, Position, WindowExt};
#[cfg(target_os = "macos")]
use tauri::AboutMetadata;
-use super::window;
-
// --- Menu
pub fn init() -> Menu {
let chat_conf = ChatConfJson::get_chat_conf();
@@ -70,7 +69,15 @@ pub fn init() -> Menu {
CustomMenuItem::new("control_center".to_string(), "Control Center")
.accelerator("CmdOrCtrl+Shift+P")
.into(),
- CustomMenuItem::new("dall_e2".to_string(), "Search DALLE-2").into(),
+ MenuItem::Separator.into(),
+ stay_on_top_menu.into(),
+ #[cfg(target_os = "macos")]
+ titlebar_menu.into(),
+ #[cfg(target_os = "macos")]
+ CustomMenuItem::new("hide_dock_icon".to_string(), "Hide Dock Icon").into(),
+ CustomMenuItem::new("inject_script".to_string(), "Inject Script")
+ .accelerator("CmdOrCtrl+J")
+ .into(),
MenuItem::Separator.into(),
Submenu::new(
"Theme",
@@ -111,14 +118,6 @@ pub fn init() -> Menu {
// })
)
.into(),
- stay_on_top_menu.into(),
- #[cfg(target_os = "macos")]
- titlebar_menu.into(),
- #[cfg(target_os = "macos")]
- CustomMenuItem::new("hide_dock_icon".to_string(), "Hide Dock Icon").into(),
- CustomMenuItem::new("inject_script".to_string(), "Inject Script")
- .accelerator("CmdOrCtrl+J")
- .into(),
MenuItem::Separator.into(),
CustomMenuItem::new("sync_prompts".to_string(), "Sync Prompts").into(),
MenuItem::Separator.into(),
@@ -178,6 +177,8 @@ pub fn init() -> Menu {
let window_menu = Submenu::new(
"Window",
Menu::new()
+ .add_item(CustomMenuItem::new("dalle2".to_string(), "DALL·E 2"))
+ .add_native_item(MenuItem::Separator)
.add_native_item(MenuItem::Minimize)
.add_native_item(MenuItem::Zoom),
);
@@ -200,9 +201,9 @@ pub fn init() -> Menu {
Menu::new()
.add_submenu(app_menu)
.add_submenu(preferences_menu)
+ .add_submenu(window_menu)
.add_submenu(edit_menu)
.add_submenu(view_menu)
- .add_submenu(window_menu)
.add_submenu(help_menu)
}
@@ -216,7 +217,7 @@ pub fn menu_handler(event: WindowMenuEvent) {
let core_window = app.get_window("core").unwrap();
let menu_handle = core_window.menu_handle();
- let query = String::from("");
+
match menu_id {
// App
"about" => {
@@ -228,11 +229,10 @@ pub fn menu_handler(event: WindowMenuEvent) {
);
}
"check_update" => {
- utils::run_check_update(app, false).unwrap();
+ utils::run_check_update(app, false, None).unwrap();
}
// Preferences
"control_center" => window::control_window(&app),
- "dall_e2"=> window::dalle2_window(&app, query),
"restart" => tauri::api::process::restart(&app.env()),
"inject_script" => open(&app, script_path),
"go_conf" => utils::open_file(utils::chat_root()),
@@ -274,8 +274,8 @@ pub fn menu_handler(event: WindowMenuEvent) {
ChatConfJson::amend(&serde_json::json!({ "theme": theme }), Some(app)).unwrap();
}
"update_prompt" | "update_silent" | "update_disable" => {
- dbg!(12);
- for id in ["update_prompt", "update_silent", "update_disable"] {
+ // for id in ["update_prompt", "update_silent", "update_disable"] {
+ for id in ["update_prompt", "update_silent"] {
menu_handle.get_item(id).set_selected(false).unwrap();
}
let auto_update = match menu_id {
@@ -313,6 +313,8 @@ pub fn menu_handler(event: WindowMenuEvent) {
win.set_always_on_top(*stay_on_top).unwrap();
ChatConfJson::amend(&serde_json::json!({ "stay_on_top": *stay_on_top }), None).unwrap();
}
+ // Window
+ "dalle2" => window::dalle2_window(&app, None, None),
// View
"reload" => win.eval("window.location.reload()").unwrap(),
"go_back" => win.eval("window.history.go(-1)").unwrap(),
diff --git a/src-tauri/src/app/setup.rs b/src-tauri/src/app/setup.rs
index 4ddb5b6..7b90f29 100644
--- a/src-tauri/src/app/setup.rs
+++ b/src-tauri/src/app/setup.rs
@@ -95,10 +95,12 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box
.unwrap();
});
}
+
// auto_update
if chat_conf.auto_update != "Disable" {
+ info!("stepup::run_check_update");
let app = app.handle();
- utils::run_check_update(app, chat_conf.auto_update == "Silent").unwrap();
+ utils::run_check_update(app, chat_conf.auto_update == "Silent", None).unwrap();
}
Ok(())
diff --git a/src-tauri/src/app/window.rs b/src-tauri/src/app/window.rs
index 8eade7a..94d6e92 100644
--- a/src-tauri/src/app/window.rs
+++ b/src-tauri/src/app/window.rs
@@ -1,4 +1,5 @@
use crate::{conf, utils};
+use log::info;
use std::time::SystemTime;
use tauri::{utils::config::WindowUrl, window::WindowBuilder};
@@ -27,7 +28,8 @@ pub fn tray_window(handle: &tauri::AppHandle) {
});
}
-pub fn dalle2_window(handle: &tauri::AppHandle, query: String) {
+pub fn dalle2_window(handle: &tauri::AppHandle, query: Option, title: Option) {
+ info!("dalle2_query: {:?}", query);
let timestamp = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
@@ -35,22 +37,32 @@ pub fn dalle2_window(handle: &tauri::AppHandle, query: String) {
let theme = conf::ChatConfJson::theme();
let app = handle.clone();
+ let query = if query.is_some() {
+ format!(
+ "window.addEventListener('DOMContentLoaded', function() {{\nwindow.__CHATGPT_QUERY__='{}';\n}})",
+ query.unwrap()
+ )
+ } else {
+ "".to_string()
+ };
+
tauri::async_runtime::spawn(async move {
- WindowBuilder::new(&app, format!("dalle2_{}", timestamp), WindowUrl::App("https://labs.openai.com".into()))
- .title("ChatGPT & DALL·E 2")
- .resizable(true)
- .fullscreen(false)
- .inner_size(800.0, 600.0)
- .always_on_top(false)
- .theme(theme)
- .initialization_script(include_str!("../assets/core.js"))
- .initialization_script(&format!(
- "window.addEventListener('DOMContentLoaded', function() {{\nwindow.__CHATGPT_QUERY__='{}';\n}})",
- query
- ))
- .initialization_script(include_str!("../assets/dalle2.js"))
- .build()
- .unwrap();
+ WindowBuilder::new(
+ &app,
+ format!("dalle2_{}", timestamp),
+ WindowUrl::App("https://labs.openai.com/".into()),
+ )
+ .title(title.unwrap_or_else(|| "DALL·E 2".to_string()))
+ .resizable(true)
+ .fullscreen(false)
+ .inner_size(800.0, 600.0)
+ .always_on_top(false)
+ .theme(theme)
+ .initialization_script(include_str!("../assets/core.js"))
+ .initialization_script(&query)
+ .initialization_script(include_str!("../assets/dalle2.js"))
+ .build()
+ .unwrap();
});
}
diff --git a/src-tauri/src/assets/dalle2.js b/src-tauri/src/assets/dalle2.js
index 0aa323b..30dfdee 100644
--- a/src-tauri/src/assets/dalle2.js
+++ b/src-tauri/src/assets/dalle2.js
@@ -10,6 +10,16 @@ async function init() {
// const searchBtn = document.querySelector('.image-prompt-form-wrapper form .image-prompt-btn');
const searchInput = document.querySelector('.image-prompt-form-wrapper form>.text-input');
if (searchInput) {
+ document.addEventListener("click", (e) => {
+ const origin = e.target.closest("a");
+ if (origin && origin.href && origin.target !== '_self') {
+ invoke('open_link', { url: origin.href });
+ }
+ });
+
+ clearInterval(window.searchInterval);
+
+ if (!window.__CHATGPT_QUERY__) return;
const query = decodeURIComponent(window.__CHATGPT_QUERY__);
searchInput.focus();
searchInput.value = query;
@@ -19,7 +29,6 @@ async function init() {
// searchBtn.classList.add('active-style');
// searchBtn.removeAttribute('disabled');
// searchBtn.classList.remove('btn-disabled', 'btn-disabled-style');
- clearInterval(window.searchInterval);
}
}, 200)
}
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 5b54118..8820dfe 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -10,6 +10,7 @@ mod utils;
use app::{cmd, fs_extra, menu, setup};
use conf::{ChatConfJson, ChatState};
use tauri::api::path;
+use tauri_plugin_autostart::MacosLauncher;
use tauri_plugin_log::{
fern::colors::{Color, ColoredLevelConfig},
LogTarget, LoggerBuilder,
@@ -70,6 +71,10 @@ async fn main() {
])
.setup(setup::init)
.plugin(tauri_plugin_positioner::init())
+ .plugin(tauri_plugin_autostart::init(
+ MacosLauncher::LaunchAgent,
+ None,
+ ))
.menu(menu::init())
.system_tray(menu::tray_menu())
.on_menu_event(menu::menu_handler)
diff --git a/src-tauri/src/utils.rs b/src-tauri/src/utils.rs
index a23c668..b36e8f0 100644
--- a/src-tauri/src/utils.rs
+++ b/src-tauri/src/utils.rs
@@ -130,7 +130,7 @@ pub async fn get_data(
}
}
-pub fn run_check_update(app: AppHandle, silent: bool) -> Result<()> {
+pub fn run_check_update(app: AppHandle, silent: bool, has_msg: Option) -> Result<()> {
tauri::async_runtime::spawn(async move {
let result = app.updater().check().await;
let update_resp = result.unwrap();
@@ -144,6 +144,14 @@ pub fn run_check_update(app: AppHandle, silent: bool) -> Result<()> {
prompt_for_install(app, update_resp).await.unwrap();
});
}
+ } else if let Some(v) = has_msg {
+ if v {
+ tauri::api::dialog::message(
+ app.app_handle().get_window("core").as_ref(),
+ "ChatGPT",
+ "Your ChatGPT is up to date",
+ );
+ }
}
});
Ok(())
diff --git a/src/layout/index.tsx b/src/layout/index.tsx
index 2def6af..bbc7dc9 100644
--- a/src/layout/index.tsx
+++ b/src/layout/index.tsx
@@ -26,7 +26,7 @@ export default function ChatLayout() {
})
const checkAppUpdate = async () => {
- await invoke('run_check_update', { silent: false });
+ await invoke('run_check_update', { silent: false, hasMsg: true });
}
return (
From bb6e431bd9e1b5d53715a1ae97f5ba20c3204e54 Mon Sep 17 00:00:00 2001
From: lencx
Date: Fri, 6 Jan 2023 16:29:59 +0800
Subject: [PATCH 09/24] readme
---
README-ZH_CN.md | 24 ++++++++++++++++--------
README.md | 32 +++++++++++++++++++-------------
2 files changed, 35 insertions(+), 21 deletions(-)
diff --git a/README-ZH_CN.md b/README-ZH_CN.md
index 7582711..46176ca 100644
--- a/README-ZH_CN.md
+++ b/README-ZH_CN.md
@@ -23,24 +23,29 @@
### 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)
-- 或者使用 [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`
+- [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://winstall.app/apps/lencx.ChatGPT):
+ ```bash
+ # install the latest version
+ winget install --id=lencx.ChatGPT -e
+
+ # install the specified version
+ winget install --id=lencx.ChatGPT -e --version 0.7.4
+ ```
**注意:如果安装路径和应用名称相同,会导致冲突 ([#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)
+- [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)_ ,你需要添加以下配置:
+ 如果你坚持使用 _[Brewfile](https://github.com/Homebrew/homebrew-bundle#usage)_ ,则需要添加以下配置:
```rb
repo = "lencx/chatgpt"
tap repo, "https://github.com/#{repo}.git"
@@ -51,7 +56,10 @@
- [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-desktop-bin](https://aur.archlinux.org/packages/chatgpt-desktop-bin): 使用 AUR 来安装
+- 使用 [AUR](https://aur.archlinux.org/packages/chatgpt-desktop-bin):
+ ```bash
+ sudo pacman -S chatgpt-desktop-bin
+ ```
@@ -63,7 +71,7 @@
### 如何使用指令?
-你可以从 [awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt-prompts) 来寻找有趣的功能来导入到应用。
+你可以从 [awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt-prompts) 来寻找有趣的功能来导入到应用。也可以使用 `Sync Prompts`,来一键同步所有,如果你不想让某些提示出现在你的斜杠命令,你可以禁用它们。


diff --git a/README.md b/README.md
index 9afc75f..2feda4c 100644
--- a/README.md
+++ b/README.md
@@ -26,17 +26,22 @@
### Windows
-- 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`
+- [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): Direct download installer
+- Use [winget](https://winstall.app/apps/lencx.ChatGPT):
+ ```bash
+ # install the latest version
+ winget install --id=lencx.ChatGPT -e
+
+ # install the specified version
+ winget install --id=lencx.ChatGPT -e --version 0.7.4
+ ```
**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)
+- [ChatGPT_0.7.4_x64.dmg](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/ChatGPT_0.7.4_x64.dmg): Direct download installer
+- [ChatGPT.app.tar.gz](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/ChatGPT.app.tar.gz): Download the `.app` installer
- Homebrew \
Or you can install with _[Homebrew](https://brew.sh) ([Cask](https://docs.brew.sh/Cask-Cookbook)):_
```sh
@@ -52,9 +57,13 @@
### 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**
-- Available on [AUR](https://aur.archlinux.org/packages/chatgpt-desktop-bin) with the package name `chatgpt-desktop-bin`, and you can use your favourite AUR package manager to install it.
+- [chat-gpt_0.7.4_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/chat-gpt_0.7.4_amd64.deb): Download `.deb` installer, advantage small size, disadvantage poor compatibility
+- [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
+- Use [AUR](https://aur.archlinux.org/packages/chatgpt-desktop-bin):
+ ```bash
+ sudo pacman -S chatgpt-desktop-bin
+ ```
+
@@ -68,19 +77,16 @@ This is a major and exciting update. It works like a `Telegram bot command` and
### How does it work?
-You can look at **[awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt-prompts)** to find interesting features to import into the app.
+You can look at **[awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt-prompts)** to find interesting features to import into the app. You can also use `Sync Prompts` to sync all in one click, and if you don't want certain prompts to appear in your slash commands, you can disable them.

-

-
- In the chatgpt text input area, type a character starting with `/` to bring up the command prompt, press the spacebar, and it will fill the input area with the text associated with the command by default (note: if it contains multiple command prompts, it will only select the first one as the fill, you can keep typing until the first prompted command is the one you want, then press the spacebar.
- Or use the mouse to click on one of the multiple commands). When the fill is complete, you simply press the Enter key.
- Under the slash command, use the tab key to modify the contents of the `{q}` tag (only single changes are supported [#54](https://github.com/lencx/ChatGPT/issues/54)). Use the keyboard `⇧` (arrow up) and `⇩` (arrow down) keys to select the slash command.
-

From ec20d03c50cee66150e198ea15e7dc3ab172662d Mon Sep 17 00:00:00 2001
From: lencx
Date: Fri, 6 Jan 2023 18:44:35 +0800
Subject: [PATCH 10/24] readme
---
README-ZH_CN.md | 12 ++++++------
README.md | 18 ++++++------------
assets/chat-cmd-1.png | Bin 1992071 -> 0 bytes
assets/chat-cmd-2.png | Bin 1126418 -> 0 bytes
assets/chatgpt-control-center-general.png | Bin 0 -> 435916 bytes
assets/chatgpt-dalle2-tray.png | Bin 0 -> 827047 bytes
assets/chatgpt-export.png | Bin 0 -> 246418 bytes
assets/chatgpt-menu.png | Bin 0 -> 757182 bytes
assets/chatgpt-sync-prompts.png | Bin 0 -> 415484 bytes
assets/control-center.png | Bin 511662 -> 0 bytes
assets/export.png | Bin 231384 -> 0 bytes
assets/tray-login.png | Bin 1012978 -> 0 bytes
assets/tray.png | Bin 556269 -> 0 bytes
src/view/General.tsx | 7 ++-----
14 files changed, 14 insertions(+), 23 deletions(-)
delete mode 100644 assets/chat-cmd-1.png
delete mode 100644 assets/chat-cmd-2.png
create mode 100644 assets/chatgpt-control-center-general.png
create mode 100644 assets/chatgpt-dalle2-tray.png
create mode 100644 assets/chatgpt-export.png
create mode 100644 assets/chatgpt-menu.png
create mode 100644 assets/chatgpt-sync-prompts.png
delete mode 100644 assets/control-center.png
delete mode 100644 assets/export.png
delete mode 100644 assets/tray-login.png
delete mode 100644 assets/tray.png
diff --git a/README-ZH_CN.md b/README-ZH_CN.md
index 46176ca..e8e500e 100644
--- a/README-ZH_CN.md
+++ b/README-ZH_CN.md
@@ -58,7 +58,7 @@
- [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` 运行失败时可以尝试它**
- 使用 [AUR](https://aur.archlinux.org/packages/chatgpt-desktop-bin):
```bash
- sudo pacman -S chatgpt-desktop-bin
+ yay -S chatgpt-desktop-bin
```
@@ -73,8 +73,8 @@
你可以从 [awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt-prompts) 来寻找有趣的功能来导入到应用。也可以使用 `Sync Prompts`,来一键同步所有,如果你不想让某些提示出现在你的斜杠命令,你可以禁用它们。
-
-
+
+
@@ -171,9 +171,9 @@
## 👀 预览
-
-
-
+
+
+
## ❓ 常见问题
diff --git a/README.md b/README.md
index 2feda4c..1122e2e 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,6 @@
ChatGPT Desktop Application
-
[](./README.md)
[](./README-ZH_CN.md)\
@@ -59,11 +58,7 @@
- [chat-gpt_0.7.4_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.7.4/chat-gpt_0.7.4_amd64.deb): Download `.deb` installer, advantage small size, disadvantage poor compatibility
- [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
-- Use [AUR](https://aur.archlinux.org/packages/chatgpt-desktop-bin):
- ```bash
- sudo pacman -S chatgpt-desktop-bin
- ```
-
+- Available on [AUR](https://aur.archlinux.org/packages/chatgpt-desktop-bin) with the package name `chatgpt-desktop-bin`, and you can use your favourite AUR package manager to install it.
@@ -79,8 +74,8 @@ This is a major and exciting update. It works like a `Telegram bot command` and
You can look at **[awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt-prompts)** to find interesting features to import into the app. You can also use `Sync Prompts` to sync all in one click, and if you don't want certain prompts to appear in your slash commands, you can disable them.
-
-
+
+
@@ -89,7 +84,6 @@ You can look at **[awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt
- Under the slash command, use the tab key to modify the contents of the `{q}` tag (only single changes are supported [#54](https://github.com/lencx/ChatGPT/issues/54)). Use the keyboard `⇧` (arrow up) and `⇩` (arrow down) keys to select the slash command.

-

## ✨ Features
@@ -187,9 +181,9 @@ Currently, only json and csv are supported for synchronizing custom files, and t
## 👀 Preview
-
-
-
+
+
+
## ❓FAQ
diff --git a/assets/chat-cmd-1.png b/assets/chat-cmd-1.png
deleted file mode 100644
index e83d4c29e405309129964f721443635c3484b3a4..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1992071
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