mirror of
https://github.com/block/buzz.git
synced 2026-10-27 12:40:30 +00:00
## Summary - Restores `#` and lock icons for public and private channels on Home, with matching loading placeholders. - Updates the dark-mode navigation colors to the desktop design-system tokens (read and unread text, section headings). - Replaces the chat color picker with the seven desktop accents (Gray, Chartreuse, Flame, Magenta, Iris, Cobalt, Jade). Saved legacy colors map to the closest one. - Uses white text in your own bubbles, and black where white falls below 4.5:1 (Chartreuse, dark-mode Gray). Links (underlined), quotes, tables and code use the same text color. - Insets code blocks in bubbles evenly, with corners concentric to the bubble and even inner padding. - The swipe-to-reply indicator uses the chosen chat color. ## Testing - `flutter analyze` and `dart format` are clean. The full mobile suite passes (3,705 tests). - Installed and checked on a Pixel 10 and an iPhone Air against a real community. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Co-authored-by: Queue <874bf2d815c2c4b459b90438c669c57f2702f3a76bb6e16fa97184259aac3e9e@buzz.block.builderlab.xyz> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
46 lines
1.6 KiB
JavaScript
46 lines
1.6 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { hexToHsl } from "./adaptive-theme.ts";
|
|
import { ACCENT_COLORS, accentPrimary } from "./ThemeProvider.tsx";
|
|
|
|
function luminance(hex) {
|
|
const channels = [1, 3, 5].map((i) => {
|
|
const value = parseInt(hex.slice(i, i + 2), 16) / 255;
|
|
return value <= 0.03928 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
|
|
});
|
|
return 0.2126 * channels[0] + 0.7152 * channels[1] + 0.0722 * channels[2];
|
|
}
|
|
|
|
function contrast(a, b) {
|
|
const [high, low] = [luminance(a), luminance(b)].sort((x, y) => y - x);
|
|
return (high + 0.05) / (low + 0.05);
|
|
}
|
|
|
|
// Light backgrounds down to the adaptive engine's 0.5-luminance light cutoff.
|
|
const LIGHT = ["#ffffff", "#fafafa", "#f6f8fa", "#eff1f5", "#bcbcbc"];
|
|
const DARK = ["#0d1117", "#24273a", "#1e1e1e"];
|
|
|
|
test("Chartreuse reads as text and as a filled control on every theme", () => {
|
|
for (const background of [...LIGHT, ...DARK]) {
|
|
const { fill, ink } = accentPrimary("#d7d72e", hexToHsl(background));
|
|
assert.ok(contrast(fill, background) >= 4.5, `text on ${background}`);
|
|
assert.ok(contrast(ink, fill) >= 4.5, `ink on fill over ${background}`);
|
|
}
|
|
// Dark themes keep the raw accent.
|
|
for (const background of DARK) {
|
|
assert.equal(
|
|
accentPrimary("#d7d72e", hexToHsl(background)).fill,
|
|
"#d7d72e",
|
|
);
|
|
}
|
|
});
|
|
|
|
test("legacy accents keep their established fill", () => {
|
|
for (const { value } of ACCENT_COLORS) {
|
|
if (value === "neutral" || value === "#d7d72e") continue;
|
|
for (const background of [...LIGHT, ...DARK]) {
|
|
assert.equal(accentPrimary(value, hexToHsl(background)).fill, value);
|
|
}
|
|
}
|
|
});
|