Merge branch 'feat/footer-share-ci' into dev
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m39s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m39s
CI keeps the 'test once per code state' plan but records commit and git tree as image labels instead of extra :sha-/:tree- tags, so the registry only holds dev, latest, vX.Y.Z and stable; the plan test now asserts the expected decisions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
141f87f3a0
22 files changed
+735
-61
No files matched your search
+73
-1
@@ -5,10 +5,12 @@
|
||||
// - Icons and manifest: from the cache, refreshed in the background.
|
||||
// - API requests are never touched; offline data comes from the app's own cache (lib/offline.ts).
|
||||
// Raise VERSION when this file changes in a way that needs fresh caches.
|
||||
const VERSION = 'v2';
|
||||
const VERSION = 'v3';
|
||||
const SHELL_CACHE = `mindsift-shell-${VERSION}`;
|
||||
const ASSET_CACHE = `mindsift-assets-${VERSION}`;
|
||||
const MAX_ASSETS = 80;
|
||||
const SHARE_DB_NAME = 'mindsift-share-target';
|
||||
const SHARE_STORE_NAME = 'shared_items';
|
||||
const SHELL_URLS = [
|
||||
'/',
|
||||
'/index.html',
|
||||
@@ -80,8 +82,78 @@ async function staleWhileRevalidate(request) {
|
||||
return hit || refresh;
|
||||
}
|
||||
|
||||
function openShareDB() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = indexedDB.open(SHARE_DB_NAME, 1);
|
||||
req.onupgradeneeded = () => {
|
||||
const db = req.result;
|
||||
if (!db.objectStoreNames.contains(SHARE_STORE_NAME)) {
|
||||
db.createObjectStore(SHARE_STORE_NAME, { autoIncrement: true, keyPath: 'id' });
|
||||
}
|
||||
};
|
||||
req.onsuccess = () => resolve(req.result);
|
||||
req.onerror = () => reject(req.error);
|
||||
});
|
||||
}
|
||||
|
||||
async function savePendingShare(item) {
|
||||
const db = await openShareDB();
|
||||
return new Promise((resolve, reject) => {
|
||||
const tx = db.transaction(SHARE_STORE_NAME, 'readwrite');
|
||||
tx.objectStore(SHARE_STORE_NAME).add(item);
|
||||
tx.oncomplete = () => {
|
||||
db.close();
|
||||
resolve();
|
||||
};
|
||||
tx.onerror = () => {
|
||||
db.close();
|
||||
reject(tx.error);
|
||||
};
|
||||
tx.onabort = () => {
|
||||
db.close();
|
||||
reject(tx.error);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async function handleShareTarget(event) {
|
||||
try {
|
||||
const formData = await event.request.formData();
|
||||
const title = formData.get('title');
|
||||
const text = formData.get('text');
|
||||
const url = formData.get('url');
|
||||
const media = formData.get('media');
|
||||
|
||||
let fileName = '';
|
||||
let hasMedia = false;
|
||||
if (media && typeof media === 'object') {
|
||||
fileName = media.name || 'image';
|
||||
hasMedia = true;
|
||||
}
|
||||
|
||||
await savePendingShare({
|
||||
title: typeof title === 'string' ? title.trim() : '',
|
||||
text: typeof text === 'string' ? text.trim() : '',
|
||||
url: typeof url === 'string' ? url.trim() : '',
|
||||
fileName,
|
||||
hasMedia,
|
||||
createdAt: Date.now(),
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('[SW] Share-Target Fehler:', err);
|
||||
}
|
||||
return Response.redirect('/?shared=pending', 303);
|
||||
}
|
||||
|
||||
self.addEventListener('fetch', (event) => {
|
||||
const { request } = event;
|
||||
if (request.method === 'POST') {
|
||||
const url = new URL(request.url);
|
||||
if (url.origin === self.location.origin && url.pathname === '/share-target') {
|
||||
event.respondWith(handleShareTarget(event));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (request.method !== 'GET') return;
|
||||
const url = new URL(request.url);
|
||||
if (url.origin !== self.location.origin || url.pathname.startsWith('/api/')) return;
|
||||
|
||||
Reference in new issue
Block a user