9 Commits

Author SHA1 Message Date
edwinQQQ
9a62183a2c refactor: 重构 AppDelegate 以优化启动流程和 UI 配置
主要变更:
1. 新增 setupUIAppearance 和 setupConfig 方法,提升代码结构和可读性。
2. 移除冗余的 iOS 15 适配代码,集中管理 UI 外观设置。
3. 更新 EPConfigManager 的调用逻辑,确保配置成功后初始化 NIMSDK。
4. 引入 ignoreVAPLog 方法,简化日志处理逻辑。

此更新旨在提升应用启动效率和代码的可维护性。
2025-10-20 18:14:55 +08:00
edwinQQQ
681b011c99 refactor: 更新 AppDelegate 和模块导入以简化配置管理
主要变更:
1. 移除不必要的模块导入,简化 AppDelegate 中的代码结构。
2. 引入新的 EPConfigManager 和 EPNIMManager,统一配置管理和 NIMSDK 初始化逻辑。
3. 更新相关方法以使用 block 回调,提升代码的可读性和维护性。
4. 新增 EPClientAPIBridge 和相关配置文件,增强项目的模块化。

此更新旨在提升代码的可维护性,减少冗余实现,确保配置管理的一致性。
2025-10-20 18:07:44 +08:00
edwinQQQ
4256e01820 refactor: 统一获取 keyWindow 的实现,简化 Swift 代码
主要变更:
1. 移除 Swift 中重复实现的 getKeyWindow() 方法,统一调用 ObjC inline 函数 kGetKeyWindow()。
2. 更新 EPLoginManager 中的相关调用,确保一致性和简洁性。

此更新旨在提升代码的可维护性,减少冗余实现,确保跨语言调用的一致性。
2025-10-20 16:12:50 +08:00
edwinQQQ
9777c3de28 refactor: 移除 Google 登录相关代码以简化项目结构
主要变更:
1. 从 Podfile 中移除 GoogleSignIn 及相关依赖,减少项目依赖。
2. 从 AppDelegate 和相关文件中删除 Google 登录初始化及相关逻辑,清理未使用的代码。
3. 移除与 Google 登录相关的 Presenter 和 ViewController 中的代码,简化登录流程。

此更新旨在提升项目的可维护性,减少冗余依赖,确保代码结构更加清晰。
2025-10-20 16:12:36 +08:00
edwinQQQ
7b88912b37 refactor: 移除分享相关代码以简化项目结构
主要变更:
1. 从 Podfile 中移除 FBSDKShareKit 和 mob_sharesdk 相关依赖,减少项目依赖。
2. 从 AppDelegate 和相关文件中删除 ShareSDK 初始化及相关逻辑,清理未使用的代码。
3. 删除与分享功能相关的 XPShareView 及其模型文件,简化项目结构。

此更新旨在提升项目的可维护性,减少冗余依赖,确保代码结构更加清晰。
2025-10-20 15:10:45 +08:00
edwinQQQ
4706f4bcc6 refactor: 移除 MobLink 相关代码以简化项目结构
主要变更:
1. 从 Podfile 中移除 mob_linksdk_pro 依赖,减少项目依赖。
2. 从 AppDelegate 和相关文件中删除 MobLink 初始化及相关逻辑,清理未使用的代码。
3. 移除 ClientConfig 中的 inviteCode 属性,简化配置管理。

此更新旨在提升项目的可维护性,减少冗余依赖,确保代码结构更加清晰。
2025-10-20 14:39:09 +08:00
edwinQQQ
37e105f04f refactor: 移除友盟相关代码并清理项目结构
主要变更:
1. 从 Podfile 中移除 UMCommon 和 UMDevice 依赖,简化项目依赖管理。
2. 从 AppDelegate 中移除友盟初始化代码,减少不必要的依赖。
3. 删除 GlobalEventManager 相关文件,清理未使用的代码。

此更新旨在提升项目的可维护性,减少冗余依赖,确保代码结构更加清晰。
2025-10-20 14:32:43 +08:00
edwinQQQ
c8173bf034 refactor: 移除 Core Data 相关代码并添加新的消息列表视图控制器
主要变更:
1. 从 AppDelegate 中移除 Core Data 相关的属性和方法,简化应用结构。
2. 新增 EPBaseListViewController 作为消息列表的基础类,提供通用的表视图功能。
3. 添加 EPMessageListVC、EPFriendListVC、EPFollowingListVC 和 EPFansListVC,分别用于展示消息、朋友、关注和粉丝列表。
4. 引入 EPMessageSegmentView 以支持消息主界面的分段控制。

此更新旨在提升代码的可维护性,简化数据管理,并增强用户界面的功能性和交互性。
2025-10-20 11:25:33 +08:00
edwinQQQ
6f5ab10562 temp save 2025-10-17 18:32:40 +08:00
3190 changed files with 359923 additions and 5652 deletions

63
Podfile
View File

