diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Controller/MainViewController/MainViewController+Input.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Controller/MainViewController/MainViewController+Input.swift index 549f17d57f..260621dd39 100644 --- a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Controller/MainViewController/MainViewController+Input.swift +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Controller/MainViewController/MainViewController+Input.swift @@ -79,18 +79,15 @@ extension MainViewController: InputBoxDelegate { Task { @MainActor in do { - // Ensure we have a current session or create one let chatManager = ChatManager.shared if let currentSession = chatManager.currentSession { - // Send message to existing session try await chatManager.sendMessage( content: inputData.text, attachments: [], // TODO: Handle attachments sessionId: currentSession.id ) } else { - // Create new session first guard let workspaceId = IntelligentContext.shared.webViewMetadata[.currentWorkspaceId] as? String, !workspaceId.isEmpty else { @@ -100,7 +97,6 @@ extension MainViewController: InputBoxDelegate { let session = try await chatManager.createSession(workspaceId: workspaceId) - // Send message to new session try await chatManager.sendMessage( content: inputData.text, attachments: [], // TODO: Handle attachments @@ -108,7 +104,6 @@ extension MainViewController: InputBoxDelegate { ) } - // Clear input after successful send inputBox.text = "" inputBox.viewModel.clearAllAttachments() diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Controller/MainViewController/MainViewController.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Controller/MainViewController/MainViewController.swift index d3fc723020..e611c4c773 100644 --- a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Controller/MainViewController/MainViewController.swift +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Controller/MainViewController/MainViewController.swift @@ -10,6 +10,27 @@ class MainViewController: UIViewController { $0.delegate = self } + lazy var tableView = UITableView().then { + $0.backgroundColor = .clear + $0.separatorStyle = .none + $0.delegate = self + $0.dataSource = self + $0.register(ChatCell.self, forCellReuseIdentifier: "ChatCell") + $0.keyboardDismissMode = .interactive + $0.contentInsetAdjustmentBehavior = .never + } + + lazy var emptyStateView = UIView().then { + $0.isHidden = true + } + + lazy var emptyStateLabel = UILabel().then { + $0.text = "Start a conversation..." + $0.font = .systemFont(ofSize: 18, weight: .medium) + $0.textColor = .systemGray + $0.textAlignment = .center + } + lazy var inputBox = InputBox().then { $0.delegate = self } @@ -28,8 +49,10 @@ class MainViewController: UIViewController { // MARK: - Properties + private var messages: [ChatMessage] = [] private var cancellables = Set() private let intelligentContext = IntelligentContext.shared + private let chatManager = ChatManager.shared var terminateEditGesture: UITapGestureRecognizer! // MARK: - Lifecycle @@ -38,21 +61,46 @@ class MainViewController: UIViewController { super.viewDidLoad() view.backgroundColor = .affineLayerBackgroundPrimary - let inputBox = InputBox().then { - $0.delegate = self - } - self.inputBox = inputBox + setupUI() + setupBindings() + view.isUserInteractionEnabled = true + terminateEditGesture = UITapGestureRecognizer(target: self, action: #selector(terminateEditing)) + view.addGestureRecognizer(terminateEditGesture) + } + + // MARK: - Setup + + private func setupUI() { view.addSubview(headerView) + view.addSubview(tableView) + view.addSubview(emptyStateView) view.addSubview(inputBox) view.addSubview(documentPickerHideDetector) view.addSubview(documentPickerView) + emptyStateView.addSubview(emptyStateLabel) + headerView.snp.makeConstraints { make in make.top.equalTo(view.safeAreaLayoutGuide) make.leading.trailing.equalToSuperview() } + tableView.snp.makeConstraints { make in + make.top.equalTo(headerView.snp.bottom) + make.leading.trailing.equalToSuperview() + make.bottom.equalTo(inputBox.snp.top) + } + + emptyStateView.snp.makeConstraints { make in + make.center.equalTo(tableView) + make.width.lessThanOrEqualTo(tableView).inset(32) + } + + emptyStateLabel.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + inputBox.snp.makeConstraints { make in make.leading.trailing.equalToSuperview() make.bottom.equalTo(view.keyboardLayoutGuide.snp.top) @@ -67,10 +115,24 @@ class MainViewController: UIViewController { make.leading.trailing.equalToSuperview() make.height.equalTo(500) } + } - view.isUserInteractionEnabled = true - terminateEditGesture = UITapGestureRecognizer(target: self, action: #selector(terminateEditing)) - view.addGestureRecognizer(terminateEditGesture) + private func setupBindings() { + chatManager.$currentSession + .receive(on: DispatchQueue.main) + .sink { [weak self] session in + self?.updateMessages(for: session?.id) + } + .store(in: &cancellables) + + chatManager.$messages + .receive(on: DispatchQueue.main) + .sink { [weak self] _ in + if let sessionId = self?.chatManager.currentSession?.id { + self?.updateMessages(for: sessionId) + } + } + .store(in: &cancellables) } override func viewWillAppear(_ animated: Bool) { @@ -90,4 +152,66 @@ class MainViewController: UIViewController { @objc func terminateEditing() { view.endEditing(true) } + + // MARK: - Chat Methods + + private func updateMessages(for sessionId: String?) { + guard let sessionId else { + messages = [] + updateEmptyState() + tableView.reloadData() + return + } + + messages = chatManager.messages[sessionId] ?? [] + updateEmptyState() + tableView.reloadData() + + if !messages.isEmpty { + let indexPath = IndexPath(row: messages.count - 1, section: 0) + tableView.scrollToRow(at: indexPath, at: .bottom, animated: true) + } + } + + private func updateEmptyState() { + emptyStateView.isHidden = !messages.isEmpty + tableView.isHidden = messages.isEmpty + } + + // MARK: - Internal Methods for Preview/Testing + + #if DEBUG + func setMessagesForPreview(_ previewMessages: [ChatMessage]) { + messages = previewMessages + updateEmptyState() + tableView.reloadData() + } + #endif +} + +// MARK: - UITableViewDataSource + +extension MainViewController: UITableViewDataSource { + func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { + messages.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "ChatCell", for: indexPath) as! ChatCell + let message = messages[indexPath.row] + cell.configure(with: message) + return cell + } +} + +// MARK: - UITableViewDelegate + +extension MainViewController: UITableViewDelegate { + func tableView(_: UITableView, heightForRowAt _: IndexPath) -> CGFloat { + UITableView.automaticDimension + } + + func tableView(_: UITableView, estimatedHeightForRowAt _: IndexPath) -> CGFloat { + 60 + } } diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ChatCell.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ChatCell.swift new file mode 100644 index 0000000000..b56b880996 --- /dev/null +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ChatCell.swift @@ -0,0 +1,155 @@ +// +// ChatCell.swift +// Intelligents +// +// Created by 秋星桥 on 6/26/25. +// + +import SnapKit +import Then +import UIKit + +class ChatCell: UITableViewCell { + // MARK: - UI Components + + private lazy var avatarImageView = UIImageView().then { + $0.contentMode = .scaleAspectFit + $0.layer.cornerRadius = 16 + $0.layer.cornerCurve = .continuous + $0.clipsToBounds = true + $0.backgroundColor = .systemGray5 + } + + private lazy var messageContainerView = UIView().then { + $0.layer.cornerRadius = 12 + $0.layer.cornerCurve = .continuous + } + + private lazy var messageLabel = UILabel().then { + $0.numberOfLines = 0 + $0.font = .systemFont(ofSize: 16) + $0.textColor = .label + } + + private lazy var timestampLabel = UILabel().then { + $0.font = .systemFont(ofSize: 12) + $0.textColor = .systemGray + $0.textAlignment = .right + } + + private lazy var stackView = UIStackView().then { + $0.axis = .horizontal + $0.spacing = 12 + $0.alignment = .top + } + + private lazy var messageStackView = UIStackView().then { + $0.axis = .vertical + $0.spacing = 4 + } + + // MARK: - Properties + + private var message: ChatMessage? + + // MARK: - Initialization + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + setupUI() + } + + @available(*, unavailable) + required init?(coder _: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Setup + + private func setupUI() { + backgroundColor = .clear + selectionStyle = .none + + contentView.addSubview(stackView) + + messageStackView.addArrangedSubview(messageContainerView) + messageStackView.addArrangedSubview(timestampLabel) + + messageContainerView.addSubview(messageLabel) + + stackView.addArrangedSubview(avatarImageView) + stackView.addArrangedSubview(messageStackView) + + stackView.snp.makeConstraints { make in + make.edges.equalToSuperview().inset(16) + } + + avatarImageView.snp.makeConstraints { make in + make.size.equalTo(32) + } + + messageLabel.snp.makeConstraints { make in + make.edges.equalToSuperview().inset(12) + } + + messageStackView.snp.makeConstraints { make in + make.width.lessThanOrEqualTo(250) + } + } + + // MARK: - Configuration + + func configure(with message: ChatMessage) { + self.message = message + + messageLabel.text = message.content + + if let createdDate = message.createdDate { + let formatter = DateFormatter() + formatter.dateStyle = .none + formatter.timeStyle = .short + timestampLabel.text = formatter.string(from: createdDate) + } else { + timestampLabel.text = "" + } + + switch message.role { + case .user: + configureUserMessage() + case .assistant: + configureAssistantMessage() + case .system: + configureSystemMessage() + } + } + + private func configureUserMessage() { + // User message - align to right + stackView.semanticContentAttribute = .forceRightToLeft + messageContainerView.backgroundColor = .systemBlue + messageLabel.textColor = .white + avatarImageView.image = UIImage(systemName: "person.circle.fill") + avatarImageView.tintColor = .systemBlue + timestampLabel.textAlignment = .left + } + + private func configureAssistantMessage() { + // Assistant message - align to left + stackView.semanticContentAttribute = .forceLeftToRight + messageContainerView.backgroundColor = .systemGray6 + messageLabel.textColor = .label + avatarImageView.image = UIImage(systemName: "brain.head.profile") + avatarImageView.tintColor = .systemPurple + timestampLabel.textAlignment = .right + } + + private func configureSystemMessage() { + // System message - center aligned + stackView.semanticContentAttribute = .forceLeftToRight + messageContainerView.backgroundColor = .systemYellow.withAlphaComponent(0.3) + messageLabel.textColor = .label + avatarImageView.image = UIImage(systemName: "gear") + avatarImageView.tintColor = .systemOrange + timestampLabel.textAlignment = .center + } +} diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/AttachmentCellViewModel.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/AttachmentCellViewModel.swift similarity index 100% rename from packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/AttachmentCellViewModel.swift rename to packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/AttachmentCellViewModel.swift diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/CellType.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/CellType.swift similarity index 100% rename from packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/CellType.swift rename to packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/CellType.swift diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/ChatCellViewModels.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/ChatCellViewModels.swift similarity index 100% rename from packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/ChatCellViewModels.swift rename to packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/ChatCellViewModels.swift diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/ContextReferenceCellViewModel.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/ContextReferenceCellViewModel.swift similarity index 100% rename from packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/ContextReferenceCellViewModel.swift rename to packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/ContextReferenceCellViewModel.swift diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/ErrorCellViewModel.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/ErrorCellViewModel.swift similarity index 100% rename from packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/ErrorCellViewModel.swift rename to packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/ErrorCellViewModel.swift diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/LoadingCellViewModel.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/LoadingCellViewModel.swift similarity index 100% rename from packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/LoadingCellViewModel.swift rename to packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/LoadingCellViewModel.swift diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/WorkflowStatusCellViewModel.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/WorkflowStatusCellViewModel.swift similarity index 100% rename from packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ViewModel/WorkflowStatusCellViewModel.swift rename to packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatCell/ViewModel/WorkflowStatusCellViewModel.swift diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ChatCell.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ChatCell.swift deleted file mode 100644 index 7efa6031b2..0000000000 --- a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ChatCell.swift +++ /dev/null @@ -1,157 +0,0 @@ -// -// ChatCell.swift -// Intelligents -// -// Created by 秋星桥 on 6/26/25. -// - -import SnapKit -import Then -import UIKit - -extension ChatListView { - class ChatCell: UITableViewCell { - // MARK: - UI Components - - private lazy var avatarImageView = UIImageView().then { - $0.contentMode = .scaleAspectFit - $0.layer.cornerRadius = 16 - $0.layer.cornerCurve = .continuous - $0.clipsToBounds = true - $0.backgroundColor = .systemGray5 - } - - private lazy var messageContainerView = UIView().then { - $0.layer.cornerRadius = 12 - $0.layer.cornerCurve = .continuous - } - - private lazy var messageLabel = UILabel().then { - $0.numberOfLines = 0 - $0.font = .systemFont(ofSize: 16) - $0.textColor = .label - } - - private lazy var timestampLabel = UILabel().then { - $0.font = .systemFont(ofSize: 12) - $0.textColor = .systemGray - $0.textAlignment = .right - } - - private lazy var stackView = UIStackView().then { - $0.axis = .horizontal - $0.spacing = 12 - $0.alignment = .top - } - - private lazy var messageStackView = UIStackView().then { - $0.axis = .vertical - $0.spacing = 4 - } - - // MARK: - Properties - - private var message: ChatMessage? - - // MARK: - Initialization - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - setupUI() - } - - @available(*, unavailable) - required init?(coder _: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - // MARK: - Setup - - private func setupUI() { - backgroundColor = .clear - selectionStyle = .none - - contentView.addSubview(stackView) - - messageStackView.addArrangedSubview(messageContainerView) - messageStackView.addArrangedSubview(timestampLabel) - - messageContainerView.addSubview(messageLabel) - - stackView.addArrangedSubview(avatarImageView) - stackView.addArrangedSubview(messageStackView) - - stackView.snp.makeConstraints { make in - make.edges.equalToSuperview().inset(16) - } - - avatarImageView.snp.makeConstraints { make in - make.size.equalTo(32) - } - - messageLabel.snp.makeConstraints { make in - make.edges.equalToSuperview().inset(12) - } - - messageStackView.snp.makeConstraints { make in - make.width.lessThanOrEqualTo(250) - } - } - - // MARK: - Configuration - - func configure(with message: ChatMessage) { - self.message = message - - messageLabel.text = message.content - - if let createdDate = message.createdDate { - let formatter = DateFormatter() - formatter.dateStyle = .none - formatter.timeStyle = .short - timestampLabel.text = formatter.string(from: createdDate) - } else { - timestampLabel.text = "" - } - - switch message.role { - case .user: - configureUserMessage() - case .assistant: - configureAssistantMessage() - case .system: - configureSystemMessage() - } - } - - private func configureUserMessage() { - // User message - align to right - stackView.semanticContentAttribute = .forceRightToLeft - messageContainerView.backgroundColor = .systemBlue - messageLabel.textColor = .white - avatarImageView.image = UIImage(systemName: "person.circle.fill") - avatarImageView.tintColor = .systemBlue - timestampLabel.textAlignment = .left - } - - private func configureAssistantMessage() { - // Assistant message - align to left - stackView.semanticContentAttribute = .forceLeftToRight - messageContainerView.backgroundColor = .systemGray6 - messageLabel.textColor = .label - avatarImageView.image = UIImage(systemName: "brain.head.profile") - avatarImageView.tintColor = .systemPurple - timestampLabel.textAlignment = .right - } - - private func configureSystemMessage() { - // System message - center aligned - stackView.semanticContentAttribute = .forceLeftToRight - messageContainerView.backgroundColor = .systemYellow.withAlphaComponent(0.3) - messageLabel.textColor = .label - avatarImageView.image = UIImage(systemName: "gear") - avatarImageView.tintColor = .systemOrange - timestampLabel.textAlignment = .center - } - } -} diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ChatListView.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ChatListView.swift deleted file mode 100644 index ab2bb81c92..0000000000 --- a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/ChatListView/ChatListView.swift +++ /dev/null @@ -1,150 +0,0 @@ -// -// ChatListView.swift -// Intelligents -// -// Created by 秋星桥 on 6/26/25. -// - -import AffineGraphQL -import Combine -import SnapKit -import Then -import UIKit - -class ChatListView: UIView { - // MARK: - UI Components - - lazy var tableView = UITableView().then { - $0.backgroundColor = .clear - $0.separatorStyle = .none - $0.delegate = self - $0.dataSource = self - $0.register(ChatCell.self, forCellReuseIdentifier: "ChatCell") - $0.keyboardDismissMode = .interactive - $0.contentInsetAdjustmentBehavior = .never - } - - lazy var emptyStateView = UIView().then { - $0.isHidden = true - } - - lazy var emptyStateLabel = UILabel().then { - $0.text = "Start a conversation..." - $0.font = .systemFont(ofSize: 18, weight: .medium) - $0.textColor = .systemGray - $0.textAlignment = .center - } - - // MARK: - Properties - - private var messages: [ChatMessage] = [] - private var cancellables = Set() - private let chatManager = ChatManager.shared - - // MARK: - Initialization - - override init(frame: CGRect) { - super.init(frame: frame) - setupUI() - setupBindings() - } - - @available(*, unavailable) - required init?(coder _: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - // MARK: - Setup - - private func setupUI() { - backgroundColor = .affineLayerBackgroundPrimary - - addSubview(tableView) - addSubview(emptyStateView) - emptyStateView.addSubview(emptyStateLabel) - - tableView.snp.makeConstraints { make in - make.edges.equalToSuperview() - } - - emptyStateView.snp.makeConstraints { make in - make.center.equalToSuperview() - make.width.lessThanOrEqualToSuperview().inset(32) - } - - emptyStateLabel.snp.makeConstraints { make in - make.edges.equalToSuperview() - } - } - - private func setupBindings() { - // Listen to current session changes - chatManager.$currentSession - .receive(on: DispatchQueue.main) - .sink { [weak self] session in - self?.updateMessages(for: session?.id) - } - .store(in: &cancellables) - - // Listen to messages changes - chatManager.$messages - .receive(on: DispatchQueue.main) - .sink { [weak self] _ in - if let sessionId = self?.chatManager.currentSession?.id { - self?.updateMessages(for: sessionId) - } - } - .store(in: &cancellables) - } - - private func updateMessages(for sessionId: String?) { - guard let sessionId else { - messages = [] - updateEmptyState() - tableView.reloadData() - return - } - - messages = chatManager.messages[sessionId] ?? [] - updateEmptyState() - tableView.reloadData() - - // Scroll to bottom for new messages - if !messages.isEmpty { - let indexPath = IndexPath(row: messages.count - 1, section: 0) - tableView.scrollToRow(at: indexPath, at: .bottom, animated: true) - } - } - - private func updateEmptyState() { - emptyStateView.isHidden = !messages.isEmpty - tableView.isHidden = messages.isEmpty - } -} - -// MARK: - UITableViewDataSource - -extension ChatListView: UITableViewDataSource { - func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { - messages.count - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "ChatCell", for: indexPath) as! ChatCell - let message = messages[indexPath.row] - cell.configure(with: message) - return cell - } -} - -// MARK: - UITableViewDelegate - -extension ChatListView: UITableViewDelegate { - func tableView(_: UITableView, heightForRowAt _: IndexPath) -> CGFloat { - UITableView.automaticDimension - } - - func tableView(_: UITableView, estimatedHeightForRowAt _: IndexPath) -> CGFloat { - 60 - } -} diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/ViewModel/InputBoxViewModel.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/ViewModel/InputBoxViewModel.swift index 6a5b06fd6f..83e6c364d8 100644 --- a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/ViewModel/InputBoxViewModel.swift +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/ViewModel/InputBoxViewModel.swift @@ -66,7 +66,7 @@ public class InputBoxViewModel: ObservableObject { .assign(to: \.canSend, on: self) .store(in: &cancellables) } - + public func clearAllAttachments() { imageAttachments.removeAll() fileAttachments.removeAll()