bug。fix
This commit is contained in:
parent
71993f438b
commit
6da7e28fbc
@ -48,7 +48,7 @@ class _RoomCpProgressDialogPreviewPage extends StatelessWidget {
|
|||||||
const RoomCpProgressDialog(
|
const RoomCpProgressDialog(
|
||||||
daysValue: '999',
|
daysValue: '999',
|
||||||
daysLabel: 'Days',
|
daysLabel: 'Days',
|
||||||
levelText: 'Lv.1 Simple Love',
|
levelText: 'Lv.0',
|
||||||
currentValue: 1,
|
currentValue: 1,
|
||||||
targetValue: 1,
|
targetValue: 1,
|
||||||
expAwayText: '1,000',
|
expAwayText: '1,000',
|
||||||
|
|||||||
@ -1676,6 +1676,14 @@ class _GiftPageState extends State<GiftPage> with TickerProviderStateMixin {
|
|||||||
if (!_isCpGift(request.gift)) {
|
if (!_isCpGift(request.gift)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (request.isSelfRecipientRequest) {
|
||||||
|
_giftFxLog(
|
||||||
|
'skip local CP waiting dialog reason=self_recipient '
|
||||||
|
'giftId=${request.gift.id} '
|
||||||
|
'acceptUserIds=${request.acceptUserIds.join(",")}',
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
final context = navigatorKey.currentState?.context;
|
final context = navigatorKey.currentState?.context;
|
||||||
final currentProfile = AccountStorage().getCurrentUser()?.userProfile;
|
final currentProfile = AccountStorage().getCurrentUser()?.userProfile;
|
||||||
final receiverProfile =
|
final receiverProfile =
|
||||||
@ -2359,9 +2367,40 @@ class _GiftSendRequest {
|
|||||||
if (!scIsCpGift(gift)) {
|
if (!scIsCpGift(gift)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (isSelfRecipientRequest) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return scCpRelationTypeForGift(gift);
|
return scCpRelationTypeForGift(gift);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get isSelfRecipientRequest {
|
||||||
|
final currentProfile = AccountStorage().getCurrentUser()?.userProfile;
|
||||||
|
final currentKeys = _profileIdentityKeys(currentProfile);
|
||||||
|
if (currentKeys.isEmpty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (final userId in acceptUserIds) {
|
||||||
|
if (currentKeys.contains(userId.trim())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (final acceptUser in acceptUsers) {
|
||||||
|
final acceptKeys = _profileIdentityKeys(acceptUser.user);
|
||||||
|
if (acceptKeys.any(currentKeys.contains)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> _profileIdentityKeys(SocialChatUserProfile? profile) {
|
||||||
|
return <String>{
|
||||||
|
profile?.id?.trim() ?? "",
|
||||||
|
profile?.account?.trim() ?? "",
|
||||||
|
profile?.getID().trim() ?? "",
|
||||||
|
}..remove("");
|
||||||
|
}
|
||||||
|
|
||||||
String get batchKey {
|
String get batchKey {
|
||||||
final sortedAcceptUserIds = List<String>.from(acceptUserIds)..sort();
|
final sortedAcceptUserIds = List<String>.from(acceptUserIds)..sort();
|
||||||
final type =
|
final type =
|
||||||
|
|||||||
@ -1449,19 +1449,7 @@ class _PersonDetailPageState extends State<PersonDetailPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _normalizeProfileRelationType(String? relationType) {
|
String _normalizeProfileRelationType(String? relationType) {
|
||||||
final value = relationType?.trim().toUpperCase() ?? "";
|
return scNormalizeCpRelationType(relationType);
|
||||||
switch (value) {
|
|
||||||
case "BROTHER":
|
|
||||||
case "BROTHERS":
|
|
||||||
case "SWORN_BROTHER":
|
|
||||||
case "SWORN_BROTHERS":
|
|
||||||
return "BROTHER";
|
|
||||||
case "SISTER":
|
|
||||||
case "SISTERS":
|
|
||||||
return "SISTERS";
|
|
||||||
default:
|
|
||||||
return "CP";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isOwnProfile(SocialChatUserProfile? profile) {
|
bool _isOwnProfile(SocialChatUserProfile? profile) {
|
||||||
@ -1639,7 +1627,12 @@ class _PersonDetailPageState extends State<PersonDetailPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _profileCpLevelAsset(CPRes relation) {
|
String _profileCpLevelAsset(CPRes relation) {
|
||||||
return "$_cpProfileAssetBase/sc_cp_profile_cp_level_${_profileRelationLevel(relation)}.png";
|
return "$_cpProfileAssetBase/sc_cp_profile_cp_level_${_profileRelationAssetLevel(relation)}.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
int _profileRelationAssetLevel(CPRes relation) {
|
||||||
|
final level = _profileRelationLevel(relation);
|
||||||
|
return level <= 0 ? 1 : level;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _profileRelationLevel(CPRes relation) {
|
int _profileRelationLevel(CPRes relation) {
|
||||||
@ -1648,7 +1641,7 @@ class _PersonDetailPageState extends State<PersonDetailPage> {
|
|||||||
|
|
||||||
String _profileRelationLevelText(CPRes relation) {
|
String _profileRelationLevelText(CPRes relation) {
|
||||||
return _profileRelationLevelDisplayText(
|
return _profileRelationLevelDisplayText(
|
||||||
_firstNonBlankProfileValue([relation.levelText, "Lv.1 Simple Love"]),
|
_firstNonBlankProfileValue([relation.levelText, "Lv.0"]),
|
||||||
relation,
|
relation,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -2639,10 +2632,7 @@ class _ProfileRelationProgressData {
|
|||||||
) {
|
) {
|
||||||
final currentValue = payload.cpValue;
|
final currentValue = payload.cpValue;
|
||||||
return _ProfileRelationProgressData(
|
return _ProfileRelationProgressData(
|
||||||
levelText:
|
levelText: scCpRelationLevelDisplayText(payload.levelText),
|
||||||
payload.levelText.trim().isEmpty
|
|
||||||
? "Lv.1 Simple Love"
|
|
||||||
: payload.levelText,
|
|
||||||
currentValue: currentValue,
|
currentValue: currentValue,
|
||||||
targetValue: currentValue > 0 ? currentValue : 1,
|
targetValue: currentValue > 0 ? currentValue : 1,
|
||||||
expAwayText: SCStringUtils.formatCompactNumber(0),
|
expAwayText: SCStringUtils.formatCompactNumber(0),
|
||||||
@ -2762,16 +2752,19 @@ class _ProfileRelationProgressData {
|
|||||||
) {
|
) {
|
||||||
final fallbackText = fallback.trim();
|
final fallbackText = fallback.trim();
|
||||||
if (level == null) {
|
if (level == null) {
|
||||||
return fallbackText.isEmpty ? "Lv.1 Simple Love" : fallbackText;
|
return scCpRelationLevelDisplayText(fallbackText);
|
||||||
}
|
}
|
||||||
final levelName = level.levelName?.trim();
|
final levelName = level.levelName?.trim();
|
||||||
|
if (level.level != null && levelName != null && levelName.isNotEmpty) {
|
||||||
|
return scCpRelationLevelDisplayText("Lv.${level.level} $levelName");
|
||||||
|
}
|
||||||
if (levelName != null && levelName.isNotEmpty) {
|
if (levelName != null && levelName.isNotEmpty) {
|
||||||
return levelName;
|
return scCpRelationLevelDisplayText(levelName);
|
||||||
}
|
}
|
||||||
if (level.level != null) {
|
if (level.level != null) {
|
||||||
return "Lv.${level.level}";
|
return "Lv.${level.level}";
|
||||||
}
|
}
|
||||||
return fallbackText.isEmpty ? "Lv.1 Simple Love" : fallbackText;
|
return scCpRelationLevelDisplayText(fallbackText);
|
||||||
}
|
}
|
||||||
|
|
||||||
static String _levelShortText(int? level, {String? fallback}) {
|
static String _levelShortText(int? level, {String? fallback}) {
|
||||||
@ -2780,9 +2773,9 @@ class _ProfileRelationProgressData {
|
|||||||
}
|
}
|
||||||
final fallbackText = fallback?.trim() ?? "";
|
final fallbackText = fallback?.trim() ?? "";
|
||||||
if (fallbackText.isNotEmpty) {
|
if (fallbackText.isNotEmpty) {
|
||||||
return fallbackText;
|
return scCpRelationLevelDisplayText(fallbackText);
|
||||||
}
|
}
|
||||||
return "Lv. 1";
|
return "Lv. 0";
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _levelIndex(String levelText) {
|
static int _levelIndex(String levelText) {
|
||||||
@ -2790,7 +2783,7 @@ class _ProfileRelationProgressData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int _nextLevelIndex(int level) {
|
static int _nextLevelIndex(int level) {
|
||||||
return (level + 1).clamp(1, 5).toInt();
|
return (level + 1).clamp(0, 5).toInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -324,9 +324,11 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
static const String _roomRocketRewardDialogTag = 'showRoomRocketRewardDialog';
|
static const String _roomRocketRewardDialogTag = 'showRoomRocketRewardDialog';
|
||||||
static const String _roomRocketPagLaunchDialogTag =
|
static const String _roomRocketPagLaunchDialogTag =
|
||||||
'showRoomRocketPagLaunchDialog';
|
'showRoomRocketPagLaunchDialog';
|
||||||
static const Duration _roomRocketGiftRefreshDelay = Duration(
|
static const List<Duration> _roomRocketGiftRefreshDelays = [
|
||||||
milliseconds: 700,
|
Duration(milliseconds: 700),
|
||||||
);
|
Duration(milliseconds: 1600),
|
||||||
|
Duration(milliseconds: 3200),
|
||||||
|
];
|
||||||
static const List<Duration> _roomRocketPostLaunchRefreshDelays = [
|
static const List<Duration> _roomRocketPostLaunchRefreshDelays = [
|
||||||
Duration(milliseconds: 800),
|
Duration(milliseconds: 800),
|
||||||
Duration(seconds: 2),
|
Duration(seconds: 2),
|
||||||
@ -389,7 +391,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
Timer? _roomEntryEffectTimer;
|
Timer? _roomEntryEffectTimer;
|
||||||
Timer? _roomRocketLaunchAnimationTimer;
|
Timer? _roomRocketLaunchAnimationTimer;
|
||||||
ValueNotifier<String?>? _roomRocketLaunchTopAvatarNotifier;
|
ValueNotifier<String?>? _roomRocketLaunchTopAvatarNotifier;
|
||||||
Timer? _roomRocketGiftRefreshTimer;
|
final List<Timer> _roomRocketGiftRefreshTimers = [];
|
||||||
final List<Timer> _roomRocketPostLaunchRefreshTimers = [];
|
final List<Timer> _roomRocketPostLaunchRefreshTimers = [];
|
||||||
final List<Timer> _roomRocketEntryReadyFallbackTimers = [];
|
final List<Timer> _roomRocketEntryReadyFallbackTimers = [];
|
||||||
Timer? _roomRedPacketPresenceTimer;
|
Timer? _roomRedPacketPresenceTimer;
|
||||||
@ -546,8 +548,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
_roomRocketLaunchAnimationTimer = null;
|
_roomRocketLaunchAnimationTimer = null;
|
||||||
SmartDialog.dismiss(tag: _roomRocketPagLaunchDialogTag);
|
SmartDialog.dismiss(tag: _roomRocketPagLaunchDialogTag);
|
||||||
_releaseRoomRocketLaunchTopAvatarNotifier();
|
_releaseRoomRocketLaunchTopAvatarNotifier();
|
||||||
_roomRocketGiftRefreshTimer?.cancel();
|
_cancelRoomRocketGiftStatusRefresh();
|
||||||
_roomRocketGiftRefreshTimer = null;
|
|
||||||
_cancelRoomRocketEntryReadyFallbacks();
|
_cancelRoomRocketEntryReadyFallbacks();
|
||||||
_cancelRoomRocketPostLaunchStatusRefresh();
|
_cancelRoomRocketPostLaunchStatusRefresh();
|
||||||
}
|
}
|
||||||
@ -3602,6 +3603,45 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
_scheduleRoomRocketAssetPreload(resolvedRoomId, res);
|
_scheduleRoomRocketAssetPreload(resolvedRoomId, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateRoomRocketStatusFromRealtime(
|
||||||
|
SCRoomRocketStatusRes update, {
|
||||||
|
String? roomId,
|
||||||
|
}) {
|
||||||
|
final resolvedRoomId =
|
||||||
|
(roomId ??
|
||||||
|
update.roomId ??
|
||||||
|
currenRoom?.roomProfile?.roomProfile?.id ??
|
||||||
|
"")
|
||||||
|
.trim();
|
||||||
|
if (resolvedRoomId.isEmpty ||
|
||||||
|
resolvedRoomId !=
|
||||||
|
(currenRoom?.roomProfile?.roomProfile?.id ?? "").trim()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!_hasRoomRocketRealtimeStatusFields(update)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final merged =
|
||||||
|
roomRocketStatus?.mergeRealtimeUpdate(update, roomId: resolvedRoomId) ??
|
||||||
|
update;
|
||||||
|
roomRocketStatus = merged;
|
||||||
|
notifyListeners();
|
||||||
|
if (!merged.isEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_scheduleRoomRocketAssetPreload(resolvedRoomId, merged);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _hasRoomRocketRealtimeStatusFields(SCRoomRocketStatusRes update) {
|
||||||
|
return update.currentLevel != null ||
|
||||||
|
update.level != null ||
|
||||||
|
update.currentEnergy != null ||
|
||||||
|
update.maxEnergy != null ||
|
||||||
|
update.displayPercent != null ||
|
||||||
|
update.energyPercent != null ||
|
||||||
|
(update.levels?.isNotEmpty ?? false);
|
||||||
|
}
|
||||||
|
|
||||||
void _scheduleRoomRocketAssetPreload(
|
void _scheduleRoomRocketAssetPreload(
|
||||||
String roomId,
|
String roomId,
|
||||||
SCRoomRocketStatusRes status, {
|
SCRoomRocketStatusRes status, {
|
||||||
@ -3639,11 +3679,25 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
if (resolvedRoomId.isEmpty) {
|
if (resolvedRoomId.isEmpty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_roomRocketGiftRefreshTimer?.cancel();
|
_cancelRoomRocketGiftStatusRefresh();
|
||||||
_roomRocketGiftRefreshTimer = Timer(_roomRocketGiftRefreshDelay, () {
|
for (final delay in _roomRocketGiftRefreshDelays) {
|
||||||
_roomRocketGiftRefreshTimer = null;
|
final timer = Timer(delay, () {
|
||||||
|
_roomRocketGiftRefreshTimers.removeWhere((item) => !item.isActive);
|
||||||
|
if (resolvedRoomId !=
|
||||||
|
(currenRoom?.roomProfile?.roomProfile?.id ?? "").trim()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
unawaited(refreshRoomRocketStatus(roomId: resolvedRoomId));
|
unawaited(refreshRoomRocketStatus(roomId: resolvedRoomId));
|
||||||
});
|
});
|
||||||
|
_roomRocketGiftRefreshTimers.add(timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cancelRoomRocketGiftStatusRefresh() {
|
||||||
|
for (final timer in _roomRocketGiftRefreshTimers) {
|
||||||
|
timer.cancel();
|
||||||
|
}
|
||||||
|
_roomRocketGiftRefreshTimers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _scheduleRoomRocketEntryReadyFallback(String roomId) {
|
void _scheduleRoomRocketEntryReadyFallback(String roomId) {
|
||||||
@ -4464,8 +4518,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
_roomRocketLaunchAnimationTimer = null;
|
_roomRocketLaunchAnimationTimer = null;
|
||||||
SmartDialog.dismiss(tag: _roomRocketPagLaunchDialogTag);
|
SmartDialog.dismiss(tag: _roomRocketPagLaunchDialogTag);
|
||||||
_releaseRoomRocketLaunchTopAvatarNotifier();
|
_releaseRoomRocketLaunchTopAvatarNotifier();
|
||||||
_roomRocketGiftRefreshTimer?.cancel();
|
_cancelRoomRocketGiftStatusRefresh();
|
||||||
_roomRocketGiftRefreshTimer = null;
|
|
||||||
_cancelRoomRocketPostLaunchStatusRefresh();
|
_cancelRoomRocketPostLaunchStatusRefresh();
|
||||||
RoomRocketAssetPreloader.cancelCurrentRoom();
|
RoomRocketAssetPreloader.cancelCurrentRoom();
|
||||||
_stopRoomRedPacketPresenceHeartbeat();
|
_stopRoomRedPacketPresenceHeartbeat();
|
||||||
@ -4528,6 +4581,9 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_stopRoomStatePolling();
|
_stopRoomStatePolling();
|
||||||
|
_cancelRoomRocketGiftStatusRefresh();
|
||||||
|
_cancelRoomRocketPostLaunchStatusRefresh();
|
||||||
|
_cancelRoomRocketEntryReadyFallbacks();
|
||||||
_clearRoomMusicPublishingStates();
|
_clearRoomMusicPublishingStates();
|
||||||
unawaited(releaseRtcEngineForAppTermination());
|
unawaited(releaseRtcEngineForAppTermination());
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|||||||
@ -55,6 +55,7 @@ import 'package:yumi/shared/data_sources/models/message/room_rocket_launch_broad
|
|||||||
import 'package:yumi/shared/data_sources/models/message/sc_floating_message.dart';
|
import 'package:yumi/shared/data_sources/models/message/sc_floating_message.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/sc_broad_cast_luck_gift_push.dart';
|
import 'package:yumi/shared/business_logic/models/res/sc_broad_cast_luck_gift_push.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/sc_room_rocket_api_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/sc_room_rocket_api_res.dart';
|
||||||
|
import 'package:yumi/shared/business_logic/models/res/sc_room_rocket_status_res.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/broad_cast_mic_change_push.dart'
|
import 'package:yumi/shared/business_logic/models/res/broad_cast_mic_change_push.dart'
|
||||||
hide Data;
|
hide Data;
|
||||||
import 'package:yumi/shared/business_logic/models/res/gift_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/gift_res.dart';
|
||||||
@ -934,6 +935,18 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (_cpInviteTargetsCurrentAsSenderAndReceiver(
|
||||||
|
invite,
|
||||||
|
currentProfile,
|
||||||
|
data,
|
||||||
|
)) {
|
||||||
|
_cpInviteLog(
|
||||||
|
'skip CP_BUILD reason=self_recipient applyId=$applyId '
|
||||||
|
'relationType=${invite.relationType}',
|
||||||
|
);
|
||||||
|
await SmartDialog.dismiss(tag: RoomCpInviteDialog.dialogTag);
|
||||||
|
return;
|
||||||
|
}
|
||||||
final isSender = _cpInviteSenderMatchesCurrent(
|
final isSender = _cpInviteSenderMatchesCurrent(
|
||||||
invite,
|
invite,
|
||||||
currentProfile,
|
currentProfile,
|
||||||
@ -1124,6 +1137,17 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
final currentProfile = AccountStorage().getCurrentUser()?.userProfile;
|
final currentProfile = AccountStorage().getCurrentUser()?.userProfile;
|
||||||
if (context != null && invite != null && currentProfile != null) {
|
if (context != null && invite != null && currentProfile != null) {
|
||||||
|
if (_cpInviteTargetsCurrentAsSenderAndReceiver(
|
||||||
|
invite,
|
||||||
|
currentProfile,
|
||||||
|
data,
|
||||||
|
)) {
|
||||||
|
_cpInviteLog(
|
||||||
|
'skip CP invite result reason=self_recipient applyId=$applyId '
|
||||||
|
'result=${result.name}',
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
final isSender = _cpInviteSenderMatchesCurrent(
|
final isSender = _cpInviteSenderMatchesCurrent(
|
||||||
invite,
|
invite,
|
||||||
currentProfile,
|
currentProfile,
|
||||||
@ -1759,6 +1783,33 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
return currentIds.any(inviteIds.contains);
|
return currentIds.any(inviteIds.contains);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _cpInviteTargetsCurrentAsSenderAndReceiver(
|
||||||
|
SCSystemInvitMessageRes invite,
|
||||||
|
SocialChatUserProfile currentProfile,
|
||||||
|
Map<String, dynamic> data,
|
||||||
|
) {
|
||||||
|
final currentIds = _cpInviteProfileIdentityValues(currentProfile);
|
||||||
|
if (currentIds.isEmpty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final inviterIds = <String>{
|
||||||
|
..._cpInviteInviterIdentityValues(data),
|
||||||
|
invite.actualAccount?.trim() ?? "",
|
||||||
|
invite.account?.trim() ?? "",
|
||||||
|
}..remove("");
|
||||||
|
final receiverIds = _cpInviteReceiverIdentityValues(data);
|
||||||
|
return inviterIds.any(currentIds.contains) &&
|
||||||
|
receiverIds.any(currentIds.contains);
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> _cpInviteProfileIdentityValues(SocialChatUserProfile profile) {
|
||||||
|
return <String>{
|
||||||
|
profile.id?.trim() ?? "",
|
||||||
|
profile.account?.trim() ?? "",
|
||||||
|
profile.getID().trim(),
|
||||||
|
}..remove("");
|
||||||
|
}
|
||||||
|
|
||||||
Set<String> _cpInviteInviterIdentityValues(Map<String, dynamic> data) {
|
Set<String> _cpInviteInviterIdentityValues(Map<String, dynamic> data) {
|
||||||
final content = _cpInviteContentMap(data);
|
final content = _cpInviteContentMap(data);
|
||||||
final values = <String?>[
|
final values = <String?>[
|
||||||
@ -3671,7 +3722,11 @@ class RealTimeMessagingManager extends ChangeNotifier {
|
|||||||
_publishRoomRocketRegionBroadcastIfNeeded(launch);
|
_publishRoomRocketRegionBroadcastIfNeeded(launch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unawaited(rtcProvider.refreshRoomRocketStatus(roomId: roomId));
|
rtcProvider.updateRoomRocketStatusFromRealtime(
|
||||||
|
SCRoomRocketStatusRes.fromJson(data),
|
||||||
|
roomId: roomId,
|
||||||
|
);
|
||||||
|
rtcProvider.scheduleRoomRocketStatusRefreshForGift(roomId: roomId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleVoiceRoomRocketLaunchBroadcast(
|
void _handleVoiceRoomRocketLaunchBroadcast(
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import 'package:yumi/shared/business_logic/models/res/room_user_card_res.dart';
|
|||||||
import 'package:yumi/shared/business_logic/models/res/sc_user_identity_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/sc_user_identity_res.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/sc_vip_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/sc_vip_res.dart';
|
||||||
import 'package:yumi/shared/tools/sc_cp_relation_level_utils.dart';
|
import 'package:yumi/shared/tools/sc_cp_relation_level_utils.dart';
|
||||||
|
import 'package:yumi/shared/tools/sc_cp_relation_notice_utils.dart';
|
||||||
|
|
||||||
class SocialChatUserProfileManager extends ChangeNotifier {
|
class SocialChatUserProfileManager extends ChangeNotifier {
|
||||||
static const List<String> _cpProfileRelationTypes = [
|
static const List<String> _cpProfileRelationTypes = [
|
||||||
@ -306,19 +307,7 @@ class SocialChatUserProfileManager extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _normalizeCpRelationType(String? relationType) {
|
String _normalizeCpRelationType(String? relationType) {
|
||||||
final value = relationType?.trim().toUpperCase() ?? "";
|
return scNormalizeCpRelationType(relationType);
|
||||||
switch (value) {
|
|
||||||
case "BROTHER":
|
|
||||||
case "BROTHERS":
|
|
||||||
case "SWORN_BROTHER":
|
|
||||||
case "SWORN_BROTHERS":
|
|
||||||
return "BROTHER";
|
|
||||||
case "SISTER":
|
|
||||||
case "SISTERS":
|
|
||||||
return "SISTERS";
|
|
||||||
default:
|
|
||||||
return "CP";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int? _cpDismissCostFromCabin(SCCpCabinRes? cabin) {
|
int? _cpDismissCostFromCabin(SCCpCabinRes? cabin) {
|
||||||
|
|||||||
@ -1157,7 +1157,19 @@ class CPRes {
|
|||||||
_days = _asString(source['days']);
|
_days = _asString(source['days']);
|
||||||
_firstDay = _asString(source['firstDay']);
|
_firstDay = _asString(source['firstDay']);
|
||||||
_cpValue = _asDouble(source['cpValue']);
|
_cpValue = _asDouble(source['cpValue']);
|
||||||
_relationType = _asString(source['relationType']);
|
_relationType = _asString(
|
||||||
|
_firstValue(source, const [
|
||||||
|
'relationType',
|
||||||
|
'relation_type',
|
||||||
|
'cpRelationType',
|
||||||
|
'cp_relation_type',
|
||||||
|
'relationshipType',
|
||||||
|
'relationship_type',
|
||||||
|
'relation',
|
||||||
|
'cpType',
|
||||||
|
'cp_type',
|
||||||
|
]),
|
||||||
|
);
|
||||||
_status = _asString(source['status']);
|
_status = _asString(source['status']);
|
||||||
_levelText = _asString(
|
_levelText = _asString(
|
||||||
source['levelText'] ??
|
source['levelText'] ??
|
||||||
|
|||||||
@ -104,13 +104,27 @@ class SCRoomRocketStatusRes {
|
|||||||
_date = json['date'] ?? json['dayKey'] ?? json['day_key'];
|
_date = json['date'] ?? json['dayKey'] ?? json['day_key'];
|
||||||
_roundNo = _intValue(json['roundNo'] ?? json['round_no']);
|
_roundNo = _intValue(json['roundNo'] ?? json['round_no']);
|
||||||
_displayRound = _boolValue(json['displayRound'] ?? json['display_round']);
|
_displayRound = _boolValue(json['displayRound'] ?? json['display_round']);
|
||||||
_currentLevel = _intValue(json['currentLevel'] ?? json['current_level']);
|
_currentLevel = _intValue(
|
||||||
|
json['currentLevel'] ??
|
||||||
|
json['current_level'] ??
|
||||||
|
json['toLevel'] ??
|
||||||
|
json['to_level'] ??
|
||||||
|
json['nextLevel'] ??
|
||||||
|
json['next_level'],
|
||||||
|
);
|
||||||
_needEnergy = _intValue(json['needEnergy'] ?? json['need_energy']);
|
_needEnergy = _intValue(json['needEnergy'] ?? json['need_energy']);
|
||||||
_displayPercent = _numValue(
|
_displayPercent = _numValue(
|
||||||
json['displayPercent'] ?? json['display_percent'],
|
json['displayPercent'] ?? json['display_percent'],
|
||||||
);
|
);
|
||||||
_shake = _boolValue(json['shake']);
|
_shake = _boolValue(json['shake']);
|
||||||
_level = json['level'] ?? json['rocket_level'] ?? _currentLevel;
|
_level =
|
||||||
|
json['level'] ??
|
||||||
|
json['rocket_level'] ??
|
||||||
|
json['toLevel'] ??
|
||||||
|
json['to_level'] ??
|
||||||
|
json['nextLevel'] ??
|
||||||
|
json['next_level'] ??
|
||||||
|
_currentLevel;
|
||||||
_levelName = json['levelName'] ?? json['level_name'];
|
_levelName = json['levelName'] ?? json['level_name'];
|
||||||
_currentEnergy = _intValue(json['currentEnergy'] ?? json['current_energy']);
|
_currentEnergy = _intValue(json['currentEnergy'] ?? json['current_energy']);
|
||||||
_maxEnergy =
|
_maxEnergy =
|
||||||
@ -346,6 +360,67 @@ class SCRoomRocketStatusRes {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SCRoomRocketStatusRes mergeRealtimeUpdate(
|
||||||
|
SCRoomRocketStatusRes update, {
|
||||||
|
String? roomId,
|
||||||
|
}) {
|
||||||
|
final updateLevels = update.levels;
|
||||||
|
final updateRewardPreviewByLevel = update.rewardPreviewByLevel;
|
||||||
|
final updateRocketKings = update.rocketKings;
|
||||||
|
final updateRocketKingsByLevel = update.rocketKingsByLevel;
|
||||||
|
return SCRoomRocketStatusRes(
|
||||||
|
roomId: update.roomId ?? roomId ?? _roomId,
|
||||||
|
date: update.date ?? _date,
|
||||||
|
level: update.level ?? _level,
|
||||||
|
levelName: update.levelName ?? _levelName,
|
||||||
|
currentEnergy: update.currentEnergy ?? _currentEnergy,
|
||||||
|
maxEnergy: update.maxEnergy ?? _maxEnergy,
|
||||||
|
energyPercent: update.energyPercent ?? _energyPercent,
|
||||||
|
status: update.status ?? _status,
|
||||||
|
statusDesc: update.statusDesc ?? _statusDesc,
|
||||||
|
totalContributors: update.totalContributors ?? _totalContributors,
|
||||||
|
claimExpireTime: update.claimExpireTime ?? _claimExpireTime,
|
||||||
|
claimCount: update.claimCount ?? _claimCount,
|
||||||
|
canClaim: update.canClaim ?? _canClaim,
|
||||||
|
hasClaimed: update.hasClaimed ?? _hasClaimed,
|
||||||
|
myContribution: update.myContribution ?? _myContribution,
|
||||||
|
myContributionRate: update.myContributionRate ?? _myContributionRate,
|
||||||
|
configured: update.configured ?? _configured,
|
||||||
|
enabled: update.enabled ?? _enabled,
|
||||||
|
roundNo: update.roundNo ?? _roundNo,
|
||||||
|
displayRound: update.displayRound ?? _displayRound,
|
||||||
|
currentLevel:
|
||||||
|
update.currentLevel ?? update.level?.toInt() ?? _currentLevel,
|
||||||
|
needEnergy: update.needEnergy ?? _needEnergy,
|
||||||
|
displayPercent: update.displayPercent ?? _displayPercent,
|
||||||
|
shake: update.shake ?? _shake,
|
||||||
|
levels:
|
||||||
|
updateLevels != null && updateLevels.isNotEmpty
|
||||||
|
? updateLevels
|
||||||
|
: _levels,
|
||||||
|
rewardPreview: update.rewardPreview ?? _rewardPreview,
|
||||||
|
rewardPreviewByLevel:
|
||||||
|
updateRewardPreviewByLevel != null &&
|
||||||
|
updateRewardPreviewByLevel.isNotEmpty
|
||||||
|
? updateRewardPreviewByLevel
|
||||||
|
: _rewardPreviewByLevel,
|
||||||
|
rocketKings:
|
||||||
|
updateRocketKings != null && updateRocketKings.isNotEmpty
|
||||||
|
? updateRocketKings
|
||||||
|
: _rocketKings,
|
||||||
|
rocketKingsByLevel:
|
||||||
|
updateRocketKingsByLevel != null &&
|
||||||
|
updateRocketKingsByLevel.isNotEmpty
|
||||||
|
? updateRocketKingsByLevel
|
||||||
|
: _rocketKingsByLevel,
|
||||||
|
timezone: update.timezone ?? _timezone,
|
||||||
|
resetRemainingSeconds:
|
||||||
|
update.resetRemainingSeconds ?? _resetRemainingSeconds,
|
||||||
|
resetTime: update.resetTime ?? _resetTime,
|
||||||
|
serverTime: update.serverTime ?? _serverTime,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
List<SCRoomRocketKingUserRes> rocketKingsForLevel(int level) {
|
List<SCRoomRocketKingUserRes> rocketKingsForLevel(int level) {
|
||||||
final normalizedLevel = level.clamp(1, 99).toInt();
|
final normalizedLevel = level.clamp(1, 99).toInt();
|
||||||
final byLevel = _rocketKingsByLevel?[normalizedLevel];
|
final byLevel = _rocketKingsByLevel?[normalizedLevel];
|
||||||
|
|||||||
@ -58,20 +58,23 @@ String scCpRelationLevelDisplayText(String? rawText) {
|
|||||||
final text = rawText?.trim() ?? '';
|
final text = rawText?.trim() ?? '';
|
||||||
final level = scCpRelationLevelIndexOrNull(text);
|
final level = scCpRelationLevelIndexOrNull(text);
|
||||||
if (text.isEmpty) {
|
if (text.isEmpty) {
|
||||||
return 'Lv.1 Simple Love';
|
return 'Lv.0';
|
||||||
|
}
|
||||||
|
if (_isSimpleLoveLevelOneText(text, level)) {
|
||||||
|
return 'Lv.1';
|
||||||
}
|
}
|
||||||
final compactLevelPattern = RegExp(
|
final compactLevelPattern = RegExp(
|
||||||
r'^(?:Lv\.?|Level)?\s*\d+$',
|
r'^(?:Lv\.?|Level)?\s*\d+$',
|
||||||
caseSensitive: false,
|
caseSensitive: false,
|
||||||
);
|
);
|
||||||
if (compactLevelPattern.hasMatch(text) && level == 1) {
|
if (compactLevelPattern.hasMatch(text) && level != null) {
|
||||||
return 'Lv.1 Simple Love';
|
return 'Lv.$level';
|
||||||
}
|
}
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
int scCpRelationLevelIndex(String? levelText) {
|
int scCpRelationLevelIndex(String? levelText) {
|
||||||
return scCpRelationLevelIndexOrNull(levelText) ?? 1;
|
return scCpRelationLevelIndexOrNull(levelText) ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int? scCpRelationLevelIndexOrNull(String? levelText) {
|
int? scCpRelationLevelIndexOrNull(String? levelText) {
|
||||||
@ -80,14 +83,14 @@ int? scCpRelationLevelIndexOrNull(String? levelText) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final levelMatch = RegExp(
|
final levelMatch = RegExp(
|
||||||
r'(?:Lv\.?|Level|等级|级)\s*([1-5])|([1-5])\s*(?:级|Level)',
|
r'(?:Lv\.?|Level|等级|级)\s*([0-5])|([0-5])\s*(?:级|Level)',
|
||||||
caseSensitive: false,
|
caseSensitive: false,
|
||||||
).firstMatch(text);
|
).firstMatch(text);
|
||||||
final fallbackMatch = RegExp(r'[1-5]').firstMatch(text);
|
final fallbackMatch = RegExp(r'[0-5]').firstMatch(text);
|
||||||
final rawLevel =
|
final rawLevel =
|
||||||
levelMatch?.group(1) ?? levelMatch?.group(2) ?? fallbackMatch?.group(0);
|
levelMatch?.group(1) ?? levelMatch?.group(2) ?? fallbackMatch?.group(0);
|
||||||
final level = int.tryParse(rawLevel ?? '');
|
final level = int.tryParse(rawLevel ?? '');
|
||||||
return level?.clamp(1, 5).toInt();
|
return level?.clamp(0, 5).toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
_CpRelationLevelSource? _currentLevelFromDynamicConfigs(
|
_CpRelationLevelSource? _currentLevelFromDynamicConfigs(
|
||||||
@ -136,10 +139,13 @@ _CpRelationLevelSource? _currentLevelFromSources(
|
|||||||
|
|
||||||
String? _formattedLevelText({int? level, String? name}) {
|
String? _formattedLevelText({int? level, String? name}) {
|
||||||
final levelName = name?.trim() ?? '';
|
final levelName = name?.trim() ?? '';
|
||||||
|
if (level == 1 && _isSimpleLoveName(levelName)) {
|
||||||
|
return 'Lv.1';
|
||||||
|
}
|
||||||
if (level != null && levelName.isNotEmpty) {
|
if (level != null && levelName.isNotEmpty) {
|
||||||
final nameLevel = scCpRelationLevelIndexOrNull(levelName);
|
final nameLevel = scCpRelationLevelIndexOrNull(levelName);
|
||||||
if (nameLevel == level) {
|
if (nameLevel == level) {
|
||||||
return levelName;
|
return scCpRelationLevelDisplayText(levelName);
|
||||||
}
|
}
|
||||||
return 'Lv.$level $levelName';
|
return 'Lv.$level $levelName';
|
||||||
}
|
}
|
||||||
@ -149,6 +155,23 @@ String? _formattedLevelText({int? level, String? name}) {
|
|||||||
return _blankAsNull(levelName);
|
return _blankAsNull(levelName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _isSimpleLoveLevelOneText(String text, int? level) {
|
||||||
|
if (level != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return RegExp(
|
||||||
|
r'^(?:Lv\.?|Level)?\s*1\s+Simple\s+Love$',
|
||||||
|
caseSensitive: false,
|
||||||
|
).hasMatch(text.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isSimpleLoveName(String text) {
|
||||||
|
return RegExp(
|
||||||
|
r'^(?:Lv\.?|Level)?\s*1?\s*Simple\s+Love$',
|
||||||
|
caseSensitive: false,
|
||||||
|
).hasMatch(text.trim());
|
||||||
|
}
|
||||||
|
|
||||||
String? _blankAsNull(String? value) {
|
String? _blankAsNull(String? value) {
|
||||||
final text = value?.trim() ?? '';
|
final text = value?.trim() ?? '';
|
||||||
return text.isEmpty ? null : text;
|
return text.isEmpty ? null : text;
|
||||||
|
|||||||
@ -99,5 +99,5 @@ String scBuildCpRelationEntryBroadcastText({
|
|||||||
required String? relationType,
|
required String? relationType,
|
||||||
}) {
|
}) {
|
||||||
return "$ownerName's ${scCpRelationEntryLabel(relationType)} "
|
return "$ownerName's ${scCpRelationEntryLabel(relationType)} "
|
||||||
"$joinedName enter the room";
|
"$joinedName has joined the party";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import 'dart:math' as math;
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
|
import 'package:yumi/shared/tools/sc_cp_relation_level_utils.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';
|
||||||
|
|
||||||
@ -31,11 +32,11 @@ class RoomCpProgressDialog extends StatelessWidget {
|
|||||||
required this.rightUser,
|
required this.rightUser,
|
||||||
this.daysValue = '999',
|
this.daysValue = '999',
|
||||||
this.daysLabel = 'Days',
|
this.daysLabel = 'Days',
|
||||||
this.levelText = 'Lv.1 Simple Love',
|
this.levelText = 'Lv.0',
|
||||||
this.currentValue = 0,
|
this.currentValue = 0,
|
||||||
this.targetValue = 1,
|
this.targetValue = 1,
|
||||||
this.expAwayText = '0',
|
this.expAwayText = '0',
|
||||||
this.nextLevelText = 'Lv. 2',
|
this.nextLevelText = 'Lv. 1',
|
||||||
this.cancelText = 'Cancel',
|
this.cancelText = 'Cancel',
|
||||||
this.dismissTag = dialogTag,
|
this.dismissTag = dialogTag,
|
||||||
this.onCancel,
|
this.onCancel,
|
||||||
@ -62,11 +63,11 @@ class RoomCpProgressDialog extends StatelessWidget {
|
|||||||
required RoomCpProgressDialogUser rightUser,
|
required RoomCpProgressDialogUser rightUser,
|
||||||
String daysValue = '999',
|
String daysValue = '999',
|
||||||
String daysLabel = 'Days',
|
String daysLabel = 'Days',
|
||||||
String levelText = 'Lv.1 Simple Love',
|
String levelText = 'Lv.0',
|
||||||
double currentValue = 0,
|
double currentValue = 0,
|
||||||
double targetValue = 1,
|
double targetValue = 1,
|
||||||
String expAwayText = '0',
|
String expAwayText = '0',
|
||||||
String nextLevelText = 'Lv. 2',
|
String nextLevelText = 'Lv. 1',
|
||||||
String cancelText = 'Cancel',
|
String cancelText = 'Cancel',
|
||||||
String dismissTag = dialogTag,
|
String dismissTag = dialogTag,
|
||||||
VoidCallback? onCancel,
|
VoidCallback? onCancel,
|
||||||
@ -164,6 +165,7 @@ class RoomCpProgressDialog extends StatelessWidget {
|
|||||||
right: 0,
|
right: 0,
|
||||||
top: 180.w,
|
top: 180.w,
|
||||||
child: _ExpAwayText(
|
child: _ExpAwayText(
|
||||||
|
levelText: levelText,
|
||||||
expAwayText: expAwayText,
|
expAwayText: expAwayText,
|
||||||
nextLevelText: nextLevelText,
|
nextLevelText: nextLevelText,
|
||||||
),
|
),
|
||||||
@ -203,7 +205,9 @@ class _DaysBadge extends StatelessWidget {
|
|||||||
final value = daysValue.trim().isEmpty ? '--' : daysValue.trim();
|
final value = daysValue.trim().isEmpty ? '--' : daysValue.trim();
|
||||||
final label = daysLabel.trim().isEmpty ? 'Days' : daysLabel.trim();
|
final label = daysLabel.trim().isEmpty ? 'Days' : daysLabel.trim();
|
||||||
final level =
|
final level =
|
||||||
levelText.trim().isEmpty ? 'Lv.1 Simple Love' : levelText.trim();
|
levelText.trim().isEmpty
|
||||||
|
? 'Lv.0'
|
||||||
|
: scCpRelationLevelDisplayText(levelText);
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: 114.w,
|
width: 114.w,
|
||||||
@ -407,16 +411,39 @@ class _ProgressBar extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ExpAwayText extends StatelessWidget {
|
class _ExpAwayText extends StatelessWidget {
|
||||||
const _ExpAwayText({required this.expAwayText, required this.nextLevelText});
|
const _ExpAwayText({
|
||||||
|
required this.levelText,
|
||||||
|
required this.expAwayText,
|
||||||
|
required this.nextLevelText,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String levelText;
|
||||||
final String expAwayText;
|
final String expAwayText;
|
||||||
final String nextLevelText;
|
final String nextLevelText;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
if (scCpRelationLevelIndex(levelText) >= 5) {
|
||||||
|
return Text(
|
||||||
|
'Maximum level reached.',
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
color: const Color(0xff67576F),
|
||||||
|
fontSize: 10.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
height: 1,
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
final exp = expAwayText.trim().isEmpty ? '0' : expAwayText.trim();
|
final exp = expAwayText.trim().isEmpty ? '0' : expAwayText.trim();
|
||||||
final nextLevel =
|
final nextLevel =
|
||||||
nextLevelText.trim().isEmpty ? 'Lv. 2' : nextLevelText.trim();
|
nextLevelText.trim().isEmpty
|
||||||
|
? 'Lv. 1'
|
||||||
|
: scCpRelationLevelDisplayText(nextLevelText);
|
||||||
|
|
||||||
return Text.rich(
|
return Text.rich(
|
||||||
TextSpan(
|
TextSpan(
|
||||||
|
|||||||
@ -6,25 +6,22 @@ class SCCpCornerLabel extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ShaderMask(
|
return Text(
|
||||||
blendMode: BlendMode.srcIn,
|
|
||||||
shaderCallback: (bounds) {
|
|
||||||
return const LinearGradient(
|
|
||||||
begin: Alignment.topCenter,
|
|
||||||
end: Alignment.bottomCenter,
|
|
||||||
colors: [Color(0xffFF91A4), Color(0xffFF3164)],
|
|
||||||
).createShader(bounds);
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
"CP",
|
"CP",
|
||||||
textScaler: TextScaler.noScaling,
|
textScaler: TextScaler.noScaling,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
foreground:
|
||||||
|
Paint()
|
||||||
|
..shader = const LinearGradient(
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
colors: [Color(0xffFF91A4), Color(0xffFF3164)],
|
||||||
|
).createShader(Rect.fromLTWH(0, 0, 20.w, 10.w)),
|
||||||
fontSize: 10.sp,
|
fontSize: 10.sp,
|
||||||
height: 1,
|
height: 1,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
decoration: TextDecoration.none,
|
decoration: TextDecoration.none,
|
||||||
),
|
shadows: const <Shadow>[],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,7 @@ class RoomPlayWidget extends StatefulWidget {
|
|||||||
|
|
||||||
class _RoomPlayWidgetState extends State<RoomPlayWidget> {
|
class _RoomPlayWidgetState extends State<RoomPlayWidget> {
|
||||||
static const double _railEnd = 8;
|
static const double _railEnd = 8;
|
||||||
static const double _railBottom = 15;
|
static const double _railBottom = 30;
|
||||||
static const double _railWidth = 58;
|
static const double _railWidth = 58;
|
||||||
static const double _railVerticalPadding = 8;
|
static const double _railVerticalPadding = 8;
|
||||||
static const double _actionExtent = 56;
|
static const double _actionExtent = 56;
|
||||||
@ -69,6 +69,7 @@ class _RoomPlayWidgetState extends State<RoomPlayWidget> {
|
|||||||
final fullHeight = _railHeight(
|
final fullHeight = _railHeight(
|
||||||
actionCount: actions.length,
|
actionCount: actions.length,
|
||||||
showToggle: false,
|
showToggle: false,
|
||||||
|
showBackground: false,
|
||||||
);
|
);
|
||||||
final availableHeight =
|
final availableHeight =
|
||||||
(constraints.maxHeight - _railBottom.w)
|
(constraints.maxHeight - _railBottom.w)
|
||||||
@ -78,17 +79,20 @@ class _RoomPlayWidgetState extends State<RoomPlayWidget> {
|
|||||||
actions.length > _compactActionCount &&
|
actions.length > _compactActionCount &&
|
||||||
availableHeight < fullHeight;
|
availableHeight < fullHeight;
|
||||||
final isExpanded = !shouldFold || _rightActionsExpanded;
|
final isExpanded = !shouldFold || _rightActionsExpanded;
|
||||||
|
final isCollapsed = shouldFold && !isExpanded;
|
||||||
final visibleActions =
|
final visibleActions =
|
||||||
isExpanded ? actions : actions.take(_compactActionCount).toList();
|
isExpanded ? actions : actions.take(_compactActionCount).toList();
|
||||||
final railHeight = _railHeight(
|
final railHeight = _railHeight(
|
||||||
actionCount: visibleActions.length,
|
actionCount: visibleActions.length,
|
||||||
showToggle: shouldFold,
|
showToggle: shouldFold,
|
||||||
|
showBackground: isCollapsed,
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget rail = _RoomSideActionRail(
|
Widget rail = _RoomSideActionRail(
|
||||||
actions: visibleActions,
|
actions: visibleActions,
|
||||||
showToggle: shouldFold,
|
showToggle: shouldFold,
|
||||||
expanded: isExpanded,
|
expanded: isExpanded,
|
||||||
|
showBackground: isCollapsed,
|
||||||
onToggle: () {
|
onToggle: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_rightActionsExpanded = !_rightActionsExpanded;
|
_rightActionsExpanded = !_rightActionsExpanded;
|
||||||
@ -144,11 +148,16 @@ class _RoomPlayWidgetState extends State<RoomPlayWidget> {
|
|||||||
false;
|
false;
|
||||||
}
|
}
|
||||||
|
|
||||||
double _railHeight({required int actionCount, required bool showToggle}) {
|
double _railHeight({
|
||||||
|
required int actionCount,
|
||||||
|
required bool showToggle,
|
||||||
|
required bool showBackground,
|
||||||
|
}) {
|
||||||
final actionGaps = actionCount > 1 ? actionCount - 1 : 0;
|
final actionGaps = actionCount > 1 ? actionCount - 1 : 0;
|
||||||
final toggleHeight =
|
final toggleHeight =
|
||||||
showToggle ? _toggleExtent + (actionCount > 0 ? _actionGap : 0) : 0.0;
|
showToggle ? _toggleExtent + (actionCount > 0 ? _actionGap : 0) : 0.0;
|
||||||
return (_railVerticalPadding * 2 +
|
final verticalPadding = showBackground ? _railVerticalPadding * 2 : 0.0;
|
||||||
|
return (verticalPadding +
|
||||||
toggleHeight +
|
toggleHeight +
|
||||||
actionCount * _actionExtent +
|
actionCount * _actionExtent +
|
||||||
actionGaps * _actionGap)
|
actionGaps * _actionGap)
|
||||||
@ -180,6 +189,7 @@ class _RoomSideActionRail extends StatelessWidget {
|
|||||||
required this.actions,
|
required this.actions,
|
||||||
required this.showToggle,
|
required this.showToggle,
|
||||||
required this.expanded,
|
required this.expanded,
|
||||||
|
required this.showBackground,
|
||||||
required this.onToggle,
|
required this.onToggle,
|
||||||
required this.actionBuilder,
|
required this.actionBuilder,
|
||||||
});
|
});
|
||||||
@ -187,6 +197,7 @@ class _RoomSideActionRail extends StatelessWidget {
|
|||||||
final List<_RoomSideAction> actions;
|
final List<_RoomSideAction> actions;
|
||||||
final bool showToggle;
|
final bool showToggle;
|
||||||
final bool expanded;
|
final bool expanded;
|
||||||
|
final bool showBackground;
|
||||||
final VoidCallback onToggle;
|
final VoidCallback onToggle;
|
||||||
final Widget Function(_RoomSideAction action) actionBuilder;
|
final Widget Function(_RoomSideAction action) actionBuilder;
|
||||||
|
|
||||||
@ -223,12 +234,16 @@ class _RoomSideActionRail extends StatelessWidget {
|
|||||||
width: _RoomPlayWidgetState._railWidth.w,
|
width: _RoomPlayWidgetState._railWidth.w,
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: 6.w,
|
horizontal: 6.w,
|
||||||
vertical: _RoomPlayWidgetState._railVerticalPadding.w,
|
vertical:
|
||||||
|
showBackground ? _RoomPlayWidgetState._railVerticalPadding.w : 0,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration:
|
||||||
|
showBackground
|
||||||
|
? BoxDecoration(
|
||||||
color: Colors.black.withValues(alpha: 0.21),
|
color: Colors.black.withValues(alpha: 0.21),
|
||||||
borderRadius: BorderRadius.circular(8.w),
|
borderRadius: BorderRadius.circular(8.w),
|
||||||
),
|
)
|
||||||
|
: null,
|
||||||
child: Column(mainAxisSize: MainAxisSize.min, children: children),
|
child: Column(mainAxisSize: MainAxisSize.min, children: children),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -760,9 +760,7 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
levelText:
|
levelText:
|
||||||
cp == null
|
cp == null
|
||||||
? ""
|
? ""
|
||||||
: _cpLevelDisplayText(
|
: _cpLevelDisplayText(_firstNonBlank([cp.levelText, "Lv.0"])),
|
||||||
_firstNonBlank([cp.levelText, "Lv.1 Simple Love"]),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -835,7 +833,12 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _cpLevelAsset(String levelText) {
|
String _cpLevelAsset(String levelText) {
|
||||||
return "$_cpProfileAssetBase/sc_cp_profile_cp_level_${_cpLevelIndex(levelText)}.png";
|
return "$_cpProfileAssetBase/sc_cp_profile_cp_level_${_cpLevelAssetIndex(levelText)}.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
int _cpLevelAssetIndex(String levelText) {
|
||||||
|
final level = _cpLevelIndex(levelText);
|
||||||
|
return level <= 0 ? 1 : level;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _cpLevelIndex(String levelText) {
|
int _cpLevelIndex(String levelText) {
|
||||||
@ -910,19 +913,7 @@ class _RoomUserInfoCardState extends State<RoomUserInfoCard> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _normalizeCpRelationType(String? relationType) {
|
String _normalizeCpRelationType(String? relationType) {
|
||||||
final value = relationType?.trim().toUpperCase() ?? "";
|
return scNormalizeCpRelationType(relationType);
|
||||||
switch (value) {
|
|
||||||
case "BROTHER":
|
|
||||||
case "BROTHERS":
|
|
||||||
case "SWORN_BROTHER":
|
|
||||||
case "SWORN_BROTHERS":
|
|
||||||
return "BROTHER";
|
|
||||||
case "SISTER":
|
|
||||||
case "SISTERS":
|
|
||||||
return "SISTERS";
|
|
||||||
default:
|
|
||||||
return "CP";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String _avatarFallback(String? avatarUrl) {
|
String _avatarFallback(String? avatarUrl) {
|
||||||
@ -1818,8 +1809,7 @@ class _RoomCpProgressData {
|
|||||||
factory _RoomCpProgressData.fallback(_RoomProfileCpData cp) {
|
factory _RoomCpProgressData.fallback(_RoomProfileCpData cp) {
|
||||||
final currentValue = cp.cpValue;
|
final currentValue = cp.cpValue;
|
||||||
return _RoomCpProgressData(
|
return _RoomCpProgressData(
|
||||||
levelText:
|
levelText: scCpRelationLevelDisplayText(cp.levelText),
|
||||||
cp.levelText.trim().isEmpty ? "Lv.1 Simple Love" : cp.levelText,
|
|
||||||
currentValue: currentValue,
|
currentValue: currentValue,
|
||||||
targetValue: currentValue > 0 ? currentValue : 1,
|
targetValue: currentValue > 0 ? currentValue : 1,
|
||||||
expAwayText: SCStringUtils.formatCompactNumber(0),
|
expAwayText: SCStringUtils.formatCompactNumber(0),
|
||||||
@ -1932,16 +1922,19 @@ class _RoomCpProgressData {
|
|||||||
static String _levelDisplayText(_CpProgressLevel? level, String fallback) {
|
static String _levelDisplayText(_CpProgressLevel? level, String fallback) {
|
||||||
final fallbackText = fallback.trim();
|
final fallbackText = fallback.trim();
|
||||||
if (level == null) {
|
if (level == null) {
|
||||||
return fallbackText.isEmpty ? "Lv.1 Simple Love" : fallbackText;
|
return scCpRelationLevelDisplayText(fallbackText);
|
||||||
}
|
}
|
||||||
final levelName = level.levelName?.trim();
|
final levelName = level.levelName?.trim();
|
||||||
|
if (level.level != null && levelName != null && levelName.isNotEmpty) {
|
||||||
|
return scCpRelationLevelDisplayText("Lv.${level.level} $levelName");
|
||||||
|
}
|
||||||
if (levelName != null && levelName.isNotEmpty) {
|
if (levelName != null && levelName.isNotEmpty) {
|
||||||
return levelName;
|
return scCpRelationLevelDisplayText(levelName);
|
||||||
}
|
}
|
||||||
if (level.level != null) {
|
if (level.level != null) {
|
||||||
return "Lv.${level.level}";
|
return "Lv.${level.level}";
|
||||||
}
|
}
|
||||||
return fallbackText.isEmpty ? "Lv.1 Simple Love" : fallbackText;
|
return scCpRelationLevelDisplayText(fallbackText);
|
||||||
}
|
}
|
||||||
|
|
||||||
static String _levelShortText(int? level, {String? fallback}) {
|
static String _levelShortText(int? level, {String? fallback}) {
|
||||||
@ -1950,9 +1943,9 @@ class _RoomCpProgressData {
|
|||||||
}
|
}
|
||||||
final fallbackText = fallback?.trim() ?? "";
|
final fallbackText = fallback?.trim() ?? "";
|
||||||
if (fallbackText.isNotEmpty) {
|
if (fallbackText.isNotEmpty) {
|
||||||
return fallbackText;
|
return scCpRelationLevelDisplayText(fallbackText);
|
||||||
}
|
}
|
||||||
return "Lv. 1";
|
return "Lv. 0";
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _levelIndex(String levelText) {
|
static int _levelIndex(String levelText) {
|
||||||
@ -1960,7 +1953,7 @@ class _RoomCpProgressData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int _nextLevelIndex(int level) {
|
static int _nextLevelIndex(int level) {
|
||||||
return (level + 1).clamp(1, 5).toInt();
|
return (level + 1).clamp(0, 5).toInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -165,7 +165,7 @@ class _RoomMicRelationEffectState extends State<RoomMicRelationEffect> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<_RoomMicRelationAsset> _cpAssetsForLevel(int? cpLevel) {
|
List<_RoomMicRelationAsset> _cpAssetsForLevel(int? cpLevel) {
|
||||||
final level = (cpLevel ?? 1).clamp(1, 5).toInt();
|
final level = (cpLevel ?? 0).clamp(0, 5).toInt();
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case 2:
|
case 2:
|
||||||
return const [
|
return const [
|
||||||
|
|||||||
@ -715,16 +715,6 @@ Widget _buildBagCardSkeleton(double progress, {required bool showTitle}) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
PositionedDirectional(
|
|
||||||
bottom: 0,
|
|
||||||
end: 0,
|
|
||||||
child: _buildStoreBagSkeletonBone(
|
|
||||||
progress,
|
|
||||||
width: 18.w,
|
|
||||||
height: 18.w,
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Column(
|
Column(
|
||||||
mainAxisSize: showTitle ? MainAxisSize.max : MainAxisSize.min,
|
mainAxisSize: showTitle ? MainAxisSize.max : MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
package io.flutter.plugins;
|
||||||
|
|
||||||
|
import androidx.annotation.Keep;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import io.flutter.Log;
|
||||||
|
|
||||||
|
import io.flutter.embedding.engine.FlutterEngine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generated file. Do not edit.
|
||||||
|
* This file is generated by the Flutter tool based on the
|
||||||
|
* plugins that support the Android platform.
|
||||||
|
*/
|
||||||
|
@Keep
|
||||||
|
public final class GeneratedPluginRegistrant {
|
||||||
|
private static final String TAG = "GeneratedPluginRegistrant";
|
||||||
|
public static void registerWith(@NonNull FlutterEngine flutterEngine) {
|
||||||
|
try {
|
||||||
|
flutterEngine.getPlugins().add(new com.example.flutter_pag_plugin.FlutterPagPlugin());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error registering plugin pag, com.example.flutter_pag_plugin.FlutterPagPlugin", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
sdk.dir=/Users/nigger/Library/Android/sdk
|
||||||
|
flutter.sdk=/Users/nigger/Desktop/develop/flutter
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
// This is a generated file; do not edit or check into version control.
|
||||||
|
FLUTTER_ROOT=/Users/nigger/Desktop/develop/flutter
|
||||||
|
FLUTTER_APPLICATION_PATH=/Users/nigger/Documents/GitHub/chatapp3-flutter/local_packages/pag-1.0.7-patched/example
|
||||||
|
COCOAPODS_PARALLEL_CODE_SIGN=true
|
||||||
|
FLUTTER_TARGET=lib/main.dart
|
||||||
|
FLUTTER_BUILD_DIR=build
|
||||||
|
FLUTTER_BUILD_NAME=1.0.0
|
||||||
|
FLUTTER_BUILD_NUMBER=1
|
||||||
|
EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386
|
||||||
|
EXCLUDED_ARCHS[sdk=iphoneos*]=armv7
|
||||||
|
DART_OBFUSCATION=false
|
||||||
|
TRACK_WIDGET_CREATION=true
|
||||||
|
TREE_SHAKE_ICONS=false
|
||||||
|
PACKAGE_CONFIG=.dart_tool/package_config.json
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
#
|
||||||
|
# Generated file, do not edit.
|
||||||
|
#
|
||||||
|
|
||||||
|
import lldb
|
||||||
|
|
||||||
|
def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict):
|
||||||
|
"""Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages."""
|
||||||
|
base = frame.register["x0"].GetValueAsAddress()
|
||||||
|
page_len = frame.register["x1"].GetValueAsUnsigned()
|
||||||
|
|
||||||
|
# Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the
|
||||||
|
# first page to see if handled it correctly. This makes diagnosing
|
||||||
|
# misconfiguration (e.g. missing breakpoint) easier.
|
||||||
|
data = bytearray(page_len)
|
||||||
|
data[0:8] = b'IHELPED!'
|
||||||
|
|
||||||
|
error = lldb.SBError()
|
||||||
|
frame.GetThread().GetProcess().WriteMemory(base, data, error)
|
||||||
|
if not error.Success():
|
||||||
|
print(f'Failed to write into {base}[+{page_len}]', error)
|
||||||
|
return
|
||||||
|
|
||||||
|
def __lldb_init_module(debugger: lldb.SBDebugger, _):
|
||||||
|
target = debugger.GetDummyTarget()
|
||||||
|
# Caveat: must use BreakpointCreateByRegEx here and not
|
||||||
|
# BreakpointCreateByName. For some reasons callback function does not
|
||||||
|
# get carried over from dummy target for the later.
|
||||||
|
bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$")
|
||||||
|
bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__))
|
||||||
|
bp.SetAutoContinue(True)
|
||||||
|
print("-- LLDB integration loaded --")
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
#
|
||||||
|
# Generated file, do not edit.
|
||||||
|
#
|
||||||
|
|
||||||
|
command script import --relative-to-command-file flutter_lldb_helper.py
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# This is a generated file; do not edit or check into version control.
|
||||||
|
export "FLUTTER_ROOT=/Users/nigger/Desktop/develop/flutter"
|
||||||
|
export "FLUTTER_APPLICATION_PATH=/Users/nigger/Documents/GitHub/chatapp3-flutter/local_packages/pag-1.0.7-patched/example"
|
||||||
|
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
|
||||||
|
export "FLUTTER_TARGET=lib/main.dart"
|
||||||
|
export "FLUTTER_BUILD_DIR=build"
|
||||||
|
export "FLUTTER_BUILD_NAME=1.0.0"
|
||||||
|
export "FLUTTER_BUILD_NUMBER=1"
|
||||||
|
export "DART_OBFUSCATION=false"
|
||||||
|
export "TRACK_WIDGET_CREATION=true"
|
||||||
|
export "TREE_SHAKE_ICONS=false"
|
||||||
|
export "PACKAGE_CONFIG=.dart_tool/package_config.json"
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#ifndef GeneratedPluginRegistrant_h
|
||||||
|
#define GeneratedPluginRegistrant_h
|
||||||
|
|
||||||
|
#import <Flutter/Flutter.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GeneratedPluginRegistrant : NSObject
|
||||||
|
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry;
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
#endif /* GeneratedPluginRegistrant_h */
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#import "GeneratedPluginRegistrant.h"
|
||||||
|
|
||||||
|
#if __has_include(<pag/FlutterPagPlugin.h>)
|
||||||
|
#import <pag/FlutterPagPlugin.h>
|
||||||
|
#else
|
||||||
|
@import pag;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@implementation GeneratedPluginRegistrant
|
||||||
|
|
||||||
|
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
|
||||||
|
[FlutterPagPlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterPagPlugin"]];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
204
local_packages/pag-1.0.7-patched/example/pubspec.lock
Normal file
204
local_packages/pag-1.0.7-patched/example/pubspec.lock
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
# Generated by pub
|
||||||
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
|
packages:
|
||||||
|
async:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: async
|
||||||
|
sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.13.1"
|
||||||
|
boolean_selector:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: boolean_selector
|
||||||
|
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.2"
|
||||||
|
characters:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: characters
|
||||||
|
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.1"
|
||||||
|
clock:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: clock
|
||||||
|
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
collection:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: collection
|
||||||
|
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.19.1"
|
||||||
|
cupertino_icons:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: cupertino_icons
|
||||||
|
sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.9"
|
||||||
|
fake_async:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fake_async
|
||||||
|
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.3"
|
||||||
|
flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
flutter_test:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
leak_tracker:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker
|
||||||
|
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "11.0.2"
|
||||||
|
leak_tracker_flutter_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_flutter_testing
|
||||||
|
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.10"
|
||||||
|
leak_tracker_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_testing
|
||||||
|
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
|
matcher:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: matcher
|
||||||
|
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.12.19"
|
||||||
|
material_color_utilities:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: material_color_utilities
|
||||||
|
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.13.0"
|
||||||
|
meta:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: meta
|
||||||
|
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.17.0"
|
||||||
|
pag:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: ".."
|
||||||
|
relative: true
|
||||||
|
source: path
|
||||||
|
version: "1.0.7"
|
||||||
|
path:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path
|
||||||
|
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.9.1"
|
||||||
|
sky_engine:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
source_span:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_span
|
||||||
|
sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.10.2"
|
||||||
|
stack_trace:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stack_trace
|
||||||
|
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.12.1"
|
||||||
|
stream_channel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stream_channel
|
||||||
|
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.4"
|
||||||
|
string_scanner:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: string_scanner
|
||||||
|
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.1"
|
||||||
|
term_glyph:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: term_glyph
|
||||||
|
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.2"
|
||||||
|
test_api:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: test_api
|
||||||
|
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.10"
|
||||||
|
vector_math:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vector_math
|
||||||
|
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
|
vm_service:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vm_service
|
||||||
|
sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "15.2.0"
|
||||||
|
sdks:
|
||||||
|
dart: ">=3.9.0 <4.0.0"
|
||||||
|
flutter: ">=3.18.0-18.0.pre.54"
|
||||||
189
local_packages/pag-1.0.7-patched/pubspec.lock
Normal file
189
local_packages/pag-1.0.7-patched/pubspec.lock
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
# Generated by pub
|
||||||
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
|
packages:
|
||||||
|
async:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: async
|
||||||
|
sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.13.1"
|
||||||
|
boolean_selector:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: boolean_selector
|
||||||
|
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.2"
|
||||||
|
characters:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: characters
|
||||||
|
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.1"
|
||||||
|
clock:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: clock
|
||||||
|
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
collection:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: collection
|
||||||
|
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.19.1"
|
||||||
|
fake_async:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fake_async
|
||||||
|
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.3"
|
||||||
|
flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
flutter_test:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
leak_tracker:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker
|
||||||
|
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "11.0.2"
|
||||||
|
leak_tracker_flutter_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_flutter_testing
|
||||||
|
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.10"
|
||||||
|
leak_tracker_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_testing
|
||||||
|
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
|
matcher:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: matcher
|
||||||
|
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.12.19"
|
||||||
|
material_color_utilities:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: material_color_utilities
|
||||||
|
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.13.0"
|
||||||
|
meta:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: meta
|
||||||
|
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.17.0"
|
||||||
|
path:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path
|
||||||
|
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.9.1"
|
||||||
|
sky_engine:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
source_span:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_span
|
||||||
|
sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.10.2"
|
||||||
|
stack_trace:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stack_trace
|
||||||
|
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.12.1"
|
||||||
|
stream_channel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stream_channel
|
||||||
|
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.4"
|
||||||
|
string_scanner:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: string_scanner
|
||||||
|
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.1"
|
||||||
|
term_glyph:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: term_glyph
|
||||||
|
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.2"
|
||||||
|
test_api:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: test_api
|
||||||
|
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.10"
|
||||||
|
vector_math:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vector_math
|
||||||
|
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.0"
|
||||||
|
vm_service:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vm_service
|
||||||
|
sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "15.2.0"
|
||||||
|
sdks:
|
||||||
|
dart: ">=3.9.0-0 <4.0.0"
|
||||||
|
flutter: ">=3.18.0-18.0.pre.54"
|
||||||
@ -40,6 +40,17 @@ void main() {
|
|||||||
expect(scCpRelationDisplayDays('12'), '13');
|
expect(scCpRelationDisplayDays('12'), '13');
|
||||||
expect(scCpRelationDisplayDays(''), '1');
|
expect(scCpRelationDisplayDays(''), '1');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('relation entry notice uses party copy', () {
|
||||||
|
expect(
|
||||||
|
scBuildCpRelationEntryBroadcastText(
|
||||||
|
ownerName: 'A',
|
||||||
|
joinedName: 'B',
|
||||||
|
relationType: 'CP',
|
||||||
|
),
|
||||||
|
"A's cp B has joined the party",
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('scCpRelationTypeForGift', () {
|
group('scCpRelationTypeForGift', () {
|
||||||
|
|||||||
@ -195,6 +195,52 @@ void main() {
|
|||||||
expect(levels?.last.progressImageUrl, 'progress-2');
|
expect(levels?.last.progressImageUrl, 'progress-2');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('parses realtime level advancement payloads', () {
|
||||||
|
final status = SCRoomRocketStatusRes.fromJson({
|
||||||
|
'room_id': 'room-1',
|
||||||
|
'from_level': 1,
|
||||||
|
'to_level': 2,
|
||||||
|
'display_percent': 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(status.currentLevel, 2);
|
||||||
|
expect(status.level, 2);
|
||||||
|
expect(status.displayPercent, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('merges realtime rocket status without dropping level assets', () {
|
||||||
|
final current = SCRoomRocketStatusRes.fromJson({
|
||||||
|
'room_id': 'room-1',
|
||||||
|
'current_level': 1,
|
||||||
|
'display_percent': 98,
|
||||||
|
'levels': [
|
||||||
|
{
|
||||||
|
'level': 1,
|
||||||
|
'rocket_icon_url': 'icon-1',
|
||||||
|
'progress_bar_url': 'progress-1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'level': 2,
|
||||||
|
'rocket_icon_url': 'icon-2',
|
||||||
|
'progress_bar_url': 'progress-2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
final realtimeUpdate = SCRoomRocketStatusRes.fromJson({
|
||||||
|
'room_id': 'room-1',
|
||||||
|
'to_level': 2,
|
||||||
|
'display_percent': 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
final merged = current.mergeRealtimeUpdate(realtimeUpdate);
|
||||||
|
final levels = RoomRocketApiMapper.levelsFromStatus(merged);
|
||||||
|
|
||||||
|
expect(merged.currentLevel, 2);
|
||||||
|
expect(merged.displayPercent, 0);
|
||||||
|
expect(levels?.last.imageUrl, 'icon-2');
|
||||||
|
expect(levels?.last.progressImageUrl, 'progress-2');
|
||||||
|
});
|
||||||
|
|
||||||
test('parses disabled rocket status from go api', () {
|
test('parses disabled rocket status from go api', () {
|
||||||
final status = SCRoomRocketStatusRes.fromJson({
|
final status = SCRoomRocketStatusRes.fromJson({
|
||||||
'configured': true,
|
'configured': true,
|
||||||
|
|||||||
@ -53,6 +53,22 @@ void main() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('detects close-friend relation aliases parsed from payload', () {
|
||||||
|
final left = SocialChatUserProfile(id: '300');
|
||||||
|
final right = SocialChatUserProfile(
|
||||||
|
id: '400',
|
||||||
|
closeFriendList: [
|
||||||
|
CPRes.fromJson({
|
||||||
|
'meUserId': '300',
|
||||||
|
'cpUserId': '400',
|
||||||
|
'cpRelationType': 'sis',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(scCpRelationTypeBetweenProfiles(left, right), 'SISTERS');
|
||||||
|
});
|
||||||
|
|
||||||
test('does not match unrelated profiles', () {
|
test('does not match unrelated profiles', () {
|
||||||
final left = SocialChatUserProfile(
|
final left = SocialChatUserProfile(
|
||||||
id: '100',
|
id: '100',
|
||||||
@ -78,5 +94,34 @@ void main() {
|
|||||||
|
|
||||||
expect(scCpRelationLevelTextFromCabin(cabin), 'Lv.2 Sweet Love');
|
expect(scCpRelationLevelTextFromCabin(cabin), 'Lv.2 Sweet Love');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'supports zero based CP levels and hides hardcoded simple love copy',
|
||||||
|
() {
|
||||||
|
expect(scCpRelationLevelIndex('Lv.0'), 0);
|
||||||
|
expect(scCpRelationLevelDisplayText(null), 'Lv.0');
|
||||||
|
expect(scCpRelationLevelDisplayText('Lv.1 Simple Love'), 'Lv.1');
|
||||||
|
|
||||||
|
final cabin = SCCpCabinRes(
|
||||||
|
cpVal: 0,
|
||||||
|
cpCabinConfigCO: const [
|
||||||
|
{'level': 0, 'levelName': 'Start', 'requiredCpValue': 0},
|
||||||
|
{'level': 1, 'levelName': 'Simple Love', 'requiredCpValue': 100},
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(scCpRelationLevelTextFromCabin(cabin), 'Lv.0 Start');
|
||||||
|
|
||||||
|
final levelOneCabin = SCCpCabinRes(
|
||||||
|
cpVal: 100,
|
||||||
|
cpCabinConfigCO: const [
|
||||||
|
{'level': 0, 'levelName': 'Start', 'requiredCpValue': 0},
|
||||||
|
{'level': 1, 'levelName': 'Simple Love', 'requiredCpValue': 100},
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(scCpRelationLevelTextFromCabin(levelOneCabin), 'Lv.1');
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user