Skip to content
This repository has been archived by the owner on Apr 2, 2024. It is now read-only.

release_v_2.18.0 #108

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public struct WysiwygComposerView: View {

@ViewBuilder
private var placeholderView: some View {
if viewModel.isContentEmpty {
if viewModel.isContentEmpty, !viewModel.textView.isDictationRunning {
Text(placeholder)
.font(Font(UIFont.preferredFont(forTextStyle: .body)))
.foregroundColor(placeholderColor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,8 @@ private extension WysiwygComposerViewModel {
/// Reconciliate the content of the model with the content of the text view.
func reconciliateIfNeeded() {
do {
guard let replacement = try StringDiffer.replacement(from: attributedContent.text.htmlChars,
guard !textView.isDictationRunning,
let replacement = try StringDiffer.replacement(from: attributedContent.text.htmlChars,
to: textView.attributedText.htmlChars) else {
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ protocol WysiwygTextViewDelegate: AnyObject {
public protocol MentionDisplayHelper { }

public class WysiwygTextView: UITextView {
private(set) var isDictationRunning = false

/// Internal delegate for the text view.
weak var wysiwygDelegate: WysiwygTextViewDelegate?

Expand All @@ -53,12 +55,42 @@ public class WysiwygTextView: UITextView {

override public init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
contentMode = .redraw
commonInit()
}

required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}

private func commonInit() {
contentMode = .redraw
NotificationCenter.default.addObserver(self,
selector: #selector(textInputCurrentInputModeDidChange),
name: UITextInputMode.currentInputModeDidChangeNotification,
object: nil)
}

@objc private func textInputCurrentInputModeDidChange(notification: Notification) {
// We don't care about the input mode if this is not the first responder
guard isFirstResponder else {
return
}

guard let inputMode = textInputMode?.primaryLanguage,
inputMode == "dictation" else {
isDictationRunning = false
return
}
isDictationRunning = true
}

override public func dictationRecordingDidEnd() {
isDictationRunning = false
}

override public func dictationRecognitionFailed() {
isDictationRunning = false
}

/// Register a pill view that has been added through `NSTextAttachmentViewProvider`.
Expand Down
81 changes: 81 additions & 0 deletions Sources/WysiwygComposer/WysiwygComposer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,73 @@ public func FfiConverterTypeComposerUpdate_lower(_ value: ComposerUpdate) -> Uns
return FfiConverterTypeComposerUpdate.lower(value)
}

public protocol MentionDetectorProtocol {
func isMention(url: String) -> Bool
}

public class MentionDetector: MentionDetectorProtocol {
fileprivate let pointer: UnsafeMutableRawPointer

// TODO: We'd like this to be `private` but for Swifty reasons,
// we can't implement `FfiConverter` without making this `required` and we can't
// make it `required` without making it `public`.
required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
self.pointer = pointer
}

deinit {
try! rustCall { uniffi_uniffi_wysiwyg_composer_fn_free_mentiondetector(pointer, $0) }
}

public func isMention(url: String) -> Bool {
return try! FfiConverterBool.lift(
try!
rustCall {
uniffi_uniffi_wysiwyg_composer_fn_method_mentiondetector_is_mention(self.pointer,
FfiConverterString.lower(url), $0)
}
)
}
}

public struct FfiConverterTypeMentionDetector: FfiConverter {
typealias FfiType = UnsafeMutableRawPointer
typealias SwiftType = MentionDetector

public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> MentionDetector {
let v: UInt64 = try readInt(&buf)
// The Rust code won't compile if a pointer won't fit in a UInt64.
// We have to go via `UInt` because that's the thing that's the size of a pointer.
let ptr = UnsafeMutableRawPointer(bitPattern: UInt(truncatingIfNeeded: v))
if ptr == nil {
throw UniffiInternalError.unexpectedNullPointer
}
return try lift(ptr!)
}

public static func write(_ value: MentionDetector, into buf: inout [UInt8]) {
// This fiddling is because `Int` is the thing that's the same size as a pointer.
// The Rust code won't compile if a pointer won't fit in a `UInt64`.
writeInt(&buf, UInt64(bitPattern: Int64(Int(bitPattern: lower(value)))))
}

public static func lift(_ pointer: UnsafeMutableRawPointer) throws -> MentionDetector {
return MentionDetector(unsafeFromRawPointer: pointer)
}

public static func lower(_ value: MentionDetector) -> UnsafeMutableRawPointer {
return value.pointer
}
}

public func FfiConverterTypeMentionDetector_lift(_ pointer: UnsafeMutableRawPointer) throws -> MentionDetector {
return try FfiConverterTypeMentionDetector.lift(pointer)
}

public func FfiConverterTypeMentionDetector_lower(_ value: MentionDetector) -> UnsafeMutableRawPointer {
return FfiConverterTypeMentionDetector.lower(value)
}

public struct Attribute {
public var key: String
public var value: String
Expand Down Expand Up @@ -1828,6 +1895,14 @@ public func newComposerModel() -> ComposerModel {
)
}

public func newMentionDetector() -> MentionDetector {
return try! FfiConverterTypeMentionDetector.lift(
try! rustCall {
uniffi_uniffi_wysiwyg_composer_fn_func_new_mention_detector($0)
}
)
}

private enum InitializationResult {
case ok
case contractVersionMismatch
Expand All @@ -1847,6 +1922,9 @@ private var initializationResult: InitializationResult {
if uniffi_uniffi_wysiwyg_composer_checksum_func_new_composer_model() != 61235 {
return InitializationResult.apiChecksumMismatch
}
if uniffi_uniffi_wysiwyg_composer_checksum_func_new_mention_detector() != 30911 {
return InitializationResult.apiChecksumMismatch
}
if uniffi_uniffi_wysiwyg_composer_checksum_method_composermodel_action_states() != 7578 {
return InitializationResult.apiChecksumMismatch
}
Expand Down Expand Up @@ -1988,6 +2066,9 @@ private var initializationResult: InitializationResult {
if uniffi_uniffi_wysiwyg_composer_checksum_method_composerupdate_text_update() != 40178 {
return InitializationResult.apiChecksumMismatch
}
if uniffi_uniffi_wysiwyg_composer_checksum_method_mentiondetector_is_mention() != 64462 {
return InitializationResult.apiChecksumMismatch
}

return InitializationResult.ok
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ typedef struct RustCallStatus {

// Callbacks for UniFFI Futures
typedef void (*UniFfiFutureCallbackUInt8)(const void * _Nonnull, uint8_t, RustCallStatus);
typedef void (*UniFfiFutureCallbackInt8)(const void * _Nonnull, int8_t, RustCallStatus);
typedef void (*UniFfiFutureCallbackUnsafeMutableRawPointer)(const void * _Nonnull, void*_Nonnull, RustCallStatus);
typedef void (*UniFfiFutureCallbackUnsafeMutableRawPointer)(const void * _Nonnull, void*_Nonnull, RustCallStatus);
typedef void (*UniFfiFutureCallbackUnsafeMutableRawPointer)(const void * _Nonnull, void*_Nonnull, RustCallStatus);
typedef void (*UniFfiFutureCallbackRustBuffer)(const void * _Nonnull, RustBuffer, RustCallStatus);
Expand Down Expand Up @@ -164,8 +166,15 @@ RustBuffer uniffi_uniffi_wysiwyg_composer_fn_method_composerupdate_menu_state(vo
);
RustBuffer uniffi_uniffi_wysiwyg_composer_fn_method_composerupdate_text_update(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status
);
void uniffi_uniffi_wysiwyg_composer_fn_free_mentiondetector(void*_Nonnull ptr, RustCallStatus *_Nonnull out_status
);
int8_t uniffi_uniffi_wysiwyg_composer_fn_method_mentiondetector_is_mention(void*_Nonnull ptr, RustBuffer url, RustCallStatus *_Nonnull out_status
);
void*_Nonnull uniffi_uniffi_wysiwyg_composer_fn_func_new_composer_model(RustCallStatus *_Nonnull out_status

);
void*_Nonnull uniffi_uniffi_wysiwyg_composer_fn_func_new_mention_detector(RustCallStatus *_Nonnull out_status

);
RustBuffer ffi_wysiwyg_composer_rustbuffer_alloc(int32_t size, RustCallStatus *_Nonnull out_status
);
Expand All @@ -177,6 +186,9 @@ RustBuffer ffi_wysiwyg_composer_rustbuffer_reserve(RustBuffer buf, int32_t addit
);
uint16_t uniffi_uniffi_wysiwyg_composer_checksum_func_new_composer_model(void

);
uint16_t uniffi_uniffi_wysiwyg_composer_checksum_func_new_mention_detector(void

);
uint16_t uniffi_uniffi_wysiwyg_composer_checksum_method_composermodel_action_states(void

Expand Down Expand Up @@ -318,6 +330,9 @@ uint16_t uniffi_uniffi_wysiwyg_composer_checksum_method_composerupdate_menu_stat
);
uint16_t uniffi_uniffi_wysiwyg_composer_checksum_method_composerupdate_text_update(void

);
uint16_t uniffi_uniffi_wysiwyg_composer_checksum_method_mentiondetector_is_mention(void

);
uint32_t ffi_wysiwyg_composer_uniffi_contract_version(void

Expand Down
Loading