import '../models/models.dart'; class AuthState { const AuthState({ this.loggedIn = false, this.pendingAction, this.phone, this.loginMethod, }); final bool loggedIn; final PendingLoginAction? pendingAction; final String? phone; final LoginMethod? loginMethod; AuthState copyWith({ bool? loggedIn, Object? pendingAction = _sentinel, Object? phone = _sentinel, Object? loginMethod = _sentinel, }) { return AuthState( loggedIn: loggedIn ?? this.loggedIn, pendingAction: identical(pendingAction, _sentinel) ? this.pendingAction : pendingAction as PendingLoginAction?, phone: identical(phone, _sentinel) ? this.phone : phone as String?, loginMethod: identical(loginMethod, _sentinel) ? this.loginMethod : loginMethod as LoginMethod?, ); } } class PendingLoginAction { const PendingLoginAction({ required this.action, required this.reportId, required this.contextText, }); final LoginRequiredAction action; final String reportId; final String contextText; } enum LoginRequiredAction { favorite, saveListen } enum LoginMethod { phone, wechat, apple } class ProfileState { const ProfileState({ this.favorites = const {}, this.savedListens = const {}, this.history = const [], }); final Set favorites; final Set savedListens; final List history; ProfileState copyWith({ Set? favorites, Set? savedListens, List? history, }) { return ProfileState( favorites: favorites ?? this.favorites, savedListens: savedListens ?? this.savedListens, history: history ?? this.history, ); } } class DetailNavigationState { const DetailNavigationState({ this.originTab = AppTab.recommend, this.stack = const [], this.tabScroll = const {}, }); final AppTab originTab; final List stack; final Map tabScroll; DetailNavigationState copyWith({ AppTab? originTab, List? stack, Map? tabScroll, }) { return DetailNavigationState( originTab: originTab ?? this.originTab, stack: stack ?? this.stack, tabScroll: tabScroll ?? this.tabScroll, ); } } class DetailStackEntry { const DetailStackEntry({ required this.type, required this.id, this.scrollTop = 0, }); final DetailEntryType type; final String id; final double scrollTop; DetailStackEntry copyWith({double? scrollTop}) { return DetailStackEntry( type: type, id: id, scrollTop: scrollTop ?? this.scrollTop, ); } } enum DetailEntryType { report, institution } enum AppTab { recommend, reports, institutions, listen, profile } class SheetState { const SheetState.hidden() : intent = null; const SheetState.visible(this.intent); final SheetIntent? intent; bool get isVisible => intent != null; } sealed class SheetIntent { const SheetIntent(); } class LoginSheetIntent extends SheetIntent { const LoginSheetIntent({required this.contextText}); final String contextText; } class FilterSheetIntent extends SheetIntent { const FilterSheetIntent(); } class OutboundSheetIntent extends SheetIntent { const OutboundSheetIntent({required this.scene, this.refId, this.targetUrl}); final String scene; final String? refId; final String? targetUrl; } class ProfileListSheetIntent extends SheetIntent { const ProfileListSheetIntent({ required this.kind, required this.title, this.reports = const [], }); final ProfileListKind kind; final String title; final List reports; } enum ProfileListKind { favorites, history, saved } class OutboundEvent { const OutboundEvent({required this.scene, this.refId, this.targetUrl}); final String scene; final String? refId; final String? targetUrl; } const Object _sentinel = Object();