@@ -1,34 +1,55 @@
# Uncomment the next line to define a global platform for your project
platform :ios, '13.0'
source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'
project 'YuMi.xcodeproj'
target 'YuMi' do
use_frameworks!
#pag动画
pod 'libpag'
pod 'Bugly'
# 滑动标签栏
pod 'JXCategoryView'
pod 'JXPagingView/Pager'
#模型转化
pod 'MJExtension', '3.4.2'
#图片加载
pod 'SDWebImage', '5.21.3'
# pod 'SDWebImageWebPCoder' 用于加载 webP
pod 'FLAnimatedImage'
pod 'SDWebImageFLPlugin' # 对FLAnimatedImage和SDWebImage的桥接
pod 'AFNetworking'
#文字自动滚动
pod 'MarqueeLabel'
pod 'YYText'
pod 'Masonry'
pod 'YYWebImage'
#输入
pod 'SZTextView'
#头饰显示
pod 'YYWebImage'
#轮播图
pod 'SDCycleScrollView'
pod 'ReactiveObjC'
pod 'MBProgressHUD'
pod 'FFPopup'
#下拉刷新控件
pod 'MJRefresh', '3.7.9'
pod 'IQKeyboardManager'
pod 'TZImagePickerController'
#TRTC
pod 'TXLiteAVSDK_TRTC'
#vap礼物动画
pod 'QGVAPlayer'
#上传音乐
pod 'CocoaAsyncSocket',:modular_headers => true
#声网
pod 'SSKeychain'
pod 'Base64'
#pop动画
pod 'pop'
#云信
pod 'NIMSDK_LITE', '~> 10.9.40'
pod 'GKCycleScrollView'
pod 'SVGAPlayer'
pod 'ZLCollectionViewFlowLayout'
pod 'TABAnimated'
@@ -54,4 +75,26 @@ post_install do |installer|
end
end
end
# 🔧 自动修复 SVGAPlayer 的 OSAtomic 导入问题
# 原因: SVGAPlayer 2.5.7 的 Svga.pbobjc.m 使用旧版 protoc 生成,
# 代码中使用了 OSAtomicCompareAndSwapPtrBarrier 但未导入头文件
svga_pbobjc_path = 'Pods/SVGAPlayer/Source/pbobjc/Svga.pbobjc.m'
if File.exist?(svga_pbobjc_path)
text = File.read(svga_pbobjc_path)
# 检查是否已经包含 OSAtomic 导入
unless text.include?('#import <libkern/OSAtomic.h>')
# 在 #endif 后的第一个空行位置插入导入语句
new_text = text.sub(
/(#define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0\n#endif\n)/,
"\\1\n#import <libkern/OSAtomic.h>\n"
)
File.write(svga_pbobjc_path, new_text)
puts "✅ [自动修复] SVGAPlayer OSAtomic 导入问题已解决"
else
puts "✓ [检查通过] SVGAPlayer OSAtomic 导入已存在"
end
else
puts "⚠️ [警告] 未找到 SVGAPlayer pbobjc 文件,跳过修复"
end
end

View File

@@ -15,13 +15,27 @@ PODS:
- AFNetworking/UIKit (4.0.1):
- AFNetworking/NSURLSession
- Base64 (1.1.2)
- Bugly (2.6.1)
- CocoaAsyncSocket (7.6.5)
- FFPopup (1.1.5)
- FLAnimatedImage (1.0.17)
- GKCycleScrollView (1.2.3)
- IQKeyboardManager (6.5.19)
- JXCategoryView (1.6.8)
- JXPagingView/Pager (2.1.3)
- libpag (4.5.3)
- MarqueeLabel (4.5.3)
- Masonry (1.1.0)
- MBProgressHUD (1.2.0)
- MJExtension (3.4.2)
- MJRefresh (3.7.9)
- NIMSDK_LITE (10.9.53):
- NIMSDK_LITE/NOS (= 10.9.53)
- YXArtemis_XCFramework
- NIMSDK_LITE/NOS (10.9.53):
- YXArtemis_XCFramework
- pop (1.0.12)
- Protobuf (3.29.5)
- QCloudCore (6.5.1):
- QCloudCore/Default (= 6.5.1)
- QCloudCore/Default (6.5.1):
@@ -31,16 +45,32 @@ PODS:
- QCloudCOSXML/Default (6.5.1):
- QCloudCore (= 6.5.1)
- QCloudTrack/Beacon (6.5.1)
- QGVAPlayer (1.0.19)
- ReactiveObjC (3.1.1)
- SDCycleScrollView (1.82):
- SDWebImage (>= 5.0.0)
- SDWebImage (5.21.3):
- SDWebImage/Core (= 5.21.3)
- SDWebImage/Core (5.21.3)
- SDWebImageFLPlugin (0.6.0):
- FLAnimatedImage (>= 1.0.11)
- SDWebImage/Core (~> 5.10)
- SnapKit (5.7.1)
- SSKeychain (1.4.1)
- SSZipArchive (2.4.3)
- SVGAPlayer (2.5.7):
- SVGAPlayer/Core (= 2.5.7)
- SVGAPlayer/ProtoFiles (= 2.5.7)
- SVGAPlayer/Core (2.5.7):
- SSZipArchive (>= 1.8.1)
- SVGAPlayer/ProtoFiles
- SVGAPlayer/ProtoFiles (2.5.7):
- Protobuf (~> 3.4)
- SZTextView (1.3.0)
- TABAnimated (2.6.6)
- TXLiteAVSDK_TRTC (12.8.19666):
- TXLiteAVSDK_TRTC/TRTC (= 12.8.19666)
- TXLiteAVSDK_TRTC/TRTC (12.8.19666)
- TYCyclePagerView (1.2.0)
- TZImagePickerController (3.8.9):
- TZImagePickerController/Basic (= 3.8.9)
@@ -48,10 +78,12 @@ PODS:
- TZImagePickerController/Basic (3.8.9)
- TZImagePickerController/Location (3.8.9)
- YuMi (0.0.1)
- YXArtemis_XCFramework (1.1.6)
- YYCache (1.0.4)
- YYImage (1.0.4):
- YYImage/Core (= 1.0.4)
- YYImage/Core (1.0.4)
- YYText (1.0.7)
- YYWebImage (1.0.5):
- YYCache
- YYImage
@@ -60,24 +92,38 @@ PODS:
DEPENDENCIES:
- AFNetworking
- Base64
- Bugly
- CocoaAsyncSocket
- FFPopup
- FLAnimatedImage
- GKCycleScrollView
- IQKeyboardManager
- JXCategoryView
- JXPagingView/Pager
- libpag
- MarqueeLabel
- Masonry
- MBProgressHUD
- MJExtension (= 3.4.2)
- MJRefresh (= 3.7.9)
- NIMSDK_LITE (~> 10.9.40)
- pop
- QCloudCOSXML
- QGVAPlayer
- ReactiveObjC
- SDCycleScrollView
- SDWebImage (= 5.21.3)
- SDWebImageFLPlugin
- SnapKit (~> 5.0)
- SSKeychain
- SVGAPlayer
- SZTextView
- TABAnimated
- TXLiteAVSDK_TRTC
- TYCyclePagerView
- TZImagePickerController
- YuMi (from `yum`)
- YYText
- YYWebImage
- ZLCollectionViewFlowLayout
@@ -85,27 +131,44 @@ SPEC REPOS:
https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git:
- AFNetworking
- Base64
- Bugly
- CocoaAsyncSocket
- FFPopup
- FLAnimatedImage
- GKCycleScrollView
- IQKeyboardManager
- JXCategoryView
- JXPagingView
- libpag
- MarqueeLabel
- Masonry
- MBProgressHUD
- MJExtension
- MJRefresh
- NIMSDK_LITE
- pop
- Protobuf
- QCloudCore
- QCloudCOSXML
- QCloudTrack
- QGVAPlayer
- ReactiveObjC
- SDCycleScrollView
- SDWebImage
- SDWebImageFLPlugin
- SnapKit
- SSKeychain
- SSZipArchive
- SVGAPlayer
- SZTextView
- TABAnimated
- TXLiteAVSDK_TRTC
- TYCyclePagerView
- TZImagePickerController
- YXArtemis_XCFramework
- YYCache
- YYImage
- YYText
- YYWebImage
- ZLCollectionViewFlowLayout
@@ -116,31 +179,48 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
AFNetworking: 3bd23d814e976cd148d7d44c3ab78017b744cd58
Base64: cecfb41a004124895a7bcee567a89bae5a89d49b
Bugly: 217ac2ce5f0f2626d43dbaa4f70764c953a26a31
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
FFPopup: a208dcee8db3e54ec4a88fcd6481f6f5d85b7a83
FLAnimatedImage: bbf914596368867157cc71b38a8ec834b3eeb32b
GKCycleScrollView: 8ed79d2142e62895a701973358b6f94b661b4829
IQKeyboardManager: c8665b3396bd0b79402b4c573eac345a31c7d485
JXCategoryView: 262d503acea0b1278c79a1c25b7332ffaef4d518
JXPagingView: afdd2e9af09c90160dd232b970d603cc6e7ddd0e
libpag: c59ae60dbae9e025465e9541ee03ee96994f4c73
MarqueeLabel: 0c57d4c6634e04a6d015af79f7c9a175b2309525
Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406
MJExtension: e97d164cb411aa9795cf576093a1fa208b4a8dd8
MJRefresh: ff9e531227924c84ce459338414550a05d2aea78
NIMSDK_LITE: 79bc52b8ad905e6c088053d8d29e7863fb9cdb98
pop: d582054913807fd11fd50bfe6a539d91c7e1a55a
Protobuf: 164aea2ae380c3951abdc3e195220c01d17400e0
QCloudCore: 6f8c67b96448472d2c6a92b9cfe1bdb5abbb1798
QCloudCOSXML: 92f50a787b4e8d9a7cb6ea8e626775256b4840a7
QCloudTrack: 20b79388365b4c8ed150019c82a56f1569f237f8
QGVAPlayer: a0bca68c9bd6f1c8de5ac2d10ddf98be6038cce9
ReactiveObjC: 011caa393aa0383245f2dcf9bf02e86b80b36040
SDCycleScrollView: a0d74c3384caa72bdfc81470bdbc8c14b3e1fbcf
SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a
SDWebImageFLPlugin: 72efd2cfbf565bc438421abb426f4bcf7b670754
SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
SSKeychain: 55cc80f66f5c73da827e3077f02e43528897db41
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
SVGAPlayer: 318b85a78b61292d6ae9dfcd651f3f0d1cdadd86
SZTextView: 094dc6acc9beec537685c545d6e3e0d4975174e1
TABAnimated: 75fece541a774193565697c7a11539d3c6f631b3
TXLiteAVSDK_TRTC: b576b0c6a477fa98b5d2b33be63fa9aa7c41f0eb
TYCyclePagerView: 2b051dade0615c70784aa34f40c646feeddb7344
TZImagePickerController: 456f470b5dea97b37226ec7a694994a8663340b2
YuMi: 6c5f00f1eccbcea3304feae03cbe659025fdb9cb
YXArtemis_XCFramework: d9a8b9439d7a6c757ed00ada53a6d2dd9b13f9c7
YYCache: 8105b6638f5e849296c71f331ff83891a4942952
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54
YYText: 5c461d709e24d55a182d1441c41dc639a18a4849
YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928
ZLCollectionViewFlowLayout: c99024652ce9f0c57d33ab53052c9b85e4a936b7
PODFILE CHECKSUM: 9e7178f1fdbc61a4ba4e3bc2ae826e7e83aff1db
PODFILE CHECKSUM: 3ef6e2b784d16a5b9d2c5cdd03f8bbf3ed3483ce
COCOAPODS: 1.16.2

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
//
// AppDelegate+ThirdConfig.h
// YUMI
//
// Created by YUMI on 2021/9/13.
//
#import "AppDelegate.h"
NS_ASSUME_NONNULL_BEGIN
@interface AppDelegate (ThirdConfig)
/// 初始化一些第三方配置
- (void)initThirdConfig;
/**
设置广告页
*/
- (void)setupLaunchADView;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,224 @@
//
// AppDelegate+ThirdConfig.m
// YUMI
//
// Created by YUMI on 2021/9/13.
//
#import "AppDelegate+ThirdConfig.h"
///Third
#import <NIMSDK/NIMSDK.h>
#import <UserNotifications/UNUserNotificationCenter.h>
#import <UserNotifications/UserNotifications.h>
///Tool
#import "YUMIConstant.h"
#import "CustomAttachmentDecoder.h"
#import "QEmotionHelper.h"
#import "XPAdvertiseView.h"
#import "XPAdImageTool.h"
#import "YUMIMacroUitls.h"
#import "AdvertiseModel.h"
#import "XPWebViewController.h"
#import "XPRoomViewController.h"
#import "XCCurrentVCStackManager.h"
#import "ClientConfig.h"
#import <UserNotifications/UserNotifications.h>
#import <Bugly/Bugly.h>
#import "BuglyManager.h"
#import <UIKit/UIDevice.h>
#import "YuMi-swift.h"
UIKIT_EXTERN NSString * kYouMiNumberCountKey;
UIKIT_EXTERN NSString * adImageName;
@implementation AppDelegate (ThirdConfig)
///
- (void)initThirdConfig{
[self setLanguage];
[self configNIMSDK];
[self configBugly];
[self registerNot];
[self initEmojiData];
}
-(void)setLanguage{
UISemanticContentAttribute attribute = UISemanticContentAttributeForceLeftToRight;
if (isMSRTL()) {
attribute = UISemanticContentAttributeForceRightToLeft;
}
[UIView appearance].semanticContentAttribute = attribute;
[UISearchBar appearance].semanticContentAttribute = attribute;
}
-(void)registerNot{
if (@available(iOS 10.0, *)) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
if (settings.authorizationStatus == UNAuthorizationStatusAuthorized){
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications];
});
}
}];
}
}];
}
}
/**
Bugly
*/
- (void) configBugly {
// 使 BuglyManager Bugly
#ifdef DEBUG
[[BuglyManager sharedManager] configureWithAppId:@"c937fd00f7" debug:YES];
#else
[[BuglyManager sharedManager] configureWithAppId:@"8627948559" debug:NO];
#endif
}
- (void)configNIMSDK {
// NIMSDK
NSString *appKey = [[ClientConfig shareConfig].configInfo nimKey];
if ([NSString isEmpty:appKey]) {
appKey = KeyWithType(KeyType_NetEase);
}
NIMSDKOption *option = [NIMSDKOption optionWithAppKey:appKey];
#ifdef DEBUG
option.apnsCername = @"pikoDevelopPush";
#else
option.apnsCername = @"newPiko";
#endif
[[NIMSDK sharedSDK] registerWithOption:option];
// NIM SDK
[NIMCustomObject registerCustomDecoder:[[CustomAttachmentDecoder alloc] init]];
[[NIMSDKConfig sharedConfig] setShouldSyncStickTopSessionInfos:YES];
[NIMSDKConfig sharedConfig].shouldConsiderRevokedMessageUnreadCount = 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
}
#pragma mark -
- (void)initEmojiData {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSArray * dicArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"emoji" ofType:@"plist"]];
NSDictionary * dic = [dicArray firstObject];
NSArray * emojiArray = dic[@"data"];
NSMutableArray * array = [NSMutableArray array];
for (int i = 0; i < emojiArray.count; i++) {
NSDictionary * emotionDic = [emojiArray xpSafeObjectAtIndex:i];
if (!emotionDic) continue;
UIImage * image = [UIImage imageNamed:emotionDic[@"file"]];
QEmotion * info = [[QEmotion alloc] init];
info.displayName = emotionDic[@"tag"];
info.identifier = emotionDic[@"id"];
info.image = image;
[array addObject:info];
}
//
QEmotionHelper *faceManager = [QEmotionHelper sharedEmotionHelper];
faceManager.emotionArray = array;
// emoji
[QEmotionHelper clearEmojiCache];
});
}
#pragma mark - 广
/**
广
*/
- (void)setupLaunchADView {
return;
NSUserDefaults * kUserDefaults = NSUserDefaults.standardUserDefaults;
// 广
NSString *adName = [kUserDefaults stringForKey:adImageName];
NSString *filePath = [XPAdImageTool.shareImageTool getFilePathWithImageName:adName];
BOOL isExist = [XPAdImageTool.shareImageTool isFileExistWithFilePath:filePath];
if (isExist) {//
// 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)
if (!shouldJump || info == nil) {
return;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self advertiseJumpHandleWithInfo:info];
});
};
[advertiseView show];
// }
}
}
/// 广
- (void)advertiseJumpHandleWithInfo:(AdvertiseModel *)info {
if (UIApplication.sharedApplication.keyWindow != self.window) {
//
return;
}
switch (info.type) {
case SplashInfoSkipTypeRoom: {
if (![[XPAdImageTool shareImageTool] isImLogin]) {
return; //
}
//
if (info.link.length > 0) {
[XPRoomViewController openRoom:info.link viewController:[XCCurrentVCStackManager shareManager].getCurrentVC];
}
}
break;
case SplashInfoSkipTypeWeb:
case SplashInfoSkipTypeWeb_CP:
case SplashInfoSkipTypeWeb_Custom:
case SplashInfoSkipTypeWeb_WeekStar: {
// H5
if (info.link.length > 0) {
XPWebViewController *webView = [[XPWebViewController alloc] initWithRoomUID:nil];
webView.url = info.link;
[[[XCCurrentVCStackManager shareManager]currentNavigationController] pushViewController:webView animated:YES];
}
}
break;
default:
break;
}
}
@end

View File

@@ -1,7 +1,9 @@
//
// AppDelegate.h
// YUMI
//
// Created by admin on 2023/3/9.
//
#import <UIKit/UIKit.h>

View File

