Commit e062205a by suolong

礼物互动完成

parent 9155725f
Showing with 485 additions and 32 deletions
...@@ -100,6 +100,8 @@ ...@@ -100,6 +100,8 @@
// 更新直播间互动游戏开关状态socket // 更新直播间互动游戏开关状态socket
#define ROOM_CID_liveInteractionGameStateDidChanged 20204 #define ROOM_CID_liveInteractionGameStateDidChanged 20204
// 更新直播间礼物互动开关状态socket(主播/观众都会收到)
#define ROOM_CID_giftInteractionStateDidChanged 20205
#define ROOM_CID_LINKMIC_SENDINVIT 30001 // 主播发送连麦邀请 #define ROOM_CID_LINKMIC_SENDINVIT 30001 // 主播发送连麦邀请
#define ROOM_CID_LINKMIC_REPLYINVIT 30002 // 用户回复连麦邀请 #define ROOM_CID_LINKMIC_REPLYINVIT 30002 // 用户回复连麦邀请
...@@ -116,6 +118,7 @@ ...@@ -116,6 +118,7 @@
#define USER_ACCOUNT_CHANGE 12000 // 推送用户账户发生变化 #define USER_ACCOUNT_CHANGE 12000 // 推送用户账户发生变化
#define ROOM_CID_GIFT_INTERACT_TASK_CHANGED 12002 // 礼物互动任务达成变化 #define ROOM_CID_GIFT_INTERACT_TASK_CHANGED 12002 // 礼物互动任务达成变化
#define ROOM_CID_GIFT_INTERACT_TASK_LIST_REFRESH 12003 // 礼物互动任务列表刷新(用于观众端面板直刷)
#define ROOM_CID_REALTIME_ACTIVITY_INFO 10091 // 直播间实时活动 #define ROOM_CID_REALTIME_ACTIVITY_INFO 10091 // 直播间实时活动
#define ROOM_CID_LIVE_ALERT 10090 // 接收到直播弹窗通知 #define ROOM_CID_LIVE_ALERT 10090 // 接收到直播弹窗通知
...@@ -132,5 +135,3 @@ ...@@ -132,5 +135,3 @@
...@@ -1668,6 +1668,7 @@ ...@@ -1668,6 +1668,7 @@
BED65A792C5B745F00668116 /* FUSLiveFunctionView.h in Headers */ = {isa = PBXBuildFile; fileRef = BED657A42C5B745D00668116 /* FUSLiveFunctionView.h */; }; BED65A792C5B745F00668116 /* FUSLiveFunctionView.h in Headers */ = {isa = PBXBuildFile; fileRef = BED657A42C5B745D00668116 /* FUSLiveFunctionView.h */; };
BED65A7A2C5B745F00668116 /* FUSLiveFunctionView.m in Sources */ = {isa = PBXBuildFile; fileRef = BED657A52C5B745D00668116 /* FUSLiveFunctionView.m */; }; BED65A7A2C5B745F00668116 /* FUSLiveFunctionView.m in Sources */ = {isa = PBXBuildFile; fileRef = BED657A52C5B745D00668116 /* FUSLiveFunctionView.m */; };
C0A1B2C32F6A000100AAAA03 /* FUSLiveGiftInteractTaskPanelView.m in Sources */ = {isa = PBXBuildFile; fileRef = C0A1B2C32F6A000100AAAA02 /* FUSLiveGiftInteractTaskPanelView.m */; }; C0A1B2C32F6A000100AAAA03 /* FUSLiveGiftInteractTaskPanelView.m in Sources */ = {isa = PBXBuildFile; fileRef = C0A1B2C32F6A000100AAAA02 /* FUSLiveGiftInteractTaskPanelView.m */; };
C0A1B2C32F6A000100AAAA06 /* FUSLiveGiftInteractAudiencePanelView.m in Sources */ = {isa = PBXBuildFile; fileRef = C0A1B2C32F6A000100AAAA05 /* FUSLiveGiftInteractAudiencePanelView.m */; };
BED65A7B2C5B745F00668116 /* FUSLiveLoadingView.h in Headers */ = {isa = PBXBuildFile; fileRef = BED657A72C5B745D00668116 /* FUSLiveLoadingView.h */; }; BED65A7B2C5B745F00668116 /* FUSLiveLoadingView.h in Headers */ = {isa = PBXBuildFile; fileRef = BED657A72C5B745D00668116 /* FUSLiveLoadingView.h */; };
BED65A7C2C5B745F00668116 /* FUSLiveLoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = BED657A82C5B745D00668116 /* FUSLiveLoadingView.m */; }; BED65A7C2C5B745F00668116 /* FUSLiveLoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = BED657A82C5B745D00668116 /* FUSLiveLoadingView.m */; };
BED65A7E2C5B745F00668116 /* FUSLiveMinimizeView.h in Headers */ = {isa = PBXBuildFile; fileRef = BED657AB2C5B745D00668116 /* FUSLiveMinimizeView.h */; }; BED65A7E2C5B745F00668116 /* FUSLiveMinimizeView.h in Headers */ = {isa = PBXBuildFile; fileRef = BED657AB2C5B745D00668116 /* FUSLiveMinimizeView.h */; };
...@@ -4093,6 +4094,8 @@ ...@@ -4093,6 +4094,8 @@
BED657A52C5B745D00668116 /* FUSLiveFunctionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUSLiveFunctionView.m; sourceTree = "<group>"; }; BED657A52C5B745D00668116 /* FUSLiveFunctionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUSLiveFunctionView.m; sourceTree = "<group>"; };
C0A1B2C32F6A000100AAAA01 /* FUSLiveGiftInteractTaskPanelView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FUSLiveGiftInteractTaskPanelView.h; sourceTree = "<group>"; }; C0A1B2C32F6A000100AAAA01 /* FUSLiveGiftInteractTaskPanelView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FUSLiveGiftInteractTaskPanelView.h; sourceTree = "<group>"; };
C0A1B2C32F6A000100AAAA02 /* FUSLiveGiftInteractTaskPanelView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUSLiveGiftInteractTaskPanelView.m; sourceTree = "<group>"; }; C0A1B2C32F6A000100AAAA02 /* FUSLiveGiftInteractTaskPanelView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUSLiveGiftInteractTaskPanelView.m; sourceTree = "<group>"; };
C0A1B2C32F6A000100AAAA04 /* FUSLiveGiftInteractAudiencePanelView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FUSLiveGiftInteractAudiencePanelView.h; sourceTree = "<group>"; };
C0A1B2C32F6A000100AAAA05 /* FUSLiveGiftInteractAudiencePanelView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUSLiveGiftInteractAudiencePanelView.m; sourceTree = "<group>"; };
BED657A72C5B745D00668116 /* FUSLiveLoadingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FUSLiveLoadingView.h; sourceTree = "<group>"; }; BED657A72C5B745D00668116 /* FUSLiveLoadingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FUSLiveLoadingView.h; sourceTree = "<group>"; };
BED657A82C5B745D00668116 /* FUSLiveLoadingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUSLiveLoadingView.m; sourceTree = "<group>"; }; BED657A82C5B745D00668116 /* FUSLiveLoadingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUSLiveLoadingView.m; sourceTree = "<group>"; };
BED657A92C5B745D00668116 /* FUSLiveLoadingView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FUSLiveLoadingView.xib; sourceTree = "<group>"; }; BED657A92C5B745D00668116 /* FUSLiveLoadingView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FUSLiveLoadingView.xib; sourceTree = "<group>"; };
...@@ -7428,6 +7431,8 @@ ...@@ -7428,6 +7431,8 @@
children = ( children = (
C0A1B2C32F6A000100AAAA01 /* FUSLiveGiftInteractTaskPanelView.h */, C0A1B2C32F6A000100AAAA01 /* FUSLiveGiftInteractTaskPanelView.h */,
C0A1B2C32F6A000100AAAA02 /* FUSLiveGiftInteractTaskPanelView.m */, C0A1B2C32F6A000100AAAA02 /* FUSLiveGiftInteractTaskPanelView.m */,
C0A1B2C32F6A000100AAAA04 /* FUSLiveGiftInteractAudiencePanelView.h */,
C0A1B2C32F6A000100AAAA05 /* FUSLiveGiftInteractAudiencePanelView.m */,
); );
path = GiftInteract; path = GiftInteract;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -10774,6 +10779,7 @@ ...@@ -10774,6 +10779,7 @@
BED658BA2C5B745E00668116 /* FUSHalfWebViewCollectionViewCell.m in Sources */, BED658BA2C5B745E00668116 /* FUSHalfWebViewCollectionViewCell.m in Sources */,
BED65A7A2C5B745F00668116 /* FUSLiveFunctionView.m in Sources */, BED65A7A2C5B745F00668116 /* FUSLiveFunctionView.m in Sources */,
C0A1B2C32F6A000100AAAA03 /* FUSLiveGiftInteractTaskPanelView.m in Sources */, C0A1B2C32F6A000100AAAA03 /* FUSLiveGiftInteractTaskPanelView.m in Sources */,
C0A1B2C32F6A000100AAAA06 /* FUSLiveGiftInteractAudiencePanelView.m in Sources */,
004773412F5EBADE00E46A79 /* FUSNewUserSevenDayCheckInControl.swift in Sources */, 004773412F5EBADE00E46A79 /* FUSNewUserSevenDayCheckInControl.swift in Sources */,
BED658FF2C5B745E00668116 /* FUSLiveChatInputBulletsListCell.m in Sources */, BED658FF2C5B745E00668116 /* FUSLiveChatInputBulletsListCell.m in Sources */,
BED6599A2C5B745E00668116 /* FUSAgoraHelper.m in Sources */, BED6599A2C5B745E00668116 /* FUSAgoraHelper.m in Sources */,
{
"images" : [
{
"filename" : "Live_bottom_leftArrow.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Live_bottom_leftArrow@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Live_bottom_leftArrow@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "Live_bottom_liveTopic.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Live_bottom_liveTopic@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Live_bottom_liveTopic@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
...@@ -97,7 +97,6 @@ static NSInteger const FUSLiveGiftInteractMaxItemCount = 6; ...@@ -97,7 +97,6 @@ static NSInteger const FUSLiveGiftInteractMaxItemCount = 6;
if (roomInfo.stateSwitch) { if (roomInfo.stateSwitch) {
roomInfo.stateSwitch.giftinteractionstate = switchState; roomInfo.stateSwitch.giftinteractionstate = switchState;
} }
[[NSNotificationCenter defaultCenter] postNotificationName:@"FUSGiftInteractSwitchDidChangeNotification" object:nil userInfo:@{@"switchState": @(switchState)}];
[weakCell fus_setupWithEnabled:switchState]; [weakCell fus_setupWithEnabled:switchState];
[weakCell fus_setSwitchUserInteractionEnabled:YES]; [weakCell fus_setSwitchUserInteractionEnabled:YES];
} failure:^(NSString *msg, NSInteger code) { } failure:^(NSString *msg, NSInteger code) {
......
...@@ -1158,6 +1158,34 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -1158,6 +1158,34 @@ NS_ASSUME_NONNULL_BEGIN
succeed:(void (^)(NSDictionary *dataDict))succeed succeed:(void (^)(NSDictionary *dataDict))succeed
failure:(void (^)(NSString *msg, NSInteger code))failure; failure:(void (^)(NSString *msg, NSInteger code))failure;
/// 礼物互动行为-主播更新任务状态(完成)
/// @param uid 用户ID
/// @param roomId 房间ID
/// @param channelId 频道ID
/// @param taskId 任务ID
/// @param status 状态(1:已完成)
/// @param succeed 成功回调
/// @param failure 失败回调
+ (void)fus_requestGiftInteractTaskCompleteWithUid:(NSString *)uid
roomId:(NSString *)roomId
channelId:(NSString *)channelId
taskId:(NSString *)taskId
status:(NSInteger)status
succeed:(void (^)(void))succeed
failure:(void (^)(NSString *msg, NSInteger code))failure;
/// 礼物互动行为-用户获取列表(观众端)
/// @param uid 用户ID
/// @param roomId 房间ID
/// @param channelId 频道ID
/// @param succeed 成功回调(返回 dataList 原始数组)
/// @param failure 失败回调
+ (void)fus_requestGiftInteractItemDataListWithUid:(NSString *)uid
roomId:(NSString *)roomId
channelId:(NSString *)channelId
succeed:(void (^)(NSArray *dataList))succeed
failure:(void (^)(NSString *msg, NSInteger code))failure;
/// 礼物互动行为-管理获取配置列表 /// 礼物互动行为-管理获取配置列表
/// @param uid 用户ID /// @param uid 用户ID
/// @param roomId 房间ID /// @param roomId 房间ID
......
...@@ -149,6 +149,69 @@ ...@@ -149,6 +149,69 @@
} }
}]; }];
} }
/// 礼物互动行为-主播更新任务状态(完成)
+ (void)fus_requestGiftInteractTaskCompleteWithUid:(NSString *)uid
roomId:(NSString *)roomId
channelId:(NSString *)channelId
taskId:(NSString *)taskId
status:(NSInteger)status
succeed:(void (^)(void))succeed
failure:(void (^)(NSString *msg, NSInteger code))failure {
if ([NSString isNullWithString:uid] ||
[NSString isNullWithString:roomId] ||
[NSString isNullWithString:channelId] ||
[NSString isNullWithString:taskId]) {
if (failure) {
failure(@"参数错误", ERROR_CODE);
}
return;
}
NSDictionary *params = @{@"uid": uid,
@"roomId": roomId,
@"channelId": channelId,
@"taskId": taskId,
@"status": @(status)};
[FUSHttpHelper postRequestBinaryWithUrl:FUSShowRoomURLs.fus_URL_interactionGiftTaskComplete params:params success:^(NSDictionary *dataDict, int code) {
if (succeed) {
succeed();
}
} failure:^(NSDictionary *dataDict, int code) {
if (failure) {
NSString *msg = [dataDict[@"msg"] isKindOfClass:NSString.class] ? dataDict[@"msg"] : FAILURE_MESSAGE;
failure(msg, code);
}
}];
}
/// 礼物互动行为-用户获取列表(观众端)
+ (void)fus_requestGiftInteractItemDataListWithUid:(NSString *)uid
roomId:(NSString *)roomId
channelId:(NSString *)channelId
succeed:(void (^)(NSArray *dataList))succeed
failure:(void (^)(NSString *msg, NSInteger code))failure {
if ([NSString isNullWithString:uid] ||
[NSString isNullWithString:roomId] ||
[NSString isNullWithString:channelId]) {
if (failure) {
failure(@"参数错误", ERROR_CODE);
}
return;
}
NSDictionary *params = @{@"uid": uid,
@"roomId": roomId,
@"channelId": channelId};
[FUSHttpHelper postRequestBinaryWithUrl:FUSShowRoomURLs.fus_URL_interactionGiftItemDataList params:params success:^(NSDictionary *dataDict, int code) {
NSArray *list = [dataDict[@"dataList"] isKindOfClass:NSArray.class] ? dataDict[@"dataList"] : @[];
if (succeed) {
succeed(list);
}
} failure:^(NSDictionary *dataDict, int code) {
if (failure) {
failure(FAILURE_MESSAGE, code);
}
}];
}
/** /**
获取包房ip/端口 连接socket 获取包房ip/端口 连接socket
......
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class FUSLiveGiftInteractSettingItemModel;
@interface FUSLiveGiftInteractAudiencePanelView : UIView
/// 刷新展示条目(支持展示礼物图标与数量)
- (void)fus_updateWithItems:(NSArray<FUSLiveGiftInteractSettingItemModel *> *)items;
@end
NS_ASSUME_NONNULL_END
#import "FUSLiveGiftInteractAudiencePanelView.h"
#import "FUSLiveGiftInteractSettingItemModel.h"
@interface FUSLiveGiftInteractAudiencePanelView ()
/// 顶部标题栏容器
@property (nonatomic, strong) UIView *headerView;
/// 顶部icon
@property (nonatomic, strong) UIImageView *headerIconView;
/// 顶部标题(“互动”)
@property (nonatomic, strong) UILabel *headerTitleLabel;
/// 空态文案(当 texts 为空时显示)
@property (nonatomic, strong) UILabel *emptyLabel;
/// 左侧文本 label 列表(按 texts 数量动态增减)
@property (nonatomic, strong) NSMutableArray<UILabel *> *textLabels;
/// 礼物图标列表(按 items 数量动态增减)
@property (nonatomic, strong) NSMutableArray<UIImageView *> *giftIconViews;
/// 礼物数量 label 列表(按 items 数量动态增减)
@property (nonatomic, strong) NSMutableArray<UILabel *> *giftCountLabels;
/// 当前展示的条目数组
@property (nonatomic, copy) NSArray<FUSLiveGiftInteractSettingItemModel *> *items;
@end
@implementation FUSLiveGiftInteractAudiencePanelView
static NSString *fus_substringComposedToLength(NSString *text, NSUInteger maxLength) {
if (text.length <= maxLength) {
return text;
}
NSRange range = NSMakeRange(0, maxLength);
NSRange safeRange = [text rangeOfComposedCharacterSequencesForRange:range];
return [text substringWithRange:safeRange];
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (!self) {
return nil;
}
self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.35];
self.layer.cornerRadius = 8;
self.clipsToBounds = YES;
self.userInteractionEnabled = YES;
self.headerView = [[UIView alloc] initWithFrame:CGRectZero];
self.headerView.backgroundColor = [UIColor colorWithHex:@"36E6ED" alpha:1];
[self addSubview:self.headerView];
self.headerIconView = [[UIImageView alloc] initWithFrame:CGRectZero];
self.headerIconView.contentMode = UIViewContentModeScaleAspectFit;
self.headerIconView.image = [FUSShowRoomCenterBunble imageNamed:@"Live_bottom_actIcon"];
[self.headerView addSubview:self.headerIconView];
self.headerTitleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
self.headerTitleLabel.text = [NSString fus_localString:@"互动"];
self.headerTitleLabel.font = [UIFont fus_themeFont:15];
self.headerTitleLabel.textColor = UIColor.blackColor;
[self.headerView addSubview:self.headerTitleLabel];
self.textLabels = [NSMutableArray array];
self.giftIconViews = [NSMutableArray array];
self.giftCountLabels = [NSMutableArray array];
self.emptyLabel = [[UILabel alloc] initWithFrame:CGRectZero];
self.emptyLabel.text = [NSString fus_localString:@"暂无"];
self.emptyLabel.textAlignment = NSTextAlignmentCenter;
self.emptyLabel.font = [UIFont fus_themeFont:12];
self.emptyLabel.textColor = UIColor.whiteColor;
[self addSubview:self.emptyLabel];
[self fus_updateWithItems:@[]];
return self;
}
- (void)fus_updateWithItems:(NSArray<FUSLiveGiftInteractSettingItemModel *> *)items {
self.items = items ?: @[];
NSInteger targetCount = self.items.count;
while (self.textLabels.count > targetCount) {
UILabel *label = self.textLabels.lastObject;
[label removeFromSuperview];
[self.textLabels removeLastObject];
}
while (self.giftIconViews.count > targetCount) {
UIImageView *view = self.giftIconViews.lastObject;
[view removeFromSuperview];
[self.giftIconViews removeLastObject];
}
while (self.giftCountLabels.count > targetCount) {
UILabel *label = self.giftCountLabels.lastObject;
[label removeFromSuperview];
[self.giftCountLabels removeLastObject];
}
while (self.textLabels.count < targetCount) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.font = [UIFont fus_themeFont:12];
label.textColor = UIColor.whiteColor;
label.numberOfLines = 1;
label.lineBreakMode = NSLineBreakByTruncatingTail;
[self addSubview:label];
[self.textLabels addObject:label];
}
while (self.giftIconViews.count < targetCount) {
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectZero];
imgView.contentMode = UIViewContentModeScaleAspectFit;
imgView.clipsToBounds = YES;
[self addSubview:imgView];
[self.giftIconViews addObject:imgView];
}
while (self.giftCountLabels.count < targetCount) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.font = [UIFont fus_themeFont:11];
label.textColor = UIColor.whiteColor;
label.textAlignment = NSTextAlignmentLeft;
label.numberOfLines = 1;
[self addSubview:label];
[self.giftCountLabels addObject:label];
}
UIImage *placeholder = [FUSShowRoomCenterBunble imageNamed:@"icon_gift_placehold"];
for (NSInteger i = 0; i < targetCount; i++) {
FUSLiveGiftInteractSettingItemModel *model = self.items[i];
NSString *action = model.name ?: @"";
NSString *text = fus_substringComposedToLength(action, 6);
UILabel *textLabel = self.textLabels[i];
textLabel.text = text ?: @"";
UIImageView *giftIconView = self.giftIconViews[i];
NSString *icon = model.giftIcon ?: @"";
if (icon.length == 0) {
giftIconView.image = placeholder;
} else {
NSString *urlString = icon;
if (![urlString containsString:@"http"]) {
urlString = [FUSConfig.sharedInstanced.pathConfigs webImagePath:urlString];
}
NSURL *url = [NSURL URLWithString:urlString];
[giftIconView setImageWithURL:url placeholder:placeholder options:0 completion:nil];
}
UILabel *countLabel = self.giftCountLabels[i];
NSInteger giftNum = model.giftNum;
countLabel.text = (giftNum > 0 ? [NSString stringWithFormat:@"x%ld", (long)giftNum] : @"");
}
self.emptyLabel.hidden = (targetCount > 0);
[self setNeedsLayout];
}
- (void)layoutSubviews {
[super layoutSubviews];
CGFloat headerH = 30;
CGFloat padding = 8;
self.headerView.frame = CGRectMake(0, 0, CGRectGetWidth(self.bounds), headerH);
CGFloat iconSize = 16;
CGFloat spacing = 4;
CGSize titleSize = [self.headerTitleLabel sizeThatFits:CGSizeMake(CGFLOAT_MAX, headerH)];
CGFloat groupW = iconSize + spacing + titleSize.width;
CGFloat groupX = (CGRectGetWidth(self.headerView.bounds) - groupW) * 0.5;
if (groupX < 0) {
groupX = 0;
}
self.headerIconView.frame = CGRectMake(groupX, (headerH - iconSize) * 0.5, iconSize, iconSize);
self.headerTitleLabel.frame = CGRectMake(CGRectGetMaxX(self.headerIconView.frame) + spacing, 0, titleSize.width, headerH);
CGFloat contentTop = CGRectGetMaxY(self.headerView.frame);
if (self.items.count == 0) {
self.emptyLabel.frame = CGRectMake(0, contentTop, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) - contentTop);
return;
}
self.emptyLabel.frame = CGRectZero;
CGFloat giftIconSize = 18;
CGFloat countW = 28;
CGFloat giftIconX = padding;
CGFloat giftCountX = giftIconX + giftIconSize + 4;
CGFloat labelX = giftCountX + countW + 8;
CGFloat labelW = CGRectGetWidth(self.bounds) - padding - labelX;
if (labelW < 0) {
labelW = 0;
}
CGFloat availableH = CGRectGetHeight(self.bounds) - contentTop - padding * 2;
CGFloat rowHeight = (availableH > 0 ? (availableH / self.items.count) : 0);
for (NSInteger i = 0; i < self.items.count; i++) {
CGFloat y = contentTop + padding + i * rowHeight;
UILabel *label = self.textLabels[i];
label.frame = CGRectMake(labelX, y, labelW, rowHeight);
UIImageView *iconView = self.giftIconViews[i];
iconView.frame = CGRectMake(giftIconX, y + (rowHeight - giftIconSize) * 0.5, giftIconSize, giftIconSize);
UILabel *countLabel = self.giftCountLabels[i];
countLabel.frame = CGRectMake(giftCountX, y, countW, rowHeight);
}
}
@end
...@@ -2,13 +2,15 @@ ...@@ -2,13 +2,15 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class FUSLiveGiftInteractSettingItemModel;
@interface FUSLiveGiftInteractTaskPanelView : UIView @interface FUSLiveGiftInteractTaskPanelView : UIView
/// 点击“消失”回调,index 对应 taskTexts 的下标 /// 点击“消失”回调,index 对应 taskTexts 的下标
@property (nonatomic, copy, nullable) void (^doneHandler)(NSInteger index); @property (nonatomic, copy, nullable) void (^doneHandler)(NSInteger index);
/// 刷新展示文本(最多展示调用方传入的数量 /// 刷新展示条目(支持展示头像、昵称与任务文案
- (void)fus_updateWithTaskTexts:(NSArray<NSString *> *)taskTexts; - (void)fus_updateWithItems:(NSArray<FUSLiveGiftInteractSettingItemModel *> *)items;
@end @end
......
#import "FUSLiveGiftInteractTaskPanelView.h" #import "FUSLiveGiftInteractTaskPanelView.h"
#import "FUSLiveGiftInteractSettingItemModel.h"
@interface FUSLiveGiftInteractTaskPanelView () @interface FUSLiveGiftInteractTaskPanelView ()
/// 顶部标题栏 /// 顶部标题栏
...@@ -9,16 +10,29 @@ ...@@ -9,16 +10,29 @@
@property (nonatomic, strong) UILabel *headerTitleLabel; @property (nonatomic, strong) UILabel *headerTitleLabel;
/// 空态文案(当 taskTexts 为空时显示) /// 空态文案(当 taskTexts 为空时显示)
@property (nonatomic, strong) UILabel *emptyLabel; @property (nonatomic, strong) UILabel *emptyLabel;
/// 当前展示的文本数组 /// 当前展示的条目数组
@property (nonatomic, copy) NSArray<NSString *> *taskTexts; @property (nonatomic, copy) NSArray<FUSLiveGiftInteractSettingItemModel *> *items;
/// 左侧文本 label 列表(按 taskTexts 数量动态增减) /// 头像列表(按 items 数量动态增减)
@property (nonatomic, strong) NSMutableArray<UILabel *> *textLabels; @property (nonatomic, strong) NSMutableArray<UIImageView *> *avatarViews;
/// 昵称 label 列表(按 items 数量动态增减)
@property (nonatomic, strong) NSMutableArray<UILabel *> *nicknameLabels;
/// 任务文案 label 列表(按 items 数量动态增减)
@property (nonatomic, strong) NSMutableArray<UILabel *> *taskLabels;
/// 右侧“消失”按钮列表(按 taskTexts 数量动态增减) /// 右侧“消失”按钮列表(按 taskTexts 数量动态增减)
@property (nonatomic, strong) NSMutableArray<UIButton *> *doneButtons; @property (nonatomic, strong) NSMutableArray<UIButton *> *doneButtons;
@end @end
@implementation FUSLiveGiftInteractTaskPanelView @implementation FUSLiveGiftInteractTaskPanelView
static NSString *fus_substringComposedToLength(NSString *text, NSUInteger maxLength) {
if (text.length <= maxLength) {
return text;
}
NSRange range = NSMakeRange(0, maxLength);
NSRange safeRange = [text rangeOfComposedCharacterSequencesForRange:range];
return [text substringWithRange:safeRange];
}
- (instancetype)initWithFrame:(CGRect)frame { - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame]; self = [super initWithFrame:frame];
if (!self) { if (!self) {
...@@ -44,7 +58,9 @@ ...@@ -44,7 +58,9 @@
self.headerTitleLabel.textColor = UIColor.blackColor; self.headerTitleLabel.textColor = UIColor.blackColor;
[self.headerView addSubview:self.headerTitleLabel]; [self.headerView addSubview:self.headerTitleLabel];
self.textLabels = [NSMutableArray array]; self.avatarViews = [NSMutableArray array];
self.nicknameLabels = [NSMutableArray array];
self.taskLabels = [NSMutableArray array];
self.doneButtons = [NSMutableArray array]; self.doneButtons = [NSMutableArray array];
self.emptyLabel = [[UILabel alloc] initWithFrame:CGRectZero]; self.emptyLabel = [[UILabel alloc] initWithFrame:CGRectZero];
...@@ -54,32 +70,60 @@ ...@@ -54,32 +70,60 @@
self.emptyLabel.textColor = UIColor.whiteColor; self.emptyLabel.textColor = UIColor.whiteColor;
[self addSubview:self.emptyLabel]; [self addSubview:self.emptyLabel];
[self fus_updateWithTaskTexts:@[]]; [self fus_updateWithItems:@[]];
return self; return self;
} }
/// 刷新内容并驱动视图子控件数量与布局更新 - (void)fus_updateWithItems:(NSArray<FUSLiveGiftInteractSettingItemModel *> *)items {
- (void)fus_updateWithTaskTexts:(NSArray<NSString *> *)taskTexts { self.items = items ?: @[];
self.taskTexts = taskTexts ?: @[]; NSInteger targetCount = self.items.count;
NSInteger targetCount = self.taskTexts.count;
while (self.textLabels.count > targetCount) { while (self.avatarViews.count > targetCount) {
UILabel *label = self.textLabels.lastObject; UIImageView *view = self.avatarViews.lastObject;
[view removeFromSuperview];
[self.avatarViews removeLastObject];
}
while (self.nicknameLabels.count > targetCount) {
UILabel *label = self.nicknameLabels.lastObject;
[label removeFromSuperview];
[self.nicknameLabels removeLastObject];
}
while (self.taskLabels.count > targetCount) {
UILabel *label = self.taskLabels.lastObject;
[label removeFromSuperview]; [label removeFromSuperview];
[self.textLabels removeLastObject]; [self.taskLabels removeLastObject];
} }
while (self.doneButtons.count > targetCount) { while (self.doneButtons.count > targetCount) {
UIButton *btn = self.doneButtons.lastObject; UIButton *btn = self.doneButtons.lastObject;
[btn removeFromSuperview]; [btn removeFromSuperview];
[self.doneButtons removeLastObject]; [self.doneButtons removeLastObject];
} }
while (self.textLabels.count < targetCount) { while (self.avatarViews.count < targetCount) {
UIImageView *view = [[UIImageView alloc] initWithFrame:CGRectZero];
view.contentMode = UIViewContentModeScaleAspectFill;
view.clipsToBounds = YES;
[self addSubview:view];
[self.avatarViews addObject:view];
}
while (self.nicknameLabels.count < targetCount) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero]; UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.font = [UIFont fus_themeFont:12]; label.font = [UIFont fus_themeFont:9];
label.textColor = UIColor.whiteColor; label.textColor = UIColor.whiteColor;
label.numberOfLines = 1; label.numberOfLines = 1;
label.alpha = 0.5;
label.lineBreakMode = NSLineBreakByTruncatingTail;
[self addSubview:label]; [self addSubview:label];
[self.textLabels addObject:label]; [self.nicknameLabels addObject:label];
}
while (self.taskLabels.count < targetCount) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.font = [UIFont fus_themeFont:10];
label.textColor = UIColor.whiteColor;
label.textAlignment = NSTextAlignmentRight;
label.lineBreakMode = NSLineBreakByTruncatingTail;
[self addSubview:label];
[self.taskLabels addObject:label];
} }
while (self.doneButtons.count < targetCount) { while (self.doneButtons.count < targetCount) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
...@@ -91,8 +135,23 @@ ...@@ -91,8 +135,23 @@
} }
for (NSInteger i = 0; i < targetCount; i++) { for (NSInteger i = 0; i < targetCount; i++) {
UILabel *label = self.textLabels[i]; FUSLiveGiftInteractSettingItemModel *model = self.items[i];
label.text = self.taskTexts[i] ?: @"";
UIImageView *avatarView = self.avatarViews[i];
avatarView.image = UIImage.fus_defaultIcon;
NSString *face = model.userFace ?: @"";
if (![NSString isNull:face]) {
[avatarView setLiveFaceWebImageWithSubURLString:face placeholder:UIImage.fus_defaultIcon];
}
UILabel *nicknameLabel = self.nicknameLabels[i];
NSString *nickname = model.userNickname ?: @"";
nicknameLabel.text = fus_substringComposedToLength(nickname, 4);
UILabel *taskLabel = self.taskLabels[i];
NSString *task = model.name ?: @"";
taskLabel.text = fus_substringComposedToLength(task, 6);
UIButton *btn = self.doneButtons[i]; UIButton *btn = self.doneButtons[i];
btn.tag = i; btn.tag = i;
} }
...@@ -122,23 +181,39 @@ ...@@ -122,23 +181,39 @@
CGFloat contentTop = CGRectGetMaxY(self.headerView.frame); CGFloat contentTop = CGRectGetMaxY(self.headerView.frame);
if (self.taskTexts.count == 0) { if (self.items.count == 0) {
self.emptyLabel.frame = CGRectMake(0, contentTop, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) - contentTop); self.emptyLabel.frame = CGRectMake(0, contentTop, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) - contentTop);
return; return;
} }
self.emptyLabel.frame = CGRectZero; self.emptyLabel.frame = CGRectZero;
CGFloat labelX = padding; CGFloat avatarSize = 18;
CGFloat avatarX = padding;
CGFloat avatarRight = avatarX + avatarSize + 4;
CGFloat nicknameW = 30;
CGFloat nicknameX = avatarRight;
CGFloat taskX = nicknameX + nicknameW + 6;
CGFloat buttonX = CGRectGetWidth(self.bounds) - padding - buttonSize; CGFloat buttonX = CGRectGetWidth(self.bounds) - padding - buttonSize;
CGFloat labelW = buttonX - labelX - 8; CGFloat taskW = buttonX - taskX - 6;
if (taskW < 0) {
taskW = 0;
}
CGFloat availableH = CGRectGetHeight(self.bounds) - contentTop - padding * 2; CGFloat availableH = CGRectGetHeight(self.bounds) - contentTop - padding * 2;
CGFloat rowHeight = (availableH > 0 ? (availableH / self.taskTexts.count) : 0); CGFloat rowHeight = (availableH > 0 ? (availableH / self.items.count) : 0);
for (NSInteger i = 0; i < self.taskTexts.count; i++) { for (NSInteger i = 0; i < self.items.count; i++) {
CGFloat y = contentTop + padding + i * rowHeight; CGFloat y = contentTop + padding + i * rowHeight;
UILabel *label = self.textLabels[i]; UIImageView *avatarView = self.avatarViews[i];
label.frame = CGRectMake(labelX, y, labelW, rowHeight); avatarView.frame = CGRectMake(avatarX, y + (rowHeight - avatarSize) * 0.5, avatarSize, avatarSize);
avatarView.layer.cornerRadius = avatarSize * 0.5;
UILabel *nicknameLabel = self.nicknameLabels[i];
nicknameLabel.frame = CGRectMake(nicknameX, y, nicknameW, rowHeight);
UILabel *taskLabel = self.taskLabels[i];
taskLabel.frame = CGRectMake(taskX, y, taskW, rowHeight);
UIButton *btn = self.doneButtons[i]; UIButton *btn = self.doneButtons[i];
btn.frame = CGRectMake(buttonX, y + (rowHeight - buttonSize) * 0.5, buttonSize, buttonSize); btn.frame = CGRectMake(buttonX, y + (rowHeight - buttonSize) * 0.5, buttonSize, buttonSize);
} }
......
...@@ -38,7 +38,7 @@ class FUSLiveStartContentThemeEditView: UIView { ...@@ -38,7 +38,7 @@ class FUSLiveStartContentThemeEditView: UIView {
let themeSubLabel = UILabel() let themeSubLabel = UILabel()
let closeBtn = UIButton(type: .custom) let closeBtn = UIButton(type: .custom)
let themeSubString = String.fus_localString("设置您的直播主题") let themeSubString = String.fus_localString("设置贴纸文字")
// 初始化data // 初始化data
func setUpData(){ func setUpData(){
......
...@@ -151,7 +151,7 @@ ...@@ -151,7 +151,7 @@
- (void)customInit { - (void)customInit {
self.contentInfoView.lineView.hidden = YES; self.contentInfoView.lineView.hidden = YES;
self.titleLabel.text = [NSString fus_localString:@"设置直播主题"]; self.titleLabel.text = [NSString fus_localString:@"设置贴纸文字"];
self.selectedThemeDescLabel.text = [NSString fus_localString:@"选择模板"]; self.selectedThemeDescLabel.text = [NSString fus_localString:@"选择模板"];
self.themeTitleDescLabel.text = [NSString fus_localString:@"输入主题内容"]; self.themeTitleDescLabel.text = [NSString fus_localString:@"输入主题内容"];
self.themeTitleTextField.placeholder = [NSString fus_localString:@"输入主题内容"]; self.themeTitleTextField.placeholder = [NSString fus_localString:@"输入主题内容"];
......
...@@ -492,6 +492,12 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -492,6 +492,12 @@ NS_ASSUME_NONNULL_BEGIN
/// 礼物互动行为-主播获取任务列表 /// 礼物互动行为-主播获取任务列表
+ (NSString *)fus_URL_interactionGiftTaskList; + (NSString *)fus_URL_interactionGiftTaskList;
/// 礼物互动行为-主播更新任务状态(完成)
+ (NSString *)fus_URL_interactionGiftTaskComplete;
/// 礼物互动行为-用户获取列表(观众端)
+ (NSString *)fus_URL_interactionGiftItemDataList;
/// 礼物互动行为-管理获取配置列表 /// 礼物互动行为-管理获取配置列表
+ (NSString *)fus_URL_interactionGiftManageList; + (NSString *)fus_URL_interactionGiftManageList;
......
...@@ -797,6 +797,16 @@ ...@@ -797,6 +797,16 @@
return [FUSConfig.sharedInstanced.pathConfigs apiUrl:@"/interaction/gift/taskdata/list"]; return [FUSConfig.sharedInstanced.pathConfigs apiUrl:@"/interaction/gift/taskdata/list"];
} }
/// 礼物互动行为-主播更新任务状态(完成)
+ (NSString *)fus_URL_interactionGiftTaskComplete{
return [FUSConfig.sharedInstanced.pathConfigs apiUrl:@"/interaction/gift/taskdata/complete"];
}
/// 礼物互动行为-用户获取列表(观众端)
+ (NSString *)fus_URL_interactionGiftItemDataList{
return [FUSConfig.sharedInstanced.pathConfigs apiUrl:@"/interaction/gift/itemdata/list"];
}
/// 礼物互动行为-管理获取配置列表 /// 礼物互动行为-管理获取配置列表
+ (NSString *)fus_URL_interactionGiftManageList{ + (NSString *)fus_URL_interactionGiftManageList{
return [FUSConfig.sharedInstanced.pathConfigs apiUrl:@"/interaction/gift/manage/list"]; return [FUSConfig.sharedInstanced.pathConfigs apiUrl:@"/interaction/gift/manage/list"];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment