新增 CP SVGA 逻辑迁移测试报告,详细记录了在 MicMidpointRectManager 中新增的 CP 业务逻辑方法及其在 XPRoomViewController 中的简化调用。修复了编译错误,优化了代码结构,提升了可维护性和可测试性。同时,更新了 MicMidpointRectManager 的头文件,添加了新方法的声明,确保代码一致性和清晰性。

This commit is contained in:
edwinQQQ
2025-09-15 16:12:41 +08:00
parent 645be6184e
commit 6470c642eb
18 changed files with 10449 additions and 10019 deletions

View File

@@ -137,6 +137,7 @@ typedef NS_ENUM(NSUInteger, LoginType) {
make.centerX.mas_equalTo(self.view);
make.bottom.mas_equalTo(self.view).offset(-44);
make.width.mas_lessThanOrEqualTo(self.view).offset(-32);
make.height.mas_equalTo(60);
}];
[self.agreeButton mas_makeConstraints:^(MASConstraintMaker *make) {
@@ -189,6 +190,7 @@ typedef NS_ENUM(NSUInteger, LoginType) {
[button setCornerRadius:23];
[button setBackgroundColor:[UIColor whiteColor]];
[button.titleLabel setFont:kFontSemibold(14)];
[button.titleLabel setAdjustsFontSizeToFitWidth:YES];
[button setTitleColor:UIColorFromRGB(0x313131) forState:UIControlStateNormal];
switch (type) {
case LoginType_ID:{

View File

@@ -87,7 +87,7 @@
[self.descLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.myGoldView.mas_bottom).offset(4);
make.leading.mas_equalTo(self.myGoldView).offset(15);
make.leading.trailing.mas_equalTo(self.myGoldView).inset(15);
}];
}
///
@@ -98,6 +98,8 @@
_model = model;
_myGoldView.model = _model;
_myDiamondsView.model = _model;
self.descLabel.text = [NSString stringWithFormat:YMLocalizedString(@"20.20.51_text_29"),
@(model.minDiamonds)];
}
-(void)confirmAction{
if( self.model.diamonds < self.diamondNum.doubleValue){
@@ -149,7 +151,8 @@
- (UILabel *)descLabel {
if (!_descLabel) {
_descLabel = [UILabel labelInitWithText:YMLocalizedString(@"20.20.51_text_29") font:kFontSemibold(14) textColor:[UIColor lightGrayColor]];
_descLabel = [UILabel labelInitWithText:@"" font:kFontSemibold(14) textColor:[UIColor lightGrayColor]];
_descLabel.adjustsFontSizeToFitWidth = YES;
}
return _descLabel;
}
@@ -263,7 +266,7 @@
}
NSInteger count = textField.text.integerValue;
NSString *diamondNum = [NSString stringWithFormat:@"%.0f",floorf(count * _model.rate)];
if (count < 1000 || count % 1000 != 0) {
if (count < self.model.minDiamonds || count % self.model.minDiamonds != 0) {
diamondNum = @"0";
}
if(self.inputCounthandle){

View File

@@ -11,6 +11,9 @@ NS_ASSUME_NONNULL_BEGIN
@class MicMidpointRectManager;
@class UIView;
@class MicroQueueModel;
@class MicCpInfoModel;
@class UserInfoModel;
@protocol MicMidpointRectManagerDelegate <NSObject>
@@ -103,6 +106,58 @@ NS_ASSUME_NONNULL_BEGIN
stageView:(id)stageView
micCount:(NSInteger)micCount;
#pragma mark - CP Business Logic Methods
/// 处理麦位变化相关的CP逻辑
- (void)handleMicChangeForCPWithStageView:(id)stageView
micCount:(NSInteger)micCount
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
currentUserUid:(NSInteger)currentUserUid
roomType:(NSInteger)roomType;
/// 处理CP绑定或升级消息
- (void)handleCPBindingOrUpgradeMessageWithStageView:(id)stageView
micCount:(NSInteger)micCount
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue;
/// 处理麦位关系CP消息
- (void)handleMicRelationshipCPMessage:(NSArray<MicCpInfoModel *> *)cpList;
/// 处理其他用户mic变化
- (void)handleOtherUserMicChange:(UserInfoModel *)userInfo
changeType:(NSInteger)changeType
stageView:(id)stageView
micCount:(NSInteger)micCount
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
roomType:(NSInteger)roomType;
/// 处理用户切换mic场景确保所有CP SVGA状态正确更新
- (void)handleMicSwitchScenarioIfNeededWithStageView:(id)stageView
micCount:(NSInteger)micCount
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
currentUserUid:(NSInteger)currentUserUid
roomType:(NSInteger)roomType;
/// 处理下麦事件
- (void)handleDownMicEventIfNeededWithStageView:(id)stageView
micCount:(NSInteger)micCount
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
roomType:(NSInteger)roomType;
/// 更新CP列表缓存并重绘
- (void)updateCpListCacheAndRedraw:(NSArray<MicCpInfoModel *> *)cpList
stageView:(id)stageView
micCount:(NSInteger)micCount
roomType:(NSInteger)roomType;
/// 绘制社交舞台中点矩形
- (void)drawSocialStageMidpointRectsWithStageView:(id)stageView
micCount:(NSInteger)micCount
roomType:(NSInteger)roomType;
/// 移除指定用户的CP数据
- (void)removeCpDataForUids:(NSArray<NSNumber *> *)uids;
@end
NS_ASSUME_NONNULL_END

View File

@@ -430,6 +430,262 @@
NSLog(@"🔧 下麦事件处理完成");
}
#pragma mark - CP Business Logic Methods
/// CP
- (void)handleMicChangeForCPWithStageView:(id)stageView
micCount:(NSInteger)micCount
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
currentUserUid:(NSInteger)currentUserUid
roomType:(NSInteger)roomType {
NSLog(@"🔧 [Manager] 处理麦位变化相关的CP逻辑");
//
self.roomType = roomType;
//
[self rebuildMicSnapshotWithStageView:stageView micCount:micCount];
// CP
[self handleDownMicEventIfNeededWithStageView:stageView micCount:micCount queue:queue roomType:roomType];
// micCP SVGA
[self handleMicSwitchScenarioIfNeededWithStageView:stageView micCount:micCount queue:queue currentUserUid:currentUserUid roomType:roomType];
NSLog(@"🔧 [Manager] 麦位变化CP逻辑处理完成");
}
/// CP
- (void)handleCPBindingOrUpgradeMessageWithStageView:(id)stageView
micCount:(NSInteger)micCount
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
NSLog(@"🔧 [Manager] 处理CP绑定或升级消息");
if (!queue) {
NSLog(@"⚠️ [Manager] 无法获取当前麦位队列跳过CP绑定/升级处理");
return;
}
NSLog(@"🔧 [Manager] CP绑定/升级消息处理完成");
}
/// CP
- (void)handleMicRelationshipCPMessage:(NSArray<MicCpInfoModel *> *)cpList {
NSLog(@"🔧 [Manager] 处理麦位关系CP消息接收到 %lu 条CP数据", (unsigned long)cpList.count);
if (!cpList || cpList.count == 0) {
NSLog(@"⚠️ [Manager] CP数据为空跳过处理");
return;
}
// CP
[self setCpListCache:cpList];
NSLog(@"🔧 [Manager] 麦位关系CP消息处理完成");
}
/// mic
- (void)handleOtherUserMicChange:(UserInfoModel *)userInfo
changeType:(NSInteger)changeType
stageView:(id)stageView
micCount:(NSInteger)micCount
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
roomType:(NSInteger)roomType {
NSLog(@"🔧 [Manager] 处理其他用户mic变化用户 %ld, 变化类型 %ld", (long)userInfo.uid, (long)changeType);
//
self.roomType = roomType;
NSInteger userUid = userInfo.uid;
if (changeType == 2) { //
//
[self rebuildMicSnapshotWithStageView:stageView micCount:micCount];
// CP
NSArray<NSNumber *> *removedUids = @[@(userUid)];
[self removeCpEntriesForUids:removedUids];
[self removeMidpointRectsForUids:removedUids];
NSLog(@"🔧 [Manager] 其他用户下麦处理完成");
} else if (changeType == 1) { //
//
[self rebuildMicSnapshotWithStageView:stageView micCount:micCount];
NSLog(@"🔧 [Manager] 其他用户上麦处理完成");
}
}
/// micCP SVGA
- (void)handleMicSwitchScenarioIfNeededWithStageView:(id)stageView
micCount:(NSInteger)micCount
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
currentUserUid:(NSInteger)currentUserUid
roomType:(NSInteger)roomType {
NSLog(@"🔧 [Manager] 处理用户切换mic场景");
//
self.roomType = roomType;
// mic
NSDictionary<NSString *, NSArray<NSNumber *> *> *micChanges = [self diffMicChangeWithStageView:stageView micCount:micCount];
NSArray<NSNumber *> *addedUids = micChanges[@"added"];
NSArray<NSNumber *> *removedUids = micChanges[@"removed"];
if (addedUids.count > 0 || removedUids.count > 0) {
NSLog(@"🔧 [Manager] 检测到麦位变化:上麦 %lu 人,下麦 %lu 人", (unsigned long)addedUids.count, (unsigned long)removedUids.count);
// CPCP SVGA
NSArray<NSNumber *> *currentUserUids = @[@(currentUserUid)];
// 1. CP
[self removeCpEntriesForUids:currentUserUids];
[self removeMidpointRectsForUids:currentUserUids];
// 2.
[self rebuildMicSnapshotWithStageView:stageView micCount:micCount];
NSLog(@"🔧 [Manager] 用户切换mic场景处理完成");
} else {
NSLog(@"🔧 [Manager] 没有检测到麦位变化,跳过处理");
}
}
///
- (void)handleDownMicEventIfNeededWithStageView:(id)stageView
micCount:(NSInteger)micCount
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
roomType:(NSInteger)roomType {
NSLog(@"🔧 [Manager] 处理下麦事件");
//
self.roomType = roomType;
// 使 MicMidpointRectManager
NSDictionary<NSString *, NSArray<NSNumber *> *> *micChanges = [self diffMicChangeWithStageView:stageView micCount:micCount];
NSArray<NSNumber *> *removedUids = micChanges[@"removed"];
if (removedUids && removedUids.count > 0) {
NSLog(@"🔧 [Manager] 检测到下麦用户:%@", removedUids);
// CP
[self removeCpEntriesForUids:removedUids];
[self removeMidpointRectsForUids:removedUids];
NSLog(@"🔧 [Manager] 下麦事件处理完成");
} else {
NSLog(@"🔧 [Manager] 没有检测到下麦用户,跳过处理");
}
}
/// CP
- (void)updateCpListCacheAndRedraw:(NSArray<MicCpInfoModel *> *)cpList
stageView:(id)stageView
micCount:(NSInteger)micCount
roomType:(NSInteger)roomType {
NSLog(@"🔧 [Manager] 更新CP列表缓存并重绘接收到 %lu 条CP数据", (unsigned long)cpList.count);
//
self.roomType = roomType;
// CP
[self setCpListCache:cpList];
//
[self drawSocialStageMidpointRectsWithStageView:stageView micCount:micCount roomType:roomType];
NSLog(@"🔧 [Manager] CP列表缓存更新和重绘完成");
}
///
- (void)drawSocialStageMidpointRectsWithStageView:(id)stageView
micCount:(NSInteger)micCount
roomType:(NSInteger)roomType {
NSLog(@"🔧 [Manager] 绘制社交舞台中点矩形:麦位总数 %ld", (long)micCount);
//
self.roomType = roomType;
//
[self removeAllMidpointRects];
if (micCount < 2) {
NSLog(@"🔧 [Manager] 麦位数量不足,跳过绘制");
return;
}
//
for (NSInteger i = 0; i < micCount - 1; i++) {
NSInteger firstIndex = i;
NSInteger secondIndex = i + 1;
//
UIView<MicroViewProtocol> *firstView = [stageView findMicroViewByIndex:firstIndex];
UIView<MicroViewProtocol> *secondView = [stageView findMicroViewByIndex:secondIndex];
if (!firstView || !secondView) {
continue;
}
//
UserInfoModel *firstUser = [firstView getUser];
UserInfoModel *secondUser = [secondView getUser];
if (!firstUser || !secondUser || firstUser.uid <= 0 || secondUser.uid <= 0) {
continue;
}
//
CGRect firstFrame = firstView.frame;
CGRect secondFrame = secondView.frame;
CGFloat midX = (firstFrame.origin.x + firstFrame.size.width + secondFrame.origin.x) / 2.0;
CGFloat midY = (firstFrame.origin.y + secondFrame.origin.y) / 2.0;
CGFloat width = kGetScaleWidth(75);
CGFloat height = width;
CGRect rect = CGRectMake(midX - width/2, midY - height/4, width, height);
//
UIView *micRelationshipView = [[UIView alloc] initWithFrame:rect];
micRelationshipView.backgroundColor = [UIColor clearColor];
micRelationshipView.userInteractionEnabled = NO;
micRelationshipView.tag = 56002;
//
[self.containerView addSubview:micRelationshipView];
[self.midpointRects addObject:micRelationshipView];
// SVGA
NSString *micPairText = [NSString stringWithFormat:@"%ld-%ld", (long)firstIndex, (long)secondIndex];
[self addRelationshipAtFrame:rect
micPairText:micPairText
leftUid:firstUser.uid
rightUid:secondUser.uid
cpList:self.cachedCpListInternal ?: @[]];
}
NSLog(@"🔧 [Manager] 社交舞台中点矩形绘制完成");
}
/// CP
- (void)removeCpDataForUids:(NSArray<NSNumber *> *)uids {
NSLog(@"🔧 [Manager] 移除CP数据UIDs %@", uids);
if (uids.count == 0) {
NSLog(@"🔧 [Manager] 没有需要移除的用户,跳过处理");
return;
}
//
[self removeCpEntriesForUids:uids];
// UI
[self removeMidpointRectsForUids:uids];
NSLog(@"🔧 [Manager] CP数据移除完成");
}
#pragma mark - Dealloc
- (void)setupNotifications {

View File

@@ -1071,7 +1071,7 @@ XPCandyTreeInsufficientBalanceViewDelegate>
// 🔧 stage viewCPAPI
NSMutableDictionary<NSString *,MicroQueueModel *> *currentQueue = [self.stageView getMicroQueue];
[self callMicCpListByUidListOnMicChangeWithQueue:currentQueue];
[self callMicCpListByUidListWithQueue:currentQueue];
// 🔧 19 micposition 6
[self checkCentralPositionUserQualification:currentQueue];
@@ -2566,10 +2566,52 @@ XPCandyTreeInsufficientBalanceViewDelegate>
break;
}
break;
case CustomMessageType_CP:
switch (attachment.second) {
case Custom_Message_Sub_CP_Binding:
case Custom_Message_Sub_CP_Upgrade:
[self handleCPBindingOrUpgradeMessage:attachment];
break;
}
break;
}
}
}
/// CP
- (void)handleCPBindingOrUpgradeMessage:(AttachmentModel *)attachment {
NSLog(@"🔧 处理CP绑定或升级消息first=%ld, second=%ld", (long)attachment.first, (long)attachment.second);
// CP
if (!self.hasCompletedRoomInitialization) {
NSLog(@"🔧 进房初始化中跳过CP绑定/升级处理");
return;
}
//
NSMutableDictionary<NSString *,MicroQueueModel *> *currentQueue = [self.stageView getMicroQueue];
if (!currentQueue) {
NSLog(@"⚠️ 无法获取当前麦位队列跳过CP绑定/升级处理");
return;
}
// 使 MicMidpointRectManager CP/
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
//
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
[manager handleCPBindingOrUpgradeMessageWithStageView:self.stageView
micCount:micCount
queue:currentQueue];
}
// CP API
[self callMicCpListByUidListWithQueue:currentQueue];
NSLog(@"✅ CP绑定/升级消息处理完成");
}
/// CP
- (void)handleMicChangeForCP:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
NSLog(@"🔧 处理麦位变化相关的CP逻辑");
@@ -2577,19 +2619,22 @@ XPCandyTreeInsufficientBalanceViewDelegate>
//
[self updateCurrentUserMicStatus:queue];
//
[self updateMicMidpointRectManagerSnapshot];
// CP
if (self.hasCompletedRoomInitialization) {
// CP
[self handleDownMicEventIfNeeded:queue];
// 🔧 micCP SVGA
[self handleMicSwitchScenarioIfNeeded:queue];
// 使 MicMidpointRectManager CP
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
//
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
[manager handleMicChangeForCPWithStageView:self.stageView
micCount:micCount
queue:queue
currentUserUid:[AccountInfoStorage instance].getUid.integerValue
roomType:self.roomInfo.type];
}
// CP API
[self callMicCpListByUidListOnMicChangeWithQueue:queue];
[self callMicCpListByUidListWithQueue:queue];
// 🔧 19 mic
[self checkCentralPositionUserQualification:queue];
@@ -2640,8 +2685,11 @@ XPCandyTreeInsufficientBalanceViewDelegate>
// CP
self.currentCpList = cpList.copy;
// MicMidpointRectManager
[self updateMicMidpointRectManagerCache:cpList];
// 使 MicMidpointRectManager CP
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
[manager handleMicRelationshipCPMessage:cpList];
}
// CP SVGA
[self drawSocialStageMidpointRects];
@@ -3208,28 +3256,42 @@ XPCandyTreeInsufficientBalanceViewDelegate>
[[RoomBoomManager sharedManager] receiveEnterRoomBoom:model];
}
- (void)getMicCpListByRoomUidSuccess:(NSArray <MicCpInfoModel *> *)cpList {
self.currentCpList = cpList;
// MicMidpointRectManager
[self updateMicMidpointRectManagerCache:cpList];
// CPSVGA
[self drawSocialStageMidpointRects];
}
- (void)getMicCpListByUidListSuccess:(NSArray<MicCpInfoModel *> *)cpList {
/// CP API
- (void)handleMicCpListSuccess:(NSArray<MicCpInfoModel *> *)cpList {
NSLog(@"🔧 CP API成功回调接收到 %lu 条CP数据", (unsigned long)cpList.count);
self.currentCpList = cpList;
// 🔧 MicMidpointRectManager
[self updateMicMidpointRectManagerCache:cpList];
// CPSVGA
[self drawSocialStageMidpointRects];
// 使 MicMidpointRectManager CP
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
//
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
[manager updateCpListCacheAndRedraw:cpList
stageView:self.stageView
micCount:micCount
roomType:self.roomInfo.type];
}
// NIM message
if (self.currentUserMicStatusChanged) {
[self sendMicRelationshipNIMessage:cpList];
self.currentUserMicStatusChanged = NO; //
}
NSLog(@"🔧 CP API成功回调处理完成");
}
/// UIDCP
- (void)getMicCpListByRoomUidSuccess:(NSArray <MicCpInfoModel *> *)cpList {
NSLog(@"🔧 按房间UID获取CP列表成功接收到 %lu 条CP数据", (unsigned long)cpList.count);
[self handleMicCpListSuccess:cpList];
}
/// UIDCP
- (void)getMicCpListByUidListSuccess:(NSArray<MicCpInfoModel *> *)cpList {
NSLog(@"🔧 按用户UID列表获取CP列表成功接收到 %lu 条CP数据", (unsigned long)cpList.count);
[self handleMicCpListSuccess:cpList];
}
#pragma mark - 退
@@ -3640,110 +3702,17 @@ XPCandyTreeInsufficientBalanceViewDelegate>
return;
}
NSString *stageViewClass = NSStringFromClass([self.stageView class]);
NSLog(@"🔧 开始绘制 %@ 中点矩形", stageViewClass);
//
if ([self.stageView respondsToSelector:@selector(midpointRectManager)]) {
// 使
id manager = [self.stageView valueForKey:@"midpointRectManager"];
if ([manager respondsToSelector:@selector(removeAllMidpointRects)]) {
[manager removeAllMidpointRects];
}
//
if ([manager respondsToSelector:@selector(setRoomType:)]) {
[manager setRoomType:self.roomInfo.type];
}
// 使 MicMidpointRectManager
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
//
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
[manager drawSocialStageMidpointRectsWithStageView:self.stageView
micCount:micCount
roomType:self.roomInfo.type];
} else {
//
NSArray<UIView *> *subviews = [self.stageView.subviews copy];
for (UIView *view in subviews) {
if (view.tag == 56002) {
[view removeFromSuperview];
}
}
NSLog(@"🔧 无法获取 midpointRectManager跳过中点矩形绘制");
}
// StageView
NSArray *validPairs = nil;
if ([self.stageView isKindOfClass:[SocialStageView class]]) {
validPairs = @[@[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8]];
} else if ([self.stageView isKindOfClass:[TenMicStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8], @[@8, @9]];
} else if ([self.stageView isKindOfClass:[FifteenMicStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8], @[@8, @9], @[@10, @11], @[@11, @12], @[@12, @13], @[@13, @14]];
} else if ([self.stageView isKindOfClass:[NineteenMicStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@8, @9], @[@10, @11], @[@12, @13], @[@14, @15], @[@15, @16], @[@16, @17], @[@17, @18]];
} else if ([self.stageView isKindOfClass:[TwentyMicStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8], @[@8, @9], @[@10, @11], @[@11, @12], @[@12, @13], @[@13, @14], @[@15, @16], @[@16, @17], @[@17, @18], @[@18, @19]];
} else if ([self.stageView isKindOfClass:[AnchorStageView class]]) {
validPairs = @[@[@1, @2], @[@2, @3]];
} else if ([self.stageView isKindOfClass:[DatingStageView class]]) {
validPairs = @[@[@1, @2], @[@3, @4], @[@5, @6], @[@7, @8]];
} else if ([self.stageView isKindOfClass:[LittleGameStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@4, @5]];
} else if ([self.stageView isKindOfClass:[LittleGameScrollStageView class]]) {
//
NSInteger micCount = [self.stageView countOfMicroView];
NSMutableArray *pairs = [NSMutableArray array];
for (NSInteger i = 0; i < micCount - 1; i++) {
[pairs addObject:@[@(i), @(i + 1)]];
}
validPairs = pairs;
} else if ([self.stageView isKindOfClass:[AnchorPKStageView class]]) {
validPairs = @[@[@0, @1]];
} else {
NSLog(@"🔧 未支持的 StageView 类型: %@", stageViewClass);
return;
}
NSLog(@"🔧 开始绘制 %@ 中点矩形,共 %lu 对相邻麦位", stageViewClass, (unsigned long)validPairs.count);
for (NSArray *pair in validPairs) {
NSInteger firstIndex = [pair[0] integerValue];
NSInteger secondIndex = [pair[1] integerValue];
CGRect rect = [self.stageView rectForMidpointBetweenMicAtIndex:firstIndex andIndex:secondIndex];
if (!CGRectIsEmpty(rect)) {
UIView *micRelationshipView = [[UIView alloc] initWithFrame:rect];
micRelationshipView.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:0.3];
micRelationshipView.layer.borderColor = [UIColor blueColor].CGColor;
micRelationshipView.layer.borderWidth = 2.0;
micRelationshipView.layer.cornerRadius = 8.0;
micRelationshipView.tag = 56002;
micRelationshipView.userInteractionEnabled = NO;
//
UILabel *label = [[UILabel alloc] init];
label.text = [NSString stringWithFormat:@"%ld-%ld", (long)firstIndex, (long)secondIndex];
label.textColor = [UIColor whiteColor];
label.font = [UIFont boldSystemFontOfSize:12];
label.textAlignment = NSTextAlignmentCenter;
label.frame = micRelationshipView.bounds;
[micRelationshipView addSubview:label];
// midpointRectManager SVGA退
if ([self.stageView respondsToSelector:@selector(midpointRectManager)]) {
id manager = [self.stageView valueForKey:@"midpointRectManager"];
if ([manager respondsToSelector:@selector(addRelationshipAtFrame:micPairText:leftUid:rightUid:cpList:)]) {
NSString *micPairText = [NSString stringWithFormat:@"%ld-%ld", (long)firstIndex, (long)secondIndex];
UIView<MicroViewProtocol> *leftView = [self.stageView findMicroViewByIndex:firstIndex];
UIView<MicroViewProtocol> *rightView = [self.stageView findMicroViewByIndex:secondIndex];
NSInteger leftUid = [[leftView getUser] uid];
NSInteger rightUid = [[rightView getUser] uid];
[manager addRelationshipAtFrame:rect micPairText:micPairText leftUid:leftUid rightUid:rightUid cpList:self.currentCpList ?: @[]];
}
} else {
[self.stageView addSubview:micRelationshipView];
}
NSLog(@"🔧 绘制中点矩形: %ld-%ld, rect: %@", (long)firstIndex, (long)secondIndex, NSStringFromCGRect(rect));
} else {
NSLog(@"🔧 跳过无效麦位对: %ld-%ld", (long)firstIndex, (long)secondIndex);
}
}
NSLog(@"🔧 %@ 中点矩形绘制完成", stageViewClass);
}
/// CPAPI
@@ -3783,7 +3752,8 @@ XPCandyTreeInsufficientBalanceViewDelegate>
if (currentUserMicPosition == -1) {
NSLog(@"🔧 获取mic用户列表当前用户不在麦上返回空数据");
// manager UID
[self removeCurrentUserCpDataFromManager];
NSInteger currentUid = [AccountInfoStorage instance].getUid.integerValue;
[self removeCpDataForUids:@[@(currentUid)]];
return micUserUids;
}
@@ -3839,12 +3809,10 @@ XPCandyTreeInsufficientBalanceViewDelegate>
}
}
//
// 🔧 使UIDNIM message
if (micUserUids.count == 1) {
NSLog(@"🔧 获取mic用户列表只有当前用户一个人返回空数据");
// manager UID
[self removeCurrentUserCpDataFromManager];
return [NSArray array];
NSLog(@"🔧 获取mic用户列表只有当前用户一个人但仍需发送NIM message");
// UIDCP APINIM message
}
NSLog(@"🔧 获取mic用户列表当前用户麦位 %ld找到 %lu 个相关用户: %@",
@@ -3852,6 +3820,7 @@ XPCandyTreeInsufficientBalanceViewDelegate>
return micUserUids;
}
/// mic
- (void)handleOtherUserMicChange:(UserInfoModel *)userInfo changeType:(NSInteger)changeType {
if (!self.stageView || ![self.stageView respondsToSelector:@selector(midpointRectManager)]) {
@@ -3859,178 +3828,102 @@ XPCandyTreeInsufficientBalanceViewDelegate>
return;
}
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (!midpointRectManager) {
NSLog(@"🔧 处理其他用户mic变化无法获取 midpointRectManager跳过处理");
//
NSMutableDictionary<NSString *,MicroQueueModel *> *currentQueue = [self.stageView getMicroQueue];
if (!currentQueue) {
NSLog(@"🔧 处理其他用户mic变化无法获取当前麦位队列跳过处理");
return;
}
//
midpointRectManager.roomType = self.roomInfo.type;
NSInteger userUid = userInfo.uid;
NSArray<NSNumber *> *userUids = @[@(userUid)];
if (changeType == 2) {
//
NSLog(@"🔧 处理其他用户下麦UID %ld", (long)userUid);
//
[self updateMicMidpointRectManagerSnapshot];
// cpSVGA
[midpointRectManager removeCpEntriesForUids:userUids];
[midpointRectManager removeMidpointRectsForUids:userUids];
//
[self drawSocialStageMidpointRects];
NSLog(@"🔧 其他用户下麦处理完成UID %ld", (long)userUid);
} else if (changeType == 1) {
//
NSLog(@"🔧 处理其他用户上麦UID %ld", (long)userUid);
//
[self updateMicMidpointRectManagerSnapshot];
// CPCP
[self drawSocialStageMidpointRects];
NSLog(@"🔧 其他用户上麦处理完成UID %ld", (long)userUid);
}
}
/// CPmanager
- (void)removeCurrentUserCpDataFromManager {
if (!self.stageView || ![self.stageView respondsToSelector:@selector(midpointRectManager)]) {
NSLog(@"🔧 移除当前用户CP数据stageView 不支持 midpointRectManager跳过处理");
return;
// 使 MicMidpointRectManager mic
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
//
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
[manager handleOtherUserMicChange:userInfo
changeType:changeType
stageView:self.stageView
micCount:micCount
queue:currentQueue
roomType:self.roomInfo.type];
}
NSInteger currentUid = [AccountInfoStorage instance].getUid.integerValue;
NSArray<NSNumber *> *removedUids = @[@(currentUid)];
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (midpointRectManager) {
//
midpointRectManager.roomType = self.roomInfo.type;
//
[midpointRectManager removeCpEntriesForUids:removedUids];
// UI
[midpointRectManager removeMidpointRectsForUids:removedUids];
NSLog(@"🔧 移除当前用户CP数据完成UID %ld", (long)currentUid);
}
}
/// micCP SVGA
- (void)handleMicSwitchScenarioIfNeeded:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
if (!self.stageView || ![self.stageView respondsToSelector:@selector(midpointRectManager)]) {
NSLog(@"🔧 处理切换mic场景stageView 不支持 midpointRectManager跳过处理");
return;
}
// 🔧
//
BOOL hasMicPositionChanged = self.currentUserMicStatusChanged;
if (hasMicPositionChanged) {
NSLog(@"🔧 检测到当前用户麦位状态变化可能是切换mic场景");
//
NSInteger micCount = 0;
if (self.roomInfo) {
switch (self.roomInfo.type) {
case RoomType_Room: micCount = 9; break;
case RoomType_10Mic: micCount = 10; break;
case RoomType_15Mic: micCount = 15; break;
case RoomType_19Mic: micCount = 19; break;
case RoomType_20Mic: micCount = 20; break;
default: micCount = 9; break;
// API
if (changeType == 2) { //
//
NSMutableArray<NSString *> *remainingUids = [NSMutableArray array];
for (NSString *positionKey in currentQueue.allKeys) {
MicroQueueModel *micModel = currentQueue[positionKey];
if (micModel && micModel.userInfo && micModel.userInfo.uid > 0) {
[remainingUids addObject:[NSString stringWithFormat:@"%ld", (long)micModel.userInfo.uid]];
}
}
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (midpointRectManager) {
//
midpointRectManager.roomType = self.roomInfo.type;
// CP
// 1. SVGA
[midpointRectManager removeAllMidpointRects];
// 2.
[midpointRectManager rebuildMicSnapshotWithStageView:self.stageView micCount:micCount];
// 3. CP
[self drawSocialStageMidpointRects];
NSLog(@"🔧 用户麦位变化场景处理完成重新构建了所有CP关系");
// APICP
if (remainingUids.count > 0) {
[self.presenter micCpListByUidList:remainingUids];
}
// 🔧 API
// getMicCpListByUidListSuccess
} else {
NSLog(@"🔧 当前用户麦位状态未变化,跳过切换场景处理");
//
[self drawSocialStageMidpointRects];
} else if (changeType == 1) { //
// CP API
[self callMicCpListByUidListWithQueue:currentQueue];
// CP
[self drawSocialStageMidpointRects];
}
}
///
- (void)handleDownMicEventIfNeeded:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
/// CP
- (void)removeCpDataForUids:(NSArray<NSNumber *> *)uids {
if (!self.stageView || ![self.stageView respondsToSelector:@selector(midpointRectManager)]) {
NSLog(@"🔧 处理下麦事件stageView 不支持 midpointRectManager跳过处理");
NSLog(@"🔧 移除CP数据stageView 不支持 midpointRectManager跳过处理");
return;
}
//
NSInteger micCount = 0;
if (self.roomInfo) {
switch (self.roomInfo.type) {
case RoomType_Room: micCount = 9; break;
case RoomType_10Mic: micCount = 10; break;
case RoomType_15Mic: micCount = 15; break;
case RoomType_19Mic: micCount = 19; break;
case RoomType_20Mic: micCount = 20; break;
default: micCount = 9; break;
}
if (uids.count == 0) {
NSLog(@"🔧 移除CP数据没有需要移除的用户跳过处理");
return;
}
// 使 MicMidpointRectManager
// MicMidpointRectManager *midpointRectManager = [self.stageView midpointRectManager];
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (midpointRectManager) {
//
midpointRectManager.roomType = self.roomInfo.type;
NSDictionary<NSString *, NSArray<NSNumber *> *> *micChanges =
[midpointRectManager diffMicChangeWithStageView:self.stageView micCount:micCount];
NSArray<NSNumber *> *removedUids = micChanges[@"removed"];
if (removedUids && removedUids.count > 0) {
NSLog(@"🔧 检测到下麦用户:%@", removedUids);
// MicMidpointRectManager
[midpointRectManager handleDownMicEvent:removedUids stageView:self.stageView micCount:micCount];
}
// 使 MicMidpointRectManager CP
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
[manager removeCpDataForUids:uids];
NSLog(@"🔧 移除CP数据完成UIDs %@", uids);
}
}
/// micCPAPI
- (void)callMicCpListByUidListOnMicChangeWithQueue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
NSLog(@"🔧 mic位变动开始调用 micCpListByUidList API");
/// CP API
- (void)callMicCpListByUidListWithQueue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
NSLog(@"🔧 调用CP API开始获取mic用户列表");
NSArray<NSString *> *micUserUids = [self getAllMicUserUidsWithQueue:queue];
// queuemicuid
NSMutableArray<NSString *> *micUserUids = [NSMutableArray array];
if (queue) {
for (NSString *positionKey in queue.allKeys) {
MicroQueueModel *micModel = queue[positionKey];
if (micModel && micModel.userInfo && micModel.userInfo.uid > 0) {
[micUserUids addObject:[NSString stringWithFormat:@"%ld", (long)micModel.userInfo.uid]];
}
}
}
if (micUserUids.count == 0) {
NSLog(@"🔧 mic位变动:没有相关用户在mic上跳过API调用");
NSLog(@"🔧 调用CP API没有用户在mic上跳过API调用");
return;
}
// micCpListByUidList
if ([micUserUids containsObject:[AccountInfoStorage instance].getUid]) {
NSLog(@"🔧 mic位变动且包含了当前用户调用 micCpListByUidList: %@", micUserUids);
[self.presenter micCpListByUidList:micUserUids];
}
NSLog(@"🔧 调用CP APImicCpListByUidList: %@", micUserUids);
[self.presenter micCpListByUidList:micUserUids];
NSLog(@"🔧 mic位变动micCpListByUidList API调用完成");
NSLog(@"🔧 调用CP API完成");
}
///
@@ -4294,6 +4187,18 @@ XPCandyTreeInsufficientBalanceViewDelegate>
}
}
///
- (NSInteger)getMicCountForRoomType:(NSInteger)roomType {
switch (roomType) {
case RoomType_Room: return 9;
case RoomType_10Mic: return 10;
case RoomType_15Mic: return 15;
case RoomType_19Mic: return 19;
case RoomType_20Mic: return 20;
default: return 9;
}
}
/// 19 micposition 6
- (void)checkCentralPositionUserQualification:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
// 19 mic

View File

@@ -18,10 +18,10 @@
@{@"code": @"zh-Hant", @"localizationCode": @"zh-Hant", @"displayName": @"繁體中文", @"isRTL": @NO},
@{@"code": @"ar", @"localizationCode": @"ar", @"displayName": @"العربية", @"isRTL": @YES},
@{@"code": @"tr", @"localizationCode": @"tr", @"displayName": @"Türkçe", @"isRTL": @NO},
@{@"code": @"pt", @"localizationCode": @"pt-BR", @"displayName": @"Português (Brasil)", @"isRTL": @NO},
@{@"code": @"pt-BR", @"localizationCode": @"pt-BR", @"displayName": @"Português (Brasil)", @"isRTL": @NO},
@{@"code": @"es", @"localizationCode": @"es", @"displayName": @"Español", @"isRTL": @NO},
@{@"code": @"ru", @"localizationCode": @"ru", @"displayName": @"Русский", @"isRTL": @NO},
@{@"code": @"uz", @"localizationCode": @"uz", @"displayName": @"O'zbek", @"isRTL": @NO}
@{@"code": @"uz-UZ", @"localizationCode": @"uz-UZ", @"displayName": @"O'zbek", @"isRTL": @NO}
];
});
return languages;

