Merge pull request 'brand: Ratatoskr replaces Cinny branding (do not merge)' (#11) from void/brand into main

This commit is contained in:
Void 2026-11-05 10:51:59 +00:00
commit 14d9fa6246
40 changed files with 312 additions and 117 deletions

View file

@ -4,21 +4,17 @@
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<title>Cinny</title>
<meta name="name" content="Cinny" />
<meta name="author" content="Ajay Bura" />
<title>Ratatoskr</title>
<meta name="name" content="Ratatoskr" />
<meta name="author" content="GameCult" />
<meta
name="description"
content="A Matrix client where you can enjoy the conversation using simple, elegant and secure interface protected by e2ee with the power of open source."
/>
<meta
name="keywords"
content="cinny, cinnyapp, cinnychat, matrix, matrix client, matrix.org, element"
/>
<meta name="keywords" content="ratatoskr, gamecult, matrix, matrix client, matrix.org" />
<meta property="og:title" content="Cinny" />
<meta property="og:url" content="https://cinny.in" />
<meta property="og:image" content="https://cinny.in/assets/favicon-48x48.png" />
<meta property="og:title" content="Ratatoskr" />
<meta property="og:url" content="https://gamecult.org" />
<meta
property="og:description"
content="A Matrix client where you can enjoy the conversation using simple, elegant and secure interface protected by e2ee with the power of open source."
@ -29,8 +25,8 @@
<link rel="manifest" href="/manifest.json" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="application-name" content="Cinny" />
<meta name="apple-mobile-web-app-title" content="Cinny" />
<meta name="application-name" content="Ratatoskr" />
<meta name="apple-mobile-web-app-title" content="Ratatoskr" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before After
Before After

View file

@ -1,7 +1,7 @@
{
"name": "Cinny",
"short_name": "Cinny",
"description": "Yet another matrix client",
"name": "Ratatoskr",
"short_name": "Ratatoskr",
"description": "GameCult's Matrix client",
"dir": "auto",
"lang": "en-US",
"display": "standalone",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 817 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before After
Before After

View file

@ -1,13 +0,0 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2707_1961)">
<path d="M10.5867 17.3522C10.0727 17.4492 9.54226 17.5 9 17.5C4.30558 17.5 0.5 13.6944 0.5 9C0.5 4.30558 4.30558 0.5 9 0.5C13.6944 0.5 17.5 4.30558 17.5 9C17.5 9.54226 17.4492 10.0727 17.3522 10.5867C16.6511 10.2123 15.8503 10 15 10C12.2386 10 10 12.2386 10 15C10 15.8503 10.2123 16.6511 10.5867 17.3522Z" fill="white"/>
<path d="M10 6.39999C10 6.67614 9.77614 6.89999 9.5 6.89999C9.22386 6.89999 9 6.67614 9 6.39999C9 6.12385 9.22386 5.89999 9.5 5.89999C9.77614 5.89999 10 6.12385 10 6.39999Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 0C4 0 0 4 0 9C0 14 4 18 9 18C9.63967 18 10.263 17.9345 10.8636 17.8099C10.3186 17.0091 10 16.0417 10 15C10 12.2386 12.2386 10 15 10C16.0417 10 17.0091 10.3186 17.8099 10.8636C17.9345 10.263 18 9.63967 18 9C18 4 14 0 9 0ZM1.2 10.8L4.7 8.5V8.2C4.7 6.4 6 5 7.8 4.8H8.2C9.4 4.8 10.5 5.4 11.1 6.4C11.4 6.3 11.7 6.3 12 6.3C12.4 6.3 12.8 6.3 13.2 6.4C13.9 6.6 14.6 6.9 15.2 7.3C14.6 7.1 14 7 13.3 7C12.1 7 11.1 7.4 10.4 8.4C9.7 9.3 9.3 10.4 9.3 11.6C9.3 13.1 8.9 14.5 8 15.8C7.93744 15.8834 7.87923 15.9625 7.82356 16.0381C7.6123 16.325 7.43739 16.5626 7.2 16.8C4.2 16.1 1.9 13.8 1.2 10.8Z" fill="black"/>
<path d="M18 15C18 16.6569 16.6569 18 15 18C13.3431 18 12 16.6569 12 15C12 13.3431 13.3431 12 15 12C16.6569 12 18 13.3431 18 15Z" fill="#45B83B"/>
</g>
<defs>
<clipPath id="clip0_2707_1961">
<rect width="18" height="18" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,13 +0,0 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2707_2015)">
<path d="M10.5867 17.3522C10.0727 17.4492 9.54226 17.5 9 17.5C4.30558 17.5 0.5 13.6944 0.5 9C0.5 4.30558 4.30558 0.5 9 0.5C13.6944 0.5 17.5 4.30558 17.5 9C17.5 9.54226 17.4492 10.0727 17.3522 10.5867C16.6511 10.2123 15.8503 10 15 10C12.2386 10 10 12.2386 10 15C10 15.8503 10.2123 16.6511 10.5867 17.3522Z" fill="white"/>
<path d="M10 6.39999C10 6.67614 9.77614 6.89999 9.5 6.89999C9.22386 6.89999 9 6.67614 9 6.39999C9 6.12385 9.22386 5.89999 9.5 5.89999C9.77614 5.89999 10 6.12385 10 6.39999Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 0C4 0 0 4 0 9C0 14 4 18 9 18C9.63967 18 10.263 17.9345 10.8636 17.8099C10.3186 17.0091 10 16.0417 10 15C10 12.2386 12.2386 10 15 10C16.0417 10 17.0091 10.3186 17.8099 10.8636C17.9345 10.263 18 9.63967 18 9C18 4 14 0 9 0ZM1.2 10.8L4.7 8.5V8.2C4.7 6.4 6 5 7.8 4.8H8.2C9.4 4.8 10.5 5.4 11.1 6.4C11.4 6.3 11.7 6.3 12 6.3C12.4 6.3 12.8 6.3 13.2 6.4C13.9 6.6 14.6 6.9 15.2 7.3C14.6 7.1 14 7 13.3 7C12.1 7 11.1 7.4 10.4 8.4C9.7 9.3 9.3 10.4 9.3 11.6C9.3 13.1 8.9 14.5 8 15.8C7.93744 15.8834 7.87923 15.9625 7.82356 16.0381C7.6123 16.325 7.43739 16.5626 7.2 16.8C4.2 16.1 1.9 13.8 1.2 10.8Z" fill="black"/>
<path d="M18 15C18 16.6569 16.6569 18 15 18C13.3431 18 12 16.6569 12 15C12 13.3431 13.3431 12 15 12C16.6569 12 18 13.3431 18 15Z" fill="#989898"/>
</g>
<defs>
<clipPath id="clip0_2707_2015">
<rect width="18" height="18" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,19 +0,0 @@
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In -->
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
x="0px" y="0px" width="18px" height="18px" viewBox="0 0 18 18" enable-background="new 0 0 18 18" xml:space="preserve">
<defs>
</defs>
<g>
<g>
<circle fill="#FFFFFF" cx="9" cy="9" r="8.5"/>
</g>
<g>
<path d="M9,0C4,0,0,4,0,9c0,5,4,9,9,9c5,0,9-4,9-9C18,4,14,0,9,0z M1.2,10.8l3.5-2.3c0-0.1,0-0.2,0-0.3c0-1.8,1.3-3.2,3.1-3.4
c0.1,0,0.2,0,0.4,0c1.2,0,2.3,0.6,2.9,1.6c0.3-0.1,0.6-0.1,0.9-0.1c0.4,0,0.8,0,1.2,0.1c0.7,0.2,1.4,0.5,2,0.9
C14.6,7.1,14,7,13.3,7c-1.2,0-2.2,0.4-2.9,1.4c-0.7,0.9-1.1,2-1.1,3.2c0,1.5-0.4,2.9-1.3,4.2c-0.3,0.4-0.5,0.7-0.8,1
C4.2,16.1,1.9,13.8,1.2,10.8z"/>
<circle cx="9.5" cy="6.4" r="0.5"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 871 B

