Passport Tier 팬덤 단위 · 활동 Badge · 진화 Emblem · Eclipse 참여 기록
This commit is contained in:
@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import '../../core/theme/tokens.dart';
|
||||
import '../home/home_screen.dart' show formatPop;
|
||||
import '../planet/planet_data.dart' show PlanetRepositoryFactory;
|
||||
import '../planet/planet_history_screen.dart';
|
||||
import 'my_data.dart';
|
||||
import 'widgets/my_cards.dart';
|
||||
import '../../core/i18n/app_locale.dart';
|
||||
@@ -98,17 +100,32 @@ class TierInfoScreen extends StatelessWidget {
|
||||
/// 명세 `549:22206` — *갤럭시에서 선택된 기본 행성의 티어를 메인으로 상단에 위치 ·*
|
||||
/// *나머지 행성 티어는 티어 높은순으로 소팅*
|
||||
///
|
||||
/// 칭호는 개인 레벨에서만 나오므로(C-18) 행성별로는 **기여 실적(POP)만** 보인다.
|
||||
/// 칭호는 개인 레벨에서만 나오므로(C-18) 행성별로는 **그 팬덤 Passport Tier 와 기여 실적**을 보인다
|
||||
/// (10/3 #10 사용자 × 팬덤). 탈퇴한 팬덤도 기록을 지우지 않고 아래에 둔다(9/21 5절 · FX §7.1 ARCHIVED).
|
||||
/// 아래 BADGE 는 별첨 1 ②-5 「배지 부여·프로필 표시」 — 앱 Figma 에 Badge 화면이 없어 이 화면 끝에 둔다.
|
||||
class TierDetailScreen extends StatelessWidget {
|
||||
const TierDetailScreen({super.key, required this.tiers});
|
||||
const TierDetailScreen({
|
||||
super.key,
|
||||
required this.tiers,
|
||||
this.badges = const [],
|
||||
this.planetRepository,
|
||||
});
|
||||
|
||||
final List<PlanetTier> tiers;
|
||||
final List<MyBadge> badges;
|
||||
|
||||
/// 기본 행성이 맨 앞, 나머지는 기여 POP 높은 순.
|
||||
/// 행성 카드를 누르면 그 팬덤의 Passport History(팬덤 역사 · 내 기록)를 연다. null 이면 열지 않는다.
|
||||
final PlanetRepositoryFactory? planetRepository;
|
||||
|
||||
/// 기본 행성이 맨 앞, 나머지는 가입 중 → 탈퇴 순, 같은 구분 안에서는 Tier · 기여 POP 높은 순.
|
||||
List<PlanetTier> get ordered {
|
||||
final primary = tiers.where((p) => p.isPrimary).toList();
|
||||
final rest = tiers.where((p) => !p.isPrimary).toList()
|
||||
..sort((a, b) => b.contributedPop.compareTo(a.contributedPop));
|
||||
..sort((a, b) {
|
||||
if (a.joined != b.joined) return a.joined ? -1 : 1;
|
||||
final byTier = b.passportTier.index.compareTo(a.passportTier.index);
|
||||
return byTier != 0 ? byTier : b.contributedPop.compareTo(a.contributedPop);
|
||||
});
|
||||
return [...primary, ...rest];
|
||||
}
|
||||
|
||||
@@ -128,9 +145,21 @@ class TierDetailScreen extends StatelessWidget {
|
||||
children: [
|
||||
for (final (i, planet) in list.indexed) ...[
|
||||
if (i > 0) const SizedBox(height: 16),
|
||||
_PlanetCard(
|
||||
planet: planet,
|
||||
progress: top == 0 ? 0 : planet.contributedPop / top,
|
||||
InkWell(
|
||||
onTap: planetRepository == null || planet.fandomId.isEmpty
|
||||
? null
|
||||
: () => Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (_) => PlanetHistoryScreen(
|
||||
repository: planetRepository!(planet.fandomId),
|
||||
fandomName: planet.fandomName,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: _PlanetCard(
|
||||
planet: planet,
|
||||
progress: top == 0 ? 0 : planet.contributedPop / top,
|
||||
),
|
||||
),
|
||||
if (i == 0 && planet.isPrimary && list.length > 1) ...[
|
||||
const SizedBox(height: 16),
|
||||
@@ -140,6 +169,19 @@ class TierDetailScreen extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
],
|
||||
if (badges.isNotEmpty) ...[
|
||||
const SizedBox(height: 24),
|
||||
Text('BADGE', style: myText(16, FontWeight.w600)),
|
||||
const SizedBox(height: 8),
|
||||
Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: [
|
||||
for (final badge in badges)
|
||||
Chip(label: Text(badge.label, style: myText(12, FontWeight.w500))),
|
||||
],
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -194,6 +236,15 @@ class _PlanetCard extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'PASSPORT ${planet.passportTier.label}',
|
||||
style: myText(
|
||||
14,
|
||||
FontWeight.w500,
|
||||
color: planet.joined ? AppColors.onCosmic : const Color(0xFF84868E),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
MyProgressBar(value: progress),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
|
||||
Reference in New Issue
Block a user