pake-cli 2.6.1 → 3.0.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -63
- package/dist/cli.js +143 -173
- package/dist/dev.js +152 -173
- package/dist/dev.js.map +1 -1
- package/package.json +9 -9
- package/src-tauri/Cargo.lock +1728 -2149
- package/src-tauri/Cargo.toml +15 -11
- package/src-tauri/capabilities/default.json +18 -0
- package/src-tauri/gen/schemas/acl-manifests.json +1 -0
- package/src-tauri/gen/schemas/capabilities.json +1 -0
- package/src-tauri/gen/schemas/desktop-schema.json +2326 -0
- package/src-tauri/gen/schemas/macOS-schema.json +2326 -0
- package/src-tauri/icons/icon.png +0 -0
- package/src-tauri/icons/xiaoyuzhou.icns +0 -0
- package/src-tauri/pake.json +4 -2
- package/src-tauri/src/app/config.rs +2 -0
- package/src-tauri/src/app/invoke.rs +13 -12
- package/src-tauri/src/app/menu.rs +25 -20
- package/src-tauri/src/app/window.rs +14 -9
- package/src-tauri/src/inject/custom.js +0 -6
- package/src-tauri/src/inject/event.js +30 -28
- package/src-tauri/src/inject/style.js +14 -1
- package/src-tauri/src/lib.rs +133 -0
- package/src-tauri/src/main.rs +1 -88
- package/src-tauri/src/util.rs +7 -5
- package/src-tauri/tauri.conf.json +12 -29
- package/src-tauri/tauri.linux.conf.json +14 -14
- package/src-tauri/tauri.macos.conf.json +17 -20
- package/src-tauri/tauri.windows.conf.json +17 -20
- package/src-tauri/.pake/pake.json +0 -29
- package/src-tauri/.pake/tauri.conf.json +0 -75
- package/src-tauri/.pake/tauri.macos.conf.json +0 -29
|
Binary file
|
|
Binary file
|
package/src-tauri/pake.json
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"width": 1200,
|
|
9
9
|
"height": 780,
|
|
10
10
|
"resizable": true,
|
|
11
|
-
"dark_mode": false,
|
|
12
11
|
"always_on_top": false,
|
|
12
|
+
"dark_mode": false,
|
|
13
13
|
"activation_shortcut": "",
|
|
14
14
|
"disabled_web_shortcuts": false
|
|
15
15
|
}
|
|
@@ -24,5 +24,7 @@
|
|
|
24
24
|
"linux": true,
|
|
25
25
|
"windows": true
|
|
26
26
|
},
|
|
27
|
-
"
|
|
27
|
+
"system_tray_path": "icons/icon.png",
|
|
28
|
+
"inject": [],
|
|
29
|
+
"proxy_url": ""
|
|
28
30
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
use crate::util::{check_file_or_append, get_download_message, show_toast, MessageType};
|
|
2
2
|
use std::fs::{self, File};
|
|
3
3
|
use std::io::Write;
|
|
4
|
-
use
|
|
5
|
-
use tauri::
|
|
4
|
+
use std::str::FromStr;
|
|
5
|
+
use tauri::http::Method;
|
|
6
|
+
use tauri::{command, AppHandle, Manager, Url, WebviewWindow};
|
|
7
|
+
use tauri_plugin_http::reqwest::{ClientBuilder, Request};
|
|
6
8
|
|
|
7
9
|
#[derive(serde::Deserialize)]
|
|
8
10
|
pub struct DownloadFileParams {
|
|
@@ -18,24 +20,23 @@ pub struct BinaryDownloadParams {
|
|
|
18
20
|
|
|
19
21
|
#[command]
|
|
20
22
|
pub async fn download_file(app: AppHandle, params: DownloadFileParams) -> Result<(), String> {
|
|
21
|
-
let window:
|
|
23
|
+
let window: WebviewWindow = app.get_webview_window("pake").unwrap();
|
|
22
24
|
show_toast(&window, &get_download_message(MessageType::Start));
|
|
23
25
|
|
|
24
|
-
let output_path =
|
|
26
|
+
let output_path = app.path().download_dir().unwrap().join(params.filename);
|
|
25
27
|
let file_path = check_file_or_append(output_path.to_str().unwrap());
|
|
26
28
|
let client = ClientBuilder::new().build().unwrap();
|
|
27
29
|
|
|
28
30
|
let response = client
|
|
29
|
-
.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
)
|
|
31
|
+
.execute(Request::new(
|
|
32
|
+
Method::GET,
|
|
33
|
+
Url::from_str(¶ms.url).unwrap(),
|
|
34
|
+
))
|
|
34
35
|
.await;
|
|
35
36
|
|
|
36
37
|
match response {
|
|
37
38
|
Ok(res) => {
|
|
38
|
-
let bytes = res.bytes().await.unwrap()
|
|
39
|
+
let bytes = res.bytes().await.unwrap();
|
|
39
40
|
|
|
40
41
|
let mut file = File::create(file_path).unwrap();
|
|
41
42
|
file.write_all(&bytes).unwrap();
|
|
@@ -54,9 +55,9 @@ pub async fn download_file_by_binary(
|
|
|
54
55
|
app: AppHandle,
|
|
55
56
|
params: BinaryDownloadParams,
|
|
56
57
|
) -> Result<(), String> {
|
|
57
|
-
let window:
|
|
58
|
+
let window: WebviewWindow = app.get_webview_window("pake").unwrap();
|
|
58
59
|
show_toast(&window, &get_download_message(MessageType::Start));
|
|
59
|
-
let output_path =
|
|
60
|
+
let output_path = app.path().download_dir().unwrap().join(params.filename);
|
|
60
61
|
let file_path = check_file_or_append(output_path.to_str().unwrap());
|
|
61
62
|
let download_file_result = fs::write(file_path, ¶ms.binary);
|
|
62
63
|
match download_file_result {
|
|
@@ -1,31 +1,36 @@
|
|
|
1
|
-
use tauri::{
|
|
1
|
+
use tauri::{
|
|
2
|
+
menu::{MenuBuilder, MenuItemBuilder},
|
|
3
|
+
tray::TrayIconBuilder,
|
|
4
|
+
AppHandle, Manager,
|
|
5
|
+
};
|
|
2
6
|
use tauri_plugin_window_state::{AppHandleExt, StateFlags};
|
|
3
7
|
|
|
4
|
-
pub fn
|
|
5
|
-
let hide_app =
|
|
6
|
-
let show_app =
|
|
7
|
-
let quit =
|
|
8
|
-
let
|
|
9
|
-
.
|
|
10
|
-
.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
pub fn system_tray_handle(app: &tauri::AppHandle, event: SystemTrayEvent) {
|
|
16
|
-
if let SystemTrayEvent::MenuItemClick { tray_id: _, id, .. } = event {
|
|
17
|
-
match id.as_str() {
|
|
8
|
+
pub fn set_system_tray(app: &AppHandle) -> tauri::Result<()> {
|
|
9
|
+
let hide_app = MenuItemBuilder::with_id("hide_app", "Hide").build(app)?;
|
|
10
|
+
let show_app = MenuItemBuilder::with_id("show_app", "Show").build(app)?;
|
|
11
|
+
let quit = MenuItemBuilder::with_id("quit", "Quit").build(app)?;
|
|
12
|
+
let menu = MenuBuilder::new(app)
|
|
13
|
+
.items(&[&hide_app, &show_app, &quit])
|
|
14
|
+
.build()?;
|
|
15
|
+
app.app_handle().remove_tray_by_id("pake-tray");
|
|
16
|
+
let tray = TrayIconBuilder::new()
|
|
17
|
+
.menu(&menu)
|
|
18
|
+
.on_menu_event(move |app, event| match event.id().as_ref() {
|
|
18
19
|
"hide_app" => {
|
|
19
|
-
app.
|
|
20
|
+
app.get_webview_window("pake").unwrap().minimize().unwrap();
|
|
20
21
|
}
|
|
21
22
|
"show_app" => {
|
|
22
|
-
app.
|
|
23
|
+
app.get_webview_window("pake").unwrap().show().unwrap();
|
|
23
24
|
}
|
|
24
25
|
"quit" => {
|
|
25
26
|
let _res = app.save_window_state(StateFlags::all());
|
|
26
27
|
std::process::exit(0);
|
|
27
28
|
}
|
|
28
|
-
_ =>
|
|
29
|
-
}
|
|
30
|
-
|
|
29
|
+
_ => (),
|
|
30
|
+
})
|
|
31
|
+
.icon(app.default_window_icon().unwrap().clone())
|
|
32
|
+
.build(app)?;
|
|
33
|
+
|
|
34
|
+
tray.set_icon_as_template(false)?;
|
|
35
|
+
Ok(())
|
|
31
36
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
use crate::app::config::PakeConfig;
|
|
2
|
-
use std::path::PathBuf;
|
|
3
|
-
use tauri::{App,
|
|
2
|
+
use std::{path::PathBuf, str::FromStr};
|
|
3
|
+
use tauri::{App, Url, WebviewUrl, WebviewWindow, WebviewWindowBuilder};
|
|
4
4
|
|
|
5
5
|
#[cfg(target_os = "macos")]
|
|
6
6
|
use tauri::{Theme, TitleBarStyle};
|
|
7
7
|
|
|
8
|
-
pub fn
|
|
8
|
+
pub fn get_window(app: &mut App, config: &PakeConfig, _data_dir: PathBuf) -> WebviewWindow {
|
|
9
9
|
let window_config = config
|
|
10
10
|
.windows
|
|
11
11
|
.first()
|
|
@@ -14,8 +14,8 @@ pub fn build_window(app: &mut App, config: PakeConfig, _data_dir: PathBuf) -> Wi
|
|
|
14
14
|
let user_agent = config.user_agent.get();
|
|
15
15
|
|
|
16
16
|
let url = match window_config.url_type.as_str() {
|
|
17
|
-
"web" =>
|
|
18
|
-
"local" =>
|
|
17
|
+
"web" => WebviewUrl::App(window_config.url.parse().unwrap()),
|
|
18
|
+
"local" => WebviewUrl::App(PathBuf::from(&window_config.url)),
|
|
19
19
|
_ => panic!("url type can only be web or local"),
|
|
20
20
|
};
|
|
21
21
|
|
|
@@ -24,10 +24,10 @@ pub fn build_window(app: &mut App, config: PakeConfig, _data_dir: PathBuf) -> Wi
|
|
|
24
24
|
serde_json::to_string(&window_config).unwrap()
|
|
25
25
|
);
|
|
26
26
|
|
|
27
|
-
let mut window_builder =
|
|
27
|
+
let mut window_builder = WebviewWindowBuilder::new(app, "pake", url)
|
|
28
28
|
.title("")
|
|
29
|
-
.visible(false)
|
|
30
29
|
.user_agent(user_agent)
|
|
30
|
+
.visible(false) // Prevent initial shaking
|
|
31
31
|
.resizable(window_config.resizable)
|
|
32
32
|
.fullscreen(window_config.fullscreen)
|
|
33
33
|
.inner_size(window_config.width, window_config.height)
|
|
@@ -36,8 +36,14 @@ pub fn build_window(app: &mut App, config: PakeConfig, _data_dir: PathBuf) -> Wi
|
|
|
36
36
|
.initialization_script(include_str!("../inject/component.js"))
|
|
37
37
|
.initialization_script(include_str!("../inject/event.js"))
|
|
38
38
|
.initialization_script(include_str!("../inject/style.js"))
|
|
39
|
+
//This is necessary to allow for file injection by external developers for customization purposes.
|
|
39
40
|
.initialization_script(include_str!("../inject/custom.js"));
|
|
40
41
|
|
|
42
|
+
if config.proxy_url != "" {
|
|
43
|
+
window_builder =
|
|
44
|
+
window_builder.proxy_url(Url::from_str(&config.proxy_url.as_str()).unwrap());
|
|
45
|
+
}
|
|
46
|
+
|
|
41
47
|
#[cfg(target_os = "macos")]
|
|
42
48
|
{
|
|
43
49
|
let title_bar_style = if window_config.hide_title_bar {
|
|
@@ -45,7 +51,6 @@ pub fn build_window(app: &mut App, config: PakeConfig, _data_dir: PathBuf) -> Wi
|
|
|
45
51
|
} else {
|
|
46
52
|
TitleBarStyle::Visible
|
|
47
53
|
};
|
|
48
|
-
|
|
49
54
|
window_builder = window_builder.title_bar_style(title_bar_style);
|
|
50
55
|
|
|
51
56
|
if window_config.dark_mode {
|
|
@@ -57,7 +62,7 @@ pub fn build_window(app: &mut App, config: PakeConfig, _data_dir: PathBuf) -> Wi
|
|
|
57
62
|
{
|
|
58
63
|
window_builder = window_builder
|
|
59
64
|
.data_directory(_data_dir)
|
|
60
|
-
.title(app.package_info().name.clone())
|
|
65
|
+
.title(app.package_info().name.clone());
|
|
61
66
|
}
|
|
62
67
|
|
|
63
68
|
window_builder.build().expect("Failed to build window")
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* This file serves as a collection point for external JS and CSS dependencies.
|
|
3
|
-
* It amalgamates these external resources for easier injection into the application.
|
|
4
|
-
* Additionally, you can directly include any script files in this file
|
|
5
|
-
* that you wish to attach to the application.
|
|
6
|
-
*/
|
|
@@ -45,22 +45,16 @@ function isDownloadLink(url) {
|
|
|
45
45
|
'jpg', 'm3u8', 'mov', 'mp3', 'mp4', 'mpa', 'mpg', 'mpeg', 'msi', 'odt',
|
|
46
46
|
'ogg', 'ogv', 'pdf', 'png', 'ppt', 'pptx', 'psd', 'rar', 'raw',
|
|
47
47
|
'svg', 'swf', 'tar', 'tif', 'tiff', 'ts', 'txt', 'wav', 'webm', 'webp',
|
|
48
|
-
'wma', 'wmv', 'xls', 'xlsx', 'xml', 'zip', 'json', 'yaml', '7zip', 'mkv'
|
|
48
|
+
'wma', 'wmv', 'xls', 'xlsx', 'xml', 'zip', 'json', 'yaml', '7zip', 'mkv',
|
|
49
49
|
];
|
|
50
50
|
const downloadLinkPattern = new RegExp(`\\.(${fileExtensions.join('|')})$`, 'i');
|
|
51
51
|
return downloadLinkPattern.test(url);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
// No need to go to the download link.
|
|
55
|
-
function externalDownLoadLink() {
|
|
56
|
-
return ['quickref.me'].indexOf(location.hostname) > -1;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
54
|
document.addEventListener('DOMContentLoaded', () => {
|
|
61
55
|
const tauri = window.__TAURI__;
|
|
62
|
-
const appWindow = tauri.window.
|
|
63
|
-
const invoke = tauri.
|
|
56
|
+
const appWindow = tauri.window.getCurrentWindow();
|
|
57
|
+
const invoke = tauri.core.invoke;
|
|
64
58
|
|
|
65
59
|
if (!document.getElementById('pake-top-dom')) {
|
|
66
60
|
const topDom = document.createElement('div');
|
|
@@ -71,19 +65,19 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
71
65
|
const domEl = document.getElementById('pake-top-dom');
|
|
72
66
|
|
|
73
67
|
domEl.addEventListener('touchstart', () => {
|
|
74
|
-
appWindow.startDragging()
|
|
68
|
+
appWindow.startDragging();
|
|
75
69
|
});
|
|
76
70
|
|
|
77
71
|
domEl.addEventListener('mousedown', e => {
|
|
78
72
|
e.preventDefault();
|
|
79
73
|
if (e.buttons === 1 && e.detail !== 2) {
|
|
80
|
-
appWindow.startDragging()
|
|
74
|
+
appWindow.startDragging();
|
|
81
75
|
}
|
|
82
76
|
});
|
|
83
77
|
|
|
84
78
|
domEl.addEventListener('dblclick', () => {
|
|
85
79
|
appWindow.isFullscreen().then(fullscreen => {
|
|
86
|
-
appWindow.setFullscreen(!fullscreen)
|
|
80
|
+
appWindow.setFullscreen(!fullscreen);
|
|
87
81
|
});
|
|
88
82
|
});
|
|
89
83
|
|
|
@@ -181,35 +175,43 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
181
175
|
};
|
|
182
176
|
}
|
|
183
177
|
|
|
178
|
+
const isExternalLink = link => window.location.host !== link.host;
|
|
184
179
|
// process special download protocol['data:','blob:']
|
|
185
180
|
const isSpecialDownload = url => ['blob', 'data'].some(protocol => url.startsWith(protocol));
|
|
186
181
|
|
|
187
182
|
const isDownloadRequired = (url, anchorElement, e) => anchorElement.download || e.metaKey || e.ctrlKey || isDownloadLink(url);
|
|
188
183
|
|
|
189
|
-
const handleExternalLink = (
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const handleDownloadLink = (e, url, filename) => {
|
|
195
|
-
e.preventDefault();
|
|
196
|
-
invoke('download_file', { params: { url, filename } });
|
|
184
|
+
const handleExternalLink = (url) => {
|
|
185
|
+
invoke('plugin:shell|open', {
|
|
186
|
+
path: url,
|
|
187
|
+
});
|
|
197
188
|
};
|
|
198
189
|
|
|
199
190
|
const detectAnchorElementClick = e => {
|
|
200
191
|
const anchorElement = e.target.closest('a');
|
|
201
|
-
if (anchorElement && anchorElement.href) {
|
|
202
|
-
if (!anchorElement.target) {
|
|
203
|
-
anchorElement.target = '_self';
|
|
204
|
-
}
|
|
205
192
|
|
|
193
|
+
if (anchorElement && anchorElement.href) {
|
|
194
|
+
const target = anchorElement.target;
|
|
206
195
|
const hrefUrl = new URL(anchorElement.href);
|
|
207
196
|
const absoluteUrl = hrefUrl.href;
|
|
208
197
|
let filename = anchorElement.download || getFilenameFromUrl(absoluteUrl);
|
|
209
198
|
|
|
199
|
+
// Handling external link redirection, _blank will automatically open.
|
|
200
|
+
if (target === '_blank') {
|
|
201
|
+
e.preventDefault();
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (target === '_new') {
|
|
206
|
+
e.preventDefault();
|
|
207
|
+
handleExternalLink(absoluteUrl);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
210
211
|
// Process download links for Rust to handle.
|
|
211
|
-
if (isDownloadRequired(absoluteUrl, anchorElement, e) && !
|
|
212
|
-
|
|
212
|
+
if (isDownloadRequired(absoluteUrl, anchorElement, e) && !isSpecialDownload(absoluteUrl)) {
|
|
213
|
+
e.preventDefault();
|
|
214
|
+
invoke('download_file', { params: { url: absoluteUrl, filename } });
|
|
213
215
|
}
|
|
214
216
|
}
|
|
215
217
|
};
|
|
@@ -222,7 +224,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
222
224
|
|
|
223
225
|
// Rewrite the window.open function.
|
|
224
226
|
const originalWindowOpen = window.open;
|
|
225
|
-
window.open = function
|
|
227
|
+
window.open = function(url, name, specs) {
|
|
226
228
|
// Apple login and google login
|
|
227
229
|
if (name === 'AppleAuthentication') {
|
|
228
230
|
//do nothing
|
|
@@ -231,7 +233,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
231
233
|
} else {
|
|
232
234
|
const baseUrl = window.location.origin + window.location.pathname;
|
|
233
235
|
const hrefUrl = new URL(url, baseUrl);
|
|
234
|
-
|
|
236
|
+
handleExternalLink(hrefUrl.href);
|
|
235
237
|
}
|
|
236
238
|
// Call the original window.open function to maintain its normal functionality.
|
|
237
239
|
return originalWindowOpen.call(window, url, name, specs);
|
|
@@ -119,7 +119,8 @@ window.addEventListener('DOMContentLoaded', _event => {
|
|
|
119
119
|
display: none !important;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
#react-root [data-testid="DMDrawer"]
|
|
122
|
+
#react-root [data-testid="DMDrawer"],
|
|
123
|
+
#root > main > footer.justify-center.ease-in {
|
|
123
124
|
visibility: hidden !important;
|
|
124
125
|
}
|
|
125
126
|
|
|
@@ -333,6 +334,14 @@ window.addEventListener('DOMContentLoaded', _event => {
|
|
|
333
334
|
#__next>div>div>.flex.h-screen.w-full.flex-col.items-center {
|
|
334
335
|
padding-top: 20px;
|
|
335
336
|
}
|
|
337
|
+
|
|
338
|
+
body > div.relative.flex.h-full.w-full.overflow-hidden.transition-colors.z-0 > div.z-\\[21\\].flex-shrink-0.overflow-x-hidden.bg-token-sidebar-surface-primary.max-md\\:\\!w-0 > div > div > div > nav > div.flex.justify-between.h-\\[60px\\].items-center.md\\:h-header-height {
|
|
339
|
+
padding-top: 25px;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
body > div.relative.flex.h-full.w-full.overflow-hidden.transition-colors.z-0 > div.relative.flex.h-full.max-w-full.flex-1.flex-col.overflow-hidden > main > div.composer-parent.flex.h-full.flex-col.focus-visible\\:outline-0 > div.flex-1.overflow-hidden.\\@container\\/thread > div > div.absolute.left-0.right-0 > div{
|
|
343
|
+
padding-top: 35px;
|
|
344
|
+
}
|
|
336
345
|
|
|
337
346
|
#__next .sticky.left-0.right-0.top-0.z-20.bg-black{
|
|
338
347
|
padding-top: 0px;
|
|
@@ -378,6 +387,10 @@ window.addEventListener('DOMContentLoaded', _event => {
|
|
|
378
387
|
.lark > .main-wrapper [data-testid="aside"] {
|
|
379
388
|
top: 15px;
|
|
380
389
|
}
|
|
390
|
+
|
|
391
|
+
#global > div.header-container > .mask-paper {
|
|
392
|
+
padding-top: 20px;
|
|
393
|
+
}
|
|
381
394
|
|
|
382
395
|
#background.ytd-masthead {
|
|
383
396
|
height: 68px;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
2
|
+
mod app;
|
|
3
|
+
mod util;
|
|
4
|
+
|
|
5
|
+
use app::{invoke, menu::set_system_tray, window};
|
|
6
|
+
use invoke::{download_file, download_file_by_binary};
|
|
7
|
+
use std::str::FromStr;
|
|
8
|
+
use std::sync::{Arc, Mutex};
|
|
9
|
+
use std::time::{Duration, Instant};
|
|
10
|
+
|
|
11
|
+
use tauri::Manager;
|
|
12
|
+
use tauri_plugin_global_shortcut::{GlobalShortcutExt, Shortcut};
|
|
13
|
+
use tauri_plugin_window_state::Builder as windowStatePlugin;
|
|
14
|
+
use util::{get_data_dir, get_pake_config};
|
|
15
|
+
use window::get_window;
|
|
16
|
+
|
|
17
|
+
pub fn run_app() {
|
|
18
|
+
let (pake_config, tauri_config) = get_pake_config();
|
|
19
|
+
|
|
20
|
+
let tauri_app = tauri::Builder::default();
|
|
21
|
+
|
|
22
|
+
let show_system_tray = pake_config.show_system_tray();
|
|
23
|
+
|
|
24
|
+
// Save the value of toggle_app_shortcut before pake_config is moved
|
|
25
|
+
let activation_shortcut = pake_config.windows[0].activation_shortcut.clone();
|
|
26
|
+
let init_fullscreen = pake_config.windows[0].fullscreen.clone();
|
|
27
|
+
|
|
28
|
+
let window_state_plugin = if init_fullscreen {
|
|
29
|
+
windowStatePlugin::default()
|
|
30
|
+
.with_state_flags(tauri_plugin_window_state::StateFlags::FULLSCREEN)
|
|
31
|
+
.build()
|
|
32
|
+
} else {
|
|
33
|
+
windowStatePlugin::default().build()
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
tauri_app
|
|
37
|
+
.plugin(window_state_plugin)
|
|
38
|
+
.plugin(tauri_plugin_oauth::init())
|
|
39
|
+
.plugin(tauri_plugin_http::init())
|
|
40
|
+
.plugin(tauri_plugin_shell::init())
|
|
41
|
+
.invoke_handler(tauri::generate_handler![
|
|
42
|
+
download_file,
|
|
43
|
+
download_file_by_binary
|
|
44
|
+
])
|
|
45
|
+
.setup(move |app| {
|
|
46
|
+
let data_dir = get_data_dir(&app.app_handle(), tauri_config.clone());
|
|
47
|
+
|
|
48
|
+
let _window = get_window(app, &pake_config, data_dir);
|
|
49
|
+
|
|
50
|
+
// Prevent initial shaking
|
|
51
|
+
_window.show().unwrap();
|
|
52
|
+
|
|
53
|
+
if show_system_tray {
|
|
54
|
+
let _ = set_system_tray(&app.app_handle());
|
|
55
|
+
} else {
|
|
56
|
+
app.app_handle().remove_tray_by_id("pake-tray");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if !activation_shortcut.is_empty() {
|
|
60
|
+
let app_handle = app.app_handle().clone();
|
|
61
|
+
let shortcut_hotkey = Shortcut::from_str(&activation_shortcut.as_str()).unwrap();
|
|
62
|
+
let last_triggered = Arc::new(Mutex::new(Instant::now()));
|
|
63
|
+
|
|
64
|
+
app_handle
|
|
65
|
+
.plugin(
|
|
66
|
+
tauri_plugin_global_shortcut::Builder::new()
|
|
67
|
+
.with_handler({
|
|
68
|
+
let last_triggered = Arc::clone(&last_triggered);
|
|
69
|
+
move |app, event, _shortcut| {
|
|
70
|
+
// Fixed the bug of tauri's hidden call, which caused repeated execution
|
|
71
|
+
let now = Instant::now();
|
|
72
|
+
let mut last = last_triggered.lock().unwrap();
|
|
73
|
+
if now.duration_since(*last) < Duration::from_millis(500) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
*last = now;
|
|
77
|
+
|
|
78
|
+
if shortcut_hotkey.eq(event) {
|
|
79
|
+
let window = app.get_webview_window("pake").unwrap();
|
|
80
|
+
let is_visible = window.is_visible().unwrap();
|
|
81
|
+
|
|
82
|
+
match is_visible {
|
|
83
|
+
true => {
|
|
84
|
+
window.minimize().unwrap();
|
|
85
|
+
}
|
|
86
|
+
false => {
|
|
87
|
+
window.unminimize().unwrap();
|
|
88
|
+
window.set_focus().unwrap();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
.build(),
|
|
95
|
+
)
|
|
96
|
+
.expect("Error registering global evoke shortcuts!");
|
|
97
|
+
|
|
98
|
+
app.global_shortcut().register(shortcut_hotkey)?;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
Ok(())
|
|
102
|
+
})
|
|
103
|
+
.on_window_event(|window, event| {
|
|
104
|
+
if let tauri::WindowEvent::CloseRequested { api, .. } = event {
|
|
105
|
+
let window = window.clone();
|
|
106
|
+
|
|
107
|
+
#[cfg(target_os = "macos")]
|
|
108
|
+
{
|
|
109
|
+
let window_handle = window.clone();
|
|
110
|
+
tauri::async_runtime::spawn(async move {
|
|
111
|
+
if window_handle.is_fullscreen().unwrap_or(false) {
|
|
112
|
+
window_handle.set_fullscreen(false).unwrap();
|
|
113
|
+
// Give a small delay to ensure the full-screen exit operation is completed.
|
|
114
|
+
tokio::time::sleep(Duration::from_millis(900)).await;
|
|
115
|
+
}
|
|
116
|
+
window_handle.minimize().unwrap();
|
|
117
|
+
window_handle.hide().unwrap();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
#[cfg(not(target_os = "macos"))]
|
|
122
|
+
window.close().unwrap();
|
|
123
|
+
|
|
124
|
+
api.prevent_close();
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
.run(tauri::generate_context!())
|
|
128
|
+
.expect("error while running tauri application");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
pub fn run() {
|
|
132
|
+
run_app()
|
|
133
|
+
}
|
package/src-tauri/src/main.rs
CHANGED
|
@@ -3,93 +3,6 @@
|
|
|
3
3
|
windows_subsystem = "windows"
|
|
4
4
|
)]
|
|
5
5
|
|
|
6
|
-
mod app;
|
|
7
|
-
mod util;
|
|
8
|
-
|
|
9
|
-
use app::{invoke, menu, window};
|
|
10
|
-
use invoke::{download_file, download_file_by_binary};
|
|
11
|
-
use menu::{get_system_tray, system_tray_handle};
|
|
12
|
-
use tauri::{GlobalShortcutManager, Manager};
|
|
13
|
-
use util::{get_data_dir, get_pake_config};
|
|
14
|
-
use window::build_window;
|
|
15
|
-
|
|
16
|
-
#[cfg(target_os = "macos")]
|
|
17
|
-
use std::time::Duration;
|
|
18
|
-
|
|
19
|
-
pub fn run_app() {
|
|
20
|
-
let (pake_config, tauri_config) = get_pake_config();
|
|
21
|
-
let data_dir = get_data_dir(tauri_config);
|
|
22
|
-
|
|
23
|
-
let mut tauri_app = tauri::Builder::default();
|
|
24
|
-
|
|
25
|
-
let show_system_tray = pake_config.show_system_tray();
|
|
26
|
-
let system_tray = get_system_tray();
|
|
27
|
-
|
|
28
|
-
if show_system_tray {
|
|
29
|
-
tauri_app = tauri_app
|
|
30
|
-
.system_tray(system_tray)
|
|
31
|
-
.on_system_tray_event(system_tray_handle);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Save the value of toggle_app_shortcut before pake_config is moved
|
|
35
|
-
let activation_shortcut = pake_config.windows[0].activation_shortcut.clone();
|
|
36
|
-
|
|
37
|
-
tauri_app
|
|
38
|
-
.plugin(tauri_plugin_window_state::Builder::default().build())
|
|
39
|
-
.plugin(tauri_plugin_oauth::init())
|
|
40
|
-
.invoke_handler(tauri::generate_handler![
|
|
41
|
-
download_file,
|
|
42
|
-
download_file_by_binary
|
|
43
|
-
])
|
|
44
|
-
.setup(move |app| {
|
|
45
|
-
let _window = build_window(app, pake_config, data_dir);
|
|
46
|
-
_window.show().unwrap();
|
|
47
|
-
if !activation_shortcut.is_empty() {
|
|
48
|
-
let app_handle = app.app_handle().clone();
|
|
49
|
-
app_handle
|
|
50
|
-
.global_shortcut_manager()
|
|
51
|
-
.register(activation_shortcut.as_str(), move || {
|
|
52
|
-
match _window.is_visible().unwrap() {
|
|
53
|
-
true => _window.hide().unwrap(),
|
|
54
|
-
false => {
|
|
55
|
-
_window.show().unwrap();
|
|
56
|
-
_window.set_focus().unwrap();
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
})
|
|
60
|
-
.expect("Error registering global evoke shortcuts!");
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
Ok(())
|
|
64
|
-
})
|
|
65
|
-
.on_window_event(|event| {
|
|
66
|
-
if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() {
|
|
67
|
-
let window = event.window();
|
|
68
|
-
|
|
69
|
-
#[cfg(target_os = "macos")]
|
|
70
|
-
{
|
|
71
|
-
let window_handle = window.clone();
|
|
72
|
-
tauri::async_runtime::spawn(async move {
|
|
73
|
-
if window_handle.is_fullscreen().unwrap_or(false) {
|
|
74
|
-
window_handle.set_fullscreen(false).unwrap();
|
|
75
|
-
// Give a small delay to ensure the full-screen exit operation is completed.
|
|
76
|
-
tokio::time::sleep(Duration::from_millis(900)).await;
|
|
77
|
-
}
|
|
78
|
-
window_handle.minimize().unwrap();
|
|
79
|
-
window_handle.hide().unwrap();
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
#[cfg(not(target_os = "macos"))]
|
|
84
|
-
window.close().unwrap();
|
|
85
|
-
|
|
86
|
-
api.prevent_close();
|
|
87
|
-
}
|
|
88
|
-
})
|
|
89
|
-
.run(tauri::generate_context!())
|
|
90
|
-
.expect("error while running tauri application");
|
|
91
|
-
}
|
|
92
|
-
|
|
93
6
|
fn main() {
|
|
94
|
-
|
|
7
|
+
app_lib::run()
|
|
95
8
|
}
|
package/src-tauri/src/util.rs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
use crate::app::config::PakeConfig;
|
|
2
2
|
use std::env;
|
|
3
3
|
use std::path::PathBuf;
|
|
4
|
-
use tauri::{
|
|
4
|
+
use tauri::{AppHandle, Config, Manager, WebviewWindow};
|
|
5
5
|
|
|
6
6
|
pub fn get_pake_config() -> (PakeConfig, Config) {
|
|
7
7
|
#[cfg(feature = "cli-build")]
|
|
@@ -23,10 +23,12 @@ pub fn get_pake_config() -> (PakeConfig, Config) {
|
|
|
23
23
|
(pake_config, tauri_config)
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
pub fn get_data_dir(_tauri_config: Config) -> PathBuf {
|
|
26
|
+
pub fn get_data_dir(app: &AppHandle, _tauri_config: Config) -> PathBuf {
|
|
27
27
|
{
|
|
28
|
-
let package_name = _tauri_config.
|
|
29
|
-
let data_dir =
|
|
28
|
+
let package_name = _tauri_config.product_name.unwrap();
|
|
29
|
+
let data_dir = app
|
|
30
|
+
.path()
|
|
31
|
+
.config_dir()
|
|
30
32
|
.expect("Failed to get data dirname")
|
|
31
33
|
.join(package_name);
|
|
32
34
|
|
|
@@ -38,7 +40,7 @@ pub fn get_data_dir(_tauri_config: Config) -> PathBuf {
|
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
pub fn show_toast(window: &
|
|
43
|
+
pub fn show_toast(window: &WebviewWindow, message: &str) {
|
|
42
44
|
let script = format!(r#"pakeToast("{}");"#, message);
|
|
43
45
|
window.eval(&script).unwrap();
|
|
44
46
|
}
|