Compare commits

...

50 Commits
v1.0.0 ... main

Author SHA1 Message Date
lencx
fe4f231d48
Merge pull request #1226 from lencx/lencx-patch-4
chore: add Noi
2024-03-11 19:13:34 +08:00
lencx
78b6f9349c
chore: add Noi 2024-03-11 19:13:23 +08:00
lencx
e547ef6c67
Merge pull request #1172 from wubaiqing/main
fix: brew cask version number
2024-03-11 10:52:21 +08:00
lencx
8cf623c7cc
Merge pull request #1223 from webbertakken/patch-1
fix: couple of typos in about
2024-03-11 10:52:08 +08:00
Webber Takken
fc5aa6a650
fix: couple of typos in about 2024-03-10 19:35:50 +01:00
lencx
1c97623156
Merge pull request #1200 from lencx/lencx-patch-3
add Noi
2024-01-29 18:34:14 +08:00
lencx
f9e75ffb2c
add Noi 2024-01-29 18:33:57 +08:00
wubaiqing
ef2bed4996
fix: brew cask version number 2023-12-13 17:25:43 +08:00
lencx
fac5a4399e v1.1.0 2023-08-03 21:30:37 +08:00
lencx
1a53fe62b8 release 2023-08-03 21:29:53 +08:00
lencx
ca1949f502 fix: layout 2023-08-03 21:24:31 +08:00
lencx
c8a79ea0bb
Merge pull request #1017 from djdarcy/main 2023-08-03 16:25:27 +08:00
Dustin Darcy
c68f1ab45b Modifying *all* <code> blocks to remove whitespace after <code>
to fix improper markdown formatting.
2023-07-29 11:23:48 -04:00
Dustin Darcy
f5491b4b15 Swapping all spaces with global &nbsp (non-blocking spaces) causes
issues with word-wrap. To solve this we now only have nbsp when we
encounter spaces or a tab at the start of a line (to maintain indentation).

A fiddle exists to test the regex at:
https://jsfiddle.net/xtraeme/x34ao9jp/13/
2023-07-27 16:09:35 -04:00
Dustin Darcy
66a0dafbc6 Improved exportMarkdown() & getName() to better preserve user input:
* Maintains proper carriage returns in markdown output
* Indented spaces / tabs are converted to &nbsp; then run through ExportMD

Also added stub code to improve readability of exported filenames, but this will likely also require changes to some of the Rust code
2023-07-27 02:31:31 -04:00
lencx
119570c4d0 chore: remove gpt4 mobile 2023-07-20 13:34:23 +08:00
lencx
bcec5775bb fix: export 2023-07-08 15:48:10 +08:00
lencx
5608bf6eb2 fix: export 2023-07-08 15:14:10 +08:00
lencx
7023b04dd2 fix: export icons 2023-07-08 11:10:24 +08:00
lencx
af77ee74b5
Merge pull request #988 from lencx/lencx-patch-3 2023-07-05 22:50:06 +08:00
lencx
85331de85b
readme 2023-07-05 22:49:55 +08:00
lencx
c499ba37bd fix: auto continue 2023-07-05 19:11:14 +08:00
lencx
94d27f0d24 feat: auto continue 2023-07-05 18:28:36 +08:00
lencx
beafad8174
Merge pull request #985 from lencx/lencx-patch-2 2023-07-05 11:27:34 +08:00
lencx
90e0659ffd
readme 2023-07-05 11:27:22 +08:00
lencx
25ca555ec4
Merge pull request #984 from asheroto/main 2023-07-04 14:02:47 +08:00
asheroto
bea27ac0af
Update bug_report.yml
Fix hyperlink
2023-07-01 00:21:25 -05:00
asheroto
3828a56fa6
Update bug_report.yml
Remove link from checkbox label
2023-07-01 00:20:42 -05:00
asheroto
ba0f7c6a82
Update bug_report.yml
Fix spacing bug
2023-07-01 00:20:15 -05:00
asheroto
81ebb7ed4f
Update bug_report.yml
Fix
2023-07-01 00:17:13 -05:00
asheroto
63928b08d2
Update bug_report.yml
Fix tabbing
2023-07-01 00:15:52 -05:00
asheroto
c44b8cc37a
Update bug_report.yml
Fix tabbing
2023-07-01 00:13:17 -05:00
asheroto
62559ad353
Update bug_report.yml 2023-07-01 00:07:28 -05:00
lencx
ce6344b534 fix: mac titlebar 2023-07-01 00:22:58 +08:00
lencx
00aa242c2a
Merge pull request #979 from tk103331/main 2023-06-30 23:59:19 +08:00
tk103331
1e4c1de971 fix: ui adaptation for no titlebar 2023-06-28 15:34:39 +08:00
lencx
b0bb6e201e readme 2023-06-02 00:21:05 +08:00
lencx
6245f73733 readme 2023-06-01 21:10:27 +08:00
lencx
87c01e3568 chore: manifest 2023-06-01 19:33:59 +08:00
lencx
26cf448e48 feat: GPT-4-Mobile 2023-06-01 19:24:14 +08:00
lencx
d9c83fd084 feat: GPT-4-Mobile 2023-06-01 19:15:35 +08:00
lencx
2b03c2ccde fix: log 2023-05-29 12:43:19 +08:00
lencx
0a88431965
Merge pull request #918 from karbassi/patch-1 2023-05-26 16:16:11 +08:00
Ali Karbassi
25dd7aaca3
Update Brewfile to 1.0.0 2023-05-25 10:24:48 -05:00
lencx
fc27ae21ac fix: cmd 2023-05-25 22:34:43 +08:00
lencx
f501607355 Merge branch 'main' of github.com:lencx/ChatGPT 2023-05-25 14:37:29 +08:00
lencx
b904b1e255 fix: export pdf 2023-05-25 14:37:14 +08:00
lencx
59afd74879
Merge pull request #914 from lencx/lencx-patch-1 2023-05-25 14:29:17 +08:00
lencx
2d18d7f457
fix: export.js 2023-05-25 14:29:07 +08:00
lencx
76c10e3662
Merge pull request #912 from lencx/dev 2023-05-25 13:24:45 +08:00
15 changed files with 306 additions and 257 deletions

View File

