102 lines
3.3 KiB
Dart
102 lines
3.3 KiB
Dart
import 'package:supabase_flutter/supabase_flutter.dart';
|
|
|
|
import '../../../feed/domain/models/feed_post_model.dart';
|
|
import '../../../music/domain/models/track_model.dart';
|
|
import '../../domain/models/discover_data_model.dart';
|
|
import '../../domain/models/trending_user_model.dart';
|
|
|
|
class DiscoverService {
|
|
const DiscoverService(this._client);
|
|
|
|
final SupabaseClient _client;
|
|
|
|
Future<DiscoverDataModel> fetchDiscoverData() async {
|
|
final users = await _fetchTrendingUsers();
|
|
final posts = await _fetchTrendingPosts();
|
|
final tracks = await _fetchTrendingTracks();
|
|
|
|
return DiscoverDataModel(
|
|
trendingUsers: users,
|
|
trendingPosts: posts,
|
|
trendingTracks: tracks,
|
|
);
|
|
}
|
|
|
|
Future<List<TrendingUserModel>> _fetchTrendingUsers() async {
|
|
// Trending users based on total engagement (mocking for now by fetching profiles)
|
|
final profiles = List<Map<String, dynamic>>.from(
|
|
await _client
|
|
.from('profiles')
|
|
.select('user_id, username, avatar_url')
|
|
.limit(20),
|
|
);
|
|
|
|
final users = <TrendingUserModel>[];
|
|
for (final profile in profiles) {
|
|
final userId = profile['user_id'] as String;
|
|
|
|
final postsResponse = await _client
|
|
.from('posts')
|
|
.select('*')
|
|
.eq('user_id', userId);
|
|
|
|
final tracksResponse = await _client
|
|
.from('tracks')
|
|
.select('*')
|
|
.eq('user_id', userId);
|
|
|
|
users.add(
|
|
TrendingUserModel(
|
|
userId: userId,
|
|
username: (profile['username'] as String?) ?? 'RIOT_USER',
|
|
avatarUrl: (profile['avatar_url'] as String?) ?? '',
|
|
postsCount: (postsResponse as List).length,
|
|
tracksCount: (tracksResponse as List).length,
|
|
),
|
|
);
|
|
}
|
|
|
|
// Sort by total content count
|
|
users.sort((a, b) => (b.postsCount + b.tracksCount).compareTo(a.postsCount + a.tracksCount));
|
|
return users.take(10).toList();
|
|
}
|
|
|
|
Future<List<FeedPostModel>> _fetchTrendingPosts() async {
|
|
final rows = List<Map<String, dynamic>>.from(
|
|
await _client
|
|
.from('posts')
|
|
.select('id, user_id, caption, image_url, likes_count, created_at, profiles(username, avatar_url)')
|
|
.order('likes_count', ascending: false)
|
|
.limit(10),
|
|
);
|
|
|
|
return rows.map((row) {
|
|
final profile = (row['profiles'] as Map<String, dynamic>?) ?? {};
|
|
return FeedPostModel(
|
|
id: row['id'] as String,
|
|
userId: row['user_id'] as String,
|
|
caption: (row['caption'] as String?) ?? '',
|
|
imageUrl: (row['image_url'] as String?) ?? '',
|
|
createdAt: DateTime.parse(row['created_at'] as String),
|
|
likesCount: (row['likes_count'] as int?) ?? 0,
|
|
isLiked: false, // Default to false for discover
|
|
username: (profile['username'] as String?) ?? 'RIOTER',
|
|
avatarUrl: (profile['avatar_url'] as String?) ?? '',
|
|
);
|
|
}).toList();
|
|
}
|
|
|
|
Future<List<TrackModel>> _fetchTrendingTracks() async {
|
|
final rows = await _client
|
|
.from('tracks')
|
|
.select('*, profiles(username)')
|
|
.order('plays', ascending: false)
|
|
.limit(10);
|
|
|
|
return List<Map<String, dynamic>>.from(rows).map((row) {
|
|
final username = (row['profiles'] as Map<String, dynamic>?)?['username'] as String?;
|
|
return TrackModel.fromJson(row, username: username);
|
|
}).toList();
|
|
}
|
|
}
|