♻️ Refactored the relationship screen according to server updates

This commit is contained in:
2026-01-07 01:42:20 +08:00
parent 757f1b880c
commit c6fd342072
12 changed files with 197 additions and 110 deletions

View File

@@ -283,14 +283,17 @@
"relationshipStatusBlocked": "Blocked",
"blockUser": "Block User",
"unblockUser": "Unblock User",
"forgotRelationship": "Forgot Relationship",
"forgotRelationshipConfirm": "Are you sure you want to forget your relationship with {}?",
"relationshipDeleted": "Relationship deleted",
"friendRequestAccepted": "Accepted friend request from {}",
"friendRequestDeclined": "Declined friend request from {}",
"requestExpiredIn": "Expired in {}",
"friendSentRequest": "Sent Friend Requests",
"friendSentRequestEmpty": "No sent friend requests",
"friendSentRequestHint": {
"one": "{} friend request sent",
"other": "{} friend requests sent"
"friendRequests": "Friend Requests",
"friendRequestsEmpty": "No related friend requests",
"friendRequestsHint": {
"one": "{} friend request",
"other": "{} friend requests"
},
"levelingProgress": "Leveling Progress",
"levelingProgressExperience": "{} EXP",

View File

@@ -265,6 +265,9 @@
"relationshipStatusBlocked": "Blocked",
"blockUser": "Block User",
"unblockUser": "Unblock User",
"forgotRelationship": "Olvidar Relación",
"forgotRelationshipConfirm": "¿Estás seguro de que quieres olvidar tu relación con {}?",
"relationshipDeleted": "Relación eliminada",
"friendRequestAccepted": "Accepted friend request from {}",
"friendRequestDeclined": "Declined friend request from {}",
"requestExpiredIn": "Expired in {}",

View File

@@ -265,6 +265,9 @@
"relationshipStatusBlocked": "Blocked",
"blockUser": "Block User",
"unblockUser": "Unblock User",
"forgotRelationship": "関係を忘れる",
"forgotRelationshipConfirm": "{} との関係を忘れてもよろしいですか?",
"relationshipDeleted": "関係が削除されました",
"friendRequestAccepted": "Accepted friend request from {}",
"friendRequestDeclined": "Declined friend request from {}",
"requestExpiredIn": "Expired in {}",

View File

@@ -265,6 +265,9 @@
"relationshipStatusBlocked": "Blocked",
"blockUser": "Block User",
"unblockUser": "Unblock User",
"forgotRelationship": "관계 잊기",
"forgotRelationshipConfirm": "{}와의 관계를 잊으시겠습니까?",
"relationshipDeleted": "관계가 삭제되었습니다",
"friendRequestAccepted": "Accepted friend request from {}",
"friendRequestDeclined": "Declined friend request from {}",
"requestExpiredIn": "Expired in {}",

View File

@@ -265,6 +265,9 @@
"relationshipStatusBlocked": "已屏蔽",
"blockUser": "屏蔽用户",
"unblockUser": "解除屏蔽用户",
"forgotRelationship": "忘记关系",
"forgotRelationshipConfirm": "确定要忘记与 {} 的关系吗?",
"relationshipDeleted": "关系已删除",
"friendRequestAccepted": "已接受 {} 的好友请求",
"friendRequestDeclined": "已拒绝 {} 的好友请求",
"requestExpiredIn": "{} 后过期",

View File

@@ -265,6 +265,9 @@
"relationshipStatusBlocked": "已阻",
"blockUser": "禁此戶",
"unblockUser": "解禁",
"forgotRelationship": "忘締交",
"forgotRelationshipConfirm": "確定要忘與 {} 之締交乎?",
"relationshipDeleted": "締交已忘",
"friendRequestAccepted": "已納 {} 締交書",
"friendRequestDeclined": "已謝 {} 締交書",
"requestExpiredIn": "效期 {}",

View File

@@ -265,6 +265,9 @@
"relationshipStatusBlocked": "已屏蔽",
"blockUser": "屏蔽用戶",
"unblockUser": "解除屏蔽用戶",
"forgotRelationship": "忘記關係",
"forgotRelationshipConfirm": "確定要忘記與 {} 的關係嗎?",
"relationshipDeleted": "關係已刪除",
"friendRequestAccepted": "已接受 {} 的好友請求",
"friendRequestDeclined": "已拒絕 {} 的好友請求",
"requestExpiredIn": "{} 後過期",

View File

@@ -12,9 +12,10 @@ sealed class SnRelationship with _$SnRelationship {
required DateTime? updatedAt,
required DateTime? deletedAt,
required String accountId,
required SnAccount account,
// Usually the account was not included in the response
required SnAccount? account,
required String relatedId,
required SnAccount related,
required SnAccount? related,
required DateTime? expiredAt,
required int status,
}) = _SnRelationship;