@@ -1,12 +1,22 @@
//
// AppDelegate.m
// YUMI
//
// Created by admin on 2023/3/9.
//
#import "AppDelegate.h"
#import "BaseNavigationController.h"
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import "ClientConfig.h"
#import "AccountModel.h"
#import "YuMi-swift.h"
#import "UIView+VAP.h"
#import "SocialShareManager.h"
#import "EPSignatureColorGuideView.h"
#import "EPEmotionColorStorage.h"
#import "EPNIMManager.h"
UIKIT_EXTERN NSString * const kOpenRoomNotification;
@@ -16,6 +26,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];
@@ -25,41 +55,52 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
self.window.rootViewController = launchScreenVC;
[self.window makeKeyAndVisible];
[self loadMainPage];
[self setupUIAppearance];
if (@available(iOS 15, *)) {
[[UITableView appearance] setSectionHeaderTopPadding:0];
}
[self setupConfig];
return YES;
}
// MARK: - Helper Methods
- (UIWindow *)getKeyWindow {
if (@available(iOS 13.0, *)) {
for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {
if (scene.activationState == UISceneActivationStateForegroundActive) {
for (UIWindow *window in scene.windows) {
if (window.isKeyWindow) {
return window;
}
}
return scene.windows.firstObject;
}
}
- (void)setupUIAppearance {
if (@available(iOS 15, *)) {
[[UITableView appearance] setSectionHeaderTopPadding:0];
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [UIApplication sharedApplication].keyWindow;
#pragma clang diagnostic pop
}
- (void)setupConfig {
// client/init client/config EPConfigManager
@kWeakify(self);
[[EPConfigManager shared] startColdBootWithOnSuccess:^{
@kStrongify(self);
if (!self) return;
// NIMSDK
@kWeakify(self);
[[EPNIMManager sharedManager] initializeWithCompletion:^(NSError * _Nullable error) {
@kStrongify(self);
if (!self) return;
if (error) {
NSLog(@"[AppDelegate] NIMSDK 初始化失败: %@", error);
} else {
NSLog(@"[AppDelegate] NIMSDK 初始化成功");
}
// NIMSDK
[self loadMainPage];
}];
} onFailure:^(NSString * _Nonnull errorMessage) {
@kStrongify(self);
if (!self) return;
//
UIAlertController *alert = [UIAlertController alertControllerWithTitle:YMLocalizedString(@"提示")
message:errorMessage
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:YMLocalizedString(@"确定") style:UIAlertActionStyleDefault handler:nil]];
[self.window.rootViewController presentViewController:alert animated:YES completion:nil];
}];
}
- (void)loadMainPage {
AccountModel *accountModel = [[AccountInfoStorage instance] getCurrentAccountInfo];
@@ -70,44 +111,50 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
}else{
[self toHomeTabbarPage];
// window
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.8 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self checkAndShowSignatureColorGuide];
});
}
[self ignoreVAPLog];
}
- (void)ignoreVAPLog {
[VAPView registerHWDLog:qg_VAP_Logger_handler];
}
///
- (void)checkAndShowSignatureColorGuide {
UIWindow *keyWindow = [self getKeyWindow];
UIWindow *keyWindow = kWindow;
if (!keyWindow) return;
BOOL hasSignatureColor = [EPEmotionColorStorage hasUserSignatureColor];
//#if DEBUG
//
// NSLog(@"[AppDelegate] Debug 模式:显示专属颜色引导页(已有颜色: %@", hasSignatureColor ? @"YES" : @"NO");
//
// EPSignatureColorGuideView *guideView = [[EPSignatureColorGuideView alloc] init];
//
//
// guideView.onColorConfirmed = ^(NSString *hexColor) {
// [EPEmotionColorStorage saveUserSignatureColor:hexColor];
// NSLog(@"[AppDelegate] 用户选择专属颜色: %@", hexColor);
// };
//
//
// if (hasSignatureColor) {
// guideView.onSkipTapped = ^{
// NSLog(@"[AppDelegate] 用户跳过专属颜色选择");
// };
// }
//
//
// [guideView showInWindow:keyWindow showSkipButton:hasSignatureColor];
//
//#else
#if 0
// Debug
NSLog(@"[AppDelegate] Debug 模式:显示专属颜色引导页(已有颜色: %@", hasSignatureColor ? @"YES" : @"NO");
EPSignatureColorGuideView *guideView = [[EPSignatureColorGuideView alloc] init];
//
guideView.onColorConfirmed = ^(NSString *hexColor) {
[EPEmotionColorStorage saveUserSignatureColor:hexColor];
NSLog(@"[AppDelegate] 用户选择专属颜色: %@", hexColor);
};
// Skip
if (hasSignatureColor) {
guideView.onSkipTapped = ^{
NSLog(@"[AppDelegate] 用户跳过专属颜色选择");
};
}
// Skip
[guideView showInWindow:keyWindow showSkipButton:hasSignatureColor];
#else
// Release
if (!hasSignatureColor) {
EPSignatureColorGuideView *guideView = [[EPSignatureColorGuideView alloc] init];
guideView.onColorConfirmed = ^(NSString *hexColor) {
@@ -116,11 +163,11 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
};
[guideView showInWindow:keyWindow];
}
//#endif
#endif
}
- (void)toLoginPage {
// 使 Swift
EPLoginViewController *lvc = [[EPLoginViewController alloc] init];
BaseNavigationController *navigationController =
[[BaseNavigationController alloc] initWithRootViewController:lvc];
@@ -132,16 +179,87 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
EPTabBarController *epTabBar = [EPTabBarController create];
[epTabBar refreshTabBarWithIsLogin:YES];
UIWindow *window = [self getKeyWindow];
UIWindow *window = kWindow;
if (window) {
window.rootViewController = epTabBar;
[window makeKeyAndVisible];
}
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSInteger count = [[EPNIMManager sharedManager] allUnreadCount];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:count];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self getAdvertisingTrackingAuthority];
[[NSNotificationCenter defaultCenter]postNotificationName:@"kAppDidBecomeActive" object:nil];
}
- (void)getAdvertisingTrackingAuthority {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (@available(iOS 14, *)) {
ATTrackingManagerAuthorizationStatus status = ATTrackingManager.trackingAuthorizationStatus;
switch (status) {
case ATTrackingManagerAuthorizationStatusDenied:
// NSLog(@"用户拒绝IDFA");
break;
case ATTrackingManagerAuthorizationStatusAuthorized:
// NSLog(@"用户允许IDFA");
break;
case ATTrackingManagerAuthorizationStatusNotDetermined: {
// NSLog(@"用户未做选择或未弹窗IDFA");
//1app
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
// NSLog(@"app追踪IDFA权限%lu",(unsigned long)status);
}];
}
break;
default:
break;
}
}
});
}
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// deviceToken EPNIMManager
[[EPNIMManager sharedManager] updateApnsToken:deviceToken];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
NSString *data = userInfo[@"data"];
if(data){
NSDictionary *dataDic = [data mj_JSONObject];
NSString *userId = dataDic[@"uid"];
if(userId){
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"type":@"kOpenChat",@"uid":userId,@"isNoAttention":@(YES)}];
ClientConfig *config = [ClientConfig shareConfig];
config.pushChatId = userId;
});
return;
}
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSString *userId = userInfo[@"uid"];
if(userId){
[[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"type":@"kOpenChat",@"uid":userId,@"isNoAttention":@(YES)}];
ClientConfig *config = [ClientConfig shareConfig];
config.pushChatId = userId;
}
});
}
///URL Scheme
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
// TODO: EPTabbar [SocialShareManager sharedManager] setHandleJumpToRoom
[[SocialShareManager sharedManager] handleURL:url];
return YES;
}
@end

View File

@@ -0,0 +1,16 @@
//
// YYTextAsyncLayer+PITextAsyncLayer.h
// YuMi
//
// Created by duoban on 2023/10/28.
//
#import <YYText/YYTextAsyncLayer.h>
NS_ASSUME_NONNULL_BEGIN
@interface YYTextAsyncLayer (PITextAsyncLayer)
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,26 @@
//
// YYTextAsyncLayer+PITextAsyncLayer.m
// YuMi
//
// Created by duoban on 2023/10/28.
//
#import "YYTextAsyncLayer+PITextAsyncLayer.h"
@implementation YYTextAsyncLayer (PITextAsyncLayer)
///iOS17bug退
+(void)load {
Method displayMethod = class_getInstanceMethod(self, @selector(display));
Method swizzingMethod = class_getInstanceMethod(self, @selector(swizzing_display));
method_exchangeImplementations(displayMethod, swizzingMethod);
}
-(void)swizzing_display{
//
if (self.bounds.size.width <= 0 || self.bounds.size.height <= 0) {
self.contents = nil;
return;
} else {
[self swizzing_display];
}
}
@end

View File