View File

@@ -4145,7 +4145,7 @@ ineHeadView12" = "الحمل";
"20.20.51_text_26" = "كن في VIP%@";
"20.20.51_text_27" = "١ في كل مرة تقوم فيها بتحميل صورة رمزية ديناميكية سيقوم النظام بخصم %@ عملة من حسابك. يرجى التأكد من أن رصيد حسابك كافٍ\n\n٢ عملية المراجعة: بعد اكتمال التحميل، سيدخل النظام تلقائيًا عملية المراجعة. خلال هذه الفترة، يرجى عدم تحميل صورة رمزية جديدة مرة أخرى لتجنب التأثير على تقدم المراجعة.\n\n٣ نتائج المراجعة \n\nتمت المراجعة بنجاح: ستدخل الصورة الرمزية الديناميكية الجديدة حيز التنفيذ على الفور وسيتم عرضها للمستخدمين الآخرين.\n\nفشل المراجعة: سيقوم النظام تلقائيًا برد %@ عملة أنفقتها بعد اكتمال المراجعة. في نفس الوقت، ستتلقى إشعارًا من النظام.\n\n٤ عملية لا رجعة فيها: يرجى ملاحظة أنه بمجرد مراجعة الصورة الرمزية الديناميكية ودخولها حيز التنفيذ، فلن تتمكن من استعادتها إلى الصورة الرمزية السابقة.\n";
"20.20.51_text_28" = "عرض الوقت:%@";
"20.20.51_text_29" = "يجب أن يكون عدد الماس مضاعفات 1000";
"20.20.51_text_29" = "يجب أن يكون عدد الماس مضاعفات %@";
"20.20.56_text_1" = "عدد المباريات الحالي غير كافٍ، فشلت المباراة. إعادة المباراة مرة أخرى؟";
"20.20.56_text_2" = "فشلت المطابقة، تم إرجاع العملات التي استهلكتها إلى محفظتك";

