캠페인 실시간 랭킹 후원자 이름 · 위치 핀 도로명 주소
This commit is contained in:
@@ -1001,6 +1001,18 @@ class _CampaignDetailScreenState extends State<CampaignDetailScreen> {
|
||||
_spent += applied;
|
||||
_raised += applied;
|
||||
});
|
||||
// 실시간 랭킹(상위 3) · 모금액을 서버 값으로 다시 읽는다. 잔액 계산(_balance · _spent)은 그대로 둔다.
|
||||
try {
|
||||
final fresh = await widget.repository.detail(widget.campaignId);
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_detail = fresh;
|
||||
_raised = fresh.card.raisedPop;
|
||||
});
|
||||
}
|
||||
} on Object catch (_) {
|
||||
// 다시 읽기 실패는 후원 결과와 무관하다 — 앞 화면을 그대로 둔다.
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _openRanking(CampaignDetail detail) =>
|
||||
|
||||
@@ -177,12 +177,15 @@ class FirestoreCampaignRepository implements CampaignRepository {
|
||||
RankWindow.weekly => DateTime.now().subtract(const Duration(days: 7)),
|
||||
};
|
||||
final totals = <String, int>{};
|
||||
final names = <String, String>{};
|
||||
for (final d in snap.docs) {
|
||||
final m = d.data();
|
||||
if (since != null && m.dateOr('createdAt', since).isBefore(since))
|
||||
continue;
|
||||
final uid = m.strOr('uid');
|
||||
totals[uid] = (totals[uid] ?? 0) + m.intOr('amount');
|
||||
// 서버가 후원 때 실은 공개 닉네임(`donorName`, M-7). 예전 후원에는 없어 「팬」이다.
|
||||
if (m.strOr('donorName').isNotEmpty) names[uid] = m.strOr('donorName');
|
||||
}
|
||||
final me = _backend.uid;
|
||||
final rows = totals.entries.toList()
|
||||
@@ -191,8 +194,10 @@ class FirestoreCampaignRepository implements CampaignRepository {
|
||||
for (var i = 0; i < rows.length; i++)
|
||||
ContributorRank(
|
||||
rank: i + 1,
|
||||
// 남의 이름은 서버에 읽을 자리가 없다. UID 는 화면에 내보내지 않는다.
|
||||
name: rows[i].key == me ? appL10n.commonMe : appL10n.commonFan,
|
||||
// UID · 이메일은 화면에 내보내지 않는다(G-07) — 공개 닉네임만.
|
||||
name: rows[i].key == me
|
||||
? appL10n.commonMe
|
||||
: publicName(names[rows[i].key]),
|
||||
pop: rows[i].value,
|
||||
isMe: rows[i].key == me,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user