Skip to content

Commit

Permalink
Fixes for returning suggested mentions (Future)
Browse files Browse the repository at this point in the history
  • Loading branch information
jguz-pubnub committed Oct 30, 2024
1 parent 99f42ae commit af7db1d
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 31 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ jobs:
with:
ruby-version: 3.2.2
bundler-cache: true
- name: Clear SPM and build cache
- name: Clear Swift Package Manager cache
run: rm -rf "$HOME/Library/Caches/org.swift.swiftpm"
- name: Clear SPM and build cache (2)
- name: Clear build cache
run: rm -rf .build
- name: Pre-load simulators list
if: ${{ matrix.environment != 'macOS' }}
Expand Down
30 changes: 16 additions & 14 deletions Sources/MessageDraft/MessageDraftChangeListener.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,46 +19,48 @@ public protocol MessageDraftChangeListener: AnyObject {
///
/// - Parameters:
/// - messageElements: An array of `MessageElement` representing current elements within the message
/// - suggestedMentions: A future object that will return the result of suggested mentions after calling its ``SuggestedMentionsFuture/async(completion:)`` method
func onChange(messageElements: [MessageElement], suggestedMentions: SuggestedMentionsFuture)
/// - suggestedMentions: A future object that will return the result of suggested mentions after calling its ``FutureObject/async(completion:)`` method
func onChange(messageElements: [MessageElement], suggestedMentions: any FutureObject<[SuggestedMention]>)
}

