mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Detect links in room detail topics and make it more obvious when the text is truncated (#2213)
This commit is contained in:
@@ -498,7 +498,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
roomProxy: roomProxy,
|
roomProxy: roomProxy,
|
||||||
mediaProvider: userSession.mediaProvider,
|
mediaProvider: userSession.mediaProvider,
|
||||||
userIndicatorController: userIndicatorController,
|
userIndicatorController: userIndicatorController,
|
||||||
notificationSettings: userSession.clientProxy.notificationSettings)
|
notificationSettings: userSession.clientProxy.notificationSettings,
|
||||||
|
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: appSettings.permalinkBaseURL,
|
||||||
|
mentionBuilder: MentionBuilder()))
|
||||||
let coordinator = RoomDetailsScreenCoordinator(parameters: params)
|
let coordinator = RoomDetailsScreenCoordinator(parameters: params)
|
||||||
coordinator.actions.sink { [weak self] action in
|
coordinator.actions.sink { [weak self] action in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ struct RoomDetailsScreenCoordinatorParameters {
|
|||||||
let mediaProvider: MediaProviderProtocol
|
let mediaProvider: MediaProviderProtocol
|
||||||
let userIndicatorController: UserIndicatorControllerProtocol
|
let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
let notificationSettings: NotificationSettingsProxyProtocol
|
let notificationSettings: NotificationSettingsProxyProtocol
|
||||||
|
let attributedStringBuilder: AttributedStringBuilderProtocol
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RoomDetailsScreenCoordinatorAction {
|
enum RoomDetailsScreenCoordinatorAction {
|
||||||
@@ -51,7 +52,8 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
|||||||
roomProxy: parameters.roomProxy,
|
roomProxy: parameters.roomProxy,
|
||||||
mediaProvider: parameters.mediaProvider,
|
mediaProvider: parameters.mediaProvider,
|
||||||
userIndicatorController: parameters.userIndicatorController,
|
userIndicatorController: parameters.userIndicatorController,
|
||||||
notificationSettingsProxy: parameters.notificationSettings)
|
notificationSettingsProxy: parameters.notificationSettings,
|
||||||
|
attributedStringBuilder: parameters.attributedStringBuilder)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ struct RoomDetailsScreenViewState: BindableState {
|
|||||||
let permalink: URL?
|
let permalink: URL?
|
||||||
|
|
||||||
var title = ""
|
var title = ""
|
||||||
var topic: String?
|
var topic: AttributedString?
|
||||||
|
var topicSummary: AttributedString?
|
||||||
var avatarURL: URL?
|
var avatarURL: URL?
|
||||||
var joinedMembersCount: Int
|
var joinedMembersCount: Int
|
||||||
var isProcessingIgnoreRequest = false
|
var isProcessingIgnoreRequest = false
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
private let mediaProvider: MediaProviderProtocol
|
private let mediaProvider: MediaProviderProtocol
|
||||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
private let notificationSettingsProxy: NotificationSettingsProxyProtocol
|
private let notificationSettingsProxy: NotificationSettingsProxyProtocol
|
||||||
|
private let attributedStringBuilder: AttributedStringBuilderProtocol
|
||||||
|
|
||||||
private var accountOwner: RoomMemberProxyProtocol? {
|
private var accountOwner: RoomMemberProxyProtocol? {
|
||||||
didSet { updatePowerLevelPermissions() }
|
didSet { updatePowerLevelPermissions() }
|
||||||
@@ -42,12 +43,16 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
roomProxy: RoomProxyProtocol,
|
roomProxy: RoomProxyProtocol,
|
||||||
mediaProvider: MediaProviderProtocol,
|
mediaProvider: MediaProviderProtocol,
|
||||||
userIndicatorController: UserIndicatorControllerProtocol,
|
userIndicatorController: UserIndicatorControllerProtocol,
|
||||||
notificationSettingsProxy: NotificationSettingsProxyProtocol) {
|
notificationSettingsProxy: NotificationSettingsProxyProtocol,
|
||||||
|
attributedStringBuilder: AttributedStringBuilderProtocol) {
|
||||||
self.accountUserID = accountUserID
|
self.accountUserID = accountUserID
|
||||||
self.roomProxy = roomProxy
|
self.roomProxy = roomProxy
|
||||||
self.mediaProvider = mediaProvider
|
self.mediaProvider = mediaProvider
|
||||||
self.userIndicatorController = userIndicatorController
|
self.userIndicatorController = userIndicatorController
|
||||||
self.notificationSettingsProxy = notificationSettingsProxy
|
self.notificationSettingsProxy = notificationSettingsProxy
|
||||||
|
self.attributedStringBuilder = attributedStringBuilder
|
||||||
|
|
||||||
|
let topic = attributedStringBuilder.fromPlain(roomProxy.topic)
|
||||||
|
|
||||||
super.init(initialViewState: .init(roomId: roomProxy.id,
|
super.init(initialViewState: .init(roomId: roomProxy.id,
|
||||||
canonicalAlias: roomProxy.canonicalAlias,
|
canonicalAlias: roomProxy.canonicalAlias,
|
||||||
@@ -55,7 +60,8 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
isDirect: roomProxy.isDirect,
|
isDirect: roomProxy.isDirect,
|
||||||
permalink: roomProxy.permalink,
|
permalink: roomProxy.permalink,
|
||||||
title: roomProxy.roomTitle,
|
title: roomProxy.roomTitle,
|
||||||
topic: roomProxy.topic,
|
topic: topic,
|
||||||
|
topicSummary: topic?.unattributedStringByReplacingNewlinesWithSpaces(),
|
||||||
avatarURL: roomProxy.avatarURL,
|
avatarURL: roomProxy.avatarURL,
|
||||||
joinedMembersCount: roomProxy.joinedMembersCount,
|
joinedMembersCount: roomProxy.joinedMembersCount,
|
||||||
notificationSettingsState: .loading,
|
notificationSettingsState: .loading,
|
||||||
@@ -126,7 +132,10 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
.sink { [weak self] _ in
|
.sink { [weak self] _ in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
self.state.title = self.roomProxy.roomTitle
|
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.avatarURL = self.roomProxy.avatarURL
|
||||||
self.state.joinedMembersCount = self.roomProxy.joinedMembersCount
|
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 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -123,10 +123,19 @@ struct RoomDetailsScreen: View {
|
|||||||
private var topicSection: some View {
|
private var topicSection: some View {
|
||||||
if context.viewState.hasTopicSection {
|
if context.viewState.hasTopicSection {
|
||||||
Section {
|
Section {
|
||||||
if let topic = context.viewState.topic, !topic.isEmpty {
|
if let topic = context.viewState.topic, !topic.characters.isEmpty, let topicSummary = context.viewState.topicSummary {
|
||||||
ListRow(label: .description(topic), kind: .label)
|
ListRow(kind: .custom {
|
||||||
.lineLimit(isTopicExpanded ? nil : 3)
|
Text(isTopicExpanded ? topic : topicSummary)
|
||||||
.onTapGesture { isTopicExpanded.toggle() }
|
.font(.compound.bodySM)
|
||||||
|
.foregroundColor(.compound.textSecondary)
|
||||||
|
.lineLimit(isTopicExpanded ? nil : 3)
|
||||||
|
.accentColor(.compound.textLinkExternal)
|
||||||
|
.padding(ListRowPadding.insets)
|
||||||
|
.textSelection(.enabled)
|
||||||
|
})
|
||||||
|
.onTapGesture {
|
||||||
|
isTopicExpanded.toggle()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ListRow(label: .plain(title: L10n.screenRoomDetailsAddTopicTitle),
|
ListRow(label: .plain(title: L10n.screenRoomDetailsAddTopicTitle),
|
||||||
kind: .button { context.send(viewAction: .processTapAddTopic) })
|
kind: .button { context.send(viewAction: .processTapAddTopic) })
|
||||||
@@ -264,7 +273,14 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
.mockCharlie
|
.mockCharlie
|
||||||
]
|
]
|
||||||
let roomProxy = RoomProxyMock(with: .init(id: "room_a_id", displayName: "Room A",
|
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,
|
isDirect: false,
|
||||||
isEncrypted: true,
|
isEncrypted: true,
|
||||||
canonicalAlias: "#alias:domain.com",
|
canonicalAlias: "#alias:domain.com",
|
||||||
@@ -279,7 +295,9 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
roomProxy: roomProxy,
|
roomProxy: roomProxy,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||||
notificationSettingsProxy: notificationSettingsProxy)
|
notificationSettingsProxy: notificationSettingsProxy,
|
||||||
|
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: .userDirectory,
|
||||||
|
mentionBuilder: MentionBuilder()))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
static let dmRoomViewModel = {
|
static let dmRoomViewModel = {
|
||||||
@@ -302,7 +320,9 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
roomProxy: roomProxy,
|
roomProxy: roomProxy,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||||
notificationSettingsProxy: notificationSettingsProxy)
|
notificationSettingsProxy: notificationSettingsProxy,
|
||||||
|
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: .userDirectory,
|
||||||
|
mentionBuilder: MentionBuilder()))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
static let simpleRoomViewModel = {
|
static let simpleRoomViewModel = {
|
||||||
@@ -322,7 +342,9 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
roomProxy: roomProxy,
|
roomProxy: roomProxy,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||||
notificationSettingsProxy: notificationSettingsProxy)
|
notificationSettingsProxy: notificationSettingsProxy,
|
||||||
|
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: .userDirectory,
|
||||||
|
mentionBuilder: MentionBuilder()))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
|
|||||||
@@ -589,7 +589,9 @@ class MockScreen: Identifiable {
|
|||||||
roomProxy: roomProxy,
|
roomProxy: roomProxy,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||||
notificationSettings: NotificationSettingsProxyMock(with: .init())))
|
notificationSettings: NotificationSettingsProxyMock(with: .init()),
|
||||||
|
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL,
|
||||||
|
mentionBuilder: MentionBuilder())))
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
case .roomDetailsScreenWithRoomAvatar:
|
case .roomDetailsScreenWithRoomAvatar:
|
||||||
@@ -608,7 +610,9 @@ class MockScreen: Identifiable {
|
|||||||
roomProxy: roomProxy,
|
roomProxy: roomProxy,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||||
notificationSettings: NotificationSettingsProxyMock(with: .init())))
|
notificationSettings: NotificationSettingsProxyMock(with: .init()),
|
||||||
|
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL,
|
||||||
|
mentionBuilder: MentionBuilder())))
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
case .roomDetailsScreenWithEmptyTopic:
|
case .roomDetailsScreenWithEmptyTopic:
|
||||||
@@ -629,7 +633,9 @@ class MockScreen: Identifiable {
|
|||||||
roomProxy: roomProxy,
|
roomProxy: roomProxy,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||||
notificationSettings: NotificationSettingsProxyMock(with: .init())))
|
notificationSettings: NotificationSettingsProxyMock(with: .init()),
|
||||||
|
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL,
|
||||||
|
mentionBuilder: MentionBuilder())))
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
case .roomDetailsScreenWithInvite:
|
case .roomDetailsScreenWithInvite:
|
||||||
@@ -646,7 +652,9 @@ class MockScreen: Identifiable {
|
|||||||
roomProxy: roomProxy,
|
roomProxy: roomProxy,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||||
notificationSettings: NotificationSettingsProxyMock(with: .init())))
|
notificationSettings: NotificationSettingsProxyMock(with: .init()),
|
||||||
|
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL,
|
||||||
|
mentionBuilder: MentionBuilder())))
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
case .roomDetailsScreenDmDetails:
|
case .roomDetailsScreenDmDetails:
|
||||||
@@ -664,7 +672,9 @@ class MockScreen: Identifiable {
|
|||||||
roomProxy: roomProxy,
|
roomProxy: roomProxy,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||||
notificationSettings: NotificationSettingsProxyMock(with: .init())))
|
notificationSettings: NotificationSettingsProxyMock(with: .init()),
|
||||||
|
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL,
|
||||||
|
mentionBuilder: MentionBuilder())))
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
case .roomEditDetails, .roomEditDetailsReadOnly:
|
case .roomEditDetails, .roomEditDetailsReadOnly:
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||||
notificationSettingsProxy: notificationSettingsProxyMock)
|
notificationSettingsProxy: notificationSettingsProxyMock,
|
||||||
|
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL,
|
||||||
|
mentionBuilder: MentionBuilder()))
|
||||||
|
|
||||||
AppSettings.reset()
|
AppSettings.reset()
|
||||||
}
|
}
|
||||||
@@ -49,7 +51,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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
|
let deferred = deferFulfillment(context.$viewState) { state in
|
||||||
state.bindings.leaveRoomAlertItem != nil
|
state.bindings.leaveRoomAlertItem != nil
|
||||||
}
|
}
|
||||||
@@ -68,7 +72,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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
|
let deferred = deferFulfillment(context.$viewState) { state in
|
||||||
state.bindings.leaveRoomAlertItem != nil
|
state.bindings.leaveRoomAlertItem != nil
|
||||||
}
|
}
|
||||||
@@ -130,7 +136,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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
|
let deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||||
state.dmRecipient != nil
|
state.dmRecipient != nil
|
||||||
@@ -154,7 +162,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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
|
var deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||||
state.dmRecipient != nil
|
state.dmRecipient != nil
|
||||||
@@ -187,7 +197,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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
|
var deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||||
state.dmRecipient != nil
|
state.dmRecipient != nil
|
||||||
@@ -221,7 +233,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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
|
var deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||||
state.dmRecipient != nil
|
state.dmRecipient != nil
|
||||||
@@ -254,7 +268,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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
|
var deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||||
state.dmRecipient != nil
|
state.dmRecipient != nil
|
||||||
@@ -287,7 +303,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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()
|
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||||
|
|
||||||
@@ -301,7 +319,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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()
|
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||||
|
|
||||||
@@ -332,7 +352,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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()
|
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||||
|
|
||||||
@@ -350,7 +372,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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()
|
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||||
|
|
||||||
@@ -368,7 +392,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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()
|
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||||
|
|
||||||
@@ -386,7 +412,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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()
|
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||||
|
|
||||||
@@ -403,7 +431,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
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()
|
_ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first()
|
||||||
|
|
||||||
@@ -418,7 +448,9 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
mediaProvider: MockMediaProvider(),
|
mediaProvider: MockMediaProvider(),
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||||
notificationSettingsProxy: notificationSettingsProxyMock)
|
notificationSettingsProxy: notificationSettingsProxyMock,
|
||||||
|
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL,
|
||||||
|
mentionBuilder: MentionBuilder()))
|
||||||
|
|
||||||
var deferred = deferFulfillment(context.$viewState) { state in
|
var deferred = deferFulfillment(context.$viewState) { state in
|
||||||
state.notificationSettingsState.isError
|
state.notificationSettingsState.isError
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:bd1d42f3e1b290a8afe9f9bcff020bb2516ac5bee17488e483b58c72e2d68ab8
|
oid sha256:9e0f795c81b1de86d8fd339a4a41da77e1ba5708ff7f1d353a84cd72872b85ae
|
||||||
size 169767
|
size 170145
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:bc9f816d6b60e9147b7f64f6a649650e73bf2ddf6ff7d50a4902a6e02d35c41a
|
oid sha256:71a9439c43fa9d524757b86286c97364fb36862f7a5baaf85195d3f6c838e9f4
|
||||||
size 172982
|
size 174322
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
Detect links in room detail topics and make it more obvious when the text is truncated
|
||||||
Reference in New Issue
Block a user