@@ -1,39 +1,44 @@
//
// APIConfig.swift
// YuMi
//
// Created by AI on 2025-10-09.
// Copyright © 2025 YuMi. All rights reserved.
//
import Foundation
/// API
/// 使 XOR + Base64
@objc class APIConfig: NSObject {
// MARK: - Private Properties
/// XOR
private static let xorKey: UInt8 = 77
/// RELEASE
/// https://api.epartylive.com
private static let releaseEncodedParts: [String] = [
"JTk5PT53YmI=",
"LD0kYw==",
"KD0sPzk0ISQ7KGMuIiA=",
"JTk5PT53YmI=", // https:// (XOR Base64)
"LD0kYw==", // api. (XOR Base64)
"KD0sPzk0ISQ7KGMuIiA=", // epartylive.com (XOR Base64)
]
// MARK: - Public Methods
/// API
/// - Returns:
@objc static func baseURL() -> String {
#if DEBUG
// DEV 使 Bridging HttpRequestHelper
// TODO: return HttpRequestHelper.getHostUrl()
return getDevBaseURL()
#else
// RELEASE 使
let url = decodeURL(from: releaseEncodedParts)
//
if url.isEmpty || !url.hasPrefix("http") {
NSLog("[APIConfig] 警告:域名解密失败,使用备用域名")
return backupURL()
@@ -43,29 +48,33 @@ import Foundation
#endif
}
/// DEV
/// - Returns: DEV
private static func getDevBaseURL() -> String {
// UserDefaults HttpRequestHelper
#if DEBUG
let isProduction = UserDefaults.standard.string(forKey: "kIsProductionEnvironment")
if isProduction == "YES" {
return "https://api.epartylive.com"
return "https://api.epartylive.com" //
} else {
return "https://test-api.yourdomain.com"
return "https://test-api.yourdomain.com" //
}
#else
return "https://api.epartylive.com"
#endif
}
///
/// - Returns: 使
@objc static func backupURL() -> String {
return getDevBaseURL()
}
// MARK: - Private Methods
///
/// - Parameter parts:
/// - Returns:
private static func decodeURL(from parts: [String]) -> String {
let decoded = parts.compactMap { part -> String? in
guard let data = Data(base64Encoded: part) else {
@@ -90,7 +99,7 @@ import Foundation
#if DEBUG
extension APIConfig {
/// /
@objc static func testEncryption() {
print("=== APIConfig 加密测试 ===")
print("Release 域名: \(decodeURL(from: releaseEncodedParts))")

View File

@@ -0,0 +1,68 @@
//
// ClientConfig.h
// YUMI
//
// Created by YUMI on 2021/12/11.
//
#import <Foundation/Foundation.h>
#import "ClientDataModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface ClientConfig : PIBaseModel
+ (instancetype)shareConfig;
///初始化
- (void)clientInit;
/// 获取 UI 配置
- (void)clientConfig:(void(^)(void))finish;
/// iOS第三方登录是否需要绑定手机号
@property (nonatomic,assign) BOOL iOSPhoneBind;
/// 是否开启了糖果树
@property (nonatomic,assign) BOOL openCandyTree;
///配置信息
@property (nonatomic,strong) ClientDataModel *configInfo;
@property (nonatomic, strong) AppUISetting *uiSetting;
///开箱子 大于等级 展示
@property (nonatomic, assign) NSInteger openCandyTreeLimitLevel;
@property(nonatomic,assign) BOOL isTF;
///是否刷新了
@property (nonatomic,assign) BOOL isLoad;
///房间id用于分享房间跳转到房间
@property (nonatomic, copy) NSString *__nullable roomId;
///用户id用于外部h5跳转到聊天页面
@property (nonatomic, copy) NSString *__nullable chatId;
///用户id推送跳转到聊天页面
@property (nonatomic, copy) NSString *__nullable pushChatId;
///表情---
@property (nonatomic, copy) NSString *version;
@property (nonatomic, copy) NSString *zipMd5;
@property (nonatomic, strong) NSURL *zipUrl;
@property(nonatomic, assign) BOOL shouldDisplayCaptcha;
- (UIColor *)bgColor;
- (NSString *)tabName:(NSInteger)tabIndex;
- (NSString *)loadDefaultNormalTabImageName:(NSInteger)tabIndex;
- (NSString *)loadDefaultSelectedTabImageName:(NSInteger)tabIndex;
- (NSString *)loadConfigNormalTabImagePath:(NSInteger)tabIndex;
- (NSString *)loadConfigSelectedTabImagePath:(NSInteger)tabIndex;
@property (nonatomic, copy) NSString *reloadNavigationAreaImageKey;
@property (nonatomic, copy) NSString *reloadViewBackgroundColorKey;
@property (nonatomic, strong) UIImage *navigationAreaBG;
@property (nonatomic, strong) UIImage *tabbarBGImage;
@property (nonatomic, copy) void(^updateTabbarBG)(UIImage *image);
@end
NS_ASSUME_NONNULL_END

274
YuMi/Config/ClientConfig.m Normal file
View File

@@ -0,0 +1,274 @@
//
// ClientConfig.m
// YUMI
//
// Created by YUMI on 2021/12/11.
//
#import "ClientConfig.h"
#import "Api+Main.h"
/// tool
#import "DESEncrypt.h"
#import "YUMIConstant.h"
#import <MJExtension/MJExtension.h>
#import "XPRoomFaceTool.h"
#import "NSString+Utils.h"
#import "YYUtility.h"
#import "XPWeakTimer.h"
#import "Api+Main.h"
#import "ChatFaceVo.h"
#import "PublicRoomManager.h"
@interface ClientConfig ()
/// 10
@property (nonatomic,assign) int retryCount;
@property (nonatomic, strong) NSMutableArray *normalTabImageSource;
@property (nonatomic, strong) NSMutableArray *selectedTabImageSource;
@property (nonatomic, strong) NetImageView *normalTabImageLoader;
@property (nonatomic, strong) NetImageView *selectedTabImageLoader;
@property (nonatomic, strong) NetImageView *tabbarBGImageLoader;
@property (nonatomic, strong) NetImageView *navigationAreaBGImageLoader;
@property (nonatomic, assign) BOOL isLoading;
@end
@implementation ClientConfig
+ (instancetype)shareConfig {
static dispatch_once_t onceToken;
static ClientConfig * config;
dispatch_once(&onceToken, ^{
config = [[ClientConfig alloc] init];
config.isTF = [ClientConfig isTestFlight];
config.reloadNavigationAreaImageKey = @"今天光线很好";
config.reloadViewBackgroundColorKey = @"年轻人买不起美国买房平均年龄飙升至56岁";
});
return config;
}
+(BOOL)isTestFlight{
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSString *receiptURLString = [receiptURL path];
BOOL isTestFlight = ([receiptURLString containsString:@"sandboxReceipt"] || [receiptURLString containsString:@"_MASReceipt/receipt"]);
return isTestFlight;
}
- (void)clientInit {
@kWeakify(self);
[Api clientInitConfig:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
@kStrongify(self);
if (code == 200) {
self.retryCount = 0;
ClientDataModel * model = [ClientDataModel modelWithDictionary:data.data];
self.iOSPhoneBind = model.iosPhoneBind;
//
self.openCandyTree = model.openBoxSwitch;
self.openCandyTreeLimitLevel = model.openBoxSwitchLevelNo;
//
NSString *json = model.faceJson.json;
NSString *deJson = [DESEncrypt decryptUseDES:json key:KeyWithType(KeyType_FacePwdEncode)];
NSDictionary *faceInitData = [deJson toJSONObject];
model.faceInitData = faceInitData;
if (faceInitData) {
[XPRoomFaceTool shareFaceTool].version = [NSString stringWithFormat:@"%@",faceInitData[@"version"]];
[XPRoomFaceTool shareFaceTool].zipMd5 = [[NSString stringWithFormat:@"%@",faceInitData[@"zipMd5"]] uppercaseString];
[XPRoomFaceTool shareFaceTool].zipUrl = [NSString stringWithFormat:@"%@",faceInitData[@"zipUrl"]];
///
[[XPRoomFaceTool shareFaceTool] saveFaceInfoList:faceInitData];
///
[[XPRoomFaceTool shareFaceTool] downFaceData];
}
NSString *trtcAppId = @(model.trtcAppId).stringValue;
NSString *curTtcKey = [[NSUserDefaults standardUserDefaults]valueForKey:@"kTrtcAppId"];
if(curTtcKey == nil){
if(trtcAppId != nil){
[[NSUserDefaults standardUserDefaults]setValue:trtcAppId forKey:@"kTrtcAppId"];
[[NSUserDefaults standardUserDefaults]synchronize];
}
}else{
if(![trtcAppId isEqualToString:curTtcKey]){
if(trtcAppId != nil){
[[NSUserDefaults standardUserDefaults]setValue:trtcAppId forKey:@"kTrtcAppId"];
[[NSUserDefaults standardUserDefaults]synchronize];
}
}
}
//
NSString *serverVer = model.appStoreAuditNoticeVersion;
NSString *shortVer = [YYUtility appVersion];
model.hideNoticeVersion = [NSString versionCompareOldStr:serverVer andNewStr:shortVer];
self.configInfo = model;
[[NSNotificationCenter defaultCenter] postNotificationName:@"reloadAfterLoadConfig" object:nil];
[self requestFaceTabNewList];
} else {
if (self.retryCount < 10) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.retryCount+=1;
[self clientInit];
});
}
}
}];
}
- (void)requestFaceTabNewList {
[Api faceTabNewList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if (code == 200) {
[[XPRoomFaceTool shareFaceTool] cacheChatFaces:data.data];
}
}];
}
- (void)clientConfig:(void(^)(void))finish {
@kWeakify(self);
[Api clientConfig:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
@kStrongify(self);
if (code == 200) {
self.uiSetting = [AppUISetting modelWithJSON:data.data[@"appUiSetting"]];
}
// tab image path
[self prepareCustomUI];
if (finish) {
finish();
}
}];
}
- (void)prepareCustomUI {
NSArray *defaultArray = @[@"", @"", @"", @"", @""];
self.normalTabImageSource = defaultArray.mutableCopy;
self.selectedTabImageSource = defaultArray.mutableCopy;
if (self.uiSetting) {
NSArray *unselectIcons = @[
self.uiSetting.homeUnSelectIcon ?: @"",
self.uiSetting.gameUnSelectIcon ?: @"",
self.uiSetting.dynamicUnSelectIcon ?: @"",
self.uiSetting.msgUnSelectIcon ?: @"",
self.uiSetting.mineUnSelectIcon ?: @""
];
NSArray *selectIcons = @[
self.uiSetting.homeSelectIcon ?: @"",
self.uiSetting.gameSelectIcon ?: @"",
self.uiSetting.dynamicSelectIcon ?: @"",
self.uiSetting.msgSelectIcon ?: @"",
self.uiSetting.mineSelectIcon ?: @""
];
self.normalTabImageSource = unselectIcons.mutableCopy;
self.selectedTabImageSource = selectIcons.mutableCopy;
[self loadNavigationAreaBG];
[self loadTabbarBG];
[self loadBGColor];
} else {
if (self.updateTabbarBG) {
self.updateTabbarBG(kImage(@"tab_bar_bg"));
}
}
}
- (UIImage *)navigationAreaBG {
if (!_navigationAreaBG) {
return kImage(@"home_top_bg");
} else {
return _navigationAreaBG;
}
}
- (void)loadNavigationAreaBG {
if (!_navigationAreaBGImageLoader) {
_navigationAreaBGImageLoader = [[NetImageView alloc] init];
}
@kWeakify(self);
[self.navigationAreaBGImageLoader loadImageWithUrl:self.uiSetting.headIcon
completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) {
@kStrongify(self);
self.navigationAreaBG = image;
[[NSNotificationCenter defaultCenter] postNotificationName:self.reloadNavigationAreaImageKey object:[image resizeTo:CGSizeMake(1125, 420)]];
} fail:^(NSError * _Nonnull error) {}];
}
- (void)loadTabbarBG {
if (!_tabbarBGImageLoader) {
_tabbarBGImageLoader = [[NetImageView alloc] init];
}
@kWeakify(self);
[self.tabbarBGImageLoader loadImageWithUrl:self.uiSetting.navbar
completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) {
@kStrongify(self);
self.tabbarBGImage = image;
if (self.updateTabbarBG) {
self.updateTabbarBG(image);
}
} fail:^(NSError * _Nonnull error) {
@kStrongify(self);
if (self.updateTabbarBG) {
self.updateTabbarBG(kImage(@"tab_bar_bg"));
}
}];
}
- (void)loadBGColor {
[[NSNotificationCenter defaultCenter] postNotificationName:self.reloadNavigationAreaImageKey
object:nil];
}
- (UIColor *)bgColor {
if (self.uiSetting && ![NSString isEmpty:self.uiSetting.backgroundColor]) {
return [DJDKMIMOMColor colorWithHexString:self.uiSetting.backgroundColor];
}
return [DJDKMIMOMColor colorWithHexString:@"#FCF4DF"];
}
- (NSString *)tabName:(NSInteger)tabIndex {
return @[YMLocalizedString(@"TabbarViewController2"),
YMLocalizedString(@"TabbarViewController6"),
YMLocalizedString(@"TabbarViewController3"),
YMLocalizedString(@"TabbarViewController4"),
YMLocalizedString(@"TabbarViewController5")][tabIndex];
}
- (NSString *)loadDefaultNormalTabImageName:(NSInteger)tabIndex {
return @[@"tab_gameHome_normal",
@"tab_gameHome_game_normal",
@"tab_monents_normal",
@"tab_message_normal",
@"tab_mine_normal"][tabIndex];
}
- (NSString *)loadDefaultSelectedTabImageName:(NSInteger)tabIndex {
return @[@"tab_gameHome_selected",
@"tab_gameHome_game_selected",
@"tab_monents_select",
@"tab_message_selected",
@"tab_mine_selected"][tabIndex];
}
- (NSString *)loadConfigNormalTabImagePath:(NSInteger)tabIndex {
return [self.normalTabImageSource xpSafeObjectAtIndex:tabIndex];
}
- (NSString *)loadConfigSelectedTabImagePath:(NSInteger)tabIndex {
return [self.selectedTabImageSource xpSafeObjectAtIndex:tabIndex];
}
- (BOOL)shouldDisplayCaptcha {
return [self.configInfo captchaSwitch];
}
@end

View File

