diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index d03fab7..0b12671 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -510,7 +510,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
- TARGETED_DEVICE_FAMILY = "1,2";
+ TARGETED_DEVICE_FAMILY = 1;
VALIDATE_PRODUCT = YES;
};
name = Profile;
@@ -524,7 +524,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1631;
+ CURRENT_PROJECT_VERSION = 102;
DEVELOPMENT_TEAM = S9YG87C297;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@@ -533,7 +533,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 1.6.3;
+ MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -647,7 +647,7 @@
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
- TARGETED_DEVICE_FAMILY = "1,2";
+ TARGETED_DEVICE_FAMILY = 1;
};
name = Debug;
};
@@ -701,7 +701,7 @@
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
- TARGETED_DEVICE_FAMILY = "1,2";
+ TARGETED_DEVICE_FAMILY = 1;
VALIDATE_PRODUCT = YES;
};
name = Release;
@@ -715,7 +715,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1631;
+ CURRENT_PROJECT_VERSION = 102;
DEVELOPMENT_TEAM = S9YG87C297;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@@ -724,7 +724,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 1.6.3;
+ MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -744,7 +744,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1631;
+ CURRENT_PROJECT_VERSION = 102;
DEVELOPMENT_TEAM = S9YG87C297;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@@ -753,7 +753,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 1.6.3;
+ MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 7a762e6..3d176d0 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -56,9 +56,9 @@
- CFBundleVersion
- $(FLUTTER_BUILD_NUMBER)
- LSRequiresIPhoneOS
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ LSRequiresIPhoneOS
NSCameraUsageDescription
We need access to your camera so you can take a photo and make it a profile picture, or take and share a picture in real time in a voice chat room.
diff --git a/lib/modules/room/online/room_online_page.dart b/lib/modules/room/online/room_online_page.dart
index 0c989b6..af9b51d 100644
--- a/lib/modules/room/online/room_online_page.dart
+++ b/lib/modules/room/online/room_online_page.dart
@@ -13,7 +13,6 @@ import '../../../ui_kit/components/sc_page_list.dart';
import '../../../ui_kit/components/sc_tts.dart';
import '../../../ui_kit/components/text/sc_text.dart';
import '../../../ui_kit/widgets/id/sc_special_id_badge.dart';
-import '../../../shared/tools/sc_lk_dialog_util.dart';
import '../../../ui_kit/widgets/badge/sc_user_badge_strip.dart';
import '../../../ui_kit/widgets/room/room_user_info_card.dart';
@@ -44,7 +43,7 @@ class _RoomOnlinePageState
if (dialogContext == null) {
return;
}
- showBottomInBottomDialog(dialogContext, RoomUserInfoCard(userId: userId));
+ RoomUserInfoCard.showPreloaded(dialogContext, userId: userId);
});
}
diff --git a/lib/modules/room/rank/room_gift_rank_tab_page.dart b/lib/modules/room/rank/room_gift_rank_tab_page.dart
index 36e9f2a..49a644c 100644
--- a/lib/modules/room/rank/room_gift_rank_tab_page.dart
+++ b/lib/modules/room/rank/room_gift_rank_tab_page.dart
@@ -1,11 +1,11 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
-import 'package:flutter_screenutil/flutter_screenutil.dart';
-import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
-import 'package:yumi/shared/business_logic/models/res/login_res.dart';
-import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
-import 'package:yumi/shared/data_sources/sources/repositories/sc_room_repository_imp.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:yumi/shared/business_logic/models/res/login_res.dart';
+import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
+import 'package:yumi/shared/data_sources/sources/repositories/sc_room_repository_imp.dart';
import 'package:yumi/main.dart';
import 'package:yumi/app_localizations.dart';
@@ -13,7 +13,6 @@ import 'package:yumi/ui_kit/components/sc_compontent.dart';
import 'package:yumi/ui_kit/components/sc_page_list.dart';
import 'package:yumi/ui_kit/components/text/sc_text.dart';
import 'package:yumi/ui_kit/components/sc_tts.dart';
-import 'package:yumi/shared/tools/sc_lk_dialog_util.dart';
import 'package:yumi/shared/business_logic/models/res/room_gift_rank_res.dart';
import 'package:yumi/ui_kit/widgets/id/sc_special_id_badge.dart';
import 'package:yumi/ui_kit/widgets/room/room_user_info_card.dart';
@@ -98,11 +97,11 @@ class _RoomGiftRankTabPageState
// headdress: userInfo.userProfile?.getHeaddress()?.sourceUrl,
),
onTap: () {
- showBottomInBottomDialog(
- navigatorKey.currentState!.context,
- RoomUserInfoCard(userId: userProfile?.id),
- );
SmartDialog.dismiss(tag: "showRoomGiftRankPage");
+ RoomUserInfoCard.showPreloaded(
+ navigatorKey.currentState!.context,
+ userId: userProfile?.id,
+ );
},
),
SizedBox(width: 3.w),
@@ -119,7 +118,7 @@ class _RoomGiftRankTabPageState
needScroll:
(userProfile?.userNickname?.characters.length ??
0) >
- 14,
+ 14,
),
],
),
@@ -137,7 +136,7 @@ class _RoomGiftRankTabPageState
animationHeight: 24.w,
showTextBesideAnimated: true,
animatedTextSpacing: 0,
- showAnimatedGradientText:
+ showAnimatedGradientText:
userProfile
?.shouldShowColoredSpecialIdText() ??
false,
@@ -195,24 +194,24 @@ class _RoomGiftRankTabPageState
SocialChatUserProfile? _mergeCurrentUserVip(
SocialChatUserProfile? profile,
) {
- if (profile == null || profile.vipLevelForColoredId > 0) {
- return profile;
- }
- final currentProfile = AccountStorage().getCurrentUser()?.userProfile;
- if (currentProfile == null ||
- currentProfile.vipLevelForColoredId <= 0 ||
- currentProfile.id != profile.id) {
- return profile;
- }
- return profile.copyWith(
- vipLevel:
- currentProfile.vipLevel ??
- currentProfile.vipLevelForColoredId.toString(),
- );
- }
-
- @override
- empty() {
+ if (profile == null || profile.vipLevelForColoredId > 0) {
+ return profile;
+ }
+ final currentProfile = AccountStorage().getCurrentUser()?.userProfile;
+ if (currentProfile == null ||
+ currentProfile.vipLevelForColoredId <= 0 ||
+ currentProfile.id != profile.id) {
+ return profile;
+ }
+ return profile.copyWith(
+ vipLevel:
+ currentProfile.vipLevel ??
+ currentProfile.vipLevelForColoredId.toString(),
+ );
+ }
+
+ @override
+ empty() {
return mainEmpty(
image: Image.asset(
'sc_images/general/sc_icon_loading.png',
diff --git a/lib/modules/user/me_page2.dart b/lib/modules/user/me_page2.dart
index a9b42e2..795d265 100644
--- a/lib/modules/user/me_page2.dart
+++ b/lib/modules/user/me_page2.dart
@@ -37,6 +37,8 @@ class MePage2 extends StatefulWidget {
class _MePage2State extends State with WidgetsBindingObserver {
static const Duration _counterStaleDuration = Duration(seconds: 30);
+ static const String _cpActivityUrl =
+ 'https://h5.global-interaction.com/activity/cp-space/yumi.html';
static const String _inviteActivityUrl =
'https://h5.haiyihy.com/app-invite/index.html';
static const double _inviteActivityHorizontalScale = 750 / 662;
@@ -299,6 +301,21 @@ class _MePage2State extends State with WidgetsBindingObserver {
);
}
+ void _openCpActivity() {
+ final cpActivityUrl = _cpActivityUrl.trim();
+ if (cpActivityUrl.isEmpty) {
+ if (kDebugMode) {
+ debugPrint('[MePage2] cp activity url is empty');
+ }
+ return;
+ }
+
+ SCNavigatorUtils.push(
+ context,
+ "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(cpActivityUrl)}&showTitle=false",
+ );
+ }
+
String _appendToken(String url) {
final token = AccountStorage().getToken();
if (token.isEmpty) return url;
@@ -480,6 +497,14 @@ class _MePage2State extends State with WidgetsBindingObserver {
iconPath: 'sc_images/index/sc_icon_bag.png',
onTap: () => SCNavigatorUtils.push(context, StoreRoute.bags),
),
+ SizedBox(width: 10.w),
+ _buildEntryItem(
+ title: 'cp',
+ iconPath: 'sc_images/index/sc_icon_cp_entry.png',
+ iconWidth: 47,
+ iconHeight: 50,
+ onTap: _openCpActivity,
+ ),
],
);
}
diff --git a/lib/modules/wallet/recharge/recharge_page.dart b/lib/modules/wallet/recharge/recharge_page.dart
index eaa3c30..1eb18a3 100644
--- a/lib/modules/wallet/recharge/recharge_page.dart
+++ b/lib/modules/wallet/recharge/recharge_page.dart
@@ -37,11 +37,6 @@ class _RechargePageState extends State {
context,
listen: false,
).initializePaymentProcessor(context);
- } else if (Platform.isIOS) {
- Provider.of(
- context,
- listen: false,
- ).initializePaymentProcessor(context);
}
}
@@ -60,7 +55,7 @@ class _RechargePageState extends State {
.getRechargePageScaffoldBackgroundColor(),
resizeToAvoidBottomInset: false,
appBar: SocialChatStandardAppBar(
- title: SCAppLocalizations.of(context)!.recharge,
+ title: SCAppLocalizations.of(context)!.wallet,
actions: [
GestureDetector(
onTap: _showRecordDialog,
@@ -83,38 +78,27 @@ class _RechargePageState extends State {
_buildWalletSection(),
SizedBox(height: 36.w),
Expanded(
- child: Padding(
- padding: EdgeInsets.fromLTRB(12.w, 8.w, 12.w, 0),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- _buildMethodSection(),
- SizedBox(height: 14.w),
- Expanded(child: _buildNativeProductList()),
- if (Platform.isIOS) ...[
- SizedBox(height: 12.w),
- _buildFooterButton(
- title:
- SCAppLocalizations.of(
- context,
- )!.restorePurchases,
- onTap: () {
- Provider.of(
- context,
- listen: false,
- ).recoverTransactions();
- },
+ child:
+ Platform.isIOS
+ ? const SizedBox.shrink()
+ : Padding(
+ padding: EdgeInsets.fromLTRB(12.w, 8.w, 12.w, 0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ _buildMethodSection(),
+ SizedBox(height: 14.w),
+ Expanded(child: _buildNativeProductList()),
+ SizedBox(height: 12.w),
+ _buildFooterButton(
+ title:
+ SCAppLocalizations.of(context)!.recharge,
+ onTap: _processNativePurchase,
+ ),
+ SizedBox(height: 14.w),
+ ],
+ ),
),
- ],
- SizedBox(height: 12.w),
- _buildFooterButton(
- title: SCAppLocalizations.of(context)!.recharge,
- onTap: _processNativePurchase,
- ),
- SizedBox(height: 14.w),
- ],
- ),
- ),
),
],
),
diff --git a/lib/services/audio/rtc_manager.dart b/lib/services/audio/rtc_manager.dart
index 15ba909..6e00c7d 100644
--- a/lib/services/audio/rtc_manager.dart
+++ b/lib/services/audio/rtc_manager.dart
@@ -5070,10 +5070,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
if (clickUser.id ==
AccountStorage().getCurrentUser()?.userProfile?.id) {
///是自己,直接打开资料卡
- showBottomInBottomDialog(
- context!,
- RoomUserInfoCard(userId: clickUser.id),
- );
+ RoomUserInfoCard.showPreloaded(context!, userId: clickUser.id);
} else {
showBottomInBottomDialog(
context!,
@@ -5183,10 +5180,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
if (normalizedUserId.isEmpty) {
return;
}
- showBottomInBottomDialog(
- context!,
- RoomUserInfoCard(userId: normalizedUserId),
- );
+ RoomUserInfoCard.showPreloaded(context!, userId: normalizedUserId);
}
addSoundVoiceChangeListener(OnSoundVoiceChange onSoundVoiceChange) {
diff --git a/lib/services/auth/user_profile_manager.dart b/lib/services/auth/user_profile_manager.dart
index d5adb4e..6b640ee 100644
--- a/lib/services/auth/user_profile_manager.dart
+++ b/lib/services/auth/user_profile_manager.dart
@@ -250,7 +250,7 @@ class SocialChatUserProfileManager extends ChangeNotifier {
return sessionSerial;
}
- Future roomUserCard(
+ Future roomUserCard(
String roomId,
String userId, {
int? sessionSerial,
@@ -272,36 +272,31 @@ class SocialChatUserProfileManager extends ChangeNotifier {
isUserCardLoading = false;
notifyListeners();
}
- return;
+ return null;
}
try {
- RoomUserCardRes? card = await SCChatRoomRepository().roomUserCard(
- normalizedRoomId,
- normalizedUserId,
+ final card = await _loadHydratedRoomUserCard(
+ roomId: normalizedRoomId,
+ userId: normalizedUserId,
);
- if (requestSerial != _userCardRequestSerial) {
- return;
+ if (requestSerial != _userCardRequestSerial ||
+ activeSessionSerial != _activeUserCardSessionSerial) {
+ return null;
}
userCardInfo = card;
userCardLoadError = null;
isUserCardLoading = false;
- isUserCardRelationLoading = card.userProfile != null;
+ isUserCardRelationLoading = false;
notifyListeners();
- unawaited(
- _hydrateRoomUserCard(
- card: card,
- userId: normalizedUserId,
- requestSerial: requestSerial,
- sessionSerial: activeSessionSerial,
- ),
- );
+ return card;
} catch (error, stackTrace) {
if (requestSerial != _userCardRequestSerial) {
- return;
+ return null;
}
userCardInfo = null;
userCardLoadError = error;
+ isUserCardRelationLoading = false;
_debugProfileLoadFailure(
scope: 'roomCard',
userId: normalizedUserId,
@@ -314,6 +309,23 @@ class SocialChatUserProfileManager extends ChangeNotifier {
notifyListeners();
}
}
+ return null;
+ }
+
+ Future preloadRoomUserCardForOpen(
+ String roomId,
+ String userId, {
+ int? sessionSerial,
+ }) {
+ return roomUserCard(roomId, userId, sessionSerial: sessionSerial);
+ }
+
+ Future _loadHydratedRoomUserCard({
+ required String roomId,
+ required String userId,
+ }) async {
+ final card = await SCChatRoomRepository().roomUserCard(roomId, userId);
+ return _withCurrentVipLevelForCard(card, userId);
}
Future _hydrateUserInfoById({
@@ -340,38 +352,6 @@ class SocialChatUserProfileManager extends ChangeNotifier {
}
}
- Future _hydrateRoomUserCard({
- required RoomUserCardRes? card,
- required String userId,
- required int requestSerial,
- required int sessionSerial,
- }) async {
- try {
- final hydratedCard = await _withCurrentVipLevelForCard(card, userId);
- if (requestSerial != _userCardRequestSerial ||
- sessionSerial != _activeUserCardSessionSerial ||
- hydratedCard == null) {
- return;
- }
- userCardInfo = hydratedCard;
- userCardLoadError = null;
- isUserCardRelationLoading = false;
- notifyListeners();
- } catch (error, stackTrace) {
- if (requestSerial == _userCardRequestSerial &&
- sessionSerial == _activeUserCardSessionSerial) {
- isUserCardRelationLoading = false;
- notifyListeners();
- }
- _debugProfileLoadFailure(
- scope: 'roomCardHydrate',
- userId: userId,
- error: error,
- stackTrace: stackTrace,
- );
- }
- }
-
void clearRoomUserCard({int? sessionSerial}) {
if (sessionSerial != null &&
sessionSerial != _activeUserCardSessionSerial) {
diff --git a/lib/ui_kit/widgets/room/empty_mai_select.dart b/lib/ui_kit/widgets/room/empty_mai_select.dart
index 1b192f4..f83ecfa 100644
--- a/lib/ui_kit/widgets/room/empty_mai_select.dart
+++ b/lib/ui_kit/widgets/room/empty_mai_select.dart
@@ -9,7 +9,6 @@ import 'package:yumi/ui_kit/widgets/room/room_user_info_card.dart';
import 'package:provider/provider.dart';
import 'package:yumi/app/constants/sc_room_msg_type.dart';
import 'package:yumi/app/constants/sc_screen.dart';
-import 'package:yumi/shared/tools/sc_lk_dialog_util.dart';
import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
import 'package:yumi/shared/business_logic/models/res/mic_res.dart';
import 'package:yumi/services/audio/rtc_manager.dart';
@@ -266,10 +265,7 @@ class EmptyMaiSelect extends StatelessWidget {
context,
() {
Navigator.of(context).pop();
- showBottomInBottomDialog(
- context,
- RoomUserInfoCard(userId: clickUser?.id),
- );
+ RoomUserInfoCard.showPreloaded(context, userId: clickUser?.id);
},
),
);
diff --git a/lib/ui_kit/widgets/room/room_user_info_card.dart b/lib/ui_kit/widgets/room/room_user_info_card.dart
index dd04730..baecda2 100644
--- a/lib/ui_kit/widgets/room/room_user_info_card.dart
+++ b/lib/ui_kit/widgets/room/room_user_info_card.dart
@@ -48,8 +48,91 @@ import '../../../modules/chat/chat_route.dart';
class RoomUserInfoCard extends StatefulWidget {
final String? userId;
+ final String? roomId;
+ final int? sessionSerial;
+ final bool preloaded;
- const RoomUserInfoCard({super.key, this.userId});
+ const RoomUserInfoCard({
+ super.key,
+ this.userId,
+ this.roomId,
+ this.sessionSerial,
+ this.preloaded = false,
+ });
+
+ static int _openRequestSerial = 0;
+
+ static Future showPreloaded(
+ BuildContext context, {
+ required String? userId,
+ }) async {
+ final normalizedUserId = (userId ?? '').trim();
+ if (normalizedUserId.isEmpty) {
+ return;
+ }
+ final openSerial = ++_openRequestSerial;
+ final sourceRoomId = _resolveCurrentRoomId(context);
+ final dialogContext = navigatorKey.currentState?.context ?? context;
+ final userProvider = Provider.of(
+ dialogContext,
+ listen: false,
+ );
+ final roomId =
+ sourceRoomId.isNotEmpty
+ ? sourceRoomId
+ : _resolveCurrentRoomId(dialogContext);
+ final sessionSerial = userProvider.beginRoomUserCardSession();
+ SCLoadingManager.show();
+ room_card.RoomUserCardRes? card;
+ try {
+ card = await userProvider.preloadRoomUserCardForOpen(
+ roomId,
+ normalizedUserId,
+ sessionSerial: sessionSerial,
+ );
+ } finally {
+ if (openSerial == _openRequestSerial) {
+ SCLoadingManager.hide();
+ }
+ }
+ if (openSerial != _openRequestSerial) {
+ return;
+ }
+ final latestDialogContext = navigatorKey.currentState?.context ?? context;
+ if (!latestDialogContext.mounted) {
+ userProvider.clearRoomUserCard(sessionSerial: sessionSerial);
+ return;
+ }
+ if (card == null) {
+ userProvider.clearRoomUserCard(sessionSerial: sessionSerial);
+ SCTts.show(
+ SCAppLocalizations.of(latestDialogContext)?.loadingFailedClickToRetry ??
+ 'Loading failed, click to retry',
+ );
+ return;
+ }
+ showBottomInBottomDialog(
+ latestDialogContext,
+ RoomUserInfoCard(
+ userId: normalizedUserId,
+ roomId: roomId,
+ sessionSerial: sessionSerial,
+ preloaded: true,
+ ),
+ );
+ }
+
+ static String _resolveCurrentRoomId(BuildContext context) {
+ try {
+ return Provider.of(
+ context,
+ listen: false,
+ ).currenRoom?.roomProfile?.roomProfile?.id ??
+ "";
+ } catch (_) {
+ return "";
+ }
+ }
@override
State createState() => _RoomUserInfoCardState();
@@ -76,12 +159,16 @@ class _RoomUserInfoCardState extends State {
context,
listen: false,
);
- WidgetsBinding.instance.addPostFrameCallback((_) {
- if (!mounted) {
- return;
- }
- _loadRoomUserCard();
- });
+ roomId = widget.roomId?.trim() ?? "";
+ _userCardSessionSerial = widget.sessionSerial;
+ if (!widget.preloaded) {
+ WidgetsBinding.instance.addPostFrameCallback((_) {
+ if (!mounted) {
+ return;
+ }
+ _loadRoomUserCard();
+ });
+ }
SCAccountRepository().userIdentity(userId: widget.userId).then((v) {
if (!mounted) {
return;
@@ -96,12 +183,7 @@ class _RoomUserInfoCardState extends State {
context,
listen: false,
);
- roomId =
- Provider.of(
- context,
- listen: false,
- ).currenRoom?.roomProfile?.roomProfile?.id ??
- "";
+ roomId = RoomUserInfoCard._resolveCurrentRoomId(context);
final sessionSerial = userProvider?.beginRoomUserCardSession();
_userCardSessionSerial = sessionSerial;
userProvider?.roomUserCard(
@@ -244,12 +326,13 @@ class _RoomUserInfoCardState extends State {
required bool relationLoading,
}) {
final defaultSheetHeight = screenHeight * _profileSheetHeightFactor;
+ final compactBadgeHeightDelta = 10.w;
if (relationLoading) {
- return defaultSheetHeight;
+ return defaultSheetHeight + compactBadgeHeightDelta;
}
final hasCpRelation = _hasCpRelation(profile);
final hasCloseFriends = _closeFriendProfileData(profile).isNotEmpty;
- var resolvedHeight = defaultSheetHeight;
+ var resolvedHeight = defaultSheetHeight + compactBadgeHeightDelta;
if (!hasCpRelation) {
resolvedHeight -= 126.w;
}
@@ -602,16 +685,16 @@ class _RoomUserInfoCardState extends State {
) {
return SizedBox(
width: double.infinity,
- height: 20.w,
+ height: 30.w,
child: Center(
child: SCUserBadgeStrip(
userId: userId,
fallbackBadges: _roomCardFallbackBadges(ref, profile),
displayScope: SCUserBadgeDisplayScope.short,
- height: 20.w,
- badgeHeight: 20.w,
- longBadgeWidth: 44.w,
- spacing: 5.w,
+ height: 30.w,
+ badgeHeight: 28.w,
+ longBadgeWidth: 62.w,
+ spacing: 6.w,
maxBadges: 3,
wrap: false,
reserveSpace: false,
diff --git a/sc_images/index/sc_icon_cp_entry.png b/sc_images/index/sc_icon_cp_entry.png
new file mode 100644
index 0000000..9b2c19d
Binary files /dev/null and b/sc_images/index/sc_icon_cp_entry.png differ
diff --git a/需求进度.md b/需求进度.md
index 3a807bf..78bc318 100644
--- a/需求进度.md
+++ b/需求进度.md
@@ -1,3 +1,23 @@
+# Me 页面 CP 入口需求进度(2026-06-24)
+
+- [x] 2026-06-24 已确认本轮需求:Me 页面 Store/Bag 旁边新增一个 `cp` 入口;点击后跳转 H5,正式 H5 链接待用户后续提供。
+- [x] 2026-06-24 已按项目约束读取现有进度文档;本轮为开发型小改动,无新增后端接口,不涉及接口 debuglog。
+- [x] 2026-06-24 已定位 Me 页面实现:`lib/modules/user/me_page2.dart`,当前 Store/Level/Bag 位于 `_buildEntryRow()`,使用 `_buildEntryItem()` 统一卡片样式。
+- [x] 2026-06-24 已确认现有 H5 打开方式:通过 `SCMainRoute.webViewPage` 进入 `WebViewPage`,页面内部会用 `SCH5UrlUtils.appendAppParams()` 补 `lang/token`。
+- [x] 2026-06-24 已通过本机 Figma Desktop MCP 读取节点 `873:592` metadata:目标为 `image 4820`,尺寸约 `46.8 × 50`。
+- [!] 2026-06-24 `get_design_context` 对该单图片节点两次调用均超时;已保留调用记录并改用 metadata + screenshot 作为实现依据。
+- [x] 2026-06-24 已通过本机 Figma Desktop MCP 获取节点 `873:592` screenshot,落地到 `build/me_cp_entry_verification/get_screenshot.png`,尺寸 `47 × 50`。
+- [x] 2026-06-24 已检查 Figma 导出图标边缘像素,无黑边;已复制为项目资源 `sc_images/index/sc_icon_cp_entry.png`。
+- [x] 2026-06-24 已实现 CP 入口:`_buildEntryRow()` 从 Store/Level/Bag 三列改为 Store/Level/Bag/cp 四列,CP 位于 Bag 右侧。
+- [x] 2026-06-24 已新增 CP H5 点击占位逻辑:`_cpActivityUrl` 为空时不跳转,仅 debug 输出;待正式 H5 链接提供后替换常量即可。
+- [x] 2026-06-24 已执行 `dart format lib/modules/user/me_page2.dart`,格式化通过。
+- [x] 2026-06-24 已执行 `flutter analyze --no-fatal-warnings --no-fatal-infos lib/modules/user/me_page2.dart`,退出码 0;报告的空 `catch` 与未引用方法为同文件既有问题,本轮未扩大清理。
+- [x] 2026-06-24 已确认 iPhone 17 Pro Max 模拟器在线,设备 ID:`8D2D87EB-4769-43B7-8DC2-580D46A76B6C`。
+- [!] 2026-06-24 按用户最新要求“不用截图”,已跳过 Me 页面截图验证。
+- [x] 2026-06-24 已结束本仓库本轮 `flutter run` / build 相关进程,未保留本轮运行会话。
+- [x] 2026-06-26 已接入 CP 入口正式 H5 链接:`https://h5.global-interaction.com/activity/cp-space/yumi.html`。
+- [x] 2026-06-26 已针对正式链接替换复跑 `dart format` 与 `flutter analyze --no-fatal-warnings --no-fatal-infos lib/modules/user/me_page2.dart`,退出码 0;仅剩同文件既有 warning/info。
+
# 首充弹窗需求进度(2026-05-21)
- [ ] 2026-05-22 新增问题:后台首充已配置,但前端未显示首充弹窗,房间礼物面板也未显示首充悬浮板;本轮需用 iPhone 17 Pro 模拟器实际排查并修复。
@@ -446,6 +466,8 @@
- 已按 2026-04-20 最新首页视觉需求,为 Party 房间列表前 3 个房卡接入新的本地排名边框 SVGA:桌面“房间排序前三的框”中的 3 份素材已导入工程并挂到首页房卡最上层,仅作用于当前列表前 3 项,其余房卡保持原样;后续又继续为前三房卡底部信息区补了横向与底部安全区,避免外扩边框直接压住国旗、房名和在线人数。同时 `Me` 板块里的 `Recent / Followed` tab 已继续对齐上方首页 tab 的斜体字样式,并移除了点击时的波浪反馈。
- 已按 2026-04-20 最新房间联调继续修正房主在自己房间里的麦位操作回归:当前房主/管理员点击自己所在麦位时,不再被“直接打开资料卡”逻辑短路,会重新回到底部麦位菜单,从而正常看到自己可用的上下麦/禁麦操作;同时上麦、下麦、禁麦、解禁、锁麦、解锁这些动作在接口成功后会立即回写本地麦位状态,并主动补拉一次最新麦位列表,减少房主端自己操作后 UI 状态延迟或短暂错乱。最新已继续收紧“换麦”场景:当前会先本地顺滑切到目标麦位,再在短保护窗内拦住把自己打回旧麦位的旧轮询/旧广播快照;同时补修 `MicRes.copyWith(user: null)` 实际不会清空用户的问题,避免切麦时出现双占位或 `1 -> 4 -> 1 -> 4` 这类来回闪动。
- 已按 2026-04-20 最新调整撤掉 `Wallet -> Recharge` 中新增的 MiFaPay 第三方支付 UI 与页面逻辑:当前充值页仅保留原生 `Google Pay / Apple Pay` 入口与商品列表,`Recharge methods` 区域也已收敛为单一原生支付卡片;此前接入的 MiFaPay 方法选择、底部弹窗、H5 收银台页以及对应页面级状态管理已从现有充值链路移除,避免继续对当前版本产生影响。
+- [x] 2026-06-26 App Review 收口:已调整 `Wallet -> Recharge` 页面,iOS 仅展示钱包余额,不再初始化/展示 Recharge methods、商品空态、恢复购买和充值按钮;顶部标题改为 Wallet,页面静态检查通过。
+- [x] 2026-06-26 iOS 提审版本号调整:Runner 的 `MARKETING_VERSION` 保持 `1.0.0`,`CFBundleVersion` / `CURRENT_PROJECT_VERSION` 已调整为 `102`,对应 App Store Connect 显示 `1.0.0 (102)`。
- 已按 2026-04-18 联调要求继续收口幸运礼物链路:项目默认 API host 已临时切到 `http://192.168.110.43:1100/` 方便直连测试环境;`/gift/give/lucky-gift` 请求体也已补齐为最新结构,除原有 `giftId/quantity/roomId/acceptUserIds/checkCombo` 外,会稳定携带 `gameId: null`、`accepts: []`、`dynamicContentId: null`、`songId: null` 这几组字段,便于和当前后端参数定义保持一致。
- 已继续补齐 `GAME_LUCKY_GIFT` 的 socket 播报与中奖动效:房间群消息收到该类型后,现在会统一落聊天室中奖消息、奖励弹层队列与发送者余额回写,不再只在 `3x+` 时才触发顶部奖励动画;同时全局飘窗已改为按服务端 `globalNews` 字段决定是否展示,避免再用前端本地倍率硬编码去猜。
- 已按最新 UI 口径重排幸运礼物中奖展示:顶部 `LuckGiftNomorAnimWidget` 不再叠加大头像、倍率和奖励框,只在“单个礼物倍率 `>= 10x`”或“单次中奖金币 `> 5000`”时负责播全屏 `luck_gift_reward_burst.svga`;原本的 `luck_gift_reward_frame.svga` 已改挂到房间礼物播报条最右侧,并在框内显示 `+formattedAwardAmount`,金额文案直接复用此前大头像下方那一份中奖金币额。