Add preference for showing attachments in timeline

Closes #330
This commit is contained in:
Shadowfacts 2023-12-04 16:18:54 -05:00
parent 34edd8a13f
commit be1ca70ebf
6 changed files with 39 additions and 5 deletions

View File

@ -62,6 +62,7 @@ public final class Preferences: Codable, ObservableObject {
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.underlineTextLinks = try container.decodeIfPresent(Bool.self, forKey: .underlineTextLinks) ?? false
self.showAttachmentsInTimeline = try container.decodeIfPresent(Bool.self, forKey: .showAttachmentsInTimeline) ?? true
if let existing = try? container.decode(Visibility.self, forKey: .defaultPostVisibility) { if let existing = try? container.decode(Visibility.self, forKey: .defaultPostVisibility) {
self.defaultPostVisibility = .visibility(existing) self.defaultPostVisibility = .visibility(existing)
@ -127,6 +128,7 @@ public final class Preferences: Codable, ObservableObject {
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(underlineTextLinks, forKey: .underlineTextLinks)
try container.encode(showAttachmentsInTimeline, forKey: .showAttachmentsInTimeline)
try container.encode(defaultPostVisibility, forKey: .defaultPostVisibility) try container.encode(defaultPostVisibility, forKey: .defaultPostVisibility)
try container.encode(defaultReplyVisibility, forKey: .defaultReplyVisibility) try container.encode(defaultReplyVisibility, forKey: .defaultReplyVisibility)
@ -182,6 +184,7 @@ public final class Preferences: Codable, ObservableObject {
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 @Published public var underlineTextLinks = false
@Published public var showAttachmentsInTimeline = true
// MARK: Composing // MARK: Composing
@Published public var defaultPostVisibility = PostVisibility.serverDefault @Published public var defaultPostVisibility = PostVisibility.serverDefault
@ -253,6 +256,7 @@ public final class Preferences: Codable, ObservableObject {
case trailingStatusSwipeActions case trailingStatusSwipeActions
case widescreenNavigationMode case widescreenNavigationMode
case underlineTextLinks case underlineTextLinks
case showAttachmentsInTimeline
case defaultPostVisibility case defaultPostVisibility
case defaultReplyVisibility case defaultReplyVisibility

View File

@ -118,12 +118,15 @@ struct AppearancePrefsView : View {
Toggle(isOn: $preferences.alwaysShowStatusVisibilityIcon) { Toggle(isOn: $preferences.alwaysShowStatusVisibilityIcon) {
Text("Always Show Status Visibility Icons") Text("Always Show Status Visibility Icons")
} }
Toggle(isOn: $preferences.hideActionsInTimeline) {
Text("Hide Actions on Timeline")
}
Toggle(isOn: $preferences.showLinkPreviews) { Toggle(isOn: $preferences.showLinkPreviews) {
Text("Show Link Previews") Text("Show Link Previews")
} }
Toggle(isOn: $preferences.showAttachmentsInTimeline) {
Text("Show Attachments on Timeline")
}
Toggle(isOn: $preferences.hideActionsInTimeline) {
Text("Hide Actions on Timeline")
}
Toggle(isOn: $preferences.underlineTextLinks) { Toggle(isOn: $preferences.underlineTextLinks) {
Text("Underline Links") Text("Underline Links")
} }

View File

@ -164,6 +164,18 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
.store(in: &cancellables) .store(in: &cancellables)
NotificationCenter.default.addObserver(self, selector: #selector(handleStatusDeleted), name: .statusDeleted, object: mastodonController) NotificationCenter.default.addObserver(self, selector: #selector(handleStatusDeleted), name: .statusDeleted, object: mastodonController)
Preferences.shared.$showAttachmentsInTimeline
// skip the initial value
.dropFirst()
// publisher fires on willChange, wait the change is actually made
.receive(on: DispatchQueue.main)
.sink { [unowned self] _ in
var snapshot = self.dataSource.snapshot()
snapshot.reconfigureItems(snapshot.itemIdentifiers)
self.dataSource.apply(snapshot, animatingDifferences: false)
}
.store(in: &cancellables)
if userActivity != nil { if userActivity != nil {
userActivityNeedsUpdate userActivityNeedsUpdate
.debounce(for: .seconds(1), scheduler: DispatchQueue.main) .debounce(for: .seconds(1), scheduler: DispatchQueue.main)

View File

@ -71,6 +71,7 @@ class AttachmentsContainerView: UIView {
let newTokens = attachments.map { AttachmentToken(attachment: $0) } let newTokens = attachments.map { AttachmentToken(attachment: $0) }
guard self.attachmentTokens != newTokens else { guard self.attachmentTokens != newTokens else {
self.isHidden = attachments.isEmpty
return return
} }

View File

@ -44,6 +44,7 @@ protocol StatusCollectionViewCell: UICollectionViewCell, AttachmentViewDelegate
var isGrayscale: Bool { get set } var isGrayscale: Bool { get set }
var cancellables: Set<AnyCancellable> { get set } var cancellables: Set<AnyCancellable> { get set }
func updateAttachmentsUI(status: StatusMO)
func updateUIForPreferences(status: StatusMO) func updateUIForPreferences(status: StatusMO)
func updateStatusState(status: StatusMO) func updateStatusState(status: StatusMO)
func estimateContentHeight() -> CGFloat func estimateContentHeight() -> CGFloat
@ -91,8 +92,7 @@ extension StatusCollectionViewCell {
contentContainer.contentTextView.setTextFrom(status: status, precomputed: precomputedContent) contentContainer.contentTextView.setTextFrom(status: status, precomputed: precomputedContent)
contentContainer.contentTextView.navigationDelegate = delegate contentContainer.contentTextView.navigationDelegate = delegate
contentContainer.attachmentsView.delegate = self self.updateAttachmentsUI(status: status)
contentContainer.attachmentsView.updateUI(attachments: status.attachments)
contentContainer.pollView.isHidden = status.poll == nil contentContainer.pollView.isHidden = status.poll == nil
contentContainer.pollView.mastodonController = mastodonController contentContainer.pollView.mastodonController = mastodonController
contentContainer.pollView.delegate = delegate contentContainer.pollView.delegate = delegate
@ -167,6 +167,11 @@ extension StatusCollectionViewCell {
return true return true
} }
func updateAttachmentsUI(status: StatusMO) {
contentContainer.attachmentsView.delegate = self
contentContainer.attachmentsView.updateUI(attachments: status.attachments)
}
func updateAccountUI(account: AccountMO) { func updateAccountUI(account: AccountMO) {
avatarImageView.update(for: account.avatar) avatarImageView.update(for: account.avatar)
displayNameLabel.updateForAccountDisplayName(account: account) displayNameLabel.updateForAccountDisplayName(account: account)

View File

@ -645,6 +645,15 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
baseUpdateStatusState(status: status) baseUpdateStatusState(status: status)
} }
func updateAttachmentsUI(status: StatusMO) {
if Preferences.shared.showAttachmentsInTimeline {
attachmentsView.delegate = self
attachmentsView.updateUI(attachments: status.attachments)
} else {
attachmentsView.isHidden = true
}
}
func estimateContentHeight() -> CGFloat { func estimateContentHeight() -> CGFloat {
let width = bounds.width /* leading spacing: */ - 16 /* avatar: */ - 50 /* spacing: 8 */ - 8 /* trailing spacing: */ - 16 let width = bounds.width /* leading spacing: */ - 16 /* avatar: */ - 50 /* spacing: 8 */ - 8 /* trailing spacing: */ - 16
return contentContainer.estimateVisibleSubviewHeight(effectiveWidth: width) return contentContainer.estimateVisibleSubviewHeight(effectiveWidth: width)