mirror of
https://github.com/FranP-code/ChatGPT.git
synced 2025-10-13 00:13:25 +00:00
Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba21fa85d2 | ||
|
|
2ab35bb925 | ||
|
|
9cacad0120 | ||
|
|
f1fa859961 | ||
|
|
9a9fb24de8 | ||
|
|
3424666ec9 | ||
|
|
416bf7064c | ||
|
|
f5cf3acd3a | ||
|
|
975ffd2d84 | ||
|
|
145264719f | ||
|
|
a929376cb2 | ||
|
|
478049e23e | ||
|
|
631dee95a7 | ||
|
|
c4ff0b4107 | ||
|
|
bcd350584e | ||
|
|
050045f644 | ||
|
|
7e9440b45e | ||
|
|
cd9c0ac742 | ||
|
|
2d018c4967 | ||
|
|
f4d3cc6c8e | ||
|
|
cd6cece45e | ||
|
|
54b5b63f0e | ||
|
|
680f1b01ad | ||
|
|
078b0296f5 | ||
|
|
c956758a4a | ||
|
|
477120ef3b | ||
|
|
0ee95630ef | ||
|
|
fb0319a977 | ||
|
|
ea1a78abf5 | ||
|
|
3428e11b85 | ||
|
|
0e0771d0ec | ||
|
|
d78e2ad0b3 | ||
|
|
ae31da0b29 | ||
|
|
39febe759e | ||
|
|
06ee907199 | ||
|
|
f8c1ca5c56 | ||
|
|
6da58269bd | ||
|
|
4bf6c61bee | ||
|
|
a07c85a9cc | ||
|
|
95a9f12b68 | ||
|
|
252b0f3e15 | ||
|
|
ed268b32b3 | ||
|
|
e2319f2fda | ||
|
|
9ec69631f3 | ||
|
|
83437ffea7 | ||
|
|
be9846dc22 | ||
|
|
f071e0d6bc | ||
|
|
62a176d20c | ||
|
|
fe236e3c66 | ||
|
|
0b0b832130 |
34
.github/workflows/release.yml
vendored
34
.github/workflows/release.yml
vendored
@@ -8,7 +8,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
create-release:
|
create-release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
outputs:
|
outputs:
|
||||||
RELEASE_UPLOAD_ID: ${{ steps.create_release.outputs.id }}
|
RELEASE_UPLOAD_ID: ${{ steps.create_release.outputs.id }}
|
||||||
|
|
||||||
@@ -36,34 +36,32 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [macos-latest, ubuntu-latest, windows-latest]
|
platform: [macos-latest, ubuntu-20.04, windows-latest]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
|
- name: setup node
|
||||||
- name: Setup node
|
uses: actions/setup-node@v3
|
||||||
uses: actions/setup-node@v1
|
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 16
|
||||||
|
|
||||||
- name: Install Rust stable
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
|
||||||
toolchain: stable
|
|
||||||
|
|
||||||
# Rust cache
|
|
||||||
- uses: Swatinem/rust-cache@v1
|
|
||||||
|
|
||||||
|
- name: install Rust stable
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
- name: install dependencies (ubuntu only)
|
- name: install dependencies (ubuntu only)
|
||||||
if: matrix.platform == 'ubuntu-latest'
|
if: matrix.platform == 'ubuntu-20.04'
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf
|
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
|
||||||
|
|
||||||
- name: Install app dependencies and build it
|
- name: Install app dependencies and build it
|
||||||
run: yarn && yarn build:fe
|
run: yarn && yarn build:fe
|
||||||
|
|
||||||
|
- name: fix tray icon
|
||||||
|
if: matrix.platform != 'macos-latest'
|
||||||
|
run: |
|
||||||
|
yarn fix:tray
|
||||||
|
|
||||||
- uses: tauri-apps/tauri-action@v0.3
|
- uses: tauri-apps/tauri-action@v0.3
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -74,7 +72,7 @@ jobs:
|
|||||||
releaseId: ${{ needs.create-release.outputs.RELEASE_UPLOAD_ID }}
|
releaseId: ${{ needs.create-release.outputs.RELEASE_UPLOAD_ID }}
|
||||||
|
|
||||||
updater:
|
updater:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
needs: [create-release, build-tauri]
|
needs: [create-release, build-tauri]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -22,9 +22,9 @@
|
|||||||
|
|
||||||
**最新版:**
|
**最新版:**
|
||||||
|
|
||||||
- `Mac`: [ChatGPT_0.6.7_x64.dmg](https://github.com/lencx/ChatGPT/releases/download/v0.6.7/ChatGPT_0.6.7_x64.dmg)
|
- `Mac`: [ChatGPT_0.7.3_x64.dmg](https://github.com/lencx/ChatGPT/releases/download/v0.7.3/ChatGPT_0.7.3_x64.dmg)
|
||||||
- `Linux`: [chat-gpt_0.6.7_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.6.7/chat-gpt_0.6.7_amd64.deb)
|
- `Linux`: [chat-gpt_0.7.3_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.7.3/chat-gpt_0.7.3_amd64.deb)
|
||||||
- `Windows`: [ChatGPT_0.6.7_x64_en-US.msi](https://github.com/lencx/ChatGPT/releases/download/v0.6.7/ChatGPT_0.6.7_x64_en-US.msi)
|
- `Windows`: [ChatGPT_0.7.3_x64_en-US.msi](https://github.com/lencx/ChatGPT/releases/download/v0.7.3/ChatGPT_0.7.3_x64_en-US.msi)
|
||||||
|
|
||||||
[其他版本...](https://github.com/lencx/ChatGPT/releases)
|
[其他版本...](https://github.com/lencx/ChatGPT/releases)
|
||||||
|
|
||||||
@@ -58,9 +58,9 @@ cask "popcorn-time", args: { "no-quarantine": true }
|
|||||||

|

|
||||||

|

|
||||||
|
|
||||||
数据导入完成后,可以重新启动应用来使配置生效(`Menu -> Preferences -> Restart ChatGPT`)。
|
<!-- 数据导入完成后,可以重新启动应用来使配置生效(`Menu -> Preferences -> Restart ChatGPT`)。 -->
|
||||||
|
|
||||||
在 ChatGPT 文本输入区域,键入 `/` 开头的字符,则会弹出指令提示,按下空格键,它会默认将命令关联的文本填充到输入区域(注意:如果包含多个指令提示,它只会选择第一个作为填充,你可以持续输入,直到第一个提示命令为你想要时,再按下空格键。或者使用鼠标来点击多条指令中的某一个)。填充完成后,你只需要按下回车键即可。斜杠命令下,使用 TAB 键修改 `{q}` 标签内容(仅支持单个修改 [#54](https://github.com/lencx/ChatGPT/issues/54))。
|
在 ChatGPT 文本输入区域,键入 `/` 开头的字符,则会弹出指令提示,按下空格键,它会默认将命令关联的文本填充到输入区域(注意:如果包含多个指令提示,它只会选择第一个作为填充,你可以持续输入,直到第一个提示命令为你想要时,再按下空格键。或者使用鼠标来点击多条指令中的某一个)。填充完成后,你只需要按下回车键即可。斜杠命令下,使用 TAB 键修改 `{q}` 标签内容(仅支持单个修改 [#54](https://github.com/lencx/ChatGPT/issues/54))。使用键盘 `⇧` 和 `⇩`(上下键)来选择斜杠指令。
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
@@ -74,6 +74,7 @@ cask "popcorn-time", args: { "no-quarantine": true }
|
|||||||
- 系统托盘悬浮窗
|
- 系统托盘悬浮窗
|
||||||
- 应用菜单功能强大
|
- 应用菜单功能强大
|
||||||
- 支持斜杠命令及其配置(可手动配置或从文件同步 [#55](https://github.com/lencx/ChatGPT/issues/55))
|
- 支持斜杠命令及其配置(可手动配置或从文件同步 [#55](https://github.com/lencx/ChatGPT/issues/55))
|
||||||
|
- 进入应用的全局快捷键 (mac: `Command + Shift + O`, windows: `Ctrl + Shift + O`)
|
||||||
|
|
||||||
### 菜单项
|
### 菜单项
|
||||||
|
|
||||||
|
|||||||
13
README.md
13
README.md
@@ -24,9 +24,9 @@
|
|||||||
|
|
||||||
**Latest:**
|
**Latest:**
|
||||||
|
|
||||||
- `Mac`: [ChatGPT_0.6.7_x64.dmg](https://github.com/lencx/ChatGPT/releases/download/v0.6.7/ChatGPT_0.6.7_x64.dmg)
|
- `Mac`: [ChatGPT_0.7.3_x64.dmg](https://github.com/lencx/ChatGPT/releases/download/v0.7.3/ChatGPT_0.7.3_x64.dmg)
|
||||||
- `Linux`: [chat-gpt_0.6.7_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.6.7/chat-gpt_0.6.7_amd64.deb)
|
- `Linux`: [chat-gpt_0.7.3_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.7.3/chat-gpt_0.7.3_amd64.deb)
|
||||||
- `Windows`: [ChatGPT_0.6.7_x64_en-US.msi](https://github.com/lencx/ChatGPT/releases/download/v0.6.7/ChatGPT_0.6.7_x64_en-US.msi)
|
- `Windows`: [ChatGPT_0.7.3_x64_en-US.msi](https://github.com/lencx/ChatGPT/releases/download/v0.7.3/ChatGPT_0.7.3_x64_en-US.msi)
|
||||||
|
|
||||||
[Other version...](https://github.com/lencx/ChatGPT/releases)
|
[Other version...](https://github.com/lencx/ChatGPT/releases)
|
||||||
|
|
||||||
@@ -60,9 +60,9 @@ You can look at [awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt-p
|
|||||||

|

|
||||||

|

|
||||||
|
|
||||||
After the data import is done, you can restart the app to make the configuration take effect (`Menu -> Preferences -> Restart ChatGPT`).
|
<!-- After the data import is done, you can restart the app to make the configuration take effect (`Menu -> Preferences -> Restart ChatGPT`). -->
|
||||||
|
|
||||||
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)).
|
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.
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
@@ -76,6 +76,7 @@ In the chatgpt text input area, type a character starting with `/` to bring up t
|
|||||||
- System tray hover window
|
- System tray hover window
|
||||||
- Powerful menu items
|
- Powerful menu items
|
||||||
- Support for slash commands and their configuration (can be configured manually or synchronized from a file [#55](https://github.com/lencx/ChatGPT/issues/55))
|
- Support for slash commands and their configuration (can be configured manually or synchronized from a file [#55](https://github.com/lencx/ChatGPT/issues/55))
|
||||||
|
- Global shortcuts to the chatgpt app (mac: `Command + Shift + O`, windows: `Ctrl + Shift + O`)
|
||||||
|
|
||||||
### MenuItem
|
### MenuItem
|
||||||
|
|
||||||
@@ -154,7 +155,7 @@ Currently, only json and csv are supported for synchronizing custom files, and t
|
|||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- Web access capability ([#20](https://github.com/lencx/ChatGPT/issues/20))
|
<!-- - Web access capability ([#20](https://github.com/lencx/ChatGPT/issues/20)) -->
|
||||||
- `Control Center` - Feature Enhancements
|
- `Control Center` - Feature Enhancements
|
||||||
- ...
|
- ...
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,36 @@
|
|||||||
# UPDATE LOG
|
# UPDATE LOG
|
||||||
|
|
||||||
## v0.6.7
|
## v0.7.3
|
||||||
|
|
||||||
fix: unable to synchronize
|
chore:
|
||||||
|
- optimize slash command style
|
||||||
|
- optimize tray menu icon and button icons
|
||||||
|
- global shortcuts to the chatgpt app (mac: `Command + Shift + O`, windows: `Ctrl + Shift + O`)
|
||||||
|
|
||||||
|
## v0.7.2
|
||||||
|
|
||||||
|
fix: some windows systems cannot start the application
|
||||||
|
|
||||||
|
## v0.7.1
|
||||||
|
|
||||||
|
fix:
|
||||||
|
- some windows systems cannot start the application
|
||||||
|
- windows and linux add about menu (show version information)
|
||||||
|
- the tray icon is indistinguishable from the background in dark mode on window and linux
|
||||||
|
|
||||||
|
## v0.7.0
|
||||||
|
|
||||||
|
fix:
|
||||||
|
- mac m1 copy/paste does not work on some system versions
|
||||||
|
- optimize the save chat log button to a small icon, the tray window no longer provides a save chat log button (the buttons causes the input area to become larger and the content area to become smaller)
|
||||||
|
|
||||||
|
feat:
|
||||||
|
- use the keyboard `⇧` (arrow up) and `⇩` (arrow down) keys to select the slash command
|
||||||
|
<!-- - global shortcuts to the chatgpt app (mac: command+shift+o, windows: ctrl+shift+o) -->
|
||||||
|
|
||||||
|
## v0.6.10
|
||||||
|
|
||||||
|
fix: sync failure on windows
|
||||||
|
|
||||||
## v0.6.4
|
## v0.6.4
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
cask "chatgpt" do
|
cask "chatgpt" do
|
||||||
version "0.1.7"
|
version "0.6.10"
|
||||||
sha256 "1320b30a67e2506f9b45ffd2a48243d6141171c231dd698994ae5156a637eb3f"
|
sha256 "e85062565f826d32219c53b184d6df9c89441d4231cdfff775c2de8c50ac9906"
|
||||||
|
|
||||||
url "https://github.com/lencx/ChatGPT/releases/download/v#{version}/ChatGPT_#{version}_x64.dmg"
|
url "https://github.com/lencx/ChatGPT/releases/download/v#{version}/ChatGPT_#{version}_x64.dmg"
|
||||||
name "ChatGPT"
|
name "ChatGPT"
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
"build": "yarn tauri build",
|
"build": "yarn tauri build",
|
||||||
"updater": "tr updater",
|
"updater": "tr updater",
|
||||||
"release": "tr release --git",
|
"release": "tr release --git",
|
||||||
|
"fix:tray": "tr override --json.tauri_systemTray_iconPath=\"icons/tray-icon-light.png\" --json.tauri_systemTray_iconAsTemplate=false",
|
||||||
|
"fix:tray:mac": "tr override --json.tauri_systemTray_iconPath=\"icons/tray-icon.png\" --json.tauri_systemTray_iconAsTemplate=true",
|
||||||
"download": "node ./scripts/download.js",
|
"download": "node ./scripts/download.js",
|
||||||
"tr": "tr",
|
"tr": "tr",
|
||||||
"tauri": "tauri"
|
"tauri": "tauri"
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ tauri-build = {version = "1.2.1", features = [] }
|
|||||||
anyhow = "1.0.66"
|
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.2", features = ["api-all", "devtools", "system-tray", "updater"] }
|
tauri = { version = "1.2.3", features = ["api-all", "devtools", "global-shortcut", "system-tray", "updater"] }
|
||||||
tauri-plugin-positioner = { version = "1.0.4", features = ["system-tray"] }
|
tauri-plugin-positioner = { version = "1.0.4", features = ["system-tray"] }
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
csv = "1.1.6"
|
csv = "1.1.6"
|
||||||
thiserror = "1.0.38"
|
thiserror = "1.0.38"
|
||||||
walkdir = "2.3.2"
|
walkdir = "2.3.2"
|
||||||
regex = "1.7.0"
|
regex = "1.7.0"
|
||||||
# tokio = { version = "1.23.0", features = ["macros"] }
|
tokio = { version = "1.23.0", features = ["macros"] }
|
||||||
# reqwest = "0.11.13"
|
# reqwest = "0.11.13"
|
||||||
|
|
||||||
[dependencies.tauri-plugin-log]
|
[dependencies.tauri-plugin-log]
|
||||||
@@ -45,4 +45,4 @@ custom-protocol = [ "tauri/custom-protocol" ]
|
|||||||
[profile.release]
|
[profile.release]
|
||||||
strip = true
|
strip = true
|
||||||
lto = true
|
lto = true
|
||||||
opt-level = "z"
|
opt-level = "s"
|
||||||
|
|||||||
BIN
src-tauri/icons/tray-icon-light.png
Normal file
BIN
src-tauri/icons/tray-icon-light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 92 KiB |
@@ -1,4 +1,7 @@
|
|||||||
use crate::{conf::ChatConfJson, utils::{self, exists}};
|
use crate::{
|
||||||
|
conf::ChatConfJson,
|
||||||
|
utils::{self, exists},
|
||||||
|
};
|
||||||
use std::{collections::HashMap, fs, path::PathBuf};
|
use std::{collections::HashMap, fs, path::PathBuf};
|
||||||
use tauri::{api, command, AppHandle, Manager};
|
use tauri::{api, command, AppHandle, Manager};
|
||||||
|
|
||||||
@@ -152,10 +155,15 @@ pub fn sync_prompts(app: AppHandle, data: String, time: u64) {
|
|||||||
let chatgpt_prompts = chat_root().join("cache_model").join("chatgpt_prompts.json");
|
let chatgpt_prompts = chat_root().join("cache_model").join("chatgpt_prompts.json");
|
||||||
|
|
||||||
if !exists(&model) {
|
if !exists(&model) {
|
||||||
fs::write(&model, serde_json::json!({
|
fs::write(
|
||||||
"name": "ChatGPT Model",
|
&model,
|
||||||
"link": "https://github.com/lencx/ChatGPT"
|
serde_json::json!({
|
||||||
}).to_string()).unwrap();
|
"name": "ChatGPT Model",
|
||||||
|
"link": "https://github.com/lencx/ChatGPT"
|
||||||
|
})
|
||||||
|
.to_string(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// chatgpt_prompts.json
|
// chatgpt_prompts.json
|
||||||
|
|||||||
@@ -3,11 +3,14 @@ use crate::{
|
|||||||
utils,
|
utils,
|
||||||
};
|
};
|
||||||
use tauri::{
|
use tauri::{
|
||||||
AboutMetadata, AppHandle, CustomMenuItem, Manager, Menu, MenuItem, Submenu, SystemTray,
|
AppHandle, CustomMenuItem, Manager, Menu, MenuItem, Submenu, SystemTray, SystemTrayEvent,
|
||||||
SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem, WindowMenuEvent,
|
SystemTrayMenu, SystemTrayMenuItem, WindowMenuEvent,
|
||||||
};
|
};
|
||||||
use tauri_plugin_positioner::{on_tray_event, Position, WindowExt};
|
use tauri_plugin_positioner::{on_tray_event, Position, WindowExt};
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
use tauri::AboutMetadata;
|
||||||
|
|
||||||
use super::window;
|
use super::window;
|
||||||
|
|
||||||
// --- Menu
|
// --- Menu
|
||||||
@@ -16,19 +19,23 @@ pub fn init() -> Menu {
|
|||||||
let name = "ChatGPT";
|
let name = "ChatGPT";
|
||||||
let app_menu = Submenu::new(
|
let app_menu = Submenu::new(
|
||||||
name,
|
name,
|
||||||
Menu::new()
|
Menu::with_items([
|
||||||
.add_native_item(MenuItem::About(name.into(), AboutMetadata::default()))
|
#[cfg(target_os = "macos")]
|
||||||
.add_native_item(MenuItem::Services)
|
MenuItem::About(name.into(), AboutMetadata::default()).into(),
|
||||||
.add_native_item(MenuItem::Separator)
|
#[cfg(not(target_os = "macos"))]
|
||||||
.add_native_item(MenuItem::Hide)
|
CustomMenuItem::new("about".to_string(), "About ChatGPT").into(),
|
||||||
.add_native_item(MenuItem::HideOthers)
|
MenuItem::Services.into(),
|
||||||
.add_native_item(MenuItem::ShowAll)
|
MenuItem::Hide.into(),
|
||||||
.add_native_item(MenuItem::Separator)
|
MenuItem::HideOthers.into(),
|
||||||
.add_native_item(MenuItem::Quit),
|
MenuItem::ShowAll.into(),
|
||||||
|
MenuItem::Separator.into(),
|
||||||
|
MenuItem::Quit.into(),
|
||||||
|
]),
|
||||||
);
|
);
|
||||||
|
|
||||||
let stay_on_top =
|
let stay_on_top =
|
||||||
CustomMenuItem::new("stay_on_top".to_string(), "Stay On Top").accelerator("CmdOrCtrl+T");
|
CustomMenuItem::new("stay_on_top".to_string(), "Stay On Top").accelerator("CmdOrCtrl+T");
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
let titlebar =
|
let titlebar =
|
||||||
CustomMenuItem::new("titlebar".to_string(), "Titlebar").accelerator("CmdOrCtrl+B");
|
CustomMenuItem::new("titlebar".to_string(), "Titlebar").accelerator("CmdOrCtrl+B");
|
||||||
let theme_light = CustomMenuItem::new("theme_light".to_string(), "Light");
|
let theme_light = CustomMenuItem::new("theme_light".to_string(), "Light");
|
||||||
@@ -40,6 +47,7 @@ pub fn init() -> Menu {
|
|||||||
} else {
|
} else {
|
||||||
stay_on_top
|
stay_on_top
|
||||||
};
|
};
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
let titlebar_menu = if chat_conf.titlebar {
|
let titlebar_menu = if chat_conf.titlebar {
|
||||||
titlebar.selected()
|
titlebar.selected()
|
||||||
} else {
|
} else {
|
||||||
@@ -175,6 +183,15 @@ pub fn menu_handler(event: WindowMenuEvent<tauri::Wry>) {
|
|||||||
let menu_handle = core_window.menu_handle();
|
let menu_handle = core_window.menu_handle();
|
||||||
|
|
||||||
match menu_id {
|
match menu_id {
|
||||||
|
// App
|
||||||
|
"about" => {
|
||||||
|
let tauri_conf = utils::get_tauri_conf().unwrap();
|
||||||
|
tauri::api::dialog::message(
|
||||||
|
app.get_window("core").as_ref(),
|
||||||
|
"ChatGPT",
|
||||||
|
format!("Version {}", tauri_conf.package.version.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()),
|
||||||
@@ -262,20 +279,32 @@ pub fn menu_handler(event: WindowMenuEvent<tauri::Wry>) {
|
|||||||
|
|
||||||
// --- SystemTray Menu
|
// --- SystemTray Menu
|
||||||
pub fn tray_menu() -> SystemTray {
|
pub fn tray_menu() -> SystemTray {
|
||||||
|
if cfg!(target_os = "macos") {
|
||||||
|
return SystemTray::new().with_menu(
|
||||||
|
SystemTrayMenu::new()
|
||||||
|
.add_item(CustomMenuItem::new(
|
||||||
|
"control_center".to_string(),
|
||||||
|
"Control Center",
|
||||||
|
))
|
||||||
|
.add_item(CustomMenuItem::new(
|
||||||
|
"show_dock_icon".to_string(),
|
||||||
|
"Show Dock Icon",
|
||||||
|
))
|
||||||
|
.add_item(CustomMenuItem::new(
|
||||||
|
"hide_dock_icon".to_string(),
|
||||||
|
"Hide Dock Icon",
|
||||||
|
))
|
||||||
|
.add_native_item(SystemTrayMenuItem::Separator)
|
||||||
|
.add_item(CustomMenuItem::new("quit".to_string(), "Quit ChatGPT")),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
SystemTray::new().with_menu(
|
SystemTray::new().with_menu(
|
||||||
SystemTrayMenu::new()
|
SystemTrayMenu::new()
|
||||||
.add_item(CustomMenuItem::new(
|
.add_item(CustomMenuItem::new(
|
||||||
"control_center".to_string(),
|
"control_center".to_string(),
|
||||||
"Control Center",
|
"Control Center",
|
||||||
))
|
))
|
||||||
.add_item(CustomMenuItem::new(
|
|
||||||
"show_dock_icon".to_string(),
|
|
||||||
"Show Dock Icon",
|
|
||||||
))
|
|
||||||
.add_item(CustomMenuItem::new(
|
|
||||||
"hide_dock_icon".to_string(),
|
|
||||||
"Hide Dock Icon",
|
|
||||||
))
|
|
||||||
.add_native_item(SystemTrayMenuItem::Separator)
|
.add_native_item(SystemTrayMenuItem::Separator)
|
||||||
.add_item(CustomMenuItem::new("quit".to_string(), "Quit ChatGPT")),
|
.add_item(CustomMenuItem::new("quit".to_string(), "Quit ChatGPT")),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,22 +1,49 @@
|
|||||||
use crate::{app::window, conf::ChatConfJson, utils};
|
use crate::{app::window, conf::ChatConfJson, utils};
|
||||||
use tauri::{utils::config::WindowUrl, window::WindowBuilder, App, Manager};
|
use log::info;
|
||||||
|
use tauri::{utils::config::WindowUrl, window::WindowBuilder, App, GlobalShortcutManager, Manager};
|
||||||
|
|
||||||
pub fn init(app: &mut App) -> std::result::Result<(), Box<dyn std::error::Error>> {
|
pub fn init(app: &mut App) -> std::result::Result<(), Box<dyn std::error::Error>> {
|
||||||
|
info!("stepup");
|
||||||
let chat_conf = ChatConfJson::get_chat_conf();
|
let chat_conf = ChatConfJson::get_chat_conf();
|
||||||
let url = chat_conf.origin.to_string();
|
let url = chat_conf.origin.to_string();
|
||||||
let theme = ChatConfJson::theme();
|
let theme = ChatConfJson::theme();
|
||||||
let handle = app.app_handle();
|
let handle = app.app_handle();
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
tokio::spawn(async move {
|
||||||
window::tray_window(&handle);
|
window::tray_window(&handle);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
info!("global_shortcut_start");
|
||||||
|
let handle = app.app_handle();
|
||||||
|
let mut shortcut = app.global_shortcut_manager();
|
||||||
|
let core_shortcut = shortcut.is_registered("CmdOrCtrl+Shift+O");
|
||||||
|
|
||||||
|
info!("is_registered: {}", core_shortcut.is_ok());
|
||||||
|
|
||||||
|
if core_shortcut.is_ok() {
|
||||||
|
shortcut
|
||||||
|
.register("CmdOrCtrl+Shift+O", move || {
|
||||||
|
if let Some(w) = handle.get_window("core") {
|
||||||
|
if w.is_visible().unwrap() {
|
||||||
|
w.hide().unwrap();
|
||||||
|
} else {
|
||||||
|
w.show().unwrap();
|
||||||
|
w.set_focus().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
};
|
||||||
|
info!("global_shortcut_end");
|
||||||
|
}
|
||||||
|
|
||||||
if chat_conf.hide_dock_icon {
|
if chat_conf.hide_dock_icon {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
app.set_activation_policy(tauri::ActivationPolicy::Accessory);
|
app.set_activation_policy(tauri::ActivationPolicy::Accessory);
|
||||||
} else {
|
} else {
|
||||||
let app = app.handle();
|
let app = app.handle();
|
||||||
std::thread::spawn(move || {
|
tokio::spawn(async move {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
WindowBuilder::new(&app, "core", WindowUrl::App(url.into()))
|
WindowBuilder::new(&app, "core", WindowUrl::App(url.into()))
|
||||||
.title("ChatGPT")
|
.title("ChatGPT")
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ pub fn tray_window(handle: &tauri::AppHandle) {
|
|||||||
let theme = conf::ChatConfJson::theme();
|
let theme = conf::ChatConfJson::theme();
|
||||||
let app = handle.clone();
|
let app = handle.clone();
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
tokio::spawn(async move {
|
||||||
WindowBuilder::new(&app, "tray", WindowUrl::App(chat_conf.origin.into()))
|
WindowBuilder::new(&app, "tray", WindowUrl::App(chat_conf.origin.into()))
|
||||||
.title("ChatGPT")
|
.title("ChatGPT")
|
||||||
.resizable(false)
|
.resizable(false)
|
||||||
@@ -16,10 +16,7 @@ pub fn tray_window(handle: &tauri::AppHandle) {
|
|||||||
.always_on_top(true)
|
.always_on_top(true)
|
||||||
.theme(theme)
|
.theme(theme)
|
||||||
.initialization_script(&utils::user_script())
|
.initialization_script(&utils::user_script())
|
||||||
.initialization_script(include_str!("../assets/html2canvas.js"))
|
|
||||||
.initialization_script(include_str!("../assets/jspdf.js"))
|
|
||||||
.initialization_script(include_str!("../assets/core.js"))
|
.initialization_script(include_str!("../assets/core.js"))
|
||||||
.initialization_script(include_str!("../assets/export.js"))
|
|
||||||
.initialization_script(include_str!("../assets/cmd.js"))
|
.initialization_script(include_str!("../assets/cmd.js"))
|
||||||
.user_agent(&chat_conf.ua_tray)
|
.user_agent(&chat_conf.ua_tray)
|
||||||
.build()
|
.build()
|
||||||
@@ -31,7 +28,7 @@ pub fn tray_window(handle: &tauri::AppHandle) {
|
|||||||
|
|
||||||
pub fn control_window(handle: &tauri::AppHandle) {
|
pub fn control_window(handle: &tauri::AppHandle) {
|
||||||
let app = handle.clone();
|
let app = handle.clone();
|
||||||
std::thread::spawn(move || {
|
tokio::spawn(async move {
|
||||||
WindowBuilder::new(&app, "main", WindowUrl::App("index.html".into()))
|
WindowBuilder::new(&app, "main", WindowUrl::App("index.html".into()))
|
||||||
.title("ChatGPT")
|
.title("ChatGPT")
|
||||||
.resizable(true)
|
.resizable(true)
|
||||||
|
|||||||
107
src-tauri/src/assets/cmd.js
vendored
107
src-tauri/src/assets/cmd.js
vendored
@@ -13,13 +13,30 @@ function init() {
|
|||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
.chat-model-cmd-list>div {
|
.chat-model-cmd-list>div {
|
||||||
border: solid 2px #d8d8d8;
|
border: solid 2px rgba(80,80,80,.3);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html.dark .chat-model-cmd-list>div {
|
||||||
|
background-color: #4a4a4a;
|
||||||
|
}
|
||||||
|
html.dark .chat-model-cmd-list .cmd-item {
|
||||||
|
border-color: #666;
|
||||||
|
}
|
||||||
|
html.dark .chat-model-cmd-list .cmd-item b {
|
||||||
|
color: #e8e8e8;
|
||||||
|
}
|
||||||
|
html.dark .chat-model-cmd-list .cmd-item i {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
html.dark .chat-model-cmd-list .cmd-item.selected {
|
||||||
|
background: rgba(59,130,246,.5);
|
||||||
|
}
|
||||||
|
|
||||||
.chat-model-cmd-list .cmd-item {
|
.chat-model-cmd-list .cmd-item {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
border-bottom: solid 1px #888;
|
border-bottom: solid 1px rgba(80,80,80,.2);
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
display: flex;
|
display: flex;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
@@ -28,6 +45,9 @@ function init() {
|
|||||||
.chat-model-cmd-list .cmd-item:last-child {
|
.chat-model-cmd-list .cmd-item:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
.chat-model-cmd-list .cmd-item.selected {
|
||||||
|
background: rgba(59,130,246,.3);
|
||||||
|
}
|
||||||
.chat-model-cmd-list .cmd-item b {
|
.chat-model-cmd-list .cmd-item b {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
@@ -46,7 +66,16 @@ function init() {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
color: #888;
|
color: #888;
|
||||||
}`;
|
}
|
||||||
|
.chatappico {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
.chatappico.pdf {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
document.head.append(styleDom);
|
document.head.append(styleDom);
|
||||||
|
|
||||||
if (window.formInterval) {
|
if (window.formInterval) {
|
||||||
@@ -70,11 +99,24 @@ async function cmdTip() {
|
|||||||
|
|
||||||
// fix: tray window
|
// fix: tray window
|
||||||
if (__TAURI_METADATA__.__currentWindow.label === 'tray') {
|
if (__TAURI_METADATA__.__currentWindow.label === 'tray') {
|
||||||
modelDom.style.bottom = '40px';
|
modelDom.style.bottom = '54px';
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelector('form').appendChild(modelDom);
|
document.querySelector('form').appendChild(modelDom);
|
||||||
const itemDom = (v) => `<div class="cmd-item" title="${v.prompt}" data-prompt="${encodeURIComponent(v.prompt)}"><b title="${v.cmd}">/${v.cmd}</b><i>${v.act}</i></div>`;
|
const itemDom = (v) => `<div class="cmd-item" title="${v.prompt}" data-cmd="${v.cmd}" data-prompt="${encodeURIComponent(v.prompt)}"><b title="${v.cmd}">/${v.cmd}</b><i>${v.act}</i></div>`;
|
||||||
|
const renderList = (v) => {
|
||||||
|
modelDom.innerHTML = `<div>${v.map(itemDom).join('')}</div>`;
|
||||||
|
window.__CHAT_MODEL_CMD_PROMPT__ = v[0]?.prompt.trim();
|
||||||
|
window.__CHAT_MODEL_CMD__ = v[0]?.cmd.trim();
|
||||||
|
window.__list = modelDom.querySelectorAll('.cmd-item');
|
||||||
|
window.__index = 0;
|
||||||
|
window.__list[window.__index].classList.add('selected');
|
||||||
|
};
|
||||||
|
const setPrompt = (v = '') => {
|
||||||
|
if (v.trim()) {
|
||||||
|
window.__CHAT_MODEL_CMD_PROMPT__ = window.__CHAT_MODEL_CMD_PROMPT__?.replace(/\{([^{}]*)\}/, `{${v.trim()}}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
const searchInput = document.querySelector('form textarea');
|
const searchInput = document.querySelector('form textarea');
|
||||||
|
|
||||||
// Enter a command starting with `/` and press a space to automatically fill `chatgpt prompt`.
|
// Enter a command starting with `/` and press a space to automatically fill `chatgpt prompt`.
|
||||||
@@ -84,6 +126,35 @@ async function cmdTip() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------ Keyboard scrolling (ArrowUp | ArrowDown) --------------------------
|
||||||
|
if (event.keyCode === 38 && window.__index > 0) { // ArrowUp
|
||||||
|
window.__list[window.__index].classList.remove('selected');
|
||||||
|
window.__index = window.__index - 1;
|
||||||
|
window.__list[window.__index].classList.add('selected');
|
||||||
|
window.__CHAT_MODEL_CMD_PROMPT__ = decodeURIComponent(window.__list[window.__index].getAttribute('data-prompt'));
|
||||||
|
searchInput.value = `/${window.__list[window.__index].getAttribute('data-cmd')}`;
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.keyCode === 40 && window.__index < window.__list.length - 1) { // ArrowDown
|
||||||
|
window.__list[window.__index].classList.remove('selected');
|
||||||
|
window.__index = window.__index + 1;
|
||||||
|
window.__list[window.__index].classList.add('selected');
|
||||||
|
window.__CHAT_MODEL_CMD_PROMPT__ = decodeURIComponent(window.__list[window.__index].getAttribute('data-prompt'));
|
||||||
|
searchInput.value = `/${window.__list[window.__index].getAttribute('data-cmd')}`;
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
const containerHeight = modelDom.offsetHeight;
|
||||||
|
const itemHeight = window.__list[0].offsetHeight + 1;
|
||||||
|
|
||||||
|
const itemTop = window.__list[window.__index].offsetTop;
|
||||||
|
const itemBottom = itemTop + itemHeight;
|
||||||
|
if (itemTop < modelDom.scrollTop || itemBottom > modelDom.scrollTop + containerHeight) {
|
||||||
|
modelDom.scrollTop = itemTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------ TAB key replaces `{q}` tag content -------------------------------
|
||||||
// feat: https://github.com/lencx/ChatGPT/issues/54
|
// feat: https://github.com/lencx/ChatGPT/issues/54
|
||||||
if (event.keyCode === 9 && !window.__CHAT_MODEL_STATUS__) {
|
if (event.keyCode === 9 && !window.__CHAT_MODEL_STATUS__) {
|
||||||
const strGroup = window.__CHAT_MODEL_CMD_PROMPT__.match(/\{([^{}]*)\}/) || [];
|
const strGroup = window.__CHAT_MODEL_CMD_PROMPT__.match(/\{([^{}]*)\}/) || [];
|
||||||
@@ -95,36 +166,34 @@ async function cmdTip() {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.__CHAT_MODEL_STATUS__ === 1 && event.keyCode === 9) {
|
if (window.__CHAT_MODEL_STATUS__ === 1 && event.keyCode === 9) { // TAB
|
||||||
const data = searchInput.value.split('|->');
|
const data = searchInput.value.split('|->');
|
||||||
if (data[1]?.trim()) {
|
if (data[1]?.trim()) {
|
||||||
window.__CHAT_MODEL_CMD_PROMPT__ = window.__CHAT_MODEL_CMD_PROMPT__?.replace(/\{([^{}]*)\}/, `{${data[1]?.trim()}}`);
|
setPrompt(data[1]);
|
||||||
window.__CHAT_MODEL_STATUS__ = 2;
|
window.__CHAT_MODEL_STATUS__ = 2;
|
||||||
}
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
// input text
|
// input text
|
||||||
if (window.__CHAT_MODEL_STATUS__ === 2 && event.keyCode === 9) {
|
if (window.__CHAT_MODEL_STATUS__ === 2 && event.keyCode === 9) { // TAB
|
||||||
searchInput.value = window.__CHAT_MODEL_CMD_PROMPT__;
|
searchInput.value = window.__CHAT_MODEL_CMD_PROMPT__;
|
||||||
modelDom.innerHTML = '';
|
modelDom.innerHTML = '';
|
||||||
delete window.__CHAT_MODEL_STATUS__;
|
delete window.__CHAT_MODEL_STATUS__;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
// type in a space to complete the fill
|
// ------------------ type in a space to complete the fill ------------------------------------
|
||||||
if (event.keyCode === 32) {
|
if (event.keyCode === 32) {
|
||||||
searchInput.value = window.__CHAT_MODEL_CMD_PROMPT__;
|
searchInput.value = window.__CHAT_MODEL_CMD_PROMPT__;
|
||||||
modelDom.innerHTML = '';
|
modelDom.innerHTML = '';
|
||||||
delete window.__CHAT_MODEL_CMD_PROMPT__;
|
delete window.__CHAT_MODEL_CMD_PROMPT__;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send
|
// ------------------ send --------------------------------------------------------------------
|
||||||
if (event.keyCode === 13 && window.__CHAT_MODEL_CMD_PROMPT__) {
|
if (event.keyCode === 13 && window.__CHAT_MODEL_CMD_PROMPT__) { // Enter
|
||||||
const data = searchInput.value.split('|->');
|
const data = searchInput.value.split('|->');
|
||||||
if (data[1]?.trim()) {
|
setPrompt(data[1]);
|
||||||
window.__CHAT_MODEL_CMD_PROMPT__ = window.__CHAT_MODEL_CMD_PROMPT__?.replace(/\{([^{}]*)\}/, `{${data[1]?.trim()}}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
searchInput.value = window.__CHAT_MODEL_CMD_PROMPT__;
|
searchInput.value = window.__CHAT_MODEL_CMD_PROMPT__;
|
||||||
modelDom.innerHTML = '';
|
modelDom.innerHTML = '';
|
||||||
@@ -135,7 +204,7 @@ async function cmdTip() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
searchInput.addEventListener('input', (event) => {
|
searchInput.addEventListener('input', () => {
|
||||||
if (searchInput.value === '') {
|
if (searchInput.value === '') {
|
||||||
delete window.__CHAT_MODEL_CMD_PROMPT__;
|
delete window.__CHAT_MODEL_CMD_PROMPT__;
|
||||||
delete window.__CHAT_MODEL_CMD__;
|
delete window.__CHAT_MODEL_CMD__;
|
||||||
@@ -152,17 +221,13 @@ async function cmdTip() {
|
|||||||
|
|
||||||
// all cmd result
|
// all cmd result
|
||||||
if (query === '/') {
|
if (query === '/') {
|
||||||
modelDom.innerHTML = `<div>${data.map(itemDom).join('')}</div>`;
|
renderList(data);
|
||||||
window.__CHAT_MODEL_CMD_PROMPT__ = data[0]?.prompt.trim();
|
|
||||||
window.__CHAT_MODEL_CMD__ = data[0]?.cmd.trim();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = data.filter(i => new RegExp(query.substring(1)).test(i.cmd));
|
const result = data.filter(i => new RegExp(query.substring(1)).test(i.cmd));
|
||||||
if (result.length > 0) {
|
if (result.length > 0) {
|
||||||
modelDom.innerHTML = `<div>${result.map(itemDom).join('')}</div>`;
|
renderList(result);
|
||||||
window.__CHAT_MODEL_CMD_PROMPT__ = result[0]?.prompt.trim();
|
|
||||||
window.__CHAT_MODEL_CMD__ = result[0]?.cmd.trim();
|
|
||||||
} else {
|
} else {
|
||||||
modelDom.innerHTML = '';
|
modelDom.innerHTML = '';
|
||||||
delete window.__CHAT_MODEL_CMD_PROMPT__;
|
delete window.__CHAT_MODEL_CMD_PROMPT__;
|
||||||
|
|||||||
2
src-tauri/src/assets/core.js
vendored
2
src-tauri/src/assets/core.js
vendored
@@ -91,8 +91,6 @@ async function init() {
|
|||||||
const res = await fetch('https://raw.githubusercontent.com/f/awesome-chatgpt-prompts/main/prompts.csv');
|
const res = await fetch('https://raw.githubusercontent.com/f/awesome-chatgpt-prompts/main/prompts.csv');
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const data = await res.text();
|
const data = await res.text();
|
||||||
console.log('«94» /src/assets/core.js ~> ', data);
|
|
||||||
|
|
||||||
await invoke('sync_prompts', { data, time: Date.now() });
|
await invoke('sync_prompts', { data, time: Date.now() });
|
||||||
} else {
|
} else {
|
||||||
invoke('messageDialog', {
|
invoke('messageDialog', {
|
||||||
|
|||||||
23
src-tauri/src/assets/export.js
vendored
23
src-tauri/src/assets/export.js
vendored
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
const buttonOuterHTMLFallback = `<button class="btn flex justify-center gap-2 btn-neutral" id="download-png-button">Try Again</button>`;
|
const buttonOuterHTMLFallback = `<button class="btn flex justify-center gap-2 btn-neutral" id="download-png-button">Try Again</button>`;
|
||||||
async function init() {
|
async function init() {
|
||||||
|
if (window.innerWidth < 767) return;
|
||||||
const chatConf = await invoke('get_chat_conf') || {};
|
const chatConf = await invoke('get_chat_conf') || {};
|
||||||
if (window.buttonsInterval) {
|
if (window.buttonsInterval) {
|
||||||
clearInterval(window.buttonsInterval);
|
clearInterval(window.buttonsInterval);
|
||||||
@@ -88,7 +89,9 @@ function addActionsButtons(actionsArea, TryAgainButton) {
|
|||||||
const downloadButton = TryAgainButton.cloneNode(true);
|
const downloadButton = TryAgainButton.cloneNode(true);
|
||||||
downloadButton.id = "download-png-button";
|
downloadButton.id = "download-png-button";
|
||||||
downloadButton.setAttribute("share-ext", "true");
|
downloadButton.setAttribute("share-ext", "true");
|
||||||
downloadButton.innerText = "Generate PNG";
|
// downloadButton.innerText = "Generate PNG";
|
||||||
|
downloadButton.title = "Generate PNG";
|
||||||
|
downloadButton.innerHTML = setIcon('png');
|
||||||
downloadButton.onclick = () => {
|
downloadButton.onclick = () => {
|
||||||
downloadThread();
|
downloadThread();
|
||||||
};
|
};
|
||||||
@@ -96,7 +99,9 @@ function addActionsButtons(actionsArea, TryAgainButton) {
|
|||||||
const downloadPdfButton = TryAgainButton.cloneNode(true);
|
const downloadPdfButton = TryAgainButton.cloneNode(true);
|
||||||
downloadPdfButton.id = "download-pdf-button";
|
downloadPdfButton.id = "download-pdf-button";
|
||||||
downloadButton.setAttribute("share-ext", "true");
|
downloadButton.setAttribute("share-ext", "true");
|
||||||
downloadPdfButton.innerText = "Download PDF";
|
// downloadPdfButton.innerText = "Download PDF";
|
||||||
|
downloadPdfButton.title = "Download PDF";
|
||||||
|
downloadPdfButton.innerHTML = setIcon('pdf');
|
||||||
downloadPdfButton.onclick = () => {
|
downloadPdfButton.onclick = () => {
|
||||||
downloadThread({ as: Format.PDF });
|
downloadThread({ as: Format.PDF });
|
||||||
};
|
};
|
||||||
@@ -104,7 +109,9 @@ function addActionsButtons(actionsArea, TryAgainButton) {
|
|||||||
const exportHtml = TryAgainButton.cloneNode(true);
|
const exportHtml = TryAgainButton.cloneNode(true);
|
||||||
exportHtml.id = "download-html-button";
|
exportHtml.id = "download-html-button";
|
||||||
downloadButton.setAttribute("share-ext", "true");
|
downloadButton.setAttribute("share-ext", "true");
|
||||||
exportHtml.innerText = "Share Link";
|
// exportHtml.innerText = "Share Link";
|
||||||
|
exportHtml.title = "Share Link";
|
||||||
|
exportHtml.innerHTML = setIcon('link');
|
||||||
exportHtml.onclick = () => {
|
exportHtml.onclick = () => {
|
||||||
sendRequest();
|
sendRequest();
|
||||||
};
|
};
|
||||||
@@ -269,4 +276,12 @@ if (
|
|||||||
init();
|
init();
|
||||||
} else {
|
} else {
|
||||||
document.addEventListener("DOMContentLoaded", init);
|
document.addEventListener("DOMContentLoaded", init);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setIcon(type) {
|
||||||
|
return {
|
||||||
|
link: `<svg class="chatappico" viewBox="0 0 1024 1024"><path d="M1007.382 379.672L655.374 75.702C624.562 49.092 576 70.694 576 112.03v160.106C254.742 275.814 0 340.2 0 644.652c0 122.882 79.162 244.618 166.666 308.264 27.306 19.862 66.222-5.066 56.154-37.262C132.132 625.628 265.834 548.632 576 544.17V720c0 41.4 48.6 62.906 79.374 36.328l352.008-304c22.142-19.124 22.172-53.506 0-72.656z" p-id="8506" fill="currentColor"></path></svg>`,
|
||||||
|
png: `<svg class="chatappico" viewBox="0 0 1070 1024"><path d="M981.783273 0H85.224727C38.353455 0 0 35.374545 0 83.083636v844.893091c0 47.616 38.353455 86.574545 85.178182 86.574546h903.633454c46.917818 0 81.733818-38.958545 81.733819-86.574546V83.083636C1070.592 35.374545 1028.701091 0 981.783273 0zM335.825455 135.912727c74.193455 0 134.330182 60.974545 134.330181 136.285091 0 75.170909-60.136727 136.192-134.330181 136.192-74.286545 0-134.516364-61.021091-134.516364-136.192 0-75.264 60.229818-136.285091 134.516364-136.285091z m-161.512728 745.937455a41.890909 41.890909 0 0 1-27.648-10.379637 43.752727 43.752727 0 0 1-4.654545-61.067636l198.097454-255.162182a42.123636 42.123636 0 0 1 57.716364-6.702545l116.549818 128.139636 286.906182-352.814545c14.615273-18.711273 90.251636-106.775273 135.866182-6.935273 0.093091-0.093091 0.093091 112.965818 0.232727 247.761455 0.093091 140.8 0.093091 317.067636 0.093091 317.067636-1.024-0.093091-762.740364 0.093091-763.112727 0.093091z" fill="currentColor"></path></svg>`,
|
||||||
|
pdf: `<svg class="chatappico pdf" viewBox="0 0 1024 1024"><path d="M821.457602 118.382249H205.725895c-48.378584 0-87.959995 39.583368-87.959996 87.963909v615.731707c0 48.378584 39.581411 87.959995 87.959996 87.959996h615.733664c48.380541 0 87.961952-39.581411 87.961952-87.959996V206.346158c-0.001957-48.378584-39.583368-87.963909-87.963909-87.963909zM493.962468 457.544987c-10.112054 32.545237-21.72487 82.872662-38.806571 124.248336-8.806957 22.378397-8.380404 18.480717-15.001764 32.609808l5.71738-1.851007c58.760658-16.443827 99.901532-20.519564 138.162194-27.561607-7.67796-6.06371-14.350194-10.751884-19.631237-15.586807-26.287817-29.101504-35.464584-34.570387-70.440002-111.862636v0.003913z m288.36767 186.413594c-7.476424 8.356924-20.670227 13.191847-40.019704 13.191847-33.427694 0-63.808858-9.229597-107.79277-31.660824-75.648648 8.356924-156.097 17.214754-201.399704 31.729308-2.199293 0.876587-4.832967 1.759043-7.916674 3.077836-54.536215 93.237125-95.031389 132.767663-130.621199 131.19646-11.286054-0.49895-27.694661-7.044-32.973748-10.11988l-6.52157-6.196764-2.29517-4.353583c-3.07588-7.91863-3.954423-15.395054-2.197337-23.751977 4.838837-23.309771 29.907651-60.251638 82.686779-93.237126 8.356924-6.159587 27.430511-15.897917 45.020944-24.25484 13.311204-21.177004 19.45905-34.744531 36.341171-72.259702 19.102937-45.324228 36.505531-99.492589 47.500041-138.191543v-0.44025c-16.267727-53.219378-25.945401-89.310095-9.67376-147.80856 3.958337-16.71189 18.46702-33.864031 34.748444-33.864031h10.552304c10.115967 0 19.791684 3.520043 26.829814 10.552304 29.029107 29.031064 15.39114 103.824649 0.8805 162.323113-0.8805 2.63563-1.322707 4.832967-1.761 6.153717 17.59239 49.697378 45.400538 98.774492 73.108895 121.647926 11.436717 8.791304 22.638634 18.899444 36.71098 26.814161 19.791684-2.20125 37.517128-4.11487 55.547812-4.11487 54.540128 0 87.525615 9.67963 100.279169 30.351814 4.400543 7.034217 6.595923 15.389184 5.281043 24.1844-0.44025 10.996467-4.39663 21.112434-12.31526 29.031064z m-27.796407-36.748157c-4.394673-4.398587-17.024957-16.936907-78.601259-16.936907-3.073923 0-10.622744-0.784623-14.57521 3.612007 32.104987 14.072347 62.830525 24.757704 83.058545 24.757703 3.083707 0 5.72325-0.442207 8.356923-0.876586h1.759044c2.20125-0.8805 3.520043-1.324663 3.960293-5.71738-0.87463-1.324663-1.757087-3.083707-3.958336-4.838837z m-387.124553 63.041845c-9.237424 5.27713-16.71189 10.112054-21.112433 13.634053-31.226444 28.586901-51.018128 57.616008-53.217422 74.331812 19.789727-6.59788 45.737084-35.626987 74.329855-87.961952v-0.003913z m125.574957-297.822284l2.197336-1.761c3.079793-14.072347 5.232127-29.189554 7.87167-38.869184l1.318794-7.036174c4.39663-25.070771 2.71781-39.720334-4.76057-50.272637l-6.59788-2.20125a57.381208 57.381208 0 0 0-3.079794 5.27713c-7.474467 18.47289-7.063567 55.283661 3.0524 94.865072l-0.001956-0.001957z" fill="currentColor"></path></svg>`
|
||||||
|
}[type];
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::utils::{chat_root, create_file, exists};
|
use crate::utils::{chat_root, create_file, exists};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use log::info;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::{collections::BTreeMap, fs, path::PathBuf, sync::Mutex};
|
use std::{collections::BTreeMap, fs, path::PathBuf, sync::Mutex};
|
||||||
use tauri::{Manager, Theme};
|
use tauri::{Manager, Theme};
|
||||||
@@ -7,8 +8,8 @@ use tauri::{Manager, Theme};
|
|||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
use tauri::TitleBarStyle;
|
use tauri::TitleBarStyle;
|
||||||
|
|
||||||
// pub const USER_AGENT: &str = "5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36";
|
// pub const USER_AGENT: &str = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15";
|
||||||
// pub const PHONE_USER_AGENT: &str = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1";
|
// pub const PHONE_USER_AGENT: &str = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1";
|
||||||
|
|
||||||
pub const ISSUES_URL: &str = "https://github.com/lencx/ChatGPT/issues";
|
pub const ISSUES_URL: &str = "https://github.com/lencx/ChatGPT/issues";
|
||||||
pub const UPDATE_LOG_URL: &str = "https://github.com/lencx/ChatGPT/blob/main/UPDATE_LOG.md";
|
pub const UPDATE_LOG_URL: &str = "https://github.com/lencx/ChatGPT/blob/main/UPDATE_LOG.md";
|
||||||
@@ -66,6 +67,7 @@ impl ChatConfJson {
|
|||||||
/// init chat.conf.json
|
/// init chat.conf.json
|
||||||
/// path: ~/.chatgpt/chat.conf.json
|
/// path: ~/.chatgpt/chat.conf.json
|
||||||
pub fn init() -> PathBuf {
|
pub fn init() -> PathBuf {
|
||||||
|
info!("chat_conf_init");
|
||||||
let conf_file = ChatConfJson::conf_path();
|
let conf_file = ChatConfJson::conf_path();
|
||||||
let content = if cfg!(target_os = "macos") {
|
let content = if cfg!(target_os = "macos") {
|
||||||
DEFAULT_CHAT_CONF_MAC
|
DEFAULT_CHAT_CONF_MAC
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ use tauri_plugin_log::{
|
|||||||
LogTarget, LoggerBuilder,
|
LogTarget, LoggerBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
ChatConfJson::init();
|
ChatConfJson::init();
|
||||||
// If the file does not exist, creating the file will block menu synchronization
|
// If the file does not exist, creating the file will block menu synchronization
|
||||||
utils::create_chatgpt_prompts();
|
utils::create_chatgpt_prompts();
|
||||||
|
|||||||
@@ -8,19 +8,18 @@ use std::{
|
|||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::Command,
|
process::Command,
|
||||||
};
|
};
|
||||||
use tauri::Manager;
|
use tauri::{utils::config::Config, Manager};
|
||||||
// use tauri::utils::config::Config;
|
|
||||||
|
|
||||||
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")
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn get_tauri_conf() -> Option<Config> {
|
pub fn get_tauri_conf() -> Option<Config> {
|
||||||
// let config_file = include_str!("../tauri.conf.json");
|
let config_file = include_str!("../tauri.conf.json");
|
||||||
// let config: Config =
|
let config: Config =
|
||||||
// serde_json::from_str(config_file).expect("failed to parse tauri.conf.json");
|
serde_json::from_str(config_file).expect("failed to parse tauri.conf.json");
|
||||||
// Some(config)
|
Some(config)
|
||||||
// }
|
}
|
||||||
|
|
||||||
pub fn exists(path: &Path) -> bool {
|
pub fn exists(path: &Path) -> bool {
|
||||||
Path::new(path).exists()
|
Path::new(path).exists()
|
||||||
|
|||||||
@@ -7,11 +7,14 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "ChatGPT",
|
"productName": "ChatGPT",
|
||||||
"version": "0.6.7"
|
"version": "0.7.3"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
"all": true,
|
"all": true,
|
||||||
|
"globalShortcut": {
|
||||||
|
"all": true
|
||||||
|
},
|
||||||
"http": {
|
"http": {
|
||||||
"all": true,
|
"all": true,
|
||||||
"scope": [
|
"scope": [
|
||||||
@@ -22,9 +25,7 @@
|
|||||||
"fs": {
|
"fs": {
|
||||||
"all": true,
|
"all": true,
|
||||||
"scope": [
|
"scope": [
|
||||||
"$HOME/*",
|
"$HOME/.chatgpt/**"
|
||||||
"$HOME/.chatgpt/*",
|
|
||||||
"$HOME/.chatgpt/cache_sync/*"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
14
src/utils.ts
vendored
14
src/utils.ts
vendored
@@ -1,4 +1,4 @@
|
|||||||
import { readTextFile, writeTextFile, exists, createDir, BaseDirectory } from '@tauri-apps/api/fs';
|
import { readTextFile, writeTextFile, exists, createDir } from '@tauri-apps/api/fs';
|
||||||
import { homeDir, join, dirname } from '@tauri-apps/api/path';
|
import { homeDir, join, dirname } from '@tauri-apps/api/path';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
@@ -28,7 +28,11 @@ type readJSONOpts = { defaultVal?: Record<string, any>, isRoot?: boolean, isList
|
|||||||
export const readJSON = async (path: string, opts: readJSONOpts = {}) => {
|
export const readJSON = async (path: string, opts: readJSONOpts = {}) => {
|
||||||
const { defaultVal = {}, isRoot = false, isList = false } = opts;
|
const { defaultVal = {}, isRoot = false, isList = false } = opts;
|
||||||
const root = await chatRoot();
|
const root = await chatRoot();
|
||||||
const file = await join(isRoot ? '' : root, path);
|
let file = path;
|
||||||
|
|
||||||
|
if (!isRoot) {
|
||||||
|
file = await join(root, path);
|
||||||
|
}
|
||||||
|
|
||||||
if (!await exists(file)) {
|
if (!await exists(file)) {
|
||||||
if (await dirname(file) !== root) {
|
if (await dirname(file) !== root) {
|
||||||
@@ -52,7 +56,11 @@ type writeJSONOpts = { dir?: string, isRoot?: boolean };
|
|||||||
export const writeJSON = async (path: string, data: Record<string, any>, opts: writeJSONOpts = {}) => {
|
export const writeJSON = async (path: string, data: Record<string, any>, opts: writeJSONOpts = {}) => {
|
||||||
const { isRoot = false } = opts;
|
const { isRoot = false } = opts;
|
||||||
const root = await chatRoot();
|
const root = await chatRoot();
|
||||||
const file = await join(isRoot ? '' : root, path);
|
let file = path;
|
||||||
|
|
||||||
|
if (!isRoot) {
|
||||||
|
file = await join(root, path);
|
||||||
|
}
|
||||||
|
|
||||||
if (isRoot && !await exists(await dirname(file))) {
|
if (isRoot && !await exists(await dirname(file))) {
|
||||||
await createDir(await dirname(file), { recursive: true });
|
await createDir(await dirname(file), { recursive: true });
|
||||||
|
|||||||
Reference in New Issue
Block a user