diff --git a/.tx/config b/.tx/config new file mode 100644 index 00000000..b3c29a25 --- /dev/null +++ b/.tx/config @@ -0,0 +1,10 @@ +[main] +host = https://www.transifex.com + +[penguin-statistics-website.main] +file_filter = src/locales/.json +minimum_perc = 0 +source_file = src/locales/zh.json +source_lang = zh +type = KEYVALUEJSON + diff --git a/build/serve.json b/build/serve.json index d5c9d01a..29375c3c 100644 --- a/build/serve.json +++ b/build/serve.json @@ -9,15 +9,6 @@ "value": "public, max-age=0, must-revalidate" } ] - }, - { - "source": "**", - "headers": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self'; script-src 'self' 'unsafe-inline' https://client.crisp.chat https://settings.crisp.chat https://www.google-analytics.com/; script-src-attr 'none'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://client.crisp.chat; img-src 'self' data: blob: https://penguin.upyun.galvincdn.com https://www.google-analytics.com https://stats.g.doubleclick.net https://image.crisp.chat https://client.crisp.chat; font-src 'self' https://fonts.gstatic.com https://fonts.gstatic.cn https://client.crisp.chat; connect-src 'self' https://penguin-stats.io https://penguin.upyun.galvincdn.com https://sentry.io https://client.crisp.chat wss://client.relay.crisp.chat https://storage.crisp.chat; prefetch-src 'self' https://penguin.upyun.galvincdn.com; upgrade-insecure-requests; block-all-mixed-content" - } - ] } ], "rewrites": [ diff --git a/now.json b/now.json index 6bec3d0e..e46ad3b9 100644 --- a/now.json +++ b/now.json @@ -10,15 +10,6 @@ "value": "public, max-age=0, must-revalidate" } ] - }, - { - "source": "(.*)", - "headers": [ - { - "key": "Content-Security-Policy", - "value": "default-src 'self'; script-src 'self' 'unsafe-inline' https://client.crisp.chat https://settings.crisp.chat https://www.google-analytics.com/; script-src-attr 'none'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://client.crisp.chat; img-src 'self' data: blob: https://penguin.upyun.galvincdn.com https://www.google-analytics.com https://stats.g.doubleclick.net https://image.crisp.chat https://client.crisp.chat; font-src 'self' https://fonts.gstatic.com https://fonts.gstatic.cn https://client.crisp.chat; connect-src 'self' https://penguin-stats.io https://penguin.upyun.galvincdn.com https://sentry.io https://client.crisp.chat wss://client.relay.crisp.chat https://storage.crisp.chat; prefetch-src 'self' https://penguin.upyun.galvincdn.com; upgrade-insecure-requests; block-all-mixed-content" - } - ] } ] } \ No newline at end of file diff --git a/package.json b/package.json index 496c9ed8..f954ebff 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,19 @@ { "name": "penguin-stats-frontend", - "version": "1.1.7", + "version": "1.1.8", "private": true, + "homepage": "https://github.com/penguin-statistics/frontend-v2#readme", + "bugs": { + "url": "https://github.com/penguin-statistics/frontend-v2/issues" + }, + "license" : "MIT", + "author": "All Contributors <*@*.*> (https://github.com/*)", + "contributors": [ + "AlvISs_Reimu (https://github.com/AlvISsReimu)", + "Galvin Gao (https://github.com/GalvinGao)", + "Asahi (https://github.com/AsahiLuna)", + "Blealtan (https://github.com/Blealtan)" + ], "scripts": { "serve": "vue-cli-service serve", "build": "npx --max_old_space_size=4096 vue-cli-service build --modern", diff --git a/public/index.html b/public/index.html index 4660766d..2441d747 100644 --- a/public/index.html +++ b/public/index.html @@ -4,10 +4,11 @@ - + 企鹅物流数据统计 + @@ -20,6 +21,21 @@ + + + + + + + + + + + + + + + diff --git a/src/App.vue b/src/App.vue index 37f4dd5d..6703d9f2 100644 --- a/src/App.vue +++ b/src/App.vue @@ -30,37 +30,14 @@ + -
- -
- - {{ $t('app.name_line1') }} - {{ $t('app.name_line2') }} - -
-
+ - + - + + @@ -89,9 +68,7 @@ {{ $t('menu.refreshData') }} - - - + @@ -102,7 +79,7 @@ :color="primaryColor" style="min-height: calc(56px + env(safe-area-inset-top)); padding-top: env(safe-area-inset-top)" :style="{'filter': isInSpecialUI ? 'grayscale(1)' : ''}" - class="x--safe-area toolbar--safe-area" + class="x--safe-area toolbar--safe-area flex-column" > !el.meta.hide); this.$store.dispatch("data/fetch", false); @@ -202,6 +177,6 @@ export default { async refreshData () { await this.$store.dispatch("data/fetch", true); }, - } + }, } diff --git a/src/apis/external.js b/src/apis/external.js new file mode 100644 index 00000000..1d7a54f4 --- /dev/null +++ b/src/apis/external.js @@ -0,0 +1,9 @@ +import service from '@/utils/service' + +export default { + geoip () { + return service.get("https://ipapi.co/json/", { + withCredentials: false + }) + } +} \ No newline at end of file diff --git a/src/apis/planner.js b/src/apis/planner.js index 4bde16de..ca5a3b7e 100644 --- a/src/apis/planner.js +++ b/src/apis/planner.js @@ -2,6 +2,8 @@ import service from '@/utils/service' export default { plan (data) { - return service.post("https://planner.penguin-stats.io/plan", data) + return service.post("https://planner.penguin-stats.io/plan", data, { + withCredentials: false + }) } } \ No newline at end of file diff --git a/src/assets/qrcodes/alipay-logo.svg b/src/assets/qrcodes/alipay-logo.svg new file mode 100644 index 00000000..95d3eb47 --- /dev/null +++ b/src/assets/qrcodes/alipay-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/qrcodes/alipay-qrcode.svg b/src/assets/qrcodes/alipay-qrcode.svg index 200ff90d..0c42a755 100644 --- a/src/assets/qrcodes/alipay-qrcode.svg +++ b/src/assets/qrcodes/alipay-qrcode.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/qrcodes/logos.svg b/src/assets/qrcodes/logos.svg new file mode 100644 index 00000000..5066c4d7 --- /dev/null +++ b/src/assets/qrcodes/logos.svg @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/src/assets/qrcodes/wechatpay-logo.svg b/src/assets/qrcodes/wechatpay-logo.svg new file mode 100644 index 00000000..deccceb7 --- /dev/null +++ b/src/assets/qrcodes/wechatpay-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/qrcodes/wechatpay-qrcode.svg b/src/assets/qrcodes/wechatpay-qrcode.svg index 613e9d95..57d92995 100644 --- a/src/assets/qrcodes/wechatpay-qrcode.svg +++ b/src/assets/qrcodes/wechatpay-qrcode.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/components/drawer/LocaleSwitcher.vue b/src/components/drawer/LocaleSwitcher.vue index 1cfb33aa..12517206 100644 --- a/src/components/drawer/LocaleSwitcher.vue +++ b/src/components/drawer/LocaleSwitcher.vue @@ -1,53 +1,33 @@ \ No newline at end of file diff --git a/src/views/Home.vue b/src/views/Home.vue index efed51a7..907b341b 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -141,7 +141,7 @@ export default { } } } catch (e) { - Console.error("HomeAnimation", "blank screen fix trial failed", e) + Console.info("HomeAnimation", "blank screen fix trial failed", e) } } }, 5000) diff --git a/src/registerServiceWorker.js b/src/workers/register.js similarity index 65% rename from src/registerServiceWorker.js rename to src/workers/register.js index 576ffb53..65f01d6f 100644 --- a/src/registerServiceWorker.js +++ b/src/workers/register.js @@ -1,13 +1,15 @@ /* eslint-disable no-console */ import { Workbox } from "workbox-window"; +import Console from "@/utils/Console"; let workbox; if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) { workbox = new Workbox(`${process.env.BASE_URL}service-worker.js`); - workbox.addEventListener("controlling", () => { + workbox.addEventListener("controlling", (event) => { + Console.info("SWRegister", "a service worker has taken control (controlling): ", event); window.location.reload(); }); diff --git a/src/workers/service-worker.js b/src/workers/service-worker.js new file mode 100644 index 00000000..5182e6a6 --- /dev/null +++ b/src/workers/service-worker.js @@ -0,0 +1,110 @@ +/* eslint-env serviceworker */ + +import { registerRoute } from 'workbox-routing'; +import { precacheAndRoute, cleanupOutdatedCaches } from 'workbox-precaching'; +import { CacheFirst } from 'workbox-strategies' +import { ExpirationPlugin } from 'workbox-expiration' +import { CacheableResponsePlugin } from 'workbox-cacheable-response' + +self.addEventListener('activate', () => self.clients.claim()); + +self.addEventListener('message', (event) => { + if (event.data && event.data.type === 'SKIP_WAITING') { + skipWaiting(); + } +}); + +cleanupOutdatedCaches(); + +// === Google Fonts === + +// registerRoute( +// /^https:\/\/fonts\.googleapis\.com/, +// new StaleWhileRevalidate({ +// cacheName: 'google-fonts-stylesheets', +// }) +// ); + +// Cache the underlying font files with a cache-first strategy for 1 year. +registerRoute( + /^https:\/\/fonts\.gstatic\.com/, + new CacheFirst({ + cacheName: 'google-fonts-webfonts', + plugins: [ + new CacheableResponsePlugin({ + statuses: [0, 200], + }), + new ExpirationPlugin({ + maxAgeSeconds: 60 * 60 * 24 * 365, + maxEntries: 30, + }), + ], + }) +); + +// === CDN Resources === + +// fancy backgrounds +registerRoute( + /^https:\/\/penguin\.upyun\.galvincdn\.com\/backgrounds\//, + new CacheFirst({ + cacheName: "penguin-backgrounds", + // plugins: [ + // new ExpirationPlugin({ + // // maxEntries: 30, + // purgeOnQuotaError: true + // }) + // ] + }) +) + +// other images +registerRoute( + /^https:\/\/penguin\.upyun\.galvincdn\.com\/(logos|avatars)\//, + new CacheFirst({ + cacheName: "penguin-images" + }) +) + +// === Site Resources === + +// // files that are versioned. safe to cache. +// registerRoute( +// /.[a-f0-9]{8}.(css|js|woff2|ttf|woff|eof|svg|png)/, +// new CacheFirst({ +// cacheName: "penguin-site-resources" +// }) +// ) + +// if the network failed, use the cache instead; otherwise use the +// fresh data coming from the api +// registerRoute( +// /^https:\/\/penguin-stats\.io\/PenguinStats\//, +// new NetworkFirst({ +// cacheName: "penguin-api-responses", +// // plugins: [ +// // new ExpirationPlugin({ +// // maxAgeSeconds: 60 * 60 * 24, +// // maxEntries: 10 +// // }), +// // ] +// }) +// ) + +// precache the item sprite file +// registerRoute( +// "https://penguin.upyun.galvincdn.com/item_sprite.png", +// new StaleWhileRevalidate({ +// cacheName: "penguin-sprite", +// plugins: [ +// new ExpirationPlugin({ +// maxAgeSeconds: 60 * 60 * 24, +// maxEntries: 3 +// }), +// ] +// }) +// ) + +// eslint-disable-next-line no-unused-vars +const manifest = self.__WB_MANIFEST; +precacheAndRoute(manifest) diff --git a/vue.config.js b/vue.config.js index 2618e200..ca34b2c8 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,5 +1,5 @@ const webpack = require("webpack"); -const { GenerateSW } = require("workbox-webpack-plugin"); +const { InjectManifest } = require("workbox-webpack-plugin"); let commitHash; @@ -29,31 +29,6 @@ module.exports = { }, integrity: true, runtimeCompiler: true, - // pwa: { - // name: "企鹅物流数据统计", - // themeColor: "#2d66ba", - // msTileColor: "#1d499b", - // appleMobileWebAppCapable: "yes", - // appleMobileWebAppStatusBarStyle: "black-translucent", - // - // workboxPluginMode: "InjectManifest", - // workboxOptions: { - // swSrc: "src/serviceWorker/service-worker.js", - // exclude: [ - // /\.map$/, - // /favicon\.ico$/, - // /manifest\.json$/, - // /precache-manifest.\.json$/, - // ] - // }, - // iconPaths: { - // favicon32: 'favicon/favicon-32x32.png', - // favicon16: 'favicon/favicon-16x16.png', - // appleTouchIcon: 'favicon/apple-touch-icon.png', - // maskIcon: 'favicon/safari-pinned-tab.svg', - // msTileImage: 'favicon/mstile-150x150.png' - // } - // }, transpileDependencies: [ "vuetify" ], @@ -62,7 +37,10 @@ module.exports = { new webpack.DefinePlugin({ GIT_COMMIT: JSON.stringify(commitHash).trim() }), - new GenerateSW() + new InjectManifest ({ + swSrc: "./src/workers/service-worker.js", + dontCacheBustURLsMatching: /.[a-f0-9]{8}./ + }) ], }, chainWebpack: config => {