View file

@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
<ellipse cx="19" cy="33" rx="13" ry="22" transform="rotate(-15 19 33)" fill="#d9742b"/>
<ellipse cx="21" cy="33" rx="7" ry="15" transform="rotate(-15 21 33)" fill="#f0a45d"/>
<ellipse cx="36" cy="43" rx="11" ry="14" transform="rotate(0 36 43)" fill="#e0833a"/>
<ellipse cx="40" cy="46" rx="6" ry="9" transform="rotate(0 40 46)" fill="#f6dcb8"/>
<polygon points="35,19 36,7 43,15" fill="#c9672a"/>
<polygon points="44,15 50,7 52,19" fill="#c9672a"/>
<circle cx="43" cy="25" r="10" fill="#e0833a"/>
<ellipse cx="47" cy="29" rx="5" ry="3.5" transform="rotate(0 47 29)" fill="#f6dcb8"/>
<circle cx="46.5" cy="23.5" r="1.8" fill="#1a1a1a"/>
<circle cx="47" cy="23" r="0.6" fill="#ffffff"/>
<circle cx="52" cy="27.5" r="1.5" fill="#1a1a1a"/>
<ellipse cx="33" cy="56" rx="5" ry="2.5" transform="rotate(0 33 56)" fill="#c9672a"/>
<ellipse cx="44" cy="56" rx="4.5" ry="2.5" transform="rotate(0 44 56)" fill="#c9672a"/>
<circle cx="52" cy="52" r="11" fill="#ffffff"/>
<circle cx="52" cy="52" r="8" fill="#45B83B"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
<ellipse cx="19" cy="33" rx="13" ry="22" transform="rotate(-15 19 33)" fill="#d9742b"/>
<ellipse cx="21" cy="33" rx="7" ry="15" transform="rotate(-15 21 33)" fill="#f0a45d"/>
<ellipse cx="36" cy="43" rx="11" ry="14" transform="rotate(0 36 43)" fill="#e0833a"/>
<ellipse cx="40" cy="46" rx="6" ry="9" transform="rotate(0 40 46)" fill="#f6dcb8"/>
<polygon points="35,19 36,7 43,15" fill="#c9672a"/>
<polygon points="44,15 50,7 52,19" fill="#c9672a"/>
<circle cx="43" cy="25" r="10" fill="#e0833a"/>
<ellipse cx="47" cy="29" rx="5" ry="3.5" transform="rotate(0 47 29)" fill="#f6dcb8"/>
<circle cx="46.5" cy="23.5" r="1.8" fill="#1a1a1a"/>
<circle cx="47" cy="23" r="0.6" fill="#ffffff"/>
<circle cx="52" cy="27.5" r="1.5" fill="#1a1a1a"/>
<ellipse cx="33" cy="56" rx="5" ry="2.5" transform="rotate(0 33 56)" fill="#c9672a"/>
<ellipse cx="44" cy="56" rx="4.5" ry="2.5" transform="rotate(0 44 56)" fill="#c9672a"/>
<circle cx="52" cy="52" r="11" fill="#ffffff"/>
<circle cx="52" cy="52" r="8" fill="#989898"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
<ellipse cx="19" cy="33" rx="13" ry="22" transform="rotate(-15 19 33)" fill="#d9742b"/>
<ellipse cx="21" cy="33" rx="7" ry="15" transform="rotate(-15 21 33)" fill="#f0a45d"/>
<ellipse cx="36" cy="43" rx="11" ry="14" transform="rotate(0 36 43)" fill="#e0833a"/>
<ellipse cx="40" cy="46" rx="6" ry="9" transform="rotate(0 40 46)" fill="#f6dcb8"/>
<polygon points="35,19 36,7 43,15" fill="#c9672a"/>
<polygon points="44,15 50,7 52,19" fill="#c9672a"/>
<circle cx="43" cy="25" r="10" fill="#e0833a"/>
<ellipse cx="47" cy="29" rx="5" ry="3.5" transform="rotate(0 47 29)" fill="#f6dcb8"/>
<circle cx="46.5" cy="23.5" r="1.8" fill="#1a1a1a"/>
<circle cx="47" cy="23" r="0.6" fill="#ffffff"/>
<circle cx="52" cy="27.5" r="1.5" fill="#1a1a1a"/>
<ellipse cx="33" cy="56" rx="5" ry="2.5" transform="rotate(0 33 56)" fill="#c9672a"/>
<ellipse cx="44" cy="56" rx="4.5" ry="2.5" transform="rotate(0 44 56)" fill="#c9672a"/>
</svg>

