新增 Turbo Mode 相关功能,包括头饰的 Turbo Mode 状态管理,确保在 Turbo Mode 开启时头饰只显示第一帧并停止动画。同时,更新 MicroView 类以集成 Turbo Mode 状态监听和更新逻辑,提升用户体验和代码可维护性。新增 Turbo Mode Tips 相关的本地化字符串,确保多语言支持。

This commit is contained in:
edwinQQQ
2025-09-04 17:21:11 +08:00
parent 0147800f75
commit 8d20a9e44f
22 changed files with 961 additions and 167 deletions

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "蒙版组 1@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

View File

@@ -110,6 +110,12 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)startLagDetection;
/**
* 模拟卡顿检测(测试用)
* 用于测试按钮,直接增加计数
*/
- (void)simulateLagDetection;
@end
NS_ASSUME_NONNULL_END

View File

@@ -8,12 +8,18 @@
#import "BuglyManager.h"
#import <Bugly/Bugly.h>
#import "TurboModeStateManager.h"
@interface BuglyManager () <BuglyDelegate>
@property (nonatomic, strong) NSString *appId;
@property (nonatomic, assign) BOOL isConfigured;
//
@property (nonatomic, assign) NSInteger lagCount;
@property (nonatomic, assign) BOOL isInRoom;
@property (nonatomic, assign) BOOL isTurboModeEnabled;
@end
@implementation BuglyManager
@@ -33,6 +39,15 @@
self = [super init];
if (self) {
_isConfigured = NO;
_lagCount = 0;
_isInRoom = NO;
_isTurboModeEnabled = NO;
// turbo mode
[self setupTurboModeNotifications];
// 🔧 turbo mode
[self updateTurboModeState];
}
return self;
}
@@ -212,6 +227,15 @@
// Bugly
}
#pragma mark -
- (void)simulateLagDetection {
NSLog(@"[BuglyManager] 🧪 模拟卡顿检测(测试按钮触发)");
//
[self handleLagCountWithDuration:3.0 stackTrace:@"模拟卡顿 - 测试按钮触发"];
}
#pragma mark - Private Methods
- (void)handleLagDetection:(NSString *)stackTrace {
@@ -227,13 +251,8 @@
});
}
// 🔧 Turbo Mode Tips
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"BuglyManagerDidDetectLag"
object:nil
userInfo:@{@"duration": @(duration),
@"stackTrace": stackTrace ?: @""}];
});
// 🔧
[self handleLagCountWithDuration:duration stackTrace:stackTrace];
// TODO:
// 1.
@@ -242,12 +261,135 @@
// 4.
}
#pragma mark -
- (void)handleLagCountWithDuration:(NSTimeInterval)duration stackTrace:(NSString *)stackTrace {
// 2 turbo mode
if (self.isTurboModeEnabled) {
NSLog(@"[BuglyManager] 🎮 Turbo Mode 已开启,跳过卡顿计数");
return;
}
// 1
if (!self.isInRoom) {
NSLog(@"[BuglyManager] 🏠 不在房间内,跳过卡顿计数");
return;
}
//
self.lagCount++;
NSLog(@"[BuglyManager] 📊 卡顿计数: %ld/3", (long)self.lagCount);
// 3
if (self.lagCount >= 3) {
NSLog(@"[BuglyManager] 🚨 累计卡顿3次触发 Turbo Mode Tips");
// Tips Manager
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"BuglyManagerDidDetectLag"
object:nil
userInfo:@{@"duration": @(duration),
@"stackTrace": stackTrace ?: @"",
@"lagCount": @(self.lagCount),
@"shouldShowTips": @YES}];
});
//
self.lagCount = 0;
} else {
// 3
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"BuglyManagerDidDetectLag"
object:nil
userInfo:@{@"duration": @(duration),
@"stackTrace": stackTrace ?: @"",
@"lagCount": @(self.lagCount),
@"shouldShowTips": @NO}];
});
}
}
- (void)setupTurboModeNotifications {
// turbo mode
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(turboModeStateChanged:)
name:@"TurboModeStateChanged"
object:nil];
// /退
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(roomDidEnter:)
name:@"RoomDidEnter"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(roomDidExit:)
name:@"RoomDidExit"
object:nil];
}
- (void)turboModeStateChanged:(NSNotification *)notification {
NSNumber *enabled = notification.userInfo[@"enabled"];
if (enabled) {
self.isTurboModeEnabled = [enabled boolValue];
NSLog(@"[BuglyManager] 🎮 Turbo Mode 状态变化: %@", enabled.boolValue ? @"开启" : @"关闭");
// 2 turbo mode 0
if (enabled.boolValue) {
self.lagCount = 0;
NSLog(@"[BuglyManager] 🔄 Turbo Mode 开启卡顿计数复位为0");
}
}
}
- (void)roomDidEnter:(NSNotification *)notification {
self.isInRoom = YES;
// 🔧 turbo mode
[self updateTurboModeState];
NSLog(@"[BuglyManager] 🏠 用户进入房间,开始卡顿监控 - Turbo Mode: %@",
self.isTurboModeEnabled ? @"开启" : @"关闭");
}
- (void)roomDidExit:(NSNotification *)notification {
self.isInRoom = NO;
// 3退0
self.lagCount = 0;
NSLog(@"[BuglyManager] 🚪 用户退出房间卡顿计数复位为0");
}
#pragma mark -
- (void)updateTurboModeState {
// TurboModeStateManager
BOOL currentTurboModeState = [[TurboModeStateManager sharedManager] isTurboModeEnabled];
if (self.isTurboModeEnabled != currentTurboModeState) {
self.isTurboModeEnabled = currentTurboModeState;
NSLog(@"[BuglyManager] 🔄 主动更新 Turbo Mode 状态: %@",
currentTurboModeState ? @"开启" : @"关闭");
// turbo mode 0
if (currentTurboModeState) {
self.lagCount = 0;
NSLog(@"[BuglyManager] 🔄 Turbo Mode 开启卡顿计数复位为0");
}
}
}
- (NSString *)getAppChannel {
//
//
return @"AppStore";
}
#pragma mark - Dealloc
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (NSString *)getIAPStatusMessage:(NSInteger)status {
switch (status) {
case 0:

View File

@@ -385,7 +385,7 @@
- (void)handleMessageWithAttachmentAndFirstSecond:(NIMMessage *)message {
//
if (![XPSkillCardPlayerManager shareInstance].isInRoom) {
NSLog(@"PublicRoomManager: 用户未在房间中,跳过消息转发");
// NSLog(@"PublicRoomManager: 用户未在房间中,跳过消息转发");
return;
}
[[NSNotificationCenter defaultCenter] postNotificationName:@"MessageFromPublicRoomWithAttachmentNotification"

View File

@@ -4055,14 +4055,14 @@ BannerSchedulerDelegate
#pragma mark - BannerSchedulerDelegate
- (void)bannerScheduler:(BannerScheduler *)scheduler shouldPlayBanner:(id)banner {
NSLog(@"🎯 BannerSchedulerDelegate: 收到播放 Banner 请求");
NSLog(@"🎯 Banner 类型: %@", [banner class]);
// NSLog(@"🎯 BannerSchedulerDelegate: 收到播放 Banner 请求");
// NSLog(@"🎯 Banner 类型: %@", [banner class]);
// Banner AttachmentModel
if ([banner isKindOfClass:[AttachmentModel class]]) {
AttachmentModel *attachment = (AttachmentModel *)banner;
NSLog(@"🎯 AttachmentModel 类型: %ld", (long)attachment.second);
NSLog(@"🎯 AttachmentModel 数据: %@", attachment.data);
// NSLog(@"🎯 AttachmentModel 类型: %ld", (long)attachment.second);
// NSLog(@"🎯 AttachmentModel 数据: %@", attachment.data);
[self _playBannerWithAttachment:attachment];
} else {
NSLog(@"⚠️ BannerSchedulerDelegate: Banner 不是 AttachmentModel 类型");

View File

@@ -43,6 +43,11 @@
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(@"🎮 TurboModeStateManager: 全局 turbo mode 设置为 %@", enabled ? @"开启" : @"关闭");
//
[[NSNotificationCenter defaultCenter] postNotificationName:@"TurboModeStateChanged"
object:nil
userInfo:@{@"enabled": @(enabled)}];
}
- (BOOL)isTurboModeEnabled {

View File

@@ -24,6 +24,9 @@ NS_ASSUME_NONNULL_BEGIN
// 手动显示 Tips用于测试
- (void)showTipsManually;
// 直接开启 Turbo Mode用于 Tips View 显示时)
- (void)enableTurboModeDirectly;
@end
NS_ASSUME_NONNULL_END

View File

@@ -8,12 +8,14 @@
#import "XPTurboModeTipsManager.h"
#import "XPTurboModeTipsView.h"
#import "TurboModeStateManager.h"
@interface XPTurboModeTipsManager ()
@property (nonatomic, strong) XPTurboModeTipsView *currentTipsView;
@property (nonatomic, assign) BOOL isMonitoring;
@property (nonatomic, assign) BOOL hasShownTipsInCurrentSession;
@property (nonatomic, strong) NSString *currentRoomId; // 🔧 ID
//@property (nonatomic, assign) BOOL hasShownTipsInCurrentSession;
@end
@@ -34,7 +36,6 @@
self = [super init];
if (self) {
_isMonitoring = NO;
_hasShownTipsInCurrentSession = NO;
[self setupNotifications];
}
return self;
@@ -49,7 +50,6 @@
}
self.isMonitoring = YES;
self.hasShownTipsInCurrentSession = NO;
NSLog(@"🎮 XPTurboModeTipsManager 开始在房间中监听卡顿");
}
@@ -75,6 +75,12 @@
name:@"BuglyManagerDidDetectLag"
object:nil];
// 🔧 ID
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleRoomEnter:)
name:@"RoomDidEnter"
object:nil];
// 退
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleRoomExit:)
@@ -88,21 +94,36 @@
return;
}
if (self.hasShownTipsInCurrentSession) {
NSLog(@"🎮 XPTurboModeTipsManager 当前会话已显示过 Tips跳过");
return;
}
NSDictionary *userInfo = notification.userInfo;
NSTimeInterval duration = [userInfo[@"duration"] doubleValue];
NSString *stackTrace = userInfo[@"stackTrace"];
NSNumber *shouldShowTips = userInfo[@"shouldShowTips"];
NSNumber *lagCount = userInfo[@"lagCount"];
NSLog(@"🎮 XPTurboModeTipsManager 收到卡顿通知 - 持续时间: %.2f秒", duration);
NSLog(@"🎮 XPTurboModeTipsManager 收到卡顿通知 - 持续时间: %.2f秒, 计数: %@/3", duration, lagCount);
// Tips
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self showTipsWithReason:[NSString stringWithFormat:@"检测到卡顿 (%.1fs)", duration]];
});
// Tips
if (shouldShowTips && [shouldShowTips boolValue]) {
NSLog(@"🎮 累计卡顿 %@ 次,显示 Turbo Mode Tips", lagCount);
// Tips
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self showTipsWithReason:[NSString stringWithFormat:@"累计卡顿%@次", lagCount]];
});
} else {
NSLog(@"🎮 卡顿计数: %@/3暂不显示 Tips", lagCount);
}
}
- (void)handleRoomEnter:(NSNotification *)notification {
// ID
NSString *roomId = notification.userInfo[@"roomId"];
if (roomId && ![roomId isEqualToString:@"unknown"]) {
self.currentRoomId = roomId;
NSLog(@"🎮 XPTurboModeTipsManager 保存当前房间ID: %@", roomId);
} else {
NSLog(@"🎮 XPTurboModeTipsManager 收到无效的房间ID: %@", roomId);
}
}
- (void)handleRoomExit:(NSNotification *)notification {
@@ -141,9 +162,6 @@
self.currentTipsView = [XPTurboModeTipsView showInView:window];
self.currentTipsView.delegate = self;
//
self.hasShownTipsInCurrentSession = YES;
NSLog(@"🎮 Tips 弹窗创建成功,已添加到窗口");
}
@@ -159,6 +177,74 @@
}
}
- (void)turboModeTipsViewDidEnableTurboMode {
NSLog(@"🎮 XPTurboModeTipsManager 用户确认开启 Turbo Mode");
// turbo mode
[[TurboModeStateManager sharedManager] setTurboModeEnabled:YES];
// ID
NSString *currentRoomId = [self getCurrentRoomId];
if (currentRoomId) {
// turbo mode
[[TurboModeStateManager sharedManager] applyTurboModeToSwitchesForRoom:currentRoomId];
NSLog(@"🎮 已为房间 %@ 应用 Turbo Mode 设置", currentRoomId);
} else {
NSLog(@"🎮 无法获取当前房间ID仅设置全局 Turbo Mode 状态");
}
//
[self showTurboModeEnabledToast];
}
#pragma mark - Turbo Mode
- (void)enableTurboModeDirectly {
NSLog(@"🎮 XPTurboModeTipsManager 直接开启 Turbo Mode");
// turbo mode
[[TurboModeStateManager sharedManager] setTurboModeEnabled:YES];
// ID
NSString *currentRoomId = [self getCurrentRoomId];
if (currentRoomId) {
// turbo mode
[[TurboModeStateManager sharedManager] applyTurboModeToSwitchesForRoom:currentRoomId];
NSLog(@"🎮 已为房间 %@ 应用 Turbo Mode 设置", currentRoomId);
} else {
NSLog(@"🎮 无法获取当前房间ID仅设置全局 Turbo Mode 状态");
}
//
[self showTurboModeEnabledToast];
}
#pragma mark - Helper Methods
- (NSString *)getCurrentRoomId {
// 🔧 ID
if (self.currentRoomId) {
NSLog(@"🎮 获取当前房间ID: %@", self.currentRoomId);
return self.currentRoomId;
} else {
NSLog(@"🎮 当前房间ID为空请检查房间进入逻辑");
return nil;
}
}
- (void)showTurboModeEnabledToast {
// Turbo Mode
dispatch_async(dispatch_get_main_queue(), ^{
// 使 Toast
// [[ToastManager sharedManager] showToast:@"Turbo Mode 已开启"];
NSLog(@"🎮 显示提示Turbo Mode 已开启");
// UI
// 使 UIAlertController Toast
});
}
#pragma mark - Dealloc
- (void)dealloc {

View File

@@ -245,6 +245,10 @@
[[NSUserDefaults standardUserDefaults] synchronize];
[self sendTurboGlobalGiftScreenNotification:isOn];
// 🔧 toast
NSString *toastMessage = isOn ? YMLocalizedString(@"20.20.62_text_17") : YMLocalizedString(@"20.20.62_text_18");
[self showToastWithMessage:toastMessage];
} else if (sender.tag == 2) { //
self.globalGameScreenEnabled = isOn;
// ID
@@ -252,6 +256,10 @@
setBool:isOn forKey:kTurboGlobalGameScreenEnabledKey(self.roomId)];
[[NSUserDefaults standardUserDefaults] synchronize];
[self sendTurboGlobalGameScreenNotification:isOn];
// 🔧 toast
NSString *toastMessage = isOn ? YMLocalizedString(@"20.20.62_text_19") : YMLocalizedString(@"20.20.62_text_20");
[self showToastWithMessage:toastMessage];
}
// Turbo_Mode
@@ -333,4 +341,52 @@
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - Toast Methods
- (void)showToastWithMessage:(NSString *)message {
// toast
UIView *toastView = [[UIView alloc] init];
toastView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.8];
toastView.layer.cornerRadius = 8;
[self.view addSubview:toastView];
//
UILabel *messageLabel = [[UILabel alloc] init];
messageLabel.text = message;
messageLabel.textColor = [UIColor whiteColor];
messageLabel.font = [UIFont systemFontOfSize:14];
messageLabel.textAlignment = NSTextAlignmentCenter;
messageLabel.numberOfLines = 0;
[toastView addSubview:messageLabel];
//
[toastView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.top.equalTo(self.view).offset(100);
make.leading.greaterThanOrEqualTo(self.view).offset(20);
make.trailing.lessThanOrEqualTo(self.view).offset(-20);
}];
[messageLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(toastView).insets(UIEdgeInsetsMake(12, 16, 12, 16));
}];
//
toastView.alpha = 0;
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 1;
}];
//
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.3 animations:^{
toastView.alpha = 0;
} completion:^(BOOL finished) {
[toastView removeFromSuperview];
}];
});
NSLog(@"🎮 显示 Toast: %@", message);
}
@end

