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, this.nebula = false, }); final EclipseRepository repository; final String fandomId; /// 내 팬덤이 아직 성운인가 — 상세 · 방어 화면이 성운 그림을 그린다. final bool nebula; @override Widget build(BuildContext context) => LiveStreamBuilder( 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( // 명세 `516:88164` 「닫기 — 하단 move out」 — 아래에서 올라오는 전체 화면. eclipseDefendRoute( repository: repository, fandomId: state.fandomId, nebula: nebula, ), ), 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; }