After

Width:  |  Height:  |  Size: 1,001 B

202
scripts/gen-brand.mjs Normal file
View file

@ -0,0 +1,202 @@
// Draws the Ratatoskr squirrel once, as shapes, and writes the SVG logos plus the
// favicon and app-icon PNGs from the same shapes (no image tools needed).
// Run: node scripts/gen-brand.mjs
import { deflateSync } from 'node:zlib';
import { mkdirSync, writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
const root = join(dirname(fileURLToPath(import.meta.url)), '..');
const BG = '#1c1b22';
// Squirrel facing right on a 64x64 grid. Later shapes draw over earlier ones.
const squirrel = [
{ t: 'ellipse', cx: 19, cy: 33, rx: 13, ry: 22, rot: -15, fill: '#d9742b' },
{ t: 'ellipse', cx: 21, cy: 33, rx: 7, ry: 15, rot: -15, fill: '#f0a45d' },
{ t: 'ellipse', cx: 36, cy: 43, rx: 11, ry: 14, rot: 0, fill: '#e0833a' },
{ t: 'ellipse', cx: 40, cy: 46, rx: 6, ry: 9, rot: 0, fill: '#f6dcb8' },
{
t: 'poly',
pts: [
[35, 19],
[36, 7],
[43, 15],
],
fill: '#c9672a',
},
{
t: 'poly',
pts: [
[44, 15],
[50, 7],
[52, 19],
],
fill: '#c9672a',
},
{ t: 'circle', cx: 43, cy: 25, r: 10, fill: '#e0833a' },
{ t: 'ellipse', cx: 47, cy: 29, rx: 5, ry: 3.5, rot: 0, fill: '#f6dcb8' },
{ t: 'circle', cx: 46.5, cy: 23.5, r: 1.8, fill: '#1a1a1a' },
{ t: 'circle', cx: 47, cy: 23, r: 0.6, fill: '#ffffff' },
{ t: 'circle', cx: 52, cy: 27.5, r: 1.5, fill: '#1a1a1a' },
{ t: 'ellipse', cx: 33, cy: 56, rx: 5, ry: 2.5, rot: 0, fill: '#c9672a' },
{ t: 'ellipse', cx: 44, cy: 56, rx: 4.5, ry: 2.5, rot: 0, fill: '#c9672a' },
];
const badge = (fill) => [
{ t: 'circle', cx: 52, cy: 52, r: 11, fill: '#ffffff' },
{ t: 'circle', cx: 52, cy: 52, r: 8, fill },
];
const background = [{ t: 'rect', x: 0, y: 0, w: 64, h: 64, fill: BG }];
const f = (n) => +n.toFixed(2);
const svgOf = (shapes) =>
shapes
.map((s) => {
if (s.t === 'circle')
return `<circle cx="${s.cx}" cy="${s.cy}" r="${s.r}" fill="${s.fill}"/>`;
if (s.t === 'rect') return `<rect width="${s.w}" height="${s.h}" fill="${s.fill}"/>`;
if (s.t === 'poly')
return `<polygon points="${s.pts.map((p) => p.join(',')).join(' ')}" fill="${s.fill}"/>`;
return `<ellipse cx="${s.cx}" cy="${s.cy}" rx="${s.rx}" ry="${s.ry}" transform="rotate(${s.rot} ${s.cx} ${s.cy})" fill="${s.fill}"/>`;
})
.join('\n');
const writeSvg = (name, shapes) =>
writeFileSync(
join(root, 'public/res/svg', name),
`<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">\n${svgOf(
shapes
)}\n</svg>\n`
);
const hex = (h) => [1, 3, 5].map((i) => parseInt(h.slice(i, i + 2), 16));
const inside = (s, x, y) => {
if (s.t === 'rect') return x >= s.x && x < s.x + s.w && y >= s.y && y < s.y + s.h;
if (s.t === 'circle') return (x - s.cx) ** 2 + (y - s.cy) ** 2 <= s.r ** 2;
if (s.t === 'ellipse') {
const a = (-s.rot * Math.PI) / 180;
const dx = x - s.cx;
const dy = y - s.cy;
const u = dx * Math.cos(a) - dy * Math.sin(a);
const v = dx * Math.sin(a) + dy * Math.cos(a);
return (u / s.rx) ** 2 + (v / s.ry) ** 2 <= 1;
}
let c = false;
for (let i = 0, j = s.pts.length - 1; i < s.pts.length; j = i++) {
const [xi, yi] = s.pts[i];
const [xj, yj] = s.pts[j];
if (yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi) c = !c;
}
return c;
};
const crcTable = Array.from({ length: 256 }, (_, n) => {
let c = n;
for (let k = 0; k < 8; k += 1) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
return c >>> 0;
});
const crc = (b) => {
let c = 0xffffffff;
for (const x of b) c = crcTable[(c ^ x) & 255] ^ (c >>> 8);
return (c ^ 0xffffffff) >>> 0;
};
const chunk = (type, data) => {
const out = Buffer.alloc(12 + data.length);
out.writeUInt32BE(data.length, 0);
out.write(type, 4, 'ascii');
data.copy(out, 8);
out.writeUInt32BE(crc(out.subarray(4, 8 + data.length)), 8 + data.length);
return out;
};
// Rasterise with 4x4 supersampling; `scale` shrinks the drawing about the centre.
const png = (shapes, size, scale = 1) => {
const rgba = Buffer.alloc(size * size * 4);
const SS = 4;
const colours = shapes.map((s) => hex(s.fill));
for (let py = 0; py < size; py += 1) {
for (let px = 0; px < size; px += 1) {
let r = 0;
let g = 0;
let b = 0;
let a = 0;
for (let sy = 0; sy < SS; sy += 1) {
for (let sx = 0; sx < SS; sx += 1) {
const gx = ((px + (sx + 0.5) / SS) / size) * 64;
const gy = ((py + (sy + 0.5) / SS) / size) * 64;
// the background rect covers the whole canvas and ignores `scale`
let hit = -1;
shapes.forEach((s, i) => {
const x = s.t === 'rect' ? gx : (gx - 32) / scale + 32;
const y = s.t === 'rect' ? gy : (gy - 32) / scale + 32;
if (inside(s, x, y)) hit = i;
});
if (hit >= 0) {
[r, g, b] = [r + colours[hit][0], g + colours[hit][1], b + colours[hit][2]];
a += 1;
}
}
}
const o = (py * size + px) * 4;
if (a > 0) {
rgba[o] = Math.round(r / a);
rgba[o + 1] = Math.round(g / a);
rgba[o + 2] = Math.round(b / a);
}
rgba[o + 3] = Math.round((a / (SS * SS)) * 255);
}
}
const raw = Buffer.alloc(size * (size * 4 + 1));
for (let y = 0; y < size; y += 1) {
raw[y * (size * 4 + 1)] = 0;
rgba.copy(raw, y * (size * 4 + 1) + 1, y * size * 4, (y + 1) * size * 4);
}
const ihdr = Buffer.alloc(13);
ihdr.writeUInt32BE(size, 0);
ihdr.writeUInt32BE(size, 4);
ihdr.set([8, 6, 0, 0, 0], 8);
return Buffer.concat([
Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]),
chunk('IHDR', ihdr),
chunk('IDAT', deflateSync(raw)),
chunk('IEND', Buffer.alloc(0)),
]);
};
// ICO container holding PNG images.
const ico = (images) => {
const head = Buffer.alloc(6 + images.length * 16);
head.writeUInt16LE(1, 2);
head.writeUInt16LE(images.length, 4);
let offset = head.length;
images.forEach(({ size, data }, i) => {
const e = 6 + i * 16;
head[e] = size;
head[e + 1] = size;
head.writeUInt16LE(1, e + 4);
head.writeUInt16LE(32, e + 6);
head.writeUInt32LE(data.length, e + 8);
head.writeUInt32LE(offset, e + 12);
offset += data.length;
});
return Buffer.concat([head, ...images.map((i) => i.data)]);
};
writeSvg('ratatoskr.svg', squirrel);
writeSvg('ratatoskr-unread.svg', [...squirrel, ...badge('#989898')]);
writeSvg('ratatoskr-highlight.svg', [...squirrel, ...badge('#45B83B')]);
const icon = [...background, ...squirrel];
const put = (dir, name, size) => {
mkdirSync(join(root, 'public/res', dir), { recursive: true });
writeFileSync(join(root, 'public/res', dir, name), png(icon, size, 0.82));
};
[36, 48, 72, 96, 144, 192, 256, 384, 512].forEach((s) =>
put('android', `android-chrome-${s}x${s}.png`, s)
);
[57, 60, 72, 76, 114, 120, 144, 152, 167, 180].forEach((s) =>
put('apple', `apple-touch-icon-${s}x${s}.png`, s)
);
writeFileSync(
join(root, 'public/favicon.ico'),
ico([16, 32, 48].map((size) => ({ size, data: png(icon, size, 0.9) })))
);
console.log('wrote svg logos, favicon.ico, android and apple icons');

