Browse Source

Static pages, service worker, manifest

imwald
Nuša Pukšič 8 months ago
parent
commit
2bc0064fa0
  1. 21
      assets/site.webmanifest
  2. 11
      public/offline.html
  3. 90
      public/service-worker.js
  4. 1
      templates/static/about.html.twig
  5. 20
      templates/static/manifest.webmanifest.twig
  6. 16
      templates/static/tos.html.twig

21
assets/site.webmanifest

@ -1,21 +0,0 @@
{
"name": "Decent Newsroom",
"short_name": "Newsroom",
"icons": [
{
"src": "/icons/web-app-manifest-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/icons/web-app-manifest-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

11
public/offline.html

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Decent Newsroom is offline</title>
</head>
<body>
<h1>You are offline</h1>
<p>Please reconnect to use the app.</p>
</body>
</html>

90
public/service-worker.js

@ -1,89 +1,11 @@
const CACHE_NAME = 'newsroom-pwa-v0.0.1'; self.addEventListener('install', async (event) => {
const URLS_TO_CACHE = [ // Activate the service worker immediately after install
'/offline.html' await self.skipWaiting();
];
// Install: cache initial assets
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then(async (cache) => {
const urls = URLS_TO_CACHE.map(async (url) => {
try {
const response = await fetch(url);
if (response.ok && response.type === 'basic') {
await cache.put(url, response.clone());
} else {
console.warn(`[SW] Skipped caching ${url}: invalid response`);
}
} catch (err) {
console.warn(`[SW] Failed to fetch ${url}:`, err);
}
});
await Promise.all(urls);
})
);
self.skipWaiting();
}); });
// Activate: clean up old caches
self.addEventListener('activate', (event) => { self.addEventListener('activate', (event) => {
event.waitUntil( // Take control of all clients immediately
caches.keys().then((cacheNames) => event.waitUntil(self.clients.claim());
Promise.all(
cacheNames
.filter((name) => name !== CACHE_NAME)
.map((name) => caches.delete(name))
)
)
);
self.clients.claim();
}); });
// Fetch: serve from cache, fallback to network, then offline // No fetch or cache handlers — fully fall-through
self.addEventListener('fetch', (event) => {
const request = event.request;
// Only handle HTTP GET requests
if (
request.method !== 'GET' ||
!request.url.startsWith('http')
) {
return;
}
// Skip cache for dynamic routes
const isDynamic = request.url.includes('/cat/') ;
// Exclude dynamic paths
const isExcluded =
request.url.startsWith('/login') ||
request.url.startsWith('/logout') ||
request.url.startsWith('/_components/');
if (isDynamic || isExcluded) {
return; // Don't intercept
}
event.respondWith(
caches.match(request).then((cached) => {
if (cached) return cached;
return fetch(request)
.then((response) => {
// Optionally cache fetched responses
if (
response &&
response.status === 200 &&
response.type === 'basic'
) {
const responseClone = response.clone();
caches.open(CACHE_NAME).then((cache) =>
cache.put(request, responseClone)
);
}
return response;
})
.catch(() => caches.match('/offline.html'));
})
);
});

1
templates/static/about.html.twig

@ -24,6 +24,7 @@
<dt><strong>Open to Writers & Publishers</strong> <span class="badge">Soon</span></dt> <dt><strong>Open to Writers & Publishers</strong> <span class="badge">Soon</span></dt>
<dd>Content creators can request indexing for their work, making it searchable and eligible for inclusion.</dd> <dd>Content creators can request indexing for their work, making it searchable and eligible for inclusion.</dd>
<dd>Publishers can create and manage their own magazines.</dd>
</dl> </dl>
<h2>Why It Matters</h2> <h2>Why It Matters</h2>

20
templates/static/manifest.webmanifest.twig

@ -0,0 +1,20 @@
{
"name": "Decent Newsroom",
"short_name": "Newsroom",
"start_url": "/?source=pwa",
"icons": [
{
"src": "{{ asset('icons/web-app-manifest-192x192.png') }}",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "{{ asset('icons/web-app-manifest-512x512.png') }}",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

16
templates/static/tos.html.twig

@ -22,21 +22,19 @@
<li> <li>
<h2>User Accounts & Responsibilities</h2> <h2>User Accounts & Responsibilities</h2>
<p>We do not store user credentials, emails, or passwords. Authentication is done via Nostr public keys (npubs).</p> <p>We do not store user credentials, emails, or passwords. Authentication is done via Nostr keys.</p>
{# <p>Some data is stored and linked to your npub, including:</p>#} <p>Some data is stored and linked to your npub for debug and accounting purposes:</p>
{# <ul>#} <ul>
{# <li>Subscription status and payment history (if applicable)</li>#} <li>Subscription status and payment history (if applicable)</li>
<li>Search requests</li>
{# <li>Indexing requests</li>#} {# <li>Indexing requests</li>#}
{# </ul>#} </ul>
{# <p>Content submitted for indexing may remain publicly discoverable even if a user stops using the platform.</p>#}
{# #}
</li> </li>
<li> <li>
<h2>Content & Ownership</h2> <h2>Content & Ownership</h2>
<p>The platform operates on the basis of open access content.</p> <p>The platform operates on the basis of open-access content.</p>
<p>We do not endorse or verify third-party content and are not responsible for its accuracy.</p> <p>We do not endorse or verify third-party content and are not responsible for its accuracy.</p>
<p>We reserve the right to include and exclude content from the indexer at our own discretion.</p> <p>We reserve the right to include and exclude content from the indexer at our own discretion.</p>
{# <p>By requesting indexing, you agree that your content may be made publicly discoverable unless otherwise specified.</p>#} {# <p>By requesting indexing, you agree that your content may be made publicly discoverable unless otherwise specified.</p>#}

Loading…
Cancel
Save