Skip to content
Open
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 @@ -328,6 +328,53 @@
verify(detailsViewController)
}

func testThatItShowsReactionWithSkinToneModifier() throws {
// GIVEN
conversation = createGroupConversation()

let message = MockMessageFactory.textMessage(withText: "Message")
message.senderUser = SelfUser.provider?.providedSelfUser
message.conversationLike = conversation
message.deliveryState = .read
message.needsReadConfirmation = false
message.backingUsersReaction = ["🙌🏻": [otherUser]]

// WHEN
let dataSource = MessageDetailsDataSource(message: message, userSession: userSession)

// THEN
let reaction = try XCTUnwrap(dataSource.reactions.first)
XCTAssertEqual(dataSource.reactions.count, 1)
XCTAssertEqual(reaction.items.count, 1)
XCTAssertTrue(try XCTUnwrap(reaction.headerText).hasPrefix("🙌🏻 "))
XCTAssertTrue(try XCTUnwrap(reaction.headerText).hasSuffix("(1)"))
}

func testThatItShowsReactionWhenEmojiRepositoryDoesNotContainIt() throws {
// GIVEN
conversation = createGroupConversation()

let message = MockMessageFactory.textMessage(withText: "Message")
message.senderUser = SelfUser.provider?.providedSelfUser
message.conversationLike = conversation
message.deliveryState = .read
message.needsReadConfirmation = false
message.backingUsersReaction = ["🫡": [otherUser]]

// WHEN
let dataSource = MessageDetailsDataSource(
message: message,
userSession: userSession,
emojiRepository: EmptyEmojiRepository()
)

// THEN
let reaction = try XCTUnwrap(dataSource.reactions.first)
XCTAssertEqual(dataSource.reactions.count, 1)
XCTAssertEqual(reaction.headerText, "🫡 (1)")
XCTAssertEqual(reaction.items.count, 1)
}

// MARK: - Non-Combined Scenarios

func testThatItShowsReceiptsOnly_Ephemeral() {
Expand Down Expand Up @@ -491,3 +538,21 @@
}

}

private final class EmptyEmojiRepository: EmojiRepositoryInterface {

func emojis(for category: EmojiCategory) -> [Emoji] {

Check warning on line 544 in wire-ios/Wire-iOS Tests/MessageDetails/MessageDetailsViewControllerTests.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unused function parameter "category" or name it "_".

See more on https://sonarcloud.io/project/issues?id=wireapp_wire-ios&issues=AZ7cckS3amZtX-ZDm-xk&open=AZ7cckS3amZtX-ZDm-xk&pullRequest=4875
[]
}

func emoji(for id: String) -> Emoji? {

Check warning on line 548 in wire-ios/Wire-iOS Tests/MessageDetails/MessageDetailsViewControllerTests.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unused function parameter "id" or name it "_".

See more on https://sonarcloud.io/project/issues?id=wireapp_wire-ios&issues=AZ7cckS3amZtX-ZDm-xl&open=AZ7cckS3amZtX-ZDm-xl&pullRequest=4875
nil
}

func registerRecentlyUsedEmojis(_ emojis: [Emoji.ID]) {}

Check failure on line 552 in wire-ios/Wire-iOS Tests/MessageDetails/MessageDetailsViewControllerTests.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add a nested comment explaining why this function is empty, or complete the implementation.

See more on https://sonarcloud.io/project/issues?id=wireapp_wire-ios&issues=AZ7cckS3amZtX-ZDm-xm&open=AZ7cckS3amZtX-ZDm-xm&pullRequest=4875

Check warning on line 552 in wire-ios/Wire-iOS Tests/MessageDetails/MessageDetailsViewControllerTests.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unused function parameter "emojis" or name it "_".

See more on https://sonarcloud.io/project/issues?id=wireapp_wire-ios&issues=AZ7cckS3amZtX-ZDm-xn&open=AZ7cckS3amZtX-ZDm-xn&pullRequest=4875

func fetchRecentlyUsedEmojis() -> [Emoji] {
[]
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,30 @@ final class MessageDetailsDataSource: NSObject, ZMMessageObserver, UserObserving
private func setupReactions() {
reactions = message.usersReaction.lazy
.compactMap { reaction, users in
guard let emoji = self.emojiRepository.emoji(for: reaction) else { return nil }
let name = emoji.localizedName ?? emoji.name
let items = MessageDetailsCellDescription.makeReactionCells(users)
guard !items.isEmpty else { return nil }

return MessageDetailsSectionDescription(
headerText: "\(emoji.value) \(name.capitalized) (\(users.count))",
items: MessageDetailsCellDescription.makeReactionCells(users)
headerText: self.reactionHeaderText(for: reaction, userCount: users.count),
items: items
)
}
.filter { !$0.items.isEmpty }
.sorted { $0.items.count > $1.items.count }
}

private func reactionHeaderText(for reaction: String, userCount: Int) -> String {
guard let emoji = emoji(for: reaction) else {
return "\(reaction) (\(userCount))"
}

let name = emoji.localizedName ?? emoji.name
return "\(reaction) \(name.capitalized) (\(userCount))"
}

private func emoji(for reaction: String) -> Emoji? {
emojiRepository.emoji(for: reaction) ?? emojiRepository.emoji(for: reaction.removingEmojiSkinToneModifiers)
}

func setupReadReceipts() {
readReceipts = [
MessageDetailsSectionDescription(
Expand All @@ -210,3 +223,19 @@ final class MessageDetailsDataSource: NSObject, ZMMessageObserver, UserObserving
}

}

private extension String {

var removingEmojiSkinToneModifiers: String {
String(unicodeScalars.filter { !$0.isEmojiSkinToneModifier })
}

}

private extension Unicode.Scalar {

var isEmojiSkinToneModifier: Bool {
(0x1F3FB ... 0x1F3FF).contains(value)
}

}
Loading