143 lines
4.0 KiB
Dart
143 lines
4.0 KiB
Dart
import 'package:supabase_flutter/supabase_flutter.dart';
|
|
|
|
class UserInfo {
|
|
final String? userId;
|
|
final String? email;
|
|
final String? username;
|
|
final String? avatarUrl;
|
|
|
|
UserInfo({this.userId, this.email, this.username, this.avatarUrl});
|
|
}
|
|
|
|
class ProfileService {
|
|
final _supabase = Supabase.instance.client;
|
|
|
|
// Cache to store profile data
|
|
final Map<String, String> _usernameCache = {};
|
|
final Map<String, String> _emailCache = {};
|
|
final Map<String, String> _avatarUrlCache = {};
|
|
|
|
String? _currentUserEmail;
|
|
String? _currentUsername;
|
|
String? _currentAvatarUrl;
|
|
|
|
Future<void> initialize() async {
|
|
await _loadCurrentUserProfile();
|
|
}
|
|
|
|
void dispose() {
|
|
// No resources to clean up
|
|
}
|
|
|
|
Future<void> _loadCurrentUserProfile() async {
|
|
final userId = _supabase.auth.currentUser?.id;
|
|
_currentUserEmail = _supabase.auth.currentUser?.email;
|
|
|
|
if (userId == null) return;
|
|
|
|
// Store current user email in cache
|
|
if (_currentUserEmail != null) {
|
|
_emailCache[userId] = _currentUserEmail!;
|
|
}
|
|
|
|
// Try to get profile data
|
|
try {
|
|
final profile = await _supabase
|
|
.from('profiles')
|
|
.select('username, avatar_url')
|
|
.eq('user_id', userId)
|
|
.single();
|
|
|
|
if (profile != null) {
|
|
if (profile['username'] != null && profile['username'].toString().isNotEmpty) {
|
|
_currentUsername = profile['username'] as String;
|
|
_usernameCache[userId] = _currentUsername!;
|
|
}
|
|
|
|
if (profile['avatar_url'] != null && profile['avatar_url'].toString().isNotEmpty) {
|
|
_currentAvatarUrl = profile['avatar_url'] as String;
|
|
_avatarUrlCache[userId] = _currentAvatarUrl!;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
print("[ERROR] Failed to get current user profile: $e");
|
|
}
|
|
|
|
// Use email as fallback username
|
|
if (_currentUsername == null && _currentUserEmail != null) {
|
|
_currentUsername = _currentUserEmail!.split('@')[0];
|
|
}
|
|
}
|
|
|
|
Future<UserInfo> getCurrentUser() async {
|
|
final userId = _supabase.auth.currentUser?.id;
|
|
|
|
if (_currentUsername == null || _currentAvatarUrl == null) {
|
|
await _loadCurrentUserProfile();
|
|
}
|
|
|
|
return UserInfo(
|
|
userId: userId,
|
|
email: _currentUserEmail,
|
|
username: _currentUsername,
|
|
avatarUrl: _currentAvatarUrl,
|
|
);
|
|
}
|
|
|
|
Future<UserInfo> getUserProfile(String userId) async {
|
|
// Check if we have this user in cache
|
|
final email = _emailCache[userId];
|
|
final username = _usernameCache[userId];
|
|
final avatarUrl = _avatarUrlCache[userId];
|
|
|
|
// If we have all the data, return from cache
|
|
if (username != null && avatarUrl != null) {
|
|
return UserInfo(
|
|
userId: userId,
|
|
email: email,
|
|
username: username,
|
|
avatarUrl: avatarUrl,
|
|
);
|
|
}
|
|
|
|
// Otherwise fetch from database
|
|
try {
|
|
final profile = await _supabase
|
|
.from('profiles')
|
|
.select('username, avatar_url')
|
|
.eq('user_id', userId)
|
|
.maybeSingle();
|
|
|
|
if (profile != null) {
|
|
final fetchedUsername = profile['username'] as String?;
|
|
final fetchedAvatarUrl = profile['avatar_url'] as String?;
|
|
|
|
// Update cache
|
|
if (fetchedUsername != null && fetchedUsername.isNotEmpty) {
|
|
_usernameCache[userId] = fetchedUsername;
|
|
}
|
|
|
|
if (fetchedAvatarUrl != null && fetchedAvatarUrl.isNotEmpty) {
|
|
_avatarUrlCache[userId] = fetchedAvatarUrl;
|
|
}
|
|
|
|
return UserInfo(
|
|
userId: userId,
|
|
email: email,
|
|
username: fetchedUsername ?? (email != null ? email.split('@')[0] : null),
|
|
avatarUrl: fetchedAvatarUrl,
|
|
);
|
|
}
|
|
} catch (e) {
|
|
print("[ERROR] Failed to fetch user profile: $e");
|
|
}
|
|
|
|
// Return what we have if fetch failed
|
|
return UserInfo(
|
|
userId: userId,
|
|
email: email,
|
|
username: username ?? (email != null ? email.split('@')[0] : null),
|
|
avatarUrl: avatarUrl,
|
|
);
|
|
}
|
|
} |