diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 92590e8..203abcc 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -14,6 +14,9 @@ module.exports = { ecmaVersion: 2022, sourceType: "module", }, + globals: { + __PACKAGE_VERSION__: "readonly", + }, plugins: [ "@stylistic/js", "vue", diff --git a/package-lock.json b/package-lock.json index d5ac7ab..e3f773d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "lindsvg-pwa", - "version": "2.0.2", + "version": "2.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "lindsvg-pwa", - "version": "2.0.2", + "version": "2.1.0", "dependencies": { "@vueuse/core": "^10.6.1", "lindsvg": "^1.3.2", diff --git a/package.json b/package.json index 746589b..b0f2e62 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "lindsvg-pwa", "private": true, - "version": "2.0.2", + "version": "2.1.0", "type": "module", "scripts": { "lint": "eslint \"src/**/*.{mjs,vue}\"", diff --git a/public/app-icons/doc-icon.png b/public/app-icons/doc-icon.png new file mode 100644 index 0000000..cd71022 Binary files /dev/null and b/public/app-icons/doc-icon.png differ diff --git a/src/App.vue b/src/App.vue index 09a58dc..06c9b47 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,7 +1,11 @@ diff --git a/src/components/PanelCollections.vue b/src/components/PanelCollections.vue index 4f94eb2..7942b27 100644 --- a/src/components/PanelCollections.vue +++ b/src/components/PanelCollections.vue @@ -1,5 +1,5 @@ @@ -177,7 +186,7 @@ function deleteLSystem(lid) { .collectionName { background: var(--color-surface); - box-shadow: 0 4px 7px 2px var(--color-surface), 0 -4px 0 0 var(--color-surface); + box-shadow: 0 4px 7px 2px var(--color-surface); margin-block: 0 8px; padding-block: 13px 5px; position: sticky; diff --git a/src/components/PanelExporting.vue b/src/components/PanelExporting.vue deleted file mode 100644 index 702bd2f..0000000 --- a/src/components/PanelExporting.vue +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - Exporting - - - - - Download SVG… - - - - - - - Permalink for the selected L-system - - - - Copy - Copied! - - - Note that permalinks are only available for L-systems from the predefined collections. - Any manual changes in an L-system parameters are ignored. - - - - - - diff --git a/src/components/PanelSettings.vue b/src/components/PanelSettings.vue index c51dd38..4542cd8 100644 --- a/src/components/PanelSettings.vue +++ b/src/components/PanelSettings.vue @@ -194,7 +194,7 @@ function plot() { &:has([data-label="B"]), &:has([data-label="F"]) { - background: rgb(from var(--color-accent) r g b / calc(alpha - 0.92)); + background: rgb(from var(--color-accent) r g b / 0.08); } } diff --git a/src/components/PanelSharing.vue b/src/components/PanelSharing.vue new file mode 100644 index 0000000..6f4b56a --- /dev/null +++ b/src/components/PanelSharing.vue @@ -0,0 +1,179 @@ + + + + + + Sharing + + + + Open file… + + LSVG + + + Save file… + + LSVG + + + SVG + + + + + + Permalink for the selected L-system + + + Copy + Copied! + + + Note that permalinks are only available for L-systems from the predefined collections. + Any manual changes in L-system parameters are not preserved. + + + + + + diff --git a/src/components/ThePopover.vue b/src/components/ThePopover.vue index 109164b..296596e 100644 --- a/src/components/ThePopover.vue +++ b/src/components/ThePopover.vue @@ -8,7 +8,7 @@ let {popover} = storeToRefs(useInterfaceStore()); diff --git a/src/manifest.webmanifest b/src/manifest.webmanifest index 7dcf381..f29884d 100644 --- a/src/manifest.webmanifest +++ b/src/manifest.webmanifest @@ -67,5 +67,22 @@ ], "background_color": "#ffffff", "theme_color": "#f5f5f5", - "display": "standalone" + "display": "standalone", + "file_handlers": [ + { + "action": "/lindsvg/index.html?action=handleFile", + "accept": { + "application/json": [".lsvg"] + }, + "label": "L-system configuration", + "icons": [ + { + "src": "/lindsvg/app-icons/doc-icon.png", + "type": "image/png", + "sizes": "256x256" + } + ], + "launch_type": "single-client" + } + ] } diff --git a/src/pwaCtrl.mjs b/src/pwaCtrl.mjs index 02cd902..f460cee 100644 --- a/src/pwaCtrl.mjs +++ b/src/pwaCtrl.mjs @@ -1,5 +1,6 @@ import "./sw.js?worker"; import {useInterfaceStore, POPOVER_ACCEPT} from "./stores/interface.mjs"; +import {useLSystemStore} from "./stores/lSystem.mjs"; export const USING_PWA = import.meta.env.PROD && ("serviceWorker" in navigator); @@ -35,3 +36,38 @@ async function suggestUpdate(newSW) { } }); } + +let launchParamsSupported = ("launchQueue" in window) && ("files" in window.LaunchParams.prototype); + +/** @see https://github.com/WICG/web-app-launch/issues/92#issuecomment-1505562033 */ +function handleActionURL(action) { + let url = new URL(location.href); + if (url.searchParams.get("action") !== action) { + return false; + } + url.searchParams.delete("action"); + window.history.replaceState(null, "", url); + return true; +} + +export function applyLaunchParams() { + if (!launchParamsSupported || !handleActionURL("handleFile")) { + return; + } + /** @see https://github.com/WICG/file-handling/blob/main/explainer.md */ + window.launchQueue.setConsumer(async ({files}) => { + if (!files.length) { + return; + } + try { + let blob = await files[0].getFile(); + let config = JSON.parse(await blob.text()); + let lSystemStore = useLSystemStore(); + lSystemStore.setup(config); + lSystemStore.buildSVG(); + } catch (error) { + useInterfaceStore().requestPopover({text: "Unfortunately, this file cannot be opened"}); + console.error("Unable to open the file", error); + } + }); +} diff --git a/src/styles/interface.module.css b/src/styles/interface.module.css index 05d638c..847b679 100644 --- a/src/styles/interface.module.css +++ b/src/styles/interface.module.css @@ -45,7 +45,11 @@ border-radius: 100px; box-sizing: border-box; color: var(--color-accent); + display: inline-flex; padding-block: 0.35em; + place-content: center; + text-align: center; + text-decoration: none; &:not(:disabled):hover, &:focus-visible { diff --git a/src/styles/main.css b/src/styles/main.css index bad6a78..8c3f408 100644 --- a/src/styles/main.css +++ b/src/styles/main.css @@ -40,6 +40,10 @@ body { font: normal 16px / 1.4 system-ui, sans-serif; } +h1, h2, h3, h4 { + text-wrap: balance; +} + a { color: var(--color-accent); text-underline-offset: 0.2em; diff --git a/src/sw.js b/src/sw.js index c7ad8f5..ff233cc 100644 --- a/src/sw.js +++ b/src/sw.js @@ -1,5 +1,5 @@ const CACHE_NS = "lindsvg"; // Never change the namespace to be able to clear old versions’ caches -const CACHE_VERSION = __PACKAGE_VERSION__; /* global __PACKAGE_VERSION__ */ +const CACHE_VERSION = __PACKAGE_VERSION__; const CACHE_NAME = `${CACHE_NS}-v${CACHE_VERSION}`; let cachedFiles = [ @@ -10,6 +10,7 @@ let cachedFiles = [ "/lindsvg/index.html", "/lindsvg/index.js", "/lindsvg/app-icons/apple-touch-icon.png", + "/lindsvg/app-icons/doc-icon.png", "/lindsvg/app-icons/favicon.svg", "/lindsvg/app-icons/icon-192.png", "/lindsvg/app-icons/icon-512.png",
- - Download SVG… - -
+ Note that permalinks are only available for L-systems from the predefined collections. + Any manual changes in L-system parameters are not preserved. +