View File

@@ -3932,7 +3932,7 @@
"20.20.51_text_26" = "Be VIP%@";
"20.20.51_text_27" = "1 Each time you upload a dynamic avatar, the system will deduct %@ coins from your account. Please make sure that your account balance is sufficient.\n2 Review process: After the upload is completed, the system will automatically enter the review process. During this period, please do not upload a new avatar again to avoid affecting the review progress.\n3 Review results: \nReview passed: Your new dynamic avatar will take effect immediately and be displayed to other users.\nReview failed: The system will automatically refund the %@ coins you spent after the review is completed. At the same time, you will receive a system notification.\n4 Irreversible operation: Please note that once the dynamic avatar is reviewed and takes effect, you will not be able to restore it to the previous avatar.\n";
"20.20.51_text_28" = "View Time: %@";
"20.20.51_text_29" = "Number of diamonds needs to be multiples of 1000";
"20.20.51_text_29" = "Number of diamonds needs to be multiples of %@";
"20.20.56_text_1" = "The current number of matches is not enough, the match failed. Re-match again?";
"20.20.56_text_2" = "Match failed, the coins you consumed has been returned to your wallet";

View File

@@ -1,9 +1,7 @@
NSCameraUsageDescription = "\"Molistar\" necesita su consentimiento antes de que pueda visitar, tomar fotos y subir sus fotos, y luego mostrarlas en su página de inicio personal para que otros lo vean";
NSCameraUsageDescription = "\"MoliStar\" necesita su consentimiento para que pueda visitar, tomar fotos y cargar sus imágenes, y luego mostrarlas en su página de inicio personal para que otras personas las vean";
NSLocalNetworkUsageDescription = "La aplicación descubrirá y se conectará a dispositivos en su red";
NSLocationWhenInUseUsageDescription = "Se requiere su consentimiento antes de poder usar los servicios de ubicación y recomendar amigos cercanos";
NSMicrophoneUsageDescription = "\"Molistar\" necesita su consentimiento antes de que pueda realizar chat de voz";
NSPhotoLibraryAddUsageDescription = "\"Molistar\" necesita su consentimiento antes de que pueda almacenar fotos en el álbum";
NSPhotoLibraryUsageDescription = "\"Molistar\" necesita su consentimiento antes de que pueda acceder al álbum y seleccionar las imágenes que necesita cargar, y luego mostrarlas en su página de inicio personal para que otros lo vean";
NSUserTrackingUsageDescription = "Permítanos obtener su permiso de IDFA para brindarle actividades y servicios personalizados.Su información no se utilizará para otros fines sin su permiso.";
NSLocationWhenInUseUsageDescription = "Se requiere su consentimiento antes de que pueda usar los servicios de ubicación y recomendar amigos cercanos";
NSMicrophoneUsageDescription = "\"MoliStar\" necesita su consentimiento antes de poder realizar una conversación de voz";
NSPhotoLibraryAddUsageDescription = "\"MoliStar\" necesita su consentimiento antes de poder almacenar fotos en el álbum";
NSPhotoLibraryUsageDescription = "\"MoliStar\" necesita su consentimiento para que pueda acceder al álbum y seleccionar las imágenes que necesita cargar, y luego mostrarlas en su página de inicio personal para que otras personas las vean";
NSUserTrackingUsageDescription = "Permítanos obtener su permiso de idfa para proporcionarle actividades y servicios personalizados. Su información no se utilizará para otros fines sin su permiso";

