UX·FX v1.5 — 햅틱 단계 · 라이브 띠 · HERO 전광판 · Push 우선순위 · Shield · 이클립스 성공·실패 연출
This commit is contained in:
@@ -14,13 +14,57 @@ import '../../../core/i18n/app_locale.dart';
|
||||
/// 별첨 B 「Global Ticker」로 Eclipse 외의 종류가 뒤에 들어오므로 종류마다 한 줄씩
|
||||
/// 늘려 간다. 모르는 종류는 공지로 읽어 티커가 멈추지 않게 한다.
|
||||
String liveEventMessage(LiveEvent event) => switch (event.kind) {
|
||||
LiveEventKind.eclipseDefense =>
|
||||
appL10n.liveEclipseDefense(event.nickname),
|
||||
LiveEventKind.artistHotTime =>
|
||||
appL10n.liveHotTime(event.nickname),
|
||||
LiveEventKind.heroGift =>
|
||||
appL10n.liveHeroGift(event.nickname),
|
||||
LiveEventKind.campaign =>
|
||||
appL10n.liveCampaign(event.nickname),
|
||||
LiveEventKind.eclipseDefense => appL10n.liveEclipseDefense(event.nickname),
|
||||
LiveEventKind.artistHotTime => appL10n.liveHotTime(event.nickname),
|
||||
LiveEventKind.heroGift => appL10n.liveHeroGift(event.nickname),
|
||||
LiveEventKind.campaign => appL10n.liveCampaign(event.nickname),
|
||||
LiveEventKind.notice => '[LIVE] ${event.nickname}',
|
||||
};
|
||||
|
||||
/// 홈 라이브 띠(전광판)에 올릴 한 줄. [hero] 면 띠가 HERO TIME 참여 진입이 된다.
|
||||
typedef TickerLine = ({String text, bool hero});
|
||||
|
||||
/// 띠 한 줄 고르기 — 원장 C-78 순서(위기 → 성취)대로 핵심 이벤트가 먼저 오른다.
|
||||
///
|
||||
/// 1. 이클립스 발생 소식 — 그 뒤 이벤트(방어 참여 등)가 아직 없을 때.
|
||||
/// 2. 방어 중 집약 — UX·FX v1.5 §1.1 「개인 이벤트를 연속 티커로 쌓기보다 집단 상태로 집약」 ·
|
||||
/// §5.1 「참여자 수 변화 중심」 · 기능명세 §2.10~§2.12 「지금 N 명이 함께 방어 중」. N 은 서버가
|
||||
/// 인정한 고유 참여자 수([EclipseState.defense])이며 2명 이상일 때 집약한다(「다수」 해석 — 해석 확인 항목).
|
||||
/// 3. HERO TIME — v1.5 §6 전광판 「공개 닉네임 + 대상 팬덤 + 진행 중 CTA」.
|
||||
/// 4. 최신 이벤트 한 건, 없으면 [fallback].
|
||||
TickerLine? tickerLine({
|
||||
required EclipseState? eclipse,
|
||||
required bool heroTime,
|
||||
required List<String> heroNicknames,
|
||||
required List<LiveEvent> events,
|
||||
required String fandomName,
|
||||
required DateTime now,
|
||||
String? fallback,
|
||||
}) {
|
||||
final event = events.isEmpty ? null : events.first;
|
||||
if (eclipse != null && eclipse.result == null) {
|
||||
final started = eclipse.startAt;
|
||||
if (event == null || started == null || event.at.isBefore(started)) {
|
||||
return (
|
||||
text: appL10n.eclipseLiveOccurred(eclipse.fandomName),
|
||||
hero: false,
|
||||
);
|
||||
}
|
||||
if (eclipse.canShake(now) && eclipse.defense >= 2) {
|
||||
return (
|
||||
text: appL10n.liveEclipseDefending('${eclipse.defense}'),
|
||||
hero: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (heroTime) {
|
||||
return (
|
||||
text: heroNicknames.isEmpty
|
||||
? appL10n.liveHeroTime(fandomName)
|
||||
: appL10n.liveHeroTimeBy(fandomName, heroNicknames.join(' · ')),
|
||||
hero: true,
|
||||
);
|
||||
}
|
||||
if (event != null) return (text: liveEventMessage(event), hero: false);
|
||||
return fallback == null ? null : (text: fallback, hero: false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user