updateProfileFields method

Future<void> updateProfileFields({
  1. String? username,
  2. String? displayName,
})

Applies whichever of username and displayName actually changed.

The two are separate endpoints because they are different things: the username is unique and charset-constrained (and so can fail with ErrorCode.usernameTaken or ErrorCode.usernameInvalid), while the display name is free-form and cannot collide.

Implementation

Future<void> updateProfileFields({
  String? username,
  String? displayName,
}) async {
  final current = state.value;
  if (current == null) return;

  final newUsername = username != current.username ? username : null;
  final newDisplayName = displayName != current.displayName
      ? displayName
      : null;
  if (newUsername == null && newDisplayName == null) return;

  state = const AsyncLoading<Profile>();
  final repository = ref.read(profileRepositoryProvider);
  try {
    if (newUsername != null) await repository.updateUsername(newUsername);
    if (newDisplayName != null) {
      await repository.updateDisplayName(newDisplayName);
    }
    await _reload(current);
  } catch (_) {
    // Re-read rather than blindly reverting: with two writes, the first may
    // have committed before the second failed, so restoring the old value
    // would misreport what the server holds.
    await _restore(current);
    rethrow;
  }
}