106 lines
3.4 KiB
Dart
106 lines
3.4 KiB
Dart
/// STATION 탭이 그리는 값의 형태.
|
|
///
|
|
/// **STATION 은 Figma 에 화면이 없다.** 있는 것은 Bottom Navigation 의 탭 하나뿐이며,
|
|
/// 근거는 견적서 v2.1 의 5탭 구성과 Firestore 설계서의 `stationLinks` ·
|
|
/// `stationSuggestions` 두 컬렉션, 그리고 화면 정의 S-S-HUB · S-S-SUGGEST 다.
|
|
/// 그래서 이 화면은 **데이터 모델이 정의한 것까지만** 그린다 — 디자인이 확정되면
|
|
/// 그 시안으로 다시 맞춘다.
|
|
///
|
|
/// 하는 일은 큐레이션이다. 운영이 검증한 판매처·공식 링크를 모아 보여 주고,
|
|
/// 사용자가 새 판매처를 제안하면 운영이 심사한다(`stationSuggestions`).
|
|
library;
|
|
|
|
import '../../core/i18n/app_locale.dart';
|
|
|
|
/// 링크 분류. `stationLinks` 의 `category` 값이다.
|
|
enum StationCategory { official, shop, ticket, media }
|
|
|
|
extension StationCategoryLabel on StationCategory {
|
|
String get label => switch (this) {
|
|
StationCategory.official => appL10n.stationOfficial,
|
|
StationCategory.shop => appL10n.stationShop,
|
|
StationCategory.ticket => appL10n.stationTicket,
|
|
StationCategory.media => appL10n.stationMedia,
|
|
};
|
|
}
|
|
|
|
/// 큐레이션 링크 한 줄.
|
|
class StationLink {
|
|
const StationLink({
|
|
required this.id,
|
|
required this.title,
|
|
required this.url,
|
|
required this.category,
|
|
this.description = '',
|
|
this.verified = false,
|
|
});
|
|
|
|
final String id;
|
|
final String title;
|
|
|
|
/// 바깥 브라우저로 여는 주소. 앱 안에서 열지 않는다 — 결제·로그인이 걸린
|
|
/// 외부 사이트를 인앱 웹뷰에 담으면 심사에서 문제가 된다.
|
|
final String url;
|
|
|
|
final StationCategory category;
|
|
final String description;
|
|
|
|
/// 운영이 검증한 판매처. 명세가 없어 표시만 하고 정렬에는 쓰지 않는다.
|
|
final bool verified;
|
|
}
|
|
|
|
class StationSnapshot {
|
|
const StationSnapshot({required this.links, this.canSuggest = true});
|
|
|
|
final List<StationLink> links;
|
|
|
|
/// 제안 버튼 노출. 로그인 사용자만 제안할 수 있다(규칙 `authorIsSelf()`).
|
|
final bool canSuggest;
|
|
}
|
|
|
|
abstract interface class StationRepository {
|
|
Future<StationSnapshot> load();
|
|
}
|
|
|
|
/// 서버가 붙기 전에 쓰는 표본.
|
|
class SampleStationRepository implements StationRepository {
|
|
const SampleStationRepository();
|
|
|
|
@override
|
|
Future<StationSnapshot> load() async => const StationSnapshot(
|
|
links: [
|
|
StationLink(
|
|
id: 'official-site',
|
|
title: 'FANUZU 공식 사이트',
|
|
url: 'https://fanuzu.co.kr',
|
|
category: StationCategory.official,
|
|
description: '공지와 일정이 가장 먼저 올라옵니다.',
|
|
verified: true,
|
|
),
|
|
StationLink(
|
|
id: 'shop-official',
|
|
title: '공식 스토어',
|
|
url: 'https://fanuzu.co.kr',
|
|
category: StationCategory.shop,
|
|
description: '앨범과 응원봉을 파는 공식 판매처입니다.',
|
|
verified: true,
|
|
),
|
|
StationLink(
|
|
id: 'ticket',
|
|
title: '팬미팅 예매',
|
|
url: 'https://fanuzu.co.kr',
|
|
category: StationCategory.ticket,
|
|
description: '예매 일정과 대기 순서를 확인하십시오.',
|
|
),
|
|
StationLink(
|
|
id: 'media',
|
|
title: '공식 미디어 채널',
|
|
url: 'https://fanuzu.co.kr',
|
|
category: StationCategory.media,
|
|
description: '무대 영상과 비하인드가 올라옵니다.',
|
|
verified: true,
|
|
),
|
|
],
|
|
);
|
|
}
|