Compare commits
7 Commits
13d649bace
...
a79b3cfd70
Author | SHA1 | Date |
---|---|---|
Shadowfacts | a79b3cfd70 | |
Shadowfacts | 9a35f96c75 | |
Shadowfacts | 60767c6a7e | |
Shadowfacts | 57668886b2 | |
Shadowfacts | ffb5c76f7c | |
Shadowfacts | 00e8dd6345 | |
Shadowfacts | 7904462920 |
|
@ -257,8 +257,8 @@ private func setInstanceBreadcrumb(instance: Instance, nodeInfo: NodeInfo?) {
|
||||||
]
|
]
|
||||||
if let nodeInfo {
|
if let nodeInfo {
|
||||||
crumb.data!["nodeInfo"] = [
|
crumb.data!["nodeInfo"] = [
|
||||||
"version": nodeInfo.version,
|
"software": nodeInfo.software.name,
|
||||||
"software": nodeInfo.software,
|
"version": nodeInfo.software.version,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
SentrySDK.addBreadcrumb(crumb: crumb)
|
SentrySDK.addBreadcrumb(crumb: crumb)
|
||||||
|
|
|
@ -52,7 +52,11 @@ class Preferences: Codable, ObservableObject {
|
||||||
self.mentionReblogger = try container.decode(Bool.self, forKey: .mentionReblogger)
|
self.mentionReblogger = try container.decode(Bool.self, forKey: .mentionReblogger)
|
||||||
self.useTwitterKeyboard = try container.decodeIfPresent(Bool.self, forKey: .useTwitterKeyboard) ?? false
|
self.useTwitterKeyboard = try container.decodeIfPresent(Bool.self, forKey: .useTwitterKeyboard) ?? false
|
||||||
|
|
||||||
self.blurAllMedia = try container.decode(Bool.self, forKey: .blurAllMedia)
|
if let blurAllMedia = try? container.decodeIfPresent(Bool.self, forKey: .blurAllMedia) {
|
||||||
|
self.attachmentBlurMode = blurAllMedia ? .always : .useStatusSetting
|
||||||
|
} else {
|
||||||
|
self.attachmentBlurMode = try container.decode(AttachmentBlurMode.self, forKey: .attachmentBlurMode)
|
||||||
|
}
|
||||||
self.blurMediaBehindContentWarning = try container.decodeIfPresent(Bool.self, forKey: .blurMediaBehindContentWarning) ?? true
|
self.blurMediaBehindContentWarning = try container.decodeIfPresent(Bool.self, forKey: .blurMediaBehindContentWarning) ?? true
|
||||||
self.automaticallyPlayGifs = try container.decode(Bool.self, forKey: .automaticallyPlayGifs)
|
self.automaticallyPlayGifs = try container.decode(Bool.self, forKey: .automaticallyPlayGifs)
|
||||||
|
|
||||||
|
@ -95,7 +99,7 @@ class Preferences: Codable, ObservableObject {
|
||||||
try container.encode(mentionReblogger, forKey: .mentionReblogger)
|
try container.encode(mentionReblogger, forKey: .mentionReblogger)
|
||||||
try container.encode(useTwitterKeyboard, forKey: .useTwitterKeyboard)
|
try container.encode(useTwitterKeyboard, forKey: .useTwitterKeyboard)
|
||||||
|
|
||||||
try container.encode(blurAllMedia, forKey: .blurAllMedia)
|
try container.encode(attachmentBlurMode, forKey: .attachmentBlurMode)
|
||||||
try container.encode(blurMediaBehindContentWarning, forKey: .blurMediaBehindContentWarning)
|
try container.encode(blurMediaBehindContentWarning, forKey: .blurMediaBehindContentWarning)
|
||||||
try container.encode(automaticallyPlayGifs, forKey: .automaticallyPlayGifs)
|
try container.encode(automaticallyPlayGifs, forKey: .automaticallyPlayGifs)
|
||||||
|
|
||||||
|
@ -140,10 +144,12 @@ class Preferences: Codable, ObservableObject {
|
||||||
@Published var useTwitterKeyboard = false
|
@Published var useTwitterKeyboard = false
|
||||||
|
|
||||||
// MARK: Media
|
// MARK: Media
|
||||||
@Published var blurAllMedia = false {
|
@Published var attachmentBlurMode = AttachmentBlurMode.useStatusSetting {
|
||||||
didSet {
|
didSet {
|
||||||
if blurAllMedia {
|
if attachmentBlurMode == .always {
|
||||||
blurMediaBehindContentWarning = true
|
blurMediaBehindContentWarning = true
|
||||||
|
} else if attachmentBlurMode == .never {
|
||||||
|
blurMediaBehindContentWarning = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,7 +197,8 @@ class Preferences: Codable, ObservableObject {
|
||||||
case mentionReblogger
|
case mentionReblogger
|
||||||
case useTwitterKeyboard
|
case useTwitterKeyboard
|
||||||
|
|
||||||
case blurAllMedia
|
case blurAllMedia // only used for migration
|
||||||
|
case attachmentBlurMode
|
||||||
case blurMediaBehindContentWarning
|
case blurMediaBehindContentWarning
|
||||||
case automaticallyPlayGifs
|
case automaticallyPlayGifs
|
||||||
|
|
||||||
|
@ -254,4 +261,23 @@ extension Preferences {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Preferences {
|
||||||
|
enum AttachmentBlurMode: Codable, Hashable, CaseIterable {
|
||||||
|
case useStatusSetting
|
||||||
|
case always
|
||||||
|
case never
|
||||||
|
|
||||||
|
var displayName: String {
|
||||||
|
switch self {
|
||||||
|
case .useStatusSetting:
|
||||||
|
return "Default"
|
||||||
|
case .always:
|
||||||
|
return "Always"
|
||||||
|
case .never:
|
||||||
|
return "Never"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension UIUserInterfaceStyle: Codable {}
|
extension UIUserInterfaceStyle: Codable {}
|
||||||
|
|
|
@ -137,6 +137,11 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func accessibilityPerformEscape() -> Bool {
|
||||||
|
dismiss(animated: true)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Page View Controller Data Source
|
// MARK: - Page View Controller Data Source
|
||||||
|
|
||||||
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
|
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
|
||||||
|
|
|
@ -123,4 +123,23 @@ class FeaturedProfileCollectionViewCell: UICollectionViewCell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: Accessibility
|
||||||
|
|
||||||
|
override var isAccessibilityElement: Bool {
|
||||||
|
get { true }
|
||||||
|
set {}
|
||||||
|
}
|
||||||
|
|
||||||
|
override var accessibilityAttributedLabel: NSAttributedString? {
|
||||||
|
get {
|
||||||
|
guard let account else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
let s = NSMutableAttributedString(string: "\(account.displayName), ")
|
||||||
|
s.append(noteTextView.attributedText)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
set {}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,9 @@ class ProfileDirectoryViewController: UIViewController {
|
||||||
|
|
||||||
title = NSLocalizedString("Profile Directory", comment: "profile directory title")
|
title = NSLocalizedString("Profile Directory", comment: "profile directory title")
|
||||||
|
|
||||||
// todo: it would be nice if there were a better "filter" icon
|
let filterItem = UIBarButtonItem(image: UIImage(systemName: "line.3.horizontal.decrease.circle"), menu: nil)
|
||||||
navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "scope"), menu: nil)
|
filterItem.accessibilityLabel = "Filter"
|
||||||
|
navigationItem.rightBarButtonItem = filterItem
|
||||||
updateFilterMenu()
|
updateFilterMenu()
|
||||||
|
|
||||||
let layout = UICollectionViewCompositionalLayout(sectionProvider: { (sectionIndex, layoutEnvironment) in
|
let layout = UICollectionViewCompositionalLayout(sectionProvider: { (sectionIndex, layoutEnvironment) in
|
||||||
|
|
|
@ -21,6 +21,7 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate, LargeIma
|
||||||
@IBOutlet weak var descriptionLabel: UILabel!
|
@IBOutlet weak var descriptionLabel: UILabel!
|
||||||
|
|
||||||
private var shareContainer: UIView!
|
private var shareContainer: UIView!
|
||||||
|
private var closeContainer: UIView!
|
||||||
private var shareImage: UIImageView!
|
private var shareImage: UIImageView!
|
||||||
private var shareButtonTopConstraint: NSLayoutConstraint!
|
private var shareButtonTopConstraint: NSLayoutConstraint!
|
||||||
private var shareButtonLeadingConstraint: NSLayoutConstraint!
|
private var shareButtonLeadingConstraint: NSLayoutConstraint!
|
||||||
|
@ -116,6 +117,12 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate, LargeIma
|
||||||
view.addGestureRecognizer(doubleTap)
|
view.addGestureRecognizer(doubleTap)
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
|
||||||
|
|
||||||
|
accessibilityElements = [
|
||||||
|
topControlsView!,
|
||||||
|
contentView,
|
||||||
|
bottomControlsView!,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupContentView() {
|
private func setupContentView() {
|
||||||
|
@ -135,6 +142,9 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate, LargeIma
|
||||||
|
|
||||||
private func setupControls() {
|
private func setupControls() {
|
||||||
shareContainer = UIView()
|
shareContainer = UIView()
|
||||||
|
shareContainer.isAccessibilityElement = true
|
||||||
|
shareContainer.accessibilityTraits = .button
|
||||||
|
shareContainer.accessibilityLabel = "Share"
|
||||||
shareContainer.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(sharePressed)))
|
shareContainer.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(sharePressed)))
|
||||||
shareContainer.translatesAutoresizingMaskIntoConstraints = false
|
shareContainer.translatesAutoresizingMaskIntoConstraints = false
|
||||||
topControlsView.addSubview(shareContainer)
|
topControlsView.addSubview(shareContainer)
|
||||||
|
@ -161,7 +171,10 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate, LargeIma
|
||||||
shareImage.heightAnchor.constraint(equalToConstant: 24),
|
shareImage.heightAnchor.constraint(equalToConstant: 24),
|
||||||
])
|
])
|
||||||
|
|
||||||
let closeContainer = UIView()
|
closeContainer = UIView()
|
||||||
|
closeContainer.isAccessibilityElement = true
|
||||||
|
closeContainer.accessibilityTraits = .button
|
||||||
|
closeContainer.accessibilityLabel = "Close"
|
||||||
closeContainer.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(closeButtonPressed)))
|
closeContainer.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(closeButtonPressed)))
|
||||||
closeContainer.translatesAutoresizingMaskIntoConstraints = false
|
closeContainer.translatesAutoresizingMaskIntoConstraints = false
|
||||||
topControlsView.addSubview(closeContainer)
|
topControlsView.addSubview(closeContainer)
|
||||||
|
|
|
@ -21,14 +21,18 @@ struct MediaPrefsView: View {
|
||||||
|
|
||||||
var viewingSection: some View {
|
var viewingSection: some View {
|
||||||
Section(header: Text("Viewing")) {
|
Section(header: Text("Viewing")) {
|
||||||
Toggle(isOn: $preferences.blurAllMedia) {
|
Picker(selection: $preferences.attachmentBlurMode) {
|
||||||
Text("Blur All Media")
|
ForEach(Preferences.AttachmentBlurMode.allCases, id: \.self) { mode in
|
||||||
|
Text(mode.displayName).tag(mode)
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
Text("Blur Media")
|
||||||
}
|
}
|
||||||
|
|
||||||
Toggle(isOn: $preferences.blurMediaBehindContentWarning) {
|
Toggle(isOn: $preferences.blurMediaBehindContentWarning) {
|
||||||
Text("Blur Media Behind Content Warning")
|
Text("Blur Media Behind Content Warning")
|
||||||
}
|
}
|
||||||
.disabled(preferences.blurAllMedia)
|
.disabled(preferences.attachmentBlurMode != .useStatusSetting)
|
||||||
|
|
||||||
Toggle(isOn: $preferences.automaticallyPlayGifs) {
|
Toggle(isOn: $preferences.automaticallyPlayGifs) {
|
||||||
Text("Automatically Play GIFs")
|
Text("Automatically Play GIFs")
|
||||||
|
|
|
@ -345,7 +345,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
||||||
|
|
||||||
private func removeTimelineDescriptionCell() {
|
private func removeTimelineDescriptionCell() {
|
||||||
var snapshot = dataSource.snapshot()
|
var snapshot = dataSource.snapshot()
|
||||||
snapshot.deleteSections([.header])
|
snapshot.deleteItems([.publicTimelineDescription])
|
||||||
dataSource.apply(snapshot, animatingDifferences: true)
|
dataSource.apply(snapshot, animatingDifferences: true)
|
||||||
isShowingTimelineDescription = false
|
isShowingTimelineDescription = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,15 +173,17 @@ class ContentTextView: LinkTextView, BaseEmojiLabel {
|
||||||
|
|
||||||
// MARK: - Navigation
|
// MARK: - Navigation
|
||||||
|
|
||||||
func getViewController(forLink url: URL, inRange range: NSRange) -> UIViewController {
|
func getViewController(forLink url: URL, inRange range: NSRange) -> UIViewController? {
|
||||||
let text = (self.text as NSString).substring(with: range)
|
let text = (self.text as NSString).substring(with: range)
|
||||||
|
|
||||||
if let mention = getMention(for: url, text: text) {
|
if let mention = getMention(for: url, text: text) {
|
||||||
return ProfileViewController(accountID: mention.id, mastodonController: mastodonController!)
|
return ProfileViewController(accountID: mention.id, mastodonController: mastodonController!)
|
||||||
} else if let tag = getHashtag(for: url, text: text) {
|
} else if let tag = getHashtag(for: url, text: text) {
|
||||||
return HashtagTimelineViewController(for: tag, mastodonController: mastodonController!)
|
return HashtagTimelineViewController(for: tag, mastodonController: mastodonController!)
|
||||||
} else {
|
} else if url.scheme == "https" || url.scheme == "http" {
|
||||||
return SFSafariViewController(url: url)
|
return SFSafariViewController(url: url)
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,16 +231,17 @@ class BaseStatusTableViewCell: UITableViewCell {
|
||||||
|
|
||||||
func updateUIForPreferences(account: AccountMO, status: StatusMO) {
|
func updateUIForPreferences(account: AccountMO, status: StatusMO) {
|
||||||
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: avatarImageView)
|
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: avatarImageView)
|
||||||
if Preferences.shared.blurAllMedia {
|
switch Preferences.shared.attachmentBlurMode {
|
||||||
attachmentsView.contentHidden = true
|
case .never:
|
||||||
} else if status.sensitive {
|
|
||||||
if !Preferences.shared.blurMediaBehindContentWarning && !status.spoilerText.isEmpty {
|
|
||||||
attachmentsView.contentHidden = false
|
|
||||||
} else {
|
|
||||||
attachmentsView.contentHidden = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
attachmentsView.contentHidden = false
|
attachmentsView.contentHidden = false
|
||||||
|
case .always:
|
||||||
|
attachmentsView.contentHidden = true
|
||||||
|
default:
|
||||||
|
if status.sensitive {
|
||||||
|
attachmentsView.contentHidden = status.spoilerText.isEmpty || Preferences.shared.blurMediaBehindContentWarning
|
||||||
|
} else {
|
||||||
|
attachmentsView.contentHidden = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStatusIconsForPreferences(status)
|
updateStatusIconsForPreferences(status)
|
||||||
|
|
|
@ -148,16 +148,17 @@ extension StatusCollectionViewCell {
|
||||||
|
|
||||||
func baseUpdateUIForPreferences(status: StatusMO) {
|
func baseUpdateUIForPreferences(status: StatusMO) {
|
||||||
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * Self.avatarImageViewSize
|
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * Self.avatarImageViewSize
|
||||||
if Preferences.shared.blurAllMedia {
|
switch Preferences.shared.attachmentBlurMode {
|
||||||
contentContainer.attachmentsView.contentHidden = true
|
case .never:
|
||||||
} else if status.sensitive {
|
|
||||||
if !Preferences.shared.blurMediaBehindContentWarning && !status.spoilerText.isEmpty {
|
|
||||||
contentContainer.attachmentsView.contentHidden = false
|
|
||||||
} else {
|
|
||||||
contentContainer.attachmentsView.contentHidden = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
contentContainer.attachmentsView.contentHidden = false
|
contentContainer.attachmentsView.contentHidden = false
|
||||||
|
case .always:
|
||||||
|
contentContainer.attachmentsView.contentHidden = true
|
||||||
|
default:
|
||||||
|
if status.sensitive {
|
||||||
|
contentContainer.attachmentsView.contentHidden = status.spoilerText.isEmpty || Preferences.shared.blurMediaBehindContentWarning
|
||||||
|
} else {
|
||||||
|
contentContainer.attachmentsView.contentHidden = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let reblogButtonImage: UIImage
|
let reblogButtonImage: UIImage
|
||||||
|
|
|
@ -369,7 +369,13 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
|
||||||
guard let status = mastodonController.persistentContainer.status(for: statusID) else {
|
guard let status = mastodonController.persistentContainer.status(for: statusID) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var str = AttributedString("\(status.account.displayOrUserName), ")
|
var str: AttributedString = ""
|
||||||
|
if let rebloggerID,
|
||||||
|
let reblogger = mastodonController.persistentContainer.account(for: rebloggerID) {
|
||||||
|
str += AttributedString("Reblogged by \(reblogger.displayOrUserName): ")
|
||||||
|
}
|
||||||
|
str += AttributedString(status.account.displayOrUserName)
|
||||||
|
str += ", "
|
||||||
if statusState.collapsed ?? false {
|
if statusState.collapsed ?? false {
|
||||||
if !status.spoilerText.isEmpty {
|
if !status.spoilerText.isEmpty {
|
||||||
str += AttributedString(status.spoilerText)
|
str += AttributedString(status.spoilerText)
|
||||||
|
@ -378,15 +384,24 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
|
||||||
str += "collapsed"
|
str += "collapsed"
|
||||||
} else {
|
} else {
|
||||||
str += AttributedString(contentTextView.attributedText)
|
str += AttributedString(contentTextView.attributedText)
|
||||||
|
|
||||||
|
if status.attachments.count > 0 {
|
||||||
|
if status.attachments.count == 1 {
|
||||||
|
let attachment = status.attachments[0]
|
||||||
|
let desc = attachment.description?.isEmpty == false ? attachment.description! : "no description"
|
||||||
|
str += AttributedString(", attachment: \(desc)")
|
||||||
|
} else {
|
||||||
|
for (index, attachment) in status.attachments.enumerated() {
|
||||||
|
let desc = attachment.description?.isEmpty == false ? attachment.description! : "no description"
|
||||||
|
str += AttributedString(", attachment \(index + 1): \(desc)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if status.poll != nil {
|
||||||
|
str += ", poll"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if status.attachments.count > 0 {
|
|
||||||
// TODO: localize me
|
|
||||||
str += AttributedString(", \(status.attachments.count) attachment\(status.attachments.count > 1 ? "s" : "")")
|
|
||||||
}
|
|
||||||
if status.poll != nil {
|
|
||||||
str += ", poll"
|
|
||||||
}
|
|
||||||
str += AttributedString(", \(status.createdAt.formatted(.relative(presentation: .numeric)))")
|
str += AttributedString(", \(status.createdAt.formatted(.relative(presentation: .numeric)))")
|
||||||
if status.visibility < .unlisted {
|
if status.visibility < .unlisted {
|
||||||
str += AttributedString(", \(status.visibility.displayName)")
|
str += AttributedString(", \(status.visibility.displayName)")
|
||||||
|
@ -394,10 +409,6 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
|
||||||
if status.localOnly {
|
if status.localOnly {
|
||||||
str += ", local"
|
str += ", local"
|
||||||
}
|
}
|
||||||
if let rebloggerID,
|
|
||||||
let reblogger = mastodonController.persistentContainer.account(for: rebloggerID) {
|
|
||||||
str += AttributedString(", reblogged by \(reblogger.displayOrUserName)")
|
|
||||||
}
|
|
||||||
return NSAttributedString(str)
|
return NSAttributedString(str)
|
||||||
}
|
}
|
||||||
set {}
|
set {}
|
||||||
|
|
|
@ -254,7 +254,13 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell {
|
||||||
guard let status = mastodonController.persistentContainer.status(for: statusID) else {
|
guard let status = mastodonController.persistentContainer.status(for: statusID) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var str = AttributedString("\(status.account.displayOrUserName), ")
|
var str: AttributedString = ""
|
||||||
|
if let rebloggerID,
|
||||||
|
let reblogger = mastodonController.persistentContainer.account(for: rebloggerID) {
|
||||||
|
str += AttributedString("Reblogged by \(reblogger.displayOrUserName): ")
|
||||||
|
}
|
||||||
|
str += AttributedString(status.account.displayOrUserName)
|
||||||
|
str += ", "
|
||||||
if statusState.collapsed ?? false {
|
if statusState.collapsed ?? false {
|
||||||
if !status.spoilerText.isEmpty {
|
if !status.spoilerText.isEmpty {
|
||||||
str += AttributedString(status.spoilerText)
|
str += AttributedString(status.spoilerText)
|
||||||
|
@ -263,15 +269,24 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell {
|
||||||
str += "collapsed"
|
str += "collapsed"
|
||||||
} else {
|
} else {
|
||||||
str += AttributedString(contentTextView.attributedText)
|
str += AttributedString(contentTextView.attributedText)
|
||||||
|
|
||||||
|
if status.attachments.count > 0 {
|
||||||
|
if status.attachments.count == 1 {
|
||||||
|
let attachment = status.attachments[0]
|
||||||
|
let desc = attachment.description?.isEmpty == false ? attachment.description! : "no description"
|
||||||
|
str += AttributedString(", attachment: \(desc)")
|
||||||
|
} else {
|
||||||
|
for (index, attachment) in status.attachments.enumerated() {
|
||||||
|
let desc = attachment.description?.isEmpty == false ? attachment.description! : "no description"
|
||||||
|
str += AttributedString(", attachment \(index + 1): \(desc)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if status.poll != nil {
|
||||||
|
str += ", poll"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if status.attachments.count > 0 {
|
|
||||||
// TODO: localize me
|
|
||||||
str += AttributedString(", \(status.attachments.count) attachment\(status.attachments.count > 1 ? "s" : "")")
|
|
||||||
}
|
|
||||||
if status.poll != nil {
|
|
||||||
str += ", poll"
|
|
||||||
}
|
|
||||||
str += AttributedString(", \(status.createdAt.formatted(.relative(presentation: .numeric)))")
|
str += AttributedString(", \(status.createdAt.formatted(.relative(presentation: .numeric)))")
|
||||||
if status.visibility < .unlisted {
|
if status.visibility < .unlisted {
|
||||||
str += AttributedString(", \(status.visibility.displayName)")
|
str += AttributedString(", \(status.visibility.displayName)")
|
||||||
|
@ -279,10 +294,6 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell {
|
||||||
if status.localOnly {
|
if status.localOnly {
|
||||||
str += ", local"
|
str += ", local"
|
||||||
}
|
}
|
||||||
if let rebloggerID,
|
|
||||||
let reblogger = mastodonController.persistentContainer.account(for: rebloggerID) {
|
|
||||||
str += AttributedString(", reblogged by \(reblogger.displayOrUserName)")
|
|
||||||
}
|
|
||||||
return NSAttributedString(str)
|
return NSAttributedString(str)
|
||||||
}
|
}
|
||||||
set {}
|
set {}
|
||||||
|
|
Loading…
Reference in New Issue