Compare commits
126 Commits
hotfix/Sen
...
aeb9fcd30e
Author | SHA1 | Date | |
---|---|---|---|
![]() |
aeb9fcd30e | ||
![]() |
6d4061bea5 | ||
![]() |
83e26bdbae | ||
![]() |
c551146afd | ||
![]() |
961edefe4a | ||
![]() |
f1daa16e59 | ||
![]() |
9688e4413b | ||
![]() |
79f6f45bc1 | ||
![]() |
3f97b0293e | ||
![]() |
84e146277a | ||
![]() |
5192d58b07 | ||
![]() |
cd4710ecf6 | ||
![]() |
edf844c1e8 | ||
![]() |
b1e46f6d28 | ||
![]() |
2a99d2238f | ||
![]() |
3da0148ad1 | ||
![]() |
9206b4be45 | ||
![]() |
2867c7ddb5 | ||
![]() |
505472b073 | ||
![]() |
64cfb1b10e | ||
![]() |
9b2ebb796f | ||
![]() |
6fd831ff42 | ||
![]() |
259ac3e2d3 | ||
![]() |
446e172939 | ||
![]() |
c0bc29486f | ||
![]() |
1fb6cadabf | ||
![]() |
e3dfd8cb0a | ||
![]() |
96c44cb032 | ||
![]() |
16f9041ba9 | ||
![]() |
99db078b62 | ||
![]() |
e32e5653fd | ||
![]() |
8a096239da | ||
![]() |
f0dad8886f | ||
![]() |
0d6570a086 | ||
![]() |
f52af5d620 | ||
![]() |
86094da26f | ||
![]() |
6f59274ca0 | ||
![]() |
e01148a3a9 | ||
![]() |
1190e0f6d9 | ||
![]() |
c5d966317b | ||
![]() |
6573c0f6fe | ||
![]() |
7810057542 | ||
![]() |
059305d3df | ||
![]() |
a15d6b34ed | ||
![]() |
6d0122f3d1 | ||
![]() |
286e68b5e3 | ||
![]() |
c0500397b6 | ||
![]() |
f62af24c48 | ||
![]() |
a72c010b56 | ||
![]() |
143ad115bc | ||
![]() |
4c76813273 | ||
![]() |
da8d88347e | ||
![]() |
06fecf1bf4 | ||
![]() |
c978a8c355 | ||
![]() |
a0fc15fefd | ||
![]() |
c1b9dd3d9f | ||
![]() |
887bb19056 | ||
![]() |
413b2c6944 | ||
![]() |
89d9b57dea | ||
![]() |
8c0276a208 | ||
![]() |
68ce148abb | ||
![]() |
4416e9f9c8 | ||
![]() |
6e814f76cb | ||
![]() |
443e1a4332 | ||
![]() |
8dab721de9 | ||
![]() |
5985b5701e | ||
![]() |
5ff62bafee | ||
![]() |
ca25ed14ac | ||
![]() |
e5c8baad34 | ||
![]() |
c765e78ec6 | ||
![]() |
95e3e2601f | ||
![]() |
0d01b1e6e9 | ||
![]() |
298a7e80c4 | ||
![]() |
b688962559 | ||
![]() |
353491f56f | ||
![]() |
a99e650d45 | ||
![]() |
bd2e5e380f | ||
![]() |
2c5a1a289e | ||
![]() |
ffdfa121f9 | ||
![]() |
07ebee2fc1 | ||
![]() |
69863a91ff | ||
![]() |
a9538c61ff | ||
![]() |
41aae87dd6 | ||
![]() |
ff365e8ae4 | ||
![]() |
40311a1d85 | ||
![]() |
2caa476640 | ||
![]() |
faa6a2c4dc | ||
![]() |
0275decc7e | ||
![]() |
bc9a02802d | ||
![]() |
d9850e2c8b | ||
![]() |
e27b564fdc | ||
![]() |
d6e13ac0fe | ||
![]() |
e7b2f594e8 | ||
![]() |
e152d0f8a1 | ||
![]() |
9d3f08c9b3 | ||
![]() |
7807824a97 | ||
![]() |
8a1ed09905 | ||
![]() |
fc399e0afc | ||
![]() |
f582077804 | ||
![]() |
b592097865 | ||
![]() |
a4651740bd | ||
![]() |
d958a3ca36 | ||
![]() |
f963f0ed81 | ||
![]() |
e2f022246f | ||
![]() |
b6325180d4 | ||
![]() |
471b8e945f | ||
![]() |
d71a139afb | ||
![]() |
9b0520c1eb | ||
![]() |
311868fde6 | ||
![]() |
a79bf667cc | ||
![]() |
bc02ca29fc | ||
![]() |
93c3304601 | ||
![]() |
d9e8d6639b | ||
![]() |
893c1ab647 | ||
![]() |
ed25b30a35 | ||
![]() |
54cc9ebde3 | ||
![]() |
81a0094dbf | ||
![]() |
4abb686790 | ||
![]() |
2c5d72846d | ||
![]() |
ab544a2d84 | ||
![]() |
83d1a1df95 | ||
![]() |
75a9bac88a | ||
![]() |
c0e7e7ff83 | ||
![]() |
47c0f141a8 | ||
![]() |
a0b2dea116 | ||
![]() |
e82939f767 |
7
.cursor/rules/next-chat.mdc
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: false
|
||||
---
|
||||
本次对话的上下文已经太长了,我打算关掉并重新开一个新的会话。
|
||||
你有什么想对你的继任者说的,以便它能更好的理解你当前的工作并顺利继续?
|
6
.gitignore
vendored
@@ -82,12 +82,6 @@ iOSInjectionProject/
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.war
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
0
.trae/rules/project_rules.md
Normal file
44
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"cSpell.ignoreWords": [
|
||||
"DJDKMIMOM",
|
||||
"Strongify",
|
||||
"Weakify",
|
||||
"instancetype",
|
||||
"nonatomic"
|
||||
],
|
||||
"cSpell.words": [
|
||||
"autoreleasepool",
|
||||
"Autoresizing",
|
||||
"BGMP",
|
||||
"Bugly",
|
||||
"Commont",
|
||||
"Contol",
|
||||
"CPSVGA",
|
||||
"Defalut",
|
||||
"erban",
|
||||
"exper",
|
||||
"Headwear",
|
||||
"HWDMP",
|
||||
"ifndef",
|
||||
"Interitem",
|
||||
"kindof",
|
||||
"MAXFLOAT",
|
||||
"Moli",
|
||||
"MSRTL",
|
||||
"NIMSDK",
|
||||
"Nonnull",
|
||||
"NSEC",
|
||||
"NSURL",
|
||||
"objc",
|
||||
"Offical",
|
||||
"Podfile",
|
||||
"Procotol",
|
||||
"QGVAP",
|
||||
"Subview",
|
||||
"subviews",
|
||||
"Superview",
|
||||
"Uids",
|
||||
"XNDJTDD"
|
||||
],
|
||||
"C_Cpp.errorSquiggles": "disabled"
|
||||
}
|
79
DOC/log.txt
Normal file
@@ -0,0 +1,79 @@
|
||||
-[XPSendGiftView xPGiftBarView:didClickSendGift:] [Line 771][Combo effect] 🎁 开始送礼物流程
|
||||
-[XPSendGiftView readyForCombo:gift:] [Line 727][Combo effect] 🔧 准备连击状态 - giftType: 18, segmentType: 8
|
||||
-[XPSendGiftView readyForCombo:gift:] [Line 745][Combo effect] ✅ 礼物支持连击,启用连击功能
|
||||
-[GiftComboManager activate] [Line 197][Combo effect] 🔧 激活连击功能
|
||||
-[GiftComboManager configureWithGiftInfo:targetUIDs:roomUID:sessionID:userInfo:countModel:sourceType:sendType:giftNum:] [Line 696][Combo effect] 🔧 统一配置连击参数
|
||||
-[GiftComboManager configureWithGiftInfo:targetUIDs:roomUID:sessionID:userInfo:countModel:sourceType:sendType:giftNum:] [Line 709][Combo effect] ✅ 连击参数配置完成 - giftId: 2263, targetCount: 1
|
||||
-[XPSendGiftView readyForCombo:gift:] [Line 761][Combo effect] ✅ 连击状态准备完成
|
||||
-[GiftComboManager printComboState] [Line 377][Combo effect] 📊 当前连击状态:
|
||||
-[GiftComboManager printComboState] [Line 378][Combo effect] - isCombing: NO
|
||||
-[GiftComboManager printComboState] [Line 379][Combo effect] - enableCombo: YES
|
||||
-[GiftComboManager printComboState] [Line 380][Combo effect] - combo: 1
|
||||
-[GiftComboManager printComboState] [Line 381][Combo effect] - hasGiftInfo: YES
|
||||
-[GiftComboManager printComboState] [Line 382][Combo effect] - targetCount: 1
|
||||
-[GiftComboManager printComboState] [Line 383][Combo effect] - errorMessage:
|
||||
-[XPSendGiftView xPGiftBarView:didClickSendGift:] [Line 778][Combo effect] ✅ 连击功能已启用,准备调用resetCombo
|
||||
-[XPSendGiftView sendGiftSuccess:originDic:uidCount:] [Line 1198][Combo effect] 📱 检查连击状态 - enableCombo: YES
|
||||
-[XPSendGiftView sendGiftSuccess:originDic:uidCount:] [Line 1207][Combo effect] 📱 originDic 连击计数检查 - comboCount: (null)
|
||||
-[XPSendGiftView sendGiftSuccess:originDic:uidCount:] [Line 1210][Combo effect] 📱 启用连击模式,重置连击状态
|
||||
-[GiftComboManager reset] [Line 141][Combo effect] 🔄 开始连击重置 - combo: 1 -> 1, enableCombo: YES, actionCallback: 为空
|
||||
-[GiftComboManager reset] [Line 154][Combo effect] 🔍 重置后验证 - combo: 1
|
||||
-[GiftComboManager reset] [Line 173][Combo effect] ⚠️ actionCallback为空,不显示连击面板
|
||||
-[GiftComboManager reset] [Line 177][Combo effect] 🎮 隐藏房间UI元素
|
||||
-[GiftComboManager reset] [Line 186][Combo effect] ✅ 连击重置完成 - isCombing: NO
|
||||
-[XPSendGiftView sendCustomMessage:oringinDic:] [Line 425][Combo effect] 📨 云信消息连击计数检查 - comboCount: 1, giftId: 2263
|
||||
-[GiftComboView setupTimer] [Line 284][Combo effect] ⏰ 设置连击倒计时
|
||||
-[CountdownRingView startCountdown] [Line 97][Combo effect] ⏰ 开始倒计时
|
||||
-[CountdownRingView animateRing] [Line 246][Combo effect] 🎬 环形动画已启动,时长: 5.0秒
|
||||
-[CountdownRingView startCountdown] [Line 109][Combo effect] ⏰ 倒计时已启动
|
||||
-[GiftComboView setupTimer] [Line 293][Combo effect] ⏰ 连击倒计时已启动
|
||||
-[GiftComboView updateCount] [Line 171][Combo effect] 🔢 更新连击次数显示 - combo: 1
|
||||
-[GiftComboManager printComboState] [Line 377][Combo effect] 📊 当前连击状态:
|
||||
-[GiftComboManager printComboState] [Line 378][Combo effect] - isCombing: NO
|
||||
-[GiftComboManager printComboState] [Line 379][Combo effect] - enableCombo: YES
|
||||
-[GiftComboManager printComboState] [Line 380][Combo effect] - combo: 1
|
||||
-[GiftComboManager printComboState] [Line 381][Combo effect] - hasGiftInfo: YES
|
||||
-[GiftComboManager printComboState] [Line 382][Combo effect] - targetCount: 1
|
||||
-[GiftComboManager printComboState] [Line 383][Combo effect] - errorMessage:
|
||||
-[GiftComboManager forceBoomStateReset] [Line 275][Combo effect] 🚨 执行强制Boom连击状态重置
|
||||
-[GiftComboManager forceBoomStateReset] [Line 278][Combo effect] ⏰ 停止所有定时器
|
||||
-[GiftComboManager forceStopAllTimers] [Line 321][Combo effect] ⏰ 强制停止所有Timer
|
||||
-[GiftComboManager forceBoomStateReset] [Line 282][Combo effect] 🗑️ 清空所有队列
|
||||
-[GiftComboManager forceBoomStateReset] [Line 287][Combo effect] 🔄 重置状态标志 - isCombing: NO -> NO
|
||||
-[GiftComboManager forceBoomStateReset] [Line 292][Combo effect] 🔄 combo计数重置为0
|
||||
-[GiftComboManager forceBoomStateReset] [Line 301][Combo effect] 📢 发送强制重置通知
|
||||
-[GiftComboManager forceBoomStateReset] [Line 309][Combo effect] 🎮 恢复房间UI元素
|
||||
-[GiftComboManager forceBoomStateReset] [Line 316][Combo effect] ✅ 强制重置完成 - enableCombo保持: YES, actionCallback保持: 为空
|
||||
-[XPSendGiftView removeAllComboRelatedViews] [Line 137][Combo effect] 🗑️ 开始移除连击相关视图
|
||||
-[XPSendGiftView removeAllComboRelatedViews] [Line 148][Combo effect] 🗑️ comboView存在但无superview,直接清理
|
||||
-[CountdownRingView stopCountdown] [Line 200][Combo effect] ⏰ 停止倒计时开始
|
||||
-[CountdownRingView stopCountdown] [Line 208][Combo effect] ⏰ Timer已停止
|
||||
-[CountdownRingView stopCountdown] [Line 214][Combo effect] ⏰ 动画已停止
|
||||
-[CountdownRingView stopCountdown] [Line 230][Combo effect] ⏰ 停止倒计时完成
|
||||
-[GiftComboView dealloc] [Line 43][Combo effect] 🗑️ GiftComboView dealloc开始 - 0x13624e600
|
||||
-[CountdownRingView stopCountdown] [Line 196][Combo effect] ⚠️ 倒计时未运行,无需停止
|
||||
-[GiftComboView dealloc] [Line 72][Combo effect] 🗑️ GiftComboView dealloc完成 - 0x13624e600
|
||||
-[XPSendGiftView removeAllComboRelatedViews] [Line 166][Combo effect] 🗑️ 连击相关视图移除完成
|
||||
-[CountdownRingView dealloc] [Line 32][Combo effect] 🗑️ CountdownRingView dealloc开始 - 0x13624e800
|
||||
-[CountdownRingView cleanup] [Line 251][Combo effect] 🗑️ 完全清理开始
|
||||
-[CountdownRingView stopCountdown] [Line 196][Combo effect] ⚠️ 倒计时未运行,无需停止
|
||||
-[CountdownRingView cleanup] [Line 260][Combo effect] 🗑️ 完全清理完成
|
||||
-[CountdownRingView dealloc] [Line 37][Combo effect] 🗑️ CountdownRingView dealloc完成 - 0x13624e800
|
||||
-[RoomAnimationView _handleGiftMessage:] [Line 1737][Combo effect] 📨 收到礼物消息 - second: 121
|
||||
-[RoomAnimationView _handleGiftMessage:] [Line 1757][Combo effect] 📨 礼物消息解析完成 - giftId: 2263, combo: 1, uid: 3184
|
||||
-[RoomAnimationView _handleGiftMessage:] [Line 1824][Combo effect] 🎁 处理普通礼物动画
|
||||
-[GiftAnimationManager enqueueGift:] [Line 237][Combo effect] 🎬 添加礼物到动画队列 - giftId: 2263, combo: 1
|
||||
-[GiftComboManager receiveGiftInfoForDisplayComboFlags:container:] [Line 407][Combo effect] 🎪 收到连击飘屏请求 - combo: 1, giftId: 2263
|
||||
-[GiftAnimationManager enqueueGift:]_block_invoke [Line 241][Combo effect] 📊 动画队列当前数量: 1
|
||||
-[GiftComboManager receiveGiftInfoForDisplayComboFlags:container:] [Line 410][Combo effect] 📊 连击飘屏队列数量: 1
|
||||
-[GiftComboManager processGiftFlagQueue] [Line 462][Combo effect] 🎪 处理连击飘屏 - combo: 1, giftId: 2263
|
||||
-[GiftComboManager processGiftFlagQueue] [Line 464][Combo effect] <20><> 移除后UI动画队列数量: 0
|
||||
-[GiftAnimationManager processNextGift]_block_invoke [Line 100][Combo effect] 🎬 开始处理动画 - giftId: 2263, combo: 1
|
||||
-[GiftAnimationManager processNextGift]_block_invoke [Line 104][Combo effect] 📊 移除后动画队列数量: 0
|
||||
-[GiftAnimationManager distributeGiftAnimation:] [Line 119][Combo effect] 🎯 开始分发动画 - uid: 3184
|
||||
-[GiftAnimationManager distributeGiftAnimation:] [Line 122][Combo effect] 🎯 目标用户数量: 1
|
||||
-[GiftAnimationManager distributeGiftAnimation:] [Line 126][Combo effect] 🎯 是否使用连击动画: NO
|
||||
-[GiftAnimationManager distributeGiftAnimation:] [Line 133][Combo effect] 🎯 使用普通动画起点: {207, 285.79999999999995}
|
||||
-[GiftAnimationManager distributeGiftAnimation:] [Line 136][Combo effect] 🎯 动画延迟时间: 0.30
|
||||
-[GiftAnimationManager distributeGiftAnimation:] [Line 140][Combo effect] 🎯 为目标用户 3184 创建动画 - 终点: {207, 285.79999999999995}
|
||||
-[GiftAnimationManager processNextGift]_block_invoke [Line 82][Combo effect] 📭 动画队列为空,停止处理
|
471
DOC/新Banner组件架构设计.md
Normal file
@@ -0,0 +1,471 @@
|
||||
# 新Banner组件架构设计
|
||||
|
||||
## 设计概述
|
||||
|
||||
基于对现有7种Banner组件的深度分析,设计一套统一的Banner组件架构,包含父类、子类、数据模型和用户反馈机制。
|
||||
|
||||
## 现有组件分析总结
|
||||
|
||||
### 共同UI结构模式
|
||||
|
||||
| 组件 | 背景 | 头像 | 标题/内容 | 礼物图标 | 操作按钮 | 动画效果 |
|
||||
|------|------|------|-----------|----------|----------|----------|
|
||||
| RoomHighValueGiftBannerAnimation | ✓ | ✓ | ✓ | ✓ | ✓ | SVGA |
|
||||
| CPGiftBanner | ✓ | ✓✓(双人) | ✓ | ✓ | - | POP |
|
||||
| BravoGiftBannerView | ✓ | ✓ | ✓ | ✓ | - | SVGA |
|
||||
| LuckyPackageBannerView | ✓ | ✓ | ✓ | - | ✓ | POP |
|
||||
| LuckyGiftWinningBannerView | ✓ | ✓ | ✓ | - | ✓ | POP |
|
||||
| GameUniversalBannerView | ✓ | ✓ | ✓ | ✓ | ✓ | SVGA |
|
||||
| PIUniversalBannerView | ✓ | - | ✓ | - | ✓ | SVGA |
|
||||
|
||||
### 共同数据模式
|
||||
|
||||
- AttachmentModel作为数据源
|
||||
- 专用ViewModel进行数据解析
|
||||
- 完成回调机制
|
||||
- 用户交互跳转
|
||||
|
||||
## 架构设计
|
||||
|
||||
### 1. 基础父类设计
|
||||
|
||||
```objc
|
||||
// YMBaseBannerView.h
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "YMBannerDataProtocol.h"
|
||||
#import "YMBannerDelegate.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class AttachmentModel, YMBaseBannerViewModel;
|
||||
|
||||
typedef NS_ENUM(NSUInteger, YMBannerType) {
|
||||
YMBannerTypeHighValueGift, // 高价值礼物
|
||||
YMBannerTypeCPGift, // CP礼物
|
||||
YMBannerTypeBravoGift, // Bravo超级礼物
|
||||
YMBannerTypeLuckyPackage, // 幸运红包
|
||||
YMBannerTypeLuckyWinning, // 幸运中奖
|
||||
YMBannerTypeGameUniversal, // 通用游戏
|
||||
YMBannerTypeUniversal // 通用飘屏
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSUInteger, YMBannerAnimationType) {
|
||||
YMBannerAnimationTypeSlide, // 滑动动画
|
||||
YMBannerAnimationTypeFade, // 淡入淡出
|
||||
YMBannerAnimationTypeBounce, // 弹跳效果
|
||||
YMBannerAnimationTypeCustom // 自定义动画
|
||||
};
|
||||
|
||||
@interface YMBaseBannerView : UIView
|
||||
|
||||
#pragma mark - 核心属性
|
||||
@property (nonatomic, assign, readonly) YMBannerType bannerType;
|
||||
@property (nonatomic, strong) AttachmentModel *attachment;
|
||||
@property (nonatomic, strong) YMBaseBannerViewModel *viewModel;
|
||||
@property (nonatomic, weak) id<YMBannerDelegate> delegate;
|
||||
|
||||
#pragma mark - UI组件 (子类可选择使用)
|
||||
@property (nonatomic, strong, readonly) UIView *containerView;
|
||||
@property (nonatomic, strong, readonly) UIImageView *backgroundImageView;
|
||||
@property (nonatomic, strong, readonly) NetImageView *avatarImageView;
|
||||
@property (nonatomic, strong, readonly) NetImageView *secondAvatarImageView; // CP双头像
|
||||
@property (nonatomic, strong, readonly) UILabel *titleLabel;
|
||||
@property (nonatomic, strong, readonly) UILabel *subtitleLabel;
|
||||
@property (nonatomic, strong, readonly) UILabel *contentLabel;
|
||||
@property (nonatomic, strong, readonly) NetImageView *iconImageView;
|
||||
@property (nonatomic, strong, readonly) UIButton *actionButton;
|
||||
@property (nonatomic, strong, readonly) SVGAImageView *svgaView;
|
||||
|
||||
#pragma mark - 动画配置
|
||||
@property (nonatomic, assign) YMBannerAnimationType animationType;
|
||||
@property (nonatomic, assign) CGFloat showDuration;
|
||||
@property (nonatomic, assign) CGFloat stayDuration;
|
||||
@property (nonatomic, assign) CGFloat hideDuration;
|
||||
@property (nonatomic, assign) BOOL enableSwipeGesture;
|
||||
|
||||
#pragma mark - 回调
|
||||
@property (nonatomic, copy) void(^onDisplayComplete)(void);
|
||||
@property (nonatomic, copy) void(^onUserTap)(YMBaseBannerView *banner);
|
||||
@property (nonatomic, copy) void(^onActionTap)(YMBaseBannerView *banner);
|
||||
@property (nonatomic, copy) void(^onDismiss)(YMBaseBannerView *banner);
|
||||
|
||||
#pragma mark - 状态
|
||||
@property (nonatomic, assign, readonly) BOOL isDisplaying;
|
||||
@property (nonatomic, assign, readonly) BOOL isDismissed;
|
||||
|
||||
#pragma mark - 类方法
|
||||
+ (instancetype)bannerWithAttachment:(AttachmentModel *)attachment;
|
||||
+ (void)displayInView:(UIView *)superView
|
||||
attachment:(AttachmentModel *)attachment
|
||||
complete:(void(^)(void))complete;
|
||||
|
||||
#pragma mark - 实例方法
|
||||
- (instancetype)initWithBannerType:(YMBannerType)type;
|
||||
- (void)configureWithAttachment:(AttachmentModel *)attachment;
|
||||
- (void)displayInView:(UIView *)superView;
|
||||
- (void)dismissWithAnimation:(BOOL)animated;
|
||||
|
||||
#pragma mark - 子类重写方法
|
||||
- (Class)viewModelClass; // 返回对应的ViewModel类
|
||||
- (void)setupUIComponents; // 设置UI组件
|
||||
- (void)layoutUIComponents; // 布局UI组件
|
||||
- (void)configureWithViewModel:(YMBaseBannerViewModel *)viewModel; // 配置数据
|
||||
- (void)performShowAnimation; // 执行显示动画
|
||||
- (void)performHideAnimation; // 执行隐藏动画
|
||||
- (void)handleUserTap; // 处理用户点击
|
||||
- (void)handleActionTap; // 处理操作按钮点击
|
||||
|
||||
#pragma mark - 用户反馈
|
||||
- (void)reportDisplayEvent; // 上报展示事件
|
||||
- (void)reportClickEvent:(NSString *)action; // 上报点击事件
|
||||
- (void)reportDismissEvent:(NSString *)reason; // 上报消失事件
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
```
|
||||
|
||||
### 2. 基础数据模型
|
||||
|
||||
```objc
|
||||
// YMBaseBannerViewModel.h
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "PIBaseModel.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface YMBaseBannerViewModel : PIBaseModel
|
||||
|
||||
#pragma mark - 基础信息
|
||||
@property (nonatomic, assign) NSInteger roomUid;
|
||||
@property (nonatomic, assign) NSInteger targetRoomUid;
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
@property (nonatomic, copy) NSString *subtitle;
|
||||
@property (nonatomic, copy) NSString *content;
|
||||
|
||||
#pragma mark - 用户信息
|
||||
@property (nonatomic, copy) NSString *senderNick;
|
||||
@property (nonatomic, copy) NSString *senderAvatar;
|
||||
@property (nonatomic, assign) NSInteger senderUid;
|
||||
@property (nonatomic, copy) NSString *receiverNick;
|
||||
@property (nonatomic, copy) NSString *receiverAvatar;
|
||||
@property (nonatomic, assign) NSInteger receiverUid;
|
||||
|
||||
#pragma mark - 视觉资源
|
||||
@property (nonatomic, copy) NSString *backgroundImageUrl;
|
||||
@property (nonatomic, copy) NSString *iconImageUrl;
|
||||
@property (nonatomic, copy) NSString *svgaUrl;
|
||||
|
||||
#pragma mark - 交互配置
|
||||
@property (nonatomic, copy) NSString *actionText;
|
||||
@property (nonatomic, copy) NSString *skipUrl;
|
||||
@property (nonatomic, assign) BOOL enableClick;
|
||||
@property (nonatomic, assign) BOOL enableAction;
|
||||
|
||||
#pragma mark - 埋点数据
|
||||
@property (nonatomic, copy) NSString *eventType;
|
||||
@property (nonatomic, strong) NSDictionary *trackingData;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
```
|
||||
|
||||
### 3. 代理协议设计
|
||||
|
||||
```objc
|
||||
// YMBannerDelegate.h
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class YMBaseBannerView;
|
||||
|
||||
@protocol YMBannerDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
#pragma mark - 生命周期回调
|
||||
- (void)bannerWillDisplay:(YMBaseBannerView *)banner;
|
||||
- (void)bannerDidDisplay:(YMBaseBannerView *)banner;
|
||||
- (void)bannerWillDismiss:(YMBaseBannerView *)banner;
|
||||
- (void)bannerDidDismiss:(YMBaseBannerView *)banner;
|
||||
|
||||
#pragma mark - 交互回调
|
||||
- (void)banner:(YMBaseBannerView *)banner didTapWithAction:(NSString *)action;
|
||||
- (void)banner:(YMBaseBannerView *)banner willNavigateToRoom:(NSInteger)roomUid;
|
||||
- (void)banner:(YMBaseBannerView *)banner willOpenURL:(NSString *)url;
|
||||
|
||||
#pragma mark - 数据回调
|
||||
- (void)banner:(YMBaseBannerView *)banner didReportEvent:(NSString *)event data:(NSDictionary *)data;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
```
|
||||
|
||||
## 子类设计
|
||||
|
||||
### 1. 高价值礼物Banner
|
||||
|
||||
```objc
|
||||
// YMHighValueGiftBannerView.h
|
||||
#import "YMBaseBannerView.h"
|
||||
|
||||
@interface YMHighValueGiftBannerView : YMBaseBannerView
|
||||
|
||||
@property (nonatomic, strong, readonly) UILabel *giftNameLabel;
|
||||
@property (nonatomic, strong, readonly) UILabel *giftCountLabel;
|
||||
@property (nonatomic, strong, readonly) MarqueeLabel *senderScrollLabel;
|
||||
@property (nonatomic, strong, readonly) MarqueeLabel *roomNameScrollLabel;
|
||||
|
||||
@end
|
||||
|
||||
// YMHighValueGiftBannerViewModel.h
|
||||
@interface YMHighValueGiftBannerViewModel : YMBaseBannerViewModel
|
||||
|
||||
@property (nonatomic, copy) NSString *giftName;
|
||||
@property (nonatomic, assign) NSInteger giftCount;
|
||||
@property (nonatomic, copy) NSString *giftImageUrl;
|
||||
@property (nonatomic, assign) NSInteger bgLevel;
|
||||
@property (nonatomic, copy) NSString *roomTitle;
|
||||
|
||||
@end
|
||||
```
|
||||
|
||||
### 2. CP礼物Banner
|
||||
|
||||
```objc
|
||||
// YMCPGiftBannerView.h
|
||||
#import "YMBaseBannerView.h"
|
||||
|
||||
@interface YMCPGiftBannerView : YMBaseBannerView
|
||||
|
||||
@property (nonatomic, strong, readonly) UIStackView *cpStackView;
|
||||
@property (nonatomic, strong, readonly) UILabel *relationLabel;
|
||||
|
||||
@end
|
||||
|
||||
// YMCPGiftBannerViewModel.h
|
||||
@interface YMCPGiftBannerViewModel : YMBaseBannerViewModel
|
||||
|
||||
@property (nonatomic, copy) NSString *giftImageUrl;
|
||||
@property (nonatomic, copy) NSString *relationText;
|
||||
|
||||
@end
|
||||
```
|
||||
|
||||
### 3. 通用游戏Banner
|
||||
|
||||
```objc
|
||||
// YMGameUniversalBannerView.h
|
||||
#import "YMBaseBannerView.h"
|
||||
|
||||
@interface YMGameUniversalBannerView : YMBaseBannerView
|
||||
|
||||
@property (nonatomic, strong, readonly) NetImageView *gameIconView;
|
||||
@property (nonatomic, assign) NSInteger gameID;
|
||||
|
||||
@end
|
||||
|
||||
// YMGameUniversalBannerViewModel.h
|
||||
@interface YMGameUniversalBannerViewModel : YMBaseBannerViewModel
|
||||
|
||||
@property (nonatomic, copy) NSString *gameIconUrl;
|
||||
@property (nonatomic, assign) NSInteger gameID;
|
||||
@property (nonatomic, copy) NSString *gameTitle;
|
||||
|
||||
@end
|
||||
```
|
||||
|
||||
## 用户反馈机制设计
|
||||
|
||||
### 1. 反馈管理器
|
||||
|
||||
```objc
|
||||
// YMBannerFeedbackManager.h
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSUInteger, YMBannerFeedbackType) {
|
||||
YMBannerFeedbackTypeDisplay, // 展示
|
||||
YMBannerFeedbackTypeClick, // 点击
|
||||
YMBannerFeedbackTypeAction, // 操作
|
||||
YMBannerFeedbackTypeDismiss, // 消失
|
||||
YMBannerFeedbackTypeError // 错误
|
||||
};
|
||||
|
||||
@interface YMBannerFeedbackManager : NSObject
|
||||
|
||||
+ (instancetype)shared;
|
||||
|
||||
#pragma mark - 事件上报
|
||||
- (void)reportBannerEvent:(YMBannerFeedbackType)type
|
||||
banner:(YMBaseBannerView *)banner
|
||||
data:(NSDictionary *)data;
|
||||
|
||||
#pragma mark - 性能监控
|
||||
- (void)startPerformanceMonitoring:(YMBaseBannerView *)banner;
|
||||
- (void)endPerformanceMonitoring:(YMBaseBannerView *)banner;
|
||||
|
||||
#pragma mark - 错误收集
|
||||
- (void)reportError:(NSError *)error
|
||||
banner:(YMBaseBannerView *)banner
|
||||
context:(NSDictionary *)context;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
```
|
||||
|
||||
### 2. 埋点事件定义
|
||||
|
||||
```objc
|
||||
// YMBannerTrackingEvents.h
|
||||
extern NSString * const kYMBannerEventDisplay; // banner_display
|
||||
extern NSString * const kYMBannerEventClick; // banner_click
|
||||
extern NSString * const kYMBannerEventAction; // banner_action
|
||||
extern NSString * const kYMBannerEventDismiss; // banner_dismiss
|
||||
extern NSString * const kYMBannerEventLoadStart; // banner_load_start
|
||||
extern NSString * const kYMBannerEventLoadEnd; // banner_load_end
|
||||
extern NSString * const kYMBannerEventError; // banner_error
|
||||
|
||||
// 埋点参数Key
|
||||
extern NSString * const kYMBannerTrackingKeyType; // banner_type
|
||||
extern NSString * const kYMBannerTrackingKeyRoomUid; // room_uid
|
||||
extern NSString * const kYMBannerTrackingKeyDuration; // duration
|
||||
extern NSString * const kYMBannerTrackingKeyAction; // action
|
||||
extern NSString * const kYMBannerTrackingKeyReason; // reason
|
||||
```
|
||||
|
||||
## 上下文调整说明
|
||||
|
||||
### 1. RoomAnimationView.m 调整
|
||||
|
||||
#### 1.1 替换现有Banner创建逻辑
|
||||
|
||||
```objc
|
||||
// 原代码
|
||||
- (void)playRoomGiftBanner:(AttachmentModel *)obj {
|
||||
[RoomHighValueGiftBannerAnimation display:self.bannerContainer
|
||||
with:obj
|
||||
complete:^{
|
||||
self.isRoomBannerV2Displaying = NO;
|
||||
[self processNextRoomEffectAttachment];
|
||||
}];
|
||||
}
|
||||
|
||||
// 新代码
|
||||
- (void)playRoomGiftBanner:(AttachmentModel *)obj {
|
||||
YMHighValueGiftBannerView *banner = [YMHighValueGiftBannerView bannerWithAttachment:obj];
|
||||
banner.delegate = self;
|
||||
banner.onDisplayComplete = ^{
|
||||
self.isRoomBannerV2Displaying = NO;
|
||||
[self processNextRoomEffectAttachment];
|
||||
};
|
||||
[banner displayInView:self.bannerContainer];
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.2 添加代理实现
|
||||
|
||||
```objc
|
||||
#pragma mark - YMBannerDelegate
|
||||
- (void)banner:(YMBaseBannerView *)banner didReportEvent:(NSString *)event data:(NSDictionary *)data {
|
||||
[[YMBannerFeedbackManager shared] reportBannerEvent:YMBannerFeedbackTypeDisplay
|
||||
banner:banner
|
||||
data:data];
|
||||
}
|
||||
|
||||
- (void)banner:(YMBaseBannerView *)banner willNavigateToRoom:(NSInteger)roomUid {
|
||||
// 处理房间跳转逻辑
|
||||
RoomInfoModel *currentRoom = self.hostDelegate.getRoomInfo;
|
||||
if (currentRoom.uid != roomUid) {
|
||||
// 执行跨房间跳转
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 项目依赖调整
|
||||
|
||||
#### 2.1 新增文件结构
|
||||
|
||||
```YuMi/Modules/YMRoom/View/Banner/
|
||||
├── Base/
|
||||
│ ├── YMBaseBannerView.h/.m
|
||||
│ ├── YMBaseBannerViewModel.h/.m
|
||||
│ └── YMBannerDelegate.h
|
||||
├── Subclasses/
|
||||
│ ├── YMHighValueGiftBannerView.h/.m
|
||||
│ ├── YMCPGiftBannerView.h/.m
|
||||
│ ├── YMBravoGiftBannerView.h/.m
|
||||
│ ├── YMGameUniversalBannerView.h/.m
|
||||
│ └── YMLuckyPackageBannerView.h/.m
|
||||
├── Manager/
|
||||
│ └── YMBannerFeedbackManager.h/.m
|
||||
└── Constants/
|
||||
└── YMBannerTrackingEvents.h/.m
|
||||
```
|
||||
|
||||
#### 2.2 Podfile依赖更新
|
||||
|
||||
```ruby
|
||||
# 确保动画库版本兼容
|
||||
pod 'pop', '~> 1.0'
|
||||
pod 'SVGAPlayer', '~> 2.3'
|
||||
|
||||
# 新增性能监控
|
||||
pod 'YMPerformanceMonitor' # 如果有自定义性能监控库
|
||||
```
|
||||
|
||||
### 3. 配置文件调整
|
||||
|
||||
#### 3.1 添加Banner配置
|
||||
|
||||
```objc
|
||||
// YMBannerConfig.h
|
||||
@interface YMBannerConfig : NSObject
|
||||
|
||||
@property (nonatomic, assign) BOOL enablePerformanceMonitoring;
|
||||
@property (nonatomic, assign) BOOL enableErrorReporting;
|
||||
@property (nonatomic, assign) CGFloat defaultShowDuration;
|
||||
@property (nonatomic, assign) CGFloat defaultStayDuration;
|
||||
@property (nonatomic, assign) CGFloat defaultHideDuration;
|
||||
|
||||
+ (instancetype)shared;
|
||||
|
||||
@end
|
||||
```
|
||||
|
||||
### 4. 迁移策略
|
||||
|
||||
#### 4.1 Phase 1: 基础架构
|
||||
|
||||
- 创建基类和协议
|
||||
- 实现反馈管理器
|
||||
- 设置基础配置
|
||||
|
||||
#### 4.2 Phase 2: 渐进迁移
|
||||
|
||||
- 优先迁移使用频率最高的Banner
|
||||
- 保持向后兼容性
|
||||
- 添加单元测试
|
||||
|
||||
#### 4.3 Phase 3: 优化完善
|
||||
|
||||
- 移除旧代码
|
||||
- 性能优化
|
||||
- 文档完善
|
||||
|
||||
## 总结
|
||||
|
||||
这套新的Banner组件架构具备以下优势:
|
||||
|
||||
1. **统一性**: 提供一致的API和行为模式
|
||||
2. **扩展性**: 易于添加新的Banner类型
|
||||
3. **可维护性**: 集中管理动画、埋点和反馈
|
||||
4. **性能优化**: 统一的资源管理和内存优化
|
||||
5. **用户体验**: 标准化的交互和反馈机制
|
||||
|
||||
通过这套架构,可以显著提升Banner组件的开发效率和用户体验质量。
|
80
DOC/飘屏组件分析文档.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# 飘屏组件分析文档
|
||||
|
||||
## 概述
|
||||
|
||||
本文档详细分析了项目中在 `RoomAnimationView.m` 的 `bannerContainer` 中展示的所有飘屏类型及其触发逻辑。
|
||||
|
||||
## 飘屏展示机制
|
||||
|
||||
- **展示容器**: `bannerContainer` (XPRoomAnimationHitView)
|
||||
- **位置**: 视图层级最顶层,距离顶部导航栏高度
|
||||
- **尺寸**: 屏幕宽度 × 180px 高度
|
||||
- **管理机制**: 统一队列管理,按优先级顺序播放
|
||||
|
||||
## 飘屏类型详细表格
|
||||
|
||||
| 序号 | 飘屏名称 | 类名 | 触发消息类型 | 处理方法 | 业务场景 | 功能描述 |
|
||||
|-----|---------|------|-------------|---------|----------|---------|
|
||||
| 1 | 高价值礼物飘屏 | RoomHighValueGiftBannerAnimation | Custom_Message_Sub_Gift_ChannelNotify | playRoomGiftBanner: | 礼物系统 | 展示高价值礼物的全服广播 |
|
||||
| 2 | CP礼物飘屏 | CPGiftBanner | Custom_Message_Sub_CP_Gift | playCPGiftBanner: | CP系统 | 展示CP相关礼物特效 |
|
||||
| 3 | Bravo超级礼物飘屏 | BravoGiftBannerView | Custom_Message_Sub_Super_Gift_Banner | playBroveBanner: | 超级礼物 | 展示Bravo超级礼物效果 |
|
||||
| 4 | 幸运红包飘屏 | LuckyPackageBannerView | Custom_Message_Sub_LuckyPackage | playLuckyPackageBanner: | 红包系统 | 展示房间红包,支持跨房间跳转 |
|
||||
| 5 | 幸运礼物中奖飘屏 | LuckyGiftWinningBannerView | Custom_Message_Sub_Super_Gift_Winning_Coins_ALL_Room | playLuckyWinningBanner: | 中奖系统 | 展示全服中奖信息 |
|
||||
| 6 | 通用游戏飘屏 | GameUniversalBannerView | Custom_Message_Sub_General_Floating_Screen_One_Room<br/>Custom_Message_Sub_General_Floating_Screen_All_Room | playGameBanner: | 游戏系统 | 展示游戏相关飘屏,支持跳转 |
|
||||
| 7 | 塔罗飘屏 | XPRoomTarrowBannerView | Custom_Message_Sub_Tarot_Advanced<br/>Custom_Message_Sub_Tarot_Intermediate | createTarotBannerAnimation: | 塔罗活动 | 展示塔罗相关活动信息 |
|
||||
| 8 | 星厨房飘屏 | XPRoomStarKitchenBannerView | Custom_Message_Sub_Star_Kitchen_FullScreen | createStarKitchenBannerAnimation: | 厨房活动 | 展示星厨房活动 |
|
||||
| 9 | 夺宝精灵飘屏 | - | Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L4<br/>Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L5<br/>Custom_Message_Sub_Treasure_Fairy_Convert_L1/L2/L3 | createTreasureFairyBannerAnimation: | 夺宝活动 | 展示夺宝精灵高等级奖励 |
|
||||
| 10 | 主播小时榜飘屏 | XPRoomAnchorRankBannerView | Custom_Message_Sub_Anchor_Hour_Rank | 创建主播排行榜飘屏 | 排行榜 | 展示主播小时榜信息 |
|
||||
| 11 | 通用H5飘屏 | XPRoomTarrowBannerView | Custom_Message_Sub_Common_H5_Novice<br/>Custom_Message_Sub_Common_H5_Advanced | createCommonH5BannerAnimation: | H5活动 | 展示通用H5活动飘屏 |
|
||||
| 12 | 通用飘屏 | PIUniversalBannerView | 多种消息类型 | createGeneralFloatingScreenAnimation: | 通用展示 | 提供通用飘屏展示能力 |
|
||||
|
||||
## 队列管理机制
|
||||
|
||||
### 核心属性
|
||||
|
||||
- **队列数组**: `roomBannertModelsQueueV2` (NSMutableArray)
|
||||
- **状态标记**: `isRoomBannerV2Displaying` (BOOL)
|
||||
|
||||
### 处理流程
|
||||
|
||||
1. **消息接收**: 调用 `inserBannerModelToQueue:` 将消息加入队列
|
||||
2. **优先级排序**: 调用 `sortBannerQueue` 按消息类型的second值排序(数值越小优先级越高)
|
||||
3. **顺序播放**: 调用 `processNextRoomEffectAttachment` 逐个播放
|
||||
4. **播放完成**: 每个飘屏播放完成后,设置 `isRoomBannerV2Displaying = NO` 并处理下一个
|
||||
|
||||
### 优先级规则
|
||||
|
||||
飘屏按 `AttachmentModel.second` 值进行排序,确保重要消息优先展示。
|
||||
|
||||
## 消息类型分类
|
||||
|
||||
### 礼物相关
|
||||
|
||||
- Custom_Message_Sub_Gift_ChannelNotify (32)
|
||||
- Custom_Message_Sub_CP_Gift
|
||||
- Custom_Message_Sub_Super_Gift_Banner (1066)
|
||||
|
||||
### 红包/福袋相关
|
||||
|
||||
- Custom_Message_Sub_LuckyPackage (607)
|
||||
- Custom_Message_Sub_Super_Gift_Winning_Coins_ALL_Room (1063)
|
||||
|
||||
### 游戏相关
|
||||
|
||||
- Custom_Message_Sub_General_Floating_Screen_One_Room (1071)
|
||||
- Custom_Message_Sub_General_Floating_Screen_All_Room (1072)
|
||||
|
||||
### 活动相关
|
||||
|
||||
- Custom_Message_Sub_Tarot_Advanced (714)
|
||||
- Custom_Message_Sub_Tarot_Intermediate (713)
|
||||
- Custom_Message_Sub_Star_Kitchen_FullScreen (1042)
|
||||
- Custom_Message_Sub_Treasure_Fairy_* (9700系列)
|
||||
|
||||
### 排行榜相关
|
||||
|
||||
- Custom_Message_Sub_Anchor_Hour_Rank (891)
|
||||
|
||||
### 通用相关
|
||||
|
||||
- Custom_Message_Sub_Common_H5_* (1100系列)
|
203
DOC/飘屏组件抽象分析.md
Normal file
@@ -0,0 +1,203 @@
|
||||
# 飘屏组件抽象分析
|
||||
|
||||
## 分析概述
|
||||
|
||||
基于对项目中12种飘屏组件的深入分析,发现这些组件存在高度相似的设计模式和实现结构,具备抽象出统一父类的条件。
|
||||
|
||||
## 现状分析
|
||||
|
||||
### 共同特征
|
||||
|
||||
经过代码分析,发现所有飘屏组件都具有以下共同特征:
|
||||
|
||||
#### 1. 统一的类方法签名模式
|
||||
|
||||
大部分Banner类都采用了相似的类方法签名:
|
||||
|
||||
``` objc
|
||||
+ (void)display:(UIView *)superView
|
||||
with:(AttachmentModel *)attachment
|
||||
complete:(void(^)(void))complete;
|
||||
|
||||
// 或者带房间信息的版本
|
||||
+ (void)display:(UIView *)superView
|
||||
inRoomUid:(NSInteger)roomUid
|
||||
with:(AttachmentModel *)attachment
|
||||
complete:(void(^)(void))complete
|
||||
exitCurrentRoom:(void(^)(void))exit;
|
||||
```
|
||||
|
||||
#### 2. 共同的内部属性结构
|
||||
|
||||
```objc
|
||||
@property (nonatomic, strong) SomeViewModel *model; // 数据模型
|
||||
@property (nonatomic, strong) UIImageView *backgroundImageView; // 背景图片
|
||||
@property (nonatomic, copy) void(^completeDisplay)(void); // 完成回调
|
||||
@property (nonatomic, copy) void(^exitCurrentRoom)(void); // 退房回调
|
||||
@property (nonatomic, assign) NSInteger currentRoomUid; // 当前房间ID
|
||||
```
|
||||
|
||||
#### 3. 相似的动画流程
|
||||
|
||||
- 从屏幕右侧滑入 (x = KScreenWidth)
|
||||
- 短暂停留展示
|
||||
- 滑出屏幕或淡出
|
||||
- 执行完成回调
|
||||
|
||||
#### 4. 统一的数据处理模式
|
||||
|
||||
- 都依赖 `AttachmentModel` 作为数据源
|
||||
- 都创建对应的ViewModel进行数据解析
|
||||
- 都继承自 `PIBaseModel`
|
||||
|
||||
#### 5. 相似的UI组件
|
||||
|
||||
- 背景图片视图
|
||||
- 用户头像
|
||||
- 文本标签
|
||||
- 可选的SVGA动画视图
|
||||
- 可选的交互按钮
|
||||
|
||||
## 抽象方案设计
|
||||
|
||||
### 建议的基类结构: `BaseRoomBannerView`
|
||||
|
||||
```objc
|
||||
@interface BaseRoomBannerView : UIView
|
||||
|
||||
#pragma mark - 核心属性
|
||||
@property (nonatomic, strong) AttachmentModel *attachment;
|
||||
@property (nonatomic, strong) PIBaseModel *viewModel;
|
||||
@property (nonatomic, assign) NSInteger currentRoomUid;
|
||||
@property (nonatomic, assign) NSInteger targetRoomUid;
|
||||
|
||||
#pragma mark - UI组件
|
||||
@property (nonatomic, strong) UIView *containerView;
|
||||
@property (nonatomic, strong) UIImageView *backgroundImageView;
|
||||
@property (nonatomic, strong) NetImageView *avatarImageView;
|
||||
@property (nonatomic, strong) UILabel *titleLabel;
|
||||
@property (nonatomic, strong) UILabel *subTitleLabel;
|
||||
@property (nonatomic, strong) UIButton *actionButton;
|
||||
@property (nonatomic, strong) SVGAImageView *svgaView;
|
||||
|
||||
#pragma mark - 动画配置
|
||||
@property (nonatomic, assign) CGFloat showDuration;
|
||||
@property (nonatomic, assign) CGFloat stayDuration;
|
||||
@property (nonatomic, assign) CGFloat hideDuration;
|
||||
@property (nonatomic, assign) BOOL useSlideAnimation;
|
||||
@property (nonatomic, assign) BOOL useFadeAnimation;
|
||||
|
||||
#pragma mark - 回调
|
||||
@property (nonatomic, copy) void(^completeDisplay)(void);
|
||||
@property (nonatomic, copy) void(^exitCurrentRoom)(void);
|
||||
@property (nonatomic, copy) void(^didTapBanner)(NSInteger roomID);
|
||||
|
||||
#pragma mark - 类方法
|
||||
+ (instancetype)createWithAttachment:(AttachmentModel *)attachment
|
||||
inRoomUid:(NSInteger)roomUid
|
||||
complete:(void(^)(void))complete
|
||||
exitCurrentRoom:(void(^)(void))exit;
|
||||
|
||||
+ (void)display:(UIView *)superView
|
||||
with:(AttachmentModel *)attachment
|
||||
complete:(void(^)(void))complete;
|
||||
|
||||
+ (void)display:(UIView *)superView
|
||||
inRoomUid:(NSInteger)roomUid
|
||||
with:(AttachmentModel *)attachment
|
||||
complete:(void(^)(void))complete
|
||||
exitCurrentRoom:(void(^)(void))exit;
|
||||
|
||||
#pragma mark - 实例方法
|
||||
- (void)setupWithAttachment:(AttachmentModel *)attachment;
|
||||
- (void)showInSuperView:(UIView *)superView;
|
||||
- (void)performShowAnimation;
|
||||
- (void)performHideAnimation;
|
||||
|
||||
#pragma mark - 子类重写方法
|
||||
- (Class)viewModelClass; // 返回对应的ViewModel类
|
||||
- (void)setupUI; // 设置UI布局
|
||||
- (void)configureWithModel:(PIBaseModel *)model; // 配置数据
|
||||
- (void)customizeAnimation; // 自定义动画
|
||||
- (void)handleTapAction; // 处理点击事件
|
||||
|
||||
@end
|
||||
```
|
||||
|
||||
### 抽象优势分析
|
||||
|
||||
#### 1. 代码复用率提升
|
||||
|
||||
- 消除重复的动画逻辑
|
||||
- 统一的数据处理流程
|
||||
- 共享的UI组件管理
|
||||
|
||||
#### 2. 维护成本降低
|
||||
|
||||
- 集中管理动画参数
|
||||
- 统一的回调处理机制
|
||||
- 标准化的生命周期管理
|
||||
|
||||
#### 3. 扩展性增强
|
||||
|
||||
- 新增飘屏类型只需继承基类
|
||||
- 便于添加通用功能(如埋点、性能监控)
|
||||
- 支持主题切换等全局功能
|
||||
|
||||
#### 4. 一致性保证
|
||||
|
||||
- 统一的动画效果和时长
|
||||
- 标准化的交互行为
|
||||
- 一致的视觉表现
|
||||
|
||||
### 实现策略
|
||||
|
||||
#### 阶段一:创建基类
|
||||
|
||||
1. 提取共同属性和方法
|
||||
2. 实现通用动画逻辑
|
||||
3. 定义子类接口规范
|
||||
|
||||
#### 阶段二:重构现有类
|
||||
|
||||
1. 逐步迁移现有Banner类继承基类
|
||||
2. 移除重复代码
|
||||
3. 保持向后兼容
|
||||
|
||||
#### 阶段三:优化和扩展
|
||||
|
||||
1. 添加性能监控
|
||||
2. 实现主题支持
|
||||
3. 统一埋点逻辑
|
||||
|
||||
### 潜在挑战
|
||||
|
||||
#### 1. 兼容性问题
|
||||
|
||||
- 现有代码的重构风险
|
||||
- 不同Banner的特殊需求差异
|
||||
- 第三方依赖的适配
|
||||
|
||||
#### 2. 性能考虑
|
||||
|
||||
- 基类功能过于复杂可能影响性能
|
||||
- 内存占用的优化
|
||||
- 动画性能的平衡
|
||||
|
||||
#### 3. 维护复杂度
|
||||
|
||||
- 基类变更可能影响所有子类
|
||||
- 需要详细的文档和测试
|
||||
- 团队学习成本
|
||||
|
||||
## 结论
|
||||
|
||||
**建议进行抽象**:项目中的飘屏组件具有高度的相似性,抽象出基类能够显著提升代码质量和开发效率。建议采用渐进式重构策略,先创建基类和接口规范,再逐步迁移现有实现,确保系统稳定性的同时实现架构优化。
|
||||
|
||||
## 优先级建议
|
||||
|
||||
1. **高优先级**:创建 `BaseRoomBannerView` 基类
|
||||
2. **中优先级**:重构使用频率最高的Banner类
|
||||
3. **低优先级**:添加扩展功能和优化
|
||||
|
||||
通过这种抽象设计,能够在保持现有功能完整性的同时,为未来的功能扩展和维护奠定良好的架构基础。
|
10
Podfile
@@ -6,12 +6,9 @@ target 'YuMi' do
|
||||
#pag动画
|
||||
pod 'libpag'
|
||||
pod 'Bugly'
|
||||
# pod 'Adjust'
|
||||
pod 'Firebase/Analytics'
|
||||
pod 'FBSDKLoginKit'
|
||||
pod 'FBSDKCoreKit'
|
||||
pod 'FBSDKShareKit'
|
||||
pod 'LineSDKSwift'
|
||||
# 滑动标签栏
|
||||
pod 'JXCategoryView'
|
||||
pod 'JXPagingView/Pager'
|
||||
@@ -47,20 +44,19 @@ target 'YuMi' do
|
||||
#上传音乐
|
||||
pod 'CocoaAsyncSocket',:modular_headers => true
|
||||
#声网
|
||||
pod 'AgoraRtcEngine_iOS'
|
||||
|
||||
pod 'SSKeychain'
|
||||
pod 'Base64'
|
||||
#pop动画
|
||||
pod 'pop'
|
||||
#云信
|
||||
pod 'NIMSDK_LITE'
|
||||
pod 'NIMSDK_LITE', '~> 10.9.40'
|
||||
pod 'GKCycleScrollView'
|
||||
pod 'SVGAPlayer'
|
||||
pod 'GoogleSignIn'
|
||||
pod 'mob_linksdk_pro'
|
||||
pod 'mob_sharesdk'
|
||||
pod 'mob_sharesdk/ShareSDKPlatforms/Apple'
|
||||
#pod 'mob_sharesdk/ShareSDKPlatforms/Line'
|
||||
pod 'mob_sharesdk/ShareSDKExtension'
|
||||
|
||||
pod 'UMCommon'
|
||||
@@ -77,6 +73,8 @@ post_install do |installer|
|
||||
project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
|
||||
config.build_settings['DEBUG_INFORMATION_FORMAT'] = 'dwarf-with-dsym'
|
||||
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
||||
xcconfig_path = config.base_configuration_reference.real_path
|
||||
xcconfig = File.read(xcconfig_path)
|
||||
xcconfig_mod = xcconfig.gsub(/DT_TOOLCHAIN_DIR/, "TOOLCHAIN_DIR")
|
||||
|
@@ -50,6 +50,13 @@
|
||||
ReferencedContainer = "container:YuMi.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<EnvironmentVariables>
|
||||
<EnvironmentVariable
|
||||
key = "OS_ACTIVITY_MODE"
|
||||
value = "disable"
|
||||
isEnabled = "NO">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
@@ -72,7 +79,7 @@
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
|
||||
#import <Bugly/Bugly.h>
|
||||
#import <UIKit/UIDevice.h>
|
||||
|
||||
#import "YuMi-swift.h"
|
||||
|
||||
@@ -75,6 +76,7 @@ UIKIT_EXTERN NSString * adImageName;
|
||||
/**
|
||||
崩溃收集 Bugly
|
||||
*/
|
||||
|
||||
- (void) configBugly {
|
||||
|
||||
BuglyConfig *config = [[BuglyConfig alloc] init];
|
||||
@@ -83,22 +85,25 @@ UIKIT_EXTERN NSString * adImageName;
|
||||
#ifdef DEBUG
|
||||
config.debugMode = NO;//YES; // debug 模式下,开启调试模式
|
||||
config.channel = [YYUtility getAppSource];
|
||||
// config.blockMonitorEnable = YES; // 卡顿监控开关,默认关闭
|
||||
config.reportLogLevel = BuglyLogLevelSilent; // BuglyLogLevelVerbose; // 设置打印日志级别
|
||||
config.reportLogLevel = BuglyLogLevelWarn;// BuglyLogLevelSilent; // BuglyLogLevelVerbose; // 设置打印日志级别
|
||||
[Bugly startWithAppId:@"c937fd00f7" config:config];
|
||||
#else
|
||||
config.unexpectedTerminatingDetectionEnable = YES; // 非正常退出事件记录开关,默认关闭
|
||||
config.debugMode = NO; // release 模式下,关闭调试模式
|
||||
config.channel = [YYUtility getAppSource];;
|
||||
config.blockMonitorEnable = NO; // 卡顿监控开关,默认关闭
|
||||
config.blockMonitorEnable = YES; // 卡顿监控开关,默认关闭
|
||||
config.reportLogLevel = BuglyLogLevelWarn; // 设置自定义日志上报的级别,默认不上报自定义日志
|
||||
NSString *buylyKey = @"8627948559"; // isEnterprise == NO ? @"5334684d86" : @"d65df59a68";
|
||||
NSString *buylyKey = @"8627948559";
|
||||
[Bugly startWithAppId:buylyKey config:config];
|
||||
#endif
|
||||
}
|
||||
- (void)configNIMSDK {
|
||||
//推荐在程序启动的时候初始化 NIMSDK
|
||||
NSString *appKey = KeyWithType(KeyType_NetEase);
|
||||
NSString *appKey = [[ClientConfig shareConfig].configInfo nimKey];
|
||||
if ([NSString isEmpty:appKey]) {
|
||||
appKey = KeyWithType(KeyType_NetEase);
|
||||
}
|
||||
|
||||
NIMSDKOption *option = [NIMSDKOption optionWithAppKey:appKey];
|
||||
#ifdef DEBUG
|
||||
option.apnsCername = @"pikoDevelopPush";
|
||||
@@ -110,18 +115,28 @@ UIKIT_EXTERN NSString * adImageName;
|
||||
|
||||
// NIM SDK初始化
|
||||
[NIMCustomObject registerCustomDecoder:[[CustomAttachmentDecoder alloc] init]];
|
||||
[[NIMSDKConfig sharedConfig] setShouldSyncStickTopSessionInfos:YES];
|
||||
[NIMSDKConfig sharedConfig].shouldConsiderRevokedMessageUnreadCount = YES;
|
||||
///置顶会话同步
|
||||
[[NIMSDKConfig sharedConfig] setShouldSyncStickTopSessionInfos:YES];
|
||||
|
||||
// cdn统计回调不触发
|
||||
[NIMSDKConfig sharedConfig].cdnTrackInterval = 0;
|
||||
|
||||
// 最小时间间隔设置为最小边界值
|
||||
[NIMSDKConfig sharedConfig].chatroomMessageReceiveMinInterval = 50;
|
||||
|
||||
#ifdef DEBUG
|
||||
[NIMSDKConfig sharedConfig].enabledHttpsForInfo = NO;
|
||||
[NIMSDKConfig sharedConfig].enabledHttpsForMessage = NO;
|
||||
#else
|
||||
// 生产环境启用HTTPS
|
||||
[NIMSDKConfig sharedConfig].enabledHttpsForInfo = YES;
|
||||
[NIMSDKConfig sharedConfig].enabledHttpsForMessage = YES;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)configShareSDK {
|
||||
|
||||
[PILineLoginManager registerLine];
|
||||
// [PILineLoginManager registerLine];
|
||||
|
||||
[ShareSDK registPlatforms:^(SSDKRegister *platformsRegister) {
|
||||
///faceBook
|
||||
@@ -145,12 +160,18 @@ UIKIT_EXTERN NSString * adImageName;
|
||||
NSArray * emojiArray = dic[@"data"];
|
||||
NSMutableArray * array = [NSMutableArray array];
|
||||
for (int i = 0; i < emojiArray.count; i++) {
|
||||
NSDictionary * dic = [emojiArray objectAtIndex:i];
|
||||
|
||||
UIImage * image = [UIImage imageNamed:dic[@"file"]];
|
||||
QEmotion * info = [[QEmotion alloc] init];
|
||||
info.identifier = dic[@"id"];
|
||||
|
||||
NSDictionary * dic = [emojiArray xpSafeObjectAtIndex:i];
|
||||
if (dic) {
|
||||
info.displayName = dic[@"tag"];
|
||||
info.identifier = dic[@"id"];
|
||||
}
|
||||
|
||||
info.image = image;
|
||||
info.displayName = dic[@"tag"];
|
||||
|
||||
[array addObject:info];
|
||||
}
|
||||
//在这里强烈建议先预加载一下表情
|
||||
@@ -171,18 +192,13 @@ UIKIT_EXTERN NSString * adImageName;
|
||||
NSString *filePath = [XPAdImageTool.shareImageTool getFilePathWithImageName:adName];
|
||||
BOOL isExist = [XPAdImageTool.shareImageTool isFileExistWithFilePath:filePath];
|
||||
|
||||
if ([kUserDefaults integerForKey:@"adShow"]) {
|
||||
[kUserDefaults setInteger:[kUserDefaults integerForKey:@"adShow"]+1
|
||||
forKey:@"adShow"];
|
||||
} else {
|
||||
[kUserDefaults setInteger:1 forKey:@"adShow"];
|
||||
}
|
||||
|
||||
if (isExist) {// 图片存在
|
||||
if ([kUserDefaults integerForKey:@"adShow"] > 4) {
|
||||
// if ([kUserDefaults integerForKey:@"adShow"] > 4) {
|
||||
@kWeakify(self);
|
||||
AdvertiseModel *info = [XPAdImageTool.shareImageTool getAdInfoFromCacheInMainWith:adName];
|
||||
XPAdvertiseView *advertiseView = [[XPAdvertiseView alloc] initWithFrame:self.window.bounds];
|
||||
advertiseView.type = info.type;
|
||||
advertiseView.fileModel = info.fillVo;
|
||||
advertiseView.filePath = filePath;
|
||||
advertiseView.dismissHandler = ^(BOOL shouldJump) {
|
||||
@kStrongify(self)
|
||||
@@ -194,7 +210,7 @@ UIKIT_EXTERN NSString * adImageName;
|
||||
});
|
||||
};
|
||||
[advertiseView show];
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +233,10 @@ UIKIT_EXTERN NSString * adImageName;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SplashInfoSkipTypeWeb: {
|
||||
case SplashInfoSkipTypeWeb:
|
||||
case SplashInfoSkipTypeWeb_CP:
|
||||
case SplashInfoSkipTypeWeb_Custom:
|
||||
case SplashInfoSkipTypeWeb_WeekStar: {
|
||||
// 跳转 H5
|
||||
if (info.link.length > 0) {
|
||||
XPWebViewController *webView = [[XPWebViewController alloc] initWithRoomUID:nil];
|
||||
|
@@ -10,7 +10,6 @@
|
||||
#import <UMCommon/UMCommon.h>
|
||||
#import <MobLinkPro/MobLink.h>
|
||||
#import <MobLinkPro/MLSDKScene.h>
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit.h>
|
||||
#import "TabbarViewController.h"
|
||||
#import "BaseNavigationController.h"
|
||||
#import "AppDelegate+ThirdConfig.h"
|
||||
@@ -18,14 +17,15 @@
|
||||
#import <AppTrackingTransparency/AppTrackingTransparency.h>
|
||||
#import "ClientConfig.h"
|
||||
#import <GoogleSignIn/GoogleSignIn.h>
|
||||
#import "GULAppDelegateSwizzler.h"
|
||||
#import <GoogleSignIn/GoogleSignIn.h>
|
||||
#import "XPLoginViewController.h"
|
||||
#import "LoginViewController.h"
|
||||
#import "AccountModel.h"
|
||||
#import "YuMi-swift.h"
|
||||
#import "SessionViewController.h"
|
||||
#import "LoginFullInfoViewController.h"
|
||||
@import Firebase;
|
||||
#import "UIView+VAP.h"
|
||||
#import "SocialShareManager.h"
|
||||
|
||||
UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
|
||||
@interface AppDelegate ()<IMLSDKRestoreDelegate>
|
||||
@@ -34,6 +34,26 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
//日志接口
|
||||
void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const char* func, NSString *module, NSString *format, ...) {
|
||||
|
||||
// 屏蔽 MP4 播放 log
|
||||
return;
|
||||
|
||||
// if (format.UTF8String == nil) {
|
||||
// NSLog(@"log包含非utf-8字符");
|
||||
// return;
|
||||
// }
|
||||
// if (level > VAPLogLevelDebug) {
|
||||
// va_list argList;
|
||||
// va_start(argList, format);
|
||||
// NSString* message = [[NSString alloc] initWithFormat:format arguments:argList];
|
||||
// file = [NSString stringWithUTF8String:file].lastPathComponent.UTF8String;
|
||||
// NSLog(@"<%@> %s(%@):%s [%@] - %@",@(level), file, @(line), func, module, message);
|
||||
// va_end(argList);
|
||||
// }
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
@@ -43,7 +63,8 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
self.window.rootViewController = launchScreenVC;
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
|
||||
[VAPView registerHWDLog:qg_VAP_Logger_handler];
|
||||
|
||||
///初始化一些 sdk配置
|
||||
[self initThirdConfig];
|
||||
[self initUM:application launchOptions:launchOptions];
|
||||
@@ -55,9 +76,12 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
[self loadMainPage];
|
||||
[self setupLaunchADView];
|
||||
});
|
||||
|
||||
}];
|
||||
|
||||
if (@available(iOS 15, *)) {
|
||||
[[UITableView appearance] setSectionHeaderTopPadding:0];
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -69,8 +93,6 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
[UMConfigure initWithAppkey:@"6434c6dfd64e686139618269"
|
||||
channel:@"appstore"];
|
||||
}
|
||||
[[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
[FIRApp configure];
|
||||
[MobLink setDelegate:self];
|
||||
}
|
||||
|
||||
@@ -83,10 +105,12 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
}else{
|
||||
[self toHomeTabbarPage];
|
||||
}
|
||||
|
||||
[[ClientConfig shareConfig] clientInit];
|
||||
}
|
||||
|
||||
- (void)toLoginPage {
|
||||
XPLoginViewController *lvc = [[XPLoginViewController alloc] init];
|
||||
LoginViewController *lvc = [[LoginViewController alloc] init];
|
||||
BaseNavigationController * navigationController = [[BaseNavigationController alloc] initWithRootViewController:lvc];
|
||||
navigationController.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||
self.window.rootViewController = navigationController;
|
||||
@@ -124,16 +148,16 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
ATTrackingManagerAuthorizationStatus status = ATTrackingManager.trackingAuthorizationStatus;
|
||||
switch (status) {
|
||||
case ATTrackingManagerAuthorizationStatusDenied:
|
||||
NSLog(@"用户拒绝IDFA");
|
||||
// NSLog(@"用户拒绝IDFA");
|
||||
break;
|
||||
case ATTrackingManagerAuthorizationStatusAuthorized:
|
||||
NSLog(@"用户允许IDFA");
|
||||
// NSLog(@"用户允许IDFA");
|
||||
break;
|
||||
case ATTrackingManagerAuthorizationStatusNotDetermined: {
|
||||
NSLog(@"用户未做选择或未弹窗IDFA");
|
||||
// NSLog(@"用户未做选择或未弹窗IDFA");
|
||||
//请求弹出用户授权框,只会在程序运行是弹框1次,除非卸载app重装,通地图、相机等权限弹框一样
|
||||
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
|
||||
NSLog(@"app追踪IDFA权限:%lu",(unsigned long)status);
|
||||
// NSLog(@"app追踪IDFA权限:%lu",(unsigned long)status);
|
||||
}];
|
||||
}
|
||||
break;
|
||||
@@ -178,57 +202,47 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
|
||||
///URL Scheme跳转
|
||||
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
|
||||
NSString *bundleID = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
|
||||
if ([url.scheme isEqualToString:[NSString stringWithFormat:@"line3rdp.%@",bundleID]]) {
|
||||
return [PILineLoginManager applicationOpenurl:app open:url];
|
||||
}
|
||||
[[SocialShareManager sharedManager] handleURL:url];
|
||||
|
||||
NSString *text = [url query];
|
||||
if(text.length){
|
||||
NSMutableDictionary *paramsDict = [NSMutableDictionary dictionary];
|
||||
NSArray *paramArray = [text componentsSeparatedByString:@"&"];
|
||||
for (NSString *param in paramArray) {
|
||||
if (param && param.length) {
|
||||
NSArray *parArr = [param componentsSeparatedByString:@"="];
|
||||
if (parArr.count == 2) {
|
||||
[paramsDict setObject:parArr[1] forKey:parArr[0]];
|
||||
}
|
||||
}
|
||||
}
|
||||
if(paramsDict[@"type"] != nil){
|
||||
NSInteger type = [paramsDict[@"type"] integerValue];
|
||||
if (type == 2) {
|
||||
NSString *uid = [NSString stringWithFormat:@"%@",paramsDict[@"uid"]];
|
||||
[[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"uid":uid}];
|
||||
ClientConfig *config = [ClientConfig shareConfig];
|
||||
config.roomId = uid;
|
||||
}else if(type == 7){
|
||||
NSString *uid = [NSString stringWithFormat:@"%@",paramsDict[@"uid"]];
|
||||
[[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"type":@"kOpenChat",@"uid":uid}];
|
||||
ClientConfig *config = [ClientConfig shareConfig];
|
||||
config.chatId = uid;
|
||||
}else if (type == 8){
|
||||
NSString *inviteCode = paramsDict[@"inviteCode"];
|
||||
if (inviteCode != nil && [[AccountInfoStorage instance]getUid].length == 0){
|
||||
ClientConfig *config = [ClientConfig shareConfig];
|
||||
config.inviteCode = inviteCode;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if([url.absoluteString containsString:@"fb1266232494209868"]){
|
||||
return [[FBSDKApplicationDelegate sharedInstance] application:app
|
||||
openURL:url
|
||||
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
|
||||
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
|
||||
}
|
||||
|
||||
return [GIDSignIn.sharedInstance handleURL:url];
|
||||
}
|
||||
|
||||
//- (void)__oldApplicationOpenURLMethod:(NSURL *)url {
|
||||
// NSString *text = [url query];
|
||||
// if(text.length){
|
||||
// NSMutableDictionary *paramsDict = [NSMutableDictionary dictionary];
|
||||
// NSArray *paramArray = [text componentsSeparatedByString:@"&"];
|
||||
// for (NSString *param in paramArray) {
|
||||
// if (param && param.length) {
|
||||
// NSArray *parArr = [param componentsSeparatedByString:@"="];
|
||||
// if (parArr.count == 2) {
|
||||
// [paramsDict setObject:parArr[1] forKey:parArr[0]];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if(paramsDict[@"type"] != nil){
|
||||
// NSInteger type = [paramsDict[@"type"] integerValue];
|
||||
// if (type == 2) {
|
||||
// NSString *uid = [NSString stringWithFormat:@"%@",paramsDict[@"uid"]];
|
||||
// [[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"uid":uid}];
|
||||
// ClientConfig *config = [ClientConfig shareConfig];
|
||||
// config.roomId = uid;
|
||||
// }else if(type == 7){
|
||||
// NSString *uid = [NSString stringWithFormat:@"%@",paramsDict[@"uid"]];
|
||||
// [[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"type":@"kOpenChat",@"uid":uid}];
|
||||
// ClientConfig *config = [ClientConfig shareConfig];
|
||||
// config.chatId = uid;
|
||||
// }else if (type == 8){
|
||||
// NSString *inviteCode = paramsDict[@"inviteCode"];
|
||||
// if (inviteCode != nil && [[AccountInfoStorage instance]getUid].length == 0){
|
||||
// ClientConfig *config = [ClientConfig shareConfig];
|
||||
// config.inviteCode = inviteCode;
|
||||
// }
|
||||
// }
|
||||
//// return YES;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
#pragma mark - Core Data stack
|
||||
@synthesize managedObjectContext = _managedObjectContext;
|
||||
@@ -270,7 +284,7 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
|
||||
// Replace this with code to handle the error appropriately.
|
||||
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
||||
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
|
||||
// NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -302,7 +316,7 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
|
||||
// Replace this implementation with code to handle the error appropriately.
|
||||
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
||||
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
|
||||
// NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
@@ -1,16 +0,0 @@
|
||||
//
|
||||
// FBSDKSettings+PISDKSettings.h
|
||||
// YuMi
|
||||
//
|
||||
// Created by duoban on 2023/9/22.
|
||||
//
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface FBSDKSettings (PISDKSettings)
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,19 +0,0 @@
|
||||
//
|
||||
// FBSDKSettings+PISDKSettings.m
|
||||
// YuMi
|
||||
//
|
||||
// Created by duoban on 2023/9/22.
|
||||
//
|
||||
|
||||
#import "FBSDKSettings+PISDKSettings.h"
|
||||
#import "GULAppDelegateSwizzler.h"
|
||||
|
||||
|
||||
@implementation FBSDKSettings (PISDKSettings)
|
||||
///必须为FBSDKSettings添加setAutoLogAppEventsEnabled方法,不然分享时会闪退
|
||||
+(void)setAutoLogAppEventsEnabled:(BOOL)is{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@end
|
BIN
YuMi/Assets.xcassets/1.0.15/luck_gift_flag.imageset/1@3x (1).png
vendored
Normal file
After Width: | Height: | Size: 98 KiB |
@@ -9,7 +9,7 @@
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "椭圆 5@3x.png",
|
||||
"filename" : "1@3x (1).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 28 KiB |
@@ -9,7 +9,7 @@
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "容器 8156@3x.png",
|
||||
"filename" : "椭圆 6@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 14 KiB |
BIN
YuMi/Assets.xcassets/1.0.15/luck_gift_flag_ball.imageset/椭圆 6@3x.png
vendored
Normal file
After Width: | Height: | Size: 41 KiB |
@@ -9,7 +9,7 @@
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "示例图@3x.png",
|
||||
"filename" : "切图 30@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/grey_arrow.imageset/切图 30@3x.png
vendored
Normal file
After Width: | Height: | Size: 1.1 KiB |
@@ -9,7 +9,7 @@
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "示例图@3x 2.png",
|
||||
"filename" : "勾选@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/region_list_selected.imageset/勾选@3x.png
vendored
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_at.imageset/3@3x.png
vendored
Normal file
After Width: | Height: | Size: 14 KiB |
@@ -9,7 +9,7 @@
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "示例图@3x (1).png",
|
||||
"filename" : "3@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_be_manager.imageset/2@3x (1).png
vendored
Normal file
After Width: | Height: | Size: 5.5 KiB |
@@ -9,7 +9,7 @@
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "room_menu_play@3x.png",
|
||||
"filename" : "2@3x (1).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_blacklist.imageset/3@3x (1).png
vendored
Normal file
After Width: | Height: | Size: 6.0 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_blacklist.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "3@3x (1).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_chat.imageset/2@3x.png
vendored
Normal file
After Width: | Height: | Size: 12 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_chat.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "2@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_clean_gift_value.imageset/2@3x.png
vendored
Normal file
After Width: | Height: | Size: 5.7 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_clean_gift_value.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "2@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_close_mic.imageset/5@3x (3).png
vendored
Normal file
After Width: | Height: | Size: 6.6 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_close_mic.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "5@3x (3).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_follow.imageset/4@3x (1).png
vendored
Normal file
After Width: | Height: | Size: 13 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_follow.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "4@3x (1).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_gift.imageset/2@3x (2).png
vendored
Normal file
After Width: | Height: | Size: 4.9 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_gift.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "2@3x (2).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_kick.imageset/1@3x.png
vendored
Normal file
After Width: | Height: | Size: 4.9 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_kick.imageset/Contents.json
vendored
Normal 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
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_lock.imageset/1@3x (1).png
vendored
Normal file
After Width: | Height: | Size: 4.9 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_lock.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "1@3x (1).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_not_manager.imageset/5@3x (2).png
vendored
Normal file
After Width: | Height: | Size: 5.8 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_not_manager.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "5@3x (2).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_open_mic.imageset/4@3x (2).png
vendored
Normal file
After Width: | Height: | Size: 5.9 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_open_mic.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "4@3x (2).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_out_mic.imageset/5@3x (1).png
vendored
Normal file
After Width: | Height: | Size: 6.2 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_out_mic.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "5@3x (1).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
21
YuMi/Assets.xcassets/1.0.31/room_user_card_report.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "举报@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_report.imageset/举报@3x.png
vendored
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_send_gift.imageset/1@3x.png
vendored
Normal file
After Width: | Height: | Size: 24 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_send_gift.imageset/Contents.json
vendored
Normal 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
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_unfollow.imageset/4@3x.png
vendored
Normal file
After Width: | Height: | Size: 5.9 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_unfollow.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "4@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_unlock.imageset/1@3x (2).png
vendored
Normal file
After Width: | Height: | Size: 5.0 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_unlock.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "1@3x (2).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_card_up_mic.imageset/5@3x.png
vendored
Normal file
After Width: | Height: | Size: 6.3 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_card_up_mic.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "5@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
21
YuMi/Assets.xcassets/1.0.31/room_user_position_empty.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "组 8307@3x (1).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_position_empty.imageset/组 8307@3x (1).png
vendored
Normal file
After Width: | Height: | Size: 9.1 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_position_owner.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "组 8307@3x (3).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_position_owner.imageset/组 8307@3x (3).png
vendored
Normal file
After Width: | Height: | Size: 16 KiB |
21
YuMi/Assets.xcassets/1.0.31/room_user_position_used.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "组 8307@3x (2).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.31/room_user_position_used.imageset/组 8307@3x (2).png
vendored
Normal file
After Width: | Height: | Size: 8.7 KiB |
21
YuMi/Assets.xcassets/1.0.34/diamond_help.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "切图 31@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/diamond_help.imageset/切图 31@3x.png
vendored
Normal file
After Width: | Height: | Size: 2.2 KiB |
21
YuMi/Assets.xcassets/1.0.34/grey_right_arrow.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "切图 30@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/grey_right_arrow.imageset/切图 30@3x.png
vendored
Normal file
After Width: | Height: | Size: 1.1 KiB |
21
YuMi/Assets.xcassets/1.0.34/luck_gift_flag_ball_BIG.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "椭圆 6@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/luck_gift_flag_ball_BIG.imageset/椭圆 6@3x.png
vendored
Normal file
After Width: | Height: | Size: 85 KiB |
21
YuMi/Assets.xcassets/1.0.34/room_boss_mic.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "组 8319@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/room_boss_mic.imageset/组 8319@3x.png
vendored
Normal file
After Width: | Height: | Size: 15 KiB |
21
YuMi/Assets.xcassets/1.0.34/room_manager_limit.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "from (2).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/room_manager_limit.imageset/from (2).png
vendored
Normal file
After Width: | Height: | Size: 44 KiB |
21
YuMi/Assets.xcassets/1.0.34/room_mic_normal.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "切图 63@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/room_mic_normal.imageset/切图 63@3x.png
vendored
Normal file
After Width: | Height: | Size: 6.1 KiB |
21
YuMi/Assets.xcassets/1.0.34/room_mode_card_bg.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "矩形 2979@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/room_mode_card_bg.imageset/矩形 2979@3x.png
vendored
Normal file
After Width: | Height: | Size: 188 KiB |
21
YuMi/Assets.xcassets/1.0.34/room_mode_default_skin.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "头像@2x@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/room_mode_default_skin.imageset/头像@2x@3x.png
vendored
Normal file
After Width: | Height: | Size: 5.0 KiB |
21
YuMi/Assets.xcassets/1.0.34/room_mode_help.imageset/Contents.json
vendored
Normal 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
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/room_mode_help.imageset/返回 1@3x.png
vendored
Normal file
After Width: | Height: | Size: 2.8 KiB |
21
YuMi/Assets.xcassets/1.0.34/room_mode_mic_10_off.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "切图 62@3x(1).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/room_mode_mic_10_off.imageset/切图 62@3x(1).png
vendored
Normal file
After Width: | Height: | Size: 4.0 KiB |
21
YuMi/Assets.xcassets/1.0.34/room_mode_mic_10_on.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "切图 62@3x(5).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/room_mode_mic_10_on.imageset/切图 62@3x(5).png
vendored
Normal file
After Width: | Height: | Size: 3.8 KiB |
21
YuMi/Assets.xcassets/1.0.34/room_mode_mic_15_off.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "切图 62@3x(2).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/room_mode_mic_15_off.imageset/切图 62@3x(2).png
vendored
Normal file
After Width: | Height: | Size: 4.9 KiB |
21
YuMi/Assets.xcassets/1.0.34/room_mode_mic_15_on.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "切图 62@3x(6).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/room_mode_mic_15_on.imageset/切图 62@3x(6).png
vendored
Normal file
After Width: | Height: | Size: 4.6 KiB |
21
YuMi/Assets.xcassets/1.0.34/room_mode_mic_19_off.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "切图 61@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/room_mode_mic_19_off.imageset/切图 61@3x.png
vendored
Normal file
After Width: | Height: | Size: 6.7 KiB |
21
YuMi/Assets.xcassets/1.0.34/room_mode_mic_19_on.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "切图 62@3x(8).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.34/room_mode_mic_19_on.imageset/切图 62@3x(8).png
vendored
Normal file
After Width: | Height: | Size: 6.4 KiB |
21
YuMi/Assets.xcassets/1.0.34/room_mode_mic_20_off.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "切图 62@3x(3).png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|