라이브 티커 · 갤럭시 검색 색인 · 주간 랭킹 스냅샷 · 연속 ZAP 상한 · 가입 행성 Zap · 성운 목표 · 랭킹 갱신 안내 · 행성 터치 반응

This commit is contained in:
Sn-Kinos
2026-10-05 22:38:42 +09:00
parent 000c058097
commit 4bb92c2ee7
44 changed files with 727 additions and 78 deletions
@@ -14,7 +14,6 @@ import '../../core/ui/app_icons.dart';
import '../eclipse/eclipse_data.dart';
import '../eclipse/widgets/eclipse_banner.dart';
import '../home/home_screen.dart' show formatPop;
import '../home/home_data.dart' show defaultNebulaTargets;
import 'lounge_post_screens.dart';
import 'moderation.dart';
import 'planet_data.dart';
@@ -41,8 +40,12 @@ class PlanetDetailScreen extends StatefulWidget {
this.watchPlanet = noPlanetWatch,
required this.repository,
required this.eclipse,
this.initialTab = 0,
});
/// 처음 열 탭 — 0 FPI · 1 팬덤 라운지. HOME 행성 터치는 커뮤니티(라운지)로 연다(Figma `2024:20758`).
final int initialTab;
/// 성운 상세인가. 성운은 아직 정식 행성이 아니다(정책 §P-08).
final bool nebula;
final PlanetRepository repository;
@@ -129,6 +132,7 @@ class _PlanetDetailScreenState extends State<PlanetDetailScreen> {
final top = MediaQuery.paddingOf(context).top;
return DefaultTabController(
length: 2,
initialIndex: widget.initialTab.clamp(0, 1),
child: Scaffold(
body: NestedScrollView(
headerSliverBuilder: (context, _) => [
@@ -431,7 +435,13 @@ class _FpiTab extends StatelessWidget {
padding: const EdgeInsets.all(16),
sliver: SliverList.list(
children: [
_NebulaFpi(pop: detail.growthPop, repository: repository),
_NebulaFpi(
pop: detail.growthPop,
target: detail.nebulaTargetPop,
members: detail.members,
targetMembers: detail.nebulaTargetMembers,
repository: repository,
),
],
),
),
@@ -525,9 +535,20 @@ class _FpiTab extends StatelessWidget {
/// 목표는 원장 B-10 의 1,000 POP(사본 500,000 은 과거 수치). 분자는 서버 `growthPop`.
/// 기여자 목록은 상세 데이터에 아직 없어 빈 상태로 둔다.
class _NebulaFpi extends StatelessWidget {
const _NebulaFpi({required this.pop, required this.repository});
const _NebulaFpi({
required this.pop,
required this.target,
required this.members,
required this.targetMembers,
required this.repository,
});
final int pop;
/// 전환 목표 — 서버 `config/policy`(B-10). 탄생은 POP · 창립 인원 **두 조건**이다.
final int target;
final int members;
final int targetMembers;
final PlanetRepository repository;
static TextStyle _b(double size, Color color, {double? height}) => TextStyle(
@@ -550,8 +571,7 @@ class _NebulaFpi extends StatelessWidget {
@override
Widget build(BuildContext context) {
final target = defaultNebulaTargets.pop;
final rate = pop * 100 ~/ target;
final rate = target <= 0 ? 0 : (pop * 100 ~/ target).clamp(0, 100);
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
@@ -593,7 +613,7 @@ class _NebulaFpi extends StatelessWidget {
ClipRRect(
borderRadius: BorderRadius.circular(AppRadius.full),
child: LinearProgressIndicator(
value: pop / target,
value: target <= 0 ? 0 : (pop / target).clamp(0.0, 1.0),
minHeight: 10,
backgroundColor: Colors.black.withValues(alpha: 0.3),
color: AppColors.cosmicTeal,
@@ -610,6 +630,12 @@ class _NebulaFpi extends StatelessWidget {
),
],
),
const SizedBox(height: 8),
// 인원 조건도 함께 — 탄생은 POP · 창립 인원 동시 충족(B-10).
Text(
'${context.l10n.growthFounders} ${formatPop(members)} / ${formatPop(targetMembers)}',
style: _b(12, const Color(0xFFA3A2A0)),
),
],
),
),