mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
reply view will now render as plain pills
instead of rendering nothing
This commit is contained in:
@@ -117,6 +117,12 @@ struct TimelineViewState: BindableState {
|
||||
/// A closure that updates the associated pill context
|
||||
var pillContextUpdater: (@MainActor (PillContext) -> Void)?
|
||||
|
||||
/// A closure that returns the associated room name give its id
|
||||
var roomNameForIDResolver: (@MainActor (String) -> String?)?
|
||||
|
||||
/// A closure that returns the associated room name give its alias
|
||||
var roomNameForAliasResolver: (@MainActor (String) -> String?)?
|
||||
|
||||
var emojiProvider: EmojiProviderProtocol
|
||||
}
|
||||
|
||||
|
||||
@@ -121,6 +121,14 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
self?.pillContextUpdater(pillContext)
|
||||
}
|
||||
|
||||
state.roomNameForIDResolver = { [weak self] roomID in
|
||||
self?.clientProxy.roomSummaryForIdentifier(roomID)?.name
|
||||
}
|
||||
|
||||
state.roomNameForAliasResolver = { [weak self] alias in
|
||||
self?.clientProxy.roomSummaryForAlias(alias)?.name
|
||||
}
|
||||
|
||||
state.timelineState.paginationState = timelineController.paginationState
|
||||
buildTimelineViews(timelineItems: timelineController.timelineItems)
|
||||
|
||||
@@ -935,19 +943,22 @@ extension TimelineViewModel {
|
||||
static let mock = mock(timelineKind: .live)
|
||||
|
||||
static func mock(timelineKind: TimelineKind = .live, timelineController: MockTimelineController? = nil) -> TimelineViewModel {
|
||||
TimelineViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Preview room")),
|
||||
focussedEventID: nil,
|
||||
timelineController: timelineController ?? MockTimelineController(timelineKind: timelineKind),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
mediaPlayerProvider: MediaPlayerProviderMock(),
|
||||
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
||||
clientProxy: ClientProxyMock(.init()))
|
||||
let clientProxyMock = ClientProxyMock(.init())
|
||||
clientProxyMock.roomSummaryForAliasReturnValue = .mock(id: "!room:matrix.org", name: "Room")
|
||||
clientProxyMock.roomSummaryForIdentifierReturnValue = .mock(id: "!room:matrix.org", name: "Room", canonicalAlias: "#room:matrix.org")
|
||||
return TimelineViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Preview room")),
|
||||
focussedEventID: nil,
|
||||
timelineController: timelineController ?? MockTimelineController(timelineKind: timelineKind),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
mediaPlayerProvider: MediaPlayerProviderMock(),
|
||||
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
||||
clientProxy: clientProxyMock)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -200,6 +200,28 @@ struct TimelineReplyView: View {
|
||||
if attributes[.MatrixAllUsersMention] as? Bool == true {
|
||||
attributedString.replaceCharacters(in: range, with: PillUtilities.atRoom)
|
||||
}
|
||||
|
||||
if let roomAlias = attributes[.MatrixRoomAlias] as? String {
|
||||
let roomName = context.viewState.roomNameForAliasResolver?(roomAlias)
|
||||
attributedString.replaceCharacters(in: range, with: PillUtilities.roomPillDisplayText(roomName: roomName, rawRoomText: roomAlias))
|
||||
}
|
||||
|
||||
if let roomID = attributes[.MatrixRoomID] as? String {
|
||||
let roomName = context.viewState.roomNameForIDResolver?(roomID)
|
||||
attributedString.replaceCharacters(in: range, with: PillUtilities.roomPillDisplayText(roomName: roomName, rawRoomText: roomID))
|
||||
}
|
||||
|
||||
if let eventOnRoomID = attributes[.MatrixEventOnRoomID] as? EventOnRoomIDAttribute.Value {
|
||||
let roomID = eventOnRoomID.roomID
|
||||
let roomName = context.viewState.roomNameForIDResolver?(roomID)
|
||||
attributedString.replaceCharacters(in: range, with: PillUtilities.eventPillDisplayText(roomName: roomName, rawRoomText: roomID))
|
||||
}
|
||||
|
||||
if let eventOnRoomAlias = attributes[.MatrixEventOnRoomAlias] as? EventOnRoomAliasAttribute.Value {
|
||||
let roomAlias = eventOnRoomAlias.alias
|
||||
let roomName = context.viewState.roomNameForAliasResolver?(roomAlias)
|
||||
attributedString.replaceCharacters(in: range, with: PillUtilities.eventPillDisplayText(roomName: roomName, rawRoomText: eventOnRoomAlias.alias))
|
||||
}
|
||||
}
|
||||
return attributedString.string
|
||||
}
|
||||
@@ -221,6 +243,30 @@ struct TimelineReplyView_Previews: PreviewProvider, TestablePreview {
|
||||
return attributedString
|
||||
}()
|
||||
|
||||
static let attributedStringWithRoomAliasMention = {
|
||||
var attributedString = AttributedString("to be replaced")
|
||||
attributedString.roomAlias = "#room:matrix.org"
|
||||
return attributedString
|
||||
}()
|
||||
|
||||
static let attributedStringWithRoomIDMention = {
|
||||
var attributedString = AttributedString("to be replaced")
|
||||
attributedString.roomID = "!room:matrix.org"
|
||||
return attributedString
|
||||
}()
|
||||
|
||||
static let attributedStringWithEventOnRoomIDMention = {
|
||||
var attributedString = AttributedString("to be replaced")
|
||||
attributedString.eventOnRoomID = .init(roomID: "!room:matrix.org", eventID: "$event")
|
||||
return attributedString
|
||||
}()
|
||||
|
||||
static let attributedStringWithEventOnRoomAliasMention = {
|
||||
var attributedString = AttributedString("to be replaced")
|
||||
attributedString.eventOnRoomAlias = .init(alias: "#room:matrix.org", eventID: "$event")
|
||||
return attributedString
|
||||
}()
|
||||
|
||||
static var previewItems: [TimelineReplyView] {
|
||||
[
|
||||
TimelineReplyView(placement: .timeline, timelineItemReplyDetails: .notLoaded(eventID: "")),
|
||||
@@ -301,6 +347,22 @@ struct TimelineReplyView_Previews: PreviewProvider, TestablePreview {
|
||||
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Bob"),
|
||||
eventID: "123",
|
||||
eventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithAtRoomMention))))),
|
||||
TimelineReplyView(placement: .timeline,
|
||||
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Bob"),
|
||||
eventID: "123",
|
||||
eventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithRoomAliasMention))))),
|
||||
TimelineReplyView(placement: .timeline,
|
||||
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Bob"),
|
||||
eventID: "123",
|
||||
eventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithRoomIDMention))))),
|
||||
TimelineReplyView(placement: .timeline,
|
||||
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Bob"),
|
||||
eventID: "123",
|
||||
eventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithEventOnRoomIDMention))))),
|
||||
TimelineReplyView(placement: .timeline,
|
||||
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Bob"),
|
||||
eventID: "123",
|
||||
eventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithEventOnRoomAliasMention))))),
|
||||
TimelineReplyView(placement: .timeline,
|
||||
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Bob"),
|
||||
eventID: "123",
|
||||
|
||||
Reference in New Issue
Block a user