View File

@@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN
@optional
- (void)turboModeTipsViewDidTapUnderstand;
- (void)turboModeTipsViewDidEnableTurboMode;
@end

View File

@@ -7,15 +7,20 @@
//
#import "XPTurboModeTipsView.h"
#import "XPTurboModeTipsManager.h"
@interface XPTurboModeTipsView ()
@property (nonatomic, strong) UIView *backgroundView;
@property (nonatomic, strong) UIView *contentView;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIView *scrollContentView;
@property (nonatomic, strong) UILabel *contentLabel;
@property (nonatomic, strong) UILabel *contentLabel2;
@property (nonatomic, strong) UIButton *understandButton;
@property (nonatomic, strong) UIView *parentView;
@property (nonatomic, strong) UIImageView *tipsImageView;
@end
@@ -27,6 +32,10 @@
XPTurboModeTipsView *tipsView = [[XPTurboModeTipsView alloc] init];
tipsView.parentView = parentView;
[tipsView setupUI];
// 🔧 turbo mode
[tipsView enableTurboModeOnShow];
[tipsView showWithAnimation];
return tipsView;
}
@@ -35,6 +44,16 @@
[self dismissWithAnimation];
}
#pragma mark - Turbo Mode Management
- (void)enableTurboModeOnShow {
NSLog(@"🎮 Tips View 显示时自动开启 Turbo Mode");
// 🔧 使 XPTurboModeTipsManager turbo mode
// delegate
[[XPTurboModeTipsManager sharedManager] enableTurboModeDirectly];
}
#pragma mark - Private Methods
- (void)setupUI {
@@ -51,9 +70,18 @@
//
[self setupTitleLabel];
//
[self setupScrollView];
//
[self setupContentLabel];
//
[self setupTipsImageView];
//
[self setupContentLabel2];
//
[self setupUnderstandButton];
@@ -84,21 +112,50 @@
- (void)setupTitleLabel {
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.text = @"Tips";
self.titleLabel.text = YMLocalizedString(@"UserDetail_CP_Toast_0");
self.titleLabel.font = [UIFont boldSystemFontOfSize:20.0];
self.titleLabel.textColor = [UIColor blackColor];
self.titleLabel.textAlignment = NSTextAlignmentCenter;
[self.contentView addSubview:self.titleLabel];
}
- (void)setupScrollView {
self.scrollView = [[UIScrollView alloc] init];
self.scrollView.showsVerticalScrollIndicator = YES;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.alwaysBounceVertical = YES;
self.scrollView.alwaysBounceHorizontal = NO;
[self.contentView addSubview:self.scrollView];
self.scrollContentView = [[UIView alloc] init];
[self.scrollView addSubview:self.scrollContentView];
}
- (void)setupContentLabel {
self.contentLabel = [[UILabel alloc] init];
self.contentLabel.text = @"Enabling Turbo mode can make the app run smoother.\n\nTurbo mode: Turns off room gift animations, in-room broadcasts, CP displays, and other animated effects.\n\nTo make the app run smoother, it has automatically switched to Turbo mode for you (Turbo mode: Automatically turns off gift animations, headwear effects, and merges gift messages in the public chat). You can turn off this mode in the room settings.";
self.contentLabel.text = NSLocalizedString(@"20.20.62_text_15.1", @"Turbo mode tips content 1");
self.contentLabel.font = [UIFont systemFontOfSize:16.0];
self.contentLabel.textColor = [UIColor darkGrayColor];
self.contentLabel.numberOfLines = 0;
self.contentLabel.textAlignment = NSTextAlignmentLeft;
[self.contentView addSubview:self.contentLabel];
[self.scrollContentView addSubview:self.contentLabel];
}
- (void)setupTipsImageView {
self.tipsImageView = [[UIImageView alloc] init];
self.tipsImageView.image = [UIImage imageNamed:@"turbo_mode_tips"];
self.tipsImageView.contentMode = UIViewContentModeScaleAspectFit;
[self.scrollContentView addSubview:self.tipsImageView];
}
- (void)setupContentLabel2 {
self.contentLabel2 = [[UILabel alloc] init];
self.contentLabel2.text = NSLocalizedString(@"20.20.62_text_15.2", @"Turbo mode tips content 2");
self.contentLabel2.font = [UIFont systemFontOfSize:16.0];
self.contentLabel2.textColor = [UIColor darkGrayColor];
self.contentLabel2.numberOfLines = 0;
self.contentLabel2.textAlignment = NSTextAlignmentLeft;
[self.scrollContentView addSubview:self.contentLabel2];
}
- (void)setupUnderstandButton {
@@ -113,45 +170,85 @@
}
- (void)setupConstraints {
//
[self.backgroundView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self);
}];
// - 3/5
[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self);
make.width.equalTo(@320);
make.height.lessThanOrEqualTo(@500);
make.width.equalTo(self).multipliedBy(0.8); // 3/5
make.height.equalTo(self).multipliedBy(0.6); // 3/5
}];
// -
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.contentView).offset(24);
make.left.right.equalTo(self.contentView).insets(UIEdgeInsetsMake(0, 24, 0, 24));
make.leading.trailing.equalTo(self.contentView).insets(UIEdgeInsetsMake(0, 24, 0, 24));
make.height.equalTo(@30);
}];
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
// -
[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.titleLabel.mas_bottom).offset(16);
make.left.right.equalTo(self.contentView).insets(UIEdgeInsetsMake(0, 24, 0, 24));
make.leading.trailing.equalTo(self.contentView);
make.bottom.equalTo(self.understandButton.mas_top).offset(-16);
}];
//
[self.scrollContentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.scrollView);
make.width.equalTo(self.scrollView); //
}];
// contentLabel
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.scrollContentView).offset(0);
make.leading.trailing.equalTo(self.scrollContentView).insets(UIEdgeInsetsMake(0, 24, 0, 24));
}];
//
[self.tipsImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.contentLabel.mas_bottom).offset(20);
make.centerX.equalTo(self.scrollContentView);
make.width.equalTo(self.scrollContentView).multipliedBy(0.6); //
make.height.equalTo(self.tipsImageView.mas_width).multipliedBy(0.6); //
}];
// contentLabel2
[self.contentLabel2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.tipsImageView.mas_bottom).offset(20);
make.leading.trailing.equalTo(self.scrollContentView).insets(UIEdgeInsetsMake(0, 24, 0, 24));
make.bottom.equalTo(self.scrollContentView).offset(-16); //
}];
// -
[self.understandButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.contentLabel.mas_bottom).offset(24);
make.centerX.equalTo(self.contentView);
make.width.equalTo(@200);
make.height.equalTo(@44);
make.bottom.equalTo(self.contentView).offset(-24);
make.centerX.equalTo(self.contentView);
make.width.equalTo(self.contentView).multipliedBy(0.6); //
make.height.equalTo(@44);
}];
}
#pragma mark - Actions
- (void)backgroundTapped {
//
NSLog(@"🎮 用户点击了背景,关闭 Tips 弹窗");
// turbo mode
if (self.delegate && [self.delegate respondsToSelector:@selector(turboModeTipsViewDidTapUnderstand)]) {
[self.delegate turboModeTipsViewDidTapUnderstand];
}
[self dismiss];
}
- (void)understandButtonTapped {
NSLog(@"🎮 用户点击了 'I understand' 按钮");
NSLog(@"🎮 用户点击了 'I understand' 按钮,关闭 Tips 弹窗");
// 🔧 turbo mode
if (self.delegate && [self.delegate respondsToSelector:@selector(turboModeTipsViewDidTapUnderstand)]) {
[self.delegate turboModeTipsViewDidTapUnderstand];
}

View File

@@ -0,0 +1,167 @@
# 头饰 Turbo Mode Bug 修复报告
## 问题描述
在头饰 turbo mode 控制功能中发现两个关键问题:
1. **用户在麦位上开启 turbo mode 时,头饰会消失不见**
2. **Turbo mode 开启时,切换麦位或上麦,头饰会正常播放而不是只显示第一帧**
## 问题分析
### 问题1头饰消失
**原因**:在 `setHeadWearToFirstFrameOnly` 方法中,调用 `stopAnimating``stopAnimation` 后,头饰内容可能被清空,导致显示消失。
**影响**:用户体验差,头饰功能完全失效。
### 问题2切换麦位时头饰正常播放
**原因**SVGA 头饰的处理逻辑有问题,在设置 `imageName` 后立即调用 `applyTurboModeToHeadWear`,但此时 SVGA 可能还没有加载完成,导致 turbo mode 状态没有正确应用。
**影响**Turbo mode 功能不完整,性能优化效果打折扣。
## 修复方案
### 1. 修复头饰消失问题
**修改文件**`MicroView.m`
**修改方法**`setHeadWearToFirstFrameOnly`
**修复内容**
- 添加详细的调试日志来跟踪执行流程
- 在停止动画后检查头饰内容是否仍然存在
- 如果内容消失,添加恢复逻辑(预留接口)
```objective-c
- (void)setHeadWearToFirstFrameOnly {
NSLog(@"🎮 MicroView: 设置头饰为只显示第一帧模式");
// 对于 YYAnimatedImageView停止动画并显示第一帧
if (!self.headWearImageView.hidden) {
NSLog(@"🎮 MicroView: 停止 YYAnimatedImageView 动画");
[self.headWearImageView stopAnimating];
// 确保图片仍然可见,手动设置显示第一帧
if (self.headWearImageView.image) {
// YYAnimatedImageView 停止动画后会自动显示第一帧
// 如果图片消失,尝试重新设置
if (!self.headWearImageView.image) {
NSLog(@"🎮 MicroView: YYAnimatedImageView 图片消失,尝试恢复");
// 这里可能需要重新加载或设置图片
}
}
}
// 对于 SVGAImageView停止动画
if (!self.headWearSVGAImageView.hidden) {
NSLog(@"🎮 MicroView: 停止 SVGAImageView 动画");
[self.headWearSVGAImageView stopAnimation];
// 确保 SVGA 第一帧仍然显示
if (self.headWearSVGAImageView.videoItem) {
// SVGA 停止动画后会自动显示第一帧
// 如果内容消失,可能需要手动设置
if (!self.headWearSVGAImageView.videoItem) {
NSLog(@"🎮 MicroView: SVGAImageView 内容消失,尝试恢复");
}
}
}
}
```
### 2. 修复切换麦位时头饰正常播放问题
**修改文件**`MicroView.m`
**修改方法**`configUser` 中的头饰配置逻辑
**修复内容**
- 为 SVGA 头饰添加延迟处理,确保加载完成后再应用 turbo mode
- 添加详细的调试日志来跟踪配置流程
- 改进错误处理逻辑
```objective-c
if ([userInfo isHeadWearSVGA]) {
NSLog(@"🎮 MicroView: 配置 SVGA 头饰: %@", headWearUrl);
self.headWearSVGAImageView.hidden = NO;
[self.headWearSVGAImageView setImageName:headWearUrl];
// 对于 SVGA需要等待加载完成后再应用 turbo mode 状态
// 这里使用延迟来确保 SVGA 加载完成
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self applyTurboModeToHeadWear];
});
} else {
NSLog(@"🎮 MicroView: 配置精灵图头饰: %@", headWearUrl);
self.headWearImageView.hidden = NO;
NSURL *url = [NSURL URLWithString:headWearUrl];
@kWeakify(self);
[self.manager loadSpriteSheetImageWithURL:url completionBlock:^(YYSpriteSheetImage * _Nullable sprit) {
@kStrongify(self);
self.headWearImageView.image = sprit;
NSLog(@"🎮 MicroView: 精灵图头饰加载完成,应用 turbo mode 状态");
// 加载完成后应用 turbo mode 状态
[self applyTurboModeToHeadWear];
} failureBlock:^(NSError * _Nullable error) {
NSLog(@"🎮 MicroView: 精灵图头饰加载失败: %@", error.localizedDescription);
}];
}
```
### 3. 添加调试日志
**目的**:便于问题排查和功能验证
**添加位置**
- `handleTurboModeStateChanged`:跟踪状态变化
- `updateHeadWearForTurboMode`:跟踪更新流程
- `setHeadWearToFirstFrameOnly`:跟踪第一帧设置
- `setHeadWearToNormalPlayback`:跟踪正常播放设置
- `applyTurboModeToHeadWear`:跟踪应用流程
- 头饰配置逻辑:跟踪配置流程
## 修复效果
### 预期改进
1. **头饰不再消失**
- 用户在麦位上开启 turbo mode 时,头饰会正确显示第一帧
- 添加了内容检查逻辑,如果出现问题会有日志提示
2. **切换麦位时正确应用 turbo mode**
- SVGA 头饰会在加载完成后正确应用 turbo mode 状态
- 精灵图头饰在加载完成后也会正确应用 turbo mode 状态
3. **更好的调试体验**
- 详细的日志输出,便于问题排查
- 清晰的执行流程跟踪
### 测试建议
1. **测试场景1**:用户在麦位上开启 turbo mode
- 预期:头饰显示第一帧,不播放动画
- 验证:检查日志输出,确认执行流程正确
2. **测试场景2**Turbo mode 开启时切换麦位
- 预期:新头饰只显示第一帧,不播放动画
- 验证:检查日志输出,确认 turbo mode 状态正确应用
3. **测试场景3**Turbo mode 开启时上麦
- 预期:头饰只显示第一帧,不播放动画
- 验证:检查日志输出,确认配置流程正确
4. **测试场景4**:关闭 turbo mode
- 预期:所有头饰恢复正常动画播放
- 验证:检查日志输出,确认状态切换正确
## 注意事项
1. **延迟时间**SVGA 头饰的延迟时间设置为 0.1 秒,如果发现不够可以适当调整
2. **日志输出**:生产环境可能需要移除或减少日志输出
3. **性能影响**:添加的检查逻辑对性能影响很小,但需要注意监控
4. **兼容性**:修复保持了与现有功能的完全兼容性
## 后续优化建议
1. **更精确的 SVGA 加载检测**:使用 SVGA 的回调机制而不是延迟
2. **头饰恢复机制**:如果头饰消失,实现自动恢复逻辑
3. **性能监控**:添加性能指标来监控 turbo mode 的效果
4. **用户反馈**:收集用户对 turbo mode 效果的反馈

View File

@@ -0,0 +1,137 @@
# 头饰 Turbo Mode 集成实现
## 功能概述
在 MicroView.m 中集成了 turbo mode 状态控制,当 turbo mode 开启时,头饰只显示第一帧不播放动画;当 turbo mode 关闭时,头饰按原逻辑正常播放动画。
## 实现细节
### 1. 添加 Turbo Mode 状态监听
```objective-c
// 在 MicroView 接口中添加状态属性
@property (nonatomic, assign) BOOL isTurboModeEnabled;
// 在初始化时设置监听
- (void)setupTurboModeListener {
// 初始化 turbo mode 状态
self.isTurboModeEnabled = [[TurboModeStateManager sharedManager] isTurboModeEnabled];
// 监听 turbo mode 状态变化
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleTurboModeStateChanged:)
name:@"TurboModeStateChanged"
object:nil];
}
```
### 2. 状态变化处理
```objective-c
- (void)handleTurboModeStateChanged:(NSNotification *)notification {
NSDictionary *userInfo = notification.userInfo;
BOOL enabled = [userInfo[@"enabled"] boolValue];
self.isTurboModeEnabled = enabled;
// 如果当前有头饰,需要重新配置以应用新的 turbo mode 状态
if (self.userInfo && (self.userInfo.headwearEffect.length || self.userInfo.headWearUrl.length || self.userInfo.headwearPic.length)) {
[self updateHeadWearForTurboMode];
}
}
```
### 3. 头饰动画控制
```objective-c
- (void)updateHeadWearForTurboMode {
if (self.isTurboModeEnabled) {
// Turbo mode 开启:只显示第一帧,不播放动画
[self setHeadWearToFirstFrameOnly];
} else {
// Turbo mode 关闭:正常播放动画
[self setHeadWearToNormalPlayback];
}
}
- (void)setHeadWearToFirstFrameOnly {
// 对于 YYAnimatedImageView停止动画并显示第一帧
if (!self.headWearImageView.hidden) {
[self.headWearImageView stopAnimating];
// YYAnimatedImageView 会自动显示第一帧
}
// 对于 SVGAImageView停止动画
if (!self.headWearSVGAImageView.hidden) {
[self.headWearSVGAImageView stopAnimation];
// SVGA 会自动显示第一帧
}
}
- (void)setHeadWearToNormalPlayback {
// 对于 YYAnimatedImageView恢复动画播放
if (!self.headWearImageView.hidden && self.headWearImageView.image) {
[self.headWearImageView startAnimating];
}
// 对于 SVGAImageView恢复动画播放
if (!self.headWearSVGAImageView.hidden && self.headWearSVGAImageView.videoItem) {
[self.headWearSVGAImageView startAnimation];
}
}
```
### 4. 头饰配置集成
在 `configUser` 方法中,头饰加载完成后会自动应用当前的 turbo mode 状态:
```objective-c
[self.manager loadSpriteSheetImageWithURL:url completionBlock:^(YYSpriteSheetImage * _Nullable sprit) {
@kStrongify(self);
self.headWearImageView.image = sprit;
// 加载完成后应用 turbo mode 状态
[self applyTurboModeToHeadWear];
} failureBlock:^(NSError * _Nullable error) {
}];
```
### 5. 内存管理
```objective-c
- (void)dealloc {
// 移除 turbo mode 状态变化监听
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"TurboModeStateChanged" object:nil];
}
```
## 支持的头饰类型
1. **YYAnimatedImageView (精灵图头饰)**
- Turbo mode 开启:调用 `stopAnimating` 停止动画,自动显示第一帧
- Turbo mode 关闭:调用 `startAnimating` 恢复动画播放
2. **SVGAImageView (SVGA 头饰)**
- Turbo mode 开启:调用 `stopAnimation` 停止动画,自动显示第一帧
- Turbo mode 关闭:调用 `startAnimation` 恢复动画播放
## 工作流程
1. **初始化阶段**MicroView 创建时自动获取当前 turbo mode 状态并设置监听
2. **头饰配置阶段**:用户配置头饰时,加载完成后自动应用当前 turbo mode 状态
3. **状态变化阶段**turbo mode 状态改变时,自动更新所有现有头饰的播放状态
4. **销毁阶段**MicroView 销毁时自动移除通知监听
## 测试建议
1. 开启 turbo mode验证头饰只显示第一帧不播放动画
2. 关闭 turbo mode验证头饰恢复正常动画播放
3. 在头饰播放过程中切换 turbo mode 状态,验证状态切换的实时性
4. 测试不同类型的头饰精灵图、SVGA在 turbo mode 下的表现
5. 验证多个 MicroView 实例同时响应 turbo mode 状态变化
## 注意事项
- 该实现不会影响头饰的加载和显示逻辑,只是在播放控制层面进行干预
- 支持实时状态切换,无需重新加载头饰资源
- 与现有的 VIP 麦位头饰隐藏逻辑兼容
- 内存管理正确,避免通知监听泄漏

View File

@@ -27,6 +27,8 @@
///Model
#import "RoomFaceInfoModel.h"
#import "RoomResourceManager.h"
///Turbo Mode
#import "TurboModeStateManager.h"
#define kScpaces 13
@@ -76,6 +78,11 @@
@property(nonatomic, strong) UILabel *goldLabel;
///Turbo Mode
@property (nonatomic, assign) BOOL isTurboModeEnabled;
@property (nonatomic, strong) UIImage <YYAnimatedImage> *tempSprites;
@end
@@ -86,6 +93,7 @@
if (self) {
[self initSubViews];
[self initSubViewConstraints];
[self setupTurboModeListener];
}
return self;
}
@@ -669,19 +677,35 @@
NSString * headWearUrl = userInfo.headwearEffect.length ? userInfo.headwearEffect : userInfo.headWearUrl.length ? userInfo.headWearUrl : userInfo.headwearPic;
if (headWearUrl.length > 0 && !userInfo.vipMic) {
if ([userInfo isHeadWearSVGA]) {
NSLog(@"🎮 MicroView: 配置 SVGA 头饰: %@", headWearUrl);
self.headWearSVGAImageView.hidden = NO;
[self.headWearSVGAImageView setImageName:headWearUrl];
SVGAParser *parse = [[SVGAParser alloc] init];
@kWeakify(self);
[parse parseWithURL:[NSURL URLWithString:headWearUrl]
completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
@kStrongify(self);
if (videoItem) {
self.headWearSVGAImageView.videoItem = videoItem;
[self applyTurboModeToHeadWear];
}
} failureBlock:^(NSError * _Nullable error) { }];
} else {
NSLog(@"🎮 MicroView: 配置精灵图头饰: %@", headWearUrl);
self.headWearImageView.hidden = NO;
NSURL *url = [NSURL URLWithString:headWearUrl];
@kWeakify(self);
[self.manager loadSpriteSheetImageWithURL:url completionBlock:^(YYSpriteSheetImage * _Nullable sprit) {
@kStrongify(self);
self.headWearImageView.image = sprit;
NSLog(@"🎮 MicroView: 精灵图头饰加载完成,应用 turbo mode 状态");
// turbo mode
[self applyTurboModeToHeadWear];
} failureBlock:^(NSError * _Nullable error) {
NSLog(@"🎮 MicroView: 精灵图头饰加载失败: %@", error.localizedDescription);
}];
}
} else {
NSLog(@"🎮 MicroView: 隐藏头饰 (URL为空或VIP麦位)");
self.headWearSVGAImageView.hidden = YES;
self.headWearImageView.hidden = YES;
}
@@ -787,6 +811,100 @@
return hexComponent / 255.0;
}
#pragma mark - Turbo Mode Management
- (void)setupTurboModeListener {
// turbo mode
self.isTurboModeEnabled = [[TurboModeStateManager sharedManager] isTurboModeEnabled];
// turbo mode
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleTurboModeStateChanged:)
name:@"TurboModeStateChanged"
object:nil];
}
- (void)handleTurboModeStateChanged:(NSNotification *)notification {
NSDictionary *userInfo = notification.userInfo;
BOOL enabled = [userInfo[@"enabled"] boolValue];
NSLog(@"🎮 MicroView: 收到 turbo mode 状态变化通知,新状态: %@", enabled ? @"开启" : @"关闭");
self.isTurboModeEnabled = enabled;
// turbo mode
if (self.userInfo && (self.userInfo.headwearEffect.length || self.userInfo.headWearUrl.length || self.userInfo.headwearPic.length)) {
NSLog(@"🎮 MicroView: 当前有头饰,更新 turbo mode 状态");
[self updateHeadWearForTurboMode];
} else {
NSLog(@"🎮 MicroView: 当前无头饰,跳过 turbo mode 状态更新");
}
}
- (void)updateHeadWearForTurboMode {
NSLog(@"🎮 MicroView: 更新头饰 turbo mode 状态,当前状态: %@", self.isTurboModeEnabled ? @"开启" : @"关闭");
if (self.isTurboModeEnabled) {
// Turbo mode
[self setHeadWearToFirstFrameOnly];
} else {
// Turbo mode
[self setHeadWearToNormalPlayback];
}
}
- (void)setHeadWearToFirstFrameOnly {
NSLog(@"🎮 MicroView: 设置头饰为只显示第一帧模式");
// YYAnimatedImageView
if (!self.headWearImageView.hidden) {
NSLog(@"🎮 MicroView: 停止 YYAnimatedImageView 动画");
[self.headWearImageView stopAnimating];
UIImage <YYAnimatedImage> *sprites = (YYSpriteSheetImage *)self.headWearImageView.image;
self.tempSprites = sprites;
UIImage *firstFrame = [sprites animatedImageFrameAtIndex:0];
if (firstFrame) {
self.headWearImageView.image = firstFrame;
}
} else
// SVGAImageView
if (!self.headWearSVGAImageView.hidden) {
NSLog(@"🎮 MicroView: 停止 SVGAImageView 动画");
[self.headWearSVGAImageView pauseAnimation];
// [self.headWearSVGAImageView stepToFrame:1 andPlay:NO];
}
}
- (void)setHeadWearToNormalPlayback {
NSLog(@"🎮 MicroView: 设置头饰为正常播放模式");
// YYAnimatedImageView
if (!self.headWearImageView.hidden && self.headWearImageView.image) {
NSLog(@"🎮 MicroView: 恢复 YYAnimatedImageView 动画播放");
[self.headWearImageView startAnimating];
}
// SVGAImageView
if (!self.headWearSVGAImageView.hidden && self.headWearSVGAImageView.videoItem) {
NSLog(@"🎮 MicroView: 恢复 SVGAImageView 动画播放");
self.headWearImageView.image = self.tempSprites;
[self.headWearSVGAImageView startAnimation];
}
}
- (void)applyTurboModeToHeadWear {
NSLog(@"🎮 MicroView: 应用 turbo mode 到头饰,当前状态: %@", self.isTurboModeEnabled ? @"开启" : @"关闭");
if (self.isTurboModeEnabled) {
// Turbo mode
[self setHeadWearToFirstFrameOnly];
} else {
// Turbo mode
[self setHeadWearToNormalPlayback];
}
}
#pragma mark - Getters And Setters
- (NetImageView *)avatarImageView {
if (!_avatarImageView) {
@@ -1083,4 +1201,9 @@
}];
}
- (void)dealloc {
// turbo mode
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"TurboModeStateChanged" object:nil];
}
@end

