퀘스트 목록 페이지 판정 · 다시 읽기 · 캠페인 응원 수를 고유 후원자 기준으로
This commit is contained in:
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user