Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Progressive Web App (PWA)" support #383

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = {
env: {
node: true,
es2022: true, // add globals and sets parserOptions.ecmaVersion to 2022
serviceworker: true, // Add this line to enable serviceworker support
},
extends: [
// Vue specific base rules, `eslint-plugin-vue`
Expand Down
10,665 changes: 10,665 additions & 0 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions src/presentation/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"
/>
<meta name="robots" content="index,follow" />
<meta name="theme-color" content="#ffffff"/>
<link rel="manifest" href="/manifest.json">
<link rel="icon" href="/favicon.ico">

<!--
Expand Down Expand Up @@ -63,5 +65,18 @@ <h1>Problem loading page</h1>
</noscript>
<div id="app"></div>
<script type="module" src="/main.ts"></script>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js')
.then(registration => {
console.log('Service Worker registered with scope:', registration.scope);
})
.catch(error => {
console.error('Service Worker registration failed:', error);
});
});
}
</script>
</body>
</html>
Binary file added src/presentation/public/icons/apple-icon-180.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 62 additions & 0 deletions src/presentation/public/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"name": "privacy.sexy",
"short_name": "privacy.sexy",
"description": "Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy.",
"version": "0.13.5",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This version should be bumped automatically. It would be better use some kind of logic in the vite build system to read the latest version and output it here.

"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#000000",
"icons": [
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to automatically update the icons.

There's logo-update.js which is executed when you run npm run build:icons. It creates all logos from single logo.svg , see README.md. We should update the script so it generates all needed icons in the icons folder (populates from the SVG).

This helps maintaining the project by updating the logo in single file/place and knowing that it will be updated throughout the application after single command.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @undergroundwires,

I attempted to run the icons:build command, but it is dependent on ImageMagick. The software uses the convert command, which conflicts with the convert.exe utility in Windows. The convert.exe file in Windows is a command-line utility used to convert file systems on a volume to FAT32 or NTFS. Due to this conflict, I am encountering several errors.

{
"src": "icons/manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "icons/manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "icons/manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "icons/manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
],
"screenshots": [
{
"src": "screenshots/screenshot-1280x720.png",
"sizes": "1280x720",
"type": "image/png",
"form_factor": "wide"
},
{
"src": "screenshots/screenshot-1366x768.png",
"sizes": "1366x768",
"type": "image/png",
"form_factor": "wide"
},
{
"src": "screenshots/screenshot-1600x900.png",
"sizes": "1600x900",
"type": "image/png",
"form_factor": "wide"
},
{
"src": "screenshots/screenshot-1920x1080.png",
"sizes": "1920x1080",
"type": "image/png",
"form_factor": "wide"
}
]
Comment on lines +36 to +61
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need those? If we do, it would be hard to maintain screenshots images on each version change. Can we create like a conceptual picture like this without really showing the application but a concept with cards and code section so it can be reused all the time? Or is the point of screenshot to be real screenshots?

image

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also use img/screenshot.png. We can move the file to public directory, and change its references to the public directory. It would be single file but easier to maintain.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We actually need screenshots of every sizes

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option is to use puppeteer to automate the flow. We can create a script that will build the application, load in a web browsers, take screenshots of different sizes and stores them.

Or else, we can just remove the screenshots from this PR and think / solve in future.

Copy link
Author

@plantindesk plantindesk Aug 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I will research on this as soon as possible 🫡

}
70 changes: 70 additions & 0 deletions src/presentation/public/service-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Event listener for when the service worker is installed
self.addEventListener('install', (event) => {
plantindesk marked this conversation as resolved.
Show resolved Hide resolved
// Log that the service worker has been installed
console.log('Service Worker: Installed');

// Open a cache called 'app-cache' and add the following URLs to it
event.waitUntil(
caches.open('app-cache').then((cache) => {
return cache.addAll([
'/', // root URL
'/icon.png',
'/favicon.ico',
'/main.ts',
]);
}),
);
});

// Event listener for when the service worker receives a fetch event
self.addEventListener('fetch', (event) => {
// Log that the service worker is fetching a URL
console.log('Service Worker: Fetching', event.request.url);

// Respond with a cached response if it exists, otherwise fetch the URL
event.respondWith(
caches.match(event.request).then((response) => {
// If a cached response exists, return it
if (response) {
console.log('Service Worker: Found in cache', event.request.url);
return response;
}

// If no cached response exists, fetch the URL and cache the response
const fetchRequest = event.request.clone();
return fetch(fetchRequest).then((response) => {
// If the response is not valid, return it without caching
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
}

// Cache the response and return it
const responseToCache = response.clone();
caches.open('app-cache').then((cache) => {
cache.put(event.request, responseToCache);
});
return response;
});
}),
);
});

// Event listener for when the service worker is activated
self.addEventListener('activate', (event) => {
// Log that the service worker has been activated
console.log('Service Worker: Activated');

// Remove old caches that start with 'app-' except for 'app-cache'
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames.filter((cacheName) => {
return cacheName.startsWith('app-') && cacheName !== 'app-cache';
}).map((cacheName) => {
return caches.delete(cacheName);
}),
);
}),
);
});