Merge develop into feature
This commit is contained in:
commit
76daf8e32c
@ -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 = "";
|
||||
|
||||
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -37,6 +37,8 @@ class MePage2 extends StatefulWidget {
|
||||
|
||||
class _MePage2State extends State<MePage2> 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<MePage2> 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<MePage2> 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,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@ -37,11 +37,6 @@ class _RechargePageState extends State<RechargePage> {
|
||||
context,
|
||||
listen: false,
|
||||
).initializePaymentProcessor(context);
|
||||
} else if (Platform.isIOS) {
|
||||
Provider.of<IOSPaymentProcessor>(
|
||||
context,
|
||||
listen: false,
|
||||
).initializePaymentProcessor(context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,7 +55,7 @@ class _RechargePageState extends State<RechargePage> {
|
||||
.getRechargePageScaffoldBackgroundColor(),
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: SocialChatStandardAppBar(
|
||||
title: SCAppLocalizations.of(context)!.recharge,
|
||||
title: SCAppLocalizations.of(context)!.wallet,
|
||||
actions: [
|
||||
GestureDetector(
|
||||
onTap: _showRecordDialog,
|
||||
@ -83,7 +78,10 @@ class _RechargePageState extends State<RechargePage> {
|
||||
_buildWalletSection(),
|
||||
SizedBox(height: 36.w),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
child:
|
||||
Platform.isIOS
|
||||
? const SizedBox.shrink()
|
||||
: Padding(
|
||||
padding: EdgeInsets.fromLTRB(12.w, 8.w, 12.w, 0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -91,24 +89,10 @@ class _RechargePageState extends State<RechargePage> {
|
||||
_buildMethodSection(),
|
||||
SizedBox(height: 14.w),
|
||||
Expanded(child: _buildNativeProductList()),
|
||||
if (Platform.isIOS) ...[
|
||||
SizedBox(height: 12.w),
|
||||
_buildFooterButton(
|
||||
title:
|
||||
SCAppLocalizations.of(
|
||||
context,
|
||||
)!.restorePurchases,
|
||||
onTap: () {
|
||||
Provider.of<IOSPaymentProcessor>(
|
||||
context,
|
||||
listen: false,
|
||||
).recoverTransactions();
|
||||
},
|
||||
),
|
||||
],
|
||||
SizedBox(height: 12.w),
|
||||
_buildFooterButton(
|
||||
title: SCAppLocalizations.of(context)!.recharge,
|
||||
SCAppLocalizations.of(context)!.recharge,
|
||||
onTap: _processNativePurchase,
|
||||
),
|
||||
SizedBox(height: 14.w),
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -250,7 +250,7 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
||||
return sessionSerial;
|
||||
}
|
||||
|
||||
Future<void> roomUserCard(
|
||||
Future<RoomUserCardRes?> 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<RoomUserCardRes?> preloadRoomUserCardForOpen(
|
||||
String roomId,
|
||||
String userId, {
|
||||
int? sessionSerial,
|
||||
}) {
|
||||
return roomUserCard(roomId, userId, sessionSerial: sessionSerial);
|
||||
}
|
||||
|
||||
Future<RoomUserCardRes?> _loadHydratedRoomUserCard({
|
||||
required String roomId,
|
||||
required String userId,
|
||||
}) async {
|
||||
final card = await SCChatRoomRepository().roomUserCard(roomId, userId);
|
||||
return _withCurrentVipLevelForCard(card, userId);
|
||||
}
|
||||
|
||||
Future<void> _hydrateUserInfoById({
|
||||
@ -340,38 +352,6 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _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) {
|
||||
|
||||
@ -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);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@ -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<void> 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<SocialChatUserProfileManager>(
|
||||
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<RtcProvider>(
|
||||
context,
|
||||
listen: false,
|
||||
).currenRoom?.roomProfile?.roomProfile?.id ??
|
||||
"";
|
||||
} catch (_) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
State<RoomUserInfoCard> createState() => _RoomUserInfoCardState();
|
||||
@ -76,12 +159,16 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
||||
context,
|
||||
listen: false,
|
||||
);
|
||||
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<RoomUserInfoCard> {
|
||||
context,
|
||||
listen: false,
|
||||
);
|
||||
roomId =
|
||||
Provider.of<RtcProvider>(
|
||||
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<RoomUserInfoCard> {
|
||||
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<RoomUserInfoCard> {
|
||||
) {
|
||||
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,
|
||||
|
||||
BIN
sc_images/index/sc_icon_cp_entry.png
Normal file
BIN
sc_images/index/sc_icon_cp_entry.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
22
需求进度.md
22
需求进度.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`,金额文案直接复用此前大头像下方那一份中奖金币额。
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user