Commit cc72931c by suolong

完成 首页标签显示和 更改主题

parent e062205a
Showing with 850 additions and 12 deletions
......@@ -117,6 +117,7 @@
#define ROOM_CID_LINKMIC_CHANGE 30012 // 麦位列表存在变化
#define USER_ACCOUNT_CHANGE 12000 // 推送用户账户发生变化
#define ROOM_CID_LIVE_TOPIC_TITLE_DID_CHANGED 12004 // 主播主题标题文案变化(接口只提交,实际展示以此 socket 为准)
#define ROOM_CID_GIFT_INTERACT_TASK_CHANGED 12002 // 礼物互动任务达成变化
#define ROOM_CID_GIFT_INTERACT_TASK_LIST_REFRESH 12003 // 礼物互动任务列表刷新(用于观众端面板直刷)
#define ROOM_CID_REALTIME_ACTIVITY_INFO 10091 // 直播间实时活动
......@@ -132,6 +133,3 @@
#define ROOM_CID_LiveThemeDidChanged 20202
......@@ -1319,6 +1319,8 @@
BEB504702D2E8C2E00EA6E6F /* FUSLiveThemeModel+FUSRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB5046E2D2E8C2E00EA6E6F /* FUSLiveThemeModel+FUSRequest.m */; };
BEB504742D2E8FEC00EA6E6F /* FUSLiveThemeView.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB504722D2E8FEC00EA6E6F /* FUSLiveThemeView.h */; };
BEB504752D2E8FEC00EA6E6F /* FUSLiveThemeView.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB504732D2E8FEC00EA6E6F /* FUSLiveThemeView.m */; };
BEF0C0DE2F9B123400A1B2C6 /* FUSLiveTopicWindowView.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF0C0DE2F9B123400A1B2C4 /* FUSLiveTopicWindowView.h */; };
BEF0C0DE2F9B123400A1B2C7 /* FUSLiveTopicWindowView.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF0C0DE2F9B123400A1B2C5 /* FUSLiveTopicWindowView.m */; };
BECF741B2D2F826B00F5ABBC /* FUSMidpointSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = BECF741A2D2F826B00F5ABBC /* FUSMidpointSlider.swift */; };
BECF74392D2FB19100F5ABBC /* FUSLivePushQualitySettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BECF74352D2FB19100F5ABBC /* FUSLivePushQualitySettingView.swift */; };
BECF743D2D2FB21B00F5ABBC /* FUSLivePushQualityItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BECF743C2D2FB21B00F5ABBC /* FUSLivePushQualityItemCell.swift */; };
......@@ -1449,6 +1451,8 @@
BED658F42C5B745E00668116 /* FUSLiveBottomToolSubView.m in Sources */ = {isa = PBXBuildFile; fileRef = BED655F12C5B745D00668116 /* FUSLiveBottomToolSubView.m */; };
BEF6C0A72F0A1B2C0033D4E5 /* FUSLiveShowTimePopView.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF6C0A52F0A1B2C0033D4E5 /* FUSLiveShowTimePopView.h */; };
BEF6C0A82F0A1B2C0033D4E5 /* FUSLiveShowTimePopView.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF6C0A62F0A1B2C0033D4E5 /* FUSLiveShowTimePopView.m */; };
BEA1B2C52F7A111100ABCDEF /* FUSLiveRoomThemePopView.h in Headers */ = {isa = PBXBuildFile; fileRef = BEA1B2C32F7A111100ABCDEF /* FUSLiveRoomThemePopView.h */; };
BEA1B2C62F7A111100ABCDEF /* FUSLiveRoomThemePopView.m in Sources */ = {isa = PBXBuildFile; fileRef = BEA1B2C42F7A111100ABCDEF /* FUSLiveRoomThemePopView.m */; };
BEF6C0BB2F0A1D3A0033D4E5 /* FUSLiveShowTimeCollectFrostedView.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF6C0B92F0A1D3A0033D4E5 /* FUSLiveShowTimeCollectFrostedView.h */; };
BEF6C0BC2F0A1D3A0033D4E5 /* FUSLiveShowTimeCollectFrostedView.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF6C0BA2F0A1D3A0033D4E5 /* FUSLiveShowTimeCollectFrostedView.m */; };
BED658F52C5B745E00668116 /* FUSLiveBottomToolView.h in Headers */ = {isa = PBXBuildFile; fileRef = BED655F22C5B745D00668116 /* FUSLiveBottomToolView.h */; };
......@@ -3708,6 +3712,8 @@
BEB5046E2D2E8C2E00EA6E6F /* FUSLiveThemeModel+FUSRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "FUSLiveThemeModel+FUSRequest.m"; sourceTree = "<group>"; };
BEB504722D2E8FEC00EA6E6F /* FUSLiveThemeView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FUSLiveThemeView.h; sourceTree = "<group>"; };
BEB504732D2E8FEC00EA6E6F /* FUSLiveThemeView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FUSLiveThemeView.m; sourceTree = "<group>"; };
BEF0C0DE2F9B123400A1B2C4 /* FUSLiveTopicWindowView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FUSLiveTopicWindowView.h; sourceTree = "<group>"; };
BEF0C0DE2F9B123400A1B2C5 /* FUSLiveTopicWindowView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FUSLiveTopicWindowView.m; sourceTree = "<group>"; };
BECF741A2D2F826B00F5ABBC /* FUSMidpointSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FUSMidpointSlider.swift; sourceTree = "<group>"; };
BECF74352D2FB19100F5ABBC /* FUSLivePushQualitySettingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FUSLivePushQualitySettingView.swift; sourceTree = "<group>"; };
BECF743C2D2FB21B00F5ABBC /* FUSLivePushQualityItemCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FUSLivePushQualityItemCell.swift; sourceTree = "<group>"; };
......@@ -3850,6 +3856,8 @@
BED655F12C5B745D00668116 /* FUSLiveBottomToolSubView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUSLiveBottomToolSubView.m; sourceTree = "<group>"; };
BEF6C0A52F0A1B2C0033D4E5 /* FUSLiveShowTimePopView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FUSLiveShowTimePopView.h; sourceTree = "<group>"; };
BEF6C0A62F0A1B2C0033D4E5 /* FUSLiveShowTimePopView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUSLiveShowTimePopView.m; sourceTree = "<group>"; };
BEA1B2C32F7A111100ABCDEF /* FUSLiveRoomThemePopView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FUSLiveRoomThemePopView.h; sourceTree = "<group>"; };
BEA1B2C42F7A111100ABCDEF /* FUSLiveRoomThemePopView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUSLiveRoomThemePopView.m; sourceTree = "<group>"; };
BEF6C0B92F0A1D3A0033D4E5 /* FUSLiveShowTimeCollectFrostedView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FUSLiveShowTimeCollectFrostedView.h; sourceTree = "<group>"; };
BEF6C0BA2F0A1D3A0033D4E5 /* FUSLiveShowTimeCollectFrostedView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FUSLiveShowTimeCollectFrostedView.m; sourceTree = "<group>"; };
BED655F22C5B745D00668116 /* FUSLiveBottomToolView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FUSLiveBottomToolView.h; sourceTree = "<group>"; };
......@@ -6528,6 +6536,15 @@
path = LiveThemeView;
sourceTree = "<group>";
};
BEF0C0DE2F9B123400A1B2C3 /* LiveThemeControl */ = {
isa = PBXGroup;
children = (
BEF0C0DE2F9B123400A1B2C4 /* FUSLiveTopicWindowView.h */,
BEF0C0DE2F9B123400A1B2C5 /* FUSLiveTopicWindowView.m */,
);
path = LiveThemeControl;
sourceTree = "<group>";
};
BECF74372D2FB19100F5ABBC /* LiveQuality */ = {
isa = PBXGroup;
children = (
......@@ -6836,6 +6853,8 @@
BED655F12C5B745D00668116 /* FUSLiveBottomToolSubView.m */,
BEF6C0A52F0A1B2C0033D4E5 /* FUSLiveShowTimePopView.h */,
BEF6C0A62F0A1B2C0033D4E5 /* FUSLiveShowTimePopView.m */,
BEA1B2C32F7A111100ABCDEF /* FUSLiveRoomThemePopView.h */,
BEA1B2C42F7A111100ABCDEF /* FUSLiveRoomThemePopView.m */,
BEF6C0B92F0A1D3A0033D4E5 /* FUSLiveShowTimeCollectFrostedView.h */,
BEF6C0BA2F0A1D3A0033D4E5 /* FUSLiveShowTimeCollectFrostedView.m */,
BED655F22C5B745D00668116 /* FUSLiveBottomToolView.h */,
......@@ -7398,6 +7417,7 @@
BEEAB2502D337F87008CD059 /* AnchorReward */,
00F0A0102F5F0A1B00C0FFEE /* PayRoom */,
BEB504712D2E8FD100EA6E6F /* LiveThemeView */,
BEF0C0DE2F9B123400A1B2C3 /* LiveThemeControl */,
C0A1B2C32F6A000100AAAA00 /* GiftInteract */,
BED655C12C5B745D00668116 /* Activity */,
BED655DC2C5B745D00668116 /* AudienceListView */,
......@@ -8695,6 +8715,7 @@
BED65B0A2C5B746000668116 /* FUSOpenScreenPushHelp.h in Headers */,
BED658F32C5B745E00668116 /* FUSLiveBottomToolSubView.h in Headers */,
BEF6C0A72F0A1B2C0033D4E5 /* FUSLiveShowTimePopView.h in Headers */,
BEA1B2C52F7A111100ABCDEF /* FUSLiveRoomThemePopView.h in Headers */,
BEF6C0BB2F0A1D3A0033D4E5 /* FUSLiveShowTimeCollectFrostedView.h in Headers */,
00B28CBA2D2FC4E10008476B /* FUSLiveEndLiveAssesModel.h in Headers */,
BE189DDF2C733B460008418B /* FSRRoomManagerViewController.h in Headers */,
......@@ -8989,6 +9010,7 @@
BED65AC22C5B745F00668116 /* FUSBannerView.h in Headers */,
BED65AEB2C5B746000668116 /* FUSRecommendedModel.h in Headers */,
BEB504742D2E8FEC00EA6E6F /* FUSLiveThemeView.h in Headers */,
BEF0C0DE2F9B123400A1B2C6 /* FUSLiveTopicWindowView.h in Headers */,
BED65ABE2C5B745F00668116 /* FUSHomeNovaListBroadcastHelper.h in Headers */,
BE189E192C733B460008418B /* FSREnterdictRoomManagerView.h in Headers */,
BED65B022C5B746000668116 /* FUSBaofangStreamPlayerView.h in Headers */,
......@@ -10771,6 +10793,7 @@
BE189DBC2C733B460008418B /* FSRSettingRoomGuarderOnlineModel.m in Sources */,
BED658F42C5B745E00668116 /* FUSLiveBottomToolSubView.m in Sources */,
BEF6C0A82F0A1B2C0033D4E5 /* FUSLiveShowTimePopView.m in Sources */,
BEA1B2C62F7A111100ABCDEF /* FUSLiveRoomThemePopView.m in Sources */,
BEF6C0BC2F0A1D3A0033D4E5 /* FUSLiveShowTimeCollectFrostedView.m in Sources */,
BED6599E2C5B745F00668116 /* FUSLinkMicItemView.m in Sources */,
BED658802C5B745E00668116 /* FUSLivePropsModel.m in Sources */,
......@@ -10886,6 +10909,7 @@
BED6599C2C5B745E00668116 /* FUSLinkMicroHttpHelper.m in Sources */,
BED658AA2C5B745E00668116 /* FUSVideoEndedView.m in Sources */,
BEB504752D2E8FEC00EA6E6F /* FUSLiveThemeView.m in Sources */,
BEF0C0DE2F9B123400A1B2C7 /* FUSLiveTopicWindowView.m in Sources */,
0089FD9D2D13F5340030DAA7 /* FUSLiveExchangeDiamondViewModel.swift in Sources */,
BED658B32C5B745E00668116 /* FUSVideoOfficialEndV2View.m in Sources */,
00E6CB092F4D4B1000B63797 /* FUSLiveChatInputToolAlertView.swift in Sources */,
{
"images" : [
{
"filename" : "home_list_pay.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "home_list_pay@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "home_list_pay@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "home_list_ticket.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "home_list_ticket@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "home_list_ticket@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "home_list_kuang.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "home_list_kuang@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "home_list_kuang@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "Live_bottom_rightArrow.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Live_bottom_rightArrow@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Live_bottom_rightArrow@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "live_setting_live_sticker.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "live_setting_live_sticker@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "live_setting_live_sticker@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
......@@ -148,5 +148,13 @@
/// 提供一个将主播列表的其他模块(如:新星主播模块)生成FUSBaoFangAnchorModel模型插入列表中的方法
+(NSMutableArray<FUSBaoFangAnchorModel *> *)fus_sortInsertModelWithDataDict:(NSDictionary *)dataDict;
/// 首页列表左上角展示的房间类型(接口字段:type)
/// 约定:0=不展示,3=宝石房,5=集票房
/// 展示规则:3 显示 home_list_pay + 底色框 home_list_kuang;5 显示 home_list_ticket + 底色框 home_list_kuang
@property (nonatomic, assign) NSInteger type;
/// 房间类型辅助数据(接口字段:typedata)
/// 说明:当 type 需要补充数值信息时使用(例如:票数“剩xx张”)
@property (nonatomic, copy) NSString *typedata;
@end
......@@ -15,6 +15,11 @@
@property (nonatomic, strong) UIImageView *bgImageView; //用户图
@property (nonatomic, strong) UIView *roomTypeTagView;
@property (nonatomic, strong) UIImageView *roomTypeBgImageView;
@property (nonatomic, strong) UIImageView *roomTypeIconImageView;
@property (nonatomic, strong) UILabel *roomTypeTextLabel;
/// 人气值
@property (nonatomic, strong) UIButton *hotNumBtn;
/// 位置
......@@ -59,6 +64,48 @@
make.edges.equalTo(self.contentView);
}];
self.roomTypeTagView = [[UIView alloc] init];
self.roomTypeTagView.backgroundColor = UIColor.clearColor;
[self.contentView addSubview:self.roomTypeTagView];
[self.roomTypeTagView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.inset(6);
make.size.mas_equalTo(CGSizeMake(52.5, 22));
}];
self.roomTypeBgImageView = [[UIImageView alloc] init];
self.roomTypeBgImageView.contentMode = UIViewContentModeScaleToFill;
UIImage *bgImage = [FUSShowRoomCenterBunble imageNamed:@"home_list_kuang"];
if (bgImage) {
CGFloat leftRightInset = MAX(0, floor((bgImage.size.width - 1) / 2.0));
CGFloat topBottomInset = MAX(0, floor((bgImage.size.height - 1) / 2.0));
bgImage = [bgImage resizableImageWithCapInsets:UIEdgeInsetsMake(topBottomInset, leftRightInset, topBottomInset, leftRightInset)
resizingMode:UIImageResizingModeStretch];
}
self.roomTypeBgImageView.image = bgImage;
[self.roomTypeTagView addSubview:self.roomTypeBgImageView];
[self.roomTypeBgImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.roomTypeTagView);
}];
self.roomTypeIconImageView = [[UIImageView alloc] init];
self.roomTypeIconImageView.contentMode = UIViewContentModeScaleAspectFit;
[self.roomTypeTagView addSubview:self.roomTypeIconImageView];
[self.roomTypeIconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.offset(3);
make.centerY.equalTo(self.roomTypeTagView);
make.size.mas_equalTo(CGSizeMake(8.5, 10.5));
}];
self.roomTypeTextLabel = [[UILabel alloc] init];
self.roomTypeTextLabel.font = [UIFont fus_themeMediumFont:10];
self.roomTypeTextLabel.textColor = [UIColor fus_textColorVeryLight];
[self.roomTypeTagView addSubview:self.roomTypeTextLabel];
[self.roomTypeTextLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.roomTypeIconImageView.mas_right).offset(4);
make.right.offset(-3);
make.centerY.equalTo(self.roomTypeTagView);
}];
self.bottomAlphaBgView = [[UIImageView alloc] initWithImage:[FUSShowRoomCenterBunble imageNamed:@"baofang_video_list_bottom_mask"]];
[self.bgImageView addSubview:self.bottomAlphaBgView];
[self.bottomAlphaBgView mas_makeConstraints:^(MASConstraintMaker *make) {
......@@ -123,6 +170,7 @@
self.hotNumBtn.hidden = YES;
self.locationBtn.hidden = YES;
self.roomTypeTagView.hidden = YES;
}
- (UIView *)playerSuperView {
......@@ -178,6 +226,7 @@
}
if (model.fus_itemType == 0) {
[self fus_updateRoomTypeTagWithModel:model];
self.nickNameLabel.hidden = NO;
self.nickNameLabel.text = model.nickname;
self.bottomAlphaBgView.hidden = NO;
......@@ -234,6 +283,7 @@
}else if (model.fus_itemType == 1 || model.fus_itemType == 2 || model.fus_itemType == 3){
// 不是正常主播的卡片
self.roomTypeTagView.hidden = YES;
self.nickNameLabel.hidden = YES;
self.locationBtn.hidden = YES;
self.hotNumBtn.hidden = YES;
......@@ -262,6 +312,38 @@
}
- (void)fus_updateRoomTypeTagWithModel:(FUSBaoFangAnchorModel *)model {
self.roomTypeTagView.hidden = NO;
UIImage *icon = nil;
NSString *text = model.typedata;
if (model.type == 3) {
icon = [FUSShowRoomCenterBunble imageNamed:@"home_list_pay"];
[self.roomTypeIconImageView mas_updateConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(8.5, 10.5));
}];
[self.roomTypeTextLabel mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.roomTypeIconImageView.mas_right).offset(4);
}];
} else if (model.type == 5) {
icon = [FUSShowRoomCenterBunble imageNamed:@"home_list_ticket"];
[self.roomTypeIconImageView mas_updateConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(18.5, 10));
}];
[self.roomTypeTextLabel mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.roomTypeIconImageView.mas_right).offset(1);
}];
}else
{
self.roomTypeTagView.hidden = YES;
}
self.roomTypeIconImageView.image = icon;
self.roomTypeTextLabel.text = text;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
......
......@@ -916,6 +916,18 @@ NS_ASSUME_NONNULL_BEGIN
succeed:(void (^)(NSDictionary *dataDict, int code))succeed
failure:(void (^)(NSString *, NSInteger))failure;
/// 更新直播主题标题文案(主播主题)
/// @param roomId 房间id
/// @param channelId 直播场次ID
/// @param content 主题标题文案
/// @param succeed 成功回调
/// @param failure 失败回调
+ (void)fus_updateLiveThemeTitleWithRoomId:(NSString *)roomId
channelId:(NSString *)channelId
content:(NSString *)content
succeed:(void (^)(NSDictionary *dataDict, int code))succeed
failure:(void (^)(NSString *, NSInteger))failure;
/// 开始直播前准备
/// @param succeed 成功回调
......
......@@ -3007,6 +3007,37 @@
if (failure) failure(dataDict[@"msg"],code);
}];
}
/// 更新直播主题标题文案(主播主题)
/// @param roomId 房间id
/// @param channelId 直播场次ID
/// @param content 主题标题文案
/// @param succeed 成功回调
/// @param failure 失败回调
+ (void)fus_updateLiveThemeTitleWithRoomId:(NSString *)roomId
channelId:(NSString *)channelId
content:(NSString *)content
succeed:(void (^)(NSDictionary *dataDict, int code))succeed
failure:(void (^)(NSString *, NSInteger))failure {
NSString *uid = FUSCacheDataShare.shareStore.userDetailInfo.uid;
if ([NSString isNull:uid]
|| [NSString isNull:roomId]
|| [NSString isNull:channelId]) {
return;
}
NSDictionary *params = @{
@"uid": uid,
@"roomId": roomId,
@"channelId": channelId,
@"content": (content ?: @"")
};
[FUSHttpHelper postRequestBinaryWithUrl:FUSShowRoomURLs.fus_URL_Live_Theme_Title_Update params:params success:succeed failure:^(NSDictionary * _Nullable dataDict, int code) {
if (failure) failure(dataDict[@"msg"], code);
}];
}
/// 获取用户直播评分历史列表
+ (void)fus_requestUserliveAssessHistoryGetListWithDateStr:(NSString *)dateStr succeed:(void (^)(FUSUserLiveAssessHistoryModel * _Nonnull))succeed failure:(void (^)(NSString * _Nonnull, NSInteger))failure{
NSDictionary *parm = @{@"dateStr": dateStr};
......
......@@ -15,9 +15,10 @@ typedef enum : NSInteger{
FUSFaceBeautychangeCamera,
FUSFaceBeautyTurnOnLight,
FUSLiveCameraMirror,
FUSLiveSetTheme,
FUSLiveSetSticker,
FUSLiveEditQuickChat,
FUSLiveGiftInteract
FUSLiveGiftInteract,
FUSLiveRoomTheme
} FUSFaceBeautyType;
@interface FUSBottomOptionalItemView : UIView
......
......@@ -88,24 +88,27 @@
[NSString fus_localString:@"反转镜头"],
[NSString fus_localString:@"闪光关闭"],
[NSString fus_localString:@"镜像"],
[NSString fus_localString:@"直播主题"],
[NSString fus_localString:@"礼物互动"]]
[NSString fus_localString:@"贴纸"],
[NSString fus_localString:@"礼物互动"],
[NSString fus_localString:@"直播主题"]]
withImages:@[@"live_icon_cameraSetting",
@"live_setting_quality",
@"live_setting_close_mic",
@"live_icon_changeCamera",
@"live_icon_turnOffLine",
@"live_setting_video_mirror",
@"live_setting_live_theme",
@"live_setting_live_giftInteract"]
@"live_setting_live_sticker",
@"live_setting_live_giftInteract",
@"live_setting_live_theme"]
withTypes:@[@(FUSFaceBeautySetting),
@(FUSLiveQuality),
@(FUSLiveCameraMic),
@(FUSFaceBeautychangeCamera),
@(FUSFaceBeautyTurnOnLight),
@(FUSLiveCameraMirror),
@(FUSLiveSetTheme),
@(FUSLiveGiftInteract)]
@(FUSLiveSetSticker),
@(FUSLiveGiftInteract),
@(FUSLiveRoomTheme)]
clickItem:click];
}else if(type == FUSShowFlashLineAndCamera){
......
......@@ -49,6 +49,12 @@ NS_ASSUME_NONNULL_BEGIN
/// - containerView: 建议承载弹窗的父视图
- (void)fus_bottomSubView:(FUSLiveBottomToolSubView *)bottomSubView didClickShowTimeOnView:(UIView *)containerView;
/// 点击“直播主题”(交由外部决定如何展示弹窗/调用接口)
/// - Parameters:
/// - bottomSubView: 当前工具子视图
/// - containerView: 建议承载弹窗的父视图
- (void)fus_bottomSubView:(FUSLiveBottomToolSubView *)bottomSubView didClickLiveRoomThemeOnView:(UIView *)containerView;
/// 点击“礼物互动设置”(由上层页面决定如何跳转)
- (void)fus_bottomSubViewDidClickGiftInteractSetting:(FUSLiveBottomToolSubView *)bottomSubView;
......
......@@ -13,6 +13,7 @@
#import "FUSLiveShareView.h"
#import "FUSScreenShotShareView.h"
#import "FUSBottomOptionalView.h"
#import "FUSLiveRoomThemePopView.h"
#import "FUSLiveAnchorSettingAlertView.h"
......@@ -431,7 +432,7 @@
[weakSelf.delegate fus_bottomSubViewDidBeautySetting:weakSelf beautyType:FUSLiveChatToolBeautyTypeQuality];
}
break;
case FUSLiveSetTheme:
case FUSLiveSetSticker:
[weakOptionalView fus_dismissOptionalView];
if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(fus_bottomSubViewDidBeautySetting:beautyType:)]) {
[weakSelf.delegate fus_bottomSubViewDidBeautySetting:weakSelf beautyType:FUSLiveChatToolBeautyTypeSetLiveTheme];
......@@ -449,6 +450,12 @@
[weakSelf.delegate fus_bottomSubViewDidClickGiftInteractSetting:weakSelf];
}
break;
case FUSLiveRoomTheme:
[weakOptionalView fus_dismissOptionalView];
if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(fus_bottomSubView:didClickLiveRoomThemeOnView:)]) {
[weakSelf.delegate fus_bottomSubView:weakSelf didClickLiveRoomThemeOnView:weakSelf.bgView];
}
return;
}
}];
}
......
......@@ -117,6 +117,12 @@ typedef NS_ENUM(NSUInteger, FUSLiveChatToolBeautyType) { //美颜工具按钮
/// - containerView: 建议承载弹窗的父视图
- (void)fus_bottomToolView:(FUSLiveBottomToolView *)bottomToolView didClickShowTimeOnView:(UIView *)containerView;
/// 点击“直播主题”(交由外部决定如何展示弹窗/调用接口)
/// - Parameters:
/// - bottomToolView: 当前工具栏
/// - containerView: 建议承载弹窗的父视图
- (void)fus_bottomToolView:(FUSLiveBottomToolView *)bottomToolView didClickLiveRoomThemeOnView:(UIView *)containerView;
/// 点击“礼物互动设置”(由上层页面决定如何跳转)
- (void)fus_bottomToolViewDidClickGiftInteractSetting:(FUSLiveBottomToolView *)bottomToolView;
......
......@@ -1345,6 +1345,12 @@
}
}
- (void)fus_bottomSubView:(FUSLiveBottomToolSubView *)bottomSubView didClickLiveRoomThemeOnView:(UIView *)containerView {
if (self.delegate && [self.delegate respondsToSelector:@selector(fus_bottomToolView:didClickLiveRoomThemeOnView:)]) {
[self.delegate fus_bottomToolView:self didClickLiveRoomThemeOnView:containerView];
}
}
- (void)fus_bottomSubViewDidBeautySetting:(FUSLiveBottomToolSubView *)bottomToolView beautyType:(FUSLiveChatToolBeautyType)type{
if (_delegate && [_delegate respondsToSelector:@selector(fus_bottomToolViewDidBeautySetting:beautyType:)]) {
......
......@@ -28,6 +28,7 @@
#import "FUSLiveShowTimePopView.h"
#import "FUSLiveShowTimeCollectFrostedView.h"
#import "FUSLiveRoomThemePopView.h"
#import "FUSLiveFunctionLayerView.h"
#import <FUSFoundation/FUSFoundation-Swift.h>
......@@ -491,6 +492,39 @@
};
}
- (void)fus_bottomToolView:(FUSLiveBottomToolView *)bottomToolView didClickLiveRoomThemeOnView:(UIView *)containerView {
UIView *popContainer = (containerView ?: [UIViewController fus_topViewController].view);
__weak typeof(self) weakSelf = self;
FUSLiveRoomThemePopView *popView = [FUSLiveRoomThemePopView fus_showOnView:popContainer defaultText:FUSLiveHelper.shareInstance.roomInfoModel.introduce];
popView.confirmHandler = ^(NSString * _Nonnull content) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
FUSRoomInfoModel *roomInfoModel = FUSLiveHelper.shareInstance.roomInfoModel;
NSString *roomId = roomInfoModel.roomId;
NSString *channelId = roomInfoModel.channelId;
if ([NSString isNull:roomId] || [NSString isNull:channelId]) {
[FUSDialogView fus_showDialog:[NSString fus_localString:@"当前房间信息异常"]];
return;
}
[FUSLoadingView fus_showProgressViewWithMessage:@""];
[FUSLiveHttpHelper fus_updateLiveThemeTitleWithRoomId:roomId channelId:channelId content:content succeed:^(NSDictionary *dataDict, int code) {
dispatch_async(dispatch_get_main_queue(), ^{
[FUSLoadingView fus_dismissProgressView];
// 这里只提交更新请求;主题展示刷新由 ROOM_CID_LIVE_TOPIC_TITLE_DID_CHANGED 的 socket 推送驱动
});
} failure:^(NSString *msg, NSInteger code) {
dispatch_async(dispatch_get_main_queue(), ^{
[FUSLoadingView fus_dismissProgressView];
[FUSDialogView fus_showDialog:([NSString isNull:msg] ? [NSString fus_localString:@"设置失败"] : msg)];
});
}];
};
}
- (void)fus_bottomToolViewDidClickGiftInteractSetting:(FUSLiveBottomToolView *)bottomToolView {
[self fus_chatInputViewDidClickGiftInteractSetting:nil];
}
......
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef void(^FUSLiveRoomThemeConfirmHandler)(NSString *content);
/// 直播主题弹窗(风格对齐“限时表演”弹窗)
@interface FUSLiveRoomThemePopView : UIView
/// 在指定容器上展示弹窗
/// - Parameters:
/// - onView: 承载弹窗的父视图
/// - defaultText: 默认展示的主题文案(可为空)
+ (instancetype)fus_showOnView:(UIView *)onView defaultText:(nullable NSString *)defaultText;
/// 点击“确定”回调(由外部决定是否发起网络请求/刷新 UI)
@property (nonatomic, copy, nullable) FUSLiveRoomThemeConfirmHandler confirmHandler;
@end
NS_ASSUME_NONNULL_END
#import "FUSLiveRoomThemePopView.h"
#import <FUSCommon/FUSCommon.h>
#import <FUSFoundation/FUSFoundation.h>
@interface FUSLiveRoomThemePopView ()
/// 背景遮罩按钮(点击空白处关闭)
@property (nonatomic, strong) UIButton *bgBtn;
/// 弹窗内容容器(从底部滑出)
@property (nonatomic, strong) UIView *contentView;
/// 顶部拖拽灰色横杠
@property (nonatomic, strong) UIView *grabberView;
/// 标题
@property (nonatomic, strong) UILabel *titleLabel;
/// 主题输入背景(灰底圆角)
@property (nonatomic, strong) UIView *themeBgView;
/// 主题输入框(展示文案;点击区域用 Alert 输入,避免键盘遮挡)
@property (nonatomic, strong) UITextField *themeTextField;
/// 确认按钮(提交“主播主题”文案)
@property (nonatomic, strong) UIButton *confirmBtn;
@end
@implementation FUSLiveRoomThemePopView
+ (instancetype)fus_showOnView:(UIView *)onView defaultText:(nullable NSString *)defaultText {
FUSLiveRoomThemePopView *view = [[FUSLiveRoomThemePopView alloc] initWithFrame:onView.bounds];
view.themeTextField.text = defaultText ?: @"";
[onView addSubview:view];
[view fus_show];
return view;
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.bgBtn = [UIButton buttonWithType:UIButtonTypeCustom];
self.bgBtn.frame = self.bounds;
self.bgBtn.backgroundColor = [UIColor colorWithWhite:0 alpha:0.35];
[self.bgBtn addTarget:self action:@selector(fus_dismiss) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.bgBtn];
CGFloat safeBottom = UIView.fus_SafeBottom;
CGFloat contentH = 180 + safeBottom;
self.contentView = [[UIView alloc] initWithFrame:CGRectMake(0, UIView.fus_screenH, UIView.fus_screenW, contentH)];
self.contentView.backgroundColor = UIColor.whiteColor;
[self.contentView addRoundedCorners:UIRectCornerTopLeft|UIRectCornerTopRight withRadii:CGSizeMake(16, 16)];
[self addSubview:self.contentView];
self.grabberView = [[UIView alloc] initWithFrame:CGRectMake(0, 8, 40, 4)];
self.grabberView.centerX = self.contentView.width / 2.0;
self.grabberView.backgroundColor = [UIColor colorWithHex:@"#DADDE1"];
self.grabberView.layer.cornerRadius = 2;
self.grabberView.layer.masksToBounds = YES;
[self.contentView addSubview:self.grabberView];
self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, self.grabberView.bottom + 10, self.contentView.width, 22)];
self.titleLabel.textAlignment = NSTextAlignmentCenter;
self.titleLabel.font = [UIFont fus_themeBoldFont:16];
self.titleLabel.textColor = [UIColor colorWithHex:@"#333333"];
self.titleLabel.text = [NSString fus_localString:@"设置主播主题"];
[self.contentView addSubview:self.titleLabel];
self.themeBgView = [[UIView alloc] initWithFrame:CGRectMake(25, self.titleLabel.bottom + 16, self.contentView.width - 50, 40)];
self.themeBgView.backgroundColor = [UIColor colorWithHex:@"#F2F3F5"];
self.themeBgView.layer.cornerRadius = 8;
self.themeBgView.layer.masksToBounds = YES;
[self.contentView addSubview:self.themeBgView];
self.themeTextField = [[UITextField alloc] initWithFrame:CGRectMake(12, 0, self.themeBgView.width - 24, self.themeBgView.height)];
self.themeTextField.font = [UIFont fus_themeFont:12];
self.themeTextField.textColor = [UIColor colorWithHex:@"#666666"];
self.themeTextField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:[NSString fus_localString:@"请输入直播主题"]
attributes:@{NSForegroundColorAttributeName:[UIColor colorWithHex:@"#9AA0A6"]}];
self.themeTextField.userInteractionEnabled = NO;
[self.themeBgView addSubview:self.themeTextField];
UITapGestureRecognizer *tapTheme = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(fus_onTapTheme)];
[self.themeBgView addGestureRecognizer:tapTheme];
CGFloat btnH = 44;
self.confirmBtn = [UIButton buttonWithType:UIButtonTypeCustom];
self.confirmBtn.frame = CGRectMake(24, self.contentView.height - safeBottom - 14 - btnH, self.contentView.width - 48, btnH);
self.confirmBtn.layer.cornerRadius = btnH / 2.0;
self.confirmBtn.layer.masksToBounds = YES;
self.confirmBtn.backgroundColor = [UIColor fus_appMainColor];
[self.confirmBtn setTitle:[NSString fus_localString:@"确定"] forState:UIControlStateNormal];
[self.confirmBtn setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
self.confirmBtn.titleLabel.font = [UIFont fus_themeBoldFont:15];
[self.confirmBtn addTarget:self action:@selector(fus_onClickConfirm) forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:self.confirmBtn];
}
return self;
}
- (void)fus_show {
[UIView animateWithDuration:0.3 animations:^{
self.contentView.bottom = UIView.fus_screenH;
}];
}
/// 隐藏弹窗并移除
- (void)fus_dismiss {
[UIView animateWithDuration:0.25 animations:^{
self.bgBtn.alpha = 0;
self.contentView.top = UIView.fus_screenH;
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
/// 点击主题输入区域:弹出系统输入框填写主题
- (void)fus_onTapTheme {
UIViewController *topVC = [UIViewController fus_topViewController];
if (!topVC) {
return;
}
UIAlertController *alert = [UIAlertController alertControllerWithTitle:[NSString fus_localString:@"设置主播主题"]
message:nil
preferredStyle:UIAlertControllerStyleAlert];
__weak typeof(self) weakSelf = self;
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.text = weakSelf.themeTextField.text ?: @"";
textField.placeholder = [NSString fus_localString:@"请输入直播主题"];
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
textField.returnKeyType = UIReturnKeyDone;
}];
[alert addAction:[UIAlertAction actionWithTitle:[NSString fus_localString:@"取消"]
style:UIAlertActionStyleCancel
handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:[NSString fus_localString:@"确定"]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
NSString *text = alert.textFields.firstObject.text ?: @"";
weakSelf.themeTextField.text = text;
}]];
[topVC presentViewController:alert animated:YES completion:nil];
}
/// 点击确定:提交“主播主题”文案并刷新底部主题展示
- (void)fus_onClickConfirm {
NSString *content = (self.themeTextField.text ?: @"");
content = [content stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if (content.length <= 0) {
[FUSDialogView fus_showDialog:[NSString fus_localString:@"请输入直播主题"]];
return;
}
if (self.confirmHandler) {
self.confirmHandler(content);
}
[self fus_dismiss];
}
@end
......@@ -181,6 +181,9 @@ typedef NS_ENUM(NSInteger, FUSFunctionMode) {
*/
- (void)fus_refreshLiveTheme;
/// 重新刷新底部“主播主题”窗口展示
- (void)fus_refreshLiveTopicWindow;
/**
根据 Model 设置 LiveFunctionView
......
......@@ -67,6 +67,7 @@
#import "FUSLiveTreasureBoxListIconView.h"
#import "FUSLiveTreasureBoxGrabView.h"
#import "FUSLiveThemeView.h"
#import "FUSLiveTopicWindowView.h"
#import "FUSHttpManager.h"
#import "FUSLiveroomActivityInfoModel.h"
......@@ -358,6 +359,8 @@ BDAlphaPlayerMetalViewDelegate
@property (nonatomic, strong) FUSPatAudiencePromptAlertView *patAudienceProptAlertView;
/// 直播主题
@property (nonatomic, strong) FUSLiveThemeView *liveThemeView;
/// 直播主题底部窗口(进房即展示,固定在 FunctionLayerView 正上方靠左)
@property (nonatomic, strong) FUSLiveTopicWindowView *liveTopicWindowView;
/// 连续点赞次数
@property (nonatomic, assign) NSInteger clickSendLikeCount;
......@@ -962,6 +965,8 @@ BDAlphaPlayerMetalViewDelegate
self.pushLinkMicroView.y = self.pusherChatTableView.y - (self.pushLinkMicroView.height + 10);
// 为了不让快捷发言出来的时候直接把上麦按钮顶到头部栏上,设定至少的y值为头部栏之下
self.linkMicroView.y = self.chatViewBgView.y - (self.linkMicroView.height + 10) < CGRectGetMaxY(self.headView.frame) ? CGRectGetMaxY(self.headView.frame) : self.chatViewBgView.y - (self.linkMicroView.height + 10);
[self fus_layoutLiveTopicWindow];
}];
}
......@@ -2639,6 +2644,47 @@ BDAlphaPlayerMetalViewDelegate
self.liveThemeView.themeModel = FUSLiveHelper.shareInstance.roomInfoModel.theme;
}
/**
刷新直播主题底部窗口(新需求:展示主播主题文案,支持展开/收起与 30 秒自动收起)
*/
- (void)fus_refreshLiveTopicWindow {
FUSRoomInfoModel *roomInfoModel = FUSLiveHelper.shareInstance.roomInfoModel;
[self fus_setupLiveTopicWindowIfNeeded];
self.liveTopicWindowView.hidden = NO;
[self.liveTopicWindowView fus_updateTopicText:roomInfoModel.introduce restartTimer:YES];
[self fus_reloadUIWithKeyboardSetPart];
}
/**
初始化直播主题底部窗口,并接入展开/收起回调
*/
- (void)fus_setupLiveTopicWindowIfNeeded {
if (self.liveTopicWindowView) {
return;
}
self.liveTopicWindowView = [[FUSLiveTopicWindowView alloc] initWithFrame:CGRectMake(8, self.bottomToolView.y - 40, 180, 34)];
self.liveTopicWindowView.hidden = YES;
__weak typeof(self) weakSelf = self;
self.liveTopicWindowView.expandedStateDidChangeHandler = ^(BOOL isExpanded) {
[weakSelf fus_reloadUIWithKeyboardSetPart];
};
[[self fus_viewWithLayer:FUSLiveFunctionLayerFunctionButtons] addSubview:self.liveTopicWindowView];
}
/**
布局直播主题底部窗口:固定在底部按钮栏正上方靠左
*/
- (void)fus_layoutLiveTopicWindow {
if (!self.liveTopicWindowView || self.liveTopicWindowView.isHidden) {
return;
}
CGFloat x = 8;
CGFloat maxWidth = self.width - 16;
CGSize size = [self.liveTopicWindowView fus_sizeThatFitsMaxWidth:maxWidth];
CGFloat y = self.bottomToolView.y - 6 - size.height;
self.liveTopicWindowView.frame = CGRectMake(x, y, size.width, size.height);
}
#pragma mark - Notification
/**
......@@ -2710,6 +2756,9 @@ BDAlphaPlayerMetalViewDelegate
// 20202:更新本场直播主题内容socket
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(recieveLiveThemeDidChangedNotification:) name:STR(ROOM_CID_LiveThemeDidChanged) object:nil];
// 12004:更新“主播主题标题文案”socket(提交接口后,实际展示以此推送为准)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(recieveLiveTopicTitleDidChangedNotification:) name:STR(ROOM_CID_LIVE_TOPIC_TITLE_DID_CHANGED) object:nil];
// 被设置为场控通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(recieveSetAsControllerNotification:) name:STR(ROOM_CID_SET_CONTROL_NOTI) object:nil];
// 被取消场控通知
......@@ -4429,6 +4478,37 @@ BDAlphaPlayerMetalViewDelegate
[self fus_refreshLiveTheme];
}
/**
12004:主播主题标题文案变化推送
*/
- (void)recieveLiveTopicTitleDidChangedNotification:(NSNotification *)notification
{
FUSSocketMessageModel *messageModel = notification.object;
if (!messageModel) {
return;
}
NSDictionary *dict = [messageModel fus_getJsonDict];
NSString *roomId = [dict[@"roomId"] description];
if ([NSString isNull:roomId] || ![FUSLiveHelper.shareInstance.roomInfoModel.roomId isEqualToString:roomId]) {
return;
}
NSString *content = [dict[@"content"] description];
if ([NSString isNull:content]) {
content = @"";
} else {
// 后端 content 可能是 URL 编码(例如 %E6%...),这里做一次解码再展示
NSString *decodedContent = [content stringByRemovingPercentEncoding];
if (![NSString isNull:decodedContent]) {
content = decodedContent;
}
}
FUSLiveHelper.shareInstance.roomInfoModel.introduce = content;
[self fus_refreshLiveTopicWindow];
}
#pragma mark - Action
- (void)fus_clearHalfWebView{
[self.halfWebManager fus_removeAllWebView];
......@@ -6046,6 +6126,7 @@ BDAlphaPlayerMetalViewDelegate
// 重载活动的页面
[self fus_reloadRealtimeActivityWebView];
[self fus_refreshLiveTheme];
[self fus_refreshLiveTopicWindow];
if (![model.roomId isEqualToString:[[FUSCacheDataShare shareStore]userDetailInfo].uid] &&
model.liked &&
......@@ -6129,6 +6210,9 @@ BDAlphaPlayerMetalViewDelegate
[self.liveThemeView removeFromSuperview];
self.liveThemeView = nil;
[self.liveTopicWindowView removeFromSuperview];
self.liveTopicWindowView = nil;
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(fus_initFastInputView) object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self];
......
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface FUSLiveTopicWindowView : UIView
/// 展开/收起状态变化回调(用于外部联动布局刷新等)
@property (nonatomic, copy, nullable) void(^expandedStateDidChangeHandler)(BOOL isExpanded);
/// 当前是否为展开态(展开态会显示主题文案)
@property (nonatomic, assign, readonly) BOOL isExpanded;
/// 当前主题文案(用于展示与变化判断)
@property (nonatomic, copy, readonly) NSString *topicText;
/// 更新主题文案;当文案变化时默认自动展开,并可选择重置 30 秒自动收起计时
- (void)fus_updateTopicText:(NSString *)topicText restartTimer:(BOOL)restartTimer;
/// 手动设置展开/收起;展开时可选择是否重置 30 秒自动收起计时
- (void)fus_setExpanded:(BOOL)expanded restartTimer:(BOOL)restartTimer;
/// 计算在最大宽度约束下的最佳尺寸(用于布局在底部按钮栏上方靠左)
- (CGSize)fus_sizeThatFitsMaxWidth:(CGFloat)maxWidth;
@end
NS_ASSUME_NONNULL_END
#import "FUSLiveTopicWindowView.h"
#import "FUSShowRoomCenterBunble.h"
#import <dispatch/dispatch.h>
static const CGFloat kFUSLiveTopicWindowHeight = 34.0;
static const CGFloat kFUSLiveTopicWindowLeftPadding = 10.0;
static const CGFloat kFUSLiveTopicWindowRightPadding = 8.0;
static const CGFloat kFUSLiveTopicWindowIconSize = 20.0;
static const CGFloat kFUSLiveTopicWindowArrowWidth = 12.5;
static const CGFloat kFUSLiveTopicWindowArrowHeight = 16.5;
static const CGFloat kFUSLiveTopicWindowInnerSpacing = 8.0;
@interface FUSLiveTopicWindowView ()
@property (nonatomic, strong) UIView *bgView;
@property (nonatomic, strong) UIImageView *topicIconView;
@property (nonatomic, strong) UILabel *topicLabel;
@property (nonatomic, strong) UIButton *arrowButton;
@property (nonatomic, strong) dispatch_source_t autoCollapseTimer;
@property (nonatomic, assign) BOOL isExpanded;
@property (nonatomic, copy) NSString *topicText;
@end
@implementation FUSLiveTopicWindowView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.clipsToBounds = NO;
[self fus_setupUI];
[self fus_setExpanded:YES restartTimer:NO];
}
return self;
}
- (void)dealloc {
[self fus_cancelAutoCollapseTimer];
}
- (void)layoutSubviews {
[super layoutSubviews];
self.arrowButton.frame = CGRectMake(self.bounds.size.width - kFUSLiveTopicWindowRightPadding - kFUSLiveTopicWindowArrowWidth,
(self.bounds.size.height - kFUSLiveTopicWindowArrowHeight) / 2.0,
kFUSLiveTopicWindowArrowWidth,
kFUSLiveTopicWindowArrowHeight);
CGFloat bgWidth = MAX(0, CGRectGetMinX(self.arrowButton.frame));
self.bgView.frame = CGRectMake(0, 0, bgWidth, self.bounds.size.height);
self.bgView.layer.cornerRadius = 12;
CGFloat x = kFUSLiveTopicWindowLeftPadding;
self.topicIconView.frame = CGRectMake(x, (self.bounds.size.height - kFUSLiveTopicWindowIconSize) / 2.0, kFUSLiveTopicWindowIconSize, kFUSLiveTopicWindowIconSize);
x = CGRectGetMaxX(self.topicIconView.frame) + kFUSLiveTopicWindowInnerSpacing;
CGFloat maxLabelWidth = MAX(0, CGRectGetMinX(self.arrowButton.frame) - x - kFUSLiveTopicWindowInnerSpacing);
self.topicLabel.frame = CGRectMake(x, 0, maxLabelWidth, self.bounds.size.height);
[self bringSubviewToFront:self.arrowButton];
}
- (CGSize)sizeThatFits:(CGSize)size {
return [self fus_sizeThatFitsMaxWidth:size.width];
}
- (CGSize)fus_sizeThatFitsMaxWidth:(CGFloat)maxWidth {
CGFloat availableMaxWidth = (maxWidth > 0) ? maxWidth : CGFLOAT_MAX;
CGFloat width = 0;
width += kFUSLiveTopicWindowLeftPadding;
width += kFUSLiveTopicWindowIconSize;
width += kFUSLiveTopicWindowInnerSpacing;
if (self.isExpanded) {
CGFloat remainingLabelWidth = availableMaxWidth - (kFUSLiveTopicWindowLeftPadding + kFUSLiveTopicWindowIconSize + kFUSLiveTopicWindowInnerSpacing + kFUSLiveTopicWindowInnerSpacing + kFUSLiveTopicWindowArrowWidth + kFUSLiveTopicWindowRightPadding);
remainingLabelWidth = MAX(0, remainingLabelWidth);
CGSize textSize = [self.topicText ?: @"" boundingRectWithSize:CGSizeMake(remainingLabelWidth, kFUSLiveTopicWindowHeight)
options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine
attributes:@{NSFontAttributeName:self.topicLabel.font}
context:nil].size;
CGFloat labelWidth = MIN(ceil(textSize.width), remainingLabelWidth);
width += labelWidth;
width += kFUSLiveTopicWindowInnerSpacing;
}
width += kFUSLiveTopicWindowArrowWidth;
width += kFUSLiveTopicWindowRightPadding;
width = MIN(width, availableMaxWidth);
width = MAX(width, kFUSLiveTopicWindowLeftPadding + kFUSLiveTopicWindowIconSize + kFUSLiveTopicWindowInnerSpacing + kFUSLiveTopicWindowArrowWidth + kFUSLiveTopicWindowRightPadding);
return CGSizeMake(width, kFUSLiveTopicWindowHeight);
}
- (void)fus_updateTopicText:(NSString *)topicText restartTimer:(BOOL)restartTimer {
NSString *safeText = topicText ?: @"";
BOOL changed = ![self.topicText ?: @"" isEqualToString:safeText];
self.topicText = safeText;
self.topicLabel.text = safeText;
if (changed) {
[self fus_setExpanded:YES restartTimer:restartTimer];
} else if (restartTimer && self.isExpanded) {
[self fus_restartAutoCollapseTimer];
}
[self setNeedsLayout];
}
- (void)fus_setExpanded:(BOOL)expanded restartTimer:(BOOL)restartTimer {
if (self.isExpanded == expanded) {
if (restartTimer && expanded) {
[self fus_restartAutoCollapseTimer];
}
return;
}
self.isExpanded = expanded;
self.topicLabel.hidden = !expanded;
// self.bgView.alpha = expanded ? 1.0 : 0.9;
UIImage *arrowImage = [FUSShowRoomCenterBunble imageNamed:(expanded ? @"Live_bottom_leftArrow" : @"Live_bottom_rightArrow")];
[self.arrowButton setBackgroundImage:arrowImage forState:UIControlStateNormal];
if (expanded) {
if (restartTimer) {
[self fus_restartAutoCollapseTimer];
}
} else {
[self fus_cancelAutoCollapseTimer];
}
if (self.expandedStateDidChangeHandler) {
self.expandedStateDidChangeHandler(expanded);
}
[self setNeedsLayout];
}
- (void)fus_setupUI {
self.backgroundColor = UIColor.clearColor;
self.bgView = [[UIView alloc] initWithFrame:CGRectZero];
self.bgView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.6];
self.bgView.layer.masksToBounds = YES;
[self addSubview:self.bgView];
self.topicIconView = [[UIImageView alloc] initWithFrame:CGRectZero];
self.topicIconView.image = [FUSShowRoomCenterBunble imageNamed:@"Live_bottom_liveTopic"];
self.topicIconView.contentMode = UIViewContentModeScaleAspectFit;
[self.bgView addSubview:self.topicIconView];
self.topicLabel = [[UILabel alloc] initWithFrame:CGRectZero];
self.topicLabel.textColor = [[UIColor blackColor] colorWithAlphaComponent:0.9];
self.topicLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium];
self.topicLabel.numberOfLines = 1;
self.topicLabel.lineBreakMode = NSLineBreakByTruncatingTail;
[self.bgView addSubview:self.topicLabel];
self.arrowButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.arrowButton setBackgroundImage:[FUSShowRoomCenterBunble imageNamed:@"Live_bottom_leftArrow"] forState:UIControlStateNormal];
[self.arrowButton addTarget:self action:@selector(fus_onClickArrow) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.arrowButton];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(fus_onTap)];
[self addGestureRecognizer:tap];
}
- (void)fus_onTap {
if (!self.isExpanded) {
[self fus_setExpanded:YES restartTimer:YES];
}
}
- (void)fus_onClickArrow {
if (self.isExpanded) {
[self fus_setExpanded:NO restartTimer:NO];
return;
}
[self fus_setExpanded:YES restartTimer:YES];
}
- (void)fus_restartAutoCollapseTimer {
[self fus_cancelAutoCollapseTimer];
__weak typeof(self) weakSelf = self;
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(30 * NSEC_PER_SEC)), DISPATCH_TIME_FOREVER, (int64_t)(0.2 * NSEC_PER_SEC));
dispatch_source_set_event_handler(timer, ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
[strongSelf fus_onAutoCollapse];
});
dispatch_resume(timer);
self.autoCollapseTimer = timer;
}
- (void)fus_onAutoCollapse {
if (!self.isExpanded) {
return;
}
[self fus_setExpanded:NO restartTimer:NO];
}
- (void)fus_cancelAutoCollapseTimer {
if (!self.autoCollapseTimer) {
return;
}
dispatch_source_cancel(self.autoCollapseTimer);
self.autoCollapseTimer = nil;
}
@end
......@@ -321,6 +321,9 @@ NS_ASSUME_NONNULL_BEGIN
/// 更新本场直播主题内容
+ (NSString *)fus_URL_Update_Live_Theme;
/// 更新直播主题标题文案(主播主题)
+ (NSString *)fus_URL_Live_Theme_Title_Update;
/// 主播直播清晰度上报,可以取存储的,但是这里最好直接使用赋值的
+ (NSString *)fus_URL_Live_Clarity_Report;
......
......@@ -587,6 +587,11 @@
+ (NSString *)fus_URL_Update_Live_Theme {
return [FUSConfig.sharedInstanced.pathConfigs apiUrl:@"/live/theme/update"];
}
/// 更新直播主题标题文案(主播主题)
+ (NSString *)fus_URL_Live_Theme_Title_Update {
return [FUSConfig.sharedInstanced.pathConfigs apiUrl:@"/live/theme/title/upd"];
}
/// 获取用户直播评分历史列表
+ (NSString *)fus_URL_userliveAssessHistoryGetList{
return [FUSConfig.sharedInstanced.pathConfigs apiUrl:@"/userlive/assess/history/getList"];
......
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