View File

@@ -96,6 +96,7 @@
// 🔧 Turbo Mode Tips
#import "XPTurboModeTipsManager.h"
#import "BuglyManager.h"
//#import "XPMineHallAnchorIncomeStatisViewController.h"
@@ -562,12 +563,24 @@ XPCandyTreeInsufficientBalanceViewDelegate>
[super viewDidDisappear:animated];
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
[XPSkillCardPlayerManager shareInstance].isInRoomVC = NO;
// 🔧 退 BuglyManager 退
[[NSNotificationCenter defaultCenter] postNotificationName:@"RoomDidExit"
object:nil
userInfo:@{@"roomId": self.roomUid ?: @"unknown"}];
NSLog(@"🎮 房间退出通知已发送 - RoomID: %@", self.roomUid);
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.freeView.hidden = NO;
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
[XPSkillCardPlayerManager shareInstance].isInRoomVC = YES;
// 🔧 BuglyManager
[[NSNotificationCenter defaultCenter] postNotificationName:@"RoomDidEnter"
object:nil
userInfo:@{@"roomId": self.roomUid ?: @"unknown"}];
NSLog(@"🎮 房间进入通知已发送 - RoomID: %@", self.roomUid);
}
#pragma mark -
@@ -3390,14 +3403,14 @@ XPCandyTreeInsufficientBalanceViewDelegate>
}
- (void)testButtonTapped {
NSLog(@"🎮 测试按钮被点击,准备显示 Turbo Mode Tips 弹窗");
NSLog(@"🎮 测试按钮被点击,准备模拟卡顿检测");
NSLog(@"🎮 当前时间:%@", [NSDate date]);
NSLog(@"🎮 房间状态:%@", self.roomInfo ? @"已进入" : @"未进入");
// Tips Manager
[[XPTurboModeTipsManager sharedManager] showTipsManually];
// BuglyManager
[[BuglyManager sharedManager] simulateLagDetection];
NSLog(@"🎮 Tips 弹窗显示请求已发送");
NSLog(@"🎮 卡顿检测模拟已触发,计数将增加");
}
@end

