144 lines
4.1 KiB
Dart
144 lines
4.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'package:pshared/provider/account.dart';
|
|
|
|
import 'package:pweb/models/state/edit_state.dart';
|
|
|
|
|
|
class AccountNameController extends ChangeNotifier {
|
|
AccountNameController({
|
|
required this.initialFirstName,
|
|
required this.initialLastName,
|
|
required this.errorMessage,
|
|
}) {
|
|
_firstNameController = TextEditingController(text: initialFirstName);
|
|
_lastNameController = TextEditingController(text: initialLastName);
|
|
_lastSyncedFirstName = initialFirstName;
|
|
_lastSyncedLastName = initialLastName;
|
|
}
|
|
|
|
AccountProvider? _accountProvider;
|
|
final String initialFirstName;
|
|
final String initialLastName;
|
|
final String errorMessage;
|
|
|
|
late final TextEditingController _firstNameController;
|
|
late final TextEditingController _lastNameController;
|
|
EditState _editState = EditState.view;
|
|
String _errorText = '';
|
|
bool _disposed = false;
|
|
String _lastSyncedFirstName = '';
|
|
String _lastSyncedLastName = '';
|
|
|
|
TextEditingController get firstNameController => _firstNameController;
|
|
TextEditingController get lastNameController => _lastNameController;
|
|
EditState get editState => _editState;
|
|
String get errorText => _errorText;
|
|
bool get isEditing => _editState != EditState.view;
|
|
bool get isSaving => _editState == EditState.saving;
|
|
bool get isBusy => (_accountProvider?.isLoading ?? false) || isSaving;
|
|
|
|
String get currentFirstName =>
|
|
_accountProvider?.account?.name ?? initialFirstName;
|
|
String get currentLastName =>
|
|
_accountProvider?.account?.lastName ?? initialLastName;
|
|
String get currentFullName {
|
|
final first = currentFirstName.trim();
|
|
final last = currentLastName.trim();
|
|
if (first.isEmpty && last.isEmpty) return '';
|
|
if (first.isEmpty) return last;
|
|
if (last.isEmpty) return first;
|
|
return '$first $last';
|
|
}
|
|
|
|
void update(AccountProvider accountProvider) {
|
|
_accountProvider = accountProvider;
|
|
final changed = _syncNamesFromProvider();
|
|
if (changed) {
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
void startEditing() => _setState(EditState.edit);
|
|
|
|
void cancelEditing() {
|
|
_firstNameController.text = currentFirstName;
|
|
_lastNameController.text = currentLastName;
|
|
_setError('');
|
|
_setState(EditState.view);
|
|
}
|
|
|
|
Future<bool> save() async {
|
|
final accountProvider = _accountProvider;
|
|
if (accountProvider == null) return false;
|
|
|
|
final newFirstName = _firstNameController.text.trim();
|
|
final newLastName = _lastNameController.text.trim();
|
|
final currentFirst = currentFirstName;
|
|
final currentLast = currentLastName;
|
|
|
|
if (newFirstName.isEmpty ||
|
|
(newFirstName == currentFirst && newLastName == currentLast)) {
|
|
cancelEditing();
|
|
return false;
|
|
}
|
|
|
|
_setError('');
|
|
_setState(EditState.saving);
|
|
|
|
try {
|
|
await accountProvider.resetUsername(
|
|
newFirstName,
|
|
lastName: newLastName,
|
|
);
|
|
_setState(EditState.view);
|
|
return true;
|
|
} catch (_) {
|
|
_setError(errorMessage);
|
|
_setState(EditState.edit);
|
|
return false;
|
|
} finally {
|
|
if (_editState == EditState.saving) {
|
|
_setState(EditState.edit);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool _syncNamesFromProvider() {
|
|
if (isEditing) return false;
|
|
final latestFirstName = currentFirstName;
|
|
final latestLastName = currentLastName;
|
|
final didChange = latestFirstName != _lastSyncedFirstName ||
|
|
latestLastName != _lastSyncedLastName;
|
|
if (_firstNameController.text != latestFirstName) {
|
|
_firstNameController.text = latestFirstName;
|
|
}
|
|
if (_lastNameController.text != latestLastName) {
|
|
_lastNameController.text = latestLastName;
|
|
}
|
|
_lastSyncedFirstName = latestFirstName;
|
|
_lastSyncedLastName = latestLastName;
|
|
return didChange;
|
|
}
|
|
|
|
void _setState(EditState value) {
|
|
if (_disposed || _editState == value) return;
|
|
_editState = value;
|
|
notifyListeners();
|
|
}
|
|
|
|
void _setError(String value) {
|
|
if (_disposed) return;
|
|
_errorText = value;
|
|
notifyListeners();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_disposed = true;
|
|
_firstNameController.dispose();
|
|
_lastNameController.dispose();
|
|
super.dispose();
|
|
}
|
|
}
|