From d84ca7bc75309d0c8ea26c8ec7a605bb06443726 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 31 Jul 2024 11:29:47 +0200 Subject: [PATCH] Fix link char count (IOS-285) --- .../MastodonCore/MastodonAuthentication.swift | 11 +++++++++++ .../ComposeContentViewModel.swift | 19 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonCore/MastodonAuthentication.swift b/MastodonSDK/Sources/MastodonCore/MastodonAuthentication.swift index 6e304d5800..d29995f540 100644 --- a/MastodonSDK/Sources/MastodonCore/MastodonAuthentication.swift +++ b/MastodonSDK/Sources/MastodonCore/MastodonAuthentication.swift @@ -5,6 +5,8 @@ import CoreDataStack import MastodonSDK public struct MastodonAuthentication: Codable, Hashable, UserIdentifier { + public static let fallbackCharactersReservedPerURL = 23 + public enum InstanceConfiguration: Codable, Hashable { case v1(Mastodon.Entity.Instance) case v2(Mastodon.Entity.V2.Instance, TranslationLanguages) @@ -38,6 +40,15 @@ public struct MastodonAuthentication: Codable, Hashable, UserIdentifier { } return version?.majorServerVersion(greaterThanOrEquals: 4) ?? false // following Tags is support beginning with Mastodon v4.0.0 } + + public var charactersReservedPerURL: Int { + switch self { + case let .v1(instance): + return instance.configuration?.statuses?.charactersReservedPerURL ?? fallbackCharactersReservedPerURL + case let .v2(instance, _): + return instance.configuration?.statuses?.charactersReservedPerURL ?? fallbackCharactersReservedPerURL + } + } } public typealias ID = UUID diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift index aec028a391..0d27d844a5 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift @@ -324,7 +324,24 @@ extension ComposeContentViewModel { // bind text $content - .map { $0.count } + .map { [weak self] input in + guard let self, let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else { + return input.count + } + let matches = detector.matches(in: input, options: [], range: NSRange(location: 0, length: input.count)) + let lengthWithoutLinks = input.count - matches.map({ match in + guard let range = Range(match.range, in: input) else { + return 0 + } + let url = input[range] + return url.count + }).reduce(0, +) + let charactersReservedPerURL = authContext.mastodonAuthenticationBox + .authentication + .instanceConfiguration? + .charactersReservedPerURL ?? MastodonAuthentication.fallbackCharactersReservedPerURL + return lengthWithoutLinks + (matches.count * charactersReservedPerURL) + } .assign(to: &$contentWeightedLength) Publishers.CombineLatest(