cozy-games/apps/mnswpr/modules/nickname/nickname.js
Ayo 969ebba067 chore: restructure to new cozy-games monorepo
Reviewed-on: https://git.ayo.run/ayo/cozy-games/pulls/1
Co-authored-by: Ayo <ayo@ayco.io>
Co-committed-by: Ayo <ayo@ayco.io>
2026-07-03 13:53:13 +00:00

100 lines
2.8 KiB
JavaScript

import { StorageService } from '@cozy-games/utils'
const NICK_KEY = 'nickname'
const MAX_LENGTH = 24
/**
* A few friendly greetings; `{nick}` is replaced with the player's nickname.
*/
const GREETINGS = [
'Welcome back, {nick}!',
'Good to see you, {nick}!',
'Hey {nick}, ready to sweep?',
'Let\'s go, {nick}!',
'Happy sweeping, {nick}!',
'Nice to have you, {nick}!'
]
/**
* Owns the player's display nickname: prompts for it once on first visit,
* persists it in localStorage, and renders a friendly greeting bar. The
* leaderboard package stays name-agnostic — the app passes this nickname in.
*/
export class NicknameService {
constructor() {
this.storage = new StorageService()
}
/**
* The stored nickname, or 'Anonymous' if none has been set yet.
* @returns {String}
*/
get() {
return this.storage.getFromLocal(NICK_KEY) || 'Anonymous'
}
/**
* Prompt for a nickname the first time only — used on page load.
*/
ensure() {
if (!this.storage.getFromLocal(NICK_KEY)) {
this.prompt()
}
}
/**
* Ask for a nickname and persist it (trimmed, capped). Cancelling keeps the
* current value. A failing/unsupported prompt must never break page load, so
* it is guarded — the player just stays 'Anonymous'.
*/
prompt() {
let next
try {
next = window.prompt('Pick a nickname for the leaderboard', this.storage.getFromLocal(NICK_KEY) || '')
} catch {
return
}
if (next && next.trim()) {
this.storage.saveToLocal(NICK_KEY, next.trim().slice(0, MAX_LENGTH))
}
}
/**
* Render the greeting bar into a container. Clicking the nickname (or the
* pencil) re-prompts and re-renders in place.
* @param {HTMLElement} container
*/
render(container) {
if (!container) return
container.innerHTML = ''
const template = GREETINGS[Math.floor(Math.random() * GREETINGS.length)]
const [before, after] = template.split('{nick}')
const nameElement = document.createElement('span')
nameElement.innerText = this.get()
nameElement.style.fontWeight = 'bold'
nameElement.style.fontStyle = 'italic'
nameElement.style.cursor = 'pointer'
nameElement.style.textDecoration = 'underline'
nameElement.style.textDecorationColor = 'orange'
nameElement.setAttribute('title', 'Click to change your nickname')
const icon = document.createElement('span')
icon.innerText = ' ✏️'
icon.style.cursor = 'pointer'
icon.style.fontSize = '0.8em'
icon.style.opacity = '0.6'
icon.setAttribute('title', 'Click to change your nickname')
const change = () => {
this.prompt()
this.render(container)
}
nameElement.onclick = change
icon.onclick = change
container.append(document.createTextNode(before), nameElement, icon, document.createTextNode(after))
}
}