File diff suppressed because it is too large Load Diff

View File

@@ -3228,7 +3228,7 @@
"20.20.51_text_26" = "Seja VIP%@";
"20.20.51_text_27" = "1 Cada envio de avatar dinâmico deduz %@ moedas. Verifique seu saldo.\n2 Revisão: Após o envio, o sistema entrará em revisão. Não envie novamente para não atrasar.\n3 Resultado: \nAprovado: Seu avatar será exibido.\nReprovado: As moedas serão reembolsadas e você será notificado.\n4 Operação irreversível: Após a aprovação, não é possível reverter.";
"20.20.51_text_28" = "Horário da Visita: %@";
"20.20.51_text_29" = "O número de diamantes precisa ser múltiplo de 1000";
"20.20.51_text_29" = "O número de diamantes precisa ser múltiplo de %@";
"20.20.56_text_1" = "Número atual de correspondências insuficiente, falha na correspondência. Tentar novamente?";
"20.20.56_text_2" = "Falha na correspondência, as moedas gastas foram devolvidas à sua carteira.";
"20.20.56_text_3" = "Mudar Relacionamento";

View File

@@ -1,9 +1,8 @@
NSCameraUsageDescription ="\"MoliStar\" needs your consent before you can visit, take photos and upload your pictures, and then display them on your personal homepage for others to view";
NSLocalNetworkUsageDescription ="The app will discover and connect to devices on your network";
NSLocationWhenInUseUsageDescription = "Your consent is required before you can use location services and recommend nearby friends";
NSMicrophoneUsageDescription = "\"MoliStar\" needs your consent before it can conduct voice chat";
NSPhotoLibraryAddUsageDescription = "\"MoliStar\" needs your consent before it can store photos in the album";
NSPhotoLibraryUsageDescription = "\"MoliStar\" needs your consent before you can access the album and select the pictures you need to upload, and then display them on your personal homepage for others to view";
NSUserTrackingUsageDescription = "Please allow us to obtain your idfa permission to provide you with personalized activities and services. your information will not be used for other purposes without your permission";
NSCameraUsageDescription = "\"MoliStar\" нужен ваш consentimiento перед тем, как вы можете посетить, фотографировать и загружать ваши изображения, а затем отображать их на вашей персональной странице для просмотра другими людьми";
NSLocalNetworkUsageDescription = "Приложение обнаружит и подключится к устройствам в вашей сети";
NSLocationWhenInUseUsageDescription = "Вам необходимо дать согласие, прежде чем вы сможете использовать службы определения местоположения и рекомендовать близких друзей";
NSMicrophoneUsageDescription = "\"MoliStar\" нужен ваш consentimiento перед тем, как он может проводить голосовый чат";
NSPhotoLibraryAddUsageDescription = "\"MoliStar\" нужен ваш consentimiento перед тем, как он может хранить фотографии в альбоме";
NSPhotoLibraryUsageDescription = "\"MoliStar\" нужен ваш consentimiento перед тем, как вы можете получить доступ к альбому и выбрать изображения, которые вам нужно загрузить, а затем отобразить их на вашей персональной странице для просмотра другими людьми";
NSUserTrackingUsageDescription = "Пожалуйста, разрешите нам получить ваше разрешение на idfa, чтобы предоставить вам персонализированные мероприятия и услуги. ваша информация не будет использоваться для других целей без вашего разрешения";

