mirror of
https://github.com/Dvorinka/1356.git
synced 2026-06-04 03:52:57 +00:00
217 lines
6.1 KiB
Dart
217 lines
6.1 KiB
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import '../../../data/models/user_model.dart' as app;
|
|
import '../../../data/repositories/user_repository.dart';
|
|
import '../../../bootstrap/supabase_client.dart';
|
|
import '../../../core/errors/failure.dart';
|
|
import '../../../core/utils/unit_conversion_utils.dart';
|
|
|
|
final profileControllerProvider = StateNotifierProvider<ProfileController, ProfileState>((ref) {
|
|
final client = supabaseClient;
|
|
final repository = client != null ? UserRepository(client) : null;
|
|
return ProfileController(repository);
|
|
});
|
|
|
|
class ProfileController extends StateNotifier<ProfileState> {
|
|
final UserRepository? _repository;
|
|
|
|
ProfileController(this._repository) : super(const ProfileState.initial());
|
|
|
|
Future<void> loadProfile(String userId) async {
|
|
if (_repository == null) {
|
|
state = const ProfileState.error('Profile is unavailable while offline.');
|
|
return;
|
|
}
|
|
|
|
state = const ProfileState.loading();
|
|
try {
|
|
final user = await _repository!.getProfile(userId);
|
|
state = ProfileState.loaded(user);
|
|
} on Failure catch (failure) {
|
|
state = ProfileState.error(failure.message);
|
|
} catch (e) {
|
|
state = ProfileState.error(e.toString());
|
|
}
|
|
}
|
|
|
|
Future<void> updateUsername(String userId, String username) async {
|
|
if (_repository == null) {
|
|
state = const ProfileState.error('Profile is unavailable while offline.');
|
|
return;
|
|
}
|
|
|
|
state = const ProfileState.loading();
|
|
try {
|
|
final isAvailable = await _repository!.isUsernameAvailable(username);
|
|
if (!isAvailable) {
|
|
state = const ProfileState.error('Username is already taken');
|
|
return;
|
|
}
|
|
|
|
final updatedUser = await _repository!.updateProfile(
|
|
userId: userId,
|
|
username: username,
|
|
);
|
|
state = ProfileState.loaded(updatedUser);
|
|
} on Failure catch (failure) {
|
|
state = ProfileState.error(failure.message);
|
|
} catch (e) {
|
|
state = ProfileState.error(e.toString());
|
|
}
|
|
}
|
|
|
|
Future<void> updateBio(String userId, String bio) async {
|
|
if (_repository == null) {
|
|
state = const ProfileState.error('Profile is unavailable while offline.');
|
|
return;
|
|
}
|
|
|
|
state = const ProfileState.loading();
|
|
try {
|
|
final updatedUser = await _repository!.updateProfile(
|
|
userId: userId,
|
|
bio: bio,
|
|
);
|
|
state = ProfileState.loaded(updatedUser);
|
|
} on Failure catch (failure) {
|
|
state = ProfileState.error(failure.message);
|
|
} catch (e) {
|
|
state = ProfileState.error(e.toString());
|
|
}
|
|
}
|
|
|
|
Future<void> updateAvatarUrl(String userId, String avatarUrl) async {
|
|
if (_repository == null) {
|
|
state = const ProfileState.error('Profile is unavailable while offline.');
|
|
return;
|
|
}
|
|
|
|
state = const ProfileState.loading();
|
|
try {
|
|
final updatedUser = await _repository!.updateProfile(
|
|
userId: userId,
|
|
avatarUrl: avatarUrl,
|
|
);
|
|
state = ProfileState.loaded(updatedUser);
|
|
} on Failure catch (failure) {
|
|
state = ProfileState.error(failure.message);
|
|
} catch (e) {
|
|
state = ProfileState.error(e.toString());
|
|
}
|
|
}
|
|
|
|
Future<void> toggleProfileVisibility(String userId) async {
|
|
if (_repository == null) {
|
|
state = const ProfileState.error('Profile is unavailable while offline.');
|
|
return;
|
|
}
|
|
|
|
final currentState = state;
|
|
if (currentState.user == null) return;
|
|
|
|
state = const ProfileState.loading();
|
|
try {
|
|
final updatedUser = await _repository!.updateProfile(
|
|
userId: userId,
|
|
isPublicProfile: !currentState.user!.isPublicProfile,
|
|
);
|
|
state = ProfileState.loaded(updatedUser);
|
|
} on Failure catch (failure) {
|
|
state = ProfileState.error(failure.message);
|
|
} catch (e) {
|
|
state = ProfileState.error(e.toString());
|
|
}
|
|
}
|
|
|
|
Future<void> completeProfileSetup({
|
|
required String userId,
|
|
required String username,
|
|
String? bio,
|
|
String? avatarUrl,
|
|
String? twitterHandle,
|
|
String? instagramHandle,
|
|
String? tiktokHandle,
|
|
String? websiteUrl,
|
|
Gender? gender,
|
|
DateTime? birthDate,
|
|
double? heightCm,
|
|
double? weightKg,
|
|
HeightUnit heightUnit = HeightUnit.metric,
|
|
WeightUnit weightUnit = WeightUnit.metric,
|
|
}) async {
|
|
if (_repository == null) {
|
|
state = const ProfileState.error('Profile is unavailable while offline.');
|
|
return;
|
|
}
|
|
|
|
state = const ProfileState.loading();
|
|
try {
|
|
final isAvailable = await _repository!.isUsernameAvailable(username);
|
|
if (!isAvailable) {
|
|
state = const ProfileState.error('Username is already taken');
|
|
return;
|
|
}
|
|
|
|
final updatedUser = await _repository!.updateProfile(
|
|
userId: userId,
|
|
username: username,
|
|
bio: bio,
|
|
avatarUrl: avatarUrl,
|
|
twitterHandle: twitterHandle,
|
|
instagramHandle: instagramHandle,
|
|
tiktokHandle: tiktokHandle,
|
|
websiteUrl: websiteUrl,
|
|
gender: gender,
|
|
birthDate: birthDate,
|
|
heightCm: heightCm,
|
|
weightKg: weightKg,
|
|
heightUnit: heightUnit,
|
|
weightUnit: weightUnit,
|
|
);
|
|
state = ProfileState.loaded(updatedUser);
|
|
} on Failure catch (failure) {
|
|
state = ProfileState.error(failure.message);
|
|
} catch (e) {
|
|
state = ProfileState.error(e.toString());
|
|
}
|
|
}
|
|
|
|
Future<bool> isProfileSetupComplete(String userId) async {
|
|
if (_repository == null) {
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
final user = await _repository!.getProfile(userId);
|
|
return user.username.isNotEmpty;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
class ProfileState {
|
|
final bool isLoading;
|
|
final app.User? user;
|
|
final String? errorMessage;
|
|
|
|
const ProfileState({
|
|
this.isLoading = false,
|
|
this.user,
|
|
this.errorMessage,
|
|
});
|
|
|
|
const ProfileState.initial() : isLoading = false, user = null, errorMessage = null;
|
|
|
|
const ProfileState.loading() : isLoading = true, user = null, errorMessage = null;
|
|
|
|
const ProfileState.loaded(this.user)
|
|
: isLoading = false,
|
|
errorMessage = null;
|
|
|
|
const ProfileState.error(this.errorMessage)
|
|
: isLoading = false,
|
|
user = null;
|
|
}
|
|
|
|
typedef ProfileStateLoaded = ProfileState;
|