mirror of https://github.com/flutter/samples.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
8.9 KiB
218 lines
8.9 KiB
'use strict';
|
|
const MANIFEST = 'flutter-app-manifest';
|
|
const TEMP = 'flutter-temp-cache';
|
|
const CACHE_NAME = 'flutter-app-cache';
|
|
|
|
const RESOURCES = {"index.html": "0457c600acf369b8ca516f270fc802fd",
|
|
"/": "0457c600acf369b8ca516f270fc802fd",
|
|
"version.json": "408e32657aac2b0495551d3fc84cc2ff",
|
|
"favicon.png": "5dcef449791fa27946b3d35ad8803796",
|
|
"assets/AssetManifest.bin": "645cde9921221c1e34f2228ce300d2ae",
|
|
"assets/FontManifest.json": "06438dbc68e4dc4c7665d2e03e14e76d",
|
|
"assets/packages/cupertino_icons/assets/CupertinoIcons.ttf": "89ed8f4e49bcdfc0b5bfc9b24591e347",
|
|
"assets/fonts/MaterialIcons-Regular.otf": "20973541082cac21ebf0682f7bdce660",
|
|
"assets/assets/images/button-start-hover.png": "39d7ee03962ad766b66be34336343e75",
|
|
"assets/assets/images/select-right.png": "a6c979b3eae49cde6c7d5797dc357034",
|
|
"assets/assets/images/fg-base.png": "9742f524c248f9795e59132bda584982",
|
|
"assets/assets/images/fg-light-receive.png": "9981f29fa2d3814768cbf9695eb7b861",
|
|
"assets/assets/images/mg-light-receive.png": "6e0e1018b6cf20f4747f5c4ef3e6f58d",
|
|
"assets/assets/images/button-start.png": "748701e42abc14ebc65963234d9a7b6a",
|
|
"assets/assets/images/particle-wave.png": "d6b73c1346b8ffd48de351cfab3daaad",
|
|
"assets/assets/images/fg-light-emit.png": "d398c8fab13becd0da8995be2a3c7799",
|
|
"assets/assets/images/bg-light-receive.png": "2f6ba99f8eea020027e10b9778b666ad",
|
|
"assets/assets/images/select-left.png": "b3fbaf9a7b1b72c26880c5bdfde6e33c",
|
|
"assets/assets/images/mg-base.png": "deba0329701a59c12f8904235539de19",
|
|
"assets/assets/images/bg-base.jpg": "3c258b33e7a71dee7ae8e3c4e83dd04f",
|
|
"assets/assets/images/mg-light-emit.png": "076ed5490a67d7d300832d86778adfc0",
|
|
"assets/assets/fonts/Exo-Medium.ttf": "822a35349a144a97433b82d94df61d1a",
|
|
"assets/assets/fonts/OFL.txt": "e542a680112942b035ac18d476288952",
|
|
"assets/assets/fonts/Exo-Bold.ttf": "a939d1d0769c88bde068c8570e5f3f22",
|
|
"assets/assets/shaders/ui_glitch.frag": "97b58db3bd4a0fd72623cc29af45f190",
|
|
"assets/assets/shaders/orb_shader.frag": "7f53dc1f64cf4ef8e12c5171dcd7efc5",
|
|
"assets/shaders/ink_sparkle.frag": "f8b80e740d33eb157090be4e995febdf",
|
|
"assets/NOTICES": "6fcee2ff82deb7efdb83058506b9574f",
|
|
"assets/AssetManifest.json": "183c6882211bd7760ebf1ff3cbfcd847",
|
|
"canvaskit/skwasm.worker.js": "51253d3321b11ddb8d73fa8aa87d3b15",
|
|
"canvaskit/skwasm.js": "95f16c6690f955a45b2317496983dbe9",
|
|
"canvaskit/canvaskit.wasm": "42df12e09ecc0d5a4a34a69d7ee44314",
|
|
"canvaskit/chromium/canvaskit.wasm": "be0e3b33510f5b7b0cc76cc4d3e50048",
|
|
"canvaskit/chromium/canvaskit.js": "96ae916cd2d1b7320fff853ee22aebb0",
|
|
"canvaskit/skwasm.wasm": "1a074e8452fe5e0d02b112e22cdcf455",
|
|
"canvaskit/canvaskit.js": "bbf39143dfd758d8d847453b120c8ebb",
|
|
"manifest.json": "80bcae284fe5b8fc18af68135b7896fe",
|
|
"flutter.js": "6fef97aeca90b426343ba6c5c9dc5d4a",
|
|
"icons/Icon-maskable-512.png": "301a7604d45b3e739efc881eb04896ea",
|
|
"icons/Icon-maskable-192.png": "c457ef57daa1d16f64b27b786ec2ea3c",
|
|
"icons/Icon-512.png": "96e752610906ba2a93c65f8abe1645f1",
|
|
"icons/Icon-192.png": "ac9a721a12bbc803b44f645561ecb1e1",
|
|
"main.dart.js": "9e672bf65b0ab0dfa55369ed33a1dabb"};
|
|
// The application shell files that are downloaded before a service worker can
|
|
// start.
|
|
const CORE = ["main.dart.js",
|
|
"index.html",
|
|
"assets/AssetManifest.json",
|
|
"assets/FontManifest.json"];
|
|
|
|
// During install, the TEMP cache is populated with the application shell files.
|
|
self.addEventListener("install", (event) => {
|
|
self.skipWaiting();
|
|
return event.waitUntil(
|
|
caches.open(TEMP).then((cache) => {
|
|
return cache.addAll(
|
|
CORE.map((value) => new Request(value, {'cache': 'reload'})));
|
|
})
|
|
);
|
|
});
|
|
// During activate, the cache is populated with the temp files downloaded in
|
|
// install. If this service worker is upgrading from one with a saved
|
|
// MANIFEST, then use this to retain unchanged resource files.
|
|
self.addEventListener("activate", function(event) {
|
|
return event.waitUntil(async function() {
|
|
try {
|
|
var contentCache = await caches.open(CACHE_NAME);
|
|
var tempCache = await caches.open(TEMP);
|
|
var manifestCache = await caches.open(MANIFEST);
|
|
var manifest = await manifestCache.match('manifest');
|
|
// When there is no prior manifest, clear the entire cache.
|
|
if (!manifest) {
|
|
await caches.delete(CACHE_NAME);
|
|
contentCache = await caches.open(CACHE_NAME);
|
|
for (var request of await tempCache.keys()) {
|
|
var response = await tempCache.match(request);
|
|
await contentCache.put(request, response);
|
|
}
|
|
await caches.delete(TEMP);
|
|
// Save the manifest to make future upgrades efficient.
|
|
await manifestCache.put('manifest', new Response(JSON.stringify(RESOURCES)));
|
|
// Claim client to enable caching on first launch
|
|
self.clients.claim();
|
|
return;
|
|
}
|
|
var oldManifest = await manifest.json();
|
|
var origin = self.location.origin;
|
|
for (var request of await contentCache.keys()) {
|
|
var key = request.url.substring(origin.length + 1);
|
|
if (key == "") {
|
|
key = "/";
|
|
}
|
|
// If a resource from the old manifest is not in the new cache, or if
|
|
// the MD5 sum has changed, delete it. Otherwise the resource is left
|
|
// in the cache and can be reused by the new service worker.
|
|
if (!RESOURCES[key] || RESOURCES[key] != oldManifest[key]) {
|
|
await contentCache.delete(request);
|
|
}
|
|
}
|
|
// Populate the cache with the app shell TEMP files, potentially overwriting
|
|
// cache files preserved above.
|
|
for (var request of await tempCache.keys()) {
|
|
var response = await tempCache.match(request);
|
|
await contentCache.put(request, response);
|
|
}
|
|
await caches.delete(TEMP);
|
|
// Save the manifest to make future upgrades efficient.
|
|
await manifestCache.put('manifest', new Response(JSON.stringify(RESOURCES)));
|
|
// Claim client to enable caching on first launch
|
|
self.clients.claim();
|
|
return;
|
|
} catch (err) {
|
|
// On an unhandled exception the state of the cache cannot be guaranteed.
|
|
console.error('Failed to upgrade service worker: ' + err);
|
|
await caches.delete(CACHE_NAME);
|
|
await caches.delete(TEMP);
|
|
await caches.delete(MANIFEST);
|
|
}
|
|
}());
|
|
});
|
|
// The fetch handler redirects requests for RESOURCE files to the service
|
|
// worker cache.
|
|
self.addEventListener("fetch", (event) => {
|
|
if (event.request.method !== 'GET') {
|
|
return;
|
|
}
|
|
var origin = self.location.origin;
|
|
var key = event.request.url.substring(origin.length + 1);
|
|
// Redirect URLs to the index.html
|
|
if (key.indexOf('?v=') != -1) {
|
|
key = key.split('?v=')[0];
|
|
}
|
|
if (event.request.url == origin || event.request.url.startsWith(origin + '/#') || key == '') {
|
|
key = '/';
|
|
}
|
|
// If the URL is not the RESOURCE list then return to signal that the
|
|
// browser should take over.
|
|
if (!RESOURCES[key]) {
|
|
return;
|
|
}
|
|
// If the URL is the index.html, perform an online-first request.
|
|
if (key == '/') {
|
|
return onlineFirst(event);
|
|
}
|
|
event.respondWith(caches.open(CACHE_NAME)
|
|
.then((cache) => {
|
|
return cache.match(event.request).then((response) => {
|
|
// Either respond with the cached resource, or perform a fetch and
|
|
// lazily populate the cache only if the resource was successfully fetched.
|
|
return response || fetch(event.request).then((response) => {
|
|
if (response && Boolean(response.ok)) {
|
|
cache.put(event.request, response.clone());
|
|
}
|
|
return response;
|
|
});
|
|
})
|
|
})
|
|
);
|
|
});
|
|
self.addEventListener('message', (event) => {
|
|
// SkipWaiting can be used to immediately activate a waiting service worker.
|
|
// This will also require a page refresh triggered by the main worker.
|
|
if (event.data === 'skipWaiting') {
|
|
self.skipWaiting();
|
|
return;
|
|
}
|
|
if (event.data === 'downloadOffline') {
|
|
downloadOffline();
|
|
return;
|
|
}
|
|
});
|
|
// Download offline will check the RESOURCES for all files not in the cache
|
|
// and populate them.
|
|
async function downloadOffline() {
|
|
var resources = [];
|
|
var contentCache = await caches.open(CACHE_NAME);
|
|
var currentContent = {};
|
|
for (var request of await contentCache.keys()) {
|
|
var key = request.url.substring(origin.length + 1);
|
|
if (key == "") {
|
|
key = "/";
|
|
}
|
|
currentContent[key] = true;
|
|
}
|
|
for (var resourceKey of Object.keys(RESOURCES)) {
|
|
if (!currentContent[resourceKey]) {
|
|
resources.push(resourceKey);
|
|
}
|
|
}
|
|
return contentCache.addAll(resources);
|
|
}
|
|
// Attempt to download the resource online before falling back to
|
|
// the offline cache.
|
|
function onlineFirst(event) {
|
|
return event.respondWith(
|
|
fetch(event.request).then((response) => {
|
|
return caches.open(CACHE_NAME).then((cache) => {
|
|
cache.put(event.request, response.clone());
|
|
return response;
|
|
});
|
|
}).catch((error) => {
|
|
return caches.open(CACHE_NAME).then((cache) => {
|
|
return cache.match(event.request).then((response) => {
|
|
if (response != null) {
|
|
return response;
|
|
}
|
|
throw error;
|
|
});
|
|
});
|
|
})
|
|
);
|
|
}
|