Passport Tier 팬덤 단위 · 활동 Badge · 진화 Emblem · Eclipse 참여 기록
This commit is contained in:
@@ -183,6 +183,7 @@ GoRouter buildRouter(AuthRepository auth, {Repositories? repositories}) {
|
||||
insides: repos.inside,
|
||||
translation: repos.translation,
|
||||
galaxy: repos.galaxy,
|
||||
planetRepository: repos.planet,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -238,7 +238,7 @@ enum PassportTier {
|
||||
|
||||
final String label;
|
||||
|
||||
/// 서버 문자열(`users.passportTier`). 없거나 모르는 값은 기본 SILVER.
|
||||
/// 서버 문자열(`users/{uid}/passports/{fandomId}.tier`). 없거나 모르는 값은 기본 SILVER.
|
||||
static PassportTier parse(String raw) => PassportTier.values.firstWhere(
|
||||
(t) => t.label == raw.toUpperCase(),
|
||||
orElse: () => PassportTier.silver,
|
||||
@@ -250,13 +250,16 @@ enum PassportTier {
|
||||
/// *갤럭시에서 선택된 기본 행성의 티어를 메인으로 상단에 위치 ·*
|
||||
/// *나머지 행성 티어는 티어 높은순으로 소팅*
|
||||
///
|
||||
/// 칭호는 개인 `userLevel` 에서만 나온다(C-18). 행성별로는 **기여 실적(POP)만**
|
||||
/// 보인다 — 행성 기여로 칭호를 매기면 MY 카드와 칭호가 갈린다(인계 결함).
|
||||
/// 칭호는 개인 `userLevel` 에서만 나온다(C-18). 행성별로는 **그 팬덤 Passport Tier 와 기여 실적**이
|
||||
/// 보인다 — Tier 는 사용자 × 팬덤 단위다(10/3 통합회신 #10 · 9/21 회신 5절).
|
||||
class PlanetTier {
|
||||
const PlanetTier({
|
||||
required this.fandomName,
|
||||
required this.contributedPop,
|
||||
this.isPrimary = false,
|
||||
this.fandomId = '',
|
||||
this.passportTier = PassportTier.silver,
|
||||
this.joined = true,
|
||||
});
|
||||
|
||||
final String fandomName;
|
||||
@@ -264,6 +267,39 @@ class PlanetTier {
|
||||
|
||||
/// 갤럭시에서 고른 기본 행성인가.
|
||||
final bool isPrimary;
|
||||
|
||||
final String fandomId;
|
||||
|
||||
/// 그 팬덤의 Passport Tier — `users/{uid}/passports/{fandomId}.tier`.
|
||||
final PassportTier passportTier;
|
||||
|
||||
/// 지금 가입 중인가. false 면 탈퇴한 팬덤의 보존 기록(FX §7.1 ARCHIVED).
|
||||
final bool joined;
|
||||
}
|
||||
|
||||
/// 보유 Badge 한 건 — `users/{uid}/badges/{badgeId}`(서버 판정). 상세정의 4장 · 22장 · 별첨 B.
|
||||
class MyBadge {
|
||||
const MyBadge({required this.id, required this.kind, required this.stage, this.axis = '',
|
||||
this.memberNo, this.toStage});
|
||||
|
||||
final String id;
|
||||
|
||||
/// `activity`(활동 카테고리 7단계) · `founder100`(팬덤/성운 최초 100명) · `evolution`(진화 기념).
|
||||
final String kind;
|
||||
final int stage;
|
||||
|
||||
/// 활동 Badge 카테고리(FPI 축 키).
|
||||
final String axis;
|
||||
final int? memberNo;
|
||||
final int? toStage;
|
||||
|
||||
/// 화면 표기. 축 이름은 답변서 v1.1 Q3 확정 표기(영문)라 번역하지 않는다.
|
||||
String get label => switch (kind) {
|
||||
'activity' => '${axis.toUpperCase()} · $stage/7',
|
||||
'founder100' => 'FIRST 100 · #${(memberNo ?? 0).toString().padLeft(3, '0')}',
|
||||
'evolution' => 'EVOLUTION · STAGE ${toStage ?? stage}',
|
||||
_ => id,
|
||||
};
|
||||
}
|
||||
|
||||
/// MY 첫 화면이 쓰는 값.
|
||||
@@ -279,6 +315,7 @@ class MyProfile {
|
||||
required this.steps,
|
||||
required this.completedQuests,
|
||||
required this.planetTiers,
|
||||
this.badges = const [],
|
||||
this.photoLabel,
|
||||
this.photoUrl,
|
||||
this.originNo,
|
||||
@@ -296,7 +333,7 @@ class MyProfile {
|
||||
/// 레벨 — `users.userLevel`. **서버가 준 값**이며 앱이 다시 매기지 않는다.
|
||||
final int userLevel;
|
||||
|
||||
/// Passport Tier — `users.passportTier`(B-65).
|
||||
/// 대표 팬덤의 Passport Tier(B-65 · 10/3 #10 사용자 × 팬덤). 팬덤별 값은 [planetTiers].
|
||||
final PassportTier passportTier;
|
||||
|
||||
/// 보유 POP(활동).
|
||||
@@ -308,6 +345,9 @@ class MyProfile {
|
||||
|
||||
final List<PlanetTier> planetTiers;
|
||||
|
||||
/// 보유 Badge — 별첨 1 ②-5 「등급·배지 부여·프로필 표시」.
|
||||
final List<MyBadge> badges;
|
||||
|
||||
/// 프로필 사진. 자산이 아직 없어 라벨로 둔다.
|
||||
final String? photoLabel;
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ import '../../core/i18n/app_locale.dart';
|
||||
/// - 프로필 `users/{uid}` (nickname · photoUrl · originNo · steps)
|
||||
/// - 완료 퀘스트 `users/{uid}/verifiedCompletions` 표식 수(무효 제외)
|
||||
/// - 누적 기여 POP `users/{uid}.totalContributedPop`(`fn-pop-spend` 가 갱신, 설계서 §3.6)
|
||||
/// - 레벨 `users/{uid}.{userExp, userLevel}` · Passport `users/{uid}.passportTier`
|
||||
/// (C-18 · B-65). 필드가 없는 기존 사용자는 Lv.1 · SILVER 로 둔다.
|
||||
/// - 레벨 `users/{uid}.{userExp, userLevel}`(C-18). 필드가 없는 기존 사용자는 Lv.1.
|
||||
/// - Passport `users/{uid}/passports/{fandomId}.tier` — **팬덤별**(10/3 #10 · 9/21 5절). 없으면 SILVER.
|
||||
/// 탈퇴한 팬덤의 Passport 도 지우지 않고 보인다(ARCHIVED).
|
||||
/// - Badge `users/{uid}/badges`(상세정의 4장 · 별첨 1 ②-5)
|
||||
/// - 잔액 `users/{uid}/wallet/main.activityBalance`
|
||||
/// - 행성별 기여 `fandoms/{fandomId}` + `fandoms/{fandomId}/members/{uid}.contributedPop`
|
||||
/// - POP 원장 `users/{uid}/popTransactions` (최신순 · 커서 `createdAt`)
|
||||
@@ -64,22 +66,47 @@ class FirestoreMyRepository extends SampleMyRepository {
|
||||
final user = (await userF).data() ?? const <String, dynamic>{};
|
||||
final wallet = (await walletF).data() ?? const <String, dynamic>{};
|
||||
|
||||
final fandomId = user.strOr('fandomId');
|
||||
var tiers = const <PlanetTier>[];
|
||||
if (fandomId.isNotEmpty) {
|
||||
final fandomF = db.doc('fandoms/$fandomId').get();
|
||||
final memberF = db.doc('fandoms/$fandomId/members/$uid').get();
|
||||
final fandom = (await fandomF).data() ?? const <String, dynamic>{};
|
||||
final member = (await memberF).data() ?? const <String, dynamic>{};
|
||||
tiers = [
|
||||
PlanetTier(
|
||||
fandomName: fandom.strOr('name', fandomId),
|
||||
// 팬덤별 누적 기여 POP. `fn-pop-spend` 가 기여 차감 때 함께 올린다.
|
||||
contributedPop: member.intOr('contributedPop'),
|
||||
isPrimary: true,
|
||||
final primaryId = user.strOr('primaryFandomId', user.strOr('fandomId'));
|
||||
final joinedIds = (user['fandomIds'] as List?)?.whereType<String>().toSet() ?? <String>{};
|
||||
if (primaryId.isNotEmpty) joinedIds.add(primaryId);
|
||||
// 규칙 배포 전 서버에서는 하위 컬렉션 읽기가 거부된다 — MY 전체를 떨어뜨리지 않는다.
|
||||
Future<List<QueryDocumentSnapshot<Map<String, dynamic>>>> docsOf(String path) => db
|
||||
.collection(path)
|
||||
.get()
|
||||
.then((q) => q.docs, onError: (Object _) => <QueryDocumentSnapshot<Map<String, dynamic>>>[]);
|
||||
final passportsF = docsOf('users/$uid/passports');
|
||||
final badgesF = docsOf('users/$uid/badges');
|
||||
final passports = {for (final d in await passportsF) d.id: d.data()};
|
||||
final ids = {...joinedIds, ...passports.keys};
|
||||
final tiers = await Future.wait(ids.map((id) async {
|
||||
final joined = joinedIds.contains(id);
|
||||
final fandom = (await db.doc('fandoms/$id').get()).data() ?? const <String, dynamic>{};
|
||||
final member = joined
|
||||
? (await db.doc('fandoms/$id/members/$uid').get()).data() ?? const <String, dynamic>{}
|
||||
: const <String, dynamic>{};
|
||||
final passport = passports[id] ?? const <String, dynamic>{};
|
||||
return PlanetTier(
|
||||
fandomId: id,
|
||||
fandomName: fandom.strOr('name', id),
|
||||
// 팬덤별 누적 기여 POP. 가입 중이면 멤버 문서(`fn-pop-spend` 가 올림), 탈퇴했으면 Passport 보존값.
|
||||
contributedPop: joined ? member.intOr('contributedPop') : passport.intOr('contributedPop'),
|
||||
isPrimary: id == primaryId,
|
||||
passportTier: PassportTier.parse(passport.strOr('tier')),
|
||||
joined: joined,
|
||||
);
|
||||
}));
|
||||
final primaryTier = tiers.where((t) => t.isPrimary).firstOrNull?.passportTier ?? PassportTier.silver;
|
||||
final badges = [
|
||||
for (final d in await badgesF)
|
||||
MyBadge(
|
||||
id: d.id,
|
||||
kind: d.data().strOr('kind'),
|
||||
stage: d.data().intOr('stage'),
|
||||
axis: d.data().strOr('axis'),
|
||||
memberNo: d.data()['memberNo'] is num ? (d.data()['memberNo'] as num).toInt() : null,
|
||||
toStage: d.data()['toStage'] is num ? (d.data()['toStage'] as num).toInt() : null,
|
||||
),
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
// 닉네임이 아직 없으면(온보딩 전) 중립 이름으로 부른다. 「— 님」은 고장처럼 보인다.
|
||||
// **이메일 앞부분을 쓰지 않는다** — 프로필 수정이 그 값을 그대로
|
||||
@@ -95,11 +122,12 @@ class FirestoreMyRepository extends SampleMyRepository {
|
||||
contributedPop: user.intOr('totalContributedPop'),
|
||||
userExp: user.intOr('userExp'),
|
||||
userLevel: user.intOr('userLevel').clamp(1, 1 << 31),
|
||||
passportTier: PassportTier.parse(user.strOr('passportTier')),
|
||||
passportTier: primaryTier,
|
||||
balancePop: wallet.intOr('activityBalance'),
|
||||
steps: user.intOr('steps'),
|
||||
completedQuests: await completedF,
|
||||
planetTiers: tiers,
|
||||
badges: badges,
|
||||
photoUrl: photoUrl.isEmpty ? null : photoUrl,
|
||||
originNo: user.containsKey('originNo') ? user.intOr('originNo') : null,
|
||||
);
|
||||
|
||||
@@ -12,6 +12,7 @@ import '../campaign/campaign_data.dart' show CampaignRepository;
|
||||
import '../galaxy/galaxy_data.dart';
|
||||
import '../galaxy/galaxy_home_screen.dart' show GalaxyHomeScreen;
|
||||
import '../inside/inside_data.dart' show InsideRepository;
|
||||
import '../planet/planet_data.dart' show PlanetRepositoryFactory;
|
||||
import '../translation/translation_data.dart' show TranslationRepository;
|
||||
import 'my_data.dart';
|
||||
import 'my_lists_screen.dart';
|
||||
@@ -36,10 +37,14 @@ class MyScreen extends StatefulWidget {
|
||||
this.insides,
|
||||
this.translation,
|
||||
this.galaxy = const SampleGalaxyRepository(),
|
||||
this.planetRepository,
|
||||
});
|
||||
|
||||
final MyRepository repository;
|
||||
|
||||
/// 팬덤별 Passport History(9/21 5절) — 티어 상세에서 행성을 누르면 그 팬덤의 기록을 연다.
|
||||
final PlanetRepositoryFactory? planetRepository;
|
||||
|
||||
/// 「행성/성운」 칸 — GALAXY 「내 행성」과 같은 가입 목록(`users/{uid}/memberships`)을 읽는다.
|
||||
final GalaxyRepository galaxy;
|
||||
|
||||
@@ -196,7 +201,11 @@ class _MyScreenState extends State<MyScreen> {
|
||||
profile: profile,
|
||||
onInfo: () => _push(const TierInfoScreen()),
|
||||
onDetail: () => _push(
|
||||
TierDetailScreen(tiers: profile.planetTiers),
|
||||
TierDetailScreen(
|
||||
tiers: profile.planetTiers,
|
||||
badges: profile.badges,
|
||||
planetRepository: widget.planetRepository,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import '../../core/theme/tokens.dart';
|
||||
import '../home/home_screen.dart' show formatPop;
|
||||
import '../planet/planet_data.dart' show PlanetRepositoryFactory;
|
||||
import '../planet/planet_history_screen.dart';
|
||||
import 'my_data.dart';
|
||||
import 'widgets/my_cards.dart';
|
||||
import '../../core/i18n/app_locale.dart';
|
||||
@@ -98,17 +100,32 @@ class TierInfoScreen extends StatelessWidget {
|
||||
/// 명세 `549:22206` — *갤럭시에서 선택된 기본 행성의 티어를 메인으로 상단에 위치 ·*
|
||||
/// *나머지 행성 티어는 티어 높은순으로 소팅*
|
||||
///
|
||||
/// 칭호는 개인 레벨에서만 나오므로(C-18) 행성별로는 **기여 실적(POP)만** 보인다.
|
||||
/// 칭호는 개인 레벨에서만 나오므로(C-18) 행성별로는 **그 팬덤 Passport Tier 와 기여 실적**을 보인다
|
||||
/// (10/3 #10 사용자 × 팬덤). 탈퇴한 팬덤도 기록을 지우지 않고 아래에 둔다(9/21 5절 · FX §7.1 ARCHIVED).
|
||||
/// 아래 BADGE 는 별첨 1 ②-5 「배지 부여·프로필 표시」 — 앱 Figma 에 Badge 화면이 없어 이 화면 끝에 둔다.
|
||||
class TierDetailScreen extends StatelessWidget {
|
||||
const TierDetailScreen({super.key, required this.tiers});
|
||||
const TierDetailScreen({
|
||||
super.key,
|
||||
required this.tiers,
|
||||
this.badges = const [],
|
||||
this.planetRepository,
|
||||
});
|
||||
|
||||
final List<PlanetTier> tiers;
|
||||
final List<MyBadge> badges;
|
||||
|
||||
/// 기본 행성이 맨 앞, 나머지는 기여 POP 높은 순.
|
||||
/// 행성 카드를 누르면 그 팬덤의 Passport History(팬덤 역사 · 내 기록)를 연다. null 이면 열지 않는다.
|
||||
final PlanetRepositoryFactory? planetRepository;
|
||||
|
||||
/// 기본 행성이 맨 앞, 나머지는 가입 중 → 탈퇴 순, 같은 구분 안에서는 Tier · 기여 POP 높은 순.
|
||||
List<PlanetTier> get ordered {
|
||||
final primary = tiers.where((p) => p.isPrimary).toList();
|
||||
final rest = tiers.where((p) => !p.isPrimary).toList()
|
||||
..sort((a, b) => b.contributedPop.compareTo(a.contributedPop));
|
||||
..sort((a, b) {
|
||||
if (a.joined != b.joined) return a.joined ? -1 : 1;
|
||||
final byTier = b.passportTier.index.compareTo(a.passportTier.index);
|
||||
return byTier != 0 ? byTier : b.contributedPop.compareTo(a.contributedPop);
|
||||
});
|
||||
return [...primary, ...rest];
|
||||
}
|
||||
|
||||
@@ -128,9 +145,21 @@ class TierDetailScreen extends StatelessWidget {
|
||||
children: [
|
||||
for (final (i, planet) in list.indexed) ...[
|
||||
if (i > 0) const SizedBox(height: 16),
|
||||
_PlanetCard(
|
||||
planet: planet,
|
||||
progress: top == 0 ? 0 : planet.contributedPop / top,
|
||||
InkWell(
|
||||
onTap: planetRepository == null || planet.fandomId.isEmpty
|
||||
? null
|
||||
: () => Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (_) => PlanetHistoryScreen(
|
||||
repository: planetRepository!(planet.fandomId),
|
||||
fandomName: planet.fandomName,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: _PlanetCard(
|
||||
planet: planet,
|
||||
progress: top == 0 ? 0 : planet.contributedPop / top,
|
||||
),
|
||||
),
|
||||
if (i == 0 && planet.isPrimary && list.length > 1) ...[
|
||||
const SizedBox(height: 16),
|
||||
@@ -140,6 +169,19 @@ class TierDetailScreen extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
],
|
||||
if (badges.isNotEmpty) ...[
|
||||
const SizedBox(height: 24),
|
||||
Text('BADGE', style: myText(16, FontWeight.w600)),
|
||||
const SizedBox(height: 8),
|
||||
Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: [
|
||||
for (final badge in badges)
|
||||
Chip(label: Text(badge.label, style: myText(12, FontWeight.w500))),
|
||||
],
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -194,6 +236,15 @@ class _PlanetCard extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'PASSPORT ${planet.passportTier.label}',
|
||||
style: myText(
|
||||
14,
|
||||
FontWeight.w500,
|
||||
color: planet.joined ? AppColors.onCosmic : const Color(0xFF84868E),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
MyProgressBar(value: progress),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
|
||||
@@ -314,6 +314,11 @@ enum PlanetHistoryKind {
|
||||
questReward,
|
||||
companyAdBonus,
|
||||
funding,
|
||||
|
||||
/// PASSPORT Stamp — Eclipse 성공 참여(FX §5.2) · 진화 기념 Emblem(상세정의 22장) · 최초 100명 Badge(별첨 B).
|
||||
eclipseSuccess,
|
||||
emblemEvolution,
|
||||
founderBadge,
|
||||
}
|
||||
|
||||
class PlanetHistoryEntry {
|
||||
@@ -325,6 +330,7 @@ class PlanetHistoryEntry {
|
||||
this.toStage,
|
||||
this.participationConfirmed = false,
|
||||
this.amount,
|
||||
this.memberNo,
|
||||
});
|
||||
final String id;
|
||||
final PlanetHistoryKind kind;
|
||||
@@ -333,6 +339,9 @@ class PlanetHistoryEntry {
|
||||
final int? toStage;
|
||||
final bool participationConfirmed;
|
||||
final int? amount;
|
||||
|
||||
/// 최초 100명 Badge 의 순번.
|
||||
final int? memberNo;
|
||||
}
|
||||
|
||||
class PlanetHistoryPage {
|
||||
|
||||
@@ -95,6 +95,9 @@ class _PlanetHistoryScreenState extends State<PlanetHistoryScreen> {
|
||||
PlanetHistoryKind.questReward => Icons.task_alt,
|
||||
PlanetHistoryKind.companyAdBonus => Icons.play_circle_outline,
|
||||
PlanetHistoryKind.funding => Icons.favorite_border,
|
||||
PlanetHistoryKind.eclipseSuccess => Icons.shield_outlined,
|
||||
PlanetHistoryKind.emblemEvolution => Icons.military_tech_outlined,
|
||||
PlanetHistoryKind.founderBadge => Icons.workspace_premium_outlined,
|
||||
}),
|
||||
title: Text(switch (item.kind) {
|
||||
PlanetHistoryKind.evolution => context.l10n.historyEvolution(
|
||||
@@ -107,6 +110,12 @@ class _PlanetHistoryScreenState extends State<PlanetHistoryScreen> {
|
||||
PlanetHistoryKind.questReward => context.l10n.historyQuest,
|
||||
PlanetHistoryKind.companyAdBonus => context.l10n.historyAdBonus,
|
||||
PlanetHistoryKind.funding => context.l10n.historyFunding,
|
||||
PlanetHistoryKind.eclipseSuccess =>
|
||||
context.l10n.historyEclipseSuccess,
|
||||
PlanetHistoryKind.emblemEvolution =>
|
||||
'${context.l10n.historyEmblemEvolution} · STAGE ${item.toStage ?? ''}',
|
||||
PlanetHistoryKind.founderBadge =>
|
||||
'${context.l10n.historyFounderBadge} · #${(item.memberNo ?? 0).toString().padLeft(3, '0')}',
|
||||
}),
|
||||
subtitle: Text(
|
||||
[
|
||||
|
||||
@@ -59,6 +59,9 @@ class FirestorePlanetRepository implements PlanetRepository {
|
||||
'quest_reward' => PlanetHistoryKind.questReward,
|
||||
'company_ad_bonus' => PlanetHistoryKind.companyAdBonus,
|
||||
'funding' => PlanetHistoryKind.funding,
|
||||
'eclipse_success' => PlanetHistoryKind.eclipseSuccess,
|
||||
'emblem_evolution' => PlanetHistoryKind.emblemEvolution,
|
||||
'badge_founder100' => PlanetHistoryKind.founderBadge,
|
||||
_ => null,
|
||||
};
|
||||
final date = row['occurredAt'] is String
|
||||
@@ -74,7 +77,12 @@ class FirestorePlanetRepository implements PlanetRepository {
|
||||
PlanetHistoryKind.companyAdBonus,
|
||||
PlanetHistoryKind.funding,
|
||||
].contains(kind);
|
||||
if (activity != personal ||
|
||||
final stamp = [
|
||||
PlanetHistoryKind.eclipseSuccess,
|
||||
PlanetHistoryKind.emblemEvolution,
|
||||
PlanetHistoryKind.founderBadge,
|
||||
].contains(kind);
|
||||
if ((activity || stamp) != personal ||
|
||||
(activity && (amount is! int || amount <= 0)) ||
|
||||
kind == null ||
|
||||
date == null ||
|
||||
@@ -95,7 +103,12 @@ class FirestorePlanetRepository implements PlanetRepository {
|
||||
occurredAt: date,
|
||||
amount: activity ? amount as int : null,
|
||||
fromStage: kind == PlanetHistoryKind.evolution ? from as int : null,
|
||||
toStage: kind == PlanetHistoryKind.evolution ? to as int : null,
|
||||
toStage: kind == PlanetHistoryKind.evolution
|
||||
? to as int
|
||||
: kind == PlanetHistoryKind.emblemEvolution && to is int
|
||||
? to
|
||||
: null,
|
||||
memberNo: row['memberNo'] is int ? row['memberNo'] as int : null,
|
||||
participationConfirmed:
|
||||
kind == PlanetHistoryKind.evolution &&
|
||||
row['participationConfirmed'] == true,
|
||||
|
||||
@@ -528,6 +528,9 @@
|
||||
"historyQuest": "Quest reward",
|
||||
"historyAdBonus": "Ad bonus reward",
|
||||
"historyFunding": "Campaign contribution",
|
||||
"historyEclipseSuccess": "Joined a successful eclipse defense",
|
||||
"historyEmblemEvolution": "Evolution emblem",
|
||||
"historyFounderBadge": "First 100 commemorative badge",
|
||||
"historyGrowthPop": "{amount} POP added to growth",
|
||||
"historyJoined": "You were part of this evolution",
|
||||
"historyLoadFailed": "Couldn't load history.",
|
||||
|
||||
@@ -528,6 +528,9 @@
|
||||
"historyQuest": "Recompensa de Quest",
|
||||
"historyAdBonus": "Recompensa extra por anuncio",
|
||||
"historyFunding": "Contribución a Campaign",
|
||||
"historyEclipseSuccess": "Participaste en una defensa exitosa del eclipse",
|
||||
"historyEmblemEvolution": "Emblema de evolución",
|
||||
"historyFounderBadge": "Insignia conmemorativa de los primeros 100",
|
||||
"historyGrowthPop": "{amount} POP sumados al crecimiento",
|
||||
"historyJoined": "Participaste en esta evolución",
|
||||
"historyLoadFailed": "No se pudo cargar el historial.",
|
||||
|
||||
@@ -528,6 +528,9 @@
|
||||
"historyQuest": "Quest報酬",
|
||||
"historyAdBonus": "広告追加報酬",
|
||||
"historyFunding": "Campaign貢献",
|
||||
"historyEclipseSuccess": "イクリプス防御成功に参加",
|
||||
"historyEmblemEvolution": "進化記念エンブレム",
|
||||
"historyFounderBadge": "最初の100人記念バッジ",
|
||||
"historyGrowthPop": "成長に{amount} POP反映",
|
||||
"historyJoined": "この進化に参加しました",
|
||||
"historyLoadFailed": "記録を読み込めませんでした。",
|
||||
|
||||
@@ -1032,6 +1032,9 @@
|
||||
"historyQuest": "Quest 보상",
|
||||
"historyAdBonus": "광고 추가 보상",
|
||||
"historyFunding": "Campaign 기여",
|
||||
"historyEclipseSuccess": "이클립스 방어 성공 참여",
|
||||
"historyEmblemEvolution": "진화 기념 Emblem",
|
||||
"historyFounderBadge": "최초 100명 기념 Badge",
|
||||
"historyGrowthPop": "성장에 {amount} POP 반영",
|
||||
"@historyGrowthPop": {
|
||||
"placeholders": {
|
||||
|
||||
@@ -3272,6 +3272,24 @@ abstract class AppLocalizations {
|
||||
/// **'Campaign 기여'**
|
||||
String get historyFunding;
|
||||
|
||||
/// No description provided for @historyEclipseSuccess.
|
||||
///
|
||||
/// In ko, this message translates to:
|
||||
/// **'이클립스 방어 성공 참여'**
|
||||
String get historyEclipseSuccess;
|
||||
|
||||
/// No description provided for @historyEmblemEvolution.
|
||||
///
|
||||
/// In ko, this message translates to:
|
||||
/// **'진화 기념 Emblem'**
|
||||
String get historyEmblemEvolution;
|
||||
|
||||
/// No description provided for @historyFounderBadge.
|
||||
///
|
||||
/// In ko, this message translates to:
|
||||
/// **'최초 100명 기념 Badge'**
|
||||
String get historyFounderBadge;
|
||||
|
||||
/// No description provided for @historyGrowthPop.
|
||||
///
|
||||
/// In ko, this message translates to:
|
||||
|
||||
@@ -1814,6 +1814,15 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
@override
|
||||
String get historyFunding => 'Campaign contribution';
|
||||
|
||||
@override
|
||||
String get historyEclipseSuccess => 'Joined a successful eclipse defense';
|
||||
|
||||
@override
|
||||
String get historyEmblemEvolution => 'Evolution emblem';
|
||||
|
||||
@override
|
||||
String get historyFounderBadge => 'First 100 commemorative badge';
|
||||
|
||||
@override
|
||||
String historyGrowthPop(String amount) {
|
||||
return '$amount POP added to growth';
|
||||
|
||||
@@ -1823,6 +1823,17 @@ class AppLocalizationsEs extends AppLocalizations {
|
||||
@override
|
||||
String get historyFunding => 'Contribución a Campaign';
|
||||
|
||||
@override
|
||||
String get historyEclipseSuccess =>
|
||||
'Participaste en una defensa exitosa del eclipse';
|
||||
|
||||
@override
|
||||
String get historyEmblemEvolution => 'Emblema de evolución';
|
||||
|
||||
@override
|
||||
String get historyFounderBadge =>
|
||||
'Insignia conmemorativa de los primeros 100';
|
||||
|
||||
@override
|
||||
String historyGrowthPop(String amount) {
|
||||
return '$amount POP sumados al crecimiento';
|
||||
|
||||
@@ -1754,6 +1754,15 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
@override
|
||||
String get historyFunding => 'Campaign貢献';
|
||||
|
||||
@override
|
||||
String get historyEclipseSuccess => 'イクリプス防御成功に参加';
|
||||
|
||||
@override
|
||||
String get historyEmblemEvolution => '進化記念エンブレム';
|
||||
|
||||
@override
|
||||
String get historyFounderBadge => '最初の100人記念バッジ';
|
||||
|
||||
@override
|
||||
String historyGrowthPop(String amount) {
|
||||
return '成長に$amount POP反映';
|
||||
|
||||
@@ -1755,6 +1755,15 @@ class AppLocalizationsKo extends AppLocalizations {
|
||||
@override
|
||||
String get historyFunding => 'Campaign 기여';
|
||||
|
||||
@override
|
||||
String get historyEclipseSuccess => '이클립스 방어 성공 참여';
|
||||
|
||||
@override
|
||||
String get historyEmblemEvolution => '진화 기념 Emblem';
|
||||
|
||||
@override
|
||||
String get historyFounderBadge => '최초 100명 기념 Badge';
|
||||
|
||||
@override
|
||||
String historyGrowthPop(String amount) {
|
||||
return '성장에 $amount POP 반영';
|
||||
|
||||
@@ -1753,6 +1753,15 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
@override
|
||||
String get historyFunding => 'Campaign 贡献';
|
||||
|
||||
@override
|
||||
String get historyEclipseSuccess => '参与日食防御成功';
|
||||
|
||||
@override
|
||||
String get historyEmblemEvolution => '进化纪念徽章';
|
||||
|
||||
@override
|
||||
String get historyFounderBadge => '前100名纪念徽章';
|
||||
|
||||
@override
|
||||
String historyGrowthPop(String amount) {
|
||||
return '$amount POP 计入成长';
|
||||
|
||||
@@ -528,6 +528,9 @@
|
||||
"historyQuest": "Quest 奖励",
|
||||
"historyAdBonus": "广告额外奖励",
|
||||
"historyFunding": "Campaign 贡献",
|
||||
"historyEclipseSuccess": "参与日食防御成功",
|
||||
"historyEmblemEvolution": "进化纪念徽章",
|
||||
"historyFounderBadge": "前100名纪念徽章",
|
||||
"historyGrowthPop": "{amount} POP 计入成长",
|
||||
"historyJoined": "你参与了这次进化",
|
||||
"historyLoadFailed": "无法加载记录。",
|
||||
|
||||
@@ -868,12 +868,21 @@ class RemoteAppLocalizations extends AppLocalizations {
|
||||
@override
|
||||
String get historyAdBonus => _remote['historyAdBonus'] ?? _base.historyAdBonus;
|
||||
|
||||
@override
|
||||
String get historyEclipseSuccess => _remote['historyEclipseSuccess'] ?? _base.historyEclipseSuccess;
|
||||
|
||||
@override
|
||||
String get historyEmblemEvolution => _remote['historyEmblemEvolution'] ?? _base.historyEmblemEvolution;
|
||||
|
||||
@override
|
||||
String historyEvolution(String from, String to) => _fill('historyEvolution', {'from': from, 'to': to}) ?? _base.historyEvolution(from, to);
|
||||
|
||||
@override
|
||||
String get historyFandomEmpty => _remote['historyFandomEmpty'] ?? _base.historyFandomEmpty;
|
||||
|
||||
@override
|
||||
String get historyFounderBadge => _remote['historyFounderBadge'] ?? _base.historyFounderBadge;
|
||||
|
||||
@override
|
||||
String get historyFunding => _remote['historyFunding'] ?? _base.historyFunding;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user