View file

@ -21,7 +21,7 @@ export function SplashScreen({ children }: SplashScreenProps) {
justifyContent="Center"
>
<Text size="H2" align="Center">
Cinny
Ratatoskr
</Text>
</Box>
</Box>

View file

@ -4,7 +4,7 @@ import { Page, PageContent, PageHeader } from '../../../components/page';
import { SequenceCard } from '../../../components/sequence-card';
import { SequenceCardStyle } from '../styles.css';
import { SettingTile } from '../../../components/setting-tile';
import CinnySVG from '../../../../../public/res/svg/cinny.svg';
import RatatoskrSVG from '../../../../../public/res/svg/ratatoskr.svg';
import { clearCacheAndReload } from '../../../../client/initMatrix';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
@ -38,23 +38,23 @@ export function About({ requestClose }: AboutProps) {
<Box shrink="No">
<img
style={{ width: toRem(60), height: toRem(60) }}
src={CinnySVG}
alt="Cinny logo"
src={RatatoskrSVG}
alt="Ratatoskr logo"
/>
</Box>
<Box direction="Column" gap="300">
<Box direction="Column" gap="100">
<Box gap="100" alignItems="End">
<Text size="H3">Cinny</Text>
<Text size="H3">Ratatoskr</Text>
<Text size="T200">v4.12.8</Text>
</Box>
<Text>Yet another matrix client.</Text>
<Text>GameCult&apos;s Matrix client.</Text>
</Box>
<Box gap="200" wrap="Wrap">
<Button
as="a"
href="https://github.com/cinnyapp/cinny"
href="https://eureka.gamecult.org/forge/GameCult/Ratatoskr"
rel="noreferrer noopener"
target="_blank"
variant="Secondary"
@ -65,20 +65,19 @@ export function About({ requestClose }: AboutProps) {
>
<Text size="B300">Source Code</Text>
</Button>
<Button
as="a"
href="https://cinny.in/#sponsor"
rel="noreferrer noopener"
target="_blank"
variant="Critical"
fill="Soft"
size="300"
radii="300"
before={<Icon src={Icons.Heart} size="100" filled />}
>
<Text size="B300">Support</Text>
</Button>
</Box>
<Text size="T300">
Based on{' '}
<a
href="https://github.com/cinnyapp/cinny"
target="_blank"
rel="noreferrer noopener"
>
Cinny
</a>{' '}
4.12.8 by Ajay Bura and contributors. Ratatoskr is free software under the GNU
Affero General Public License v3; its source is at the Source Code link above.
</Text>
</Box>
</Box>
<Box direction="Column" gap="100">

View file

@ -28,7 +28,7 @@ function ExportKeys() {
const blob = new Blob([encKeys], {
type: 'text/plain;charset=us-ascii',
});
FileSaver.saveAs(blob, 'cinny-keys.txt');
FileSaver.saveAs(blob, 'ratatoskr-keys.txt');
},
[mx]
)

View file

@ -27,7 +27,7 @@ function EmailNotification() {
device_display_name: email,
lang: 'en',
data: {
brand: 'Cinny',
brand: 'Ratatoskr',
},
append: true,
});

View file

@ -5,20 +5,26 @@ import * as css from './styles.css';
export function AuthFooter() {
return (
<Box className={css.AuthFooter} justifyContent="Center" gap="400" wrap="Wrap">
<Text as="a" size="T300" href="https://cinny.in" target="_blank" rel="noreferrer">
<Text as="a" size="T300" href="https://gamecult.org" target="_blank" rel="noreferrer">
About
</Text>
<Text
as="a"
size="T300"
href="https://github.com/ajbura/cinny/releases"
href="https://eureka.gamecult.org/forge/GameCult/Ratatoskr"
target="_blank"
rel="noreferrer"
>
v4.12.8
Source
</Text>
<Text as="a" size="T300" href="https://twitter.com/cinnyapp" target="_blank" rel="noreferrer">
Twitter
<Text
as="a"
size="T300"
href="https://github.com/cinnyapp/cinny"
target="_blank"
rel="noreferrer"
>
Based on Cinny
</Text>
<Text as="a" size="T300" href="https://matrix.org" target="_blank" rel="noreferrer">
Powered by Matrix

View file

@ -20,7 +20,7 @@ import {
} from '../../hooks/useClientConfig';
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
import { LOGIN_PATH, REGISTER_PATH, RESET_PASSWORD_PATH } from '../paths';
import CinnySVG from '../../../../public/res/svg/cinny.svg';
import RatatoskrSVG from '../../../../public/res/svg/ratatoskr.svg';
import { ServerPicker } from './ServerPicker';
import { AutoDiscoveryAction, autoDiscovery } from '../../cs-api';
import { SpecVersionsLoader } from '../../components/SpecVersionsLoader';
@ -134,8 +134,8 @@ export function AuthLayout() {
<Box direction="Column" className={css.AuthCard}>
<Header className={css.AuthHeader} size="600" variant="Surface">
<Box grow="Yes" direction="Row" gap="300" alignItems="Center">
<img className={css.AuthLogo} src={CinnySVG} alt="Cinny Logo" />
<Text size="H3">Cinny</Text>
<img className={css.AuthLogo} src={RatatoskrSVG} alt="Ratatoskr logo" />
<Text size="H3">Ratatoskr</Text>
</Box>
</Header>
<Box className={css.AuthCardContent} direction="Column">

View file

@ -133,7 +133,7 @@ export function PasswordLoginForm({ defaultUsername, defaultEmail }: PasswordLog
user: username,
},
password,
initial_device_display_name: 'Cinny Web',
initial_device_display_name: 'Ratatoskr Web',
});
};
@ -151,7 +151,7 @@ export function PasswordLoginForm({ defaultUsername, defaultEmail }: PasswordLog
user: mxIdUsername,
},
password,
initial_device_display_name: 'Cinny Web',
initial_device_display_name: 'Ratatoskr Web',
});
};
const handleEmailLogin = (email: string, password: string) => {
@ -163,7 +163,7 @@ export function PasswordLoginForm({ defaultUsername, defaultEmail }: PasswordLog
address: email,
},
password,
initial_device_display_name: 'Cinny Web',
initial_device_display_name: 'Ratatoskr Web',
});
};

