Support tapping Matrix URIs in messages. (#2828)

This commit is contained in:
Doug
2024-05-10 15:22:22 +01:00
committed by GitHub
parent d8845303fd
commit 6984afd6c0
5 changed files with 70 additions and 4 deletions
@@ -149,7 +149,7 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
// Event identifiers and room aliases and identifiers detected in plain text are techincally incomplete
// without via parameters and we won't bother detecting them
var matches: [TextParsingMatch] = MatrixEntityRegex.userIdentifierRegex.matches(in: string, options: []).compactMap { match in
var matches: [TextParsingMatch] = MatrixEntityRegex.userIdentifierRegex.matches(in: string).compactMap { match in
guard let matchRange = Range(match.range, in: string) else {
return nil
}
@@ -159,7 +159,7 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
return TextParsingMatch(type: .userID(identifier: identifier), range: match.range)
}
matches.append(contentsOf: MatrixEntityRegex.roomAliasRegex.matches(in: string, options: []).compactMap { match in
matches.append(contentsOf: MatrixEntityRegex.roomAliasRegex.matches(in: string).compactMap { match in
guard let matchRange = Range(match.range, in: string) else {
return nil
}
@@ -169,7 +169,17 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
return TextParsingMatch(type: .roomAlias(alias: alias), range: match.range)
})
matches.append(contentsOf: MatrixEntityRegex.linkRegex.matches(in: string, options: []).compactMap { match in
matches.append(contentsOf: MatrixEntityRegex.uriRegex.matches(in: string).compactMap { match in
guard let matchRange = Range(match.range, in: string) else {
return nil
}
let uri = String(string[matchRange])
return TextParsingMatch(type: .matrixURI(uri: uri), range: match.range)
})
matches.append(contentsOf: MatrixEntityRegex.linkRegex.matches(in: string).compactMap { match in
guard let matchRange = Range(match.range, in: string) else {
return nil
}
@@ -183,7 +193,7 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
return TextParsingMatch(type: .link(urlString: link), range: match.range)
})
matches.append(contentsOf: MatrixEntityRegex.allUsersRegex.matches(in: attributedString.string, options: []).map { match in
matches.append(contentsOf: MatrixEntityRegex.allUsersRegex.matches(in: attributedString.string).map { match in
TextParsingMatch(type: .atRoom, range: match.range)
})
@@ -217,6 +227,10 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
if let url = try? matrixToRoomAliasPermalink(roomAlias: alias) {
attributedString.addAttribute(.link, value: url, range: match.range)
}
case .matrixURI(let uri):
if let url = URL(string: uri) {
attributedString.addAttribute(.link, value: url, range: match.range)
}
case .userID, .link:
if let url = match.link {
attributedString.addAttribute(.link, value: url, range: match.range)
@@ -357,6 +371,7 @@ private struct TextParsingMatch {
enum MatchType {
case userID(identifier: String)
case roomAlias(alias: String)
case matrixURI(uri: String)
case link(urlString: String)
case atRoom
}
@@ -22,6 +22,7 @@ enum MatrixEntityRegex: String {
case homeserver
case userID
case roomAlias
case uri
case allUsers
var rawValue: String {
@@ -32,6 +33,8 @@ enum MatrixEntityRegex: String {
return "@[\\x21-\\x39\\x3B-\\x7F]+:" + MatrixEntityRegex.homeserver.rawValue
case .roomAlias:
return "#[A-Z0-9._%#@=+-]+:" + MatrixEntityRegex.homeserver.rawValue
case .uri:
return "matrix:(r|u|roomid)\\/[A-Z0-9\\-._~:/?#\\[\\]@!$&'()*+,;=%]*(?:\\?[A-Z0-9\\-._~:/?#\\[\\]@!$&'()*+,;=%]*)?"
case .allUsers:
return PillConstants.atRoom
}
@@ -41,6 +44,7 @@ enum MatrixEntityRegex: String {
static var homeserverRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.homeserver.rawValue, options: .caseInsensitive)
static var userIdentifierRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.userID.rawValue, options: .caseInsensitive)
static var roomAliasRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.roomAlias.rawValue, options: .caseInsensitive)
static var uriRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.uri.rawValue, options: .caseInsensitive)
static var allUsersRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.allUsers.rawValue)
static var linkRegex = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
// swiftlint:enable force_try
@@ -69,6 +73,14 @@ enum MatrixEntityRegex: String {
return match.range.length == alias.count
}
static func isMatrixURI(_ uri: String) -> Bool {
guard let match = uriRegex.firstMatch(in: uri) else {
return false
}
return match.range.length == uri.count
}
static func containsMatrixAllUsers(_ string: String) -> Bool {
guard allUsersRegex.firstMatch(in: string) != nil else {
return false