Files
YungR1otz/lib/features/profile/data/services/profile_service.dart
Lucas Saburido cabf2025cd first commit
2026-05-13 16:26:45 +01:00

137 lines
3.5 KiB
Dart

import 'dart:typed_data';
import 'package:supabase_flutter/supabase_flutter.dart';
import '../../domain/models/profile_model.dart';
import '../../domain/models/profile_stats_model.dart';
class ProfileService {
const ProfileService(this._client);
final SupabaseClient _client;
User get _currentUser {
final user = _client.auth.currentUser;
if (user == null) {
throw StateError('No authenticated user');
}
return user;
}
Future<ProfileModel> fetchMyProfile() async {
final user = _currentUser;
final response = await _client
.from('profiles')
.select()
.eq('user_id', user.id)
.maybeSingle();
if (response == null) {
final created = await _client
.from('profiles')
.insert({
'user_id': user.id,
'username': (user.userMetadata?['username'] as String?) ?? '',
'bio': '',
'avatar_url': '',
})
.select()
.single();
return ProfileModel.fromJson(created);
}
return ProfileModel.fromJson(response);
}
Future<ProfileModel> updateUsername(String username) async {
final user = _currentUser;
await _client.auth.updateUser(UserAttributes(data: {'username': username}));
final updated = await _client
.from('profiles')
.update({'username': username})
.eq('user_id', user.id)
.select()
.single();
return ProfileModel.fromJson(updated);
}
Future<ProfileModel> updateBio(String bio) async {
final user = _currentUser;
final updated = await _client
.from('profiles')
.update({'bio': bio})
.eq('user_id', user.id)
.select()
.single();
return ProfileModel.fromJson(updated);
}
Future<ProfileModel> updateProfile({
required String username,
required String bio,
}) async {
final user = _currentUser;
await _client.auth.updateUser(UserAttributes(data: {'username': username}));
final updated = await _client
.from('profiles')
.update({
'username': username,
'bio': bio,
})
.eq('user_id', user.id)
.select()
.single();
return ProfileModel.fromJson(updated);
}
Future<ProfileModel> uploadAvatar({
required Uint8List bytes,
required String extension,
}) async {
final user = _currentUser;
final path =
'avatars/${user.id}/${DateTime.now().millisecondsSinceEpoch}.$extension';
await _client.storage.from('avatars').uploadBinary(
path,
bytes,
fileOptions: const FileOptions(upsert: true),
);
final avatarUrl = _client.storage.from('avatars').getPublicUrl(path);
final updated = await _client
.from('profiles')
.update({'avatar_url': avatarUrl})
.eq('user_id', user.id)
.select()
.single();
return ProfileModel.fromJson(updated);
}
Future<ProfileStatsModel> fetchMyStats() async {
final user = _currentUser;
final postResponse = await _client
.from('posts')
.select('*')
.eq('user_id', user.id);
final commentResponse = await _client
.from('comments')
.select('*')
.eq('user_id', user.id);
final trackResponse = await _client
.from('tracks')
.select('*')
.eq('user_id', user.id);
return ProfileStatsModel(
postsCount: (postResponse as List).length,
commentsCount: (commentResponse as List).length,
tracksCount: (trackResponse as List).length,
);
}
}