replies timeline only, appview-less bluesky client
1import type { Did, Handle } from '@atcute/lexicons'; 2import { writable } from 'svelte/store'; 3 4export type Account = { 5 did: Did; 6 handle: Handle; 7 password: string; 8}; 9 10let _accounts: Account[] = []; 11export const accounts = (() => { 12 const raw = localStorage.getItem('accounts'); 13 _accounts = raw ? JSON.parse(raw) : []; 14 const store = writable<Account[]>(_accounts); 15 store.subscribe((accounts) => { 16 _accounts = accounts; 17 localStorage.setItem('accounts', JSON.stringify(accounts)); 18 }); 19 return store; 20})(); 21 22export const addAccount = (account: Account): void => { 23 accounts.update((accounts) => [...accounts, account]); 24}; 25 26export const generateColorForDid = (did: string) => hashColor(did); 27 28function hashColor(input: string | number): string { 29 let hash = typeof input === 'string' ? stringToHash(input) : input; 30 31 hash ^= hash >>> 16; 32 hash = Math.imul(hash, 0x85ebca6b); 33 hash ^= hash >>> 13; 34 hash = Math.imul(hash, 0xb00b1355); 35 hash ^= hash >>> 16; 36 hash = hash >>> 0; 37 38 const hue = hash % 360; 39 const saturation = 0.7 + ((hash >>> 8) % 30) * 0.01; 40 const value = 0.6 + ((hash >>> 16) % 40) * 0.01; 41 42 const rgb = hsvToRgb(hue, saturation, value); 43 const hex = rgb.map((value) => value.toString(16).padStart(2, '0')).join(''); 44 45 return `#${hex}`; 46} 47 48function stringToHash(str: string): number { 49 let hash = 0; 50 for (let i = 0; i < str.length; i++) { 51 hash = (Math.imul(hash << 5, 1) - hash + str.charCodeAt(i)) | 0; 52 } 53 return hash >>> 0; 54} 55 56function hsvToRgb(h: number, s: number, v: number): [number, number, number] { 57 const c = v * s; 58 const hPrime = h * 0.016666667; 59 const x = c * (1 - Math.abs((hPrime % 2) - 1)); 60 const m = v - c; 61 62 let r: number, g: number, b: number; 63 64 if (h < 60) { 65 r = c; 66 g = x; 67 b = 0; 68 } else if (h < 120) { 69 r = x; 70 g = c; 71 b = 0; 72 } else if (h < 180) { 73 r = 0; 74 g = c; 75 b = x; 76 } else if (h < 240) { 77 r = 0; 78 g = x; 79 b = c; 80 } else if (h < 300) { 81 r = x; 82 g = 0; 83 b = c; 84 } else { 85 r = c; 86 g = 0; 87 b = x; 88 } 89 90 return [((r + m) * 255) | 0, ((g + m) * 255) | 0, ((b + m) * 255) | 0]; 91}