@@ -0,0 +1,117 @@
//
// ClientDataModel.h
// YUMI
//
// Created by YUMI on 2022/3/7.
//
#import <Foundation/Foundation.h>
#import "ClientRedPacketModel.h"
#import "AdvertiseModel.h"
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, FaceLivenessStrategy) {
FaceLivenessStrategy_Pass = 0,
FaceLivenessStrategy_Force = 1,
FaceLivenessStrategy_Guide = 2,
};
@interface FaceJson : PIBaseModel
@property (nonatomic, assign) NSInteger status;
@property (nonatomic, assign) NSInteger id;
@property (nonatomic, assign) NSTimeInterval createTime;
@property (nonatomic, copy) NSString *json;
@property (nonatomic, assign) NSInteger version;
@end
@interface AppUISetting : PIBaseModel
@property (nonatomic, assign) NSInteger settingStatus;
@property (nonatomic, copy) NSString *headIcon;
@property (nonatomic, copy) NSString *navbar;
@property (nonatomic, copy) NSString *backgroundColor;
@property (nonatomic, copy) NSString *homeSelectIcon;
@property (nonatomic, copy) NSString *homeUnSelectIcon;
@property (nonatomic, copy) NSString *gameSelectIcon;
@property (nonatomic, copy) NSString *gameUnSelectIcon;
@property (nonatomic, copy) NSString *dynamicSelectIcon;
@property (nonatomic, copy) NSString *dynamicUnSelectIcon;
@property (nonatomic, copy) NSString *msgSelectIcon;
@property (nonatomic, copy) NSString *msgUnSelectIcon;
@property (nonatomic, copy) NSString *mineSelectIcon;
@property (nonatomic, copy) NSString *mineUnSelectIcon;
@property (nonatomic, copy) NSString *selectBar;
@end
@interface ClientDataModel : PIBaseModel
@property (nonatomic, strong) AppUISetting *appUiSetting;
///首页tag 配置
@property (nonatomic,strong) NSArray<NSString *> *homeTabList;
///房间表情的数据
@property (nonatomic,copy) NSDictionary *faceInitData;
///是否隐藏房间公告
@property (nonatomic,assign) BOOL hideNoticeVersion;
//进入房间拉取N条聊天数据
@property(nonatomic, assign) NSInteger roomMessageCount;
///发现萌新展示等级
@property (nonatomic,assign) NSInteger findNewbieCharmLevel;
///送礼物隐藏座驾动画的值
@property (nonatomic,assign) double hideCarEffectGiftPrice;
//航海等级限制
@property (nonatomic, assign) NSInteger linearlyPoolOpenLevel;
///红包配置
@property (nonatomic, strong) ClientRedPacketModel *redEnvelopeConfig;
///启动图
@property (nonatomic,strong) AdvertiseModel *splashVo;
///官方消息Uid列表
@property (nonatomic, strong) NSArray<NSString *> *officialMsgUids;
///官方账号 小秘书 红包消息
@property (nonatomic,strong) NSArray<NSString *> *officialAccountUids;
@property(nonatomic,copy) NSDictionary *publicChatRoomIdMap; // 公聊大厅房间 IDs已不使用该业务逻辑 -> 又要使用了
///星座礼物顶部是否开启
@property (nonatomic,assign) BOOL twelveStarSwitch;
/// 开房是否需要实名
@property (nonatomic,assign) FaceLivenessStrategy certificationType;
///转赠钻石白名单
@property (nonatomic,strong) NSMutableArray *giveDiamondErbanNoList;
///转赠礼物白名单
@property (nonatomic,strong) NSMutableArray *giveGiftErbanNoList;
///每日转赠钻石总额限制
@property (nonatomic,assign) NSInteger giveDiamondDailyNum;
///转赠钻石单笔最大限额
@property (nonatomic,assign) NSInteger giveDiamondOnceLimitNum;
///转赠钻石财富等级
@property (nonatomic,assign) NSInteger giveDiamondExperLevel;
///转赠礼物财富等级
@property (nonatomic,assign) NSInteger giveGiftExperLevel;
///转赠手续费率
@property (nonatomic,assign) double giveDiamondRate;
@property (nonatomic, assign) BOOL iosPhoneBind;
@property (nonatomic, assign) BOOL openBoxSwitch;
@property (nonatomic, assign) NSInteger openBoxSwitchLevelNo;
@property (nonatomic, strong) FaceJson *faceJson;
@property (nonatomic, assign) NSInteger trtcAppId;
@property (nonatomic, copy) NSString *appStoreAuditNoticeVersion;
@property(nonatomic, assign) BOOL captchaSwitch;
@property (nonatomic, copy) NSString *sudId;
@property (nonatomic, copy) NSString *sudkey;
@property (nonatomic, copy) NSString *nimKey;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,30 @@
//
// ClientDataModel.m
// YUMI
//
// Created by YUMI on 2022/3/7.
//
#import "ClientDataModel.h"
#import "XPAdImageTool.h"
@implementation FaceJson
@end
@implementation AppUISetting
@end
@implementation ClientDataModel
- (void)setSplashVo:(AdvertiseModel *)splashVo {
_splashVo = splashVo;
if (_splashVo) {
[XPAdImageTool.shareImageTool saveAdInfo:splashVo];
}
}
@end

View File

@@ -0,0 +1,52 @@
//
// ClientRedPacketModel.h
// YUMI
//
// Created by YUMI on 2022/8/31.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
//@class
@interface ClientRedPacketModel : PIBaseModel
///红包开关
@property (nonatomic, assign) BOOL open;
///红包推送id
@property (nonatomic, assign) long long pushUserId;
///厅内红包个数最大值
@property (nonatomic, strong) NSNumber *roomRedEnvelopeMaxNum;
///厅内红包数额最小值
@property (nonatomic, strong) NSNumber *roomRedEnvelopeMinAmount;
///厅内红包个数最小值
@property (nonatomic, strong) NSNumber *roomRedEnvelopeMinNum;
///全服红包个数最大值
@property (nonatomic, strong) NSNumber *serverRedEnvelopeMaxNum;
///全服红包数额最小值
@property (nonatomic, strong) NSNumber *serverRedEnvelopeMinAmount;
///全服红包个数最小值
@property (nonatomic, strong) NSNumber *serverRedEnvelopeMinNum;
///厅内红包数额最大值
@property (nonatomic, strong) NSNumber *roomRedEnvelopeMaxAmount;
///全服红包数额最大值
@property (nonatomic, strong) NSNumber *serverRedEnvelopeMaxAmount;
///默认红包位置1厅内 2全服
@property (nonatomic, strong) NSNumber *redEnvelopedPosition;
///默认红包类型1 钻石 2礼物
@property (nonatomic, strong) NSNumber *redEnvelopeType;
///钻石红包比例
@property (nonatomic, strong) NSNumber *exchangeDiamondsRate;
///版本
@property (nonatomic, copy) NSString *serverAppVersion;
//@property (nonatomic, strong) NSArray<> *gold2GiftIds;
@property (nonatomic, strong) NSArray *openRooms;
@property(nonatomic,assign) NSInteger beginSecond;
///红包有效时间
@property(nonatomic,assign) NSInteger endSecond;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,16 @@
//
// ClientRedPacketModel.m
// YUMI
//
// Created by YUMI on 2022/8/31.
//
#import "ClientRedPacketModel.h"
@implementation ClientRedPacketModel
//+ (NSDictionary *)objectClassInArray {
// return @{@"contents":GuildMessageLayoutInfoModel.class};
//}
@end

View File

@@ -0,0 +1,44 @@
//
// AdvertiseModel.h
// YUMI
//
// Created by YUMI on 2022/10/31.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, SplashInfoSkipType) {
SplashInfoSkipTypePage = 1,
SplashInfoSkipTypeRoom = 2,
SplashInfoSkipTypeWeb = 3,
SplashInfoSkipTypeWeb_CP = 4,
SplashInfoSkipTypeWeb_WeekStar = 5,
SplashInfoSkipTypeWeb_Custom = 6,
};
@interface AdvertiseFillModel : PIBaseModel
@property(nonatomic, copy) NSString *loverNick;
@property(nonatomic, copy) NSString *loverErbanNo;
@property(nonatomic, copy) NSString *loverAvatar;
@property(nonatomic, copy) NSString *nick;
@property(nonatomic, copy) NSString *erbanNo;
@property(nonatomic, copy) NSString *avatar;
@property(nonatomic, copy) NSString *picUrl;
@property(nonatomic, copy) NSString *giftName;
@property(nonatomic, copy) NSString *giftId;
@end
@interface AdvertiseModel : PIBaseModel
@property (nonatomic, strong) NSString *link;
@property (nonatomic, assign) SplashInfoSkipType type;// 1跳app页面2跳聊天室3跳h5页面,
@property (nonatomic, copy) NSString *pict;
@property(nonatomic, strong) AdvertiseFillModel *fillVo;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,23 @@
//
// AdvertiseModel.m
// YUMI
//
// Created by YUMI on 2022/10/31.
//
#import "AdvertiseModel.h"
@implementation AdvertiseFillModel
@end
@implementation AdvertiseModel
+ (NSDictionary *)objectClassInArray {
return @{
@"fillVo": [AdvertiseFillModel class],
};
}
@end

View File

@@ -0,0 +1,48 @@
//
// YMAdImageTool.h
// YUMI
//
// Created by YUMI on 2022/10/31.
//
#import <Foundation/Foundation.h>
#import "AdvertiseModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface XPAdImageTool : PIBaseModel
+ (instancetype)shareImageTool;
///是否登录成功im
@property (nonatomic,assign)BOOL isImLogin;
//去除广告信息
- (AdvertiseModel *)getAdInfoFromCacheInMainWith:(NSString *)link;
///保存信息
- (void)saveAdInfo:(AdvertiseModel *)adInfo;
/**
* 判断文件是否存在
*/
- (BOOL)isFileExistWithFilePath:(NSString *)filePath;
/**
* 初始化广告页面
*/
- (void)getAdvertisingImage;
/**
* 下载新图片
*/
- (void)downloadAdImageWithUrl:(NSString *)imageUrl imageName:(NSString *)imageName;
/**
* 删除旧图片
*/
- (void)deleteOldImage;
/**
* 根据图片名拼接文件路径
*/
- (NSString *)getFilePathWithImageName:(NSString *)imageName;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,158 @@
//
// YMAdImageTool.m
// YUMI
//
// Created by YUMI on 2022/10/31.
//
#import "XPAdImageTool.h"
#import <YYCache/YYCache.h>
#import "UploadFile.h"
#define CACHENAME @"XPUserCache"
UIKIT_EXTERN NSString * const adImageName;
@interface XPAdImageTool ()
@property (nonatomic, strong) YYCache *yyCache;
///广
@property (nonatomic,strong) AdvertiseModel *infoModel;
@end
static XPAdImageTool* tool;
@implementation XPAdImageTool
+ (instancetype)shareImageTool {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
tool = [[XPAdImageTool alloc] init];
});
return tool;
}
- (instancetype)init
{
self = [super init];
if (self) {
self.yyCache = [YYCache cacheWithName:CACHENAME];
}
return self;
}
//广
- (AdvertiseModel *)getAdInfoFromCacheInMainWith:(NSString *)link {
if (link.length > 0) {
if ([self.yyCache containsObjectForKey:link]) {
return (AdvertiseModel *)[self.yyCache objectForKey:link];
}else {
return nil;
}
}else {
return nil;
}
return nil;
}
///
- (void)saveAdInfo:(AdvertiseModel *)adInfo {
self.infoModel = adInfo;
NSArray *stringArr = [adInfo.pict componentsSeparatedByString:@"/"];
NSString *key = stringArr.lastObject;
[self.yyCache setObject:(id<NSCoding> )adInfo forKey:key withBlock:^{
}];
[self getAdvertisingImage];
}
/**
*
*/
- (BOOL)isFileExistWithFilePath:(NSString *)filePath {
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isDirectory = FALSE;
return [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory];
}
/**
* 广
*/
- (void)getAdvertisingImage {
if (self.infoModel.pict.length > 0) {
NSString *imageUrl = self.infoModel.pict;
//
NSArray *stringArr = [imageUrl componentsSeparatedByString:@"/"];
NSString *imageName = stringArr.lastObject;
//
NSString *filePath = [self getFilePathWithImageName:imageName];
BOOL isExist = [self isFileExistWithFilePath:filePath];
if (!isExist){//
[self downloadAdImageWithUrl:imageUrl imageName:imageName];
}
}else {
[self deleteOldImage];
}
}
/**
*
*/
- (void)downloadAdImageWithUrl:(NSString *)imageUrl imageName:(NSString *)imageName {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *filePath = [self getFilePathWithImageName:imageName]; //
if ([imageUrl.lowercaseString hasSuffix:@"svga"]) {
@kWeakify(self);
[[UploadFile share] download:imageUrl path:filePath complete:^{
@kStrongify(self);
[self deleteOldImage];
[[NSUserDefaults standardUserDefaults] setValue:imageName forKey:adImageName];
[[NSUserDefaults standardUserDefaults] synchronize];
} failure:^{
@kStrongify(self);
[self deleteOldImage];
}];
} else {
NSString *encode = [imageUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:encode]];
UIImage *image = [UIImage imageWithData:data];
if ([UIImagePNGRepresentation(image) writeToFile:filePath atomically:YES]) {//
[self deleteOldImage];
[[NSUserDefaults standardUserDefaults] setValue:imageName forKey:adImageName];
[[NSUserDefaults standardUserDefaults] synchronize];
}else{
[self deleteOldImage];
}
}
});
}
/**
*
*/
- (void)deleteOldImage {
NSString *imageName = [[NSUserDefaults standardUserDefaults] valueForKey:adImageName];
if (imageName) {
NSString *filePath = [self getFilePathWithImageName:imageName];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:filePath error:nil];
}
}
/**
*
*/
- (NSString *)getFilePathWithImageName:(NSString *)imageName {
if (imageName) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES);
NSString *filePath = [[paths xpSafeObjectAtIndex:0] stringByAppendingPathComponent:imageName];
return filePath;
}
return nil;
}
@end