View file

@ -57,7 +57,7 @@ export function TokenLogin({ token }: TokenLoginProps) {
startLogin(baseUrl, {
type: 'm.login.token',
token,
initial_device_display_name: 'Cinny Web',
initial_device_display_name: 'Ratatoskr Web',
});
}, [baseUrl, token, startLogin]);

View file

@ -109,7 +109,7 @@ function RegisterUIAFlow({
auth: authDict,
password,
username,
initial_device_display_name: 'Cinny Web',
initial_device_display_name: 'Ratatoskr Web',
});
},
[onRegister, formData]
@ -250,7 +250,7 @@ export function PasswordRegisterForm({
auth: {
session: authData.session,
},
initial_device_display_name: 'Cinny Web',
initial_device_display_name: 'Ratatoskr Web',
});
};

View file

@ -3,9 +3,9 @@ import React, { ReactNode, useCallback, useEffect, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import { RoomEvent, RoomEventHandlerMap } from 'matrix-js-sdk';
import { roomToUnreadAtom, unreadEqual, unreadInfoToUnread } from '../../state/room/roomToUnread';
import LogoSVG from '../../../../public/res/svg/cinny.svg';
import LogoUnreadSVG from '../../../../public/res/svg/cinny-unread.svg';
import LogoHighlightSVG from '../../../../public/res/svg/cinny-highlight.svg';
import LogoSVG from '../../../../public/res/svg/ratatoskr.svg';
import LogoUnreadSVG from '../../../../public/res/svg/ratatoskr-unread.svg';
import LogoHighlightSVG from '../../../../public/res/svg/ratatoskr-highlight.svg';
import NotificationSound from '../../../../public/sound/notification.ogg';
import InviteSound from '../../../../public/sound/invite.ogg';
import { notificationPermission, setFavicon } from '../../utils/dom';

View file

@ -1,7 +1,7 @@
import React from 'react';
import { Box, Button, Icon, Icons, Text, config, toRem } from 'folds';
import { Page, PageHero, PageHeroSection } from '../../components/page';
import CinnySVG from '../../../../public/res/svg/cinny.svg';
import RatatoskrSVG from '../../../../public/res/svg/ratatoskr.svg';
export function WelcomePage() {
return (
@ -14,17 +14,17 @@ export function WelcomePage() {
>
<PageHeroSection>
<PageHero
icon={<img width="70" height="70" src={CinnySVG} alt="Cinny Logo" />}
title="Welcome to Cinny"
icon={<img width="70" height="70" src={RatatoskrSVG} alt="Ratatoskr logo" />}
title="Welcome to Ratatoskr"
subTitle={
<span>
Yet another matrix client.{' '}
GameCult&apos;s Matrix client, based on{' '}
<a
href="https://github.com/cinnyapp/cinny/releases"
href="https://github.com/cinnyapp/cinny"
target="_blank"
rel="noreferrer noopener"
>
v4.12.8
Cinny
</a>
</span>
}
@ -33,7 +33,7 @@ export function WelcomePage() {
<Box grow="Yes" style={{ maxWidth: toRem(300) }} direction="Column" gap="300">
<Button
as="a"
href="https://github.com/cinnyapp/cinny"
href="https://eureka.gamecult.org/forge/GameCult/Ratatoskr"
target="_blank"
rel="noreferrer noopener"
before={<Icon size="200" src={Icons.Code} />}
@ -42,18 +42,6 @@ export function WelcomePage() {
Source Code
</Text>
</Button>
<Button
as="a"
href="https://cinny.in/#sponsor"
target="_blank"
rel="noreferrer noopener"
fill="Soft"
before={<Icon size="200" src={Icons.Heart} />}
>
<Text as="span" size="B400" truncate>
Support
</Text>
</Button>
</Box>
</Box>
</PageHero>