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): string {
29 let hash: number;
30
31 const id = input.split(':').pop() || input;
32
33 hash = 0;
34 for (let i = 0; i < Math.min(10, id.length); i++) {
35 hash = (hash << 4) + id.charCodeAt(i);
36 }
37 hash = hash >>> 0;
38
39 // magic mixing
40 hash ^= hash >>> 16;
41 hash = Math.imul(hash, 0x21f0aaad);
42 hash ^= hash >>> 15;
43 hash = hash >>> 0;
44
45 const hue = hash % 360;
46 const saturation = 0.8 + ((hash >>> 10) % 20) * 0.01; // 80-100%
47 const lightness = 0.45 + ((hash >>> 20) % 35) * 0.01; // 50-75%
48
49 const rgb = hslToRgb(hue, saturation, lightness);
50 const hex = rgb.map((value) => value.toString(16).padStart(2, '0')).join('');
51
52 return `#${hex}`;
53}
54
55function hslToRgb(h: number, s: number, l: number): [number, number, number] {
56 const c = (1 - Math.abs(2 * l - 1)) * s;
57 const hPrime = h / 60;
58 const x = c * (1 - Math.abs((hPrime % 2) - 1));
59 const m = l - c / 2;
60
61 let r: number, g: number, b: number;
62
63 if (hPrime < 1) {
64 r = c;
65 g = x;
66 b = 0;
67 } else if (hPrime < 2) {
68 r = x;
69 g = c;
70 b = 0;
71 } else if (hPrime < 3) {
72 r = 0;
73 g = c;
74 b = x;
75 } else if (hPrime < 4) {
76 r = 0;
77 g = x;
78 b = c;
79 } else if (hPrime < 5) {
80 r = x;
81 g = 0;
82 b = c;
83 } else {
84 r = c;
85 g = 0;
86 b = x;
87 }
88
89 return [Math.round((r + m) * 255), Math.round((g + m) * 255), Math.round((b + m) * 255)];
90}