diff --git a/Packages/TuskerPreferences/Sources/TuskerPreferences/Preferences.swift b/Packages/TuskerPreferences/Sources/TuskerPreferences/Preferences.swift index 5328bdb9..b5fcce2e 100644 --- a/Packages/TuskerPreferences/Sources/TuskerPreferences/Preferences.swift +++ b/Packages/TuskerPreferences/Sources/TuskerPreferences/Preferences.swift @@ -61,6 +61,7 @@ public final class Preferences: Codable, ObservableObject { self.leadingStatusSwipeActions = try container.decodeIfPresent([StatusSwipeAction].self, forKey: .leadingStatusSwipeActions) ?? leadingStatusSwipeActions self.trailingStatusSwipeActions = try container.decodeIfPresent([StatusSwipeAction].self, forKey: .trailingStatusSwipeActions) ?? trailingStatusSwipeActions self.widescreenNavigationMode = try container.decodeIfPresent(WidescreenNavigationMode.self, forKey: .widescreenNavigationMode) ?? Self.defaultWidescreenNavigationMode + self.underlineTextLinks = try container.decodeIfPresent(Bool.self, forKey: .underlineTextLinks) ?? false self.defaultPostVisibility = try container.decode(Visibility.self, forKey: .defaultPostVisibility) self.defaultReplyVisibility = try container.decodeIfPresent(ReplyVisibility.self, forKey: .defaultReplyVisibility) ?? .sameAsPost @@ -121,6 +122,7 @@ public final class Preferences: Codable, ObservableObject { try container.encode(leadingStatusSwipeActions, forKey: .leadingStatusSwipeActions) try container.encode(trailingStatusSwipeActions, forKey: .trailingStatusSwipeActions) try container.encode(widescreenNavigationMode, forKey: .widescreenNavigationMode) + try container.encode(underlineTextLinks, forKey: .underlineTextLinks) try container.encode(defaultPostVisibility, forKey: .defaultPostVisibility) try container.encode(defaultReplyVisibility, forKey: .defaultReplyVisibility) @@ -175,6 +177,7 @@ public final class Preferences: Codable, ObservableObject { @Published public var trailingStatusSwipeActions: [StatusSwipeAction] = [.reply, .share] private static var defaultWidescreenNavigationMode = WidescreenNavigationMode.splitScreen @Published public var widescreenNavigationMode = Preferences.defaultWidescreenNavigationMode + @Published public var underlineTextLinks = false // MARK: Composing @Published public var defaultPostVisibility = Visibility.public @@ -245,6 +248,7 @@ public final class Preferences: Codable, ObservableObject { case leadingStatusSwipeActions case trailingStatusSwipeActions case widescreenNavigationMode + case underlineTextLinks case defaultPostVisibility case defaultReplyVisibility diff --git a/Tusker/Screens/Preferences/AppearancePrefsView.swift b/Tusker/Screens/Preferences/AppearancePrefsView.swift index 1f441b16..1e50daa5 100644 --- a/Tusker/Screens/Preferences/AppearancePrefsView.swift +++ b/Tusker/Screens/Preferences/AppearancePrefsView.swift @@ -124,6 +124,9 @@ struct AppearancePrefsView : View { Toggle(isOn: $preferences.showLinkPreviews) { Text("Show Link Previews") } + Toggle(isOn: $preferences.underlineTextLinks) { + Text("Underline Links") + } NavigationLink("Leading Swipe Actions") { SwipeActionsPrefsView(selection: $preferences.leadingStatusSwipeActions) .edgesIgnoringSafeArea(.all) diff --git a/Tusker/Views/ContentTextView.swift b/Tusker/Views/ContentTextView.swift index a2c61180..75b93de9 100644 --- a/Tusker/Views/ContentTextView.swift +++ b/Tusker/Views/ContentTextView.swift @@ -12,6 +12,7 @@ import Pachyderm import SafariServices import WebURL import WebURLFoundationExtras +import Combine private let emojiRegex = try! NSRegularExpression(pattern: ":(\\w+):", options: []) private let dataDetectorsScheme = "x-apple-data-detectors" @@ -52,6 +53,8 @@ class ContentTextView: LinkTextView, BaseEmojiLabel { // The preview created in the previewForHighlighting method, so that we can use the same one in previewForDismissing. private weak var currentTargetedPreview: UITargetedPreview? + private var underlineTextLinksCancellable: AnyCancellable? + override init(frame: CGRect, textContainer: NSTextContainer?) { super.init(frame: frame, textContainer: textContainer) commonInit() @@ -84,11 +87,20 @@ class ContentTextView: LinkTextView, BaseEmojiLabel { let recognizer = UITapGestureRecognizer(target: self, action: #selector(textTapped(_:))) addGestureRecognizer(recognizer) - NotificationCenter.default.addObserver(self, selector: #selector(updateLinkUnderlineStyle), name: UIAccessibility.buttonShapesEnabledStatusDidChangeNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(_updateLinkUnderlineStyle), name: UIAccessibility.buttonShapesEnabledStatusDidChangeNotification, object: nil) + underlineTextLinksCancellable = + Preferences.shared.$underlineTextLinks + .sink { [unowned self] in + self.updateLinkUnderlineStyle(preference: $0) + } } - @objc private func updateLinkUnderlineStyle() { - if UIAccessibility.buttonShapesEnabled { + @objc private func _updateLinkUnderlineStyle() { + updateLinkUnderlineStyle() + } + + private func updateLinkUnderlineStyle(preference: Bool = Preferences.shared.underlineTextLinks) { + if UIAccessibility.buttonShapesEnabled || preference { linkTextAttributes[.underlineStyle] = NSUnderlineStyle.single.rawValue } else { linkTextAttributes.removeValue(forKey: .underlineStyle)