Merge branch 'feature' of gitea.haiyihy.com:hy/chatapp3-flutter into feature
This commit is contained in:
commit
a73e2ff14b
@ -346,15 +346,15 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
app_links: 585674be3c6661708e6cd794ab4f39fb9d8356f9
|
||||
app_links: 3dbc685f76b1693c66a6d9dd1e9ab6f73d97dc0a
|
||||
AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73
|
||||
AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f
|
||||
audioplayers_darwin: f15e209a3e856d1a7edcf98dc029f484fead2242
|
||||
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
|
||||
audioplayers_darwin: 835ced6edd4c9fc8ebb0a7cc9e294a91d99917d5
|
||||
device_info_plus: 71ffc6ab7634ade6267c7a93088ed7e4f74e5896
|
||||
Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e
|
||||
firebase_auth: 5342db41af2ba5ed32a6177d9e326eecbebda912
|
||||
firebase_core: 99a37263b3c27536063a7b601d9e2a49400a433c
|
||||
firebase_crashlytics: 986773c0c7ea4c3f5a4ead141b58522fcd9dfdb1
|
||||
firebase_auth: 50af8366c87bb88c80ebeae62eb60189c7246b9b
|
||||
firebase_core: 995454a784ff288be5689b796deb9e9fa3601818
|
||||
firebase_crashlytics: 30dcd6dfd2fe895c0848af46722a4227346c19aa
|
||||
FirebaseAppCheckInterop: 06fe5a3799278ae4667e6c432edd86b1030fa3df
|
||||
FirebaseAuth: a6575e5fbf46b046c58dc211a28a5fbdd8d4c83b
|
||||
FirebaseAuthInterop: 7087d7a4ee4bc4de019b2d0c240974ed5d89e2fd
|
||||
@ -366,47 +366,47 @@ SPEC CHECKSUMS:
|
||||
FirebaseRemoteConfigInterop: 1c6135e8a094cc6368949f5faeeca7ee8948b8aa
|
||||
FirebaseSessions: b9a92c1c51bbb81e78fc3142cda6d925d700f8e7
|
||||
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
|
||||
flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e
|
||||
fluttertoast: 21eecd6935e7064cc1fcb733a4c5a428f3f24f0f
|
||||
google_sign_in_ios: 7411fab6948df90490dc4620ecbcabdc3ca04017
|
||||
flutter_image_compress_common: 1697a328fd72bfb335507c6bca1a65fa5ad87df1
|
||||
fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
|
||||
google_sign_in_ios: b48bb9af78576358a168361173155596c845f0b9
|
||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||
GoogleSignIn: ce8c89bb9b37fb624b92e7514cc67335d1e277e4
|
||||
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
|
||||
GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de
|
||||
GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6
|
||||
HydraAsync: 8d589bd725b0224f899afafc9a396327405f8063
|
||||
image_cropper: a3291c624a953049bc6a02e1f8c8ceb162a24b25
|
||||
image_picker_ios: 4f2f91b01abdb52842a8e277617df877e40f905b
|
||||
in_app_purchase_storekit: 2342c0a5da86593124d08dd13d920f39a52b273a
|
||||
image_cropper: 655b3ba703c9e15e3111e79151624d6154288774
|
||||
image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326
|
||||
in_app_purchase_storekit: 22cca7d08eebca9babdf4d07d0baccb73325d3c8
|
||||
libpag: 98742fad4b3ac2a2ee31e383d2483495fb9a5fb4
|
||||
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
|
||||
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
|
||||
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||
on_audio_query_ios: e5afb0d4b42cfa3e8762d8ec1953540cb4f02100
|
||||
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
|
||||
pag: ff30ba5e4be59380a5ddac6b183905729be15a3c
|
||||
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
|
||||
on_audio_query_ios: 28a780e2d0d85d92d500ba6e12c6c8167022b2fa
|
||||
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||
pag: f01aa9017ab0e04a83ba4a20d6070a50f0ac9da8
|
||||
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
|
||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
|
||||
RecaptchaInterop: 11e0b637842dfb48308d242afc3f448062325aba
|
||||
SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf
|
||||
SDWebImageWebPCoder: 0e06e365080397465cc73a7a9b472d8a3bd0f377
|
||||
shared_preferences_foundation: 5086985c1d43c5ba4d5e69a4e8083a389e2909e6
|
||||
sign_in_with_apple: f3bf75217ea4c2c8b91823f225d70230119b8440
|
||||
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
|
||||
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
|
||||
sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418
|
||||
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
|
||||
SwiftyBeaver: 84069991dd5dca07d7069100985badaca7f0ce82
|
||||
tancent_vap: eceaaf095167d102727cf799c75891057834c311
|
||||
tencent_cloud_chat_sdk: 546bb906bbe585814e3d2d33afdb91f09c0eac44
|
||||
tencent_rtc_sdk: 1ca5201f7bddc691a3a95486325ad6dc792a273d
|
||||
tancent_vap: fa8ad93814a9f950514a7074c662d2c937084c68
|
||||
tencent_cloud_chat_sdk: 55e5fffe20f6b7937a26a674ccccb639563a9790
|
||||
tencent_rtc_sdk: f77558b6b436a149d378557c2a837f73c09061bc
|
||||
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
|
||||
TXCustomBeautyProcesserPlugin: 099393b941cb40eda12b3a80bf6c0319957b1cfd
|
||||
TXIMSDK_Plus_iOS_XCFramework: 5d1933192fb3b7ef2fe933f1623de4a0486a7fe2
|
||||
TXLiteAVSDK_Professional: e792e6084a208ecef6196c5f28237ad8078b4d7c
|
||||
url_launcher_ios: bb13df5870e8c4234ca12609d04010a21be43dfa
|
||||
video_player_avfoundation: e54d03b3b19f64f2c557354f72ce538387541ba6
|
||||
video_thumbnail: c4e2a3c539e247d4de13cd545344fd2d26ffafd1
|
||||
wakelock_plus: 76957ab028e12bfa4e66813c99e46637f367fc7e
|
||||
webview_flutter_wkwebview: 29eb20d43355b48fe7d07113835b9128f84e3af4
|
||||
url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
|
||||
video_player_avfoundation: 3453f792138786248960ca029747fcd9f318ef52
|
||||
video_thumbnail: b637e0ad5f588ca9945f6e2c927f73a69a661140
|
||||
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
|
||||
webview_flutter_wkwebview: 8ebf4fded22593026f7dbff1fbff31ea98573c8d
|
||||
|
||||
PODFILE CHECKSUM: a6f49a93e5f85201a2efdadcd7cf184b0e310894
|
||||
|
||||
|
||||
@ -19,7 +19,6 @@ 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/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_user_repository_impl.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/main.dart';
|
||||
@ -1520,8 +1519,6 @@ class _GiftPageState extends State<GiftPage> with TickerProviderStateMixin {
|
||||
'giftType=$giftType',
|
||||
);
|
||||
|
||||
await _showCpGiftRelationCheckToastIfNeeded(request);
|
||||
|
||||
try {
|
||||
final repository = SCChatRoomRepository();
|
||||
_giftFxLog(
|
||||
@ -1728,49 +1725,6 @@ 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(
|
||||
SCChatRoomRepository repository,
|
||||
_GiftSendRequest request,
|
||||
|
||||
@ -7,7 +7,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:yumi/app_localizations.dart';
|
||||
import 'package:yumi/app/constants/sc_global_config.dart';
|
||||
import 'package:yumi/main.dart' show modalRouteObserver;
|
||||
import 'package:yumi/main.dart' show routeObserver;
|
||||
import 'package:yumi/ui_kit/components/sc_compontent.dart';
|
||||
import 'package:yumi/services/audio/rtc_manager.dart';
|
||||
import 'package:yumi/ui_kit/widgets/room/room_bottom_widget.dart';
|
||||
@ -83,7 +83,7 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
|
||||
bool _roomProviderRebuildScheduled = false;
|
||||
bool _roomRouteVisibleScheduled = false;
|
||||
bool _roomVisualEffectsEnsureScheduled = false;
|
||||
ModalRoute<dynamic>? _routeObserverRoute;
|
||||
PageRoute<dynamic>? _routeObserverRoute;
|
||||
SCRoomTopLayerGuardLease? _coveredRouteGuardLease;
|
||||
bool _roomRouteVisible = false;
|
||||
|
||||
@ -91,9 +91,6 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
|
||||
void initState() {
|
||||
super.initState();
|
||||
_tabController = TabController(length: _chatTabCount, vsync: this);
|
||||
SCRoomTopLayerGuard().activeListenable.addListener(
|
||||
_handleRoomTopLayerGuardChanged,
|
||||
);
|
||||
_tabController.addListener(_handleTabChange);
|
||||
_subscription = eventBus.on<SCGiveRoomLuckPageDisposeEvent>().listen((
|
||||
event,
|
||||
@ -123,12 +120,12 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
|
||||
context.read<RoomMusicManager>().attachRtcProvider(rtcProvider);
|
||||
}
|
||||
final route = ModalRoute.of(context);
|
||||
if (route != null && _routeObserverRoute != route) {
|
||||
if (route is PageRoute<dynamic> && _routeObserverRoute != route) {
|
||||
if (_routeObserverRoute != null) {
|
||||
modalRouteObserver.unsubscribe(this);
|
||||
routeObserver.unsubscribe(this);
|
||||
}
|
||||
_routeObserverRoute = route;
|
||||
modalRouteObserver.subscribe(this, route);
|
||||
routeObserver.subscribe(this, route);
|
||||
if (route.isCurrent) {
|
||||
_scheduleRoomRouteVisible();
|
||||
} else {
|
||||
@ -140,10 +137,7 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
SCRoomTopLayerGuard().activeListenable.removeListener(
|
||||
_handleRoomTopLayerGuardChanged,
|
||||
);
|
||||
modalRouteObserver.unsubscribe(this);
|
||||
routeObserver.unsubscribe(this);
|
||||
_routeObserverRoute = null;
|
||||
_releaseCoveredRouteGuard();
|
||||
_setRoomRouteVisible(false);
|
||||
@ -215,13 +209,6 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
|
||||
_coveredRouteGuardLease = null;
|
||||
}
|
||||
|
||||
void _handleRoomTopLayerGuardChanged() {
|
||||
if (!SCRoomTopLayerGuard().isActive || !mounted) {
|
||||
return;
|
||||
}
|
||||
_clearTransientRoomVisualEffects(reason: 'room_top_layer_guard');
|
||||
}
|
||||
|
||||
void _setRoomRouteVisible(bool visible) {
|
||||
if (_roomRouteVisible == visible) {
|
||||
return;
|
||||
|
||||
@ -1588,7 +1588,7 @@ class _PersonDetailPageState extends State<PersonDetailPage> with RouteAware {
|
||||
if (payload.rightUserId.trim().isEmpty) {
|
||||
return;
|
||||
}
|
||||
const cancelText = 'unbing';
|
||||
const cancelText = 'unbind';
|
||||
SCLoadingManager.show(context: context);
|
||||
late final _ProfileRelationProgressData progress;
|
||||
try {
|
||||
@ -1629,7 +1629,10 @@ class _PersonDetailPageState extends State<PersonDetailPage> with RouteAware {
|
||||
Future<_ProfileRelationProgressData> _loadProfileRelationProgressData(
|
||||
_ProfileRelationProgressPayload payload,
|
||||
) async {
|
||||
final partnerUserId = payload.rightUserId.trim();
|
||||
final partnerUserId = _counterpartUserIdForCurrentUser(
|
||||
leftUserId: payload.leftUserId,
|
||||
rightUserId: payload.rightUserId,
|
||||
);
|
||||
final fallback = _ProfileRelationProgressData.fallback(payload);
|
||||
if (partnerUserId.isEmpty) {
|
||||
return fallback;
|
||||
@ -1666,11 +1669,34 @@ class _PersonDetailPageState extends State<PersonDetailPage> with RouteAware {
|
||||
}
|
||||
}
|
||||
|
||||
String _counterpartUserIdForCurrentUser({
|
||||
required String leftUserId,
|
||||
required String rightUserId,
|
||||
}) {
|
||||
final currentUserId =
|
||||
AccountStorage().getCurrentUser()?.userProfile?.id?.trim() ?? "";
|
||||
final leftId = leftUserId.trim();
|
||||
final rightId = rightUserId.trim();
|
||||
if (currentUserId.isEmpty) {
|
||||
return rightId;
|
||||
}
|
||||
if (currentUserId == leftId) {
|
||||
return rightId;
|
||||
}
|
||||
if (currentUserId == rightId) {
|
||||
return leftId;
|
||||
}
|
||||
return rightId;
|
||||
}
|
||||
|
||||
Future<void> _showProfileRelationDismissConfirm(
|
||||
_ProfileRelationProgressPayload payload, {
|
||||
int? dismissCost,
|
||||
}) async {
|
||||
final partnerUserId = payload.rightUserId.trim();
|
||||
final partnerUserId = _counterpartUserIdForCurrentUser(
|
||||
leftUserId: payload.leftUserId,
|
||||
rightUserId: payload.rightUserId,
|
||||
);
|
||||
if (partnerUserId.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -544,10 +544,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
||||
int? get previewRoomSeatCount => _previewRoomSeatCount;
|
||||
|
||||
bool get shouldShowRoomVisualEffects =>
|
||||
currenRoom != null &&
|
||||
_roomVisualEffectsEnabled &&
|
||||
_voiceRoomRouteVisible &&
|
||||
!SCRoomTopLayerGuard().isActive;
|
||||
currenRoom != null && _roomVisualEffectsEnabled && _voiceRoomRouteVisible;
|
||||
|
||||
void _startVoiceRoomForegroundService() {
|
||||
final roomProfile = currenRoom?.roomProfile?.roomProfile;
|
||||
|
||||
@ -3100,7 +3100,10 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
void _enqueueCpRelationBroadcastFloatingIfNeeded(Msg msg) {
|
||||
void _enqueueCpRelationBroadcastFloatingIfNeeded(
|
||||
Msg msg, {
|
||||
bool isRegionBroadcast = false,
|
||||
}) {
|
||||
if (msg.type != SCRoomMsgType.cpSystemNotice) {
|
||||
return;
|
||||
}
|
||||
@ -3108,8 +3111,7 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
||||
if (action != "RELATION_ESTABLISHED" && action != "RELATION_JOINED_ROOM") {
|
||||
return;
|
||||
}
|
||||
if (!_isLiveCpRelationBroadcastMessage(msg) ||
|
||||
!_shouldShowCpRelationBroadcastFloating(msg.groupId ?? "")) {
|
||||
if (!_isLiveCpRelationBroadcastMessage(msg)) {
|
||||
return;
|
||||
}
|
||||
final relationType = scNormalizeCpRelationType(msg.role);
|
||||
@ -3132,6 +3134,8 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
||||
giftTab: relationType,
|
||||
displayText: msg.msg ?? "",
|
||||
durationSeconds: 5,
|
||||
broadcastScope:
|
||||
isRegionBroadcast ? SCFloatingMessage.broadcastScopeRegion : '',
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -3187,23 +3191,6 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
||||
return DateTime.now().millisecondsSinceEpoch - timestamp < 60000;
|
||||
}
|
||||
|
||||
bool _shouldShowCpRelationBroadcastFloating(String groupId) {
|
||||
final normalizedGroupId = groupId.trim();
|
||||
final currentContext = context;
|
||||
if (normalizedGroupId.isEmpty ||
|
||||
currentContext == null ||
|
||||
!currentContext.mounted ||
|
||||
!_isCurrentVoiceRoomGroup(normalizedGroupId)) {
|
||||
return false;
|
||||
}
|
||||
final rtcProvider = Provider.of<RealTimeCommunicationManager>(
|
||||
currentContext,
|
||||
listen: false,
|
||||
);
|
||||
return rtcProvider.shouldShowRoomVisualEffects &&
|
||||
rtcProvider.isVoiceRoomRouteVisible;
|
||||
}
|
||||
|
||||
String _roomMsgUserId(SocialChatUserProfile? profile) {
|
||||
return _firstCpInviteValue([profile?.id, profile?.account]) ?? "";
|
||||
}
|
||||
@ -6044,6 +6031,34 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
||||
if (isRegionBroadcastGroup) {
|
||||
_handleRegionGiftBroadcast(data["data"]);
|
||||
}
|
||||
} else if (type == SCRoomMsgType.cpSystemNotice) {
|
||||
final payload = data["data"] ?? data;
|
||||
final payloadMap = _broadcastPayloadMap(payload);
|
||||
if (payloadMap.isEmpty) {
|
||||
return;
|
||||
}
|
||||
final msg = Msg.fromJson(payloadMap);
|
||||
msg.type ??= SCRoomMsgType.cpSystemNotice;
|
||||
msg.groupId = _firstNonBlank([
|
||||
msg.groupId,
|
||||
_payloadText(payloadMap["groupId"]),
|
||||
_payloadText(payloadMap["roomId"]),
|
||||
_payloadText(data["groupId"]),
|
||||
_payloadText(data["roomId"]),
|
||||
]);
|
||||
msg.noticeAction ??= data["noticeAction"]?.toString();
|
||||
if ((msg.role ?? "").trim().isEmpty) {
|
||||
msg.role = _firstNonBlank([
|
||||
_payloadText(payloadMap["role"]),
|
||||
_payloadText(payloadMap["relationType"]),
|
||||
_payloadText(data["role"]),
|
||||
_payloadText(data["relationType"]),
|
||||
]);
|
||||
}
|
||||
_enqueueCpRelationBroadcastFloatingIfNeeded(
|
||||
msg,
|
||||
isRegionBroadcast: isRegionBroadcastGroup,
|
||||
);
|
||||
} else if (type == SCRoomMsgType.inviteRoom) {
|
||||
///邀请进入房间
|
||||
var fdata = data["data"];
|
||||
|
||||
@ -631,10 +631,7 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
||||
required String relationType,
|
||||
String? fallbackText,
|
||||
}) async {
|
||||
if (!_isCurrentUserId(userId)) {
|
||||
return null;
|
||||
}
|
||||
final partnerUserId = _cpPartnerUserId(userId, cpPair);
|
||||
final partnerUserId = _cpPartnerUserIdForCurrentUser(cpPair);
|
||||
if (partnerUserId.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
@ -659,14 +656,21 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
String _cpPartnerUserId(String userId, CPRes cpPair) {
|
||||
final currentId = userId.trim();
|
||||
String _cpPartnerUserIdForCurrentUser(CPRes cpPair) {
|
||||
final currentUserId =
|
||||
AccountStorage().getCurrentUser()?.userProfile?.id?.trim() ?? "";
|
||||
if (currentUserId.isEmpty) {
|
||||
return "";
|
||||
}
|
||||
final meUserId = cpPair.meUserId?.trim() ?? "";
|
||||
final cpUserId = cpPair.cpUserId?.trim() ?? "";
|
||||
if (currentId.isNotEmpty && currentId == cpUserId) {
|
||||
if (currentUserId == meUserId) {
|
||||
return cpUserId;
|
||||
}
|
||||
if (currentUserId == cpUserId) {
|
||||
return meUserId;
|
||||
}
|
||||
return cpUserId;
|
||||
return "";
|
||||
}
|
||||
|
||||
bool _hasCpPair(CPRes? pair) {
|
||||
|
||||
@ -803,10 +803,22 @@ class OverlayManager {
|
||||
return message.type == 2 && message.isRegionBroadcast;
|
||||
}
|
||||
|
||||
bool _isRegionCpGiftMessage(SCFloatingMessage message) {
|
||||
return message.type == 1 &&
|
||||
message.isRegionBroadcast &&
|
||||
scIsCpGiftTab(message.giftTab);
|
||||
}
|
||||
|
||||
bool _isRegionCpRelationMessage(SCFloatingMessage message) {
|
||||
return message.type == 6 && message.isRegionBroadcast;
|
||||
}
|
||||
|
||||
bool _isCrossRoomRegionFloatingMessage(SCFloatingMessage message) {
|
||||
return _isRegionRedPacketMessage(message) ||
|
||||
_isRegionRoomRocketMessage(message) ||
|
||||
_isRegionGameWinMessage(message);
|
||||
_isRegionGameWinMessage(message) ||
|
||||
_isRegionCpGiftMessage(message) ||
|
||||
_isRegionCpRelationMessage(message);
|
||||
}
|
||||
|
||||
bool _shouldDeferRegionRedPacketMessage(
|
||||
@ -931,15 +943,20 @@ class OverlayManager {
|
||||
currentRoomId.isNotEmpty &&
|
||||
messageRoomId.isNotEmpty &&
|
||||
currentRoomId == messageRoomId;
|
||||
final isGlobalStackedBroadcast =
|
||||
message.type == 4 ||
|
||||
message.type == 3 ||
|
||||
message.type == 6 ||
|
||||
_isRegionCpGiftMessage(message);
|
||||
if (isCurrentVisibleRoom) {
|
||||
// 区域红包/火箭在当前房间仍然需要展示;区域礼物当前房间由 RTM 层跳过,避免和房间 IM 礼物飘屏重复。
|
||||
return message.type == 4 || message.type == 3 || message.type == 2;
|
||||
// 区域红包/火箭/CP 类飘窗在当前房间仍然需要展示;普通区域礼物当前房间由 RTM 层跳过,避免和房间 IM 礼物飘屏重复。
|
||||
return isGlobalStackedBroadcast || message.type == 2;
|
||||
}
|
||||
final isCurrentRoomMessage =
|
||||
currentRoomId.isNotEmpty &&
|
||||
messageRoomId.isNotEmpty &&
|
||||
currentRoomId == messageRoomId;
|
||||
if ((message.type == 4 || message.type == 3 || message.type == 2) &&
|
||||
if ((isGlobalStackedBroadcast || message.type == 2) &&
|
||||
isCurrentRoomMessage) {
|
||||
return false;
|
||||
}
|
||||
@ -952,11 +969,10 @@ class OverlayManager {
|
||||
}
|
||||
return SCGlobalConfig.isFloatingBroadcastAll && _homeRootTabsVisible;
|
||||
}
|
||||
if ((message.type == 4 || message.type == 3) &&
|
||||
rtcProvider.shouldShowRoomVisualEffects) {
|
||||
if (isGlobalStackedBroadcast && rtcProvider.shouldShowRoomVisualEffects) {
|
||||
return true;
|
||||
}
|
||||
if (message.type == 4 || message.type == 3) {
|
||||
if (isGlobalStackedBroadcast) {
|
||||
return _homeRootTabsVisible;
|
||||
}
|
||||
if (SCGlobalConfig.isFloatingBroadcastRoomOnly) {
|
||||
|
||||
@ -1524,25 +1524,12 @@ class SCAccountRepository implements SocialChatUserRepository {
|
||||
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;
|
||||
}
|
||||
return http.get<SCCpGiftRelationCheckRes>(
|
||||
"/user/cp-relationship/gift-relation/check",
|
||||
queryParams: query,
|
||||
extra: const {BaseNetworkClient.silentErrorToastKey: true},
|
||||
fromJson: SCCpGiftRelationCheckRes.fromJson,
|
||||
);
|
||||
}
|
||||
|
||||
///user/cp/cabin
|
||||
|
||||
@ -5,9 +5,6 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:yumi/shared/data_sources/sources/local/floating_screen_manager.dart';
|
||||
import 'package:yumi/shared/tools/sc_gift_vap_svga_manager.dart';
|
||||
import 'package:yumi/shared/tools/sc_room_effect_scheduler.dart';
|
||||
import 'package:yumi/ui_kit/widgets/room/anim/room_entrance_widget.dart';
|
||||
|
||||
class SCRoomTopLayerGuard {
|
||||
static const int _maxDeferredActions = 16;
|
||||
@ -56,11 +53,6 @@ class SCRoomTopLayerGuard {
|
||||
}
|
||||
_activeListenable.value = true;
|
||||
OverlayManager().beginSuppressFloatingScreens(reason: reason);
|
||||
SCRoomEffectScheduler().beginSuppressEffects(reason: reason);
|
||||
SCRoomEffectScheduler().clearDeferredTasks(reason: reason);
|
||||
RoomEntranceHelper.clearQueue();
|
||||
SCGiftVapSvgaManager().stopPlayback();
|
||||
SCGiftVapSvgaManager().pauseAnim();
|
||||
if (!keepDialogTags.contains(_redPacketOpenDialogTag)) {
|
||||
unawaited(SmartDialog.dismiss(tag: _redPacketOpenDialogTag));
|
||||
}
|
||||
@ -81,8 +73,6 @@ class SCRoomTopLayerGuard {
|
||||
return;
|
||||
}
|
||||
OverlayManager().endSuppressFloatingScreens(reason: reason);
|
||||
SCRoomEffectScheduler().endSuppressEffects(reason: reason);
|
||||
SCGiftVapSvgaManager().resumeAnim();
|
||||
_activeListenable.value = false;
|
||||
_drainDeferredActions();
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ class RoomCpProgressDialog extends StatelessWidget {
|
||||
this.targetValue = 1,
|
||||
this.expAwayText = '0',
|
||||
this.nextLevelText = 'Lv. 1',
|
||||
this.cancelText = 'unbing',
|
||||
this.cancelText = 'unbind',
|
||||
this.dismissTag = dialogTag,
|
||||
this.onCancel,
|
||||
});
|
||||
@ -68,7 +68,7 @@ class RoomCpProgressDialog extends StatelessWidget {
|
||||
double targetValue = 1,
|
||||
String expAwayText = '0',
|
||||
String nextLevelText = 'Lv. 1',
|
||||
String cancelText = 'unbing',
|
||||
String cancelText = 'unbind',
|
||||
String dismissTag = dialogTag,
|
||||
VoidCallback? onCancel,
|
||||
}) async {
|
||||
@ -495,7 +495,7 @@ class _CancelButton extends StatelessWidget {
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
Text(
|
||||
text.trim().isEmpty ? 'unbing' : text.trim(),
|
||||
text.trim().isEmpty ? 'unbind' : text.trim(),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.center,
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:yumi/shared/data_sources/models/message/sc_floating_message.dart';
|
||||
@ -157,7 +159,7 @@ class _FloatingCpRelationScreenWidgetState
|
||||
}
|
||||
final explicitText = widget.message.displayText?.trim() ?? "";
|
||||
if (explicitText.isNotEmpty) {
|
||||
return _stripSystemNotificationPrefix(explicitText);
|
||||
return _stripSystemNotificationPrefix(_repairMojibake(explicitText));
|
||||
}
|
||||
return _stripSystemNotificationPrefix(
|
||||
scBuildCpRelationEstablishedNotice(
|
||||
@ -169,7 +171,7 @@ class _FloatingCpRelationScreenWidgetState
|
||||
}
|
||||
|
||||
String _shortName(String? value) {
|
||||
final text = value?.trim() ?? "";
|
||||
final text = _repairMojibake(value?.trim() ?? "");
|
||||
if (text.length <= 14) {
|
||||
return text;
|
||||
}
|
||||
@ -188,7 +190,7 @@ class _FloatingCpRelationScreenWidgetState
|
||||
}
|
||||
|
||||
String _stripSystemNotificationPrefix(String text) {
|
||||
return text
|
||||
return _repairMojibake(text)
|
||||
.replaceFirst(
|
||||
RegExp(
|
||||
r'^\s*[\[\【]\s*sys(?:tem|term)\s+notification\s*[\]\】]\s*',
|
||||
@ -199,6 +201,35 @@ class _FloatingCpRelationScreenWidgetState
|
||||
.trim();
|
||||
}
|
||||
|
||||
String _repairMojibake(String value) {
|
||||
final text = value.trim();
|
||||
if (text.isEmpty || !_looksLikeMojibake(text)) {
|
||||
return text;
|
||||
}
|
||||
try {
|
||||
final repaired = utf8.decode(latin1.encode(text), allowMalformed: true);
|
||||
return _mojibakeScore(repaired) < _mojibakeScore(text) ? repaired : text;
|
||||
} catch (_) {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
bool _looksLikeMojibake(String value) {
|
||||
return value.contains('Ã') ||
|
||||
value.contains('Â') ||
|
||||
value.contains('â') ||
|
||||
value.contains('ð') ||
|
||||
value.contains('<EFBFBD>');
|
||||
}
|
||||
|
||||
int _mojibakeScore(String value) {
|
||||
var score = 0;
|
||||
for (final marker in const ['Ã', 'Â', 'â', 'ð', '<EFBFBD>']) {
|
||||
score += marker.allMatches(value).length;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
List<Color> _relationColors(String? relationType) {
|
||||
switch (scNormalizeCpRelationType(relationType)) {
|
||||
case "BROTHER":
|
||||
|
||||
@ -612,16 +612,16 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
||||
) {
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
height: 16.w,
|
||||
height: 20.w,
|
||||
child: Center(
|
||||
child: SCUserBadgeStrip(
|
||||
userId: userId,
|
||||
fallbackBadges: _roomCardFallbackBadges(ref, profile),
|
||||
displayScope: SCUserBadgeDisplayScope.short,
|
||||
height: 16.w,
|
||||
badgeHeight: 16.w,
|
||||
longBadgeWidth: 32.w,
|
||||
spacing: 4.w,
|
||||
height: 20.w,
|
||||
badgeHeight: 20.w,
|
||||
longBadgeWidth: 44.w,
|
||||
spacing: 5.w,
|
||||
maxBadges: 3,
|
||||
wrap: false,
|
||||
reserveSpace: false,
|
||||
@ -1633,7 +1633,7 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
||||
SocialChatUserProfile? profile,
|
||||
) async {
|
||||
final cp = _cpProfileData(profile);
|
||||
const cancelText = 'unbing';
|
||||
const cancelText = 'unbind';
|
||||
SCLoadingManager.show();
|
||||
late final _RoomCpProgressData progress;
|
||||
try {
|
||||
@ -1673,7 +1673,10 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
||||
}
|
||||
|
||||
Future<_RoomCpProgressData> _loadCpProgressData(_RoomProfileCpData cp) async {
|
||||
final partnerUserId = cp.rightUserId.trim();
|
||||
final partnerUserId = _counterpartUserIdForCurrentUser(
|
||||
leftUserId: cp.leftUserId,
|
||||
rightUserId: cp.rightUserId,
|
||||
);
|
||||
final fallback = _RoomCpProgressData.fallback(cp);
|
||||
if (partnerUserId.isEmpty) {
|
||||
return fallback;
|
||||
@ -1707,13 +1710,36 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
||||
}
|
||||
}
|
||||
|
||||
String _counterpartUserIdForCurrentUser({
|
||||
required String leftUserId,
|
||||
required String rightUserId,
|
||||
}) {
|
||||
final currentUserId =
|
||||
AccountStorage().getCurrentUser()?.userProfile?.id?.trim() ?? "";
|
||||
final leftId = leftUserId.trim();
|
||||
final rightId = rightUserId.trim();
|
||||
if (currentUserId.isEmpty) {
|
||||
return rightId;
|
||||
}
|
||||
if (currentUserId == leftId) {
|
||||
return rightId;
|
||||
}
|
||||
if (currentUserId == rightId) {
|
||||
return leftId;
|
||||
}
|
||||
return rightId;
|
||||
}
|
||||
|
||||
Future<void> _showCpDismissConfirm(
|
||||
BuildContext context,
|
||||
_RoomProfileCpData cp, {
|
||||
int? dismissCost,
|
||||
}) async {
|
||||
final l10n = SCAppLocalizations.of(context)!;
|
||||
final partnerUserId = cp.rightUserId.trim();
|
||||
final partnerUserId = _counterpartUserIdForCurrentUser(
|
||||
leftUserId: cp.leftUserId,
|
||||
rightUserId: cp.rightUserId,
|
||||
);
|
||||
if (partnerUserId.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user