mirror of
https://github.com/molstar/molstar.git
synced 2026-06-04 13:30:24 +08:00
simplify, add pwa files during deploy
This commit is contained in:
15
data/pwa/README.md
Normal file
15
data/pwa/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
The files in this directory are used for deploying the Mol* Viewer as a PWA (Progressive Web App) at https://molstar.org/viewer/. They may serve as an example for creating your own PWA but wont work as-is. See `/script/deploy.js` for where these files are copied and how they are transformed during deployment.
|
||||
|
||||
|
||||
## PWA features
|
||||
|
||||
- The Service Worker will cache static resources so the Viewer can be used without internet access. This works without installing, i.e., also in Firefox.
|
||||
- Once installed, file types listed in the Manifest can be opened from, e.g., the Windows File Explorer.
|
||||
|
||||
|
||||
## Notes for development
|
||||
|
||||
In Chrome you can see a list of installed PWAs at chrome://apps/. A right-click opens a menu with an option uninstall.
|
||||
|
||||
The Chrome Dev Tools have a section 'Application' to inspect and manage PWA aspects like the Manifest and Service Workers.
|
||||
BIN
data/pwa/logo-144.png
Normal file
BIN
data/pwa/logo-144.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
39
data/pwa/manifest.webmanifest
Normal file
39
data/pwa/manifest.webmanifest
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"id": "https://molstar.org/viewer/",
|
||||
"name": "Mol* Viewer",
|
||||
"short_name": "Mol*",
|
||||
"description": "Mol* Viewer: a modern web app for 3D visualization and analysis of large biomolecular structures.",
|
||||
"start_url": "./index.html",
|
||||
"theme_color": "#eeece7",
|
||||
"background_color": "#eeece7",
|
||||
"display": "standalone",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "48x48"
|
||||
},
|
||||
{
|
||||
"src": "logo-144.png",
|
||||
"sizes": "144x144"
|
||||
}
|
||||
],
|
||||
"file_handlers": [
|
||||
{
|
||||
"action": "./index.html",
|
||||
"accept": {
|
||||
"application/vnd.molstar": [".molx", ".molj"],
|
||||
"text/plain": [
|
||||
".mol", ".mol2", ".sdf", ".sd", ".pdb", ".ent", ".pdbqt", ".cif", ".mcif", ".mmcif", ".xyz", ".gro", ".lammpstrj",
|
||||
".cub", ".cube", ".dx"
|
||||
],
|
||||
"application/octet-stream": [
|
||||
".bcif",
|
||||
".dxbin", ".ccp4", ".mrc", ".map", ".dsn6", ".brix"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"launch_handler": {
|
||||
"client_mode": ["auto"]
|
||||
}
|
||||
}
|
||||
44
data/pwa/pwa.js
Normal file
44
data/pwa/pwa.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Andy Turner <agdturner@gmail.com>
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
window.addEventListener('molstarViewerCreated', e => {
|
||||
const viewer = e.detail.viewer;
|
||||
|
||||
// Handle incoming files
|
||||
if ('launchQueue' in window) {
|
||||
launchQueue.setConsumer((launchParams) => {
|
||||
if (!launchParams.files.length) return;
|
||||
|
||||
const files = [];
|
||||
for (const fileHandle of launchParams.files) {
|
||||
files.push(fileHandle.getFile());
|
||||
}
|
||||
|
||||
Promise.all(files).then((files) => {
|
||||
viewer.loadFiles(files);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Register Progressive Web App service worker.
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', function () {
|
||||
navigator.serviceWorker.register('./sw.js')
|
||||
.then(function (registration) {
|
||||
// Registration was successful
|
||||
if (molstar.isDebugMode) {
|
||||
console.log('ServiceWorker registration successful with scope: ', registration.scope);
|
||||
}
|
||||
}, function (err) {
|
||||
// registration failed :(
|
||||
if (molstar.isDebugMode) {
|
||||
console.error('ServiceWorker registration failed: ', err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
60
data/pwa/sw.js
Normal file
60
data/pwa/sw.js
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright (c) 2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Andy Turner <agdturner@gmail.com>
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
/** version from package.json, to be filled in during deployment */
|
||||
const VERSION = '__MOLSTAR_VERSION__';
|
||||
|
||||
const CACHE_NAME = `molstar-viewer-${VERSION}`;
|
||||
|
||||
// The static resources that the app needs to function.
|
||||
const APP_STATIC_RESOURCES = [
|
||||
'favicon.ico',
|
||||
'index.html',
|
||||
'molstar.css',
|
||||
'molstar.js',
|
||||
'manifest.webmanifest',
|
||||
'logo-144.png',
|
||||
'pwa.js'
|
||||
];
|
||||
|
||||
async function cacheStaticResources() {
|
||||
const cache = await caches.open(CACHE_NAME);
|
||||
await cache.addAll(APP_STATIC_RESOURCES);
|
||||
await self.skipWaiting(); // Ensures the new service worker takes control immediately.
|
||||
}
|
||||
|
||||
async function deleteOldCaches() {
|
||||
const keys = await caches.keys();
|
||||
await Promise.all(
|
||||
keys.map((key) => {
|
||||
if (key !== CACHE_NAME) {
|
||||
return caches.delete(key);
|
||||
}
|
||||
}),
|
||||
);
|
||||
await self.clients.claim(); // Ensures the new service worker takes control immediately.
|
||||
}
|
||||
|
||||
async function respondWithCacheFirst(request) {
|
||||
// Try to match the request with the cache
|
||||
const cachedResponse = await caches.match(request);
|
||||
return cachedResponse || fetch(request);
|
||||
}
|
||||
|
||||
self.addEventListener('install', (event) => {
|
||||
// console.log(`Service Worker version ${VERSION} installed.`);
|
||||
event.waitUntil(cacheStaticResources());
|
||||
});
|
||||
|
||||
self.addEventListener('activate', (event) => {
|
||||
// console.log(`Service Worker version ${VERSION} activated.`);
|
||||
event.waitUntil(deleteOldCaches());
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', (event) => {
|
||||
event.respondWith(respondWithCacheFirst(event.request));
|
||||
});
|
||||
Reference in New Issue
Block a user