1.1
This commit is contained in:
parent
4de757b9ad
commit
7c7b205ffb
@ -502,7 +502,7 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 35;
|
CURRENT_PROJECT_VERSION = 2;
|
||||||
DEVELOPMENT_TEAM = S9X2AJ2US9;
|
DEVELOPMENT_TEAM = S9X2AJ2US9;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -511,7 +511,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.0;
|
MARKETING_VERSION = 1.1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -693,7 +693,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 35;
|
CURRENT_PROJECT_VERSION = 2;
|
||||||
DEVELOPMENT_TEAM = F33K8VUZ62;
|
DEVELOPMENT_TEAM = F33K8VUZ62;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -702,7 +702,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.0;
|
MARKETING_VERSION = 1.1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -722,7 +722,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 35;
|
CURRENT_PROJECT_VERSION = 2;
|
||||||
DEVELOPMENT_TEAM = F33K8VUZ62;
|
DEVELOPMENT_TEAM = F33K8VUZ62;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -731,7 +731,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.0;
|
MARKETING_VERSION = 1.1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
|||||||
@ -76,6 +76,7 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
static const int _luckyGiftFloatMinMultiple = 5;
|
static const int _luckyGiftFloatMinMultiple = 5;
|
||||||
static const int _luckyGiftBurstMinMultiple = 10;
|
static const int _luckyGiftBurstMinMultiple = 10;
|
||||||
static const int _luckyGiftBurstMinAwardAmount = 5000;
|
static const int _luckyGiftBurstMinAwardAmount = 5000;
|
||||||
|
static const int _luckyGiftBurstDisplayDurationMs = 2000;
|
||||||
|
|
||||||
BuildContext? context;
|
BuildContext? context;
|
||||||
|
|
||||||
@ -1019,6 +1020,7 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
userName: rewardData?.nickname,
|
userName: rewardData?.nickname,
|
||||||
toUserName: rewardData?.acceptNickname,
|
toUserName: rewardData?.acceptNickname,
|
||||||
giftUrl: rewardData?.giftCover,
|
giftUrl: rewardData?.giftCover,
|
||||||
|
giftId: rewardData?.giftId,
|
||||||
number: rewardData?.giftQuantity,
|
number: rewardData?.giftQuantity,
|
||||||
coins: rewardData?.awardAmount,
|
coins: rewardData?.awardAmount,
|
||||||
multiple: rewardData?.multiple,
|
multiple: rewardData?.multiple,
|
||||||
@ -1765,12 +1767,15 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
? null
|
? null
|
||||||
: _luckyGiftPushEventKey(currentPlayingLuckGift!);
|
: _luckyGiftPushEventKey(currentPlayingLuckGift!);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
Future.delayed(Duration(milliseconds: 3000), () {
|
Future.delayed(
|
||||||
|
Duration(milliseconds: _luckyGiftBurstDisplayDurationMs),
|
||||||
|
() {
|
||||||
currentPlayingLuckGift = null;
|
currentPlayingLuckGift = null;
|
||||||
_currentLuckGiftPushKey = null;
|
_currentLuckGiftPushKey = null;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
playLuckGiftBackCoins();
|
playLuckGiftBackCoins();
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String _luckyGiftPushEventKey(SCBroadCastLuckGiftPush broadCastRes) {
|
String _luckyGiftPushEventKey(SCBroadCastLuckGiftPush broadCastRes) {
|
||||||
|
|||||||
@ -7,6 +7,7 @@ class SCFloatingMessage {
|
|||||||
String? userName; // 用户昵称
|
String? userName; // 用户昵称
|
||||||
String? toUserName; // 用户昵称
|
String? toUserName; // 用户昵称
|
||||||
String? giftUrl; // 礼物图标
|
String? giftUrl; // 礼物图标
|
||||||
|
String? giftId; // 礼物id
|
||||||
int? type;
|
int? type;
|
||||||
int? rocketLevel;
|
int? rocketLevel;
|
||||||
num? coins;
|
num? coins;
|
||||||
@ -25,6 +26,7 @@ class SCFloatingMessage {
|
|||||||
this.userName = '',
|
this.userName = '',
|
||||||
this.toUserName = '',
|
this.toUserName = '',
|
||||||
this.giftUrl = '',
|
this.giftUrl = '',
|
||||||
|
this.giftId = '',
|
||||||
this.number = 0,
|
this.number = 0,
|
||||||
this.coins = 0,
|
this.coins = 0,
|
||||||
this.priority = 10,
|
this.priority = 10,
|
||||||
@ -42,6 +44,7 @@ class SCFloatingMessage {
|
|||||||
userName = json['userName'];
|
userName = json['userName'];
|
||||||
toUserName = json['toUserName'];
|
toUserName = json['toUserName'];
|
||||||
giftUrl = json['giftUrl'];
|
giftUrl = json['giftUrl'];
|
||||||
|
giftId = json['giftId'];
|
||||||
coins = json['coins'];
|
coins = json['coins'];
|
||||||
number = json['number'];
|
number = json['number'];
|
||||||
priority = json['priority'];
|
priority = json['priority'];
|
||||||
@ -60,6 +63,7 @@ class SCFloatingMessage {
|
|||||||
map['userName'] = userName;
|
map['userName'] = userName;
|
||||||
map['toUserName'] = toUserName;
|
map['toUserName'] = toUserName;
|
||||||
map['giftUrl'] = giftUrl;
|
map['giftUrl'] = giftUrl;
|
||||||
|
map['giftId'] = giftId;
|
||||||
map['coins'] = coins;
|
map['coins'] = coins;
|
||||||
map['number'] = number;
|
map['number'] = number;
|
||||||
map['priority'] = priority;
|
map['priority'] = priority;
|
||||||
|
|||||||
@ -98,7 +98,7 @@ class _LuckGiftNomorAnimWidgetState extends State<LuckGiftNomorAnimWidget> {
|
|||||||
child: Align(
|
child: Align(
|
||||||
alignment: const Alignment(0, 0.12),
|
alignment: const Alignment(0, 0.12),
|
||||||
child: Transform.translate(
|
child: Transform.translate(
|
||||||
offset: Offset(0, 0),
|
offset: Offset(5.w, -4.w),
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth: ScreenUtil().screenWidth * 0.56,
|
maxWidth: ScreenUtil().screenWidth * 0.56,
|
||||||
@ -106,7 +106,7 @@ class _LuckGiftNomorAnimWidgetState extends State<LuckGiftNomorAnimWidget> {
|
|||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(left: 6.w, right: 2.w),
|
padding: EdgeInsets.only(left: 0.w, right: 0.w),
|
||||||
child: Text(
|
child: Text(
|
||||||
_formatAwardAmount(rewardData.awardAmount ?? 0),
|
_formatAwardAmount(rewardData.awardAmount ?? 0),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_debouncer/flutter_debouncer.dart';
|
import 'package:flutter_debouncer/flutter_debouncer.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
import 'package:yumi/ui_kit/components/sc_compontent.dart';
|
import 'package:yumi/ui_kit/components/sc_compontent.dart';
|
||||||
import 'package:yumi/ui_kit/components/text/sc_text.dart';
|
import 'package:yumi/ui_kit/components/text/sc_text.dart';
|
||||||
import 'package:yumi/app/constants/sc_global_config.dart';
|
import 'package:yumi/app/constants/sc_global_config.dart';
|
||||||
|
import 'package:yumi/services/general/sc_app_general_manager.dart';
|
||||||
import 'package:yumi/shared/tools/sc_room_utils.dart';
|
import 'package:yumi/shared/tools/sc_room_utils.dart';
|
||||||
import 'package:yumi/main.dart';
|
import 'package:yumi/main.dart';
|
||||||
import 'package:marquee/marquee.dart';
|
import 'package:marquee/marquee.dart';
|
||||||
@ -294,11 +296,7 @@ class _FloatingLuckGiftScreenWidgetState
|
|||||||
TextSpan(text: "from ", style: baseStyle),
|
TextSpan(text: "from ", style: baseStyle),
|
||||||
WidgetSpan(
|
WidgetSpan(
|
||||||
alignment: PlaceholderAlignment.middle,
|
alignment: PlaceholderAlignment.middle,
|
||||||
child: netImage(
|
child: _buildGiftIcon(context),
|
||||||
url: widget.message.giftUrl ?? "",
|
|
||||||
width: 18.w,
|
|
||||||
height: 18.w,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -314,6 +312,57 @@ class _FloatingLuckGiftScreenWidgetState
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildGiftIcon(BuildContext context) {
|
||||||
|
final primaryGiftUrl = (widget.message.giftUrl ?? "").trim();
|
||||||
|
final fallbackGiftUrl = _resolveFallbackGiftUrl(context);
|
||||||
|
final displayGiftUrl =
|
||||||
|
primaryGiftUrl.isNotEmpty ? primaryGiftUrl : fallbackGiftUrl;
|
||||||
|
if (displayGiftUrl.isEmpty) {
|
||||||
|
return _buildGiftIconPlaceholder();
|
||||||
|
}
|
||||||
|
|
||||||
|
final backupUrl =
|
||||||
|
fallbackGiftUrl.isNotEmpty && fallbackGiftUrl != displayGiftUrl
|
||||||
|
? fallbackGiftUrl
|
||||||
|
: "";
|
||||||
|
|
||||||
|
return netImage(
|
||||||
|
url: displayGiftUrl,
|
||||||
|
width: 18.w,
|
||||||
|
height: 18.w,
|
||||||
|
borderRadius: BorderRadius.circular(3.w),
|
||||||
|
loadingWidget: _buildGiftIconPlaceholder(),
|
||||||
|
errorWidget:
|
||||||
|
backupUrl.isNotEmpty
|
||||||
|
? netImage(
|
||||||
|
url: backupUrl,
|
||||||
|
width: 18.w,
|
||||||
|
height: 18.w,
|
||||||
|
borderRadius: BorderRadius.circular(3.w),
|
||||||
|
noDefaultImg: true,
|
||||||
|
loadingWidget: _buildGiftIconPlaceholder(),
|
||||||
|
errorWidget: _buildGiftIconPlaceholder(),
|
||||||
|
)
|
||||||
|
: _buildGiftIconPlaceholder(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String _resolveFallbackGiftUrl(BuildContext context) {
|
||||||
|
final giftId = (widget.message.giftId ?? "").trim();
|
||||||
|
if (giftId.isEmpty) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
final gift = Provider.of<SCAppGeneralManager>(
|
||||||
|
context,
|
||||||
|
listen: false,
|
||||||
|
).getGiftById(giftId);
|
||||||
|
return (gift?.giftPhoto ?? "").trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildGiftIconPlaceholder() {
|
||||||
|
return SizedBox(width: 18.w, height: 18.w);
|
||||||
|
}
|
||||||
|
|
||||||
String _formatCoins(num? coins) {
|
String _formatCoins(num? coins) {
|
||||||
final value = (coins ?? 0);
|
final value = (coins ?? 0);
|
||||||
if (value > 9999) {
|
if (value > 9999) {
|
||||||
|
|||||||
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 1.0.0+1
|
version: 1.1.0+2
|
||||||
|
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
2
需求进度.md
2
需求进度.md
@ -41,6 +41,8 @@
|
|||||||
- 已继续修正幸运礼物 `burst` 中央金额文案的细节对位:当前已再上移 `2` 个单位,并给金额文本左侧补出额外留白,避免斜体 `+` 号因为字形外扩而贴边或被裁掉,确保 `+金币` 能完整落在特效中部。
|
- 已继续修正幸运礼物 `burst` 中央金额文案的细节对位:当前已再上移 `2` 个单位,并给金额文本左侧补出额外留白,避免斜体 `+` 号因为字形外扩而贴边或被裁掉,确保 `+金币` 能完整落在特效中部。
|
||||||
- 已继续按最新联调口径修正幸运礼物 `burst` 中央金额文案:当前已去掉文本里的 `+` 字符,仅保留金币数本身显示;同时维持上一版向上微调后的纵向位置,让金额落点保持在特效中部偏上的稳定区域。
|
- 已继续按最新联调口径修正幸运礼物 `burst` 中央金额文案:当前已去掉文本里的 `+` 字符,仅保留金币数本身显示;同时维持上一版向上微调后的纵向位置,让金额落点保持在特效中部偏上的稳定区域。
|
||||||
- 已继续收口幸运礼物 `burst` 金额文案与 `svga` 本体的时机同步:此前中央金币文本直接跟外层中奖数据显隐,而 `svga` 自身还存在资源加载和单次播放完成的生命周期,所以两者在出现/消失时会有肉眼可见的前后差;当前已给 `SCSvgaAssetWidget` 补上播放开始/结束回调,并让 `burst` 中央金额只在 `svga` 真正开始播时显示、在它播完清帧时一并隐藏。
|
- 已继续收口幸运礼物 `burst` 金额文案与 `svga` 本体的时机同步:此前中央金币文本直接跟外层中奖数据显隐,而 `svga` 自身还存在资源加载和单次播放完成的生命周期,所以两者在出现/消失时会有肉眼可见的前后差;当前已给 `SCSvgaAssetWidget` 补上播放开始/结束回调,并让 `burst` 中央金额只在 `svga` 真正开始播时显示、在它播完清帧时一并隐藏。
|
||||||
|
- 已按 2026-04-21 最新联调继续细调幸运礼物 `burst` 中央金币文案:当前已在现有基础上再向上微调 `4` 个单位、向右微调 `5` 个单位,让金额更贴近特效中部的目标槽位;同时 `burst` 的整体展示时长也已再缩短 `1` 秒,避免命中后在屏上停留过久。
|
||||||
|
- 已继续修复幸运礼物顶部横幅 `from` 后礼物图标偶发显示不出来的问题:此前这条紫色 lucky gift 横幅只直接使用 socket 下发的 `giftCover/giftUrl` 渲染礼物图,一旦服务端该字段为空或图片加载失败,就只会退回默认占位;当前已把 `giftId` 一并挂进 `SCFloatingMessage`,并在 `FloatingLuckGiftScreenWidget` 内增加“优先用 `giftUrl`,失败时再回退到本地礼物列表缓存中的 `giftPhoto`”的双重兜底,避免横幅末尾再出现空白占位块。
|
||||||
- 已优化语言房麦位/头像的二次确认交互:普通用户点击可上麦的空麦位时,当前会直接执行上麦,不再先弹出只有 `Take the mic / Cancel` 的确认层;普通用户点击房间头像或已占麦位上的用户头像时,也会直接打开个人卡片,不再额外弹出仅含 `Open user profile card / Cancel` 的底部确认。房主/管理员仍保留原有带禁麦、锁麦、邀请上麦等管理动作的底部菜单,避免误删管理能力。
|
- 已优化语言房麦位/头像的二次确认交互:普通用户点击可上麦的空麦位时,当前会直接执行上麦,不再先弹出只有 `Take the mic / Cancel` 的确认层;普通用户点击房间头像或已占麦位上的用户头像时,也会直接打开个人卡片,不再额外弹出仅含 `Open user profile card / Cancel` 的底部确认。房主/管理员仍保留原有带禁麦、锁麦、邀请上麦等管理动作的底部菜单,避免误删管理能力。
|
||||||
- 已继续收窄语言房个人卡片前的“确认意义”弹层:当前用户在麦位上点击自己的头像时,也会直接打开自己的个人卡片,不再先弹出仅包含 `Leave the mic / Open user profile card / Cancel` 的底部菜单;同时个人卡片内的“离开麦位”入口已替换为新的 `leave` 视觉素材,和最新房间交互稿保持一致。
|
- 已继续收窄语言房个人卡片前的“确认意义”弹层:当前用户在麦位上点击自己的头像时,也会直接打开自己的个人卡片,不再先弹出仅包含 `Leave the mic / Open user profile card / Cancel` 的底部菜单;同时个人卡片内的“离开麦位”入口已替换为新的 `leave` 视觉素材,和最新房间交互稿保持一致。
|
||||||
- 已继续微调语言房个人卡片与送礼 UI:个人卡片底部动作文案现已支持两行居中展示,避免 `Leave the mic` 这类英文按钮被硬截断;房间底部礼物入口也已切换为新的本地 `SVGA` 资源 `room_bottom_gift_button.svga`,保持房间底栏视觉和最新动效稿一致。
|
- 已继续微调语言房个人卡片与送礼 UI:个人卡片底部动作文案现已支持两行居中展示,避免 `Leave the mic` 这类英文按钮被硬截断;房间底部礼物入口也已切换为新的本地 `SVGA` 资源 `room_bottom_gift_button.svga`,保持房间底栏视觉和最新动效稿一致。
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user