Commit 759e2683 authored by Mahmoud Aglan's avatar Mahmoud Aglan

feat(game): sticker marks on notifications, leaderboard filters and tournament tickets

Co-Authored-By: 's avatarClaude Opus 5.5 <noreply@anthropic.com>
parent 3e2a893c
...@@ -13,7 +13,7 @@ import * as audio from '../../../core/audio.js'; ...@@ -13,7 +13,7 @@ import * as audio from '../../../core/audio.js';
import * as store from '../../../core/store.js'; import * as store from '../../../core/store.js';
import * as juice from '../../../core/juice.js'; import * as juice from '../../../core/juice.js';
import { t } from '../../../core/i18n.js'; import { t } from '../../../core/i18n.js';
import { icon, GAME_MARK } from '../../../core/icons.js'; import { icon, gicon, GAME_MARK } from '../../../core/icons.js';
import { screenHead, loadingRows, emptyState, errorState, avatar, esc } from '../../../core/ui.js'; import { screenHead, loadingRows, emptyState, errorState, avatar, esc } from '../../../core/ui.js';
const GAMES = ['chess', 'domino', 'ludo', 'backgammon']; const GAMES = ['chess', 'domino', 'ludo', 'backgammon'];
...@@ -31,7 +31,7 @@ export async function mountLeaderboard(el) { ...@@ -31,7 +31,7 @@ export async function mountLeaderboard(el) {
<div class="chips lb-games" id="game-tabs" role="group" aria-label="${t('rank.lb_games')}"> <div class="chips lb-games" id="game-tabs" role="group" aria-label="${t('rank.lb_games')}">
${GAMES.map(g => ` ${GAMES.map(g => `
<button class="chip${g === activeGame ? ' active' : ''}" data-game="${g}" aria-pressed="${g === activeGame}"> <button class="chip${g === activeGame ? ' active' : ''}" data-game="${g}" aria-pressed="${g === activeGame}">
${icon(GAME_MARK[g].icon, 16, { cls: GAME_MARK[g].ink === 'red' ? 'lb-mark-red' : '' })}${t('game.' + g)} ${gicon(g, 24)}${t('game.' + g)}
</button>`).join('')} </button>`).join('')}
</div> </div>
<div id="leaderboard-list" class="lb-list" aria-live="polite">${loadingRows(6)}</div> <div id="leaderboard-list" class="lb-list" aria-live="polite">${loadingRows(6)}</div>
......
...@@ -10,7 +10,7 @@ import * as scene from '../../../core/scene.js'; ...@@ -10,7 +10,7 @@ import * as scene from '../../../core/scene.js';
import * as audio from '../../../core/audio.js'; import * as audio from '../../../core/audio.js';
import * as juice from '../../../core/juice.js'; import * as juice from '../../../core/juice.js';
import { t, getLang } from '../../../core/i18n.js'; import { t, getLang } from '../../../core/i18n.js';
import { icon, GAME_MARK } from '../../../core/icons.js'; import { icon, gicon, GAME_MARK } from '../../../core/icons.js';
import { screenHead, wireBack, loadingRows, emptyState, esc } from '../../../core/ui.js'; import { screenHead, wireBack, loadingRows, emptyState, esc } from '../../../core/ui.js';
export async function mountTournaments(el) { export async function mountTournaments(el) {
...@@ -264,7 +264,7 @@ export function ticketMarkup(tour, { cls = '', stub = '', open = true, draftOpen ...@@ -264,7 +264,7 @@ export function ticketMarkup(tour, { cls = '', stub = '', open = true, draftOpen
return ` return `
<article class="deck-card tkt deal-in ${mark.ink === 'red' ? 'ink-red' : ''} ${cls}" data-id="${esc(tour.id || '')}"> <article class="deck-card tkt deal-in ${mark.ink === 'red' ? 'ink-red' : ''} ${cls}" data-id="${esc(tour.id || '')}">
<span class="index top" aria-hidden="true">${icon(mark.icon, 18)}</span> <span class="index top" aria-hidden="true">${gicon(GAME_MARK[tour.game_key] ? tour.game_key : 'chess', 30)}</span>
${face} ${face}
${stub ? `<div class="tkt-perf" aria-hidden="true"></div><div class="tkt-stub">${stub}</div>` : ''} ${stub ? `<div class="tkt-perf" aria-hidden="true"></div><div class="tkt-stub">${stub}</div>` : ''}
</article>`; </article>`;
......
...@@ -3,17 +3,17 @@ import * as store from '../../../core/store.js'; ...@@ -3,17 +3,17 @@ import * as store from '../../../core/store.js';
import * as scene from '../../../core/scene.js'; import * as scene from '../../../core/scene.js';
import * as bus from '../../../core/bus.js'; import * as bus from '../../../core/bus.js';
import { t } from '../../../core/i18n.js'; import { t } from '../../../core/i18n.js';
import { icon } from '../../../core/icons.js'; import { icon, gicon } from '../../../core/icons.js';
import { screenHead, wireBack, emptyState, loadingRows, errorState, esc } from '../../../core/ui.js'; import { screenHead, wireBack, emptyState, loadingRows, errorState, esc } from '../../../core/ui.js';
// Each kind of notice gets its mark, printed in the ink that fits it. // Each kind of notice gets its mark, printed in the ink that fits it.
function markFor(type) { function markFor(type) {
if (type === 'friend_request') return ['user-plus', '']; if (type === 'friend_request') return ['friends', ''];
if (type === 'friend_accept') return ['user-check', 'win']; if (type === 'friend_accept') return ['check', 'win'];
if (type === 'match_invite' || type === 'challenge' || type === 'group_game') return ['swords', 'red']; if (type === 'match_invite' || type === 'challenge' || type === 'group_game') return ['swords', 'red'];
if (type.startsWith('tournament')) return ['trophy', 'gold']; if (type.startsWith('tournament')) return ['trophy', 'gold'];
if (type === 'achievement') return ['medal', 'gold']; if (type === 'achievement') return ['medal', 'gold'];
if (type === 'group_added') return ['users', '']; if (type === 'group_added') return ['team', ''];
return ['bell', '']; return ['bell', ''];
} }
...@@ -56,7 +56,7 @@ function renderNotifications(el, notifications) { ...@@ -56,7 +56,7 @@ function renderNotifications(el, notifications) {
const body = n.body_ar || n.body || ''; const body = n.body_ar || n.body || '';
return ` return `
<div class="row snt-row notif-item deal-in${n.is_read ? ' read' : ''}" data-id="${n.id}" role="button" tabindex="0"> <div class="row snt-row notif-item deal-in${n.is_read ? ' read' : ''}" data-id="${n.id}" role="button" tabindex="0">
<span class="snt-tile ${tone}">${icon(mark, 20)}</span> <span class="snt-tile ${tone}">${gicon(mark, 34)}</span>
<div class="row-main"> <div class="row-main">
<div class="snt-title">${esc(title)}</div> <div class="snt-title">${esc(title)}</div>
${body ? `<div class="snt-body">${esc(body)}</div>` : ''} ${body ? `<div class="snt-body">${esc(body)}</div>` : ''}
...@@ -119,12 +119,12 @@ const STYLE = ` ...@@ -119,12 +119,12 @@ const STYLE = `
.snt-row { align-items: flex-start; padding: var(--s-3) 0; cursor: pointer; } .snt-row { align-items: flex-start; padding: var(--s-3) 0; cursor: pointer; }
.snt-tile { .snt-tile {
width: 40px; height: 40px; width: 50px; height: 50px;
flex-shrink: 0; flex-shrink: 0;
display: flex; align-items: center; justify-content: center; display: flex; align-items: center; justify-content: center;
border-radius: var(--r-md); border-radius: 14px;
background: var(--back-950); background: radial-gradient(circle at 50% 35%, rgba(255, 220, 150, 0.22), rgba(0, 0, 0, 0.4) 70%);
color: var(--text-secondary); box-shadow: 0 0 0 2px rgba(20, 8, 2, 0.8), inset 0 0 0 1px rgba(255, 210, 140, 0.2);
} }
.snt-tile.red { color: var(--red); } .snt-tile.red { color: var(--red); }
.snt-tile.gold { color: var(--gold); } .snt-tile.gold { color: var(--gold); }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment