Add service worker

old-stable24
Varun Patil 2022-10-16 19:52:44 -07:00
parent de4bb84e40
commit 36e2f9d9ff
7 changed files with 1826 additions and 513 deletions

View File

@ -32,5 +32,8 @@ return [
// Config API
['name' => 'api#setUserConfig', 'url' => '/api/config/{key}', 'verb' => 'PUT'],
// Service worker
['name' => 'api#serviceWorker', 'url' => '/service-worker.js', 'verb' => 'GET'],
]
];

View File

@ -33,6 +33,8 @@ use OCP\App\IAppManager;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\StreamResponse;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\Files\IRootFolder;
use OCP\IConfig;
use OCP\IDBConnection;
@ -637,4 +639,22 @@ class ApiController extends Controller {
$this->config->setUserValue($userId, Application::APPNAME, $key, $value);
return new JSONResponse([], Http::STATUS_OK);
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function serviceWorker(): StreamResponse {
$response = new StreamResponse(__DIR__.'/../../js/memories-service-worker.js');
$response->setHeaders([
'Content-Type' => 'application/javascript',
'Service-Worker-Allowed' => '/'
]);
$policy = new ContentSecurityPolicy();
$policy->addAllowedWorkerSrcDomain("'self'");
$policy->addAllowedScriptDomain("'self'");
$policy->addAllowedConnectDomain("'self'");
$response->setContentSecurityPolicy($policy);
return $response;
}
}

View File

@ -9,6 +9,7 @@ use OCA\Files\Event\LoadSidebar;
use OCP\AppFramework\Controller;
use OCP\App\IAppManager;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\IConfig;
use OCP\IUserSession;
use OCP\Util;
@ -71,7 +72,12 @@ class PageController extends Controller {
$this->initialState->provideInitialState('recognize', $this->appManager->isEnabledForUser('recognize') === true);
$this->initialState->provideInitialState('version', $this->appManager->getAppInfo('memories')["version"]);
$policy = new ContentSecurityPolicy();
$policy->addAllowedWorkerSrcDomain("'self'");
$policy->addAllowedScriptDomain("'self'");
$response = new TemplateResponse($this->appName, 'main');
$response->setContentSecurityPolicy($policy);
return $response;
}

2246
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -65,6 +65,7 @@
"@types/url-parse": "^1.4.8",
"playwright": "^1.27.1",
"ts-loader": "^9.4.1",
"typescript": "^4.8.4"
"typescript": "^4.8.4",
"workbox-webpack-plugin": "^6.5.4"
}
}

View File

@ -57,6 +57,7 @@ import {
NcContent, NcAppContent, NcAppNavigation,
NcAppNavigationItem, NcAppNavigationSettings,
} from '@nextcloud/vue';
import { generateUrl } from '@nextcloud/router'
import Timeline from './components/Timeline.vue'
import Settings from './components/Settings.vue'
@ -104,6 +105,23 @@ export default class App extends Mixins(GlobalMixin, UserConfig) {
contentVue.classList.add('nextcloud-major-' + version[0]);
}
}
async beforeMount() {
if ('serviceWorker' in navigator) {
// Use the window load event to keep the page load performant
window.addEventListener('load', async () => {
try {
const url = generateUrl('/apps/memories/service-worker.js');
const registration = await navigator.serviceWorker.register(url, { scope: generateUrl('/apps/memories') });
console.log('SW registered: ', registration);
} catch (error) {
console.error('SW registration failed: ', error);
}
})
} else {
console.debug('Service Worker is not enabled on this browser.')
}
}
}
</script>

View File

@ -1,6 +1,10 @@
const webpackConfig = require('@nextcloud/webpack-vue-config')
const WorkboxPlugin = require('workbox-webpack-plugin')
const path = require('path')
const buildMode = process.env.NODE_ENV
const isDev = buildMode === 'development'
webpackConfig.module.rules.push({
test: /\.ts?$/,
loader: 'ts-loader',
@ -21,4 +25,43 @@ webpackConfig.watchOptions = {
aggregateTimeout: 300,
};
if (!isDev) {
webpackConfig.plugins.push(
new WorkboxPlugin.GenerateSW({
swDest: 'memories-service-worker.js',
clientsClaim: true,
skipWaiting: true,
exclude: [new RegExp('.*')], // don't do precaching
inlineWorkboxRuntime: true,
sourcemap: false,
// Define runtime caching rules.
runtimeCaching: [{
// Match any preview file request
urlPattern: /^.*\/core\/preview\?fileId=.*/,
handler: 'CacheFirst',
options: {
cacheName: 'images',
expiration: {
maxAgeSeconds: 3600 * 24 * 7, // one week
maxEntries: 20000, // 20k images
},
},
}, {
// Match page requests
urlPattern: /^.*\/.*$/,
handler: 'NetworkFirst',
options: {
cacheName: 'pages',
expiration: {
maxAgeSeconds: 3600 * 24 * 7, // one week
maxEntries: 2000, // assets
},
},
}],
})
);
}
module.exports = webpackConfig