HOME 퀘스트 줄 분류 · 일시 정지 표기
This commit is contained in:
@@ -11,7 +11,7 @@ library;
|
||||
import 'package:flutter/painting.dart' show Color;
|
||||
import '../../core/i18n/app_locale.dart';
|
||||
import '../../core/ui/planet_25d.dart' show planetColors;
|
||||
import '../quest/quest_data.dart' show QuestType;
|
||||
import '../quest/quest_data.dart' show QuestSession, QuestType;
|
||||
import '../inside/inside_data.dart' show InsideQuestion, SampleInsideRepository;
|
||||
|
||||
/// 팬덤 행성의 성장 상태. 정책 근거는 정책 설계서 §P-08.
|
||||
@@ -182,12 +182,16 @@ class QuestSummary {
|
||||
this.endsAt,
|
||||
this.type,
|
||||
this.category,
|
||||
this.pausedSession,
|
||||
});
|
||||
|
||||
/// 일시 정지 세션(원장 C-83). 있으면 보조 줄이 「카테고리 · 일시 정지 · n/m」.
|
||||
final QuestSession? pausedSession;
|
||||
|
||||
final String title;
|
||||
|
||||
/// 보조 줄 — 퀘스트 카테고리(사본 「오늘의 출석체크」 · 「커뮤니티」). 퀘스트 목록의
|
||||
/// 카테고리 이름과 같은 원천(`QuestType.label`).
|
||||
/// 카테고리 이름과 같은 원천(`QuestType.category`).
|
||||
final String? category;
|
||||
|
||||
/// `quests.type`. 줄 왼쪽 아이콘을 고르는 데만 쓴다(없으면 제목으로 고른다).
|
||||
|
||||
@@ -11,7 +11,7 @@ import 'home_data.dart';
|
||||
import '../inside/inside_repository_firestore.dart' show insideQuestionFrom;
|
||||
import '../quest/quest_data.dart' show QuestType;
|
||||
import '../quest/quest_repository_firestore.dart'
|
||||
show openTimeAttack, questTitle, questToday;
|
||||
show FirestoreQuestRepository, openTimeAttack, questTitle, questToday;
|
||||
import '../../core/i18n/app_locale.dart';
|
||||
|
||||
/// 홈의 실 서버 구현 — 화면 대조 원장 F1.
|
||||
@@ -413,7 +413,14 @@ class FirestoreHomeRepository implements HomeRepository {
|
||||
return QuestSummary(
|
||||
title: questTitle(quest),
|
||||
type: QuestType.parse(quest.strOr('type')),
|
||||
category: QuestType.parse(quest.strOr('type')).label,
|
||||
// 퀘스트 목록 · 상세와 같은 분류 표기(Figma `264:46867` 줄 아래 「커뮤니티」).
|
||||
category: QuestType.parse(quest.strOr('type')).category,
|
||||
pausedSession: progress == null
|
||||
? null
|
||||
: FirestoreQuestRepository.pausedSessionOf(
|
||||
QuestType.parse(quest.strOr('type')),
|
||||
progress,
|
||||
),
|
||||
rewardPop:
|
||||
openTimeAttack(quest)?.rewardPop ??
|
||||
QuestType.parse(quest.strOr('type')).rewardFrom(quest, policy),
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
|
||||
import '../../../core/theme/tokens.dart';
|
||||
import '../../../core/ui/app_icons.dart';
|
||||
import '../../quest/widgets/quest_card_tile.dart'
|
||||
show QuestIconBox, questImageFor;
|
||||
show QuestIconBox, questImageFor, questSubLine;
|
||||
import '../home_data.dart';
|
||||
|
||||
/// 홈 「TODAY'S QUEST」 묶음 — Figma 「홈」 `2097:16428`: 343×270 · r12 안에 343×90 줄
|
||||
@@ -98,7 +98,8 @@ class QuestRow extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
_sub(quest.category ?? ''),
|
||||
// 진행중 탭 카드와 같은 일시 정지 표기(원장 C-83).
|
||||
_sub(questSubLine(quest.category ?? '', quest.pausedSession)),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user