feat: migrate to monorepo
4
.gitattributes
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/.yarn/** linguist-vendored
|
||||
/.yarn/releases/* binary
|
||||
/.yarn/plugins/**/* binary
|
||||
/.pnp.* binary linguist-generated
|
11
.gitignore
vendored
@ -8,11 +8,12 @@ pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
dist-electron
|
||||
native
|
||||
release
|
||||
.yarn
|
||||
**/dist
|
||||
**/dist-ssr
|
||||
**/dist-electron
|
||||
**/native
|
||||
**/release
|
||||
*.local
|
||||
.env
|
||||
|
||||
|
893
.yarn/releases/yarn-4.0.2.cjs
vendored
Normal file
3
.yarnrc.yml
Normal file
@ -0,0 +1,3 @@
|
||||
nodeLinker: node-modules
|
||||
|
||||
yarnPath: .yarn/releases/yarn-4.0.2.cjs
|
139
Cargo.lock
generated
@ -2,6 +2,22 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addon"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"clipboard-win",
|
||||
"image",
|
||||
"napi",
|
||||
"napi-build",
|
||||
"napi-derive",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"static_vcruntime",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
@ -102,9 +118,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
|
||||
checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
@ -113,22 +129,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.15"
|
||||
version = "0.9.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
|
||||
checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.16"
|
||||
version = "0.8.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
|
||||
checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
@ -141,12 +156,12 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.2.5"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e366bff8cd32dd8754b0991fb66b279dc48f598c3a18914852a6673deef583"
|
||||
checksum = "30d2b3721e861707777e3195b0158f950ae6dc4a27e4d02ff9f67e3eb3de199e"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -249,9 +264,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||
|
||||
[[package]]
|
||||
name = "jpeg-decoder"
|
||||
@ -270,18 +285,18 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.149"
|
||||
version = "0.2.151"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
|
||||
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.4"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||
checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"winapi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -321,9 +336,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "napi"
|
||||
version = "2.13.3"
|
||||
version = "2.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd063c93b900149304e3ba96ce5bf210cd4f81ef5eb80ded0d100df3e85a3ac0"
|
||||
checksum = "1133249c46e92da921bafc8aba4912bf84d6c475f7625183772ed2d0844dc3a7"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"ctor",
|
||||
@ -334,29 +349,29 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "napi-build"
|
||||
version = "2.0.1"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "882a73d9ef23e8dc2ebbffb6a6ae2ef467c0f18ac10711e4cc59c5485d41df0e"
|
||||
checksum = "d4b4532cf86bfef556348ac65e561e3123879f0e7566cca6d43a6ff5326f13df"
|
||||
|
||||
[[package]]
|
||||
name = "napi-derive"
|
||||
version = "2.13.0"
|
||||
version = "2.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da1c6a8fa84d549aa8708fcd062372bf8ec6e849de39016ab921067d21bde367"
|
||||
checksum = "9b5af262f1d8e660742eb722abc7113a5b3c3de4144d0ef23ede2518672ceff1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"convert_case",
|
||||
"napi-derive-backend",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi-derive-backend"
|
||||
version = "1.0.52"
|
||||
version = "1.0.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20bbc7c69168d06a848f925ec5f0e0997f98e8c8d4f2cc30157f0da51c009e17"
|
||||
checksum = "4ea236321b521d6926213a2021e407b0562e28a257c037a45919e414d2cdb4f8"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"once_cell",
|
||||
@ -364,14 +379,14 @@ dependencies = [
|
||||
"quote",
|
||||
"regex",
|
||||
"semver",
|
||||
"syn 1.0.109",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi-sys"
|
||||
version = "2.2.3"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "166b5ef52a3ab5575047a9fe8d4a030cdd0f63c96f071cd6907674453b07bae3"
|
||||
checksum = "2503fa6af34dc83fb74888df8b22afe933b58d37daf7d80424b1c60c68196b8b"
|
||||
dependencies = [
|
||||
"libloading",
|
||||
]
|
||||
@ -408,9 +423,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
@ -427,9 +442,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.69"
|
||||
version = "1.0.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -501,27 +516,11 @@ version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "rust"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"clipboard-win",
|
||||
"image",
|
||||
"napi",
|
||||
"napi-build",
|
||||
"napi-derive",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"static_vcruntime",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.15"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
@ -537,22 +536,22 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.190"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7"
|
||||
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.190"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3"
|
||||
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -574,9 +573,9 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.11.1"
|
||||
version = "1.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
|
||||
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
@ -601,20 +600,9 @@ checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
version = "2.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
|
||||
checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -681,6 +669,15 @@ dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
|
9
Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["./packages/addon"]
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
opt-level = 3
|
||||
strip = "symbols"
|
6
build.rs
@ -1,6 +0,0 @@
|
||||
extern crate napi_build;
|
||||
|
||||
fn main() {
|
||||
static_vcruntime::metabuild();
|
||||
napi_build::setup();
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
import { join, dirname } from "node:path";
|
||||
import Database from "better-sqlite3-multiple-ciphers";
|
||||
import { getUserDataPath } from "../main/commons";
|
||||
|
||||
let database: Database.Database;
|
||||
let cacheDatabase: Database.Database;
|
||||
|
||||
function getDataSqlite3() {
|
||||
let filename = join(getUserDataPath(), "Data.db");
|
||||
database ??= new Database(filename, {
|
||||
nativeBinding: join(
|
||||
process.env.NODE_ENV !== "development" ? dirname(process.execPath) : "",
|
||||
import.meta.env.VITE_BETTER_SQLITE3_BINDING
|
||||
),
|
||||
});
|
||||
return database;
|
||||
}
|
||||
|
||||
function getCacheDataSqlite3() {
|
||||
let filename = join(getUserDataPath(), "CacheData.db");
|
||||
cacheDatabase ??= new Database(filename, {
|
||||
nativeBinding: join(
|
||||
process.env.NODE_ENV !== "development" ? dirname(process.execPath) : "",
|
||||
import.meta.env.VITE_BETTER_SQLITE3_BINDING
|
||||
),
|
||||
});
|
||||
return cacheDatabase;
|
||||
}
|
||||
|
||||
function getCustomDataSqlite3(filePath: string) {
|
||||
let db = new Database(filePath, {
|
||||
nativeBinding: join(
|
||||
process.env.NODE_ENV !== "development" ? dirname(process.execPath) : "",
|
||||
import.meta.env.VITE_BETTER_SQLITE3_BINDING
|
||||
),
|
||||
});
|
||||
return db;
|
||||
}
|
||||
|
||||
export { getDataSqlite3, getCacheDataSqlite3, getCustomDataSqlite3 };
|
@ -1,336 +0,0 @@
|
||||
import { Menu, MenuItem, ipcMain, dialog } from "electron";
|
||||
import { Classification } from "../../../types/classification";
|
||||
import {
|
||||
createAddEditWindow,
|
||||
createAssociateFolderWindow,
|
||||
createSetIconWindow,
|
||||
getItemLayoutMenu,
|
||||
getItemSortMenu,
|
||||
getItemColumnNumber,
|
||||
setAssociateFolder,
|
||||
getItemIconSize,
|
||||
addClassificationByDirectory,
|
||||
getItemShowOnly,
|
||||
createAggregateWindow,
|
||||
updateAggregate,
|
||||
updateExcludeSearch,
|
||||
} from "./index";
|
||||
import {
|
||||
add,
|
||||
del,
|
||||
list,
|
||||
selectById,
|
||||
update,
|
||||
updateOrder,
|
||||
updateIcon,
|
||||
hasChildClassification,
|
||||
batchUpdateFixed,
|
||||
} from "./data";
|
||||
import { setShortcutKey } from "../setting";
|
||||
import { closeWindow, getDot, sendToWebContent } from "../commons/index";
|
||||
|
||||
export default function () {
|
||||
// 获取分类列表
|
||||
ipcMain.on("getClassificationList", (event) => {
|
||||
event.returnValue = list(null);
|
||||
});
|
||||
// 根据ID查询分类
|
||||
ipcMain.on("getClassificationById", (event, args) => {
|
||||
event.returnValue = selectById(args.id);
|
||||
});
|
||||
// 添加分类
|
||||
ipcMain.on("addClassification", (event, args) => {
|
||||
let classification = add(
|
||||
args.parentId,
|
||||
args.name,
|
||||
args.shortcutKey,
|
||||
args.globalShortcutKey
|
||||
);
|
||||
setShortcutKey();
|
||||
event.returnValue = classification;
|
||||
});
|
||||
// 更新分类
|
||||
ipcMain.on("updateClassification", (event, args) => {
|
||||
let res = update(args);
|
||||
setShortcutKey();
|
||||
event.returnValue = res;
|
||||
});
|
||||
// 更新序号
|
||||
ipcMain.on("updateClassificationOrder", (event, args) => {
|
||||
event.returnValue = updateOrder(args.fromId, args.toId, args.parentId);
|
||||
});
|
||||
// 更新图标
|
||||
ipcMain.on("updateClassificationIcon", (event, args) => {
|
||||
event.returnValue = updateIcon(args.id, args.icon);
|
||||
});
|
||||
// 显示新增/修改窗口
|
||||
ipcMain.on("showClassificationAddEditWindow", () => {
|
||||
if (global.classificationAddEditWindow) {
|
||||
global.classificationAddEditWindow.show();
|
||||
}
|
||||
});
|
||||
// 关闭新增/修改窗口
|
||||
ipcMain.on("closeClassificationAddEditWindow", () => {
|
||||
closeWindow(global.classificationAddEditWindow);
|
||||
});
|
||||
// 显示设置图标窗口
|
||||
ipcMain.on("showClassificationSetIconWindow", () => {
|
||||
if (global.classificationSetIconWindow) {
|
||||
global.classificationSetIconWindow.show();
|
||||
}
|
||||
});
|
||||
// 关闭设置图标窗口
|
||||
ipcMain.on("closeClassificationSetIconWindow", () => {
|
||||
closeWindow(global.classificationSetIconWindow);
|
||||
});
|
||||
// 右键菜单
|
||||
ipcMain.on("showClassificationRightMenu", (event, args) => {
|
||||
// 锁定/解锁分类
|
||||
let lockClassification: boolean = args.lockClassification;
|
||||
// 分类
|
||||
let classification: Classification | null = args.classification;
|
||||
// 菜单
|
||||
let menuList: Array<MenuItem> = [];
|
||||
// 组装菜单
|
||||
if (!classification) {
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.newClassification,
|
||||
click: () => {
|
||||
// 创建窗口
|
||||
createAddEditWindow(null, null);
|
||||
},
|
||||
}),
|
||||
new MenuItem({ type: "separator" }),
|
||||
new MenuItem({
|
||||
label: !lockClassification
|
||||
? global.language.lockClassification
|
||||
: global.language.unlockClassification,
|
||||
click: () => {
|
||||
sendToWebContent("mainWindow", "onLockClassification", []);
|
||||
},
|
||||
})
|
||||
);
|
||||
} else {
|
||||
if (!classification.parentId && classification.type === 0) {
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.newSubclassification,
|
||||
click: () => {
|
||||
// 创建窗口
|
||||
createAddEditWindow(null, classification.id);
|
||||
},
|
||||
}),
|
||||
new MenuItem({ type: "separator" })
|
||||
);
|
||||
}
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.fixedClassification,
|
||||
icon: classification.data.fixed ? getDot() : null,
|
||||
click: () => {
|
||||
batchUpdateFixed(
|
||||
classification.data.fixed ? null : classification.id
|
||||
);
|
||||
sendToWebContent(
|
||||
"mainWindow",
|
||||
"onUpdateClassificationFixed",
|
||||
classification.data.fixed ? null : classification.id
|
||||
);
|
||||
},
|
||||
})
|
||||
);
|
||||
if (classification.type === 0 || classification.type === 1) {
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.excludeSearch,
|
||||
icon: classification.data.excludeSearch ? getDot() : null,
|
||||
click: () => {
|
||||
updateExcludeSearch(
|
||||
classification.id,
|
||||
!classification.data.excludeSearch
|
||||
);
|
||||
sendToWebContent(
|
||||
"mainWindow",
|
||||
"onUpdateClassificationExcludeSearch",
|
||||
{
|
||||
id: classification.id,
|
||||
value: !classification.data.excludeSearch,
|
||||
}
|
||||
);
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
menuList.push(new MenuItem({ type: "separator" }));
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.setIcon,
|
||||
click: () => {
|
||||
// 创建窗口
|
||||
createSetIconWindow(classification.id);
|
||||
},
|
||||
}),
|
||||
new MenuItem({
|
||||
label: global.language.deleteIcon,
|
||||
click: () => {
|
||||
let res = updateIcon(classification.id, null);
|
||||
if (res) {
|
||||
sendToWebContent("mainWindow", "onUpdateClassificationIcon", {
|
||||
id: classification.id,
|
||||
icon: null,
|
||||
});
|
||||
}
|
||||
},
|
||||
})
|
||||
);
|
||||
// 子分类、没有子分类的父级分类可以显示
|
||||
if (
|
||||
classification.parentId ||
|
||||
(!classification.parentId && !hasChildClassification(classification.id))
|
||||
) {
|
||||
menuList.push(new MenuItem({ type: "separator" }));
|
||||
if (classification.type === 0 || classification.type === 1) {
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.associateFolder,
|
||||
click: () => {
|
||||
// 创建窗口
|
||||
createAssociateFolderWindow(classification.id);
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
if (classification.type === 0 || classification.type === 2) {
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.aggregateClassification,
|
||||
click: () => {
|
||||
// 创建窗口
|
||||
createAggregateWindow(classification.id);
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
// 分割线
|
||||
menuList.push(new MenuItem({ type: "separator" }));
|
||||
if (classification.type !== 2) {
|
||||
// 排序
|
||||
menuList.push(getItemSortMenu(classification));
|
||||
}
|
||||
// 布局
|
||||
menuList.push(getItemLayoutMenu(classification));
|
||||
// 列数
|
||||
if (
|
||||
!hasChildClassification(classification.id) &&
|
||||
(classification.data.itemLayout === "list" ||
|
||||
(global.setting.item.layout === "list" &&
|
||||
classification.data.itemLayout === "default"))
|
||||
) {
|
||||
// 只有子级分类或没有子级分类的父级分类并且布局是列表的才显示列数
|
||||
menuList.push(getItemColumnNumber(classification));
|
||||
}
|
||||
// 图标
|
||||
menuList.push(getItemIconSize(classification));
|
||||
// 显示
|
||||
menuList.push(getItemShowOnly(classification));
|
||||
// 编辑/删除
|
||||
menuList.push(
|
||||
new MenuItem({ type: "separator" }),
|
||||
new MenuItem({
|
||||
label: global.language.edit,
|
||||
click: () => {
|
||||
// 创建窗口
|
||||
createAddEditWindow(classification.id, null);
|
||||
},
|
||||
}),
|
||||
new MenuItem({
|
||||
label: global.language.delete,
|
||||
click: () => {
|
||||
let res = dialog.showMessageBoxSync(global.mainWindow, {
|
||||
message: global.language.deleteClassificationPrompt,
|
||||
buttons: [global.language.ok, global.language.cancel],
|
||||
type: "question",
|
||||
noLink: true,
|
||||
cancelId: 1,
|
||||
});
|
||||
if (res === 0) {
|
||||
// 删除数据
|
||||
if (del(classification.id)) {
|
||||
// 快捷键
|
||||
setShortcutKey();
|
||||
// 通知前端删除数据
|
||||
sendToWebContent(
|
||||
"mainWindow",
|
||||
"onDeleteClassification",
|
||||
classification.id
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
// 载入菜单
|
||||
let menu = Menu.buildFromTemplate(menuList);
|
||||
// 菜单显示
|
||||
menu.on("menu-will-show", () => {
|
||||
global.classificationRightMenu = true;
|
||||
});
|
||||
// 菜单关闭
|
||||
menu.on("menu-will-close", () => {
|
||||
global.classificationRightMenu = false;
|
||||
});
|
||||
// 显示
|
||||
menu.popup();
|
||||
});
|
||||
// 显示关联文件夹窗口
|
||||
ipcMain.on("showClassificationAssociateFolderWindow", () => {
|
||||
if (global.classificationAssociateFolderWindow) {
|
||||
global.classificationAssociateFolderWindow.show();
|
||||
}
|
||||
});
|
||||
// 关闭关联文件夹窗口
|
||||
ipcMain.on("closeClassificationAssociateFolderWindow", () => {
|
||||
closeWindow(global.classificationAssociateFolderWindow);
|
||||
});
|
||||
// 设置关联文件夹
|
||||
ipcMain.on("setClassificationAssociateFolder", (event, args) => {
|
||||
// 分类ID
|
||||
let id: number = args.id;
|
||||
// 文件夹路径
|
||||
let dir: string | null = args.dir;
|
||||
if (!dir || dir.trim() === "") {
|
||||
dir = null;
|
||||
}
|
||||
// 隐藏项
|
||||
let hiddenItems: string | null = args.hiddenItems;
|
||||
// 设置
|
||||
event.returnValue = setAssociateFolder(id, dir, hiddenItems);
|
||||
});
|
||||
// 是否拥有子分类
|
||||
ipcMain.on("hasChildClassification", (event, args) => {
|
||||
event.returnValue = hasChildClassification(args);
|
||||
});
|
||||
// 根据文件夹创建分类
|
||||
ipcMain.on("addClassificationByDirectory", (event, args) => {
|
||||
let res = addClassificationByDirectory(args);
|
||||
// 通知页面
|
||||
sendToWebContent("mainWindow", "onAddClassificationByDirectory", res);
|
||||
});
|
||||
// 显示聚合分类窗口
|
||||
ipcMain.on("showClassificationAggregateWindow", () => {
|
||||
if (global.classificationAggregateWindow) {
|
||||
global.classificationAggregateWindow.show();
|
||||
}
|
||||
});
|
||||
// 关闭聚合分类窗口
|
||||
ipcMain.on("closeClassificationAggregateWindow", () => {
|
||||
closeWindow(global.classificationAggregateWindow);
|
||||
});
|
||||
// 更新聚合分类
|
||||
ipcMain.on("updateClassificationAggregate", (event, args) => {
|
||||
event.returnValue = updateAggregate(args.id, args.sort, args.itemCount);
|
||||
});
|
||||
}
|
78
package.json
@ -1,74 +1,18 @@
|
||||
{
|
||||
"name": "dawn-launcher",
|
||||
"name": "@dawn-launcher/monorepos",
|
||||
"productName": "Dawn Launcher",
|
||||
"version": "1.3.5",
|
||||
"main": "dist-electron/main/index.js",
|
||||
"description": "Windows 快捷启动工具,帮助您整理杂乱无章的桌面,分门别类管理您的桌面快捷方式,让您的桌面保持干净整洁。",
|
||||
"author": "FanChenIO",
|
||||
"private": true,
|
||||
"keywords": [
|
||||
"electron",
|
||||
"vite",
|
||||
"vue"
|
||||
"author": "FanChenIO",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
],
|
||||
"debug": {
|
||||
"env": {
|
||||
"VITE_DEV_SERVER_URL": "http://127.0.0.1:3344/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc --noEmit && vite build && electron-builder",
|
||||
"preview": "vite preview",
|
||||
"rsbuild": "napi build --release --strip ./native",
|
||||
"rebuild": "electron rebuild.js",
|
||||
"postinstall": "yarn run rebuild && yarn run rsbuild"
|
||||
"dev": "yarn workspace @dawn-launcher/electron dev",
|
||||
"build:addon": "yarn workspace @dawn-launcher/addon build",
|
||||
"build:sqlite": "npx electron rebuild.js",
|
||||
"postinstall": "yarn build:addon && yarn build:sqlite"
|
||||
},
|
||||
"napi": {
|
||||
"name": "addon"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@napi-rs/cli": "^2.16.3",
|
||||
"@vicons/material": "^0.12.0",
|
||||
"@vicons/ionicons5": "^0.12.0",
|
||||
"@vicons/utils": "^0.1.4",
|
||||
"@vitejs/plugin-vue": "^4.4.0",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"better-sqlite3-multiple-ciphers": "^9.0.0",
|
||||
"electron": "^26.4.2",
|
||||
"electron-builder": "^24.6.4",
|
||||
"less": "^4.2.0",
|
||||
"less-loader": "^11.1.3",
|
||||
"naive-ui": "^2.35.0",
|
||||
"postcss": "^8.4.31",
|
||||
"tailwindcss": "^3.3.5",
|
||||
"typescript": "^5.2.2",
|
||||
"vite": "^4.4.11",
|
||||
"vite-plugin-electron": "^0.15.4",
|
||||
"vue": "^3.3.7",
|
||||
"vue-tsc": "^1.8.22"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/dompurify": "^3.0.3",
|
||||
"@types/mime": "^3.0.2",
|
||||
"@types/request": "^2.48.10",
|
||||
"@types/retry": "^0.12.3",
|
||||
"@types/sortablejs": "^1.15.3",
|
||||
"@types/urijs": "^1.19.22",
|
||||
"@types/xml2js": "^0.4.12",
|
||||
"cheerio": "1.0.0-rc.12",
|
||||
"dompurify": "^3.0.6",
|
||||
"electron-log": "^5.0.0",
|
||||
"electron-store": "^8.1.0",
|
||||
"mime": "^3.0.0",
|
||||
"pinia": "^2.1.7",
|
||||
"pinyin-pro": "^3.17.0",
|
||||
"request": "^2.88.2",
|
||||
"retry": "^0.13.1",
|
||||
"simplebar": "^6.2.5",
|
||||
"sortablejs": "^1.15.0",
|
||||
"urijs": "^1.19.11",
|
||||
"vue-router": "^4.2.5",
|
||||
"xml2js": "^0.6.2"
|
||||
}
|
||||
}
|
||||
"packageManager": "yarn@4.0.2"
|
||||
}
|
||||
|
197
packages/addon/.gitignore
vendored
Normal file
@ -0,0 +1,197 @@
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/node
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=node
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/node
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/macos
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=macos
|
||||
|
||||
### macOS ###
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### macOS Patch ###
|
||||
# iCloud generated files
|
||||
*.icloud
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/macos
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/windows
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=windows
|
||||
|
||||
### Windows ###
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/windows
|
||||
|
||||
#Added by cargo
|
||||
|
||||
/target
|
||||
Cargo.lock
|
||||
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
*.node
|
13
packages/addon/.npmignore
Normal file
@ -0,0 +1,13 @@
|
||||
target
|
||||
Cargo.lock
|
||||
.cargo
|
||||
.github
|
||||
npm
|
||||
.eslintrc
|
||||
.prettierignore
|
||||
rustfmt.toml
|
||||
yarn.lock
|
||||
*.node
|
||||
.yarn
|
||||
__test__
|
||||
renovate.json
|
1
packages/addon/.yarnrc.yml
Normal file
@ -0,0 +1 @@
|
||||
nodeLinker: node-modules
|
@ -1,11 +1,10 @@
|
||||
[package]
|
||||
name = "rust"
|
||||
version = "0.0.0"
|
||||
build = "build.rs"
|
||||
edition = "2021"
|
||||
name = "addon"
|
||||
version = "0.0.1"
|
||||
authors = ["fanchenio <fanchenio@163.com>", "DarkSky <darksky2048@gmail.com>"]
|
||||
|
||||
[lib]
|
||||
path = "rust/lib.rs"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
@ -13,12 +12,12 @@ napi = { version = "2", features = ["napi4"] }
|
||||
napi-derive = "2"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
image = "0.24.6"
|
||||
image = "0.24.7"
|
||||
base64 = "0.21.2"
|
||||
clipboard-win = "4.5.0"
|
||||
|
||||
[dependencies.windows]
|
||||
version = "0.48"
|
||||
version = "0.48.0"
|
||||
features = [
|
||||
"Win32_Foundation",
|
||||
"Win32_Graphics_Gdi",
|
||||
@ -40,3 +39,6 @@ features = [
|
||||
[build-dependencies]
|
||||
napi-build = "2"
|
||||
static_vcruntime = "2.0"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
6
packages/addon/build.rs
Normal file
@ -0,0 +1,6 @@
|
||||
extern crate napi_build;
|
||||
|
||||
fn main() {
|
||||
static_vcruntime::metabuild();
|
||||
napi_build::setup();
|
||||
}
|
85
packages/addon/index.d.ts
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
/* auto-generated by NAPI-RS */
|
||||
|
||||
/**
|
||||
* 获取图标
|
||||
*/
|
||||
export function getFileIcon(path: string): string | null
|
||||
/**
|
||||
* 搜索路径
|
||||
*/
|
||||
export function searchPath(path: string): string | null
|
||||
/**
|
||||
* 解析快捷方式
|
||||
*/
|
||||
export function getShortcutFileInfo(path: string): Record<string, string> | null
|
||||
/**
|
||||
* 运行
|
||||
*/
|
||||
export function shellExecute(operation: string, file: string, params: string, startLocation?: string | undefined | null): void
|
||||
/**
|
||||
* 运行系统项目
|
||||
*/
|
||||
export function systemItemExecute(target: string, params?: string | undefined | null): void
|
||||
/**
|
||||
* 打开文件所在位置
|
||||
*/
|
||||
export function openFileLocation(path: string): void
|
||||
/**
|
||||
* 资源管理器菜单
|
||||
*/
|
||||
export function explorerContextMenu(window: number, path: string, x: number, y: number): void
|
||||
/**
|
||||
* 获取环境变量
|
||||
*/
|
||||
export function getEnvByName(name: string): string | null
|
||||
/**
|
||||
* 是否是全屏模式
|
||||
*/
|
||||
export function isFullscreen(): boolean
|
||||
/**
|
||||
* 切换英文输入法
|
||||
*/
|
||||
export function switchEnglish(window: number): void
|
||||
/**
|
||||
* 创建鼠标HOOK
|
||||
*/
|
||||
export function createMouseHook(callback: (...args: any[]) => any): void
|
||||
/**
|
||||
* 启用鼠标HOOK
|
||||
*/
|
||||
export function enableMouseHook(): void
|
||||
/**
|
||||
* 禁用鼠标HOOK
|
||||
*/
|
||||
export function disableMouseHook(): void
|
||||
/**
|
||||
* 获取鼠标点击的窗口ClassName
|
||||
*/
|
||||
export function getCursorPosWindowClassName(): string
|
||||
/**
|
||||
* 获取剪切板文件列表
|
||||
*/
|
||||
export function getClipboardFileList(): Array<string>
|
||||
/**
|
||||
* 剪切板是否存在BITMAP
|
||||
*/
|
||||
export function clipboardHasBitmap(): boolean
|
||||
/**
|
||||
* 获取剪切板BITMAP的BASE64
|
||||
*/
|
||||
export function getClipboardBitmapBase64(): string | null
|
||||
/**
|
||||
* 清空回收站
|
||||
*/
|
||||
export function emptyRecycleBin(window: number): void
|
||||
/**
|
||||
* 去掉窗口动画
|
||||
*/
|
||||
export function removeWindowAnimation(window: number): void
|
||||
/**
|
||||
* 获取APPX列表
|
||||
*/
|
||||
export function getAppxList(): Array<Record<string, string>>
|
305
packages/addon/index.js
Normal file
@ -0,0 +1,305 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
/* auto-generated by NAPI-RS */
|
||||
|
||||
const { existsSync, readFileSync } = require('fs')
|
||||
const { join } = require('path')
|
||||
|
||||
const { platform, arch } = process
|
||||
|
||||
let nativeBinding = null
|
||||
let localFileExisted = false
|
||||
let loadError = null
|
||||
|
||||
function isMusl() {
|
||||
// For Node 10
|
||||
if (!process.report || typeof process.report.getReport !== 'function') {
|
||||
try {
|
||||
const lddPath = require('child_process').execSync('which ldd').toString().trim()
|
||||
return readFileSync(lddPath, 'utf8').includes('musl')
|
||||
} catch (e) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
const { glibcVersionRuntime } = process.report.getReport().header
|
||||
return !glibcVersionRuntime
|
||||
}
|
||||
}
|
||||
|
||||
switch (platform) {
|
||||
case 'android':
|
||||
switch (arch) {
|
||||
case 'arm64':
|
||||
localFileExisted = existsSync(join(__dirname, 'addon.android-arm64.node'))
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.android-arm64.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-android-arm64')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
break
|
||||
case 'arm':
|
||||
localFileExisted = existsSync(join(__dirname, 'addon.android-arm-eabi.node'))
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.android-arm-eabi.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-android-arm-eabi')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
break
|
||||
default:
|
||||
throw new Error(`Unsupported architecture on Android ${arch}`)
|
||||
}
|
||||
break
|
||||
case 'win32':
|
||||
switch (arch) {
|
||||
case 'x64':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'addon.win32-x64-msvc.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.win32-x64-msvc.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-win32-x64-msvc')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
break
|
||||
case 'ia32':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'addon.win32-ia32-msvc.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.win32-ia32-msvc.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-win32-ia32-msvc')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
break
|
||||
case 'arm64':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'addon.win32-arm64-msvc.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.win32-arm64-msvc.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-win32-arm64-msvc')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
break
|
||||
default:
|
||||
throw new Error(`Unsupported architecture on Windows: ${arch}`)
|
||||
}
|
||||
break
|
||||
case 'darwin':
|
||||
localFileExisted = existsSync(join(__dirname, 'addon.darwin-universal.node'))
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.darwin-universal.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-darwin-universal')
|
||||
}
|
||||
break
|
||||
} catch {}
|
||||
switch (arch) {
|
||||
case 'x64':
|
||||
localFileExisted = existsSync(join(__dirname, 'addon.darwin-x64.node'))
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.darwin-x64.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-darwin-x64')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
break
|
||||
case 'arm64':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'addon.darwin-arm64.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.darwin-arm64.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-darwin-arm64')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
break
|
||||
default:
|
||||
throw new Error(`Unsupported architecture on macOS: ${arch}`)
|
||||
}
|
||||
break
|
||||
case 'freebsd':
|
||||
if (arch !== 'x64') {
|
||||
throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
|
||||
}
|
||||
localFileExisted = existsSync(join(__dirname, 'addon.freebsd-x64.node'))
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.freebsd-x64.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-freebsd-x64')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
break
|
||||
case 'linux':
|
||||
switch (arch) {
|
||||
case 'x64':
|
||||
if (isMusl()) {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'addon.linux-x64-musl.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.linux-x64-musl.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-linux-x64-musl')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
} else {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'addon.linux-x64-gnu.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.linux-x64-gnu.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-linux-x64-gnu')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'arm64':
|
||||
if (isMusl()) {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'addon.linux-arm64-musl.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.linux-arm64-musl.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-linux-arm64-musl')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
} else {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'addon.linux-arm64-gnu.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.linux-arm64-gnu.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-linux-arm64-gnu')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'arm':
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'addon.linux-arm-gnueabihf.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.linux-arm-gnueabihf.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-linux-arm-gnueabihf')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
break
|
||||
case 'riscv64':
|
||||
if (isMusl()) {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'addon.linux-riscv64-musl.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.linux-riscv64-musl.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-linux-riscv64-musl')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
} else {
|
||||
localFileExisted = existsSync(
|
||||
join(__dirname, 'addon.linux-riscv64-gnu.node')
|
||||
)
|
||||
try {
|
||||
if (localFileExisted) {
|
||||
nativeBinding = require('./addon.linux-riscv64-gnu.node')
|
||||
} else {
|
||||
nativeBinding = require('@dawn-launcher/addon-linux-riscv64-gnu')
|
||||
}
|
||||
} catch (e) {
|
||||
loadError = e
|
||||
}
|
||||
}
|
||||
break
|
||||
default:
|
||||
throw new Error(`Unsupported architecture on Linux: ${arch}`)
|
||||
}
|
||||
break
|
||||
default:
|
||||
throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
|
||||
}
|
||||
|
||||
if (!nativeBinding) {
|
||||
if (loadError) {
|
||||
throw loadError
|
||||
}
|
||||
throw new Error(`Failed to load native binding`)
|
||||
}
|
||||
|
||||
const { getFileIcon, searchPath, getShortcutFileInfo, shellExecute, systemItemExecute, openFileLocation, explorerContextMenu, getEnvByName, isFullscreen, switchEnglish, createMouseHook, enableMouseHook, disableMouseHook, getCursorPosWindowClassName, getClipboardFileList, clipboardHasBitmap, getClipboardBitmapBase64, emptyRecycleBin, removeWindowAnimation, getAppxList } = nativeBinding
|
||||
|
||||
module.exports.getFileIcon = getFileIcon
|
||||
module.exports.searchPath = searchPath
|
||||
module.exports.getShortcutFileInfo = getShortcutFileInfo
|
||||
module.exports.shellExecute = shellExecute
|
||||
module.exports.systemItemExecute = systemItemExecute
|
||||
module.exports.openFileLocation = openFileLocation
|
||||
module.exports.explorerContextMenu = explorerContextMenu
|
||||
module.exports.getEnvByName = getEnvByName
|
||||
module.exports.isFullscreen = isFullscreen
|
||||
module.exports.switchEnglish = switchEnglish
|
||||
module.exports.createMouseHook = createMouseHook
|
||||
module.exports.enableMouseHook = enableMouseHook
|
||||
module.exports.disableMouseHook = disableMouseHook
|
||||
module.exports.getCursorPosWindowClassName = getCursorPosWindowClassName
|
||||
module.exports.getClipboardFileList = getClipboardFileList
|
||||
module.exports.clipboardHasBitmap = clipboardHasBitmap
|
||||
module.exports.getClipboardBitmapBase64 = getClipboardBitmapBase64
|
||||
module.exports.emptyRecycleBin = emptyRecycleBin
|
||||
module.exports.removeWindowAnimation = removeWindowAnimation
|
||||
module.exports.getAppxList = getAppxList
|
3
packages/addon/npm/win32-arm64-msvc/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# `addon-win32-arm64-msvc`
|
||||
|
||||
This is the **aarch64-pc-windows-msvc** binary for `addon`
|
18
packages/addon/npm/win32-arm64-msvc/package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "addon-win32-arm64-msvc",
|
||||
"version": "0.0.0",
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"main": "addon.win32-arm64-msvc.node",
|
||||
"files": [
|
||||
"addon.win32-arm64-msvc.node"
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
}
|
3
packages/addon/npm/win32-x64-msvc/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# `addon-win32-x64-msvc`
|
||||
|
||||
This is the **x86_64-pc-windows-msvc** binary for `addon`
|
18
packages/addon/npm/win32-x64-msvc/package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "addon-win32-x64-msvc",
|
||||
"version": "0.0.0",
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"main": "addon.win32-x64-msvc.node",
|
||||
"files": [
|
||||
"addon.win32-x64-msvc.node"
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
}
|
36
packages/addon/package.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "@dawn-launcher/addon",
|
||||
"version": "0.0.1",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"napi": {
|
||||
"name": "addon",
|
||||
"triples": {
|
||||
"defaults": false,
|
||||
"additional": [
|
||||
"aarch64-pc-windows-msvc",
|
||||
"x86_64-pc-windows-msvc"
|
||||
]
|
||||
}
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@napi-rs/cli": "^2.17.0",
|
||||
"ava": "^5.1.1"
|
||||
},
|
||||
"ava": {
|
||||
"timeout": "3m"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"scripts": {
|
||||
"artifacts": "napi artifacts",
|
||||
"build": "napi build --platform --release",
|
||||
"build:debug": "napi build --platform",
|
||||
"prepublishOnly": "napi prepublish -t npm",
|
||||
"test": "ava",
|
||||
"universal": "napi universal",
|
||||
"version": "napi version"
|
||||
}
|
||||
}
|
2
packages/addon/rustfmt.toml
Normal file
@ -0,0 +1,2 @@
|
||||
tab_spaces = 2
|
||||
edition = "2021"
|
@ -10,7 +10,7 @@ mod windows;
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn get_file_icon(path: String) -> Option<String> {
|
||||
windows::get_file_icon(&path)
|
||||
windows::get_file_icon(&path)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -19,7 +19,7 @@ fn get_file_icon(path: String) -> Option<String> {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn search_path(path: String) -> Option<String> {
|
||||
windows::search_path(&path)
|
||||
windows::search_path(&path)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -28,7 +28,7 @@ fn search_path(path: String) -> Option<String> {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn get_shortcut_file_info(path: String) -> Option<HashMap<String, String>> {
|
||||
windows::get_shortcut_file_info(&path)
|
||||
windows::get_shortcut_file_info(&path)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -37,7 +37,7 @@ fn get_shortcut_file_info(path: String) -> Option<HashMap<String, String>> {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn shell_execute(operation: String, file: String, params: String, start_location: Option<String>) {
|
||||
windows::shell_execute(operation, file, params, start_location)
|
||||
windows::shell_execute(operation, file, params, start_location)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,7 +46,7 @@ fn shell_execute(operation: String, file: String, params: String, start_location
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn system_item_execute(target: String, params: Option<String>) {
|
||||
windows::system_item_execute(&target, params.as_deref())
|
||||
windows::system_item_execute(&target, params.as_deref())
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,7 +55,7 @@ fn system_item_execute(target: String, params: Option<String>) {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn open_file_location(path: String) {
|
||||
windows::open_file_location(&path)
|
||||
windows::open_file_location(&path)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,7 +64,7 @@ fn open_file_location(path: String) {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn explorer_context_menu(window: i32, path: String, x: i32, y: i32) {
|
||||
windows::explorer_context_menu(window, &path, x, y)
|
||||
windows::explorer_context_menu(window, &path, x, y)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,7 +73,7 @@ fn explorer_context_menu(window: i32, path: String, x: i32, y: i32) {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn get_env_by_name(name: String) -> Option<String> {
|
||||
windows::get_env_by_name(&name)
|
||||
windows::get_env_by_name(&name)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,7 +82,7 @@ fn get_env_by_name(name: String) -> Option<String> {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn is_fullscreen() -> bool {
|
||||
windows::is_fullscreen()
|
||||
windows::is_fullscreen()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,7 +91,7 @@ fn is_fullscreen() -> bool {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn switch_english(window: i32) {
|
||||
windows::switch_english(window)
|
||||
windows::switch_english(window)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,7 +100,7 @@ fn switch_english(window: i32) {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn create_mouse_hook(callback: JsFunction) {
|
||||
windows::create_mouse_hook(callback)
|
||||
windows::create_mouse_hook(callback)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,7 +109,7 @@ fn create_mouse_hook(callback: JsFunction) {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn enable_mouse_hook() {
|
||||
windows::enable_mouse_hook()
|
||||
windows::enable_mouse_hook()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,7 +118,7 @@ fn enable_mouse_hook() {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn disable_mouse_hook() {
|
||||
windows::disable_mouse_hook()
|
||||
windows::disable_mouse_hook()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -127,7 +127,7 @@ fn disable_mouse_hook() {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn get_cursor_pos_window_class_name() -> String {
|
||||
windows::get_cursor_pos_window_class_name()
|
||||
windows::get_cursor_pos_window_class_name()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -136,7 +136,7 @@ fn get_cursor_pos_window_class_name() -> String {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn get_clipboard_file_list() -> Vec<String> {
|
||||
windows::get_clipboard_file_list()
|
||||
windows::get_clipboard_file_list()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,7 +145,7 @@ fn get_clipboard_file_list() -> Vec<String> {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn clipboard_has_bitmap() -> bool {
|
||||
windows::clipboard_has_bitmap()
|
||||
windows::clipboard_has_bitmap()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -154,7 +154,7 @@ fn clipboard_has_bitmap() -> bool {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn get_clipboard_bitmap_base64() -> Option<String> {
|
||||
windows::get_clipboard_bitmap_base64()
|
||||
windows::get_clipboard_bitmap_base64()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,7 +163,7 @@ fn get_clipboard_bitmap_base64() -> Option<String> {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn empty_recycle_bin(window: i32) {
|
||||
windows::empty_recycle_bin(window)
|
||||
windows::empty_recycle_bin(window)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,7 +172,7 @@ fn empty_recycle_bin(window: i32) {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn remove_window_animation(window: i32) {
|
||||
windows::remove_window_animation(window);
|
||||
windows::remove_window_animation(window);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -181,5 +181,5 @@ fn remove_window_animation(window: i32) {
|
||||
#[allow(dead_code)]
|
||||
#[napi]
|
||||
fn get_appx_list() -> Vec<HashMap<String, String>> {
|
||||
windows::get_appx_list()
|
||||
windows::get_appx_list()
|
||||
}
|
9
packages/addon/tsconfig.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": false,
|
||||
"outDir": "lib",
|
||||
"composite": true
|
||||
},
|
||||
"include": ["index.d.ts"]
|
||||
}
|
31
packages/electron/electron/commons/betterSqlite3.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { join, dirname } from 'node:path'
|
||||
import Database from 'better-sqlite3-multiple-ciphers'
|
||||
import { getUserDataPath } from '../main/commons'
|
||||
|
||||
let database: Database.Database
|
||||
let cacheDatabase: Database.Database
|
||||
|
||||
function getDataSqlite3() {
|
||||
let filename = join(getUserDataPath(), 'Data.db')
|
||||
database ??= new Database(filename, {
|
||||
nativeBinding: join(process.env.NODE_ENV !== 'development' ? dirname(process.execPath) : '', import.meta.env.VITE_BETTER_SQLITE3_BINDING),
|
||||
})
|
||||
return database
|
||||
}
|
||||
|
||||
function getCacheDataSqlite3() {
|
||||
let filename = join(getUserDataPath(), 'CacheData.db')
|
||||
cacheDatabase ??= new Database(filename, {
|
||||
nativeBinding: join(process.env.NODE_ENV !== 'development' ? dirname(process.execPath) : '', import.meta.env.VITE_BETTER_SQLITE3_BINDING),
|
||||
})
|
||||
return cacheDatabase
|
||||
}
|
||||
|
||||
function getCustomDataSqlite3(filePath: string) {
|
||||
let db = new Database(filePath, {
|
||||
nativeBinding: join(process.env.NODE_ENV !== 'development' ? dirname(process.execPath) : '', import.meta.env.VITE_BETTER_SQLITE3_BINDING),
|
||||
})
|
||||
return db
|
||||
}
|
||||
|
||||
export { getDataSqlite3, getCacheDataSqlite3, getCustomDataSqlite3 }
|
297
packages/electron/electron/main/classification/ipcEvent.ts
Normal file
@ -0,0 +1,297 @@
|
||||
import { Menu, MenuItem, ipcMain, dialog } from 'electron'
|
||||
import { Classification } from '../../../types/classification'
|
||||
import {
|
||||
createAddEditWindow,
|
||||
createAssociateFolderWindow,
|
||||
createSetIconWindow,
|
||||
getItemLayoutMenu,
|
||||
getItemSortMenu,
|
||||
getItemColumnNumber,
|
||||
setAssociateFolder,
|
||||
getItemIconSize,
|
||||
addClassificationByDirectory,
|
||||
getItemShowOnly,
|
||||
createAggregateWindow,
|
||||
updateAggregate,
|
||||
updateExcludeSearch,
|
||||
} from './index'
|
||||
import { add, del, list, selectById, update, updateOrder, updateIcon, hasChildClassification, batchUpdateFixed } from './data'
|
||||
import { setShortcutKey } from '../setting'
|
||||
import { closeWindow, getDot, sendToWebContent } from '../commons/index'
|
||||
|
||||
export default function () {
|
||||
// 获取分类列表
|
||||
ipcMain.on('getClassificationList', (event) => {
|
||||
event.returnValue = list(null)
|
||||
})
|
||||
// 根据ID查询分类
|
||||
ipcMain.on('getClassificationById', (event, args) => {
|
||||
event.returnValue = selectById(args.id)
|
||||
})
|
||||
// 添加分类
|
||||
ipcMain.on('addClassification', (event, args) => {
|
||||
let classification = add(args.parentId, args.name, args.shortcutKey, args.globalShortcutKey)
|
||||
setShortcutKey()
|
||||
event.returnValue = classification
|
||||
})
|
||||
// 更新分类
|
||||
ipcMain.on('updateClassification', (event, args) => {
|
||||
let res = update(args)
|
||||
setShortcutKey()
|
||||
event.returnValue = res
|
||||
})
|
||||
// 更新序号
|
||||
ipcMain.on('updateClassificationOrder', (event, args) => {
|
||||
event.returnValue = updateOrder(args.fromId, args.toId, args.parentId)
|
||||
})
|
||||
// 更新图标
|
||||
ipcMain.on('updateClassificationIcon', (event, args) => {
|
||||
event.returnValue = updateIcon(args.id, args.icon)
|
||||
})
|
||||
// 显示新增/修改窗口
|
||||
ipcMain.on('showClassificationAddEditWindow', () => {
|
||||
if (global.classificationAddEditWindow) {
|
||||
global.classificationAddEditWindow.show()
|
||||
}
|
||||
})
|
||||
// 关闭新增/修改窗口
|
||||
ipcMain.on('closeClassificationAddEditWindow', () => {
|
||||
closeWindow(global.classificationAddEditWindow)
|
||||
})
|
||||
// 显示设置图标窗口
|
||||
ipcMain.on('showClassificationSetIconWindow', () => {
|
||||
if (global.classificationSetIconWindow) {
|
||||
global.classificationSetIconWindow.show()
|
||||
}
|
||||
})
|
||||
// 关闭设置图标窗口
|
||||
ipcMain.on('closeClassificationSetIconWindow', () => {
|
||||
closeWindow(global.classificationSetIconWindow)
|
||||
})
|
||||
// 右键菜单
|
||||
ipcMain.on('showClassificationRightMenu', (event, args) => {
|
||||
// 锁定/解锁分类
|
||||
let lockClassification: boolean = args.lockClassification
|
||||
// 分类
|
||||
let classification: Classification | null = args.classification
|
||||
// 菜单
|
||||
let menuList: Array<MenuItem> = []
|
||||
// 组装菜单
|
||||
if (!classification) {
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.newClassification,
|
||||
click: () => {
|
||||
// 创建窗口
|
||||
createAddEditWindow(null, null)
|
||||
},
|
||||
}),
|
||||
new MenuItem({ type: 'separator' }),
|
||||
new MenuItem({
|
||||
label: !lockClassification ? global.language.lockClassification : global.language.unlockClassification,
|
||||
click: () => {
|
||||
sendToWebContent('mainWindow', 'onLockClassification', [])
|
||||
},
|
||||
})
|
||||
)
|
||||
} else {
|
||||
if (!classification.parentId && classification.type === 0) {
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.newSubclassification,
|
||||
click: () => {
|
||||
// 创建窗口
|
||||
createAddEditWindow(null, classification.id)
|
||||
},
|
||||
}),
|
||||
new MenuItem({ type: 'separator' })
|
||||
)
|
||||
}
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.fixedClassification,
|
||||
icon: classification.data.fixed ? getDot() : null,
|
||||
click: () => {
|
||||
batchUpdateFixed(classification.data.fixed ? null : classification.id)
|
||||
sendToWebContent('mainWindow', 'onUpdateClassificationFixed', classification.data.fixed ? null : classification.id)
|
||||
},
|
||||
})
|
||||
)
|
||||
if (classification.type === 0 || classification.type === 1) {
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.excludeSearch,
|
||||
icon: classification.data.excludeSearch ? getDot() : null,
|
||||
click: () => {
|
||||
updateExcludeSearch(classification.id, !classification.data.excludeSearch)
|
||||
sendToWebContent('mainWindow', 'onUpdateClassificationExcludeSearch', {
|
||||
id: classification.id,
|
||||
value: !classification.data.excludeSearch,
|
||||
})
|
||||
},
|
||||
})
|
||||
)
|
||||
}
|
||||
menuList.push(new MenuItem({ type: 'separator' }))
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.setIcon,
|
||||
click: () => {
|
||||
// 创建窗口
|
||||
createSetIconWindow(classification.id)
|
||||
},
|
||||
}),
|
||||
new MenuItem({
|
||||
label: global.language.deleteIcon,
|
||||
click: () => {
|
||||
let res = updateIcon(classification.id, null)
|
||||
if (res) {
|
||||
sendToWebContent('mainWindow', 'onUpdateClassificationIcon', {
|
||||
id: classification.id,
|
||||
icon: null,
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
)
|
||||
// 子分类、没有子分类的父级分类可以显示
|
||||
if (classification.parentId || (!classification.parentId && !hasChildClassification(classification.id))) {
|
||||
menuList.push(new MenuItem({ type: 'separator' }))
|
||||
if (classification.type === 0 || classification.type === 1) {
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.associateFolder,
|
||||
click: () => {
|
||||
// 创建窗口
|
||||
createAssociateFolderWindow(classification.id)
|
||||
},
|
||||
})
|
||||
)
|
||||
}
|
||||
if (classification.type === 0 || classification.type === 2) {
|
||||
menuList.push(
|
||||
new MenuItem({
|
||||
label: global.language.aggregateClassification,
|
||||
click: () => {
|
||||
// 创建窗口
|
||||
createAggregateWindow(classification.id)
|
||||
},
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
// 分割线
|
||||
menuList.push(new MenuItem({ type: 'separator' }))
|
||||
if (classification.type !== 2) {
|
||||
// 排序
|
||||
menuList.push(getItemSortMenu(classification))
|
||||
}
|
||||
// 布局
|
||||
menuList.push(getItemLayoutMenu(classification))
|
||||
// 列数
|
||||
if (
|
||||
!hasChildClassification(classification.id) &&
|
||||
(classification.data.itemLayout === 'list' || (global.setting.item.layout === 'list' && classification.data.itemLayout === 'default'))
|
||||
) {
|
||||
// 只有子级分类或没有子级分类的父级分类并且布局是列表的才显示列数
|
||||
menuList.push(getItemColumnNumber(classification))
|
||||
}
|
||||
// 图标
|
||||
menuList.push(getItemIconSize(classification))
|
||||
// 显示
|
||||
menuList.push(getItemShowOnly(classification))
|
||||
// 编辑/删除
|
||||
menuList.push(
|
||||
new MenuItem({ type: 'separator' }),
|
||||
new MenuItem({
|
||||
label: global.language.edit,
|
||||
click: () => {
|
||||
// 创建窗口
|
||||
createAddEditWindow(classification.id, null)
|
||||
},
|
||||
}),
|
||||
new MenuItem({
|
||||
label: global.language.delete,
|
||||
click: () => {
|
||||
let res = dialog.showMessageBoxSync(global.mainWindow, {
|
||||
message: global.language.deleteClassificationPrompt,
|
||||
buttons: [global.language.ok, global.language.cancel],
|
||||
type: 'question',
|
||||
noLink: true,
|
||||
cancelId: 1,
|
||||
})
|
||||
if (res === 0) {
|
||||
// 删除数据
|
||||
if (del(classification.id)) {
|
||||
// 快捷键
|
||||
setShortcutKey()
|
||||
// 通知前端删除数据
|
||||
sendToWebContent('mainWindow', 'onDeleteClassification', classification.id)
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
)
|
||||
}
|
||||
// 载入菜单
|
||||
let menu = Menu.buildFromTemplate(menuList)
|
||||
// 菜单显示
|
||||
menu.on('menu-will-show', () => {
|
||||
global.classificationRightMenu = true
|
||||
})
|
||||
// 菜单关闭
|
||||
menu.on('menu-will-close', () => {
|
||||
global.classificationRightMenu = false
|
||||
})
|
||||
// 显示
|
||||
menu.popup()
|
||||
})
|
||||
// 显示关联文件夹窗口
|
||||
ipcMain.on('showClassificationAssociateFolderWindow', () => {
|
||||
if (global.classificationAssociateFolderWindow) {
|
||||
global.classificationAssociateFolderWindow.show()
|
||||
}
|
||||
})
|
||||
// 关闭关联文件夹窗口
|
||||
ipcMain.on('closeClassificationAssociateFolderWindow', () => {
|
||||
closeWindow(global.classificationAssociateFolderWindow)
|
||||
})
|
||||
// 设置关联文件夹
|
||||
ipcMain.on('setClassificationAssociateFolder', (event, args) => {
|
||||
// 分类ID
|
||||
let id: number = args.id
|
||||
// 文件夹路径
|
||||
let dir: string | null = args.dir
|
||||
if (!dir || dir.trim() === '') {
|
||||
dir = null
|
||||
}
|
||||
// 隐藏项
|
||||
let hiddenItems: string | null = args.hiddenItems
|
||||
// 设置
|
||||
event.returnValue = setAssociateFolder(id, dir, hiddenItems)
|
||||
})
|
||||
// 是否拥有子分类
|
||||
ipcMain.on('hasChildClassification', (event, args) => {
|
||||
event.returnValue = hasChildClassification(args)
|
||||
})
|
||||
// 根据文件夹创建分类
|
||||
ipcMain.on('addClassificationByDirectory', (event, args) => {
|
||||
let res = addClassificationByDirectory(args)
|
||||
// 通知页面
|
||||
sendToWebContent('mainWindow', 'onAddClassificationByDirectory', res)
|
||||
})
|
||||
// 显示聚合分类窗口
|
||||
ipcMain.on('showClassificationAggregateWindow', () => {
|
||||
if (global.classificationAggregateWindow) {
|
||||
global.classificationAggregateWindow.show()
|
||||
}
|
||||
})
|
||||
// 关闭聚合分类窗口
|
||||
ipcMain.on('closeClassificationAggregateWindow', () => {
|
||||
closeWindow(global.classificationAggregateWindow)
|
||||
})
|
||||
// 更新聚合分类
|
||||
ipcMain.on('updateClassificationAggregate', (event, args) => {
|
||||
event.returnValue = updateAggregate(args.id, args.sort, args.itemCount)
|
||||
})
|
||||
}
|
@ -55,7 +55,7 @@ if (!app.requestSingleInstanceLock()) {
|
||||
app.whenReady().then(() => {
|
||||
try {
|
||||
// addon
|
||||
global.addon = require("../../native/addon.node");
|
||||
global.addon = require("@dawn-launcher/addon");
|
||||
// 初始化数据
|
||||
settingDataInit();
|
||||
// 获取语言
|
@ -21,7 +21,7 @@ export interface AppxInfo {
|
||||
}
|
||||
|
||||
// addon
|
||||
global.addon = require("../../native/addon.node");
|
||||
global.addon = require("@dawn-launcher/addon");
|
||||
|
||||
// 接收消息
|
||||
process.parentPort.once("message", async (event) => {
|
70
packages/electron/package.json
Normal file
@ -0,0 +1,70 @@
|
||||
{
|
||||
"name": "@dawn-launcher/electron",
|
||||
"productName": "Dawn Launcher",
|
||||
"version": "1.3.5",
|
||||
"main": "dist-electron/main/index.js",
|
||||
"description": "Windows 快捷启动工具,帮助您整理杂乱无章的桌面,分门别类管理您的桌面快捷方式,让您的桌面保持干净整洁。",
|
||||
"author": "FanChenIO",
|
||||
"private": true,
|
||||
"keywords": [
|
||||
"electron",
|
||||
"vite",
|
||||
"vue"
|
||||
],
|
||||
"debug": {
|
||||
"env": {
|
||||
"VITE_DEV_SERVER_URL": "http://127.0.0.1:3344/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc --noEmit && vite build && electron-builder",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@dawn-launcher/addon": "workspace:*",
|
||||
"@napi-rs/cli": "^2.16.3",
|
||||
"@vicons/ionicons5": "^0.12.0",
|
||||
"@vicons/material": "^0.12.0",
|
||||
"@vicons/utils": "^0.1.4",
|
||||
"@vitejs/plugin-vue": "^4.4.0",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"better-sqlite3-multiple-ciphers": "^9.0.0",
|
||||
"electron": "^26.4.2",
|
||||
"electron-builder": "^24.6.4",
|
||||
"less": "^4.2.0",
|
||||
"less-loader": "^11.1.3",
|
||||
"naive-ui": "^2.35.0",
|
||||
"postcss": "^8.4.31",
|
||||
"tailwindcss": "^3.3.5",
|
||||
"typescript": "^5.2.2",
|
||||
"vite": "^4.4.11",
|
||||
"vite-plugin-commonjs": "^0.10.1",
|
||||
"vite-plugin-electron": "^0.15.4",
|
||||
"vue": "^3.3.7",
|
||||
"vue-tsc": "^1.8.22"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/dompurify": "^3.0.3",
|
||||
"@types/mime": "^3.0.2",
|
||||
"@types/request": "^2.48.10",
|
||||
"@types/retry": "^0.12.3",
|
||||
"@types/sortablejs": "^1.15.3",
|
||||
"@types/urijs": "^1.19.22",
|
||||
"@types/xml2js": "^0.4.12",
|
||||
"cheerio": "1.0.0-rc.12",
|
||||
"dompurify": "^3.0.6",
|
||||
"electron-log": "^5.0.0",
|
||||
"electron-store": "^8.1.0",
|
||||
"mime": "^3.0.0",
|
||||
"pinia": "^2.1.7",
|
||||
"pinyin-pro": "^3.17.0",
|
||||
"request": "^2.88.2",
|
||||
"retry": "^0.13.1",
|
||||
"simplebar": "^6.2.5",
|
||||
"sortablejs": "^1.15.0",
|
||||
"urijs": "^1.19.11",
|
||||
"vue-router": "^4.2.5",
|
||||
"xml2js": "^0.6.2"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 352 B After Width: | Height: | Size: 352 B |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 440 KiB After Width: | Height: | Size: 440 KiB |
Before Width: | Height: | Size: 428 KiB After Width: | Height: | Size: 428 KiB |