Files
keyboard/keyBoard/Class/AiTalk/V/KBAICommentView.m

778 lines
25 KiB
Mathematica
Raw Normal View History

//
// KBAICommentView.m
// keyBoard
//
// Created by Mac on 2026/1/16.
//
#import "KBAICommentView.h"
2026-01-16 15:55:08 +08:00
#import "KBAICommentFooterView.h"
#import "KBAICommentHeaderView.h"
#import "KBAICommentInputView.h"
#import "KBAICommentModel.h"
#import "KBAIReplyCell.h"
#import "KBAIReplyModel.h"
2026-01-28 12:04:31 +08:00
#import "KBCommentModel.h"
#import "AiVM.h"
2026-01-16 15:55:08 +08:00
#import <MJExtension/MJExtension.h>
#import <Masonry/Masonry.h>
static NSString *const kCommentHeaderIdentifier = @"CommentHeader";
static NSString *const kReplyCellIdentifier = @"ReplyCell";
static NSString *const kCommentFooterIdentifier = @"CommentFooter";
@interface KBAICommentView () <UITableViewDataSource, UITableViewDelegate>
2026-01-28 13:43:36 +08:00
@property(nonatomic, strong) UIVisualEffectView *blurBackgroundView;
2026-01-16 15:55:08 +08:00
@property(nonatomic, strong) UIView *headerView;
@property(nonatomic, strong) UILabel *titleLabel;
@property(nonatomic, strong) UIButton *closeButton;
2026-01-16 19:09:54 +08:00
@property(nonatomic, strong) BaseTableView *tableView;
2026-01-16 15:55:08 +08:00
@property(nonatomic, strong) KBAICommentInputView *inputView;
@property(nonatomic, strong) NSMutableArray<KBAICommentModel *> *comments;
@property(nonatomic, assign) NSInteger totalCommentCount;
///
@property(nonatomic, assign) CGFloat keyboardHeight;
///
@property(nonatomic, strong) MASConstraint *inputBottomConstraint;
2026-01-16 20:31:42 +08:00
///
@property(nonatomic, weak) KBAICommentModel *replyToComment;
///
@property(nonatomic, weak) KBAIReplyModel *replyToReply;
2026-01-28 12:04:31 +08:00
/// AiVM
@property(nonatomic, strong) AiVM *aiVM;
2026-01-16 15:55:08 +08:00
@end
@implementation KBAICommentView
2026-01-16 15:55:08 +08:00
#pragma mark - Lifecycle
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.comments = [NSMutableArray array];
[self setupUI];
[self setupKeyboardObservers];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - UI Setup
- (void)setupUI {
2026-01-28 13:43:36 +08:00
//
self.backgroundColor = [UIColor clearColor];
2026-01-16 15:55:08 +08:00
self.layer.cornerRadius = 12;
self.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner;
self.clipsToBounds = YES;
2026-01-28 13:43:36 +08:00
//
[self addSubview:self.blurBackgroundView];
[self.blurBackgroundView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self);
}];
2026-01-16 15:55:08 +08:00
[self addSubview:self.headerView];
[self.headerView addSubview:self.titleLabel];
[self.headerView addSubview:self.closeButton];
[self addSubview:self.tableView];
[self addSubview:self.inputView];
[self.headerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.equalTo(self);
make.height.mas_equalTo(50);
}];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.headerView);
}];
[self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.headerView).offset(-16);
make.centerY.equalTo(self.headerView);
2026-01-28 13:55:11 +08:00
make.width.height.mas_equalTo(25);
2026-01-16 15:55:08 +08:00
}];
[self.inputView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self);
make.height.mas_equalTo(50);
2026-01-16 20:44:10 +08:00
self.inputBottomConstraint =
make.bottom.equalTo(self).offset(-KB_SafeAreaBottom());
2026-01-16 15:55:08 +08:00
}];
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.headerView.mas_bottom);
make.left.right.equalTo(self);
make.bottom.equalTo(self.inputView.mas_top);
}];
}
#pragma mark - Keyboard Observers
- (void)setupKeyboardObservers {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification {
CGRect keyboardFrame =
[notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSTimeInterval duration =
[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey]
doubleValue];
self.keyboardHeight = keyboardFrame.size.height;
[self.inputBottomConstraint uninstall];
[self.inputView mas_updateConstraints:^(MASConstraintMaker *make) {
self.inputBottomConstraint =
make.bottom.equalTo(self).offset(-self.keyboardHeight);
}];
[UIView animateWithDuration:duration
animations:^{
[self layoutIfNeeded];
}];
}
- (void)keyboardWillHide:(NSNotification *)notification {
NSTimeInterval duration =
[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey]
doubleValue];
self.keyboardHeight = 0;
[self.inputBottomConstraint uninstall];
[self.inputView mas_updateConstraints:^(MASConstraintMaker *make) {
2026-01-16 20:44:10 +08:00
self.inputBottomConstraint =
make.bottom.equalTo(self).offset(-KB_SafeAreaBottom());
2026-01-16 15:55:08 +08:00
}];
[UIView animateWithDuration:duration
animations:^{
[self layoutIfNeeded];
}];
}
#pragma mark - Data Loading
- (void)loadComments {
2026-01-28 12:04:31 +08:00
if (self.companionId <= 0) {
NSLog(@"[KBAICommentView] companionId 未设置,无法加载评论");
2026-01-16 15:55:08 +08:00
return;
}
2026-01-28 12:04:31 +08:00
__weak typeof(self) weakSelf = self;
[self.aiVM fetchCommentsWithCompanionId:self.companionId
pageNum:1
pageSize:20
completion:^(KBCommentPageModel *pageModel, NSError *error) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
if (error) {
NSLog(@"[KBAICommentView] 加载评论失败:%@", error.localizedDescription);
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
[strongSelf updateCommentsWithPageModel:pageModel];
});
}];
}
2026-01-16 15:55:08 +08:00
2026-01-28 12:04:31 +08:00
/// KBCommentPageModel UI KBAICommentModel
- (void)updateCommentsWithPageModel:(KBCommentPageModel *)pageModel {
if (!pageModel) {
NSLog(@"[KBAICommentView] pageModel 为空");
2026-01-16 15:55:08 +08:00
return;
}
2026-01-28 12:04:31 +08:00
self.totalCommentCount = pageModel.total;
2026-01-16 15:55:08 +08:00
[self.comments removeAllObjects];
2026-01-28 12:04:31 +08:00
2026-01-16 19:09:54 +08:00
// tableView
CGFloat tableWidth = self.tableView.bounds.size.width;
if (tableWidth <= 0) {
tableWidth = [UIScreen mainScreen].bounds.size.width;
}
2026-01-28 12:04:31 +08:00
NSLog(@"[KBAICommentView] 加载到 %ld 条评论,共 %ld 条", (long)pageModel.records.count, (long)pageModel.total);
for (KBCommentItem *item in pageModel.records) {
// KBAICommentModel使 MJExtension
KBAICommentModel *comment = [KBAICommentModel mj_objectWithKeyValues:[item mj_keyValues]];
2026-01-16 19:09:54 +08:00
// Header
2026-01-28 12:04:31 +08:00
comment.cachedHeaderHeight = [comment calculateHeaderHeightWithMaxWidth:tableWidth];
2026-01-16 19:09:54 +08:00
// Reply
for (KBAIReplyModel *reply in comment.replies) {
2026-01-28 12:04:31 +08:00
reply.cachedCellHeight = [reply calculateCellHeightWithMaxWidth:tableWidth];
2026-01-16 19:09:54 +08:00
}
2026-01-28 12:04:31 +08:00
2026-01-16 15:55:08 +08:00
[self.comments addObject:comment];
}
2026-01-28 12:04:31 +08:00
2026-01-16 15:55:08 +08:00
[self updateTitle];
[self.tableView reloadData];
}
- (void)updateTitle {
NSString *countText;
if (self.totalCommentCount >= 10000) {
countText = [NSString
stringWithFormat:@"%.1fw条评论", self.totalCommentCount / 10000.0];
} else {
countText =
[NSString stringWithFormat:@"%ld条评论", (long)self.totalCommentCount];
}
self.titleLabel.text = countText;
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.comments.count;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
KBAICommentModel *comment = self.comments[section];
return comment.displayedReplies.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
KBAIReplyCell *cell =
[tableView dequeueReusableCellWithIdentifier:kReplyCellIdentifier
forIndexPath:indexPath];
KBAICommentModel *comment = self.comments[indexPath.section];
KBAIReplyModel *reply = comment.displayedReplies[indexPath.row];
[cell configureWithReply:reply];
__weak typeof(self) weakSelf = self;
cell.onLikeAction = ^{
2026-01-28 13:55:11 +08:00
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
// ID NSInteger
NSInteger commentId = [reply.replyId integerValue];
//
[strongSelf.aiVM likeCommentWithCommentId:commentId completion:^(KBCommentLikeResponse * _Nullable response, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"[KBAICommentView] 二级评论点赞失败:%@", error.localizedDescription);
// TODO:
return;
}
if (response && response.code == 0) {
// data = true: data = false:
BOOL isNowLiked = response.data;
//
if (isNowLiked) {
// +1
reply.isLiked = YES;
reply.likeCount = MAX(0, reply.likeCount + 1);
NSLog(@"[KBAICommentView] 二级评论点赞成功ID: %ld", (long)commentId);
} else {
// -1
reply.isLiked = NO;
reply.likeCount = MAX(0, reply.likeCount - 1);
NSLog(@"[KBAICommentView] 二级评论取消点赞成功ID: %ld", (long)commentId);
}
//
[strongSelf.tableView reloadRowsAtIndexPaths:@[ indexPath ]
withRowAnimation:UITableViewRowAnimationNone];
} else {
NSLog(@"[KBAICommentView] 二级评论点赞失败:%@", response.message ?: @"未知错误");
// TODO:
}
});
}];
2026-01-16 15:55:08 +08:00
};
2026-01-16 20:44:10 +08:00
2026-01-16 20:31:42 +08:00
cell.onReplyAction = ^{
[weakSelf setReplyToComment:comment reply:reply];
};
2026-01-16 15:55:08 +08:00
return cell;
}
#pragma mark - UITableViewDelegate
- (UIView *)tableView:(UITableView *)tableView
viewForHeaderInSection:(NSInteger)section {
KBAICommentHeaderView *header = [tableView
dequeueReusableHeaderFooterViewWithIdentifier:kCommentHeaderIdentifier];
KBAICommentModel *comment = self.comments[section];
[header configureWithComment:comment];
__weak typeof(self) weakSelf = self;
header.onLikeAction = ^{
2026-01-28 13:55:11 +08:00
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
// ID NSInteger
NSInteger commentId = [comment.commentId integerValue];
//
[strongSelf.aiVM likeCommentWithCommentId:commentId completion:^(KBCommentLikeResponse * _Nullable response, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"[KBAICommentView] 一级评论点赞失败:%@", error.localizedDescription);
// TODO:
return;
}
if (response && response.code == 0) {
// data = true: data = false:
BOOL isNowLiked = response.data;
//
if (isNowLiked) {
// +1
comment.liked = YES;
comment.likeCount = MAX(0, comment.likeCount + 1);
NSLog(@"[KBAICommentView] 一级评论点赞成功ID: %ld", (long)commentId);
} else {
// -1
comment.liked = NO;
comment.likeCount = MAX(0, comment.likeCount - 1);
NSLog(@"[KBAICommentView] 一级评论取消点赞成功ID: %ld", (long)commentId);
}
// section
[strongSelf.tableView reloadSections:[NSIndexSet indexSetWithIndex:section]
withRowAnimation:UITableViewRowAnimationNone];
} else {
NSLog(@"[KBAICommentView] 一级评论点赞失败:%@", response.message ?: @"未知错误");
// TODO:
}
});
}];
2026-01-16 15:55:08 +08:00
};
2026-01-16 20:44:10 +08:00
2026-01-16 20:31:42 +08:00
header.onReplyAction = ^{
[weakSelf setReplyToComment:comment reply:nil];
};
2026-01-16 15:55:08 +08:00
return header;
}
- (UIView *)tableView:(UITableView *)tableView
viewForFooterInSection:(NSInteger)section {
KBAICommentModel *comment = self.comments[section];
KBAIReplyFooterState state = [comment footerState];
//
if (state == KBAIReplyFooterStateHidden) {
return nil;
}
KBAICommentFooterView *footer = [tableView
dequeueReusableHeaderFooterViewWithIdentifier:kCommentFooterIdentifier];
[footer configureWithComment:comment];
__weak typeof(self) weakSelf = self;
footer.onAction = ^{
[weakSelf handleFooterActionForSection:section];
};
return footer;
}
- (CGFloat)tableView:(UITableView *)tableView
heightForHeaderInSection:(NSInteger)section {
2026-01-16 19:09:54 +08:00
KBAICommentModel *comment = self.comments[section];
return comment.cachedHeaderHeight;
}
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath {
KBAICommentModel *comment = self.comments[indexPath.section];
KBAIReplyModel *reply = comment.displayedReplies[indexPath.row];
return reply.cachedCellHeight;
2026-01-16 15:55:08 +08:00
}
- (CGFloat)tableView:(UITableView *)tableView
heightForFooterInSection:(NSInteger)section {
KBAICommentModel *comment = self.comments[section];
KBAIReplyFooterState state = [comment footerState];
if (state == KBAIReplyFooterStateHidden) {
return CGFLOAT_MIN;
}
return 30;
}
#pragma mark - Footer Actions
///
static NSInteger const kRepliesLoadCount = 5;
2026-01-16 15:55:08 +08:00
- (void)handleFooterActionForSection:(NSInteger)section {
KBAICommentModel *comment = self.comments[section];
KBAIReplyFooterState state = [comment footerState];
switch (state) {
case KBAIReplyFooterStateExpand:
case KBAIReplyFooterStateLoadMore: {
[self loadMoreRepliesForSection:section];
2026-01-16 15:55:08 +08:00
break;
}
case KBAIReplyFooterStateCollapse: {
[self collapseRepliesForSection:section];
break;
}
default:
break;
}
}
- (void)loadMoreRepliesForSection:(NSInteger)section {
2026-01-16 15:55:08 +08:00
KBAICommentModel *comment = self.comments[section];
NSInteger currentCount = comment.displayedReplies.count;
2026-01-16 20:44:10 +08:00
//
[comment loadMoreReplies:kRepliesLoadCount];
2026-01-16 20:44:10 +08:00
//
NSInteger newCount = comment.displayedReplies.count;
NSMutableArray *insertIndexPaths = [NSMutableArray array];
for (NSInteger i = currentCount; i < newCount; i++) {
2026-01-16 20:44:10 +08:00
[insertIndexPaths addObject:[NSIndexPath indexPathForRow:i
inSection:section]];
}
2026-01-16 20:44:10 +08:00
// Header
[self.tableView beginUpdates];
if (insertIndexPaths.count > 0) {
[self.tableView insertRowsAtIndexPaths:insertIndexPaths
withRowAnimation:UITableViewRowAnimationAutomatic];
}
[self.tableView endUpdates];
2026-01-16 20:44:10 +08:00
// Footer
KBAICommentFooterView *footerView =
(KBAICommentFooterView *)[self.tableView footerViewForSection:section];
if (footerView) {
[footerView configureWithComment:comment];
}
2026-01-16 15:55:08 +08:00
}
- (void)collapseRepliesForSection:(NSInteger)section {
KBAICommentModel *comment = self.comments[section];
NSInteger rowCount = comment.displayedReplies.count;
2026-01-16 20:44:10 +08:00
//
NSMutableArray *deleteIndexPaths = [NSMutableArray array];
for (NSInteger i = 0; i < rowCount; i++) {
2026-01-16 20:44:10 +08:00
[deleteIndexPaths addObject:[NSIndexPath indexPathForRow:i
inSection:section]];
}
2026-01-16 20:44:10 +08:00
2026-01-16 19:09:54 +08:00
//
2026-01-16 15:55:08 +08:00
[comment collapseReplies];
2026-01-16 20:44:10 +08:00
// Header
[self.tableView beginUpdates];
if (deleteIndexPaths.count > 0) {
[self.tableView deleteRowsAtIndexPaths:deleteIndexPaths
withRowAnimation:UITableViewRowAnimationAutomatic];
}
[self.tableView endUpdates];
2026-01-16 20:44:10 +08:00
// Footer
KBAICommentFooterView *footerView =
(KBAICommentFooterView *)[self.tableView footerViewForSection:section];
if (footerView) {
[footerView configureWithComment:comment];
}
2026-01-16 15:55:08 +08:00
}
#pragma mark - Actions
- (void)closeButtonTapped {
2026-01-28 12:04:31 +08:00
[self.popView dismiss];
2026-01-16 15:55:08 +08:00
//
2026-01-28 12:04:31 +08:00
// [[NSNotificationCenter defaultCenter]
// postNotificationName:@"KBAICommentViewCloseNotification"
// object:nil];
2026-01-16 15:55:08 +08:00
}
#pragma mark - Lazy Loading
2026-01-28 13:43:36 +08:00
- (UIVisualEffectView *)blurBackgroundView {
if (!_blurBackgroundView) {
// 43pt
// iOS UIBlurEffect API使 dark
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
_blurBackgroundView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
//
// #0000000.31
UIView *darkOverlay = [[UIView alloc] init];
darkOverlay.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.31];
[_blurBackgroundView.contentView addSubview:darkOverlay];
[darkOverlay mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(_blurBackgroundView);
}];
}
return _blurBackgroundView;
}
2026-01-16 15:55:08 +08:00
- (UIView *)headerView {
if (!_headerView) {
_headerView = [[UIView alloc] init];
2026-01-28 13:43:36 +08:00
_headerView.backgroundColor = [UIColor clearColor];
2026-01-16 15:55:08 +08:00
}
return _headerView;
}
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.font = [UIFont systemFontOfSize:15 weight:UIFontWeightMedium];
2026-01-28 13:43:36 +08:00
_titleLabel.textColor = [UIColor whiteColor];
2026-01-16 15:55:08 +08:00
_titleLabel.text = @"0条评论";
}
return _titleLabel;
}
- (UIButton *)closeButton {
if (!_closeButton) {
_closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
2026-01-28 13:55:11 +08:00
[_closeButton setImage:[UIImage imageNamed:@"comment_close_icon"]
2026-01-16 15:55:08 +08:00
forState:UIControlStateNormal];
[_closeButton addTarget:self
action:@selector(closeButtonTapped)
forControlEvents:UIControlEventTouchUpInside];
}
return _closeButton;
}
2026-01-16 19:09:54 +08:00
- (BaseTableView *)tableView {
2026-01-16 15:55:08 +08:00
if (!_tableView) {
2026-01-16 19:09:54 +08:00
_tableView = [[BaseTableView alloc] initWithFrame:CGRectZero
2026-01-16 20:44:10 +08:00
style:UITableViewStyleGrouped];
2026-01-16 15:55:08 +08:00
_tableView.dataSource = self;
_tableView.delegate = self;
2026-01-28 13:43:36 +08:00
_tableView.backgroundColor = [UIColor clearColor];
2026-01-16 15:55:08 +08:00
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
// Header/Cell/Footer
[_tableView registerClass:[KBAICommentHeaderView class]
forHeaderFooterViewReuseIdentifier:kCommentHeaderIdentifier];
[_tableView registerClass:[KBAIReplyCell class]
forCellReuseIdentifier:kReplyCellIdentifier];
[_tableView registerClass:[KBAICommentFooterView class]
forHeaderFooterViewReuseIdentifier:kCommentFooterIdentifier];
//
if (@available(iOS 15.0, *)) {
_tableView.sectionHeaderTopPadding = 0;
}
}
return _tableView;
}
- (KBAICommentInputView *)inputView {
if (!_inputView) {
_inputView = [[KBAICommentInputView alloc] init];
_inputView.placeholder = @"说点什么...";
__weak typeof(self) weakSelf = self;
_inputView.onSend = ^(NSString *text) {
2026-01-16 19:36:41 +08:00
[weakSelf sendCommentWithText:text];
2026-01-16 15:55:08 +08:00
};
}
return _inputView;
}
2026-01-16 20:31:42 +08:00
#pragma mark - Reply
2026-01-16 20:44:10 +08:00
- (void)setReplyToComment:(KBAICommentModel *)comment
reply:(KBAIReplyModel *)reply {
2026-01-16 20:31:42 +08:00
self.replyToComment = comment;
self.replyToReply = reply;
2026-01-16 20:44:10 +08:00
2026-01-16 20:31:42 +08:00
if (reply) {
//
2026-01-16 20:44:10 +08:00
self.inputView.placeholder =
[NSString stringWithFormat:@"回复 @%@", reply.userName];
2026-01-16 20:31:42 +08:00
} else if (comment) {
//
2026-01-16 20:44:10 +08:00
self.inputView.placeholder =
[NSString stringWithFormat:@"回复 @%@", comment.userName];
2026-01-16 20:31:42 +08:00
} else {
//
self.inputView.placeholder = @"说点什么...";
}
2026-01-16 20:44:10 +08:00
//
[self.inputView showKeyboard];
2026-01-16 20:31:42 +08:00
}
- (void)clearReplyTarget {
self.replyToComment = nil;
self.replyToReply = nil;
self.inputView.placeholder = @"说点什么...";
}
2026-01-16 19:36:41 +08:00
#pragma mark - Send Comment
- (void)sendCommentWithText:(NSString *)text {
2026-01-16 20:44:10 +08:00
if (text.length == 0)
return;
2026-01-16 20:31:42 +08:00
CGFloat tableWidth = self.tableView.bounds.size.width;
if (tableWidth <= 0) {
tableWidth = [UIScreen mainScreen].bounds.size.width;
}
2026-01-16 20:44:10 +08:00
2026-01-16 20:31:42 +08:00
if (self.replyToComment) {
//
[self sendReplyWithText:text tableWidth:tableWidth];
} else {
//
[self sendNewCommentWithText:text tableWidth:tableWidth];
}
2026-01-16 20:44:10 +08:00
2026-01-16 20:31:42 +08:00
//
[self.inputView clearText];
[self clearReplyTarget];
}
- (void)sendNewCommentWithText:(NSString *)text tableWidth:(CGFloat)tableWidth {
2026-01-28 12:04:31 +08:00
// TODO:
NSLog(@"[KBAICommentView] 发送一级评论:%@", text);
//
// [self.aiVM sendCommentWithCompanionId:self.companionId
// content:text
// completion:^(KBCommentItem *newItem, NSError *error) {
// if (error) {
// NSLog(@"[KBAICommentView] 发送评论失败:%@", error.localizedDescription);
// return;
// }
//
// // KBAICommentModel
// KBAICommentModel *comment = [KBAICommentModel mj_objectWithKeyValues:[newItem mj_keyValues]];
// comment.cachedHeaderHeight = [comment calculateHeaderHeightWithMaxWidth:tableWidth];
//
// //
// [self.comments insertObject:comment atIndex:0];
// self.totalCommentCount++;
// [self updateTitle];
//
// // section
// [self.tableView insertSections:[NSIndexSet indexSetWithIndex:0]
// withRowAnimation:UITableViewRowAnimationAutomatic];
//
// //
// [self.tableView setContentOffset:CGPointZero animated:YES];
// }];
2026-01-16 20:31:42 +08:00
}
- (void)sendReplyWithText:(NSString *)text tableWidth:(CGFloat)tableWidth {
KBAICommentModel *comment = self.replyToComment;
2026-01-16 20:44:10 +08:00
if (!comment)
return;
2026-01-28 12:04:31 +08:00
// TODO:
NSLog(@"[KBAICommentView] 回复评论 %@%@", comment.commentId, text);
//
// NSInteger parentId = [comment.commentId integerValue];
// [self.aiVM replyCommentWithParentId:parentId
// content:text
// completion:^(KBCommentItem *newItem, NSError *error) {
// if (error) {
// NSLog(@"[KBAICommentView] 回复评论失败:%@", error.localizedDescription);
// return;
// }
//
// // KBAIReplyModel
// KBAIReplyModel *newReply = [KBAIReplyModel mj_objectWithKeyValues:[newItem mj_keyValues]];
// newReply.cachedCellHeight = [newReply calculateCellHeightWithMaxWidth:tableWidth];
//
// // replies
// NSMutableArray *newReplies = [NSMutableArray arrayWithArray:comment.replies];
// [newReplies addObject:newReply];
// comment.replies = newReplies;
// comment.totalReplyCount = newReplies.count;
//
// // section
// NSInteger section = [self.comments indexOfObject:comment];
// if (section == NSNotFound) return;
//
// // displayedReplies
// if (comment.isRepliesExpanded) {
// NSInteger newRowIndex = comment.displayedReplies.count;
// [comment.displayedReplies addObject:newReply];
//
// NSIndexPath *indexPath = [NSIndexPath indexPathForRow:newRowIndex inSection:section];
// [self.tableView insertRowsAtIndexPaths:@[indexPath]
// withRowAnimation:UITableViewRowAnimationAutomatic];
//
// // Footer
// KBAICommentFooterView *footerView = (KBAICommentFooterView *)[self.tableView footerViewForSection:section];
// if (footerView) {
// [footerView configureWithComment:comment];
// }
//
// //
// [self.tableView scrollToRowAtIndexPath:indexPath
// atScrollPosition:UITableViewScrollPositionBottom
// animated:YES];
// } else {
// // Footer
// KBAICommentFooterView *footerView = (KBAICommentFooterView *)[self.tableView footerViewForSection:section];
// if (footerView) {
// [footerView configureWithComment:comment];
// }
// }
// }];
}
2026-01-16 20:44:10 +08:00
2026-01-28 12:04:31 +08:00
- (AiVM *)aiVM {
if (!_aiVM) {
_aiVM = [[AiVM alloc] init];
2026-01-16 20:31:42 +08:00
}
2026-01-28 12:04:31 +08:00
return _aiVM;
2026-01-16 19:36:41 +08:00
}
@end