pake-cli 1.3.1 → 2.0.0-alpha6
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 +26 -22
- package/dist/about_pake.html +16 -0
- package/dist/cli.js +389 -86
- package/package.json +3 -2
- package/src-tauri/.cargo/cn_config.bak +14 -0
- package/src-tauri/Cargo.lock +1420 -586
- package/src-tauri/Cargo.toml +13 -14
- package/src-tauri/pake.json +28 -0
- package/src-tauri/src/app/config.rs +63 -0
- package/src-tauri/src/app/invoke.rs +47 -0
- package/src-tauri/src/app/menu.rs +114 -0
- package/src-tauri/src/app/mod.rs +4 -0
- package/src-tauri/src/app/window.rs +49 -0
- package/src-tauri/src/inject/component.js +143 -0
- package/src-tauri/src/inject/event.js +175 -0
- package/src-tauri/src/{pake.js → inject/style.js} +41 -141
- package/src-tauri/src/main.rs +58 -268
- package/src-tauri/src/util.rs +78 -0
- package/src-tauri/tauri.conf.json +26 -29
- package/src-tauri/tauri.linux.conf.json +18 -30
- package/dist/index.html +0 -22
- package/dist/script.js +0 -7
|
@@ -1,39 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* 见 <https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values>
|
|
4
|
-
* @typedef {() => void} OnKeyDown 使用者按下 [CtrlKey] 或者 ⌘ [KeyboardKey]时应该执行的行为
|
|
5
|
-
* 以 Ctrl键或者Meta 键 (⌘) 为首的快捷键清单。
|
|
6
|
-
* 每个写在这里的 shortcuts 都会运行 {@link Event.preventDefault}.
|
|
7
|
-
* @type {Record<KeyboardKey, OnKeyDown>}
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const metaKeyShortcuts = {
|
|
11
|
-
ArrowUp: () => scrollTo(0, 0),
|
|
12
|
-
ArrowDown: () => scrollTo(0, document.body.scrollHeight),
|
|
13
|
-
"[": () => window.history.back(),
|
|
14
|
-
"]": () => window.history.forward(),
|
|
15
|
-
r: () => window.location.reload(),
|
|
16
|
-
"-": () => zoomOut(),
|
|
17
|
-
"=": () => zoomIn(),
|
|
18
|
-
"+": () => zoomIn(),
|
|
19
|
-
0: () => zoomCommon(() => "100%"),
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const ctrlKeyShortcuts = {
|
|
23
|
-
ArrowUp: () => scrollTo(0, 0),
|
|
24
|
-
ArrowDown: () => scrollTo(0, document.body.scrollHeight),
|
|
25
|
-
ArrowLeft: () => window.history.back(),
|
|
26
|
-
ArrowRight: () => window.history.forward(),
|
|
27
|
-
r: () => window.location.reload(),
|
|
28
|
-
"-": () => zoomOut(),
|
|
29
|
-
"=": () => zoomIn(),
|
|
30
|
-
"+": () => zoomIn(),
|
|
31
|
-
0: () => zoomCommon(() => "100%"),
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
window.addEventListener("DOMContentLoaded", (_event) => {
|
|
35
|
-
const style = document.createElement("style");
|
|
36
|
-
style.innerHTML = `
|
|
1
|
+
window.addEventListener('DOMContentLoaded', (_event) => {
|
|
2
|
+
const css = `
|
|
37
3
|
#page #footer-wrapper,
|
|
38
4
|
.drawing-board .toolbar .toolbar-action,
|
|
39
5
|
.c-swiper-container,
|
|
@@ -49,6 +15,8 @@ window.addEventListener("DOMContentLoaded", (_event) => {
|
|
|
49
15
|
#masthead-ad,
|
|
50
16
|
#app > header > div > div.menu,
|
|
51
17
|
#root > div > div.fixed.top-0.left-0.w-64.h-screen.p-10.pb-0.flex.flex-col.justify-between > div > div.space-y-4 > a:nth-child(3),
|
|
18
|
+
#app > div.layout > div.main-container > div.side-bar > div,
|
|
19
|
+
#app > div.layout > div.main-container > div.side-bar > li.divider,
|
|
52
20
|
#Rightbar > div:nth-child(6) > div.sidebar_compliance {
|
|
53
21
|
display: none !important;
|
|
54
22
|
}
|
|
@@ -68,7 +36,7 @@ window.addEventListener("DOMContentLoaded", (_event) => {
|
|
|
68
36
|
}
|
|
69
37
|
|
|
70
38
|
.fui-FluentProvider .fui-Button[data-testid="HomeButton"]{
|
|
71
|
-
|
|
39
|
+
padding-top: 20px;
|
|
72
40
|
}
|
|
73
41
|
|
|
74
42
|
.chakra-ui-light #app .chakra-heading,
|
|
@@ -77,7 +45,7 @@ window.addEventListener("DOMContentLoaded", (_event) => {
|
|
|
77
45
|
.chakra-ui-dark #app .chakra-stack,
|
|
78
46
|
.app-main .sidebar-mouse-in-out,
|
|
79
47
|
.chakra-modal__content-container .chakra-modal__header > div > div {
|
|
80
|
-
|
|
48
|
+
padding-top: 10px;
|
|
81
49
|
}
|
|
82
50
|
|
|
83
51
|
#__next .overflow-hidden>.hidden.bg-gray-900 span.rounded-md.bg-yellow-200 {
|
|
@@ -89,7 +57,7 @@ window.addEventListener("DOMContentLoaded", (_event) => {
|
|
|
89
57
|
}
|
|
90
58
|
|
|
91
59
|
#__next .absolute .px-3.pt-2.pb-3.text-center {
|
|
92
|
-
|
|
60
|
+
visibility: hidden;
|
|
93
61
|
}
|
|
94
62
|
|
|
95
63
|
.lark > .dashboard-sidebar, .lark > .dashboard-sidebar > .sidebar-user-info , .lark > .dashboard-sidebar .index-module_wrapper_F-Wbq{
|
|
@@ -130,7 +98,8 @@ window.addEventListener("DOMContentLoaded", (_event) => {
|
|
|
130
98
|
top: 30px;
|
|
131
99
|
}
|
|
132
100
|
|
|
133
|
-
.geist-page nav.dashboard_nav__PRmJv
|
|
101
|
+
.geist-page nav.dashboard_nav__PRmJv,
|
|
102
|
+
#app > div.layout > div.header-container.showSearchBoxOrHeaderFixed > header > a {
|
|
134
103
|
padding-top:10px;
|
|
135
104
|
}
|
|
136
105
|
|
|
@@ -285,6 +254,33 @@ window.addEventListener("DOMContentLoaded", (_event) => {
|
|
|
285
254
|
}
|
|
286
255
|
}
|
|
287
256
|
|
|
257
|
+
@media (min-width:1024px){
|
|
258
|
+
#__next .text-base.lg\\:max-w-xl, #__next form.stretch.lg\\:max-w-2xl {
|
|
259
|
+
max-width: 44rem;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
@media (min-width:1280px){
|
|
264
|
+
#__next .text-base.xl\\:max-w-3xl, #__next form.stretch.xl\\:max-w-3xl {
|
|
265
|
+
max-width: 48rem;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
@media (min-width:640px){
|
|
270
|
+
#__next .sticky.top-0{
|
|
271
|
+
padding-top: 15px;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
#__next .prose ol {
|
|
276
|
+
overflow: hidden;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
#__next .prose ol li p {
|
|
280
|
+
margin: 0;
|
|
281
|
+
display: inline;
|
|
282
|
+
}
|
|
283
|
+
|
|
288
284
|
#pack-top-dom:active {
|
|
289
285
|
cursor: grabbing;
|
|
290
286
|
cursor: -webkit-grabbing;
|
|
@@ -297,109 +293,13 @@ window.addEventListener("DOMContentLoaded", (_event) => {
|
|
|
297
293
|
width: 100%;
|
|
298
294
|
height: 20px;
|
|
299
295
|
cursor: grab;
|
|
300
|
-
|
|
296
|
+
-webkit-app-region: drag;
|
|
301
297
|
user-select: none;
|
|
298
|
+
-webkit-user-select: none;
|
|
302
299
|
z-index: 90000;
|
|
303
300
|
}
|
|
304
301
|
`;
|
|
305
|
-
document.
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
document.body.appendChild(topDom);
|
|
309
|
-
|
|
310
|
-
const domEl = document.getElementById("pack-top-dom");
|
|
311
|
-
|
|
312
|
-
domEl.addEventListener("mousedown", (e) => {
|
|
313
|
-
e && e.preventDefault();
|
|
314
|
-
if (e.buttons === 1 && e.detail !== 2) {
|
|
315
|
-
window.ipc.postMessage("drag_window");
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
domEl.addEventListener("touchstart", () => {
|
|
320
|
-
window.ipc.postMessage("drag_window");
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
domEl.addEventListener("dblclick", () => {
|
|
324
|
-
window.ipc.postMessage("fullscreen");
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
document.addEventListener("keyup", function (event) {
|
|
328
|
-
const preventDefault = (f) => {
|
|
329
|
-
event.preventDefault();
|
|
330
|
-
f();
|
|
331
|
-
};
|
|
332
|
-
if (/windows|linux/i.test(navigator.userAgent)) {
|
|
333
|
-
if (event.ctrlKey && event.key in ctrlKeyShortcuts) {
|
|
334
|
-
preventDefault(ctrlKeyShortcuts[event.key]);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
if (/macintosh|mac os x/i.test(navigator.userAgent)) {
|
|
338
|
-
if (event.metaKey && event.key in metaKeyShortcuts) {
|
|
339
|
-
preventDefault(metaKeyShortcuts[event.key]);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
document.addEventListener("click", (e) => {
|
|
345
|
-
const origin = e.target.closest("a");
|
|
346
|
-
if (origin && origin.href) {
|
|
347
|
-
const target = origin.target
|
|
348
|
-
origin.target = "_self";
|
|
349
|
-
const hrefUrl = new URL(origin.href)
|
|
350
|
-
|
|
351
|
-
if (
|
|
352
|
-
window.location.host !== hrefUrl.host && // 如果 a 标签内链接的域名和当前页面的域名不一致 且
|
|
353
|
-
target === '_blank' // a 标签内链接的 target 属性为 _blank 时
|
|
354
|
-
) {
|
|
355
|
-
e.preventDefault();
|
|
356
|
-
window.ipc.postMessage(`open_browser:${origin.href}`);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
});
|
|
302
|
+
const styleElement = document.createElement('style');
|
|
303
|
+
styleElement.innerHTML = css;
|
|
304
|
+
document.head.appendChild(styleElement);
|
|
360
305
|
});
|
|
361
|
-
|
|
362
|
-
setDefaultZoom();
|
|
363
|
-
|
|
364
|
-
function setDefaultZoom() {
|
|
365
|
-
const htmlZoom = window.localStorage.getItem("htmlZoom");
|
|
366
|
-
if (htmlZoom) {
|
|
367
|
-
document.getElementsByTagName("html")[0].style.zoom = htmlZoom;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* @param {(htmlZoom: string) => string} [zoomRule]
|
|
373
|
-
*/
|
|
374
|
-
function zoomCommon(zoomRule) {
|
|
375
|
-
const htmlZoom = window.localStorage.getItem("htmlZoom") || "100%";
|
|
376
|
-
const html = document.getElementsByTagName("html")[0];
|
|
377
|
-
const zoom = zoomRule(htmlZoom);
|
|
378
|
-
html.style.zoom = zoom;
|
|
379
|
-
window.localStorage.setItem("htmlZoom", zoom);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
function zoomIn() {
|
|
383
|
-
zoomCommon((htmlZoom) => `${Math.min(parseInt(htmlZoom) + 10, 200)}%`);
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
function zoomOut() {
|
|
387
|
-
zoomCommon((htmlZoom) => `${Math.max(parseInt(htmlZoom) - 10, 30)}%`);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
function pakeToast(msg) {
|
|
392
|
-
const m = document.createElement('div');
|
|
393
|
-
m.innerHTML = msg;
|
|
394
|
-
m.style.cssText = "max-width:60%;min-width: 180px;padding:0 8px;height: 36px;color: rgb(255, 255, 255);line-height: 36px;text-align: center;border-radius: 4px;position: fixed;bottom:16px;right: 16px;transform: translate(-50%, -50%);z-index: 999999;background: rgba(0, 0, 0,.9);font-size: 14px;";
|
|
395
|
-
document.body.appendChild(m);
|
|
396
|
-
setTimeout(function() {
|
|
397
|
-
const d = 0.5;
|
|
398
|
-
m.style.transition = 'transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
|
|
399
|
-
m.style.opacity = '0';
|
|
400
|
-
setTimeout(function() {
|
|
401
|
-
document.body.removeChild(m)
|
|
402
|
-
}, d * 1000);
|
|
403
|
-
}, 2500);
|
|
404
|
-
}
|
|
405
|
-
|
package/src-tauri/src/main.rs
CHANGED
|
@@ -1,278 +1,68 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
use wry::application::window::Icon;
|
|
28
|
-
|
|
29
|
-
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
|
30
|
-
use wry::webview::WebContext;
|
|
31
|
-
|
|
32
|
-
enum UserEvent {
|
|
33
|
-
DownloadStarted(String, String),
|
|
34
|
-
DownloadComplete(Option<PathBuf>, bool),
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
fn main() -> wry::Result<()> {
|
|
38
|
-
#[cfg(target_os = "macos")]
|
|
39
|
-
let (menu_bar_menu, close_item) = {
|
|
40
|
-
let mut menu_bar_menu = Menu::new();
|
|
41
|
-
let mut first_menu = Menu::new();
|
|
42
|
-
first_menu.add_native_item(MenuItem::Hide);
|
|
43
|
-
first_menu.add_native_item(MenuItem::EnterFullScreen);
|
|
44
|
-
first_menu.add_native_item(MenuItem::Minimize);
|
|
45
|
-
first_menu.add_native_item(MenuItem::Separator);
|
|
46
|
-
first_menu.add_native_item(MenuItem::Copy);
|
|
47
|
-
first_menu.add_native_item(MenuItem::Cut);
|
|
48
|
-
first_menu.add_native_item(MenuItem::Paste);
|
|
49
|
-
first_menu.add_native_item(MenuItem::Undo);
|
|
50
|
-
first_menu.add_native_item(MenuItem::Redo);
|
|
51
|
-
first_menu.add_native_item(MenuItem::SelectAll);
|
|
52
|
-
first_menu.add_native_item(MenuItem::Separator);
|
|
53
|
-
let close_item = first_menu.add_item(
|
|
54
|
-
MenuItemAttributes::new("CloseWindow")
|
|
55
|
-
.with_accelerators(&Accelerator::new(SysMods::Cmd, KeyCode::KeyW)),
|
|
56
|
-
);
|
|
57
|
-
first_menu.add_native_item(MenuItem::Quit);
|
|
58
|
-
menu_bar_menu.add_submenu("App", true, first_menu);
|
|
59
|
-
(menu_bar_menu, close_item)
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
|
63
|
-
let (
|
|
64
|
-
package_name,
|
|
65
|
-
WindowConfig {
|
|
66
|
-
url,
|
|
67
|
-
width,
|
|
68
|
-
height,
|
|
69
|
-
resizable,
|
|
70
|
-
fullscreen,
|
|
71
|
-
..
|
|
72
|
-
},
|
|
73
|
-
) = {
|
|
74
|
-
let (package_name, windows_config) = get_windows_config();
|
|
75
|
-
(
|
|
76
|
-
package_name
|
|
77
|
-
.expect("can't get package name in config file")
|
|
78
|
-
.to_lowercase(),
|
|
79
|
-
windows_config.unwrap_or_default(),
|
|
80
|
-
)
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
#[cfg(target_os = "macos")]
|
|
84
|
-
let WindowConfig {
|
|
85
|
-
url,
|
|
86
|
-
width,
|
|
87
|
-
height,
|
|
88
|
-
resizable,
|
|
89
|
-
transparent,
|
|
90
|
-
fullscreen,
|
|
91
|
-
..
|
|
92
|
-
} = get_windows_config().1.unwrap_or_default();
|
|
93
|
-
|
|
94
|
-
let event_loop: EventLoop<UserEvent> = EventLoop::with_user_event();
|
|
95
|
-
let proxy = event_loop.create_proxy();
|
|
96
|
-
let common_window = WindowBuilder::new()
|
|
97
|
-
.with_title("")
|
|
98
|
-
.with_resizable(resizable)
|
|
99
|
-
.with_fullscreen(if fullscreen {
|
|
100
|
-
Some(Fullscreen::Borderless(None))
|
|
101
|
-
} else {
|
|
102
|
-
None
|
|
103
|
-
})
|
|
104
|
-
.with_inner_size(wry::application::dpi::LogicalSize::new(width, height));
|
|
105
|
-
|
|
106
|
-
#[cfg(target_os = "windows")]
|
|
107
|
-
let window = {
|
|
108
|
-
let mut icon_path = format!("png/{}_32.ico", package_name);
|
|
109
|
-
// If there is no setting, use the default one.
|
|
110
|
-
if !std::path::Path::new(&icon_path).exists() {
|
|
111
|
-
icon_path = "png/icon_32.ico".to_string();
|
|
112
|
-
}
|
|
113
|
-
let icon = load_icon(std::path::Path::new(&icon_path));
|
|
114
|
-
common_window
|
|
115
|
-
.with_decorations(true)
|
|
116
|
-
.with_window_icon(Some(icon))
|
|
117
|
-
.build(&event_loop)
|
|
118
|
-
.unwrap()
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
#[cfg(target_os = "linux")]
|
|
122
|
-
let window = common_window.build(&event_loop).unwrap();
|
|
123
|
-
|
|
124
|
-
#[cfg(target_os = "macos")]
|
|
125
|
-
let window = common_window
|
|
126
|
-
.with_fullsize_content_view(true)
|
|
127
|
-
.with_titlebar_buttons_hidden(false)
|
|
128
|
-
.with_titlebar_transparent(transparent)
|
|
129
|
-
.with_title_hidden(true)
|
|
130
|
-
.with_menu(menu_bar_menu)
|
|
131
|
-
.build(&event_loop)
|
|
132
|
-
.unwrap();
|
|
133
|
-
|
|
134
|
-
// Handling events of JS -> Rust
|
|
135
|
-
let handler = move |window: &Window, req: String| {
|
|
136
|
-
if req == "drag_window" {
|
|
137
|
-
let _ = window.drag_window();
|
|
138
|
-
} else if req == "fullscreen" {
|
|
139
|
-
let is_maximized = window.is_maximized();
|
|
140
|
-
window.set_maximized(!is_maximized);
|
|
141
|
-
} else if req.starts_with("open_browser") {
|
|
142
|
-
let href = req.replace("open_browser:", "");
|
|
143
|
-
webbrowser::open(&href).expect("no browser");
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
let download_started = {
|
|
148
|
-
let proxy = proxy.clone();
|
|
149
|
-
move |uri: String, default_path: &mut PathBuf| {
|
|
150
|
-
let path = download_dir()
|
|
151
|
-
.unwrap()
|
|
152
|
-
.join(default_path.display().to_string())
|
|
153
|
-
.as_path()
|
|
154
|
-
.to_path_buf();
|
|
155
|
-
*default_path = path.clone();
|
|
156
|
-
let submitted = proxy
|
|
157
|
-
.send_event(UserEvent::DownloadStarted(uri, path.display().to_string()))
|
|
158
|
-
.is_ok();
|
|
159
|
-
submitted
|
|
160
|
-
}
|
|
161
|
-
};
|
|
1
|
+
#![cfg_attr(
|
|
2
|
+
all(not(debug_assertions), target_os = "windows"),
|
|
3
|
+
windows_subsystem = "windows"
|
|
4
|
+
)]
|
|
5
|
+
|
|
6
|
+
mod app;
|
|
7
|
+
mod util;
|
|
8
|
+
|
|
9
|
+
use app::{invoke, menu, window};
|
|
10
|
+
use invoke::{download_file, drag_window, fullscreen, open_browser};
|
|
11
|
+
use menu::{get_menu, menu_event_handle};
|
|
12
|
+
use tauri_plugin_window_state::Builder as windowStatePlugin;
|
|
13
|
+
use util::{get_data_dir, get_pake_config};
|
|
14
|
+
use window::get_window;
|
|
15
|
+
|
|
16
|
+
pub fn run_app() {
|
|
17
|
+
let (pake_config, tauri_config) = get_pake_config();
|
|
18
|
+
let show_menu = pake_config.show_menu();
|
|
19
|
+
let menu = get_menu();
|
|
20
|
+
let data_dir = get_data_dir(tauri_config);
|
|
21
|
+
|
|
22
|
+
let mut tauri_app = tauri::Builder::default();
|
|
23
|
+
|
|
24
|
+
if show_menu {
|
|
25
|
+
tauri_app = tauri_app.menu(menu).on_menu_event(menu_event_handle);
|
|
26
|
+
}
|
|
162
27
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
};
|
|
28
|
+
#[cfg(not(target_os = "macos"))]
|
|
29
|
+
{
|
|
30
|
+
use menu::{get_system_tray, system_tray_handle};
|
|
168
31
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
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";
|
|
172
|
-
WebViewBuilder::new(window)?
|
|
173
|
-
.with_user_agent(user_agent_string)
|
|
174
|
-
.with_url(&url.to_string())?
|
|
175
|
-
.with_devtools(cfg!(feature = "devtools"))
|
|
176
|
-
.with_initialization_script(include_str!("pake.js"))
|
|
177
|
-
.with_ipc_handler(handler)
|
|
178
|
-
.with_back_forward_navigation_gestures(true)
|
|
179
|
-
.with_download_started_handler(download_started)
|
|
180
|
-
.with_download_completed_handler(download_completed)
|
|
181
|
-
.build()?
|
|
182
|
-
};
|
|
32
|
+
let show_system_tray = pake_config.show_system_tray();
|
|
33
|
+
let system_tray = get_system_tray(show_menu);
|
|
183
34
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
None => panic!("Error, can't found you home dir!!"),
|
|
189
|
-
};
|
|
190
|
-
#[cfg(target_os = "windows")]
|
|
191
|
-
let data_dir = home_dir.join("AppData").join("Roaming").join(package_name);
|
|
192
|
-
#[cfg(target_os = "linux")]
|
|
193
|
-
let data_dir = home_dir.join(".config").join(package_name);
|
|
194
|
-
if !data_dir.exists() {
|
|
195
|
-
std::fs::create_dir(&data_dir)
|
|
196
|
-
.unwrap_or_else(|_| panic!("can't create dir {}", data_dir.display()));
|
|
35
|
+
if show_system_tray {
|
|
36
|
+
tauri_app = tauri_app
|
|
37
|
+
.system_tray(system_tray)
|
|
38
|
+
.on_system_tray_event(system_tray_handle);
|
|
197
39
|
}
|
|
198
|
-
let mut web_content = WebContext::new(Some(data_dir));
|
|
199
|
-
#[cfg(target_os = "windows")]
|
|
200
|
-
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";
|
|
201
|
-
#[cfg(target_os = "linux")]
|
|
202
|
-
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";
|
|
203
|
-
WebViewBuilder::new(window)?
|
|
204
|
-
.with_user_agent(user_agent_string)
|
|
205
|
-
.with_url(&url.to_string())?
|
|
206
|
-
.with_devtools(cfg!(feature = "devtools"))
|
|
207
|
-
.with_initialization_script(include_str!("pake.js"))
|
|
208
|
-
.with_ipc_handler(handler)
|
|
209
|
-
.with_web_context(&mut web_content)
|
|
210
|
-
.with_download_started_handler(download_started)
|
|
211
|
-
.with_download_completed_handler(download_completed)
|
|
212
|
-
.build()?
|
|
213
|
-
};
|
|
214
|
-
#[cfg(feature = "devtools")]
|
|
215
|
-
{
|
|
216
|
-
webview.open_devtools();
|
|
217
40
|
}
|
|
218
41
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
println!("Clicked on {menu_id:?}");
|
|
238
|
-
}
|
|
239
|
-
Event::UserEvent(UserEvent::DownloadStarted(uri, temp_dir)) => {
|
|
240
|
-
println!("Download: {uri}");
|
|
241
|
-
println!("Will write to: {temp_dir:?}");
|
|
242
|
-
}
|
|
243
|
-
Event::UserEvent(UserEvent::DownloadComplete(_, success)) => {
|
|
244
|
-
println!("Succeeded: {success}");
|
|
245
|
-
if success {
|
|
246
|
-
let _ = webview
|
|
247
|
-
.evaluate_script("window.pakeToast('Downloaded to download folder~')");
|
|
248
|
-
} else {
|
|
249
|
-
println!("No output path")
|
|
250
|
-
}
|
|
42
|
+
tauri_app
|
|
43
|
+
.plugin(windowStatePlugin::default().build())
|
|
44
|
+
.invoke_handler(tauri::generate_handler![
|
|
45
|
+
drag_window,
|
|
46
|
+
fullscreen,
|
|
47
|
+
open_browser,
|
|
48
|
+
download_file
|
|
49
|
+
])
|
|
50
|
+
.setup(|app| {
|
|
51
|
+
let _window = get_window(app, pake_config, data_dir);
|
|
52
|
+
// Prevent initial shaking
|
|
53
|
+
_window.show().unwrap();
|
|
54
|
+
Ok(())
|
|
55
|
+
})
|
|
56
|
+
.on_window_event(|event| {
|
|
57
|
+
if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() {
|
|
58
|
+
event.window().minimize().unwrap();
|
|
59
|
+
api.prevent_close();
|
|
251
60
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
fn get_windows_config() -> (Option<String>, Option<WindowConfig>) {
|
|
258
|
-
let config_file = include_str!("../tauri.conf.json");
|
|
259
|
-
let config: Config = serde_json::from_str(config_file).expect("failed to parse windows config");
|
|
260
|
-
(
|
|
261
|
-
config.package.product_name.clone(),
|
|
262
|
-
config.tauri.windows.first().cloned(),
|
|
263
|
-
)
|
|
61
|
+
})
|
|
62
|
+
.run(tauri::generate_context!())
|
|
63
|
+
.expect("error while running tauri application");
|
|
264
64
|
}
|
|
265
65
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
let (icon_rgba, icon_width, icon_height) = {
|
|
269
|
-
// alternatively, you can embed the icon in the binary through `include_bytes!` macro and use `image::load_from_memory`
|
|
270
|
-
let image = image::open(path)
|
|
271
|
-
.expect("Failed to open icon path")
|
|
272
|
-
.into_rgba8();
|
|
273
|
-
let (width, height) = image.dimensions();
|
|
274
|
-
let rgba = image.into_raw();
|
|
275
|
-
(rgba, width, height)
|
|
276
|
-
};
|
|
277
|
-
Icon::from_rgba(icon_rgba, icon_width, icon_height).expect("Failed to open icon")
|
|
66
|
+
fn main() {
|
|
67
|
+
run_app()
|
|
278
68
|
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
use crate::app::config::PakeConfig;
|
|
2
|
+
use std::env;
|
|
3
|
+
use std::path::PathBuf;
|
|
4
|
+
use tauri::{api, Config, Window};
|
|
5
|
+
|
|
6
|
+
pub fn get_pake_config() -> (PakeConfig, Config) {
|
|
7
|
+
let pake_config: PakeConfig =
|
|
8
|
+
serde_json::from_str(include_str!("../pake.json")).expect("Failed to parse pake config");
|
|
9
|
+
|
|
10
|
+
let tauri_config: Config = serde_json::from_str(include_str!("../tauri.conf.json"))
|
|
11
|
+
.expect("Failed to parse tauri config");
|
|
12
|
+
|
|
13
|
+
(pake_config, tauri_config)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
pub fn get_data_dir(_tauri_config: Config) -> PathBuf {
|
|
17
|
+
{
|
|
18
|
+
let package_name = _tauri_config.package.product_name.unwrap();
|
|
19
|
+
let data_dir = api::path::config_dir()
|
|
20
|
+
.expect("Failed to get data dirname")
|
|
21
|
+
.join(package_name);
|
|
22
|
+
|
|
23
|
+
if !data_dir.exists() {
|
|
24
|
+
std::fs::create_dir(&data_dir)
|
|
25
|
+
.unwrap_or_else(|_| panic!("Can't create dir {}", data_dir.display()));
|
|
26
|
+
}
|
|
27
|
+
data_dir
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
pub fn show_toast(window: &Window, message: &str) {
|
|
32
|
+
let script = format!(r#"pakeToast("{}");"#, message);
|
|
33
|
+
window.eval(&script).unwrap();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
pub fn get_download_message() -> String {
|
|
37
|
+
let default_message = "Download successful, saved to download directory~";
|
|
38
|
+
let chinese_message = "下载成功,已保存到下载目录~";
|
|
39
|
+
|
|
40
|
+
env::var("LANG")
|
|
41
|
+
.map(|lang| {
|
|
42
|
+
if lang.starts_with("zh") {
|
|
43
|
+
chinese_message
|
|
44
|
+
} else {
|
|
45
|
+
default_message
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
.unwrap_or(default_message)
|
|
49
|
+
.to_string()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Check if the file exists, if it exists, add a number to file name
|
|
53
|
+
pub fn check_file_or_append(file_path: &str) -> String {
|
|
54
|
+
let mut new_path = PathBuf::from(file_path);
|
|
55
|
+
let mut counter = 0;
|
|
56
|
+
|
|
57
|
+
while new_path.exists() {
|
|
58
|
+
let file_stem = new_path.file_stem().unwrap().to_string_lossy().to_string();
|
|
59
|
+
let extension = new_path.extension().unwrap().to_string_lossy().to_string();
|
|
60
|
+
let parent_dir = new_path.parent().unwrap();
|
|
61
|
+
|
|
62
|
+
let new_file_stem = match file_stem.rfind('-') {
|
|
63
|
+
Some(index) if file_stem[index + 1..].parse::<u32>().is_ok() => {
|
|
64
|
+
let base_name = &file_stem[..index];
|
|
65
|
+
counter = file_stem[index + 1..].parse::<u32>().unwrap() + 1;
|
|
66
|
+
format!("{}-{}", base_name, counter)
|
|
67
|
+
}
|
|
68
|
+
_ => {
|
|
69
|
+
counter += 1;
|
|
70
|
+
format!("{}-{}", file_stem, counter)
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
new_path = parent_dir.join(format!("{}.{}", new_file_stem, extension));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
new_path.to_string_lossy().into_owned()
|
|
78
|
+
}
|