Commit 1733e6bd authored by Mahmoud Aglan's avatar Mahmoud Aglan

fix: wire up emoji() theming so uploaded PNGs actually replace hardcoded emojis

The emoji() function existed in theme.js but no component imported or called it.
All emojis were hardcoded strings. Now result screens, daily rewards, challenges,
shop, and history use emoji() which checks for admin-uploaded replacements.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent f96c69db
...@@ -3,6 +3,7 @@ import * as net from '../../../core/net.js'; ...@@ -3,6 +3,7 @@ import * as net from '../../../core/net.js';
import * as audio from '../../../core/audio.js'; import * as audio from '../../../core/audio.js';
import * as store from '../../../core/store.js'; import * as store from '../../../core/store.js';
import { t } from '../../../core/i18n.js'; import { t } from '../../../core/i18n.js';
import { emoji } from '../../../core/theme.js';
export async function mountHistory(el) { export async function mountHistory(el) {
el.innerHTML = ` el.innerHTML = `
...@@ -47,9 +48,9 @@ function renderHistory(el, matches) { ...@@ -47,9 +48,9 @@ function renderHistory(el, matches) {
const isWhite = m.white_player_id === userId; const isWhite = m.white_player_id === userId;
const myResult = getMyResult(m.result, isWhite); const myResult = getMyResult(m.result, isWhite);
const resultConfig = { const resultConfig = {
win: { label: 'فوز', color: '#34D399', icon: '🏆' }, win: { label: 'فوز', color: '#34D399', icon: emoji('trophy', '🏆', 20) },
loss: { label: 'خسارة', color: '#F87171', icon: '💀' }, loss: { label: 'خسارة', color: '#F87171', icon: emoji('skull', '💀', 20) },
draw: { label: 'تعادل', color: '#E4AC38', icon: '🤝' }, draw: { label: 'تعادل', color: '#E4AC38', icon: emoji('handshake', '🤝', 20) },
unknown: { label: '—', color: '#64748b', icon: '•' } unknown: { label: '—', color: '#64748b', icon: '•' }
}; };
const cfg = resultConfig[myResult] || resultConfig.unknown; const cfg = resultConfig[myResult] || resultConfig.unknown;
......
...@@ -4,6 +4,7 @@ import * as bus from '../../../core/bus.js'; ...@@ -4,6 +4,7 @@ import * as bus from '../../../core/bus.js';
import * as store from '../../../core/store.js'; import * as store from '../../../core/store.js';
import { t } from '../../../core/i18n.js'; import { t } from '../../../core/i18n.js';
import * as juice from '../../../core/juice.js'; import * as juice from '../../../core/juice.js';
import { emoji } from '../../../core/theme.js';
export function mountResult(el, params) { export function mountResult(el, params) {
const { result, reason, coins = 0, xp = 0, moves = 0, mode, botId, pgn, moveHistory = [] } = params; const { result, reason, coins = 0, xp = 0, moves = 0, mode, botId, pgn, moveHistory = [] } = params;
...@@ -15,9 +16,9 @@ export function mountResult(el, params) { ...@@ -15,9 +16,9 @@ export function mountResult(el, params) {
const ratingStr = ratingChange >= 0 ? `+${ratingChange}` : `${ratingChange}`; const ratingStr = ratingChange >= 0 ? `+${ratingChange}` : `${ratingChange}`;
const resultConfig = { const resultConfig = {
win: { icon: '🏆', title: t('game.you_win'), color: '#34D399' }, win: { icon: emoji('trophy', '🏆', 72), title: t('game.you_win'), color: '#34D399' },
loss: { icon: '💀', title: t('game.you_lose'), color: '#F87171' }, loss: { icon: emoji('skull', '💀', 72), title: t('game.you_lose'), color: '#F87171' },
draw: { icon: '🤝', title: t('game.draw_result'), color: '#E4AC38' } draw: { icon: emoji('handshake', '🤝', 72), title: t('game.draw_result'), color: '#E4AC38' }
}; };
const cfg = resultConfig[result] || resultConfig.loss; const cfg = resultConfig[result] || resultConfig.loss;
......
...@@ -2,11 +2,12 @@ import * as scene from '../../../core/scene.js'; ...@@ -2,11 +2,12 @@ import * as scene from '../../../core/scene.js';
import * as bus from '../../../core/bus.js'; import * as bus from '../../../core/bus.js';
import * as audio from '../../../core/audio.js'; import * as audio from '../../../core/audio.js';
import { t } from '../../../core/i18n.js'; import { t } from '../../../core/i18n.js';
import { emoji } from '../../../core/theme.js';
export function mountResult(el, params) { export function mountResult(el, params) {
const { result, scores = [] } = params; const { result, scores = [] } = params;
const isWin = result === 'win'; const isWin = result === 'win';
const icon = isWin ? '🏆' : '💀'; const icon = isWin ? emoji('trophy', '🏆', 64) : emoji('skull', '💀', 64);
const title = isWin ? t('game.you_win') : t('game.you_lose'); const title = isWin ? t('game.you_win') : t('game.you_lose');
const color = isWin ? 'var(--win)' : 'var(--loss)'; const color = isWin ? 'var(--win)' : 'var(--loss)';
......
...@@ -2,6 +2,7 @@ import * as scene from '../../../core/scene.js'; ...@@ -2,6 +2,7 @@ import * as scene from '../../../core/scene.js';
import * as bus from '../../../core/bus.js'; import * as bus from '../../../core/bus.js';
import * as audio from '../../../core/audio.js'; import * as audio from '../../../core/audio.js';
import { t } from '../../../core/i18n.js'; import { t } from '../../../core/i18n.js';
import { emoji } from '../../../core/theme.js';
export function mountResult(el, params) { export function mountResult(el, params) {
const { result } = params; const { result } = params;
...@@ -9,7 +10,7 @@ export function mountResult(el, params) { ...@@ -9,7 +10,7 @@ export function mountResult(el, params) {
el.innerHTML = ` el.innerHTML = `
<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:var(--s-6);padding:var(--s-6);"> <div style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:var(--s-6);padding:var(--s-6);">
<div style="font-size:64px;animation:float 2s ease-in-out infinite;">${isWin ? '🏆' : '💀'}</div> <div style="font-size:64px;animation:float 2s ease-in-out infinite;">${isWin ? emoji('trophy', '🏆', 64) : emoji('skull', '💀', 64)}</div>
<div style="font-size:28px;font-weight:800;color:${isWin ? 'var(--win)' : 'var(--loss)'};">${isWin ? t('game.you_win') : t('game.you_lose')}</div> <div style="font-size:28px;font-weight:800;color:${isWin ? 'var(--win)' : 'var(--loss)'};">${isWin ? t('game.you_win') : t('game.you_lose')}</div>
<div style="display:flex;gap:var(--s-3);margin-top:var(--s-6);"> <div style="display:flex;gap:var(--s-3);margin-top:var(--s-6);">
<button class="btn btn-primary" id="btn-again">${t('game.rematch')}</button> <button class="btn btn-primary" id="btn-again">${t('game.rematch')}</button>
......
...@@ -4,6 +4,7 @@ import * as juice from '../../../core/juice.js'; ...@@ -4,6 +4,7 @@ import * as juice from '../../../core/juice.js';
import * as bus from '../../../core/bus.js'; import * as bus from '../../../core/bus.js';
import * as store from '../../../core/store.js'; import * as store from '../../../core/store.js';
import * as scene from '../../../core/scene.js'; import * as scene from '../../../core/scene.js';
import { emoji } from '../../../core/theme.js';
export async function mountChallenges(el) { export async function mountChallenges(el) {
el.innerHTML = ` el.innerHTML = `
...@@ -52,7 +53,7 @@ function renderChallenges(el, data) { ...@@ -52,7 +53,7 @@ function renderChallenges(el, data) {
<div style="text-align:center;min-width:50px;"> <div style="text-align:center;min-width:50px;">
${c.claimed ? '<span style="color:#34D399;font-size:16px;">✓</span>' : ${c.claimed ? '<span style="color:#34D399;font-size:16px;">✓</span>' :
c.completed ? `<button class="claim-btn" data-id="${c.id}" data-coins="${c.reward_coins}" data-xp="${c.reward_xp}" style="background:#E4AC38;color:#1a1a1a;border:none;border-radius:8px;padding:6px 10px;font-size:11px;font-weight:700;cursor:pointer;">اجمع</button>` : c.completed ? `<button class="claim-btn" data-id="${c.id}" data-coins="${c.reward_coins}" data-xp="${c.reward_xp}" style="background:#E4AC38;color:#1a1a1a;border:none;border-radius:8px;padding:6px 10px;font-size:11px;font-weight:700;cursor:pointer;">اجمع</button>` :
`<span style="font-size:11px;color:#E4AC38;font-weight:600;">${c.reward_coins}🪙</span>`} `<span style="font-size:11px;color:#E4AC38;font-weight:600;">${c.reward_coins}${emoji('coin', '🪙', 14)}</span>`}
</div> </div>
</div> </div>
`).join(''); `).join('');
......
...@@ -5,6 +5,7 @@ import * as store from '../../../core/store.js'; ...@@ -5,6 +5,7 @@ import * as store from '../../../core/store.js';
import * as scene from '../../../core/scene.js'; import * as scene from '../../../core/scene.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 { emoji } from '../../../core/theme.js';
const DAY_REWARDS = [50, 75, 100, 125, 150, 200, 300]; const DAY_REWARDS = [50, 75, 100, 125, 150, 200, 300];
...@@ -20,7 +21,7 @@ export async function mountDaily(el) { ...@@ -20,7 +21,7 @@ export async function mountDaily(el) {
<!-- Header --> <!-- Header -->
<div style="display:flex;align-items:center;gap:12px;padding:12px 16px;background:#0f0f1e;border-bottom:1px solid rgba(255,255,255,0.06);"> <div style="display:flex;align-items:center;gap:12px;padding:12px 16px;background:#0f0f1e;border-bottom:1px solid rgba(255,255,255,0.06);">
<button class="btn btn-secondary" id="back-btn" style="min-height:32px;padding:4px 12px;font-size:12px;">←</button> <button class="btn btn-secondary" id="back-btn" style="min-height:32px;padding:4px 12px;font-size:12px;">←</button>
<span style="font-size:16px;font-weight:700;color:#f8fafc;">🎁 المكافأة اليومية</span> <span style="font-size:16px;font-weight:700;color:#f8fafc;">${emoji('gift', '🎁', 16)} المكافأة اليومية</span>
</div> </div>
<div style="flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;align-items:center;gap:16px;"> <div style="flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;align-items:center;gap:16px;">
...@@ -59,9 +60,9 @@ export async function mountDaily(el) { ...@@ -59,9 +60,9 @@ export async function mountDaily(el) {
<div style="font-size:16px;font-weight:700;color:#34D399;">تم استلام مكافأة اليوم</div> <div style="font-size:16px;font-weight:700;color:#34D399;">تم استلام مكافأة اليوم</div>
<div style="font-size:13px;color:#64748b;margin-top:4px;">عد غداً لمكافأة أكبر!</div> <div style="font-size:13px;color:#64748b;margin-top:4px;">عد غداً لمكافأة أكبر!</div>
` : ` ` : `
<div style="font-size:56px;margin-bottom:8px;animation:float 3s ease-in-out infinite;">🎁</div> <div style="font-size:56px;margin-bottom:8px;animation:float 3s ease-in-out infinite;">${emoji('gift', '🎁', 56)}</div>
<div style="font-size:16px;font-weight:700;color:#f8fafc;margin-bottom:4px;">مكافأة اليوم</div> <div style="font-size:16px;font-weight:700;color:#f8fafc;margin-bottom:4px;">مكافأة اليوم</div>
<div style="font-size:28px;font-weight:800;color:#E4AC38;margin-bottom:16px;">${DAY_REWARDS[Math.min(streak, 6)]} 🪙</div> <div style="font-size:28px;font-weight:800;color:#E4AC38;margin-bottom:16px;">${DAY_REWARDS[Math.min(streak, 6)]} ${emoji('coin', '🪙', 24)}</div>
<button class="btn btn-primary" id="claim-btn" style="font-size:16px;padding:14px 48px;">استلم المكافأة</button> <button class="btn btn-primary" id="claim-btn" style="font-size:16px;padding:14px 48px;">استلم المكافأة</button>
`} `}
</div> </div>
......
...@@ -3,6 +3,7 @@ import * as audio from '../../../core/audio.js'; ...@@ -3,6 +3,7 @@ import * as audio from '../../../core/audio.js';
import * as store from '../../../core/store.js'; import * as store from '../../../core/store.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 { emoji } from '../../../core/theme.js';
const RARITY_COLORS = { common: 'var(--text-secondary)', uncommon: 'var(--success)', rare: 'var(--blue)', epic: 'var(--purple)', legendary: 'var(--gold)' }; const RARITY_COLORS = { common: 'var(--text-secondary)', uncommon: 'var(--success)', rare: 'var(--blue)', epic: 'var(--purple)', legendary: 'var(--gold)' };
...@@ -42,8 +43,8 @@ function renderItems(el, items) { ...@@ -42,8 +43,8 @@ function renderItems(el, items) {
<div style="font-size:13px;font-weight:600;margin-bottom:2px;">${item.name || item.id}</div> <div style="font-size:13px;font-weight:600;margin-bottom:2px;">${item.name || item.id}</div>
<div style="font-size:10px;color:${RARITY_COLORS[item.rarity] || 'var(--text-muted)'};margin-bottom:var(--s-1);">${item.rarity || 'common'}</div> <div style="font-size:10px;color:${RARITY_COLORS[item.rarity] || 'var(--text-muted)'};margin-bottom:var(--s-1);">${item.rarity || 'common'}</div>
<div style="font-size:12px;font-weight:700;color:var(--gold);"> <div style="font-size:12px;font-weight:700;color:var(--gold);">
${item.price_coins ? `${item.price_coins} 🪙` : ''} ${item.price_coins ? `${item.price_coins} ${emoji('coin', '🪙', 14)}` : ''}
${item.price_gems ? `${item.price_gems} 💎` : ''} ${item.price_gems ? `${item.price_gems} ${emoji('gem', '💎', 14)}` : ''}
</div> </div>
</div> </div>
`).join(''); `).join('');
...@@ -67,7 +68,7 @@ async function purchasePrompt(el, item) { ...@@ -67,7 +68,7 @@ async function purchasePrompt(el, item) {
overlay.innerHTML = ` overlay.innerHTML = `
<div class="card" style="max-width:300px;width:90%;padding:var(--s-6);text-align:center;"> <div class="card" style="max-width:300px;width:90%;padding:var(--s-6);text-align:center;">
<div style="font-size:18px;font-weight:700;margin-bottom:var(--s-2);">${item.name || item.id}</div> <div style="font-size:18px;font-weight:700;margin-bottom:var(--s-2);">${item.name || item.id}</div>
<div style="font-size:14px;color:var(--gold);margin-bottom:var(--s-4);">${item.price_coins || 0} 🪙</div> <div style="font-size:14px;color:var(--gold);margin-bottom:var(--s-4);">${item.price_coins || 0} ${emoji('coin', '🪙', 16)}</div>
${canAfford ${canAfford
? `<button class="btn btn-primary w-full" id="buy-btn">${t('common.confirm')}</button>` ? `<button class="btn btn-primary w-full" id="buy-btn">${t('common.confirm')}</button>`
: `<p style="color:var(--error);font-size:13px;">رصيد غير كافي</p>` : `<p style="color:var(--error);font-size:13px;">رصيد غير كافي</p>`
......
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