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}