chore: basic setup of v2 AI (#12864)

Co-authored-by: Hwang <hwangdev97@gmail.com>
This commit is contained in:
Lakr
2025-06-20 13:09:33 +08:00
committed by GitHub
parent 5a87d3d9f6
commit eb5a2ffe05
199 changed files with 3478 additions and 8311 deletions

View File

@@ -5,123 +5,18 @@
// Created by on 2025/1/8.
//
import ChidoriMenu
import Intelligents
import UIKit
extension AFFiNEViewController: IntelligentsButtonDelegate, IntelligentsFocusApertureViewDelegate {
extension AFFiNEViewController: IntelligentsButtonDelegate {
func onIntelligentsButtonTapped(_ button: IntelligentsButton) {
guard let webView else {
assertionFailure() // ? wdym ?
return
}
IntelligentContext.shared.webView = webView!
button.beginProgress()
let group = DispatchGroup()
group.enter()
webView.evaluateScript(.getCurrentServerBaseUrl) { result in
self.baseUrl = result as? String
print("[*] setting baseUrl: \(self.baseUrl ?? "")")
group.leave()
}
group.enter()
webView.evaluateScript(.getCurrentDocId) { result in
self.documentID = result as? String
print("[*] setting documentID: \(self.documentID ?? "")")
group.leave()
}
group.enter()
webView.evaluateScript(.getCurrentWorkspaceId) { result in
self.workspaceID = result as? String
print("[*] setting workspaceID: \(self.workspaceID ?? "")")
group.leave()
}
group.enter()
webView.evaluateScript(.getCurrentDocContentInMarkdown) { input in
self.documentContent = input as? String
print("[*] setting documentContent: \(self.documentContent?.count ?? 0) chars")
group.leave()
}
DispatchQueue.global().asyncAfter(deadline: .now()) {
group.wait()
DispatchQueue.main.async {
button.stopProgress()
webView.resignFirstResponder()
self.openIntelligentsSheet()
}
}
}
@discardableResult
func openIntelligentsSheet() -> IntelligentsFocusApertureView? {
dismissIntelligentsButton()
view.resignFirstResponder()
// stop scroll on webview
if let contentOffset = webView?.scrollView.contentOffset {
webView?.scrollView.contentOffset = contentOffset
}
let focus = IntelligentsFocusApertureView()
focus.prepareAnimationWith(
capturingTargetContentView: webView ?? .init(),
coveringRootViewController: self
)
focus.delegate = self
focus.executeAnimationKickIn()
dismissIntelligentsButton()
return focus
}
func openSimpleChat() {
let targetController = IntelligentsChatController()
presentIntoCurrentContext(withTargetController: targetController)
}
func focusApertureRequestAction(
from view: IntelligentsFocusApertureView,
actionType: IntelligentsFocusApertureViewActionType
) {
switch actionType {
case .translateTo:
var actions: [UIAction] = []
for lang in IntelligentsEphemeralActionController.EphemeralAction.Language.allCases {
actions.append(.init(title: lang.rawValue) { [weak self] _ in
guard let self else { return }
let controller = IntelligentsEphemeralActionController(
action: .translate(to: lang)
)
controller.workspaceID = workspaceID ?? ""
controller.documentID = documentID ?? ""
controller.documentContent = documentContent ?? ""
controller.configure(previewImage: view.capturedImage ?? .init())
presentIntoCurrentContext(withTargetController: controller)
})
}
view.present(menu: .init(children: actions)) { controller in
controller.overrideUserInterfaceStyle = .dark
} controllerDidPresent: { _ in }
case .summary:
let controller = IntelligentsEphemeralActionController(
action: .summarize
)
controller.configure(previewImage: view.capturedImage ?? .init())
controller.workspaceID = workspaceID ?? ""
controller.documentID = documentID ?? ""
controller.documentContent = documentContent ?? ""
presentIntoCurrentContext(withTargetController: controller)
case .chatWithAI:
let controller = IntelligentsChatController()
controller.metadata[.documentID] = documentID
controller.metadata[.workspaceID] = workspaceID
controller.metadata[.content] = documentContent
presentIntoCurrentContext(withTargetController: controller)
case .dismiss:
presentIntelligentsButton()
IntelligentContext.shared.preparePresent() {
button.stopProgress()
let controller = IntelligentsController()
self.present(controller, animated: true)
}
}
}

View File

@@ -3,13 +3,6 @@ import Intelligents
import UIKit
class AFFiNEViewController: CAPBridgeViewController {
var baseUrl: String? {
didSet { Intelligents.setUpstreamEndpoint(baseUrl ?? "") }
}
var documentID: String?
var workspaceID: String?
var documentContent: String?
override func viewDidLoad() {
super.viewDidLoad()
webView?.allowsBackForwardNavigationGestures = true
@@ -36,7 +29,7 @@ class AFFiNEViewController: CAPBridgeViewController {
CookiePlugin(),
HashcashPlugin(),
NavigationGesturePlugin(),
IntelligentsPlugin(representController: self),
// IntelligentsPlugin(representController: self), // no longer put in use
NbStorePlugin(),
]
plugins.forEach { bridge?.registerPluginInstance($0) }
@@ -45,16 +38,11 @@ class AFFiNEViewController: CAPBridgeViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
navigationController?.setNavigationBarHidden(false, animated: animated)
}
#if DEBUG
override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
super.motionEnded(motion, with: event)
if motion == .motionShake {
presentIntelligentsButton()
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.presentIntelligentsButton()
}
}
#endif
}

View File

@@ -42,7 +42,7 @@
<key>NSPhotoLibraryUsageDescription</key>
<string>AFFiNE requires access to select photos from your photo library and insert them into your documents</string>
<key>NSUserTrackingUsageDescription</key>
<string>Rest assured, enabling this permission won&apos;t access your private info on other sites. It&apos;s only used to identify your device and improve security and product experience.</string>
<string>Rest assured, enabling this permission won't access your private info on other sites. It's only used to identify your device and improve security and product experience.</string>
<key>UILaunchScreen</key>
<dict>
<key>UIImageName</key>

View File

@@ -1,36 +1,36 @@
import Capacitor
import Foundation
@objc(IntelligentsPlugin)
public class IntelligentsPlugin: CAPPlugin, CAPBridgedPlugin {
public let identifier = "IntelligentsPlugin"
public let jsName = "Intelligents"
public let pluginMethods: [CAPPluginMethod] = [
CAPPluginMethod(name: "presentIntelligentsButton", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "dismissIntelligentsButton", returnType: CAPPluginReturnPromise),
]
public private(set) weak var representController: UIViewController?
init(representController: UIViewController) {
self.representController = representController
super.init()
}
deinit {
representController = nil
}
@objc public func presentIntelligentsButton(_ call: CAPPluginCall) {
DispatchQueue.main.async {
self.representController?.presentIntelligentsButton()
call.resolve()
}
}
@objc public func dismissIntelligentsButton(_ call: CAPPluginCall) {
DispatchQueue.main.async {
self.representController?.dismissIntelligentsButton()
call.resolve()
}
}
}
//@objc(IntelligentsPlugin)
//public class IntelligentsPlugin: CAPPlugin, CAPBridgedPlugin {
// public let identifier = "IntelligentsPlugin"
// public let jsName = "Intelligents"
// public let pluginMethods: [CAPPluginMethod] = [
// CAPPluginMethod(name: "presentIntelligentsButton", returnType: CAPPluginReturnPromise),
// CAPPluginMethod(name: "dismissIntelligentsButton", returnType: CAPPluginReturnPromise),
// ]
// public private(set) weak var representController: UIViewController?
//
// init(representController: UIViewController) {
// self.representController = representController
// super.init()
// }
//
// deinit {
// representController = nil
// }
//
// @objc public func presentIntelligentsButton(_ call: CAPPluginCall) {
// DispatchQueue.main.async {
// self.representController?.presentIntelligentsButton()
// call.resolve()
// }
// }
//
// @objc public func dismissIntelligentsButton(_ call: CAPPluginCall) {
// DispatchQueue.main.async {
// self.representController?.dismissIntelligentsButton()
// call.resolve()
// }
// }
//}

View File

@@ -1711,6 +1711,7 @@ extension UniffiError: Equatable, Hashable {}
extension UniffiError: Foundation.LocalizedError {
public var errorDescription: String? {
String(reflecting: self)
@@ -1718,6 +1719,8 @@ extension UniffiError: Foundation.LocalizedError {
}
#if swift(>=5.8)
@_documentation(visibility: private)
#endif

View File

@@ -1,4 +1,7 @@
module affine_mobile_nativeFFI {
header "affine_mobile_nativeFFI.h"
export *
use "Darwin"
use "_Builtin_stdbool"
use "_Builtin_stdint"
}