HOME 퀘스트 줄 분류 · 일시 정지 표기

This commit is contained in:
Sn-Kinos
2026-10-06 04:06:36 +09:00
parent 55f3f503a3
commit 65f73280aa
6 changed files with 79 additions and 22 deletions
@@ -156,8 +156,17 @@ class FirestoreQuestRepository implements QuestRepository {
return _walkSteps > 0 ? _walkSteps : null;
}
/// 목록 카드가 「일시 정지」로 보는 세션 — 진행완료가 아니고 Walk 가 아닌 남은 세션(앱이 꺼진
/// inProgress 포함). 카드 단계 판정([QuestStage.paused])과 같은 규칙이다. 아니면 null.
static QuestSession? pausedSessionOf(QuestType type, Map<String, dynamic> progress) {
final s = sessionOf(progress);
return s == null || type == QuestType.steps || s.state == QuestStage.completed
? null
: s;
}
/// 진행 세션(`questProgress.session` — `fn-quest-progress` 만 쓴다 · 원장 C-83).
static QuestSession? _sessionOf(Map<String, dynamic> progress) {
static QuestSession? sessionOf(Map<String, dynamic> progress) {
final raw = progress['session'];
if (raw is! Map) return null;
final m = Map<String, dynamic>.from(raw);
@@ -229,7 +238,7 @@ class FirestoreQuestRepository implements QuestRepository {
: type == QuestType.musicShake
? quest.intOr('bpm')
: dailyLimit;
final session = _sessionOf(progress);
final session = sessionOf(progress);
final cardGoal = authorUid.isEmpty ? goal : quest.intOr('goal', 1);
// 걸음은 화면 밖 걸음까지 실제 값(C-62) — 오늘 걸음, 없으면 세션의 마지막 값.
final walked = steps && session != null ? walk ?? session.progress : null;
@@ -71,16 +71,28 @@ class QuestIconBox extends StatelessWidget {
};
/// 일시 정지 표기 — 「카테고리 · 일시 정지 · 43/60」. 카드와 탭 위 캡슐이 같이 쓴다(원장 C-83).
String pausedLabel(QuestCard card, {bool title = false}) {
final session = card.session;
return [
if (!title) card.categoryName,
appL10n.questPaused,
if (title) card.title,
if (session != null && session.total > 0)
'${formatPop(session.progress)}/${formatPop(session.total)}',
].join(' · ');
}
String pausedLabel(QuestCard card, {bool title = false}) =>
title ? _paused(card.title, card.session, titleLast: true)
: _paused(card.categoryName, card.session);
String _paused(String lead, QuestSession? session, {bool titleLast = false}) => [
if (!titleLast) lead,
appL10n.questPaused,
if (titleLast) lead,
if (session != null && session.total > 0)
'${formatPop(session.progress)}/${formatPop(session.total)}',
].join(' · ');
/// 퀘스트 줄 · 카드의 보조 줄 — 일시 정지면 「카테고리 · 일시 정지 · 43/60」, 아니면 카테고리.
/// 진행중 탭 카드 · 「전체」 탭 맨 위 줄 · HOME TODAY'S QUEST 줄이 모두 이 표기를 쓴다
/// (10/6 실기기 — 맨 위 줄 · HOME 줄에만 일시 정지가 빠져 있었다).
/// [pausedSession] 은 `FirestoreQuestRepository.pausedSessionOf` 가 고른 세션이다.
String questSubLine(String category, QuestSession? pausedSession) =>
pausedSession == null ? category : _paused(category, pausedSession);
String questCardSubLine(QuestCard card) => card.stage == QuestStage.paused
? pausedLabel(card)
: card.categoryName;
/// 목록의 퀘스트 카드 한 장 — 시안 `264:46867` 카드(#1a1a1c r12 · 안쪽 20).
///
@@ -148,9 +160,7 @@ class QuestCardTile extends StatelessWidget {
const SizedBox(height: 6),
Text(
// 진행 상태 값 「일시 정지」 · 멈춘 진행값(원장 C-83 — 기존 카드 영역 안).
card.stage == QuestStage.paused
? pausedLabel(card)
: card.categoryName,
questCardSubLine(card),
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w400,
@@ -385,7 +395,7 @@ class QuestAdminRow extends StatelessWidget {
),
const SizedBox(height: 4),
Text(
card.categoryName,
questCardSubLine(card),
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,