View File

@@ -0,0 +1,26 @@
//
// YMAdvertiseView.h
// YUMI
//
// Created by YUMI on 2022/10/31.
//
#import <UIKit/UIKit.h>
#import "AdvertiseModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface XPAdvertiseView : UIView
/** 显示广告页面方法*/
- (void)show;
/** 图片路径*/
@property (nonatomic, copy) NSString *filePath;
@property(nonatomic, assign) SplashInfoSkipType type;
@property(nonatomic, strong) AdvertiseFillModel *fileModel;
@property (nonatomic, strong) UIImage *adImage;
@property (nonatomic, copy) void(^dismissHandler)(BOOL shouldJump); //闪屏消失回调
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,288 @@
//
// YMAdvertiseView.m
// YUMI
//
// Created by YUMI on 2022/10/31.
//
#import "XPAdvertiseView.h"
#import "AppDelegate.h"
//tool
#import <SVGA.h>
#import <sys/sysctl.h>
#import <sys/utsname.h>
#import "YUMIMacroUitls.h"
///Tool
#import "UIImage+Utils.h"
NSString *const adImageName = @"adImageName";
NSString *const adUrl = @"adUrl";
// 广
static int const showtime = 3;
@interface XPAdvertiseView() <SVGAPlayerDelegate>
@property(nonatomic, strong) SVGAImageView *svgaView;
@property (nonatomic, strong) UIImageView *adView;//广
@property (nonatomic, strong) UIButton *countdownButton;//
@property (nonatomic, strong) NSTimer *countTimer;
@property (nonatomic, assign) int count;
@property (nonatomic, strong) UIWindow *window;
@property(nonatomic, strong) NSMutableArray *imageLoaders;
@end
@implementation XPAdvertiseView
#pragma mark - Initialize Methods
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
_adView = [[UIImageView alloc] initWithFrame:frame];
_adView.userInteractionEnabled = YES;
_adView.contentMode = UIViewContentModeScaleAspectFill;
_adView.clipsToBounds = YES;
[self addSubview:_adView];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapAdViewAction)];
[_adView addGestureRecognizer:tap];
[self addSubview:self.countdownButton];
[self.countdownButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.trailing.mas_equalTo(-24);
// make.width.mas_equalTo(60);
make.height.mas_equalTo(30);
make.top.mas_equalTo(40);
}];
// //
// if ([self needCountDownBtn]) {
// [self addSubview:self.countdownButton];
// }
}
return self;
}
#pragma mark - Public Methods
- (void)show {
// 1GCD
[self gcdCoundownHander];
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
[self.window.rootViewController.view addSubview:self];
[self.window makeKeyAndVisible];
[keyWindow makeKeyWindow];
}
#pragma mark - Event Response
///
- (void)onTapAdViewAction {
[self dismissWithJumpHandle:YES];
}
///
- (void)onClickSkipButton:(UIButton *)sender {
[self dismissWithJumpHandle:NO];
}
#pragma mark - Privite Method
// GCD
- (void)gcdCoundownHander {
__block int timeout = showtime;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0); //
dispatch_source_set_event_handler(_timer, ^{
if (timeout <= 0) { //
dispatch_source_cancel(_timer);
dispatch_async(dispatch_get_main_queue(), ^{
[self dismissWithJumpHandle:NO];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
if (self.countdownButton) {
[self.countdownButton setTitle:YMLocalizedString(@"XPAdvertiseView0") forState:UIControlStateNormal];
}
});
timeout--;
}
});
dispatch_resume(_timer);
}
// 广
- (void)dismissWithJumpHandle:(BOOL)shouldJump {
if (self.countTimer) {
[self.countTimer invalidate];
self.countTimer = nil;
}
@kWeakify(self)
[UIView animateWithDuration:0.5f animations:^{
@kStrongify(self)
self.window.hidden = YES;
} completion:^(BOOL finished) {
@kStrongify(self)
[self removeFromSuperview];
self.window = nil;
!self.dismissHandler ?: self.dismissHandler(shouldJump);
}];
}
- (NSString *)deviceName {
// Gets a string with the device model
size_t size;
int nR = sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *machine = (char *)malloc(size);
nR = sysctlbyname("hw.machine", machine, &size, NULL, 0);
NSString *platform = [NSString stringWithCString:machine encoding:NSUTF8StringEncoding];
free(machine);
return platform;
}
- (BOOL)needCountDownBtn {
NSString *platform = [self deviceName];
BOOL needBtn = YES;
if ([platform isEqualToString:@"iPhone6,1"] ||
[platform isEqualToString:@"iPhone6,2"] ||
[platform isEqualToString:@"iPhone7,1"] ||
[platform isEqualToString:@"iPhone7,2"] ||
[platform isEqualToString:@"iPhone8,1"] ||
[platform isEqualToString:@"iPhone8,2"] ||
[platform isEqualToString:@"iPhone8,4"]) {
needBtn = NO;
}
return needBtn;
}
#pragma mark - Setter
- (void)setFilePath:(NSString *)filePath {
_filePath = filePath;
_imageLoaders = @[].mutableCopy;
if (self.type == SplashInfoSkipTypeWeb_CP || self.type == SplashInfoSkipTypeWeb_Custom || self.type == SplashInfoSkipTypeWeb_WeekStar) {
_svgaView = [[SVGAImageView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)];
_svgaView.delegate = self;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapAdViewAction)];
[_svgaView addGestureRecognizer:tap];
// [self addSubview:_svgaView];
[self insertSubview:_svgaView belowSubview:self.countdownButton];
SVGAParser *p = [[SVGAParser alloc] init];
@kWeakify(self);
[p parseWithURL:[[NSURL alloc] initFileURLWithPath:filePath] completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
@kStrongify(self);
if (videoItem) {
self.svgaView.autoPlay = YES;
self.svgaView.clearsAfterStop = YES;
self.svgaView.videoItem = videoItem;
if (self.fileModel) {
[self updateSvgaImage:self.fileModel.avatar key:@"avatar"];
[self updateSvgaImage:self.fileModel.picUrl key:@"gift"];
[self updateSvgaImage:self.fileModel.avatar key:@"avatar_1"];
[self updateSvgaImage:self.fileModel.loverAvatar key:@"avatar_2"];
[self updateSvgaText:[NSString stringWithFormat:@"ID: %@", self.fileModel.erbanNo] key:@"id"];
[self updateSvgaText:self.fileModel.giftName key:@"name"];
[self updateSvgaText:[NSString stringWithFormat:@"ID: %@", self.fileModel.erbanNo] key:@"id_1"];
[self updateSvgaText:[NSString stringWithFormat:@"ID: %@", self.fileModel.loverErbanNo] key:@"id_2"];
}
[self.svgaView startAnimation];
}
} failureBlock:^(NSError * _Nullable error) {
@kStrongify(self);
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
self.adView.image = [image cutImage:[UIScreen mainScreen].bounds.size];
}];
} else {
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
self.adView.image = [image cutImage:[UIScreen mainScreen].bounds.size];
}
}
- (void)updateSvgaImage:(NSString *)imagePath key:(NSString *)key {
if (self.svgaView && ![NSString isEmpty:imagePath] && ![NSString isEmpty:key]) {
UIImage *image = [UIImage imageWithColor:[UIColor colorWithWhite:0.9 alpha:0.9] size:CGSizeMake(100, 100)];
[self.svgaView setImage:image
forKey:key];
__block NetImageView *loader = [[NetImageView alloc] init];
@kWeakify(self);
@kWeakify(loader);
[loader loadImageWithUrl:imagePath
completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) {
@kStrongify(self);
@kStrongify(loader);
[self.svgaView setImage:image
forKey:key];
[self.imageLoaders removeObject:loader];
}];
[self.imageLoaders addObject:loader];
}
}
- (void)updateSvgaText:(NSString *)content key:(NSString *)key {
if (self.svgaView && ![NSString isEmpty:content] && ![NSString isEmpty:key]) {
NSAttributedString *string = [[NSAttributedString alloc] initWithString:content
attributes:@{
NSFontAttributeName: kFontMedium(kGetScaleWidth(24)),
NSForegroundColorAttributeName: UIColorFromRGB(0xFDF565)
}];
[self.svgaView setAttributedText:string
forKey:key];
}
}
- (void)setAdImage:(UIImage *)adImage {
_adImage = adImage;
_adView.image = [adImage cutImage:[UIScreen mainScreen].bounds.size];
}
#pragma mark - SVGAPlayerDelegate
#pragma mark - Getter
- (UIWindow *)window {
if (_window == nil) {
_window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
_window.windowLevel = UIWindowLevelAlert;
_window.userInteractionEnabled = YES;
_window.rootViewController = [[UIViewController alloc] init];
}
return _window;
}
- (UIButton *)countdownButton {
if (_countdownButton == nil) {
_countdownButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_countdownButton addTarget:self action:@selector(onClickSkipButton:) forControlEvents:UIControlEventTouchUpInside];
[_countdownButton setTitle:YMLocalizedString(@"XPAdvertiseView1") forState:UIControlStateNormal];
_countdownButton.titleLabel.font = [UIFont systemFontOfSize:15];
[_countdownButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
_countdownButton.backgroundColor = [UIColor colorWithRed:38 /255.0 green:38 /255.0 blue:38 /255.0 alpha:0.6];
_countdownButton.layer.cornerRadius = 4;
_countdownButton.contentEdgeInsets = UIEdgeInsetsMake(0, 8, 0, 8);
[_countdownButton sizeToFit];
}
return _countdownButton;
}
@end

