pake-cli 3.6.2 โ†’ 3.6.3

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/dist/cli.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import log from 'loglevel';
3
+ import updateNotifier from 'update-notifier';
3
4
  import path from 'path';
4
5
  import fsExtra from 'fs-extra';
5
6
  import { fileURLToPath } from 'url';
@@ -13,8 +14,6 @@ import dns from 'dns';
13
14
  import http from 'http';
14
15
  import { promisify } from 'util';
15
16
  import fs from 'fs';
16
- import updateNotifier from 'update-notifier';
17
- import axios from 'axios';
18
17
  import { dir } from 'tmp-promise';
19
18
  import { fileTypeFromBuffer } from 'file-type';
20
19
  import icongen from 'icon-gen';
@@ -22,6 +21,112 @@ import sharp from 'sharp';
22
21
  import * as psl from 'psl';
23
22
  import { InvalidArgumentError, program as program$1, Option } from 'commander';
24
23
 
24
+ var name = "pake-cli";
25
+ var version = "3.6.3";
26
+ var description = "๐Ÿคฑ๐Ÿป Turn any webpage into a desktop app with one command. ๐Ÿคฑ๐Ÿป ไธ€้”ฎๆ‰“ๅŒ…็ฝ‘้กต็”Ÿๆˆ่ฝป้‡ๆกŒ้ขๅบ”็”จใ€‚";
27
+ var engines = {
28
+ node: ">=18.0.0"
29
+ };
30
+ var packageManager = "pnpm@10.15.0";
31
+ var bin = {
32
+ pake: "./dist/cli.js"
33
+ };
34
+ var repository = {
35
+ type: "git",
36
+ url: "https://github.com/tw93/pake.git"
37
+ };
38
+ var author = {
39
+ name: "Tw93",
40
+ email: "tw93@qq.com"
41
+ };
42
+ var keywords = [
43
+ "pake",
44
+ "pake-cli",
45
+ "rust",
46
+ "tauri",
47
+ "no-electron",
48
+ "productivity"
49
+ ];
50
+ var files = [
51
+ "dist",
52
+ "src-tauri"
53
+ ];
54
+ var scripts = {
55
+ start: "pnpm run dev",
56
+ dev: "pnpm run tauri dev",
57
+ build: "tauri build",
58
+ "build:debug": "tauri build --debug",
59
+ "build:mac": "tauri build --target universal-apple-darwin",
60
+ analyze: "cd src-tauri && cargo bloat --release --crates",
61
+ tauri: "tauri",
62
+ cli: "cross-env NODE_ENV=development rollup -c -w",
63
+ "cli:build": "cross-env NODE_ENV=production rollup -c",
64
+ test: "pnpm run cli:build && cross-env PAKE_CREATE_APP=1 node tests/index.js",
65
+ format: "prettier --write . --ignore-unknown && find tests -name '*.js' -exec sed -i '' 's/[[:space:]]*$//' {} \\; && cd src-tauri && cargo fmt --verbose",
66
+ "format:check": "prettier --check . --ignore-unknown",
67
+ update: "pnpm update --verbose && cd src-tauri && cargo update",
68
+ prepublishOnly: "pnpm run cli:build"
69
+ };
70
+ var type = "module";
71
+ var exports = "./dist/cli.js";
72
+ var license = "MIT";
73
+ var dependencies = {
74
+ "@tauri-apps/api": "^2.9.0",
75
+ "@tauri-apps/cli": "^2.9.0",
76
+ chalk: "^5.6.2",
77
+ commander: "^12.1.0",
78
+ execa: "^9.6.0",
79
+ "file-type": "^18.7.0",
80
+ "fs-extra": "^11.3.2",
81
+ "icon-gen": "^5.0.0",
82
+ loglevel: "^1.9.2",
83
+ ora: "^8.2.0",
84
+ prompts: "^2.4.2",
85
+ psl: "^1.15.0",
86
+ sharp: "^0.33.5",
87
+ "tmp-promise": "^3.0.3",
88
+ "update-notifier": "^7.3.1"
89
+ };
90
+ var devDependencies = {
91
+ "@rollup/plugin-alias": "^5.1.1",
92
+ "@rollup/plugin-commonjs": "^28.0.8",
93
+ "@rollup/plugin-json": "^6.1.0",
94
+ "@rollup/plugin-replace": "^6.0.2",
95
+ "@rollup/plugin-terser": "^0.4.4",
96
+ "@types/fs-extra": "^11.0.4",
97
+ "@types/node": "^20.19.23",
98
+ "@types/page-icon": "^0.3.6",
99
+ "@types/prompts": "^2.4.9",
100
+ "@types/tmp": "^0.2.6",
101
+ "@types/update-notifier": "^6.0.8",
102
+ "app-root-path": "^3.1.0",
103
+ "cross-env": "^7.0.3",
104
+ prettier: "^3.6.2",
105
+ rollup: "^4.52.5",
106
+ "rollup-plugin-typescript2": "^0.36.0",
107
+ tslib: "^2.8.1",
108
+ typescript: "^5.9.3",
109
+ vitest: "^4.0.15"
110
+ };
111
+ var packageJson = {
112
+ name: name,
113
+ version: version,
114
+ description: description,
115
+ engines: engines,
116
+ packageManager: packageManager,
117
+ bin: bin,
118
+ repository: repository,
119
+ author: author,
120
+ keywords: keywords,
121
+ files: files,
122
+ scripts: scripts,
123
+ type: type,
124
+ exports: exports,
125
+ license: license,
126
+ dependencies: dependencies,
127
+ devDependencies: devDependencies
128
+ };
129
+
25
130
  // Convert the current module URL to a file path
