Compare commits
No commits in common. "157c8629a93069e3ccfddc0987fb3b8948565ac1" and "c4bf5d406d1c436db0ab926c02a0dcc7f6ad92c1" have entirely different histories.
157c8629a9
...
c4bf5d406d
|
@ -61,7 +61,6 @@ public final class Preferences: Codable, ObservableObject {
|
||||||
self.leadingStatusSwipeActions = try container.decodeIfPresent([StatusSwipeAction].self, forKey: .leadingStatusSwipeActions) ?? leadingStatusSwipeActions
|
self.leadingStatusSwipeActions = try container.decodeIfPresent([StatusSwipeAction].self, forKey: .leadingStatusSwipeActions) ?? leadingStatusSwipeActions
|
||||||
self.trailingStatusSwipeActions = try container.decodeIfPresent([StatusSwipeAction].self, forKey: .trailingStatusSwipeActions) ?? trailingStatusSwipeActions
|
self.trailingStatusSwipeActions = try container.decodeIfPresent([StatusSwipeAction].self, forKey: .trailingStatusSwipeActions) ?? trailingStatusSwipeActions
|
||||||
self.widescreenNavigationMode = try container.decodeIfPresent(WidescreenNavigationMode.self, forKey: .widescreenNavigationMode) ?? Self.defaultWidescreenNavigationMode
|
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.defaultPostVisibility = try container.decode(Visibility.self, forKey: .defaultPostVisibility)
|
||||||
self.defaultReplyVisibility = try container.decodeIfPresent(ReplyVisibility.self, forKey: .defaultReplyVisibility) ?? .sameAsPost
|
self.defaultReplyVisibility = try container.decodeIfPresent(ReplyVisibility.self, forKey: .defaultReplyVisibility) ?? .sameAsPost
|
||||||
|
@ -122,7 +121,6 @@ public final class Preferences: Codable, ObservableObject {
|
||||||
try container.encode(leadingStatusSwipeActions, forKey: .leadingStatusSwipeActions)
|
try container.encode(leadingStatusSwipeActions, forKey: .leadingStatusSwipeActions)
|
||||||
try container.encode(trailingStatusSwipeActions, forKey: .trailingStatusSwipeActions)
|
try container.encode(trailingStatusSwipeActions, forKey: .trailingStatusSwipeActions)
|
||||||
try container.encode(widescreenNavigationMode, forKey: .widescreenNavigationMode)
|
try container.encode(widescreenNavigationMode, forKey: .widescreenNavigationMode)
|
||||||
try container.encode(underlineTextLinks, forKey: .underlineTextLinks)
|
|
||||||
|
|
||||||
try container.encode(defaultPostVisibility, forKey: .defaultPostVisibility)
|
try container.encode(defaultPostVisibility, forKey: .defaultPostVisibility)
|
||||||
try container.encode(defaultReplyVisibility, forKey: .defaultReplyVisibility)
|
try container.encode(defaultReplyVisibility, forKey: .defaultReplyVisibility)
|
||||||
|
@ -177,7 +175,6 @@ public final class Preferences: Codable, ObservableObject {
|
||||||
@Published public var trailingStatusSwipeActions: [StatusSwipeAction] = [.reply, .share]
|
@Published public var trailingStatusSwipeActions: [StatusSwipeAction] = [.reply, .share]
|
||||||
private static var defaultWidescreenNavigationMode = WidescreenNavigationMode.splitScreen
|
private static var defaultWidescreenNavigationMode = WidescreenNavigationMode.splitScreen
|
||||||
@Published public var widescreenNavigationMode = Preferences.defaultWidescreenNavigationMode
|
@Published public var widescreenNavigationMode = Preferences.defaultWidescreenNavigationMode
|
||||||
@Published public var underlineTextLinks = false
|
|
||||||
|
|
||||||
// MARK: Composing
|
// MARK: Composing
|
||||||
@Published public var defaultPostVisibility = Visibility.public
|
@Published public var defaultPostVisibility = Visibility.public
|
||||||
|
@ -248,7 +245,6 @@ public final class Preferences: Codable, ObservableObject {
|
||||||
case leadingStatusSwipeActions
|
case leadingStatusSwipeActions
|
||||||
case trailingStatusSwipeActions
|
case trailingStatusSwipeActions
|
||||||
case widescreenNavigationMode
|
case widescreenNavigationMode
|
||||||
case underlineTextLinks
|
|
||||||
|
|
||||||
case defaultPostVisibility
|
case defaultPostVisibility
|
||||||
case defaultReplyVisibility
|
case defaultReplyVisibility
|
||||||
|
|
|
@ -59,14 +59,9 @@ public final class AccountMO: NSManagedObject, AccountProtocol {
|
||||||
super.awakeFromFetch()
|
super.awakeFromFetch()
|
||||||
|
|
||||||
managedObjectContext?.perform {
|
managedObjectContext?.perform {
|
||||||
self.touch()
|
self.lastFetchedAt = Date()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the `lastFetchedAt` date so this object isn't pruned early.
|
|
||||||
func touch() {
|
|
||||||
lastFetchedAt = Date()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,15 +89,10 @@ public final class StatusMO: NSManagedObject, StatusProtocol {
|
||||||
super.awakeFromFetch()
|
super.awakeFromFetch()
|
||||||
|
|
||||||
managedObjectContext?.perform {
|
managedObjectContext?.perform {
|
||||||
self.touch()
|
self.lastFetchedAt = Date()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the `lastFetchedAt` date so this object isn't pruned early.
|
|
||||||
func touch() {
|
|
||||||
lastFetchedAt = Date()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension StatusMO {
|
extension StatusMO {
|
||||||
|
|
|
@ -124,9 +124,6 @@ struct AppearancePrefsView : View {
|
||||||
Toggle(isOn: $preferences.showLinkPreviews) {
|
Toggle(isOn: $preferences.showLinkPreviews) {
|
||||||
Text("Show Link Previews")
|
Text("Show Link Previews")
|
||||||
}
|
}
|
||||||
Toggle(isOn: $preferences.underlineTextLinks) {
|
|
||||||
Text("Underline Links")
|
|
||||||
}
|
|
||||||
NavigationLink("Leading Swipe Actions") {
|
NavigationLink("Leading Swipe Actions") {
|
||||||
SwipeActionsPrefsView(selection: $preferences.leadingStatusSwipeActions)
|
SwipeActionsPrefsView(selection: $preferences.leadingStatusSwipeActions)
|
||||||
.edgesIgnoringSafeArea(.all)
|
.edgesIgnoringSafeArea(.all)
|
||||||
|
|
|
@ -20,8 +20,6 @@ class TimelineJumpButton: UIView {
|
||||||
var config = UIButton.Configuration.plain()
|
var config = UIButton.Configuration.plain()
|
||||||
config.image = UIImage(systemName: "arrow.up")
|
config.image = UIImage(systemName: "arrow.up")
|
||||||
config.contentInsets = .zero
|
config.contentInsets = .zero
|
||||||
// We don't want a background for this button, even when accessibility button shapes are enabled, because it's in the navbar.
|
|
||||||
config.background.backgroundColor = .clear
|
|
||||||
return UIButton(configuration: config)
|
return UIButton(configuration: config)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -440,15 +440,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
||||||
private func loadStatusesToRestore(position: TimelinePosition) async -> Bool {
|
private func loadStatusesToRestore(position: TimelinePosition) async -> Bool {
|
||||||
let originalPositionStatusIDs = position.statusIDs
|
let originalPositionStatusIDs = position.statusIDs
|
||||||
|
|
||||||
var unloaded = [String]()
|
let unloaded = position.statusIDs.filter({ mastodonController.persistentContainer.status(for: $0) == nil })
|
||||||
for id in position.statusIDs {
|
|
||||||
if let status = mastodonController.persistentContainer.status(for: id) {
|
|
||||||
// touch the status so that, even if it's old, it doesn't get pruned when we go into the background
|
|
||||||
status.touch()
|
|
||||||
} else {
|
|
||||||
unloaded.append(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
guard !unloaded.isEmpty else {
|
guard !unloaded.isEmpty else {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,9 +211,11 @@ extension TimelineLikeCollectionViewController {
|
||||||
extension TimelineLikeCollectionViewController {
|
extension TimelineLikeCollectionViewController {
|
||||||
// apply(_:animatingDifferences:) is marked as nonisolated, so just awaiting it doesn't dispatch to the main thread, unlike other async @MainActor methods
|
// apply(_:animatingDifferences:) is marked as nonisolated, so just awaiting it doesn't dispatch to the main thread, unlike other async @MainActor methods
|
||||||
// but we always want to update the data source on the main thread for consistency, so this method does that
|
// but we always want to update the data source on the main thread for consistency, so this method does that
|
||||||
@MainActor
|
|
||||||
func apply(_ snapshot: NSDiffableDataSourceSnapshot<Section, Item>, animatingDifferences: Bool) async {
|
func apply(_ snapshot: NSDiffableDataSourceSnapshot<Section, Item>, animatingDifferences: Bool) async {
|
||||||
await self.dataSource.apply(snapshot, animatingDifferences: animatingDifferences)
|
let task = Task { @MainActor in
|
||||||
|
self.dataSource.apply(snapshot, animatingDifferences: animatingDifferences)
|
||||||
|
}
|
||||||
|
await task.value
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
|
|
|
@ -12,7 +12,6 @@ import Pachyderm
|
||||||
import SafariServices
|
import SafariServices
|
||||||
import WebURL
|
import WebURL
|
||||||
import WebURLFoundationExtras
|
import WebURLFoundationExtras
|
||||||
import Combine
|
|
||||||
|
|
||||||
private let emojiRegex = try! NSRegularExpression(pattern: ":(\\w+):", options: [])
|
private let emojiRegex = try! NSRegularExpression(pattern: ":(\\w+):", options: [])
|
||||||
private let dataDetectorsScheme = "x-apple-data-detectors"
|
private let dataDetectorsScheme = "x-apple-data-detectors"
|
||||||
|
@ -53,8 +52,6 @@ class ContentTextView: LinkTextView, BaseEmojiLabel {
|
||||||
// The preview created in the previewForHighlighting method, so that we can use the same one in previewForDismissing.
|
// The preview created in the previewForHighlighting method, so that we can use the same one in previewForDismissing.
|
||||||
private weak var currentTargetedPreview: UITargetedPreview?
|
private weak var currentTargetedPreview: UITargetedPreview?
|
||||||
|
|
||||||
private var underlineTextLinksCancellable: AnyCancellable?
|
|
||||||
|
|
||||||
override init(frame: CGRect, textContainer: NSTextContainer?) {
|
override init(frame: CGRect, textContainer: NSTextContainer?) {
|
||||||
super.init(frame: frame, textContainer: textContainer)
|
super.init(frame: frame, textContainer: textContainer)
|
||||||
commonInit()
|
commonInit()
|
||||||
|
@ -81,30 +78,10 @@ class ContentTextView: LinkTextView, BaseEmojiLabel {
|
||||||
linkTextAttributes = [
|
linkTextAttributes = [
|
||||||
.foregroundColor: UIColor.tintColor
|
.foregroundColor: UIColor.tintColor
|
||||||
]
|
]
|
||||||
updateLinkUnderlineStyle()
|
|
||||||
|
|
||||||
// the text view's builtin link interaction code is tied to isSelectable, so we need to use our own tap recognizer
|
// the text view's builtin link interaction code is tied to isSelectable, so we need to use our own tap recognizer
|
||||||
let recognizer = UITapGestureRecognizer(target: self, action: #selector(textTapped(_:)))
|
let recognizer = UITapGestureRecognizer(target: self, action: #selector(textTapped(_:)))
|
||||||
addGestureRecognizer(recognizer)
|
addGestureRecognizer(recognizer)
|
||||||
|
|
||||||
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() {
|
|
||||||
updateLinkUnderlineStyle()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func updateLinkUnderlineStyle(preference: Bool = Preferences.shared.underlineTextLinks) {
|
|
||||||
if UIAccessibility.buttonShapesEnabled || preference {
|
|
||||||
linkTextAttributes[.underlineStyle] = NSUnderlineStyle.single.rawValue
|
|
||||||
} else {
|
|
||||||
linkTextAttributes.removeValue(forKey: .underlineStyle)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Emojis
|
// MARK: - Emojis
|
||||||
|
|
Loading…
Reference in New Issue