/// A closure-based implementation of the ``MessageDraftChangeListener`` protocol.
///
/// This class allows you to handle delegate events by passing a closure, reducing the need to implement the ``MessageDraftChangeListener`` protocol.
/// This is useful when you want to quickly handle messages without writing additional boilerplate code.
final public class ClosureMessageDraftChangeListener: MessageDraftChangeListener {
let onChangeClosure: (([MessageElement], SuggestedMentionsFuture) -> Void)
let onChangeClosure: (([MessageElement], any FutureObject<[SuggestedMention]>) -> Void)

init(onChange: @escaping ([MessageElement], SuggestedMentionsFuture) -> Void) {
init(onChange: @escaping ([MessageElement], any FutureObject<[SuggestedMention]>) -> Void) {
self.onChangeClosure = onChange
}

public func onChange(messageElements: [MessageElement], suggestedMentions: SuggestedMentionsFuture) {
public func onChange(messageElements: [MessageElement], suggestedMentions: any FutureObject<[SuggestedMention]>) {
onChangeClosure(messageElements, suggestedMentions)
}
}

/// A protocol representing a `[SuggestedMention]` value that will be available in the future.
public protocol SuggestedMentionsFuture {
/// Starts an asynchronous operation and provides the result upon completion.
/// A custom future-like object representing a value that will be provided asynchronously in the future.
public protocol FutureObject<T> {
/// An associaded type representing the success value associated with this protocol or class. Defined by a conforming type
associatedtype T
/// Registers a completion handler to be called asynchronously with the result (success or failure).
///
/// - Parameters:
/// - completion: The async `Result` of the method call
/// - **Success**: The successful result of the operation
/// - completion: The async result of the call
/// - **Success**: A successful value
/// - **Failure**: An `Error` describing the failure
func async(completion: @escaping (Swift.Result<[SuggestedMention], Error>) -> Void)
func async(completion: @escaping (Swift.Result<T, Error>) -> Void)
}

class SuggestedMentionsFutureImpl: SuggestedMentionsFuture {
class SuggestedMentionsFuture: FutureObject {
let future: PubNubChat.PNFuture

init(future: PubNubChat.PNFuture) {
self.future = future
}

func async(completion: @escaping (Swift.Result<[SuggestedMention], Error>) -> Void) {
future.async(caller: self, callback: { (result: FutureResult<SuggestedMentionsFutureImpl, [PubNubChat.SuggestedMention]>) in
future.async(caller: self, callback: { (result: FutureResult<SuggestedMentionsFuture, [PubNubChat.SuggestedMention]>) in
switch result.result {
case let .success(suggestedMentions):
completion(.success(suggestedMentions.compactMap { SuggestedMention.from(mention: $0) }))
Expand Down
2 changes: 1 addition & 1 deletion Sources/MessageDraft/MessageDraftImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ extension MessageDraftImpl: MessageDraft {
let underlyingListener = KMPMessageDraftChangeListener { elements, mentions in
listener.onChange(
messageElements: elements.compactMap { MessageElement.from(element: $0) },
suggestedMentions: SuggestedMentionsFutureImpl(future: mentions)
suggestedMentions: SuggestedMentionsFuture(future: mentions)
)
}

Expand Down
28 changes: 14 additions & 14 deletions Tests/MessageDraftIntegrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class MessageDraftIntegrationTests: PubNubSwiftChatSDKIntegrationTests {
expectation.expectedFulfillmentCount = 1

let messageDraft = channel.createMessageDraft()
let listener = ClosureMessageDraftChangeListener(onChange: { elements, future in
let listener = ClosureMessageDraftChangeListener() { elements, future in
if !elements.containsAnyMention() {
future.async() {
switch $0 {
Expand All @@ -80,7 +80,7 @@ class MessageDraftIntegrationTests: PubNubSwiftChatSDKIntegrationTests {
}
}
}
})
}

messageDraft.addChangeListener(listener)
messageDraft.update(text: "This is a @user")
Expand Down Expand Up @@ -114,7 +114,7 @@ class MessageDraftIntegrationTests: PubNubSwiftChatSDKIntegrationTests {
expectation.expectedFulfillmentCount = 1

let messageDraft = channel.createMessageDraft()
let listener = ClosureMessageDraftChangeListener(onChange: { elements, future in
let listener = ClosureMessageDraftChangeListener() { elements, future in
if !elements.containsAnyMention() {
future.async() {
switch $0 {
Expand All @@ -130,7 +130,7 @@ class MessageDraftIntegrationTests: PubNubSwiftChatSDKIntegrationTests {
}
}
}
})
}

messageDraft.addChangeListener(listener)
messageDraft.update(text: "This is a #chnl")
Expand Down Expand Up @@ -178,12 +178,12 @@ class MessageDraftIntegrationTests: PubNubSwiftChatSDKIntegrationTests {
text: suggestedMention.replaceWith
)

let listener = ClosureMessageDraftChangeListener(onChange: { [unowned self] elements, future in
let listener = ClosureMessageDraftChangeListener() { [unowned self] elements, future in
XCTAssertEqual(elements.count, 2)
XCTAssertEqual(elements[0], .plainText(text: "Some prefix. This is a "))
XCTAssertEqual(elements[1], .link(text: channel.name ?? "", target: .channel(channelId: channel.id)))
expectation.fulfill()
})
}

messageDraft.addChangeListener(listener)
messageDraft.insertText(offset: 0, text: "Some prefix. ")
Expand Down Expand Up @@ -211,11 +211,11 @@ class MessageDraftIntegrationTests: PubNubSwiftChatSDKIntegrationTests {
text: suggestedMention.replaceWith
)

let listener = ClosureMessageDraftChangeListener(onChange: { [unowned self] elements, future in
let listener = ClosureMessageDraftChangeListener() { [unowned self] elements, future in
XCTAssertEqual(elements.count, 1)
XCTAssertEqual(elements[0], .link(text: channel.name ?? "", target: .channel(channelId: channel.id)))
expectation.fulfill()
})
}

messageDraft.addChangeListener(listener)
messageDraft.removeText(offset: 0, length: 10)
Expand Down Expand Up @@ -243,10 +243,10 @@ class MessageDraftIntegrationTests: PubNubSwiftChatSDKIntegrationTests {
text: suggestedMention.replaceWith
)

let listener = ClosureMessageDraftChangeListener(onChange: { [unowned self] elements, future in
let listener = ClosureMessageDraftChangeListener() { [unowned self] elements, future in
XCTAssertEqual(elements[0], .plainText(text: "This is a \(channel.name ?? "")"))
expectation.fulfill()
})
}

messageDraft.addChangeListener(listener)
messageDraft.removeMention(offset: suggestedMention.offset)
Expand Down Expand Up @@ -276,11 +276,11 @@ class MessageDraftIntegrationTests: PubNubSwiftChatSDKIntegrationTests {
text: suggestedMention.replaceWith
)

let listener = ClosureMessageDraftChangeListener(onChange: { elements, future in
let listener = ClosureMessageDraftChangeListener() { elements, future in
XCTAssertEqual(elements.count, 1)
XCTAssertFalse(elements[0].isLink())
expectation.fulfill()
})
}

messageDraft.addChangeListener(listener)
messageDraft.insertText(offset: 12, text: "_!!!!!_")
Expand Down Expand Up @@ -310,11 +310,11 @@ class MessageDraftIntegrationTests: PubNubSwiftChatSDKIntegrationTests {
text: suggestedMention.replaceWith
)

let listener = ClosureMessageDraftChangeListener(onChange: { elements, future in
let listener = ClosureMessageDraftChangeListener() { elements, future in
XCTAssertEqual(elements.count, 1)
XCTAssertFalse(elements[0].isLink())
expectation.fulfill()
})
}

messageDraft.addChangeListener(listener)
messageDraft.removeText(offset: 12, length: 5)
Expand Down

0 comments on commit af7db1d

Please sign in to comment.