26
131
  const currentModulePath = fileURLToPath(import.meta.url);
27
132
  // Resolve the parent directory of the current module
@@ -385,7 +490,7 @@ async function mergeConfig(url, options, tauriConf) {
385
490
  disabled_web_shortcuts: disabledWebShortcuts,
386
491
  hide_on_close: platformHideOnClose,
387
492
  incognito: incognito,
388
- title: title || null,
493
+ title: title,
389
494
  enable_wasm: wasm,
390
495
  enable_drag_drop: enableDragDrop,
391
496
  start_to_tray: startToTray && showSystemTray,
@@ -1249,120 +1354,6 @@ class BuilderProvider {
1249
1354
  }
1250
1355
  }
1251
1356
 
1252
- var name = "pake-cli";
1253
- var version = "3.6.2";
1254
- var description = "๐Ÿคฑ๐Ÿป Turn any webpage into a desktop app with one command. ๐Ÿคฑ๐Ÿป ไธ€้”ฎๆ‰“ๅŒ…็ฝ‘้กต็”Ÿๆˆ่ฝป้‡ๆกŒ้ขๅบ”็”จใ€‚";
1255
- var engines = {
1256
- node: ">=18.0.0"
1257
- };
1258
- var packageManager = "pnpm@10.15.0";
1259
- var bin = {
1260
- pake: "./dist/cli.js"
1261
- };
1262
- var repository = {
1263
- type: "git",
1264
- url: "https://github.com/tw93/pake.git"
1265
- };
1266
- var author = {
1267
- name: "Tw93",
1268
- email: "tw93@qq.com"
1269
- };
1270
- var keywords = [
1271
- "pake",
1272
- "pake-cli",
1273
- "rust",
1274
- "tauri",
1275
- "no-electron",
1276
- "productivity"
1277
- ];
1278
- var files = [
1279
- "dist",
1280
- "src-tauri"
1281
- ];
1282
- var scripts = {
1283
- start: "pnpm run dev",
1284
- dev: "pnpm run tauri dev",
1285
- build: "tauri build",
1286
- "build:debug": "tauri build --debug",
1287
- "build:mac": "tauri build --target universal-apple-darwin",
1288
- analyze: "cd src-tauri && cargo bloat --release --crates",
1289
- tauri: "tauri",
1290
- cli: "cross-env NODE_ENV=development rollup -c -w",
1291
- "cli:dev": "cross-env NODE_ENV=development rollup -c -w",
1292
- "cli:build": "cross-env NODE_ENV=production rollup -c",
1293
- test: "pnpm run cli:build && cross-env PAKE_CREATE_APP=1 node tests/index.js",
1294
- format: "prettier --write . --ignore-unknown && find tests -name '*.js' -exec sed -i '' 's/[[:space:]]*$//' {} \\; && cd src-tauri && cargo fmt --verbose",
1295
- "format:check": "prettier --check . --ignore-unknown",
1296
- update: "pnpm update --verbose && cd src-tauri && cargo update",
1297
- prepublishOnly: "pnpm run cli:build"
1298
- };
1299
- var type = "module";
1300
- var exports = "./dist/cli.js";
1301
- var license = "MIT";
1302
- var dependencies = {
1303
- "@tauri-apps/api": "^2.9.0",
1304
- "@tauri-apps/cli": "^2.9.0",
1305
- axios: "^1.12.2",
1306
- chalk: "^5.6.2",
1307
- commander: "^12.1.0",
1308
- execa: "^9.6.0",
1309
- "file-type": "^18.7.0",
1310
- "fs-extra": "^11.3.2",
1311
- "icon-gen": "^5.0.0",
1312
- loglevel: "^1.9.2",
1313
- ora: "^8.2.0",
1314
- prompts: "^2.4.2",
1315
- psl: "^1.15.0",
1316
- sharp: "^0.33.5",
1317
- "tmp-promise": "^3.0.3",
1318
- "update-notifier": "^7.3.1"
1319
- };
1320
- var devDependencies = {
1321
- "@rollup/plugin-alias": "^5.1.1",
1322
- "@rollup/plugin-commonjs": "^28.0.8",
1323
- "@rollup/plugin-json": "^6.1.0",
1324
- "@rollup/plugin-replace": "^6.0.2",
1325
- "@rollup/plugin-terser": "^0.4.4",
1326
- "@types/fs-extra": "^11.0.4",
1327
- "@types/node": "^20.19.23",
1328
- "@types/page-icon": "^0.3.6",
1329
- "@types/prompts": "^2.4.9",
1330
- "@types/tmp": "^0.2.6",
1331
- "@types/update-notifier": "^6.0.8",
1332
- "app-root-path": "^3.1.0",
1333
- "cross-env": "^7.0.3",
1334
- prettier: "^3.6.2",
1335
- rollup: "^4.52.5",
1336
- "rollup-plugin-typescript2": "^0.36.0",
1337
- tslib: "^2.8.1",
1338
- typescript: "^5.9.3",
1339
- vitest: "^4.0.15"
1340
- };
1341
- var packageJson = {
1342
- name: name,
1343
- version: version,
1344
- description: description,
1345
- engines: engines,
1346
- packageManager: packageManager,
1347
- bin: bin,
1348
- repository: repository,
1349
- author: author,
1350
- keywords: keywords,
1351
- files: files,
1352
- scripts: scripts,
1353
- type: type,
1354
- exports: exports,
1355
- license: license,
1356
- dependencies: dependencies,
1357
- devDependencies: devDependencies
1358
- };
1359
-
1360
- async function checkUpdateTips() {
1361
- updateNotifier({ pkg: packageJson, updateCheckInterval: 1000 * 60 }).notify({
1362
- isGlobal: true,
1363
- });
1364
- }
1365
-
1366
1357
  const ICON_CONFIG = {
1367
1358
  minFileSize: 100,
1368
1359
  supportedFormats: ['png', 'ico', 'jpeg', 'jpg', 'webp', 'icns'],
@@ -1705,24 +1696,40 @@ async function tryGetFavicon(url, appName) {
1705
1696
  * Downloads icon from URL
1706
1697
  */
1707
1698
  async function downloadIcon(iconUrl, showSpinner = true, customTimeout) {
1699
+ const controller = new AbortController();
1700
+ const timeoutId = setTimeout(() => {
1701
+ controller.abort();
1702
+ }, customTimeout || 10000);
1708
1703
  try {
1709
- const response = await axios.get(iconUrl, {
1710
- responseType: 'arraybuffer',
1711
- timeout: customTimeout || 10000,
1704
+ const response = await fetch(iconUrl, {
1705
+ signal: controller.signal,
1712
1706
  });
1713
- const iconData = response.data;
1714
- if (!iconData || iconData.byteLength < ICON_CONFIG.minFileSize)
1707
+ clearTimeout(timeoutId);
1708
+ if (!response.ok) {
1709
+ if (response.status === 404 && !showSpinner) {
1710
+ return null;
1711
+ }
1712
+ throw new Error(`HTTP ${response.status} ${response.statusText}`);
1713
+ }
1714
+ const arrayBuffer = await response.arrayBuffer();
1715
+ if (!arrayBuffer || arrayBuffer.byteLength < ICON_CONFIG.minFileSize)
1715
1716
  return null;
1716
- const fileDetails = await fileTypeFromBuffer(iconData);
1717
+ const fileDetails = await fileTypeFromBuffer(arrayBuffer);
1717
1718
  if (!fileDetails ||
1718
1719
  !ICON_CONFIG.supportedFormats.includes(fileDetails.ext)) {
1719
1720
  return null;
1720
1721
  }
1721
- return await saveIconFile(iconData, fileDetails.ext);
1722
+ return await saveIconFile(arrayBuffer, fileDetails.ext);
1722
1723
  }
1723
1724
  catch (error) {
1724
- if (showSpinner && !(error.response?.status === 404)) {
1725
- logger.error('Icon download failed!', error);
1725
+ clearTimeout(timeoutId);
1726
+ if (showSpinner) {
1727
+ if (error instanceof Error && error.name === 'AbortError') {
1728
+ logger.error('Icon download timed out!');
1729
+ }
1730
+ else {
1731
+ logger.error('Icon download failed!', error instanceof Error ? error.message : String(error));
1732
+ }
1726
1733
  }
1727
1734
  return null;
1728
1735
  }
@@ -2041,6 +2048,11 @@ ${green('|_| \\__,_|_|\\_\\___| can turn any webpage into a desktop app with
2041
2048
  }
2042
2049
 
2043
2050
  const program = getCliProgram();
2051
+ async function checkUpdateTips() {
2052
+ updateNotifier({ pkg: packageJson, updateCheckInterval: 1000 * 60 }).notify({
2053
+ isGlobal: true,
2054
+ });
2055
+ }
2044
2056
  program.action(async (url, options) => {
2045
2057
  await checkUpdateTips();
2046
2058
  if (!url) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pake-cli",
3
- "version": "3.6.2",
3
+ "version": "3.6.3",
4
4
  "description": "๐Ÿคฑ๐Ÿป Turn any webpage into a desktop app with one command. ๐Ÿคฑ๐Ÿป ไธ€้”ฎๆ‰“ๅŒ…็ฝ‘้กต็”Ÿๆˆ่ฝป้‡ๆกŒ้ขๅบ”็”จใ€‚",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"
@@ -38,7 +38,6 @@
38
38
  "analyze": "cd src-tauri && cargo bloat --release --crates",
39
39
  "tauri": "tauri",
40
40
  "cli": "cross-env NODE_ENV=development rollup -c -w",
41
- "cli:dev": "cross-env NODE_ENV=development rollup -c -w",
42
41
  "cli:build": "cross-env NODE_ENV=production rollup -c",
43
42
  "test": "pnpm run cli:build && cross-env PAKE_CREATE_APP=1 node tests/index.js",
44
43
  "format": "prettier --write . --ignore-unknown && find tests -name '*.js' -exec sed -i '' 's/[[:space:]]*$//' {} \\; && cd src-tauri && cargo fmt --verbose",
@@ -52,7 +51,6 @@
52
51
  "dependencies": {
53
52
  "@tauri-apps/api": "^2.9.0",
54
53
  "@tauri-apps/cli": "^2.9.0",
55
- "axios": "^1.12.2",
56
54
  "chalk": "^5.6.2",
57
55
  "commander": "^12.1.0",
58
56
  "execa": "^9.6.0",
@@ -0,0 +1,10 @@
1
+ [source.crates-io]
2
+ replace-with = 'rsproxy-sparse'
3
+ [source.rsproxy]
4
+ registry = "https://rsproxy.cn/crates.io-index"
5
+ [source.rsproxy-sparse]
6
+ registry = "sparse+https://rsproxy.cn/index/"
7
+ [registries.rsproxy]
8
+ index = "https://rsproxy.cn/crates.io-index"
9
+ [net]
10
+ git-fetch-with-cli = true
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "windows": [
3
3
  {
4
- "url": "https://github.com",
4
+ "url": "https://twitter.com/",
5
5
  "url_type": "web",
6
- "hide_title_bar": true,
6
+ "hide_title_bar": false,
7
7
  "fullscreen": false,
8
8
  "width": 1200,
9
- "height": 800,
9
+ "height": 780,
10
10
  "resizable": true,
11
11
  "always_on_top": false,
12
12
  "dark_mode": false,
@@ -19,7 +19,6 @@
19
19
  "maximize": false,
20
20
  "start_to_tray": false,
21
21
  "force_internal_navigation": false,
22
- "title": null,
23
22
  "zoom": 100,
24
23
  "min_width": 0,
25
24
  "min_height": 0,
@@ -1,6 +1,6 @@
1
1
  {
2
- "productName": "GitHubMultiArch",
3
- "identifier": "com.pake.3097fc",
2
+ "productName": "twitter",
3
+ "identifier": "com.pake.4fd9c9",
4
4
  "version": "1.0.0",
5
5
  "app": {
6
6
  "withGlobalTauri": true,
@@ -14,14 +14,11 @@
14
14
  },
15
15
  "bundle": {
16
16
  "icon": [
17
- "icons/githubmultiarch.icns"
17
+ "icons/icon.icns"
18
18
  ],
19
19
  "active": true,
20
20
  "targets": [
21
21
  "app"
22
- ],
23
- "resources": [
24
- "icons/githubmultiarch.icns"
25
22
  ]
26
23
  }
27
24
  }
@@ -1,14 +1,11 @@
1
1
  {
2
2
  "bundle": {
3
3
  "icon": [
4
- "icons/githubmultiarch.icns"
4
+ "icons/icon.icns"
5
5
  ],
6
6
  "active": true,
7
7
  "targets": [
8
8
  "app"
9
- ],
10
- "resources": [
11
- "icons/githubmultiarch.icns"
12
9
  ]
13
10
  }
14
11
  }
@@ -2588,7 +2588,7 @@ dependencies = [
2588
2588
 
2589
2589
  [[package]]
2590
2590
  name = "pake"
2591
- version = "3.6.1"
2591
+ version = "3.6.3"
2592
2592
  dependencies = [
2593
2593
  "serde",
2594
2594
  "serde_json",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "pake"
3
- version = "3.6.1"
3
+ version = "3.6.3"
4
4
  description = "๐Ÿคฑ๐Ÿป Turn any webpage into a desktop app with Rust."
5
5
  authors = ["Tw93"]
6
6
  license = "MIT"
@@ -21,7 +21,12 @@ tauri-build = { version = "2.5.3", features = [] }
21
21
  serde_json = "1.0.145"
22
22
  serde = { version = "1.0.228", features = ["derive"] }
23
23
  tokio = { version = "1.48.0", features = ["full"] }
24
- tauri = { version = "2.9.4", features = ["tray-icon", "image-ico", "image-png", "macos-proxy"] }
24
+ tauri = { version = "2.9.4", features = [
25
+ "tray-icon",
26
+ "image-ico",
27
+ "image-png",
28
+ "macos-proxy",
29
+ ] }
25
30
  tauri-plugin-window-state = "2.4.1"
26
31
  tauri-plugin-oauth = "2.0.0"
27
32
  tauri-plugin-http = "2.5.4"
@@ -32,29 +32,48 @@ pub struct NotificationParams {
32
32
 
33
33
  #[command]
34
34
  pub async fn download_file(app: AppHandle, params: DownloadFileParams) -> Result<(), String> {
35
- let window: WebviewWindow = app.get_webview_window("pake").unwrap();
35
+ let window: WebviewWindow = app.get_webview_window("pake").ok_or("Window not found")?;
36
+
36
37
  show_toast(
37
38
  &window,
38
39
  &get_download_message_with_lang(MessageType::Start, params.language.clone()),
39
40
  );
40
41
 
41
- let output_path = app.path().download_dir().unwrap().join(params.filename);
42
- let file_path = check_file_or_append(output_path.to_str().unwrap());
43
- let client = ClientBuilder::new().build().unwrap();
42
+ let download_dir = app
43
+ .path()
44
+ .download_dir()
45
+ .map_err(|e| format!("Failed to get download dir: {}", e))?;
46
+
47
+ let output_path = download_dir.join(&params.filename);
48
+
49
+ let path_str = output_path.to_str().ok_or("Invalid output path")?;
50
+
51
+ let file_path = check_file_or_append(path_str);
44
52
 
45
- let response = client
46
- .execute(Request::new(
47
- Method::GET,
48
- Url::from_str(&params.url).unwrap(),
49
- ))
50
- .await;
53
+ let client = ClientBuilder::new()
54
+ .build()
55
+ .map_err(|e| format!("Failed to build client: {}", e))?;
56
+
57
+ let url = Url::from_str(&params.url).map_err(|e| format!("Invalid URL: {}", e))?;
58
+
59
+ let request = Request::new(Method::GET, url);
60
+
61
+ let response = client.execute(request).await;
51
62
 
52
63
  match response {
53
64
  Ok(mut res) => {
54
- let mut file = File::create(file_path).unwrap();
55
- while let Some(chunk) = res.chunk().await.unwrap() {
56
- file.write_all(&chunk).unwrap();
65
+ let mut file =
66
+ File::create(file_path).map_err(|e| format!("Failed to create file: {}", e))?;
67
+
68
+ while let Some(chunk) = res
69
+ .chunk()
70
+ .await
71
+ .map_err(|e| format!("Failed to get chunk: {}", e))?
72
+ {
73
+ file.write_all(&chunk)
74
+ .map_err(|e| format!("Failed to write chunk: {}", e))?;
57
75
  }
76
+
58
77
  show_toast(
59
78
  &window,
60
79
  &get_download_message_with_lang(MessageType::Success, params.language.clone()),
@@ -76,15 +95,25 @@ pub async fn download_file_by_binary(
76
95
  app: AppHandle,
77
96
  params: BinaryDownloadParams,
78
97
  ) -> Result<(), String> {
79
- let window: WebviewWindow = app.get_webview_window("pake").unwrap();
98
+ let window: WebviewWindow = app.get_webview_window("pake").ok_or("Window not found")?;
99
+
80
100
  show_toast(
81
101
  &window,
82
102
  &get_download_message_with_lang(MessageType::Start, params.language.clone()),
83
103
  );
84
- let output_path = app.path().download_dir().unwrap().join(params.filename);
85
- let file_path = check_file_or_append(output_path.to_str().unwrap());
86
- let download_file_result = fs::write(file_path, &params.binary);
87
- match download_file_result {
104
+
105
+ let download_dir = app
106
+ .path()
107
+ .download_dir()
108
+ .map_err(|e| format!("Failed to get download dir: {}", e))?;
109
+
110
+ let output_path = download_dir.join(&params.filename);
111
+
112
+ let path_str = output_path.to_str().ok_or("Invalid output path")?;
113
+
114
+ let file_path = check_file_or_append(path_str);
115
+
116
+ match fs::write(file_path, &params.binary) {
88
117
  Ok(_) => {
89
118
  show_toast(
90
119
  &window,
@@ -111,7 +140,7 @@ pub fn send_notification(app: AppHandle, params: NotificationParams) -> Result<(
111
140
  .body(&params.body)
112
141
  .icon(&params.icon)
113
142
  .show()
114
- .unwrap();
143
+ .map_err(|e| format!("Failed to show notification: {}", e))?;
115
144
  Ok(())
116
145
  }
117
146
 
@@ -119,13 +148,14 @@ pub fn send_notification(app: AppHandle, params: NotificationParams) -> Result<(
119
148
  pub async fn update_theme_mode(app: AppHandle, mode: String) {
120
149
  #[cfg(target_os = "macos")]
121
150
  {
122
- let window = app.get_webview_window("pake").unwrap();
123
- let theme = if mode == "dark" {
124
- Theme::Dark
125
- } else {
126
- Theme::Light
127
- };
128
- let _ = window.set_theme(Some(theme));
151
+ if let Some(window) = app.get_webview_window("pake") {
152
+ let theme = if mode == "dark" {
153
+ Theme::Dark
154
+ } else {
155
+ Theme::Light
156
+ };
157
+ let _ = window.set_theme(Some(theme));
158
+ }
129
159
  }
130
160
  #[cfg(not(target_os = "macos"))]
131
161
  {
@@ -2,208 +2,171 @@ use tauri::menu::{AboutMetadata, Menu, MenuItem, PredefinedMenuItem, Submenu};
2
2
  use tauri::{AppHandle, Manager, Wry};
3
3
  use tauri_plugin_opener::OpenerExt;
4
4
 
5
- pub fn get_menu(app: &AppHandle<Wry>) -> Menu<Wry> {
5
+ pub fn get_menu(app: &AppHandle<Wry>) -> tauri::Result<Menu<Wry>> {
6
6
  let pake_version = env!("CARGO_PKG_VERSION");
7
7
  let pake_menu_item_title = format!("Built with Pake V{}", pake_version);
8
8
 
9
- // App Menu (macOS specific, e.g., "Pake")
10
- let app_menu = Submenu::new(app, "Pake", true).unwrap();
11
- let about_metadata = AboutMetadata::default();
12
- app_menu
13
- .append(&PredefinedMenuItem::about(app, Some("Pake"), Some(about_metadata)).unwrap())
14
- .unwrap();
15
- app_menu
16
- .append(&PredefinedMenuItem::separator(app).unwrap())
17
- .unwrap();
18
- app_menu
19
- .append(&PredefinedMenuItem::services(app, None).unwrap())
20
- .unwrap();
21
- app_menu
22
- .append(&PredefinedMenuItem::separator(app).unwrap())
23
- .unwrap();
24
- app_menu
25
- .append(&PredefinedMenuItem::hide(app, None).unwrap())
26
- .unwrap();
27
- app_menu
28
- .append(&PredefinedMenuItem::hide_others(app, None).unwrap())
29
- .unwrap();
30
- app_menu
31
- .append(&PredefinedMenuItem::show_all(app, None).unwrap())
32
- .unwrap();
33
- app_menu
34
- .append(&PredefinedMenuItem::separator(app).unwrap())
35
- .unwrap();
36
- app_menu
37
- .append(&PredefinedMenuItem::quit(app, None).unwrap())
38
- .unwrap();
9
+ let menu = Menu::with_items(
10
+ app,
11
+ &[
12
+ &app_menu(app)?,
13
+ &file_menu(app)?,
14
+ &edit_menu(app)?,
15
+ &view_menu(app)?,
16
+ &navigation_menu(app)?,
17
+ &window_menu(app)?,
18
+ &help_menu(app, &pake_menu_item_title)?,
19
+ ],
20
+ )?;
39
21
 
40
- // File Menu
41
- let file_menu = Submenu::new(app, "File", true).unwrap();
42
- file_menu
43
- .append(&PredefinedMenuItem::close_window(app, None).unwrap())
44
- .unwrap();
45
- file_menu
46
- .append(&PredefinedMenuItem::separator(app).unwrap())
47
- .unwrap();
48
- file_menu
49
- .append(
50
- &MenuItem::with_id(
51
- app,
52
- "clear_cache_restart",
53
- "Clear Cache & Restart",
54
- true,
55
- Some("CmdOrCtrl+Shift+Backspace"),
56
- )
57
- .unwrap(),
58
- )
59
- .unwrap();
22
+ Ok(menu)
23
+ }
60
24
 
61
- // Edit Menu
62
- let edit_menu = Submenu::new(app, "Edit", true).unwrap();
63
- edit_menu
64
- .append(&PredefinedMenuItem::undo(app, None).unwrap())
65
- .unwrap();
66
- edit_menu
67
- .append(&PredefinedMenuItem::redo(app, None).unwrap())
68
- .unwrap();
69
- edit_menu
70
- .append(&PredefinedMenuItem::separator(app).unwrap())
71
- .unwrap();
72
- edit_menu
73
- .append(&PredefinedMenuItem::cut(app, None).unwrap())
74
- .unwrap();
75
- edit_menu
76
- .append(&PredefinedMenuItem::copy(app, None).unwrap())
77
- .unwrap();
78
- edit_menu
79
- .append(&PredefinedMenuItem::paste(app, None).unwrap())
80
- .unwrap();
81
- edit_menu
82
- .append(&PredefinedMenuItem::select_all(app, None).unwrap())
83
- .unwrap();
84
- edit_menu
85
- .append(&PredefinedMenuItem::separator(app).unwrap())
86
- .unwrap();
87
- edit_menu
88
- .append(&MenuItem::with_id(app, "copy_url", "Copy URL", true, Some("CmdOrCtrl+L")).unwrap())
89
- .unwrap();
25
+ fn app_menu(app: &AppHandle<Wry>) -> tauri::Result<Submenu<Wry>> {
26
+ let app_menu = Submenu::new(app, "Pake", true)?;
27
+ let about_metadata = AboutMetadata::default();
28
+ app_menu.append(&PredefinedMenuItem::about(
29
+ app,
30
+ Some("Pake"),
31
+ Some(about_metadata),
32
+ )?)?;
33
+ app_menu.append(&PredefinedMenuItem::separator(app)?)?;
34
+ app_menu.append(&PredefinedMenuItem::services(app, None)?)?;
35
+ app_menu.append(&PredefinedMenuItem::separator(app)?)?;
36
+ app_menu.append(&PredefinedMenuItem::hide(app, None)?)?;
37
+ app_menu.append(&PredefinedMenuItem::hide_others(app, None)?)?;
38
+ app_menu.append(&PredefinedMenuItem::show_all(app, None)?)?;
39
+ app_menu.append(&PredefinedMenuItem::separator(app)?)?;
40
+ app_menu.append(&PredefinedMenuItem::quit(app, None)?)?;
41
+ Ok(app_menu)
42
+ }
90
43
 
91
- // View Menu
92
- let view_menu = Submenu::new(app, "View", true).unwrap();
93
- view_menu
94
- .append(&MenuItem::with_id(app, "reload", "Reload", true, Some("CmdOrCtrl+R")).unwrap())
95
- .unwrap();
96
- view_menu
97
- .append(&PredefinedMenuItem::separator(app).unwrap())
98
- .unwrap();
99
- view_menu
100
- .append(&MenuItem::with_id(app, "zoom_in", "Zoom In", true, Some("CmdOrCtrl+=")).unwrap())
101
- .unwrap();
102
- view_menu
103
- .append(&MenuItem::with_id(app, "zoom_out", "Zoom Out", true, Some("CmdOrCtrl+-")).unwrap())
104
- .unwrap();
105
- view_menu
106
- .append(
107
- &MenuItem::with_id(app, "zoom_reset", "Actual Size", true, Some("CmdOrCtrl+0"))
108
- .unwrap(),
109
- )
110
- .unwrap();
111
- view_menu
112
- .append(&PredefinedMenuItem::separator(app).unwrap())
113
- .unwrap();
114
- view_menu
115
- .append(&PredefinedMenuItem::fullscreen(app, None).unwrap())
116
- .unwrap();
117
- view_menu
118
- .append(&PredefinedMenuItem::separator(app).unwrap())
119
- .unwrap();
120
- view_menu
121
- .append(
122
- &MenuItem::with_id(
123
- app,
124
- "toggle_devtools",
125
- "Toggle Developer Tools",
126
- cfg!(debug_assertions),
127
- Some("CmdOrCtrl+Option+I"),
128
- )
129
- .unwrap(),
130
- )
131
- .unwrap();
44
+ fn file_menu(app: &AppHandle<Wry>) -> tauri::Result<Submenu<Wry>> {
45
+ let file_menu = Submenu::new(app, "File", true)?;
46
+ file_menu.append(&PredefinedMenuItem::close_window(app, None)?)?;
47
+ file_menu.append(&PredefinedMenuItem::separator(app)?)?;
48
+ file_menu.append(&MenuItem::with_id(
49
+ app,
50
+ "clear_cache_restart",
51
+ "Clear Cache & Restart",
52
+ true,
53
+ Some("CmdOrCtrl+Shift+Backspace"),
54
+ )?)?;
55
+ Ok(file_menu)
56
+ }
132
57
 
133
- // Navigation Menu
134
- let navigation_menu = Submenu::new(app, "Navigation", true).unwrap();
135
- navigation_menu
136
- .append(&MenuItem::with_id(app, "go_back", "Back", true, Some("CmdOrCtrl+[")).unwrap())
137
- .unwrap();
138
- navigation_menu
139
- .append(
140
- &MenuItem::with_id(app, "go_forward", "Forward", true, Some("CmdOrCtrl+]")).unwrap(),
141
- )
142
- .unwrap();
143
- navigation_menu
144
- .append(
145
- &MenuItem::with_id(app, "go_home", "Go Home", true, Some("CmdOrCtrl+Shift+H")).unwrap(),
146
- )
147
- .unwrap();
58
+ fn edit_menu(app: &AppHandle<Wry>) -> tauri::Result<Submenu<Wry>> {
59
+ let edit_menu = Submenu::new(app, "Edit", true)?;
60
+ edit_menu.append(&PredefinedMenuItem::undo(app, None)?)?;
61
+ edit_menu.append(&PredefinedMenuItem::redo(app, None)?)?;
62
+ edit_menu.append(&PredefinedMenuItem::separator(app)?)?;
63
+ edit_menu.append(&PredefinedMenuItem::cut(app, None)?)?;
64
+ edit_menu.append(&PredefinedMenuItem::copy(app, None)?)?;
65
+ edit_menu.append(&PredefinedMenuItem::paste(app, None)?)?;
66
+ edit_menu.append(&PredefinedMenuItem::select_all(app, None)?)?;
67
+ edit_menu.append(&PredefinedMenuItem::separator(app)?)?;
68
+ edit_menu.append(&MenuItem::with_id(
69
+ app,
70
+ "copy_url",
71
+ "Copy URL",
72
+ true,
73
+ Some("CmdOrCtrl+L"),
74
+ )?)?;
75
+ Ok(edit_menu)
76
+ }
148
77
 
149
- // Window Menu
150
- let window_menu = Submenu::new(app, "Window", true).unwrap();
151
- window_menu
152
- .append(&PredefinedMenuItem::minimize(app, None).unwrap())
153
- .unwrap();
154
- window_menu
155
- .append(&PredefinedMenuItem::maximize(app, None).unwrap())
156
- .unwrap();
157
- window_menu
158
- .append(&PredefinedMenuItem::separator(app).unwrap())
159
- .unwrap();
160
- window_menu
161
- .append(
162
- &MenuItem::with_id(
163
- app,
164
- "always_on_top",
165
- "Toggle Always on Top",
166
- true,
167
- None::<&str>,
168
- )
169
- .unwrap(),
170
- )
171
- .unwrap();
172
- window_menu
173
- .append(&PredefinedMenuItem::separator(app).unwrap())
174
- .unwrap();
175
- window_menu
176
- .append(&PredefinedMenuItem::close_window(app, None).unwrap())
177
- .unwrap();
78
+ fn view_menu(app: &AppHandle<Wry>) -> tauri::Result<Submenu<Wry>> {
79
+ let view_menu = Submenu::new(app, "View", true)?;
80
+ view_menu.append(&MenuItem::with_id(
81
+ app,
82
+ "reload",
83
+ "Reload",
84
+ true,
85
+ Some("CmdOrCtrl+R"),
86
+ )?)?;
87
+ view_menu.append(&PredefinedMenuItem::separator(app)?)?;
88
+ view_menu.append(&MenuItem::with_id(
89
+ app,
90
+ "zoom_in",
91
+ "Zoom In",
92
+ true,
93
+ Some("CmdOrCtrl+="),
94
+ )?)?;
95
+ view_menu.append(&MenuItem::with_id(
96
+ app,
97
+ "zoom_out",
98
+ "Zoom Out",
99
+ true,
100
+ Some("CmdOrCtrl+-"),
101
+ )?)?;
102
+ view_menu.append(&MenuItem::with_id(
103
+ app,
104
+ "zoom_reset",
105
+ "Actual Size",
106
+ true,
107
+ Some("CmdOrCtrl+0"),
108
+ )?)?;
109
+ view_menu.append(&PredefinedMenuItem::separator(app)?)?;
110
+ view_menu.append(&PredefinedMenuItem::fullscreen(app, None)?)?;
111
+ view_menu.append(&PredefinedMenuItem::separator(app)?)?;
112
+ view_menu.append(&MenuItem::with_id(
113
+ app,
114
+ "toggle_devtools",
115
+ "Toggle Developer Tools",
116
+ cfg!(debug_assertions),
117
+ Some("CmdOrCtrl+Option+I"),
118
+ )?)?;
119
+ Ok(view_menu)
120
+ }
178
121
 
179
- // Help Menu (Custom)
180
- let help_menu = Submenu::new(app, "Help", true).unwrap();
181
- let github_item = MenuItem::with_id(
122
+ fn navigation_menu(app: &AppHandle<Wry>) -> tauri::Result<Submenu<Wry>> {
123
+ let navigation_menu = Submenu::new(app, "Navigation", true)?;
124
+ navigation_menu.append(&MenuItem::with_id(
182
125
  app,
183
- "pake_github_link",
184
- &pake_menu_item_title,
126
+ "go_back",
127
+ "Back",
185
128
  true,
186
- None::<&str>,
187
- )
188
- .unwrap();
189
- help_menu.append(&github_item).unwrap();
129
+ Some("CmdOrCtrl+["),
130
+ )?)?;
131
+ navigation_menu.append(&MenuItem::with_id(
132
+ app,
133
+ "go_forward",
134
+ "Forward",
135
+ true,
136
+ Some("CmdOrCtrl+]"),
137
+ )?)?;
138
+ navigation_menu.append(&MenuItem::with_id(
139
+ app,
140
+ "go_home",
141
+ "Go Home",
142
+ true,
143
+ Some("CmdOrCtrl+Shift+H"),
144
+ )?)?;
145
+ Ok(navigation_menu)
146
+ }
190
147
 
191
- // Construct the Menu Bar
192
- let menu = Menu::with_items(
148
+ fn window_menu(app: &AppHandle<Wry>) -> tauri::Result<Submenu<Wry>> {
149
+ let window_menu = Submenu::new(app, "Window", true)?;
150
+ window_menu.append(&PredefinedMenuItem::minimize(app, None)?)?;
151
+ window_menu.append(&PredefinedMenuItem::maximize(app, None)?)?;
152
+ window_menu.append(&PredefinedMenuItem::separator(app)?)?;
153
+ window_menu.append(&MenuItem::with_id(
193
154
  app,
194
- &[
195
- &app_menu,
196
- &file_menu,
197
- &edit_menu,
198
- &view_menu,
199
- &navigation_menu,
200
- &window_menu,
201
- &help_menu,
202
- ],
203
- )
204
- .unwrap();
155
+ "always_on_top",
156
+ "Toggle Always on Top",
157
+ true,
158
+ None::<&str>,
159
+ )?)?;
160
+ window_menu.append(&PredefinedMenuItem::separator(app)?)?;
161
+ window_menu.append(&PredefinedMenuItem::close_window(app, None)?)?;
162
+ Ok(window_menu)
163
+ }
205
164
 
206
- menu
165
+ fn help_menu(app: &AppHandle<Wry>, title: &str) -> tauri::Result<Submenu<Wry>> {
166
+ let help_menu = Submenu::new(app, "Help", true)?;
167
+ let github_item = MenuItem::with_id(app, "pake_github_link", title, true, None::<&str>)?;
168
+ help_menu.append(&github_item)?;
169
+ Ok(help_menu)
207
170
  }
208
171
 
209
172
  pub fn handle_menu_click(app_handle: &AppHandle, id: &str) {
@@ -9,6 +9,8 @@ use tauri_plugin_window_state::StateFlags;
9
9
  #[cfg(target_os = "macos")]
10
10
  use std::time::Duration;
11
11
 
12
+ const WINDOW_SHOW_DELAY: u64 = 50;
13
+
12
14
  use app::{
13
15
  invoke::{
14
16
  clear_cache_and_restart, download_file, download_file_by_binary, send_notification,
@@ -69,13 +71,16 @@ pub fn run_app() {
69
71
  ])
70
72
  .setup(move |app| {
71
73
  // --- Menu Construction Start ---
72
- let menu = app::menu::get_menu(app.app_handle());
73
- app.set_menu(menu)?;
74
+ #[cfg(target_os = "macos")]
75
+ {
76
+ let menu = app::menu::get_menu(app.app_handle())?;
77
+ app.set_menu(menu)?;
74
78
 
75
- // Event Handling for Custom Menu Item
76
- app.on_menu_event(move |app_handle, event| {
77
- app::menu::handle_menu_click(app_handle, event.id().as_ref());
78
- });
79
+ // Event Handling for Custom Menu Item
80
+ app.on_menu_event(move |app_handle, event| {
81
+ app::menu::handle_menu_click(app_handle, event.id().as_ref());
82
+ });
83
+ }
79
84
  // --- Menu Construction End ---
80
85
 
81
86
  let window = set_window(app, &pake_config, &tauri_config);
@@ -92,7 +97,7 @@ pub fn run_app() {
92
97
  if !start_to_tray {
93
98
  let window_clone = window.clone();
94
99
  tauri::async_runtime::spawn(async move {
95
- tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
100
+ tokio::time::sleep(tokio::time::Duration::from_millis(WINDOW_SHOW_DELAY)).await;
96
101
  window_clone.show().unwrap();
97
102
  });
98
103
  }