import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:arcx/app/app_theme.dart'; import 'package:arcx/core/constants/app_defaults.dart'; import 'package:arcx/data/local/models/models.dart'; import 'package:arcx/features/profile/application/profile_controller.dart'; class ProfileEditDialog extends ConsumerStatefulWidget { const ProfileEditDialog({super.key}); @override ConsumerState createState() => _ProfileEditDialogState(); } class _ProfileEditDialogState extends ConsumerState { late final TextEditingController _controller; bool _saving = false; @override void initState() { super.initState(); final profile = ref.read(profileProvider).value; _controller = TextEditingController(text: profile?.nickname ?? ''); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final profile = ref.watch(profileProvider).value; return AlertDialog( title: const Text('编辑个人资料'), content: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ GestureDetector( onTap: _saving ? null : () => _pickAvatar(context), child: _AvatarPreview(profile: profile), ), if (profile?.avatarSource == AvatarSource.localFile) TextButton.icon( onPressed: _saving ? null : _resetAvatar, icon: const Icon(Icons.refresh, size: 18), label: const Text('恢复默认头像'), ), const SizedBox(height: 8), TextField( controller: _controller, maxLength: 12, decoration: const InputDecoration( labelText: '昵称', hintText: '1~12 个字符', counterText: '', ), ), ], ), ), actions: [ TextButton( onPressed: _saving ? null : () => Navigator.pop(context), child: const Text('取消'), ), FilledButton( onPressed: _saving ? null : _save, child: const Text('保存'), ), ], ); } Future _pickAvatar(BuildContext context) async { final choice = await showModalBottomSheet( context: context, builder: (_) => SafeArea( child: Column( mainAxisSize: MainAxisSize.min, children: [ ListTile( leading: const Icon(Icons.photo_outlined), title: const Text('从相册选择'), onTap: () => Navigator.pop(context, AvatarAction.gallery), ), ListTile( leading: const Icon(Icons.camera_alt_outlined), title: const Text('拍摄照片'), onTap: () => Navigator.pop(context, AvatarAction.camera), ), ], ), ), ); if (choice == null) return; setState(() => _saving = true); await ref .read(profileProvider.notifier) .updateAvatar(fromCamera: choice == AvatarAction.camera); if (mounted) setState(() => _saving = false); } Future _resetAvatar() async { setState(() => _saving = true); await ref.read(profileProvider.notifier).resetAvatar(); if (mounted) setState(() => _saving = false); } Future _save() async { final name = _controller.text.trim(); if (name.isEmpty) { ScaffoldMessenger.of( context, ).showSnackBar(const SnackBar(content: Text('昵称不能为空'))); return; } setState(() => _saving = true); await ref.read(profileProvider.notifier).updateNickname(name); if (mounted) { setState(() => _saving = false); Navigator.pop(context); } } } enum AvatarAction { gallery, camera } class _AvatarPreview extends StatelessWidget { const _AvatarPreview({required this.profile}); final UserProfile? profile; @override Widget build(BuildContext context) { final p = profile; final ImageProvider image; if (p != null && p.avatarSource == AvatarSource.localFile && p.avatarLocalPath != null && p.avatarLocalPath!.isNotEmpty) { image = FileImage(File(p.avatarLocalPath!)); } else { image = const AssetImage(AppDefaults.defaultAvatarAssetPath); } return Stack( alignment: Alignment.bottomRight, children: [ CircleAvatar( radius: 44, backgroundColor: AppTheme.surfaceMuted, backgroundImage: image, ), Container( padding: const EdgeInsets.all(6), decoration: const BoxDecoration( color: AppTheme.primary, shape: BoxShape.circle, ), child: const Icon(Icons.edit, color: Colors.white, size: 16), ), ], ); } }