From 40b100d59696a4f5802ee2df2bf4edf5083d02d5 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 12 Dec 2023 15:52:10 +0200 Subject: [PATCH] Detect links in room detail topics and make it more obvious when the text is truncated (#2213) --- .../RoomFlowCoordinator.swift | 4 +- .../RoomDetailsScreenCoordinator.swift | 4 +- .../RoomDetailsScreenModels.swift | 3 +- .../RoomDetailsScreenViewModel.swift | 22 ++++++- .../View/RoomDetailsScreen.swift | 38 ++++++++--- .../UITests/UITestsAppCoordinator.swift | 20 ++++-- .../Sources/RoomDetailsViewModelTests.swift | 64 ++++++++++++++----- .../test_roomDetailsScreen.DM-Room.png | 4 +- .../test_roomDetailsScreen.Generic-Room.png | 4 +- changelog.d/2210.bugfix | 1 + 10 files changed, 125 insertions(+), 39 deletions(-) create mode 100644 changelog.d/2210.bugfix diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift index cc81f7d21..923642b5b 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift @@ -498,7 +498,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { roomProxy: roomProxy, mediaProvider: userSession.mediaProvider, userIndicatorController: userIndicatorController, - notificationSettings: userSession.clientProxy.notificationSettings) + notificationSettings: userSession.clientProxy.notificationSettings, + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: appSettings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) let coordinator = RoomDetailsScreenCoordinator(parameters: params) coordinator.actions.sink { [weak self] action in guard let self else { return } diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenCoordinator.swift b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenCoordinator.swift index 0b055fa3c..0fd6be78c 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenCoordinator.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenCoordinator.swift @@ -23,6 +23,7 @@ struct RoomDetailsScreenCoordinatorParameters { let mediaProvider: MediaProviderProtocol let userIndicatorController: UserIndicatorControllerProtocol let notificationSettings: NotificationSettingsProxyProtocol + let attributedStringBuilder: AttributedStringBuilderProtocol } enum RoomDetailsScreenCoordinatorAction { @@ -51,7 +52,8 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol { roomProxy: parameters.roomProxy, mediaProvider: parameters.mediaProvider, userIndicatorController: parameters.userIndicatorController, - notificationSettingsProxy: parameters.notificationSettings) + notificationSettingsProxy: parameters.notificationSettings, + attributedStringBuilder: parameters.attributedStringBuilder) } // MARK: - Public diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift index ad78b45d6..46d8f1b97 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift @@ -39,7 +39,8 @@ struct RoomDetailsScreenViewState: BindableState { let permalink: URL? var title = "" - var topic: String? + var topic: AttributedString? + var topicSummary: AttributedString? var avatarURL: URL? var joinedMembersCount: Int var isProcessingIgnoreRequest = false diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift index 25971f003..7bb581819 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift @@ -25,6 +25,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr private let mediaProvider: MediaProviderProtocol private let userIndicatorController: UserIndicatorControllerProtocol private let notificationSettingsProxy: NotificationSettingsProxyProtocol + private let attributedStringBuilder: AttributedStringBuilderProtocol private var accountOwner: RoomMemberProxyProtocol? { didSet { updatePowerLevelPermissions() } @@ -42,12 +43,16 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr roomProxy: RoomProxyProtocol, mediaProvider: MediaProviderProtocol, userIndicatorController: UserIndicatorControllerProtocol, - notificationSettingsProxy: NotificationSettingsProxyProtocol) { + notificationSettingsProxy: NotificationSettingsProxyProtocol, + attributedStringBuilder: AttributedStringBuilderProtocol) { self.accountUserID = accountUserID self.roomProxy = roomProxy self.mediaProvider = mediaProvider self.userIndicatorController = userIndicatorController self.notificationSettingsProxy = notificationSettingsProxy + self.attributedStringBuilder = attributedStringBuilder + + let topic = attributedStringBuilder.fromPlain(roomProxy.topic) super.init(initialViewState: .init(roomId: roomProxy.id, canonicalAlias: roomProxy.canonicalAlias, @@ -55,7 +60,8 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr isDirect: roomProxy.isDirect, permalink: roomProxy.permalink, title: roomProxy.roomTitle, - topic: roomProxy.topic, + topic: topic, + topicSummary: topic?.unattributedStringByReplacingNewlinesWithSpaces(), avatarURL: roomProxy.avatarURL, joinedMembersCount: roomProxy.joinedMembersCount, notificationSettingsState: .loading, @@ -126,7 +132,10 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr .sink { [weak self] _ in guard let self else { return } self.state.title = self.roomProxy.roomTitle - self.state.topic = self.roomProxy.topic + + let topic = attributedStringBuilder.fromPlain(self.roomProxy.topic) + self.state.topic = topic + self.state.topicSummary = topic?.unattributedStringByReplacingNewlinesWithSpaces() self.state.avatarURL = self.roomProxy.avatarURL self.state.joinedMembersCount = self.roomProxy.joinedMembersCount } @@ -299,3 +308,10 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr } } } + +private extension AttributedString { + /// Returns a new string without attributes and in which newlines are replaced with spaces + func unattributedStringByReplacingNewlinesWithSpaces() -> AttributedString { + AttributedString(characters.map { $0.isNewline ? " " : $0 }) + } +} diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift b/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift index 6484f4e80..471d20de5 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift @@ -123,10 +123,19 @@ struct RoomDetailsScreen: View { private var topicSection: some View { if context.viewState.hasTopicSection { Section { - if let topic = context.viewState.topic, !topic.isEmpty { - ListRow(label: .description(topic), kind: .label) - .lineLimit(isTopicExpanded ? nil : 3) - .onTapGesture { isTopicExpanded.toggle() } + if let topic = context.viewState.topic, !topic.characters.isEmpty, let topicSummary = context.viewState.topicSummary { + ListRow(kind: .custom { + Text(isTopicExpanded ? topic : topicSummary) + .font(.compound.bodySM) + .foregroundColor(.compound.textSecondary) + .lineLimit(isTopicExpanded ? nil : 3) + .accentColor(.compound.textLinkExternal) + .padding(ListRowPadding.insets) + .textSelection(.enabled) + }) + .onTapGesture { + isTopicExpanded.toggle() + } } else { ListRow(label: .plain(title: L10n.screenRoomDetailsAddTopicTitle), kind: .button { context.send(viewAction: .processTapAddTopic) }) @@ -264,7 +273,14 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview { .mockCharlie ] let roomProxy = RoomProxyMock(with: .init(id: "room_a_id", displayName: "Room A", - topic: "Bacon ipsum dolor amet short ribs buffalo pork loin cupim frankfurter. Burgdoggen pig shankle biltong flank ham jowl sirloin bacon cow. T-bone alcatra boudin beef spare ribs pig fatback jerky swine short ribs shankle chislic frankfurter pork loin. Chicken tri-tip bresaola t-bone pastrami brisket.", // swiftlint:disable:this line_length + topic: """ + Discussions about Element X iOS | https://github.com/vector-im/element-x-ios + + Feature Status: https://github.com/vector-im/element-x-ios/issues/1225 + + App Store: https://apple.co/3r6LJHZ + TestFlight: https://testflight.apple.com/join/uZbeZCOi + """, isDirect: false, isEncrypted: true, canonicalAlias: "#alias:domain.com", @@ -279,7 +295,9 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview { roomProxy: roomProxy, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: notificationSettingsProxy) + notificationSettingsProxy: notificationSettingsProxy, + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: .userDirectory, + mentionBuilder: MentionBuilder())) }() static let dmRoomViewModel = { @@ -302,7 +320,9 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview { roomProxy: roomProxy, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: notificationSettingsProxy) + notificationSettingsProxy: notificationSettingsProxy, + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: .userDirectory, + mentionBuilder: MentionBuilder())) }() static let simpleRoomViewModel = { @@ -322,7 +342,9 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview { roomProxy: roomProxy, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: notificationSettingsProxy) + notificationSettingsProxy: notificationSettingsProxy, + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: .userDirectory, + mentionBuilder: MentionBuilder())) }() static var previews: some View { diff --git a/ElementX/Sources/UITests/UITestsAppCoordinator.swift b/ElementX/Sources/UITests/UITestsAppCoordinator.swift index 26a72a9fe..6d46cb67f 100644 --- a/ElementX/Sources/UITests/UITestsAppCoordinator.swift +++ b/ElementX/Sources/UITests/UITestsAppCoordinator.swift @@ -589,7 +589,9 @@ class MockScreen: Identifiable { roomProxy: roomProxy, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettings: NotificationSettingsProxyMock(with: .init()))) + notificationSettings: NotificationSettingsProxyMock(with: .init()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder()))) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .roomDetailsScreenWithRoomAvatar: @@ -608,7 +610,9 @@ class MockScreen: Identifiable { roomProxy: roomProxy, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettings: NotificationSettingsProxyMock(with: .init()))) + notificationSettings: NotificationSettingsProxyMock(with: .init()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder()))) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .roomDetailsScreenWithEmptyTopic: @@ -629,7 +633,9 @@ class MockScreen: Identifiable { roomProxy: roomProxy, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettings: NotificationSettingsProxyMock(with: .init()))) + notificationSettings: NotificationSettingsProxyMock(with: .init()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder()))) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .roomDetailsScreenWithInvite: @@ -646,7 +652,9 @@ class MockScreen: Identifiable { roomProxy: roomProxy, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettings: NotificationSettingsProxyMock(with: .init()))) + notificationSettings: NotificationSettingsProxyMock(with: .init()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder()))) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .roomDetailsScreenDmDetails: @@ -664,7 +672,9 @@ class MockScreen: Identifiable { roomProxy: roomProxy, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettings: NotificationSettingsProxyMock(with: .init()))) + notificationSettings: NotificationSettingsProxyMock(with: .init()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder()))) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .roomEditDetails, .roomEditDetailsReadOnly: diff --git a/UnitTests/Sources/RoomDetailsViewModelTests.swift b/UnitTests/Sources/RoomDetailsViewModelTests.swift index 06eda2b17..b11594f92 100644 --- a/UnitTests/Sources/RoomDetailsViewModelTests.swift +++ b/UnitTests/Sources/RoomDetailsViewModelTests.swift @@ -37,7 +37,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: notificationSettingsProxyMock) + notificationSettingsProxy: notificationSettingsProxyMock, + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) AppSettings.reset() } @@ -49,7 +51,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) let deferred = deferFulfillment(context.$viewState) { state in state.bindings.leaveRoomAlertItem != nil } @@ -68,7 +72,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) let deferred = deferFulfillment(context.$viewState) { state in state.bindings.leaveRoomAlertItem != nil } @@ -130,7 +136,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) let deferred = deferFulfillment(viewModel.context.$viewState) { state in state.dmRecipient != nil @@ -154,7 +162,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) var deferred = deferFulfillment(viewModel.context.$viewState) { state in state.dmRecipient != nil @@ -187,7 +197,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) var deferred = deferFulfillment(viewModel.context.$viewState) { state in state.dmRecipient != nil @@ -221,7 +233,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) var deferred = deferFulfillment(viewModel.context.$viewState) { state in state.dmRecipient != nil @@ -254,7 +268,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) var deferred = deferFulfillment(viewModel.context.$viewState) { state in state.dmRecipient != nil @@ -287,7 +303,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -301,7 +319,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -332,7 +352,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -350,7 +372,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -368,7 +392,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -386,7 +412,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -403,7 +431,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())) + notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -418,7 +448,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase { roomProxy: roomProxyMock, mediaProvider: MockMediaProvider(), userIndicatorController: ServiceLocator.shared.userIndicatorController, - notificationSettingsProxy: notificationSettingsProxyMock) + notificationSettingsProxy: notificationSettingsProxyMock, + attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, + mentionBuilder: MentionBuilder())) var deferred = deferFulfillment(context.$viewState) { state in state.notificationSettingsState.isError diff --git a/UnitTests/__Snapshots__/PreviewTests/test_roomDetailsScreen.DM-Room.png b/UnitTests/__Snapshots__/PreviewTests/test_roomDetailsScreen.DM-Room.png index 627ba86ef..c68665281 100644 --- a/UnitTests/__Snapshots__/PreviewTests/test_roomDetailsScreen.DM-Room.png +++ b/UnitTests/__Snapshots__/PreviewTests/test_roomDetailsScreen.DM-Room.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd1d42f3e1b290a8afe9f9bcff020bb2516ac5bee17488e483b58c72e2d68ab8 -size 169767 +oid sha256:9e0f795c81b1de86d8fd339a4a41da77e1ba5708ff7f1d353a84cd72872b85ae +size 170145 diff --git a/UnitTests/__Snapshots__/PreviewTests/test_roomDetailsScreen.Generic-Room.png b/UnitTests/__Snapshots__/PreviewTests/test_roomDetailsScreen.Generic-Room.png index bf8f0210d..b09de985d 100644 --- a/UnitTests/__Snapshots__/PreviewTests/test_roomDetailsScreen.Generic-Room.png +++ b/UnitTests/__Snapshots__/PreviewTests/test_roomDetailsScreen.Generic-Room.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bc9f816d6b60e9147b7f64f6a649650e73bf2ddf6ff7d50a4902a6e02d35c41a -size 172982 +oid sha256:71a9439c43fa9d524757b86286c97364fb36862f7a5baaf85195d3f6c838e9f4 +size 174322 diff --git a/changelog.d/2210.bugfix b/changelog.d/2210.bugfix new file mode 100644 index 000000000..bc30f2739 --- /dev/null +++ b/changelog.d/2210.bugfix @@ -0,0 +1 @@ +Detect links in room detail topics and make it more obvious when the text is truncated \ No newline at end of file