feat(badges): zibll-style badge modal with category grid, detail view, and wear UX

This commit is contained in:
2026-08-04 12:46:44 +08:00
parent 4849869289
commit ed19937e99
9 changed files with 904 additions and 246 deletions
+24 -15
View File
@@ -166,20 +166,30 @@ class Home {
if (class_exists('AKSRT\\User\\Badges')) {
$list = Badges::list_for_user($user_id, true);
$badge_count = 0;
foreach ((array) ($list['items'] ?? []) as $item) {
if ($badge_count >= $limit) {
$done = false;
foreach ((array) ($list['categories'] ?? []) as $cat) {
foreach ((array) ($cat['items'] ?? []) as $item) {
if (empty($item['owned'])) {
continue;
}
if ($badge_count >= $limit) {
$done = true;
break;
}
$signals[] = [
'type' => 'badge',
'slug' => (string) ($item['slug'] ?? ''),
'label' => (string) ($item['label'] ?? ''),
'icon' => 'award',
'tone' => 'info',
'icon_url' => (string) ($item['icon_url'] ?? ''),
'wear' => !empty($item['wear']),
];
$badge_count++;
}
if ($done) {
break;
}
$signals[] = [
'type' => 'badge',
'slug' => (string) ($item['slug'] ?? ''),
'label' => (string) ($item['label'] ?? ''),
'icon' => 'award',
'tone' => (string) ($item['tone'] ?? 'neutral'),
'icon_url' => (string) ($item['icon_url'] ?? ''),
'wear' => !empty($item['wear']),
];
$badge_count++;
}
} else {
$badge_map = [];
@@ -189,9 +199,8 @@ class Home {
}
}
$assigned = get_user_meta($user_id, 'aksrt_user_badges', true);
if (!is_array($assigned)) {
$assigned = preg_split('/[\s,]+/', (string) $assigned, -1, PREG_SPLIT_NO_EMPTY);
}
// Storage shape: associative map slug => grant time.
$assigned = is_array($assigned) ? array_keys($assigned) : [];
$wear = sanitize_key((string) get_user_meta($user_id, 'aksrt_wear_badge', true));
$assigned = array_values(array_filter(array_map(static function ($slug) {
return sanitize_key((string) $slug);