Enhance task synchronization and logging; update service worker caching strategy

This commit is contained in:
2025-01-31 18:59:16 +01:00
parent 2a7005f53c
commit b277b1f8f0
3 changed files with 45 additions and 19 deletions

View File

@@ -1,6 +1,7 @@
import { checkSession, login, logout } from './auth.js'; import { checkSession, login, logout } from './auth.js';
import { saveTask } from './tasks.js'; import { saveTask } from './tasks.js';
import { saveTags, loadTags } from './tags.js'; import { saveTags, loadTags } from './tags.js';
import { idb } from './utils.js';
if ('serviceWorker' in navigator) { if ('serviceWorker' in navigator) {
window.addEventListener('load', () => { window.addEventListener('load', () => {
@@ -32,8 +33,7 @@ if ('serviceWorker' in navigator) {
}); });
} }
document.addEventListener('DOMContentLoaded', async function() {
document.addEventListener('DOMContentLoaded', function() {
const loginForm = document.getElementById('loginForm'); const loginForm = document.getElementById('loginForm');
const loginContainer = document.getElementById('loginContainer'); const loginContainer = document.getElementById('loginContainer');
const appContainer = document.getElementById('appContainer'); const appContainer = document.getElementById('appContainer');
@@ -55,12 +55,13 @@ document.addEventListener('DOMContentLoaded', function() {
const tomorrow = new Date(today); const tomorrow = new Date(today);
tomorrow.setDate(today.getDate() + 1); tomorrow.setDate(today.getDate() + 1);
// Initialize datepicker with tomorrow as the default date // Initialize datepicker with tomorrow as the default date and disable past dates
M.Datepicker.init(document.querySelectorAll('.datepicker'), { M.Datepicker.init(document.querySelectorAll('.datepicker'), {
format: 'yyyy-mm-dd', format: 'yyyy-mm-dd',
defaultDate: tomorrow, defaultDate: tomorrow,
setDefaultDate: true, setDefaultDate: true,
firstDay: 1 firstDay: 1,
minDate: today // Disable past dates
}); });
// Initialize timepicker // Initialize timepicker
@@ -187,7 +188,7 @@ document.addEventListener('DOMContentLoaded', function() {
// Save task to server or IndexedDB if offline // Save task to server or IndexedDB if offline
try { try {
const data = await saveTask(taskData); const data = await saveTask(taskData);
document.getElementById('responseMessage').textContent = "Task saved successfully!"; document.getElementById('responseMessage').textContent = data.message;
taskForm.reset(); // Reset the form after saving the task taskForm.reset(); // Reset the form after saving the task
} catch (error) { } catch (error) {
if (error.status === 401) { if (error.status === 401) {
@@ -199,4 +200,19 @@ document.addEventListener('DOMContentLoaded', function() {
} }
} }
}); });
// Synchronize tasks when back online
window.addEventListener('online', async () => {
const db = await idb.openDB('org-todo-pwa', 1);
const tasks = await db.getAll('tasks');
for (const task of tasks) {
try {
await saveTask(task);
await db.delete('tasks', task.id);
console.log(`Task synchronized: ${task.subject}`);
} catch (error) {
console.error('Error synchronizing task:', error);
}
}
});
}); });

View File

@@ -2,9 +2,14 @@ const CACHE_NAME = 'org-todo-pwa-cache-v1';
const urlsToCache = [ const urlsToCache = [
'/', '/',
'/index.html', '/index.html',
'/style.css', '/css/style.css',
'/app.js', '/js/auth.js',
'/manifest.json' '/js/tasks.js',
'/js/tags.js',
'/js/utils.js',
'/js/main.js',
'https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css',
'https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js'
]; ];
self.addEventListener('install', event => { self.addEventListener('install', event => {
@@ -14,22 +19,21 @@ self.addEventListener('install', event => {
return cache.addAll(urlsToCache); return cache.addAll(urlsToCache);
}) })
); );
self.skipWaiting(); // Force the waiting service worker to become the active service worker
}); });
self.addEventListener('activate', event => { self.addEventListener('activate', event => {
const cacheWhitelist = [CACHE_NAME];
event.waitUntil( event.waitUntil(
caches.keys().then(cacheNames => { caches.keys().then(cacheNames => {
return Promise.all( return Promise.all(
cacheNames.map(cacheName => { cacheNames.map(cacheName => {
if (cacheName !== CACHE_NAME) { if (!cacheWhitelist.includes(cacheName)) {
return caches.delete(cacheName); return caches.delete(cacheName);
} }
}) })
); );
}) })
); );
self.clients.claim(); // Take control of all clients immediately
}); });
self.addEventListener('fetch', event => { self.addEventListener('fetch', event => {
@@ -39,13 +43,19 @@ self.addEventListener('fetch', event => {
if (response) { if (response) {
return response; return response;
} }
return fetch(event.request); return fetch(event.request).then(
response => {
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
const responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(cache => {
cache.put(event.request, responseToCache);
});
return response;
}
);
}) })
); );
}); });
self.addEventListener('message', event => {
if (event.data === 'skipWaiting') {
self.skipWaiting();
}
});

View File

@@ -52,13 +52,13 @@ router.post('/add-task', auth, async (req, res) => {
- State "TODO" from "TODO" [${currentDateTime}] - State "TODO" from "TODO" [${currentDateTime}]
:END: :END:
`; `;
logger.info(`Task added: ${orgFormattedData}`);
} }
const filePath = path.join(dataDir, 'tasks.org'); const filePath = path.join(dataDir, 'tasks.org');
try { try {
await fs.promises.appendFile(filePath, orgFormattedData); await fs.promises.appendFile(filePath, orgFormattedData);
res.json({ message: 'Task added successfully' }); res.json({ message: 'Task added successfully' });
logger.info(`Task added: ${orgFormattedData}`);
} catch (error) { } catch (error) {
logger.error('Error writing to tasks.org file:', error); logger.error('Error writing to tasks.org file:', error);
res.status(500).json({ message: 'Error adding task' }); res.status(500).json({ message: 'Error adding task' });