diff --git a/WireFoundation/Sources/WireFoundation/Utilities/PrivateUserDefaults.swift b/WireFoundation/Sources/WireFoundation/Utilities/PrivateUserDefaults.swift index 084293e5e78..cdfee8637e6 100644 --- a/WireFoundation/Sources/WireFoundation/Utilities/PrivateUserDefaults.swift +++ b/WireFoundation/Sources/WireFoundation/Utilities/PrivateUserDefaults.swift @@ -93,6 +93,9 @@ public extension PrivateUserDefaults { storage.removeObject(forKey: scopeKey(key)) } + func stringArray(forKey key: Key) -> [String]? { + storage.stringArray(forKey: scopeKey(key)) + } } public protocol DefaultsKey { @@ -131,6 +134,8 @@ public protocol UserDefaultsProtocol { func removeObject(forKey defaultName: String) func dictionaryRepresentation() -> [String: Any] + + func stringArray(forKey defaultName: String) -> [String]? } public extension UserDefaultsProtocol { diff --git a/WireUI/Sources/WireReusableUIComponents/SDKExtensions/UIKit/UIView+Constraints.swift b/WireUI/Sources/WireReusableUIComponents/SDKExtensions/UIKit/UIView+Constraints.swift index 19aec9e5493..8fae7218abd 100644 --- a/WireUI/Sources/WireReusableUIComponents/SDKExtensions/UIKit/UIView+Constraints.swift +++ b/WireUI/Sources/WireReusableUIComponents/SDKExtensions/UIKit/UIView+Constraints.swift @@ -75,6 +75,14 @@ public extension UIView { return self } + @discardableResult + func minHeightConstraint(_ value: CGFloat) -> Self { + translatesAutoresizingMaskIntoConstraints = false + + heightAnchor.constraint(greaterThanOrEqualToConstant: 38).isActive = true + return self + } + @discardableResult func setTranslatesAutoresizingMaskIntoConstraints(_ value: Bool) -> Self { translatesAutoresizingMaskIntoConstraints = value @@ -115,4 +123,28 @@ public extension UIView { return view } + + /// Returns a container view which is specifically useful not to stretch its content. + func wrapInViewWithFlexibleTopAndBottom() -> UIView { + let view = UIView() + view.clipsToBounds = false + translatesAutoresizingMaskIntoConstraints = false + view.addSubview(self) + + let bottomConstraint = view.bottomAnchor.constraint(equalTo: bottomAnchor) + bottomConstraint.priority = .defaultLow + + let topConstraint = view.topAnchor.constraint(equalTo: topAnchor) + topConstraint.priority = .defaultLow + + NSLayoutConstraint.activate([ + leadingAnchor.constraint(equalTo: view.leadingAnchor), + view.trailingAnchor.constraint(equalTo: trailingAnchor), + topConstraint, + bottomConstraint + ]) + + return view + } + } diff --git a/wire-ios-data-model/Source/Model/Message/Message.swift b/wire-ios-data-model/Source/Model/Message/Message.swift index b8f1109a3d5..84bdb2c056f 100644 --- a/wire-ios-data-model/Source/Model/Message/Message.swift +++ b/wire-ios-data-model/Source/Model/Message/Message.swift @@ -26,6 +26,10 @@ public extension ZMConversationMessage { textMessageData != nil } + var isTextWithNoLinks: Bool { + isText && !hasLinks + } + var isImage: Bool { imageMessageData != nil || (fileMessageData != nil && fileMessageData!.v3_isImage) } @@ -64,6 +68,12 @@ public extension ZMConversationMessage { systemMessageData != nil } + // Checks if message has link preview or link attachment + // Does not check if there is Markdown links + var hasLinks: Bool { + textMessageData?.linkPreview != nil || linkAttachments?.first != nil + } + var isNormal: Bool { isText || isImage diff --git a/wire-ios/Tests/Mocks/MockMessage+Creation.swift b/wire-ios/Tests/Mocks/MockMessage+Creation.swift index da2e757ebb5..7e83c54df1a 100644 --- a/wire-ios/Tests/Mocks/MockMessage+Creation.swift +++ b/wire-ios/Tests/Mocks/MockMessage+Creation.swift @@ -212,6 +212,34 @@ enum MockMessageFactory { return message } + static func textMessageWithLinkAttachment( + withText text: String? = "Just a random text message", + sender: UserType? = nil, + conversation: Conversation? = nil, + includingRichMedia shouldIncludeRichMedia: Bool = false + ) -> MockMessage { + let message: MockMessage = MockMessageFactory.messageTemplate( + sender: sender, + conversation: conversation + ) + + let textMessageData = MockTextMessageData() + textMessageData + .messageText = shouldIncludeRichMedia ? + "Check this 500lb squirrel! -> https://www.youtube.com/watch?v=0so5er4X3dc" : text! + message.backingTextMessageData = textMessageData + + message.linkAttachments = [LinkAttachment( + type: .youTubeVideo, + title: "Lagar mat med Fernando Di Luca", + permalink: URL(string: "https://www.youtube.com/watch?v=l7aqpSTa234")!, + thumbnails: [], + originalRange: NSRange(location: 0, length: 5) + )] + + return message + } + static func linkMessage() -> MockMessage { let message = MockMessageFactory.messageTemplate() diff --git a/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationCollapsedMessageCellSnapshotTests.swift b/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationCollapsedMessageCellSnapshotTests.swift index d725b65814c..68b6923f5c1 100644 --- a/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationCollapsedMessageCellSnapshotTests.swift +++ b/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationCollapsedMessageCellSnapshotTests.swift @@ -55,12 +55,38 @@ final class ConversationCollapsedMessageCellSnapshotTests: ConversationMessageSn "location": MockMessageFactory.locationMessage(), "text": MockMessageFactory .textMessage( - withText: "Long long long Long long long Long long long Long long long Long long long Long long long" + withText: + """ + Long long long Long long long Long long long Long long long Long long long Long long long\n + Long long long Long long long Long long long Long long long Long long long Long long long + Long long long Long long long Long long long Long long long Long long long Long long long + """ ) ] messages.forEach { verify(message: $0.value, named: $0.key) } } + func testTextCollapsed() { + let messages: [String: MockMessage] = [ + "singleLineText": MockMessageFactory.textMessage(withText: "Single Line text"), + "twoLineText": MockMessageFactory.textMessage(withText: "First Line text\n Second line"), + "threeLineText": MockMessageFactory.textMessage( + withText: "Long long long Long long long Long long long Long long long Long long long Long long long" + ), + "moreThenThreeLineText": MockMessageFactory + .textMessage( + withText: + """ + Long long long Long long long Long long long Long long long Long long long Long long long\n + Long long long Long long long Long long long Long long long Long long long Long long long + Long long long Long long long Long long long Long long long Long long long Long long long + """ + ) + ] + messages.forEach { verify(message: $0.value, named: $0.key) } + + } + func testUploadedCell_fromThisDevice_collapseOwnMessagesDisabled() { message.backingFileMessageData.transferState = .uploaded message.backingFileMessageData.fileURL = Bundle.main.bundleURL diff --git a/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationMessageSectionControllerTests.swift b/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationMessageSectionControllerTests.swift index ddd3cf2adf3..3fe94abbdb8 100644 --- a/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationMessageSectionControllerTests.swift +++ b/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationMessageSectionControllerTests.swift @@ -47,6 +47,7 @@ final class ConversationMessageSectionControllerTests: XCTestCase { searchQueries: [], previousMessageIsKnock: false ) + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [] mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = false } @@ -281,12 +282,233 @@ final class ConversationMessageSectionControllerTests: XCTestCase { XCTAssertFalse(sut.isCollapsed) } + func testSavingWasUncollapsed_FileMessage() throws { + // Given + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true + let message = try XCTUnwrap(MockMessageFactory.fileTransferMessage()) + message.senderUser = mockSelfUser + let nonce = message.nonce!.uuidString + let sut = makeSUT(message: message) + XCTAssertTrue(sut.isCollapsed) + + let expectation = XCTestExpectation() + mockUserDefaults.setValueAnyForKeyDefaultNameStringVoidClosure = { value, _ in + XCTAssertEqual(value as? [String], [nonce]) + expectation.fulfill() + } + + // When: uncollapse + sut.collapse() + // Then + XCTAssertFalse(sut.isCollapsed) + wait(for: [expectation]) + } + + func testResetWasUncollapsed_FileMessage() throws { + // Given already saved that was uncollapsed + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true + let message = try XCTUnwrap(MockMessageFactory.fileTransferMessage()) + message.senderUser = mockSelfUser + let nonce = message.nonce!.uuidString + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [nonce] + // When + let sut = makeSUT(message: message) + // Then not collapsed + XCTAssertFalse(sut.isCollapsed) + + // Given + let expectation = XCTestExpectation() + mockUserDefaults.setValueAnyForKeyDefaultNameStringVoidClosure = { value, _ in + XCTAssertEqual(value as? [String], []) + expectation.fulfill() + } + // When collapse back + sut.collapse() + // Then is collapsed and removed what was saved + XCTAssertTrue(sut.isCollapsed) + wait(for: [expectation]) + } + + func testWhenWasUncollapsedBefore_File() throws { + // Given + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true + let message = try XCTUnwrap(MockMessageFactory.fileTransferMessage()) + message.senderUser = mockSelfUser + let nonce = message.nonce!.uuidString + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [nonce] + // When + let sut = makeSUT(message: message) + // Then re-create expected to take into account that it was uncollapsed before and stay uncollapsed + XCTAssertFalse(sut.isCollapsed) + } + + func testNotSavingWasUncollapsed_TextMessage() throws { + // Given + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true + let longText = """ + one + two + three + four + """ + let message = try XCTUnwrap( + MockMessageFactory.textMessage(withText: longText) + ) + message.senderUser = mockSelfUser + let sut = makeSUT(message: message) + XCTAssertTrue(sut.isCollapsed) + + let expectation = XCTestExpectation() + expectation.isInverted = true + mockUserDefaults.setValueAnyForKeyDefaultNameStringVoidClosure = { _, _ in + expectation.fulfill() + } + + // When uncollapse + sut.collapse() + // Then not collapsed + XCTAssertFalse(sut.isCollapsed) + // And not saved + wait(for: [expectation], timeout: 0) + } + + func testSavingWasUncollapsed_TextMessageWithLink() throws { + // Given + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true + let message = try XCTUnwrap( + MockMessageFactory.textMessageWithLinkAttachment(withText: "onetwothreefour") + ) + message.senderUser = mockSelfUser + let sut = makeSUT(message: message) + XCTAssertTrue(sut.isCollapsed) + + let expectation = XCTestExpectation() + mockUserDefaults.setValueAnyForKeyDefaultNameStringVoidClosure = { _, _ in + expectation.fulfill() + } + + // When uncollapse + sut.collapse() + // Then after re-created expected to take into account that it was uncollapsed before and stay uncollapsed + XCTAssertFalse(sut.isCollapsed) + // And saved + wait(for: [expectation], timeout: 0) + } + + func testNotCollapsed_TextMessageWithLink_SentByOther() throws { + // Given + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true + let message = try XCTUnwrap( + MockMessageFactory.textMessageWithLinkAttachment(withText: "onetwothreefour") + ) + message.senderUser = MockUserType.createDefaultOtherUser() + // When + let sut = makeSUT(message: message) + // Then + XCTAssertFalse(sut.isCollapsed) + } + + func testRecreatedCellBecomesCollapsed_LinkAttachmentMessage() { + // Given + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true + let message = MockMessageFactory.textMessage(withText: "www.example.com") + message.senderUser = mockSelfUser + let sut = makeSUT(message: message) + XCTAssertFalse(sut.isCollapsed) + XCTAssertEqual(sut.cellDescriptionsForTesting.count, 3) + + // When + message.linkAttachments = [LinkAttachment( + type: .youTubeVideo, + title: "Lagar mat med Fernando Di Luca", + permalink: URL(string: "https://www.youtube.com/watch?v=l7aqpSTa234")!, + thumbnails: [], + originalRange: NSRange(location: 0, length: 5) + )] + + sut.recreateCellDescriptions(in: sut.context) + // Then + XCTAssertEqual(sut.cellDescriptionsForTesting.count, 1) + XCTAssertTrue(sut.cellDescriptionsForTesting.first?.instance is ConversationCollapsedMessageCellDescription) + } + + func testRecreatedCellNotBecomesCollapsed_LinkAttachmentMessage_FromOther() { + // Given + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true + let message = MockMessageFactory.textMessage(withText: "www.example.com") + message.senderUser = MockUserType() + let sut = makeSUT(message: message) + XCTAssertFalse(sut.isCollapsed) + XCTAssertEqual(sut.cellDescriptionsForTesting.count, 3) + // When + message.linkAttachments = [LinkAttachment( + type: .youTubeVideo, + title: "Lagar mat med Fernando Di Luca", + permalink: URL(string: "https://www.youtube.com/watch?v=l7aqpSTa234")!, + thumbnails: [], + originalRange: NSRange(location: 0, length: 5) + )] + + sut.recreateCellDescriptions(in: sut.context) + // Then + XCTAssertEqual(sut.cellDescriptionsForTesting.count, 4) + } + + func testRecreatedCellBecomesCollapsed_LinkPreviewMessage() { + // Given + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true + let message = MockMessageFactory.textMessage(withText: "www.example.com") + message.senderUser = mockSelfUser + let sut = makeSUT(message: message) + XCTAssertFalse(sut.isCollapsed) + XCTAssertEqual(sut.cellDescriptionsForTesting.count, 3) + // When + let textData = MockTextMessageData() + let article = ArticleMetadata( + originalURLString: "http://foo.bar/baz", + permanentURLString: "http://foo.bar/baz", + resolvedURLString: "http://foo.bar/baz", + offset: 0 + ) + textData.backingLinkPreview = article + message.backingTextMessageData = textData + + sut.recreateCellDescriptions(in: sut.context) + // Then + XCTAssertEqual(sut.cellDescriptionsForTesting.count, 1) + XCTAssertTrue(sut.cellDescriptionsForTesting.first?.instance is ConversationCollapsedMessageCellDescription) + } + + func testRecreatedCellNotBecomesCollapsed_LinkPreviewMessage_FromOther() { + // Given + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true + let message = MockMessageFactory.textMessage(withText: "www.example.com") + message.senderUser = MockUserType() + let sut = makeSUT(message: message) + XCTAssertFalse(sut.isCollapsed) + XCTAssertEqual(sut.cellDescriptionsForTesting.count, 3) + // When + let textData = MockTextMessageData() + let article = ArticleMetadata( + originalURLString: "http://foo.bar/baz", + permanentURLString: "http://foo.bar/baz", + resolvedURLString: "http://foo.bar/baz", + offset: 0 + ) + textData.backingLinkPreview = article + message.backingTextMessageData = textData + + sut.recreateCellDescriptions(in: sut.context) + // Then + XCTAssertEqual(sut.cellDescriptionsForTesting.count, 3) + } + private func makeSUT( message: MockMessage = MockMessage(), context: ConversationMessageContext? = nil, useInvertedIndices: Bool = false ) -> ConversationMessageSectionController { - // WHEN + let section = ConversationMessageSectionController( message: message, context: context ?? self.context, diff --git a/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationMessageSnapshotTestCase.swift b/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationMessageSnapshotTestCase.swift index 60363c611ad..da88e03d6ac 100644 --- a/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationMessageSnapshotTestCase.swift +++ b/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationMessageSnapshotTestCase.swift @@ -53,6 +53,7 @@ class ConversationMessageSnapshotTestCase: ZMSnapshotTestCase { override func setUp() { super.setUp() userSession = UserSessionMock() + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [] mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = false } diff --git a/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationTextMessageTests.swift b/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationTextMessageTests.swift index b32c0839db9..b1a6fbc0e6c 100644 --- a/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationTextMessageTests.swift +++ b/wire-ios/Wire-iOS Tests/ConversationMessageCell/ConversationTextMessageTests.swift @@ -32,6 +32,7 @@ final class ConversationTextMessageTests: ConversationMessageSnapshotTestCase { super.setUp() UIColor.setAccentOverride(.red) message = createMessage() + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true } // MARK: - tearDown @@ -76,7 +77,13 @@ final class ConversationTextMessageTests: ConversationMessageSnapshotTestCase { message.backingTextMessageData.backingLinkPreview = article // THEN + + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [message.nonce!.uuidString] verify(message: message) + + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [] + message.senderUser = userSession.selfUser + verify(message: message, named: "Collapsed") } func testTextWithLinkPreview() { @@ -94,7 +101,14 @@ final class ConversationTextMessageTests: ConversationMessageSnapshotTestCase { message.backingTextMessageData.backingLinkPreview = article // THEN + + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [message.nonce!.uuidString] + verify(message: message) + + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [] + message.senderUser = userSession.selfUser + verify(message: message, named: "Collapsed") } func testTextWithQuote() { @@ -130,6 +144,7 @@ final class ConversationTextMessageTests: ConversationMessageSnapshotTestCase { message.backingTextMessageData.backingLinkPreview = article message.backingTextMessageData.hasQuote = true message.backingTextMessageData.quoteMessage = quote + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [message.nonce!.uuidString] // THEN verify(message: message) @@ -149,7 +164,14 @@ final class ConversationTextMessageTests: ConversationMessageSnapshotTestCase { ] // THEN + + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [message.nonce!.uuidString] + verify(message: message, waitForTextViewToLoad: true) + + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [] + message.senderUser = userSession.selfUser + verify(message: message, named: "Collapsed", waitForTextViewToLoad: true) } func testSoundCloudMediaPreviewAttachment() { @@ -173,6 +195,8 @@ final class ConversationTextMessageTests: ConversationMessageSnapshotTestCase { verify(message: message, waitForTextViewToLoad: true) } #else + verify(message: message, named: "Collapsed", waitForTextViewToLoad: true) + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [message.nonce!.uuidString] verify(message: message, waitForTextViewToLoad: true) #endif } @@ -190,6 +214,7 @@ final class ConversationTextMessageTests: ConversationMessageSnapshotTestCase { ) ] + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [message.nonce!.uuidString] // THEN verify(message: message, waitForTextViewToLoad: true) } @@ -218,7 +243,13 @@ final class ConversationTextMessageTests: ConversationMessageSnapshotTestCase { ] // THEN + + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [message.nonce!.uuidString] verify(message: message) + + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [] + message.senderUser = userSession.selfUser + verify(message: message, named: "Collapsed") } // MARK: - Helper Methods diff --git a/wire-ios/Wire-iOS Tests/ConversationMessageCell/MessageActionsViewControllerTests.swift b/wire-ios/Wire-iOS Tests/ConversationMessageCell/MessageActionsViewControllerTests.swift index be262c22260..c6bec32c7f6 100644 --- a/wire-ios/Wire-iOS Tests/ConversationMessageCell/MessageActionsViewControllerTests.swift +++ b/wire-ios/Wire-iOS Tests/ConversationMessageCell/MessageActionsViewControllerTests.swift @@ -34,6 +34,8 @@ final class MessageActionsViewControllerTests: XCTestCase { let mockSelfUser = MockUserType.createSelfUser(name: "selfUser") SelfUser.provider = SelfProvider(providedSelfUser: mockSelfUser) + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [] + mockUserDefaults.setValueAnyForKeyDefaultNameStringVoidClosure = { _, _ in } mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = false } @@ -186,7 +188,6 @@ final class MessageActionsViewControllerTests: XCTestCase { actionController.isCollapsed?.toggle() XCTAssertEqual(actionController.isCollapsed, false) - XCTAssertEqual(actionController.selfUserId, selfUser.remoteIdentifier) let sut = MessageActionsViewController.controller( withActions: MessageAction.allCases, @@ -202,6 +203,38 @@ final class MessageActionsViewControllerTests: XCTestCase { ) } + func testMenuActionsForImageMessage_collapseOwnMessagesEnabled_wasUncollapsedBefore() { + // GIVEN + let selfUser = MockUserType.createSelfUser(name: "Tarja Turunen") + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true + + let message = MockMessageFactory.imageMessage() + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [message.nonce!.uuidString] + // WHEN + let (actionController, _) = makeSut( + message: message, + sender: selfUser, + isCollapsed: false, + selfUserId: selfUser.remoteIdentifier + ) + message.senderUser = selfUser + + XCTAssertEqual(actionController.isCollapsed, false) + + let sut = MessageActionsViewController.controller( + withActions: MessageAction.allCases, + actionController: actionController + ) + + // expand message + + // THEN + XCTAssertEqual( + sut.titles, + ["Copy", "Collapse", "Reply", "Details", "Save", "Delete", "Cancel"] + ) + } + func testMenuActionsForFileMessage_fromOtherUser_hasNoCollapse() { // GIVEN let message = MockMessageFactory.fileTransferMessage() @@ -217,12 +250,55 @@ final class MessageActionsViewControllerTests: XCTestCase { message.senderUser = selfUser XCTAssertEqual(actionController.isCollapsed, false) - XCTAssertEqual(actionController.selfUserId, selfUser.remoteIdentifier) // THEN XCTAssertEqual(sut.titles, ["Reply", "Details", "Download", "Delete", "Cancel"]) } + func testMenuActionsForTextMessageWithPreview_hasCollapse() { + // GIVEN + let message = MockMessageFactory.linkMessage() + let selfUser = MockUserType.createSelfUser(name: "Tarja Turunen") + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [message.nonce!.uuidString] + + // WHEN + let (actionController, sut) = makeSut( + message: message, + sender: selfUser, + isCollapsed: false, + selfUserId: selfUser.remoteIdentifier + ) + message.senderUser = selfUser + + XCTAssertEqual(actionController.isCollapsed, false) + + // THEN + XCTAssertTrue(sut.titles.contains("Collapse")) + } + + func testMenuActionsForTextMessageWithLinkAttachments_hasCollapse() { + // GIVEN + let message = MockMessageFactory.textMessageWithLinkAttachment() + let selfUser = MockUserType.createSelfUser(name: "Tarja Turunen") + mockUserDefaults.boolForKeyDefaultNameStringBoolReturnValue = true + mockUserDefaults.stringArrayForKeyDefaultNameStringStringReturnValue = [message.nonce!.uuidString] + + // WHEN + let (actionController, sut) = makeSut( + message: message, + sender: selfUser, + isCollapsed: false, + selfUserId: selfUser.remoteIdentifier + ) + message.senderUser = selfUser + + XCTAssertEqual(actionController.isCollapsed, false) + + // THEN + XCTAssertTrue(sut.titles.contains("Collapse")) + } + private func actionsTitlesForMessage(message: MockMessage) -> [String] { makeSut(message: message).1.titles } diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.moreThenThreeLineText-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.moreThenThreeLineText-320-0.png new file mode 100644 index 00000000000..e7a9a0f0f35 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.moreThenThreeLineText-320-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2bef5c6811044f4257c628a74838502a60e2c3599ae3146734c55604eaf5fdbd +size 19377 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.moreThenThreeLineText-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.moreThenThreeLineText-375-0.png new file mode 100644 index 00000000000..df8b4edf0c3 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.moreThenThreeLineText-375-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec1f848d36d8055680ccaa17a16732dd406184d4a55fe0223d2c30f0de22f7a6 +size 20050 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.moreThenThreeLineText-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.moreThenThreeLineText-414-0.png new file mode 100644 index 00000000000..3a1cd5ee9f8 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.moreThenThreeLineText-414-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9529e3d960a41fdcfdb7fda6d50fd16b04f534403354ff44e90d5bfb82f834f +size 23482 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.singleLineText-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.singleLineText-320-0.png new file mode 100644 index 00000000000..43c4778c8eb --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.singleLineText-320-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04e9b12d826a12f28204f9ca3f7aa54f2ab30b1408f64de1ad87d81bbb830445 +size 17204 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.singleLineText-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.singleLineText-375-0.png new file mode 100644 index 00000000000..83a84153060 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.singleLineText-375-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b006be4eef6a1848bbeac39002a68cda50c5285c6a5d069d54235b0a0d9990b +size 18103 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.singleLineText-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.singleLineText-414-0.png new file mode 100644 index 00000000000..5ed62111cda --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.singleLineText-414-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c4002de2dc5aaa1e3c4eac30202b11d81749fe3dd8a5b979e95dc868fb1c23c +size 18634 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.threeLineText-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.threeLineText-320-0.png new file mode 100644 index 00000000000..d221f971b31 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.threeLineText-320-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f50116d5b8afad18aa627086c4dd80a4b336f01ea88671d883e70864c87d76a4 +size 26902 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.threeLineText-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.threeLineText-375-0.png new file mode 100644 index 00000000000..239ea3adc19 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.threeLineText-375-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60f26d47301d73c975e456bc1f7bd29d1b0867e441efbd79a9f0fa16314b6e2a +size 28124 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.threeLineText-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.threeLineText-414-0.png new file mode 100644 index 00000000000..9574e3316b0 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.threeLineText-414-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef16b398b532dcc8d7f6ec33cae3cd2486a908b57d716d873120f704bc120ca2 +size 24880 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.twoLineText-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.twoLineText-320-0.png new file mode 100644 index 00000000000..24a44a3631c --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.twoLineText-320-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5e9ad3cb25c747c97b894bb139c42b1f52a2df3bcb1001b93fd59376f6a80f5 +size 22501 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.twoLineText-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.twoLineText-375-0.png new file mode 100644 index 00000000000..104f53114ca --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.twoLineText-375-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29ddcabdc02ded7d4daa376f1fe596b1ba4c900985876de17d0fbbfb4235ac71 +size 23718 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.twoLineText-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.twoLineText-414-0.png new file mode 100644 index 00000000000..07254e54346 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testTextCollapsed.twoLineText-414-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:959b8d11face63c02472673d498c0c80dd4c77ced7dc7f6876f546557ef489b9 +size 24437 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.audio-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.audio-320-0.png index 3561780fed4..53407031f56 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.audio-320-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.audio-320-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8501559c5d3b081eb2eafa1d98b0cfafa32c180832123e497cf82a68c652ab20 -size 14307 +oid sha256:bc25c88eb3ea4f0b6bec53ba8fdcf6a9a31b9fb8cf81776146e8455ee26a5156 +size 14345 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.audio-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.audio-375-0.png index b95a7467eb4..a6a5c7e4ffe 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.audio-375-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.audio-375-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4e515d7d3c7a1bc01ead4cd3dd877958b6ee7140429a08dcb5a23dcf98259f12 -size 14861 +oid sha256:322a4dd8efa8298127e3ea9aba3c57f38a96ca26f41c8b02741fa982417e7754 +size 14868 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.audio-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.audio-414-0.png index 813b92fb299..1a9253091e4 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.audio-414-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.audio-414-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0b429241d6d88085a6b0857ebfc7b762fcc47bba7554ca8d4aff7aca23798f0b -size 15270 +oid sha256:fd1cf2c7e91c8a07063ab1fdf5678a9ebcd7cc05d7860cc4e17f0239bba36f2a +size 15332 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.file-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.file-320-0.png index 7321ab01665..eef18e545a1 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.file-320-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.file-320-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:222ddcbbd6b6da030daa821ef7f437f1615e88b5d89825841c4a284179bc087d -size 12221 +oid sha256:a71b8f651d328861ff302ad62bba5650ad00d84ef6fea668da8e88f6ad81b33e +size 12200 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.file-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.file-375-0.png index a2447a4466e..6da197a4d4f 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.file-375-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.file-375-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:399fe84bc9d2f866cc74b8eeaa29af6267ba083dff7a08b1217307aae5306a2e -size 12666 +oid sha256:de370f05540c1621b7afed3bb43e897eefd7114e9d793791da9e639b2103a970 +size 12726 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.file-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.file-414-0.png index 580c34b159e..6a260323934 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.file-414-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.file-414-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:91114f256139e3e4f6ec2228d3f01ca0f7aec4ac3df1da1cd0084df3e7205424 -size 13052 +oid sha256:45104087ece8843cd58b4e017d5991aebdd8e7676893d08267e62f2c2753394b +size 13053 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.image-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.image-320-0.png index 9299aa80ca5..00810cf5373 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.image-320-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.image-320-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:545189c220aadf4b9318608f2b125be60df067b0643eee4556fe50906e85d907 -size 12811 +oid sha256:9a7be8637d76e8a0ff513c5e5c13768afc28248c0bc2e51eb798f14175068070 +size 12937 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.image-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.image-375-0.png index 034acfeb46b..19a9e8550e7 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.image-375-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.image-375-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:618be66211cab554e387b6297cb89bfa09f6c3a5a62674de3b78e31d3cf782b6 -size 13373 +oid sha256:f55842cd8c148c1f0cc03de64d9f9cf966f2288c4cedb89806e2552238cf5ce2 +size 13430 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.image-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.image-414-0.png index 43803d85663..c23997ebdc7 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.image-414-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.image-414-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ec878949ab2cb48f808f98c9f960a80ee04c1cae2a3fec09662ae68ff899c929 -size 13789 +oid sha256:dbfe9c781b40ed960e44914c1749859c8e91b373090624440e809316baed4fec +size 13822 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.location-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.location-320-0.png index d8b04d17a3c..aea29fda4f8 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.location-320-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.location-320-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ec33c25e3ff659c3087a18c9686c308a524ffc78c5c07fd06b8df82a6ecd456 -size 13288 +oid sha256:6b68d0d4ac7d086b8f5c5e1f9d729ea45b4e29a6db708fa9017a4bd159254d14 +size 13364 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.location-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.location-375-0.png index 72ea4702712..82c193570e7 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.location-375-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.location-375-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a6b41b4648df905f440c7983a91370e6370295e30851f86d1dd4ff30ced8c6ce -size 13881 +oid sha256:a2f99bd8f1489860f7473076c1241ff560d2a98e5d84511005df5bccd2b1ab73 +size 13935 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.location-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.location-414-0.png index eb6b8619180..cd7e074752e 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.location-414-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.location-414-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:824bfae36915b4513e1955c4d79012dea35c39003f645d7ddf9a00e196ed1601 -size 14274 +oid sha256:2b91224e218f50322a87de72dbfc60df4e3bcc5055dfa76263216c7add324706 +size 14321 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.text-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.text-320-0.png index e3578ef13c1..e7a9a0f0f35 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.text-320-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.text-320-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3b0b344c8e213b0fe7dee63fee6a63e8011de04826e8ba412b8aba7f899a3919 -size 8937 +oid sha256:2bef5c6811044f4257c628a74838502a60e2c3599ae3146734c55604eaf5fdbd +size 19377 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.text-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.text-375-0.png index ef63232a036..df8b4edf0c3 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.text-375-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.text-375-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:15cf518005efb963461ab70d1f169facca1594bbfd70e0248b8d032b83b1f5a5 -size 9765 +oid sha256:ec1f848d36d8055680ccaa17a16732dd406184d4a55fe0223d2c30f0de22f7a6 +size 20050 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.text-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.text-414-0.png index 878be4accd7..3a1cd5ee9f8 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.text-414-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.text-414-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ebea08a7eaaa2c19d70cf686432253a903dc95348fd30b1b6a7e64bbf01f075 -size 10322 +oid sha256:b9529e3d960a41fdcfdb7fda6d50fd16b04f534403354ff44e90d5bfb82f834f +size 23482 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.video-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.video-320-0.png index e0f2686168c..cee949626ec 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.video-320-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.video-320-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:00fee86b8bf191745c438212814a5ec7451923637182830835fa0bdd719eb7ea -size 12285 +oid sha256:47968b94a291ceb745fa7a6f03595933c47ea427bb3b3d244b97026363367d22 +size 12342 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.video-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.video-375-0.png index 2223ccac5ef..dd520d62003 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.video-375-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.video-375-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b20548fa392f1c1cf58f4da71b01914553c6e2922aca7dc265d1735df3f0dd80 -size 12862 +oid sha256:bb6c2d40400e6272442a027b0c3db7edb05bf3e12f26f4988a2704ad82e5b841 +size 12901 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.video-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.video-414-0.png index 35ffd1a69cf..33f81d1a78d 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.video-414-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationCollapsedMessageCellSnapshotTests/testUploadedCell_fromThisDevice.video-414-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d63a93af93bc1cbedf9715c854cb8517edce7b63a1a015f07281a42c49d6923 -size 13196 +oid sha256:26f901f8ea07dec70e84b84fccde34b04b6d3c22f319b4a24660ab5f585a29e0 +size 13254 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testBlacklistedLinkPreview_YouTube.Collapsed-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testBlacklistedLinkPreview_YouTube.Collapsed-320-0.png new file mode 100644 index 00000000000..c9cddfa8be1 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testBlacklistedLinkPreview_YouTube.Collapsed-320-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28040653778ce7a7db2306aee64de2772869e5f209cbc591e8e7c227dfb2a773 +size 13289 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testBlacklistedLinkPreview_YouTube.Collapsed-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testBlacklistedLinkPreview_YouTube.Collapsed-375-0.png new file mode 100644 index 00000000000..95ad1a27994 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testBlacklistedLinkPreview_YouTube.Collapsed-375-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56784d2e504b817b2f843f28b44dda39db1bda9e67d60c464dbe2e12b57533d3 +size 13818 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testBlacklistedLinkPreview_YouTube.Collapsed-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testBlacklistedLinkPreview_YouTube.Collapsed-414-0.png new file mode 100644 index 00000000000..103a14c1d05 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testBlacklistedLinkPreview_YouTube.Collapsed-414-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:246efb2c1d315734da6e659dac4f76d81a41d08dabeed3040413380837d04e0d +size 14148 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testLinkPreview.Collapsed-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testLinkPreview.Collapsed-320-0.png new file mode 100644 index 00000000000..c9cddfa8be1 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testLinkPreview.Collapsed-320-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28040653778ce7a7db2306aee64de2772869e5f209cbc591e8e7c227dfb2a773 +size 13289 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testLinkPreview.Collapsed-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testLinkPreview.Collapsed-375-0.png new file mode 100644 index 00000000000..95ad1a27994 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testLinkPreview.Collapsed-375-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56784d2e504b817b2f843f28b44dda39db1bda9e67d60c464dbe2e12b57533d3 +size 13818 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testLinkPreview.Collapsed-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testLinkPreview.Collapsed-414-0.png new file mode 100644 index 00000000000..103a14c1d05 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testLinkPreview.Collapsed-414-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:246efb2c1d315734da6e659dac4f76d81a41d08dabeed3040413380837d04e0d +size 14148 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testMediaPreviewAttachment.Collapsed-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testMediaPreviewAttachment.Collapsed-320-0.png new file mode 100644 index 00000000000..c9cddfa8be1 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testMediaPreviewAttachment.Collapsed-320-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28040653778ce7a7db2306aee64de2772869e5f209cbc591e8e7c227dfb2a773 +size 13289 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testMediaPreviewAttachment.Collapsed-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testMediaPreviewAttachment.Collapsed-375-0.png new file mode 100644 index 00000000000..95ad1a27994 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testMediaPreviewAttachment.Collapsed-375-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56784d2e504b817b2f843f28b44dda39db1bda9e67d60c464dbe2e12b57533d3 +size 13818 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testMediaPreviewAttachment.Collapsed-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testMediaPreviewAttachment.Collapsed-414-0.png new file mode 100644 index 00000000000..103a14c1d05 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testMediaPreviewAttachment.Collapsed-414-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:246efb2c1d315734da6e659dac4f76d81a41d08dabeed3040413380837d04e0d +size 14148 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreview.Collapsed-320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreview.Collapsed-320-0.png new file mode 100644 index 00000000000..c9cddfa8be1 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreview.Collapsed-320-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28040653778ce7a7db2306aee64de2772869e5f209cbc591e8e7c227dfb2a773 +size 13289 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreview.Collapsed-375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreview.Collapsed-375-0.png new file mode 100644 index 00000000000..95ad1a27994 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreview.Collapsed-375-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56784d2e504b817b2f843f28b44dda39db1bda9e67d60c464dbe2e12b57533d3 +size 13818 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreview.Collapsed-414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreview.Collapsed-414-0.png new file mode 100644 index 00000000000..103a14c1d05 --- /dev/null +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreview.Collapsed-414-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:246efb2c1d315734da6e659dac4f76d81a41d08dabeed3040413380837d04e0d +size 14148 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreviewAndQuote.320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreviewAndQuote.320-0.png index c62c5d61133..67aa7a81ec5 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreviewAndQuote.320-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreviewAndQuote.320-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:264b942a72cadc713575e5d0e0de9b126e370d0c020caf369f66b47034f82ac6 -size 57428 +oid sha256:c4d6569c79738d5f8641000f5cdcc13794242520159a0e7c381757987688a654 +size 56078 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreviewAndQuote.375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreviewAndQuote.375-0.png index 570ee3322f5..bd7202d5407 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreviewAndQuote.375-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreviewAndQuote.375-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b19fed7249c15972b7b748c703d2950e5a98afdaaf3a969bafc6c14577f8ce90 -size 56665 +oid sha256:13f389aa6e9213c1b6d7ddbe180d4a17e69e9c33492294537d12a4ce0b617d00 +size 55280 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreviewAndQuote.414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreviewAndQuote.414-0.png index 44a9ae2ae54..6947ed50449 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreviewAndQuote.414-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationTextMessageTests/testTextWithLinkPreviewAndQuote.414-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7040a8858d97860137da9b22e68ad183597f7358a2c5c11ffdabda1889ea3376 -size 58833 +oid sha256:5551dadb950a003999dbdb1c5e15efacf3fecfae3cddb2c3956f92759455b36e +size 57469 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/SettingsTableViewControllerSnapshotTests/testForOptionsGroupFullTableView.1.png b/wire-ios/Wire-iOS Tests/ReferenceImages/SettingsTableViewControllerSnapshotTests/testForOptionsGroupFullTableView.1.png index cb8738306ec..326d52fbf39 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/SettingsTableViewControllerSnapshotTests/testForOptionsGroupFullTableView.1.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/SettingsTableViewControllerSnapshotTests/testForOptionsGroupFullTableView.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a32fbba4029071f612173d4c65bcb82ea0ca8a1ebfd16fb9faa8b12f707dddc4 -size 403832 +oid sha256:35afbafc153833ebc702fa7335eb755e816d7c0281ba5b9e87975b565386f0cd +size 403899 diff --git a/wire-ios/Wire-iOS UnitTests/Developer/DeveloperTools/DebugActions/DeveloperDebugActionsViewModelTests.swift b/wire-ios/Wire-iOS UnitTests/Developer/DeveloperTools/DebugActions/DeveloperDebugActionsViewModelTests.swift index 6435b4e774e..bc903ded22f 100644 --- a/wire-ios/Wire-iOS UnitTests/Developer/DeveloperTools/DebugActions/DeveloperDebugActionsViewModelTests.swift +++ b/wire-ios/Wire-iOS UnitTests/Developer/DeveloperTools/DebugActions/DeveloperDebugActionsViewModelTests.swift @@ -27,7 +27,7 @@ final class DeveloperDebugActionsViewModelTests: XCTestCase { // when // then - XCTAssertEqual(viewModel.debugItems.count, 11) + XCTAssertEqual(viewModel.debugItems.count, 12) } // MARK: - Helpers diff --git a/wire-ios/Wire-iOS/Generated/Strings+Generated.swift b/wire-ios/Wire-iOS/Generated/Strings+Generated.swift index daddebe6c58..2caaf63c113 100644 --- a/wire-ios/Wire-iOS/Generated/Strings+Generated.swift +++ b/wire-ios/Wire-iOS/Generated/Strings+Generated.swift @@ -1703,6 +1703,10 @@ internal enum L10n { /// You sent a picture internal static let title = L10n.tr("Localizable", "content.collapsed.image.title", fallback: "You sent a picture") } + internal enum Link { + /// You sent a link + internal static let title = L10n.tr("Localizable", "content.collapsed.link.title", fallback: "You sent a link") + } internal enum Location { /// You sent your location internal static let title = L10n.tr("Localizable", "content.collapsed.location.title", fallback: "You sent your location") @@ -5690,8 +5694,8 @@ internal enum L10n { /// Lock With Passcode internal static let lockApp = L10n.tr("Localizable", "self.settings.privacy_security.lock_app", fallback: "Lock With Passcode") internal enum CollapseOwnMessages { - /// When this is on, all your messages collapse to a single line. - internal static let footer = L10n.tr("Localizable", "self.settings.privacy_security.collapse_own_messages.footer", fallback: "When this is on, all your messages collapse to a single line.") + /// When this is on, all your messages collapse after three lines. + internal static let footer = L10n.tr("Localizable", "self.settings.privacy_security.collapse_own_messages.footer", fallback: "When this is on, all your messages collapse after three lines.") /// Collapse my messages internal static let title = L10n.tr("Localizable", "self.settings.privacy_security.collapse_own_messages.title", fallback: "Collapse my messages") } diff --git a/wire-ios/Wire-iOS/Resources/Images/Images.xcassets/Link.imageset/Contents.json b/wire-ios/Wire-iOS/Resources/Images/Images.xcassets/Link.imageset/Contents.json new file mode 100644 index 00000000000..9963d717cb7 --- /dev/null +++ b/wire-ios/Wire-iOS/Resources/Images/Images.xcassets/Link.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "Link.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/wire-ios/Wire-iOS/Resources/Images/Images.xcassets/Link.imageset/Link.svg b/wire-ios/Wire-iOS/Resources/Images/Images.xcassets/Link.imageset/Link.svg new file mode 100644 index 00000000000..3239284b9f6 --- /dev/null +++ b/wire-ios/Wire-iOS/Resources/Images/Images.xcassets/Link.imageset/Link.svg @@ -0,0 +1,3 @@ + + + diff --git a/wire-ios/Wire-iOS/Resources/Localization/Base.lproj/Localizable.strings b/wire-ios/Wire-iOS/Resources/Localization/Base.lproj/Localizable.strings index 9ec59635b8c..ec45751ccbf 100644 --- a/wire-ios/Wire-iOS/Resources/Localization/Base.lproj/Localizable.strings +++ b/wire-ios/Wire-iOS/Resources/Localization/Base.lproj/Localizable.strings @@ -654,6 +654,7 @@ "content.collapsed.video.title" = "You sent a video"; "content.collapsed.audio.title" = "You sent an audio message"; "content.collapsed.location.title" = "You sent your location"; +"content.collapsed.link.title" = "You sent a link"; "content.message.like" = "Like"; "content.message.unlike" = "Unlike"; @@ -1327,7 +1328,7 @@ "self.settings.privacy_security.disable_link_previews.footer" = "Previews may still be shown for links from other people."; "self.settings.privacy_security.collapse_own_messages.title" = "Collapse my messages"; -"self.settings.privacy_security.collapse_own_messages.footer" = "When this is on, all your messages collapse to a single line."; +"self.settings.privacy_security.collapse_own_messages.footer" = "When this is on, all your messages collapse after three lines."; "self.settings.privacy_analytics_menu.devices.title" = "Devices"; diff --git a/wire-ios/Wire-iOS/Sources/Components/Settings/SettingsPropertyFactory.swift b/wire-ios/Wire-iOS/Sources/Components/Settings/SettingsPropertyFactory.swift index 967638790ca..6e7a66cf431 100644 --- a/wire-ios/Wire-iOS/Sources/Components/Settings/SettingsPropertyFactory.swift +++ b/wire-ios/Wire-iOS/Sources/Components/Settings/SettingsPropertyFactory.swift @@ -452,4 +452,5 @@ final class SettingsPropertyFactory { enum CollapseKey: String, DefaultsKey { case collapseOwnMessages + case uncollapsedMessages } diff --git a/wire-ios/Wire-iOS/Sources/Developer/DeveloperTools/DebugActions/DeveloperDebugActionsViewModel.swift b/wire-ios/Wire-iOS/Sources/Developer/DeveloperTools/DebugActions/DeveloperDebugActionsViewModel.swift index 74ed69d4e3b..1a5a6debd2d 100644 --- a/wire-ios/Wire-iOS/Sources/Developer/DeveloperTools/DebugActions/DeveloperDebugActionsViewModel.swift +++ b/wire-ios/Wire-iOS/Sources/Developer/DeveloperTools/DebugActions/DeveloperDebugActionsViewModel.swift @@ -19,6 +19,7 @@ import Foundation import SwiftUI import WireDataModel +import WireFoundation import WireLogging import WireSyncEngine @@ -78,7 +79,8 @@ final class DeveloperDebugActionsViewModel: ObservableObject { .init(title: "Update MLS migration status", action: updateMLSMigrationStatus), .init(title: "Delete domains in the database", action: deleteDomains), .init(title: "Find Conversation with MLS Group", action: showSearchMLSConversations), - .init(title: "Clear access token & cookie (forces logout)", action: clearAccessTokenAndCookie) + .init(title: "Clear access token & cookie (forces logout)", action: clearAccessTokenAndCookie), + .init(title: "Clear collapsed messages cache", action: clearCollapsedMessagesCache) ] let toggleItems: [DeveloperDebugActionsDisplayModel.ToggleItem] = [ @@ -118,6 +120,14 @@ final class DeveloperDebugActionsViewModel: ObservableObject { onDismiss?() } + private func clearCollapsedMessagesCache() { + let defaults = PrivateUserDefaults( + userID: selfClient!.user!.remoteIdentifier + ) + defaults.removeObject(forKey: .uncollapsedMessages) + onDismiss?() + } + // MARK: Send Logs private func sendDebugLogs() { diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Content/Text/ConversationCollapsedMessageCell.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Content/Text/ConversationCollapsedMessageCell.swift index f6e1ae3b8ec..c441323d741 100644 --- a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Content/Text/ConversationCollapsedMessageCell.swift +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Content/Text/ConversationCollapsedMessageCell.swift @@ -92,7 +92,7 @@ final class ConversationCollapsedMessageCell: UIView, ConversationMessageCell { view.setContentHuggingPriority(.required, for: .vertical) view.setContentCompressionResistancePriority(.required, for: .vertical) - view.textContainer.maximumNumberOfLines = 1 + view.textContainer.maximumNumberOfLines = 3 view.isScrollEnabled = false view.textContainer.lineBreakMode = .byTruncatingTail @@ -145,7 +145,7 @@ final class ConversationCollapsedMessageCell: UIView, ConversationMessageCell { } let message = object.message - if message.isText { + if message.isText, !message.hasLinks { typeIcon.isHidden = true if let textMessageData = message.textMessageData { messageTextView.attributedText = NSAttributedString @@ -174,6 +174,9 @@ final class ConversationCollapsedMessageCell: UIView, ConversationMessageCell { } else if message.isFile { typeIcon.image = .init(resource: .file) messageTextView.text = L10n.Localizable.Content.Collapsed.File.title + } else if message.hasLinks { + typeIcon.image = .init(resource: .link) + messageTextView.text = L10n.Localizable.Content.Collapsed.Link.title } } @@ -204,28 +207,45 @@ final class ConversationCollapsedMessageCell: UIView, ConversationMessageCell { let spacingView = UIView() spacingView.widthAnchor.constraint(equalToConstant: 13).isActive = true + let rightStack = [typeIcon, collapseButton.wrapInView(trailingInset: margins.right)] + .horizontalStack(spacing: 8, alignment: .center) + let stack = UIStackView.horizontal( views: [ spacingView, - avatar, + avatar.wrapInViewWithFlexibleTopAndBottom(), messageTextView, - [typeIcon, collapseButton.wrapInView(trailingInset: margins.right)] - .horizontalStack(spacing: 8) - .wrapInView(bottomInset: -1) + rightStack.wrapInViewWithFlexibleTopAndBottom() ], spacing: 7, - alignment: .center + alignment: .top ) stack.setCustomSpacing(12, after: avatar) stack.setCustomSpacing(10, after: messageTextView) - addSubview(stack) + rightStack.centerYAnchor + .constraint( + equalTo: messageTextView.firstBaselineAnchor, + constant: -5 + ).isActive = true + + avatar.centerYAnchor + .constraint( + equalTo: messageTextView.firstBaselineAnchor, + constant: -5 + ).isActive = true + + let stackWithTopMargin = stack.wrapInView(topInset: 8) + addSubview(stackWithTopMargin) + + stackWithTopMargin + .pin(to: self) + .minHeightConstraint(30) + .setIsUserInteractionEnabled(false) stack .setTranslatesAutoresizingMaskIntoConstraints(false) .setIsUserInteractionEnabled(false) - .pin(to: self) - .heightConstraint(38) typeIcon.constraintToSquare(sideLength: 16) } diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/ConversationMessageActionController.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/ConversationMessageActionController.swift index c65f6d45f58..65967a640fc 100644 --- a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/ConversationMessageActionController.swift +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/ConversationMessageActionController.swift @@ -41,13 +41,9 @@ final class ConversationMessageActionController { private var isCollapsedWasUpdated: Bool = false - /// used to get collapse own messages settings for a specific user - /// nil if not applicable - var selfUserId: UUID? - weak var responder: MessageActionResponder? weak var view: UIView! - private let userDefaults: UserDefaultsProtocol + private var privateDefaults: PrivateUserDefaults? init( responder: MessageActionResponder?, @@ -63,8 +59,9 @@ final class ConversationMessageActionController { self.context = context self.view = view self.isCollapsed = isCollapsed - self.selfUserId = selfUserId - self.userDefaults = userDefaults + if let selfUserId { + self.privateDefaults = PrivateUserDefaults(userID: selfUserId, storage: userDefaults) + } } // MARK: - List of Actions @@ -75,9 +72,7 @@ final class ConversationMessageActionController { } private var collapseOwnMessagesEnabled: Bool { - guard let selfUserId else { return false } - return PrivateUserDefaults(userID: selfUserId, storage: userDefaults) - .bool(forKey: .collapseOwnMessages) + privateDefaults?.bool(forKey: .collapseOwnMessages) ?? false } func allMessageMenuElements() -> [UIAction] { @@ -147,9 +142,11 @@ final class ConversationMessageActionController { return message.canVisitLink case .collapse: guard let isCollapsed, - collapseOwnMessagesEnabled, !isCollapsed, - isCollapsedWasUpdated else { + isCollapsedWasUpdated || ( + message.isCollapsingSupported && wasUncollapsedBefore() + ) + else { return false } @@ -161,6 +158,11 @@ final class ConversationMessageActionController { } } + private func wasUncollapsedBefore() -> Bool { + privateDefaults? + .wasMessagedUncollapsedBefore(message) ?? false + } + func canPerformAction(_ selector: Selector) -> Bool { guard let action = MessageAction.allCases.first(where: { $0.selector == selector diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/ConversationMessageSectionController.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/ConversationMessageSectionController.swift index e0c040866c3..972349758d6 100644 --- a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/ConversationMessageSectionController.swift +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/ConversationMessageSectionController.swift @@ -111,7 +111,7 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { private var changeObservers: [Any] = [] private let userSession: UserSession - private let userDefaults: UserDefaultsProtocol + private let privateDefaults: PrivateUserDefaults /// width of a container view to calculate whether message should be collapsed var contentWidth: CGFloat @@ -137,7 +137,10 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { self.userSession = userSession self.useInvertedIndices = useInvertedIndices self.contentWidth = contentWidth - self.userDefaults = userDefaults + self.privateDefaults = PrivateUserDefaults( + userID: selfUser.remoteIdentifier, + storage: userDefaults + ) super.init() @@ -153,9 +156,7 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { } private var collapseOwnMessagesEnabled: Bool { - guard let selfUserId = selfUser.remoteIdentifier else { return false } - return PrivateUserDefaults(userID: selfUserId, storage: userDefaults) - .bool(forKey: .collapseOwnMessages) + privateDefaults.bool(forKey: .collapseOwnMessages) } private func isCollapsedInitialValue() -> Bool { @@ -170,12 +171,21 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { return false } - if message.isText { + if privateDefaults.wasMessagedUncollapsedBefore(message) { + return false + } + + if message.isTextWithNoLinks { + guard let textMessage = message.textMessageData?.messageText else { return false } - return willTextExceedOneLine(text: textMessage, availableWidth: contentWidth) + return willTextExceedLines( + text: textMessage, + availableWidth: contentWidth, + numberOfLines: 3 + ) } else { return message.isSentBySelfUser && message.isCollapsingSupported } @@ -221,6 +231,11 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { private func handleCollapseExpand() { isCollapsed = !isCollapsed + if isCollapsed { + privateDefaults.removeWasUncollapsed(message) + } else { + privateDefaults.saveWasUncollapsed(message) + } sectionDelegate?.messageSectionController(self, didRequestRefreshForMessage: message) } @@ -238,7 +253,7 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { } private func addImageMessageCell() -> [AnyConversationMessageCellDescription] { - if needToAddCollapsedCell() { + if shouldCollapseCell() { return addCollapsedCell() } let conversationImageMessageCellDescription = ConversationImageMessageCellDescription( @@ -248,8 +263,24 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { return [AnyConversationMessageCellDescription(conversationImageMessageCellDescription)] } - func needToAddCollapsedCell() -> Bool { - !isMessageWithCollapsedByDefault() && isCollapsed + private func shouldCollapseCell() -> Bool { + // There are system type of messages are collapsed by default + guard !isMessageWithCollapsedByDefault() else { + return false + } + // Collapse if it was set to be collapsed + if isCollapsed { + return true + } + // Then there are cases when we receive live update that fits criteria to be collapsed + // for example if messages has links previews or attachments + // when cell is refreshed, we recalculate + if collapseOwnMessagesEnabled, message.isSentBySelfUser, message.hasLinks, + !privateDefaults.wasMessagedUncollapsedBefore(message) { + return true + } + + return false } private func addCollapsedCell() -> [AnyConversationMessageCellDescription] { @@ -264,7 +295,7 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { } private func addTextMessageCells() -> [AnyConversationMessageCellDescription] { - if needToAddCollapsedCell() { + if shouldCollapseCell() { return addCollapsedCell() } return ConversationTextMessageCellDescription @@ -277,7 +308,7 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { } private func addLocationMessageCells() -> [AnyConversationMessageCellDescription] { - if needToAddCollapsedCell() { + if shouldCollapseCell() { return addCollapsedCell() } @@ -288,7 +319,7 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { } private func addAudioMessageCell() -> [AnyConversationMessageCellDescription] { - if needToAddCollapsedCell() { + if shouldCollapseCell() { return addCollapsedCell() } let cellDescription = ConversationAudioMessageCellDescription(message: message) @@ -296,7 +327,7 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { } private func addVideoMessageCell() -> [AnyConversationMessageCellDescription] { - if needToAddCollapsedCell() { + if shouldCollapseCell() { return addCollapsedCell() } let cellDescription = ConversationVideoMessageCellDescription(message: message) @@ -304,7 +335,7 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { } private func addFileMessageCell() -> [AnyConversationMessageCellDescription] { - guard !needToAddCollapsedCell() else { + guard !shouldCollapseCell() else { return addCollapsedCell() } @@ -458,7 +489,7 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { } // for all messages that support collapsing and is collapsed - if !isMessageWithCollapsedByDefault(), isCollapsed { + if shouldCollapseCell() { // if message failed, always show footer with error message and retry button if message.deliveryState == .failedToSend { return true @@ -479,7 +510,7 @@ final class ConversationMessageSectionController: NSObject, ZMMessageObserver { return false } - if !isMessageWithCollapsedByDefault() && isCollapsed { + if shouldCollapseCell() { return false } @@ -601,22 +632,22 @@ extension ConversationMessageSectionController { // TODO: [WPB-16627] https://wearezeta.atlassian.net/browse/WPB-16627 // improve by having one place to calculate width and for actual view to present text - func willTextExceedOneLine(text: String, availableWidth: CGFloat) -> Bool { - + func willTextExceedLines(text: String, availableWidth: CGFloat, numberOfLines: Int) -> Bool { let textSize = CGSize(width: availableWidth, height: CGFloat.greatestFiniteMagnitude) let font = UIFont.normalLightFont let attributes: [NSAttributedString.Key: Any] = [.font: font] + let boundingBox = text.boundingRect( with: textSize, - options: .usesLineFragmentOrigin, + options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: attributes, context: nil ) let singleLineHeight = NSAttributedString.paragraphStyle.minimumLineHeight + let maxHeight = singleLineHeight * CGFloat(numberOfLines) - return boundingBox.height > singleLineHeight + return boundingBox.height > maxHeight } - } diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/PrivateUserDefaults+CollapseKey.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/PrivateUserDefaults+CollapseKey.swift new file mode 100644 index 00000000000..a23cca2bd88 --- /dev/null +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/PrivateUserDefaults+CollapseKey.swift @@ -0,0 +1,60 @@ +// +// Wire +// Copyright (C) 2025 Wire Swiss GmbH +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. +// + +import Foundation +import WireDataModel +import WireFoundation + +extension PrivateUserDefaults where Key == CollapseKey { + + func wasMessagedUncollapsedBefore(_ message: ZMConversationMessage) -> Bool { + guard let nonce = message.nonce?.uuidString, + let uncollapsedMessages = stringArray(forKey: .uncollapsedMessages) else { + return false + } + return uncollapsedMessages.contains(nonce) + } + + func removeWasUncollapsed(_ message: ConversationMessage) { + guard message.shouldSaveUncollapsed, + let nonce = message.nonce?.uuidString else { return } + var uncollapsedMessages: [String] = stringArray(forKey: .uncollapsedMessages) ?? [] + uncollapsedMessages.removeAll(where: { $0 == nonce }) + set(uncollapsedMessages, forKey: .uncollapsedMessages) + } + + func saveWasUncollapsed(_ message: ConversationMessage) { + guard message.shouldSaveUncollapsed, + let nonce = message.nonce?.uuidString else { return } + var uncollapsedMessages: [String] = stringArray(forKey: .uncollapsedMessages) ?? [] + if uncollapsedMessages.firstIndex(of: nonce) == nil { + uncollapsedMessages.append(nonce) + } + set(uncollapsedMessages, forKey: .uncollapsedMessages) + } +} + +private extension ZMConversationMessage { + + var shouldSaveUncollapsed: Bool { + if isText { + return hasLinks + } + return isCollapsingSupported + } +} diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/Utility/NSAttributedString+MessageFormatting.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/Utility/NSAttributedString+MessageFormatting.swift index 012142bb970..870976b7c9e 100644 --- a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/Utility/NSAttributedString+MessageFormatting.swift +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/Utility/NSAttributedString+MessageFormatting.swift @@ -137,7 +137,11 @@ extension NSAttributedString { return markdownText } - static func format(message: TextMessageData, isObfuscated: Bool, accentColor: AccentColor) -> NSAttributedString { + static func format( + message: TextMessageData, + isObfuscated: Bool, + accentColor: AccentColor + ) -> NSAttributedString { var plainText = message.messageText ?? ""