diff --git a/.editorconfig b/.editorconfig index 8759d9b..259fb8e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,7 +10,7 @@ trim_trailing_whitespace = true insert_final_newline = true # Use 4 spaces for Python, Rust and Bash files -[*.{py,rs,sh,md}] +[*.{py,rs,sh}] indent_size = 4 # Makefiles always use tabs for indentation @@ -22,3 +22,6 @@ indent_size = 2 [*.md] trim_trailing_whitespace = false + +[*.ts] +quote_type= "single" diff --git a/.github/workflows/pake_build.yaml b/.github/workflows/pake_build.yaml index 2cc3142..aac097d 100644 --- a/.github/workflows/pake_build.yaml +++ b/.github/workflows/pake_build.yaml @@ -4,6 +4,7 @@ on: # Sequence of patterns matched against refs/tags tags: - "V*" + workflow_dispatch: jobs: build: @@ -48,7 +49,7 @@ jobs: if: matrix.os == 'ubuntu-latest' run: | 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 webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf gnome-video-effects gnome-video-effects-extra - name: build for Ubuntu if: matrix.os == 'ubuntu-latest' @@ -77,9 +78,15 @@ jobs: # files: | # output/*/*.* - - uses: ncipollo/release-action@v1 - if: startsWith(github.ref, 'refs/tags/v') - with: - allowUpdates: true - artifacts: "output/*/*.*" - token: ${{ secrets.GITHUB_TOKEN }} + # - uses: ncipollo/release-action@v1 + # if: startsWith(github.ref, 'refs/tags/v') + # with: + # allowUpdates: true + # artifacts: "output/*/*.*" + # token: ${{ secrets.GITHUB_TOKEN }} + - name: Upload files + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -L https://github.com/probonopd/uploadtool/raw/master/upload.sh --output upload.sh + bash upload.sh output/*/*.* diff --git a/.gitignore b/.gitignore index 6f8dd99..a6966ae 100644 --- a/.gitignore +++ b/.gitignore @@ -9,13 +9,10 @@ lerna-debug.log* node_modules dist-ssr -dist/cli.js *.local # Editor directories and files -.vscode/* -!.vscode/extensions.json -!.vscode/settings.json +.vscode .idea .DS_Store *.suo @@ -25,6 +22,10 @@ dist/cli.js *.sw? .npmrc output +*.msi +*.deb +*.AppImage +*.dmg package-lock.json yarn.lock diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index e23975b..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "cSpell.words": ["loglevel", "Pake", "tauri"], - "typescript.preferences.importModuleSpecifierEnding": "js" -} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f913e7b..4c58c4d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,11 +11,11 @@ graph LR ``` - `dev` branch - - `dev` is the developing branch. - - It's **RECOMMENDED** to commit feature PR to `dev`. + - `dev` is the developing branch. + - It's **RECOMMENDED** to commit feature PR to `dev`. - `master` branch - - `master` is the release branch, we will make tag and publish version on this branch. - - If it is a document modification, it can be submitted to this branch. + - `master` is the release branch, we will make tag and publish version on this branch. + - If it is a document modification, it can be submitted to this branch. ## Commit Log diff --git a/README.md b/README.md index 3e32e83..dabdc35 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@

中文 | English

+

Pake

@@ -14,29 +15,28 @@ GitHub closed issues
-
很简单的用 Rust 打包网页生成很小的桌面 App,支持 Mac / Windows / Linux 系统,常用包下载、命令行一键打包定制开发 可见下面文档,也欢迎去 讨论区 交流。
-

+
很简单的用 Rust 打包网页生成很小的桌面 App,支持 Mac / Windows / Linux 系统,常用包下载、命令行一键打包定制开发 可见下面文档,也欢迎去 讨论区 交流。
## 特征 -🏂 **小**:相比传统的 Electron 套壳打包,要小将近 40 倍,不到 3M -😂 **快**:Pake 的底层使用的 Rust Tauri 框架,性能体验较 JS 框架要轻快不少,内存小很多 -🩴 **特**:不是单纯打包,实现了快捷键的透传、沉浸式的窗口、拖动、样式改写、去广告、产品的极简风格定制 -🐶 **玩**:只是一个很简单的小玩具,用 Rust 替代之前套壳网页打包的老思路,其实 PWA 也很好 +🏂 **小**:相比传统的 Electron 套壳打包,要小将近 40 倍,不到 3M。 +😂 **快**:Pake 的底层使用的 Rust Tauri 框架,性能体验较 JS 框架要轻快不少,内存小很多。 +🩴 **特**:不是单纯打包,实现了快捷键的透传、沉浸式的窗口、拖动、样式改写、去广告、产品的极简风格定制。 +🐶 **玩**:只是一个很简单的小玩具,用 Rust 替代之前套壳网页打包的老思路,其实 PWA 也很好。 -## 下载 +## 常用包下载 @@ -44,79 +44,60 @@ - - + - - - + - - + - - - + +
WeRead Mac - Linux Windows + Linux Twitter Mac - Linux Windows + Linux
YouTube - Mac - Linux - Windows + LiZhi + Mac + Windows + Linux Reference - Mac - Linux - Windows + YouTube + Mac + Windows + Linux
Code Mac - Linux Windows + Linux Google Translate - Mac - Linux - Windows + Reference + Mac + Windows + Linux
Flomo - Mac - Linux - Windows +
Qwerty + Mac + Windows + Linux YuQue - Mac - Linux - Windows + ChatGPT + Mac + Windows + Linux
+
-注意:Windows 下不能安装到 `C:\Program File`,会直接闪退,建议安装到其他非管理员权限目录,比如 `D:\Program Files (x86)` 。 +🏂 更多应用如 Flomo / 语雀可去 Release下载,此外点击可展开快捷键说明 -## 命令行打包 - - - - -

