Merge pull request #200 from Tlntin/dev_2022_12_27

Dev 2022 12 27
This commit is contained in:
Tlntin
2022-12-27 21:52:02 +08:00
committed by GitHub
62 changed files with 4218 additions and 1232 deletions

View File

@@ -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"

View File

@@ -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/*/*.*

9
.gitignore vendored
View File

@@ -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

View File

@@ -1,4 +0,0 @@
{
"cSpell.words": ["loglevel", "Pake", "tauri"],
"typescript.preferences.importModuleSpecifierEnding": "js"
}

View File

@@ -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

244
README.md
View File

@@ -1,6 +1,7 @@
<p align="left"><strong>中文</strong> | <a href="https://github.com/tw93/Pake/blob/master/README_EN.md">English</a></p>
<p align="center">
<img src=https://gw.alipayobjects.com/zos/k/fa/logo-modified.png width=138/>
</p>
<h1 align="center">Pake</h1>
<div align="center">
<a href="https://twitter.com/HiTw93" target="_blank">
@@ -14,29 +15,28 @@
<a href="https://github.com/tw93/Pake/issues?q=is%3Aissue+is%3Aclosed" target="_blank">
<img alt="GitHub closed issues" src="https://img.shields.io/github/issues-closed/tw93/Pake.svg?style=flat-square"></a>
</div>
<div align="left">很简单的用 Rust 打包网页生成很小的桌面 App支持 Mac / Windows / Linux 系统,常用包下载、<a href="#命令行打包">命令行一键打包</a>、<a href="#开发">定制开发</a> 可见下面文档,也欢迎去 <a href=https://github.com/tw93/Pake/discussions>讨论区</a> 交流。</div>
</p>
<div align="left">很简单的用 Rust 打包网页生成很小的桌面 App支持 Mac / Windows / Linux 系统,常用包下载、<a href="#命令行一键打包">命令行一键打包</a>、<a href="#定制开发">定制开发</a> 可见下面文档,也欢迎去 <a href=https://github.com/tw93/Pake/discussions>讨论区</a> 交流。</div>
## 特征
🏂 **小**:相比传统的 Electron 套壳打包,要小将近 40 倍,不到 3M
😂 **快**Pake 的底层使用的 Rust Tauri 框架,性能体验较 JS 框架要轻快不少,内存小很多
🩴 **特**:不是单纯打包,实现了快捷键的透传、沉浸式的窗口、拖动、样式改写、去广告、产品的极简风格定制
🐶 **玩**:只是一个很简单的小玩具,用 Rust 替代之前套壳网页打包的老思路,其实 PWA 也很好
🏂 **小**:相比传统的 Electron 套壳打包,要小将近 40 倍,不到 3M
😂 **快**Pake 的底层使用的 Rust Tauri 框架,性能体验较 JS 框架要轻快不少,内存小很多
🩴 **特**:不是单纯打包,实现了快捷键的透传、沉浸式的窗口、拖动、样式改写、去广告、产品的极简风格定制
🐶 **玩**:只是一个很简单的小玩具,用 Rust 替代之前套壳网页打包的老思路,其实 PWA 也很好
## 下载
## 常用包下载
<table>
<tr>
<td>WeRead
<a href="https://github.com/tw93/Pake/releases/latest/download/WeRead.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/WeRead_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/WeRead_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/WeRead_amd64.deb">Linux</a>
</td>
<td>Twitter
<a href="https://github.com/tw93/Pake/releases/latest/download/Twitter.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Twitter_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Twitter_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Twitter_amd64.deb">Linux</a>
</td>
</tr>
<tr>
@@ -44,79 +44,60 @@
<td><img src=https://cdn.fliggy.com/upic/mc41xq.jpg width=600/></td>
</tr>
<tr>
<td>YouTube
<a href="https://github.com/tw93/Pake/releases/latest/download/YouTube.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/YouTube_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/YouTube_x64.msi">Windows</a>
<td>LiZhi
<a href="https://github.com/tw93/Pake/releases/latest/download/LiZhi.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/LiZhi_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/LiZhi_amd64.deb">Linux</a>
</td>
<td>Reference
<a href="https://github.com/tw93/Pake/releases/latest/download/Reference.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Reference_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Reference_x64.msi">Windows</a>
<td>YouTube
<a href="https://github.com/tw93/Pake/releases/latest/download/YouTube.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/YouTube_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/YouTube_amd64.deb">Linux</a>
</td>
</tr>
<tr>
<td><img src=https://cdn.fliggy.com/upic/DX3dfG.png width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/Ea5ZRw.png width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/KFsZIY.png width=600/></td>
</tr>
<tr>
<td>Code
<a href="https://github.com/tw93/Pake/releases/latest/download/Code.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Code_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Code_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Code_amd64.deb">Linux</a>
</td>
<td>Google Translate
<a href="https://github.com/tw93/Pake/releases/latest/download/GoogleTranslate.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/GoogleTranslate_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/GoogleTranslate_x64.msi">Windows</a>
<td>Reference
<a href="https://github.com/tw93/Pake/releases/latest/download/Reference.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Reference_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Reference_amd64.deb">Linux</a>
</td>
</tr>
<tr>
<td><img src=https://cdn.fliggy.com/upic/EB1OYP.jpg width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/EmjUGy.png width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/KFsZIY.png width=600/></td>
</tr>
<tr>
<td>Flomo
<a href="https://github.com/tw93/Pake/releases/latest/download/Flomo.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Flomo_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Flomo_x64.msi">Windows</a>
<tr>
<td>Qwerty
<a href="https://github.com/tw93/Pake/releases/latest/download/Qwerty.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Qwerty_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Qwerty_amd64.deb">Linux</a>
</td>
<td>YuQue
<a href="https://github.com/tw93/Pake/releases/latest/download/YuQue.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/YuQue_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/YuQue_x64.msi">Windows</a>
<td>ChatGPT
<a href="https://github.com/tw93/Pake/releases/latest/download/ChatGPT.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/ChatGPT_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/ChatGPT_amd64.deb">Linux</a>
</td>
</tr>
<tr>
<td><img src=https://cdn.fliggy.com/upic/jg9Eeu.jpg width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/02SZQl.png width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/CJjagn.jpg width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/sfnTXf.png width=600/></td>
</tr>
</table>
<details>
注意Windows 下不能安装到 `C:\Program File`,会直接闪退,建议安装到其他非管理员权限目录,比如 `D:\Program Files (x86)`
<summary>🏂 更多应用如 Flomo / 语雀可去 <a href="https://github.com/tw93/Pake/releases">Release</a>下载,<b>此外点击可展开快捷键说明</b></summary>
## 命令行打包
<kbd>
<img src="https://cdn.fliggy.com/upic/cOC1lF.gif" width="100%">
</kbd>
<br/><br/>
**Pake 提供了命令行工具,可以更快捷方便地一键自定义打你需要的包,详细可见 [文档](./bin/README.md)。**
```bash
// 使用 npm 进行安装
npm install -g pake-cli
// 命令使用
pake url [options]
// 随便玩玩,首次由于安装环境会有些慢,后面就快了
pake https://weekly.tw93.fun --name Weekly --transparent
```
## 快捷键
<br/>
| Mac | Windows/Linux | 功能 |
| --------------------------- | ------------------------------ | ------------------ |
@@ -131,49 +112,63 @@ pake https://weekly.tw93.fun --name Weekly --transparent
| <kbd>⌘</kbd> + <kbd>=</kbd> | <kbd>Ctrl</kbd> + <kbd>=</kbd> | 放大页面 |
| <kbd>⌘</kbd> + <kbd>0</kbd> | <kbd>Ctrl</kbd> + <kbd>0</kbd> | 重置页面缩放 |
此外还支持双击头部进行全屏切换,拖拽头部进行移动窗口,还有其他需求,欢迎提过来。
此外还支持双击头部进行全屏切换,拖拽头部进行移动窗口,Mac 用户支持手势方式返回和去下一页,还有其他需求,欢迎提过来。
## 开发
</details>
开始前参考 [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 都会,那可试试下面的 「[定制开发](#定制开发)」,可深度二次开发定制你的功能。
## 命令行一键打包
<kbd>
<img src="https://gw.alipayobjects.com/zos/k/zd/pake.gif" width="100%">
</kbd>
<br/><br/>
**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 们,一起贡献了大量能力,也欢
<sub><b>Pan93412</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/wanghanzhen">
<img src="https://avatars.githubusercontent.com/u/25301012?v=4" width="90;" alt="wanghanzhen"/>
<br />
<sub><b>Volare</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/liby">
<img src="https://avatars.githubusercontent.com/u/38807139?v=4" width="90;" alt="liby"/>
@@ -211,10 +213,10 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢
</a>
</td>
<td align="center">
<a href="https://github.com/wanghanzhen">
<img src="https://avatars.githubusercontent.com/u/25301012?v=4" width="90;" alt="wanghanzhen"/>
<a href="https://github.com/essesoul">
<img src="https://avatars.githubusercontent.com/u/58624474?v=4" width="90;" alt="essesoul"/>
<br />
<sub><b>Volare</b></sub>
<sub><b>Essesoul</b></sub>
</a>
</td>
<td align="center">
@@ -223,22 +225,8 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢
<br />
<sub><b>Horus</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/QingZ11">
<img src="https://avatars.githubusercontent.com/u/38887077?v=4" width="90;" alt="QingZ11"/>
<br />
<sub><b>Steam</b></sub>
</a>
</td></tr>
<tr>
<td align="center">
<a href="https://github.com/2nthony">
<img src="https://avatars.githubusercontent.com/u/19513289?v=4" width="90;" alt="2nthony"/>
<br />
<sub><b>2nthony</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/AielloChan">
<img src="https://avatars.githubusercontent.com/u/7900765?v=4" width="90;" alt="AielloChan"/>
@@ -246,13 +234,49 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢
<sub><b>Aiello</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/QingZ11">
<img src="https://avatars.githubusercontent.com/u/38887077?v=4" width="90;" alt="QingZ11"/>
<br />
<sub><b>Steam</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/2nthony">
<img src="https://avatars.githubusercontent.com/u/19513289?v=4" width="90;" alt="2nthony"/>
<br />
<sub><b>2nthony</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/nekomeowww">
<img src="https://avatars.githubusercontent.com/u/11081491?v=4" width="90;" alt="nekomeowww"/>
<br />
<sub><b>Ayaka Neko</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/turkyden">
<img src="https://avatars.githubusercontent.com/u/24560160?v=4" width="90;" alt="turkyden"/>
<br />
<sub><b>Dengju Deng</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/princemaple">
<img src="https://avatars.githubusercontent.com/u/1329716?v=4" width="90;" alt="princemaple"/>
<br />
<sub><b>Po Chen</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/houhoz">
<img src="https://avatars.githubusercontent.com/u/19684376?v=4" width="90;" alt="houhoz"/>
<br />
<sub><b>Hyzhao</b></sub>
</a>
</td>
</td></tr>
<tr>
<td align="center">
<a href="https://github.com/liusishan">
<img src="https://avatars.githubusercontent.com/u/33129823?v=4" width="90;" alt="liusishan"/>
@@ -272,11 +296,7 @@ Pake 的发展离不开这些 Hacker 们,一起贡献了大量能力,也欢
## 支持
- 我有两只猫,一只叫汤圆,一只叫可乐,假如觉得 Pake 让你生活更美好,可以给汤圆可乐 <a href="https://miaoyan.app/cats.html?name=Pake" target="_blank">喂罐头 🥩🍤</a>。
- 如果你喜欢 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 让你生活更美好,可以给汤圆可乐 <a href="https://miaoyan.app/cats.html?name=Pake" target="_blank">喂罐头 🥩🍤</a>。
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 的网页也很欢迎告诉我。

View File

@@ -1,6 +1,7 @@
<p align="left"><a href="https://github.com/tw93/Pake">中文</a> | <strong>English</strong></p>
<p align="center">
<img src=https://gw.alipayobjects.com/zos/k/fa/logo-modified.png width=138/>
</p>
<h1 align="center">Pake</h1>
<div align="center">
<a href="https://twitter.com/HiTw93" target="_blank">
@@ -14,8 +15,7 @@
<a href="https://github.com/tw93/Pake/issues?q=is%3Aissue+is%3Aclosed" target="_blank">
<img alt="GitHub closed issues" src="https://img.shields.io/github/issues-closed/tw93/Pake.svg?style=flat-square"></a>
</div>
<div align="left">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 <a href=https://github.com/tw93/Pake/discussions>Discussions</a> to see if there have anything you interesting.</div>
</p>
<div align="left">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 <a href=https://github.com/tw93/Pake/discussions>Discussions</a> to see if there have anything you're interesting.</div>
## Features
@@ -30,13 +30,13 @@
<tr>
<td>WeRead
<a href="https://github.com/tw93/Pake/releases/latest/download/WeRead.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/WeRead_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/WeRead_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/WeRead_amd64.deb">Linux</a>
</td>
<td>Twitter
<a href="https://github.com/tw93/Pake/releases/latest/download/Twitter.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Twitter_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Twitter_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Twitter_amd64.deb">Linux</a>
</td>
</tr>
<tr>
@@ -44,58 +44,59 @@
<td><img src=https://cdn.fliggy.com/upic/mc41xq.jpg width=600/></td>
</tr>
<tr>
<td>YouTube
<td>LiZhi
<a href="https://github.com/tw93/Pake/releases/latest/download/LiZhi.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/LiZhi_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/LiZhi_amd64.deb">Linux</a>
</td>
<td>YouTube
<a href="https://github.com/tw93/Pake/releases/latest/download/YouTube.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/YouTube_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/YouTube_x64.msi">Windows</a>
</td>
<td>Reference
<a href="https://github.com/tw93/Pake/releases/latest/download/Reference.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Reference_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Reference_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/YouTube_amd64.deb">Linux</a>
</td>
</tr>
<tr>
<td><img src=https://cdn.fliggy.com/upic/DX3dfG.png width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/Ea5ZRw.png width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/KFsZIY.png width=600/></td>
</tr>
<tr>
<td>Code
<a href="https://github.com/tw93/Pake/releases/latest/download/Code.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Code_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Code_x64.msi">Windows</a>
</td>
<td>Google Translate
<a href="https://github.com/tw93/Pake/releases/latest/download/GoogleTranslate.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/GoogleTranslate_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/GoogleTranslate_x64.msi">Windows</a>
</td>
<td>Code
<a href="https://github.com/tw93/Pake/releases/latest/download/Code.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Code_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Code_amd64.deb">Linux</a>
</td>
<td>Reference
<a href="https://github.com/tw93/Pake/releases/latest/download/Reference.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Reference_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Reference_amd64.deb">Linux</a>
</td>
</tr>
<tr>
<td><img src=https://cdn.fliggy.com/upic/EB1OYP.jpg width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/EmjUGy.png width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/EB1OYP.jpg width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/KFsZIY.png width=600/></td>
</tr>
<tr>
<td>Flomo
<a href="https://github.com/tw93/Pake/releases/latest/download/Flomo.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Flomo_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Flomo_x64.msi">Windows</a>
</td>
<td>YuQue
<a href="https://github.com/tw93/Pake/releases/latest/download/YuQue.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/YuQue_amd64.deb">Linux</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/YuQue_x64.msi">Windows</a>
</td>
<td>Qwerty
<a href="https://github.com/tw93/Pake/releases/latest/download/Qwerty.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Qwerty_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/Qwerty_amd64.deb">Linux</a>
</td>
<td>ChatGPT
<a href="https://github.com/tw93/Pake/releases/latest/download/ChatGPT.dmg">Mac</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/ChatGPT_x64.msi">Windows</a>
<a href="https://github.com/tw93/Pake/releases/latest/download/ChatGPT_amd64.deb">Linux</a>
</td>
</tr>
<tr>
<td><img src=https://cdn.fliggy.com/upic/jg9Eeu.jpg width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/02SZQl.png width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/CJjagn.jpg width=600/></td>
<td><img src=https://cdn.fliggy.com/upic/sfnTXf.png width=600/></td>
</tr>
</table>
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).
<details>
<summary>🏂 <b>Expand the shortcut key</b></summary>
## Shortcuts
<br/>
| Mac | Windows/Linux | Function |
| --------------------------- | ------------------------------ | ----------------------------- |
@@ -110,11 +111,41 @@ Note: it cannot be installed to C:\Program File under Windows, and it will crash
| <kbd>⌘</kbd> + <kbd>=</kbd> | <kbd>Ctrl</kbd> + <kbd>=</kbd> | Zoom in the Page |
| <kbd>⌘</kbd> + <kbd>0</kbd> | <kbd>Ctrl</kbd> + <kbd>0</kbd> | 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.
</details>
## 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
<kbd>
<img src="https://gw.alipayobjects.com/zos/k/zd/pake.gif" width="100%">
</kbd>
<br/><br/>
**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 environmentrefer 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 <a href="https://miaoyan.app/cats.html?name=Pake" target="_blank">feed canned food 🥩🍤</a>.
- 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 <a href="https://miaoyan.app/cats.html?name=Pake" target="_blank">feed canned food 🥩🍤</a>.
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.

View File

@@ -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/
1 name(Linux) name(Mac/Windows) name_zh url
2 twitter Twitter 推特 https://twitter.com/
translate GoogleTranslate 谷歌翻译 https://translate.google.com/
3 youtube YouTube YouTube https://youtube.com
4 reference Reference Reference https://wangchujiang.com/reference/index.html
5 code Code Code https://riju.codes/
6 yuque YuQue 语雀 https://www.yuque.com/
7 flomo chatgpt Flomo ChatGPT 浮墨 ChatGPT https://flomoapp.com/mine https://chat.openai.com/chat
8 flomo Flomo 浮墨 https://v.flomoapp.com/mine
9 qwerty Qwerty Qwerty https://qwerty.kaiyi.cool/
10 lizhi LiZhi 李志 https://lizhi.turkyden.com/?from=pake
11 weread WeRead 微信阅读 https://weread.qq.com/

21
bin/README.md vendored
View File

@@ -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 <value>
@@ -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 <path>
@@ -46,7 +51,7 @@ url 为你需要打包的网页链接 🔗,必须提供。
#### [height]
打包后的应用窗口高度,默认 `800px`
打包后的应用窗口高度,默认 `780px`
```shell
--height <number>
@@ -54,7 +59,7 @@ url 为你需要打包的网页链接 🔗,必须提供。
#### [width]
打包后的应用窗口宽度,默认 `1280px`
打包后的应用窗口宽度,默认 `1200px`
```shell
--width <number>

89
bin/README_EN.md vendored Normal file
View File

@@ -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 <value>
```
#### [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 <path>
```
#### [height]
The height of the packaged application window. The default is `780px`.
```shell
--height <number>
```
#### [width]
The width of the packaged application window. The default is `1200px`.
```shell
--width <number>
```
#### [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 <value>
```

View File

@@ -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!!');
}
}

View File

@@ -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
);
}
}

View File

@@ -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
);
}
}

View File

@@ -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
);
}
}

View File

@@ -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')
);
}

27
bin/builders/tauriConf.js vendored Normal file
View File

@@ -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;

20
bin/cli.ts vendored
View File

@@ -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('<url>', 'the web url you want to package', validateUrlInput)
.argument('[url]', 'the web url you want to package', validateUrlInput)
.option('--name <string>', 'application name')
.option('--icon <string>', 'application icon', DEFAULT_PAKE_OPTIONS.icon)
.option('--height <number>', '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');
}

4
bin/defaults.ts vendored
View File

@@ -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,

8
bin/helpers/rust.ts vendored
View File

@@ -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);

7
bin/helpers/updater.ts vendored Normal file
View File

@@ -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();
}

21
bin/options/icon.ts vendored
View File

@@ -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) {

22
bin/options/logger.ts vendored Normal file
View File

@@ -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;

4
bin/types.ts vendored
View File

@@ -5,10 +5,10 @@ export interface PakeCliOptions {
/** 应用icon */
icon: string;
/** 应用窗口宽度,默认 1280px */
/** 应用窗口宽度,默认 1200px */
width: number;
/** 应用窗口高度,默认 800px */
/** 应用窗口高度,默认 780px */
height: number;
/** 是否可以拖动默认true */

