/ app / lib / providers / user_profile_provider.dart
user_profile_provider.dart
  1  import 'dart:io';
  2  
  3  import 'package:flutter_riverpod/flutter_riverpod.dart';
  4  
  5  import '../services/user_profile_service.dart';
  6  
  7  /// Provider for the UserProfileService singleton.
  8  final userProfileServiceProvider = Provider<UserProfileService>((ref) {
  9    return UserProfileService.instance;
 10  });
 11  
 12  /// State for the user profile.
 13  class UserProfileState {
 14    final String? picturePath;
 15    final String? displayName;
 16    final Set<String> shareProfileContactIds;
 17    final bool shareWithAll;
 18  
 19    const UserProfileState({
 20      this.picturePath,
 21      this.displayName,
 22      this.shareProfileContactIds = const {},
 23      this.shareWithAll = false,
 24    });
 25  
 26    UserProfileState copyWith({
 27      String? picturePath,
 28      String? displayName,
 29      Set<String>? shareProfileContactIds,
 30      bool? shareWithAll,
 31      bool clearPicture = false,
 32      bool clearDisplayName = false,
 33    }) {
 34      return UserProfileState(
 35        picturePath: clearPicture ? null : (picturePath ?? this.picturePath),
 36        displayName: clearDisplayName ? null : (displayName ?? this.displayName),
 37        shareProfileContactIds:
 38            shareProfileContactIds ?? this.shareProfileContactIds,
 39        shareWithAll: shareWithAll ?? this.shareWithAll,
 40      );
 41    }
 42  }
 43  
 44  /// Notifier for user profile state.
 45  class UserProfileNotifier extends StateNotifier<UserProfileState> {
 46    final UserProfileService _service;
 47  
 48    UserProfileNotifier(this._service) : super(const UserProfileState()) {
 49      _load();
 50    }
 51  
 52    Future<void> _load() async {
 53      await _service.init();
 54      state = UserProfileState(
 55        picturePath: await _service.picturePath,
 56        displayName: _service.displayName,
 57        shareProfileContactIds: _service.shareProfileContactIds,
 58        shareWithAll: _service.shareWithAll,
 59      );
 60    }
 61  
 62    Future<void> setPicture(File imageFile) async {
 63      final path = await _service.setPicture(imageFile);
 64      state = state.copyWith(picturePath: path);
 65    }
 66  
 67    Future<void> removePicture() async {
 68      await _service.removePicture();
 69      state = state.copyWith(clearPicture: true);
 70    }
 71  
 72    Future<void> setDisplayName(String? name) async {
 73      await _service.setDisplayName(name);
 74      if (name == null || name.isEmpty) {
 75        state = state.copyWith(clearDisplayName: true);
 76      } else {
 77        state = state.copyWith(displayName: name);
 78      }
 79    }
 80  
 81    bool isSharedWith(String contactIdHex) {
 82      return _service.isSharedWith(contactIdHex);
 83    }
 84  
 85    /// Toggle sharing and return the new state.
 86    Future<bool> toggleShareWith(String contactIdHex) async {
 87      final nowShared = await _service.toggleShareWith(contactIdHex);
 88      state = state.copyWith(
 89        shareProfileContactIds: _service.shareProfileContactIds,
 90      );
 91      return nowShared;
 92    }
 93  
 94    Future<void> setShareWith(String contactIdHex, bool share) async {
 95      await _service.setShareWith(contactIdHex, share);
 96      state = state.copyWith(
 97        shareProfileContactIds: _service.shareProfileContactIds,
 98      );
 99    }
100  
101    int get sharedContactCount => state.shareProfileContactIds.length;
102  
103    Future<void> setShareWithAll(bool value) async {
104      await _service.setShareWithAll(value);
105      state = state.copyWith(shareWithAll: value);
106    }
107  
108    Future<List<String>> ensureAllContactsShared(List<String> allContactHexIds) async {
109      final newIds = await _service.ensureAllContactsShared(allContactHexIds);
110      state = state.copyWith(
111        shareProfileContactIds: _service.shareProfileContactIds,
112      );
113      return newIds;
114    }
115  }
116  
117  /// Provider for user profile notifier.
118  final userProfileProvider =
119      StateNotifierProvider<UserProfileNotifier, UserProfileState>((ref) {
120    final service = ref.watch(userProfileServiceProvider);
121    return UserProfileNotifier(service);
122  });