- -**Pake 提供了命令行工具,可以更快捷方便地一键自定义打你需要的包,详细可见 [文档](./bin/README.md)。** - -```bash -// 使用 npm 进行安装 -npm install -g pake-cli - -// 命令使用 -pake url [options] - -// 随便玩玩,首次由于安装环境会有些慢,后面就快了 -pake https://weekly.tw93.fun --name Weekly --transparent -``` - -## 快捷键 +
| Mac | Windows/Linux | 功能 | | --------------------------- | ------------------------------ | ------------------ | @@ -131,49 +112,63 @@ pake https://weekly.tw93.fun --name Weekly --transparent | + = | Ctrl + = | 放大页面 | | + 0 | Ctrl + 0 | 重置页面缩放 | -此外还支持双击头部进行全屏切换,拖拽头部进行移动窗口,还有其他需求,欢迎提过来。 +此外还支持双击头部进行全屏切换,拖拽头部进行移动窗口,Mac 用户支持手势方式返回和去下一页,还有其他需求,欢迎提过来。 -## 开发 +
-开始前参考 [Tauri](https://tauri.app/v1/guides/getting-started/prerequisites#setting-up-macos) 快速配置好环境。 +## 开始之前 + +1. **小白用户**:使用 「常用包下载」 方式来把玩 Pake 的能力,可去 [讨论群](https://github.com/tw93/Pake/discussions) 寻求帮助,也可试试 [Action](https://github.com/tw93/Pake/wiki/GitHub-Actions-%E5%9C%A8%E7%BA%BF%E7%BC%96%E8%AF%91%E5%A4%9A%E7%B3%BB%E7%BB%9F%E7%89%88%E6%9C%AC) 方式。 +2. **开发用户**:使用 「命令行一键打包」,对 Mac 比较友好,Windows / Linux 需折腾下 [环境配置](https://tauri.app/v1/guides/getting-started/prerequisites)。 +3. **折腾用户**:假如你前端和 Rust 都会,那可试试下面的 「[定制开发](#定制开发)」,可深度二次开发定制你的功能。 + +## 命令行一键打包 + + + + +

+ +**Pake 提供了命令行工具,可以更快捷方便地一键自定义打你需要的包,详细可见 [文档](./bin/README.md)。** + +```bash +// 使用 npm 进行安装 +npm install -g pake-cli + +// 命令使用 +pake url [options] + +// 随便玩玩,首次由于安装环境会有些慢,后面就快了 +pake https://weekly.tw93.fun --name Weekly --transparent +``` + +假如你不太会使用命令行,或许使用 **GitHub Actions 在线编译多系统版本** 是一个不错的选择,可查看 [文档](https://github.com/tw93/Pake/wiki/GitHub-Actions-%E5%9C%A8%E7%BA%BF%E7%BC%96%E8%AF%91%E5%A4%9A%E7%B3%BB%E7%BB%9F%E7%89%88%E6%9C%AC)。 + +## 定制开发 + +开始前请确保电脑已经安装了 Rust 和 Node 的环境,此外需参考 [Tauri 文档](https://tauri.app/v1/guides/getting-started/prerequisites) 快速配置好环境才可以开始使用,假如你太不懂,使用上面的命令行打包会更加合适。 ```sh // 安装依赖 npm i -// 调试 +// 本地开发 npm run dev -// 打包 Mac 应用 +// 本地调试 +npm run dev:debug + +// 打包应用 npm run build -// 打包 Windows 应用 -npm run build:windows - -// 打包 Linux 应用 -npm run build:linux ``` -## 打新包 +## 高级使用 -1. 修改 `src-tauri` 目录下的 `tauri.conf.json` 中的 `url、productName、icon、identifier` 这 4 个字段,其中 icon 可以从 icons 目录选择一个,也可以去 [macOSicons](https://macosicons.com/#/) 下载符合产品名称的 -2. 关于窗口属性设置,可以在 `tauri.conf.json` 修改 `windows` 属性对应的 `width/height`,是否全屏 `fullscreen`,是否可以调整大小 `resizable`,假如想适配 Mac 沉浸式头部,可以将 `transparent` 设置成 `true`,找到 Header 元素加一个 `padding-top` 样式即可,不想适配改成 `false` 也行 -3. `npm run dev` 本地调试看看效果,此外可以使用 `npm run dev:debug` 进行容器调试 -4. `npm run build` 运行即可打生产包 - -## 高级用法 - -#### 1. 如何改写样式,如去掉原站广告、不想要的模块、甚至重新设计? - -首先需要使用 `npm run dev:debug` 打开 devtools 调试模式,找到你需要修改的样式名称,先在 devtools 里面验证效果;找到 `pake.js` 中样式位置 `style.innerHTML` ,将需要覆盖的样式加上即可,有一些案例你可以模仿。 - -#### 2. 如何注入 JS 的逻辑,比如实现事件监听,比如说键盘快捷键? - -参考 `pake.js` 中事件监听 `document.addEventListener`,直接编写即可,这里更多是基础前端的技术。 - -#### 3. 如何进行容器内的事件和 Pake 通信,比如说 Web 的拖拽、滚动、特殊点击传递啥的? - -参考 `pake.js` 中通信代码 `postMessage`,写好事件监听,然后用 `window.ipc.postMessage` 将事件以及参数传递出来,然后参考容器接收事件 `window.drag_window`,自己处理即可,更多可以参考 tauri 以及 wry 的官方文档。 +1. 代码结构可参考 [文档](https://github.com/tw93/Pake/wiki/Pake-%E7%9A%84%E4%BB%A3%E7%A0%81%E7%BB%93%E6%9E%84%E8%AF%B4%E6%98%8E),便于你在开发前了解更多。 +2. 修改 src-tauri 目录下的 `tauri.conf.json`以及 `tauri.xxx.conf.json` 中的 url、productName、icon、identifier 这 4 个字段,其中 icon 可以从 icons 目录选择一个,也可以去 [macOSicons](https://macosicons.com/#/) 下载符合效果的。 +3. 关于窗口属性设置,可以在 `tauri.conf.json` 修改 windows 属性对应的 `width/height`,fullscreen 是否全屏,resizable 是否可以调整大小,假如想适配 Mac 沉浸式头部,可以将 transparent 设置成 `true`,找到 Header 元素加一个 padding-top 样式即可,不想适配改成 `false` 也行。 +4. 此外样式改写、屏蔽广告、逻辑代码注入、容器消息通信、自定义快捷键可见 [高级用法](https://github.com/tw93/Pake/wiki/Pake-%E7%9A%84%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95)。 ## 开发者 @@ -203,6 +198,13 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢 Pan93412 + + + wanghanzhen +
+ Volare +
+ liby @@ -211,10 +213,10 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢 - - wanghanzhen + + essesoul
- Volare + Essesoul
@@ -223,22 +225,8 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢
Horus - - - - QingZ11 -
- Steam -
- - - 2nthony -
- 2nthony -
- AielloChan @@ -246,13 +234,49 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢 Aiello + + + QingZ11 +
+ Steam +
+ + + + 2nthony +
+ 2nthony +
+ + + + nekomeowww +
+ Ayaka Neko +
+ + + + turkyden +
+ Dengju Deng +
+ + + + princemaple +
+ Po Chen +
+ houhoz
Hyzhao
- + + liusishan @@ -272,11 +296,7 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢 ## 支持 -- 我有两只猫,一只叫汤圆,一只叫可乐,假如觉得 Pake 让你生活更美好,可以给汤圆可乐 喂罐头 🥩🍤。 -- 如果你喜欢 Pake,可以在 Github Star,更欢迎 [推荐](https://twitter.com/intent/tweet?url=https://github.com/tw93/Pake&text=Pake%20%E4%B8%80%E4%B8%AA%E5%BE%88%E7%AE%80%E5%8D%95%E7%9A%84%E7%94%A8%20Rust%20%E6%89%93%E5%8C%85%E7%BD%91%E9%A1%B5%E7%94%9F%E6%88%90%20Mac%20App%20%E7%9A%84%E5%B7%A5%E5%85%B7%EF%BC%8C%E7%9B%B8%E6%AF%94%E4%BC%A0%E7%BB%9F%E7%9A%84%20Electron%20%E5%A5%97%E5%A3%B3%E6%89%93%E5%8C%85%EF%BC%8C%E5%A4%A7%E5%B0%8F%E8%A6%81%E5%B0%8F%E5%B0%86%E8%BF%91%2040%20%E5%80%8D%EF%BC%8C%E4%B8%80%E8%88%AC%202M%20%E5%B7%A6%E5%8F%B3%EF%BC%8C%E5%BA%95%E5%B1%82%E4%BD%BF%E7%94%A8Tauri%20%EF%BC%8C%E6%80%A7%E8%83%BD%E4%BD%93%E9%AA%8C%E8%BE%83%20JS%20%E6%A1%86%E6%9E%B6%E8%A6%81%E8%BD%BB%E5%BF%AB%E4%B8%8D%E5%B0%91%EF%BC%8C%E5%86%85%E5%AD%98%E5%B0%8F%E5%BE%88%E5%A4%9A%EF%BC%8C%E6%94%AF%E6%8C%81%E5%BE%AE%E4%BF%A1%E8%AF%BB%E4%B9%A6%E3%80%81Twitter%E3%80%81Youtube%E3%80%81RunCode%E3%80%81Flomo%E3%80%81%E8%AF%AD%E9%9B%80%E7%AD%89%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%BE%88%E6%96%B9%E4%BE%BF%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91~) 给你志同道合的朋友使用。 -- 可以关注我的 [Twitter](https://twitter.com/HiTw93) 获取到最新的 Pake 更新消息,也欢迎加入 [Telegram](https://t.me/miaoyan) 聊天群。 - -## 最后 - -1. 希望大伙玩的过程中有一种学习新技术的喜悦感,如果有新点子欢迎告诉我 -2. 假如你发现有很适合做成桌面 App 的网页也很欢迎告诉我,我给加到里面来 +1. 我有两只猫,一只叫汤圆,一只叫可乐,假如觉得 Pake 让你生活更美好,可以给汤圆可乐 喂罐头 🥩🍤。 +2. 如果你喜欢 Pake,可以在 Github Star,更欢迎 [推荐](https://twitter.com/intent/tweet?url=https://github.com/tw93/Pake&text=%23Pake%20%E4%B8%80%E4%B8%AA%E5%BE%88%E7%AE%80%E5%8D%95%E7%9A%84%E7%94%A8%20Rust%20%E6%89%93%E5%8C%85%E7%BD%91%E9%A1%B5%E7%94%9F%E6%88%90%20Mac%20App%20%E7%9A%84%E5%B7%A5%E5%85%B7%EF%BC%8C%E7%9B%B8%E6%AF%94%E4%BC%A0%E7%BB%9F%E7%9A%84%20Electron%20%E5%A5%97%E5%A3%B3%E6%89%93%E5%8C%85%EF%BC%8C%E5%A4%A7%E5%B0%8F%E8%A6%81%E5%B0%8F%E5%B0%86%E8%BF%91%2040%20%E5%80%8D%EF%BC%8C%E4%B8%80%E8%88%AC%202M%20%E5%B7%A6%E5%8F%B3%EF%BC%8C%E5%BA%95%E5%B1%82%E4%BD%BF%E7%94%A8Tauri%20%EF%BC%8C%E6%80%A7%E8%83%BD%E4%BD%93%E9%AA%8C%E8%BE%83%20JS%20%E6%A1%86%E6%9E%B6%E8%A6%81%E8%BD%BB%E5%BF%AB%E4%B8%8D%E5%B0%91%EF%BC%8C%E5%86%85%E5%AD%98%E5%B0%8F%E5%BE%88%E5%A4%9A%EF%BC%8C%E6%94%AF%E6%8C%81%E5%BE%AE%E4%BF%A1%E8%AF%BB%E4%B9%A6%E3%80%81Twitter%E3%80%81Youtube%E3%80%81RunCode%E3%80%81Flomo%E3%80%81%E8%AF%AD%E9%9B%80%E7%AD%89%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%BE%88%E6%96%B9%E4%BE%BF%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91~) 给你志同道合的朋友使用。 +3. 可以关注我的 [Twitter](https://twitter.com/HiTw93) 获取到最新的 Pake 更新消息,也欢迎加入 [Telegram](https://t.me/miaoyan) 聊天群。 +4. 希望大伙玩的过程中有一种学习新技术的喜悦感,假如你发现有很适合做成桌面 App 的网页也很欢迎告诉我。 diff --git a/README_EN.md b/README_EN.md index 0317182..97096e2 100644 --- a/README_EN.md +++ b/README_EN.md @@ -1,6 +1,7 @@

中文 | English

+

Pake

@@ -14,8 +15,7 @@ GitHub closed issues
-
A simple way to package a web page to desktop application, supporting Mac / Windows / Linux, app download、command line one-click packaging、custom development can be found in the following documents, welcome to Discussions to see if there have anything you interesting.
-

+
A simple way to package a web page to desktop application, supporting Mac / Windows / Linux, app download、command line one-click packaging、custom development can be found in the following documents, welcome to Discussions to see if there have anything you're interesting.
## Features @@ -30,13 +30,13 @@ WeRead Mac - Linux Windows + Linux Twitter Mac - Linux Windows + Linux @@ -44,58 +44,59 @@ - YouTube + LiZhi + Mac + Windows + Linux + + YouTube Mac - Linux Windows - - Reference - Mac - Linux - Windows + Linux + - - Code - Mac - Linux - Windows - - Google Translate - Mac - Linux - Windows - + Code + Mac + Windows + Linux + + Reference + Mac + Windows + Linux + - - + + - Flomo - Mac - Linux - Windows - - YuQue - Mac - Linux - Windows - + Qwerty + Mac + Windows + Linux + + ChatGPT + Mac + Windows + Linux + - - + + -Note: it cannot be installed to C:\Program File under Windows, and it will crash directly. It is recommended to install to other non-administrator directories, such as D:\Program Files (x86). +
+🏂 Expand the shortcut key -## Shortcuts +
| Mac | Windows/Linux | Function | | --------------------------- | ------------------------------ | ----------------------------- | @@ -110,11 +111,41 @@ Note: it cannot be installed to C:\Program File under Windows, and it will crash | + = | Ctrl + = | Zoom in the Page | | + 0 | Ctrl + 0 | Reset the page zoom | -In addition, it supports double clicking the head to switch to full screen, and dragging the head to move the window +In addition, it supports double-clicking the head to switch to full screen, Mac users support gesture mode to return and go to the next page, and dragging the head to move the window. + +
+ +## Before you start + +1. **Beginner users**: Use the 「Download」 method to play with Pake's capabilities, go to discussion groups for help, or try the [Action](https://github.com/tw93/Pake/wiki/GitHub-Actions-Online-Compilation-Multi-system-Version) method. +2. **Development users**: Use 「command line packing」, Mac friendly, Windows/Linux requires a bit of tinkering, but both require environment [configuration](https://tauri.app/v1/guides/getting-started/prerequisites). +3. **Hacker users**: If you know both front-end and rust, try the following custom development, which allows you to customize your features with deep secondary development. + +## Command line packing + + + + +

+ +**Pake provides a command line tool that makes it quicker and easier to customize the packages you need, as detailed in [documentation](./.github/workflows/docs/README_EN.md).** + +```bash +// Install with npm +npm install -g pake-cli + +// Command usage +pake url [options] + +// Play casually, first time due to the installation environment will be a little slow +pake https://weekly.tw93.fun --name Weekly --transparent +``` + +If you are a little white who doesn't know how to use the command line, a good option is to use **GitHub Actions online compilation**, see the [tutorial](https://github.com/tw93/Pake/wiki/GitHub-Actions-Online-Compilation-Multi-system-Version). ## Development -Refer to the [Tauri documentation](https://tauri.app/v1/guides/getting-started/prerequisites#setting-up-macos) to quickly configure your environment before you start. +Before starting, make sure that the computer has installed the Rust and Node environment,refer to the [Tauri documentation](https://tauri.app/v1/guides/getting-started/prerequisites) to quickly configure your environment before you start. If you don't understand, it will be more appropriate to use the above command line to pack with one click. ```sh // Install Dependencies @@ -123,53 +154,24 @@ npm i // Local development npm run dev -// Pack Mac application +// Local debug +npm run dev:debug + +// Pack application npm run build -// Pack Windows application -npm run build:windows - -// Pack Linux application -npm run build:linux - -// One-click packaging of all Linux/Mac projects -chmod +x build.sh && ./build.sh - -// One-click packaging of all Windows projects -.\build.bat ``` -// Package all your projects in one click -chmod +x build.sh && ./build.sh +## Advanced use -## New pack - -1. Modify the `tauri.conf.json` in the `src-tauri` directory to include 4 fields `url, productName, icon, identifier`, icon can be selected from the `icons` directory or downloaded from [macOSicons](https://macosicons.com/#/) to match the product. -2. For window property settings, you can modify the `width/height` of the `windows` property in `tauri.conf.json`, whether it is `fullscreen`, whether it is `resizable`, If you want to adapt the immersive header under Mac, you can set `transparent` to `true` and then find header element and add the `padding-top` style. -3. `npm run dev` for local debugging; `npm run dev:debug` to open the devtools for container debugging. -4. `npm run build` can be run to package for production. - -## Advanced - -#### 1. How do I rewrite the style, e.g. to remove ads from the original site, or even redesign it? - -First, open devtools debug mode with `npm run dev:debug`. After that, find the name of the style you want to change and verify the effect in devtools, and find the location of the style in `pake.js` with `style.innerHTML`. Finally, add the style you need to override, there are some examples you can copy. - -#### 2. How to inject js code, e.g. to implement event listeners, e.g. keyboard shortcuts? - -Refer to the event listener in `pake.js` with `document.addEventListener`, and write it directly, it's more of a basic front-end technique here. - -#### 3. How to communicate with Pake about events in containers, such as dragging and dropping, scrolling, special clicks on the Web, etc.? - -Refer to the communication code in `pake.js` with `postMessage`, write the event listener and then use `window.ipc.postMessage` to pass the event and its parameters, then refer to the container to receive events `window.drag_window` and handle them yourself, for more information, refer to tauri and wry's official documentation. +1. The code structure can be referred to [Here](https://github.com/tw93/Pake/wiki/Description-of-Pake's-code-structure), it is convenient for you to learn more before development. +2. Modify the `tauri.conf.json` and `tauri.xxx.conf.json` in the `src-tauri` directory to include 4 fields `url, productName, icon, identifier`, icon can be selected from the `icons` directory or downloaded from [macOSicons](https://macosicons.com/#/) to match the product. +3. For window property settings, you can modify the `width/height` of the `windows` property in `tauri.conf.json`, whether it is `fullscreen`, whether it is `resizable`, If you want to adapt the immersive header under Mac, you can set `transparent` to `true` and then find header element and add the `padding-top` style. +4. About style rewriting, advertising shielding, js injection, container message communication, and user-defined shortcut keys, you can see [Advanced Usage of Make](https://github.com/tw93/Pake/wiki/Advanced-Usage-of-Make). ## Support -- I have two cats, one is called TangYuan, and one is called Coke, If you think Pake makes your life better, you can give my cats feed canned food 🥩🍤. -- If you like Pake, you can star it in Github. We are more welcome to [recommend Pake](https://twitter.com/intent/tweet?url=https://github.com/tw93/Pake&text=Pake%20-%20A%20simple%20Rust%20packaged%20web%20pages%20to%20generate%20Mac%20App%20tool,%20compared%20to%20traditional%20Electron%20package,%20the%20size%20of%20nearly%2040%20times%20smaller,%20generally%20about%202M,%20the%20underlying%20use%20of%20Tauri,%20performance%20experience%20than%20the%20JS%20framework%20is%20much%20lighter~) to your like-minded friends. -- You can follow my [Twitter](https://twitter.com/HiTw93) to get the latest news of Pake, or join [Telegram](https://t.me/miaoyan) chat group. - -## Finally - -1. I hope that you will enjoy playing with it and let me know if you have any new ideas. -2. If you find a page that would be great for a Mac App, please let me know and I'll add it to the list. +1. I have two cats, one is called TangYuan, and one is called Coke, If you think Pake makes your life better, you can give my cats feed canned food 🥩🍤. +2. If you like Pake, you can star it in Github. Also welcome to [recommend Pake](https://twitter.com/intent/tweet?url=https://github.com/tw93/Pake&text=%23Pake%20-%20A%20simple%20Rust%20packaged%20web%20pages%20to%20generate%20Mac%20App%20tool,%20compared%20to%20traditional%20Electron%20package,%20the%20size%20of%20nearly%2040%20times%20smaller,%20generally%20about%202M,%20the%20underlying%20use%20of%20Tauri,%20performance%20experience%20than%20the%20JS%20framework%20is%20much%20lighter~) to your friends. +3. You can follow my [Twitter](https://twitter.com/HiTw93) to get the latest news of Pake, or join [Telegram](https://t.me/miaoyan) chat group. +4. I hope that you will enjoy playing with it. If you find a page that would be great for a Mac App, please let me know. diff --git a/app.csv b/app.csv index 81cb7e9..5da3cf1 100644 --- a/app.csv +++ b/app.csv @@ -1,9 +1,11 @@ name(Linux),name(Mac/Windows),name_zh,url twitter,Twitter,推特,https://twitter.com/ -translate,GoogleTranslate,谷歌翻译,https://translate.google.com/ youtube,YouTube,YouTube,https://youtube.com reference,Reference,Reference,https://wangchujiang.com/reference/index.html code,Code,Code,https://riju.codes/ yuque,YuQue,语雀,https://www.yuque.com/ -flomo,Flomo,浮墨,https://flomoapp.com/mine +chatgpt,ChatGPT,ChatGPT,https://chat.openai.com/chat +flomo,Flomo,浮墨,https://v.flomoapp.com/mine +qwerty,Qwerty,Qwerty,https://qwerty.kaiyi.cool/ +lizhi,LiZhi,李志,https://lizhi.turkyden.com/?from=pake weread,WeRead,微信阅读,https://weread.qq.com/ diff --git a/bin/README.md b/bin/README.md index 82b18ac..b6b8bc4 100644 --- a/bin/README.md +++ b/bin/README.md @@ -4,20 +4,23 @@ npm install -g pake-cli ``` -如果安装失败提示没有权限,请使用 `sudo` 运行。 +如果安装失败提示没有权限,请参考该贴解决:[链接](https://gist.github.com/Giancarlos/d087f8a9e6516716da98ad0c0f5a8f58)。 + +此外,请确保你使用的是正确的 Node.js 版本(`^14.13 || >=16.0.0`)。如果你在使用 [nvm](https://github.com/nvm-sh/nvm) 进行 Node.js 版本管理,可以尝试在项目的目录下运行 `nvm use`,就会拿到正确的版本;其他一众 Node.js 版本工具,比如 [fnm](https://github.com/Schniz/fnm)、[tj/n](https://github.com/tj/n) 应该也有类似的功能。 + +**尽量不要使用 `sudo` 权限**。 如果实在要用 sudo,请手动安装 rust 到系统环境。Mac 可以用 brew 命令安装,Linux 如 Ubuntu 可以用 apt 命令安装。 + ## 用法 ```bash -pake url [options] +pake url [options] ``` 打包完成后的应用程序默认为当前工作目录,首次打包由于需配置好环境,需要一些时间,请耐心等待即可。 Note: 打包需要用 `Rust` 环境,如果没有 `Rust`,会提示确认安装。如遇安装失败或超时,可[自行安装](https://www.rust-lang.org/tools/install)。 -Note: 目前仅支持 MacOs,后续会支持其他平台。 - ### url url 为你需要打包的网页链接 🔗,必须提供。 @@ -28,7 +31,7 @@ url 为你需要打包的网页链接 🔗,必须提供。 #### [name] -应用名称,如输入时未指定,会提示你输入。 +应用名称,如输入时未指定,会提示你输入,尽量使用英语。 ```shell --name @@ -36,9 +39,11 @@ url 为你需要打包的网页链接 🔗,必须提供。 #### [icon] -应用 icon,支持本地/远程文件,默认为 Pake 自带图标。 +应用 icon,支持本地/远程文件,默认为 Pake 自带图标,定制的可以去 [icon-icons](https://icon-icons.com) 或 [macOSicons](https://macosicons.com/#/) 搜索下载。 - MacOS 下必须为 `.icns` +- Windows 下必须为 `.ico` +- Linux 下必须为 `.png` ```shell --icon @@ -46,7 +51,7 @@ url 为你需要打包的网页链接 🔗,必须提供。 #### [height] -打包后的应用窗口高度,默认 `800px`。 +打包后的应用窗口高度,默认 `780px`。 ```shell --height @@ -54,7 +59,7 @@ url 为你需要打包的网页链接 🔗,必须提供。 #### [width] -打包后的应用窗口宽度,默认 `1280px`。 +打包后的应用窗口宽度,默认 `1200px`。 ```shell --width diff --git a/bin/README_EN.md b/bin/README_EN.md new file mode 100644 index 0000000..683e9d7 --- /dev/null +++ b/bin/README_EN.md @@ -0,0 +1,89 @@ +## Install + +```bash +npm install -g pake-cli +``` + +If the installation fails and you are prompted that you do not have permission, please see this [website](https://gist.github.com/Giancarlos/d087f8a9e6516716da98ad0c0f5a8f58) . + +Also make sure that you're using a correct Node.js version (`^14.13 || >=16.0.0`). If you're using [nvm](https://github.com/nvm-sh/nvm) for Node.js version management you may run `nvm use` from the root folder of the project and the correct version will be picked up. Other Node.js version management tools, such as [fnm](https://github.com/Schniz/fnm) and [tj/n](https://github.com/tj/n), should also have similar feature. + +**try not to use `sudo` permissions**, If you must use sudo, you need install rust in you system environment. For Mac, you can use brew to install it. For Linux like Ubuntu, you need apt to install it. + +## Usage + +```bash +pake url [options] +``` + +After the packaging, the application defaults to the current working directory. Since the environment needs to be configured for the first packaging, it will take some time. Please wait patiently. + +Note: The Rust environment is required for packaging. If you do not have Rust, you will be prompted to confirm the installation. If the installation fails or times out, you can [install](https://www.rust-lang.org/tools/install) it yourself. + +### url + +The url🔗 is the webpage link you need to package, Must be provided. + +### [options] + +Some specific options are provided. When packaging, corresponding parameters can be passed to achieve customized effects. + +#### [name] + +The application name, if not specified when entering, will prompt you to enter, input must be English. + +```shell +--name +``` + +#### [icon] + +The application icon, support local and remote files, the default is brand icon of Pake. Customized product icon can go to [icon icons](https://icon-icons.com) Or [macOSicons](https://macosicons.com/#/) download it. + +- MacOS must be `.icns` +- Windows must be `.ico` +- Linux must be `.png` + +```shell +--icon +``` + +#### [height] + +The height of the packaged application window. The default is `780px`. + +```shell +--height +``` + +#### [width] + +The width of the packaged application window. The default is `1200px`. + +```shell +--width +``` + +#### [transparent] + +Whether to enable the immersive header. The default is `false`. + +```shell +--transparent +``` + +#### [resize] + +Whether the size can be dragged. The default value is `true`. + +```shell +--no-resizable +``` + +#### [fullscreen] + +Whether to open the full screen after opening the application. The default is `false`. + +```shell +--fullscreen +``` diff --git a/bin/builders/BuilderFactory.ts b/bin/builders/BuilderFactory.ts index 18ec650..759ef70 100644 --- a/bin/builders/BuilderFactory.ts +++ b/bin/builders/BuilderFactory.ts @@ -1,12 +1,20 @@ -import { IS_MAC } from '@/utils/platform.js'; +import { IS_MAC, IS_WIN, IS_LINUX } from '@/utils/platform.js'; import { IBuilder } from './base.js'; import MacBuilder from './MacBuilder.js'; +import WinBuilder from './WinBulider.js'; +import LinuxBuilder from './LinuxBuilder.js'; export default class BuilderFactory { static create(): IBuilder { if (IS_MAC) { return new MacBuilder(); } - throw new Error('The current system does not support'); + if (IS_WIN) { + return new WinBuilder(); + } + if (IS_LINUX) { + return new LinuxBuilder(); + } + throw new Error('The current system does not support!!'); } } diff --git a/bin/builders/LinuxBuilder.ts b/bin/builders/LinuxBuilder.ts index e69de29..cec50b1 100644 --- a/bin/builders/LinuxBuilder.ts +++ b/bin/builders/LinuxBuilder.ts @@ -0,0 +1,81 @@ +import fs from 'fs/promises'; +import path from 'path'; +import prompts from 'prompts'; +import { checkRustInstalled, installRust } from '@/helpers/rust.js'; +import { PakeAppOptions } from '@/types.js'; +import { IBuilder } from './base.js'; +import { shellExec } from '@/utils/shell.js'; +// @ts-expect-error 加上resolveJsonModule rollup会打包报错 +// import tauriConf from '../../src-tauri/tauri.windows.conf.json'; +import tauriConf from './tauriConf.js'; + +import { fileURLToPath } from 'url'; +import logger from '@/options/logger.js'; +import { mergeTauriConfig } from './common.js'; +import { npmDirectory } from '@/utils/dir.js'; + +export default class LinuxBuilder implements IBuilder { + async prepare() { + logger.info( + 'To build the Linux app, you need to install Rust and Linux package' + ); + logger.info( + 'See more in https://tauri.app/v1/guides/getting-started/prerequisites#installing\n' + ); + if (checkRustInstalled()) { + return; + } + + const res = await prompts({ + type: 'confirm', + message: 'We detected that you have not installed Rust. Install it now?', + name: 'value', + }); + + if (res.value) { + // TODO 国内有可能会超时 + await installRust(); + } else { + logger.error('Error: Pake needs Rust to package your webapp!!!'); + process.exit(2); + } + } + + async build(url: string, options: PakeAppOptions) { + logger.debug('PakeAppOptions', options); + const { name } = options; + + await mergeTauriConfig(url, options, tauriConf); + const _ = await shellExec(`cd ${npmDirectory} && npm install && npm run build`); + let arch = ""; + if (process.arch === "x64") { + arch = "amd64"; + } else { + arch = process.arch; + } + const debName = `${name}_${tauriConf.package.version}_${arch}.deb`; + const appPath = this.getBuildedAppPath(npmDirectory, "deb", debName); + const distPath = path.resolve(`${name}.deb`); + await fs.copyFile(appPath, distPath); + await fs.unlink(appPath); + + + const appImageName = `${name}_${tauriConf.package.version}_${arch}.AppImage`; + const appImagePath = this.getBuildedAppPath(npmDirectory, "appimage", appImageName); + const distAppPath = path.resolve(`${name}.AppImage`); + await fs.copyFile(appImagePath, distAppPath); + await fs.unlink(appImagePath); + logger.success('Build success!'); + logger.success('You can find the deb app installer in', distPath); + logger.success('You can find the Appimage app installer in', distAppPath); + } + + getBuildedAppPath(npmDirectory: string,packageType: string, packageName: string) { + return path.join( + npmDirectory, + 'src-tauri/target/release/bundle/', + packageType, + packageName + ); + } +} \ No newline at end of file diff --git a/bin/builders/MacBuilder.ts b/bin/builders/MacBuilder.ts index b557cd9..8a5fdcb 100644 --- a/bin/builders/MacBuilder.ts +++ b/bin/builders/MacBuilder.ts @@ -6,9 +6,12 @@ import { PakeAppOptions } from '@/types.js'; import { IBuilder } from './base.js'; import { shellExec } from '@/utils/shell.js'; // @ts-expect-error 加上resolveJsonModule rollup会打包报错 -import tauriConf from '../../src-tauri/tauri.conf.json'; -import { fileURLToPath } from 'url'; +// import tauriConf from '../../src-tauri/tauri.macos.conf.json'; +import tauriConf from './tauriConf.js'; import log from 'loglevel'; +import { mergeTauriConfig } from './common.js'; +import { npmDirectory } from '@/utils/dir.js'; +import logger from '@/options/logger.js'; export default class MacBuilder implements IBuilder { async prepare() { @@ -33,34 +36,32 @@ export default class MacBuilder implements IBuilder { async build(url: string, options: PakeAppOptions) { log.debug('PakeAppOptions', options); + const { name } = options; - const { width, height, fullscreen, transparent, resizable, identifier, name } = options; + await mergeTauriConfig(url, options, tauriConf); - const tauriConfWindowOptions = { - width, - height, - fullscreen, - transparent, - resizable, - }; - - // TODO 下面这块逻辑还可以再拆 目前比较简单 - Object.assign(tauriConf.tauri.windows[0], { url, ...tauriConfWindowOptions }); - tauriConf.package.productName = name; - tauriConf.tauri.bundle.identifier = identifier; - tauriConf.tauri.bundle.icon = [options.icon]; - - const npmDirectory = path.join(path.dirname(fileURLToPath(import.meta.url)), '..'); - const configJsonPath = path.join(npmDirectory, 'src-tauri/tauri.conf.json'); - await fs.writeFile(configJsonPath, Buffer.from(JSON.stringify(tauriConf), 'utf-8')); - - const code = await shellExec(`cd ${npmDirectory} && npm run build`); - const dmgName = `${name}_${tauriConf.package.version}_universal.dmg`; + const _ = await shellExec(`cd ${npmDirectory} && npm install && npm run build`); + let arch = "x64"; + if (process.arch === "arm64") { + arch = "aarch64"; + } else { + arch = process.arch; + } + const dmgName = `${name}_${tauriConf.package.version}_${arch}.dmg`; const appPath = this.getBuildedAppPath(npmDirectory, dmgName); - await fs.copyFile(appPath, path.resolve(`${name}_universal.dmg`)); + const distPath = path.resolve(`${name}.dmg`); + await fs.copyFile(appPath, distPath); + await fs.unlink(appPath); + + logger.success('Build success!'); + logger.success('You can find the app installer in', distPath); } getBuildedAppPath(npmDirectory: string, dmgName: string) { - return path.join(npmDirectory, 'src-tauri/target/universal-apple-darwin/release/bundle/dmg', dmgName); + return path.join( + npmDirectory, + 'src-tauri/target/release/bundle/dmg', + dmgName + ); } } diff --git a/bin/builders/WinBulider.ts b/bin/builders/WinBulider.ts index e69de29..2ca2958 100644 --- a/bin/builders/WinBulider.ts +++ b/bin/builders/WinBulider.ts @@ -0,0 +1,69 @@ +import fs from 'fs/promises'; +import path from 'path'; +import prompts from 'prompts'; +import { checkRustInstalled, installRust } from '@/helpers/rust.js'; +import { PakeAppOptions } from '@/types.js'; +import { IBuilder } from './base.js'; +import { shellExec } from '@/utils/shell.js'; +// @ts-expect-error 加上resolveJsonModule rollup会打包报错 +// import tauriConf from '../../src-tauri/tauri.windows.conf.json'; +import tauriConf from './tauriConf.js'; + +import { fileURLToPath } from 'url'; +import logger from '@/options/logger.js'; +import { mergeTauriConfig } from './common.js'; +import { npmDirectory } from '@/utils/dir.js'; + +export default class WinBuilder implements IBuilder { + async prepare() { + logger.info( + 'To build the Windows app, you need to install Rust and VS Build Tools.' + ); + logger.info( + 'See more in https://tauri.app/v1/guides/getting-started/prerequisites#installing\n' + ); + if (checkRustInstalled()) { + return; + } + + const res = await prompts({ + type: 'confirm', + message: 'We detected that you have not installed Rust. Install it now?', + name: 'value', + }); + + if (res.value) { + // TODO 国内有可能会超时 + await installRust(); + } else { + logger.error('Error: Pake needs Rust to package your webapp!!!'); + process.exit(2); + } + } + + async build(url: string, options: PakeAppOptions) { + logger.debug('PakeAppOptions', options); + const { name } = options; + + await mergeTauriConfig(url, options, tauriConf); + + const _ = await shellExec(`cd ${npmDirectory} && npm install && npm run build`); + const language = tauriConf.tauri.bundle.windows.wix.language[0]; + const arch = process.arch; + const msiName = `${name}_${tauriConf.package.version}_${arch}_${language}.msi`; + const appPath = this.getBuildedAppPath(npmDirectory, msiName); + const distPath = path.resolve(`${name}.msi`); + await fs.copyFile(appPath, distPath); + await fs.unlink(appPath); + logger.success('Build success!'); + logger.success('You can find the app installer in', distPath); + } + + getBuildedAppPath(npmDirectory: string, dmgName: string) { + return path.join( + npmDirectory, + 'src-tauri/target/release/bundle/msi', + dmgName + ); + } +} diff --git a/bin/builders/common.ts b/bin/builders/common.ts index 6f881d6..b081e35 100644 --- a/bin/builders/common.ts +++ b/bin/builders/common.ts @@ -1,4 +1,9 @@ +import { PakeAppOptions } from '@/types.js'; import prompts from 'prompts'; +import path from 'path'; +import fs from 'fs/promises'; +import { npmDirectory } from '@/utils/dir.js'; +import logger from '@/options/logger.js'; export async function promptText(message: string, initial?: string) { const response = await prompts({ @@ -9,3 +14,97 @@ export async function promptText(message: string, initial?: string) { }); return response.content; } + +export async function mergeTauriConfig( + url: string, + options: PakeAppOptions, + tauriConf: any +) { + const { + width, + height, + fullscreen, + transparent, + resizable, + identifier, + name, + } = options; + + const tauriConfWindowOptions = { + width, + height, + fullscreen, + transparent, + resizable, + }; + + Object.assign(tauriConf.tauri.windows[0], { url, ...tauriConfWindowOptions }); + tauriConf.package.productName = name; + tauriConf.tauri.bundle.identifier = identifier; + const exists = await fs.stat(options.icon) + .then(() => true) + .catch(() => false); + if (exists) { + let updateIconPath = true; + let customIconExt = path.extname(options.icon).toLowerCase(); + if (process.platform === "win32") { + if (customIconExt === ".ico") { + const ico_path = path.join(npmDirectory, `src-tauri/png/${name.toLowerCase()}_32.ico`); + tauriConf.tauri.bundle.resources = [`png/${name.toLowerCase()}_32.ico`]; + await fs.copyFile(options.icon, ico_path); + } else { + updateIconPath = false; + logger.warn(`icon file in Windows must be 256 * 256 pix with .ico type, but you give ${customIconExt}`); + } + } + if (process.platform === "linux") { + delete tauriConf.tauri.bundle.deb.files; + if (customIconExt != ".png") { + updateIconPath = false; + logger.warn(`icon file in Linux must be 512 * 512 pix with .png type, but you give ${customIconExt}`); + } + } + + if (process.platform === "darwin" && customIconExt !== ".icns") { + updateIconPath = false; + logger.warn(`icon file in MacOS must be .icns type, but you give ${customIconExt}`); + } + if (updateIconPath) { + tauriConf.tauri.bundle.icon = [options.icon]; + } else { + logger.warn(`icon file will not change with default.`); + } + } else { + logger.warn("the custom icon path may not exists. we will use default icon to replace it"); + } + + + let configPath = ""; + switch (process.platform) { + case "win32": { + configPath = path.join(npmDirectory, 'src-tauri/tauri.windows.conf.json'); + break; + } + case "darwin": { + configPath = path.join(npmDirectory, 'src-tauri/tauri.macos.conf.json'); + break; + } + case "linux": { + configPath = path.join(npmDirectory, 'src-tauri/tauri.linux.conf.json'); + break; + } + } + + let bundleConf = {tauri: {bundle: tauriConf.tauri.bundle}}; + await fs.writeFile( + configPath, + Buffer.from(JSON.stringify(bundleConf), 'utf-8') + ); + + + const configJsonPath = path.join(npmDirectory, 'src-tauri/tauri.conf.json') + await fs.writeFile( + configJsonPath, + Buffer.from(JSON.stringify(tauriConf), 'utf-8') + ); +} diff --git a/bin/builders/tauriConf.js b/bin/builders/tauriConf.js new file mode 100644 index 0000000..2b5fd20 --- /dev/null +++ b/bin/builders/tauriConf.js @@ -0,0 +1,27 @@ +import CommonConf from '../../src-tauri/tauri.conf.json'; +import WinConf from '../../src-tauri/tauri.windows.conf.json'; +import MacConf from '../../src-tauri/tauri.macos.conf.json'; +import LinuxConf from '../../src-tauri/tauri.linux.conf.json'; + +let tauriConf = { + package: CommonConf.package, + tauri: CommonConf.tauri +} +switch (process.platform) { + case "win32": { + tauriConf.tauri.bundle = WinConf.tauri.bundle; + break; + } + case "darwin": { + tauriConf.tauri.bundle = MacConf.tauri.bundle; + break; + } + case "linux": { + tauriConf.tauri.bundle = LinuxConf.tauri.bundle; + break; + } +} + +export default tauriConf; + + diff --git a/bin/cli.ts b/bin/cli.ts index fddffdb..14a6d0e 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -1,16 +1,21 @@ import { program } from 'commander'; +import log from 'loglevel'; +import chalk from 'chalk'; import { DEFAULT_PAKE_OPTIONS } from './defaults.js'; import { PakeCliOptions } from './types.js'; import { validateNumberInput, validateUrlInput } from './utils/validate.js'; import handleInputOptions from './options/index.js'; import BuilderFactory from './builders/BuilderFactory.js'; -import log from 'loglevel'; +import { checkUpdateTips } from './helpers/updater.js'; +// @ts-expect-error +import packageJson from '../package.json'; +import logger from './options/logger.js'; -program.version('0.0.1').description('A cli application can package a web page to desktop application'); +program.version(packageJson.version).description('A cli application can package a web page to desktop application.'); program .showHelpAfterError() - .argument('', 'the web url you want to package', validateUrlInput) + .argument('[url]', 'the web url you want to package', validateUrlInput) .option('--name ', 'application name') .option('--icon ', 'application icon', DEFAULT_PAKE_OPTIONS.icon) .option('--height ', 'window height', validateNumberInput, DEFAULT_PAKE_OPTIONS.height) @@ -20,7 +25,14 @@ program .option('--transparent', 'transparent title bar', DEFAULT_PAKE_OPTIONS.transparent) .option('--debug', 'debug', DEFAULT_PAKE_OPTIONS.transparent) .action(async (url: string, options: PakeCliOptions) => { - log.setDefaultLevel('info') + checkUpdateTips(); + + if (!url) { + // 直接 pake 不需要出现url提示 + program.help(); + } + + log.setDefaultLevel('info'); if (options.debug) { log.setLevel('debug'); } diff --git a/bin/defaults.ts b/bin/defaults.ts index 5f808d2..fb5cbff 100644 --- a/bin/defaults.ts +++ b/bin/defaults.ts @@ -2,8 +2,8 @@ import { PakeCliOptions } from './types.js'; export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = { icon: '', - height: 800, - width: 1280, + height: 780, + width: 1200, fullscreen: false, resizable: true, transparent: false, diff --git a/bin/helpers/rust.ts b/bin/helpers/rust.ts index af9811c..a626818 100644 --- a/bin/helpers/rust.ts +++ b/bin/helpers/rust.ts @@ -1,12 +1,16 @@ +import { IS_WIN } from '@/utils/platform.js'; import ora from 'ora'; import shelljs from 'shelljs'; import { shellExec } from '../utils/shell.js'; -const InstallRustScript = "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y"; +const RustInstallScriptFocMac = + "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y"; +const RustInstallScriptForWin = 'winget install --id Rustlang.Rustup'; + export async function installRust() { const spinner = ora('Downloading Rust').start(); try { - await shellExec(InstallRustScript); + await shellExec(IS_WIN ? RustInstallScriptForWin : RustInstallScriptFocMac); spinner.succeed(); } catch (error) { console.error('install rust return code', error.message); diff --git a/bin/helpers/updater.ts b/bin/helpers/updater.ts new file mode 100644 index 0000000..a0948b7 --- /dev/null +++ b/bin/helpers/updater.ts @@ -0,0 +1,7 @@ +import updateNotifier from 'update-notifier'; +// @ts-expect-error +import packageJson from '../../package.json'; + +export async function checkUpdateTips() { + updateNotifier({ pkg: packageJson }).notify(); +} diff --git a/bin/options/icon.ts b/bin/options/icon.ts index 7e1c5d8..8aff0d6 100644 --- a/bin/options/icon.ts +++ b/bin/options/icon.ts @@ -4,8 +4,9 @@ import { PakeAppOptions } from '../types.js'; import { dir } from 'tmp-promise'; import path from 'path'; import fs from 'fs/promises'; -import { fileURLToPath } from 'url'; -import log from 'loglevel'; +import logger from './logger.js'; +import { npmDirectory } from '@/utils/dir.js'; +import { IS_LINUX, IS_WIN } from '@/utils/platform.js'; export async function handleIcon(options: PakeAppOptions, url: string) { if (options.icon) { @@ -16,14 +17,20 @@ export async function handleIcon(options: PakeAppOptions, url: string) { } } if (!options.icon) { - return inferIcon(options.name, url); + return getDefaultIcon(); } } -export async function inferIcon(name: string, url: string) { - log.info('You have not provided an app icon, use the default icon(can use --icon option to assign an icon)') - const npmDirectory = path.join(path.dirname(fileURLToPath(import.meta.url)), '..'); - return path.join(npmDirectory, 'pake-default.icns'); +export async function getDefaultIcon() { + logger.info('You have not provided an app icon, use the default icon.(use --icon option to assign an icon)') + let iconPath = 'src-tauri/icons/icon.icns'; + if (IS_WIN) { + iconPath = 'src-tauri/png/icon_256.ico'; + } else if (IS_LINUX) { + iconPath = 'src-tauri/png/icon_512.png'; + } + + return path.join(npmDirectory, iconPath); } // export async function getIconFromPageUrl(url: string) { diff --git a/bin/options/logger.ts b/bin/options/logger.ts new file mode 100644 index 0000000..da6cafa --- /dev/null +++ b/bin/options/logger.ts @@ -0,0 +1,22 @@ +import log from 'loglevel'; +import chalk from 'chalk'; + +const logger = { + info(...msg: any[]) { + log.info(...msg.map((m) => chalk.blue.bold(m))); + }, + debug(...msg: any[]) { + log.debug(...msg); + }, + error(...msg: any[]) { + log.error(...msg.map((m) => chalk.red.bold(m))); + }, + warn(...msg: any[]) { + log.info(...msg.map((m) => chalk.yellow.bold(m))); + }, + success(...msg: any[]) { + log.info(...msg.map((m) => chalk.green.bold(m))); + } +}; + +export default logger; diff --git a/bin/types.ts b/bin/types.ts index 30ce729..9610edb 100644 --- a/bin/types.ts +++ b/bin/types.ts @@ -5,10 +5,10 @@ export interface PakeCliOptions { /** 应用icon */ icon: string; - /** 应用窗口宽度,默认 1280px */ + /** 应用窗口宽度,默认 1200px */ width: number; - /** 应用窗口高度,默认 800px */ + /** 应用窗口高度,默认 780px */ height: number; /** 是否可以拖动,默认true */ diff --git a/bin/utils/dir.ts b/bin/utils/dir.ts new file mode 100644 index 0000000..76da5af --- /dev/null +++ b/bin/utils/dir.ts @@ -0,0 +1,8 @@ +import path from 'path'; +import { fileURLToPath } from 'url'; + + +export const npmDirectory = path.join( + path.dirname(fileURLToPath(import.meta.url)), + '..' +); diff --git a/dist/about_pake.html b/dist/about_pake.html new file mode 100644 index 0000000..e1655dd --- /dev/null +++ b/dist/about_pake.html @@ -0,0 +1,16 @@ + + + + + + Document + + +
Welcome from Pake!
+

version: 1.0.1

+ Project link
+ Discussions
+ Issues
+

LICENSE: MIT

+ + \ No newline at end of file diff --git a/dist/cli.js b/dist/cli.js new file mode 100644 index 0000000..0415c56 --- /dev/null +++ b/dist/cli.js @@ -0,0 +1,2302 @@ +import * as Commander from 'commander'; +import { program } from 'commander'; +import log from 'loglevel'; +import url, { fileURLToPath } from 'url'; +import isurl from 'is-url'; +import prompts from 'prompts'; +import path from 'path'; +import fs from 'fs/promises'; +import chalk from 'chalk'; +import crypto from 'crypto'; +import axios from 'axios'; +import { fileTypeFromBuffer } from 'file-type'; +import { dir } from 'tmp-promise'; +import ora from 'ora'; +import shelljs from 'shelljs'; +import updateNotifier from 'update-notifier'; + +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ + +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +const DEFAULT_PAKE_OPTIONS = { + icon: '', + height: 780, + width: 1200, + fullscreen: false, + resizable: true, + transparent: false, + debug: false, +}; + +const tlds = [ + "aaa", + "aarp", + "abarth", + "abb", + "abbott", + "abbvie", + "abc", + "able", + "abogado", + "abudhabi", + "ac", + "academy", + "accenture", + "accountant", + "accountants", + "aco", + "actor", + "ad", + "adac", + "ads", + "adult", + "ae", + "aeg", + "aero", + "aetna", + "af", + "afl", + "africa", + "ag", + "agakhan", + "agency", + "ai", + "aig", + "airbus", + "airforce", + "airtel", + "akdn", + "al", + "alfaromeo", + "alibaba", + "alipay", + "allfinanz", + "allstate", + "ally", + "alsace", + "alstom", + "am", + "amazon", + "americanexpress", + "americanfamily", + "amex", + "amfam", + "amica", + "amsterdam", + "analytics", + "android", + "anquan", + "anz", + "ao", + "aol", + "apartments", + "app", + "apple", + "aq", + "aquarelle", + "ar", + "arab", + "aramco", + "archi", + "army", + "arpa", + "art", + "arte", + "as", + "asda", + "asia", + "associates", + "at", + "athleta", + "attorney", + "au", + "auction", + "audi", + "audible", + "audio", + "auspost", + "author", + "auto", + "autos", + "avianca", + "aw", + "aws", + "ax", + "axa", + "az", + "azure", + "ba", + "baby", + "baidu", + "banamex", + "bananarepublic", + "band", + "bank", + "bar", + "barcelona", + "barclaycard", + "barclays", + "barefoot", + "bargains", + "baseball", + "basketball", + "bauhaus", + "bayern", + "bb", + "bbc", + "bbt", + "bbva", + "bcg", + "bcn", + "bd", + "be", + "beats", + "beauty", + "beer", + "bentley", + "berlin", + "best", + "bestbuy", + "bet", + "bf", + "bg", + "bh", + "bharti", + "bi", + "bible", + "bid", + "bike", + "bing", + "bingo", + "bio", + "biz", + "bj", + "black", + "blackfriday", + "blockbuster", + "blog", + "bloomberg", + "blue", + "bm", + "bms", + "bmw", + "bn", + "bnpparibas", + "bo", + "boats", + "boehringer", + "bofa", + "bom", + "bond", + "boo", + "book", + "booking", + "bosch", + "bostik", + "boston", + "bot", + "boutique", + "box", + "br", + "bradesco", + "bridgestone", + "broadway", + "broker", + "brother", + "brussels", + "bs", + "bt", + "build", + "builders", + "business", + "buy", + "buzz", + "bv", + "bw", + "by", + "bz", + "bzh", + "ca", + "cab", + "cafe", + "cal", + "call", + "calvinklein", + "cam", + "camera", + "camp", + "canon", + "capetown", + "capital", + "capitalone", + "car", + "caravan", + "cards", + "care", + "career", + "careers", + "cars", + "casa", + "case", + "cash", + "casino", + "cat", + "catering", + "catholic", + "cba", + "cbn", + "cbre", + "cbs", + "cc", + "cd", + "center", + "ceo", + "cern", + "cf", + "cfa", + "cfd", + "cg", + "ch", + "chanel", + "channel", + "charity", + "chase", + "chat", + "cheap", + "chintai", + "christmas", + "chrome", + "church", + "ci", + "cipriani", + "circle", + "cisco", + "citadel", + "citi", + "citic", + "city", + "cityeats", + "ck", + "cl", + "claims", + "cleaning", + "click", + "clinic", + "clinique", + "clothing", + "cloud", + "club", + "clubmed", + "cm", + "cn", + "co", + "coach", + "codes", + "coffee", + "college", + "cologne", + "com", + "comcast", + "commbank", + "community", + "company", + "compare", + "computer", + "comsec", + "condos", + "construction", + "consulting", + "contact", + "contractors", + "cooking", + "cookingchannel", + "cool", + "coop", + "corsica", + "country", + "coupon", + "coupons", + "courses", + "cpa", + "cr", + "credit", + "creditcard", + "creditunion", + "cricket", + "crown", + "crs", + "cruise", + "cruises", + "cu", + "cuisinella", + "cv", + "cw", + "cx", + "cy", + "cymru", + "cyou", + "cz", + "dabur", + "dad", + "dance", + "data", + "date", + "dating", + "datsun", + "day", + "dclk", + "dds", + "de", + "deal", + "dealer", + "deals", + "degree", + "delivery", + "dell", + "deloitte", + "delta", + "democrat", + "dental", + "dentist", + "desi", + "design", + "dev", + "dhl", + "diamonds", + "diet", + "digital", + "direct", + "directory", + "discount", + "discover", + "dish", + "diy", + "dj", + "dk", + "dm", + "dnp", + "do", + "docs", + "doctor", + "dog", + "domains", + "dot", + "download", + "drive", + "dtv", + "dubai", + "dunlop", + "dupont", + "durban", + "dvag", + "dvr", + "dz", + "earth", + "eat", + "ec", + "eco", + "edeka", + "edu", + "education", + "ee", + "eg", + "email", + "emerck", + "energy", + "engineer", + "engineering", + "enterprises", + "epson", + "equipment", + "er", + "ericsson", + "erni", + "es", + "esq", + "estate", + "et", + "etisalat", + "eu", + "eurovision", + "eus", + "events", + "exchange", + "expert", + "exposed", + "express", + "extraspace", + "fage", + "fail", + "fairwinds", + "faith", + "family", + "fan", + "fans", + "farm", + "farmers", + "fashion", + "fast", + "fedex", + "feedback", + "ferrari", + "ferrero", + "fi", + "fiat", + "fidelity", + "fido", + "film", + "final", + "finance", + "financial", + "fire", + "firestone", + "firmdale", + "fish", + "fishing", + "fit", + "fitness", + "fj", + "fk", + "flickr", + "flights", + "flir", + "florist", + "flowers", + "fly", + "fm", + "fo", + "foo", + "food", + "foodnetwork", + "football", + "ford", + "forex", + "forsale", + "forum", + "foundation", + "fox", + "fr", + "free", + "fresenius", + "frl", + "frogans", + "frontdoor", + "frontier", + "ftr", + "fujitsu", + "fun", + "fund", + "furniture", + "futbol", + "fyi", + "ga", + "gal", + "gallery", + "gallo", + "gallup", + "game", + "games", + "gap", + "garden", + "gay", + "gb", + "gbiz", + "gd", + "gdn", + "ge", + "gea", + "gent", + "genting", + "george", + "gf", + "gg", + "ggee", + "gh", + "gi", + "gift", + "gifts", + "gives", + "giving", + "gl", + "glass", + "gle", + "global", + "globo", + "gm", + "gmail", + "gmbh", + "gmo", + "gmx", + "gn", + "godaddy", + "gold", + "goldpoint", + "golf", + "goo", + "goodyear", + "goog", + "google", + "gop", + "got", + "gov", + "gp", + "gq", + "gr", + "grainger", + "graphics", + "gratis", + "green", + "gripe", + "grocery", + "group", + "gs", + "gt", + "gu", + "guardian", + "gucci", + "guge", + "guide", + "guitars", + "guru", + "gw", + "gy", + "hair", + "hamburg", + "hangout", + "haus", + "hbo", + "hdfc", + "hdfcbank", + "health", + "healthcare", + "help", + "helsinki", + "here", + "hermes", + "hgtv", + "hiphop", + "hisamitsu", + "hitachi", + "hiv", + "hk", + "hkt", + "hm", + "hn", + "hockey", + "holdings", + "holiday", + "homedepot", + "homegoods", + "homes", + "homesense", + "honda", + "horse", + "hospital", + "host", + "hosting", + "hot", + "hoteles", + "hotels", + "hotmail", + "house", + "how", + "hr", + "hsbc", + "ht", + "hu", + "hughes", + "hyatt", + "hyundai", + "ibm", + "icbc", + "ice", + "icu", + "id", + "ie", + "ieee", + "ifm", + "ikano", + "il", + "im", + "imamat", + "imdb", + "immo", + "immobilien", + "in", + "inc", + "industries", + "infiniti", + "info", + "ing", + "ink", + "institute", + "insurance", + "insure", + "int", + "international", + "intuit", + "investments", + "io", + "ipiranga", + "iq", + "ir", + "irish", + "is", + "ismaili", + "ist", + "istanbul", + "it", + "itau", + "itv", + "jaguar", + "java", + "jcb", + "je", + "jeep", + "jetzt", + "jewelry", + "jio", + "jll", + "jm", + "jmp", + "jnj", + "jo", + "jobs", + "joburg", + "jot", + "joy", + "jp", + "jpmorgan", + "jprs", + "juegos", + "juniper", + "kaufen", + "kddi", + "ke", + "kerryhotels", + "kerrylogistics", + "kerryproperties", + "kfh", + "kg", + "kh", + "ki", + "kia", + "kids", + "kim", + "kinder", + "kindle", + "kitchen", + "kiwi", + "km", + "kn", + "koeln", + "komatsu", + "kosher", + "kp", + "kpmg", + "kpn", + "kr", + "krd", + "kred", + "kuokgroup", + "kw", + "ky", + "kyoto", + "kz", + "la", + "lacaixa", + "lamborghini", + "lamer", + "lancaster", + "lancia", + "land", + "landrover", + "lanxess", + "lasalle", + "lat", + "latino", + "latrobe", + "law", + "lawyer", + "lb", + "lc", + "lds", + "lease", + "leclerc", + "lefrak", + "legal", + "lego", + "lexus", + "lgbt", + "li", + "lidl", + "life", + "lifeinsurance", + "lifestyle", + "lighting", + "like", + "lilly", + "limited", + "limo", + "lincoln", + "linde", + "link", + "lipsy", + "live", + "living", + "lk", + "llc", + "llp", + "loan", + "loans", + "locker", + "locus", + "loft", + "lol", + "london", + "lotte", + "lotto", + "love", + "lpl", + "lplfinancial", + "lr", + "ls", + "lt", + "ltd", + "ltda", + "lu", + "lundbeck", + "luxe", + "luxury", + "lv", + "ly", + "ma", + "macys", + "madrid", + "maif", + "maison", + "makeup", + "man", + "management", + "mango", + "map", + "market", + "marketing", + "markets", + "marriott", + "marshalls", + "maserati", + "mattel", + "mba", + "mc", + "mckinsey", + "md", + "me", + "med", + "media", + "meet", + "melbourne", + "meme", + "memorial", + "men", + "menu", + "merckmsd", + "mg", + "mh", + "miami", + "microsoft", + "mil", + "mini", + "mint", + "mit", + "mitsubishi", + "mk", + "ml", + "mlb", + "mls", + "mm", + "mma", + "mn", + "mo", + "mobi", + "mobile", + "moda", + "moe", + "moi", + "mom", + "monash", + "money", + "monster", + "mormon", + "mortgage", + "moscow", + "moto", + "motorcycles", + "mov", + "movie", + "mp", + "mq", + "mr", + "ms", + "msd", + "mt", + "mtn", + "mtr", + "mu", + "museum", + "music", + "mutual", + "mv", + "mw", + "mx", + "my", + "mz", + "na", + "nab", + "nagoya", + "name", + "natura", + "navy", + "nba", + "nc", + "ne", + "nec", + "net", + "netbank", + "netflix", + "network", + "neustar", + "new", + "news", + "next", + "nextdirect", + "nexus", + "nf", + "nfl", + "ng", + "ngo", + "nhk", + "ni", + "nico", + "nike", + "nikon", + "ninja", + "nissan", + "nissay", + "nl", + "no", + "nokia", + "northwesternmutual", + "norton", + "now", + "nowruz", + "nowtv", + "np", + "nr", + "nra", + "nrw", + "ntt", + "nu", + "nyc", + "nz", + "obi", + "observer", + "office", + "okinawa", + "olayan", + "olayangroup", + "oldnavy", + "ollo", + "om", + "omega", + "one", + "ong", + "onl", + "online", + "ooo", + "open", + "oracle", + "orange", + "org", + "organic", + "origins", + "osaka", + "otsuka", + "ott", + "ovh", + "pa", + "page", + "panasonic", + "paris", + "pars", + "partners", + "parts", + "party", + "passagens", + "pay", + "pccw", + "pe", + "pet", + "pf", + "pfizer", + "pg", + "ph", + "pharmacy", + "phd", + "philips", + "phone", + "photo", + "photography", + "photos", + "physio", + "pics", + "pictet", + "pictures", + "pid", + "pin", + "ping", + "pink", + "pioneer", + "pizza", + "pk", + "pl", + "place", + "play", + "playstation", + "plumbing", + "plus", + "pm", + "pn", + "pnc", + "pohl", + "poker", + "politie", + "porn", + "post", + "pr", + "pramerica", + "praxi", + "press", + "prime", + "pro", + "prod", + "productions", + "prof", + "progressive", + "promo", + "properties", + "property", + "protection", + "pru", + "prudential", + "ps", + "pt", + "pub", + "pw", + "pwc", + "py", + "qa", + "qpon", + "quebec", + "quest", + "racing", + "radio", + "re", + "read", + "realestate", + "realtor", + "realty", + "recipes", + "red", + "redstone", + "redumbrella", + "rehab", + "reise", + "reisen", + "reit", + "reliance", + "ren", + "rent", + "rentals", + "repair", + "report", + "republican", + "rest", + "restaurant", + "review", + "reviews", + "rexroth", + "rich", + "richardli", + "ricoh", + "ril", + "rio", + "rip", + "ro", + "rocher", + "rocks", + "rodeo", + "rogers", + "room", + "rs", + "rsvp", + "ru", + "rugby", + "ruhr", + "run", + "rw", + "rwe", + "ryukyu", + "sa", + "saarland", + "safe", + "safety", + "sakura", + "sale", + "salon", + "samsclub", + "samsung", + "sandvik", + "sandvikcoromant", + "sanofi", + "sap", + "sarl", + "sas", + "save", + "saxo", + "sb", + "sbi", + "sbs", + "sc", + "sca", + "scb", + "schaeffler", + "schmidt", + "scholarships", + "school", + "schule", + "schwarz", + "science", + "scot", + "sd", + "se", + "search", + "seat", + "secure", + "security", + "seek", + "select", + "sener", + "services", + "ses", + "seven", + "sew", + "sex", + "sexy", + "sfr", + "sg", + "sh", + "shangrila", + "sharp", + "shaw", + "shell", + "shia", + "shiksha", + "shoes", + "shop", + "shopping", + "shouji", + "show", + "showtime", + "si", + "silk", + "sina", + "singles", + "site", + "sj", + "sk", + "ski", + "skin", + "sky", + "skype", + "sl", + "sling", + "sm", + "smart", + "smile", + "sn", + "sncf", + "so", + "soccer", + "social", + "softbank", + "software", + "sohu", + "solar", + "solutions", + "song", + "sony", + "soy", + "spa", + "space", + "sport", + "spot", + "sr", + "srl", + "ss", + "st", + "stada", + "staples", + "star", + "statebank", + "statefarm", + "stc", + "stcgroup", + "stockholm", + "storage", + "store", + "stream", + "studio", + "study", + "style", + "su", + "sucks", + "supplies", + "supply", + "support", + "surf", + "surgery", + "suzuki", + "sv", + "swatch", + "swiss", + "sx", + "sy", + "sydney", + "systems", + "sz", + "tab", + "taipei", + "talk", + "taobao", + "target", + "tatamotors", + "tatar", + "tattoo", + "tax", + "taxi", + "tc", + "tci", + "td", + "tdk", + "team", + "tech", + "technology", + "tel", + "temasek", + "tennis", + "teva", + "tf", + "tg", + "th", + "thd", + "theater", + "theatre", + "tiaa", + "tickets", + "tienda", + "tiffany", + "tips", + "tires", + "tirol", + "tj", + "tjmaxx", + "tjx", + "tk", + "tkmaxx", + "tl", + "tm", + "tmall", + "tn", + "to", + "today", + "tokyo", + "tools", + "top", + "toray", + "toshiba", + "total", + "tours", + "town", + "toyota", + "toys", + "tr", + "trade", + "trading", + "training", + "travel", + "travelchannel", + "travelers", + "travelersinsurance", + "trust", + "trv", + "tt", + "tube", + "tui", + "tunes", + "tushu", + "tv", + "tvs", + "tw", + "tz", + "ua", + "ubank", + "ubs", + "ug", + "uk", + "unicom", + "university", + "uno", + "uol", + "ups", + "us", + "uy", + "uz", + "va", + "vacations", + "vana", + "vanguard", + "vc", + "ve", + "vegas", + "ventures", + "verisign", + "vermögensberater", + "vermögensberatung", + "versicherung", + "vet", + "vg", + "vi", + "viajes", + "video", + "vig", + "viking", + "villas", + "vin", + "vip", + "virgin", + "visa", + "vision", + "viva", + "vivo", + "vlaanderen", + "vn", + "vodka", + "volkswagen", + "volvo", + "vote", + "voting", + "voto", + "voyage", + "vu", + "vuelos", + "wales", + "walmart", + "walter", + "wang", + "wanggou", + "watch", + "watches", + "weather", + "weatherchannel", + "webcam", + "weber", + "website", + "wed", + "wedding", + "weibo", + "weir", + "wf", + "whoswho", + "wien", + "wiki", + "williamhill", + "win", + "windows", + "wine", + "winners", + "wme", + "wolterskluwer", + "woodside", + "work", + "works", + "world", + "wow", + "ws", + "wtc", + "wtf", + "xbox", + "xerox", + "xfinity", + "xihuan", + "xin", + "xxx", + "xyz", + "yachts", + "yahoo", + "yamaxun", + "yandex", + "ye", + "yodobashi", + "yoga", + "yokohama", + "you", + "youtube", + "yt", + "yun", + "za", + "zappos", + "zara", + "zero", + "zip", + "zm", + "zone", + "zuerich", + "zw", + "ελ", + "ευ", + "бг", + "бел", + "дети", + "ею", + "католик", + "ком", + "мкд", + "мон", + "москва", + "онлайн", + "орг", + "рус", + "рф", + "сайт", + "срб", + "укр", + "қаз", + "հայ", + "ישראל", + "קום", + "ابوظبي", + "اتصالات", + "ارامكو", + "الاردن", + "البحرين", + "الجزائر", + "السعودية", + "العليان", + "المغرب", + "امارات", + "ایران", + "بارت", + "بازار", + "بيتك", + "بھارت", + "تونس", + "سودان", + "سورية", + "شبكة", + "عراق", + "عرب", + "عمان", + "فلسطين", + "قطر", + "كاثوليك", + "كوم", + "مصر", + "مليسيا", + "موريتانيا", + "موقع", + "همراه", + "پاکستان", + "ڀارت", + "कॉम", + "नेट", + "भारत", + "भारतम्", + "भारोत", + "संगठन", + "বাংলা", + "ভারত", + "ভাৰত", + "ਭਾਰਤ", + "ભારત", + "ଭାରତ", + "இந்தியா", + "இலங்கை", + "சிங்கப்பூர்", + "భారత్", + "ಭಾರತ", + "ഭാരതം", + "ලංකා", + "คอม", + "ไทย", + "ລາວ", + "გე", + "みんな", + "アマゾン", + "クラウド", + "グーグル", + "コム", + "ストア", + "セール", + "ファッション", + "ポイント", + "世界", + "中信", + "中国", + "中國", + "中文网", + "亚马逊", + "企业", + "佛山", + "信息", + "健康", + "八卦", + "公司", + "公益", + "台湾", + "台灣", + "商城", + "商店", + "商标", + "嘉里", + "嘉里大酒店", + "在线", + "大拿", + "天主教", + "娱乐", + "家電", + "广东", + "微博", + "慈善", + "我爱你", + "手机", + "招聘", + "政务", + "政府", + "新加坡", + "新闻", + "时尚", + "書籍", + "机构", + "淡马锡", + "游戏", + "澳門", + "点看", + "移动", + "组织机构", + "网址", + "网店", + "网站", + "网络", + "联通", + "诺基亚", + "谷歌", + "购物", + "通販", + "集团", + "電訊盈科", + "飞利浦", + "食品", + "餐厅", + "香格里拉", + "香港", + "닷넷", + "닷컴", + "삼성", + "한국", +]; + +function getDomain(inputUrl) { + const parsed = url.parse(inputUrl).host; + var parts = parsed.split('.'); + if (parts[0] === 'www' && parts[1] !== 'com') { + parts.shift(); + } + var ln = parts.length, i = ln, minLength = parts[parts.length - 1].length, part; + // iterate backwards + while ((part = parts[--i])) { + // stop when we find a non-TLD part + if (i === 0 || // 'asia.com' (last remaining must be the SLD) + i < ln - 2 || // TLDs only span 2 levels + part.length < minLength || // 'www.cn.com' (valid TLD as second-level domain) + tlds.indexOf(part) < 0 // officialy not a TLD + ) { + return part; + } + } +} +function appendProtocol(inputUrl) { + const parsed = url.parse(inputUrl); + if (!parsed.protocol) { + const urlWithProtocol = `https://${inputUrl}`; + return urlWithProtocol; + } + return inputUrl; +} +function normalizeUrl(urlToNormalize) { + const urlWithProtocol = appendProtocol(urlToNormalize); + if (isurl(urlWithProtocol)) { + return urlWithProtocol; + } + else { + throw new Error(`Your url "${urlWithProtocol}" is invalid`); + } +} + +function validateNumberInput(value) { + const parsedValue = Number(value); + if (isNaN(parsedValue)) { + throw new Commander.InvalidArgumentError('Not a number.'); + } + return parsedValue; +} +function validateUrlInput(url) { + try { + return normalizeUrl(url); + } + catch (error) { + throw new Commander.InvalidArgumentError(error.message); + } +} + +const npmDirectory = path.join(path.dirname(fileURLToPath(import.meta.url)), '..'); + +const logger = { + info(...msg) { + log.info(...msg.map((m) => chalk.blue.bold(m))); + }, + debug(...msg) { + log.debug(...msg); + }, + error(...msg) { + log.error(...msg.map((m) => chalk.red.bold(m))); + }, + warn(...msg) { + log.info(...msg.map((m) => chalk.yellow.bold(m))); + }, + success(...msg) { + log.info(...msg.map((m) => chalk.green.bold(m))); + } +}; + +function promptText(message, initial) { + return __awaiter(this, void 0, void 0, function* () { + const response = yield prompts({ + type: 'text', + name: 'content', + message, + initial, + }); + return response.content; + }); +} +function mergeTauriConfig(url, options, tauriConf) { + return __awaiter(this, void 0, void 0, function* () { + const { width, height, fullscreen, transparent, resizable, identifier, name, } = options; + const tauriConfWindowOptions = { + width, + height, + fullscreen, + transparent, + resizable, + }; + Object.assign(tauriConf.tauri.windows[0], Object.assign({ url }, tauriConfWindowOptions)); + tauriConf.package.productName = name; + tauriConf.tauri.bundle.identifier = identifier; + const exists = yield fs.stat(options.icon) + .then(() => true) + .catch(() => false); + if (exists) { + let updateIconPath = true; + let customIconExt = path.extname(options.icon).toLowerCase(); + if (process.platform === "win32") { + if (customIconExt === ".ico") { + const ico_path = path.join(npmDirectory, `src-tauri/png/${name.toLowerCase()}_32.ico`); + tauriConf.tauri.bundle.resources = [`png/${name.toLowerCase()}_32.ico`]; + yield fs.copyFile(options.icon, ico_path); + } + else { + updateIconPath = false; + logger.warn(`icon file in Windows must be 256 * 256 pix with .ico type, but you give ${customIconExt}`); + } + } + if (process.platform === "linux") { + delete tauriConf.tauri.bundle.deb.files; + if (customIconExt != ".png") { + updateIconPath = false; + logger.warn(`icon file in Linux must be 512 * 512 pix with .png type, but you give ${customIconExt}`); + } + } + if (process.platform === "darwin" && customIconExt !== ".icns") { + updateIconPath = false; + logger.warn(`icon file in MacOS must be .icns type, but you give ${customIconExt}`); + } + if (updateIconPath) { + tauriConf.tauri.bundle.icon = [options.icon]; + } + else { + logger.warn(`icon file will not change with default.`); + } + } + else { + logger.warn("the custom icon path may not exists. we will use default icon to replace it"); + } + let configPath = ""; + switch (process.platform) { + case "win32": { + configPath = path.join(npmDirectory, 'src-tauri/tauri.windows.conf.json'); + break; + } + case "darwin": { + configPath = path.join(npmDirectory, 'src-tauri/tauri.macos.conf.json'); + break; + } + case "linux": { + configPath = path.join(npmDirectory, 'src-tauri/tauri.linux.conf.json'); + break; + } + } + let bundleConf = { tauri: { bundle: tauriConf.tauri.bundle } }; + yield fs.writeFile(configPath, Buffer.from(JSON.stringify(bundleConf), 'utf-8')); + const configJsonPath = path.join(npmDirectory, 'src-tauri/tauri.conf.json'); + yield fs.writeFile(configJsonPath, Buffer.from(JSON.stringify(tauriConf), 'utf-8')); + }); +} + +function getIdentifier(name, url) { + const hash = crypto.createHash('md5'); + hash.update(url); + const postFixHash = hash.digest('hex').substring(0, 6); + return `pake-${postFixHash}`; +} + +const IS_MAC = process.platform === 'darwin'; +const IS_WIN = process.platform === 'win32'; +const IS_LINUX = process.platform === 'linux'; + +function handleIcon(options, url) { + return __awaiter(this, void 0, void 0, function* () { + if (options.icon) { + if (options.icon.startsWith('http')) { + return downloadIcon(options.icon); + } + else { + return path.resolve(options.icon); + } + } + if (!options.icon) { + return getDefaultIcon(); + } + }); +} +function getDefaultIcon() { + return __awaiter(this, void 0, void 0, function* () { + logger.info('You have not provided an app icon, use the default icon.(use --icon option to assign an icon)'); + let iconPath = 'src-tauri/icons/icon.icns'; + if (IS_WIN) { + iconPath = 'src-tauri/png/icon_256.ico'; + } + else if (IS_LINUX) { + iconPath = 'src-tauri/png/icon_512.png'; + } + return path.join(npmDirectory, iconPath); + }); +} +// export async function getIconFromPageUrl(url: string) { +// const icon = await pageIcon(url); +// console.log(icon); +// if (icon.ext === '.ico') { +// const a = await ICO.parse(icon.data); +// icon.data = Buffer.from(a[0].buffer); +// } +// const iconDir = (await dir()).path; +// const iconPath = path.join(iconDir, `/icon.icns`); +// const out = png2icons.createICNS(icon.data, png2icons.BILINEAR, 0); +// await fs.writeFile(iconPath, out); +// return iconPath; +// } +// export async function getIconFromMacosIcons(name: string) { +// const data = { +// query: name, +// filters: 'approved:true', +// hitsPerPage: 10, +// page: 1, +// }; +// const res = await axios.post('https://p1txh7zfb3-2.algolianet.com/1/indexes/macOSicons/query?x-algolia-agent=Algolia%20for%20JavaScript%20(4.13.1)%3B%20Browser', data, { +// headers: { +// 'x-algolia-api-key': '0ba04276e457028f3e11e38696eab32c', +// 'x-algolia-application-id': 'P1TXH7ZFB3', +// }, +// }); +// if (!res.data.hits.length) { +// return ''; +// } else { +// return downloadIcon(res.data.hits[0].icnsUrl); +// } +// } +function downloadIcon(iconUrl) { + return __awaiter(this, void 0, void 0, function* () { + let iconResponse; + try { + iconResponse = yield axios.get(iconUrl, { + responseType: 'arraybuffer', + }); + } + catch (error) { + if (error.response && error.response.status === 404) { + return null; + } + throw error; + } + const iconData = yield iconResponse.data; + if (!iconData) { + return null; + } + const fileDetails = yield fileTypeFromBuffer(iconData); + if (!fileDetails) { + return null; + } + const { path } = yield dir(); + const iconPath = `${path}/icon.${fileDetails.ext}`; + yield fs.writeFile(iconPath, iconData); + return iconPath; + }); +} + +function handleOptions(options, url) { + return __awaiter(this, void 0, void 0, function* () { + const appOptions = Object.assign(Object.assign({}, options), { identifier: '' }); + if (!appOptions.name) { + appOptions.name = yield promptText('please input your application name', getDomain(url)); + } + appOptions.identifier = getIdentifier(appOptions.name, url); + appOptions.icon = yield handleIcon(appOptions); + return appOptions; + }); +} + +function shellExec(command) { + return new Promise((resolve, reject) => { + shelljs.exec(command, { async: true, silent: false }, (code) => { + if (code === 0) { + resolve(0); + } + else { + reject(new Error(`${code}`)); + } + }); + }); +} + +const RustInstallScriptFocMac = "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y"; +const RustInstallScriptForWin = 'winget install --id Rustlang.Rustup'; +function installRust() { + return __awaiter(this, void 0, void 0, function* () { + const spinner = ora('Downloading Rust').start(); + try { + yield shellExec(IS_WIN ? RustInstallScriptForWin : RustInstallScriptFocMac); + spinner.succeed(); + } + catch (error) { + console.error('install rust return code', error.message); + spinner.fail(); + process.exit(1); + } + }); +} +function checkRustInstalled() { + return shelljs.exec('rustc --version', { silent: true }).code === 0; +} + +var tauri$3 = { + windows: [ + { + url: "https://weread.qq.com/", + transparent: true, + fullscreen: false, + width: 1200, + height: 780, + resizable: true + } + ], + security: { + csp: null + }, + updater: { + active: false + } +}; +var build = { + devPath: "../dist", + distDir: "../dist", + beforeBuildCommand: "", + beforeDevCommand: "" +}; +var CommonConf = { + "package": { + productName: "WeRead", + version: "1.0.0" +}, + tauri: tauri$3, + build: build +}; + +var tauri$2 = { + bundle: { + icon: [ + "png/weread_256.ico", + "png/weread_32.ico" + ], + identifier: "com.tw93.weread", + active: true, + category: "DeveloperTool", + copyright: "", + externalBin: [ + ], + longDescription: "", + resources: [ + "png/weread_32.ico" + ], + shortDescription: "", + targets: [ + "msi" + ], + windows: { + certificateThumbprint: null, + digestAlgorithm: "sha256", + timestampUrl: "", + wix: { + language: [ + "en-US" + ], + template: "assets/main.wxs" + } + } + } +}; +var WinConf = { + tauri: tauri$2 +}; + +var tauri$1 = { + bundle: { + icon: [ + "icons/weread.icns" + ], + identifier: "com.tw93.weread", + active: true, + category: "DeveloperTool", + copyright: "", + externalBin: [ + ], + longDescription: "", + macOS: { + entitlements: null, + exceptionDomain: "", + frameworks: [ + ], + providerShortName: null, + signingIdentity: null + }, + resources: [ + ], + shortDescription: "", + targets: [ + "dmg" + ] + } +}; +var MacConf = { + tauri: tauri$1 +}; + +var tauri = { + bundle: { + icon: [ + "png/weread_256.ico", + "png/weread_512.png" + ], + identifier: "com.tw93.weread", + active: true, + category: "DeveloperTool", + copyright: "", + deb: { + depends: [ + "libwebkit2gtk-4.0-dev", + "build-essential", + "curl", + "wget", + "libssl-dev", + "libgtk-3-dev", + "libayatana-appindicator3-dev", + "librsvg2-dev", + "gnome-video-effects", + "gnome-video-effects-extra" + ], + files: { + "/usr/share/applications/com-tw93-weread.desktop": "assets/com-tw93-weread.desktop" + } + }, + externalBin: [ + ], + longDescription: "", + resources: [ + ], + shortDescription: "", + targets: [ + "deb", + "appimage" + ] + } +}; +var LinuxConf = { + tauri: tauri +}; + +let tauriConf = { + package: CommonConf.package, + tauri: CommonConf.tauri +}; +switch (process.platform) { + case "win32": { + tauriConf.tauri.bundle = WinConf.tauri.bundle; + break; + } + case "darwin": { + tauriConf.tauri.bundle = MacConf.tauri.bundle; + break; + } + case "linux": { + tauriConf.tauri.bundle = LinuxConf.tauri.bundle; + break; + } +} + +class MacBuilder { + prepare() { + return __awaiter(this, void 0, void 0, function* () { + if (checkRustInstalled()) { + return; + } + const res = yield prompts({ + type: 'confirm', + message: 'We detected that you have not installed Rust. Install it now?', + name: 'value', + }); + if (res.value) { + // TODO 国内有可能会超时 + yield installRust(); + } + else { + log.error('Error: Pake need Rust to package your webapp!!!'); + process.exit(2); + } + }); + } + build(url, options) { + return __awaiter(this, void 0, void 0, function* () { + log.debug('PakeAppOptions', options); + const { name } = options; + yield mergeTauriConfig(url, options, tauriConf); + yield shellExec(`cd ${npmDirectory} && npm install && npm run build`); + let arch = "x64"; + if (process.arch === "arm64") { + arch = "aarch64"; + } + else { + arch = process.arch; + } + const dmgName = `${name}_${tauriConf.package.version}_${arch}.dmg`; + const appPath = this.getBuildedAppPath(npmDirectory, dmgName); + const distPath = path.resolve(`${name}.dmg`); + yield fs.copyFile(appPath, distPath); + yield fs.unlink(appPath); + logger.success('Build success!'); + logger.success('You can find the app installer in', distPath); + }); + } + getBuildedAppPath(npmDirectory, dmgName) { + return path.join(npmDirectory, 'src-tauri/target/release/bundle/dmg', dmgName); + } +} + +class WinBuilder { + prepare() { + return __awaiter(this, void 0, void 0, function* () { + logger.info('To build the Windows app, you need to install Rust and VS Build Tools.'); + logger.info('See more in https://tauri.app/v1/guides/getting-started/prerequisites#installing\n'); + if (checkRustInstalled()) { + return; + } + const res = yield prompts({ + type: 'confirm', + message: 'We detected that you have not installed Rust. Install it now?', + name: 'value', + }); + if (res.value) { + // TODO 国内有可能会超时 + yield installRust(); + } + else { + logger.error('Error: Pake needs Rust to package your webapp!!!'); + process.exit(2); + } + }); + } + build(url, options) { + return __awaiter(this, void 0, void 0, function* () { + logger.debug('PakeAppOptions', options); + const { name } = options; + yield mergeTauriConfig(url, options, tauriConf); + yield shellExec(`cd ${npmDirectory} && npm install && npm run build`); + const language = tauriConf.tauri.bundle.windows.wix.language[0]; + const arch = process.arch; + const msiName = `${name}_${tauriConf.package.version}_${arch}_${language}.msi`; + const appPath = this.getBuildedAppPath(npmDirectory, msiName); + const distPath = path.resolve(`${name}.msi`); + yield fs.copyFile(appPath, distPath); + yield fs.unlink(appPath); + logger.success('Build success!'); + logger.success('You can find the app installer in', distPath); + }); + } + getBuildedAppPath(npmDirectory, dmgName) { + return path.join(npmDirectory, 'src-tauri/target/release/bundle/msi', dmgName); + } +} + +class LinuxBuilder { + prepare() { + return __awaiter(this, void 0, void 0, function* () { + logger.info('To build the Linux app, you need to install Rust and Linux package'); + logger.info('See more in https://tauri.app/v1/guides/getting-started/prerequisites#installing\n'); + if (checkRustInstalled()) { + return; + } + const res = yield prompts({ + type: 'confirm', + message: 'We detected that you have not installed Rust. Install it now?', + name: 'value', + }); + if (res.value) { + // TODO 国内有可能会超时 + yield installRust(); + } + else { + logger.error('Error: Pake needs Rust to package your webapp!!!'); + process.exit(2); + } + }); + } + build(url, options) { + return __awaiter(this, void 0, void 0, function* () { + logger.debug('PakeAppOptions', options); + const { name } = options; + yield mergeTauriConfig(url, options, tauriConf); + yield shellExec(`cd ${npmDirectory} && npm install && npm run build`); + let arch = ""; + if (process.arch === "x64") { + arch = "amd64"; + } + else { + arch = process.arch; + } + const debName = `${name}_${tauriConf.package.version}_${arch}.deb`; + const appPath = this.getBuildedAppPath(npmDirectory, "deb", debName); + const distPath = path.resolve(`${name}.deb`); + yield fs.copyFile(appPath, distPath); + yield fs.unlink(appPath); + const appImageName = `${name}_${tauriConf.package.version}_${arch}.AppImage`; + const appImagePath = this.getBuildedAppPath(npmDirectory, "appimage", appImageName); + const distAppPath = path.resolve(`${name}.AppImage`); + yield fs.copyFile(appImagePath, distAppPath); + yield fs.unlink(appImagePath); + logger.success('Build success!'); + logger.success('You can find the deb app installer in', distPath); + logger.success('You can find the Appimage app installer in', distAppPath); + }); + } + getBuildedAppPath(npmDirectory, packageType, packageName) { + return path.join(npmDirectory, 'src-tauri/target/release/bundle/', packageType, packageName); + } +} + +class BuilderFactory { + static create() { + if (IS_MAC) { + return new MacBuilder(); + } + if (IS_WIN) { + return new WinBuilder(); + } + if (IS_LINUX) { + return new LinuxBuilder(); + } + throw new Error('The current system does not support!!'); + } +} + +var name = "pake-cli"; +var version = "1.0.1"; +var description = "🤱🏻 很简单的用 Rust 打包网页生成很小的桌面 App 🤱🏻 A simple way to make any web page a desktop application using Rust."; +var engines = { + node: "^14.13 || >=16.0.0" +}; +var bin = { + pake: "./cli.js" +}; +var repository = { + type: "git", + url: "https://github.com/tw93/pake.git" +}; +var author = { + name: "Tw93", + email: "tw93@qq.com" +}; +var keywords = [ + "pake", + "pake-cli", + "rust", + "tauri", + "no-electron", + "productivity" +]; +var files = [ + "dist", + "src-tauri", + "cli.js" +]; +var scripts = { + start: "npm run dev", + dev: "npm run tauri dev", + "dev:debug": "npm run tauri dev -- --features devtools", + build: "npm run tauri build --release", + "build:mac": "npm run tauri build -- --target universal-apple-darwin", + "build:all-unix": "chmod +x ./script/build.sh && ./script/build.sh", + "build:all-windows": ".\\script\\build.bat", + tauri: "tauri", + cli: "rollup -c rollup.config.js --watch", + "cli:build": "cross-env NODE_ENV=production rollup -c rollup.config.js", + "cli:publish": "npm run cli:build && npm publish" +}; +var type = "module"; +var exports = "./dist/pake.js"; +var license = "MIT"; +var dependencies = { + "@tauri-apps/api": "^1.2.0", + "@tauri-apps/cli": "^1.2.2", + axios: "^1.1.3", + chalk: "^5.1.2", + commander: "^9.4.1", + "file-type": "^18.0.0", + "is-url": "^1.2.4", + loglevel: "^1.8.1", + ora: "^6.1.2", + prompts: "^2.4.2", + shelljs: "^0.8.5", + "tmp-promise": "^3.0.3", + "update-notifier": "^6.0.2" +}; +var devDependencies = { + "@rollup/plugin-alias": "^4.0.2", + "@rollup/plugin-commonjs": "^23.0.2", + "@rollup/plugin-json": "^5.0.1", + "@rollup/plugin-terser": "^0.1.0", + "@rollup/plugin-typescript": "^9.0.2", + "@types/is-url": "^1.2.30", + "@types/page-icon": "^0.3.4", + "@types/prompts": "^2.4.1", + "@types/shelljs": "^0.8.11", + "@types/tmp": "^0.2.3", + "@types/update-notifier": "^6.0.1", + "app-root-path": "^3.1.0", + concurrently: "^7.5.0", + "cross-env": "^7.0.3", + rollup: "^3.3.0", + tslib: "^2.4.1", + typescript: "^4.9.3" +}; +var packageJson = { + name: name, + version: version, + description: description, + engines: engines, + bin: bin, + repository: repository, + author: author, + keywords: keywords, + files: files, + scripts: scripts, + type: type, + exports: exports, + license: license, + dependencies: dependencies, + devDependencies: devDependencies +}; + +function checkUpdateTips() { + return __awaiter(this, void 0, void 0, function* () { + updateNotifier({ pkg: packageJson }).notify(); + }); +} + +program.version(packageJson.version).description('A cli application can package a web page to desktop application.'); +program + .showHelpAfterError() + .argument('[url]', 'the web url you want to package', validateUrlInput) + .option('--name ', 'application name') + .option('--icon ', 'application icon', DEFAULT_PAKE_OPTIONS.icon) + .option('--height ', 'window height', validateNumberInput, DEFAULT_PAKE_OPTIONS.height) + .option('--width ', 'window width', validateNumberInput, DEFAULT_PAKE_OPTIONS.width) + .option('--no-resizable', 'whether the window can be resizable', DEFAULT_PAKE_OPTIONS.resizable) + .option('--fullscreen', 'makes the packaged app start in full screen', DEFAULT_PAKE_OPTIONS.fullscreen) + .option('--transparent', 'transparent title bar', DEFAULT_PAKE_OPTIONS.transparent) + .option('--debug', 'debug', DEFAULT_PAKE_OPTIONS.transparent) + .action((url, options) => __awaiter(void 0, void 0, void 0, function* () { + checkUpdateTips(); + if (!url) { + // 直接 pake 不需要出现url提示 + program.help(); + } + log.setDefaultLevel('info'); + if (options.debug) { + log.setLevel('debug'); + } + const builder = BuilderFactory.create(); + yield builder.prepare(); + const appOptions = yield handleOptions(options, url); + builder.build(url, appOptions); +})); +program.parse(); diff --git a/package.json b/package.json index 935e6b2..0edaf8d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,10 @@ { "name": "pake-cli", - "version": "0.0.6", + "version": "1.0.1", "description": "🤱🏻 很简单的用 Rust 打包网页生成很小的桌面 App 🤱🏻 A simple way to make any web page a desktop application using Rust.", + "engines": { + "node": "^14.13 || >=16.0.0" + }, "bin": { "pake": "./cli.js" }, @@ -13,33 +16,40 @@ "name": "Tw93", "email": "tw93@qq.com" }, + "keywords": [ + "pake", + "pake-cli", + "rust", + "tauri", + "no-electron", + "productivity" + ], "files": [ "dist", "src-tauri", - "cli.js", - "pake-default.icns" + "cli.js" ], "scripts": { "start": "npm run dev", "dev": "npm run tauri dev", "dev:debug": "npm run tauri dev -- --features devtools", - "build": "npm run tauri build -- --target universal-apple-darwin", - "build:windows": "npm run tauri build -- --target x86_64-pc-windows-msvc", - "build:linux": "npm run tauri build --release", - "build:all-unix":"chmod +x ./script/build.sh && ./script/build.sh", + "build": "npm run tauri build --release", + "build:mac": "npm run tauri build -- --target universal-apple-darwin", + "build:all-unix": "chmod +x ./script/build.sh && ./script/build.sh", "build:all-windows": ".\\script\\build.bat", "tauri": "tauri", "cli": "rollup -c rollup.config.js --watch", "cli:build": "cross-env NODE_ENV=production rollup -c rollup.config.js", - "cli:publish": "npm run cli:build && npm publish" + "prepublishOnly": "npm run cli:build" }, "type": "module", "exports": "./dist/pake.js", "license": "MIT", "dependencies": { "@tauri-apps/api": "^1.2.0", - "@tauri-apps/cli": "^1.2.1", + "@tauri-apps/cli": "^1.2.2", "axios": "^1.1.3", + "chalk": "^5.1.2", "commander": "^9.4.1", "file-type": "^18.0.0", "is-url": "^1.2.4", @@ -47,7 +57,8 @@ "ora": "^6.1.2", "prompts": "^2.4.2", "shelljs": "^0.8.5", - "tmp-promise": "^3.0.3" + "tmp-promise": "^3.0.3", + "update-notifier": "^6.0.2" }, "devDependencies": { "@rollup/plugin-alias": "^4.0.2", @@ -60,11 +71,12 @@ "@types/prompts": "^2.4.1", "@types/shelljs": "^0.8.11", "@types/tmp": "^0.2.3", + "@types/update-notifier": "^6.0.1", "app-root-path": "^3.1.0", "concurrently": "^7.5.0", "cross-env": "^7.0.3", "rollup": "^3.3.0", "tslib": "^2.4.1", - "typescript": "^4.8.4" + "typescript": "^4.9.3" } } diff --git a/pake-default.icns b/pake-default.icns deleted file mode 100644 index 16a4920..0000000 Binary files a/pake-default.icns and /dev/null differ diff --git a/rollup.config.js b/rollup.config.js index 13987e4..6fdfbba 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -4,9 +4,6 @@ import typescript from '@rollup/plugin-typescript'; import alias from '@rollup/plugin-alias'; import commonjs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; -import terser from '@rollup/plugin-terser'; - -const isDev = process.env.NODE_ENV !== "production"; export default { input: 'bin/cli.ts', @@ -23,6 +20,5 @@ export default { alias({ entries: [{ find: '@', replacement: path.join(appRootPath.path, 'bin') }], }), - !isDev && terser(), ], }; diff --git a/script/build.bat b/script/build.bat index 1137d95..395cc01 100644 --- a/script/build.bat +++ b/script/build.bat @@ -31,8 +31,14 @@ set old_title=WeRead set old_zh_name=微信阅读 set old_url=https://weread.qq.com/ +:: set init name, we will recovery code to init when build finish. +set init_name=%old_name% +set init_title=%old_title% +set init_zh_name=%old_zh_name% +set init_url=%old_url% + :: for windows, we need replace package name to title -.\script\sd.exe "\"productName\": \"weread\"" "\"productName\": \"WeRead\"" src-tauri\tauri.conf.json +:: .\script\sd.exe "\"productName\": \"weread\"" "\"productName\": \"WeRead\"" src-tauri\tauri.conf.json for /f "skip=1 tokens=1-4 delims=," %%i in (app.csv) do ( setlocal enabledelayedexpansion @@ -44,13 +50,11 @@ for /f "skip=1 tokens=1-4 delims=," %%i in (app.csv) do ( ::echo name is !name! !name_zh! !url! :: replace url - .\script\sd.exe !old_url! !url! src-tauri\tauri.conf.json + .\script\sd.exe -s !old_url! !url! src-tauri\tauri.conf.json ::replace pacakge name .\script\sd.exe !old_title! !title! src-tauri\tauri.conf.json - .\script\sd.exe !old_name! !name! src-tauri\tauri.conf.json - echo update ico with 32x32 pictue - .\script\sd.exe !old_name! !name! src-tauri\src\main.rs - ::copy src-tauri\png\!name!_32.ico src-tauri\icons\icon.ico + .\script\sd.exe !old_name! !name! src-tauri\tauri.windows.conf.json + echo. ::update package info set old_zh_name=!name_zh! @@ -86,3 +90,8 @@ for /f "skip=1 tokens=1-4 delims=," %%i in (app.csv) do ( :: for windows, we need replace package name to lower again :: .\script\sd.exe "\"productName\": \"WeRead\"" "\"productName\": \"weread\"" src-tauri\tauri.conf.json echo "output dir is output\windows" + +::recovery code +.\script\sd.exe %url% %init_url% src-tauri\tauri.conf.json +.\script\sd.exe %title% %init_title% src-tauri\tauri.conf.json +.\script\sd.exe %name% %init_name% src-tauri\tauri.windows.conf.json \ No newline at end of file diff --git a/script/build.sh b/script/build.sh index 95e5ca9..7d370bc 100755 --- a/script/build.sh +++ b/script/build.sh @@ -28,11 +28,13 @@ total=$(sed -n '$=' app.csv) export total=$((total-1)) export index=1 -old_name="weread" -old_title="WeRead" -old_zh_name="微信阅读" -old_url="https://weread.qq.com/" -package_prefix="com-tw93" +export old_name="weread" +export old_title="WeRead" +export old_zh_name="微信阅读" +export old_url="https://weread.qq.com/" +export package_prefix="com-tw93" + + if [[ "$OSTYPE" =~ ^linux ]]; then echo "===============" @@ -64,15 +66,15 @@ do package_title=${arr[1]} package_zh_name=${arr[2]} url=${arr[3]} - echo "update package name and url" # replace package info - $sd "${old_url}" "${url}" src-tauri/tauri.conf.json + $sd -s "${old_url}" "${url}" src-tauri/tauri.conf.json $sd "${old_name}" "${package_name}" src-tauri/tauri.conf.json - echo "update ico with 32x32 pictue" - $sd "${old_name}" "${package_name}" src-tauri/src/main.rs + # echo "update ico with 32x32 pictue" + # $sd "${old_name}" "${package_name}" src-tauri/src/main.rs # for apple, need replace title if [[ "$OSTYPE" =~ ^darwin ]]; then + $sd "${old_name}" "${package_name}" src-tauri/tauri.macos.conf.json $sd "${old_title}" "${package_title}" src-tauri/tauri.conf.json fi @@ -80,6 +82,7 @@ do # cp "src-tauri/png/${package_name}_32.ico" "src-tauri/icons/icon.ico" if [[ "$OSTYPE" =~ ^linux ]]; then + $sd "${old_name}" "${package_name}" src-tauri/tauri.linux.conf.json echo "update desktop" old_desktop="src-tauri/assets/${package_prefix}-${old_name}.desktop" new_desktop="src-tauri/assets/${package_prefix}-${package_name}.desktop" @@ -99,7 +102,8 @@ do if [[ "$OSTYPE" =~ ^linux ]]; then npm run tauri build - mv src-tauri/target/release/bundle/deb/*.deb output/linux/${package_title}_amd64.deb + mv src-tauri/target/release/bundle/deb/${package_prefix}-${package_name}*.deb output/linux/${package_title}_amd64.deb + mv src-tauri/target/release/bundle/appimage/${package_prefix}-${package_name}*.AppImage output/linux/${package_title}_amd64.AppImage fi if [[ "$OSTYPE" =~ ^darwin ]]; then @@ -114,13 +118,5 @@ do done echo "build all package success!" -if [[ "$OSTYPE" =~ ^linux ]]; then -$sd "\"productName\": \"com-tw93-weread\"" "\"productName\": \"WeRead\"" src-tauri/tauri.conf.json - echo "result file in output/linux" -fi - -if [[ "$OSTYPE" =~ ^darwin ]]; then - # replace again - $sd "\"productName\": \"weread\"" "\"productName\": \"WeRead\"" src-tauri/tauri.conf.json - echo "result file in output/macos" -fi +echo "you run 'rm src-tauri/assets/*.desktop && git checkout src-tauri' to recovery code" +# rm src-tauri/assets/*.desktop && git checkout src-tauri diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 9cc86ca..fa36a96 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -42,14 +42,15 @@ checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" name = "app" version = "0.1.0" dependencies = [ + "home", "image", "serde", "serde_json", "tauri", "tauri-build", + "tauri-plugin-window-state", "tauri-utils", - "webbrowser", - "wry 0.21.1", + "webkit2gtk", ] [[package]] @@ -76,22 +77,6 @@ dependencies = [ "system-deps 6.0.3", ] -[[package]] -name = "attohttpc" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcf00bc6d5abb29b5f97e3c61a90b6d3caa12f3faf897d4a3e3607c050a35a7" -dependencies = [ - "flate2", - "http", - "log", - "native-tls", - "serde", - "serde_json", - "serde_urlencoded", - "url", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -104,6 +89,15 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bit_field" version = "0.10.1" @@ -514,17 +508,6 @@ dependencies = [ "syn", ] -[[package]] -name = "dbus" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8bcdd56d2e5c4ed26a529c5a9029f5db8290d433497506f958eae3be148eb6" -dependencies = [ - "libc", - "libdbus-sys", - "winapi", -] - [[package]] name = "derive_more" version = "0.99.17" @@ -653,14 +636,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9663d381d07ae25dc88dbdf27df458faa83a9b25336bcac83d5e452b5fc9d3" +checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9" dependencies = [ "cfg-if", "libc", "redox_syscall", - "windows-sys 0.42.0", + "windows-sys", ] [[package]] @@ -878,15 +861,15 @@ dependencies = [ [[package]] name = "generator" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc184cace1cea8335047a471cc1da80f18acf8a76f3bab2028d499e328948ec7" +checksum = "d266041a359dfa931b370ef684cceb84b166beb14f7f0421f4a6a3d0c446d12e" dependencies = [ "cc", "libc", "log", "rustversion", - "windows 0.32.0", + "windows", ] [[package]] @@ -1132,6 +1115,15 @@ dependencies = [ "libc", ] +[[package]] +name = "home" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747309b4b440c06d57b0b25f2aee03ee9b5e5397d288c60e21fc709bb98a7408" +dependencies = [ + "winapi", +] + [[package]] name = "html5ever" version = "0.25.2" @@ -1289,20 +1281,6 @@ dependencies = [ "system-deps 5.0.0", ] -[[package]] -name = "jni" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" -dependencies = [ - "cesu8", - "combine", - "jni-sys", - "log", - "thiserror", - "walkdir", -] - [[package]] name = "jni" version = "0.20.0" @@ -1343,9 +1321,9 @@ dependencies = [ [[package]] name = "json-patch" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f995a3c8f2bc3dd52a18a583e90f9ec109c047fa1603a853e46bcda14d2e279d" +checksum = "eb3fa5a61630976fc4c353c70297f2e93f1930e3ccee574d59d618ccbd5154ce" dependencies = [ "serde", "serde_json", @@ -1377,18 +1355,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] -name = "libc" -version = "0.2.137" +name = "libappindicator" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "db2d3cb96d092b4824cb306c9e544c856a4cb6210c1081945187f7f1924b47e8" +dependencies = [ + "glib", + "gtk", + "gtk-sys", + "libappindicator-sys", + "log", +] [[package]] -name = "libdbus-sys" -version = "0.2.2" +name = "libappindicator-sys" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c185b5b7ad900923ef3a8ff594083d4d9b5aea80bb4f32b8342363138c0d456b" +checksum = "f1b3b6681973cea8cc3bce7391e6d7d5502720b80a581c9a95c9cbaf592826aa" dependencies = [ - "pkg-config", + "gtk-sys", + "libloading", + "once_cell", +] + +[[package]] +name = "libc" +version = "0.2.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", ] [[package]] @@ -1440,19 +1443,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" -[[package]] -name = "mac-notification-sys" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e72d50edb17756489e79d52eb146927bec8eba9dd48faadf9ef08bca3791ad5" -dependencies = [ - "cc", - "dirs-next", - "objc-foundation", - "objc_id", - "time", -] - [[package]] name = "malloc_buf" version = "0.0.6" @@ -1533,24 +1523,6 @@ dependencies = [ "getrandom 0.2.8", ] -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "ndk" version = "0.6.0" @@ -1591,17 +1563,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" -[[package]] -name = "notify-rust" -version = "4.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368e89ea58df747ce88be669ae44e79783c1d30bfd540ad0fc520b3f41f0b3b0" -dependencies = [ - "dbus", - "mac-notification-sys", - "tauri-winrt-notification", -] - [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -1683,17 +1644,6 @@ dependencies = [ "objc_exception", ] -[[package]] -name = "objc-foundation" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" -dependencies = [ - "block", - "objc", - "objc_id", -] - [[package]] name = "objc_exception" version = "0.1.2" @@ -1718,82 +1668,6 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" -[[package]] -name = "open" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2078c0039e6a54a0c42c28faa984e115fb4c2d5bf2208f77d1961002df8576f8" -dependencies = [ - "pathdiff", - "windows-sys 0.42.0", -] - -[[package]] -name = "openssl" -version = "0.10.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020433887e44c27ff16365eaa2d380547a94544ad509aff6eb5b6e3e0b27b376" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07d5c8cb6e57b3a3612064d7b18b117912b4ce70955c2504d4b741c9e244b132" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "os_info" -version = "3.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4750134fb6a5d49afc80777394ad5d95b04bc12068c6abb92fae8f43817270f" -dependencies = [ - "log", - "serde", - "winapi", -] - -[[package]] -name = "os_pipe" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6a252f1f8c11e84b3ab59d7a488e48e4478a93937e027076638c49536204639" -dependencies = [ - "libc", - "windows-sys 0.42.0", -] - [[package]] name = "overload" version = "0.1.1" @@ -1845,20 +1719,14 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys 0.42.0", + "windows-sys", ] [[package]] name = "paste" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" - -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "cf1c2c742266c2f1041c914ba65355a83ae8747b05f208319784083583494b4b" [[package]] name = "percent-encoding" @@ -1868,9 +1736,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.5.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f400b0f7905bf702f9f3dc3df5a121b16c54e9e8012c082905fdf09a931861a" +checksum = "cc8bed3549e0f9b0a2a78bf7c0018237a2cdf085eecbbc048e52612438e4e9d0" dependencies = [ "thiserror", "ucd-trie", @@ -2100,15 +1968,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "quick-xml" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11bafc859c6815fbaffbbbf4229ecb767ac913fecb27f9ad4343662e9ef099ea" -dependencies = [ - "memchr", -] - [[package]] name = "quote" version = "1.0.21" @@ -2210,11 +2069,10 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" dependencies = [ - "crossbeam-deque", "either", "rayon-core", ] @@ -2286,30 +2144,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "rfd" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0149778bd99b6959285b0933288206090c50e2327f47a9c463bfdbf45c8823ea" -dependencies = [ - "block", - "dispatch", - "glib-sys", - "gobject-sys", - "gtk-sys", - "js-sys", - "lazy_static", - "log", - "objc", - "objc-foundation", - "objc_id", - "raw-window-handle", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows 0.37.0", -] - [[package]] name = "rustc_version" version = "0.3.3" @@ -2355,16 +2189,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "schannel" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" -dependencies = [ - "lazy_static", - "windows-sys 0.36.1", -] - [[package]] name = "scoped-tls" version = "1.0.1" @@ -2383,29 +2207,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "security-framework" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "selectors" version = "0.22.0" @@ -2455,18 +2256,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.148" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc" +checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.148" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c" +checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" dependencies = [ "proc-macro2", "quote", @@ -2495,18 +2296,6 @@ dependencies = [ "syn", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa 1.0.4", - "ryu", - "serde", -] - [[package]] name = "serde_with" version = "1.14.0" @@ -2581,16 +2370,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "shared_child" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "siphasher" version = "0.3.10" @@ -2696,32 +2475,11 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "strum" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7ac893c7d471c8a21f31cfe213ec4f6d9afeed25537c772e08ef3f005f8729e" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339f799d8b549e3744c7ac7feb216383e4005d94bdb22561b3ab8f3b808ae9fb" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "syn" -version = "1.0.104" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae548ec36cf198c0ef7710d3c230987c2d6d7bd98ad6edc0274462724c585ce" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" dependencies = [ "proc-macro2", "quote", @@ -2756,9 +2514,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.14.0" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43336f5d1793543ba96e2a1e75f3a5c7dcd592743be06a0ab3a190f4fcb4b934" +checksum = "a1fa15735311b4816d030ff54da58560b047daca0970e1031aed5502e84231a8" dependencies = [ "bitflags", "cairo-rs", @@ -2767,6 +2525,7 @@ dependencies = [ "core-foundation", "core-graphics", "crossbeam-channel", + "dirs-next", "dispatch", "gdk", "gdk-pixbuf", @@ -2778,8 +2537,9 @@ dependencies = [ "gtk", "image", "instant", - "jni 0.19.0", + "jni", "lazy_static", + "libappindicator", "libc", "log", "ndk", @@ -2795,53 +2555,7 @@ dependencies = [ "serde", "unicode-segmentation", "uuid 1.2.2", - "windows 0.39.0", - "windows-implement", - "x11-dl", -] - -[[package]] -name = "tao" -version = "0.15.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c8fab9f2ba9a6d7ad55b46f812984b6ab203d774c162163ac297edc9567404b" -dependencies = [ - "bitflags", - "cairo-rs", - "cc", - "cocoa", - "core-foundation", - "core-graphics", - "crossbeam-channel", - "dispatch", - "gdk", - "gdk-pixbuf", - "gdk-sys", - "gdkx11-sys", - "gio", - "glib", - "glib-sys", - "gtk", - "image", - "instant", - "jni 0.20.0", - "lazy_static", - "libc", - "log", - "ndk", - "ndk-context", - "ndk-sys", - "objc", - "once_cell", - "parking_lot", - "paste", - "png", - "raw-window-handle", - "scopeguard", - "serde", - "unicode-segmentation", - "uuid 1.2.2", - "windows 0.39.0", + "windows", "windows-implement", "x11-dl", ] @@ -2859,12 +2573,11 @@ dependencies = [ [[package]] name = "tauri" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18203448b9d4dcad55607eafeda6dc7fe135848e5f567cd8bdade6cafd8b1a85" +checksum = "d8ea1d785ab2164373703817bff144c4610a69ad3f659becaca0e1ea004b98d8" dependencies = [ "anyhow", - "attohttpc", "cocoa", "dirs-next", "embed_plist", @@ -2877,23 +2590,16 @@ dependencies = [ "heck 0.4.0", "http", "ignore", - "notify-rust", "objc", "once_cell", - "open", - "os_info", - "os_pipe", "percent-encoding", "rand 0.8.5", "raw-window-handle", - "regex", - "rfd", "semver 1.0.14", "serde", "serde_json", "serde_repr", "serialize-to-javascript", - "shared_child", "state", "tar", "tauri-macros", @@ -2907,7 +2613,7 @@ dependencies = [ "uuid 1.2.2", "webkit2gtk", "webview2-com", - "windows 0.39.0", + "windows", ] [[package]] @@ -2940,7 +2646,6 @@ dependencies = [ "png", "proc-macro2", "quote", - "regex", "semver 1.0.14", "serde", "serde_json", @@ -2966,6 +2671,17 @@ dependencies = [ "tauri-utils", ] +[[package]] +name = "tauri-plugin-window-state" +version = "0.1.0" +source = "git+https://github.com/tauri-apps/tauri-plugin-window-state?branch=dev#17f468062904e64bb3ebf5f1b7486883aaafa1cf" +dependencies = [ + "bincode", + "serde", + "tauri", + "thiserror", +] + [[package]] name = "tauri-runtime" version = "0.12.1" @@ -2983,14 +2699,14 @@ dependencies = [ "thiserror", "uuid 1.2.2", "webview2-com", - "windows 0.39.0", + "windows", ] [[package]] name = "tauri-runtime-wry" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7821c34cf1bd6d89ff46b46a53f3a5050d92afaf2053569f1cc4531167257b24" +checksum = "36b1c5764a41a13176a4599b5b7bd0881bea7d94dfe45e1e755f789b98317e30" dependencies = [ "cocoa", "gtk", @@ -3002,8 +2718,8 @@ dependencies = [ "uuid 1.2.2", "webkit2gtk", "webview2-com", - "windows 0.39.0", - "wry 0.22.5", + "windows", + "wry", ] [[package]] @@ -3031,18 +2747,7 @@ dependencies = [ "thiserror", "url", "walkdir", - "windows 0.39.0", -] - -[[package]] -name = "tauri-winrt-notification" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58de036c4d2e20717024de2a3c4bf56c301f07b21bc8ef9b57189fce06f1f3b" -dependencies = [ - "quick-xml", - "strum", - "windows 0.39.0", + "windows", ] [[package]] @@ -3116,9 +2821,9 @@ dependencies = [ [[package]] name = "tiff" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17def29300a156c19ae30814710d9c63cd50288a49c6fd3a10ccfbe4cf886fd" +checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" dependencies = [ "flate2", "jpeg-decoder", @@ -3169,15 +2874,16 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.22.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" dependencies = [ "autocfg", "bytes", "memchr", "num_cpus", "pin-project-lite", + "windows-sys", ] [[package]] @@ -3262,9 +2968,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" @@ -3338,12 +3044,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version-compare" version = "0.0.11" @@ -3410,18 +3110,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.83" @@ -3451,32 +3139,6 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" -[[package]] -name = "web-sys" -version = "0.3.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webbrowser" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0cc7962b5aaa0dfcebaeef0161eec6edf5f4606c12e6777fd7d392f52033a5" -dependencies = [ - "jni 0.20.0", - "ndk-context", - "objc", - "raw-window-handle", - "url", - "web-sys", - "widestring", - "winapi", -] - [[package]] name = "webkit2gtk" version = "0.18.2" @@ -3532,7 +3194,7 @@ checksum = "b4a769c9f1a64a8734bde70caafac2b96cada12cd4aefa49196b3a386b8b4178" dependencies = [ "webview2-com-macros", "webview2-com-sys", - "windows 0.39.0", + "windows", "windows-implement", ] @@ -3557,7 +3219,7 @@ dependencies = [ "serde", "serde_json", "thiserror", - "windows 0.39.0", + "windows", "windows-bindgen", "windows-metadata", ] @@ -3568,12 +3230,6 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" -[[package]] -name = "widestring" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" - [[package]] name = "winapi" version = "0.3.9" @@ -3605,32 +3261,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbedf6db9096bc2364adce0ae0aa636dcd89f3c3f2cd67947062aaf0ca2a10ec" -dependencies = [ - "windows_aarch64_msvc 0.32.0", - "windows_i686_gnu 0.32.0", - "windows_i686_msvc 0.32.0", - "windows_x86_64_gnu 0.32.0", - "windows_x86_64_msvc 0.32.0", -] - -[[package]] -name = "windows" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57b543186b344cc61c85b5aab0d2e3adf4e0f99bc076eff9aa5927bcc0b8a647" -dependencies = [ - "windows_aarch64_msvc 0.37.0", - "windows_i686_gnu 0.37.0", - "windows_i686_msvc 0.37.0", - "windows_x86_64_gnu 0.37.0", - "windows_x86_64_msvc 0.37.0", -] - [[package]] name = "windows" version = "0.39.0" @@ -3671,19 +3301,6 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ee5e275231f07c6e240d14f34e1b635bf1faa1c76c57cfd59a5cdb9848e4278" -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", -] - [[package]] name = "windows-sys" version = "0.42.0" @@ -3711,24 +3328,6 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" -[[package]] -name = "windows_aarch64_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a" - [[package]] name = "windows_aarch64_msvc" version = "0.39.0" @@ -3741,24 +3340,6 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" -[[package]] -name = "windows_i686_gnu" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" - -[[package]] -name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - -[[package]] -name = "windows_i686_gnu" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1" - [[package]] name = "windows_i686_gnu" version = "0.39.0" @@ -3771,24 +3352,6 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" -[[package]] -name = "windows_i686_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" - -[[package]] -name = "windows_i686_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - -[[package]] -name = "windows_i686_msvc" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c" - [[package]] name = "windows_i686_msvc" version = "0.39.0" @@ -3801,24 +3364,6 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" -[[package]] -name = "windows_x86_64_gnu" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d" - [[package]] name = "windows_x86_64_gnu" version = "0.39.0" @@ -3837,24 +3382,6 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" -[[package]] -name = "windows_x86_64_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d" - [[package]] name = "windows_x86_64_msvc" version = "0.39.0" @@ -3878,45 +3405,9 @@ dependencies = [ [[package]] name = "wry" -version = "0.21.1" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff5c1352b4266fdf92c63479d2f58ab4cd29dc4e78fbc1b62011ed1227926945" -dependencies = [ - "base64", - "block", - "cocoa", - "core-graphics", - "crossbeam-channel", - "gdk", - "gio", - "glib", - "gtk", - "html5ever", - "http", - "kuchiki", - "libc", - "log", - "objc", - "objc_id", - "once_cell", - "serde", - "serde_json", - "sha2", - "tao 0.14.0", - "thiserror", - "url", - "webkit2gtk", - "webkit2gtk-sys", - "webview2-com", - "windows 0.39.0", - "windows-implement", -] - -[[package]] -name = "wry" -version = "0.22.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b4906cc7b3c5959893f3984bb60882ec94539eb14622077e6529f5b3d008ee" +checksum = "4c1ad8e2424f554cc5bdebe8aa374ef5b433feff817aebabca0389961fc7ef98" dependencies = [ "base64", "block", @@ -3940,13 +3431,13 @@ dependencies = [ "serde_json", "sha2", "soup2", - "tao 0.15.6", + "tao", "thiserror", "url", "webkit2gtk", "webkit2gtk-sys", "webview2-com", - "windows 0.39.0", + "windows", "windows-implement", ] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index b64ef54..d829449 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -15,13 +15,16 @@ rust-version = "1.61.0" tauri-build = { version = "1.2.1", features = [] } [dependencies] -serde_json = "1.0.88" -serde = { version = "1.0.147", features = ["derive"] } -tauri = { version = "1.2.1", features = ["api-all"] } +serde_json = "1.0.89" +serde = { version = "1.0.150", features = ["derive"] } +tauri = { version = "1.2.2", features = ["system-tray"] } image = "0.24.5" +home = "0.5" tauri-utils = "1.2.1" -webbrowser = "0.8.2" -wry = "0.21.1" +tauri-plugin-window-state = { git = "https://github.com/tauri-apps/tauri-plugin-window-state", branch = "dev"} +webkit2gtk = "0.18.0" +# webbrowser = "0.8.2" +# wry = "0.23.4" [features] # by default Tauri runs in production mode diff --git a/src-tauri/assets/main.wxs b/src-tauri/assets/main.wxs new file mode 100644 index 0000000..4b92bd7 --- /dev/null +++ b/src-tauri/assets/main.wxs @@ -0,0 +1,310 @@ + + + + + + + + + + + + + + + + + + + + {{#if allow_downgrades}} + + {{else}} + + {{/if}} + + + Installed AND NOT UPGRADINGPRODUCTCODE + + + + + {{#if banner_path}} + + {{/if}} + {{#if dialog_image_path}} + + {{/if}} + {{#if license}} + + {{/if}} + + + + + + + + + + + + + + + + + + + WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed + + + + {{#unless license}} + + 1 + 1 + {{/unless}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{#each binaries as |bin| ~}} + + + + {{/each~}} + {{#if enable_elevated_update_task}} + + + + + + + + + + {{/if}} + {{{resources}}} + + + + + + + + + + + + + + + + + + + + + {{#each merge_modules as |msm| ~}} + + + + + + + + {{/each~}} + + + + + + {{#each resource_file_ids as |resource_file_id| ~}} + + {{/each~}} + + {{#if enable_elevated_update_task}} + + + + {{/if}} + + + + + + + + + + + {{#each binaries as |bin| ~}} + + {{/each~}} + + + + + {{#each component_group_refs as |id| ~}} + + {{/each~}} + {{#each component_refs as |id| ~}} + + {{/each~}} + {{#each feature_group_refs as |id| ~}} + + {{/each~}} + {{#each feature_refs as |id| ~}} + + {{/each~}} + {{#each merge_refs as |id| ~}} + + {{/each~}} + + + {{#if install_webview}} + + + + + + + {{#if download_bootstrapper}} + + + + + + + {{/if}} + + + {{#if webview2_bootstrapper_path}} + + + + + + + + {{/if}} + + + {{#if webview2_installer_path}} + + + + + + + + {{/if}} + + {{/if}} + + {{#if enable_elevated_update_task}} + + + + + NOT(REMOVE) + + + + + + + (REMOVE = "ALL") AND NOT UPGRADINGPRODUCTCODE + + + {{/if}} + + + + diff --git a/src-tauri/icons/chatgpt.icns b/src-tauri/icons/chatgpt.icns new file mode 100644 index 0000000..6a8cbe5 Binary files /dev/null and b/src-tauri/icons/chatgpt.icns differ diff --git a/src-tauri/icons/lizhi.icns b/src-tauri/icons/lizhi.icns new file mode 100644 index 0000000..cbf1d15 Binary files /dev/null and b/src-tauri/icons/lizhi.icns differ diff --git a/src-tauri/icons/qwerty.icns b/src-tauri/icons/qwerty.icns new file mode 100644 index 0000000..c2b20df Binary files /dev/null and b/src-tauri/icons/qwerty.icns differ diff --git a/src-tauri/icons/translate.icns b/src-tauri/icons/translate.icns deleted file mode 100644 index 7231fc4..0000000 Binary files a/src-tauri/icons/translate.icns and /dev/null differ diff --git a/src-tauri/pake.json b/src-tauri/pake.json new file mode 100644 index 0000000..32b5543 --- /dev/null +++ b/src-tauri/pake.json @@ -0,0 +1,18 @@ +{ + "windows": [ + { + "url": "https://weread.qq.com/", + "transparent": true, + "fullscreen": false, + "width": 1200, + "height": 780, + "resizable": true, + "url_type": "web" + } + ], + "user_agent": { + "macos": "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", + "linux": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "windows": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36" + } +} \ No newline at end of file diff --git a/src-tauri/png/chatgpt_256.ico b/src-tauri/png/chatgpt_256.ico new file mode 100644 index 0000000..a56cef3 Binary files /dev/null and b/src-tauri/png/chatgpt_256.ico differ diff --git a/src-tauri/png/chatgpt_32.ico b/src-tauri/png/chatgpt_32.ico new file mode 100644 index 0000000..1ba3963 Binary files /dev/null and b/src-tauri/png/chatgpt_32.ico differ diff --git a/src-tauri/png/chatgpt_512.png b/src-tauri/png/chatgpt_512.png new file mode 100644 index 0000000..efbcf48 Binary files /dev/null and b/src-tauri/png/chatgpt_512.png differ diff --git a/src-tauri/png/icon_256.ico b/src-tauri/png/icon_256.ico new file mode 100644 index 0000000..2cdca32 Binary files /dev/null and b/src-tauri/png/icon_256.ico differ diff --git a/src-tauri/png/icon_32.ico b/src-tauri/png/icon_32.ico new file mode 100644 index 0000000..b4c4b50 Binary files /dev/null and b/src-tauri/png/icon_32.ico differ diff --git a/src-tauri/png/icon_512.png b/src-tauri/png/icon_512.png new file mode 100644 index 0000000..bbda5c8 Binary files /dev/null and b/src-tauri/png/icon_512.png differ diff --git a/src-tauri/png/lizhi_256.ico b/src-tauri/png/lizhi_256.ico new file mode 100644 index 0000000..4407e63 Binary files /dev/null and b/src-tauri/png/lizhi_256.ico differ diff --git a/src-tauri/png/lizhi_32.ico b/src-tauri/png/lizhi_32.ico new file mode 100644 index 0000000..723a8f7 Binary files /dev/null and b/src-tauri/png/lizhi_32.ico differ diff --git a/src-tauri/png/lizhi_512.png b/src-tauri/png/lizhi_512.png new file mode 100644 index 0000000..9846846 Binary files /dev/null and b/src-tauri/png/lizhi_512.png differ diff --git a/src-tauri/png/qwerty_256.ico b/src-tauri/png/qwerty_256.ico new file mode 100644 index 0000000..f96eae1 Binary files /dev/null and b/src-tauri/png/qwerty_256.ico differ diff --git a/src-tauri/png/qwerty_32.ico b/src-tauri/png/qwerty_32.ico new file mode 100644 index 0000000..a70dddd Binary files /dev/null and b/src-tauri/png/qwerty_32.ico differ diff --git a/src-tauri/png/qwerty_512.png b/src-tauri/png/qwerty_512.png new file mode 100644 index 0000000..03cab91 Binary files /dev/null and b/src-tauri/png/qwerty_512.png differ diff --git a/src-tauri/png/translate_256.ico b/src-tauri/png/translate_256.ico deleted file mode 100644 index ebbd667..0000000 Binary files a/src-tauri/png/translate_256.ico and /dev/null differ diff --git a/src-tauri/png/translate_32.ico b/src-tauri/png/translate_32.ico deleted file mode 100644 index c9fe263..0000000 Binary files a/src-tauri/png/translate_32.ico and /dev/null differ diff --git a/src-tauri/png/translate_512.png b/src-tauri/png/translate_512.png deleted file mode 100644 index 984b507..0000000 Binary files a/src-tauri/png/translate_512.png and /dev/null differ diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs new file mode 100644 index 0000000..e69de29 diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 17c63f6..611f93a 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,258 +1,349 @@ -// at the top of main.rs - that will prevent the console from showing -#![windows_subsystem = "windows"] -extern crate image; -use tauri_utils::config::{Config, WindowConfig}; +#![cfg_attr( + all(not(debug_assertions), target_os = "windows"), + windows_subsystem = "windows" +)] #[cfg(target_os = "macos")] -use wry::application::platform::macos::WindowBuilderExtMacOS; +use tauri::MenuItem; -#[cfg(target_os = "macos")] -use wry::{ - application::{ - accelerator::{Accelerator, SysMods}, - event::{Event, StartCause, WindowEvent}, - event_loop::{ControlFlow, EventLoop}, - keyboard::KeyCode, - menu::{MenuBar as Menu, MenuItem, MenuItemAttributes, MenuType}, - window::{Fullscreen, Window, WindowBuilder}, - }, - webview::WebViewBuilder, +use tauri::{ + CustomMenuItem, Menu, Submenu, WindowBuilder, App, Config, + Window, WindowUrl, WindowMenuEvent, window::PlatformWebview, + SystemTrayMenu, SystemTray, SystemTrayEvent, Manager }; -#[cfg(target_os = "windows")] -use wry::{ - application::{ - event::{Event, StartCause, WindowEvent}, - event_loop::{ControlFlow, EventLoop}, - menu::MenuType, - window::{Fullscreen, Icon, Window, WindowBuilder}, - }, - webview::WebViewBuilder, -}; +// use tauri::Config; -#[cfg(target_os = "linux")] -use wry::{ - application::{ - event::{Event, StartCause, WindowEvent}, - event_loop::{ControlFlow, EventLoop}, - menu::MenuType, - window::{Fullscreen, Window, WindowBuilder}, - }, - webview::{WebContext, WebViewBuilder}, -}; +pub mod pake { + use serde::Deserialize; -fn main() -> wry::Result<()> { - #[cfg(target_os = "macos")] - let mut menu_bar_menu = Menu::new(); - #[cfg(target_os = "macos")] - let mut first_menu = Menu::new(); - #[cfg(target_os = "macos")] - first_menu.add_native_item(MenuItem::Hide); - #[cfg(target_os = "macos")] - first_menu.add_native_item(MenuItem::EnterFullScreen); - #[cfg(target_os = "macos")] - first_menu.add_native_item(MenuItem::Minimize); - #[cfg(target_os = "macos")] - first_menu.add_native_item(MenuItem::Separator); - #[cfg(target_os = "macos")] - first_menu.add_native_item(MenuItem::Copy); - #[cfg(target_os = "macos")] - first_menu.add_native_item(MenuItem::Cut); - #[cfg(target_os = "macos")] - first_menu.add_native_item(MenuItem::Paste); - #[cfg(target_os = "macos")] - first_menu.add_native_item(MenuItem::Undo); - #[cfg(target_os = "macos")] - first_menu.add_native_item(MenuItem::Redo); - #[cfg(target_os = "macos")] - first_menu.add_native_item(MenuItem::SelectAll); - #[cfg(target_os = "macos")] - first_menu.add_native_item(MenuItem::Separator); + #[derive(Debug, Deserialize)] + pub struct WindowConfig { + pub url: String, + pub transparent: bool, + pub fullscreen: bool, + pub width: f64, + pub height: f64, + pub resizable: bool, + pub url_type: String + } - #[cfg(target_os = "macos")] - let close_item = first_menu.add_item( - MenuItemAttributes::new("CloseWindow") - .with_accelerators(&Accelerator::new(SysMods::Cmd, KeyCode::KeyW)), - ); - #[cfg(target_os = "macos")] - first_menu.add_native_item(MenuItem::Quit); + #[derive(Debug, Deserialize)] + pub struct UserAgent { + pub macos: String, + pub linux: String, + pub windows: String, + } + + #[derive(Debug, Deserialize)] + pub struct PakeConfig { + pub windows: Vec, + pub user_agent: UserAgent, + } +} +use pake::PakeConfig; + +pub fn get_pake_config() -> (PakeConfig, Config){ + let pake_config_path = include_str!("../pake.json"); + let pake_config: PakeConfig = serde_json::from_str(pake_config_path) + .expect("failed to parse pake config"); + // println!("{:#?}", config); + let tauri_config_path = include_str!("../tauri.conf.json"); + let tauri_config: Config = serde_json::from_str(tauri_config_path) + .expect("failed to parse tauri config"); + (pake_config, tauri_config) +} + + +pub fn get_menu() -> Menu { + // first menu + let hide = CustomMenuItem::new("hide", "Hide"); + let close = CustomMenuItem::new("close", "Close"); + let quit = CustomMenuItem::new("quit", "Quit"); #[cfg(target_os = "macos")] - menu_bar_menu.add_submenu("App", true, first_menu); + let first_menu = Menu::new() + .add_native_item(MenuItem::EnterFullScreen) + .add_native_item(MenuItem::Minimize) + .add_native_item(MenuItem::Separator) + .add_native_item(MenuItem::Copy) + .add_native_item(MenuItem::Cut) + .add_native_item(MenuItem::Paste) + .add_native_item(MenuItem::Undo) + .add_native_item(MenuItem::Redo) + .add_native_item(MenuItem::SelectAll) + .add_native_item(MenuItem::Separator) + .add_item(debug) + .add_item(hide) + .add_item(close) + .add_item(quit); + #[cfg(any(target_os = "linux", target_os = "windows"))] + let first_menu = Menu::new() + .add_item(hide) + .add_item(close) + .add_item(quit); + let first_menu = Submenu::new("File", first_menu); + // Hot Key + // let top = CustomMenuItem::new("top", "Top (↑)"); + // let buttom = CustomMenuItem::new("buttom", "Bottom (↓)"); + // let previous = CustomMenuItem::new("previous", "Previous (←)"); + // let next = CustomMenuItem::new("next", "next (→)"); + // let refresh = CustomMenuItem::new("refresh", "Refresh"); + let zoom_out = CustomMenuItem::new("zoom_out", "Zoom Out (125%)"); + let zoom_in = CustomMenuItem::new("zoom_in", "Zoom In (75%)"); + let zoom_reset = CustomMenuItem::new("reset", "Zoom Reset"); + let hot_key = Menu::new() + // .add_item(top) + // .add_item(buttom) + // .add_item(previous) + // .add_item(next) + // .add_item(refresh) + .add_item(zoom_in) + .add_item(zoom_out) + .add_item(zoom_reset); + let hot_key_menu = Submenu::new("Hot Key", hot_key); + + // Help + // let instructions = CustomMenuItem::new("instruction", "Instruction"); + // let about = CustomMenuItem::new("about", "About"); + // let help = Menu::new() + // .add_item(instructions) + // .add_item(about); + // let help_menu = Submenu::new("Help", help); + let menu = Menu::new() + .add_submenu(first_menu) + .add_submenu(hot_key_menu); + // .add_submenu(help_menu); + menu + + +} + + +pub fn get_data_dir(tauri_config: Config) -> std::path::PathBuf { + let package_name = tauri_config.package.product_name.unwrap(); + let home_dir = match home::home_dir() { + Some(path1) => path1, + None => panic!("Error, can't found you home dir!!"), + }; + #[cfg(target_os = "windows")] + let data_dir = home_dir.join("AppData").join("Roaming").join(package_name); #[cfg(target_os = "linux")] - let WindowConfig { - url, - width, - height, - resizable, - fullscreen, - .. - } = get_windows_config().unwrap_or_default(); - #[cfg(target_os = "windows")] - let WindowConfig { - url, - width, - height, - resizable, - fullscreen, - .. - } = get_windows_config().unwrap_or_default(); + let data_dir = home_dir.join(".config").join(package_name); + if !data_dir.exists() { + std::fs::create_dir(&data_dir) + .unwrap_or_else(|_| panic!("can't create dir {}", data_dir.display())); + } + data_dir +} + + +pub fn get_window(app: & mut App, config: PakeConfig, data_dir: std::path::PathBuf) -> Window { + let window_config = config.windows.first().unwrap(); + let user_agent = config.user_agent; + let url = match window_config.url_type.as_str() { + "web" => WindowUrl::External(window_config.url.parse().unwrap()), + "local" => WindowUrl::App(std::path::PathBuf::from(&window_config.url)), + _ => panic!("url type only can be web or local"), + }; #[cfg(target_os = "macos")] - let WindowConfig { - url, - width, - height, - resizable, - transparent, - fullscreen, - .. - } = get_windows_config().unwrap_or_default(); - let event_loop = EventLoop::new(); + let window = WindowBuilder::new( + app, + "pake", + url + ) + .title("") + .user_agent(user_agent.macos.as_str()) + .resizable(window_config.resizable) + .fullscreen(window_config.fullscreen) + .transparent(window_config.transparent) + .inner_size(window_config.width, window_config.height) + .initialization_script(include_str!("pake.js")); - let common_window = WindowBuilder::new() - .with_title("") - .with_resizable(resizable) - .with_fullscreen(if fullscreen { - Some(Fullscreen::Borderless(None)) - } else { - None - }) - .with_inner_size(wry::application::dpi::LogicalSize::new(width, height)); - #[cfg(target_os = "windows")] - let icon = load_icon(std::path::Path::new("png/weread_32.ico")); - - #[cfg(target_os = "windows")] - let window = common_window - .with_decorations(true) - .with_window_icon(Some(icon)) - .build(&event_loop) - .unwrap(); + #[cfg(any(target_os = "linux", target_os = "windows"))] + let window = { + #[cfg(target_os = "linux")] + let user_agent = user_agent.linux.as_str(); + #[cfg(target_os = "windows")] + let user_agent = user_agent.windows.as_str(); + WindowBuilder::new( + app, + "pake", + url + ) + .title("") + .data_directory(data_dir) + .resizable(window_config.resizable) + .fullscreen(window_config.fullscreen) + .user_agent(user_agent) + .inner_size(window_config.width, window_config.height) + .initialization_script(include_str!("pake.js")) + }; + window.build().unwrap() + +} +pub fn set_zoom(webview: PlatformWebview, zoom_value: f64) { #[cfg(target_os = "linux")] - let window = common_window.build(&event_loop).unwrap(); + { + // see https://docs.rs/webkit2gtk/0.18.2/webkit2gtk/struct.WebView.html + // and https://docs.rs/webkit2gtk/0.18.2/webkit2gtk/trait.WebViewExt.html + use webkit2gtk::traits::WebViewExt; + webview.inner().set_zoom_level(zoom_value); + } - #[cfg(target_os = "macos")] - let window = common_window - .with_fullsize_content_view(true) - .with_titlebar_buttons_hidden(false) - .with_titlebar_transparent(transparent) - .with_title_hidden(true) - .with_menu(menu_bar_menu) - .build(&event_loop) - .unwrap(); + #[cfg(windows)] + unsafe { + // see https://docs.rs/webview2-com/0.19.1/webview2_com/Microsoft/Web/WebView2/Win32/struct.ICoreWebView2Controller.html + webview.controller().SetZoomFactor(zoom_value).unwrap(); + } - let handler = move |window: &Window, req: String| { - if req == "drag_window" { - let _ = window.drag_window(); - } else if req == "fullscreen" { - if window.fullscreen().is_some() { - window.set_fullscreen(None); - } else { - window.set_fullscreen(Some(Fullscreen::Borderless(None))); + #[cfg(target_os = "macos")] + unsafe { + let () = msg_send![webview.inner(), setPageZoom: zoom_value]; + let () = msg_send![webview.controller(), removeAllUserScripts]; + let bg_color: cocoa::base::id = msg_send![class!(NSColor), colorWithDeviceRed:0.5 green:0.2 blue:0.4 alpha:1.]; + let () = msg_send![webview.ns_window(), setBackgroundColor: bg_color]; + } +} + +pub fn set_zoom_out(webview: PlatformWebview) { + set_zoom(webview, 1.25); +} + + +pub fn set_zoom_in(webview: PlatformWebview) { + set_zoom(webview, 0.75); +} + + +pub fn zoom_reset(webview: PlatformWebview) { + set_zoom(webview, 1.0); +} + +pub fn menu_event_handle(event: WindowMenuEvent) { + match event.menu_item_id() { + "hide" => event.window().hide().expect("can't hide window"), + "close" => event.window().close().expect("can't close window"), + "quit" => std::process::exit(0), + "zoom_out" => { + event.window() + .with_webview(set_zoom_out) + .expect("can't set zoom out"); + }, + "zoom_in" => { + event.window() + .with_webview(set_zoom_in) + .expect("can't set zoom in"); + }, + "reset" => { + event.window() + .with_webview(zoom_reset) + .expect("can't reset zoom"); + }, + _ => {}, + } +} + + +pub fn get_system_tray() -> SystemTray { + let hide = CustomMenuItem::new("hide".to_string(), "Hide"); + let show = CustomMenuItem::new("show".to_string(), "Show"); + let quit = CustomMenuItem::new("quit".to_string(), "Quit"); + let about = CustomMenuItem::new("about".to_string(), "About"); + let tray_menu = SystemTrayMenu::new() + .add_item(hide) + .add_item(show) + .add_item(quit) + .add_item(about); + SystemTray::new().with_menu(tray_menu) +} + + +pub fn system_tray_handle(app: &tauri::AppHandle, event: tauri::SystemTrayEvent) { + if let SystemTrayEvent::MenuItemClick { tray_id: _, id, .. } = event { + match id.as_str() { + "hide" => { + app.get_window("pake").unwrap().hide().unwrap(); + }, + "show" => { + app.get_window("pake").unwrap().show().unwrap(); + }, + "quit" => { + std::process::exit(0); + }, + "about" => { + let _about_window = WindowBuilder::new( + app, + "about", + WindowUrl::App(std::path::PathBuf::from("about_pake.html")) + ) + .resizable(true) + .title("About") + .inner_size(100.0, 100.0) + .build() + .expect("can't open about!") + ; } - } else if req.starts_with("open_browser") { - let href = req.replace("open_browser:", ""); - webbrowser::open(&href).expect("no browser"); + _ => {}, } }; +} - // 用于欺骗部分页面对于浏览器的强检测 - - // #[cfg(target_os = "macos")] - // let user_agent_string = "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 fn run_app() { + let system_tray = get_system_tray(); #[cfg(target_os = "macos")] - let webview = WebViewBuilder::new(window)? - // .with_user_agent(user_agent_string) - // .with_accept_first_mouse(true) - .with_url(&url.to_string())? - .with_devtools(cfg!(feature = "devtools")) - .with_initialization_script(include_str!("pake.js")) - .with_ipc_handler(handler) - // .with_back_forward_navigation_gestures(true) - .build()?; - - #[cfg(target_os = "windows")] - let webview = WebViewBuilder::new(window)? - // .with_user_agent(user_agent_string) - // .with_accept_first_mouse(true) - .with_url(&url.to_string())? - .with_devtools(cfg!(feature = "devtools")) - .with_initialization_script(include_str!("pake.js")) - .with_ipc_handler(handler) - // .with_back_forward_navigation_gestures(true) - .build()?; - // 自定义cookie文件夹,仅用于Linux - // Custom Cookie folder, only for Linux - #[cfg(target_os = "linux")] - let data_path = - std::path::PathBuf::from(concat!("/home/", env!("USER"), "/.config/com-tw93-weread/")); - #[cfg(target_os = "linux")] - if !std::path::Path::new(&data_path).exists() { - std::fs::create_dir(&data_path)?; - } - #[cfg(target_os = "linux")] - let mut web_content = WebContext::new(Some(data_path)); - #[cfg(target_os = "linux")] - let webview = WebViewBuilder::new(window)? - // .with_user_agent(user_agent_string) - // .with_accept_first_mouse(true) - .with_url(&url.to_string())? - .with_devtools(cfg!(feature = "devtools")) - .with_initialization_script(include_str!("pake.js")) - .with_ipc_handler(handler) - .with_web_context(&mut web_content) - // .with_back_forward_navigation_gestures(true) - .build()?; - - #[cfg(feature = "devtools")] { - webview.open_devtools(); + let (pake_config, _) = get_pake_config(); + let menu = get_menu(); + tauri::Builder::default() + .menu(menu) + .on_menu_event(menu_event_handle) + .system_tray(system_tray) + .on_system_tray_event(system_tray_handle) + .plugin(tauri_plugin_window_state::Builder::default().build()) + .invoke_handler(tauri::generate_handler![]) + .setup(|app| { + let _window = get_window(app, pake_config, std::path::PathBuf::new()); + #[cfg(feature = "devtools")] + { + app.get_window("pake").unwrap().open_devtools(); + } + Ok(()) + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); + } + #[cfg(any(target_os = "linux", target_os = "windows"))] + { + let (pake_config, tauri_config) = get_pake_config(); + let data_dir = get_data_dir(tauri_config); + // let menu = get_menu(); + tauri::Builder::default() + // .menu(menu) + // .on_menu_event(menu_event_handle) + .system_tray(system_tray) + .on_system_tray_event(system_tray_handle) + .plugin(tauri_plugin_window_state::Builder::default().build()) + .invoke_handler(tauri::generate_handler![]) + .setup(|app| { + let _window = get_window(app, pake_config, data_dir); + #[cfg(feature = "devtools")] + { + app.get_window("pake").unwrap().open_devtools(); + } + Ok(()) + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); } - event_loop.run(move |event, _, control_flow| { - *control_flow = ControlFlow::Wait; - match event { - Event::NewEvents(StartCause::Init) => println!("Wry has started!"), - Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } => *control_flow = ControlFlow::Exit, - Event::MenuEvent { - menu_id, - origin: MenuType::MenuBar, - .. - } => { - #[cfg(target_os = "macos")] - if menu_id == close_item.clone().id() { - webview.window().set_minimized(true); - } - println!("Clicked on {:?}", menu_id); - println!("Clicked on {:?}", webview.window().is_visible()); - } - _ => (), - } - }); } -fn get_windows_config() -> Option { - let config_file = include_str!("../tauri.conf.json"); - let config: Config = serde_json::from_str(config_file).expect("failed to parse windows config"); - config.tauri.windows.first().cloned() -} - -#[cfg(target_os = "windows")] -fn load_icon(path: &std::path::Path) -> Icon { - let (icon_rgba, icon_width, icon_height) = { - // alternatively, you can embed the icon in the binary through `include_bytes!` macro and use `image::load_from_memory` - let image = image::open(path) - .expect("Failed to open icon path") - .into_rgba8(); - let (width, height) = image.dimensions(); - let rgba = image.into_raw(); - (rgba, width, height) - }; - Icon::from_rgba(icon_rgba, icon_width, icon_height).expect("Failed to open icon") +fn main() { + run_app() + } diff --git a/src-tauri/src/main.rs.bak b/src-tauri/src/main.rs.bak new file mode 100644 index 0000000..5763754 --- /dev/null +++ b/src-tauri/src/main.rs.bak @@ -0,0 +1,229 @@ +// at the top of main.rs - that will prevent the console from showing +#![windows_subsystem = "windows"] +extern crate image; +use tauri_utils::config::{Config, WindowConfig}; +use wry::{ + application::{ + event::{Event, StartCause, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, + menu::MenuType, + window::{Fullscreen, Window, WindowBuilder}, + }, + webview::WebViewBuilder, +}; + +#[cfg(target_os = "macos")] +use wry::application::{ + accelerator::{Accelerator, SysMods}, + keyboard::KeyCode, + menu::{MenuBar as Menu, MenuItem, MenuItemAttributes}, + platform::macos::WindowBuilderExtMacOS, +}; + +#[cfg(target_os = "windows")] +use wry::application::window::Icon; + +#[cfg(any(target_os = "linux", target_os = "windows"))] +use wry::webview::WebContext; + +fn main() -> wry::Result<()> { + #[cfg(target_os = "macos")] + let (menu_bar_menu, close_item) = { + let mut menu_bar_menu = Menu::new(); + let mut first_menu = Menu::new(); + first_menu.add_native_item(MenuItem::Hide); + first_menu.add_native_item(MenuItem::EnterFullScreen); + first_menu.add_native_item(MenuItem::Minimize); + first_menu.add_native_item(MenuItem::Separator); + first_menu.add_native_item(MenuItem::Copy); + first_menu.add_native_item(MenuItem::Cut); + first_menu.add_native_item(MenuItem::Paste); + first_menu.add_native_item(MenuItem::Undo); + first_menu.add_native_item(MenuItem::Redo); + first_menu.add_native_item(MenuItem::SelectAll); + first_menu.add_native_item(MenuItem::Separator); + let close_item = first_menu.add_item( + MenuItemAttributes::new("CloseWindow") + .with_accelerators(&Accelerator::new(SysMods::Cmd, KeyCode::KeyW)), + ); + first_menu.add_native_item(MenuItem::Quit); + menu_bar_menu.add_submenu("App", true, first_menu); + (menu_bar_menu, close_item) + }; + + #[cfg(any(target_os = "linux", target_os = "windows"))] + let ( + package_name, + WindowConfig { + url, + width, + height, + resizable, + fullscreen, + .. + }, + ) = { + let (package_name, windows_config) = get_windows_config(); + ( + package_name + .expect("can't get package name in config file") + .to_lowercase(), + windows_config.unwrap_or_default(), + ) + }; + + #[cfg(target_os = "macos")] + let WindowConfig { + url, + width, + height, + resizable, + transparent, + fullscreen, + .. + } = get_windows_config().1.unwrap_or_default(); + let event_loop = EventLoop::new(); + + let common_window = WindowBuilder::new() + .with_title("") + .with_resizable(resizable) + .with_fullscreen(if fullscreen { + Some(Fullscreen::Borderless(None)) + } else { + None + }) + .with_inner_size(wry::application::dpi::LogicalSize::new(width, height)); + #[cfg(target_os = "windows")] + let window = { + let icon_path = format!("png/{}_32.ico", package_name); + let icon = load_icon(std::path::Path::new(&icon_path)); + common_window + .with_decorations(true) + .with_window_icon(Some(icon)) + .build(&event_loop) + .unwrap() + }; + + #[cfg(target_os = "linux")] + let window = common_window.build(&event_loop).unwrap(); + + #[cfg(target_os = "macos")] + let window = common_window + .with_fullsize_content_view(true) + .with_titlebar_buttons_hidden(false) + .with_titlebar_transparent(transparent) + .with_title_hidden(true) + .with_menu(menu_bar_menu) + .build(&event_loop) + .unwrap(); + + let handler = move |window: &Window, req: String| { + if req == "drag_window" { + let _ = window.drag_window(); + } else if req == "fullscreen" { + if window.fullscreen().is_some() { + window.set_fullscreen(None); + } else { + window.set_fullscreen(Some(Fullscreen::Borderless(None))); + } + } else if req.starts_with("open_browser") { + let href = req.replace("open_browser:", ""); + webbrowser::open(&href).expect("no browser"); + } + }; + + // 用于欺骗部分页面对于浏览器的强检测 + + #[cfg(target_os = "macos")] + let webview = { + let user_agent_string = "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"; + WebViewBuilder::new(window)? + .with_user_agent(user_agent_string) + .with_url(&url.to_string())? + .with_devtools(cfg!(feature = "devtools")) + .with_initialization_script(include_str!("pake.js")) + .with_ipc_handler(handler) + .with_back_forward_navigation_gestures(true) + .build()? + }; + + #[cfg(any(target_os = "linux", target_os = "windows"))] + let webview = { + let home_dir = match home::home_dir() { + Some(path1) => path1, + None => panic!("Error, can't found you home dir!!"), + }; + #[cfg(target_os = "windows")] + let data_dir = home_dir.join("AppData").join("Roaming").join(package_name); + #[cfg(target_os = "linux")] + let data_dir = home_dir.join(".config").join(package_name); + if !data_dir.exists() { + std::fs::create_dir(&data_dir) + .unwrap_or_else(|_| panic!("can't create dir {}", data_dir.display())); + } + let mut web_content = WebContext::new(Some(data_dir)); + #[cfg(target_os = "windows")] + let user_agent_string = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"; + #[cfg(target_os = "linux")] + let user_agent_string = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"; + WebViewBuilder::new(window)? + .with_user_agent(user_agent_string) + .with_url(&url.to_string())? + .with_devtools(cfg!(feature = "devtools")) + .with_initialization_script(include_str!("pake.js")) + .with_ipc_handler(handler) + .with_web_context(&mut web_content) + .build()? + }; + #[cfg(feature = "devtools")] + { + webview.open_devtools(); + } + + event_loop.run(move |event, _, control_flow| { + *control_flow = ControlFlow::Wait; + match event { + Event::NewEvents(StartCause::Init) => println!("Wry has started!"), + Event::WindowEvent { + event: WindowEvent::CloseRequested, + .. + } => *control_flow = ControlFlow::Exit, + Event::MenuEvent { + menu_id, + origin: MenuType::MenuBar, + .. + } => { + #[cfg(target_os = "macos")] + if menu_id == close_item.clone().id() { + webview.window().set_minimized(true); + } + println!("Clicked on {:?}", menu_id); + println!("Clicked on {:?}", webview.window().is_visible()); + } + _ => (), + } + }); +} + +fn get_windows_config() -> (Option, Option) { + let config_file = include_str!("../tauri.conf.json"); + let config: Config = serde_json::from_str(config_file).expect("failed to parse windows config"); + ( + config.package.product_name.clone(), + config.tauri.windows.first().cloned(), + ) +} + +#[cfg(target_os = "windows")] +fn load_icon(path: &std::path::Path) -> Icon { + let (icon_rgba, icon_width, icon_height) = { + // alternatively, you can embed the icon in the binary through `include_bytes!` macro and use `image::load_from_memory` + let image = image::open(path) + .expect("Failed to open icon path") + .into_rgba8(); + let (width, height) = image.dimensions(); + let rgba = image.into_raw(); + (rgba, width, height) + }; + Icon::from_rgba(icon_rgba, icon_width, icon_height).expect("Failed to open icon") +} diff --git a/src-tauri/src/pake.js b/src-tauri/src/pake.js index ee05646..9b095ee 100644 --- a/src-tauri/src/pake.js +++ b/src-tauri/src/pake.js @@ -55,6 +55,18 @@ window.addEventListener("DOMContentLoaded", (_event) => { padding-top: 20px; } + #__next .overflow-hidden .flex.flex-1.flex-col { + padding-left: 0; + } + + #__next .overflow-hidden>.hidden.bg-gray-900 { + display: none; + } + + #__next .overflow-hidden main .absolute .text-xs{ + visibility: hidden; + } + .lark > .dashboard-sidebar, .lark > .dashboard-sidebar > .sidebar-user-info , .lark > .dashboard-sidebar .index-module_wrapper_F-Wbq{ padding-top:15px; } @@ -200,10 +212,8 @@ window.addEventListener("DOMContentLoaded", (_event) => { left: 1px !important; } - #react-root [data-testid="SideNav_NewTweet_Button"] { - position: fixed !important; - right: 16px !important; - bottom: 24px !important; + #react-root [data-testid="SideNav_NewTweet_Button"], #react-root [aria-label="Twitter Blue"]{ + display: none; } } @@ -306,16 +316,16 @@ window.addEventListener("DOMContentLoaded", (_event) => { document.addEventListener("click", (e) => { const origin = e.target.closest("a"); if (origin && origin.href) { + const target = origin.target origin.target = "_self"; + const hrefUrl = new URL(origin.href) - //额外处理下 twitter 的外跳,对于其他需要外跳的可以改这里成对应域名 - const href = origin.href; if ( - location.host === "twitter.com" && - href.indexOf("twitter.com") === -1 + window.location.host !== hrefUrl.host && // 如果 a 标签内链接的域名和当前页面的域名不一致 且 + target === '_blank' // a 标签内链接的 target 属性为 _blank 时 ) { e.preventDefault(); - window.ipc.postMessage(`open_browser:${href}`); + window.ipc.postMessage(`open_browser:${origin.href}`); } } }); diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 02499b7..35ed045 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -4,71 +4,15 @@ "version": "1.0.0" }, "tauri": { - "windows": [ - { - "url": "https://weread.qq.com/", - "transparent": true, - "fullscreen": false, - "width": 1200, - "height": 728, - "resizable": true - } - ], - "allowlist": { - "all": true - }, - "bundle": { - "icon": [ - "icons/weread.icns", - "png/weread_256.ico", - "png/weread_32.ico", - "png/weread_512.png" - ], - "identifier": "com.tw93.weread", - "active": true, - "category": "DeveloperTool", - "copyright": "", - "deb": { - "depends": [ - "libwebkit2gtk-4.0-dev", - "build-essential", - "curl", - "wget", - "libssl-dev", - "libgtk-3-dev", - "libayatana-appindicator3-dev", - "librsvg2-dev" - ], - "files": { - "/usr/share/applications/com-tw93-weread.desktop": "assets/com-tw93-weread.desktop" - } - }, - "externalBin": [], - "longDescription": "", - "macOS": { - "entitlements": null, - "exceptionDomain": "", - "frameworks": [], - "providerShortName": null, - "signingIdentity": null - }, - "resources": ["png/weread_32.ico"], - "shortDescription": "", - "targets": ["deb", "msi", "dmg"], - "windows": { - "certificateThumbprint": null, - "digestAlgorithm": "sha256", - "timestampUrl": "", - "wix": { - "language": ["en-US"] - } - } - }, "security": { "csp": null }, "updater": { "active": false + }, + "systemTray": { + "iconPath": "png/weread_512.png", + "iconAsTemplate": true } }, "build": { diff --git a/src-tauri/tauri.linux.conf.json b/src-tauri/tauri.linux.conf.json new file mode 100644 index 0000000..c4c78b0 --- /dev/null +++ b/src-tauri/tauri.linux.conf.json @@ -0,0 +1,36 @@ +{ + "tauri": { + "bundle": { + "icon": [ + "png/weread_256.ico", + "png/weread_512.png" + ], + "identifier": "com.tw93.weread", + "active": true, + "category": "DeveloperTool", + "copyright": "", + "deb": { + "depends": [ + "libwebkit2gtk-4.0-dev", + "build-essential", + "curl", + "wget", + "libssl-dev", + "libgtk-3-dev", + "libayatana-appindicator3-dev", + "librsvg2-dev", + "gnome-video-effects", + "gnome-video-effects-extra" + ], + "files": { + "/usr/share/applications/com-tw93-weread.desktop": "assets/com-tw93-weread.desktop" + } + }, + "externalBin": [], + "longDescription": "", + "resources": [], + "shortDescription": "", + "targets": ["deb", "appimage"] + } + } +} diff --git a/src-tauri/tauri.macos.conf.json b/src-tauri/tauri.macos.conf.json new file mode 100644 index 0000000..5b09612 --- /dev/null +++ b/src-tauri/tauri.macos.conf.json @@ -0,0 +1,25 @@ +{ + "tauri": { + "bundle": { + "icon": [ + "icons/weread.icns" + ], + "identifier": "com.tw93.weread", + "active": true, + "category": "DeveloperTool", + "copyright": "", + "externalBin": [], + "longDescription": "", + "macOS": { + "entitlements": null, + "exceptionDomain": "", + "frameworks": [], + "providerShortName": null, + "signingIdentity": null + }, + "resources": [], + "shortDescription": "", + "targets": ["dmg"] + } + } +} diff --git a/src-tauri/tauri.windows.conf.json b/src-tauri/tauri.windows.conf.json new file mode 100644 index 0000000..0c2eb5b --- /dev/null +++ b/src-tauri/tauri.windows.conf.json @@ -0,0 +1,28 @@ +{ + "tauri": { + "bundle": { + "icon": [ + "png/weread_256.ico", + "png/weread_32.ico" + ], + "identifier": "com.tw93.weread", + "active": true, + "category": "DeveloperTool", + "copyright": "", + "externalBin": [], + "longDescription": "", + "resources": ["png/weread_32.ico"], + "shortDescription": "", + "targets": ["msi"], + "windows": { + "certificateThumbprint": null, + "digestAlgorithm": "sha256", + "timestampUrl": "", + "wix": { + "language": ["en-US"], + "template": "assets/main.wxs" + } + } + } + } +}