8
bin/utils/dir.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
import path from 'path';
import { fileURLToPath } from 'url';
export const npmDirectory = path.join(
path.dirname(fileURLToPath(import.meta.url)),
'..'
);

16
dist/about_pake.html vendored Normal file
View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h5>Welcome from Pake!</h5>
<p>version: 1.0.1</p>
<a href="https://github.com/tw93/Pake" target="_blank">Project link</a><br>
<a href="https://github.com/tw93/Pake/discussions" target="_blank">Discussions</a><br>
<a href="https://github.com/tw93/Pake/issues" target="_blank">Issues</a><br>
<p>LICENSE: MIT</p>
</body>
</html>

2302
dist/cli.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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"
}
}

Binary file not shown.

4
rollup.config.js vendored
View File

@@ -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(),
],
};

21
script/build.bat vendored
View File

@@ -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

36
script/build.sh vendored
View File

@@ -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

735
src-tauri/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -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

310
src-tauri/assets/main.wxs Normal file
View File

@@ -0,0 +1,310 @@
<?if $(sys.BUILDARCH)="x86"?>
<?define Win64 = "no" ?>
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?elseif $(sys.BUILDARCH)="x64"?>
<?define Win64 = "yes" ?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?else?>
<?error Unsupported value of sys.BUILDARCH=$(sys.BUILDARCH)?>
<?endif?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product
Id="*"
Name="{{{product_name}}}"
UpgradeCode="{{{upgrade_code}}}"
Language="!(loc.TauriLanguage)"
Manufacturer="{{{manufacturer}}}"
Version="{{{version}}}">
<Package Id="*"
Keywords="Installer"
InstallerVersion="450"
Languages="0"
Compressed="yes"
InstallScope="perMachine"
SummaryCodepage="!(loc.TauriCodepage)"/>
<!-- https://docs.microsoft.com/en-us/windows/win32/msi/reinstallmode -->
<!-- reinstall all files; rewrite all registry entries; reinstall all shortcuts -->
<Property Id="REINSTALLMODE" Value="amus" />
{{#if allow_downgrades}}
<MajorUpgrade Schedule="afterInstallInitialize" AllowDowngrades="yes" />
{{else}}
<MajorUpgrade Schedule="afterInstallInitialize" DowngradeErrorMessage="!(loc.DowngradeErrorMessage)" AllowSameVersionUpgrades="yes" />
{{/if}}
<InstallExecuteSequence>
<RemoveShortcuts>Installed AND NOT UPGRADINGPRODUCTCODE</RemoveShortcuts>
</InstallExecuteSequence>
<Media Id="1" Cabinet="app.cab" EmbedCab="yes" />
{{#if banner_path}}
<WixVariable Id="WixUIBannerBmp" Value="{{{banner_path}}}" />
{{/if}}
{{#if dialog_image_path}}
<WixVariable Id="WixUIDialogBmp" Value="{{{dialog_image_path}}}" />
{{/if}}
{{#if license}}
<WixVariable Id="WixUILicenseRtf" Value="{{{license}}}" />
{{/if}}
<Icon Id="ProductIcon" SourceFile="{{{icon_path}}}"/>
<Property Id="ARPPRODUCTICON" Value="ProductIcon" />
<Property Id="ARPNOREPAIR" Value="yes" Secure="yes" /> <!-- Remove repair -->
<SetProperty Id="ARPNOMODIFY" Value="1" After="InstallValidate" Sequence="execute"/>
<!-- initialize with previous InstallDir -->
<Property Id="INSTALLDIR">
<RegistrySearch Id="PrevInstallDirReg" Root="HKCU" Key="Software\\{{{manufacturer}}}\\{{{product_name}}}" Name="InstallDir" Type="raw"/>
</Property>
<!-- launch app checkbox -->
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="!(loc.LaunchApp)" />
<Property Id="WixShellExecTarget" Value="[!Path]" />
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
<UI>
<!-- launch app checkbox -->
<Publish Dialog="ExitDialog" Control="Finish" Event="DoAction" Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
{{#unless license}}
<!-- Skip license dialog -->
<Publish Dialog="WelcomeDlg"
Control="Next"
Event="NewDialog"
Value="InstallDirDlg"
Order="2">1</Publish>
<Publish Dialog="InstallDirDlg"
Control="Back"
Event="NewDialog"
Value="WelcomeDlg"
Order="2">1</Publish>
{{/unless}}
</UI>
<UIRef Id="WixUI_InstallDir" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="ApplicationShortcutDesktop" Guid="*">
<Shortcut Id="ApplicationDesktopShortcut" Name="{{{product_name}}}" Description="Runs {{{product_name}}}" Target="[!Path]" WorkingDirectory="INSTALLDIR" />
<RemoveFolder Id="DesktopFolder" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\\{{{manufacturer}}}\\{{{product_name}}}" Name="Desktop Shortcut" Type="integer" Value="1" KeyPath="yes" />
</Component>
</Directory>
<Directory Id="$(var.PlatformProgramFilesFolder)" Name="PFiles">
<Directory Id="INSTALLDIR" Name="{{{product_name}}}"/>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="{{{product_name}}}"/>
</Directory>
</Directory>
<DirectoryRef Id="INSTALLDIR">
<Component Id="RegistryEntries" Guid="*">
<RegistryKey Root="HKCU" Key="Software\\{{{manufacturer}}}\\{{{product_name}}}">
<RegistryValue Name="InstallDir" Type="string" Value="[INSTALLDIR]" KeyPath="yes" />
</RegistryKey>
</Component>
<Component Id="Path" Guid="{{{path_component_guid}}}" Win64="$(var.Win64)">
<File Id="Path" Source="{{{app_exe_source}}}" KeyPath="yes" Checksum="yes"/>
</Component>
{{#each binaries as |bin| ~}}
<Component Id="{{ bin.id }}" Guid="{{bin.guid}}" Win64="$(var.Win64)">
<File Id="Bin_{{ bin.id }}" Source="{{bin.path}}" KeyPath="yes"/>
</Component>
{{/each~}}
{{#if enable_elevated_update_task}}
<Component Id="UpdateTask" Guid="C492327D-9720-4CD5-8DB8-F09082AF44BE" Win64="$(var.Win64)">
<File Id="UpdateTask" Source="update.xml" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="UpdateTaskInstaller" Guid="011F25ED-9BE3-50A7-9E9B-3519ED2B9932" Win64="$(var.Win64)">
<File Id="UpdateTaskInstaller" Source="install-task.ps1" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="UpdateTaskUninstaller" Guid="D4F6CC3F-32DC-5FD0-95E8-782FFD7BBCE1" Win64="$(var.Win64)">
<File Id="UpdateTaskUninstaller" Source="uninstall-task.ps1" KeyPath="yes" Checksum="yes"/>
</Component>
{{/if}}
{{{resources}}}
<Component Id="CMP_UninstallShortcut" Guid="*">
<Shortcut Id="UninstallShortcut"
Name="Uninstall {{{product_name}}}"
Description="Uninstalls {{{product_name}}}"
Target="[System64Folder]msiexec.exe"
Arguments="/x [ProductCode]" />
<RemoveFolder Id="INSTALLDIR"
On="uninstall" />
<RegistryValue Root="HKCU"
Key="Software\\{{{manufacturer}}}\\{{{product_name}}}"
Name="Uninstaller Shortcut"
Type="integer"
Value="1"
KeyPath="yes" />
</Component>
</DirectoryRef>
<DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="ApplicationShortcut" Guid="*">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="{{{product_name}}}"
Description="Runs {{{product_name}}}"
Target="[!Path]"
Icon="ProductIcon"
WorkingDirectory="INSTALLDIR">
<ShortcutProperty Key="System.AppUserModel.ID" Value="{{{bundle_id}}}"/>
</Shortcut>
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\\{{{manufacturer}}}\\{{{product_name}}}" Name="Start Menu Shortcut" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</DirectoryRef>
{{#each merge_modules as |msm| ~}}
<DirectoryRef Id="TARGETDIR">
<Merge Id="{{ msm.name }}" SourceFile="{{ msm.path }}" DiskId="1" Language="!(loc.TauriLanguage)" />
</DirectoryRef>
<Feature Id="{{ msm.name }}" Title="{{ msm.name }}" AllowAdvertise="no" Display="hidden" Level="1">
<MergeRef Id="{{ msm.name }}"/>
</Feature>
{{/each~}}
<Feature
Id="MainProgram"
Title="Application"
Description="!(loc.InstallAppFeature)"
Level="1"
ConfigurableDirectory="INSTALLDIR"
AllowAdvertise="no"
Display="expand"
Absent="disallow">
<ComponentRef Id="RegistryEntries"/>
{{#each resource_file_ids as |resource_file_id| ~}}
<ComponentRef Id="{{ resource_file_id }}"/>
{{/each~}}
{{#if enable_elevated_update_task}}
<ComponentRef Id="UpdateTask" />
<ComponentRef Id="UpdateTaskInstaller" />
<ComponentRef Id="UpdateTaskUninstaller" />
{{/if}}
<Feature Id="ShortcutsFeature"
Title="Shortcuts"
Level="1">
<ComponentRef Id="Path"/>
<ComponentRef Id="CMP_UninstallShortcut" />
<ComponentRef Id="ApplicationShortcut" />
<ComponentRef Id="ApplicationShortcutDesktop" />
</Feature>
<Feature
Id="Environment"
Title="PATH Environment Variable"
Description="!(loc.PathEnvVarFeature)"
Level="1"
Absent="allow">
<ComponentRef Id="Path"/>
{{#each binaries as |bin| ~}}
<ComponentRef Id="{{ bin.id }}"/>
{{/each~}}
</Feature>
</Feature>
<Feature Id="External" AllowAdvertise="no" Absent="disallow">
{{#each component_group_refs as |id| ~}}
<ComponentGroupRef Id="{{ id }}"/>
{{/each~}}
{{#each component_refs as |id| ~}}
<ComponentRef Id="{{ id }}"/>
{{/each~}}
{{#each feature_group_refs as |id| ~}}
<FeatureGroupRef Id="{{ id }}"/>
{{/each~}}
{{#each feature_refs as |id| ~}}
<FeatureRef Id="{{ id }}"/>
{{/each~}}
{{#each merge_refs as |id| ~}}
<MergeRef Id="{{ id }}"/>
{{/each~}}
</Feature>
{{#if install_webview}}
<!-- WebView2 -->
<Property Id="WVRTINSTALLED">
<RegistrySearch Id="WVRTInstalledSystem" Root="HKLM" Key="SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" Name="pv" Type="raw" Win64="no" />
<RegistrySearch Id="WVRTInstalledUser" Root="HKCU" Key="SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" Name="pv" Type="raw"/>
</Property>
{{#if download_bootstrapper}}
<CustomAction Id='DownloadAndInvokeBootstrapper' Directory="INSTALLDIR" Execute="deferred" ExeCommand='powershell.exe -NoProfile -windowstyle hidden try [\{] [\[]Net.ServicePointManager[\]]::SecurityProtocol = [\[]Net.SecurityProtocolType[\]]::Tls12 [\}] catch [\{][\}]; Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/p/?LinkId=2124703" -OutFile "$env:TEMP\MicrosoftEdgeWebview2Setup.exe" ; Start-Process -FilePath "$env:TEMP\MicrosoftEdgeWebview2Setup.exe" -ArgumentList ({{{webview_installer_args}}} &apos;/install&apos;) -Wait' Return='check'/>
<InstallExecuteSequence>
<Custom Action='DownloadAndInvokeBootstrapper' Before='InstallFinalize'>
<![CDATA[NOT(REMOVE OR WVRTINSTALLED)]]>
</Custom>
</InstallExecuteSequence>
{{/if}}
<!-- Embedded webview bootstrapper mode -->
{{#if webview2_bootstrapper_path}}
<Binary Id="MicrosoftEdgeWebview2Setup.exe" SourceFile="{{{webview2_bootstrapper_path}}}"/>
<CustomAction Id='InvokeBootstrapper' BinaryKey='MicrosoftEdgeWebview2Setup.exe' Execute="deferred" ExeCommand='{{{webview_installer_args}}} /install' Return='check' />
<InstallExecuteSequence>
<Custom Action='InvokeBootstrapper' Before='InstallFinalize'>
<![CDATA[NOT(REMOVE OR WVRTINSTALLED)]]>
</Custom>
</InstallExecuteSequence>
{{/if}}
<!-- Embedded offline installer -->
{{#if webview2_installer_path}}
<Binary Id="MicrosoftEdgeWebView2RuntimeInstaller.exe" SourceFile="{{{webview2_installer_path}}}"/>
<CustomAction Id='InvokeStandalone' BinaryKey='MicrosoftEdgeWebView2RuntimeInstaller.exe' Execute="deferred" ExeCommand='{{{webview_installer_args}}} /install' Return='check' />
<InstallExecuteSequence>
<Custom Action='InvokeStandalone' Before='InstallFinalize'>
<![CDATA[NOT(REMOVE OR WVRTINSTALLED)]]>
</Custom>
</InstallExecuteSequence>
{{/if}}
{{/if}}
{{#if enable_elevated_update_task}}
<!-- Install an elevated update task within Windows Task Scheduler -->
<CustomAction
Id="CreateUpdateTask"
Return="check"
Directory="INSTALLDIR"
Execute="commit"
Impersonate="yes"
ExeCommand="powershell.exe -WindowStyle hidden .\install-task.ps1" />
<InstallExecuteSequence>
<Custom Action='CreateUpdateTask' Before='InstallFinalize'>
NOT(REMOVE)
</Custom>
</InstallExecuteSequence>
<!-- Remove elevated update task during uninstall -->
<CustomAction
Id="DeleteUpdateTask"
Return="check"
Directory="INSTALLDIR"
ExeCommand="powershell.exe -WindowStyle hidden .\uninstall-task.ps1" />
<InstallExecuteSequence>
<Custom Action="DeleteUpdateTask" Before='InstallFinalize'>
(REMOVE = "ALL") AND NOT UPGRADINGPRODUCTCODE
</Custom>
</InstallExecuteSequence>
{{/if}}
<SetProperty Id="ARPINSTALLLOCATION" Value="[INSTALLDIR]" After="CostFinalize"/>
</Product>
</Wix>

Binary file not shown.

BIN
src-tauri/icons/lizhi.icns Normal file

Binary file not shown.

BIN
src-tauri/icons/qwerty.icns Normal file

Binary file not shown.

Binary file not shown.

18
src-tauri/pake.json Normal file
View File

@@ -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"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
src-tauri/png/icon_256.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
src-tauri/png/icon_32.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
src-tauri/png/icon_512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
src-tauri/png/lizhi_256.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
src-tauri/png/lizhi_32.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
src-tauri/png/lizhi_512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
src-tauri/png/qwerty_32.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

0
src-tauri/src/lib.rs Normal file
View File

View File

@@ -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<WindowConfig>,
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<WindowConfig> {
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()
}

229
src-tauri/src/main.rs.bak Normal file
View File

@@ -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<String>, Option<WindowConfig>) {
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")
}

28
src-tauri/src/pake.js vendored
View File

@@ -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}`);
}
}
});

View File

@@ -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": {

View File

@@ -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"]
}
}
}

View File

@@ -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"]
}
}
}

View File

@@ -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"
}
}
}
}
}