import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../core/network/dio_client.dart'; import '../data/models/announcement/announcement.dart'; import '../data/services/announcement_service.dart'; import 'app_provider.dart'; // ── State ────────────────────────────────────────────────── class HelpCenterState { final List groups; final Set expandedIndices; final bool isLoading; final String? errorMessage; const HelpCenterState({ this.groups = const [], this.expandedIndices = const {}, this.isLoading = false, this.errorMessage, }); HelpCenterState copyWith({ List? groups, Set? expandedIndices, bool? isLoading, String? errorMessage, }) => HelpCenterState( groups: groups ?? this.groups, expandedIndices: expandedIndices ?? this.expandedIndices, isLoading: isLoading ?? this.isLoading, errorMessage: errorMessage, ); } // ── Notifier ─────────────────────────────────────────────── class HelpCenterNotifier extends AutoDisposeNotifier { AnnouncementService get _service => AnnouncementService(ref.read(dioClientProvider)); @override HelpCenterState build() { ref.listen(localeProvider, (previous, next) { if (previous != null && previous != next) { Future.microtask(_load); } }); Future.microtask(_load); return const HelpCenterState(isLoading: true); } Future _load() async { try { final lang = backendLangFromLocale(ref.read(localeProvider)); final groups = await _service.getHelpList(lang: lang); state = state.copyWith(groups: groups, isLoading: false); } catch (e) { state = state.copyWith(isLoading: false, errorMessage: e.toString()); } } Future refresh() async { state = state.copyWith(isLoading: true, errorMessage: null); await _load(); } void toggleExpand(int index) { final expanded = Set.from(state.expandedIndices); if (expanded.contains(index)) { expanded.remove(index); } else { expanded.add(index); } state = state.copyWith(expandedIndices: expanded); } } final helpCenterProvider = AutoDisposeNotifierProvider( HelpCenterNotifier.new, ); // ── 帮助详情 Provider ────────────────────────────────────── /// 特殊 id → type 映射 const _specialHelpRoutes = { '63': 'desclaimer', '64': 'privacy', '68': 'follow', }; /// 协议列表(按 categoryCode 分组缓存) final protocolListProvider = FutureProvider.autoDispose.family, String>((ref, categoryCode) { final dio = ref.read(dioClientProvider); return AnnouncementService(dio).getProtocolList(categoryCode: categoryCode); }); /// 按 (categoryCode, title) 查找协议内容 /// title 为空时返回列表第一项(适用于单条目分类如 FOLLOW_PROTOCOL) final protocolByTitleProvider = FutureProvider.autoDispose.family( (ref, params) async { final (categoryCode, title) = params; final list = await ref.watch(protocolListProvider(categoryCode).future); if (list.isEmpty) return null; if (title.isEmpty) return list.first; try { return list.firstWhere((e) => e.title == title); } catch (_) { return list.first; } }); final helpDetailProvider = FutureProvider.autoDispose.family((ref, id) { final dio = ref.read(dioClientProvider); final service = AnnouncementService(dio); final specialType = _specialHelpRoutes[id]; if (specialType != null) { return service.getHelpSpecial(specialType); } return service.getHelpDetail(id); });