이클립스 흐름 — 배너 진입 · 이벤트 버튼 · 오버레이 · 방어 진행 표시 · 흔들기 감지 통일
This commit is contained in:
@@ -4,6 +4,7 @@ import '../../../core/theme/tokens.dart';
|
||||
import '../../../core/ui/live_stream.dart';
|
||||
import '../../home/home_screen.dart' show formatPop;
|
||||
import '../eclipse_data.dart';
|
||||
import '../eclipse_defend_screen.dart';
|
||||
import '../../../core/i18n/app_locale.dart';
|
||||
|
||||
/// 이클립스 인앱 경보 배너 — HOME · GALAXY 상단.
|
||||
@@ -52,7 +53,16 @@ class EclipseBanner extends StatelessWidget {
|
||||
? const SizedBox.shrink()
|
||||
: Padding(
|
||||
padding: margin,
|
||||
child: EclipseBannerCard(state: state, onTap: onTap),
|
||||
// 넘겨받은 동작이 없으면 「흔들어 방어」 화면을 연다 — HOME·행성 상세·GALAXY 홈
|
||||
// 모두 이 기본 동작을 쓴다(배너를 눌러도 아무 일이 없던 결함).
|
||||
child: EclipseBannerCard(
|
||||
state: state,
|
||||
onTap: onTap ?? () => Navigator.of(context, rootNavigator: true).push(
|
||||
MaterialPageRoute<void>(builder: (_) => EclipseDefendScreen(
|
||||
repository: repository, fandomId: state.fandomId,
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../core/i18n/app_locale.dart';
|
||||
import '../../../core/theme/tokens.dart';
|
||||
import '../../../core/ui/live_stream.dart';
|
||||
import '../eclipse_data.dart';
|
||||
import '../eclipse_defend_screen.dart';
|
||||
|
||||
/// HOME 이클립스 이벤트 버튼 — 사본 「홈」(`373:443167`)의 `Group 563`.
|
||||
///
|
||||
/// 명세 `516:88125` *데이터: 이클립스 발생 잔여 시간 · 규칙: 성운(행성) 아래 중앙 정렬,
|
||||
/// 어드민에서 설정된 이클립스 이벤트 발생 시간의 N분 전 노출 · 동작: 클릭 시 이클립스 상세로
|
||||
/// 이동*. N분은 서버 회차의 `warnAt`(원장 C-22 발생 3분 전)이다 — 회차 문서가 그때부터
|
||||
/// `scheduled` 로 있으므로 그 문서가 보이는 동안 띄운다. 발생 뒤 방어 창(60초) 동안은
|
||||
/// 남은 초로 바뀌고, 결과가 나거나 창이 닫히면 접는다.
|
||||
///
|
||||
/// 모양: 위를 가리키는 꼭지 + 검정 80% 알약(229×46 · r 끝까지) · 42dot Medium 12 흰색 두 줄.
|
||||
class EclipseEventButton extends StatelessWidget {
|
||||
const EclipseEventButton({
|
||||
super.key,
|
||||
required this.repository,
|
||||
required this.fandomId,
|
||||
});
|
||||
|
||||
final EclipseRepository repository;
|
||||
final String fandomId;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => LiveStreamBuilder<EclipseState?>(
|
||||
key: ValueKey('eclipse-button-$fandomId'),
|
||||
create: () => repository.watch(fandomId: fandomId, includeScheduled: true),
|
||||
builder: (context, state) {
|
||||
if (state == null) return const SizedBox.shrink();
|
||||
return EclipseTicker(
|
||||
builder: (context, now) {
|
||||
if (state.result != null || state.defended || state.isExpired(now)) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final text = state.hasStarted(now)
|
||||
? context.l10n.eclipseButtonActive(
|
||||
'${((state.remaining(now)?.inMilliseconds ?? 0) / 1000).ceil()}',
|
||||
)
|
||||
: context.l10n.eclipseButtonSoon(
|
||||
eclipseLeftLabel(state.startAt!.difference(now)),
|
||||
);
|
||||
return Semantics(
|
||||
button: true,
|
||||
liveRegion: true,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () => Navigator.of(context, rootNavigator: true).push(
|
||||
MaterialPageRoute<void>(
|
||||
// 명세 `516:88164` 「닫기 — 하단 move out」 — 아래에서 올라오는 전체 화면.
|
||||
fullscreenDialog: true,
|
||||
builder: (_) => EclipseDefendScreen(
|
||||
repository: repository,
|
||||
fandomId: state.fandomId,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CustomPaint(
|
||||
size: const Size(16, 7),
|
||||
painter: _Tip(),
|
||||
),
|
||||
Container(
|
||||
constraints: const BoxConstraints(minWidth: 229, minHeight: 46),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: AppSpace.s4,
|
||||
vertical: 6,
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xCC000000),
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
),
|
||||
child: Text(
|
||||
text,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontFamily: AppFonts.body,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 17 / 12,
|
||||
color: AppColors.onCosmic,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 말풍선 꼭지 — 행성을 가리킨다.
|
||||
class _Tip extends CustomPainter {
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) => canvas.drawPath(
|
||||
Path()
|
||||
..moveTo(size.width / 2, 0)
|
||||
..lineTo(size.width, size.height)
|
||||
..lineTo(0, size.height)
|
||||
..close(),
|
||||
Paint()..color = const Color(0xCC000000),
|
||||
);
|
||||
|
||||
@override
|
||||
bool shouldRepaint(_Tip old) => false;
|
||||
}
|
||||
Reference in New Issue
Block a user