Files
sendico/frontend/pweb/lib/controllers/auth/account_name.dart
2026-02-21 21:55:20 +03:00

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();
}
}