replies timeline only, appview-less bluesky client
at main 1.5 kB view raw
1export type Theme = Record<string, string> & { 2 bg: string; 3 fg: string; 4 accent: string; 5 accent2: string; 6}; 7 8export const defaultTheme: Theme = { 9 bg: '#11001c', 10 fg: '#f8fafc', 11 accent: '#ec4899', 12 accent2: '#8b5cf6' 13}; 14 15export const hashColor = (input: string): string => { 16 let hash: number; 17 18 const id = input.split(':').pop() || input; 19 20 hash = 0; 21 for (let i = 0; i < Math.min(10, id.length); i++) hash = (hash << 4) + id.charCodeAt(i); 22 hash = hash >>> 0; 23 24 // magic mixing 25 hash ^= hash >>> 16; 26 hash = Math.imul(hash, 0x21f0aaad); 27 hash ^= hash >>> 15; 28 hash = hash >>> 0; 29 30 const hue = hash % 360; 31 const saturation = 0.8 + ((hash >>> 10) % 20) * 0.01; // 80-100% 32 const lightness = 0.45 + ((hash >>> 20) % 35) * 0.01; // 45-80% 33 34 const rgb = hslToRgb(hue, saturation, lightness); 35 const hex = rgb.map((value) => value.toString(16).padStart(2, '0')).join(''); 36 37 return `#${hex}`; 38}; 39 40const hslToRgb = (h: number, s: number, l: number): [number, number, number] => { 41 const c = (1 - Math.abs(2 * l - 1)) * s; 42 const hPrime = h / 60; 43 const x = c * (1 - Math.abs((hPrime % 2) - 1)); 44 const m = l - c / 2; 45 46 let r: number, g: number, b: number; 47 48 if (hPrime < 1) { 49 r = c; 50 g = x; 51 b = 0; 52 } else if (hPrime < 2) { 53 r = x; 54 g = c; 55 b = 0; 56 } else if (hPrime < 3) { 57 r = 0; 58 g = c; 59 b = x; 60 } else if (hPrime < 4) { 61 r = 0; 62 g = x; 63 b = c; 64 } else if (hPrime < 5) { 65 r = x; 66 g = 0; 67 b = c; 68 } else { 69 r = c; 70 g = 0; 71 b = x; 72 } 73 74 return [Math.round((r + m) * 255), Math.round((g + m) * 255), Math.round((b + m) * 255)]; 75};