@ -6,7 +6,17 @@ labels:
body: body:
- type: markdown - type: markdown
attributes: attributes:
value: 'Please make sure to [search for existing issues](https://github.com/lencx/ChatGPT/issues) before filing a new one!' value: |
Please **DO NOT** file issues here if you are having problems with ChatGPT itself. Issues should **ONLY** be created here for bugs that pertain to this package, [lencx/ChatGPT](https://github.com/lencx/ChatGPT). If you are experiencing an issue on [chat.openai.com](https://chat.openai.com), please contact **OpenAI** for support or submit feedback through ChatGPT itself. If you **only have an issue with this app** and do not have the issue on [chat.openai.com](https://chat.openai.com), please file an issue here.
Please make sure to [search for existing issues](https://github.com/lencx/ChatGPT/issues) before filing a new one!
- type: checkboxes
attributes:
label: Non-ChatGPT bug
options:
- label: |
This issue does not occur on chat.openai.com and only occurs on this app.
required: true
- type: markdown - type: markdown
attributes: attributes:
value: | value: |

3
.gitignore vendored
View File

@ -4,6 +4,9 @@ node_modules/
.yarn/* .yarn/*
.pnp.* .pnp.*
# Testing
private/
# rust # rust
target/ target/

View File

@ -32,7 +32,7 @@
### Windows ### Windows
- [ChatGPT_1.0.0_windows_x86_64.msi](https://github.com/lencx/ChatGPT/releases/download/v1.0.0/ChatGPT_1.0.0_windows_x86_64.msi) - [ChatGPT_1.1.0_windows_x86_64.msi](https://github.com/lencx/ChatGPT/releases/download/v1.1.0/ChatGPT_1.1.0_windows_x86_64.msi)
- 使用 [winget](https://winstall.app/apps/lencx.ChatGPT): - 使用 [winget](https://winstall.app/apps/lencx.ChatGPT):
```bash ```bash
@ -47,8 +47,8 @@
### Mac ### Mac
- [ChatGPT_1.0.0_macos_aarch64.dmg](https://github.com/lencx/ChatGPT/releases/download/v1.0.0/ChatGPT_1.0.0_macos_aarch64.dmg) - [ChatGPT_1.1.0_macos_aarch64.dmg](https://github.com/lencx/ChatGPT/releases/download/v1.1.0/ChatGPT_1.1.0_macos_aarch64.dmg)
- [ChatGPT_1.0.0_macos_x86_64.dmg](https://github.com/lencx/ChatGPT/releases/download/v1.0.0/ChatGPT_1.0.0_macos_x86_64.dmg) - [ChatGPT_1.1.0_macos_x86_64.dmg](https://github.com/lencx/ChatGPT/releases/download/v1.1.0/ChatGPT_1.1.0_macos_x86_64.dmg)
- Homebrew \ - Homebrew \
_[Homebrew 快捷安装](https://brew.sh) ([Cask](https://docs.brew.sh/Cask-Cookbook)):_ _[Homebrew 快捷安装](https://brew.sh) ([Cask](https://docs.brew.sh/Cask-Cookbook)):_
```sh ```sh
@ -70,8 +70,8 @@ sudo xattr -r -d com.apple.quarantine /YOUR_PATH/ChatGPT.app
### Linux ### Linux
- [ChatGPT_1.0.0_linux_x86_64.deb](https://github.com/lencx/ChatGPT/releases/download/v1.0.0/ChatGPT_1.0.0_linux_x86_64.deb) - [ChatGPT_1.1.0_linux_x86_64.deb](https://github.com/lencx/ChatGPT/releases/download/v1.1.0/ChatGPT_1.1.0_linux_x86_64.deb)
- [ChatGPT_1.0.0_linux_x86_64.AppImage.tar.gz](https://github.com/lencx/ChatGPT/releases/download/v1.0.0/ChatGPT_1.0.0_linux_x86_64.AppImage.tar.gz): **工作可靠,`.deb` 运行失败时可以尝试它** - [ChatGPT_1.1.0_linux_x86_64.AppImage.tar.gz](https://github.com/lencx/ChatGPT/releases/download/v1.1.0/ChatGPT_1.1.0_linux_x86_64.AppImage.tar.gz): **工作可靠,`.deb` 运行失败时可以尝试它**
<!-- tr-download-end --> <!-- tr-download-end -->

View File

@ -1,28 +1,35 @@
<p align="center"> <p align="center">
<img width="180" src="./public/logo.png" alt="ChatGPT"> <img width="180" src="./public/logo.png" alt="ChatGPT">
<h1 align="center">ChatGPT</h1> <h1 align="center">ChatGPT</h1>
<p align="center">ChatGPT Desktop Application (Mac, Windows and Linux)</p> <p align="center">ChatGPT Desktop Application (Available on Mac, Windows, and Linux)</p>
</p> </p>
[![English badge](https://img.shields.io/badge/%E8%8B%B1%E6%96%87-English-blue)](./README.md) [![English badge](https://img.shields.io/badge/%E8%8B%B1%E6%96%87-English-blue)](./README.md)
[![简体中文 badge](https://img.shields.io/badge/%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87-Simplified%20Chinese-blue)](./README-ZH_CN.md)\ [![简体中文 badge](https://img.shields.io/badge/%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87-Simplified%20Chinese-blue)](./README-ZH_CN.md)\
[![ChatGPT downloads](https://img.shields.io/github/downloads/lencx/ChatGPT/total.svg?style=flat-square)](https://github.com/lencx/ChatGPT/releases) [![ChatGPT downloads](https://img.shields.io/github/downloads/lencx/ChatGPT/total.svg?style=flat-square)](https://github.com/lencx/ChatGPT/releases)
[![chat](https://img.shields.io/badge/chat-discord-blue?style=flat&logo=discord)](https://discord.gg/aPhCRf4zZr) [![chat](https://img.shields.io/badge/chat-discord-blue?style=flat&logo=discord)](https://discord.gg/aPhCRf4zZr)
[![lencx](https://img.shields.io/badge/follow-lencx__-blue?style=flat&logo=Twitter)](https://twitter.com/lencx_) [![twitter](https://img.shields.io/badge/follow-lencx__-blue?style=flat&logo=Twitter)](https://twitter.com/lencx_)
[![youtube](https://img.shields.io/youtube/channel/subscribers/UC__gTZL-OZKDPic7s_6Ntgg?style=social)](https://www.youtube.com/@lencx)
<a href="https://www.buymeacoffee.com/lencx" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-blue.png" alt="Buy Me A Coffee" style="height: 40px !important;width: 145px !important;" ></a> <a href="https://www.buymeacoffee.com/lencx" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-blue.png" alt="Buy Me A Coffee" style="height: 40px !important;width: 145px !important;" ></a>
--- ---
**It is an unofficial project intended for personal learning and research purposes only. During the time that the ChatGPT desktop application was open-sourced, it received a lot of attention, and I would like to thank everyone for their support. However, as things have developed, there are two issues that seriously affect the project's next development plan:** > [!NOTE]
> **If you want to experience a more powerful AI wrapper application, you can try the Noi (https://github.com/lencx/Noi), which is a successor to the ChatGPT desktop application concept.**
- **Some people have used it for repackaging and selling for profit.**
- **The name and icon of ChatGPT may be involved in infringement issues.**
**New repository: https://github.com/lencx/nofwl**
--- ---
This is an unofficial project solely intended for personal learning and research. Since the ChatGPT desktop application was open-sourced, it has garnered a lot of attention, and I want to thank everyone for their support. However, as the project progressed, two issues have arisen that greatly impact its future development:
- Some individuals have repackaged and sold it for profit.
- The name and icon of ChatGPT could potentially lead to infringement disputes.
## Live Demo
- [ChatGPT Desktop Application v1.0.0](https://youtu.be/IIuuB5vFFAQ)
- [ChatGPT automatically performs the "Continue generating" button, freeing up your hands.](https://youtu.be/bbL5cPmiGig)
## 📦 Install ## 📦 Install
- [📝 Update Log](./UPDATE_LOG.md) - [📝 Update Log](./UPDATE_LOG.md)
@ -32,7 +39,7 @@
### Windows ### Windows
- [ChatGPT_1.0.0_windows_x86_64.msi](https://github.com/lencx/ChatGPT/releases/download/v1.0.0/ChatGPT_1.0.0_windows_x86_64.msi): Direct download installer - [ChatGPT_1.1.0_windows_x86_64.msi](https://github.com/lencx/ChatGPT/releases/download/v1.1.0/ChatGPT_1.1.0_windows_x86_64.msi): Direct download installer
- Use [winget](https://winstall.app/apps/lencx.ChatGPT): - Use [winget](https://winstall.app/apps/lencx.ChatGPT):
```bash ```bash
@ -40,15 +47,15 @@
winget install --id=lencx.ChatGPT -e winget install --id=lencx.ChatGPT -e
# install the specified version # install the specified version
winget install --id=lencx.ChatGPT -e --version 0.10.0 winget install --id=lencx.ChatGPT -e --version 1.1.0
``` ```
**Note: If the installation path and application name are the same, it will lead to conflict ([#142](https://github.com/lencx/ChatGPT/issues/142))** **Note: If the installation path and application name are the same, it will lead to conflict ([#142](https://github.com/lencx/ChatGPT/issues/142))**
### Mac ### Mac
- [ChatGPT_1.0.0_macos_aarch64.dmg](https://github.com/lencx/ChatGPT/releases/download/v1.0.0/ChatGPT_1.0.0_macos_aarch64.dmg): Direct download installer - [ChatGPT_1.1.0_macos_aarch64.dmg](https://github.com/lencx/ChatGPT/releases/download/v1.1.0/ChatGPT_1.1.0_macos_aarch64.dmg): Direct download installer
- [ChatGPT_1.0.0_macos_x86_64.dmg](https://github.com/lencx/ChatGPT/releases/download/v1.0.0/ChatGPT_1.0.0_macos_x86_64.dmg): Direct download installer - [ChatGPT_1.1.0_macos_x86_64.dmg](https://github.com/lencx/ChatGPT/releases/download/v1.1.0/ChatGPT_1.1.0_macos_x86_64.dmg): Direct download installer
- Homebrew \ - Homebrew \
Or you can install with _[Homebrew](https://brew.sh) ([Cask](https://docs.brew.sh/Cask-Cookbook)):_ Or you can install with _[Homebrew](https://brew.sh) ([Cask](https://docs.brew.sh/Cask-Cookbook)):_
```sh ```sh
@ -70,8 +77,8 @@ sudo xattr -r -d com.apple.quarantine /YOUR_PATH/ChatGPT.app
### Linux ### Linux
- [ChatGPT_1.0.0_linux_x86_64.deb](https://github.com/lencx/ChatGPT/releases/download/v1.0.0/ChatGPT_1.0.0_linux_x86_64.deb): Download `.deb` installer, advantage small size, disadvantage poor compatibility - [ChatGPT_1.1.0_linux_x86_64.deb](https://github.com/lencx/ChatGPT/releases/download/v1.1.0/ChatGPT_1.1.0_linux_x86_64.deb): Download `.deb` installer, advantage small size, disadvantage poor compatibility
- [ChatGPT_1.0.0_linux_x86_64.AppImage.tar.gz](https://github.com/lencx/ChatGPT/releases/download/v1.0.0/ChatGPT_1.0.0_linux_x86_64.AppImage.tar.gz): Works reliably, you can try it if `.deb` fails to run - [ChatGPT_1.1.0_linux_x86_64.AppImage.tar.gz](https://github.com/lencx/ChatGPT/releases/download/v1.1.0/ChatGPT_1.1.0_linux_x86_64.AppImage.tar.gz): Works reliably, you can try it if `.deb` fails to run
<!-- tr-download-end --> <!-- tr-download-end -->
@ -94,12 +101,6 @@ You can look at **[awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt
- Customize global shortcuts ([#108](https://github.com/lencx/ChatGPT/issues/108)) - Customize global shortcuts ([#108](https://github.com/lencx/ChatGPT/issues/108))
- Pop-up Search ([#122](https://github.com/lencx/ChatGPT/issues/122) mouse selected content, no more than 400 characters): The application is built using Tauri, and due to its security restrictions, some of the action buttons will not work, so we recommend going to your browser. - Pop-up Search ([#122](https://github.com/lencx/ChatGPT/issues/122) mouse selected content, no more than 400 characters): The application is built using Tauri, and due to its security restrictions, some of the action buttons will not work, so we recommend going to your browser.
## ❤️ Sponsors
### **ChatGPT-Powered Email Finding & Outreach at Scale**
[FinalScout](https://finalscout.com/?utm_source=github&utm_medium=lencx&utm_campaign=chatgpt): Extract valid email addresses from LinkedIn & craft tailored emails based on LinkedIn profile with ChatGPT, guaranteeing up to 98% email deliverability. Scale your outreach efforts and connect with potential customers or clients like never before. [Begin automating your email finding and writing process](https://finalscout.com/?utm_source=github&utm_medium=lencx&utm_campaign=chatgpt)
## Thanks ## Thanks
- The core implementation of the share button code was copied from the [@liady](https://github.com/liady) extension with some modifications. - The core implementation of the share button code was copied from the [@liady](https://github.com/liady) extension with some modifications.
@ -111,12 +112,15 @@ You can look at **[awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt
## 中国用户 ## 中国用户
> [!NOTE]
> **如果你喜欢 ChatGPT 桌面应用,也可以关注一下 [lencx/Noi](https://github.com/lencx/Noi),它是一个定制化的 AI 浏览器。这里有两篇使用文档,对 Noi 的理念和插件系统做了详细介绍:**
> - [Noi跨平台定制化浏览器最得力 AI 助手](https://mp.weixin.qq.com/s/dAN7LOw7mH609HdAyEvXfg)
> - [Noi插件介绍](https://mp.weixin.qq.com/s/M6gO6MdK5obCvs2LIBZA3w)
国内用户如果遇到使用问题或者想交流 ChatGPT 技巧,可以关注公众号“浮之静”,发送 “chat” 进群参与讨论。公众号会更新[《Tauri 系列》](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzIzNjE2NTI3NQ==&action=getalbum&album_id=2593843659863752704)文章,技术思考等等,如果对 tauri 开发应用感兴趣可以关注公众号后回复 “tauri” 进技术开发群(想私聊的也可以关注公众号,来添加微信)。开源不易,如果这个项目对你有帮助可以分享给更多人,或者微信扫码打赏。 国内用户如果遇到使用问题或者想交流 ChatGPT 技巧,可以关注公众号“浮之静”,发送 “chat” 进群参与讨论。公众号会更新[《Tauri 系列》](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzIzNjE2NTI3NQ==&action=getalbum&album_id=2593843659863752704)文章,技术思考等等,如果对 tauri 开发应用感兴趣可以关注公众号后回复 “tauri” 进技术开发群(想私聊的也可以关注公众号,来添加微信)。开源不易,如果这个项目对你有帮助可以分享给更多人,或者微信扫码打赏。
<img width="180" src="https://user-images.githubusercontent.com/16164244/207228300-ea5c4688-c916-4c55-a8c3-7f862888f351.png"> <img width="200" src="https://user-images.githubusercontent.com/16164244/207228025-117b5f77-c5d2-48c2-a070-774b7a1596f2.png"> <img width="180" src="https://user-images.githubusercontent.com/16164244/207228300-ea5c4688-c916-4c55-a8c3-7f862888f351.png"> <img width="200" src="https://user-images.githubusercontent.com/16164244/207228025-117b5f77-c5d2-48c2-a070-774b7a1596f2.png">
<a href="https://t.zsxq.com/0bQikmcVw"><img width="360" src="./assets/zsxq.png"></a>
## License ## License
AGPL-3.0 License AGPL-3.0 License

View File

@ -1,11 +1,5 @@
# UPDATE LOG # UPDATE LOG
**🛑 URGENT NOTICE: A hacker has been found to take advantage of the heat of `lencx/ChatGPT` to plant a Trojan horse after the fork project and rebuild the installer. If you have friends around you who are using this desktop application, please remind them not to download unknown links freely. Now the project will remove other installation ways and only provide this download link https://github.com/lencx/ChatGPT/releases**
**🛑 紧急通知:目前发现有黑客利用 `lencx/ChatGPT` 的热度,在 fork 项目后植入木马,重新构建安装程序。如果你身边有朋友正在使用此桌面应用,请提醒 TA 们不要随意下载不明链接。现在项目将删除其他安装途径,仅提供此下载链接 https://github.com/lencx/ChatGPT/releases**
---
**It is an unofficial project intended for personal learning and research purposes only. During the time that the ChatGPT desktop application was open-sourced, it received a lot of attention, and I would like to thank everyone for their support. However, as things have developed, there are two issues that seriously affect the project's next development plan:** **It is an unofficial project intended for personal learning and research purposes only. During the time that the ChatGPT desktop application was open-sourced, it received a lot of attention, and I would like to thank everyone for their support. However, as things have developed, there are two issues that seriously affect the project's next development plan:**
- **Some people have used it for repackaging and selling for profit.** - **Some people have used it for repackaging and selling for profit.**
@ -13,6 +7,13 @@
**New repository: https://github.com/lencx/nofwl** **New repository: https://github.com/lencx/nofwl**
## v1.1.0
Fix:
- Fixed the issue where the cmd slash command does not work in some cases.
- Moved the export button to the sidebar to prevent layout conflicts.
## v1.0.0 ## v1.0.0
Note: This version modifies some configuration files. It is recommended to backup the `~/.chatgpt` folder in advance to avoid loss of important configurations. Note: This version modifies some configuration files. It is recommended to backup the `~/.chatgpt` folder in advance to avoid loss of important configurations.

View File

@ -1,9 +1,9 @@
cask "chatgpt" do cask "chatgpt" do
version "0.12.0" version "1.1.0"
arch = Hardware::CPU.arch.to_s arch = Hardware::CPU.arch.to_s
sha256s = { sha256s = {
"x86_64" => "d7f32d11f86ad8ac073dd451452124324e1c9154c318f15b77b5cd254000a3c4", "x86_64" => "6747e61a507402fa4b36db443c37a79299a4e1d4ba9904298a0b00c3e6a243b6",
"aarch64" => "c4c10eeb4a2c9a885da13047340372f461d411711c20472fc673fbf958bf6378" "aarch64" => "f870ba135ad990715474cbb038b5b38acb8d08640803e2c79c878e210f4800f6"
} }
if arch == "arm64" then arch = "aarch64" end if arch == "arm64" then arch = "aarch64" end
url "https://github.com/lencx/ChatGPT/releases/download/v#{version}/ChatGPT_#{version}_macos_#{arch}.dmg" url "https://github.com/lencx/ChatGPT/releases/download/v#{version}/ChatGPT_#{version}_macos_#{arch}.dmg"

44
scripts/chat.js vendored
View File

@ -1,6 +1,6 @@
/** /**
* @name chat.js * @name chat.js
* @version 0.1.0 * @version 0.1.4
* @url https://github.com/lencx/ChatGPT/tree/main/scripts/chat.js * @url https://github.com/lencx/ChatGPT/tree/main/scripts/chat.js
*/ */
@ -25,6 +25,7 @@ function chatInit() {
}); });
document.addEventListener('visibilitychange', focusOnInput); document.addEventListener('visibilitychange', focusOnInput);
autoContinue();
} }
function observeMutations(mutationsList) { function observeMutations(mutationsList) {
@ -115,11 +116,42 @@ function chatInit() {
}; };
} }
function autoContinue() {
// Create an instance of the observer
const observer = new MutationObserver((mutationsList) => {
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
const btn = Array.from(mutation.target.querySelectorAll('button.btn')).find((btn) =>
btn.innerText.includes('Continue generating'),
);
if (btn) {
console.log("Found the button of 'Continue generating'");
setTimeout(() => {
console.log('Clicked it to continue generating after 1 second');
btn.click();
}, 1000);
return;
}
}
}
});
// Wait until the form exists
const interval = setInterval(() => {
if (document.forms[0]) {
// Start observing the dom change of the form
observer.observe(document.forms[0], {
attributes: false,
childList: true,
subtree: true,
});
clearInterval(interval); // Stop checking when the form exists
}
}, 1000);
}
init(); init();
} }
if (document.readyState === 'complete' || document.readyState === 'interactive') { document.addEventListener('DOMContentLoaded', chatInit);
chatInit();
} else {
document.addEventListener('DOMContentLoaded', chatInit);
}

