번역 평가 버튼 · 내 퀘스트 검토 버튼 · MY 질문 상세 · MY 완료 퀘스트 수 · 행성/성운 칸 · 라운지 빈 상태 수정

This commit is contained in:
Sn-Kinos
2026-10-05 15:12:33 +09:00
parent 5ad229b971
commit f84d696c21
18 changed files with 666 additions and 365 deletions
+116 -116
View File
@@ -71,120 +71,115 @@ enum PopTxType {
/// Functions 의 `ReasonCode`(`firebase/functions/src/ledger/ledger.ts`)와 짝이며,
/// 모르는 코드는 원문을 그대로 내보이지 않고 중립 문구로 접는다 — 사용자 화면에
/// `QUEST_MUSIC_SHAKE` 같은 내부 식별자가 새면 고장으로 읽힌다.
({String title, String type}) popReasonLabel(String reasonCode) =>
switch (reasonCode) {
'QUEST_STEPS' => (
title: appL10n.popReasonQuestSteps,
type: appL10n.popTypeQuest,
),
'QUEST_MUSIC_SHAKE' => (
title: appL10n.popReasonQuestMusicShake,
type: appL10n.popTypeQuest,
),
'QUEST_PLACE' => (
title: appL10n.popReasonQuestPlace,
type: appL10n.popTypeQuest,
),
'QUEST_ATTEND' => (
title: appL10n.popReasonQuestAttend,
type: appL10n.popTypeQuest,
),
'QUEST_UGC' => (
title: appL10n.popReasonQuestUgc,
type: appL10n.popTypeQuest,
),
'QUEST_FEE' => (
title: appL10n.popReasonQuestFee,
type: appL10n.popTypeFee,
),
'QUEST_POOL_DEPOSIT' => (
title: appL10n.popReasonQuestPoolDeposit,
type: appL10n.popTypeQuest,
),
// 정상 종료 반환(C-09)과 공개 전 실패 환불은 사용자에게 같은 「반환」이다.
'QUEST_POOL_RETURN' || 'QUEST_POOL_REFUND' => (
title: appL10n.popReasonQuestPoolReturn,
type: appL10n.popTxRefund,
),
'QUEST_TIMEATTACK' => (
title: appL10n.popReasonQuestTimeAttack,
type: appL10n.popTypeQuest,
),
'AD_REWARD' => (
title: appL10n.popReasonAdReward,
type: appL10n.popTypeReward,
),
'HERO_DROP' => (
title: appL10n.popReasonHeroDrop,
type: appL10n.popTypeReward,
),
'HERO_DROP_TRIGGER' => (
title: appL10n.popReasonHeroDropTrigger,
type: appL10n.commonContribute,
),
'TRANSLATION' => (
title: appL10n.popReasonTranslation,
type: appL10n.popTypeReward,
),
'IAP_PURCHASE' => (
title: appL10n.popReasonIapPurchase,
type: appL10n.popTypePayment,
),
'FOCUS_DAILY' => (
title: appL10n.popReasonFocusDaily,
type: appL10n.popTypeSubscription,
),
'PREREG_BONUS' => (
title: appL10n.popReasonPreregBonus,
type: appL10n.popTypeReward,
),
'REFERRAL_REWARD' => (
// 사본 POP 내역 `554:23742` 「친구 초대 · 레퍼럴」.
title: appL10n.popReasonReferral,
type: appL10n.popTypeReferral,
),
'ADMIN_GRANT' => (
title: appL10n.popReasonAdminGrant,
type: appL10n.popTypeAdmin,
),
'ADMIN_CLAWBACK' => (
title: appL10n.popReasonAdminClawback,
type: appL10n.popTypeAdmin,
),
'CAMPAIGN_FUND' => (
title: appL10n.popReasonCampaignFund,
type: appL10n.commonContribute,
),
'CAMPAIGN_REFUND' => (
title: appL10n.popReasonCampaignRefund,
type: appL10n.popTxRefund,
),
'CAMPAIGN_FEE_REFUND' => (
title: appL10n.popReasonCampaignFeeRefund,
type: appL10n.popTxRefund,
),
'CAMPAIGN_FEE' => (
title: appL10n.popReasonCampaignFee,
type: appL10n.popTypeFee,
),
'QNA_BOUNTY' => (
title: appL10n.popReasonQnaBounty,
type: appL10n.commonContribute,
),
'QNA_REFUND' => (
title: appL10n.popReasonQnaRefund,
type: appL10n.popTxRefund,
),
'QNA_REWARD' => (
title: appL10n.popReasonQnaReward,
type: appL10n.popTypeReward,
),
'ECLIPSE_DEFENSE' => (
title: appL10n.popReasonEclipseDefense,
type: appL10n.commonContribute,
),
_ => (title: appL10n.popReasonOther, type: appL10n.commonEtc),
};
({String title, String type}) popReasonLabel(
String reasonCode,
) => switch (reasonCode) {
'QUEST_STEPS' => (
title: appL10n.popReasonQuestSteps,
type: appL10n.popTypeQuest,
),
'QUEST_MUSIC_SHAKE' => (
title: appL10n.popReasonQuestMusicShake,
type: appL10n.popTypeQuest,
),
'QUEST_PLACE' => (
title: appL10n.popReasonQuestPlace,
type: appL10n.popTypeQuest,
),
'QUEST_ATTEND' => (
title: appL10n.popReasonQuestAttend,
type: appL10n.popTypeQuest,
),
'QUEST_UGC' => (title: appL10n.popReasonQuestUgc, type: appL10n.popTypeQuest),
'QUEST_FEE' => (title: appL10n.popReasonQuestFee, type: appL10n.popTypeFee),
'QUEST_POOL_DEPOSIT' => (
title: appL10n.popReasonQuestPoolDeposit,
type: appL10n.popTypeQuest,
),
// 정상 종료 반환(C-09)과 공개 전 실패 환불은 사용자에게 같은 「반환」이다.
'QUEST_POOL_RETURN' || 'QUEST_POOL_REFUND' => (
title: appL10n.popReasonQuestPoolReturn,
type: appL10n.popTxRefund,
),
'QUEST_TIMEATTACK' => (
title: appL10n.popReasonQuestTimeAttack,
type: appL10n.popTypeQuest,
),
'AD_REWARD' => (
title: appL10n.popReasonAdReward,
type: appL10n.popTypeReward,
),
'HERO_DROP' => (
title: appL10n.popReasonHeroDrop,
type: appL10n.popTypeReward,
),
'HERO_DROP_TRIGGER' => (
title: appL10n.popReasonHeroDropTrigger,
type: appL10n.commonContribute,
),
'TRANSLATION' => (
title: appL10n.popReasonTranslation,
type: appL10n.popTypeReward,
),
'IAP_PURCHASE' => (
title: appL10n.popReasonIapPurchase,
type: appL10n.popTypePayment,
),
'FOCUS_DAILY' => (
title: appL10n.popReasonFocusDaily,
type: appL10n.popTypeSubscription,
),
'PREREG_BONUS' => (
title: appL10n.popReasonPreregBonus,
type: appL10n.popTypeReward,
),
'REFERRAL_REWARD' => (
// 사본 POP 내역 `554:23742` 「친구 초대 · 레퍼럴」.
title: appL10n.popReasonReferral,
type: appL10n.popTypeReferral,
),
'ADMIN_GRANT' => (
title: appL10n.popReasonAdminGrant,
type: appL10n.popTypeAdmin,
),
'ADMIN_CLAWBACK' => (
title: appL10n.popReasonAdminClawback,
type: appL10n.popTypeAdmin,
),
'CAMPAIGN_FUND' => (
title: appL10n.popReasonCampaignFund,
type: appL10n.commonContribute,
),
'CAMPAIGN_REFUND' => (
title: appL10n.popReasonCampaignRefund,
type: appL10n.popTxRefund,
),
'CAMPAIGN_FEE_REFUND' => (
title: appL10n.popReasonCampaignFeeRefund,
type: appL10n.popTxRefund,
),
'CAMPAIGN_FEE' => (
title: appL10n.popReasonCampaignFee,
type: appL10n.popTypeFee,
),
'QNA_BOUNTY' => (
title: appL10n.popReasonQnaBounty,
type: appL10n.commonContribute,
),
'QNA_REFUND' => (
title: appL10n.popReasonQnaRefund,
type: appL10n.popTxRefund,
),
'QNA_REWARD' => (
title: appL10n.popReasonQnaReward,
type: appL10n.popTypeReward,
),
'ECLIPSE_DEFENSE' => (
title: appL10n.popReasonEclipseDefense,
type: appL10n.commonContribute,
),
_ => (title: appL10n.popReasonOther, type: appL10n.commonEtc),
};
/// 레벨 칭호 — 정책 원장 **C-18 · B-66**.
///
@@ -586,7 +581,11 @@ const int nicknameMaxLength = 20;
/// 운영 사칭으로 읽힐 수 있는 이름 — 대소문자 무시 부분 일치로 막는다.
/// `firestore.rules` 의 `nicknameOk` 가 같은 목록을 본다.
const List<String> reservedNicknameWords = [
'fanuzu', '운영팀', '관리자', 'admin', 'official',
'fanuzu',
'운영팀',
'관리자',
'admin',
'official',
];
/// 닉네임 없는 작성자 표기([storedFanName] 「팬」)와 그 번역 — 정확히 일치하면 막는다.
@@ -603,7 +602,8 @@ String normalizeNickname(String nickname) => nickname
bool nicknameReserved(String nickname) {
final key = normalizeNickname(nickname);
return reservedFanNames.contains(key) || reservedNicknameWords.any(key.contains);
return reservedFanNames.contains(key) ||
reservedNicknameWords.any(key.contains);
}
/// 차단한 계정 한 건 — 설계서 `users/{uid}/blocks/{targetUid}`.