Merge branch 'develop' into feature/MFA
3
.github/workflows/nightly.yml
vendored
@ -5,6 +5,9 @@ on:
|
||||
- cron: "0 2 * * *" # run at 2 AM UTC
|
||||
# This can be used to allow manually triggering nightlies from the web interface
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- renovate/electron-forge*
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/actions/build-electron/*
|
||||
|
3
.vscode/extensions.json
vendored
@ -2,6 +2,7 @@
|
||||
"recommendations": [
|
||||
"lokalise.i18n-ally",
|
||||
"editorconfig.editorconfig",
|
||||
"vitest.explorer"
|
||||
"vitest.explorer",
|
||||
"ms-playwright.playwright"
|
||||
]
|
||||
}
|
||||
|
@ -47,6 +47,10 @@ test("User can change language from settings", async ({ page, context }) => {
|
||||
|
||||
// Select Chinese and ensure the translation is set.
|
||||
await languageCombobox.selectOption("cn");
|
||||
|
||||
// Press the refresh button.
|
||||
await app.currentNoteSplit.getByRole("button", { name: "Restart the application" }).click();
|
||||
|
||||
await expect(app.currentNoteSplit).toContainText("一周的第一天", { timeout: 15000 });
|
||||
await expect(languageCombobox).toHaveValue("cn");
|
||||
|
||||
|
BIN
images/app-icons/tray/new-windowTemplate-inverted.png
Normal file
After Width: | Height: | Size: 348 B |
BIN
images/app-icons/tray/new-windowTemplate-inverted@1.25x.png
Normal file
After Width: | Height: | Size: 427 B |
BIN
images/app-icons/tray/new-windowTemplate-inverted@1.5x.png
Normal file
After Width: | Height: | Size: 514 B |
BIN
images/app-icons/tray/new-windowTemplate-inverted@2x.png
Normal file
After Width: | Height: | Size: 649 B |
BIN
images/app-icons/tray/new-windowTemplate.png
Normal file
After Width: | Height: | Size: 331 B |
BIN
images/app-icons/tray/new-windowTemplate@1.25x.png
Normal file
After Width: | Height: | Size: 409 B |
BIN
images/app-icons/tray/new-windowTemplate@1.5x.png
Normal file
After Width: | Height: | Size: 481 B |
BIN
images/app-icons/tray/new-windowTemplate@2x.png
Normal file
After Width: | Height: | Size: 626 B |
267
package-lock.json
generated
@ -69,7 +69,7 @@
|
||||
"leaflet-gpx": "2.1.2",
|
||||
"mark.js": "8.11.1",
|
||||
"marked": "15.0.7",
|
||||
"mermaid": "11.5.0",
|
||||
"mermaid": "11.6.0",
|
||||
"mime-types": "2.1.35",
|
||||
"multer": "1.4.5-lts.2",
|
||||
"normalize-strings": "1.1.1",
|
||||
@ -102,14 +102,14 @@
|
||||
"trilium": "src/main.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "7.7.0",
|
||||
"@electron-forge/maker-deb": "7.7.0",
|
||||
"@electron-forge/maker-dmg": "7.7.0",
|
||||
"@electron-forge/maker-flatpak": "7.7.0",
|
||||
"@electron-forge/maker-rpm": "7.7.0",
|
||||
"@electron-forge/maker-squirrel": "7.7.0",
|
||||
"@electron-forge/maker-zip": "7.7.0",
|
||||
"@electron-forge/plugin-auto-unpack-natives": "7.7.0",
|
||||
"@electron-forge/cli": "7.8.0",
|
||||
"@electron-forge/maker-deb": "7.8.0",
|
||||
"@electron-forge/maker-dmg": "7.8.0",
|
||||
"@electron-forge/maker-flatpak": "7.8.0",
|
||||
"@electron-forge/maker-rpm": "7.8.0",
|
||||
"@electron-forge/maker-squirrel": "7.8.0",
|
||||
"@electron-forge/maker-zip": "7.8.0",
|
||||
"@electron-forge/plugin-auto-unpack-natives": "7.8.0",
|
||||
"@electron/rebuild": "3.7.1",
|
||||
"@eslint/js": "9.23.0",
|
||||
"@fullcalendar/core": "6.1.15",
|
||||
@ -571,9 +571,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/cli": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/cli/-/cli-7.7.0.tgz",
|
||||
"integrity": "sha512-QfnjghmlHMb7dyArR5cbPA+MP9ff/ulWZi6R/a5MkHlKyhrysRfjzDtZDsmkEv9mGQgRwylssgXrZrKHGlxFkw==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/cli/-/cli-7.8.0.tgz",
|
||||
"integrity": "sha512-XZ+Hg7pxeE9pgrahqcpMlND+VH0l0UTZLyO5wkI+YfanNyBQksB2mw24XeEtCA6x8F2IaEYdIGgijmPF6qpjzA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@ -587,15 +587,16 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/core": "7.7.0",
|
||||
"@electron-forge/core-utils": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.7.0",
|
||||
"@electron-forge/core": "7.8.0",
|
||||
"@electron-forge/core-utils": "7.8.0",
|
||||
"@electron-forge/shared-types": "7.8.0",
|
||||
"@electron/get": "^3.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"commander": "^11.1.0",
|
||||
"debug": "^4.3.1",
|
||||
"fs-extra": "^10.0.0",
|
||||
"listr2": "^7.0.2",
|
||||
"log-symbols": "^4.0.0",
|
||||
"semver": "^7.2.1"
|
||||
},
|
||||
"bin": {
|
||||
@ -636,9 +637,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/core": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/core/-/core-7.7.0.tgz",
|
||||
"integrity": "sha512-BWhg1Zw1bhpDuZowGH3lXDiL9zZBsYFNjtqyMqmkjcEm5xf9Dzs8mpRpNjtkpf3jit3LB4PNGMLj3c8ix0h4vQ==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/core/-/core-7.8.0.tgz",
|
||||
"integrity": "sha512-7byf660ECZND+irOhGxvpmRXjk1bMrsTWh5J2AZMEvaXI8tub9OrZY9VSbi5fcDt0lpHPKmgVk7NRf/ZjJ+beQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@ -652,17 +653,17 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/core-utils": "7.7.0",
|
||||
"@electron-forge/maker-base": "7.7.0",
|
||||
"@electron-forge/plugin-base": "7.7.0",
|
||||
"@electron-forge/publisher-base": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.7.0",
|
||||
"@electron-forge/template-base": "7.7.0",
|
||||
"@electron-forge/template-vite": "7.7.0",
|
||||
"@electron-forge/template-vite-typescript": "7.7.0",
|
||||
"@electron-forge/template-webpack": "7.7.0",
|
||||
"@electron-forge/template-webpack-typescript": "7.7.0",
|
||||
"@electron-forge/tracer": "7.7.0",
|
||||
"@electron-forge/core-utils": "7.8.0",
|
||||
"@electron-forge/maker-base": "7.8.0",
|
||||
"@electron-forge/plugin-base": "7.8.0",
|
||||
"@electron-forge/publisher-base": "7.8.0",
|
||||
"@electron-forge/shared-types": "7.8.0",
|
||||
"@electron-forge/template-base": "7.8.0",
|
||||
"@electron-forge/template-vite": "7.8.0",
|
||||
"@electron-forge/template-vite-typescript": "7.8.0",
|
||||
"@electron-forge/template-webpack": "7.8.0",
|
||||
"@electron-forge/template-webpack-typescript": "7.8.0",
|
||||
"@electron-forge/tracer": "7.8.0",
|
||||
"@electron/get": "^3.0.0",
|
||||
"@electron/packager": "^18.3.5",
|
||||
"@electron/rebuild": "^3.7.0",
|
||||
@ -691,13 +692,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/core-utils": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/core-utils/-/core-utils-7.7.0.tgz",
|
||||
"integrity": "sha512-kgOkiLzqnySkcpt26rBg8AoZsI1ID3f6s/dQlzfRJisWZTKTu4ryiMcaC0F07DVjaYFnEl9SQ86IvkTcyS97mQ==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/core-utils/-/core-utils-7.8.0.tgz",
|
||||
"integrity": "sha512-ZioRzqkXVOGuwkfvXN/FPZxcssJ9AkOZx6RvxomQn90F77G2KfEbw4ZwAxVTQ+jWNUzydTic5qavWle++Y5IeA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/shared-types": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.8.0",
|
||||
"@electron/rebuild": "^3.7.0",
|
||||
"@malept/cross-spawn-promise": "^2.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
@ -768,13 +769,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/maker-base": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-base/-/maker-base-7.7.0.tgz",
|
||||
"integrity": "sha512-9u+mmBLBAUHuH0+IGw94EGVTDD4CPKX05h5pp5/PIaijy16ss5dymK4vEp3s2XJMFlza2PsCgLLYBgDcAE2Dqg==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-base/-/maker-base-7.8.0.tgz",
|
||||
"integrity": "sha512-yGRvz70w+NnKO7PhzNFRgYM+x6kxYFgpbChJIQBs3WChd9bGjL+MZLrwYqmxOFLpWNwRAJ6PEi4E/8U5GgV6AQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/shared-types": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.8.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"which": "^2.0.2"
|
||||
},
|
||||
@ -811,14 +812,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/maker-deb": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-deb/-/maker-deb-7.7.0.tgz",
|
||||
"integrity": "sha512-yMT0TWpCwXaC9+AYpSr9PBIhcZR297wdJUk5PnEnIROsvOW2y1sh7ny7YdHXTxkvhWdbqY8sLQruL3BE+CyE8w==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-deb/-/maker-deb-7.8.0.tgz",
|
||||
"integrity": "sha512-9jjhLm/1IBIo0UuRdELgvBhUkNjK3tHNlUsrqeb8EJwWJZShbPwHYZJj+VbgjQfJFFzhHwBBDJViBXJ/4ePv+g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/maker-base": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.7.0"
|
||||
"@electron-forge/maker-base": "7.8.0",
|
||||
"@electron-forge/shared-types": "7.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16.4.0"
|
||||
@ -828,14 +829,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/maker-dmg": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-dmg/-/maker-dmg-7.7.0.tgz",
|
||||
"integrity": "sha512-Hq4nsY6eOdtigN4RLc9i2SbLEr46J6FfbdU+r39R/EVIJ82WRk7JPrCqbckEM7KY1TjhmrnhPWeviWoGAjbXhA==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-dmg/-/maker-dmg-7.8.0.tgz",
|
||||
"integrity": "sha512-ml6GpHvUyhOapIF1ALEM4zCqXiAf2+t+3FqKnjNtiVbH5fnV2CW//SWWozrvAGTrYGi/6V4s9TL/rIek0BHOPA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/maker-base": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.7.0",
|
||||
"@electron-forge/maker-base": "7.8.0",
|
||||
"@electron-forge/shared-types": "7.8.0",
|
||||
"fs-extra": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@ -874,14 +875,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/maker-flatpak": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-flatpak/-/maker-flatpak-7.7.0.tgz",
|
||||
"integrity": "sha512-WDNmGTulgPe4FEgxq128TI58EtVyS2Fq3loXhfirNuzoXpBtvt0LHK447cmtKHAvZZ+R802uriTcj28L+Iub3A==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-flatpak/-/maker-flatpak-7.8.0.tgz",
|
||||
"integrity": "sha512-tnOWQLVvNZVO9xWmhUHK4OsQgYUpEIn0DX1M8FkgQCYSDXcPg/CZaZ66zqj/gu1KzGAOWg1m5KlTbITRY5Jmcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/maker-base": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.7.0",
|
||||
"@electron-forge/maker-base": "7.8.0",
|
||||
"@electron-forge/shared-types": "7.8.0",
|
||||
"fs-extra": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@ -920,14 +921,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/maker-rpm": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-rpm/-/maker-rpm-7.7.0.tgz",
|
||||
"integrity": "sha512-M9cFO6bCnOuA6BwBUUw35FrnWciWeFyLuByO0KOn3zEYeBDqG2fbBgXXS6OKcRHrpnJVTwiLY5S7eviyO1DJzQ==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-rpm/-/maker-rpm-7.8.0.tgz",
|
||||
"integrity": "sha512-oTH951NE39LOX2wYMg+C06vBZDWUP/0dsK01PlXEl5e5YfQM5Cifsk3E7BzE6BpZdWRJL3k/ETqpyYeIGNb1jw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/maker-base": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.7.0"
|
||||
"@electron-forge/maker-base": "7.8.0",
|
||||
"@electron-forge/shared-types": "7.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16.4.0"
|
||||
@ -937,14 +938,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/maker-squirrel": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-squirrel/-/maker-squirrel-7.7.0.tgz",
|
||||
"integrity": "sha512-9Gcq8e6+1MuXGeE7bEpk7VTd86c0riXTsDFKW8OqwVozeBYhoCd6GU59RmI3b7mcAIKOY1cBY97B+/5bnZ8ZYg==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-squirrel/-/maker-squirrel-7.8.0.tgz",
|
||||
"integrity": "sha512-On8WIyjNtNlWf8NJRRVToighGCCU+wcxytFM0F8Zx/pLszgc01bt7wIarOiAIzuIT9Z8vshAYA0iG1U099jfeA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/maker-base": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.7.0",
|
||||
"@electron-forge/maker-base": "7.8.0",
|
||||
"@electron-forge/shared-types": "7.8.0",
|
||||
"fs-extra": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@ -983,14 +984,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/maker-zip": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-zip/-/maker-zip-7.7.0.tgz",
|
||||
"integrity": "sha512-/rRFiPcojk0hcn+NOfHv2SlMNvghBk1RN0nuLHbbe8r+C0vG4LJV9ee/Y0HhVKkcpapJOQ+MasXJ86fzAp5uAg==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/maker-zip/-/maker-zip-7.8.0.tgz",
|
||||
"integrity": "sha512-7MLD7GkZdlGecC9GvgBu0sWYt48p3smYvr+YCwlpdH1CTeLmWhvCqeH33a2AB0XI5CY8U8jnkG2jgdTkzr/EQw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/maker-base": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.7.0",
|
||||
"@electron-forge/maker-base": "7.8.0",
|
||||
"@electron-forge/shared-types": "7.8.0",
|
||||
"cross-zip": "^4.0.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"got": "^11.8.5"
|
||||
@ -1028,53 +1029,53 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/plugin-auto-unpack-natives": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/plugin-auto-unpack-natives/-/plugin-auto-unpack-natives-7.7.0.tgz",
|
||||
"integrity": "sha512-cYeD4x2oQXUyK4+DtIR6wMxcIHvyPgsJq1diEuBoQ+MFTh+s6DXZl6JvwtI3scD0XieCkzcmUmf8ygzqs124+w==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/plugin-auto-unpack-natives/-/plugin-auto-unpack-natives-7.8.0.tgz",
|
||||
"integrity": "sha512-JGal5ltZmbTQ5rNq67OgGC4MJ2zjjFW0fqykHy8X9J8cgaH7SRdKkT4yYZ8jH01IAF1J57FD2zIob1MvcBqjcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/plugin-base": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.7.0"
|
||||
"@electron-forge/plugin-base": "7.8.0",
|
||||
"@electron-forge/shared-types": "7.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/plugin-base": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/plugin-base/-/plugin-base-7.7.0.tgz",
|
||||
"integrity": "sha512-6wisQ4ZKOWey48wFF+JHzih7AuQuVma5KauwNEju2Dh2ibwDMJmPy0FWVolMSg7XUIMbGKLADGilxX6XRv8qNQ==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/plugin-base/-/plugin-base-7.8.0.tgz",
|
||||
"integrity": "sha512-rDeeChRWIp5rQVo3Uc1q0ncUvA+kWWURW7tMuQjPvy2qVSgX+jIf5krk+T1Dp06+D4YZzEIrkibRaamAaIcR1w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/shared-types": "7.7.0"
|
||||
"@electron-forge/shared-types": "7.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/publisher-base": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/publisher-base/-/publisher-base-7.7.0.tgz",
|
||||
"integrity": "sha512-jHKvUc1peBBSl2t5d1x6M3CNyCMyNB+NnTO9LmA1dWFQ3oRDFwromIH5KjRqPJj6l4AyH0/XJogdO7Nn4Eyn6Q==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/publisher-base/-/publisher-base-7.8.0.tgz",
|
||||
"integrity": "sha512-wrZyptJ0Uqvlh2wYzDZfIu2HgCQ+kdGiBlcucmLY4W+GUqf043O8cbYso3D9NXQxOow55QC/1saCQkgLphprPA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/shared-types": "7.7.0"
|
||||
"@electron-forge/shared-types": "7.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/shared-types": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/shared-types/-/shared-types-7.7.0.tgz",
|
||||
"integrity": "sha512-1zQsmudkAuHv0HnJtSJY3pvTeuN3fnSa9BR6cbeUlcpOfrnG4OTG03FqerHfyIWaBRVy7jGgif0NhKKE9azKyg==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/shared-types/-/shared-types-7.8.0.tgz",
|
||||
"integrity": "sha512-Ul+7HPvAZiAirqpZm0vc9YvlkAE+2bcrI10p3t50mEtuxn5VO/mB72NXiEKfWzHm8F31JySIe9bUV6s1MHQcCw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/tracer": "7.7.0",
|
||||
"@electron-forge/tracer": "7.8.0",
|
||||
"@electron/packager": "^18.3.5",
|
||||
"@electron/rebuild": "^3.7.0",
|
||||
"listr2": "^7.0.2"
|
||||
@ -1084,14 +1085,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/template-base": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/template-base/-/template-base-7.7.0.tgz",
|
||||
"integrity": "sha512-jwnhEHNIyQfbwJ6R8SuZIJApHKBykDr/rSgUF3km9nr2qAUSoUUV7RaJa/uiQJMtvamXenuo5K84C2NzumzS3A==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/template-base/-/template-base-7.8.0.tgz",
|
||||
"integrity": "sha512-hc8NwoDqEEmZFH/p0p3MK/7xygMmI+cm8Gavoj2Mr2xS7VUUu4r3b5PwIGKvkLfPG34uwsiVwtid2t1rWGF4UA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/core-utils": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.7.0",
|
||||
"@electron-forge/core-utils": "7.8.0",
|
||||
"@electron-forge/shared-types": "7.8.0",
|
||||
"@malept/cross-spawn-promise": "^2.0.0",
|
||||
"debug": "^4.3.1",
|
||||
"fs-extra": "^10.0.0",
|
||||
@ -1130,14 +1131,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/template-vite": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/template-vite/-/template-vite-7.7.0.tgz",
|
||||
"integrity": "sha512-6p+U6FDWrmF7XgSLkrO07OOgJcrrrArbnExSckGJdBnupxmIDf1Y+exwfHHKdxX6/FfkA6JST5nRGjgA5CFqcw==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/template-vite/-/template-vite-7.8.0.tgz",
|
||||
"integrity": "sha512-bf/jd8WzD0gU7Jet+WSi0Lm0SQmseb08WY27ZfJYEs2EVNMiwDfPicgQnOaqP++2yTrXhj1OY/rolZCP9CUyVw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/shared-types": "7.7.0",
|
||||
"@electron-forge/template-base": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.8.0",
|
||||
"@electron-forge/template-base": "7.8.0",
|
||||
"fs-extra": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@ -1145,14 +1146,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/template-vite-typescript": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/template-vite-typescript/-/template-vite-typescript-7.7.0.tgz",
|
||||
"integrity": "sha512-32C/+PF+hIloTdbRx7OutvqnTkkC7BHeQxNw4/zG2TfQ3cjl7JUD6A2UvTUHtv5KHkK2hDw6ZdahPwpJO41YSA==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/template-vite-typescript/-/template-vite-typescript-7.8.0.tgz",
|
||||
"integrity": "sha512-kW3CaVxKHUYuVfY+rT3iepeZ69frBRGh3YZOngLY2buCvGIqNEx+VCgrFBRDDbOKGmwQtwO1E9wp2rtC8q6Ztg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/shared-types": "7.7.0",
|
||||
"@electron-forge/template-base": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.8.0",
|
||||
"@electron-forge/template-base": "7.8.0",
|
||||
"fs-extra": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@ -1216,14 +1217,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/template-webpack": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/template-webpack/-/template-webpack-7.7.0.tgz",
|
||||
"integrity": "sha512-7Hb1wejKqtvPXqhelubUNAh39FtClB/4JDtWzyAsL2iC3XeB5qh6pITz8+nW/rF2qW/JAepc/lnreqKn34P2ig==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/template-webpack/-/template-webpack-7.8.0.tgz",
|
||||
"integrity": "sha512-AdLGC6NVgrd7Q0SaaeiwJKmSBjN6C2EHxZgLMy1yxNSpazU9m3DtYQilDjXqmCWfxkeNzdke0NaeDvLgdJSw5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/shared-types": "7.7.0",
|
||||
"@electron-forge/template-base": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.8.0",
|
||||
"@electron-forge/template-base": "7.8.0",
|
||||
"fs-extra": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@ -1231,14 +1232,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/template-webpack-typescript": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/template-webpack-typescript/-/template-webpack-typescript-7.7.0.tgz",
|
||||
"integrity": "sha512-w1vRAjGy0MjjdEDYPpZcpkMo2e3z5uEwfJdwVOpBeha7p2WM/Y6go21K+7pSqGp8Xmq4zlE20hq5MEx8Bs8eZg==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/template-webpack-typescript/-/template-webpack-typescript-7.8.0.tgz",
|
||||
"integrity": "sha512-Pl8l+gv3HzqCfFIMLxlEsoAkNd0VEWeZZ675SYyqs0/kBQUifn0bKNhVE4gUZwKGgQCcG1Gvb23KdVGD3H3XmA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron-forge/shared-types": "7.7.0",
|
||||
"@electron-forge/template-base": "7.7.0",
|
||||
"@electron-forge/shared-types": "7.8.0",
|
||||
"@electron-forge/template-base": "7.8.0",
|
||||
"fs-extra": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@ -1302,9 +1303,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron-forge/tracer": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/tracer/-/tracer-7.7.0.tgz",
|
||||
"integrity": "sha512-R/JiGFzWhwfVyc6ioT4l5FFChRLS4Z2tWPeQfPcyoemdpzKpI1rvMHti42gzWXFW8GdzkhG0G3ZWfKiF3y3x/Q==",
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-forge/tracer/-/tracer-7.8.0.tgz",
|
||||
"integrity": "sha512-t4fIATZEX6/7PJNfyh6tLzKEsNMpO01Nz/rgHWBxeRvjCw5UNul9OOxoM7b43vfFAO9Jv++34oI3VJ09LeVQ2Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -1315,9 +1316,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/asar": {
|
||||
"version": "3.2.17",
|
||||
"resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.17.tgz",
|
||||
"integrity": "sha512-OcWImUI686w8LkghQj9R2ynZ2ME693Ek6L1SiaAgqGKzBaTIZw3fHDqN82Rcl+EU1Gm9EgkJ5KLIY/q5DCRbbA==",
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.3.1.tgz",
|
||||
"integrity": "sha512-WtpC/+34p0skWZiarRjLAyqaAX78DofhDxnREy/V5XHfu1XEXbFCSSMcDQ6hNCPJFaPy8/NnUgYuf9uiCkvKPg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -1513,9 +1514,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/osx-sign": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.2.tgz",
|
||||
"integrity": "sha512-KqVlm9WMWq19lBpCXQoThC/Koaiji2zotUDYwZDaZlZZym+FXY9mQW8wN6sUQ93nkVc42f3TQ1S/XN9S1kjM5Q==",
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.3.tgz",
|
||||
"integrity": "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
@ -1679,13 +1680,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/universal": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.1.tgz",
|
||||
"integrity": "sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.2.tgz",
|
||||
"integrity": "sha512-mqY1szx5/d5YLvfCDWWoJdkSIjIz+NdWN4pN0r78lYiE7De+slLpuF3lVxIT+hlJnwk5sH2wFRMl6/oUgUVO3A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron/asar": "^3.2.7",
|
||||
"@electron/asar": "^3.3.1",
|
||||
"@malept/cross-spawn-promise": "^2.0.0",
|
||||
"debug": "^4.3.1",
|
||||
"dir-compare": "^4.2.0",
|
||||
@ -3602,12 +3603,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mermaid-js/parser": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.3.0.tgz",
|
||||
"integrity": "sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA==",
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.4.0.tgz",
|
||||
"integrity": "sha512-wla8XOWvQAwuqy+gxiZqY+c7FokraOTHRWMsbB4AgRx9Sy7zKslNyejy7E+a77qHfey5GXw/ik3IXv/NHMJgaA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"langium": "3.0.0"
|
||||
"langium": "3.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@mind-elixir/node-menu": {
|
||||
@ -13451,9 +13452,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/langium": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz",
|
||||
"integrity": "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==",
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/langium/-/langium-3.3.1.tgz",
|
||||
"integrity": "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chevrotain": "~11.0.3",
|
||||
@ -14128,14 +14129,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mermaid": {
|
||||
"version": "11.5.0",
|
||||
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.5.0.tgz",
|
||||
"integrity": "sha512-IYhyukID3zzDj1EihKiN1lp+PXNImoJ3Iyz73qeDAgnus4BNGsJV1n471P4PyeGxPVONerZxignwGxGTSwZnlg==",
|
||||
"version": "11.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.6.0.tgz",
|
||||
"integrity": "sha512-PE8hGUy1LDlWIHWBP05SFdqUHGmRcCcK4IzpOKPE35eOw+G9zZgcnMpyunJVUEOgb//KBORPjysKndw8bFLuRg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^7.0.4",
|
||||
"@iconify/utils": "^2.1.33",
|
||||
"@mermaid-js/parser": "^0.3.0",
|
||||
"@mermaid-js/parser": "^0.4.0",
|
||||
"@types/d3": "^7.4.3",
|
||||
"cytoscape": "^3.29.3",
|
||||
"cytoscape-cose-bilkent": "^4.1.0",
|
||||
|
18
package.json
@ -129,7 +129,7 @@
|
||||
"leaflet-gpx": "2.1.2",
|
||||
"mark.js": "8.11.1",
|
||||
"marked": "15.0.7",
|
||||
"mermaid": "11.5.0",
|
||||
"mermaid": "11.6.0",
|
||||
"mime-types": "2.1.35",
|
||||
"multer": "1.4.5-lts.2",
|
||||
"normalize-strings": "1.1.1",
|
||||
@ -159,14 +159,14 @@
|
||||
"yauzl": "3.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "7.7.0",
|
||||
"@electron-forge/maker-deb": "7.7.0",
|
||||
"@electron-forge/maker-dmg": "7.7.0",
|
||||
"@electron-forge/maker-flatpak": "7.7.0",
|
||||
"@electron-forge/maker-rpm": "7.7.0",
|
||||
"@electron-forge/maker-squirrel": "7.7.0",
|
||||
"@electron-forge/maker-zip": "7.7.0",
|
||||
"@electron-forge/plugin-auto-unpack-natives": "7.7.0",
|
||||
"@electron-forge/cli": "7.8.0",
|
||||
"@electron-forge/maker-deb": "7.8.0",
|
||||
"@electron-forge/maker-dmg": "7.8.0",
|
||||
"@electron-forge/maker-flatpak": "7.8.0",
|
||||
"@electron-forge/maker-rpm": "7.8.0",
|
||||
"@electron-forge/maker-squirrel": "7.8.0",
|
||||
"@electron-forge/maker-zip": "7.8.0",
|
||||
"@electron-forge/plugin-auto-unpack-natives": "7.8.0",
|
||||
"@electron/rebuild": "3.7.1",
|
||||
"@eslint/js": "9.23.0",
|
||||
"@fullcalendar/core": "6.1.15",
|
||||
|
@ -190,8 +190,11 @@
|
||||
--right-pane-item-hover-background: #ffffff26;
|
||||
--right-pane-item-hover-color: white;
|
||||
|
||||
--scrollbar-border-color: #666;
|
||||
--scrollbar-background-color: #333;
|
||||
--scrollbar-thumb-color: #fdfdfd5c;
|
||||
--scrollbar-thumb-color-hover: #ffffff7d;
|
||||
--scrollbar-border-color: unset; /* Deprecated */
|
||||
--scrollbar-background-color: unset; /* Deprecated */
|
||||
|
||||
--link-color: lightskyblue;
|
||||
|
||||
--mermaid-theme: dark;
|
||||
|
@ -189,8 +189,11 @@
|
||||
--right-pane-item-hover-background: #ececec;
|
||||
--right-pane-item-hover-color: inherit;
|
||||
|
||||
--scrollbar-border-color: #ddd;
|
||||
--scrollbar-background-color: #ddd;
|
||||
--scrollbar-thumb-color: #0000005c;
|
||||
--scrollbar-thumb-color-hover: #00000066;
|
||||
--scrollbar-border-color: unset; /* Deprecated */
|
||||
--scrollbar-background-color: unset; /* Deprecated */
|
||||
|
||||
--link-color: blue;
|
||||
|
||||
--mermaid-theme: default;
|
||||
|
@ -660,3 +660,83 @@ a.tn-link:hover[href^="https://"]:not(.no-arrow)::after,
|
||||
input[type="range"] {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/*
|
||||
* WebKit scrollbars
|
||||
*/
|
||||
|
||||
:root {
|
||||
--scrollbar-thickness: 10px;
|
||||
--scrollbar-thumb-thickness: 3px;
|
||||
--scrollbar-thumb-hover-thickness: 6px;
|
||||
--scrollbar-start-end-gap: 8px;
|
||||
}
|
||||
|
||||
/* Scrollbar's body */
|
||||
|
||||
::-webkit-scrollbar:vertical {
|
||||
width: var(--scrollbar-thickness) !important;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar:horizontal {
|
||||
height: var(--scrollbar-thickness) !important;
|
||||
}
|
||||
|
||||
/* Scrollbar's thumb */
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
--s-thumb-thickness: var(--scrollbar-thumb-thickness);
|
||||
--s-thumb-color: var(--scrollbar-thumb-color);
|
||||
|
||||
--s-gradient-angle: 90deg;
|
||||
--s-gradient-p1: calc((var(--scrollbar-thickness) - var(--s-thumb-thickness)) / 2);
|
||||
--s-gradient-p2: calc(var(--s-gradient-p1) + var(--s-thumb-thickness));
|
||||
|
||||
border: none !important;
|
||||
background: linear-gradient(var(--s-gradient-angle),
|
||||
transparent, transparent var(--s-gradient-p1),
|
||||
var(--s-thumb-color) 0px, var(--s-thumb-color) var(--s-gradient-p2),
|
||||
transparent 0) !important;
|
||||
|
||||
border-radius: calc(var(--scrollbar-thickness) / 2) !important;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:horizontal {
|
||||
--s-gradient-angle: 0deg;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
--s-thumb-thickness: var(--scrollbar-thumb-hover-thickness);
|
||||
--s-thumb-color: var(--scrollbar-thumb-color-hover);
|
||||
}
|
||||
|
||||
/* Scrollbar's increment/decrement buttons (repurposed as a scrollbar start/end gap) */
|
||||
|
||||
::-webkit-scrollbar-button:vertical {
|
||||
height: var(--scrollbar-start-end-gap);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button:horizontal {
|
||||
width: var(--scrollbar-start-end-gap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Firefox scrollbars
|
||||
*
|
||||
* Unsupported features: --scrollbar-thumb-thickness, --scrollbar-thumb-hover-thickness,
|
||||
* --scrollbar-start-end-gap, --scrollbar-thumb-color-hover.
|
||||
*/
|
||||
|
||||
:root {
|
||||
scrollbar-color: var(--scrollbar-thumb-color) transparent;
|
||||
scrollbar-width: var(--scrollbar-thickness);
|
||||
}
|
||||
|
||||
@supports selector(::-webkit-scrollbar) {
|
||||
/* Prevent the scrollbar-color and scrollbar-width properties to override the custom styles
|
||||
* defined using ::-webkit-scrollbar. */
|
||||
:root {
|
||||
scrollbar-color: unset;
|
||||
scrollbar-width: unset;
|
||||
}
|
||||
}
|
@ -25,7 +25,12 @@ function getOptionOrNull(name: OptionNames): string | null {
|
||||
option = becca.getOption(name);
|
||||
} else {
|
||||
// e.g. in initial sync becca is not loaded because DB is not initialized
|
||||
option = sql.getRow<OptionRow>("SELECT * FROM options WHERE name = ?", [name]);
|
||||
try {
|
||||
option = sql.getRow<OptionRow>("SELECT * FROM options WHERE name = ?", [name]);
|
||||
} catch (e: unknown) {
|
||||
// DB is not initialized.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return option ? option.value : null;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Menu, Tray } from "electron";
|
||||
import { Menu, Tray, BrowserWindow } from "electron";
|
||||
import path from "path";
|
||||
import windowService from "./window.js";
|
||||
import optionService from "./options.js";
|
||||
@ -17,7 +17,7 @@ import cls from "./cls.js";
|
||||
let tray: Tray;
|
||||
// `mainWindow.isVisible` doesn't work with `mainWindow.show` and `mainWindow.hide` - it returns `false` when the window
|
||||
// is minimized
|
||||
let isVisible = true;
|
||||
let windowVisibilityMap: Record<number, boolean> = {};; // Dictionary for storing window ID and its visibility status
|
||||
|
||||
function getTrayIconPath() {
|
||||
let name: string;
|
||||
@ -37,53 +37,93 @@ function getIconPath(name: string) {
|
||||
return path.join(path.dirname(fileURLToPath(import.meta.url)), "../..", "images", "app-icons", "tray", `${name}Template${suffix}.png`);
|
||||
}
|
||||
|
||||
function registerVisibilityListener() {
|
||||
const mainWindow = windowService.getMainWindow();
|
||||
if (!mainWindow) {
|
||||
function registerVisibilityListener(window: BrowserWindow) {
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
// They need to be registered before the tray updater is registered
|
||||
mainWindow.on("show", () => {
|
||||
isVisible = true;
|
||||
window.on("show", () => {
|
||||
windowVisibilityMap[window.id] = true;
|
||||
updateTrayMenu();
|
||||
});
|
||||
mainWindow.on("hide", () => {
|
||||
isVisible = false;
|
||||
window.on("hide", () => {
|
||||
windowVisibilityMap[window.id] = false;
|
||||
updateTrayMenu();
|
||||
});
|
||||
|
||||
mainWindow.on("minimize", updateTrayMenu);
|
||||
mainWindow.on("maximize", updateTrayMenu);
|
||||
if (!isMac) {
|
||||
// macOS uses template icons which work great on dark & light themes.
|
||||
nativeTheme.on("updated", updateTrayMenu);
|
||||
}
|
||||
ipcMain.on("reload-tray", updateTrayMenu);
|
||||
i18next.on("languageChanged", updateTrayMenu);
|
||||
window.on("minimize", updateTrayMenu);
|
||||
window.on("maximize", updateTrayMenu);
|
||||
}
|
||||
|
||||
function updateTrayMenu() {
|
||||
const mainWindow = windowService.getMainWindow();
|
||||
if (!mainWindow) {
|
||||
function getWindowTitle(window: BrowserWindow | null) {
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
const title = window.getTitle();
|
||||
const titleWithoutAppName = title.replace(/\s-\s[^-]+$/, ''); // Remove the name of the app
|
||||
|
||||
function ensureVisible() {
|
||||
if (mainWindow) {
|
||||
mainWindow.show();
|
||||
mainWindow.focus();
|
||||
// Limit title maximum length to 17
|
||||
if (titleWithoutAppName.length > 20) {
|
||||
return titleWithoutAppName.substring(0, 17) + '...';
|
||||
}
|
||||
|
||||
return titleWithoutAppName;
|
||||
}
|
||||
|
||||
function updateWindowVisibilityMap(allWindows: BrowserWindow[]) {
|
||||
const currentWindowIds: number[] = allWindows.map(window => window.id);
|
||||
|
||||
// Deleting closed windows from windowVisibilityMap
|
||||
for (const [id, visibility] of Object.entries(windowVisibilityMap)) {
|
||||
const windowId = Number(id);
|
||||
if (!currentWindowIds.includes(windowId)) {
|
||||
delete windowVisibilityMap[windowId];
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate through allWindows to make sure the ID of each window exists in windowVisibilityMap
|
||||
allWindows.forEach(window => {
|
||||
const windowId = window.id;
|
||||
if (!(windowId in windowVisibilityMap)) {
|
||||
// If it does not exist, it is the newly created window
|
||||
windowVisibilityMap[windowId] = true;
|
||||
registerVisibilityListener(window);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function updateTrayMenu() {
|
||||
const lastFocusedWindow = windowService.getLastFocusedWindow();
|
||||
const allWindows = windowService.getAllWindows();
|
||||
updateWindowVisibilityMap(allWindows);
|
||||
|
||||
function ensureVisible(win: BrowserWindow) {
|
||||
if (win) {
|
||||
win.show();
|
||||
win.focus();
|
||||
}
|
||||
}
|
||||
|
||||
function openNewWindow() {
|
||||
if (lastFocusedWindow){
|
||||
lastFocusedWindow.webContents.send("globalShortcut", "openNewWindow");
|
||||
}
|
||||
}
|
||||
|
||||
function triggerKeyboardAction(actionName: KeyboardActionNames) {
|
||||
mainWindow?.webContents.send("globalShortcut", actionName);
|
||||
ensureVisible();
|
||||
if (lastFocusedWindow){
|
||||
lastFocusedWindow.webContents.send("globalShortcut", actionName);
|
||||
ensureVisible(lastFocusedWindow);
|
||||
}
|
||||
}
|
||||
|
||||
function openInSameTab(note: BNote | BRecentNote) {
|
||||
mainWindow?.webContents.send("openInSameTab", note.noteId);
|
||||
ensureVisible();
|
||||
if (lastFocusedWindow){
|
||||
lastFocusedWindow.webContents.send("openInSameTab", note.noteId);
|
||||
ensureVisible(lastFocusedWindow);
|
||||
}
|
||||
}
|
||||
|
||||
function buildBookmarksMenu() {
|
||||
@ -144,20 +184,44 @@ function updateTrayMenu() {
|
||||
return menuItems;
|
||||
}
|
||||
|
||||
const contextMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
label: t("tray.show-windows"),
|
||||
const windowVisibilityMenuItems: Electron.MenuItemConstructorOptions[] = [];
|
||||
|
||||
// Only call getWindowTitle if windowVisibilityMap has more than one window
|
||||
const showTitle = Object.keys(windowVisibilityMap).length > 1;
|
||||
|
||||
for (const idStr in windowVisibilityMap) {
|
||||
const id = parseInt(idStr, 10); // Get the ID of the window and make sure it is a number
|
||||
const isVisible = windowVisibilityMap[id];
|
||||
const win = allWindows.find(w => w.id === id);
|
||||
if (!win) {
|
||||
continue;
|
||||
}
|
||||
windowVisibilityMenuItems.push({
|
||||
label: showTitle ? `${t("tray.show-windows")}: ${getWindowTitle(win)}` : t("tray.show-windows"),
|
||||
type: "checkbox",
|
||||
checked: isVisible,
|
||||
click: () => {
|
||||
if (isVisible) {
|
||||
mainWindow.hide();
|
||||
win.hide();
|
||||
windowVisibilityMap[id] = false;
|
||||
} else {
|
||||
ensureVisible();
|
||||
ensureVisible(win);
|
||||
windowVisibilityMap[id] = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const contextMenu = Menu.buildFromTemplate([
|
||||
...windowVisibilityMenuItems,
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: t("tray.open_new_window"),
|
||||
type: "normal",
|
||||
icon: getIconPath("new-window"),
|
||||
click: () => openNewWindow()
|
||||
},
|
||||
{
|
||||
label: t("tray.new-note"),
|
||||
type: "normal",
|
||||
@ -188,7 +252,10 @@ function updateTrayMenu() {
|
||||
type: "normal",
|
||||
icon: getIconPath("close"),
|
||||
click: () => {
|
||||
mainWindow.close();
|
||||
const windows = BrowserWindow.getAllWindows();
|
||||
windows.forEach(window => {
|
||||
window.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
]);
|
||||
@ -197,16 +264,18 @@ function updateTrayMenu() {
|
||||
}
|
||||
|
||||
function changeVisibility() {
|
||||
const window = windowService.getMainWindow();
|
||||
if (!window) {
|
||||
const lastFocusedWindow = windowService.getLastFocusedWindow();
|
||||
|
||||
if (!lastFocusedWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isVisible) {
|
||||
window.hide();
|
||||
// If the window is visible, hide it
|
||||
if (windowVisibilityMap[lastFocusedWindow.id]) {
|
||||
lastFocusedWindow.hide();
|
||||
} else {
|
||||
window.show();
|
||||
window.focus();
|
||||
lastFocusedWindow.show();
|
||||
lastFocusedWindow.focus();
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,9 +290,15 @@ function createTray() {
|
||||
tray.on("click", changeVisibility);
|
||||
updateTrayMenu();
|
||||
|
||||
registerVisibilityListener();
|
||||
if (!isMac) {
|
||||
// macOS uses template icons which work great on dark & light themes.
|
||||
nativeTheme.on("updated", updateTrayMenu);
|
||||
}
|
||||
ipcMain.on("reload-tray", updateTrayMenu);
|
||||
i18next.on("languageChanged", updateTrayMenu);
|
||||
}
|
||||
|
||||
export default {
|
||||
createTray
|
||||
createTray,
|
||||
updateTrayMenu
|
||||
};
|
||||
|
@ -11,6 +11,7 @@ import remoteMain from "@electron/remote/main/index.js";
|
||||
import { BrowserWindow, shell, type App, type BrowserWindowConstructorOptions, type WebContents } from "electron";
|
||||
import { dialog, ipcMain } from "electron";
|
||||
import { formatDownloadTitle, isDev, isMac, isWindows } from "./utils.js";
|
||||
import tray from "./tray.js";
|
||||
|
||||
import { fileURLToPath } from "url";
|
||||
import { dirname } from "path";
|
||||
@ -19,6 +20,26 @@ import { t } from "i18next";
|
||||
// Prevent the window being garbage collected
|
||||
let mainWindow: BrowserWindow | null;
|
||||
let setupWindow: BrowserWindow | null;
|
||||
let allWindows: BrowserWindow[] = []; // // Used to store all windows, sorted by the order of focus.
|
||||
|
||||
function trackWindowFocus(win: BrowserWindow) {
|
||||
// We need to get the last focused window from allWindows. If the last window is closed, we return the previous window.
|
||||
// Therefore, we need to push the window into the allWindows array every time it gets focused.
|
||||
win.on("focus", () => {
|
||||
allWindows = allWindows.filter(w => !w.isDestroyed() && w !== win);
|
||||
allWindows.push(win);
|
||||
if (!optionService.getOptionBool("disableTray")) {
|
||||
tray.updateTrayMenu();
|
||||
}
|
||||
});
|
||||
|
||||
win.on("closed", () => {
|
||||
allWindows = allWindows.filter(w => !w.isDestroyed());
|
||||
if (!optionService.getOptionBool("disableTray")) {
|
||||
tray.updateTrayMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function createExtraWindow(extraWindowHash: string) {
|
||||
const spellcheckEnabled = optionService.getOptionBool("spellCheckEnabled");
|
||||
@ -42,6 +63,8 @@ async function createExtraWindow(extraWindowHash: string) {
|
||||
win.loadURL(`http://127.0.0.1:${port}/?extraWindow=1${extraWindowHash}`);
|
||||
|
||||
configureWebContents(win.webContents, spellcheckEnabled);
|
||||
|
||||
trackWindowFocus(win);
|
||||
}
|
||||
|
||||
ipcMain.on("create-extra-window", (event, arg) => {
|
||||
@ -154,18 +177,21 @@ async function createMainWindow(app: App) {
|
||||
configureWebContents(mainWindow.webContents, spellcheckEnabled);
|
||||
|
||||
app.on("second-instance", (event, commandLine) => {
|
||||
const lastFocusedWindow = getLastFocusedWindow();
|
||||
if (commandLine.includes("--new-window")) {
|
||||
createExtraWindow("");
|
||||
} else if (mainWindow) {
|
||||
} else if (lastFocusedWindow) {
|
||||
// Someone tried to run a second instance, we should focus our window.
|
||||
// see www.ts "requestSingleInstanceLock" for the rest of this logic with explanation
|
||||
if (mainWindow.isMinimized()) {
|
||||
mainWindow.restore();
|
||||
if (lastFocusedWindow.isMinimized()) {
|
||||
lastFocusedWindow.restore();
|
||||
}
|
||||
|
||||
mainWindow.focus();
|
||||
lastFocusedWindow.show();
|
||||
lastFocusedWindow.focus();
|
||||
}
|
||||
});
|
||||
|
||||
trackWindowFocus(mainWindow);
|
||||
}
|
||||
|
||||
function getWindowExtraOpts() {
|
||||
@ -296,10 +322,20 @@ function getMainWindow() {
|
||||
return mainWindow;
|
||||
}
|
||||
|
||||
function getLastFocusedWindow() {
|
||||
return allWindows.length > 0 ? allWindows[allWindows.length - 1] : null;
|
||||
}
|
||||
|
||||
function getAllWindows(){
|
||||
return allWindows;
|
||||
}
|
||||
|
||||
export default {
|
||||
createMainWindow,
|
||||
createSetupWindow,
|
||||
closeSetupWindow,
|
||||
registerGlobalShortcuts,
|
||||
getMainWindow
|
||||
getMainWindow,
|
||||
getLastFocusedWindow,
|
||||
getAllWindows
|
||||
};
|
||||
|
@ -273,7 +273,8 @@
|
||||
"bookmarks": "书签",
|
||||
"today": "打开今天的日记笔记",
|
||||
"new-note": "新建笔记",
|
||||
"show-windows": "显示窗口"
|
||||
"show-windows": "显示窗口",
|
||||
"open_new_window": "打开新窗口"
|
||||
},
|
||||
"migration": {
|
||||
"old_version": "由您当前版本的直接迁移不被支持。请先升级到最新的 v0.60.4 然后再到这个版本。",
|
||||
|
@ -274,7 +274,8 @@
|
||||
"bookmarks": "Bookmarks",
|
||||
"today": "Open today's journal note",
|
||||
"new-note": "New note",
|
||||
"show-windows": "Show windows"
|
||||
"show-windows": "Show windows",
|
||||
"open_new_window": "Open new window"
|
||||
},
|
||||
"migration": {
|
||||
"old_version": "Direct migration from your current version is not supported. Please upgrade to the latest v0.60.4 first and only then to this version.",
|
||||
|