View File

@@ -15,7 +15,8 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$SnRelationship {
DateTime? get createdAt; DateTime? get updatedAt; DateTime? get deletedAt; String get accountId; SnAccount get account; String get relatedId; SnAccount get related; DateTime? get expiredAt; int get status;
DateTime? get createdAt; DateTime? get updatedAt; DateTime? get deletedAt; String get accountId;// Usually the account was not included in the response
SnAccount? get account; String get relatedId; SnAccount? get related; DateTime? get expiredAt; int get status;
/// Create a copy of SnRelationship
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -48,11 +49,11 @@ abstract mixin class $SnRelationshipCopyWith<$Res> {
factory $SnRelationshipCopyWith(SnRelationship value, $Res Function(SnRelationship) _then) = _$SnRelationshipCopyWithImpl;
@useResult
$Res call({
DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, String accountId, SnAccount account, String relatedId, SnAccount related, DateTime? expiredAt, int status
DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, String accountId, SnAccount? account, String relatedId, SnAccount? related, DateTime? expiredAt, int status
});
$SnAccountCopyWith<$Res> get account;$SnAccountCopyWith<$Res> get related;
$SnAccountCopyWith<$Res>? get account;$SnAccountCopyWith<$Res>? get related;
}
/// @nodoc
@@ -65,16 +66,16 @@ class _$SnRelationshipCopyWithImpl<$Res>
/// Create a copy of SnRelationship
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? accountId = null,Object? account = null,Object? relatedId = null,Object? related = null,Object? expiredAt = freezed,Object? status = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? accountId = null,Object? account = freezed,Object? relatedId = null,Object? related = freezed,Object? expiredAt = freezed,Object? status = null,}) {
return _then(_self.copyWith(
createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,account: null == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
as SnAccount,relatedId: null == relatedId ? _self.relatedId : relatedId // ignore: cast_nullable_to_non_nullable
as String,related: null == related ? _self.related : related // ignore: cast_nullable_to_non_nullable
as SnAccount,expiredAt: freezed == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
as String,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
as SnAccount?,relatedId: null == relatedId ? _self.relatedId : relatedId // ignore: cast_nullable_to_non_nullable
as String,related: freezed == related ? _self.related : related // ignore: cast_nullable_to_non_nullable
as SnAccount?,expiredAt: freezed == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
as DateTime?,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as int,
));
@@ -83,18 +84,24 @@ as int,
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountCopyWith<$Res> get account {
return $SnAccountCopyWith<$Res>(_self.account, (value) {
$SnAccountCopyWith<$Res>? get account {
if (_self.account == null) {
return null;
}
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
return _then(_self.copyWith(account: value));
});
}/// Create a copy of SnRelationship
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountCopyWith<$Res> get related {
return $SnAccountCopyWith<$Res>(_self.related, (value) {
$SnAccountCopyWith<$Res>? get related {
if (_self.related == null) {
return null;
}
return $SnAccountCopyWith<$Res>(_self.related!, (value) {
return _then(_self.copyWith(related: value));
});
}
@@ -176,7 +183,7 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, String accountId, SnAccount account, String relatedId, SnAccount related, DateTime? expiredAt, int status)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, String accountId, SnAccount? account, String relatedId, SnAccount? related, DateTime? expiredAt, int status)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnRelationship() when $default != null:
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.accountId,_that.account,_that.relatedId,_that.related,_that.expiredAt,_that.status);case _:
@@ -197,7 +204,7 @@ return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.accountId,
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, String accountId, SnAccount account, String relatedId, SnAccount related, DateTime? expiredAt, int status) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, String accountId, SnAccount? account, String relatedId, SnAccount? related, DateTime? expiredAt, int status) $default,) {final _that = this;
switch (_that) {
case _SnRelationship():
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.accountId,_that.account,_that.relatedId,_that.related,_that.expiredAt,_that.status);}
@@ -214,7 +221,7 @@ return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.accountId,
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, String accountId, SnAccount account, String relatedId, SnAccount related, DateTime? expiredAt, int status)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, String accountId, SnAccount? account, String relatedId, SnAccount? related, DateTime? expiredAt, int status)? $default,) {final _that = this;
switch (_that) {
case _SnRelationship() when $default != null:
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.accountId,_that.account,_that.relatedId,_that.related,_that.expiredAt,_that.status);case _:
@@ -236,9 +243,10 @@ class _SnRelationship implements SnRelationship {
@override final DateTime? updatedAt;
@override final DateTime? deletedAt;
@override final String accountId;
@override final SnAccount account;
// Usually the account was not included in the response
@override final SnAccount? account;
@override final String relatedId;
@override final SnAccount related;
@override final SnAccount? related;
@override final DateTime? expiredAt;
@override final int status;
@@ -275,11 +283,11 @@ abstract mixin class _$SnRelationshipCopyWith<$Res> implements $SnRelationshipCo
factory _$SnRelationshipCopyWith(_SnRelationship value, $Res Function(_SnRelationship) _then) = __$SnRelationshipCopyWithImpl;
@override @useResult
$Res call({
DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, String accountId, SnAccount account, String relatedId, SnAccount related, DateTime? expiredAt, int status
DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, String accountId, SnAccount? account, String relatedId, SnAccount? related, DateTime? expiredAt, int status
});
@override $SnAccountCopyWith<$Res> get account;@override $SnAccountCopyWith<$Res> get related;
@override $SnAccountCopyWith<$Res>? get account;@override $SnAccountCopyWith<$Res>? get related;
}
/// @nodoc
@@ -292,16 +300,16 @@ class __$SnRelationshipCopyWithImpl<$Res>
/// Create a copy of SnRelationship
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? accountId = null,Object? account = null,Object? relatedId = null,Object? related = null,Object? expiredAt = freezed,Object? status = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? accountId = null,Object? account = freezed,Object? relatedId = null,Object? related = freezed,Object? expiredAt = freezed,Object? status = null,}) {
return _then(_SnRelationship(
createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,account: null == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
as SnAccount,relatedId: null == relatedId ? _self.relatedId : relatedId // ignore: cast_nullable_to_non_nullable
as String,related: null == related ? _self.related : related // ignore: cast_nullable_to_non_nullable
as SnAccount,expiredAt: freezed == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
as String,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
as SnAccount?,relatedId: null == relatedId ? _self.relatedId : relatedId // ignore: cast_nullable_to_non_nullable
as String,related: freezed == related ? _self.related : related // ignore: cast_nullable_to_non_nullable
as SnAccount?,expiredAt: freezed == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
as DateTime?,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as int,
));
@@ -311,18 +319,24 @@ as int,
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountCopyWith<$Res> get account {
return $SnAccountCopyWith<$Res>(_self.account, (value) {
$SnAccountCopyWith<$Res>? get account {
if (_self.account == null) {
return null;
}
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
return _then(_self.copyWith(account: value));
});
}/// Create a copy of SnRelationship
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountCopyWith<$Res> get related {
return $SnAccountCopyWith<$Res>(_self.related, (value) {
$SnAccountCopyWith<$Res>? get related {
if (_self.related == null) {
return null;
}
return $SnAccountCopyWith<$Res>(_self.related!, (value) {
return _then(_self.copyWith(related: value));
});
}

View File

@@ -18,9 +18,13 @@ _SnRelationship _$SnRelationshipFromJson(Map<String, dynamic> json) =>
? null
: DateTime.parse(json['deleted_at'] as String),
accountId: json['account_id'] as String,
account: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
account: json['account'] == null
? null
: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
relatedId: json['related_id'] as String,
related: SnAccount.fromJson(json['related'] as Map<String, dynamic>),
related: json['related'] == null
? null
: SnAccount.fromJson(json['related'] as Map<String, dynamic>),
expiredAt: json['expired_at'] == null
? null
: DateTime.parse(json['expired_at'] as String),
@@ -33,9 +37,9 @@ Map<String, dynamic> _$SnRelationshipToJson(_SnRelationship instance) =>
'updated_at': instance.updatedAt?.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
'account_id': instance.accountId,
'account': instance.account.toJson(),
'account': instance.account?.toJson(),
'related_id': instance.relatedId,
'related': instance.related.toJson(),
'related': instance.related?.toJson(),
'expired_at': instance.expiredAt?.toIso8601String(),
'status': instance.status,
};

View File

@@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/pods/paging.dart';
import 'package:island/pods/userinfo.dart';
@@ -31,11 +32,9 @@ Future<List<SnRelationship>> sentFriendRequest(Ref ref) async {
.toList();
}
final relationshipListNotifierProvider =
AsyncNotifierProvider.autoDispose<
RelationshipListNotifier,
PaginationState<SnRelationship>
>(RelationshipListNotifier.new);
final relationshipListNotifierProvider = AsyncNotifierProvider.autoDispose(
RelationshipListNotifier.new,
);
class RelationshipListNotifier
extends AsyncNotifier<PaginationState<SnRelationship>>
@@ -84,6 +83,7 @@ class RelationshipListTile extends StatelessWidget {
final String? currentUserId;
final bool showRelatedAccount;
final Function(SnRelationship, int)? onUpdateStatus;
final Function(SnRelationship)? onDelete;
const RelationshipListTile({
super.key,
@@ -96,18 +96,19 @@ class RelationshipListTile extends StatelessWidget {
required this.currentUserId,
this.showRelatedAccount = false,
this.onUpdateStatus,
this.onDelete,
});
@override
Widget build(BuildContext context) {
final account = showRelatedAccount
? relationship.related
: relationship.account;
? relationship.related!
: relationship.account!;
final isPending =
relationship.status == 0 && relationship.relatedId == currentUserId;
final isWaiting =
relationship.status == 0 && relationship.accountId == currentUserId;
final isEstablished = relationship.status == 1 || relationship.status == 2;
final isEstablished = relationship.status != 0;
return ListTile(
contentPadding: const EdgeInsets.only(left: 16, right: 12),
@@ -185,21 +186,36 @@ class RelationshipListTile extends StatelessWidget {
itemBuilder: (context) => [
if (relationship.status >= 100) // If friend
PopupMenuItem(
child: ListTile(
leading: const Icon(Symbols.block),
title: Text('blockUser').tr(),
contentPadding: EdgeInsets.zero,
),
onTap: () => onUpdateStatus?.call(relationship, -100),
child: Row(
children: [
const Icon(Symbols.block),
const Gap(12),
Text('blockUser').tr(),
],
),
)
else if (relationship.status <= -100) // If blocked
PopupMenuItem(
child: ListTile(
leading: const Icon(Symbols.person_add),
title: Text('unblockUser').tr(),
contentPadding: EdgeInsets.zero,
),
onTap: () => onUpdateStatus?.call(relationship, 100),
child: Row(
children: [
const Icon(Symbols.person_add),
const Gap(12),
Text('unblockUser').tr(),
],
),
),
if (onDelete != null)
PopupMenuItem(
onTap: () => onDelete?.call(relationship),
child: Row(
children: [
const Icon(Symbols.delete),
const Gap(12),
Text('forgotRelationship').tr(),
],
),
),
],
),
@@ -230,40 +246,11 @@ class RelationshipScreen extends HookConsumerWidget {
final client = ref.read(apiClientProvider);
await client.post('/pass/relationships/${result.id}/friends');
ref.invalidate(sentFriendRequestProvider);
ref.invalidate(friendRequestProvider);
}
final submitting = useState(false);
Future<void> handleFriendRequest(
SnRelationship relationship,
bool isAccept,
) async {
try {
submitting.value = true;
final client = ref.read(apiClientProvider);
await client.post(
'/pass/relationships/${relationship.accountId}/friends/${isAccept ? 'accept' : 'decline'}',
);
relationshipNotifier.refresh();
if (!context.mounted) return;
if (isAccept) {
showSnackBar(
'friendRequestAccepted'.tr(args: ['@${relationship.account.name}']),
);
} else {
showSnackBar(
'friendRequestDeclined'.tr(args: ['@${relationship.account.name}']),
);
}
HapticFeedback.lightImpact();
} catch (err) {
showErrorAlert(err);
} finally {
submitting.value = false;
}
}
Future<void> updateRelationship(
SnRelationship relationship,
int newStatus,
@@ -276,8 +263,32 @@ class RelationshipScreen extends HookConsumerWidget {
relationshipNotifier.refresh();
}
Future<void> deleteRelationship(SnRelationship relationship) async {
final confirmed = await showConfirmAlert(
'forgotRelationshipConfirm'.tr(
args: ['@${relationship.related!.name}'],
),
'forgotRelationship'.tr(),
isDanger: true,
);
if (!confirmed) return;
if (!context.mounted) return;
showLoadingModal(context);
try {
final client = ref.read(apiClientProvider);
await client.delete('/pass/relationships/${relationship.accountId}');
relationshipNotifier.refresh();
showSnackBar('relationshipDeleted'.tr());
} catch (err) {
showErrorAlert(err);
} finally {
if (context.mounted) hideLoadingModal(context);
}
}
final user = ref.watch(userInfoProvider);
final requests = ref.watch(sentFriendRequestProvider);
final requests = ref.watch(friendRequestProvider);
return AppScaffold(
appBar: AppBar(title: Text('relationships').tr()),
@@ -293,9 +304,9 @@ class RelationshipScreen extends HookConsumerWidget {
if (requests.hasValue && requests.value!.isNotEmpty)
ListTile(
leading: const Icon(Symbols.send),
title: Text('friendSentRequest').tr(),
title: Text('friendRequests').tr(),
subtitle: Text(
'friendSentRequestHint'.plural(requests.value!.length),
'friendRequestsHint'.plural(requests.value!.length),
),
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
onTap: () {
@@ -316,11 +327,10 @@ class RelationshipScreen extends HookConsumerWidget {
return RelationshipListTile(
relationship: relationship,
submitting: submitting.value,
onAccept: () => handleFriendRequest(relationship, true),
onDecline: () => handleFriendRequest(relationship, false),
currentUserId: user.value?.id,
showRelatedAccount: false,
showRelatedAccount: true,
onUpdateStatus: updateRelationship,
onDelete: deleteRelationship,
);
},
),
@@ -336,19 +346,54 @@ class _SentFriendRequestsSheet extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final requests = ref.watch(sentFriendRequestProvider);
final requests = ref.watch(friendRequestProvider);
final user = ref.watch(userInfoProvider);
Future<void> cancelRequest(SnRelationship request) async {
try {
final client = ref.read(apiClientProvider);
await client.delete('/pass/relationships/${request.relatedId}/friends');
ref.invalidate(sentFriendRequestProvider);
ref.invalidate(friendRequestProvider);
} catch (err) {
showErrorAlert(err);
}
}
final submitting = useState(false);
Future<void> handleFriendRequest(
SnRelationship relationship,
bool isAccept,
) async {
try {
submitting.value = true;
final client = ref.read(apiClientProvider);
await client.post(
'/pass/relationships/${relationship.accountId}/friends/${isAccept ? 'accept' : 'decline'}',
);
ref.invalidate(friendRequestProvider);
if (!context.mounted) return;
if (isAccept) {
showSnackBar(
'friendRequestAccepted'.tr(
args: ['@${relationship.account!.name}'],
),
);
} else {
showSnackBar(
'friendRequestDeclined'.tr(
args: ['@${relationship.account!.name}'],
),
);
}
HapticFeedback.lightImpact();
} catch (err) {
showErrorAlert(err);
} finally {
submitting.value = false;
}
}
return Container(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.8,
@@ -366,7 +411,7 @@ class _SentFriendRequestsSheet extends HookConsumerWidget {
child: Row(
children: [
Text(
'friendSentRequest'.tr(),
'friendRequests'.tr(),
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.w600,
letterSpacing: -0.5,
@@ -377,7 +422,7 @@ class _SentFriendRequestsSheet extends HookConsumerWidget {
icon: const Icon(Symbols.refresh),
style: IconButton.styleFrom(minimumSize: const Size(36, 36)),
onPressed: () {
ref.invalidate(sentFriendRequestProvider);
ref.invalidate(friendRequestProvider);
},
),
IconButton(
@@ -394,7 +439,7 @@ class _SentFriendRequestsSheet extends HookConsumerWidget {
data: (items) => items.isEmpty
? Center(
child: Text(
'friendSentRequestEmpty'.tr(),
'friendRequestsEmpty'.tr(),
textAlign: TextAlign.center,
),
)
@@ -406,6 +451,8 @@ class _SentFriendRequestsSheet extends HookConsumerWidget {
return RelationshipListTile(
relationship: request,
onCancel: () => cancelRequest(request),
onAccept: () => handleFriendRequest(request, true),
onDecline: () => handleFriendRequest(request, false),
currentUserId: user.value?.id,
showRelatedAccount: true,
);

View File

@@ -9,10 +9,10 @@ part of 'relationship.dart';
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
@ProviderFor(sentFriendRequest)
final sentFriendRequestProvider = SentFriendRequestProvider._();
@ProviderFor(friendRequest)
final friendRequestProvider = FriendRequestProvider._();
final class SentFriendRequestProvider
final class FriendRequestProvider
extends
$FunctionalProvider<
AsyncValue<List<SnRelationship>>,
@@ -22,19 +22,19 @@ final class SentFriendRequestProvider
with
$FutureModifier<List<SnRelationship>>,
$FutureProvider<List<SnRelationship>> {
SentFriendRequestProvider._()
FriendRequestProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'sentFriendRequestProvider',
name: r'friendRequestProvider',
isAutoDispose: true,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$sentFriendRequestHash();
String debugGetCreateSourceHash() => _$friendRequestHash();
@$internal
@override
@@ -44,8 +44,8 @@ final class SentFriendRequestProvider
@override
FutureOr<List<SnRelationship>> create(Ref ref) {
return sentFriendRequest(ref);
return friendRequest(ref);
}
}
String _$sentFriendRequestHash() => r'0c52813eb6f86c05f6e0b1e4e840d0d9c350aa9e';
String _$friendRequestHash() => r'b066553f9bd0505a7a272cf10cb3ca312152acd6';