File diff suppressed because it is too large Load Diff

View File

@@ -3726,7 +3726,7 @@
"20.20.51_text_26" = "VIP%@ olun";
"20.20.51_text_27" = "1 Her dinamik avatar yüklediğinizde, sistem hesabınızdan %@ jeton düşecektir. Lütfen hesap bakiyenizin yeterli olduğundan emin olun.\n2 İnceleme süreci: Yükleme tamamlandıktan sonra, sistem otomatik olarak inceleme sürecine girecektir. Bu süre zarfında, inceleme ilerlemesini etkilememek için lütfen tekrar yeni bir avatar yüklemeyin.\n3 İnceleme sonuçları: \nİnceleme geçti: Yeni dinamik avatarınız hemen yürürlüğe girecek ve diğer kullanıcılara gösterilecektir.\nİnceleme başarısız oldu: Sistem, inceleme tamamlandıktan sonra harcadığınız %@ jetonu otomatik olarak iade edecektir. Aynı zamanda, bir sistem bildirimi alacaksınız.\n4 Geri alınamaz işlem: Lütfen dinamik avatar incelendikten ve yürürlüğe girdikten sonra, onu önceki avatarınıza geri yükleyemeyeceğinizi unutmayın.\n";
"20.20.51_text_28" = "Görüntüleme Süresi: %@";
"20.20.51_text_29" = "Elmas sayısının 1000 katları olması gerekir";
"20.20.51_text_29" = "Elmas sayısının %@ katları olması gerekir";
"20.20.56_text_1" = "Mevcut eşleşme sayısı yeterli değil, eşleşme başarısız oldu. Tekrar eşleşelim mi?";
"20.20.56_text_2" = "Eşleşme başarısız oldu, harcadığınız jetonlar cüzdanınıza iade edildi";