61
scripts/cmd.js vendored
View File

@ -1,6 +1,6 @@
/** /**
* @name cmd.js * @name cmd.js
* @version 0.1.0 * @version 0.1.2
* @url https://github.com/lencx/ChatGPT/tree/main/scripts/cmd.js * @url https://github.com/lencx/ChatGPT/tree/main/scripts/cmd.js
*/ */
@ -72,24 +72,12 @@ function cmdInit() {
color: #888; color: #888;
} }
.chatappico { .chatappico {
width: 20px; width: 1rem;
height: 20px; height: 1rem;
} }
.chatappico.pdf, .chatappico.md { .chatappico.png {
width: 22px; width: 0.8rem;
height: 22px; height: 0.9rem;
}
.chatappico.copy {
width: 16px;
height: 16px;
}
.chatappico.cpok {
width: 16px;
height: 16px;
}
.chatappico.refresh {
width: 22px;
height: 22px;
} }
#download-markdown-button, #download-markdown-button,
#download-png-button, #download-png-button,
@ -134,6 +122,32 @@ function cmdInit() {
} }
}); });
} }
if (mutation.type === 'childList' && mutation.removedNodes.length) {
for (let node of mutation.removedNodes) {
if (node.querySelector('form textarea')) {
initDom();
cmdTip();
(async function () {
async function platform() {
return invoke('platform', {
__tauriModule: 'Os',
message: { cmd: 'platform' },
});
}
if (__TAURI_METADATA__.__currentWindow.label !== 'tray') {
const _platform = await platform();
const chatConf = (await invoke('get_app_conf')) || {};
if (/darwin/.test(_platform) && !chatConf.titlebar) {
const nav = document.body.querySelector('nav');
if (nav) {
nav.style.paddingTop = '25px';
}
}
}
})();
}
}
}
} }
}).observe(document.body, { }).observe(document.body, {
childList: true, childList: true,
@ -159,8 +173,17 @@ function cmdInit() {
promptDom.style.bottom = '54px'; promptDom.style.bottom = '54px';
} }
const convertToSafeHtml = (v) => {
return JSON.stringify(v, null, 2)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
};
const itemDom = (v) => const itemDom = (v) =>
`<div class="cmd-item" title="${v.prompt}" data-cmd="${ `<div class="cmd-item" title="${convertToSafeHtml(v.prompt)}" data-cmd="${
v.cmd v.cmd
}" data-prompt="${encodeURIComponent(v.prompt)}"><b title="${v.cmd}">/${v.cmd}</b><i>${ }" data-prompt="${encodeURIComponent(v.prompt)}"><b title="${v.cmd}">/${v.cmd}</b><i>${
v.act v.act

24
scripts/core.js vendored
View File

@ -1,6 +1,6 @@
/** /**
* @name core.js * @name core.js
* @version 0.1.0 * @version 0.1.2
* @url https://github.com/lencx/ChatGPT/tree/main/scripts/core.js * @url https://github.com/lencx/ChatGPT/tree/main/scripts/core.js
*/ */
@ -84,21 +84,13 @@ function coreInit() {
document.body.appendChild(topDom); document.body.appendChild(topDom);
if (window.location.host === 'chat.openai.com') { if (window.location.host === 'chat.openai.com') {
const nav = document.body.querySelector('nav'); const intervalId = setInterval(function () {
if (nav) { const nav = document.body.querySelector('nav');
const currentPaddingTop = parseInt( if (nav) {
window nav.style.paddingTop = '25px';
.getComputedStyle(document.querySelector('nav'), null) clearInterval(intervalId);
.getPropertyValue('padding-top') }
.replace('px', ''), }, 1000);
10,
);
const navStyleDom = document.createElement('style');
navStyleDom.innerHTML = `nav{padding-top:${
currentPaddingTop + topDom.clientHeight
}px !important}`;
document.head.appendChild(navStyleDom);
}
} }
topDom.addEventListener('mousedown', () => invoke('drag_window')); topDom.addEventListener('mousedown', () => invoke('drag_window'));

309
scripts/export.js vendored
View File

@ -1,180 +1,68 @@
/** /**
* @name export.js * @name export.js
* @version 0.1.0 * @version 0.1.5
* @url https://github.com/lencx/ChatGPT/tree/main/scripts/export.js * @url https://github.com/lencx/ChatGPT/tree/main/scripts/export.js
*/ */
async function exportInit() { async function exportInit() {
if (window.location.pathname === '/auth/login') return; const SELECTOR = 'main div.group';
const buttonOuterHTMLFallback = `<button class="btn flex justify-center gap-2 btn-neutral">Try Again</button>`; const USER_INPUT_SELECTOR = 'div.empty\\:hidden';
removeButtons();
if (window.buttonsInterval) {
clearInterval(window.buttonsInterval);
}
if (window.innerWidth < 767) return;
const chatConf = (await invoke('get_app_conf')) || {};
window.buttonsInterval = setInterval(() => {
const actionsArea = document.querySelector('form>div>div>div');
const hasBtn = document.querySelector('form>div>div>div button');
if (!actionsArea || !hasBtn) {
return;
}
if (shouldAddButtons(actionsArea)) {
let TryAgainButton = actionsArea.querySelector('button');
if (!TryAgainButton) {
const parentNode = document.createElement('div');
parentNode.innerHTML = buttonOuterHTMLFallback;
TryAgainButton = parentNode.querySelector('button');
}
addActionsButtons(actionsArea, TryAgainButton, chatConf);
} else if (shouldRemoveButtons()) {
removeButtons();
}
}, 1000);
const Format = { const Format = {
PNG: 'png', PNG: 'png',
PDF: 'pdf', PDF: 'pdf',
}; };
function shouldRemoveButtons() { function processNode(node, replaceInUserInput = false) {
if (document.querySelector('form .text-2xl')) { let j = node.cloneNode(true);
return true; if (/dark\:bg-gray-800/.test(node.getAttribute('class'))) {
} j.innerHTML = `<blockquote>${node.innerHTML}</blockquote>`;
return false;
}
function shouldAddButtons(actionsArea) {
// first, check if there's a "Try Again" button and no other buttons
const buttons = actionsArea.querySelectorAll('button');
const hasTryAgainButton = Array.from(buttons).some((button) => {
return !/download-/.test(button.id);
});
const stopBtn = buttons?.[0]?.innerText;
if (/Stop generating/gi.test(stopBtn)) {
return false;
} }
if ( if (replaceInUserInput) {
buttons.length === 2 && const userInputBlocks = j.querySelectorAll(USER_INPUT_SELECTOR);
(/Regenerate response/gi.test(stopBtn) || buttons[1].innerText === '') userInputBlocks.forEach((block) => {
) { //For quicker testing use js fiddle: https://jsfiddle.net/xtraeme/x34ao9jp/13/
return true; block.innerHTML = block.innerHTML
.replace(/&nbsp;|\u00A0/g, ' ') //Replace =C2=A0 (nbsp non-breaking space) /w breaking-space
.replace(/\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;') // Replace tab with 4 non-breaking spaces
.replace(/^ +/gm, function (match) {
return '&nbsp;'.repeat(match.length);
}) //Add =C2=A0
.replace(/\n/g, '<br/>');
});
} }
if (hasTryAgainButton && buttons.length === 1) { return j.innerHTML;
return true;
}
// otherwise, check if open screen is not visible
const isOpenScreen = document.querySelector('h1.text-4xl');
if (isOpenScreen) {
return false;
}
// check if the conversation is finished and there are no share buttons
const finishedConversation = document.querySelector('form button>svg');
const hasShareButtons = actionsArea.querySelectorAll('button[share-ext]');
if (finishedConversation && !hasShareButtons.length) {
return true;
}
return false;
}
function removeButtons() {
const downloadPngButton = document.getElementById('download-png-button');
const downloadPdfButton = document.getElementById('download-pdf-button');
const downloadMdButton = document.getElementById('download-markdown-button');
const refreshButton = document.getElementById('refresh-page-button');
if (downloadPngButton) {
downloadPngButton.remove();
}
if (downloadPdfButton) {
downloadPdfButton.remove();
}
if (downloadPdfButton) {
downloadMdButton.remove();
}
if (refreshButton) {
refreshButton.remove();
}
}
function addActionsButtons(actionsArea, TryAgainButton) {
// Export markdown
const exportMd = TryAgainButton.cloneNode(true);
exportMd.id = 'download-markdown-button';
exportMd.setAttribute('share-ext', 'true');
exportMd.title = 'Export Markdown';
exportMd.innerHTML = setIcon('md');
exportMd.onclick = () => {
exportMarkdown();
};
actionsArea.appendChild(exportMd);
// Generate PNG
const downloadPngButton = TryAgainButton.cloneNode(true);
downloadPngButton.id = 'download-png-button';
downloadPngButton.setAttribute('share-ext', 'true');
downloadPngButton.title = 'Generate PNG';
downloadPngButton.innerHTML = setIcon('png');
downloadPngButton.onclick = () => {
downloadThread();
};
actionsArea.appendChild(downloadPngButton);
// Generate PDF
const downloadPdfButton = TryAgainButton.cloneNode(true);
downloadPdfButton.id = 'download-pdf-button';
downloadPdfButton.setAttribute('share-ext', 'true');
downloadPdfButton.title = 'Download PDF';
downloadPdfButton.innerHTML = setIcon('pdf');
downloadPdfButton.onclick = () => {
downloadThread({ as: Format.PDF });
};
actionsArea.appendChild(downloadPdfButton);
// Refresh
const refreshButton = TryAgainButton.cloneNode(true);
refreshButton.id = 'refresh-page-button';
refreshButton.title = 'Refresh the Page';
refreshButton.innerHTML = setIcon('refresh');
refreshButton.onclick = () => {
window.location.reload();
};
actionsArea.appendChild(refreshButton);
} }
async function exportMarkdown() { async function exportMarkdown() {
const content = Array.from(document.querySelectorAll('main div.group')) const allBlocks = document.querySelectorAll(SELECTOR);
.map((i) => { const nodes = Array.from(allBlocks);
let j = i.cloneNode(true);
if (/dark\:bg-gray-800/.test(i.getAttribute('class'))) { //<code> blocks with leading spaces mess up ExportMD markdown conversion. ex/
j.innerHTML = `<blockquote>${i.innerHTML}</blockquote>`; // <code ...> import package
} //becomes (spaces are moved to the front of the ''' line)):
return j.innerHTML; // '''Python import package
}) //so we remove whitespace after <code> tags and add <br/> and/or \n
.join(''); allBlocks.forEach((block) => {
const data = ExportMD.turndown(content); block.innerHTML = block.innerHTML.replace(/(<code[^>]*>)\s*/g, '$1<br\\/>\n'); // Add \n or <br/> after opening code tag
});
const updatedContent = nodes.map((i) => processNode(i, true)).join('');
const data = ExportMD.turndown(updatedContent);
const { id, filename } = getName(); const { id, filename } = getName();
await invoke('save_file', { name: `notes/${id}.md`, content: data }); await invoke('save_file', { name: `notes/${id}.md`, content: data });
await invoke('download_list', { pathname: 'chat.notes.json', filename, id, dir: 'notes' }); await invoke('download_list', { pathname: 'chat.notes.json', filename, id, dir: 'notes' });
} }
async function downloadThread({ asF = Format.PNG } = {}) { async function downloadThread({ as = Format.PNG } = {}) {
const { startLoading, stopLoading } = new window.__LoadingMask('Exporting in progress...'); const { startLoading, stopLoading } = new window.__LoadingMask('Exporting in progress...');
startLoading(); startLoading();
const elements = new Elements(); const elements = new Elements();
await elements.fixLocation(); await elements.fixLocation();
const pixelRatio = window.devicePixelRatio; const pixelRatio = window.devicePixelRatio;
const minRatio = asF === Format.PDF ? 2 : 2.5; const minRatio = as === Format.PDF ? 2 : 2.5;
window.devicePixelRatio = Math.max(pixelRatio, minRatio); window.devicePixelRatio = Math.max(pixelRatio, minRatio);
html2canvas(elements.thread, { html2canvas(elements.thread, {
@ -185,7 +73,7 @@ async function exportInit() {
window.devicePixelRatio = pixelRatio; window.devicePixelRatio = pixelRatio;
const imgData = canvas.toDataURL('image/png'); const imgData = canvas.toDataURL('image/png');
requestAnimationFrame(async () => { requestAnimationFrame(async () => {
if (asF === Format.PDF) { if (as === Format.PDF) {
await handlePdf(imgData, canvas, pixelRatio); await handlePdf(imgData, canvas, pixelRatio);
} else { } else {
await handleImg(imgData); await handleImg(imgData);
@ -267,11 +155,13 @@ async function exportInit() {
const chatImagePromises = this.chatImages.map(async (img) => { const chatImagePromises = this.chatImages.map(async (img) => {
const src = img.getAttribute('src'); const src = img.getAttribute('src');
if (!/^http/.test(src)) return; if (!/^http/.test(src)) return;
if (['fileserviceuploadsperm.blob.core.windows.net'].includes(new URL(src)?.host)) return;
const data = await invoke('fetch_image', { url: src }); const data = await invoke('fetch_image', { url: src });
const blob = new Blob([new Uint8Array(data)], { type: 'image/png' }); const blob = new Blob([new Uint8Array(data)], { type: 'image/png' });
img.src = URL.createObjectURL(blob); img.src = URL.createObjectURL(blob);
}); });
await Promise.all(chatImagePromises); await Promise.all(chatImagePromises);
document.body.style.lineHeight = '0.5';
} }
async restoreLocation() { async restoreLocation() {
this.hiddens.forEach((el) => { this.hiddens.forEach((el) => {
@ -286,15 +176,6 @@ async function exportInit() {
} }
} }
function setIcon(type) {
return {
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>`,
md: `<svg class="chatappico md" viewBox="0 0 1024 1024" width="200" height="200"><path d="M128 128h768a42.666667 42.666667 0 0 1 42.666667 42.666667v682.666666a42.666667 42.666667 0 0 1-42.666667 42.666667H128a42.666667 42.666667 0 0 1-42.666667-42.666667V170.666667a42.666667 42.666667 0 0 1 42.666667-42.666667z m170.666667 533.333333v-170.666666l85.333333 85.333333 85.333333-85.333333v170.666666h85.333334v-298.666666h-85.333334l-85.333333 85.333333-85.333333-85.333333H213.333333v298.666666h85.333334z m469.333333-128v-170.666666h-85.333333v170.666666h-85.333334l128 128 128-128h-85.333333z" p-id="1381" fill="currentColor"></path></svg>`,
refresh: `<svg class="chatappico refresh" viewBox="0 0 1024 1024"><path d="M512 63.5C264.3 63.5 63.5 264.3 63.5 512S264.3 960.5 512 960.5 960.5 759.7 960.5 512 759.7 63.5 512 63.5zM198 509.6h87.6c0-136.3 102.3-243.4 233.7-238.5 43.8 0 82.8 14.6 121.7 34.1L597.2 349c-24.4-9.8-53.6-19.5-82.8-19.5-92.5 0-170.4 77.9-170.4 180.1h87.6L314.8 631.3 198 509.6z m540.3-0.1c0 131.4-102.2 243.4-228.8 243.4-43.8 0-82.8-19.4-121.7-38.9l43.8-43.8c24.4 9.8 53.6 19.5 82.8 19.5 92.5 0 170.4-77.9 170.4-180.1h-92.5l116.9-121.7L826 509.5h-87.7z" fill="currentColor"></path></svg>`,
}[type];
}
function formatDateTime() { function formatDateTime() {
const now = new Date(); const now = new Date();
const year = now.getFullYear(); const year = now.getFullYear();
@ -307,15 +188,119 @@ async function exportInit() {
return formattedDateTime; return formattedDateTime;
} }
// function sanitizeFilename(filename) {
// if (!filename || filename === '') return '';
// // Replace whitespaces with underscores
// let sanitizedFilename = filename.replace(/\s/g, '_');
// // Replace invalid filename characters with #
// const invalidCharsRegex = /[<>:"/\\|?*\x00-\x1F]/g;
// sanitizedFilename = sanitizedFilename.replace(invalidCharsRegex, '#');
// // Check for filenames ending with period or space (Windows)
// if (sanitizedFilename && /[\s.]$/.test(sanitizedFilename)) {
// sanitizedFilename = sanitizedFilename.slice(0, -1) + '#';
// }
// //console.log(sanitizedFilename);
// return sanitizedFilename;
// }
function btnInit() {
const intervalId = setInterval(function () {
const navActionArea = document.querySelector('nav .border-t > div');
const addArea = document.querySelector('#chatgpt-nav-action-area');
if (!navActionArea || addArea) return;
const cloneNode = document.createElement('div');
cloneNode.id = 'chatgpt-nav-action-area';
cloneNode.classList = `${navActionArea.className} border-b border-white/20 mb-2 pb-2`;
cloneNode.appendChild(addBtn('png'));
cloneNode.appendChild(addBtn('pdf'));
cloneNode.appendChild(addBtn('md'));
cloneNode.appendChild(addBtn('refresh'));
navActionArea.parentNode.insertBefore(cloneNode, navActionArea);
clearInterval(intervalId);
function debounce(func, wait) {
let timeout;
return function () {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args);
}, wait);
};
}
const target = document.querySelector('nav');
const debouncedFunction = debounce(function () {
btnInit();
}, 300);
const observer = new MutationObserver(debouncedFunction);
const config = { attributes: true, childList: true, characterData: true, subtree: true };
observer.observe(target, config);
}, 1000);
}
function addBtn(type) {
const btn = document.createElement('button');
btn.className = `btn dark:text-gray-500 hover:dark:text-gray-300`;
btn.title = {
png: 'Export PNG',
pdf: 'Export PDF',
md: 'Export Markdown',
refresh: 'Refresh the Page',
}[type];
btn.innerHTML = setIcon(type);
btn.onclick = () => {
const content = document.querySelector('main .group');
if (!content && type !== 'refresh') {
alert('Please open a thread first.');
return;
}
switch (type) {
case 'png':
downloadThread();
break;
case 'pdf':
downloadThread({ as: 'pdf' });
break;
case 'md':
exportMarkdown();
break;
case 'refresh':
window.location.reload();
break;
default:
break;
}
};
return btn;
}
function setIcon(type) {
return {
png: `<svg class="chatappico png" viewBox="0 0 1024 1024"><path d="M264.258065 338.580645c16.780387 0 31.281548-6.144 43.536516-18.398968 12.254968-12.221935 18.398968-26.756129 18.398967-43.536516s-6.144-31.281548-18.398967-43.536516A59.524129 59.524129 0 0 0 264.258065 214.709677c-16.780387 0-31.281548 6.144-43.536517 18.398968-12.254968 12.221935-18.398968 26.756129-18.398967 43.536516s6.144 31.281548 18.398967 43.536516c12.221935 12.254968 26.756129 18.398968 43.536517 18.398968zM883.612903 28.903226H140.387097a119.345548 119.345548 0 0 0-87.568516 36.302451A119.345548 119.345548 0 0 0 16.516129 152.774194v743.225806c0 34.188387 12.089806 63.388903 36.302452 87.568516a119.345548 119.345548 0 0 0 87.568516 36.302452h743.225806a119.345548 119.345548 0 0 0 87.568516-36.302452A119.345548 119.345548 0 0 0 1007.483871 896v-743.225806a119.345548 119.345548 0 0 0-36.302452-87.568517A119.345548 119.345548 0 0 0 883.612903 28.903226zM264.258065 152.774194c34.188387 0 63.388903 12.089806 87.568516 36.302451a119.345548 119.345548 0 0 1 36.302451 87.568516 119.345548 119.345548 0 0 1-36.302451 87.568516A119.345548 119.345548 0 0 1 264.258065 400.516129a119.345548 119.345548 0 0 1-87.568517-36.302452A119.345548 119.345548 0 0 1 140.387097 276.645161c0-34.188387 12.089806-63.388903 36.302451-87.568516A119.345548 119.345548 0 0 1 264.258065 152.774194zM140.387097 957.935484c-16.780387 0-31.281548-6.144-43.536516-18.398968a59.524129 59.524129 0 0 1-18.398968-43.536516v-29.035355l245.793032-220.655484L635.870968 957.935484h-495.483871z m805.16129-61.935484c0 16.780387-6.144 31.281548-18.398968 43.536516-12.221935 12.254968-26.756129 18.398968-43.536516 18.398968h-159.677935l-228.385033-231.291871L759.741935 462.451613l185.806452 185.806452v247.741935z" 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>`,
md: `<svg class="chatappico md" viewBox="0 0 1024 1024"><path d="M128 128h768a42.666667 42.666667 0 0 1 42.666667 42.666667v682.666666a42.666667 42.666667 0 0 1-42.666667 42.666667H128a42.666667 42.666667 0 0 1-42.666667-42.666667V170.666667a42.666667 42.666667 0 0 1 42.666667-42.666667z m170.666667 533.333333v-170.666666l85.333333 85.333333 85.333333-85.333333v170.666666h85.333334v-298.666666h-85.333334l-85.333333 85.333333-85.333333-85.333333H213.333333v298.666666h85.333334z m469.333333-128v-170.666666h-85.333333v170.666666h-85.333334l128 128 128-128h-85.333333z" fill="currentColor"></path></svg>`,
refresh: `<svg class="chatappico refresh" viewBox="0 0 1024 1024"><path d="M512 63.5C264.3 63.5 63.5 264.3 63.5 512S264.3 960.5 512 960.5 960.5 759.7 960.5 512 759.7 63.5 512 63.5zM198 509.6h87.6c0-136.3 102.3-243.4 233.7-238.5 43.8 0 82.8 14.6 121.7 34.1L597.2 349c-24.4-9.8-53.6-19.5-82.8-19.5-92.5 0-170.4 77.9-170.4 180.1h87.6L314.8 631.3 198 509.6z m540.3-0.1c0 131.4-102.2 243.4-228.8 243.4-43.8 0-82.8-19.4-121.7-38.9l43.8-43.8c24.4 9.8 53.6 19.5 82.8 19.5 92.5 0 170.4-77.9 170.4-180.1h-92.5l116.9-121.7L826 509.5h-87.7z" fill="currentColor"></path></svg>`,
}[type];
}
function getName() { function getName() {
const id = window.crypto.getRandomValues(new Uint32Array(1))[0].toString(36); const id = window.crypto.getRandomValues(new Uint32Array(1))[0].toString(36);
const name = const name =
document.querySelector('nav .overflow-y-auto a.hover\\:bg-gray-800')?.innerText?.trim() || ''; document.querySelector('nav .overflow-y-auto a.hover\\:bg-gray-800')?.innerText?.trim() || '';
return { filename: name ? name : id, id, pathname: 'chat.download.json' }; // clean_name = sanitizeFilename(name);
return {
id,
filename: name ? name : id,
pathname: 'chat.download.json',
};
} }
}
window.addEventListener('resize', exportInit); btnInit();
}
if (document.readyState === 'complete' || document.readyState === 'interactive') { if (document.readyState === 'complete' || document.readyState === 'interactive') {
exportInit(); exportInit();

View File

@ -5,20 +5,16 @@
"url": "https://github.com/lencx/ChatGPT/tree/main/scripts", "url": "https://github.com/lencx/ChatGPT/tree/main/scripts",
"scripts": [ "scripts": [
{ {
"name": "core.js", "name": "chat.js",
"version": "0.1.0" "version": "0.1.4"
}, },
{ {
"name": "cmd.js", "name": "cmd.js",
"version": "0.1.0" "version": "0.1.2"
},
{
"name": "chat.js",
"version": "0.1.0"
}, },
{ {
"name": "core.js", "name": "core.js",
"version": "0.1.0" "version": "0.1.2"
}, },
{ {
"name": "dalle2.js", "name": "dalle2.js",
@ -26,7 +22,7 @@
}, },
{ {
"name": "export.js", "name": "export.js",
"version": "0.1.0" "version": "0.1.5"
}, },
{ {
"name": "markdown.export.js", "name": "markdown.export.js",

View File

@ -26,7 +26,7 @@ dark-light = "1.0.0"
wry = "0.*" wry = "0.*"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.23.0", features = ["macros"] } tokio = { version = "1.23.0", features = ["macros"] }
tauri = { version = "1.3.0", features = ["devtools", "fs-create-dir", "fs-exists", "fs-read-dir", "fs-read-file", "fs-remove-dir", "fs-remove-file", "fs-write-file", "global-shortcut", "global-shortcut-all", "os-all", "path-all", "process-all", "shell-all", "shell-open-api", "system-tray", "updater"] } tauri = { version = "1.3.0", features = ["devtools", "dialog-all", "fs-create-dir", "fs-exists", "fs-read-dir", "fs-read-file", "fs-remove-dir", "fs-remove-file", "fs-write-file", "global-shortcut", "global-shortcut-all", "os-all", "path-all", "process-all", "shell-all", "shell-open-api", "system-tray", "updater"] }
tauri-plugin-positioner = { git = "https://github.com/lencx/tauri-plugins-workspace", features = ["system-tray"] } tauri-plugin-positioner = { git = "https://github.com/lencx/tauri-plugins-workspace", features = ["system-tray"] }
tauri-plugin-log = { git = "https://github.com/lencx/tauri-plugins-workspace", branch = "dev", features = ["colored"] } tauri-plugin-log = { git = "https://github.com/lencx/tauri-plugins-workspace", branch = "dev", features = ["colored"] }
tauri-plugin-autostart = { git = "https://github.com/lencx/tauri-plugins-workspace", branch = "dev" } tauri-plugin-autostart = { git = "https://github.com/lencx/tauri-plugins-workspace", branch = "dev" }

View File

@ -102,7 +102,9 @@ pub fn init(app: &mut App) -> Result<(), Box<dyn std::error::Error>> {
.initialization_script(&load_script("chat.js")) .initialization_script(&load_script("chat.js"))
} }
main_win.build().unwrap(); if let Err(err) = main_win.build() {
error!("core_build_error: {}", err);
}
}); });
} }

View File

@ -7,7 +7,7 @@
}, },
"package": { "package": {
"productName": "ChatGPT", "productName": "ChatGPT",
"version": "1.0.0" "version": "1.1.0"
}, },
"tauri": { "tauri": {
"allowlist": { "allowlist": {
@ -38,6 +38,9 @@
"os": { "os": {
"all": true "all": true
}, },
"dialog": {
"all": true
},
"process": { "process": {
"all": true, "all": true,
"exit": true, "exit": true,

View File

@ -40,8 +40,7 @@ const AboutChatGPT = () => {
<p> <p>
It is just a wrapper for the It is just a wrapper for the
<a href="https://chat.openai.com" target="_blank" title="https://chat.openai.com"> <a href="https://chat.openai.com" target="_blank" title="https://chat.openai.com">
{' '} OpenAI ChatGPT
OpenAI ChatGPT{' '}
</a> </a>
website, no other data transfer exists (you can check the{' '} website, no other data transfer exists (you can check the{' '}
<a <a
@ -49,8 +48,7 @@ const AboutChatGPT = () => {
target="_blank" target="_blank"
title="https://github.com/lencx/ChatGPT" title="https://github.com/lencx/ChatGPT"
> >
{' '} source code
source code{' '}
</a> </a>
). The development and maintenance of this software has taken up a lot of my time. If it ). The development and maintenance of this software has taken up a lot of my time. If it
helps you, you can buy me a cup of coffee (Chinese users can use WeChat to scan the code), helps you, you can buy me a cup of coffee (Chinese users can use WeChat to scan the code),
@ -62,7 +60,7 @@ const AboutChatGPT = () => {
src="https://cdn.buymeacoffee.com/buttons/v2/default-blue.png" src="https://cdn.buymeacoffee.com/buttons/v2/default-blue.png"
alt="Buy Me A Coffee" alt="Buy Me A Coffee"
/> />
</a>{' '} </a>
<br /> <br />
<img <img
width="200" width="200"