View File

@@ -1,7 +1,9 @@
//
// DJDKMIMOMColor.h
// YUMI
//
// Created by YUMI on 2021/9/9.
//
#import <Foundation/Foundation.h>
@@ -11,58 +13,62 @@
NS_ASSUME_NONNULL_BEGIN
@interface DJDKMIMOMColor : NSObject
/// 主题色0x9682FF
+ (UIColor *)appMainColor;
///强调色 #248CFE
+ (UIColor *)appEmphasizeColor;
///强调色1 0xBF36FF
+ (UIColor *)appEmphasizeColor1;
///强调色2 0xFB486A
+ (UIColor *)appEmphasizeColor2;
/* ------页面相关颜色 START------ */
/// view的背景色 0xF3F5FA
+ (UIColor *)appBackgroundColor;
/// cell的背景色 0xFFFFFF
+ (UIColor *)appCellBackgroundColor;
///正文颜色 0x333333
+ (UIColor *)mainTextColor;
/// 二级文字颜色 0x666666
+ (UIColor *)secondTextColor;
///三级文字的颜色 0x999999
+ (UIColor *)textThirdColor;
///分割线的颜色 0xE8E8E8
+ (UIColor *)dividerColor;
/* ------页面相关颜色 END------ */
/* ------Button 相关颜色 START------ */
/// button 可用 渐变色的开始 0xFFA936
+ (UIColor *)confirmButtonGradientStartColor;
/// button 可用 渐变色的中间 #9CB3FF
+ (UIColor *)confirmButtonGradientMiddleColor;
/// button 可用 渐变色的开始 0xFFCB47
+ (UIColor *)confirmButtonGradientEndColor;
/// 确定的按钮文字颜色 #FFFFFF
+ (UIColor *)confirmButtonTextColor;
/// 取消按钮 渐变色的开始 0xF7DDBF
+ (UIColor *)cancelButtonGradientStartColor;
/// 取消按钮 渐变色的结束 0xF7E8C4
+ (UIColor *)cancelButtonGradientEndColor;
/// 取消的按钮文字颜色 0xFFA936
+ (UIColor *)cancelButtonTextColor;
/// 取消按钮单一普通背景色 0xFFCE4E
+ (UIColor *)cancelButtonNormalBgColor;
/// 按钮不可点击背景色 0xD2D5D7
+ (UIColor *)disableButtonColor;
/// 按钮不可点击文字颜色 0xF9F9F9
+ (UIColor *)disableButtonTextColor;
/* ------Button 相关颜色 END------ */
/* ------弹窗相关颜色 START------ */
+ (UIColor *)alertBackgroundColor;
+ (UIColor *)alertTitleColor;
+ (UIColor *)alertMessageColor;
+ (UIColor *)actionSeparatorColor;
/* ------弹窗相关颜色 END------ */
///tabbar 没有点击的时候颜色 0x333333, 0.4
+ (UIColor *)tabbarNormalColor;
/// tabbar的View的color 0xFFFFFF
+ (UIColor *)tabbarViewColor;
+ (UIColor *)colorWithHexString:(NSString *)hexString;

View File

@@ -1,99 +1,105 @@
//
// DJDKMIMOMColor.m
// YUMI
//
// Created by YUMI on 2021/9/9.
//
#import "DJDKMIMOMColor.h"
@implementation DJDKMIMOMColor
/// 0x9682FF
+ (UIColor *)appMainColor {
return UIColorFromRGB(0x9682FF);
}
/// #248CFE
+ (UIColor *)appEmphasizeColor {
return UIColorFromRGB(0x248CFE);
}
///1 0xBF36FF
+ (UIColor *)appEmphasizeColor1 {
return UIColorFromRGB(0xBF36FF);
}
///2 0xFB486A
+ (UIColor *)appEmphasizeColor2 {
return UIColorFromRGB(0xFB486A);
}
/* ------ START------ */
/// view 0xF3F5FA
+ (UIColor *)appBackgroundColor {
return UIColorFromRGB(0xF3F5FA);
}
/// cell 0xFFFFFF
+ (UIColor *)appCellBackgroundColor {
return UIColorFromRGB(0xFFFFFF);
}
/// 0x333333
+ (UIColor *)mainTextColor {
return UIColorFromRGB(0x161958);
}
/// 0x666666
+ (UIColor *)secondTextColor {
return UIColorFromRGB(0x8A8CAB);
}
/// 0x999999
+ (UIColor *)textThirdColor {
return UIColorFromRGB(0xBABBCD);
}
///线 0xE8E8E8
+ (UIColor *)dividerColor {
return UIColorFromRGB(0xE8E8E8);
}
/* ------ END------ */
/* ------Button START------ */
/// button 0x3CAAFF
+ (UIColor *)confirmButtonGradientStartColor {
return UIColorFromRGB(0x13E2F5);
}
/// button 0xB176FF
+ (UIColor *)confirmButtonGradientEndColor {
return UIColorFromRGB(0xCC66FF);
}
/// #FFFFFF
+ (UIColor *)confirmButtonTextColor {
return UIColorFromRGB(0xFFFFFF);
}
/// 0xF7DDBF
+ (UIColor *)cancelButtonGradientStartColor {
return UIColorFromRGB(0xCEEFFD);
}
/// button #9CB3FF
+ (UIColor *)confirmButtonGradientMiddleColor {
return UIColorFromRGB(0xf9CB3FF);
}
/// 0xF7E8C4
+ (UIColor *)cancelButtonGradientEndColor {
return UIColorFromRGB(0xD2F4F4);
}
/// 0xFFA936
+ (UIColor *)cancelButtonTextColor {
return UIColorFromRGB(0x5FCCE4);
}
/// 0xFFCE4E
+ (UIColor *)cancelButtonNormalBgColor {
return UIColorFromRGB(0xCEEFFD);
}
/// 0xD2D5D7
+ (UIColor *)disableButtonColor {
return UIColorFromRGB(0xCEEFFD);
}
/// 0xF9F9F9
+ (UIColor *)disableButtonTextColor {
return UIColorFromRGB(0xB3B3C3);
}
/* ------Button END------ */
/* ------ START------ */
+ (UIColor *)alertBackgroundColor {
return UIColorFromRGB(0xFFFFFF);
}
@@ -106,12 +112,13 @@
+ (UIColor *)actionSeparatorColor {
return UIColorFromRGB(0xF0F0F0);
}
/* ------ END------ */
///tabbar 0x333333, 0.4
+ (UIColor *)tabbarNormalColor {
return UIColorRGBAlpha(0x333333, 0.4);
}
/// tabbarViewcolor 0xFFFFFF
+ (UIColor *)tabbarViewColor {
return UIColorFromRGB(0xFFFFFF);
}
@@ -123,25 +130,25 @@
NSString *colorString = [[hexString stringByReplacingOccurrencesOfString: @"#" withString: @""] uppercaseString];
CGFloat alpha, red, blue, green;
switch ([colorString length]) {
case 3:
case 3: // #RGB
alpha = 1.0f;
red = [self colorComponentFrom: colorString start: 0 length: 1];
green = [self colorComponentFrom: colorString start: 1 length: 1];
blue = [self colorComponentFrom: colorString start: 2 length: 1];
break;
case 4:
case 4: // #ARGB
alpha = [self colorComponentFrom: colorString start: 0 length: 1];
red = [self colorComponentFrom: colorString start: 1 length: 1];
green = [self colorComponentFrom: colorString start: 2 length: 1];
blue = [self colorComponentFrom: colorString start: 3 length: 1];
break;
case 6:
case 6: // #RRGGBB
alpha = 1.0f;
red = [self colorComponentFrom: colorString start: 0 length: 2];
green = [self colorComponentFrom: colorString start: 2 length: 2];
blue = [self colorComponentFrom: colorString start: 4 length: 2];
break;
case 8:
case 8: // #AARRGGBB
alpha = [self colorComponentFrom: colorString start: 0 length: 2];
red = [self colorComponentFrom: colorString start: 2 length: 2];
green = [self colorComponentFrom: colorString start: 4 length: 2];
@@ -162,7 +169,7 @@
return hexComponent / 255.0;
}
/// #1F1A4E
+ (UIColor *)inputTextColor {
return [self colorWithHexString:@"#1F1A4E"];
}

View File

@@ -0,0 +1,16 @@
//
// EmptyDataView.h
// YuMi
//
// Created by P on 2024/12/23.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface EmptyDataView : UIView
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,20 @@
//
// EmptyDataView.m
// YuMi
//
// Created by P on 2024/12/23.
//
#import "EmptyDataView.h"
@implementation EmptyDataView
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
@end

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,54 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "chat_icon_emoji_black_l_normal@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "chat_icon_emoji_black_l_normal@2x-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "chat_icon_emoji_black_l_normal@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "chat_icon_emoji_black_l_normal@3x-1.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1017 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 973 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

View File

@@ -0,0 +1,54 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "chat_icon_more_black_l_normal@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "chat_icon_more_black_l_normal@2x-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "chat_icon_more_black_l_normal@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "chat_icon_more_black_l_normal@3x-1.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

View File

@@ -0,0 +1,54 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "chat_icon_keyboard_black_l_normal@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "chat_icon_keyboard_black_l_normal@2x-1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "chat_icon_keyboard_black_l_normal@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "chat_icon_keyboard_black_l_normal@3x-1.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

View File

@@ -0,0 +1,54 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "chat_icon_voice@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "chat_icon_voice_dark@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "chat_icon_voice@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "chat_icon_voice_dark@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,52 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "white_rect.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "white_btn_dark.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 B

View File

@@ -0,0 +1,52 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "white_rect.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "white_input_btn_dark.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 B

View File