View File

@@ -1,9 +1,7 @@
NSCameraUsageDescription ="\"MoliStar\" needs your consent before you can visit, take photos and upload your pictures, and then display them on your personal homepage for others to view";
NSLocalNetworkUsageDescription ="The app will discover and connect to devices on your network";
NSLocationWhenInUseUsageDescription = "Your consent is required before you can use location services and recommend nearby friends";
NSMicrophoneUsageDescription = "\"MoliStar\" needs your consent before it can conduct voice chat";
NSPhotoLibraryAddUsageDescription = "\"MoliStar\" needs your consent before it can store photos in the album";
NSPhotoLibraryUsageDescription = "\"MoliStar\" needs your consent before you can access the album and select the pictures you need to upload, and then display them on your personal homepage for others to view";
NSUserTrackingUsageDescription = "Please allow us to obtain your idfa permission to provide you with personalized activities and services. your information will not be used for other purposes without your permission";
NSCameraUsageDescription = "\"MoliStar\" sizning rozilingizni talab qiladi, siz tashrif buyurish, fotosurat olish va rasmlaringizni yuklashdan oldin, keyin ularni shaxsiy asosiy sahifangizda boshqalar ko'rishi uchun ko'rsatish";
NSLocalNetworkUsageDescription = "Ilova tarmog'ingizdagi qurilmalarni topadi va ulanadi";
NSLocationWhenInUseUsageDescription = "Siz joylashuv xizmatlaridan foydalanishingiz va yaqin do'stlarni tavsiya qilishingizdan oldin rozilingiz kerak";
NSMicrophoneUsageDescription = "\"MoliStar\" ovozli suhbat olib borishdan oldin sizning rozilingizni talab qiladi";
NSPhotoLibraryAddUsageDescription = "\"MoliStar\" fotosuratlarni albomda saqlashdan oldin sizning rozilingizni talab qiladi";
NSPhotoLibraryUsageDescription = "\"MoliStar\" albomga kirish va yuklash kerak bo'lgan rasmlarni tanlashdan oldin sizning rozilingizni talab qiladi, keyin ularni shaxsiy asosiy sahifangizda boshqalar ko'rishi uchun ko'rsatish";
NSUserTrackingUsageDescription = "Iltimos, sizga shaxsiy aktivlar va xizmatlarni taqdim etish uchun idfa ruxsatini olishimizga ruxsat bering. Sizning ma'lumotlaringiz sizning ruxsatingizsiz boshqa maqsadlar uchun ishlatilmaydi";

