mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-06 00:41:39 +08:00
feat: input box menu
This commit is contained in:
@@ -18,7 +18,7 @@ let package = Package(
|
|||||||
.package(url: "https://github.com/apple/swift-collections", from: "1.2.0"),
|
.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/devxoul/Then", from: "3.0.0"),
|
||||||
.package(url: "https://github.com/SnapKit/SnapKit.git", from: "5.0.1"),
|
.package(url: "https://github.com/SnapKit/SnapKit.git", from: "5.0.1"),
|
||||||
.package(url: "https://github.com/SwifterSwift/SwifterSwift.git", from: "6.0.0")
|
.package(url: "https://github.com/SwifterSwift/SwifterSwift.git", from: "6.0.0"),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(name: "Intelligents", dependencies: [
|
.target(name: "Intelligents", dependencies: [
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// File.swift
|
// MainViewController+Header.swift
|
||||||
// Intelligents
|
// Intelligents
|
||||||
//
|
//
|
||||||
// Created by 秋星桥 on 6/19/25.
|
// Created by 秋星桥 on 6/19/25.
|
||||||
|
|||||||
+16
@@ -8,6 +8,22 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
extension MainViewController: InputBoxDelegate {
|
extension MainViewController: InputBoxDelegate {
|
||||||
|
func inputBoxDidSelectTakePhoto(_ inputBox: InputBox) {
|
||||||
|
print(#function, inputBox)
|
||||||
|
}
|
||||||
|
|
||||||
|
func inputBoxDidSelectPhotoLibrary(_ inputBox: InputBox) {
|
||||||
|
print(#function, inputBox)
|
||||||
|
}
|
||||||
|
|
||||||
|
func inputBoxDidSelectAttachFiles(_ inputBox: InputBox) {
|
||||||
|
print(#function, inputBox)
|
||||||
|
}
|
||||||
|
|
||||||
|
func inputBoxDidSelectEmbedDocs(_ inputBox: InputBox) {
|
||||||
|
print(#function, inputBox)
|
||||||
|
}
|
||||||
|
|
||||||
func inputBoxDidSelectAttachment(_ inputBox: InputBox) {
|
func inputBoxDidSelectAttachment(_ inputBox: InputBox) {
|
||||||
print(#function, inputBox)
|
print(#function, inputBox)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// File.swift
|
// AccentColor.swift
|
||||||
// Intelligents
|
// Intelligents
|
||||||
//
|
//
|
||||||
// Created by 秋星桥 on 6/19/25.
|
// Created by 秋星桥 on 6/19/25.
|
||||||
|
|||||||
+19
-7
@@ -70,7 +70,7 @@ class InputBox: UIView {
|
|||||||
updateTextViewHeight()
|
updateTextViewHeight()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override init(frame: CGRect = .zero) {
|
override init(frame: CGRect = .zero) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
setupViews()
|
setupViews()
|
||||||
@@ -164,15 +164,15 @@ class InputBox: UIView {
|
|||||||
func updateTextViewHeight() {
|
func updateTextViewHeight() {
|
||||||
let size = textView.sizeThatFits(CGSize(width: textView.frame.width, height: CGFloat.greatestFiniteMagnitude))
|
let size = textView.sizeThatFits(CGSize(width: textView.frame.width, height: CGFloat.greatestFiniteMagnitude))
|
||||||
let newHeight = max(minTextViewHeight, min(maxTextViewHeight, size.height))
|
let newHeight = max(minTextViewHeight, min(maxTextViewHeight, size.height))
|
||||||
|
|
||||||
let height = textView.frame.height
|
let height = textView.frame.height
|
||||||
guard height != newHeight else { return }
|
guard height != newHeight else { return }
|
||||||
|
|
||||||
textViewHeightConstraint?.update(offset: newHeight)
|
textViewHeightConstraint?.update(offset: newHeight)
|
||||||
textView.isScrollEnabled = size.height > maxTextViewHeight
|
textView.isScrollEnabled = size.height > maxTextViewHeight
|
||||||
|
|
||||||
if height == 0 || superview == nil || window == nil || isHidden { return }
|
if height == 0 || superview == nil || window == nil || isHidden { return }
|
||||||
|
|
||||||
UIView.animate(
|
UIView.animate(
|
||||||
withDuration: 0.5,
|
withDuration: 0.5,
|
||||||
delay: 0,
|
delay: 0,
|
||||||
@@ -231,8 +231,20 @@ class InputBox: UIView {
|
|||||||
// MARK: - InputBoxFunctionBarDelegate
|
// MARK: - InputBoxFunctionBarDelegate
|
||||||
|
|
||||||
extension InputBox: InputBoxFunctionBarDelegate {
|
extension InputBox: InputBoxFunctionBarDelegate {
|
||||||
func functionBarDidTapAttachment(_: InputBoxFunctionBar) {
|
func functionBarDidTapTakePhoto(_: InputBoxFunctionBar) {
|
||||||
delegate?.inputBoxDidSelectAttachment(self)
|
delegate?.inputBoxDidSelectTakePhoto(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
func functionBarDidTapPhotoLibrary(_: InputBoxFunctionBar) {
|
||||||
|
delegate?.inputBoxDidSelectPhotoLibrary(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
func functionBarDidTapAttachFiles(_: InputBoxFunctionBar) {
|
||||||
|
delegate?.inputBoxDidSelectAttachFiles(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
func functionBarDidTapEmbedDocs(_: InputBoxFunctionBar) {
|
||||||
|
delegate?.inputBoxDidSelectEmbedDocs(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
func functionBarDidTapTool(_: InputBoxFunctionBar) {
|
func functionBarDidTapTool(_: InputBoxFunctionBar) {
|
||||||
|
|||||||
+4
-1
@@ -8,7 +8,10 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
protocol InputBoxDelegate: AnyObject {
|
protocol InputBoxDelegate: AnyObject {
|
||||||
func inputBoxDidSelectAttachment(_ inputBox: InputBox)
|
func inputBoxDidSelectTakePhoto(_ inputBox: InputBox)
|
||||||
|
func inputBoxDidSelectPhotoLibrary(_ inputBox: InputBox)
|
||||||
|
func inputBoxDidSelectAttachFiles(_ inputBox: InputBox)
|
||||||
|
func inputBoxDidSelectEmbedDocs(_ inputBox: InputBox)
|
||||||
func inputBoxDidSend(_ inputBox: InputBox)
|
func inputBoxDidSend(_ inputBox: InputBox)
|
||||||
func inputBoxTextDidChange(_ text: String)
|
func inputBoxTextDidChange(_ text: String)
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-5
@@ -3,7 +3,10 @@ import Then
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
protocol InputBoxFunctionBarDelegate: AnyObject {
|
protocol InputBoxFunctionBarDelegate: AnyObject {
|
||||||
func functionBarDidTapAttachment(_ functionBar: InputBoxFunctionBar)
|
func functionBarDidTapTakePhoto(_ functionBar: InputBoxFunctionBar)
|
||||||
|
func functionBarDidTapPhotoLibrary(_ functionBar: InputBoxFunctionBar)
|
||||||
|
func functionBarDidTapAttachFiles(_ functionBar: InputBoxFunctionBar)
|
||||||
|
func functionBarDidTapEmbedDocs(_ functionBar: InputBoxFunctionBar)
|
||||||
func functionBarDidTapTool(_ functionBar: InputBoxFunctionBar)
|
func functionBarDidTapTool(_ functionBar: InputBoxFunctionBar)
|
||||||
func functionBarDidTapNetwork(_ functionBar: InputBoxFunctionBar)
|
func functionBarDidTapNetwork(_ functionBar: InputBoxFunctionBar)
|
||||||
func functionBarDidTapDeepThinking(_ functionBar: InputBoxFunctionBar)
|
func functionBarDidTapDeepThinking(_ functionBar: InputBoxFunctionBar)
|
||||||
@@ -20,7 +23,8 @@ class InputBoxFunctionBar: UIView {
|
|||||||
$0.setImage(UIImage(named: "inputbox.add.attachment", in: .module, with: nil), for: .normal)
|
$0.setImage(UIImage(named: "inputbox.add.attachment", in: .module, with: nil), for: .normal)
|
||||||
$0.tintColor = unselectedColor
|
$0.tintColor = unselectedColor
|
||||||
$0.imageView?.contentMode = .scaleAspectFit
|
$0.imageView?.contentMode = .scaleAspectFit
|
||||||
$0.addTarget(self, action: #selector(attachmentButtonTapped), for: .touchUpInside)
|
$0.showsMenuAsPrimaryAction = true
|
||||||
|
$0.menu = createAttachmentMenu()
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy var toolButton = UIButton(type: .system).then {
|
lazy var toolButton = UIButton(type: .system).then {
|
||||||
@@ -131,12 +135,49 @@ class InputBoxFunctionBar: UIView {
|
|||||||
sendButton.alpha = canSend ? 1.0 : 0.5
|
sendButton.alpha = canSend ? 1.0 : 0.5
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Actions
|
// MARK: - Private Methods
|
||||||
|
|
||||||
@objc private func attachmentButtonTapped() {
|
private func createAttachmentMenu() -> UIMenu {
|
||||||
delegate?.functionBarDidTapAttachment(self)
|
let takePhotoAction = UIAction(
|
||||||
|
title: "Take Photo or Video",
|
||||||
|
image: UIImage(systemName: "camera")
|
||||||
|
) { [weak self] _ in
|
||||||
|
guard let self else { return }
|
||||||
|
delegate?.functionBarDidTapTakePhoto(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
let photoLibraryAction = UIAction(
|
||||||
|
title: "Photo Library",
|
||||||
|
image: UIImage(systemName: "photo.on.rectangle")
|
||||||
|
) { [weak self] _ in
|
||||||
|
guard let self else { return }
|
||||||
|
delegate?.functionBarDidTapPhotoLibrary(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
let attachFilesAction = UIAction(
|
||||||
|
title: "Attach Files (pdf, txt, csv)",
|
||||||
|
image: UIImage(systemName: "arrow.up.doc")
|
||||||
|
) { [weak self] _ in
|
||||||
|
guard let self else { return }
|
||||||
|
delegate?.functionBarDidTapAttachFiles(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
let embedDocsAction = UIAction(
|
||||||
|
title: "Embed AFFINE Docs",
|
||||||
|
image: UIImage(systemName: "doc.text")
|
||||||
|
) { [weak self] _ in
|
||||||
|
guard let self else { return }
|
||||||
|
delegate?.functionBarDidTapEmbedDocs(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
return UIMenu(
|
||||||
|
options: [.displayInline],
|
||||||
|
children: [takePhotoAction, photoLibraryAction, attachFilesAction, embedDocsAction].reversed()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Actions
|
||||||
|
|
||||||
@objc private func toolButtonTapped() {
|
@objc private func toolButtonTapped() {
|
||||||
delegate?.functionBarDidTapTool(self)
|
delegate?.functionBarDidTapTool(self)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user