added icon
All checks were successful
/ depoly (push) Successful in 1m20s

This commit is contained in:
thislight 2024-10-22 17:48:17 +08:00
parent 29b8b5307e
commit 7eb55e2a14
No known key found for this signature in database
GPG key ID: A50F9451AC56A63E
9 changed files with 204 additions and 18 deletions

BIN
bun.lockb

Binary file not shown.

26
docs/optimizing.md Normal file
View file

@ -0,0 +1,26 @@
# Optimizing Tutu
Topic Index:
- Time to first byte
- Time to first draw: [Load size](#load-size)
- CLS
- Framerate: [Algorithm](#algorithm)
## Load size
The baseline for the load size is lowest 3G download bandwidth in 2s, typically 1.1Mbps (or ~137 kilobytes/s) * 2s = 274 kilobytes.
In another words there is 274 kilobytes budget for an interaction without further notice. Notice and progress are needed if the interaction needs than that.
The service worker can use 1 chunk of size.
## Algorithm
Don't choose algorithm solely on the time complexity. GUI app needs smooth, not fast. The priority:
- On the main thread: batching. Batching is usually required to spread the work to multiple frames.
- Think in Map-Reduce framework if you don't have any idea.
- On the worker thread: balance the speed and the memory usage.
- Arrays are usually faster and use less memory.
- Worker is always available on our target platforms, but workers introduce latency in the starting and the communication.

10
manifest.config.ts Normal file
View file

@ -0,0 +1,10 @@
import { ManifestOptions } from "vite-plugin-pwa";
const manifest: Partial<ManifestOptions> = {
name: "Tutu for Mastodon",
short_name: "Tutu",
description: "Tutu is an app to read, post, dog and cat on the mastodon.",
theme_color: "#673ab7"
};
export default manifest;

View file

@ -14,40 +14,41 @@
"author": "Rubicon",
"license": "Apache-2.0",
"devDependencies": {
"@suid/vite-plugin": "^0.3.0",
"@types/hammerjs": "^2.0.45",
"postcss": "^8.4.45",
"@suid/vite-plugin": "^0.3.1",
"@types/hammerjs": "^2.0.46",
"@vite-pwa/assets-generator": "^0.2.6",
"postcss": "^8.4.47",
"prettier": "^3.3.3",
"typescript": "^5.6.2",
"vite": "^5.4.5",
"typescript": "^5.6.3",
"vite": "^5.4.9",
"vite-plugin-package-version": "^1.1.0",
"vite-plugin-pwa": "^0.20.5",
"vite-plugin-solid": "^2.10.2",
"vite-plugin-solid-styled": "^0.11.1",
"workbox-build": "^7.1.1",
"wrangler": "^3.78.2"
"wrangler": "^3.81.0"
},
"dependencies": {
"@formatjs/intl-localematcher": "^0.5.4",
"@formatjs/intl-localematcher": "^0.5.5",
"@nanostores/persistent": "^0.10.2",
"@nanostores/solid": "^0.4.2",
"@nanostores/solid": "^0.5.0",
"@solid-primitives/event-listener": "^2.3.3",
"@solid-primitives/i18n": "^2.1.1",
"@solid-primitives/intersection-observer": "^2.1.6",
"@solid-primitives/map": "^0.4.13",
"@solid-primitives/resize-observer": "^2.0.26",
"@solidjs/router": "^0.14.5",
"@suid/icons-material": "^0.8.0",
"@suid/material": "^0.17.0",
"@solidjs/router": "^0.14.10",
"@suid/icons-material": "^0.8.1",
"@suid/material": "^0.18.0",
"blurhash": "^2.0.5",
"colorjs.io": "^0.5.2",
"date-fns": "^3.6.0",
"date-fns": "^4.1.0",
"fast-average-color": "^9.4.0",
"hammerjs": "^2.0.8",
"iso-639-1": "^3.1.3",
"masto": "^6.8.0",
"masto": "^6.10.0",
"nanostores": "^0.11.3",
"solid-js": "^1.8.22",
"solid-js": "^1.9.2",
"solid-styled": "^0.11.1",
"stacktrace-js": "^2.0.2",
"web-animations-js": "^2.3.2",

133
public/logo.svg Normal file
View file

@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="512"
height="512"
viewBox="0 0 512 512"
version="1.1"
id="svg1"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<title
id="title6">Tutu's Icon</title>
<defs
id="defs1">
<linearGradient
id="linearGradient4">
<stop
style="stop-color:#fac8a3;stop-opacity:1;"
offset="0"
id="stop4" />
<stop
style="stop-color:#fac8a3;stop-opacity:1;"
offset="0.72011906"
id="stop6" />
<stop
style="stop-color:#f48d8a;stop-opacity:1;"
offset="1"
id="stop5" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient4"
id="linearGradient5"
x1="244.74585"
y1="430.05423"
x2="281.31232"
y2="82.147469"
gradientUnits="userSpaceOnUse" />
<linearGradient
xlink:href="#linearGradient4"
id="linearGradient9"
gradientUnits="userSpaceOnUse"
x1="244.74585"
y1="430.05423"
x2="281.31232"
y2="82.147469" />
</defs>
<g
id="layer1"
transform="matrix(0,1.4786237,-1.4786237,0,642.78291,-98.6117)"
style="display:none">
<path
style="fill:url(#linearGradient5);stroke:#000000;stroke-width:2;stroke-dasharray:none"
d="m 142.83262,404.32618 c 82.40343,-32.96137 141.81198,28.9112 141.81198,28.9112 0,0 21.1442,-23.1068 65.90935,-81.91599 51.82799,-68.08783 41.673,-112.8227 41.673,-112.8227 0,0 2.09565,-72.92272 -51.48333,-125.1428 C 299.2268,72.892041 192.11851,96.043081 192.11851,96.043081 c 0,0 -84.44469,24.815289 -100.925375,105.021299 -16.480686,80.20601 51.639485,203.2618 51.639485,203.2618 z"
id="path2" />
<g
id="g6"
style="stroke-width:2;stroke-dasharray:none">
<path
style="fill:none;stroke:#000000;stroke-width:2.3;stroke-dasharray:none"
d="m 210.50439,396.31338 c 0,0 -29.4511,-105.3688 -28.96641,-141.50635 0.34942,-26.05202 -0.47344,-34.47943 3.80644,-54.3634 5.96795,-27.72652 12.70659,-35.21402 12.70659,-35.21402"
id="path3" />
<path
style="fill:none;stroke:#000000;stroke-width:1.8;stroke-dasharray:none"
d="m 185.10879,292.14608 c 2.88624,-0.57725 6.83376,-30.94178 44.70393,-42.39467"
id="path4" />
</g>
</g>
<g
id="g9"
transform="matrix(0,1.5553086,-1.5553086,0,668.42415,-94.877994)">
<path
style="fill:url(#linearGradient9);stroke:#000000;stroke-width:2;stroke-dasharray:none"
d="m 117.92992,367.86152 c 25.48298,38.39529 93.78536,33.94838 93.78536,33.94838 0,0 58.98001,-7.82594 105.93153,-57.60357 51.75,-54.86494 41.67301,-98.59259 41.67301,-98.59259 0,0 0.85581,-49.23349 -57.70901,-95.79319 -44.18497,-35.12756 -115.71798,-13.75528 -115.71798,-13.75528 0,0 -87.11283,22.14714 -94.699695,109.46821 -7.087568,81.5744 26.736785,122.32804 26.736785,122.32804 z"
id="path6" />
<g
id="g8"
style="stroke-width:2;stroke-dasharray:none"
transform="translate(-1.7787639,5.3362916)">
<path
style="fill:none;stroke:#000000;stroke-width:2.3;stroke-dasharray:none"
d="m 210.50439,396.31338 c 0,0 -29.4511,-105.3688 -28.96641,-141.50635 0.34942,-26.05202 -0.47344,-34.47943 3.80644,-54.3634 5.96795,-27.72652 12.70659,-35.21402 12.70659,-35.21402"
id="path7" />
<path
style="fill:none;stroke:#000000;stroke-width:1.8;stroke-dasharray:none"
d="m 185.10879,292.14608 c 2.88624,-0.57725 6.83376,-30.94178 44.70393,-42.39467"
id="path8" />
</g>
</g>
<metadata
id="metadata6">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:title>Tutu's Icon</dc:title>
<dc:date>2024/10/22</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>Rubicon</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>Rubicon</dc:title>
</cc:Agent>
</dc:rights>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-nc-sa/4.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-nc-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:prohibits
rdf:resource="http://creativecommons.org/ns#CommercialUse" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

2
public/robots.txt Normal file
View file

@ -0,0 +1,2 @@
User-agent: *
Allow: /

12
pwa-assets.config.ts Normal file
View file

@ -0,0 +1,12 @@
import {
defineConfig,
minimal2023Preset as preset
} from '@vite-pwa/assets-generator/config'
export default defineConfig({
headLinkOptions: {
preset: '2023'
},
preset,
images: ['public/logo.svg']
})

View file

@ -78,7 +78,7 @@ async function importDateFnLocale(tag: string): Promise<Locale> {
case "en_us":
return (await import("date-fns/locale/en-US")).enUS;
case "en_gb":
return (await import("date-fns/locale/en-GB")).enGB;
return enGB;
case "zh_cn":
return (await import("date-fns/locale/zh-CN")).zhCN;
default:

View file

@ -4,6 +4,7 @@ import solidStyled from "vite-plugin-solid-styled";
import suid from "@suid/vite-plugin";
import { VitePWA } from "vite-plugin-pwa";
import version from "vite-plugin-package-version";
import manifest from "./manifest.config";
export default defineConfig(({ mode }) => ({
plugins: [
@ -23,9 +24,10 @@ export default defineConfig(({ mode }) => ({
},
srcDir: "src/serviceworker",
filename: "main.ts",
manifest: {
theme_color: "#673ab7"
}
manifest: manifest,
pwaAssets: {
config: true,
},
}),
version(),
],