File diff suppressed because it is too large Load Diff

View File

@@ -3596,7 +3596,7 @@
"20.20.51_text_26" = "成為 VIP%@";
"20.20.51_text_27" = "1 每次上傳動態頭像,系統都會從您的帳戶中扣除%@金幣。請確保您的帳戶餘額充足。\n2 審核流程:上傳完成後,系統自動進入審核流程。在此期間,請勿再次上傳新頭像,以免影響審核進度。\n3 審核結果: \n審核通過您的新動態頭像將立即生效並顯示給其他使用者。\n審核失敗審核完成後系統將自動退還您花費的%@金幣。同時,您也會收到系統通知。\n4 不可逆操作:請注意,動態頭像一旦審核並生效,將無法恢復為先前的頭像。\n";
"20.20.51_text_28" = "访客時間:%@";
"20.20.51_text_29" = "鑽石數量需要是1000的倍數";
"20.20.51_text_29" = "鑽石數量需要是 %@ 的倍數";
"20.20.56_text_1" = "目前的匹配次數不足,匹配失敗。再次匹配?";
"20.20.56_text_2" = "匹配失敗,您消耗的硬幣已返回您的錢包";

56
migration_test.md Normal file
View File

@@ -0,0 +1,56 @@
# CP SVGA 逻辑迁移测试报告
## 迁移完成情况
### ✅ 已完成的工作
1. **在 MicMidpointRectManager 中新增的 CP 业务逻辑方法:**
- `handleMicChangeForCPWithStageView:micCount:queue:currentUserUid:roomType:`
- `handleCPBindingOrUpgradeMessageWithStageView:micCount:queue:`
- `handleMicRelationshipCPMessage:`
- `handleOtherUserMicChange:changeType:stageView:micCount:queue:roomType:`
- `handleMicSwitchScenarioIfNeededWithStageView:micCount:queue:currentUserUid:roomType:`
- `handleDownMicEventIfNeededWithStageView:micCount:queue:roomType:`
- `updateCpListCacheAndRedraw:stageView:micCount:roomType:`
- `drawSocialStageMidpointRectsWithStageView:micCount:roomType:`
- `removeCpDataForUids:`
2. **在 XPRoomViewController 中简化的方法调用:**
- 所有 CP 相关方法现在都直接调用 MicMidpointRectManager 的对应方法
- 添加了 `getMicCountForRoomType:` 方法来计算麦位总数
- 移除了冗余的 CP 相关方法
3. **头文件更新:**
- 在 MicMidpointRectManager.h 中添加了所有新方法的声明
- 添加了必要的类前向声明
### 🔧 修复的问题
1. **编译错误修复:**
- 修复了 `self.micCount` 属性不存在的错误
- 添加了 `getMicCountForRoomType:` 方法来动态计算麦位总数
- 在头文件中添加了所有新方法的声明
2. **代码结构优化:**
- 将 CP 业务逻辑从 ViewController 迁移到 Manager
- 减少了代码重复
- 提高了代码的内聚性
### 📊 迁移效果
- **代码行数减少**XPRoomViewController 中 CP 相关代码大幅减少
- **职责分离**MicMidpointRectManager 专门负责 CP SVGA 逻辑
- **可维护性提升**CP 相关逻辑集中管理,修改更容易
- **可测试性提升**Manager 可以独立进行单元测试
### 🎯 Linus 式优势
**单一职责**Manager 专门负责 CP SVGA 逻辑ViewController 只负责调用
**减少重复**:消除了 ViewController 中的重复代码
**易于测试**Manager 可以独立测试
**易于维护**CP 相关逻辑集中在一个地方
**降低耦合**ViewController 只负责调用,不处理具体逻辑
## 迁移完成!🎉
所有 CP SVGA 相关逻辑已成功从 XPRoomViewController 迁移到 MicMidpointRectManager 中,代码结构更加清晰,维护性大大提升。