Merge branch 'test' into feature
This commit is contained in:
commit
671f925232
@ -587,7 +587,11 @@ class _PersonDetailPageState extends State<PersonDetailPage> {
|
|||||||
return Stack(
|
return Stack(
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: [
|
children: [
|
||||||
SCDataCardResourceView(resource: dataCard, fit: BoxFit.cover),
|
SCDataCardResourceView(
|
||||||
|
resource: dataCard,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
fallback: DecoratedBox(decoration: _defaultDataCardDecoration()),
|
||||||
|
),
|
||||||
DecoratedBox(
|
DecoratedBox(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
@ -606,6 +610,21 @@ class _PersonDetailPageState extends State<PersonDetailPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BoxDecoration _defaultDataCardDecoration() {
|
||||||
|
return const BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
colors: [
|
||||||
|
Color(0xff18F2B1),
|
||||||
|
Color(0xffE4FFF6),
|
||||||
|
Color(0xffF7FFFC),
|
||||||
|
Color(0xffFFFFFF),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
PropsResources? _activeDataCard(SocialChatUserProfile? profile) {
|
PropsResources? _activeDataCard(SocialChatUserProfile? profile) {
|
||||||
final now = DateTime.now().millisecondsSinceEpoch;
|
final now = DateTime.now().millisecondsSinceEpoch;
|
||||||
for (final item in profile?.useProps ?? const <UseProps>[]) {
|
for (final item in profile?.useProps ?? const <UseProps>[]) {
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import 'package:yumi/shared/tools/sc_loading_manager.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/sc_debounce_widget.dart';
|
import 'package:yumi/ui_kit/components/sc_debounce_widget.dart';
|
||||||
import 'package:yumi/ui_kit/components/sc_tts.dart';
|
import 'package:yumi/ui_kit/components/sc_tts.dart';
|
||||||
|
import 'package:yumi/ui_kit/widgets/props/sc_data_card_resource_view.dart';
|
||||||
|
|
||||||
class VipDetailPage extends StatefulWidget {
|
class VipDetailPage extends StatefulWidget {
|
||||||
const VipDetailPage({super.key});
|
const VipDetailPage({super.key});
|
||||||
@ -58,7 +59,6 @@ class _VipDetailPageState extends State<VipDetailPage> {
|
|||||||
final status = results[1] as SCVipStatusRes;
|
final status = results[1] as SCVipStatusRes;
|
||||||
final resolvedStatus = _resolveStatus(status, home.state);
|
final resolvedStatus = _resolveStatus(status, home.state);
|
||||||
final selectedLevel = _resolveInitialLevel(home, resolvedStatus);
|
final selectedLevel = _resolveInitialLevel(home, resolvedStatus);
|
||||||
_logLoadedVipData(home, resolvedStatus, selectedLevel);
|
|
||||||
|
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -141,11 +141,6 @@ class _VipDetailPageState extends State<VipDetailPage> {
|
|||||||
_selectedLevel = level;
|
_selectedLevel = level;
|
||||||
_preview = null;
|
_preview = null;
|
||||||
});
|
});
|
||||||
_logSelectedLevelResources(
|
|
||||||
level,
|
|
||||||
config: _levelConfigFor(level),
|
|
||||||
status: _status,
|
|
||||||
);
|
|
||||||
_loadPreviewForLevel(level);
|
_loadPreviewForLevel(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,6 +196,7 @@ class _VipDetailPageState extends State<VipDetailPage> {
|
|||||||
await _loadVipData(showLoading: false);
|
await _loadVipData(showLoading: false);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
debugPrint('VIP purchase failed: $error');
|
||||||
} finally {
|
} finally {
|
||||||
SCLoadingManager.hide();
|
SCLoadingManager.hide();
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
@ -214,56 +210,6 @@ class _VipDetailPageState extends State<VipDetailPage> {
|
|||||||
return 'vip-buy-$userId-${DateTime.now().millisecondsSinceEpoch}';
|
return 'vip-buy-$userId-${DateTime.now().millisecondsSinceEpoch}';
|
||||||
}
|
}
|
||||||
|
|
||||||
void _logLoadedVipData(
|
|
||||||
SCVipHomeRes home,
|
|
||||||
SCVipStatusRes? status,
|
|
||||||
int selectedLevel,
|
|
||||||
) {
|
|
||||||
if (home.configured != true) {}
|
|
||||||
if (home.levels.isEmpty) {}
|
|
||||||
_logSelectedLevelResources(
|
|
||||||
selectedLevel,
|
|
||||||
config: _levelConfigFromHome(home, selectedLevel),
|
|
||||||
status: status,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _logSelectedLevelResources(
|
|
||||||
int level, {
|
|
||||||
required SCVipLevelConfigRes? config,
|
|
||||||
required SCVipStatusRes? status,
|
|
||||||
}) {
|
|
||||||
final state = status?.levelInt == level ? status : null;
|
|
||||||
if (config == null && state == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final badge = _preferResource(config?.badge, state?.badge);
|
|
||||||
final avatarFrame = _preferResource(
|
|
||||||
config?.avatarFrame,
|
|
||||||
state?.avatarFrame,
|
|
||||||
);
|
|
||||||
final entryEffect = _preferResource(
|
|
||||||
config?.entryEffect,
|
|
||||||
state?.entryEffect,
|
|
||||||
);
|
|
||||||
final chatBubble = _preferResource(config?.chatBubble, state?.chatBubble);
|
|
||||||
final floatPicture = _preferResource(
|
|
||||||
config?.floatPicture,
|
|
||||||
state?.floatPicture,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String _resourceLogValue(SCVipResourceRes? resource) {
|
|
||||||
if (!_hasResource(resource)) {
|
|
||||||
return 'null';
|
|
||||||
}
|
|
||||||
return '{id:${resource?.resourceId},name:${resource?.name},'
|
|
||||||
'hasPreviewUrl:${resource?.hasPreviewUrl},'
|
|
||||||
'hasSourceUrl:${resource?.hasSourceUrl},'
|
|
||||||
'previewUrl:${resource?.previewUrl},'
|
|
||||||
'sourceUrl:${resource?.sourceResourceUrl}}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -524,6 +470,8 @@ class _VipDetailPageState extends State<VipDetailPage> {
|
|||||||
|
|
||||||
Widget _buildLevelCard() {
|
Widget _buildLevelCard() {
|
||||||
final assetLevel = _assetLevel;
|
final assetLevel = _assetLevel;
|
||||||
|
final backgroundCard = _selectedBackgroundCard;
|
||||||
|
final effectImage = _selectedEffectImage ?? _selectedLongBadge;
|
||||||
return Center(
|
return Center(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 351.w,
|
width: 351.w,
|
||||||
@ -532,18 +480,23 @@ class _VipDetailPageState extends State<VipDetailPage> {
|
|||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
children: [
|
children: [
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: Container(
|
child: ClipRRect(
|
||||||
decoration: BoxDecoration(
|
borderRadius: BorderRadius.circular(8.w),
|
||||||
borderRadius: BorderRadius.circular(8.w),
|
child: _buildVipCardBackground(
|
||||||
border: Border.all(
|
resource: backgroundCard,
|
||||||
color: const Color(0xFFEBCB76),
|
assetLevel: assetLevel,
|
||||||
width: 1.w,
|
),
|
||||||
),
|
),
|
||||||
image: DecorationImage(
|
),
|
||||||
image: AssetImage(
|
Positioned.fill(
|
||||||
'sc_images/vip/sc_vip_card_bg_$assetLevel.png',
|
child: IgnorePointer(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(8.w),
|
||||||
|
border: Border.all(
|
||||||
|
color: const Color(0xFFEBCB76),
|
||||||
|
width: 1.w,
|
||||||
),
|
),
|
||||||
fit: BoxFit.fill,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -575,8 +528,8 @@ class _VipDetailPageState extends State<VipDetailPage> {
|
|||||||
PositionedDirectional(
|
PositionedDirectional(
|
||||||
end: 24.w,
|
end: 24.w,
|
||||||
top: -36.w,
|
top: -36.w,
|
||||||
child: _buildResourceImage(
|
child: _buildDynamicResourceVisual(
|
||||||
resource: _selectedBadge,
|
resource: effectImage,
|
||||||
width: 135.w,
|
width: 135.w,
|
||||||
height: 135.w,
|
height: 135.w,
|
||||||
fallbackIcon: Icons.workspace_premium_outlined,
|
fallbackIcon: Icons.workspace_premium_outlined,
|
||||||
@ -588,6 +541,27 @@ class _VipDetailPageState extends State<VipDetailPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildVipCardBackground({
|
||||||
|
required SCVipResourceRes? resource,
|
||||||
|
required int assetLevel,
|
||||||
|
}) {
|
||||||
|
final fallback = Image.asset(
|
||||||
|
'sc_images/vip/sc_vip_card_bg_$assetLevel.png',
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
width: double.infinity,
|
||||||
|
height: double.infinity,
|
||||||
|
);
|
||||||
|
if (!_hasResourceUrl(resource)) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
return SCDataCardResourceView(
|
||||||
|
sourceUrl: resource?.sourceResourceUrl,
|
||||||
|
coverUrl: resource?.previewUrl,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
fallback: fallback,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildLevelDivider() {
|
Widget _buildLevelDivider() {
|
||||||
final ornamentLayout = _ornamentLayoutForLevel(_assetLevel);
|
final ornamentLayout = _ornamentLayoutForLevel(_assetLevel);
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
@ -713,9 +687,14 @@ class _VipDetailPageState extends State<VipDetailPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SCVipResourceRes? get _selectedBadge => _selectedResource(
|
SCVipResourceRes? get _selectedLongBadge => _selectedResource(
|
||||||
fromConfig: (config) => config.badge,
|
fromConfig: (config) => config.longBadge,
|
||||||
fromState: (status) => status.badge,
|
fromState: (status) => status.longBadge,
|
||||||
|
);
|
||||||
|
|
||||||
|
SCVipResourceRes? get _selectedShortBadge => _selectedResource(
|
||||||
|
fromConfig: (config) => config.shortBadge,
|
||||||
|
fromState: (status) => status.shortBadge,
|
||||||
);
|
);
|
||||||
|
|
||||||
SCVipResourceRes? get _selectedAvatarFrame => _selectedResource(
|
SCVipResourceRes? get _selectedAvatarFrame => _selectedResource(
|
||||||
@ -738,6 +717,16 @@ class _VipDetailPageState extends State<VipDetailPage> {
|
|||||||
fromState: (status) => status.floatPicture,
|
fromState: (status) => status.floatPicture,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
SCVipResourceRes? get _selectedBackgroundCard => _selectedResource(
|
||||||
|
fromConfig: (config) => config.backgroundCard,
|
||||||
|
fromState: (status) => status.backgroundCard,
|
||||||
|
);
|
||||||
|
|
||||||
|
SCVipResourceRes? get _selectedEffectImage => _selectedResource(
|
||||||
|
fromConfig: (config) => config.effectImage,
|
||||||
|
fromState: (status) => status.effectImage,
|
||||||
|
);
|
||||||
|
|
||||||
SCVipResourceRes? _selectedResource({
|
SCVipResourceRes? _selectedResource({
|
||||||
required SCVipResourceRes? Function(SCVipLevelConfigRes config) fromConfig,
|
required SCVipResourceRes? Function(SCVipLevelConfigRes config) fromConfig,
|
||||||
required SCVipResourceRes? Function(SCVipStatusRes status) fromState,
|
required SCVipResourceRes? Function(SCVipStatusRes status) fromState,
|
||||||
@ -768,8 +757,14 @@ class _VipDetailPageState extends State<VipDetailPage> {
|
|||||||
final items = <_VipFeatureData>[];
|
final items = <_VipFeatureData>[];
|
||||||
_addResourceItem(
|
_addResourceItem(
|
||||||
items,
|
items,
|
||||||
resource: _selectedBadge,
|
resource: _selectedLongBadge,
|
||||||
fallbackTitle: 'VIP Badge',
|
fallbackTitle: 'Long Badge',
|
||||||
|
fallbackIcon: Icons.workspace_premium_outlined,
|
||||||
|
);
|
||||||
|
_addResourceItem(
|
||||||
|
items,
|
||||||
|
resource: _selectedShortBadge,
|
||||||
|
fallbackTitle: 'Short Badge',
|
||||||
fallbackIcon: Icons.workspace_premium_outlined,
|
fallbackIcon: Icons.workspace_premium_outlined,
|
||||||
);
|
);
|
||||||
_addResourceItem(
|
_addResourceItem(
|
||||||
@ -797,12 +792,19 @@ class _VipDetailPageState extends State<VipDetailPage> {
|
|||||||
fallbackIcon: Icons.airline_seat_recline_extra,
|
fallbackIcon: Icons.airline_seat_recline_extra,
|
||||||
wide: true,
|
wide: true,
|
||||||
);
|
);
|
||||||
|
_addResourceItem(
|
||||||
|
items,
|
||||||
|
resource: _selectedBackgroundCard,
|
||||||
|
fallbackTitle: 'Profile Card',
|
||||||
|
fallbackIcon: Icons.badge_outlined,
|
||||||
|
wide: true,
|
||||||
|
);
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<_VipFeatureData> get _vipPrivilegeItems {
|
List<_VipFeatureData> get _vipPrivilegeItems {
|
||||||
// The VIP home API currently returns resource perks only:
|
// The VIP home API currently returns resource perks only:
|
||||||
// badge/avatarFrame/entryEffect/chatBubble/floatPicture.
|
// badges/avatarFrame/entryEffect/chatBubble/floatPicture/backgroundCard.
|
||||||
// Do not render demo-only functional privileges without backend data.
|
// Do not render demo-only functional privileges without backend data.
|
||||||
return const <_VipFeatureData>[];
|
return const <_VipFeatureData>[];
|
||||||
}
|
}
|
||||||
@ -844,6 +846,40 @@ class _VipDetailPageState extends State<VipDetailPage> {
|
|||||||
return fallbackTitle;
|
return fallbackTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildDynamicResourceVisual({
|
||||||
|
required SCVipResourceRes? resource,
|
||||||
|
required double width,
|
||||||
|
required double height,
|
||||||
|
required IconData fallbackIcon,
|
||||||
|
}) {
|
||||||
|
final sourceUrl = resource?.sourceResourceUrl?.trim();
|
||||||
|
final previewUrl = resource?.previewUrl?.trim();
|
||||||
|
final hasSource = sourceUrl != null && sourceUrl.isNotEmpty;
|
||||||
|
final hasPreview = previewUrl != null && previewUrl.isNotEmpty;
|
||||||
|
if (hasSource || hasPreview) {
|
||||||
|
return SCDataCardResourceView(
|
||||||
|
sourceUrl: sourceUrl,
|
||||||
|
coverUrl: previewUrl,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
fallback: _buildResourceImage(
|
||||||
|
resource: resource,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
fallbackIcon: fallbackIcon,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _buildResourceImage(
|
||||||
|
resource: resource,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
fallbackIcon: fallbackIcon,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildResourceImage({
|
Widget _buildResourceImage({
|
||||||
required SCVipResourceRes? resource,
|
required SCVipResourceRes? resource,
|
||||||
required double width,
|
required double width,
|
||||||
|
|||||||
@ -110,10 +110,14 @@ class SCVipStatusRes {
|
|||||||
String? startAt,
|
String? startAt,
|
||||||
String? expireAt,
|
String? expireAt,
|
||||||
SCVipResourceRes? badge,
|
SCVipResourceRes? badge,
|
||||||
|
SCVipResourceRes? longBadge,
|
||||||
|
SCVipResourceRes? shortBadge,
|
||||||
SCVipResourceRes? avatarFrame,
|
SCVipResourceRes? avatarFrame,
|
||||||
SCVipResourceRes? entryEffect,
|
SCVipResourceRes? entryEffect,
|
||||||
SCVipResourceRes? chatBubble,
|
SCVipResourceRes? chatBubble,
|
||||||
SCVipResourceRes? floatPicture,
|
SCVipResourceRes? floatPicture,
|
||||||
|
SCVipResourceRes? backgroundCard,
|
||||||
|
SCVipResourceRes? effectImage,
|
||||||
}) {
|
}) {
|
||||||
_userId = userId;
|
_userId = userId;
|
||||||
_sysOrigin = sysOrigin;
|
_sysOrigin = sysOrigin;
|
||||||
@ -125,10 +129,14 @@ class SCVipStatusRes {
|
|||||||
_startAt = startAt;
|
_startAt = startAt;
|
||||||
_expireAt = expireAt;
|
_expireAt = expireAt;
|
||||||
_badge = badge;
|
_badge = badge;
|
||||||
|
_longBadge = longBadge;
|
||||||
|
_shortBadge = shortBadge;
|
||||||
_avatarFrame = avatarFrame;
|
_avatarFrame = avatarFrame;
|
||||||
_entryEffect = entryEffect;
|
_entryEffect = entryEffect;
|
||||||
_chatBubble = chatBubble;
|
_chatBubble = chatBubble;
|
||||||
_floatPicture = floatPicture;
|
_floatPicture = floatPicture;
|
||||||
|
_backgroundCard = backgroundCard;
|
||||||
|
_effectImage = effectImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCVipStatusRes.fromJson(dynamic json) {
|
SCVipStatusRes.fromJson(dynamic json) {
|
||||||
@ -144,10 +152,14 @@ class SCVipStatusRes {
|
|||||||
_startAt = _stringValue(map['startAt']);
|
_startAt = _stringValue(map['startAt']);
|
||||||
_expireAt = _stringValue(map['expireAt']);
|
_expireAt = _stringValue(map['expireAt']);
|
||||||
_badge = _resourceValue(map['badge']);
|
_badge = _resourceValue(map['badge']);
|
||||||
|
_longBadge = _resourceValue(map['longBadge']) ?? _badge;
|
||||||
|
_shortBadge = _resourceValue(map['shortBadge']);
|
||||||
_avatarFrame = _resourceValue(map['avatarFrame']);
|
_avatarFrame = _resourceValue(map['avatarFrame']);
|
||||||
_entryEffect = _resourceValue(map['entryEffect']);
|
_entryEffect = _resourceValue(map['entryEffect']);
|
||||||
_chatBubble = _resourceValue(map['chatBubble']);
|
_chatBubble = _resourceValue(map['chatBubble']);
|
||||||
_floatPicture = _resourceValue(map['floatPicture']);
|
_floatPicture = _resourceValue(map['floatPicture']);
|
||||||
|
_backgroundCard = _resourceValue(map['backgroundCard']);
|
||||||
|
_effectImage = _resourceValue(map['effectImage']);
|
||||||
}
|
}
|
||||||
|
|
||||||
String? _userId;
|
String? _userId;
|
||||||
@ -160,10 +172,14 @@ class SCVipStatusRes {
|
|||||||
String? _startAt;
|
String? _startAt;
|
||||||
String? _expireAt;
|
String? _expireAt;
|
||||||
SCVipResourceRes? _badge;
|
SCVipResourceRes? _badge;
|
||||||
|
SCVipResourceRes? _longBadge;
|
||||||
|
SCVipResourceRes? _shortBadge;
|
||||||
SCVipResourceRes? _avatarFrame;
|
SCVipResourceRes? _avatarFrame;
|
||||||
SCVipResourceRes? _entryEffect;
|
SCVipResourceRes? _entryEffect;
|
||||||
SCVipResourceRes? _chatBubble;
|
SCVipResourceRes? _chatBubble;
|
||||||
SCVipResourceRes? _floatPicture;
|
SCVipResourceRes? _floatPicture;
|
||||||
|
SCVipResourceRes? _backgroundCard;
|
||||||
|
SCVipResourceRes? _effectImage;
|
||||||
|
|
||||||
String? get userId => _userId;
|
String? get userId => _userId;
|
||||||
|
|
||||||
@ -183,7 +199,11 @@ class SCVipStatusRes {
|
|||||||
|
|
||||||
String? get expireAt => _expireAt;
|
String? get expireAt => _expireAt;
|
||||||
|
|
||||||
SCVipResourceRes? get badge => _badge;
|
SCVipResourceRes? get badge => longBadge;
|
||||||
|
|
||||||
|
SCVipResourceRes? get longBadge => _longBadge ?? _badge;
|
||||||
|
|
||||||
|
SCVipResourceRes? get shortBadge => _shortBadge;
|
||||||
|
|
||||||
SCVipResourceRes? get avatarFrame => _avatarFrame;
|
SCVipResourceRes? get avatarFrame => _avatarFrame;
|
||||||
|
|
||||||
@ -193,6 +213,10 @@ class SCVipStatusRes {
|
|||||||
|
|
||||||
SCVipResourceRes? get floatPicture => _floatPicture;
|
SCVipResourceRes? get floatPicture => _floatPicture;
|
||||||
|
|
||||||
|
SCVipResourceRes? get backgroundCard => _backgroundCard;
|
||||||
|
|
||||||
|
SCVipResourceRes? get effectImage => _effectImage;
|
||||||
|
|
||||||
bool get isActive => _active == true && (_level ?? 0) > 0;
|
bool get isActive => _active == true && (_level ?? 0) > 0;
|
||||||
|
|
||||||
int get levelInt => (_level ?? 0).toInt();
|
int get levelInt => (_level ?? 0).toInt();
|
||||||
@ -216,11 +240,17 @@ class SCVipStatusRes {
|
|||||||
map['displayName'] = _displayName;
|
map['displayName'] = _displayName;
|
||||||
map['startAt'] = _startAt;
|
map['startAt'] = _startAt;
|
||||||
map['expireAt'] = _expireAt;
|
map['expireAt'] = _expireAt;
|
||||||
if (_badge != null) map['badge'] = _badge?.toJson();
|
if (badge != null) map['badge'] = badge?.toJson();
|
||||||
|
if (longBadge != null) map['longBadge'] = longBadge?.toJson();
|
||||||
|
if (_shortBadge != null) map['shortBadge'] = _shortBadge?.toJson();
|
||||||
if (_avatarFrame != null) map['avatarFrame'] = _avatarFrame?.toJson();
|
if (_avatarFrame != null) map['avatarFrame'] = _avatarFrame?.toJson();
|
||||||
if (_entryEffect != null) map['entryEffect'] = _entryEffect?.toJson();
|
if (_entryEffect != null) map['entryEffect'] = _entryEffect?.toJson();
|
||||||
if (_chatBubble != null) map['chatBubble'] = _chatBubble?.toJson();
|
if (_chatBubble != null) map['chatBubble'] = _chatBubble?.toJson();
|
||||||
if (_floatPicture != null) map['floatPicture'] = _floatPicture?.toJson();
|
if (_floatPicture != null) map['floatPicture'] = _floatPicture?.toJson();
|
||||||
|
if (_backgroundCard != null) {
|
||||||
|
map['backgroundCard'] = _backgroundCard?.toJson();
|
||||||
|
}
|
||||||
|
if (_effectImage != null) map['effectImage'] = _effectImage?.toJson();
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,10 +264,14 @@ class SCVipLevelConfigRes {
|
|||||||
num? durationDays,
|
num? durationDays,
|
||||||
num? priceGold,
|
num? priceGold,
|
||||||
SCVipResourceRes? badge,
|
SCVipResourceRes? badge,
|
||||||
|
SCVipResourceRes? longBadge,
|
||||||
|
SCVipResourceRes? shortBadge,
|
||||||
SCVipResourceRes? avatarFrame,
|
SCVipResourceRes? avatarFrame,
|
||||||
SCVipResourceRes? entryEffect,
|
SCVipResourceRes? entryEffect,
|
||||||
SCVipResourceRes? chatBubble,
|
SCVipResourceRes? chatBubble,
|
||||||
SCVipResourceRes? floatPicture,
|
SCVipResourceRes? floatPicture,
|
||||||
|
SCVipResourceRes? backgroundCard,
|
||||||
|
SCVipResourceRes? effectImage,
|
||||||
bool? canPurchase,
|
bool? canPurchase,
|
||||||
num? payableGold,
|
num? payableGold,
|
||||||
}) {
|
}) {
|
||||||
@ -248,10 +282,14 @@ class SCVipLevelConfigRes {
|
|||||||
_durationDays = durationDays;
|
_durationDays = durationDays;
|
||||||
_priceGold = priceGold;
|
_priceGold = priceGold;
|
||||||
_badge = badge;
|
_badge = badge;
|
||||||
|
_longBadge = longBadge;
|
||||||
|
_shortBadge = shortBadge;
|
||||||
_avatarFrame = avatarFrame;
|
_avatarFrame = avatarFrame;
|
||||||
_entryEffect = entryEffect;
|
_entryEffect = entryEffect;
|
||||||
_chatBubble = chatBubble;
|
_chatBubble = chatBubble;
|
||||||
_floatPicture = floatPicture;
|
_floatPicture = floatPicture;
|
||||||
|
_backgroundCard = backgroundCard;
|
||||||
|
_effectImage = effectImage;
|
||||||
_canPurchase = canPurchase;
|
_canPurchase = canPurchase;
|
||||||
_payableGold = payableGold;
|
_payableGold = payableGold;
|
||||||
}
|
}
|
||||||
@ -266,10 +304,14 @@ class SCVipLevelConfigRes {
|
|||||||
_durationDays = _numValue(map['durationDays']);
|
_durationDays = _numValue(map['durationDays']);
|
||||||
_priceGold = _numValue(map['priceGold']);
|
_priceGold = _numValue(map['priceGold']);
|
||||||
_badge = _resourceValue(map['badge']);
|
_badge = _resourceValue(map['badge']);
|
||||||
|
_longBadge = _resourceValue(map['longBadge']) ?? _badge;
|
||||||
|
_shortBadge = _resourceValue(map['shortBadge']);
|
||||||
_avatarFrame = _resourceValue(map['avatarFrame']);
|
_avatarFrame = _resourceValue(map['avatarFrame']);
|
||||||
_entryEffect = _resourceValue(map['entryEffect']);
|
_entryEffect = _resourceValue(map['entryEffect']);
|
||||||
_chatBubble = _resourceValue(map['chatBubble']);
|
_chatBubble = _resourceValue(map['chatBubble']);
|
||||||
_floatPicture = _resourceValue(map['floatPicture']);
|
_floatPicture = _resourceValue(map['floatPicture']);
|
||||||
|
_backgroundCard = _resourceValue(map['backgroundCard']);
|
||||||
|
_effectImage = _resourceValue(map['effectImage']);
|
||||||
_canPurchase = _boolValue(map['canPurchase']);
|
_canPurchase = _boolValue(map['canPurchase']);
|
||||||
_payableGold = _numValue(map['payableGold']);
|
_payableGold = _numValue(map['payableGold']);
|
||||||
}
|
}
|
||||||
@ -281,10 +323,14 @@ class SCVipLevelConfigRes {
|
|||||||
num? _durationDays;
|
num? _durationDays;
|
||||||
num? _priceGold;
|
num? _priceGold;
|
||||||
SCVipResourceRes? _badge;
|
SCVipResourceRes? _badge;
|
||||||
|
SCVipResourceRes? _longBadge;
|
||||||
|
SCVipResourceRes? _shortBadge;
|
||||||
SCVipResourceRes? _avatarFrame;
|
SCVipResourceRes? _avatarFrame;
|
||||||
SCVipResourceRes? _entryEffect;
|
SCVipResourceRes? _entryEffect;
|
||||||
SCVipResourceRes? _chatBubble;
|
SCVipResourceRes? _chatBubble;
|
||||||
SCVipResourceRes? _floatPicture;
|
SCVipResourceRes? _floatPicture;
|
||||||
|
SCVipResourceRes? _backgroundCard;
|
||||||
|
SCVipResourceRes? _effectImage;
|
||||||
bool? _canPurchase;
|
bool? _canPurchase;
|
||||||
num? _payableGold;
|
num? _payableGold;
|
||||||
|
|
||||||
@ -300,7 +346,11 @@ class SCVipLevelConfigRes {
|
|||||||
|
|
||||||
num? get priceGold => _priceGold;
|
num? get priceGold => _priceGold;
|
||||||
|
|
||||||
SCVipResourceRes? get badge => _badge;
|
SCVipResourceRes? get badge => longBadge;
|
||||||
|
|
||||||
|
SCVipResourceRes? get longBadge => _longBadge ?? _badge;
|
||||||
|
|
||||||
|
SCVipResourceRes? get shortBadge => _shortBadge;
|
||||||
|
|
||||||
SCVipResourceRes? get avatarFrame => _avatarFrame;
|
SCVipResourceRes? get avatarFrame => _avatarFrame;
|
||||||
|
|
||||||
@ -310,6 +360,10 @@ class SCVipLevelConfigRes {
|
|||||||
|
|
||||||
SCVipResourceRes? get floatPicture => _floatPicture;
|
SCVipResourceRes? get floatPicture => _floatPicture;
|
||||||
|
|
||||||
|
SCVipResourceRes? get backgroundCard => _backgroundCard;
|
||||||
|
|
||||||
|
SCVipResourceRes? get effectImage => _effectImage;
|
||||||
|
|
||||||
bool? get canPurchase => _canPurchase;
|
bool? get canPurchase => _canPurchase;
|
||||||
|
|
||||||
num? get payableGold => _payableGold;
|
num? get payableGold => _payableGold;
|
||||||
@ -332,11 +386,17 @@ class SCVipLevelConfigRes {
|
|||||||
map['enabled'] = _enabled;
|
map['enabled'] = _enabled;
|
||||||
map['durationDays'] = _durationDays;
|
map['durationDays'] = _durationDays;
|
||||||
map['priceGold'] = _priceGold;
|
map['priceGold'] = _priceGold;
|
||||||
if (_badge != null) map['badge'] = _badge?.toJson();
|
if (badge != null) map['badge'] = badge?.toJson();
|
||||||
|
if (longBadge != null) map['longBadge'] = longBadge?.toJson();
|
||||||
|
if (_shortBadge != null) map['shortBadge'] = _shortBadge?.toJson();
|
||||||
if (_avatarFrame != null) map['avatarFrame'] = _avatarFrame?.toJson();
|
if (_avatarFrame != null) map['avatarFrame'] = _avatarFrame?.toJson();
|
||||||
if (_entryEffect != null) map['entryEffect'] = _entryEffect?.toJson();
|
if (_entryEffect != null) map['entryEffect'] = _entryEffect?.toJson();
|
||||||
if (_chatBubble != null) map['chatBubble'] = _chatBubble?.toJson();
|
if (_chatBubble != null) map['chatBubble'] = _chatBubble?.toJson();
|
||||||
if (_floatPicture != null) map['floatPicture'] = _floatPicture?.toJson();
|
if (_floatPicture != null) map['floatPicture'] = _floatPicture?.toJson();
|
||||||
|
if (_backgroundCard != null) {
|
||||||
|
map['backgroundCard'] = _backgroundCard?.toJson();
|
||||||
|
}
|
||||||
|
if (_effectImage != null) map['effectImage'] = _effectImage?.toJson();
|
||||||
map['canPurchase'] = _canPurchase;
|
map['canPurchase'] = _canPurchase;
|
||||||
map['payableGold'] = _payableGold;
|
map['payableGold'] = _payableGold;
|
||||||
return map;
|
return map;
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
enum SCPropsType {
|
// ignore_for_file: constant_identifier_names
|
||||||
AVATAR_FRAME,
|
|
||||||
FLOAT_PICTURE,
|
enum SCPropsType {
|
||||||
DATA_CARD,
|
AVATAR_FRAME,
|
||||||
CHAT_BUBBLE,
|
FLOAT_PICTURE,
|
||||||
RIDE,
|
DATA_CARD,
|
||||||
LAYOUT,
|
CHAT_BUBBLE,
|
||||||
THEME,
|
RIDE,
|
||||||
BADGE,
|
LAYOUT,
|
||||||
NOBLE_VIP,
|
THEME,
|
||||||
FRAGMENTS,
|
BADGE,
|
||||||
RED_PACKET,
|
NOBLE_VIP,
|
||||||
}
|
VIP_EFFECT_IMAGE,
|
||||||
|
FRAGMENTS,
|
||||||
|
RED_PACKET,
|
||||||
|
}
|
||||||
|
|||||||
@ -362,6 +362,7 @@ class _LoopingDataCardVapVideoState extends State<_LoopingDataCardVapVideo> {
|
|||||||
_controller = controller;
|
_controller = controller;
|
||||||
controller.setAnimListener(
|
controller.setAnimListener(
|
||||||
onFailed: (_, __, ___) => _markFailed(),
|
onFailed: (_, __, ___) => _markFailed(),
|
||||||
|
onVideoComplete: _handleVideoComplete,
|
||||||
onVideoStart: () {
|
onVideoStart: () {
|
||||||
if (mounted && _failed) {
|
if (mounted && _failed) {
|
||||||
setState(() => _failed = false);
|
setState(() => _failed = false);
|
||||||
@ -371,6 +372,19 @@ class _LoopingDataCardVapVideoState extends State<_LoopingDataCardVapVideo> {
|
|||||||
_play();
|
_play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _handleVideoComplete() {
|
||||||
|
if (!mounted || !widget.loop || _failed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unawaited(
|
||||||
|
Future<void>.delayed(Duration.zero, () {
|
||||||
|
if (mounted && widget.loop && !_failed) {
|
||||||
|
return _play();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _play() async {
|
Future<void> _play() async {
|
||||||
final controller = _controller;
|
final controller = _controller;
|
||||||
final url = widget.url.trim();
|
final url = widget.url.trim();
|
||||||
|
|||||||
@ -270,7 +270,11 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
return Stack(
|
return Stack(
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: [
|
children: [
|
||||||
SCDataCardResourceView(resource: dataCard, fit: BoxFit.cover),
|
SCDataCardResourceView(
|
||||||
|
resource: dataCard,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
fallback: DecoratedBox(decoration: _sheetDecoration()),
|
||||||
|
),
|
||||||
DecoratedBox(
|
DecoratedBox(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user