1
This commit is contained in:
@@ -36,6 +36,7 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
|
||||
@property (nonatomic, strong) UILabel *introFooterLabel;
|
||||
@property (nonatomic, assign) CGSize lastIntroFooterTableSize;
|
||||
@property (nonatomic, assign) BOOL applyingIntroFooter;
|
||||
@property (nonatomic, copy) NSString *remoteAudioToken;
|
||||
|
||||
@end
|
||||
|
||||
@@ -894,6 +895,7 @@ static inline CGFloat KBChatAbsTimeInterval(NSTimeInterval interval) {
|
||||
self.introFooterText = text ?: @"";
|
||||
if (self.introFooterText.length == 0) {
|
||||
self.tableView.tableFooterView = nil;
|
||||
self.tableView.scrollEnabled = YES;
|
||||
self.lastIntroFooterTableSize = CGSizeZero;
|
||||
self.applyingIntroFooter = NO;
|
||||
return;
|
||||
@@ -907,7 +909,7 @@ static inline CGFloat KBChatAbsTimeInterval(NSTimeInterval interval) {
|
||||
self.introFooterLabel.numberOfLines = 0;
|
||||
self.introFooterLabel.font = [UIFont systemFontOfSize:14];
|
||||
self.introFooterLabel.textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.9];
|
||||
self.introFooterLabel.textAlignment = NSTextAlignmentCenter;
|
||||
self.introFooterLabel.textAlignment = NSTextAlignmentLeft;
|
||||
[self.introFooterContainer addSubview:self.introFooterLabel];
|
||||
}
|
||||
|
||||
@@ -924,28 +926,25 @@ static inline CGFloat KBChatAbsTimeInterval(NSTimeInterval interval) {
|
||||
}
|
||||
self.lastIntroFooterTableSize = CGSizeMake(width, height);
|
||||
|
||||
CGFloat horizontalPadding = 24;
|
||||
CGFloat leftPadding = 16;
|
||||
CGFloat verticalPadding = 16;
|
||||
CGFloat labelWidth = MAX(0, width - horizontalPadding * 2);
|
||||
CGFloat labelWidth = MAX(0, width * 0.75);
|
||||
CGSize labelSize = [self.introFooterLabel sizeThatFits:CGSizeMake(labelWidth, CGFLOAT_MAX)];
|
||||
CGFloat containerHeight = MAX(height, labelSize.height + verticalPadding * 2);
|
||||
|
||||
self.introFooterContainer.frame = CGRectMake(0, 0, width, containerHeight);
|
||||
self.introFooterLabel.frame = CGRectMake(horizontalPadding, verticalPadding, labelWidth, labelSize.height);
|
||||
CGFloat labelY = containerHeight - verticalPadding - labelSize.height;
|
||||
labelY = MAX(verticalPadding, labelY);
|
||||
self.introFooterLabel.frame = CGRectMake(leftPadding, labelY, labelWidth, labelSize.height);
|
||||
self.tableView.tableFooterView = self.introFooterContainer;
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.tableView layoutIfNeeded];
|
||||
CGFloat contentHeight = self.tableView.contentSize.height;
|
||||
CGFloat tableHeight = CGRectGetHeight(self.tableView.bounds);
|
||||
CGFloat minOffset = -self.tableView.contentInset.top;
|
||||
CGFloat maxOffset = contentHeight - tableHeight + self.tableView.contentInset.bottom;
|
||||
if (maxOffset < minOffset) {
|
||||
maxOffset = minOffset;
|
||||
}
|
||||
CGFloat targetOffset = self.inverted ? maxOffset : minOffset;
|
||||
[self.tableView setContentOffset:CGPointMake(0, targetOffset) animated:NO];
|
||||
[self.tableView setContentOffset:CGPointMake(0, minOffset) animated:NO];
|
||||
});
|
||||
|
||||
self.tableView.scrollEnabled = (self.messages.count > 0);
|
||||
self.applyingIntroFooter = NO;
|
||||
}
|
||||
|
||||
@@ -1383,6 +1382,62 @@ static inline CGFloat KBChatAbsTimeInterval(NSTimeInterval interval) {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)playRemoteAudioWithURLString:(NSString *)urlString {
|
||||
if (urlString.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self stopPlayingAudio];
|
||||
self.remoteAudioToken = [NSUUID UUID].UUIDString;
|
||||
NSString *token = self.remoteAudioToken;
|
||||
|
||||
NSURL *url = [NSURL URLWithString:urlString];
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
|
||||
__weak typeof(self) weakSelf = self;
|
||||
NSURLSessionDataTask *task = [session dataTaskWithURL:url
|
||||
completionHandler:^(NSData *_Nullable data,
|
||||
NSURLResponse *_Nullable response,
|
||||
NSError *_Nullable error) {
|
||||
__strong typeof(weakSelf) strongSelf = weakSelf;
|
||||
if (!strongSelf) {
|
||||
return;
|
||||
}
|
||||
if (![strongSelf.remoteAudioToken isEqualToString:token]) {
|
||||
return;
|
||||
}
|
||||
if (error || !data || data.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (![strongSelf.remoteAudioToken isEqualToString:token]) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSError *sessionError = nil;
|
||||
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
|
||||
[audioSession setCategory:AVAudioSessionCategoryPlayback error:&sessionError];
|
||||
[audioSession setActive:YES error:&sessionError];
|
||||
|
||||
NSError *playerError = nil;
|
||||
strongSelf.audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:&playerError];
|
||||
if (playerError || !strongSelf.audioPlayer) {
|
||||
return;
|
||||
}
|
||||
strongSelf.audioPlayer.delegate = strongSelf;
|
||||
strongSelf.audioPlayer.volume = 1.0;
|
||||
[strongSelf.audioPlayer prepareToPlay];
|
||||
[strongSelf.audioPlayer play];
|
||||
});
|
||||
}];
|
||||
[task resume];
|
||||
}
|
||||
|
||||
#pragma mark - Audio Preload (自动预加载,不播放)
|
||||
|
||||
/// 预加载音频(不自动播放)
|
||||
|
||||
Reference in New Issue
Block a user