사용자 화면 문구·표본 데이터 · 퀘스트 참여 흐름 · HOME 진입 구획 · 미니맵 · 공통 확인 창 배치 수정

This commit is contained in:
Sn-Kinos
2026-10-05 00:44:39 +09:00
parent c8d29d032b
commit 8a0297eb92
66 changed files with 1812 additions and 959 deletions
@@ -192,11 +192,6 @@ class _RankingBody extends StatelessWidget {
return ListView(
padding: const EdgeInsets.all(AppSpace.s4),
children: [
// 실데이터가 아니면 숨기지 않고 그대로 알린다.
if (data.mockNote case final note?) ...[
MockBadge(note: note),
const SizedBox(height: AppSpace.s3),
],
if (data.mine case final me?) ...[
Text(myLabel, style: _rt(24, AppColors.onCosmic, FontWeight.w500)),
const SizedBox(height: AppSpace.s4),
@@ -461,29 +456,3 @@ class _Podium extends StatelessWidget {
],
);
}
/// 실데이터가 아닌 자리를 숨기지 않고 그대로 알리는 배지 — 대조표 3-5.
/// 랭킹 화면과 행성 상세 FPI 탭이 같은 배지를 쓴다.
class MockBadge extends StatelessWidget {
const MockBadge({super.key, required this.note});
final String note;
@override
Widget build(BuildContext context) => Container(
width: double.infinity,
margin: const EdgeInsets.fromLTRB(AppSpace.s4, AppSpace.s3, AppSpace.s4, 0),
padding: const EdgeInsets.all(AppSpace.s3),
decoration: BoxDecoration(
color: AppColors.cosmicVoid,
borderRadius: BorderRadius.circular(AppRadius.sm),
border: Border.all(color: AppColors.neonViolet),
),
child: Text(
'MOCK · $note',
style: Theme.of(
context,
).textTheme.labelSmall?.copyWith(color: AppColors.neonViolet),
),
);
}
+3 -3
View File
@@ -130,7 +130,7 @@ class FpiRanking {
final FpiRankRow? mine;
/// 실데이터가 아닌 경우의 사유. null 이면 실연동이다.
/// 화면이 이 문구를 그대로 배지로 띄운다 — 숨기지 않는다.
/// 개발자 진단 · 테스트용이며 사용자 화면에는 내보내지 않는다(10/4 실기기 — MOCK 문구 노출).
final String? mockNote;
bool get isMock => mockNote != null;
@@ -279,8 +279,8 @@ class PlanetDetail {
final int members;
final List<LoungePost> posts;
/// 이 화면에 실데이터가 아닌 자리가 남아 있으면 그 사유. 화면이 그대로 배지로
/// 띄운다 — 숨기지 않는다(대조표 3-5).
/// 이 화면에 실데이터가 아닌 자리가 남아 있으면 그 사유.
/// 개발자 진단 · 테스트용이며 사용자 화면에는 내보내지 않는다(10/4 실기기 — MOCK 문구 노출).
final String? mockNote;
/// 육각형 그래프 정규화 기준.
@@ -383,11 +383,6 @@ class _FpiTab extends StatelessWidget {
padding: const EdgeInsets.all(16),
sliver: SliverList.list(
children: [
if (detail.mockNote case final note?)
Padding(
padding: const EdgeInsets.only(bottom: AppSpace.s3),
child: MockBadge(note: note),
),
const _NebulaFpi(),
],
),
@@ -400,12 +395,6 @@ class _FpiTab extends StatelessWidget {
padding: const EdgeInsets.fromLTRB(20, 16, 20, 16),
sliver: SliverList.list(
children: [
// 실데이터가 아닌 자리가 남아 있으면 숨기지 않고 그대로 알린다(대조표 3-5).
if (detail.mockNote case final note?)
Padding(
padding: const EdgeInsets.only(bottom: AppSpace.s3),
child: MockBadge(note: note),
),
// 침식·방어 진행 — `fn-eclipse-aggregate` 의 집계 문서와 샤드를 구독한다.
// TOTAL FPI 카드 위에 두는 이유는 침식이 곧 이 카드의 값을 깎기 때문이다
// (원장 B-55 — FPI 감소는 Eclipse 가 담당한다).
@@ -705,12 +694,17 @@ class _ScoreCard extends StatelessWidget {
),
Row(
children: [
// 순위가 없으면(집계 모집단 밖 · 0) 「전체 0위」 대신 「순위 집계 전」.
Text(
context.l10n.planetOverallRank('${score.rank}'),
score.rank > 0
? context.l10n.planetOverallRank('${score.rank}')
: context.l10n.planetRankNone,
style: _t(12, color),
),
const SizedBox(width: 4),
if (trend == 0)
if (score.rank <= 0)
const SizedBox.shrink()
else if (trend == 0)
Text(
'-',
style: _t(
@@ -765,7 +759,7 @@ class _ScoreCard extends StatelessWidget {
// 서버 산출값이 없으면 숫자를 짓지 않는다 — 「상위 100%」는
// 최하위라는 사실 주장이 되어 버린다(대조표 3-5).
score.myTopPercent == null
? context.l10n.planetTallying
? '—'
: context.l10n.planetTopPercent('${score.myTopPercent}'),
style: _t(10, AppColors.onCosmic, height: 1),
),
@@ -176,8 +176,10 @@ class FirestorePlanetRepository implements PlanetRepository {
trend: daily.isEmpty
? 0
: axes.intOr(_axisKey(metric)) - daily.intOr(_axisKey(metric)),
// 없으면 null — 화면이 숫자 대신 「집계 준비 중」을 띄운다.
myTopPercent: myTopOf(metric),
// 없으면 null — 화면이 숫자 대신 「—」를 띄운다. 행성 값이 0 이면
// 기여를 나눌 모수가 없으니 남아 있는 값(시드 등)도 쓰지 않는다.
myTopPercent:
axes.intOr(_axisKey(metric)) > 0 ? myTopOf(metric) : null,
),
],
posts: posts,