chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:35:01 +08:00
commit a2e318a963
2974 changed files with 158180 additions and 0 deletions
@@ -0,0 +1,25 @@
//
// TLExpressionBannerCell.h
// TLChat
//
// Created by 李伯坤 on 16/4/20.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol TLExpressionBannerCellDelegate <NSObject>
- (void)expressionBannerCellDidSelectBanner:(id)item;
@end
@interface TLExpressionBannerCell : UITableViewCell <ZZFlexibleLayoutViewProtocol>
@property (nonatomic, assign) id<TLExpressionBannerCellDelegate>delegate;
@property (nonatomic, strong) NSArray *data;
@property (nonatomic, copy) void (^bannerClickAction)(id bannerModel);
@end
@@ -0,0 +1,104 @@
//
// TLExpressionBannerCell.m
// TLChat
//
// Created by 李伯坤 on 16/4/20.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import "TLExpressionBannerCell.h"
#import "TLPictureCarouselView.h"
#import "TLExpressionGroupModel.h"
@interface TLExpressionBannerCell ()
@property (nonatomic, strong) TLPictureCarouselView *picCarouselView;
@end
@implementation TLExpressionBannerCell
#pragma mark - # Protocol
+ (CGFloat)viewHeightByDataModel:(id)dataModel
{
return 0.4 * SCREEN_WIDTH;
}
- (void)setViewDataModel:(id)dataModel
{
[self setData:dataModel];
}
- (void)setViewDelegate:(id)delegate
{
[self setDelegate:delegate];
}
- (void)setViewEventAction:(id (^)(NSInteger, id))eventAction
{
[self setBannerClickAction:^(id bannerModel) {
if (eventAction) {
eventAction(0, bannerModel);
}
}];
}
#pragma mark - # Public Methods
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
[self setSelectionStyle:UITableViewCellSelectionStyleNone];
[self.contentView addSubview:self.picCarouselView];
[self p_addMasonry];
}
return self;
}
- (void)setData:(NSArray *)data
{
_data = data;
[self.picCarouselView setData:data];
}
#pragma mark - # Private Methods
- (void)p_addMasonry
{
[self.picCarouselView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.contentView);
}];
}
#pragma mark - # Getter
- (TLPictureCarouselView *)picCarouselView
{
if (_picCarouselView == nil) {
_picCarouselView = [[TLPictureCarouselView alloc] init];
@weakify(self);
[_picCarouselView setDidSelectItem:^(TLPictureCarouselView *pictureCarouselView, id<TLPictureCarouselProtocol> model){
@strongify(self);
if (self.bannerClickAction) {
self.bannerClickAction(model);
}
if (self.delegate && [self.delegate respondsToSelector:@selector(expressionBannerCellDidSelectBanner:)]) {
[self.delegate expressionBannerCellDidSelectBanner:model];
}
}];
}
return _picCarouselView;
}
@end
#pragma mark - ## TLExpressionGroupModel (TLExpressionBannerCell)
@interface TLExpressionGroupModel (TLExpressionBannerCell) <TLPictureCarouselProtocol>
@end
@implementation TLExpressionGroupModel (TLExpressionBannerCell)
- (NSString *)pictureURL
{
return self.bannerURL;
}
@end
@@ -0,0 +1,25 @@
//
// TLExpressionDownloadButton.h
// TLChat
//
// Created by 李伯坤 on 2018/1/2.
// Copyright © 2018年 李伯坤. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, TLExpressionDownloadButtonStatus) {
TLExpressionDownloadButtonStatusNet,
TLExpressionDownloadButtonStatusDownloading,
TLExpressionDownloadButtonStatusDownloaded,
};
@interface TLExpressionDownloadButton : UIView
@property (nonatomic, assign) TLExpressionDownloadButtonStatus status;
@property (nonatomic, assign) CGFloat progress;
@property (nonatomic, copy) void (^downloadButtonClick)();
@end
@@ -0,0 +1,77 @@
//
// TLExpressionDownloadButton.m
// TLChat
//
// Created by 李伯坤 on 2018/1/2.
// Copyright © 2018年 李伯坤. All rights reserved.
//
#import "TLExpressionDownloadButton.h"
@interface TLExpressionDownloadButton ()
@property (nonatomic, strong) UIButton *downloadButton;
@property (nonatomic, strong) UIView *progressView;
@end
@implementation TLExpressionDownloadButton
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self.layer setMasksToBounds:YES];
[self.layer setCornerRadius:3];
[self.layer setBorderWidth:1];
self.progressView = self.addView(1)
.backgroundColor([UIColor colorGreenDefault])
.view;
@weakify(self);
self.downloadButton = self.addButton(2)
.titleFont([UIFont systemFontOfSize:14.0f])
.masonry(^ (MASConstraintMaker *make) {
make.edges.mas_equalTo(0);
})
.eventBlock(UIControlEventTouchUpInside, ^(UIButton *sender) {
@strongify(self);
if (self.downloadButtonClick) {
self.downloadButtonClick();
}
})
.view;
[self setStatus:TLExpressionDownloadButtonStatusNet];
}
return self;
}
- (void)setStatus:(TLExpressionDownloadButtonStatus)status
{
_status = status;
if (status == TLExpressionDownloadButtonStatusNet) {
self.downloadButton.zz_make.title(LOCSTR(@"下载")).titleColor([UIColor colorGreenDefault]).userInteractionEnabled(YES);
[self.layer setBorderColor:[UIColor colorGreenDefault].CGColor];
[self.progressView setHidden:YES];
}
else if (status == TLExpressionDownloadButtonStatusDownloaded) {
self.downloadButton.zz_make.title(LOCSTR(@"已下载")).titleColor([UIColor colorGrayLine]).userInteractionEnabled(NO);
[self.layer setBorderColor:[UIColor colorGrayLine].CGColor];
[self.progressView setHidden:YES];
}
else {
self.downloadButton.zz_make.title(LOCSTR(@"下载中")).titleColor([UIColor whiteColor]).userInteractionEnabled(NO);
[self.layer setBorderColor:[UIColor colorGreenDefault].CGColor];
[self.progressView setHidden:NO];
}
}
- (void)setProgress:(CGFloat)progress
{
_progress = progress;
[self.progressView setFrame:CGRectMake(0, 0, self.frame.size.width * progress, self.frame.size.height)];
}
@end
@@ -0,0 +1,16 @@
//
// TLExpressionItemCell.h
// TLChat
//
// Created by 李伯坤 on 16/4/4.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import <UIKit/UIKit.h>
@class TLExpressionGroupModel;
@interface TLExpressionItemCell : UITableViewCell <ZZFlexibleLayoutViewProtocol>
@property (nonatomic, strong) TLExpressionGroupModel *groupModel;
@end
@@ -0,0 +1,192 @@
//
// TLExpressionItemCell.m
// TLChat
//
// Created by 李伯坤 on 16/4/4.
// Copyright © 2016年 李伯坤. All rights reserved.
//
#import "TLExpressionItemCell.h"
#import "TLExpressionGroupModel+Download.h"
#import "TLExpressionDownloadButton.h"
#import "TLExpressionGroupModel.h"
@interface TLExpressionItemCell ()
@property (nonatomic, strong) UIImageView *iconView;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UILabel *detailLabel;
@property (nonatomic, strong) UIImageView *tagView;
@property (nonatomic, strong) TLExpressionDownloadButton *downloadButton;
@property (nonatomic, copy) id (^eventAction)(NSInteger eventType, id data);
@end
@implementation TLExpressionItemCell
+ (CGFloat)viewHeightByDataModel:(id)dataModel
{
return 80;
}
- (void)setViewDataModel:(id)dataModel
{
[self setGroupModel:dataModel];
}
- (void)setViewEventAction:(id (^)(NSInteger, id))eventAction
{
[self setEventAction:eventAction];
}
- (void)viewIndexPath:(NSIndexPath *)indexPath sectionItemCount:(NSInteger)count
{
self.addSeparator(ZZSeparatorPositionBottom).beginAt(15);
}
#pragma mark - # Public Methods
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
[self.contentView addSubview:self.iconView];
[self.contentView addSubview:self.titleLabel];
[self.contentView addSubview:self.detailLabel];
[self.contentView addSubview:self.tagView];
[self.contentView addSubview:self.downloadButton];
[self p_addMasonry];
}
return self;
}
- (void)setGroupModel:(TLExpressionGroupModel *)groupModel
{
_groupModel = groupModel;
UIImage *image = [UIImage imageNamed:groupModel.path];
if (image) {
[self.iconView setImage:image];
}
else {
[self.iconView tt_setImageWithURL:TLURL(groupModel.iconURL)];
}
[self.titleLabel setText:groupModel.name];
[self.detailLabel setText:groupModel.detail];
if (groupModel.status == TLExpressionGroupStatusLocal) {
[self.downloadButton setStatus:TLExpressionDownloadButtonStatusDownloaded];
}
else if (groupModel.status == TLExpressionGroupStatusDownloading) {
[self.downloadButton setStatus:TLExpressionDownloadButtonStatusDownloading];
}
else {
[self.downloadButton setStatus:TLExpressionDownloadButtonStatusNet];
}
@weakify(self);
[self.downloadButton setProgress:groupModel.downloadProgress];
[groupModel setDownloadProgressAction:^(TLExpressionGroupModel *groupModel, CGFloat progress) {
@strongify(self);
[self.downloadButton setProgress:progress];
}];
[groupModel setDownloadCompleteAction:^(TLExpressionGroupModel *groupModel, BOOL success, id data) {
@strongify(self);
[self setGroupModel:groupModel];
}];
}
#pragma mark - # Private Methods
- (void)p_addMasonry
{
[self.iconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.contentView).mas_offset(15);
make.top.mas_equalTo(self.contentView).mas_offset(10);
make.bottom.mas_equalTo(self.contentView).mas_offset(-10);
make.width.mas_equalTo(self.iconView.mas_height);
}];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(self.iconView.mas_centerY).mas_offset(-2.0f);
make.left.mas_equalTo(self.iconView.mas_right).mas_offset(13.0f);
make.right.mas_lessThanOrEqualTo(self.downloadButton.mas_left).mas_offset(-15);
}];
[self.detailLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.iconView.mas_centerY).mas_offset(5.0);
make.left.mas_equalTo(self.titleLabel);
make.right.mas_lessThanOrEqualTo(self.downloadButton.mas_left).mas_offset(-15);
}];
[self.tagView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.top.mas_equalTo(self.contentView);
}];
[self.downloadButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(self.contentView).mas_offset(-15);
make.centerY.mas_equalTo(self.contentView);
make.size.mas_equalTo(CGSizeMake(70, 27));
}];
}
#pragma mark - # Getter
- (UIImageView *)iconView
{
if (_iconView == nil) {
_iconView = [[UIImageView alloc] init];
[_iconView setBackgroundColor:[UIColor clearColor]];
[_iconView.layer setMasksToBounds:YES];
[_iconView.layer setCornerRadius:5.0f];
}
return _iconView;
}
- (UILabel *)titleLabel
{
if (_titleLabel == nil) {
_titleLabel = [[UILabel alloc] init];
[_titleLabel setFont:[UIFont systemFontOfSize:16.0f]];
[_titleLabel setBackgroundColor:[UIColor whiteColor]];
[_titleLabel setClipsToBounds:YES];
}
return _titleLabel;
}
- (UILabel *)detailLabel
{
if (_detailLabel == nil) {
_detailLabel = [[UILabel alloc] init];
[_detailLabel setFont:[UIFont systemFontOfSize:13.0f]];
[_detailLabel setTextColor:[UIColor grayColor]];
[_detailLabel setBackgroundColor:[UIColor whiteColor]];
[_detailLabel setClipsToBounds:YES];
}
return _detailLabel;
}
- (UIImageView *)tagView
{
if (_tagView == nil) {
_tagView = [[UIImageView alloc] init];
[_tagView setImage:[UIImage imageNamed:@"icon_corner_new"]];
[_tagView setHidden:YES];
}
return _tagView;
}
- (TLExpressionDownloadButton *)downloadButton
{
if (_downloadButton == nil) {
_downloadButton = [[TLExpressionDownloadButton alloc] init];
@weakify(self);
[_downloadButton setDownloadButtonClick:^{
@strongify(self);
if (self.groupModel.status == TLExpressionGroupStatusNet) {
[self.groupModel startDownload];
[self setGroupModel:self.groupModel];
}
}];
}
return _downloadButton;
}
@end
@@ -0,0 +1,13 @@
//
// TLExpressionTitleView.h
// TLChat
//
// Created by 李伯坤 on 2017/7/23.
// Copyright © 2017年 李伯坤. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface TLExpressionTitleView : UITableViewHeaderFooterView <ZZFlexibleLayoutViewProtocol>
@end
@@ -0,0 +1,64 @@
//
// TLExpressionTitleView.m
// TLChat
//
// Created by 李伯坤 on 2017/7/23.
// Copyright © 2017年 李伯坤. All rights reserved.
//
#import "TLExpressionTitleView.h"
@interface TLExpressionTitleView ()
@property (nonatomic, strong) UILabel *titleLabel;
@end
@implementation TLExpressionTitleView
+ (CGFloat)viewHeightByDataModel:(id)dataModel
{
return 55;
}
- (void)setViewDataModel:(id)dataModel
{
if (dataModel && [dataModel isKindOfClass:[NSString class]]) {
[self.titleLabel setText:dataModel];
}
else {
[self.titleLabel setText:nil];
}
}
#pragma mark - # Public Methods
- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithReuseIdentifier:reuseIdentifier]) {
UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 40)];
[bgView setBackgroundColor:[UIColor whiteColor]];
[self setBackgroundView:bgView];
[self setTintColor:[UIColor whiteColor]];
self.titleLabel = self.contentView.addLabel(1)
.backgroundColor([UIColor whiteColor])
.clipsToBounds(YES)
.font([UIFont systemFontOfSize:17])
.masonry(^(MASConstraintMaker *make) {
make.left.mas_equalTo(15);
make.right.mas_lessThanOrEqualTo(-15);
make.bottom.mas_equalTo(-12);
})
.view;
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.addSeparator(ZZSeparatorPositionBottom).beginAt(15).length(SCREEN_WIDTH - 15);
}
@end