All checks were successful
Release / meta (push) Successful in 9s
Release / linux-build (push) Successful in 6m37s
Release / web-build (push) Successful in 5m29s
Release / android-build (push) Successful in 15m58s
Release / release-master (push) Successful in 20s
Release / release-dev (push) Successful in 26s
283 lines
8.2 KiB
Dart
283 lines
8.2 KiB
Dart
part of 'data_service.dart';
|
|
|
|
extension DataServiceFriendships on DataService {
|
|
Future<void> fetchFriendships() async {
|
|
_isFriendshipsLoading = true;
|
|
try {
|
|
final json = await api.get('/friendships');
|
|
List<dynamic>? list;
|
|
if (json is List) {
|
|
list = json;
|
|
} else if (json is Map) {
|
|
for (final key in ['friendships', 'data', 'items', 'results']) {
|
|
final value = json[key];
|
|
if (value is List) {
|
|
list = value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
final parsed = list
|
|
?.whereType<Map>()
|
|
.map((e) => Friendship.fromJson(
|
|
e.map((k, v) => MapEntry(k.toString(), v)),
|
|
))
|
|
.where((f) => f.isAccepted)
|
|
.toList();
|
|
_friendships = parsed ?? [];
|
|
} catch (e) {
|
|
debugPrint('Failed to fetch friendships: $e');
|
|
_friendships = [];
|
|
} finally {
|
|
_isFriendshipsLoading = false;
|
|
_notifyAsync();
|
|
}
|
|
}
|
|
|
|
Future<void> fetchPendingFriendships() async {
|
|
_isPendingFriendshipsLoading = true;
|
|
try {
|
|
final incoming = await _fetchPending('incoming');
|
|
final outgoing = await _fetchPending('outgoing');
|
|
_pendingIncoming = incoming;
|
|
_pendingOutgoing = outgoing;
|
|
} catch (e) {
|
|
debugPrint('Failed to fetch pending friendships: $e');
|
|
_pendingIncoming = [];
|
|
_pendingOutgoing = [];
|
|
} finally {
|
|
_isPendingFriendshipsLoading = false;
|
|
_notifyAsync();
|
|
}
|
|
}
|
|
|
|
Future<List<Friendship>> _fetchPending(String direction) async {
|
|
final json = await api.get('/friendships/pending?direction=$direction');
|
|
List<dynamic>? list;
|
|
if (json is List) {
|
|
list = json;
|
|
} else if (json is Map) {
|
|
for (final key in ['friendships', 'data', 'items', 'results']) {
|
|
final value = json[key];
|
|
if (value is List) {
|
|
list = value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return list
|
|
?.whereType<Map>()
|
|
.map((e) => Friendship.fromJson(
|
|
e.map((k, v) => MapEntry(k.toString(), v)),
|
|
))
|
|
.where((f) => f.isPending)
|
|
.toList() ??
|
|
const [];
|
|
}
|
|
|
|
Future<Friendship?> fetchFriendshipById(String friendshipId) async {
|
|
try {
|
|
final json = await api.get('/friendships/$friendshipId');
|
|
if (json is Map) {
|
|
return Friendship.fromJson(
|
|
json.map((k, v) => MapEntry(k.toString(), v)),
|
|
);
|
|
}
|
|
} catch (e) {
|
|
debugPrint('Failed to fetch friendship $friendshipId: $e');
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Future<List<UserSummary>> searchUsers(
|
|
String query, {
|
|
bool friendsOnly = false,
|
|
}) async {
|
|
final encoded = Uri.encodeComponent(query);
|
|
final json = await api.get(
|
|
'/users/search?search=$encoded${friendsOnly ? '&friends_only=true' : ''}',
|
|
);
|
|
List<dynamic>? list;
|
|
if (json is List) {
|
|
list = json;
|
|
} else if (json is Map) {
|
|
for (final key in ['users', 'data', 'results', 'items']) {
|
|
final value = json[key];
|
|
if (value is List) {
|
|
list = value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (list == null) return const [];
|
|
return list
|
|
.whereType<Map>()
|
|
.map((e) => UserSummary.fromJson(
|
|
e.map((k, v) => MapEntry(k.toString(), v)),
|
|
))
|
|
.toList();
|
|
}
|
|
|
|
Future<Friendship> fetchFriendshipStatus(String targetUserId) async {
|
|
try {
|
|
final json = await api.get('/friendships/status/$targetUserId');
|
|
if (json is Map) {
|
|
return Friendship.fromStatusJson(
|
|
json.map((k, v) => MapEntry(k.toString(), v)),
|
|
targetUserId: targetUserId,
|
|
);
|
|
}
|
|
} catch (e) {
|
|
debugPrint('Failed to fetch friendship status for $targetUserId: $e');
|
|
}
|
|
return Friendship(
|
|
id: null,
|
|
status: 'none',
|
|
requesterId: '',
|
|
addresseeId: targetUserId,
|
|
);
|
|
}
|
|
|
|
Future<Friendship> requestFriendship(
|
|
String targetUserId, {
|
|
UserSummary? targetUser,
|
|
}) async {
|
|
final json = await api.post('/friendships/request', {
|
|
"target_user_id": targetUserId,
|
|
});
|
|
final friendship = _parseAndUpsertFriendship(
|
|
json,
|
|
fallbackStatus: 'pending',
|
|
overrideAddressee: targetUser,
|
|
);
|
|
_pendingOutgoing = [friendship, ..._pendingOutgoing];
|
|
_notifyAsync();
|
|
return friendship;
|
|
}
|
|
|
|
Future<Friendship> acceptFriendship(String friendshipId) async {
|
|
final json = await api.post('/friendships/$friendshipId/accept', {});
|
|
final friendship = _parseAndUpsertFriendship(json, fallbackStatus: 'accepted');
|
|
_pendingIncoming = _pendingIncoming.where((f) => f.id != friendshipId).toList();
|
|
_notifyAsync();
|
|
return friendship;
|
|
}
|
|
|
|
Future<Friendship> rejectFriendship(String friendshipId) async {
|
|
final json = await api.post('/friendships/$friendshipId/reject', {});
|
|
final friendship = _parseAndUpsertFriendship(json, fallbackStatus: 'declined');
|
|
_pendingIncoming = _pendingIncoming.where((f) => f.id != friendshipId).toList();
|
|
_notifyAsync();
|
|
return friendship;
|
|
}
|
|
|
|
Future<Friendship> cancelFriendship(String friendshipId) async {
|
|
final json = await api.post('/friendships/$friendshipId/cancel', {});
|
|
final friendship =
|
|
_parseAndRemoveFriendship(json, friendshipId, status: 'none');
|
|
_pendingOutgoing =
|
|
_pendingOutgoing.where((f) => f.id != friendshipId).toList();
|
|
_notifyAsync();
|
|
return friendship;
|
|
}
|
|
|
|
Future<void> deleteFriendship(String friendshipId) async {
|
|
try {
|
|
await api.delete('/friendships/$friendshipId');
|
|
} catch (e) {
|
|
debugPrint('Failed to delete friendship $friendshipId: $e');
|
|
rethrow;
|
|
}
|
|
_friendships = _friendships.where((f) => f.id != friendshipId).toList();
|
|
_pendingIncoming =
|
|
_pendingIncoming.where((f) => f.id != friendshipId).toList();
|
|
_pendingOutgoing =
|
|
_pendingOutgoing.where((f) => f.id != friendshipId).toList();
|
|
_notifyAsync();
|
|
}
|
|
|
|
Future<Friendship> blockUser(String targetUserId) async {
|
|
final json = await api.post('/friendships/block', {
|
|
"target_user_id": targetUserId,
|
|
});
|
|
final friendship = _parseAndUpsertFriendship(json, fallbackStatus: 'blocked');
|
|
_pendingIncoming = _pendingIncoming
|
|
.where((f) => f.addresseeId != targetUserId && f.requesterId != targetUserId)
|
|
.toList();
|
|
_pendingOutgoing = _pendingOutgoing
|
|
.where((f) => f.addresseeId != targetUserId && f.requesterId != targetUserId)
|
|
.toList();
|
|
_notifyAsync();
|
|
return friendship;
|
|
}
|
|
|
|
Friendship _parseAndUpsertFriendship(
|
|
dynamic json, {
|
|
String fallbackStatus = 'none',
|
|
UserSummary? overrideAddressee,
|
|
}) {
|
|
Friendship friendship;
|
|
if (json is Map) {
|
|
friendship = Friendship.fromJson(
|
|
json.map((k, v) => MapEntry(k.toString(), v)),
|
|
);
|
|
} else {
|
|
friendship = Friendship(
|
|
id: null,
|
|
status: fallbackStatus,
|
|
requesterId: '',
|
|
addresseeId: '',
|
|
);
|
|
}
|
|
if (overrideAddressee != null &&
|
|
(friendship.addressee == null ||
|
|
friendship.addressee!.userId.isEmpty ||
|
|
friendship.addressee!.displayName.isEmpty)) {
|
|
friendship = friendship.copyWith(
|
|
addressee: overrideAddressee,
|
|
addresseeId: overrideAddressee.userId,
|
|
);
|
|
}
|
|
_upsertFriendship(friendship);
|
|
return friendship;
|
|
}
|
|
|
|
Friendship _parseAndRemoveFriendship(
|
|
dynamic json,
|
|
String friendshipId, {
|
|
required String status,
|
|
}) {
|
|
Friendship friendship;
|
|
if (json is Map) {
|
|
friendship = Friendship.fromJson(
|
|
json.map((k, v) => MapEntry(k.toString(), v)),
|
|
);
|
|
} else {
|
|
friendship = Friendship(
|
|
id: friendshipId,
|
|
status: status,
|
|
requesterId: '',
|
|
addresseeId: '',
|
|
);
|
|
}
|
|
_friendships = _friendships.where((f) => f.id != friendshipId).toList();
|
|
_notifyAsync();
|
|
return friendship;
|
|
}
|
|
|
|
void _upsertFriendship(Friendship friendship) {
|
|
if (friendship.id == null || friendship.id!.isEmpty) {
|
|
_notifyAsync();
|
|
return;
|
|
}
|
|
final idx = _friendships.indexWhere((f) => f.id == friendship.id);
|
|
if (idx >= 0) {
|
|
_friendships[idx] = friendship;
|
|
} else {
|
|
_friendships = [friendship, ..._friendships];
|
|
}
|
|
_friendships = _friendships.where((f) => f.isAccepted).toList();
|
|
_notifyAsync();
|
|
}
|
|
}
|