퀘스트 목록 페이지 판정 · 다시 읽기 · 캠페인 응원 수를 고유 후원자 기준으로

This commit is contained in:
Sn-Kinos
2026-10-06 02:19:40 +09:00
parent 807e446b8b
commit 82662b9b9f
8 changed files with 164 additions and 18 deletions
+44 -15
View File
@@ -85,11 +85,20 @@ class _QuestListScreenState extends State<QuestListScreen> {
setState(() {
_cards = cards;
_loading = false;
// 저장소는 걸러져 모자란 만큼 이어 읽고, 10장보다 적으면 문서가 끝난 것이다(QuestRepository.load).
_end = cards.length < 10;
if (pop != null) _pop = pop;
});
_fill();
}
/// 보이는 카드가 화면을 못 채우면(탭으로 걸러져 비었을 때 포함) 스크롤 없이도 다음 페이지를 읽는다.
/// 스크롤 리스너만 두면 걸러진 탭에서 다음 페이지로 갈 방법이 없다.
void _fill() => WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted || _end || _more || _loading) return;
if (!_scroll.hasClients || _scroll.position.maxScrollExtent <= 240) _loadMore();
});
Future<void> _loadMore() async {
if (_more || _end) return;
setState(() => _more = true);
@@ -98,8 +107,9 @@ class _QuestListScreenState extends State<QuestListScreen> {
setState(() {
_cards = [..._cards, ...next];
_more = false;
_end = next.isEmpty;
_end = next.length < 10;
});
_fill();
}
List<QuestCard> get _visible {
@@ -295,25 +305,44 @@ class _QuestListScreenState extends State<QuestListScreen> {
preferredSize: const Size.fromHeight(44),
child: QuestTabStrip(
selected: _tab,
onSelect: (tab) => setState(() => _tab = tab),
// 탭을 바꿀 때마다 다시 읽는다 — 「내 퀘스트」 검토 중 → 반려됨이 재진입 없이 바뀌게(2026-10-06 실기기).
onSelect: (tab) {
setState(() => _tab = tab);
_load();
},
),
),
),
body: _loading
? const Center(child: CircularProgressIndicator())
: _visible.isEmpty
? Center(
child: Text(
context.l10n.questTabEmpty,
style: Theme.of(context).textTheme.bodyMedium,
),
)
: ListView(
controller: _scroll,
// 아래 여백은 「새 퀘스트」 버튼(36)이 마지막 카드를 가리지 않게 둔다.
padding: const EdgeInsets.fromLTRB(16, 16, 16, 16 + 36 + 16),
children: _body(),
),
// 당겨서 새로고침 — 상태(검토 중 · 반려됨)와 헤더 보유 POP 을 다시 읽는다.
: RefreshIndicator(
onRefresh: _load,
child: _visible.isEmpty
? LayoutBuilder(
builder: (context, box) => ListView(
physics: const AlwaysScrollableScrollPhysics(),
children: [
SizedBox(
height: box.maxHeight,
child: Center(
child: Text(
context.l10n.questTabEmpty,
style: Theme.of(context).textTheme.bodyMedium,
),
),
),
],
),
)
: ListView(
controller: _scroll,
physics: const AlwaysScrollableScrollPhysics(),
// 아래 여백은 「새 퀘스트」 버튼(36)이 마지막 카드를 가리지 않게 둔다.
padding: const EdgeInsets.fromLTRB(16, 16, 16, 16 + 36 + 16),
children: _body(),
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: Material(
color: const Color(0xFF19191C),