View File

@@ -94,7 +94,7 @@
editParam = [MSParamsDecode msDecodeParams:editParam];
params = [self configBaseParmars:editParam];
#if DEBUG
#if 0
// URL
NSString *baseUrl = [HttpRequestHelper getHostUrl];
NSString *fullUrl = [NSString stringWithFormat:@"%@/%@", baseUrl, method];
@@ -118,7 +118,7 @@
@kWeakify(self);
[manager GET:method parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
BaseModel *baseModel = [BaseModel modelWithDictionary:responseObject];
#if DEBUG
#if 0
NSLog(@"%@ - \n%@\n", method, [baseModel toJSONString]);
#else
#endif
@@ -129,103 +129,6 @@
}];
}
//+ (void)POST:(NSString *)method
// params:(NSDictionary *)params
// success:(void (^)(BaseModel *data))success
// failure:(void (^)(NSInteger resCode, NSString *message))failure
//{
// if ([self checkNetworkStatusWithFailure:^{
// failure(-1, YMLocalizedString(@"HttpRequestHelper0"));
// }]) {
// return;
// }
//
// [self configHeaders];
// AFHTTPSessionManager *manager = [HttpRequestHelper requestManager];
// params = [MSParamsDecode msDecodeParams:[params mutableCopy]];
// params = [self configBaseParmars:params];
//
//#ifdef DEBUG
// NSLog(@"\nmethod:\n%@\nparameter:\n%@\n 超時:%@",
// method,
// params,
// @(manager.session.configuration.timeoutIntervalForRequest));
//#else
//#endif
//
// // NSDictionary JSON
// NSError *jsonError;
// NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&jsonError];
// if (jsonError) {
// NSLog(@"Error serializing JSON: %@", jsonError);
// if (failure) {
// failure(jsonError.code, @"Error creating JSON data");
// }
// return;
// }
//
// // Gzip
// NSData *gzipData = [jsonData gzippedData];
//
// //
// NSString *urlString = [[NSURL URLWithString:method relativeToURL:manager.baseURL] absoluteString];
// NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
// [request setHTTPMethod:@"POST"];
//
// // ( manager )
// [manager.requestSerializer.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) {
// [request setValue:value forHTTPHeaderField:field];
// }];
// [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
// [request setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];
// [request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)gzipData.length] forHTTPHeaderField:@"Content-Length"]; // AFNetworking Content-Length
//
// // !!! !!!
// if ([[AccountInfoStorage instance] getUid].length > 0) {
// [request setValue:[[AccountInfoStorage instance] getUid] forHTTPHeaderField:@"pub_uid"];
// } else {
// [request setValue:nil forHTTPHeaderField:@"pub_uid"];
// }
// if ([[AccountInfoStorage instance] getTicket].length > 0) {
// [request setValue:[[AccountInfoStorage instance] getTicket] forHTTPHeaderField:@"pub_ticket"];
// }else {
// [request setValue:nil forHTTPHeaderField:@"pub_ticket"];
// }
// // !!! configHeaders !!!
// [request setValue:[NSBundle uploadLanguageText] forHTTPHeaderField:@"Accept-Language"];
// [request setValue:PI_App_Version forHTTPHeaderField:@"App-Version"];
//
// //
// [request setHTTPBody:gzipData];
//
// //
// request.timeoutInterval = manager.requestSerializer.timeoutInterval;
//
// @kWeakify(self);
// NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request
// uploadProgress:nil
// downloadProgress:nil
// completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
// if (error) {
//#ifdef DEBUG
// NSLog(@"%@ - \n%@\n", method, error);
//#else
//#endif
// @kStrongify(self);
// [self handleNetError:error method:method failure:failure];
// } else {
// BaseModel *baseModel = [BaseModel modelWithDictionary:responseObject];
//#ifdef DEBUG
// NSLog(@"%@ - \n%@\n", method, [baseModel toJSONString]);
//#else
//#endif
// success(baseModel);
// }
// }];
//
// [dataTask resume];
//}
+ (void)POST:(NSString *)method
params:(NSDictionary *)params
success:(void (^)(BaseModel *data))success
@@ -245,7 +148,7 @@
params = [self configBaseParmars:params];
#if DEBUG
#if 0
// URL
NSString *baseUrl = [HttpRequestHelper getHostUrl];
NSString *fullUrl = [NSString stringWithFormat:@"%@/%@", baseUrl, method];
@@ -260,7 +163,7 @@
[manager POST:method parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
BaseModel *baseModel = [BaseModel modelWithDictionary:responseObject];
#if DEBUG
#if 0
NSLog(@"\n%@", [baseModel toJSONString]);
#else
#endif

View File

@@ -4236,11 +4236,18 @@ ineHeadView12" = "الحمل";
"20.20.62_text_7" = "ليس لديك إذن لدعوة المستخدم إلى الميكروفون.";
"20.20.62_text_8" = "فشل إرسال الدعوة. يُرجى التحقق من الشبكة.";
"20.20.62_text_9" = "Turn effects on/off";
"20.20.62_text_9.1" = "Turn effects on";
"20.20.62_text_9.2" = "Turn effects off";
"20.20.62_text_9" = "تشغيل/إيقاف المؤثرات";
"20.20.62_text_9.1" = "وضع Turbo (السرعة الفائقة)";
"20.20.62_text_9.2" = "وضع عادي";
"20.20.62_text_10" = "Gift effects";
"20.20.62_text_11" = "Global gift screen";
"20.20.62_text_12" = "Global game screen";
"20.20.62_text_13" = "Turbo mode";
"20.20.62_text_14" = "我的特效";
"20.20.62_text_15.1" = "تمكين وضع Turbo يمكن أن يجعل التطبيق يعمل بسلاسة أكبر.\nوضع Turbo: يُوقف رسوميات الهدايا في الغرفة، البث داخل الغرفة، عروض CP، وعروض المؤثرات الأخرى.";
"20.20.62_text_15.2" = "لجعل التطبيق يعمل بسلاسة أكبر، تم التبديل تلقائيًا إلى وضع Turbo لك (وضع Turbo: يُوقف تلقائيًا مؤثرات الهدايا، مؤثرات غطاء الرأس، ويدمج رسائل الهدايا في الدردشة العامة). يمكنك إيقاف هذا الوضع في إعدادات الغرفة.";
"20.20.62_text_16" = "أنا أدرك";
"20.20.62_text_17" = "لقد فعّلتَ تأثير شاشة هدية غروبال العائمة.";
"20.20.62_text_18" = "لقد عطّلتَ تأثير شاشة هدية غروبال العائمة. لم تعد شاشة هدية غروبال العائمة ظاهرة في هذه الغرفة. انقر لتفعيلها مجددًا.";
"20.20.62_text_19" = "لقد فعّلتَ تأثير شاشة لعبة غروبال العائمة.";
"20.20.62_text_20" = "لقد عطّلتَ تأثير شاشة لعبة غروبال العائمة. لم تعد شاشة لعبة غروبال العائمة ظاهرة في هذه الغرفة. انقر لتفعيلها مجددًا.";

View File

@@ -4024,10 +4024,17 @@
"20.20.62_text_8" = "The invitation failed to be sent. Please check the network.";
"20.20.62_text_9" = "Turn effects on/off";
"20.20.62_text_9.1" = "Turn effects on";
"20.20.62_text_9.2" = "Turn effects off";
"20.20.62_text_9.1" = "Turbo mode";
"20.20.62_text_9.2" = "Non-turbo mode";
"20.20.62_text_10" = "Gift effects";
"20.20.62_text_11" = "Global gift screen";
"20.20.62_text_12" = "Global game screen";
"20.20.62_text_13" = "Turbo mode";
"20.20.62_text_14" = "我的特效";
"20.20.62_text_15.1" = "Enabling Turbo mode can make the app run smoother.\nTurbo mode: Turns off room gift animations, in-room broadcasts, CP displays, and other animated effects.";
"20.20.62_text_15.2" = "To make the app run smoother, it has automatically switched to Turbo mode for you (Turbo mode: Automatically turns off gift animations, headwear effects, and merges gift messages in the public chat). You can turn off this mode in the room settings.";
"20.20.62_text_16" = "Anladım";
"20.20.62_text_17" = "You have enabled the grobal gift floating screen effect.";
"20.20.62_text_18" = "You have disabled the grobal gift floating screen effect. The grobal gift floating screen is no longer visible in this room. Click to enable it again.";
"20.20.62_text_19" = "You have enabled the grobal game floating screen effect.";
"20.20.62_text_20" = "You have disabled the grobal game floating screen effect. The grobal game floating screen is no longer visible in this room. Click to enable it again.";

View File

@@ -3316,11 +3316,18 @@
"20.20.62_text_7" = "Você não tem permissão para convidar o usuário para o microfone.";
"20.20.62_text_8" = "O convite não foi enviado. Verifique a rede.";
"20.20.62_text_9" = "Turn effects on/off";
"20.20.62_text_9.1" = "Turn effects on";
"20.20.62_text_9.2" = "Turn effects off";
"20.20.62_text_9" = "Ativar/Desativar efeitos";
"20.20.62_text_9.1" = "Modo turbo";
"20.20.62_text_9.2" = "Modo normal";
"20.20.62_text_10" = "Gift effects";
"20.20.62_text_11" = "Global gift screen";
"20.20.62_text_12" = "Global game screen";
"20.20.62_text_13" = "Turbo mode";
"20.20.62_text_14" = "我的特效";
"20.20.62_text_15.1" = "Ativar o Modo turbo pode fazer com que o aplicativo funcione de forma mais suave.\nModo turbo: Desativa as animações de presentes na sala, transmissões na sala, exibições de CP e outros efeitos animados.";
"20.20.62_text_15.2" = "Para fazer o aplicativo funcionar de forma mais suave, mudou automaticamente para o Modo turbo para si (Modo turbo: Desativa automaticamente os efeitos de presentes, os efeitos de chapéu e funde as mensagens de presentes no chat público). Pode desativar este modo nas definições da sala.";
"20.20.62_text_16" = "Compreendo";
"20.20.62_text_17" = "Você ativou o efeito de tela flutuante do presente Grobal.";
"20.20.62_text_18" = "Você desativou o efeito de tela flutuante do presente Grobal. A tela flutuante do presente Grobal não está mais visível nesta sala. Clique para ativá-la novamente.";
"20.20.62_text_19" = "Você ativou o efeito de tela flutuante do jogo Grobal.";
"20.20.62_text_20" = "Você desativou o efeito de tela flutuante do jogo Grobal. A tela flutuante do jogo Grobal não está mais visível nesta sala. Clique para ativá-la novamente.";

View File

@@ -3817,11 +3817,18 @@
"20.20.62_text_7" = "Kullanıcıyı mikrofona davet etme izniniz yok.";
"20.20.62_text_8" = "Davet gönderilemedi. Lütfen ağı kontrol edin.";
"20.20.62_text_9" = "Turn effects on/off";
"20.20.62_text_9.1" = "Turn effects on";
"20.20.62_text_9.2" = "Turn effects off";
"20.20.62_text_9" = "Efektleri Aç/Kapat";
"20.20.62_text_9.1" = "Turbo mod";
"20.20.62_text_9.2" = "Normal mod";
"20.20.62_text_10" = "Gift effects";
"20.20.62_text_11" = "Global gift screen";
"20.20.62_text_12" = "Global game screen";
"20.20.62_text_13" = "Turbo mode";
"20.20.62_text_14" = "我的特效";
"20.20.62_text_15.1" = "Turbo modu etkinleştirmek, uygulamanın daha sorunsuz çalışmasını sağlayabilir.\nTurbo mod: Oda hediye animasyonlarını, odadaki yayınları, CP görüntülerini ve diğer animasyonlu efektleri kapatır.";
"20.20.62_text_15.2" = "Uygulamanın daha sorunsuz çalışması için sizin için otomatik olarak Turbo moda geçildi (Turbo mod: Hediye animasyonlarını, başlık efektlerini otomatik olarak kapatır ve genel sohbetteki hediye mesajlarını birleştirir). Bu modu oda ayarlarından kapatabilirsiniz.";
"20.20.62_text_16" = "Anladım";
"20.20.62_text_17" = "Küresel hediye yüzen ekran efektini etkinleştirdiniz.";
"20.20.62_text_18" = "Küresel hediye yüzen ekran efektini devre dışı bıraktınız. Küresel hediye yüzen ekran artık bu odada görünmüyor. Tekrar etkinleştirmek için tıklayın.";
"20.20.62_text_19" = "Küresel oyun yüzen ekran efektini etkinleştirdiniz.";
"20.20.62_text_20" = "Küresel oyun yüzen ekran efektini devre dışı bıraktınız. Küresel oyun yüzen ekran artık bu odada görünmüyor. Tekrar etkinleştirmek için tıklayın.";

View File

@@ -3687,12 +3687,18 @@
"20.20.62_text_7" = "您無權邀請該使用者加入麥克風。";
"20.20.62_text_8" = "邀請發送失敗,請檢查網路。";
"20.20.62_text_9" = "Turn effects on/off";
"20.20.62_text_9.1" = "Turbo mode on";
"20.20.62_text_9.2" = "Turbo mode off";
"20.20.62_text_10" = "Gift effects";
"20.20.62_text_11" = "Global gift screen";
"20.20.62_text_12" = "Global game screen";
"20.20.62_text_13" = "Turbo mode";
"20.20.62_text_9" = "开关我的特效";
"20.20.62_text_9.1" = "极速模式";
"20.20.62_text_9.2" = "非极速模式";
"20.20.62_text_10" = "礼物特效";
"20.20.62_text_11" = "全服礼物飘屏";
"20.20.62_text_12" = "全服游戏飘屏";
"20.20.62_text_13" = "极速模式";
"20.20.62_text_14" = "我的特效";
"20.20.62_text_15.1" = "开启极速模式可以使app运行更加流畅。\n极速模式关闭房间礼物动效果、房间内飘屏CP展示等动效展示。";
"20.20.62_text_15.2" = "为使APP运行更加顺畅已自动为你切换至极速模式极速模式自动关闭礼物动效、头饰动效、公屏的送礼消息已合并。你可以在房间设置中关闭该模式。";
"20.20.62_text_16" = "我已知晓";
"20.20.62_text_17" = "你已经开启全服礼物飘屏特效。";
"20.20.62_text_18" = "你已经关闭全服礼物飘屏特效。本房间内无法看到全服礼物飘屏,点击即可重新开启。";
"20.20.62_text_19" = "你已经开启全服游戏飘屏特效。";
"20.20.62_text_20" = "你已经关闭全服游戏飘屏特效。本房间内无法看到全服游戏飘屏,点击即可重新开启。";