Enhance map functionality and API documentation

- Updated API documentation for the `rebuildZooms` endpoint to clarify its long execution time and response behavior.
- Modified MapView component to manage tile cache invalidation after rebuilding zoom levels, ensuring fresh tile display.
- Introduced a new composable for handling tile cache invalidation state after admin actions.
- Enhanced character icon creation to reflect ownership status with distinct colors.
- Improved loading state handling in various components for better user experience during data fetching.
This commit is contained in:
2026-03-01 19:09:46 +03:00
parent 8331473808
commit 225aaa36e7
16 changed files with 236 additions and 52 deletions

View File

@@ -0,0 +1,48 @@
/**
* Palette of distinguishable colors for character markers (readable on typical map tiles).
* Same character id always maps to the same color via id % palette.length.
*/
const CHARACTER_PALETTE_FILL: string[] = [
'#0d9488', // teal
'#dc2626', // red
'#2563eb', // blue
'#16a34a', // green
'#ea580c', // orange
'#7c3aed', // violet
'#db2777', // pink
'#ca8a04', // yellow/amber
'#0891b2', // cyan
'#65a30d', // lime
'#4f46e5', // indigo
'#b45309', // brown/amber-dark
]
/** Darken a hex color by a factor (01). Used for stroke. */
function darkenHex(hex: string, factor: number): string {
const n = hex.slice(1)
const r = Math.max(0, parseInt(n.slice(0, 2), 16) * (1 - factor))
const g = Math.max(0, parseInt(n.slice(2, 4), 16) * (1 - factor))
const b = Math.max(0, parseInt(n.slice(4, 6), 16) * (1 - factor))
return '#' + [r, g, b].map((x) => Math.round(x).toString(16).padStart(2, '0')).join('')
}
export interface CharacterColors {
fill: string
stroke: string
}
/**
* Returns stable fill and stroke colors for a character by id.
* Optionally use a distinct style for "owned by me" (e.g. brighter stroke).
*/
export function getColorForCharacterId(
id: number,
options?: { ownedByMe?: boolean }
): CharacterColors {
const fill = CHARACTER_PALETTE_FILL[Math.abs(id) % CHARACTER_PALETTE_FILL.length]
const stroke = darkenHex(fill, 0.25)
if (options?.ownedByMe) {
return { fill, stroke: '#1e293b' }
}
return { fill, stroke }
}