修复问题
This commit is contained in:
parent
de4a06be77
commit
5f6bd6f5f8
@ -889,6 +889,9 @@ class _MessageItem extends StatelessWidget {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final state = _cpInviteStateForMessage(data);
|
final state = _cpInviteStateForMessage(data);
|
||||||
|
if (_shouldRenderCpInviteCardForData(data, state)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (state == _CpInviteMessageState.pending || !_isCpInvitePayload(data)) {
|
if (state == _CpInviteMessageState.pending || !_isCpInvitePayload(data)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1325,6 +1328,21 @@ class _MessageItem extends StatelessWidget {
|
|||||||
return _firstNonBlankString([nickname, actualAccount, account, fallback]);
|
return _firstNonBlankString([nickname, actualAccount, account, fallback]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _shouldRenderCpInviteCardForData(
|
||||||
|
Map<String, dynamic> data, [
|
||||||
|
_CpInviteMessageState? state,
|
||||||
|
]) {
|
||||||
|
if (!_isCpInvitePayload(data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final applyId = _cpApplyIdFromData(data);
|
||||||
|
if (applyId.isEmpty || _cpInviteFromMessageData(data) == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final effectiveState = state ?? _cpInviteStateForMessage(data);
|
||||||
|
return effectiveState != _CpInviteMessageState.accepted;
|
||||||
|
}
|
||||||
|
|
||||||
String _firstNonBlankString(
|
String _firstNonBlankString(
|
||||||
Iterable<String?> values, {
|
Iterable<String?> values, {
|
||||||
String fallback = "User",
|
String fallback = "User",
|
||||||
@ -1506,7 +1524,7 @@ class _MessageItem extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
} else if (type == SCSysytemMessageType.CP_BUILD.name) {
|
} else if (_shouldRenderCpInviteCardForData(data)) {
|
||||||
final cpInvite = _cpInviteFromMessageData(data);
|
final cpInvite = _cpInviteFromMessageData(data);
|
||||||
return _buildCpBuildMessage(data, (ct, content) {
|
return _buildCpBuildMessage(data, (ct, content) {
|
||||||
_showMsgItemMenu(ct, content);
|
_showMsgItemMenu(ct, content);
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import 'package:yumi/shared/tools/sc_gift_vap_svga_manager.dart';
|
|||||||
import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
|
import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
|
||||||
import 'package:yumi/shared/data_sources/sources/remote/net/api.dart';
|
import 'package:yumi/shared/data_sources/sources/remote/net/api.dart';
|
||||||
import 'package:yumi/shared/data_sources/sources/repositories/sc_room_repository_imp.dart';
|
import 'package:yumi/shared/data_sources/sources/repositories/sc_room_repository_imp.dart';
|
||||||
|
import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/login_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/login_res.dart';
|
||||||
import 'package:yumi/shared/tools/sc_cp_gift_relation_utils.dart';
|
import 'package:yumi/shared/tools/sc_cp_gift_relation_utils.dart';
|
||||||
import 'package:yumi/main.dart';
|
import 'package:yumi/main.dart';
|
||||||
@ -1519,6 +1520,8 @@ class _GiftPageState extends State<GiftPage> with TickerProviderStateMixin {
|
|||||||
'giftType=$giftType',
|
'giftType=$giftType',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await _showCpGiftRelationCheckToastIfNeeded(request);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final repository = SCChatRoomRepository();
|
final repository = SCChatRoomRepository();
|
||||||
_giftFxLog(
|
_giftFxLog(
|
||||||
@ -1725,6 +1728,49 @@ class _GiftPageState extends State<GiftPage> with TickerProviderStateMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _showCpGiftRelationCheckToastIfNeeded(
|
||||||
|
_GiftSendRequest request,
|
||||||
|
) async {
|
||||||
|
final relationType = request.cpRelationType;
|
||||||
|
if (relationType == null || relationType.trim().isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final acceptUserId = request.acceptUserIds
|
||||||
|
.map((userId) => userId.trim())
|
||||||
|
.firstWhere((userId) => userId.isNotEmpty, orElse: () => '');
|
||||||
|
if (acceptUserId.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final result = await SCAccountRepository().cpGiftRelationCheck(
|
||||||
|
acceptUserId: acceptUserId,
|
||||||
|
relationType: relationType,
|
||||||
|
);
|
||||||
|
final message = result.msg.trim();
|
||||||
|
_giftFxLog(
|
||||||
|
'cp gift relation check '
|
||||||
|
'acceptUserId=$acceptUserId '
|
||||||
|
'relationType=$relationType '
|
||||||
|
'status=${result.status} '
|
||||||
|
'msg=$message '
|
||||||
|
'userCount=${result.userRelationCount}/${result.maxRelationCount} '
|
||||||
|
'acceptCount=${result.acceptUserRelationCount}/${result.maxRelationCount}',
|
||||||
|
);
|
||||||
|
if (!result.status &&
|
||||||
|
message.isNotEmpty &&
|
||||||
|
message.toUpperCase() != 'OK') {
|
||||||
|
SCTts.show(message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
_giftFxLog(
|
||||||
|
'cp gift relation check skipped '
|
||||||
|
'acceptUserId=$acceptUserId '
|
||||||
|
'relationType=$relationType '
|
||||||
|
'error=$error',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<MicRes>> _giveBackpackGiftToRecipients(
|
Future<List<MicRes>> _giveBackpackGiftToRecipients(
|
||||||
SCChatRoomRepository repository,
|
SCChatRoomRepository repository,
|
||||||
_GiftSendRequest request,
|
_GiftSendRequest request,
|
||||||
@ -1857,7 +1903,7 @@ class _GiftPageState extends State<GiftPage> with TickerProviderStateMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
num coins = (gift.giftCandy ?? 0) * quantity;
|
num coins = (gift.giftCandy ?? 0) * quantity;
|
||||||
if (coins > 9999) {
|
if (coins > 9999 && !_isCpGift(gift)) {
|
||||||
var fMsg = SCFloatingMessage(
|
var fMsg = SCFloatingMessage(
|
||||||
type: 1,
|
type: 1,
|
||||||
userId: AccountStorage().getCurrentUser()?.userProfile?.id ?? "",
|
userId: AccountStorage().getCurrentUser()?.userProfile?.id ?? "",
|
||||||
@ -1900,7 +1946,8 @@ class _GiftPageState extends State<GiftPage> with TickerProviderStateMixin {
|
|||||||
'animationCount=$animationCount',
|
'animationCount=$animationCount',
|
||||||
);
|
);
|
||||||
SCGiftVapSvgaManager().play(gift.giftSourceUrl!);
|
SCGiftVapSvgaManager().play(gift.giftSourceUrl!);
|
||||||
} else if (SCGlobalConfig.isLowPerformanceDevice &&
|
} else if (!_isCpGift(gift) &&
|
||||||
|
SCGlobalConfig.isLowPerformanceDevice &&
|
||||||
SCGlobalConfig.isGiftSpecialEffects &&
|
SCGlobalConfig.isGiftSpecialEffects &&
|
||||||
(rtcProvider?.shouldShowRoomVisualEffects ?? false)) {
|
(rtcProvider?.shouldShowRoomVisualEffects ?? false)) {
|
||||||
_enqueueLowPerformanceGiftCompensation(
|
_enqueueLowPerformanceGiftCompensation(
|
||||||
|
|||||||
@ -21,10 +21,12 @@ import 'package:yumi/services/music/room_music_manager.dart';
|
|||||||
import 'package:yumi/services/audio/rtm_manager.dart';
|
import 'package:yumi/services/audio/rtm_manager.dart';
|
||||||
import 'package:yumi/shared/tools/sc_gift_vap_svga_manager.dart';
|
import 'package:yumi/shared/tools/sc_gift_vap_svga_manager.dart';
|
||||||
import 'package:yumi/shared/tools/sc_lucky_gift_win_sound_player.dart';
|
import 'package:yumi/shared/tools/sc_lucky_gift_win_sound_player.dart';
|
||||||
|
import 'package:yumi/shared/tools/sc_cp_gift_relation_utils.dart';
|
||||||
import 'package:yumi/shared/tools/sc_network_image_utils.dart';
|
import 'package:yumi/shared/tools/sc_network_image_utils.dart';
|
||||||
import 'package:yumi/shared/tools/sc_path_utils.dart';
|
import 'package:yumi/shared/tools/sc_path_utils.dart';
|
||||||
import 'package:yumi/shared/tools/sc_room_effect_scheduler.dart';
|
import 'package:yumi/shared/tools/sc_room_effect_scheduler.dart';
|
||||||
import 'package:yumi/shared/tools/sc_room_top_layer_guard.dart';
|
import 'package:yumi/shared/tools/sc_room_top_layer_guard.dart';
|
||||||
|
import 'package:yumi/shared/data_sources/models/message/sc_floating_message.dart';
|
||||||
import 'package:yumi/shared/data_sources/sources/local/floating_screen_manager.dart';
|
import 'package:yumi/shared/data_sources/sources/local/floating_screen_manager.dart';
|
||||||
import 'package:yumi/ui_kit/widgets/room/anim/l_gift_animal_view.dart';
|
import 'package:yumi/ui_kit/widgets/room/anim/l_gift_animal_view.dart';
|
||||||
import 'package:yumi/ui_kit/widgets/room/anim/room_gift_seat_flight_overlay.dart';
|
import 'package:yumi/ui_kit/widgets/room/anim/room_gift_seat_flight_overlay.dart';
|
||||||
@ -741,6 +743,7 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
final giftPhoto = (msg.gift?.giftPhoto ?? "").trim();
|
final giftPhoto = (msg.gift?.giftPhoto ?? "").trim();
|
||||||
|
_enqueueCpGiftFloatingIfNeeded(msg);
|
||||||
if (_supportsComboMilestoneEffects(msg)) {
|
if (_supportsComboMilestoneEffects(msg)) {
|
||||||
_handleComboMilestoneVisuals(msg, targetGroupKey);
|
_handleComboMilestoneVisuals(msg, targetGroupKey);
|
||||||
}
|
}
|
||||||
@ -762,6 +765,48 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _enqueueCpGiftFloatingIfNeeded(Msg msg) {
|
||||||
|
final gift = msg.gift;
|
||||||
|
if (!scIsCpGift(gift) || gift == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final quantity = msg.number ?? 0;
|
||||||
|
if (quantity <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final roomId = _resolveGiftFloatingRoomId(msg);
|
||||||
|
OverlayManager().addMessage(
|
||||||
|
SCFloatingMessage(
|
||||||
|
type: 1,
|
||||||
|
priority: 900,
|
||||||
|
userId: msg.user?.id ?? "",
|
||||||
|
toUserId: msg.toUser?.id ?? "",
|
||||||
|
userAvatarUrl: msg.user?.userAvatar ?? "",
|
||||||
|
toUserAvatarUrl: msg.toUser?.userAvatar ?? "",
|
||||||
|
userName: msg.user?.userNickname ?? "",
|
||||||
|
toUserName: msg.toUser?.userNickname ?? "",
|
||||||
|
giftUrl: gift.giftPhoto ?? "",
|
||||||
|
giftId: gift.id,
|
||||||
|
giftTab: scCpRelationTypeForGift(gift),
|
||||||
|
number: quantity,
|
||||||
|
coins: quantity * (gift.giftCandy ?? 0),
|
||||||
|
roomId: roomId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String _resolveGiftFloatingRoomId(Msg msg) {
|
||||||
|
final messageRoomId = (msg.msg ?? "").trim();
|
||||||
|
if (messageRoomId.isNotEmpty) {
|
||||||
|
return messageRoomId;
|
||||||
|
}
|
||||||
|
return Provider.of<RtcProvider>(
|
||||||
|
context,
|
||||||
|
listen: false,
|
||||||
|
).currenRoom?.roomProfile?.roomProfile?.id ??
|
||||||
|
"";
|
||||||
|
}
|
||||||
|
|
||||||
void _luckyGiftRewardTickerListener(Msg msg) {
|
void _luckyGiftRewardTickerListener(Msg msg) {
|
||||||
if (!Provider.of<RtcProvider>(
|
if (!Provider.of<RtcProvider>(
|
||||||
context,
|
context,
|
||||||
|
|||||||
@ -259,9 +259,7 @@ class _EditUserInfoPage2State extends State<EditUserInfoPage2>
|
|||||||
sex == 1
|
sex == 1
|
||||||
? SCAppLocalizations.of(context)!.man
|
? SCAppLocalizations.of(context)!.man
|
||||||
: SCAppLocalizations.of(context)!.woman,
|
: SCAppLocalizations.of(context)!.woman,
|
||||||
() {
|
null,
|
||||||
_showSexDialog();
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
|
|
||||||
_buildItem(
|
_buildItem(
|
||||||
@ -538,6 +536,7 @@ class _EditUserInfoPage2State extends State<EditUserInfoPage2>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore: unused_element
|
||||||
void _showSexDialog() {
|
void _showSexDialog() {
|
||||||
showCenterDialog(
|
showCenterDialog(
|
||||||
context,
|
context,
|
||||||
@ -619,7 +618,7 @@ class _EditUserInfoPage2State extends State<EditUserInfoPage2>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildItem(String title, String value, Function() func) {
|
_buildItem(String title, String value, Function()? func) {
|
||||||
return SCDebounceWidget(
|
return SCDebounceWidget(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
@ -638,11 +637,12 @@ class _EditUserInfoPage2State extends State<EditUserInfoPage2>
|
|||||||
child: text(value, textColor: Colors.white, fontSize: 15.sp),
|
child: text(value, textColor: Colors.white, fontSize: 15.sp),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Icon(
|
if (func != null)
|
||||||
Icons.keyboard_arrow_right,
|
Icon(
|
||||||
size: 20.w,
|
Icons.keyboard_arrow_right,
|
||||||
color: Colors.white70,
|
size: 20.w,
|
||||||
),
|
color: Colors.white70,
|
||||||
|
),
|
||||||
SizedBox(width: 8.w),
|
SizedBox(width: 8.w),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -656,7 +656,7 @@ class _EditUserInfoPage2State extends State<EditUserInfoPage2>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
func.call();
|
func?.call();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -109,13 +109,25 @@ class _PersonDetailPageState extends State<PersonDetailPage> with RouteAware {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Provider.of<SocialChatUserProfileManager>(context, listen: false)
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
.userProfile = null;
|
if (!mounted) {
|
||||||
Provider.of<SocialChatUserProfileManager>(
|
return;
|
||||||
|
}
|
||||||
|
_loadInitialProfileData();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _loadInitialProfileData() {
|
||||||
|
final profileManager = Provider.of<SocialChatUserProfileManager>(
|
||||||
context,
|
context,
|
||||||
listen: false,
|
listen: false,
|
||||||
).getUserInfoById(widget.tageId);
|
);
|
||||||
|
profileManager.userProfile = null;
|
||||||
|
profileManager.getUserInfoById(widget.tageId);
|
||||||
SCAccountRepository().userIdentity(userId: widget.tageId).then((v) {
|
SCAccountRepository().userIdentity(userId: widget.tageId).then((v) {
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
userIdentity = v;
|
userIdentity = v;
|
||||||
setState(() {});
|
setState(() {});
|
||||||
});
|
});
|
||||||
@ -123,11 +135,17 @@ class _PersonDetailPageState extends State<PersonDetailPage> with RouteAware {
|
|||||||
SCAccountRepository()
|
SCAccountRepository()
|
||||||
.followCheck(widget.tageId)
|
.followCheck(widget.tageId)
|
||||||
.then((v) {
|
.then((v) {
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
isFollow = v;
|
isFollow = v;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
setState(() {});
|
setState(() {});
|
||||||
})
|
})
|
||||||
.catchError((e) {
|
.catchError((e) {
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
});
|
});
|
||||||
@ -135,6 +153,9 @@ class _PersonDetailPageState extends State<PersonDetailPage> with RouteAware {
|
|||||||
SCAccountRepository()
|
SCAccountRepository()
|
||||||
.blacklistCheck(widget.tageId)
|
.blacklistCheck(widget.tageId)
|
||||||
.then((v) {
|
.then((v) {
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
isBlacklist = v;
|
isBlacklist = v;
|
||||||
isBlacklistLoading = false;
|
isBlacklistLoading = false;
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@ -145,6 +166,9 @@ class _PersonDetailPageState extends State<PersonDetailPage> with RouteAware {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catchError((e) {
|
.catchError((e) {
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
isBlacklistLoading = false;
|
isBlacklistLoading = false;
|
||||||
});
|
});
|
||||||
@ -1564,7 +1588,7 @@ class _PersonDetailPageState extends State<PersonDetailPage> with RouteAware {
|
|||||||
if (payload.rightUserId.trim().isEmpty) {
|
if (payload.rightUserId.trim().isEmpty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final cancelText = SCAppLocalizations.of(context)!.cancel;
|
const cancelText = 'unbing';
|
||||||
SCLoadingManager.show(context: context);
|
SCLoadingManager.show(context: context);
|
||||||
late final _ProfileRelationProgressData progress;
|
late final _ProfileRelationProgressData progress;
|
||||||
try {
|
try {
|
||||||
@ -1668,6 +1692,15 @@ class _PersonDetailPageState extends State<PersonDetailPage> with RouteAware {
|
|||||||
if (!mounted) {
|
if (!mounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final profileManager = Provider.of<SocialChatUserProfileManager>(
|
||||||
|
context,
|
||||||
|
listen: false,
|
||||||
|
);
|
||||||
|
profileManager.removeLoadedCpRelation(
|
||||||
|
userId: payload.leftUserId,
|
||||||
|
peerUserId: partnerUserId,
|
||||||
|
relationType: payload.relationType,
|
||||||
|
);
|
||||||
Provider.of<RtcProvider?>(
|
Provider.of<RtcProvider?>(
|
||||||
context,
|
context,
|
||||||
listen: false,
|
listen: false,
|
||||||
@ -1676,10 +1709,12 @@ class _PersonDetailPageState extends State<PersonDetailPage> with RouteAware {
|
|||||||
peerUserId: partnerUserId,
|
peerUserId: partnerUserId,
|
||||||
relationType: payload.relationType,
|
relationType: payload.relationType,
|
||||||
);
|
);
|
||||||
await Provider.of<SocialChatUserProfileManager>(
|
await profileManager.refreshLoadedCpProfiles();
|
||||||
context,
|
profileManager.removeLoadedCpRelation(
|
||||||
listen: false,
|
userId: payload.leftUserId,
|
||||||
).refreshLoadedCpProfiles();
|
peerUserId: partnerUserId,
|
||||||
|
relationType: payload.relationType,
|
||||||
|
);
|
||||||
await SmartDialog.dismiss(tag: RoomCpProgressDialog.dialogTag);
|
await SmartDialog.dismiss(tag: RoomCpProgressDialog.dialogTag);
|
||||||
SCTts.show(l10n.operationSuccessful);
|
SCTts.show(l10n.operationSuccessful);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
@ -2693,7 +2728,21 @@ class _PersonDetailPageState extends State<PersonDetailPage> with RouteAware {
|
|||||||
ref.userProfile?.id ?? "",
|
ref.userProfile?.id ?? "",
|
||||||
relationType: cpRelation?.relationType ?? "CP",
|
relationType: cpRelation?.relationType ?? "CP",
|
||||||
)
|
)
|
||||||
.then((result) {
|
.then((result) async {
|
||||||
|
final currentUserId =
|
||||||
|
AccountStorage()
|
||||||
|
.getCurrentUser()
|
||||||
|
?.userProfile
|
||||||
|
?.id
|
||||||
|
?.trim() ??
|
||||||
|
"";
|
||||||
|
final profileUserId =
|
||||||
|
ref.userProfile?.id?.trim() ?? "";
|
||||||
|
ref.removeLoadedCpRelation(
|
||||||
|
userId: currentUserId,
|
||||||
|
peerUserId: profileUserId,
|
||||||
|
relationType: cpRelation?.relationType ?? "CP",
|
||||||
|
);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
Provider.of<RtcProvider?>(
|
Provider.of<RtcProvider?>(
|
||||||
context,
|
context,
|
||||||
@ -2708,7 +2757,12 @@ class _PersonDetailPageState extends State<PersonDetailPage> with RouteAware {
|
|||||||
relationType: cpRelation?.relationType ?? "CP",
|
relationType: cpRelation?.relationType ?? "CP",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ref.refreshLoadedCpProfiles();
|
await ref.refreshLoadedCpProfiles();
|
||||||
|
ref.removeLoadedCpRelation(
|
||||||
|
userId: currentUserId,
|
||||||
|
peerUserId: profileUserId,
|
||||||
|
relationType: cpRelation?.relationType ?? "CP",
|
||||||
|
);
|
||||||
SmartDialog.dismiss(tag: "showPartWaysDialog");
|
SmartDialog.dismiss(tag: "showPartWaysDialog");
|
||||||
SCTts.show(
|
SCTts.show(
|
||||||
SCAppLocalizations.of(
|
SCAppLocalizations.of(
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import 'package:yumi/app/constants/sc_room_msg_type.dart';
|
|||||||
import 'package:yumi/shared/tools/sc_permission_utils.dart';
|
import 'package:yumi/shared/tools/sc_permission_utils.dart';
|
||||||
import 'package:yumi/shared/tools/sc_room_utils.dart';
|
import 'package:yumi/shared/tools/sc_room_utils.dart';
|
||||||
import 'package:yumi/shared/tools/sc_room_top_layer_guard.dart';
|
import 'package:yumi/shared/tools/sc_room_top_layer_guard.dart';
|
||||||
import 'package:yumi/shared/tools/sc_cp_relation_level_utils.dart';
|
|
||||||
import 'package:yumi/shared/tools/sc_cp_relation_notice_utils.dart';
|
import 'package:yumi/shared/tools/sc_cp_relation_notice_utils.dart';
|
||||||
import 'package:yumi/shared/data_sources/models/message/room_rocket_launch_broadcast_message.dart';
|
import 'package:yumi/shared/data_sources/models/message/room_rocket_launch_broadcast_message.dart';
|
||||||
import 'package:yumi/shared/data_sources/models/message/sc_floating_message.dart';
|
import 'package:yumi/shared/data_sources/models/message/sc_floating_message.dart';
|
||||||
@ -1833,31 +1832,23 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
final closeFriendPairs = <CPRes>[];
|
final closeFriendPairs = <CPRes>[];
|
||||||
await Future.wait(
|
await Future.wait(
|
||||||
_roomMicRelationTypes.map((relationType) async {
|
_roomMicRelationTypes.map((relationType) async {
|
||||||
final cabin = await _safeLoadRoomMicRelationCabin(userId, relationType);
|
final pairs = await _safeLoadRoomMicRelationPairs(userId, relationType);
|
||||||
final pair = cabin?.cpPairUserProfileCO;
|
for (final pair in pairs) {
|
||||||
if (!_hasRoomMicRelationPair(pair)) {
|
if (!_hasRoomMicRelationPair(pair)) {
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
final normalizedType = scNormalizeCpRelationType(
|
final normalizedType = scNormalizeCpRelationType(
|
||||||
pair?.relationType ?? relationType,
|
pair.relationType ?? relationType,
|
||||||
);
|
);
|
||||||
final enrichedPair = pair!.copyWith(
|
final enrichedPair = pair.copyWith(relationType: normalizedType);
|
||||||
relationType: normalizedType,
|
if (_isRoomMicRelationLocallyDismissed(enrichedPair)) {
|
||||||
cpValue: pair.cpValue ?? cabin?.cpVal?.toDouble(),
|
continue;
|
||||||
levelText:
|
}
|
||||||
scCpRelationLevelTextFromCabin(
|
if (normalizedType == "CP") {
|
||||||
cabin,
|
cpPairs.add(enrichedPair);
|
||||||
fallbackText: pair.levelText,
|
} else {
|
||||||
) ??
|
closeFriendPairs.add(enrichedPair);
|
||||||
_roomMicRelationLevelTextFromCabin(cabin),
|
}
|
||||||
);
|
|
||||||
if (_isRoomMicRelationLocallyDismissed(enrichedPair)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (normalizedType == "CP") {
|
|
||||||
cpPairs.add(enrichedPair);
|
|
||||||
} else {
|
|
||||||
closeFriendPairs.add(enrichedPair);
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -1868,53 +1859,26 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SCCpCabinRes?> _safeLoadRoomMicRelationCabin(
|
Future<List<CPRes>> _safeLoadRoomMicRelationPairs(
|
||||||
String userId,
|
String userId,
|
||||||
String relationType,
|
String relationType,
|
||||||
) async {
|
) async {
|
||||||
try {
|
try {
|
||||||
return await SCAccountRepository().cpCabin(
|
return await SCAccountRepository().cpRelationshipPairs(
|
||||||
userId,
|
userId: userId,
|
||||||
relationType: relationType,
|
relationType: relationType,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
debugPrint(
|
debugPrint(
|
||||||
"[CP][MicRelation] cabin failed userId=$userId "
|
"[CP][MicRelation] pair failed userId=$userId "
|
||||||
"relationType=$relationType error=$error",
|
"relationType=$relationType error=$error",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return const <CPRes>[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String? _roomMicRelationLevelTextFromCabin(SCCpCabinRes? cabin) {
|
|
||||||
final config = cabin?.currentCpCabinConfigCO;
|
|
||||||
if (config is! Map) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final level = _firstRoomMicRelationConfigText([
|
|
||||||
config["level"],
|
|
||||||
config["cpLevel"],
|
|
||||||
config["cabinLevel"],
|
|
||||||
config["lv"],
|
|
||||||
]);
|
|
||||||
if (level.isEmpty) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return "Lv.$level";
|
|
||||||
}
|
|
||||||
|
|
||||||
String _firstRoomMicRelationConfigText(Iterable<dynamic> values) {
|
|
||||||
for (final value in values) {
|
|
||||||
final text = value?.toString().trim() ?? "";
|
|
||||||
if (text.isNotEmpty) {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void _applyHydratedRoomMicRelationProfile(
|
void _applyHydratedRoomMicRelationProfile(
|
||||||
String roomId,
|
String roomId,
|
||||||
String userId,
|
String userId,
|
||||||
|
|||||||
@ -6338,7 +6338,8 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
'giftId=${gift.id} giftName=${gift.giftName}',
|
'giftId=${gift.id} giftName=${gift.giftName}',
|
||||||
);
|
);
|
||||||
SCGiftVapSvgaManager().play(giftSourceUrl);
|
SCGiftVapSvgaManager().play(giftSourceUrl);
|
||||||
} else if (SCGlobalConfig.isLowPerformanceDevice &&
|
} else if (!scIsCpGift(gift) &&
|
||||||
|
SCGlobalConfig.isLowPerformanceDevice &&
|
||||||
SCGlobalConfig.isGiftSpecialEffects &&
|
SCGlobalConfig.isGiftSpecialEffects &&
|
||||||
rtcProvider.shouldShowRoomVisualEffects) {
|
rtcProvider.shouldShowRoomVisualEffects) {
|
||||||
final roomId =
|
final roomId =
|
||||||
@ -6414,7 +6415,7 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
final coins = (msg.number ?? 0) * (gift.giftCandy ?? 0);
|
final coins = (msg.number ?? 0) * (gift.giftCandy ?? 0);
|
||||||
if (coins > 9999) {
|
if (coins > 9999 && !scIsCpGift(gift)) {
|
||||||
_enqueueGiftFloatingMessage(
|
_enqueueGiftFloatingMessage(
|
||||||
SCFloatingMessage(
|
SCFloatingMessage(
|
||||||
type: 1,
|
type: 1,
|
||||||
|
|||||||
@ -210,6 +210,7 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
|||||||
RoomUserCardRes? userCardInfo;
|
RoomUserCardRes? userCardInfo;
|
||||||
Object? userCardLoadError;
|
Object? userCardLoadError;
|
||||||
bool isUserCardLoading = false;
|
bool isUserCardLoading = false;
|
||||||
|
bool isUserCardRelationLoading = false;
|
||||||
int _userCardRequestSerial = 0;
|
int _userCardRequestSerial = 0;
|
||||||
int _userCardSessionSerial = 0;
|
int _userCardSessionSerial = 0;
|
||||||
int? _activeUserCardSessionSerial;
|
int? _activeUserCardSessionSerial;
|
||||||
@ -235,6 +236,7 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
|||||||
userCardInfo = null;
|
userCardInfo = null;
|
||||||
userCardLoadError = null;
|
userCardLoadError = null;
|
||||||
isUserCardLoading = true;
|
isUserCardLoading = true;
|
||||||
|
isUserCardRelationLoading = false;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
if (normalizedUserId.isEmpty) {
|
if (normalizedUserId.isEmpty) {
|
||||||
@ -257,6 +259,7 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
|||||||
userCardInfo = card;
|
userCardInfo = card;
|
||||||
userCardLoadError = null;
|
userCardLoadError = null;
|
||||||
isUserCardLoading = false;
|
isUserCardLoading = false;
|
||||||
|
isUserCardRelationLoading = card.userProfile != null;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
unawaited(
|
unawaited(
|
||||||
_hydrateRoomUserCard(
|
_hydrateRoomUserCard(
|
||||||
@ -325,8 +328,14 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
userCardInfo = hydratedCard;
|
userCardInfo = hydratedCard;
|
||||||
userCardLoadError = null;
|
userCardLoadError = null;
|
||||||
|
isUserCardRelationLoading = false;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stackTrace) {
|
||||||
|
if (requestSerial == _userCardRequestSerial &&
|
||||||
|
sessionSerial == _activeUserCardSessionSerial) {
|
||||||
|
isUserCardRelationLoading = false;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
_debugProfileLoadFailure(
|
_debugProfileLoadFailure(
|
||||||
scope: 'roomCardHydrate',
|
scope: 'roomCardHydrate',
|
||||||
userId: userId,
|
userId: userId,
|
||||||
@ -346,6 +355,7 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
|||||||
userCardInfo = null;
|
userCardInfo = null;
|
||||||
userCardLoadError = null;
|
userCardLoadError = null;
|
||||||
isUserCardLoading = false;
|
isUserCardLoading = false;
|
||||||
|
isUserCardRelationLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<RoomUserCardRes?> _withCurrentVipLevelForCard(
|
Future<RoomUserCardRes?> _withCurrentVipLevelForCard(
|
||||||
@ -357,7 +367,7 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
|||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
var mergedProfile = await _withCurrentVipLevel(profile, userId);
|
var mergedProfile = await _withCurrentVipLevel(profile, userId);
|
||||||
mergedProfile = await _withCpRelationshipProfiles(mergedProfile, userId);
|
mergedProfile = await _withCpCabinProfiles(mergedProfile, userId);
|
||||||
if (mergedProfile == profile) {
|
if (mergedProfile == profile) {
|
||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
@ -487,44 +497,6 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SocialChatUserProfile> _withCpRelationshipProfiles(
|
|
||||||
SocialChatUserProfile profile,
|
|
||||||
String userId,
|
|
||||||
) async {
|
|
||||||
if (userId.trim().isEmpty) {
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
final cpPairs = <CPRes>[];
|
|
||||||
final closeFriendPairs = <CPRes>[];
|
|
||||||
_addCpRelationPairs(
|
|
||||||
cpPairs: cpPairs,
|
|
||||||
closeFriendPairs: closeFriendPairs,
|
|
||||||
relations: profile.cpList,
|
|
||||||
fallbackRelationType: 'CP',
|
|
||||||
);
|
|
||||||
_addCpRelationPairs(
|
|
||||||
cpPairs: cpPairs,
|
|
||||||
closeFriendPairs: closeFriendPairs,
|
|
||||||
relations: profile.closeFriendList,
|
|
||||||
);
|
|
||||||
await Future.wait(
|
|
||||||
_cpProfileRelationTypes.map((relationType) async {
|
|
||||||
final pairs = await _safeLoadCpRelationshipPairs(userId, relationType);
|
|
||||||
_addCpRelationPairs(
|
|
||||||
cpPairs: cpPairs,
|
|
||||||
closeFriendPairs: closeFriendPairs,
|
|
||||||
relations: pairs,
|
|
||||||
fallbackRelationType: relationType,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
return profile.copyWith(
|
|
||||||
cpList: cpPairs,
|
|
||||||
closeFriendList: closeFriendPairs,
|
|
||||||
isCpRelation: cpPairs.isNotEmpty,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _addCpRelationPairs({
|
void _addCpRelationPairs({
|
||||||
required List<CPRes> cpPairs,
|
required List<CPRes> cpPairs,
|
||||||
required List<CPRes> closeFriendPairs,
|
required List<CPRes> closeFriendPairs,
|
||||||
@ -953,6 +925,127 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
|||||||
await _refreshLoadedCpProfilesForUserIds(normalizedUserIds);
|
await _refreshLoadedCpProfilesForUserIds(normalizedUserIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removeLoadedCpRelation({
|
||||||
|
required String userId,
|
||||||
|
required String peerUserId,
|
||||||
|
required String relationType,
|
||||||
|
}) {
|
||||||
|
final normalizedUserId = userId.trim();
|
||||||
|
final normalizedPeerUserId = peerUserId.trim();
|
||||||
|
final normalizedRelationType = _normalizeCpRelationType(relationType);
|
||||||
|
if (normalizedUserId.isEmpty ||
|
||||||
|
normalizedPeerUserId.isEmpty ||
|
||||||
|
normalizedRelationType.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var changed = false;
|
||||||
|
final currentProfile = currentUserProfile;
|
||||||
|
if (currentProfile != null) {
|
||||||
|
final nextCurrentProfile = _profileWithoutCpRelation(
|
||||||
|
currentProfile,
|
||||||
|
userId: normalizedUserId,
|
||||||
|
peerUserId: normalizedPeerUserId,
|
||||||
|
relationType: normalizedRelationType,
|
||||||
|
);
|
||||||
|
if (!identical(nextCurrentProfile, currentProfile)) {
|
||||||
|
final currentUser = AccountStorage().getCurrentUser();
|
||||||
|
currentUser?.setUserProfile(nextCurrentProfile);
|
||||||
|
if (currentUser != null) {
|
||||||
|
AccountStorage().setCurrentUser(currentUser);
|
||||||
|
}
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final detailProfile = userProfile;
|
||||||
|
if (detailProfile != null) {
|
||||||
|
final nextDetailProfile = _profileWithoutCpRelation(
|
||||||
|
detailProfile,
|
||||||
|
userId: normalizedUserId,
|
||||||
|
peerUserId: normalizedPeerUserId,
|
||||||
|
relationType: normalizedRelationType,
|
||||||
|
);
|
||||||
|
if (!identical(nextDetailProfile, detailProfile)) {
|
||||||
|
userProfile = nextDetailProfile;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final cardProfile = userCardInfo?.userProfile;
|
||||||
|
if (cardProfile != null) {
|
||||||
|
final nextCardProfile = _profileWithoutCpRelation(
|
||||||
|
cardProfile,
|
||||||
|
userId: normalizedUserId,
|
||||||
|
peerUserId: normalizedPeerUserId,
|
||||||
|
relationType: normalizedRelationType,
|
||||||
|
);
|
||||||
|
if (!identical(nextCardProfile, cardProfile)) {
|
||||||
|
userCardInfo = userCardInfo?.copyWith(userProfile: nextCardProfile);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SocialChatUserProfile _profileWithoutCpRelation(
|
||||||
|
SocialChatUserProfile profile, {
|
||||||
|
required String userId,
|
||||||
|
required String peerUserId,
|
||||||
|
required String relationType,
|
||||||
|
}) {
|
||||||
|
var changed = false;
|
||||||
|
List<CPRes>? filterRelations(List<CPRes>? relations) {
|
||||||
|
if (relations == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final filtered =
|
||||||
|
relations.where((relation) {
|
||||||
|
return !_matchesCpRelation(
|
||||||
|
relation,
|
||||||
|
userId: userId,
|
||||||
|
peerUserId: peerUserId,
|
||||||
|
relationType: relationType,
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
if (filtered.length != relations.length) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
final nextCpList = filterRelations(profile.cpList);
|
||||||
|
final nextCloseFriendList = filterRelations(profile.closeFriendList);
|
||||||
|
if (!changed) {
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
return profile.copyWith(
|
||||||
|
cpList: nextCpList,
|
||||||
|
closeFriendList: nextCloseFriendList,
|
||||||
|
isCpRelation: nextCpList?.isNotEmpty == true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _matchesCpRelation(
|
||||||
|
CPRes relation, {
|
||||||
|
required String userId,
|
||||||
|
required String peerUserId,
|
||||||
|
required String relationType,
|
||||||
|
}) {
|
||||||
|
if (_normalizeCpRelationType(relation.relationType) != relationType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final relationUserIds = <String>{
|
||||||
|
relation.meUserId?.trim() ?? "",
|
||||||
|
relation.cpUserId?.trim() ?? "",
|
||||||
|
}..remove("");
|
||||||
|
return relationUserIds.contains(userId) &&
|
||||||
|
relationUserIds.contains(peerUserId);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _refreshLoadedCpProfilesForUserIds(Set<String>? userIds) async {
|
Future<void> _refreshLoadedCpProfilesForUserIds(Set<String>? userIds) async {
|
||||||
String refreshedUserId(String? userId) {
|
String refreshedUserId(String? userId) {
|
||||||
final normalizedUserId = userId?.trim() ?? "";
|
final normalizedUserId = userId?.trim() ?? "";
|
||||||
@ -981,7 +1074,7 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
|||||||
final cardUserId = refreshedUserId(cardProfile?.id);
|
final cardUserId = refreshedUserId(cardProfile?.id);
|
||||||
if (userCardInfo != null && cardProfile != null && cardUserId.isNotEmpty) {
|
if (userCardInfo != null && cardProfile != null && cardUserId.isNotEmpty) {
|
||||||
userCardInfo = userCardInfo?.copyWith(
|
userCardInfo = userCardInfo?.copyWith(
|
||||||
userProfile: await _withCpRelationshipProfiles(cardProfile, cardUserId),
|
userProfile: await _withCpCabinProfiles(cardProfile, cardUserId),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,90 @@
|
|||||||
|
class SCCpGiftRelationCheckRes {
|
||||||
|
const SCCpGiftRelationCheckRes({
|
||||||
|
this.status = true,
|
||||||
|
this.msg = '',
|
||||||
|
this.relationType = '',
|
||||||
|
this.userId = '',
|
||||||
|
this.acceptUserId = '',
|
||||||
|
this.userRelationCount = 0,
|
||||||
|
this.acceptUserRelationCount = 0,
|
||||||
|
this.maxRelationCount = 0,
|
||||||
|
this.userRelationFull = false,
|
||||||
|
this.acceptUserRelationFull = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory SCCpGiftRelationCheckRes.fromJson(dynamic json) {
|
||||||
|
final source =
|
||||||
|
json is Map
|
||||||
|
? json.map((key, value) => MapEntry(key.toString(), value))
|
||||||
|
: const <String, dynamic>{};
|
||||||
|
return SCCpGiftRelationCheckRes(
|
||||||
|
status: _asBool(source['status']) ?? true,
|
||||||
|
msg: source['msg']?.toString() ?? '',
|
||||||
|
relationType: source['relationType']?.toString() ?? '',
|
||||||
|
userId: source['userId']?.toString() ?? '',
|
||||||
|
acceptUserId: source['acceptUserId']?.toString() ?? '',
|
||||||
|
userRelationCount: _asInt(source['userRelationCount']) ?? 0,
|
||||||
|
acceptUserRelationCount: _asInt(source['acceptUserRelationCount']) ?? 0,
|
||||||
|
maxRelationCount: _asInt(source['maxRelationCount']) ?? 0,
|
||||||
|
userRelationFull: _asBool(source['userRelationFull']) ?? false,
|
||||||
|
acceptUserRelationFull:
|
||||||
|
_asBool(source['acceptUserRelationFull']) ?? false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final bool status;
|
||||||
|
final String msg;
|
||||||
|
final String relationType;
|
||||||
|
final String userId;
|
||||||
|
final String acceptUserId;
|
||||||
|
final int userRelationCount;
|
||||||
|
final int acceptUserRelationCount;
|
||||||
|
final int maxRelationCount;
|
||||||
|
final bool userRelationFull;
|
||||||
|
final bool acceptUserRelationFull;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'status': status,
|
||||||
|
'msg': msg,
|
||||||
|
'relationType': relationType,
|
||||||
|
'userId': userId,
|
||||||
|
'acceptUserId': acceptUserId,
|
||||||
|
'userRelationCount': userRelationCount,
|
||||||
|
'acceptUserRelationCount': acceptUserRelationCount,
|
||||||
|
'maxRelationCount': maxRelationCount,
|
||||||
|
'userRelationFull': userRelationFull,
|
||||||
|
'acceptUserRelationFull': acceptUserRelationFull,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool? _asBool(dynamic value) {
|
||||||
|
if (value is bool) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (value is num) {
|
||||||
|
return value != 0;
|
||||||
|
}
|
||||||
|
final text = value?.toString().trim().toLowerCase() ?? '';
|
||||||
|
if (text.isEmpty) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (text == 'true' || text == '1' || text == 'yes') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (text == 'false' || text == '0' || text == 'no') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int? _asInt(dynamic value) {
|
||||||
|
if (value is int) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (value is num) {
|
||||||
|
return value.toInt();
|
||||||
|
}
|
||||||
|
return int.tryParse(value?.toString() ?? '');
|
||||||
|
}
|
||||||
@ -29,6 +29,7 @@ import 'package:yumi/shared/business_logic/models/res/sc_user_red_packet_grab_re
|
|||||||
import 'package:yumi/shared/business_logic/models/res/sc_user_red_packet_send_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/sc_user_red_packet_send_res.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/sc_violation_handle_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/sc_violation_handle_res.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/sc_cp_rights_config_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/sc_cp_rights_config_res.dart';
|
||||||
|
import 'package:yumi/shared/business_logic/models/res/sc_cp_gift_relation_check_res.dart';
|
||||||
|
|
||||||
abstract class SocialChatUserRepository {
|
abstract class SocialChatUserRepository {
|
||||||
Future<SocialChatLoginRes> getUser(String id);
|
Future<SocialChatLoginRes> getUser(String id);
|
||||||
@ -329,6 +330,12 @@ abstract class SocialChatUserRepository {
|
|||||||
///查询 CP 小屋
|
///查询 CP 小屋
|
||||||
Future<SCCpCabinRes> cpCabin(String userId, {String relationType = 'CP'});
|
Future<SCCpCabinRes> cpCabin(String userId, {String relationType = 'CP'});
|
||||||
|
|
||||||
|
///CP 礼物关系名额校验
|
||||||
|
Future<SCCpGiftRelationCheckRes> cpGiftRelationCheck({
|
||||||
|
required String acceptUserId,
|
||||||
|
String relationType = 'CP',
|
||||||
|
});
|
||||||
|
|
||||||
///查询 CP 值
|
///查询 CP 值
|
||||||
Future<SCCpCabinValueRes> cpCabinValue(
|
Future<SCCpCabinValueRes> cpCabinValue(
|
||||||
String userId, {
|
String userId, {
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import 'package:yumi/shared/business_logic/models/res/sc_prop_coupon_record_list
|
|||||||
import 'package:yumi/shared/business_logic/models/res/sc_public_message_page_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/sc_public_message_page_res.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/room_res.dart'
|
import 'package:yumi/shared/business_logic/models/res/room_res.dart'
|
||||||
hide WearBadge;
|
hide WearBadge;
|
||||||
|
import 'package:yumi/shared/business_logic/models/res/sc_cp_gift_relation_check_res.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/sc_cp_rights_config_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/sc_cp_rights_config_res.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/sc_task_list_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/sc_task_list_res.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/sc_user_counter_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/sc_user_counter_res.dart';
|
||||||
@ -1516,6 +1517,34 @@ class SCAccountRepository implements SocialChatUserRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///user/cp-relationship/gift-relation/check
|
||||||
|
@override
|
||||||
|
Future<SCCpGiftRelationCheckRes> cpGiftRelationCheck({
|
||||||
|
required String acceptUserId,
|
||||||
|
String relationType = 'CP',
|
||||||
|
}) async {
|
||||||
|
final query = {"acceptUserId": acceptUserId, "relationType": relationType};
|
||||||
|
_cpDebugLog('giftRelationCheck request query=$query');
|
||||||
|
try {
|
||||||
|
final result = await http.get<SCCpGiftRelationCheckRes>(
|
||||||
|
"/user/cp-relationship/gift-relation/check",
|
||||||
|
queryParams: query,
|
||||||
|
extra: const {BaseNetworkClient.silentErrorToastKey: true},
|
||||||
|
fromJson: SCCpGiftRelationCheckRes.fromJson,
|
||||||
|
);
|
||||||
|
_cpDebugLog(
|
||||||
|
'giftRelationCheck response query=$query '
|
||||||
|
'status=${result.status} msg=${result.msg} '
|
||||||
|
'userFull=${result.userRelationFull} '
|
||||||
|
'acceptFull=${result.acceptUserRelationFull}',
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
_cpDebugLog('giftRelationCheck failed query=$query error=$error');
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///user/cp/cabin
|
///user/cp/cabin
|
||||||
@override
|
@override
|
||||||
Future<SCCpCabinRes> cpCabin(
|
Future<SCCpCabinRes> cpCabin(
|
||||||
|
|||||||
@ -37,7 +37,7 @@ class RoomCpProgressDialog extends StatelessWidget {
|
|||||||
this.targetValue = 1,
|
this.targetValue = 1,
|
||||||
this.expAwayText = '0',
|
this.expAwayText = '0',
|
||||||
this.nextLevelText = 'Lv. 1',
|
this.nextLevelText = 'Lv. 1',
|
||||||
this.cancelText = 'Cancel',
|
this.cancelText = 'unbing',
|
||||||
this.dismissTag = dialogTag,
|
this.dismissTag = dialogTag,
|
||||||
this.onCancel,
|
this.onCancel,
|
||||||
});
|
});
|
||||||
@ -68,7 +68,7 @@ class RoomCpProgressDialog extends StatelessWidget {
|
|||||||
double targetValue = 1,
|
double targetValue = 1,
|
||||||
String expAwayText = '0',
|
String expAwayText = '0',
|
||||||
String nextLevelText = 'Lv. 1',
|
String nextLevelText = 'Lv. 1',
|
||||||
String cancelText = 'Cancel',
|
String cancelText = 'unbing',
|
||||||
String dismissTag = dialogTag,
|
String dismissTag = dialogTag,
|
||||||
VoidCallback? onCancel,
|
VoidCallback? onCancel,
|
||||||
}) async {
|
}) async {
|
||||||
@ -495,7 +495,7 @@ class _CancelButton extends StatelessWidget {
|
|||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
text.trim().isEmpty ? 'Cancel' : text.trim(),
|
text.trim().isEmpty ? 'unbing' : text.trim(),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
|
|||||||
@ -76,7 +76,12 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
context,
|
context,
|
||||||
listen: false,
|
listen: false,
|
||||||
);
|
);
|
||||||
_loadRoomUserCard();
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_loadRoomUserCard();
|
||||||
|
});
|
||||||
SCAccountRepository().userIdentity(userId: widget.userId).then((v) {
|
SCAccountRepository().userIdentity(userId: widget.userId).then((v) {
|
||||||
if (!mounted) {
|
if (!mounted) {
|
||||||
return;
|
return;
|
||||||
@ -139,7 +144,11 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
|
|
||||||
final profile = ref.userCardInfo?.userProfile;
|
final profile = ref.userCardInfo?.userProfile;
|
||||||
final dataCard = _activeDataCard(ref.userCardInfo);
|
final dataCard = _activeDataCard(ref.userCardInfo);
|
||||||
final sheetHeight = _resolvedProfileSheetHeight(screenHeight, profile);
|
final sheetHeight = _resolvedProfileSheetHeight(
|
||||||
|
screenHeight,
|
||||||
|
profile,
|
||||||
|
relationLoading: ref.isUserCardRelationLoading,
|
||||||
|
);
|
||||||
|
|
||||||
return _buildProfileSheet(
|
return _buildProfileSheet(
|
||||||
context: context,
|
context: context,
|
||||||
@ -231,9 +240,13 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
|
|
||||||
double _resolvedProfileSheetHeight(
|
double _resolvedProfileSheetHeight(
|
||||||
double screenHeight,
|
double screenHeight,
|
||||||
SocialChatUserProfile? profile,
|
SocialChatUserProfile? profile, {
|
||||||
) {
|
required bool relationLoading,
|
||||||
|
}) {
|
||||||
final defaultSheetHeight = screenHeight * _profileSheetHeightFactor;
|
final defaultSheetHeight = screenHeight * _profileSheetHeightFactor;
|
||||||
|
if (relationLoading) {
|
||||||
|
return defaultSheetHeight;
|
||||||
|
}
|
||||||
final hasCpRelation = _hasCpRelation(profile);
|
final hasCpRelation = _hasCpRelation(profile);
|
||||||
final hasCloseFriends = _closeFriendProfileData(profile).isNotEmpty;
|
final hasCloseFriends = _closeFriendProfileData(profile).isNotEmpty;
|
||||||
var resolvedHeight = defaultSheetHeight;
|
var resolvedHeight = defaultSheetHeight;
|
||||||
@ -356,6 +369,7 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
}) {
|
}) {
|
||||||
final hasCpRelation = _hasCpRelation(profile);
|
final hasCpRelation = _hasCpRelation(profile);
|
||||||
final closeFriends = _closeFriendProfileData(profile);
|
final closeFriends = _closeFriendProfileData(profile);
|
||||||
|
final isRelationLoading = ref.isUserCardRelationLoading;
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
@ -386,7 +400,12 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
ref,
|
ref,
|
||||||
profile,
|
profile,
|
||||||
),
|
),
|
||||||
if (hasCpRelation) ...[
|
if (isRelationLoading) ...[
|
||||||
|
SizedBox(height: 12.w),
|
||||||
|
_buildCpRelationSkeletonCard(),
|
||||||
|
SizedBox(height: 11.w),
|
||||||
|
_buildCloseFriendSkeletonStrip(),
|
||||||
|
] else if (hasCpRelation) ...[
|
||||||
SizedBox(height: 12.w),
|
SizedBox(height: 12.w),
|
||||||
_buildCpRelationCard(
|
_buildCpRelationCard(
|
||||||
context: context,
|
context: context,
|
||||||
@ -400,7 +419,9 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
],
|
],
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height:
|
height:
|
||||||
hasCpRelation || closeFriends.isNotEmpty
|
isRelationLoading ||
|
||||||
|
hasCpRelation ||
|
||||||
|
closeFriends.isNotEmpty
|
||||||
? 14.w
|
? 14.w
|
||||||
: 12.w,
|
: 12.w,
|
||||||
),
|
),
|
||||||
@ -691,6 +712,51 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildCpRelationSkeletonCard() {
|
||||||
|
return SizedBox(
|
||||||
|
height: 114.w,
|
||||||
|
child: DecoratedBox(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withValues(alpha: 0.10),
|
||||||
|
borderRadius: BorderRadius.circular(12.w),
|
||||||
|
border: Border.all(color: Colors.white.withValues(alpha: 0.12)),
|
||||||
|
),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Positioned(
|
||||||
|
left: 39.w,
|
||||||
|
top: 26.w,
|
||||||
|
child: _buildSkeletonCircle(60.w),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
right: 38.w,
|
||||||
|
top: 26.w,
|
||||||
|
child: _buildSkeletonCircle(60.w),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 142.w,
|
||||||
|
right: 142.w,
|
||||||
|
top: 28.w,
|
||||||
|
child: _buildSkeletonBlock(height: 18.w, radius: 9.w),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 156.w,
|
||||||
|
right: 156.w,
|
||||||
|
top: 54.w,
|
||||||
|
child: _buildSkeletonBlock(height: 10.w, radius: 5.w),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 118.w,
|
||||||
|
right: 118.w,
|
||||||
|
top: 80.w,
|
||||||
|
child: _buildSkeletonBlock(height: 14.w, radius: 7.w),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildCpCardText(
|
Widget _buildCpCardText(
|
||||||
String value, {
|
String value, {
|
||||||
required Color color,
|
required Color color,
|
||||||
@ -791,6 +857,69 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildCloseFriendSkeletonStrip() {
|
||||||
|
return SizedBox(
|
||||||
|
height: 41.w,
|
||||||
|
width: double.infinity,
|
||||||
|
child: DecoratedBox(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withValues(alpha: 0.10),
|
||||||
|
borderRadius: BorderRadius.circular(12.w),
|
||||||
|
border: Border.all(color: Colors.white.withValues(alpha: 0.12)),
|
||||||
|
),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
PositionedDirectional(
|
||||||
|
top: 13.w,
|
||||||
|
start: 16.w,
|
||||||
|
width: 118.w,
|
||||||
|
child: _buildSkeletonBlock(height: 14.w, radius: 7.w),
|
||||||
|
),
|
||||||
|
PositionedDirectional(
|
||||||
|
top: 8.w,
|
||||||
|
end: 13.w,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 25.w,
|
||||||
|
width: 112.w,
|
||||||
|
child: Stack(
|
||||||
|
alignment: AlignmentDirectional.centerEnd,
|
||||||
|
children: [
|
||||||
|
for (var index = 0; index < 4; index++)
|
||||||
|
PositionedDirectional(
|
||||||
|
end: (3 - index) * 17.w,
|
||||||
|
child: _buildSkeletonCircle(25.w),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSkeletonBlock({required double height, required double radius}) {
|
||||||
|
return Container(
|
||||||
|
height: height,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withValues(alpha: 0.22),
|
||||||
|
borderRadius: BorderRadius.circular(radius),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSkeletonCircle(double size) {
|
||||||
|
return Container(
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
color: Colors.white.withValues(alpha: 0.22),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
_RoomProfileCpData _cpProfileData(SocialChatUserProfile? profile) {
|
_RoomProfileCpData _cpProfileData(SocialChatUserProfile? profile) {
|
||||||
final currentProfile = AccountStorage().getCurrentUser()?.userProfile;
|
final currentProfile = AccountStorage().getCurrentUser()?.userProfile;
|
||||||
final cp = _firstRelation(
|
final cp = _firstRelation(
|
||||||
@ -1432,8 +1561,15 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
void _openProfile(BuildContext context) {
|
void _openProfile(BuildContext context) {
|
||||||
final route =
|
final route =
|
||||||
"${SCMainRoute.person}?isMe=${AccountStorage().getCurrentUser()?.userProfile?.id == widget.userId}&tageId=${widget.userId}";
|
"${SCMainRoute.person}?isMe=${AccountStorage().getCurrentUser()?.userProfile?.id == widget.userId}&tageId=${widget.userId}";
|
||||||
|
final rootContext = navigatorKey.currentState?.context;
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
SCNavigatorUtils.push(navigatorKey.currentState?.context ?? context, route);
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
final targetContext = navigatorKey.currentState?.context ?? rootContext;
|
||||||
|
if (targetContext == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SCNavigatorUtils.push(targetContext, route);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _openChat(BuildContext context) async {
|
Future<void> _openChat(BuildContext context) async {
|
||||||
@ -1497,7 +1633,7 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
SocialChatUserProfile? profile,
|
SocialChatUserProfile? profile,
|
||||||
) async {
|
) async {
|
||||||
final cp = _cpProfileData(profile);
|
final cp = _cpProfileData(profile);
|
||||||
final cancelText = SCAppLocalizations.of(context)!.cancel;
|
const cancelText = 'unbing';
|
||||||
SCLoadingManager.show();
|
SCLoadingManager.show();
|
||||||
late final _RoomCpProgressData progress;
|
late final _RoomCpProgressData progress;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -21,4 +21,24 @@ void main() {
|
|||||||
|
|
||||||
expect(manager.userCardInfo, isNull);
|
expect(manager.userCardInfo, isNull);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('removeLoadedCpRelation removes matching close friend relation', () {
|
||||||
|
final manager = SocialChatUserProfileManager();
|
||||||
|
manager.userProfile = SocialChatUserProfile(
|
||||||
|
id: '100',
|
||||||
|
closeFriendList: [
|
||||||
|
CPRes(meUserId: '100', cpUserId: '200', relationType: 'BROTHER'),
|
||||||
|
CPRes(meUserId: '100', cpUserId: '300', relationType: 'SISTERS'),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
manager.removeLoadedCpRelation(
|
||||||
|
userId: '100',
|
||||||
|
peerUserId: '200',
|
||||||
|
relationType: 'BROTHER',
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(manager.userProfile?.closeFriendList, hasLength(1));
|
||||||
|
expect(manager.userProfile?.closeFriendList?.single.cpUserId, '300');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user