deploy: 1818925286
After Width: | Height: | Size: 418 KiB |
After Width: | Height: | Size: 114 KiB |
After Width: | Height: | Size: 386 KiB |
After Width: | Height: | Size: 108 KiB |
After Width: | Height: | Size: 384 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 389 KiB |
After Width: | Height: | Size: 103 KiB |
@ -0,0 +1,74 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Flutter samples</title>
|
||||||
|
<link href="styles.css" rel="stylesheet" media="screen">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Google+Sans|Google+Sans+Display|Roboto:300,400,500&display=swap" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<script src="packages/mdc_web/material-components-web.min.js"></script>
|
||||||
|
<script src="https://kit.fontawesome.com/16cc04762e.js"></script>
|
||||||
|
<script defer src="description.dart.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<div class="navbar">
|
||||||
|
<a class="leading" href="./">
|
||||||
|
<img src="images/logos/logo_lockup_flutter_horizontal_wht_96.png" />
|
||||||
|
<span class="title">Samples</span>
|
||||||
|
</a>
|
||||||
|
<div class="nav-items">
|
||||||
|
<a href="https://flutter.dev/">Flutter Home</a>
|
||||||
|
<a href="https://api.flutter.dev/">API Docs</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="description-title-row">
|
||||||
|
<h1>Navigation and Routing</h1>
|
||||||
|
<div class="type-label type-label-bordered">sample</div>
|
||||||
|
</div>
|
||||||
|
<p>By Flutter</p>
|
||||||
|
<div class="toolbar">
|
||||||
|
<div class="buttons">
|
||||||
|
<button class="mdc-button mdc-button--outlined" onclick="window.location.href = 'web/navigation_and_routing';"><span class="mdc-button__ripple"></span> Launch App</button><button class="mdc-button mdc-button--outlined" onclick="window.location.href = 'https://github.com/flutter/samples/tree/master/navigation_and_Routing';">
|
||||||
|
<div class="mdc-button__ripple"></div>
|
||||||
|
<i class="material-icons mdc-button__icon" aria-hidden="true">code</i>
|
||||||
|
<span class="mdc-button__label">Source Code</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="tags-container">
|
||||||
|
<div class="tags-label">
|
||||||
|
<i class="material-icons">local_offer</i>
|
||||||
|
<span>Tags</span>
|
||||||
|
</div>
|
||||||
|
<div class="tags">
|
||||||
|
<a href="./#?search=tag%3Aadvanced">advanced</a>
|
||||||
|
<a href="./#?search=tag%3Asample">sample</a>
|
||||||
|
<a href="./#?search=tag%3Anavigation">navigation</a>
|
||||||
|
<a href="./#?search=tag%3Arouter">router</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="slider-container">
|
||||||
|
<div class="slider-content">
|
||||||
|
<div class="slider-single"><img class="slider-single-image" src="images/navigation_and_routing1.png" alt="Navigation and Routing screenshot" /></div>
|
||||||
|
<div class="slider-single"><img class="slider-single-image" src="images/navigation_and_routing2.png" alt="Navigation and Routing screenshot" /></div>
|
||||||
|
<div class="slider-single"><img class="slider-single-image" src="images/navigation_and_routing3.png" alt="Navigation and Routing screenshot" /></div>
|
||||||
|
<div class="slider-single"><img class="slider-single-image" src="images/navigation_and_routing4.png" alt="Navigation and Routing screenshot" /></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="description">
|
||||||
|
<p>A Flutter sample app that shows how to use how to use the Router API to handle common navigation scenarios.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<span>© Flutter 2020</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</html>
|
@ -0,0 +1 @@
|
|||||||
|
2915258d7281811579731bcf136f2206
|
@ -0,0 +1 @@
|
|||||||
|
{"packages/cupertino_icons/assets/CupertinoIcons.ttf":["packages/cupertino_icons/assets/CupertinoIcons.ttf"]}
|
@ -0,0 +1 @@
|
|||||||
|
[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]},{"family":"packages/cupertino_icons/CupertinoIcons","fonts":[{"asset":"packages/cupertino_icons/assets/CupertinoIcons.ttf"}]}]
|
After Width: | Height: | Size: 917 B |
@ -0,0 +1,190 @@
|
|||||||
|
'use strict';
|
||||||
|
const MANIFEST = 'flutter-app-manifest';
|
||||||
|
const TEMP = 'flutter-temp-cache';
|
||||||
|
const CACHE_NAME = 'flutter-app-cache';
|
||||||
|
const RESOURCES = {
|
||||||
|
"assets/AssetManifest.json": "2efbb41d7877d10aac9d091f58ccd7b9",
|
||||||
|
"assets/FontManifest.json": "dc3d03800ccca4601324923c0b1d6d57",
|
||||||
|
"assets/fonts/MaterialIcons-Regular.otf": "4e6447691c9509f7acdbf8a931a85ca1",
|
||||||
|
"assets/packages/cupertino_icons/assets/CupertinoIcons.ttf": "6d342eb68f170c97609e9da345464e5e",
|
||||||
|
"assets/NOTICES": "5b59f719bc51c1166a8368324c91b335",
|
||||||
|
"icons/Icon-192.png": "ac9a721a12bbc803b44f645561ecb1e1",
|
||||||
|
"icons/Icon-512.png": "96e752610906ba2a93c65f8abe1645f1",
|
||||||
|
"favicon.png": "5dcef449791fa27946b3d35ad8803796",
|
||||||
|
"manifest.json": "5d94931eac503e97b830d7f00bdbc4ba",
|
||||||
|
"version.json": "bdb4806f54523c14a30b7e256984d0e9",
|
||||||
|
"main.dart.js": "ee7d528ade2e779e34308b8f5d530c97",
|
||||||
|
"index.html": "0c9187962b168ada2379ad4df2e8352d",
|
||||||
|
"/": "0c9187962b168ada2379ad4df2e8352d"
|
||||||
|
};
|
||||||
|
|
||||||
|
// The application shell files that are downloaded before a service worker can
|
||||||
|
// start.
|
||||||
|
const CORE = [
|
||||||
|
"/",
|
||||||
|
"main.dart.js",
|
||||||
|
"index.html",
|
||||||
|
"assets/NOTICES",
|
||||||
|
"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)));
|
||||||
|
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)));
|
||||||
|
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.
|
||||||
|
return response || fetch(event.request).then((response) => {
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 8.1 KiB |
@ -0,0 +1,98 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!--
|
||||||
|
If you are serving your web app in a path other than the root, change the
|
||||||
|
href value below to reflect the base path you are serving from.
|
||||||
|
|
||||||
|
The path provided below has to start and end with a slash "/" in order for
|
||||||
|
it to work correctly.
|
||||||
|
|
||||||
|
For more details:
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
|
||||||
|
-->
|
||||||
|
<base href="/">
|
||||||
|
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
||||||
|
<meta name="description" content="Navigation and routing sample app">
|
||||||
|
|
||||||
|
<!-- iOS meta tags & icons -->
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="bookstore">
|
||||||
|
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
||||||
|
|
||||||
|
<title>bookstore</title>
|
||||||
|
<link rel="manifest" href="manifest.json">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- This script installs service_worker.js to provide PWA functionality to
|
||||||
|
application. For more information, see:
|
||||||
|
https://developers.google.com/web/fundamentals/primers/service-workers -->
|
||||||
|
<script>
|
||||||
|
var serviceWorkerVersion = '4201788812';
|
||||||
|
var scriptLoaded = false;
|
||||||
|
function loadMainDartJs() {
|
||||||
|
if (scriptLoaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
scriptLoaded = true;
|
||||||
|
var scriptTag = document.createElement('script');
|
||||||
|
scriptTag.src = 'main.dart.js';
|
||||||
|
scriptTag.type = 'application/javascript';
|
||||||
|
document.body.append(scriptTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
// Service workers are supported. Use them.
|
||||||
|
window.addEventListener('load', function () {
|
||||||
|
// Wait for registration to finish before dropping the <script> tag.
|
||||||
|
// Otherwise, the browser will load the script multiple times,
|
||||||
|
// potentially different versions.
|
||||||
|
var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
|
||||||
|
navigator.serviceWorker.register(serviceWorkerUrl)
|
||||||
|
.then((reg) => {
|
||||||
|
function waitForActivation(serviceWorker) {
|
||||||
|
serviceWorker.addEventListener('statechange', () => {
|
||||||
|
if (serviceWorker.state == 'activated') {
|
||||||
|
console.log('Installed new service worker.');
|
||||||
|
loadMainDartJs();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!reg.active && (reg.installing || reg.waiting)) {
|
||||||
|
// No active web worker and we have installed or are installing
|
||||||
|
// one for the first time. Simply wait for it to activate.
|
||||||
|
waitForActivation(reg.installing ?? reg.waiting);
|
||||||
|
} else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
|
||||||
|
// When the app updates the serviceWorkerVersion changes, so we
|
||||||
|
// need to ask the service worker to update.
|
||||||
|
console.log('New service worker available.');
|
||||||
|
reg.update();
|
||||||
|
waitForActivation(reg.installing);
|
||||||
|
} else {
|
||||||
|
// Existing service worker is still good.
|
||||||
|
console.log('Loading app from service worker.');
|
||||||
|
loadMainDartJs();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// If service worker doesn't succeed in a reasonable amount of time,
|
||||||
|
// fallback to plaint <script> tag.
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!scriptLoaded) {
|
||||||
|
console.warn(
|
||||||
|
'Failed to load app from service worker. Falling back to plain <script> tag.',
|
||||||
|
);
|
||||||
|
loadMainDartJs();
|
||||||
|
}
|
||||||
|
}, 4000);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Service workers not supported. Just drop the <script> tag.
|
||||||
|
loadMainDartJs();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "bookstore",
|
||||||
|
"short_name": "bookstore",
|
||||||
|
"start_url": ".",
|
||||||
|
"display": "standalone",
|
||||||
|
"background_color": "#0175C2",
|
||||||
|
"theme_color": "#0175C2",
|
||||||
|
"description": "Navigation and routing sample app",
|
||||||
|
"orientation": "portrait-primary",
|
||||||
|
"prefer_related_applications": false,
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "icons/Icon-192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "icons/Icon-512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
{"app_name":"bookstore","version":"1.0.0","build_number":"1"}
|