修复聊天最后一条跑到最上面的问题
This commit is contained in:
@@ -90,10 +90,13 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
|
|||||||
make.edges.equalTo(self);
|
make.edges.equalTo(self);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// 关键修复:减少初始 contentBottomInset,因为 chatView 已经通过约束避开了底部
|
// 初始化 contentInset
|
||||||
self.contentBottomInset = 20; // 简单的缓冲空间
|
self.contentBottomInset = 0;
|
||||||
[self updateContentBottomInset:self.contentBottomInset];
|
[self updateContentBottomInset:self.contentBottomInset];
|
||||||
|
|
||||||
|
// 暂时禁用 mj_footer,排查问题
|
||||||
|
// TODO: 如果需要加载更多功能,重新启用
|
||||||
|
/*
|
||||||
__weak typeof(self) weakSelf = self;
|
__weak typeof(self) weakSelf = self;
|
||||||
self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
|
self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
|
||||||
__strong typeof(weakSelf) strongSelf = weakSelf;
|
__strong typeof(weakSelf) strongSelf = weakSelf;
|
||||||
@@ -114,11 +117,12 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
|
|||||||
}];
|
}];
|
||||||
|
|
||||||
// 隐藏"已经全部加载完毕"的提示文字
|
// 隐藏"已经全部加载完毕"的提示文字
|
||||||
MJRefreshAutoNormalFooter *footer = (MJRefreshAutoNormalFooter *)self.tableView.mj_footer;
|
// MJRefreshAutoNormalFooter *footer = (MJRefreshAutoNormalFooter *)self.tableView.mj_footer;
|
||||||
footer.stateLabel.hidden = YES; // 隐藏状态文字
|
// footer.stateLabel.hidden = YES; // 隐藏状态文字
|
||||||
footer.refreshingBlock = footer.refreshingBlock; // 保持刷新逻辑
|
// footer.refreshingBlock = footer.refreshingBlock; // 保持刷新逻辑
|
||||||
|
|
||||||
self.tableView.mj_footer.hidden = YES;
|
// self.tableView.mj_footer.hidden = YES;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Public Methods
|
#pragma mark - Public Methods
|
||||||
@@ -206,39 +210,56 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
|
|||||||
// 关键修复:使用 layoutIfNeeded 确保布局完成后再滚动
|
// 关键修复:使用 layoutIfNeeded 确保布局完成后再滚动
|
||||||
[self.tableView layoutIfNeeded];
|
[self.tableView layoutIfNeeded];
|
||||||
|
|
||||||
NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:self.messages.count - 1
|
// 计算需要滚动到的位置
|
||||||
inSection:0];
|
CGFloat contentHeight = self.tableView.contentSize.height;
|
||||||
|
CGFloat tableViewHeight = self.tableView.bounds.size.height;
|
||||||
|
CGFloat bottomInset = self.tableView.contentInset.bottom;
|
||||||
|
|
||||||
// 直接滚动到最后一条消息,不检查是否可见(确保新消息能被看到)
|
// 如果内容高度小于 tableView 高度,不需要滚动
|
||||||
[self.tableView scrollToRowAtIndexPath:lastIndexPath
|
if (contentHeight <= tableViewHeight) {
|
||||||
atScrollPosition:UITableViewScrollPositionBottom
|
NSLog(@"[KBChatTableView] 内容高度(%.2f) <= tableView高度(%.2f),不需要滚动", contentHeight, tableViewHeight);
|
||||||
animated:animated];
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算滚动到底部的 offset
|
||||||
|
CGFloat offsetY = contentHeight - tableViewHeight + bottomInset;
|
||||||
|
|
||||||
|
NSLog(@"[KBChatTableView] scrollToBottom - contentHeight: %.2f, tableViewHeight: %.2f, bottomInset: %.2f, offsetY: %.2f",
|
||||||
|
contentHeight, tableViewHeight, bottomInset, offsetY);
|
||||||
|
|
||||||
|
[self.tableView setContentOffset:CGPointMake(0, offsetY) animated:animated];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Public Helpers
|
#pragma mark - Public Helpers
|
||||||
|
|
||||||
- (void)endLoadMoreWithHasMoreData:(BOOL)hasMoreData {
|
- (void)endLoadMoreWithHasMoreData:(BOOL)hasMoreData {
|
||||||
self.hasMoreData = hasMoreData;
|
self.hasMoreData = hasMoreData;
|
||||||
if (hasMoreData) {
|
// 暂时禁用 mj_footer
|
||||||
[self.tableView.mj_footer endRefreshing];
|
// if (hasMoreData) {
|
||||||
} else {
|
// [self.tableView.mj_footer endRefreshing];
|
||||||
[self.tableView.mj_footer endRefreshingWithNoMoreData];
|
// } else {
|
||||||
}
|
// [self.tableView.mj_footer endRefreshingWithNoMoreData];
|
||||||
|
// }
|
||||||
[self updateFooterVisibility];
|
[self updateFooterVisibility];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)resetNoMoreData {
|
- (void)resetNoMoreData {
|
||||||
self.hasMoreData = YES;
|
self.hasMoreData = YES;
|
||||||
[self.tableView.mj_footer resetNoMoreData];
|
// 暂时禁用 mj_footer
|
||||||
|
// [self.tableView.mj_footer resetNoMoreData];
|
||||||
[self updateFooterVisibility];
|
[self updateFooterVisibility];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateContentBottomInset:(CGFloat)bottomInset {
|
- (void)updateContentBottomInset:(CGFloat)bottomInset {
|
||||||
self.contentBottomInset = bottomInset;
|
self.contentBottomInset = bottomInset;
|
||||||
UIEdgeInsets insets = self.tableView.contentInset;
|
|
||||||
|
// 直接设置 contentInset
|
||||||
|
UIEdgeInsets insets = UIEdgeInsetsZero;
|
||||||
insets.bottom = bottomInset;
|
insets.bottom = bottomInset;
|
||||||
self.tableView.contentInset = insets;
|
self.tableView.contentInset = insets;
|
||||||
self.tableView.scrollIndicatorInsets = insets;
|
self.tableView.scrollIndicatorInsets = insets;
|
||||||
|
|
||||||
|
NSLog(@"[KBChatTableView] updateContentBottomInset: %.2f", bottomInset);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addMessage:(KBAiChatMessage *)message
|
- (void)addMessage:(KBAiChatMessage *)message
|
||||||
@@ -296,10 +317,32 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSLog(@"[KBChatTableView] ========== reloadWithMessages 开始 ==========");
|
||||||
|
NSLog(@"[KBChatTableView] 消息数量: %ld", (long)self.messages.count);
|
||||||
|
NSLog(@"[KBChatTableView] tableView.frame: %@", NSStringFromCGRect(self.tableView.frame));
|
||||||
|
NSLog(@"[KBChatTableView] tableView.bounds: %@", NSStringFromCGRect(self.tableView.bounds));
|
||||||
|
NSLog(@"[KBChatTableView] 刷新前 contentSize: %@", NSStringFromCGSize(self.tableView.contentSize));
|
||||||
|
NSLog(@"[KBChatTableView] 刷新前 contentInset: %@", NSStringFromUIEdgeInsets(self.tableView.contentInset));
|
||||||
|
|
||||||
[self.tableView reloadData];
|
[self.tableView reloadData];
|
||||||
[self.tableView layoutIfNeeded];
|
[self.tableView layoutIfNeeded];
|
||||||
[self updateFooterVisibility];
|
[self updateFooterVisibility];
|
||||||
|
|
||||||
|
NSLog(@"[KBChatTableView] 刷新后 contentSize: %@", NSStringFromCGSize(self.tableView.contentSize));
|
||||||
|
NSLog(@"[KBChatTableView] 刷新后 contentInset: %@", NSStringFromUIEdgeInsets(self.tableView.contentInset));
|
||||||
|
NSLog(@"[KBChatTableView] 刷新后 contentOffset: %@", NSStringFromCGPoint(self.tableView.contentOffset));
|
||||||
|
|
||||||
|
// 打印每个 Cell 的高度
|
||||||
|
for (NSInteger i = 0; i < self.messages.count; i++) {
|
||||||
|
CGRect cellRect = [self.tableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
|
||||||
|
KBAiChatMessage *msg = self.messages[i];
|
||||||
|
NSLog(@"[KBChatTableView] Cell[%ld] type=%ld, height=%.2f, text=%@",
|
||||||
|
(long)i, (long)msg.type, cellRect.size.height,
|
||||||
|
msg.text.length > 20 ? [msg.text substringToIndex:20] : msg.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog(@"[KBChatTableView] ========== reloadWithMessages 结束 ==========");
|
||||||
|
|
||||||
if (keepOffset) {
|
if (keepOffset) {
|
||||||
CGFloat newContentHeight = self.tableView.contentSize.height;
|
CGFloat newContentHeight = self.tableView.contentSize.height;
|
||||||
CGFloat delta = newContentHeight - oldContentHeight;
|
CGFloat delta = newContentHeight - oldContentHeight;
|
||||||
@@ -310,8 +353,21 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (scrollToBottom) {
|
if (scrollToBottom) {
|
||||||
// 关键修复:直接滚动,不使用延迟
|
NSLog(@"[KBChatTableView] 准备滚动到底部...");
|
||||||
[self scrollToBottomAnimated:NO];
|
// 关键修复:使用 dispatch_after 延迟执行,确保 reloadData 和布局完全完成
|
||||||
|
__weak typeof(self) weakSelf = self;
|
||||||
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||||
|
__strong typeof(weakSelf) strongSelf = weakSelf;
|
||||||
|
if (!strongSelf) {
|
||||||
|
NSLog(@"[KBChatTableView] ⚠️ strongSelf 为空,跳过滚动");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NSLog(@"[KBChatTableView] dispatch_after 执行 scrollToBottom");
|
||||||
|
NSLog(@"[KBChatTableView] 滚动前 contentSize: %@", NSStringFromCGSize(strongSelf.tableView.contentSize));
|
||||||
|
NSLog(@"[KBChatTableView] 滚动前 tableView.frame: %@", NSStringFromCGRect(strongSelf.tableView.frame));
|
||||||
|
[strongSelf scrollToBottomAnimated:NO];
|
||||||
|
NSLog(@"[KBChatTableView] scrollToBottom 后 contentOffset: %@", NSStringFromCGPoint(strongSelf.tableView.contentOffset));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,9 +456,10 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateFooterVisibility {
|
- (void)updateFooterVisibility {
|
||||||
BOOL canLoadMore = (self.delegate &&
|
// 暂时禁用 mj_footer
|
||||||
[self.delegate respondsToSelector:@selector(chatTableViewDidTriggerLoadMore:)]);
|
// BOOL canLoadMore = (self.delegate &&
|
||||||
self.tableView.mj_footer.hidden = !canLoadMore || self.messages.count == 0;
|
// [self.delegate respondsToSelector:@selector(chatTableViewDidTriggerLoadMore:)]);
|
||||||
|
// self.tableView.mj_footer.hidden = !canLoadMore || self.messages.count == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - UITableViewDataSource
|
#pragma mark - UITableViewDataSource
|
||||||
|
|||||||
@@ -177,19 +177,17 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
|||||||
self.currentPage = 1;
|
self.currentPage = 1;
|
||||||
self.hasMoreHistory = YES;
|
self.hasMoreHistory = YES;
|
||||||
|
|
||||||
// ✅ 尝试从缓存加载 messages
|
// ⚠️ 临时禁用缓存,排查问题
|
||||||
NSArray *cachedMessages = [[KBAIChatMessageCacheManager shared] messagesForCompanionId:persona.personaId];
|
// NSArray *cachedMessages = [[KBAIChatMessageCacheManager shared] messagesForCompanionId:persona.personaId];
|
||||||
if (cachedMessages.count > 0) {
|
// if (cachedMessages.count > 0) {
|
||||||
// 缓存命中,直接使用
|
// self.messages = [cachedMessages mutableCopy];
|
||||||
self.messages = [cachedMessages mutableCopy];
|
// self.hasLoadedData = YES;
|
||||||
self.hasLoadedData = YES;
|
// NSLog(@"[Cell] ✅ 从缓存加载:personaId=%ld, 消息数=%ld", (long)persona.personaId, (long)cachedMessages.count);
|
||||||
NSLog(@"[Cell] ✅ 从缓存加载:personaId=%ld, 消息数=%ld", (long)persona.personaId, (long)cachedMessages.count);
|
// } else {
|
||||||
} else {
|
|
||||||
// 缓存未命中,需要请求
|
|
||||||
self.messages = [NSMutableArray array];
|
self.messages = [NSMutableArray array];
|
||||||
self.hasLoadedData = NO;
|
self.hasLoadedData = NO;
|
||||||
NSLog(@"[Cell] ⚠️ 缓存未命中:personaId=%ld, 需要请求数据", (long)persona.personaId);
|
NSLog(@"[Cell] ⚠️ 缓存已禁用:personaId=%ld, 需要请求数据", (long)persona.personaId);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// 设置 UI
|
// 设置 UI
|
||||||
[self.backgroundImageView sd_setImageWithURL:[NSURL URLWithString:persona.coverImageUrl]
|
[self.backgroundImageView sd_setImageWithURL:[NSURL URLWithString:persona.coverImageUrl]
|
||||||
@@ -205,6 +203,12 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
|||||||
// 确保开场白在第一条
|
// 确保开场白在第一条
|
||||||
[self ensureOpeningMessageAtTop];
|
[self ensureOpeningMessageAtTop];
|
||||||
|
|
||||||
|
NSLog(@"[KBPersonaChatCell] ========== setPersona 调试 ==========");
|
||||||
|
NSLog(@"[KBPersonaChatCell] personaId: %ld", (long)persona.personaId);
|
||||||
|
NSLog(@"[KBPersonaChatCell] messages.count: %ld", (long)self.messages.count);
|
||||||
|
NSLog(@"[KBPersonaChatCell] chatView.frame: %@", NSStringFromCGRect(self.chatView.frame));
|
||||||
|
NSLog(@"[KBPersonaChatCell] contentView.frame: %@", NSStringFromCGRect(self.contentView.frame));
|
||||||
|
|
||||||
// 如果有消息,直接显示(包含开场白)
|
// 如果有消息,直接显示(包含开场白)
|
||||||
if (self.messages.count > 0) {
|
if (self.messages.count > 0) {
|
||||||
// 同步缓存,避免下次从缓存缺少开场白
|
// 同步缓存,避免下次从缓存缺少开场白
|
||||||
@@ -217,6 +221,8 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
|||||||
[self.chatView clearMessages];
|
[self.chatView clearMessages];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSLog(@"[KBPersonaChatCell] ========== setPersona 结束 ==========");
|
||||||
|
|
||||||
[self.commentButton setTitle:persona.commentCount forState:UIControlStateNormal];
|
[self.commentButton setTitle:persona.commentCount forState:UIControlStateNormal];
|
||||||
[self.likeButton setTitle:persona.likeCount forState:UIControlStateNormal];
|
[self.likeButton setTitle:persona.likeCount forState:UIControlStateNormal];
|
||||||
self.likeButton.selected = persona.liked;
|
self.likeButton.selected = persona.liked;
|
||||||
@@ -294,7 +300,10 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 插入历史消息(确保开场白始终是第一条)
|
// 插入历史消息(确保开场白始终是第一条)
|
||||||
if (weakSelf.currentPage == 1) {
|
// 关键修复:在 dispatch_async 之前保存当前页码,避免异步执行时 currentPage 已经被递增
|
||||||
|
NSInteger loadedPage = weakSelf.currentPage;
|
||||||
|
|
||||||
|
if (loadedPage == 1) {
|
||||||
// 第一页,直接赋值
|
// 第一页,直接赋值
|
||||||
weakSelf.messages = newMessages;
|
weakSelf.messages = newMessages;
|
||||||
[weakSelf ensureOpeningMessageAtTop];
|
[weakSelf ensureOpeningMessageAtTop];
|
||||||
@@ -310,15 +319,26 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
|
|||||||
|
|
||||||
// 刷新 UI
|
// 刷新 UI
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
BOOL keepOffset = (weakSelf.currentPage != 1);
|
__strong typeof(weakSelf) strongSelf = weakSelf;
|
||||||
BOOL scrollToBottom = (weakSelf.currentPage == 1);
|
if (!strongSelf) {
|
||||||
[weakSelf.chatView reloadWithMessages:weakSelf.messages
|
NSLog(@"[KBPersonaChatCell] ⚠️ strongSelf 为空,跳过刷新");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用保存的页码判断,而不是 currentPage(可能已被递增)
|
||||||
|
BOOL keepOffset = (loadedPage != 1);
|
||||||
|
BOOL scrollToBottom = (loadedPage == 1);
|
||||||
|
|
||||||
|
NSLog(@"[KBPersonaChatCell] 刷新 UI - loadedPage: %ld, keepOffset: %d, scrollToBottom: %d",
|
||||||
|
(long)loadedPage, keepOffset, scrollToBottom);
|
||||||
|
|
||||||
|
[strongSelf.chatView reloadWithMessages:strongSelf.messages
|
||||||
keepOffset:keepOffset
|
keepOffset:keepOffset
|
||||||
scrollToBottom:scrollToBottom];
|
scrollToBottom:scrollToBottom];
|
||||||
[weakSelf.chatView endLoadMoreWithHasMoreData:weakSelf.hasMoreHistory];
|
[strongSelf.chatView endLoadMoreWithHasMoreData:strongSelf.hasMoreHistory];
|
||||||
|
|
||||||
// ✅ 保存到缓存(包含开场白)
|
// ✅ 保存到缓存(包含开场白)
|
||||||
[[KBAIChatMessageCacheManager shared] saveMessages:weakSelf.messages
|
[[KBAIChatMessageCacheManager shared] saveMessages:strongSelf.messages
|
||||||
forCompanionId:companionId];
|
forCompanionId:companionId];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -451,7 +451,7 @@
|
|||||||
#pragma mark - Private
|
#pragma mark - Private
|
||||||
|
|
||||||
- (void)updateChatViewBottomInset {
|
- (void)updateChatViewBottomInset {
|
||||||
// 问题2修复:键盘弹起时,增加 bottomInset 让最后一条消息显示在 VoiceInputBar 上方
|
// 键盘弹起时,增加 bottomInset 让最后一条消息显示在 VoiceInputBar 上方
|
||||||
CGFloat bottomInset;
|
CGFloat bottomInset;
|
||||||
|
|
||||||
if (self.currentKeyboardHeight > 0.0) {
|
if (self.currentKeyboardHeight > 0.0) {
|
||||||
@@ -468,13 +468,13 @@
|
|||||||
bottomInset = (self.currentKeyboardHeight + self.voiceInputBarHeight) - chatViewPhysicalBottomSpace;
|
bottomInset = (self.currentKeyboardHeight + self.voiceInputBarHeight) - chatViewPhysicalBottomSpace;
|
||||||
|
|
||||||
// 确保不会是负数
|
// 确保不会是负数
|
||||||
bottomInset = MAX(bottomInset, 20);
|
bottomInset = MAX(bottomInset, 0);
|
||||||
|
|
||||||
NSLog(@"[KBAIHomeVC] 键盘弹起 - bottomInset: %.2f (键盘: %.2f + InputBar: %.2f - 已避开: %.2f)",
|
NSLog(@"[KBAIHomeVC] 键盘弹起 - bottomInset: %.2f (键盘: %.2f + InputBar: %.2f - 已避开: %.2f)",
|
||||||
bottomInset, self.currentKeyboardHeight, self.voiceInputBarHeight, chatViewPhysicalBottomSpace);
|
bottomInset, self.currentKeyboardHeight, self.voiceInputBarHeight, chatViewPhysicalBottomSpace);
|
||||||
} else {
|
} else {
|
||||||
// 键盘隐藏时:恢复原来的 bottomInset
|
// 键盘隐藏时:不需要额外的 bottomInset
|
||||||
bottomInset = 20; // 简单的缓冲空间
|
bottomInset = 0;
|
||||||
NSLog(@"[KBAIHomeVC] 键盘隐藏 - bottomInset: %.2f", bottomInset);
|
NSLog(@"[KBAIHomeVC] 键盘隐藏 - bottomInset: %.2f", bottomInset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,21 +486,11 @@
|
|||||||
// 键盘弹起时,自动滚动到最后一条消息
|
// 键盘弹起时,自动滚动到最后一条消息
|
||||||
if (self.currentKeyboardHeight > 0.0) {
|
if (self.currentKeyboardHeight > 0.0) {
|
||||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||||
[cell.chatView scrollToBottom]; // 修复:使用无参数的方法
|
[cell.chatView scrollToBottom];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NSLog(@"[KBAIHomeVC] 更新 ChatView bottomInset: %.2f (键盘高度: %.2f)", bottomInset, self.currentKeyboardHeight);
|
|
||||||
|
|
||||||
for (NSIndexPath *indexPath in self.collectionView.indexPathsForVisibleItems) {
|
|
||||||
KBPersonaChatCell *cell = (KBPersonaChatCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
|
|
||||||
if (cell) {
|
|
||||||
[cell updateChatViewBottomInset:bottomInset];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)showChatLimitPopWithMessage:(NSString *)message {
|
- (void)showChatLimitPopWithMessage:(NSString *)message {
|
||||||
|
|||||||
Reference in New Issue
Block a user