라이브 티커 · 갤럭시 검색 색인 · 주간 랭킹 스냅샷 · 연속 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
+20
View File
@@ -523,6 +523,26 @@ class _HomeBody extends StatelessWidget {
),
),
),
// Figma `2024:20758` — 행성 터치는 흔들림 1번 뒤 커뮤니티(팬덤 라운지)로.
onTapPlanet:
planetRepository == null ||
data.fandomId.isEmpty
? null
: () => Navigator.of(
context,
rootNavigator: true,
).push(
MaterialPageRoute<void>(
builder: (_) => PlanetDetailScreen(
repository: planetRepository!(
data.fandomId,
),
watchPlanet: watchPlanet,
eclipse: eclipse,
initialTab: 1,
),
),
),
onOpenHistory: planetRepository == null
? null
: () => Navigator.of(context).push(
+56 -1
View File
@@ -8,6 +8,7 @@ import '../../../core/ui/hero_time_status.dart';
import 'growth_conditions.dart';
import 'dart:math' as math;
import 'package:flutter/services.dart' show HapticFeedback;
import 'dart:ui' show ImageFilter;
import 'package:flutter/material.dart';
@@ -38,6 +39,7 @@ class HomeHero extends StatefulWidget {
this.onHeroParticipate,
this.onOpenHistory,
this.onOpenPlanet,
this.onTapPlanet,
this.zap,
this.zapData,
this.ticker,
@@ -61,6 +63,9 @@ class HomeHero extends StatefulWidget {
/// 성장 카드의 「BTS ›」 — 사본 흐름대로 행성 상세(F3)로 간다.
final VoidCallback? onOpenPlanet;
/// 행성 본체 터치 — Figma `2024:20758` 「행성 1회 터치시 흔들림 1번, 커뮤니티 이동」.
final VoidCallback? onTapPlanet;
final String fandomId;
final PlanetWatch watchPlanet;
final VoidCallback? onHeroParticipate;
@@ -207,7 +212,9 @@ class _HomeHeroState extends State<HomeHero> {
clipBehavior: Clip.none,
children: [
Positioned.fill(
child: LivePlanet25D(
child: _TapShake(
onTap: widget.onTapPlanet,
child: LivePlanet25D(
onOpenHistory: widget.onOpenHistory,
key: _planetKey,
fandomId: fandomId,
@@ -221,6 +228,7 @@ class _HomeHeroState extends State<HomeHero> {
),
glow: AppColors.neonViolet,
),
),
),
],
),
@@ -265,6 +273,7 @@ class _HomeHeroState extends State<HomeHero> {
Positioned.fill(
child: IgnorePointer(
child: ZapFeedback(
fandomName: widget.growth.fandomName,
touchSerial: zap.touchSerial,
pending: zap.pending > 0 || zap.sending,
result: zap.result,
@@ -1022,3 +1031,49 @@ class HomeZap extends StatelessWidget {
},
);
}
/// 행성 터치 반응 — Figma `2024:20758` 「행성 1회 터치시 흔들림 1번」 · UX·FX v1.5 §3 Light Haptic.
/// 흔들림이 끝나면 [onTap](커뮤니티 이동)을 부른다. [onTap] 이 없으면 아무 반응도 하지 않는다.
class _TapShake extends StatefulWidget {
const _TapShake({required this.child, this.onTap});
final Widget child;
final VoidCallback? onTap;
@override
State<_TapShake> createState() => _TapShakeState();
}
class _TapShakeState extends State<_TapShake> with SingleTickerProviderStateMixin {
late final _shake = AnimationController(vsync: this, duration: const Duration(milliseconds: 320));
@override
void dispose() {
_shake.dispose();
super.dispose();
}
Future<void> _tap() async {
final onTap = widget.onTap;
if (onTap == null || _shake.isAnimating) return;
HapticFeedback.lightImpact();
if (!MediaQuery.disableAnimationsOf(context)) await _shake.forward(from: 0);
if (mounted) onTap();
}
@override
Widget build(BuildContext context) => GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: widget.onTap == null ? null : _tap,
child: AnimatedBuilder(
animation: _shake,
// 한 번 좌우로 흔들리고 제자리 — 진폭 6 · 감쇠.
builder: (context, child) => Transform.translate(
offset: Offset(math.sin(_shake.value * math.pi * 4) * 6 * (1 - _shake.value), 0),
child: child,
),
child: widget.child,
),
);
}