diff --git a/.vscode/settings.json b/.vscode/settings.json
index 396755a634..0e9dd5ce2c 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -59,5 +59,6 @@
"*.ts": "${capture}.spec.ts,${capture}.mock.ts"
},
"svelte.enable-ts-plugin": true,
- "typescript.preferences.importModuleSpecifier": "non-relative"
+ "typescript.preferences.importModuleSpecifier": "non-relative",
+ "html.customData": [".web/node_modules/vidstack/vscode.html-data.json"]
}
diff --git a/web/package-lock.json b/web/package-lock.json
index 75c55aa779..edd274be06 100644
--- a/web/package-lock.json
+++ b/web/package-lock.json
@@ -35,7 +35,8 @@
"svelte-i18n": "^4.0.1",
"svelte-maplibre": "^1.0.0",
"svelte-persisted-store": "^0.12.0",
- "thumbhash": "^0.1.1"
+ "thumbhash": "^0.1.1",
+ "vidstack": "^1.12.13"
},
"devDependencies": {
"@eslint/eslintrc": "^3.1.0",
@@ -2442,6 +2443,12 @@
"@types/geojson": "*"
}
},
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "license": "MIT"
+ },
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.31.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.31.0.tgz",
@@ -5800,6 +5807,15 @@
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"license": "MIT"
},
+ "node_modules/lit-html": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
+ "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@types/trusted-types": "^2.0.2"
+ }
+ },
"node_modules/locate-character": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
@@ -6066,6 +6082,15 @@
"node": ">= 0.4"
}
},
+ "node_modules/media-captions": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/media-captions/-/media-captions-1.0.4.tgz",
+ "integrity": "sha512-cyDNmuZvvO4H27rcBq2Eudxo9IZRDCOX/I7VEyqbxsEiD2Ei7UYUhG/Sc5fvMZjmathgz3fEK7iAKqvpY+Ux1w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ }
+ },
"node_modules/memoizee": {
"version": "0.4.17",
"resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz",
@@ -8987,6 +9012,19 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/unplugin": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz",
+ "integrity": "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==",
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.14.0",
+ "webpack-virtual-modules": "^0.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/update-browserslist-db": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
@@ -9056,6 +9094,21 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "node_modules/vidstack": {
+ "version": "1.12.13",
+ "resolved": "https://registry.npmjs.org/vidstack/-/vidstack-1.12.13.tgz",
+ "integrity": "sha512-vuNeyRmWoH/7EoFVDYjp9nkgcqtCMmal518LDeb78dYKgWb+p6+vtY0AzDhrkBv5q1UiCn+xwmjMmwvSlPLuhQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/dom": "^1.6.10",
+ "lit-html": "^2.8.0",
+ "media-captions": "^1.0.4",
+ "unplugin": "^1.12.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/vite": {
"version": "6.3.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.3.tgz",
@@ -9725,6 +9778,12 @@
"node": ">=12"
}
},
+ "node_modules/webpack-virtual-modules": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
+ "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
+ "license": "MIT"
+ },
"node_modules/whatwg-encoding": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
diff --git a/web/package.json b/web/package.json
index 7c5a0147bb..2cebe22aa9 100644
--- a/web/package.json
+++ b/web/package.json
@@ -51,7 +51,8 @@
"svelte-i18n": "^4.0.1",
"svelte-maplibre": "^1.0.0",
"svelte-persisted-store": "^0.12.0",
- "thumbhash": "^0.1.1"
+ "thumbhash": "^0.1.1",
+ "vidstack": "^1.12.13"
},
"devDependencies": {
"@eslint/eslintrc": "^3.1.0",
diff --git a/web/src/lib/components/asset-viewer/asset-viewer.svelte b/web/src/lib/components/asset-viewer/asset-viewer.svelte
index 08772bcec4..0221040d6e 100644
--- a/web/src/lib/components/asset-viewer/asset-viewer.svelte
+++ b/web/src/lib/components/asset-viewer/asset-viewer.svelte
@@ -373,6 +373,10 @@
handlePromiseError(handleGetAllAlbums());
}
});
+ let controlsVisible = $state(true);
+ const onControlsChange = ({ controlsVisible: visible }: { controlsVisible: boolean }) => {
+ controlsVisible = visible;
+ };