feat: Remove localStorage for game states and implement cross-domain player ID sync
- Remove localStorage for game states and statistics (backend only) - Add API route to suggest player ID based on recently updated states - Add async player ID lookup that finds existing IDs across domains - When visiting a new domain, automatically find and use existing player ID - Enables cross-domain synchronization between hoerdle.de and hördle.de
This commit is contained in:
@@ -20,11 +20,75 @@ function generatePlayerId(): string {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find an existing player ID from the backend
|
||||
*
|
||||
* @param genreKey - Genre key to search for
|
||||
* @returns Player ID if found, null otherwise
|
||||
*/
|
||||
async function findExistingPlayerId(genreKey: string): Promise<string | null> {
|
||||
try {
|
||||
const response = await fetch('/api/player-id/suggest', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ genreKey }),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
if (data.playerId) {
|
||||
return data.playerId;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('[playerId] Failed to find existing player ID:', error);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create a player identifier
|
||||
*
|
||||
* If no identifier exists in localStorage, a new UUID is generated and stored.
|
||||
* The same identifier is used across all domains (hoerdle.de and hördle.de).
|
||||
* If no identifier exists in localStorage, tries to find an existing one from the backend
|
||||
* (based on recently updated states). If none found, generates a new UUID.
|
||||
* This enables cross-domain synchronization between hoerdle.de and hördle.de.
|
||||
*
|
||||
* @param genreKey - Optional genre key to search for existing player ID
|
||||
* @returns Player identifier (UUID v4)
|
||||
*/
|
||||
export async function getOrCreatePlayerIdAsync(genreKey?: string): Promise<string> {
|
||||
if (typeof window === 'undefined') {
|
||||
// Server-side: return empty string (not used on server)
|
||||
return '';
|
||||
}
|
||||
|
||||
let playerId = localStorage.getItem(STORAGE_KEY);
|
||||
|
||||
if (!playerId) {
|
||||
// Try to find an existing player ID from backend if genreKey is provided
|
||||
if (genreKey) {
|
||||
const existingId = await findExistingPlayerId(genreKey);
|
||||
if (existingId) {
|
||||
playerId = existingId;
|
||||
localStorage.setItem(STORAGE_KEY, playerId);
|
||||
return playerId;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate new UUID if no existing ID found
|
||||
playerId = generatePlayerId();
|
||||
localStorage.setItem(STORAGE_KEY, playerId);
|
||||
}
|
||||
|
||||
return playerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create a player identifier (synchronous version)
|
||||
*
|
||||
* This is the legacy synchronous version. For cross-domain sync, use getOrCreatePlayerIdAsync instead.
|
||||
*
|
||||
* @returns Player identifier (UUID v4)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user