Adop the new SDK permalink detector and user builder

This commit is contained in:
Stefan Ceriu
2024-04-12 13:26:41 +03:00
committed by Stefan Ceriu
parent f8920d4d11
commit fcc25dd441
26 changed files with 201 additions and 483 deletions
@@ -289,8 +289,6 @@ final class AppSettings {
#endif
// MARK: - Shared
let permalinkBaseURL: URL = "https://matrix.to"
@UserPreference(key: UserDefaultsKeys.logLevel, defaultValue: TracingConfiguration.LogLevel.info, storageType: .userDefaults(store))
var logLevel
@@ -15,6 +15,7 @@
//
import Foundation
import MatrixRustSDK
enum AppRoute: Equatable {
/// The callback used to complete login with OIDC.
@@ -43,7 +44,7 @@ struct AppRouteURLParser {
init(appSettings: AppSettings) {
urlParsers = [
MatrixPermalinkParser(appSettings: appSettings),
MatrixPermalinkParser(),
OIDCCallbackURLParser(appSettings: appSettings),
ElementCallURLParser()
]
@@ -121,13 +122,15 @@ struct ElementCallURLParser: URLParser {
}
struct MatrixPermalinkParser: URLParser {
let appSettings: AppSettings
func route(from url: URL) -> AppRoute? {
switch PermalinkBuilder.detectPermalink(in: url, baseURL: appSettings.permalinkBaseURL) {
case .userIdentifier(let userID):
guard let matrixEntity = parseMatrixEntityFrom(uri: url.absoluteString) else {
return nil
}
switch matrixEntity.id {
case .user(let userID):
return .roomMemberDetails(userID: userID)
case .roomIdentifier(let roomID):
case .room(let roomID):
return .room(roomID: roomID)
default:
return nil
@@ -421,8 +421,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let userID = userSession.clientProxy.userID
let timelineItemFactory = RoomTimelineItemFactory(userID: userID,
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: appSettings.permalinkBaseURL,
mentionBuilder: MentionBuilder()),
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID))
let timelineController = roomTimelineControllerFactory.buildRoomTimelineController(roomProxy: roomProxy,
@@ -509,8 +508,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
analyticsService: analytics,
userIndicatorController: userIndicatorController,
notificationSettings: userSession.clientProxy.notificationSettings,
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: appSettings.permalinkBaseURL,
mentionBuilder: MentionBuilder()))
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()))
let coordinator = RoomDetailsScreenCoordinator(parameters: params)
coordinator.actions.sink { [weak self] action in
guard let self else { return }
@@ -846,8 +844,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let userID = userSession.clientProxy.userID
let timelineItemFactory = RoomTimelineItemFactory(userID: userID,
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: appSettings.permalinkBaseURL,
mentionBuilder: MentionBuilder()),
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID))
let roomTimelineController = roomTimelineControllerFactory.buildRoomTimelineController(roomProxy: roomProxy,
@@ -326,8 +326,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
private func presentHomeScreen() {
let parameters = HomeScreenCoordinatorParameters(userSession: userSession,
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL,
mentionBuilder: MentionBuilder()),
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
bugReportService: bugReportService,
navigationStackCoordinator: detailNavigationStackCoordinator,
selectedRoomPublisher: selectedRoomSubject.asCurrentValuePublisher())
@@ -17,12 +17,12 @@
import DTCoreText
import Foundation
import LRUCache
import MatrixRustSDK
struct AttributedStringBuilder: AttributedStringBuilderProtocol {
private let cacheKey: String
private let temporaryBlockquoteMarkingColor = UIColor.magenta
private let temporaryCodeBlockMarkingColor = UIColor.cyan
private let permalinkBaseURL: URL
private let mentionBuilder: MentionBuilderProtocol
private static let defaultKey = "default"
@@ -34,9 +34,8 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
caches.removeAll()
}
init(cacheKey: String = defaultKey, permalinkBaseURL: URL, mentionBuilder: MentionBuilderProtocol) {
init(cacheKey: String = defaultKey, mentionBuilder: MentionBuilderProtocol) {
self.cacheKey = cacheKey
self.permalinkBaseURL = permalinkBaseURL
self.mentionBuilder = mentionBuilder
}
@@ -206,29 +205,45 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
private func addLinksAndMentions(_ attributedString: NSMutableAttributedString) {
let string = attributedString.string
var matches = MatrixEntityRegex.userIdentifierRegex.matches(in: string, options: []).map { TypedMatch(match: $0, type: .permalink(type: .userID)) }
matches.append(contentsOf: MatrixEntityRegex.roomIdentifierRegex.matches(in: string, options: []).map { TypedMatch(match: $0, type: .permalink(type: .roomID)) })
// Event identifiers and room aliases and identifiers detected in plain text are techincally incomplete
// without via parameters and we won't bother detecting them
// As of right now we do not handle event id links in any way so there is no need to add them as links
// matches.append(contentsOf: MatrixEntityRegex.eventIdentifierRegex.matches(in: string, options: []))
var matches: [TextParsingMatch] = MatrixEntityRegex.userIdentifierRegex.matches(in: string, options: []).compactMap { match in
guard let matchRange = Range(match.range, in: string) else {
return nil
}
let identifier = String(string[matchRange])
return TextParsingMatch(type: .userID(identifier: identifier), range: match.range)
}
matches.append(contentsOf: MatrixEntityRegex.roomAliasRegex.matches(in: string, options: []).map { TypedMatch(match: $0, type: .permalink(type: .roomAlias)) })
matches.append(contentsOf: MatrixEntityRegex.linkRegex.matches(in: string, options: []).compactMap { match in
guard let matchRange = Range(match.range, in: string) else {
return nil
}
var link = String(string[matchRange])
if !link.contains("://") {
link.insert(contentsOf: "https://", at: link.startIndex)
}
return TextParsingMatch(type: .link(urlString: link), range: match.range)
})
matches.append(contentsOf: MatrixEntityRegex.linkRegex.matches(in: string, options: []).map { TypedMatch(match: $0, type: .link) })
matches.append(contentsOf: MatrixEntityRegex.allUsersRegex.matches(in: attributedString.string, options: []).map { TypedMatch(match: $0, type: .atRoom) })
matches.append(contentsOf: MatrixEntityRegex.allUsersRegex.matches(in: attributedString.string, options: []).map { match in
TextParsingMatch(type: .atRoom, range: match.range)
})
guard matches.count > 0 else {
return
}
// Sort the links by length so the longest one always takes priority
matches.sorted { $0.match.range.length > $1.match.range.length }.forEach { [attributedString] typedMatch in
guard let matchRange = Range(typedMatch.match.range, in: string) else {
return
}
matches.sorted { $0.range.length > $1.range.length }.forEach { [attributedString] match in
var hasLink = false
attributedString.enumerateAttribute(.link, in: typedMatch.match.range, options: []) { value, _, stop in
attributedString.enumerateAttribute(.link, in: match.range, options: []) { value, _, stop in
if value != nil {
hasLink = true
stop.pointee = true
@@ -239,24 +254,12 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
return
}
switch typedMatch.type {
switch match.type {
case .atRoom:
attributedString.addAttribute(.MatrixAllUsersMention, value: true, range: typedMatch.match.range)
case let .permalink(type):
let identifier = String(string[matchRange])
if let url = type.getPermalinkFrom(identifier: identifier, baseURL: permalinkBaseURL) {
attributedString.addAttribute(.link, value: url, range: typedMatch.match.range)
}
case .link:
var link = String(string[matchRange])
if !link.contains("://") {
link.insert(contentsOf: "https://", at: link.startIndex)
}
if let url = URL(string: link) {
attributedString.addAttribute(.link, value: url, range: typedMatch.match.range)
attributedString.addAttribute(.MatrixAllUsersMention, value: true, range: match.range)
case .userID, .link:
if let url = match.link {
attributedString.addAttribute(.link, value: url, range: match.range)
}
}
}
@@ -265,18 +268,18 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
func detectPermalinks(_ attributedString: NSMutableAttributedString) {
attributedString.enumerateAttribute(.link, in: .init(location: 0, length: attributedString.length), options: []) { value, range, _ in
if value != nil {
if let url = value as? URL {
switch PermalinkBuilder.detectPermalink(in: url, baseURL: permalinkBaseURL) {
case .userIdentifier(let identifier):
mentionBuilder.handleUserMention(for: attributedString, in: range, url: url, userID: identifier)
case .roomIdentifier(let identifier):
attributedString.addAttributes([.MatrixRoomID: identifier], range: range)
if let url = value as? URL, let matrixEntity = parseMatrixEntityFrom(uri: url.absoluteString) {
switch matrixEntity.id {
case .user(let userID):
mentionBuilder.handleUserMention(for: attributedString, in: range, url: url, userID: userID)
case .room(let roomID):
attributedString.addAttributes([.MatrixRoomID: roomID], range: range)
case .roomAlias(let alias):
attributedString.addAttributes([.MatrixRoomAlias: alias], range: range)
case .event(let roomIdentifier, let eventIdentifier):
attributedString.addAttributes([.MatrixEventID: EventIDAttributeValue(roomID: roomIdentifier, eventID: eventIdentifier)], range: range)
case .none:
break
case .eventOnRoomId(let roomID, let eventID):
attributedString.addAttributes([.MatrixEventOnRoomID: EventOnRoomIDAttribute.Value(roomID: roomID, eventID: eventID)], range: range)
case .eventOnRoomAlias(let alias, let eventID):
attributedString.addAttributes([.MatrixEventOnRoomAlias: EventOnRoomAliasAttribute.Value(alias: alias, eventID: eventID)], range: range)
}
}
}
@@ -347,7 +350,8 @@ extension NSAttributedString.Key {
static let MatrixUserID: NSAttributedString.Key = .init(rawValue: UserIDAttribute.name)
static let MatrixRoomID: NSAttributedString.Key = .init(rawValue: RoomIDAttribute.name)
static let MatrixRoomAlias: NSAttributedString.Key = .init(rawValue: RoomAliasAttribute.name)
static let MatrixEventID: NSAttributedString.Key = .init(rawValue: EventIDAttribute.name)
static let MatrixEventOnRoomID: NSAttributedString.Key = .init(rawValue: EventOnRoomIDAttribute.name)
static let MatrixEventOnRoomAlias: NSAttributedString.Key = .init(rawValue: EventOnRoomAliasAttribute.name)
static let MatrixAllUsersMention: NSAttributedString.Key = .init(rawValue: AllUsersMentionAttribute.name)
}
@@ -356,30 +360,24 @@ protocol MentionBuilderProtocol {
func handleAllUsersMention(for attributedString: NSMutableAttributedString, in range: NSRange)
}
private struct TypedMatch {
private struct TextParsingMatch {
enum MatchType {
case permalink(type: MentionType)
case link
case userID(identifier: String)
case link(urlString: String)
case atRoom
}
enum MentionType {
case roomAlias
case roomID
case userID
func getPermalinkFrom(identifier: String, baseURL: URL) -> URL? {
switch self {
case .roomAlias:
return try? PermalinkBuilder.permalinkTo(roomAlias: identifier, baseURL: baseURL)
case .roomID:
return try? PermalinkBuilder.permalinkTo(roomIdentifier: identifier, baseURL: baseURL)
case .userID:
return try? PermalinkBuilder.permalinkTo(userIdentifier: identifier, baseURL: baseURL)
}
let type: MatchType
let range: NSRange
var link: URL? {
switch type {
case .userID(let identifier):
return try? URL(string: matrixToUserPermalink(userId: identifier))
case .link(let urlString):
return URL(string: urlString)
default:
return nil
}
}
let match: NSTextCheckingResult
let type: MatchType
}
@@ -36,21 +36,29 @@ enum RoomAliasAttribute: AttributedStringKey {
static var name = "MXRoomAliasAttribute"
}
enum EventOnRoomIDAttribute: AttributedStringKey {
struct Value: Hashable {
let roomID: String
let eventID: String
}
static var name = "MXEventOnRoomIDAttribute"
}
enum EventOnRoomAliasAttribute: AttributedStringKey {
struct Value: Hashable {
let alias: String
let eventID: String
}
static var name = "MXEventOnRoomAliasAttribute"
}
enum AllUsersMentionAttribute: AttributedStringKey {
typealias Value = Bool
static var name = "MXAllUsersMentionAttribute"
}
struct EventIDAttributeValue: Hashable {
let roomID: String
let eventID: String
}
enum EventIDAttribute: AttributedStringKey {
typealias Value = EventIDAttributeValue
static var name = "MXEventIDAttribute"
}
// periphery: ignore - required to make NSAttributedString to AttributedString conversion even if not used directly
extension AttributeScopes {
struct ElementXAttributes: AttributeScope {
@@ -59,7 +67,8 @@ extension AttributeScopes {
let userID: UserIDAttribute
let roomID: RoomIDAttribute
let roomAlias: RoomAliasAttribute
let eventID: EventIDAttribute
let eventOnRoomID: EventOnRoomIDAttribute
let eventOnRoomAlias: EventOnRoomAliasAttribute
let allUsersMention: AllUsersMentionAttribute
@@ -1,152 +0,0 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
enum PermalinkBuilderError: Error {
case invalidUserIdentifier
case invalidRoomIdentifier
case invalidRoomAlias
case invalidEventIdentifier
case failedConstructingURL
case failedAddingPercentEncoding
}
enum PermalinkType: Equatable {
case userIdentifier(String)
case roomIdentifier(String)
case roomAlias(String)
case event(roomIdentifier: String, eventIdentifier: String)
}
enum PermalinkBuilder {
private static var uriComponentCharacterSet: CharacterSet = {
var charset = CharacterSet.alphanumerics
charset.insert(charactersIn: "-_.!~*'()")
return charset
}()
static func detectPermalink(in url: URL, baseURL: URL) -> PermalinkType? {
guard url.absoluteString.hasPrefix(baseURL.absoluteString) else {
return nil
}
guard let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
return nil
}
guard var fragment = urlComponents.fragment else {
return nil
}
if fragment.hasPrefix("/") {
fragment = String(fragment.dropFirst(1))
}
if let userIdentifierRange = MatrixEntityRegex.userIdentifierRegex.firstMatch(in: fragment)?.range {
return .userIdentifier((fragment as NSString).substring(with: userIdentifierRange))
}
if let roomAliasRange = MatrixEntityRegex.roomAliasRegex.firstMatch(in: fragment)?.range {
return .roomAlias((fragment as NSString).substring(with: roomAliasRange))
}
if let roomIdentifierRange = MatrixEntityRegex.roomIdentifierRegex.firstMatch(in: fragment)?.range {
let roomIdentifier = (fragment as NSString).substring(with: roomIdentifierRange)
if let eventIdentifierRange = MatrixEntityRegex.eventIdentifierRegex.firstMatch(in: fragment)?.range {
let eventIdentifier = (fragment as NSString).substring(with: eventIdentifierRange)
return .event(roomIdentifier: roomIdentifier, eventIdentifier: eventIdentifier)
}
return .roomIdentifier(roomIdentifier)
}
return nil
}
@available(*, deprecated, message: "Use a room's `matrixToPermalink` method instead")
static func permalinkTo(userIdentifier: String, baseURL: URL) throws -> URL {
guard MatrixEntityRegex.isMatrixUserIdentifier(userIdentifier) else {
throw PermalinkBuilderError.invalidUserIdentifier
}
let urlString = "\(baseURL)/#/\(userIdentifier)"
guard let url = URL(string: urlString) else {
throw PermalinkBuilderError.failedConstructingURL
}
return url
}
@available(*, deprecated, message: "Use a room's `matrixToPermalink` method instead")
static func permalinkTo(roomIdentifier: String, baseURL: URL) throws -> URL {
guard MatrixEntityRegex.isMatrixRoomIdentifier(roomIdentifier) else {
throw PermalinkBuilderError.invalidRoomIdentifier
}
return try permalinkTo(roomIdentifierOrAlias: roomIdentifier, baseURL: baseURL)
}
@available(*, deprecated, message: "Use a room's `matrixToPermalink` method instead")
static func permalinkTo(roomAlias: String, baseURL: URL) throws -> URL {
guard MatrixEntityRegex.isMatrixRoomAlias(roomAlias) else {
throw PermalinkBuilderError.invalidRoomAlias
}
return try permalinkTo(roomIdentifierOrAlias: roomAlias, baseURL: baseURL)
}
@available(*, deprecated, message: "Use a room's `matrixToEventPermalink` method instead")
static func permalinkTo(eventIdentifier: String, roomIdentifier: String, baseURL: URL) throws -> URL {
guard MatrixEntityRegex.isMatrixEventIdentifier(eventIdentifier) else {
throw PermalinkBuilderError.invalidEventIdentifier
}
guard MatrixEntityRegex.isMatrixRoomIdentifier(roomIdentifier) else {
throw PermalinkBuilderError.invalidRoomIdentifier
}
guard let roomId = roomIdentifier.addingPercentEncoding(withAllowedCharacters: uriComponentCharacterSet),
let eventId = eventIdentifier.addingPercentEncoding(withAllowedCharacters: uriComponentCharacterSet) else {
throw PermalinkBuilderError.failedAddingPercentEncoding
}
let urlString = "\(baseURL)/#/\(roomId)/\(eventId)"
guard let url = URL(string: urlString) else {
throw PermalinkBuilderError.failedConstructingURL
}
return url
}
// MARK: - Private
private static func permalinkTo(roomIdentifierOrAlias: String, baseURL: URL) throws -> URL {
guard let identifier = roomIdentifierOrAlias.addingPercentEncoding(withAllowedCharacters: uriComponentCharacterSet) else {
throw PermalinkBuilderError.failedAddingPercentEncoding
}
let urlString = "\(baseURL)/#/\(identifier)"
guard let url = URL(string: urlString) else {
throw PermalinkBuilderError.failedConstructingURL
}
return url
}
}
@@ -14,6 +14,7 @@
// limitations under the License.
//
import MatrixRustSDK
import SwiftUI
final class MessageTextView: UITextView, PillAttachmentViewProviderDelegate {
@@ -129,8 +130,7 @@ struct MessageText: UIViewRepresentable {
final class Coordinator: NSObject, UITextViewDelegate {
var openURLAction: OpenURLAction
let permalinkBaseURL = ServiceLocator.shared.settings.permalinkBaseURL
init(openURLAction: OpenURLAction) {
self.openURLAction = openURLAction
}
@@ -146,7 +146,7 @@ struct MessageText: UIViewRepresentable {
return false
case .preview:
// We don't want to show a URL preview for permalinks
return PermalinkBuilder.detectPermalink(in: URL, baseURL: permalinkBaseURL) == nil
return parseMatrixEntityFrom(uri: URL.absoluteString) == nil
default:
return true
}
@@ -157,7 +157,7 @@ struct MessageText: UIViewRepresentable {
switch textItem.content {
case let .link(url):
// We don't want to show a URL preview for permalinks
let isPermalink = PermalinkBuilder.detectPermalink(in: url, baseURL: permalinkBaseURL) != nil
let isPermalink = parseMatrixEntityFrom(uri: url.absoluteString) != nil
return .init(preview: isPermalink ? nil : .default, menu: defaultMenu)
default:
return nil
@@ -197,7 +197,7 @@ struct MessageText_Previews: PreviewProvider, TestablePreview {
private static let htmlStringWithList = "<p>This is a list</p>\n<ul>\n<li>One</li>\n<li>Two</li>\n<li>And number 3</li>\n</ul>\n"
private static let attributedStringBuilder = AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, mentionBuilder: MentionBuilder())
private static let attributedStringBuilder = AttributedStringBuilder(mentionBuilder: MentionBuilder())
static var attachmentPreview: some View {
MessageText(attributedString: attributedStringWithAttachment)
@@ -14,6 +14,7 @@
// limitations under the License.
//
import MatrixRustSDK
import SwiftUI
struct MatrixUserShareLink<Label: View>: View {
@@ -22,8 +23,7 @@ struct MatrixUserShareLink<Label: View>: View {
init(userID: String, @ViewBuilder label: () -> Label) {
self.label = label()
permalink = try? PermalinkBuilder.permalinkTo(userIdentifier: userID,
baseURL: ServiceLocator.shared.settings.permalinkBaseURL)
permalink = try? URL(string: matrixToUserPermalink(userId: userID))
}
var body: some View {
@@ -17,6 +17,7 @@
import Combine
import Foundation
import GameKit
import MatrixRustSDK
import SwiftUI
import WysiwygComposer
@@ -210,7 +211,7 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
private func setupMentionsHandling(mentionDisplayHelper: MentionDisplayHelper) {
wysiwygViewModel.mentionDisplayHelper = mentionDisplayHelper
let attributedStringBuilder = AttributedStringBuilder(cacheKey: "Composer", permalinkBaseURL: appSettings.permalinkBaseURL, mentionBuilder: MentionBuilder())
let attributedStringBuilder = AttributedStringBuilder(cacheKey: "Composer", mentionBuilder: MentionBuilder())
wysiwygViewModel.mentionReplacer = ComposerMentionReplacer { urlString, string in
let attributedString: NSMutableAttributedString
@@ -231,7 +232,7 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
private func handleSuggestion(_ suggestion: SuggestionItem) {
switch suggestion {
case let .user(item):
guard let url = try? PermalinkBuilder.permalinkTo(userIdentifier: item.id, baseURL: appSettings.permalinkBaseURL) else {
guard let url = try? URL(string: matrixToUserPermalink(userId: item.id)) else {
MXLog.error("Could not build user permalink")
return
}
@@ -319,8 +319,7 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
analyticsService: ServiceLocator.shared.analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
notificationSettingsProxy: notificationSettingsProxy,
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: .userDirectory,
mentionBuilder: MentionBuilder()))
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()))
}()
static let dmRoomViewModel = {
@@ -345,8 +344,7 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
analyticsService: ServiceLocator.shared.analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
notificationSettingsProxy: notificationSettingsProxy,
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: .userDirectory,
mentionBuilder: MentionBuilder()))
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()))
}()
static let simpleRoomViewModel = {
@@ -370,8 +368,7 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
analyticsService: ServiceLocator.shared.analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
notificationSettingsProxy: notificationSettingsProxy,
attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: .userDirectory,
mentionBuilder: MentionBuilder()))
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()))
}()
static var previews: some View {
@@ -209,7 +209,7 @@ struct FormattedBodyText_Previews: PreviewProvider, TestablePreview {
"<p>test</p>\n<p>test</p>"
]
let attributedStringBuilder = AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, mentionBuilder: MentionBuilder())
let attributedStringBuilder = AttributedStringBuilder(mentionBuilder: MentionBuilder())
ScrollView {
VStack(alignment: .leading, spacing: 24.0) {
@@ -110,7 +110,7 @@ struct TextRoomTimelineView_Previews: PreviewProvider, TestablePreview {
}
private static func itemWith(html: String, timestamp: String, isOutgoing: Bool, senderId: String) -> TextRoomTimelineItem {
let builder = AttributedStringBuilder(cacheKey: "preview", permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, mentionBuilder: MentionBuilder())
let builder = AttributedStringBuilder(cacheKey: "preview", mentionBuilder: MentionBuilder())
let attributedString = builder.fromHTML(html)
return TextRoomTimelineItem(id: .random,
@@ -681,7 +681,6 @@ class ClientProxy: ClientProxyProtocol {
let roomListService = syncService.roomListService()
let roomMessageEventStringBuilder = RoomMessageEventStringBuilder(attributedStringBuilder: AttributedStringBuilder(cacheKey: "roomList",
permalinkBaseURL: appSettings.permalinkBaseURL,
mentionBuilder: PlainMentionBuilder()))
let eventStringBuilder = RoomEventStringBuilder(stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID),
messageEventStringBuilder: roomMessageEventStringBuilder)
@@ -37,8 +37,7 @@ extension RoomMemberProxyProtocol {
}
var permalink: URL? {
try? PermalinkBuilder.permalinkTo(userIdentifier: userID,
baseURL: ServiceLocator.shared.settings.permalinkBaseURL)
try? URL(string: matrixToUserPermalink(userId: userID))
}
/// The name used for sorting the member alphabetically. This will be the displayname if,
@@ -97,8 +97,7 @@ enum RoomTimelineItemFixtures {
isThreaded: false,
sender: .init(id: "", displayName: "Helena"),
content: .init(body: "",
formattedBody: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL,
mentionBuilder: MentionBuilder())
formattedBody: AttributedStringBuilder(mentionBuilder: MentionBuilder())
.fromHTML("Hol' up <blockquote>New home office set up!</blockquote>That's amazing! Congrats 🥳")))
]