···11+import 'package:atproto/core.dart';
12import 'package:sparksocial/src/core/network/atproto/data/models/actor_models.dart';
2334/// Interface for Actor-related API endpoints
···1718 /// [displayName] The new display name
1819 /// [description] The new description
1920 /// [avatar] The new avatar (optional)
2020- Future<void> updateProfile({required String displayName, required String description, dynamic avatar});
2121+ Future<void> updateProfile({required String displayName, required String description, Blob? avatar});
21222223 /// Check if a user is an early supporter
2324 ///
···70707171 state = state.copyWith(isSaving: true);
72727373- dynamic avatarToSend;
7373+ final atprotoClient = _authRepository.atproto;
7474+ if (atprotoClient == null) {
7575+ throw Exception('AtProto client not initialized');
7676+ }
7777+7878+ Blob? avatarToSend;
74797580 if (state.localAvatar is Uint8List) {
7676- // Upload new avatar blob
7777- final client = _authRepository.atproto!;
7878- final respBlob = await client.repo.uploadBlob(state.localAvatar as Uint8List);
8181+ // A new avatar image was picked, upload it as a blob.
8282+ final respBlob = await atprotoClient.repo.uploadBlob(state.localAvatar as Uint8List);
7983 if (respBlob.status.code != 200) {
8084 throw Exception('Failed to upload avatar blob');
8185 }
8282- avatarToSend = respBlob.data.blob.toJson();
8383- } else if (state.localAvatar is String && state.localAvatar != state.initialAvatar) {
8484- // A string URL was passed that's different from initial - fetch existing record
8686+ avatarToSend = respBlob.data.blob;
8787+ } else if (state.localAvatar == null) {
8888+ // If localAvatar is null, it means the avatar was cleared or never set.
8989+ // Send null to remove any existing avatar from the profile.
9090+ avatarToSend = null;
9191+ } else {
9292+ // If localAvatar is a String (and not null), it implies the avatar was not changed
9393+ // and we need to maintain the existing one by fetching its Blob from the record.
9494+ logger.d('Maintaining existing avatar from record ${state.profile.did}');
8595 final uri = AtUri.parse('at://${state.profile.did}/so.sprk.actor.profile/self');
8686- final recRes = await _authRepository.atproto!.repo.getRecord(uri: uri);
9696+ final recRes = await atprotoClient.repo.getRecord(uri: uri);
8797 final recordData = recRes.data.value;
8888- avatarToSend = recordData['avatar'];
8989- } else if (state.initialAvatar != null) {
9090- // No change but avatar exists - maintain it
9191- final uri = AtUri.parse('at://${state.profile.did}/so.sprk.actor.profile/self');
9292- final recRes = await _authRepository.atproto!.repo.getRecord(uri: uri);
9393- final recordData = recRes.data.value;
9494- avatarToSend = recordData['avatar'];
9898+9999+ // Ensure the 'avatar' field exists and is a Map before converting to Blob.
100100+ // If it's null, it means the user had no avatar on the record.
101101+ if (recordData['avatar'] is Map<String, dynamic>) {
102102+ avatarToSend = Blob.fromJson(recordData['avatar']);
103103+ logger.d('Blob avatar: $avatarToSend');
104104+ } else {
105105+ // This case handles an inconsistency where localAvatar was a string (URL),
106106+ // but the actual record on the server has no avatar. Set to null gracefully.
107107+ logger.w('Local avatar was string, but record has no avatar. Setting avatarToSend to null.');
108108+ avatarToSend = null;
109109+ }
95110 }
9611197112 await actorRepository.updateProfile(