| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- import 'package:flutter/material.dart';
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import 'package:go_router/go_router.dart';
- import 'package:shimmer/shimmer.dart';
- import '../../../core/l10n/app_localizations.dart';
- import '../../../core/theme/app_colors.dart';
- import '../../../providers/help_center_provider.dart';
- import '../../widgets/common/app_refresh_indicator.dart';
- class HelpCenterScreen extends ConsumerWidget {
- const HelpCenterScreen({super.key});
- @override
- Widget build(BuildContext context, WidgetRef ref) {
- final cs = Theme.of(context).colorScheme;
- final state = ref.watch(helpCenterProvider);
- final notifier = ref.read(helpCenterProvider.notifier);
- return Scaffold(
- appBar: AppBar(
- elevation: 0,
- leading: IconButton(
- icon: const Icon(Icons.chevron_left, size: 28),
- onPressed: () => context.pop(),
- ),
- title: Text(
- AppLocalizations.of(context)!.helpCenter,
- style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
- ),
- centerTitle: true,
- ),
- body: _buildBody(context, cs, state, notifier),
- );
- }
- Widget _buildBody(
- BuildContext context,
- ColorScheme cs,
- HelpCenterState state,
- HelpCenterNotifier notifier,
- ) {
- final isDark = Theme.of(context).brightness == Brightness.dark;
- // 首次加载 → shimmer 骨架屏
- if (state.isLoading && state.groups.isEmpty) {
- return _ShimmerGroups(cs: cs);
- }
- if (state.groups.isEmpty) {
- return Center(
- child: Text(
- AppLocalizations.of(context)!.noHelpContent,
- style: TextStyle(color: cs.onSurface.withAlpha(153)),
- ),
- );
- }
- return AppRefreshIndicator(
- onRefresh: notifier.refresh,
- child: ListView.builder(
- padding: const EdgeInsets.fromLTRB(16, 16, 16, 32),
- itemCount: state.groups.length,
- itemBuilder: (_, index) {
- final group = state.groups[index];
- final isExpanded = state.expandedIndices.contains(index);
- return Container(
- margin: const EdgeInsets.only(bottom: 12),
- decoration: BoxDecoration(
- color: isDark ? AppColors.darkBgSecondary : AppColors.lightBgSecondary,
- borderRadius: BorderRadius.circular(12),
- ),
- child: Column(
- children: [
- // 分组标题
- InkWell(
- onTap: () => notifier.toggleExpand(index),
- borderRadius: BorderRadius.circular(12),
- child: Padding(
- padding: const EdgeInsets.symmetric(
- horizontal: 16, vertical: 14),
- child: Row(
- children: [
- Expanded(
- child: Text(
- group.localizedGroupTitle,
- style: TextStyle(
- color: cs.onSurface,
- fontSize: 15,
- fontWeight: FontWeight.w600,
- ),
- ),
- ),
- Icon(
- isExpanded
- ? Icons.keyboard_arrow_up
- : Icons.keyboard_arrow_down,
- color: cs.onSurface.withAlpha(153),
- size: 22,
- ),
- ],
- ),
- ),
- ),
- // 子项列表
- if (isExpanded)
- ...group.items.map((item) {
- return Column(
- children: [
- Divider(height: 1, indent: 16, color: cs.outline),
- InkWell(
- onTap: () =>
- context.push('/user/help/${item.id}'),
- child: Padding(
- padding: const EdgeInsets.symmetric(
- horizontal: 16, vertical: 12),
- child: Row(
- children: [
- Expanded(
- child: Text(
- item.title,
- style: TextStyle(
- color: cs.onSurface,
- fontSize: 14,
- ),
- maxLines: 2,
- overflow: TextOverflow.ellipsis,
- ),
- ),
- Icon(
- Icons.chevron_right,
- size: 18,
- color: cs.onSurface.withAlpha(153),
- ),
- ],
- ),
- ),
- ),
- ],
- );
- }),
- ],
- ),
- );
- },
- ),
- );
- }
- }
- // ── Shimmer 骨架屏 ──────────────────────────────────────────
- class _ShimmerGroups extends StatelessWidget {
- const _ShimmerGroups({required this.cs});
- final ColorScheme cs;
- @override
- Widget build(BuildContext context) {
- return Shimmer.fromColors(
- baseColor: cs.onSurface.withAlpha(15),
- highlightColor: cs.onSurface.withAlpha(30),
- child: Padding(
- padding: const EdgeInsets.fromLTRB(16, 16, 16, 0),
- child: Column(
- children: List.generate(5, (i) {
- return Container(
- margin: const EdgeInsets.only(bottom: 12),
- padding:
- const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
- decoration: BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.circular(12),
- ),
- child: Row(
- children: [
- Expanded(
- child: Container(
- height: 16,
- decoration: BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.circular(4),
- ),
- ),
- ),
- const SizedBox(width: 40),
- Container(
- height: 20,
- width: 20,
- decoration: BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.circular(4),
- ),
- ),
- ],
- ),
- );
- }),
- ),
- ),
- );
- }
- }
|