Compare commits

...

3 Commits

6 changed files with 35 additions and 19 deletions

View File

@ -10,11 +10,11 @@ import Foundation
extension Date {
private static let unitFlags = Set<Calendar.Component>([.second, .minute, .hour, .day, .weekOfYear, .month, .year])
func timeAgo() -> (Int, Calendar.Component) {
let calendar = NSCalendar.current
let unitFlags = Set<Calendar.Component>([.second, .minute, .hour, .day, .weekOfYear, .month, .year])
let components = calendar.dateComponents(unitFlags, from: self, to: Date())
let components = calendar.dateComponents(Date.unitFlags, from: self, to: Date())
if components.year! >= 1 {
return (components.year!, .year)

View File

@ -133,16 +133,15 @@ extension MenuPreviewProvider {
]
}
func actionsForStatus(statusID: String, sourceView: UIView?) -> [UIMenuElement] {
guard let mastodonController = mastodonController,
let status = mastodonController.persistentContainer.status(for: statusID) else { return [] }
func actionsForStatus(_ status: StatusMO, sourceView: UIView?) -> [UIMenuElement] {
guard let mastodonController = mastodonController else { return [] }
guard mastodonController.loggedIn else {
return [
openInSafariAction(url: status.url!),
createAction(identifier: "share", title: "Share...", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in
guard let self = self else { return }
self.navigationDelegate?.showMoreOptions(forStatus: statusID, sourceView: sourceView)
self.navigationDelegate?.showMoreOptions(forStatus: status.id, sourceView: sourceView)
})
]
}
@ -153,11 +152,11 @@ extension MenuPreviewProvider {
var actionsSection = [
createAction(identifier: "reply", title: "Reply", systemImageName: "arrowshape.turn.up.left", handler: { [weak self] (_) in
guard let self = self else { return }
self.navigationDelegate?.compose(inReplyToID: statusID)
self.navigationDelegate?.compose(inReplyToID: status.id)
}),
createAction(identifier: "bookmark", title: bookmarked ? "Unbookmark" : "Bookmark", systemImageName: bookmarked ? "bookmark.fill" : "bookmark", handler: { [weak self] (_) in
guard let self = self else { return }
let request = (bookmarked ? Status.unbookmark : Status.bookmark)(statusID)
let request = (bookmarked ? Status.unbookmark : Status.bookmark)(status.id)
self.mastodonController?.run(request) { (response) in
if case let .success(status, _) = response {
self.mastodonController?.persistentContainer.addOrUpdate(status: status, incrementReferenceCount: false)
@ -166,7 +165,7 @@ extension MenuPreviewProvider {
}),
createAction(identifier: "mute", title: muted ? "Unmute" : "Mute", systemImageName: muted ? "speaker" : "speaker.slash", handler: { [weak self] (_) in
guard let self = self else { return }
let request = (muted ? Status.unmuteConversation : Status.muteConversation)(statusID)
let request = (muted ? Status.unmuteConversation : Status.muteConversation)(status.id)
self.mastodonController?.run(request) { (response) in
if case let .success(status, _) = response {
self.mastodonController?.persistentContainer.addOrUpdate(status: status, incrementReferenceCount: false)
@ -179,7 +178,7 @@ extension MenuPreviewProvider {
let pinned = status.pinned ?? false
actionsSection.append(createAction(identifier: "", title: pinned ? "Unpin" : "Pin", systemImageName: pinned ? "pin.slash" : "pin", handler: { [weak self] (_) in
guard let self = self else { return }
let request = (pinned ? Status.unpin : Status.pin)(statusID)
let request = (pinned ? Status.unpin : Status.pin)(status.id)
self.mastodonController?.run(request, completion: { [weak self] (response) in
guard let self = self else { return }
if case let .success(status, _) = response {
@ -193,7 +192,7 @@ extension MenuPreviewProvider {
openInSafariAction(url: status.url!),
createAction(identifier: "share", title: "Share...", systemImageName: "square.and.arrow.up", handler: { [weak self] (_) in
guard let self = self else { return }
self.navigationDelegate?.showMoreOptions(forStatus: statusID, sourceView: sourceView)
self.navigationDelegate?.showMoreOptions(forStatus: status.id, sourceView: sourceView)
}),
]
@ -203,7 +202,7 @@ extension MenuPreviewProvider {
return
}
// todo: this should try to find an existing session
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: UserActivityManager.showConversationActivity(mainStatusID: statusID, accountID: id), options: nil, errorHandler: nil)
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: UserActivityManager.showConversationActivity(mainStatusID: status.id, accountID: id), options: nil, errorHandler: nil)
}))
#endif

View File

@ -22,6 +22,8 @@ class ContentTextView: LinkTextView {
var defaultFont: UIFont = .systemFont(ofSize: 17)
var defaultColor: UIColor = .label
private(set) var hasEmojis = false
// The link range currently being previewed
private var currentPreviewedLinkRange: NSRange?
// The preview created in the previewForHighlighting method, so that we can use the same one in previewForDismissing.
@ -49,7 +51,11 @@ class ContentTextView: LinkTextView {
// MARK: - Emojis
func setEmojis(_ emojis: [Emoji]) {
guard !emojis.isEmpty else { return }
guard !emojis.isEmpty else {
hasEmojis = false
return
}
hasEmojis = true
let emojiImages = MultiThreadDictionary<String, UIImage>(name: "ContentTextView Emoji Images")

View File

@ -11,6 +11,8 @@ import Pachyderm
class EmojiLabel: UILabel, BaseEmojiLabel {
private(set) var hasEmojis = false
var emojiIdentifier: String?
var emojiRequests: [ImageCache.Request] = []
var emojiFont: UIFont { font }
@ -22,6 +24,7 @@ class EmojiLabel: UILabel, BaseEmojiLabel {
self.emojiIdentifier = identifier
emojiRequests.forEach { $0.cancel() }
emojiRequests = []
hasEmojis = true
replaceEmojis(in: attributedText.string, emojis: emojis, identifier: identifier) { [weak self] (newAttributedText) in
guard let self = self, self.emojiIdentifier == identifier else { return }
@ -35,6 +38,7 @@ class EmojiLabel: UILabel, BaseEmojiLabel {
emojiIdentifier = nil
emojiRequests.forEach { $0.cancel() }
emojiRequests = []
hasEmojis = false
}
}

View File

@ -147,6 +147,7 @@ class BaseStatusTableViewCell: UITableViewCell {
let account = status.account
self.accountID = account.id
updateUI(account: account)
contentTextView.setTextFrom(status: status)
updateGrayscaleableUI(account: account, status: status)
updateUIForPreferences(account: account, status: status)
@ -212,7 +213,7 @@ class BaseStatusTableViewCell: UITableViewCell {
if #available(iOS 14.0, *) {
// keep menu in sync with changed states e.g. bookmarked, muted
moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: actionsForStatus(statusID: statusID, sourceView: moreButton))
moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: actionsForStatus(status, sourceView: moreButton))
}
}
@ -230,7 +231,7 @@ class BaseStatusTableViewCell: UITableViewCell {
func updateUIForPreferences(account: AccountMO, status: StatusMO) {
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: avatarImageView)
attachmentsView.contentHidden = Preferences.shared.blurAllMedia || (mastodonController.persistentContainer.status(for: statusID)?.sensitive ?? false)
attachmentsView.contentHidden = Preferences.shared.blurAllMedia || status.sensitive
updateStatusIconsForPreferences(status)
@ -274,7 +275,9 @@ class BaseStatusTableViewCell: UITableViewCell {
}
}
contentTextView.setTextFrom(status: status)
if contentTextView.hasEmojis {
contentTextView.setTextFrom(status: status)
}
displayNameLabel.updateForAccountDisplayName(account: account)
}

View File

@ -98,6 +98,7 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell {
super.updateGrayscaleableUI(account: account, status: status)
if let rebloggerID = rebloggerID,
reblogLabel.hasEmojis,
let reblogger = mastodonController.persistentContainer.account(for: rebloggerID) {
updateRebloggerLabel(reblogger: reblogger)
}
@ -180,10 +181,13 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell {
}
override func getStatusCellPreviewProviders(for location: CGPoint, sourceViewController: UIViewController) -> BaseStatusTableViewCell.PreviewProviders? {
guard let mastodonController = mastodonController else { return nil }
guard let mastodonController = mastodonController,
let status = mastodonController.persistentContainer.status(for: statusID) else {
return nil
}
return (
content: { ConversationTableViewController(for: self.statusID, state: self.statusState.copy(), mastodonController: mastodonController) },
actions: { self.actionsForStatus(statusID: self.statusID, sourceView: self) }
actions: { self.actionsForStatus(status, sourceView: self) }
)
}