INSIDE · STATION · 참여형 번역 · 알림 · MY 화면
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import '../../core/data/backend.dart';
|
||||
import 'station_data.dart';
|
||||
|
||||
/// STATION 허브의 실 서버 구현 — S-S-HUB.
|
||||
///
|
||||
/// `stationLinks` 는 운영만 쓰고 로그인 사용자는 읽기만 한다(보안 규칙 §7).
|
||||
/// 정렬은 팬덤별 `rank` 오름차순이며, 이 순서가 곧 운영이 정한 노출 순서다.
|
||||
/// 앱에서 다시 정렬하지 않는다 — 그러면 운영 화면과 앱이 다르게 보인다.
|
||||
class FirestoreStationRepository implements StationRepository {
|
||||
FirestoreStationRepository(this._backend);
|
||||
|
||||
final Backend _backend;
|
||||
|
||||
/// 소속 팬덤. 라우터가 모르는 값이라 사용자 문서에서 한 번 읽어 들고 있는다.
|
||||
String? _fandomId;
|
||||
|
||||
@override
|
||||
Future<StationSnapshot> load() async {
|
||||
final cached = _fandomId;
|
||||
final String id;
|
||||
if (cached != null) {
|
||||
id = cached;
|
||||
} else {
|
||||
final snap = await _backend.db.doc('users/${_backend.requireUid}').get();
|
||||
id = _fandomId = (snap.data() ?? const {}).strOr('fandomId');
|
||||
}
|
||||
// 팬덤이 없으면 큐레이션 대상이 정해지지 않는다. 빈 상태로 두고 화면이 안내한다.
|
||||
if (id.isEmpty) {
|
||||
return const StationSnapshot(links: [], canSuggest: false);
|
||||
}
|
||||
|
||||
final snap = await _backend.db
|
||||
.collection('stationLinks')
|
||||
.where('fandomId', isEqualTo: id)
|
||||
.orderBy('rank')
|
||||
.limit(30)
|
||||
.get();
|
||||
|
||||
return StationSnapshot(
|
||||
links: [
|
||||
for (final doc in snap.docs)
|
||||
StationLink(
|
||||
id: doc.id,
|
||||
title: doc.data().strOr('title'),
|
||||
url: doc.data().strOr('url'),
|
||||
category: _category(doc.data().strOr('category')),
|
||||
description: doc.data().strOr('description'),
|
||||
verified: doc.data()['verified'] == true,
|
||||
),
|
||||
],
|
||||
canSuggest: _backend.uid != null,
|
||||
);
|
||||
}
|
||||
|
||||
/// 모르는 값은 「공식」으로 떨어뜨리지 않고 판매처로 본다 — 공식 배지를
|
||||
/// 검증하지 않은 링크에 붙이는 쪽이 더 위험하다.
|
||||
StationCategory _category(String raw) => switch (raw) {
|
||||
'official' => StationCategory.official,
|
||||
'ticket' => StationCategory.ticket,
|
||||
'media' => StationCategory.media,
|
||||
_ => StationCategory.shop,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user