File size: 1,325 Bytes
76fc93a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
 * Collab user identity: shared types, color hashing and the localStorage
 * fallback used when the viewer is not authenticated yet.
 */

export interface CollabUser {
  name: string;
  color: string;
  avatarUrl?: string;
}

const COLORS = [
  "#958DF1", "#F98181", "#FBBC88", "#FAF594",
  "#70CFF8", "#94FADB", "#B9F18D", "#C4B5FD",
];

/** Deterministic color from a name, used for cursors and author chips. */
export function colorFromName(name: string): string {
  let hash = 0;
  for (let i = 0; i < name.length; i++) hash = (hash * 31 + name.charCodeAt(i)) | 0;
  return COLORS[Math.abs(hash) % COLORS.length];
}

const STORAGE_KEY = "collab-editor:fallback-user";
const FALLBACK_NAMES = ["Alice", "Bob", "Carol", "Dave", "Eve", "Frank", "Grace", "Heidi"];

/**
 * Pick (and persist) a random pseudonymous user when the session is anonymous.
 * Stored in localStorage so a refresh keeps the same name/color.
 */
export function stableFallbackUser(): CollabUser {
  const stored = localStorage.getItem(STORAGE_KEY);
  if (stored) {
    try { return JSON.parse(stored); } catch { /* fall through */ }
  }
  const name = FALLBACK_NAMES[Math.floor(Math.random() * FALLBACK_NAMES.length)];
  const user = { name, color: colorFromName(name) };
  localStorage.setItem(STORAGE_KEY, JSON.stringify(user));
  return user;
}