diff --git a/.gitignore b/.gitignore index 789f14aecd..e833f8dbd2 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,4 @@ yarn-error.log public/google*.html report.html composer.phar -app.js.map +app.js.map \ No newline at end of file diff --git a/frontend/src/serviceworker.js b/frontend/src/serviceworker.js new file mode 100644 index 0000000000..dda3b1111b --- /dev/null +++ b/frontend/src/serviceworker.js @@ -0,0 +1,58 @@ +/* + * serviceworker.js + * Copyright (c) 2021 Lorenzo Breda (https://github.com/lbreda) + * + * This file is part of Firefly III (https://github.com/firefly-iii). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +let staticCachePrefix = "firefly-III-" +let staticCacheName = staticCachePrefix + new Date().getTime(); +let cachedFiles = [ + '/offline', + '/v2/plugins/local-fonts/gf-source.css', + '/v2/css/app.css', +]; + +// Create cache on install +self.addEventListener("install", event => { + this.skipWaiting(); + event.waitUntil( + caches.open(staticCacheName).then(cache => cache.addAll(cachedFiles)) + ) +}); + +// Clear cache on activate +self.addEventListener('activate', event => { + event.waitUntil( + caches.keys().then(cacheNames => { + return Promise.all( + cacheNames + .filter(cacheName => (cacheName.startsWith(staticCachePrefix))) + .filter(cacheName => (cacheName !== staticCacheName)) + .map(cacheName => caches.delete(cacheName)) + ); + }) + ); +}); + +// Serve from Cache or return the offline page +self.addEventListener("fetch", event => { + event.respondWith( + caches.match(event.request) + .then(response => (response || fetch(event.request))) + .catch(() => caches.match('offline')) + ) +}); diff --git a/public/manifest.webmanifest b/public/manifest.webmanifest index cb44fea0e3..cf49fb98e2 100644 --- a/public/manifest.webmanifest +++ b/public/manifest.webmanifest @@ -3,15 +3,83 @@ "short_name": "Firefly III", "start_url": "/", "icons": [ + { + "src": "/maskable72.png", + "sizes": "72x72", + "type": "image/png", + "scope": "maskable" + }, + { + "src": "/maskable76.png", + "sizes": "76x76", + "type": "image/png", + "scope": "maskable" + }, + { + "src": "/maskable96.png", + "sizes": "96x96", + "type": "image/png", + "scope": "maskable" + }, + { + "src": "/maskable120.png", + "sizes": "120x120", + "type": "image/png", + "scope": "maskable" + }, + { + "src": "/maskable128.png", + "sizes": "128x128", + "type": "image/png", + "scope": "maskable" + }, + { + "src": "/maskable144.png", + "sizes": "144x144", + "type": "image/png", + "scope": "maskable" + }, + { + "src": "/maskable152.png", + "sizes": "152x152", + "type": "image/png", + "scope": "maskable" + }, + { + "src": "/maskable180.png", + "sizes": "180x180", + "type": "image/png", + "scope": "maskable" + }, { "src": "/android-chrome-192x192.png", "sizes": "192x192", - "type": "image/png" + "type": "image/png", + "scope": "any" + }, + { + "src": "/maskable192.png", + "sizes": "192x192", + "type": "image/png", + "scope": "maskable" + }, + { + "src": "/maskable384.png", + "sizes": "384x384", + "type": "image/png", + "scope": "maskable" }, { "src": "/android-chrome-512x512.png", "sizes": "512x512", - "type": "image/png" + "type": "image/png", + "scope": "any" + }, + { + "src": "/maskable512.png", + "sizes": "512x512", + "type": "image/png", + "scope": "maskable" } ], "theme_color": "#1e6581", diff --git a/public/maskable-icon.svg b/public/maskable-icon.svg new file mode 100644 index 0000000000..6eb3ecc6f5 --- /dev/null +++ b/public/maskable-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/maskable120.png b/public/maskable120.png new file mode 100644 index 0000000000..28472c71b9 Binary files /dev/null and b/public/maskable120.png differ diff --git a/public/maskable128.png b/public/maskable128.png new file mode 100644 index 0000000000..6a29bd5ded Binary files /dev/null and b/public/maskable128.png differ diff --git a/public/maskable144.png b/public/maskable144.png new file mode 100644 index 0000000000..7567806438 Binary files /dev/null and b/public/maskable144.png differ diff --git a/public/maskable152.png b/public/maskable152.png new file mode 100644 index 0000000000..8301098084 Binary files /dev/null and b/public/maskable152.png differ diff --git a/public/maskable180.png b/public/maskable180.png new file mode 100644 index 0000000000..a3eb3f2127 Binary files /dev/null and b/public/maskable180.png differ diff --git a/public/maskable192.png b/public/maskable192.png new file mode 100644 index 0000000000..f280d1d2b2 Binary files /dev/null and b/public/maskable192.png differ diff --git a/public/maskable384.png b/public/maskable384.png new file mode 100644 index 0000000000..bed923b227 Binary files /dev/null and b/public/maskable384.png differ diff --git a/public/maskable512.png b/public/maskable512.png new file mode 100644 index 0000000000..311b9015b1 Binary files /dev/null and b/public/maskable512.png differ diff --git a/public/maskable72.png b/public/maskable72.png new file mode 100644 index 0000000000..d4e50a6039 Binary files /dev/null and b/public/maskable72.png differ diff --git a/public/maskable76.png b/public/maskable76.png new file mode 100644 index 0000000000..d793ac1218 Binary files /dev/null and b/public/maskable76.png differ diff --git a/public/maskable96.png b/public/maskable96.png new file mode 100644 index 0000000000..5a02b5acf1 Binary files /dev/null and b/public/maskable96.png differ diff --git a/public/serviceworker.js b/public/serviceworker.js new file mode 100644 index 0000000000..1eb9b19f82 --- /dev/null +++ b/public/serviceworker.js @@ -0,0 +1,58 @@ +/* + * serviceworker.js + * Copyright (c) 2021 james@firefly-iii.org + * + * This file is part of Firefly III (https://github.com/firefly-iii). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +let staticCachePrefix = "firefly-III-" +let staticCacheName = staticCachePrefix + new Date().getTime(); +let cachedFiles = [ + '/offline', + '/v2/plugins/local-fonts/gf-source.css', + '/v2/css/app.css', +]; + +// Create cache on install +self.addEventListener("install", event => { + this.skipWaiting(); + event.waitUntil( + caches.open(staticCacheName).then(cache => cache.addAll(cachedFiles)) + ) +}); + +// Clear cache on activate +self.addEventListener('activate', event => { + event.waitUntil( + caches.keys().then(cacheNames => { + return Promise.all( + cacheNames + .filter(cacheName => (cacheName.startsWith(staticCachePrefix))) + .filter(cacheName => (cacheName !== staticCacheName)) + .map(cacheName => caches.delete(cacheName)) + ); + }) + ); +}); + +// Serve from Cache or return the offline page +self.addEventListener("fetch", event => { + event.respondWith( + caches.match(event.request) + .then(response => (response || fetch(event.request))) + .catch(() => caches.match('offline')) + ) +}); diff --git a/resources/lang/en_GB/errors.php b/resources/lang/en_GB/errors.php index 1818adc8c6..4dac63fc73 100644 --- a/resources/lang/en_GB/errors.php +++ b/resources/lang/en_GB/errors.php @@ -47,5 +47,4 @@ return [ 'tell_more' => 'Tell us more than "it says Whoops!"', 'include_logs' => 'Include error logs (see above).', 'what_did_you_do' => 'Tell us what you were doing.', - ]; diff --git a/resources/lang/en_US/errors.php b/resources/lang/en_US/errors.php index 1818adc8c6..b63c231504 100644 --- a/resources/lang/en_US/errors.php +++ b/resources/lang/en_US/errors.php @@ -47,5 +47,8 @@ return [ 'tell_more' => 'Tell us more than "it says Whoops!"', 'include_logs' => 'Include error logs (see above).', 'what_did_you_do' => 'Tell us what you were doing.', + 'offline_header' => 'You are probably offline', + 'offline_unreachable' => 'Firefly III is unreachable. Your device is currently offline or the server is not working.', + 'offline_github' => 'If you are sure both your device and the server are online, please open a ticket on GitHub.', ]; diff --git a/resources/lang/it_IT/errors.php b/resources/lang/it_IT/errors.php index bdd4fe0a54..5bb4f6a123 100644 --- a/resources/lang/it_IT/errors.php +++ b/resources/lang/it_IT/errors.php @@ -47,5 +47,4 @@ return [ 'tell_more' => 'Dicci di più di "dice Oops!"', 'include_logs' => 'Includi i log degli errori (vedi sopra).', 'what_did_you_do' => 'Dicci cosa stavi facendo.', - ]; diff --git a/resources/views/errors/offline.twig b/resources/views/errors/offline.twig new file mode 100644 index 0000000000..b1130978ee --- /dev/null +++ b/resources/views/errors/offline.twig @@ -0,0 +1,41 @@ + + + + + + + Firefly III | Offline + + + + + + + + + +
+
+
+
+

+ +
+

Offline

+

+ {{ trans('errors.offline_header') }} +

+

+ {{ trans('errors.offline_unreachable') }} +

+

+ {{ trans('errors.offline_github')|raw }} +

+
+
+
+
+
+ + + diff --git a/resources/views/v1/layout/default.twig b/resources/views/v1/layout/default.twig index 29956298df..cf02557e28 100644 --- a/resources/views/v1/layout/default.twig +++ b/resources/views/v1/layout/default.twig @@ -228,5 +228,17 @@ {% endif %} + + diff --git a/resources/views/v1/layout/empty.twig b/resources/views/v1/layout/empty.twig index 25fad9fe06..8cf3ac77f5 100644 --- a/resources/views/v1/layout/empty.twig +++ b/resources/views/v1/layout/empty.twig @@ -61,5 +61,17 @@ {% endif %} + + diff --git a/resources/views/v1/layout/guest.twig b/resources/views/v1/layout/guest.twig index c7e01b512e..f406a12376 100644 --- a/resources/views/v1/layout/guest.twig +++ b/resources/views/v1/layout/guest.twig @@ -76,5 +76,17 @@ {% endif %} + + diff --git a/resources/views/v1/layout/install.twig b/resources/views/v1/layout/install.twig index f2086d5cc3..d8ff303d88 100644 --- a/resources/views/v1/layout/install.twig +++ b/resources/views/v1/layout/install.twig @@ -36,5 +36,17 @@ {% block scripts %}{% endblock %} + + diff --git a/resources/views/v2/layout/auth.twig b/resources/views/v2/layout/auth.twig index 9cfe20eba1..01a74ef422 100644 --- a/resources/views/v2/layout/auth.twig +++ b/resources/views/v2/layout/auth.twig @@ -19,5 +19,17 @@ {% block content %}{% endblock %} {% block scripts %}{% endblock %} + + diff --git a/resources/views/v2/layout/default.twig b/resources/views/v2/layout/default.twig index b6b7147c01..21cb1f65da 100644 --- a/resources/views/v2/layout/default.twig +++ b/resources/views/v2/layout/default.twig @@ -46,9 +46,11 @@

- {% if mainTitleIcon|default(false) %}{% endif %} + {% if mainTitleIcon|default(false) %}{% endif %} {{ title }} - {% if subTitleIcon|default(false) %}{% endif %} + {% if subTitleIcon|default(false) %}{% endif %} {{ subTitle|default('') }}

@@ -91,6 +93,18 @@ {% block scripts %}{% endblock %} + + diff --git a/resources/views/v2/partials/layout/favicons.twig b/resources/views/v2/partials/layout/favicons.twig index 826e2d5dc8..17199c3a97 100644 --- a/resources/views/v2/partials/layout/favicons.twig +++ b/resources/views/v2/partials/layout/favicons.twig @@ -1,8 +1,28 @@ - - +{# main icons #} - + +{# iOS icons #} + + + + + +{# Pinned tab #} - + +{# Android #} + + + +{# Manifest #} + + +{# Android colors #} + +{# Microsoft meta #} + + + + diff --git a/routes/web.php b/routes/web.php index 0a0599c8db..d9b42c4b44 100644 --- a/routes/web.php +++ b/routes/web.php @@ -37,6 +37,13 @@ Route::group( } ); +Route::group( + ['middleware' => 'binders-only'], + static function () { + Route::get('offline', fn () => view('errors.offline')); + } +); + /** * These routes only work when the user is NOT logged in. */