diff --git a/packages/frontend/apps/ios/App/App.xcworkspace/xcshareddata/swiftpm/Package.resolved b/packages/frontend/apps/ios/App/App.xcworkspace/xcshareddata/swiftpm/Package.resolved index 6c76aeb265..0973b9f21f 100644 --- a/packages/frontend/apps/ios/App/App.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/packages/frontend/apps/ios/App/App.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -45,6 +45,15 @@ "version" : "1.0.4" } }, + { + "identity" : "swifterswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SwifterSwift/SwifterSwift.git", + "state" : { + "revision" : "39fa28c90a3ebe3d53f80289304fd880cf2c42d0", + "version" : "6.2.0" + } + }, { "identity" : "then", "kind" : "remoteSourceControl", diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Package.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Package.swift index eb76742bed..16facb48c6 100644 --- a/packages/frontend/apps/ios/App/Packages/Intelligents/Package.swift +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Package.swift @@ -18,12 +18,14 @@ let package = Package( .package(url: "https://github.com/apple/swift-collections", from: "1.2.0"), .package(url: "https://github.com/devxoul/Then", from: "3.0.0"), .package(url: "https://github.com/SnapKit/SnapKit.git", from: "5.0.1"), + .package(url: "https://github.com/SwifterSwift/SwifterSwift.git", from: "6.0.0") ], targets: [ .target(name: "Intelligents", dependencies: [ "AffineGraphQL", "SnapKit", "Then", + "SwifterSwift", .product(name: "Apollo", package: "apollo-ios"), .product(name: "OrderedCollections", package: "swift-collections"), ], resources: [ diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Controller/MainViewController/MainViewController+Header.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Controller/MainViewController/MainViewController+Header.swift new file mode 100644 index 0000000000..69bc267a05 --- /dev/null +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Controller/MainViewController/MainViewController+Header.swift @@ -0,0 +1,22 @@ +// +// File.swift +// Intelligents +// +// Created by 秋星桥 on 6/19/25. +// + +import UIKit + +extension MainViewController: MainHeaderViewDelegate { + func mainHeaderViewDidTapClose() { + dismiss(animated: true) + } + + func mainHeaderViewDidTapDropdown() { + print(#function) + } + + func mainHeaderViewDidTapMenu() { + print(#function) + } +} 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 new file mode 100644 index 0000000000..b1b4efa52b --- /dev/null +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Controller/MainViewController/MainViewController+Input.swift @@ -0,0 +1,22 @@ +// +// MainViewController+Input.swift +// Intelligents +// +// Created by 秋星桥 on 6/19/25. +// + +import UIKit + +extension MainViewController: InputBoxDelegate { + func inputBoxDidSelectAttachment(_ inputBox: InputBox) { + print(#function, inputBox) + } + + func inputBoxDidSend(_ inputBox: InputBox) { + print(#function, inputBox, inputBox.viewModel) + } + + func inputBoxTextDidChange(_ text: String) { + print(#function, text) + } +} 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 456f7b2ee9..d57faaf982 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 @@ -23,19 +23,15 @@ class MainViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - view.layoutIfNeeded() setupUI() - view.layoutIfNeeded() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) navigationController!.setNavigationBarHidden(true, animated: animated) - } - - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - inputBox.textView.becomeFirstResponder() + DispatchQueue.main.async { + self.inputBox.textView.becomeFirstResponder() + } } override func viewWillDisappear(_ animated: Bool) { @@ -47,19 +43,10 @@ class MainViewController: UIViewController { private func setupUI() { view.backgroundColor = .systemBackground - - // 计算 InputBox 的初始 frame 以避免布局动画 - let inputBoxFrame = CGRect( - x: 0, - y: view.bounds.height - 150, // 预估高度 - width: view.bounds.width, - height: 150 - ) - let inputBox = InputBox(frame: inputBoxFrame).then { + let inputBox = InputBox().then { $0.delegate = self } self.inputBox = inputBox - self.inputBox.layoutIfNeeded() view.addSubview(headerView) view.addSubview(inputBox) @@ -75,37 +62,3 @@ class MainViewController: UIViewController { } } } - -// MARK: - MainHeaderViewDelegate - -extension MainViewController: MainHeaderViewDelegate { - func mainHeaderViewDidTapClose() { - dismiss(animated: true) - } - - func mainHeaderViewDidTapDropdown() { - // TODO: 实现下拉功能 - print("Dropdown tapped") - } - - func mainHeaderViewDidTapMenu() { - // TODO: 实现菜单功能 - print("Menu tapped") - } -} - -// MARK: - InputBoxDelegate - -extension MainViewController: InputBoxDelegate { - func inputBoxDidSelectAttachment(_ inputBox: InputBox) { - print(#function, inputBox) - } - - func inputBoxDidSend(_ inputBox: InputBox) { - print(#function, inputBox, inputBox.viewModel) - } - - func inputBoxTextDidChange(_ text: String) { - print(#function, text) - } -} diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Supplement/AccentColor.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Supplement/AccentColor.swift new file mode 100644 index 0000000000..3a60a305da --- /dev/null +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/Supplement/AccentColor.swift @@ -0,0 +1,12 @@ +// +// File.swift +// Intelligents +// +// Created by 秋星桥 on 6/19/25. +// + +import UIKit + +extension UIColor { + static let accent: UIColor = .init(red: 30 / 255, green: 150 / 255, blue: 235 / 255, alpha: 1.0) +} diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/InputBox.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/InputBox.swift index 1092968c2e..638a25c530 100644 --- a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/InputBox.swift +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/InputBox.swift @@ -10,14 +10,19 @@ class InputBox: UIView { var cancellables = Set() lazy var containerView = UIView().then { - $0.backgroundColor = .systemBackground - $0.layer.cornerRadius = 12 - $0.layer.borderWidth = 0.5 - $0.layer.borderColor = UIColor.systemGray4.cgColor + $0.backgroundColor = UIColor( + named: "InputBoxBackground", + in: .module, + compatibleWith: nil + )! + $0.layer.cornerRadius = 16 + $0.layer.cornerCurve = .continuous + $0.layer.borderWidth = 1 + $0.layer.borderColor = UIColor.systemGray.withAlphaComponent(0.1).cgColor $0.layer.shadowColor = UIColor.black.cgColor - $0.layer.shadowOffset = CGSize(width: 0, height: 2) - $0.layer.shadowRadius = 6 - $0.layer.shadowOpacity = 0.04 + $0.layer.shadowOffset = CGSize(width: 0, height: 0) + $0.layer.shadowRadius = 12 + $0.layer.shadowOpacity = 0.075 $0.clipsToBounds = false } @@ -29,7 +34,7 @@ class InputBox: UIView { $0.textContainer.lineFragmentPadding = 0 $0.textContainerInset = .zero $0.delegate = self - $0.text = "This is AFFiNE AI" + $0.text = "" } lazy var placeholderLabel = UILabel().then { diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/InputBox.xcassets/InputBoxBackground.colorset/Contents.json b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/InputBox.xcassets/InputBoxBackground.colorset/Contents.json new file mode 100644 index 0000000000..0cba25aa67 --- /dev/null +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/InputBox.xcassets/InputBoxBackground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "255", + "green" : "255", + "red" : "255" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "32", + "green" : "32", + "red" : "32" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/InputBoxFunctionBar.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/InputBoxFunctionBar.swift index 52ae48188a..c643f018ce 100644 --- a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/InputBoxFunctionBar.swift +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/InputBox/InputBoxFunctionBar.swift @@ -10,40 +10,41 @@ protocol InputBoxFunctionBarDelegate: AnyObject { func functionBarDidTapSend(_ functionBar: InputBoxFunctionBar) } +private let unselectedColor: UIColor = .secondaryLabel +private let selectedColor: UIColor = .accent + class InputBoxFunctionBar: UIView { weak var delegate: InputBoxFunctionBarDelegate? lazy var attachmentButton = UIButton(type: .system).then { - $0.backgroundColor = .systemBackground $0.setImage(UIImage(named: "inputbox.add.attachment", in: .module, with: nil), for: .normal) - $0.tintColor = .secondaryLabel + $0.tintColor = unselectedColor $0.imageView?.contentMode = .scaleAspectFit $0.addTarget(self, action: #selector(attachmentButtonTapped), for: .touchUpInside) } lazy var toolButton = UIButton(type: .system).then { $0.setImage(UIImage(named: "inputbox.tool", in: .module, with: nil), for: .normal) - $0.tintColor = .secondaryLabel + $0.tintColor = unselectedColor $0.imageView?.contentMode = .scaleAspectFit $0.addTarget(self, action: #selector(toolButtonTapped), for: .touchUpInside) } lazy var networkButton = UIButton(type: .system).then { $0.setImage(UIImage(named: "inputbox.network", in: .module, with: nil), for: .normal) - $0.tintColor = .secondaryLabel + $0.tintColor = unselectedColor $0.imageView?.contentMode = .scaleAspectFit $0.addTarget(self, action: #selector(networkButtonTapped), for: .touchUpInside) } lazy var deepThinkingButton = UIButton(type: .system).then { $0.setImage(UIImage(named: "inputbox.deep.thinking", in: .module, with: nil), for: .normal) - $0.tintColor = .secondaryLabel + $0.tintColor = unselectedColor $0.imageView?.contentMode = .scaleAspectFit $0.addTarget(self, action: #selector(deepThinkingButtonTapped), for: .touchUpInside) } lazy var sendButton = UIButton(type: .system).then { - $0.backgroundColor = UIColor.systemBlue $0.setImage(UIImage(named: "inputbox.send", in: .module, with: nil), for: .normal) $0.tintColor = .white $0.imageView?.contentMode = .scaleAspectFit @@ -103,27 +104,26 @@ class InputBoxFunctionBar: UIView { } } - override func layoutSubviews() { super.layoutSubviews() sendButton.layer.cornerRadius = sendButton.bounds.height / 2 + for button in [toolButton, networkButton, deepThinkingButton] { + button.layer.cornerRadius = button.bounds.height / 2 + } } // MARK: - Public Methods func updateToolState(isEnabled: Bool) { - toolButton.isSelected = isEnabled - toolButton.tintColor = isEnabled ? .systemBlue : .secondaryLabel + toolButton.tintColor = isEnabled ? selectedColor : unselectedColor } func updateNetworkState(isEnabled: Bool) { - networkButton.isSelected = isEnabled - networkButton.tintColor = isEnabled ? .systemBlue : .secondaryLabel + networkButton.tintColor = isEnabled ? selectedColor : unselectedColor } func updateDeepThinkingState(isEnabled: Bool) { - deepThinkingButton.isSelected = isEnabled - deepThinkingButton.tintColor = isEnabled ? .systemBlue : .secondaryLabel + deepThinkingButton.tintColor = isEnabled ? selectedColor : unselectedColor } func updateSendState(canSend: Bool) { diff --git a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/MainHeaderView/MainHeaderView.swift b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/MainHeaderView/MainHeaderView.swift index 195cfd666e..fc8112cf37 100644 --- a/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/MainHeaderView/MainHeaderView.swift +++ b/packages/frontend/apps/ios/App/Packages/Intelligents/Sources/Intelligents/Interface/View/MainHeaderView/MainHeaderView.swift @@ -22,7 +22,7 @@ class MainHeaderView: UIView { private lazy var titleLabel = UILabel().then { $0.text = "AFFiNE" $0.font = .systemFont(ofSize: 16, weight: .medium) - $0.textColor = .black + $0.textColor = .label $0.textAlignment = .center } @@ -68,7 +68,6 @@ class MainHeaderView: UIView { init() { super.init(frame: .zero) - backgroundColor = .white addSubview(mainStackView) mainStackView.snp.makeConstraints { make in