diff --git a/index.html b/index.html index 9cf6532..7d9a070 100644 --- a/index.html +++ b/index.html @@ -5,10 +5,12 @@ - Home · Nofated + Amane's Intro
+ + diff --git a/public/quicklink.js b/public/quicklink.js new file mode 100644 index 0000000..153efcf --- /dev/null +++ b/public/quicklink.js @@ -0,0 +1 @@ +!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(e.quicklink={})}(this,function(e){function n(e){return new Promise(function(n,r,t){(t=new XMLHttpRequest).open("GET",e,t.withCredentials=!0),t.onload=function(){200===t.status?n():r()},t.send()})}var r,t=(r=document.createElement("link")).relList&&r.relList.supports&&r.relList.supports("prefetch")?function(e){return new Promise(function(n,r,t){(t=document.createElement("link")).rel="prefetch",t.href=e,t.onload=n,t.onerror=r,document.head.appendChild(t)})}:n,o=window.requestIdleCallback||function(e){var n=Date.now();return setTimeout(function(){e({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-n))}})},1)},i=new Set,c=new Set,u=!1;function a(e){if(e){if(e.saveData)return new Error("Save-Data is enabled");if(/2g/.test(e.effectiveType))return new Error("network conditions are poor")}return!0}function s(e,r,o){var s=a(navigator.connection);return s instanceof Error?Promise.reject(new Error("Cannot prefetch, "+s.message)):(c.size>0&&!u&&console.warn("[Warning] You are using both prefetching and prerendering on the same document"),Promise.all([].concat(e).map(function(e){if(!i.has(e))return i.add(e),(r?function(e){return window.fetch?fetch(e,{credentials:"include"}):n(e)}:t)(new URL(e,location.href).toString())})))}function f(e,n){var r=a(navigator.connection);if(r instanceof Error)return Promise.reject(new Error("Cannot prerender, "+r.message));if(!HTMLScriptElement.supports("speculationrules"))return s(e),Promise.reject(new Error("This browser does not support the speculation rules API. Falling back to prefetch."));if(document.querySelector('script[type="speculationrules"]'))return Promise.reject(new Error("Speculation Rules is already defined and cannot be altered."));for(var t=0,o=[].concat(e);t0&&!u&&console.warn("[Warning] You are using both prefetching and prerendering on the same document");var l=function(e){var n=document.createElement("script");n.type="speculationrules",n.text='{"prerender":[{"source": "list","urls": ["'+Array.from(e).join('","')+'"]}]}';try{document.head.appendChild(n)}catch(e){return e}return!0}(c);return!0===l?Promise.resolve():Promise.reject(l)}e.listen=function(e){if(e||(e={}),window.IntersectionObserver){var n=function(e){e=e||1;var n=[],r=0;function t(){r0&&(n.shift()(),r++)}return[function(e){n.push(e)>1||t()},function(){r--,t()}]}(e.throttle||1/0),r=n[0],t=n[1],a=e.limit||1/0,l=e.origins||[location.hostname],d=e.ignores||[],h=e.delay||0,p=[],m=e.timeoutFn||o,w="function"==typeof e.hrefFn&&e.hrefFn,g=e.prerender||!1;u=e.prerenderAndPrefetch||!1;var v=new IntersectionObserver(function(n){n.forEach(function(n){if(n.isIntersecting)p.push((n=n.target).href),function(e,n){n?setTimeout(e,n):e()}(function(){-1!==p.indexOf(n.href)&&(v.unobserve(n),(u||g)&&c.size<1?f(w?w(n):n.href).catch(function(n){if(!e.onError)throw n;e.onError(n)}):i.size-1&&p.splice(o)}})},{threshold:e.threshold||0});return m(function(){(e.el||document).querySelectorAll("a").forEach(function(e){l.length&&!l.includes(e.hostname)||function e(n,r){return Array.isArray(r)?r.some(function(r){return e(n,r)}):(r.test||r).call(r,n.href,n)}(e,d)||v.observe(e)})},{timeout:e.timeout||2e3}),function(){i.clear(),v.disconnect()}}},e.prefetch=s,e.prerender=f}); diff --git a/public/sw.js b/public/sw.js new file mode 100644 index 0000000..7125899 --- /dev/null +++ b/public/sw.js @@ -0,0 +1,202 @@ +importScripts('https://cdn.staticfile.org/workbox-sw/5.1.4/workbox-sw.min.js'); + +workbox.setConfig({ + modulePathPrefix: 'https://cdn.staticfile.org/workbox-sw/5.1.4/' +}); + +const { core, precaching, routing, strategies, expiration, cacheableResponse, backgroundSync } = workbox; +const { CacheFirst, NetworkFirst, NetworkOnly, StaleWhileRevalidate } = strategies; +const { ExpirationPlugin } = expiration; +const { CacheableResponsePlugin } = cacheableResponse; + +const cacheSuffixVersion = '-231126a', + // precacheCacheName = core.cacheNames.precache, + // runtimeCacheName = core.cacheNames.runtime, + maxEntries = 100; + +self.addEventListener('activate', (event) => { + event.waitUntil( + caches.keys().then((keys) => { + return Promise.all(keys.map((key) => { + if (!key.includes(cacheSuffixVersion)) return caches.delete(key); + })); + }) + ); +}); + + +core.setCacheNameDetails({ + prefix: 'amaneintro', + suffix: cacheSuffixVersion +}); + +core.skipWaiting(); +core.clientsClaim(); +precaching.cleanupOutdatedCaches(); + +routing.registerRoute( + /.*xgjalbum\.oss-cn-hangzhou\.aliyuncs\.com/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + +routing.registerRoute( + /.*cdn\.staticfile\.org/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + +routing.registerRoute( + /.*cdn\.nofated\.win/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + +routing.registerRoute( + /.*cdn\.jsdelivr\.net/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + +routing.registerRoute( + /.*fonts\.googleapis\.cn/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + +routing.registerRoute( + /.*fonts\.gstatic\.cn/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + +routing.registerRoute( + new RegExp('analytics.google.com'), + new NetworkOnly({ + plugins: [ + new backgroundSync.BackgroundSyncPlugin('ga_new', { + maxRetentionTime: 12 * 60 + }), + ] + }), + "POST" +) + +const StaleWhileRevalidateInstance = new StaleWhileRevalidate(); +/* + * Others img + * Method: staleWhileRevalidate + * cacheName: img-cache + */ +routing.registerRoute( + // Cache image files + /.*\.(?:png|jpg|jpeg|gif|webp)/, + StaleWhileRevalidateInstance +); + +/* + * Static Assets + * Method: staleWhileRevalidate + * cacheName: static-assets-cache + */ +routing.registerRoute( + // Cache CSS files + /.*\.(css|js)/, + // Use cache but update in the background ASAP + StaleWhileRevalidateInstance +); + +/* + * sw.js - Revalidate every time + * staleWhileRevalidate + */ +routing.registerRoute( + '/sw.js', + StaleWhileRevalidateInstance +); + + + +routing.registerRoute( + new RegExp('moe'), + StaleWhileRevalidateInstance +); + +routing.registerRoute( + /.*localhost/, + new NetworkOnly() +); + +/* + * Default - Serve as it is + * StaleWhileRevalidate + */ +routing.setDefaultHandler( + new NetworkOnly() +); diff --git a/src/App.tsx b/src/App.tsx index 249c0ee..a9065ec 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -84,21 +84,21 @@ export default function App() { {/* */} - Nofated + Amane - + - + @@ -109,7 +109,7 @@ export default function App() { Yoo! - I'm Nofated, aka Tanikaze Amane. + I'm Amane, aka Nofated. @@ -117,7 +117,7 @@ export default function App() { Misc - 📒️ I have a blog based on Hexo.
+ 📒️ I have a blog based on Hexo.
⌨️ Coding and open-source are great! Let's contribute together!
🧪 I used to be an iGEMer. My team won a 🥈silver medal in iGEM Competition 2023!
@@ -144,13 +144,15 @@ export default function App() { About + + My full name is Tanikaze Amane, but you may here some one call me Nofated or nof. + I am in senior high and I'm preparing for the Chinese College Entrance Examination, aka GaoKao. I do open-source works, you can check them on GitHub. Most of them are useless and have lots of bugs. -