92 lines
2.3 KiB
Dart
92 lines
2.3 KiB
Dart
// Author: fruit.com.cn
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import '../../core/data/models/account_profile.dart';
|
|
import '../../core/data/remote/api_client.dart';
|
|
import '../../core/data/repositories/account_repository.dart';
|
|
|
|
/// 个人资料页状态与保存动作。
|
|
class AccountProfileLogic extends ChangeNotifier {
|
|
AccountProfileLogic(this._repository, {required this.onProfileUpdated});
|
|
|
|
static const maxNicknameLength = 30;
|
|
|
|
final AccountRepository _repository;
|
|
final Future<void> Function(AccountProfile profile) onProfileUpdated;
|
|
|
|
AccountProfile? profile;
|
|
bool loading = false;
|
|
bool saving = false;
|
|
String? error;
|
|
String? fieldError;
|
|
bool _disposed = false;
|
|
|
|
/// 进入页面时加载当前资料。
|
|
Future<void> load() async {
|
|
loading = true;
|
|
error = null;
|
|
_notify();
|
|
try {
|
|
profile = await _repository.profile();
|
|
} catch (failure) {
|
|
error = _message(failure);
|
|
} finally {
|
|
loading = false;
|
|
_notify();
|
|
}
|
|
}
|
|
|
|
/// 只提交本次改动;成功后同步登录态摘要。
|
|
Future<bool> save({
|
|
required String nickname,
|
|
required String gender,
|
|
String? birthday,
|
|
}) async {
|
|
final current = profile;
|
|
if (current == null) return false;
|
|
final trimmed = nickname.trim();
|
|
if (trimmed.isEmpty || trimmed.length > maxNicknameLength) {
|
|
fieldError = 'accountNicknameInvalid';
|
|
_notify();
|
|
return false;
|
|
}
|
|
final update = AccountProfileUpdate(
|
|
nickname: trimmed == current.nickname ? null : trimmed,
|
|
gender: gender.isEmpty || gender == current.gender ? null : gender,
|
|
birthday: birthday == null || birthday.isEmpty ? null : birthday,
|
|
);
|
|
if (update.toJson().isEmpty) return true;
|
|
|
|
saving = true;
|
|
error = null;
|
|
fieldError = null;
|
|
_notify();
|
|
try {
|
|
final next = await _repository.updateProfile(update);
|
|
profile = next;
|
|
await onProfileUpdated(next);
|
|
return true;
|
|
} catch (failure) {
|
|
error = _message(failure);
|
|
return false;
|
|
} finally {
|
|
saving = false;
|
|
_notify();
|
|
}
|
|
}
|
|
|
|
String _message(Object failure) =>
|
|
failure is ApiException ? failure.message : 'networkError';
|
|
|
|
void _notify() {
|
|
if (!_disposed) notifyListeners();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_disposed = true;
|
|
super.dispose();
|
|
}
|
|
}
|