@@ -0,0 +1,52 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "white_input_press_btn.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "white_input_press_btn_dark.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,131 @@
<?xml version="1.0" encoding="utf-8"?>
<PopoEmoticons>
<Catalog ID="default" Title="emoji" Icon="emoj_s_normal.png" IconPressed="emoj_s_pressed.png">
<Emoticon ID="emoticon_emoji_01" Tag="[可爱]" File="emoji_01.png" />
<Emoticon ID="emoticon_emoji_0" Tag="[大笑]" File="emoji_00.png" />
<Emoticon ID="emoticon_emoji_02" Tag="[色]" File="emoji_02.png" />
<Emoticon ID="emoticon_emoji_03" Tag="[嘘]" File="emoji_03.png" />
<Emoticon ID="emoticon_emoji_04" Tag="[亲]" File="emoji_04.png" />
<Emoticon ID="emoticon_emoji_05" Tag="[呆]" File="emoji_05.png" />
<Emoticon ID="emoticon_emoji_06" Tag="[口水]" File="emoji_06.png" />
<Emoticon ID="emoticon_emoji_145" Tag="[汗]" File="emoji_145.png" />
<Emoticon ID="emoticon_emoji_07" Tag="[呲牙]" File="emoji_07.png" />
<Emoticon ID="emoticon_emoji_08" Tag="[鬼脸]" File="emoji_08.png" />
<Emoticon ID="emoticon_emoji_09" Tag="[害羞]" File="emoji_09.png" />
<Emoticon ID="emoticon_emoji_10" Tag="[偷笑]" File="emoji_10.png" />
<Emoticon ID="emoticon_emoji_11" Tag="[调皮]" File="emoji_11.png" />
<Emoticon ID="emoticon_emoji_12" Tag="[可怜]" File="emoji_12.png" />
<Emoticon ID="emoticon_emoji_13" Tag="[敲]" File="emoji_13.png" />
<Emoticon ID="emoticon_emoji_14" Tag="[惊讶]" File="emoji_14.png" />
<Emoticon ID="emoticon_emoji_15" Tag="[流感]" File="emoji_15.png" />
<Emoticon ID="emoticon_emoji_16" Tag="[委屈]" File="emoji_16.png" />
<Emoticon ID="emoticon_emoji_17" Tag="[流泪]" File="emoji_17.png" />
<Emoticon ID="emoticon_emoji_18" Tag="[嚎哭]" File="emoji_18.png" />
<Emoticon ID="emoticon_emoji_19" Tag="[惊恐]" File="emoji_19.png" />
<Emoticon ID="emoticon_emoji_20" Tag="[怒]" File="emoji_20.png" />
<Emoticon ID="emoticon_emoji_21" Tag="[酷]" File="emoji_21.png" />
<Emoticon ID="emoticon_emoji_22" Tag="[不说]" File="emoji_22.png" />
<Emoticon ID="emoticon_emoji_23" Tag="[鄙视]" File="emoji_23.png" />
<Emoticon ID="emoticon_emoji_24" Tag="[阿弥陀佛]" File="emoji_24.png" />
<Emoticon ID="emoticon_emoji_25" Tag="[奸笑]" File="emoji_25.png" />
<Emoticon ID="emoticon_emoji_26" Tag="[睡着]" File="emoji_26.png" />
<Emoticon ID="emoticon_emoji_27" Tag="[口罩]" File="emoji_27.png" />
<Emoticon ID="emoticon_emoji_28" Tag="[努力]" File="emoji_28.png" />
<Emoticon ID="emoticon_emoji_29" Tag="[抠鼻孔]" File="emoji_29.png" />
<Emoticon ID="emoticon_emoji_30" Tag="[疑问]" File="emoji_30.png" />
<Emoticon ID="emoticon_emoji_31" Tag="[怒骂]" File="emoji_31.png" />
<Emoticon ID="emoticon_emoji_32" Tag="[晕]" File="emoji_32.png" />
<Emoticon ID="emoticon_emoji_33" Tag="[呕吐]" File="emoji_33.png" />
<Emoticon ID="emoticon_emoji_160" Tag="[拜一拜]" File="emoji_160.png" />
<Emoticon ID="emoticon_emoji_161" Tag="[惊喜]" File="emoji_161.png" />
<Emoticon ID="emoticon_emoji_162" Tag="[流汗]" File="emoji_162.png" />
<Emoticon ID="emoticon_emoji_163" Tag="[卖萌]" File="emoji_163.png" />
<Emoticon ID="emoticon_emoji_164" Tag="[默契眨眼]" File="emoji_164.png" />
<Emoticon ID="emoticon_emoji_165" Tag="[烧香拜佛]" File="emoji_165.png" />
<Emoticon ID="emoticon_emoji_166" Tag="[晚安]" File="emoji_166.png" />
<Emoticon ID="emoticon_emoji_34" Tag="[强]" File="emoji_34.png" />
<Emoticon ID="emoticon_emoji_35" Tag="[弱]" File="emoji_35.png" />
<Emoticon ID="emoticon_emoji_36" Tag="[OK]" File="emoji_36.png" />
<Emoticon ID="emoticon_emoji_37" Tag="[拳头]" File="emoji_37.png" />
<Emoticon ID="emoticon_emoji_38" Tag="[胜利]" File="emoji_38.png" />
<Emoticon ID="emoticon_emoji_39" Tag="[鼓掌]" File="emoji_39.png" />
<Emoticon ID="emoticon_emoji_200" Tag="[握手]" File="emoji_200.png" />
<Emoticon ID="emoticon_emoji_40" Tag="[发怒]" File="emoji_40.png" />
<Emoticon ID="emoticon_emoji_41" Tag="[骷髅]" File="emoji_41.png" />
<Emoticon ID="emoticon_emoji_42" Tag="[便便]" File="emoji_42.png" />
<Emoticon ID="emoticon_emoji_43" Tag="[火]" File="emoji_43.png" />
<Emoticon ID="emoticon_emoji_44" Tag="[溜]" File="emoji_44.png" />
<Emoticon ID="emoticon_emoji_45" Tag="[爱心]" File="emoji_45.png" />
<Emoticon ID="emoticon_emoji_46" Tag="[心碎]" File="emoji_46.png" />
<Emoticon ID="emoticon_emoji_47" Tag="[钟情]" File="emoji_47.png" />
<Emoticon ID="emoticon_emoji_48" Tag="[唇]" File="emoji_48.png" />
<Emoticon ID="emoticon_emoji_49" Tag="[戒指]" File="emoji_49.png" />
<Emoticon ID="emoticon_emoji_50" Tag="[钻石]" File="emoji_50.png" />
<Emoticon ID="emoticon_emoji_51" Tag="[太阳]" File="emoji_51.png" />
<Emoticon ID="emoticon_emoji_52" Tag="[有时晴]" File="emoji_52.png" />
<Emoticon ID="emoticon_emoji_53" Tag="[多云]" File="emoji_53.png" />
<Emoticon ID="emoticon_emoji_54" Tag="[雷]" File="emoji_54.png" />
<Emoticon ID="emoticon_emoji_55" Tag="[雨]" File="emoji_55.png" />
<Emoticon ID="emoticon_emoji_56" Tag="[雪花]" File="emoji_56.png" />
<Emoticon ID="emoticon_emoji_57" Tag="[爱人]" File="emoji_57.png" />
<Emoticon ID="emoticon_emoji_58" Tag="[帽子]" File="emoji_58.png" />
<Emoticon ID="emoticon_emoji_59" Tag="[皇冠]" File="emoji_59.png" />
<Emoticon ID="emoticon_emoji_60" Tag="[篮球]" File="emoji_60.png" />
<Emoticon ID="emoticon_emoji_61" Tag="[足球]" File="emoji_61.png" />
<Emoticon ID="emoticon_emoji_62" Tag="[垒球]" File="emoji_62.png" />
<Emoticon ID="emoticon_emoji_63" Tag="[网球]" File="emoji_63.png" />
<Emoticon ID="emoticon_emoji_64" Tag="[台球]" File="emoji_64.png" />
<Emoticon ID="emoticon_emoji_65" Tag="[咖啡]" File="emoji_65.png" />
<Emoticon ID="emoticon_emoji_66" Tag="[啤酒]" File="emoji_66.png" />
<Emoticon ID="emoticon_emoji_67" Tag="[干杯]" File="emoji_67.png" />
<Emoticon ID="emoticon_emoji_68" Tag="[柠檬汁]" File="emoji_68.png" />
<Emoticon ID="emoticon_emoji_69" Tag="[餐具]" File="emoji_69.png" />
<Emoticon ID="emoticon_emoji_70" Tag="[汉堡]" File="emoji_70.png" />
<Emoticon ID="emoticon_emoji_71" Tag="[鸡腿]" File="emoji_71.png" />
<Emoticon ID="emoticon_emoji_72" Tag="[面条]" File="emoji_72.png" />
<Emoticon ID="emoticon_emoji_73" Tag="[冰淇淋]" File="emoji_73.png" />
<Emoticon ID="emoticon_emoji_74" Tag="[沙冰]" File="emoji_74.png" />
<Emoticon ID="emoticon_emoji_75" Tag="[生日蛋糕]" File="emoji_75.png" />
<Emoticon ID="emoticon_emoji_76" Tag="[蛋糕]" File="emoji_76.png" />
<Emoticon ID="emoticon_emoji_77" Tag="[糖果]" File="emoji_77.png" />
<Emoticon ID="emoticon_emoji_78" Tag="[葡萄]" File="emoji_78.png" />
<Emoticon ID="emoticon_emoji_79" Tag="[西瓜]" File="emoji_79.png" />
<Emoticon ID="emoticon_emoji_80" Tag="[光碟]" File="emoji_80.png" />
<Emoticon ID="emoticon_emoji_81" Tag="[手机]" File="emoji_81.png" />
<Emoticon ID="emoticon_emoji_82" Tag="[电话]" File="emoji_82.png" />
<Emoticon ID="emoticon_emoji_83" Tag="[电视]" File="emoji_83.png" />
<Emoticon ID="emoticon_emoji_84" Tag="[声音开启]" File="emoji_84.png" />
<Emoticon ID="emoticon_emoji_85" Tag="[声音关闭]" File="emoji_85.png" />
<Emoticon ID="emoticon_emoji_86" Tag="[铃铛]" File="emoji_86.png" />
<Emoticon ID="emoticon_emoji_87" Tag="[锁头]" File="emoji_87.png" />
<Emoticon ID="emoticon_emoji_88" Tag="[放大镜]" File="emoji_88.png" />
<Emoticon ID="emoticon_emoji_89" Tag="[灯泡]" File="emoji_89.png" />
<Emoticon ID="emoticon_emoji_90" Tag="[锤头]" File="emoji_90.png" />
<Emoticon ID="emoticon_emoji_91" Tag="[烟]" File="emoji_91.png" />
<Emoticon ID="emoticon_emoji_92" Tag="[炸弹]" File="emoji_92.png" />
<Emoticon ID="emoticon_emoji_93" Tag="[枪]" File="emoji_93.png" />
<Emoticon ID="emoticon_emoji_94" Tag="[刀]" File="emoji_94.png" />
<Emoticon ID="emoticon_emoji_95" Tag="[药]" File="emoji_95.png" />
<Emoticon ID="emoticon_emoji_96" Tag="[打针]" File="emoji_96.png" />
<Emoticon ID="emoticon_emoji_97" Tag="[钱袋]" File="emoji_97.png" />
<Emoticon ID="emoticon_emoji_98" Tag="[钞票]" File="emoji_98.png" />
<Emoticon ID="emoticon_emoji_99" Tag="[银行卡]" File="emoji_99.png" />
<Emoticon ID="emoticon_emoji_100" Tag="[手柄]" File="emoji_100.png" />
<Emoticon ID="emoticon_emoji_101" Tag="[麻将]" File="emoji_101.png" />
<Emoticon ID="emoticon_emoji_102" Tag="[调色板]" File="emoji_102.png" />
<Emoticon ID="emoticon_emoji_103" Tag="[电影]" File="emoji_103.png" />
<Emoticon ID="emoticon_emoji_104" Tag="[麦克风]" File="emoji_104.png" />
<Emoticon ID="emoticon_emoji_105" Tag="[耳机]" File="emoji_105.png" />
<Emoticon ID="emoticon_emoji_106" Tag="[音乐]" File="emoji_106.png" />
<Emoticon ID="emoticon_emoji_107" Tag="[吉他]" File="emoji_107.png" />
<Emoticon ID="emoticon_emoji_108" Tag="[火箭]" File="emoji_108.png" />
<Emoticon ID="emoticon_emoji_109" Tag="[飞机]" File="emoji_109.png" />
<Emoticon ID="emoticon_emoji_110" Tag="[火车]" File="emoji_110.png" />
<Emoticon ID="emoticon_emoji_111" Tag="[公交]" File="emoji_111.png" />
<Emoticon ID="emoticon_emoji_112" Tag="[轿车]" File="emoji_112.png" />
<Emoticon ID="emoticon_emoji_113" Tag="[出租车]" File="emoji_113.png" />
<Emoticon ID="emoticon_emoji_114" Tag="[警车]" File="emoji_114.png" />
<Emoticon ID="emoticon_emoji_115" Tag="[自行车]" File="emoji_115.png" />
</Catalog>
</PopoEmoticons>
˜

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Some files were not shown because too many files have changed in this diff Show More