Compare commits
No commits in common. "06442b5629a5d673f57c8f729effc8666c958962" and "24a1e7ceb99d4e9c0b47fe15f806d63d38bbdbb4" have entirely different histories.
06442b5629
...
24a1e7ceb9
|
@ -12,18 +12,12 @@ public class NotificationGroup {
|
||||||
public let notificationIDs: [String]
|
public let notificationIDs: [String]
|
||||||
public let id: String
|
public let id: String
|
||||||
public let kind: Notification.Kind
|
public let kind: Notification.Kind
|
||||||
public let statusState: StatusState?
|
|
||||||
|
|
||||||
init?(notifications: [Notification]) {
|
init?(notifications: [Notification]) {
|
||||||
guard !notifications.isEmpty else { return nil }
|
guard !notifications.isEmpty else { return nil }
|
||||||
self.notificationIDs = notifications.map { $0.id }
|
self.notificationIDs = notifications.map { $0.id }
|
||||||
self.id = notifications.first!.id
|
self.id = notifications.first!.id
|
||||||
self.kind = notifications.first!.kind
|
self.kind = notifications.first!.kind
|
||||||
if kind == .mention {
|
|
||||||
self.statusState = .unknown
|
|
||||||
} else {
|
|
||||||
self.statusState = nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func createGroups(notifications: [Notification], only allowedTypes: [Notification.Kind]) -> [NotificationGroup] {
|
public static func createGroups(notifications: [Notification], only allowedTypes: [Notification.Kind]) -> [NotificationGroup] {
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
//
|
|
||||||
// StatusState.swift
|
|
||||||
// Pachyderm
|
|
||||||
//
|
|
||||||
// Created by Shadowfacts on 11/24/19.
|
|
||||||
// Copyright © 2019 Shadowfacts. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
public class StatusState: Equatable, Hashable {
|
|
||||||
public var collapsible: Bool?
|
|
||||||
public var collapsed: Bool?
|
|
||||||
|
|
||||||
public var unknown: Bool {
|
|
||||||
collapsible == nil || collapsed == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
public init(collapsible: Bool?, collapsed: Bool?) {
|
|
||||||
self.collapsible = collapsible
|
|
||||||
self.collapsed = collapsed
|
|
||||||
}
|
|
||||||
|
|
||||||
public func copy() -> StatusState {
|
|
||||||
return StatusState(collapsible: self.collapsible, collapsed: self.collapsed)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func hash(into hasher: inout Hasher) {
|
|
||||||
hasher.combine(collapsible)
|
|
||||||
hasher.combine(collapsed)
|
|
||||||
}
|
|
||||||
|
|
||||||
public static var unknown: StatusState {
|
|
||||||
StatusState(collapsible: nil, collapsed: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func == (lhs: StatusState, rhs: StatusState) -> Bool {
|
|
||||||
lhs.collapsible == rhs.collapsible && lhs.collapsed == rhs.collapsed
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -90,7 +90,6 @@
|
||||||
D6333B372137838300CE884A /* AttributedString+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B362137838300CE884A /* AttributedString+Helpers.swift */; };
|
D6333B372137838300CE884A /* AttributedString+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B362137838300CE884A /* AttributedString+Helpers.swift */; };
|
||||||
D6333B772138D94E00CE884A /* ComposeMediaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B762138D94E00CE884A /* ComposeMediaView.swift */; };
|
D6333B772138D94E00CE884A /* ComposeMediaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B762138D94E00CE884A /* ComposeMediaView.swift */; };
|
||||||
D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B782139AEFD00CE884A /* Date+TimeAgo.swift */; };
|
D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B782139AEFD00CE884A /* Date+TimeAgo.swift */; };
|
||||||
D63569E023908A8D003DD353 /* StatusState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60A4FFB238B726A008AC647 /* StatusState.swift */; };
|
|
||||||
D63661C02381C144004B9E16 /* PreferencesNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63661BF2381C144004B9E16 /* PreferencesNavigationController.swift */; };
|
D63661C02381C144004B9E16 /* PreferencesNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63661BF2381C144004B9E16 /* PreferencesNavigationController.swift */; };
|
||||||
D640D76922BAF5E6004FBE69 /* DomainBlocks.plist in Resources */ = {isa = PBXBuildFile; fileRef = D640D76822BAF5E6004FBE69 /* DomainBlocks.plist */; };
|
D640D76922BAF5E6004FBE69 /* DomainBlocks.plist in Resources */ = {isa = PBXBuildFile; fileRef = D640D76822BAF5E6004FBE69 /* DomainBlocks.plist */; };
|
||||||
D641C773213CAA25004B4513 /* NotificationsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D641C772213CAA25004B4513 /* NotificationsTableViewController.swift */; };
|
D641C773213CAA25004B4513 /* NotificationsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D641C772213CAA25004B4513 /* NotificationsTableViewController.swift */; };
|
||||||
|
@ -286,7 +285,6 @@
|
||||||
04DACE8D212CC7CC009840C4 /* ImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCache.swift; sourceTree = "<group>"; };
|
04DACE8D212CC7CC009840C4 /* ImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCache.swift; sourceTree = "<group>"; };
|
||||||
04ED00B021481ED800567C53 /* SteppedProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SteppedProgressView.swift; sourceTree = "<group>"; };
|
04ED00B021481ED800567C53 /* SteppedProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SteppedProgressView.swift; sourceTree = "<group>"; };
|
||||||
D6028B9A2150811100F223B9 /* MastodonCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonCache.swift; sourceTree = "<group>"; };
|
D6028B9A2150811100F223B9 /* MastodonCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonCache.swift; sourceTree = "<group>"; };
|
||||||
D60A4FFB238B726A008AC647 /* StatusState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusState.swift; sourceTree = "<group>"; };
|
|
||||||
D60A548B21ED515800F1F87C /* GMImagePicker.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GMImagePicker.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
D60A548B21ED515800F1F87C /* GMImagePicker.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GMImagePicker.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
D60A548D21ED515800F1F87C /* GMImagePicker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GMImagePicker.h; sourceTree = "<group>"; };
|
D60A548D21ED515800F1F87C /* GMImagePicker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GMImagePicker.h; sourceTree = "<group>"; };
|
||||||
D60A548E21ED515800F1F87C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
D60A548E21ED515800F1F87C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
@ -1002,7 +1000,6 @@
|
||||||
D6A3BC7223218C6E00FD64D5 /* Utilities */ = {
|
D6A3BC7223218C6E00FD64D5 /* Utilities */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D60A4FFB238B726A008AC647 /* StatusState.swift */,
|
|
||||||
D6E6F26221603F8B006A8599 /* CharacterCounter.swift */,
|
D6E6F26221603F8B006A8599 /* CharacterCounter.swift */,
|
||||||
D6A3BC7323218C6E00FD64D5 /* TimelineSegment.swift */,
|
D6A3BC7323218C6E00FD64D5 /* TimelineSegment.swift */,
|
||||||
D6A3BC7823218E9200FD64D5 /* NotificationGroup.swift */,
|
D6A3BC7823218E9200FD64D5 /* NotificationGroup.swift */,
|
||||||
|
@ -1537,7 +1534,6 @@
|
||||||
D61099F5214568C300432DC2 /* Notification.swift in Sources */,
|
D61099F5214568C300432DC2 /* Notification.swift in Sources */,
|
||||||
D61099EF214566C000432DC2 /* Instance.swift in Sources */,
|
D61099EF214566C000432DC2 /* Instance.swift in Sources */,
|
||||||
D61099D22144B2E600432DC2 /* Body.swift in Sources */,
|
D61099D22144B2E600432DC2 /* Body.swift in Sources */,
|
||||||
D63569E023908A8D003DD353 /* StatusState.swift in Sources */,
|
|
||||||
D6109A0121456B0800432DC2 /* Hashtag.swift in Sources */,
|
D6109A0121456B0800432DC2 /* Hashtag.swift in Sources */,
|
||||||
D61099FD21456A1D00432DC2 /* SearchResults.swift in Sources */,
|
D61099FD21456A1D00432DC2 /* SearchResults.swift in Sources */,
|
||||||
D61099F12145686D00432DC2 /* List.swift in Sources */,
|
D61099F12145686D00432DC2 /* List.swift in Sources */,
|
||||||
|
|
|
@ -15,9 +15,8 @@ class ConversationTableViewController: EnhancedTableViewController {
|
||||||
static let showPostsImage = UIImage(systemName: "eye.fill")!
|
static let showPostsImage = UIImage(systemName: "eye.fill")!
|
||||||
static let hidePostsImage = UIImage(systemName: "eye.slash.fill")!
|
static let hidePostsImage = UIImage(systemName: "eye.slash.fill")!
|
||||||
|
|
||||||
let mainStatusID: String
|
var mainStatusID: String!
|
||||||
let mainStatusState: StatusState
|
var statusIDs: [String] = [] {
|
||||||
var statuses: [(id: String, state: StatusState)] = [] {
|
|
||||||
didSet {
|
didSet {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.tableView.reloadData()
|
self.tableView.reloadData()
|
||||||
|
@ -28,9 +27,8 @@ class ConversationTableViewController: EnhancedTableViewController {
|
||||||
var showStatusesAutomatically = false
|
var showStatusesAutomatically = false
|
||||||
var visibilityBarButtonItem: UIBarButtonItem!
|
var visibilityBarButtonItem: UIBarButtonItem!
|
||||||
|
|
||||||
init(for mainStatusID: String, state: StatusState = .unknown) {
|
init(for mainStatusID: String) {
|
||||||
self.mainStatusID = mainStatusID
|
self.mainStatusID = mainStatusID
|
||||||
self.mainStatusState = state
|
|
||||||
|
|
||||||
super.init(style: .plain)
|
super.init(style: .plain)
|
||||||
}
|
}
|
||||||
|
@ -53,9 +51,9 @@ class ConversationTableViewController: EnhancedTableViewController {
|
||||||
visibilityBarButtonItem = UIBarButtonItem(image: ConversationTableViewController.showPostsImage, style: .plain, target: self, action: #selector(toggleVisibilityButtonPressed))
|
visibilityBarButtonItem = UIBarButtonItem(image: ConversationTableViewController.showPostsImage, style: .plain, target: self, action: #selector(toggleVisibilityButtonPressed))
|
||||||
navigationItem.rightBarButtonItem = visibilityBarButtonItem
|
navigationItem.rightBarButtonItem = visibilityBarButtonItem
|
||||||
|
|
||||||
statuses = [(mainStatusID, mainStatusState)]
|
statusIDs = [mainStatusID]
|
||||||
|
|
||||||
guard let mainStatus = MastodonCache.status(for: mainStatusID) else { fatalError("Missing cached status \(mainStatusID)") }
|
guard let mainStatus = MastodonCache.status(for: mainStatusID) else { fatalError("Missing cached status \(mainStatusID!)") }
|
||||||
|
|
||||||
let request = Status.getContext(mainStatus)
|
let request = Status.getContext(mainStatus)
|
||||||
MastodonController.client.run(request) { response in
|
MastodonController.client.run(request) { response in
|
||||||
|
@ -63,8 +61,8 @@ class ConversationTableViewController: EnhancedTableViewController {
|
||||||
let parents = self.getDirectParents(of: mainStatus, from: context.ancestors)
|
let parents = self.getDirectParents(of: mainStatus, from: context.ancestors)
|
||||||
MastodonCache.addAll(statuses: parents)
|
MastodonCache.addAll(statuses: parents)
|
||||||
MastodonCache.addAll(statuses: context.descendants)
|
MastodonCache.addAll(statuses: context.descendants)
|
||||||
self.statuses = parents.map { ($0.id, .unknown) } + self.statuses + context.descendants.map { ($0.id, .unknown) }
|
self.statusIDs = parents.map { $0.id } + [self.mainStatusID] + context.descendants.map { $0.id }
|
||||||
let indexPath = IndexPath(row: parents.count, section: 0)
|
let indexPath = IndexPath(row: self.statusIDs.firstIndex(of: self.mainStatusID)!, section: 0)
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.tableView.scrollToRow(at: indexPath, at: .middle, animated: false)
|
self.tableView.scrollToRow(at: indexPath, at: .middle, animated: false)
|
||||||
}
|
}
|
||||||
|
@ -91,30 +89,30 @@ class ConversationTableViewController: EnhancedTableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
return statuses.count
|
return statusIDs.count
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
let (id, state) = statuses[indexPath.row]
|
let statusID = statusIDs[indexPath.row]
|
||||||
|
|
||||||
if id == mainStatusID {
|
if statusID == mainStatusID {
|
||||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: "mainStatusCell", for: indexPath) as? ConversationMainStatusTableViewCell else { fatalError() }
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: "mainStatusCell", for: indexPath) as? ConversationMainStatusTableViewCell else { fatalError() }
|
||||||
cell.selectionStyle = .none
|
cell.selectionStyle = .none
|
||||||
cell.showStatusAutomatically = showStatusesAutomatically
|
cell.showStatusAutomatically = showStatusesAutomatically
|
||||||
cell.updateUI(statusID: id, state: state)
|
cell.updateUI(statusID: statusID)
|
||||||
cell.delegate = self
|
cell.delegate = self
|
||||||
return cell
|
return cell
|
||||||
} else {
|
} else {
|
||||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? TimelineStatusTableViewCell else { fatalError() }
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? TimelineStatusTableViewCell else { fatalError() }
|
||||||
cell.showStatusAutomatically = showStatusesAutomatically
|
cell.showStatusAutomatically = showStatusesAutomatically
|
||||||
cell.updateUI(statusID: id, state: state)
|
cell.updateUI(statusID: statusID)
|
||||||
cell.delegate = self
|
cell.delegate = self
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
|
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
|
||||||
let statusID = statuses[indexPath.row].id
|
let statusID = statusIDs[indexPath.row]
|
||||||
return statusID == mainStatusID ? nil : indexPath
|
return statusID == mainStatusID ? nil : indexPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,20 +131,13 @@ class ConversationTableViewController: EnhancedTableViewController {
|
||||||
@objc func toggleVisibilityButtonPressed() {
|
@objc func toggleVisibilityButtonPressed() {
|
||||||
showStatusesAutomatically = !showStatusesAutomatically
|
showStatusesAutomatically = !showStatusesAutomatically
|
||||||
|
|
||||||
for (_, state) in statuses where state.collapsible == true {
|
|
||||||
state.collapsed = !showStatusesAutomatically
|
|
||||||
}
|
|
||||||
|
|
||||||
for cell in tableView.visibleCells {
|
for cell in tableView.visibleCells {
|
||||||
guard let cell = cell as? BaseStatusTableViewCell,
|
guard let cell = cell as? BaseStatusTableViewCell,
|
||||||
cell.collapsible else { continue }
|
cell.collapsible else { continue }
|
||||||
cell.showStatusAutomatically = showStatusesAutomatically
|
cell.showStatusAutomatically = showStatusesAutomatically
|
||||||
cell.setCollapsed(!showStatusesAutomatically, animated: false)
|
cell.setCollapsed(!showStatusesAutomatically, animated: false)
|
||||||
}
|
}
|
||||||
|
statusCollapsedStateChanged()
|
||||||
// recalculate cell heights
|
|
||||||
tableView.beginUpdates()
|
|
||||||
tableView.endUpdates()
|
|
||||||
|
|
||||||
if showStatusesAutomatically {
|
if showStatusesAutomatically {
|
||||||
visibilityBarButtonItem.image = ConversationTableViewController.hidePostsImage
|
visibilityBarButtonItem.image = ConversationTableViewController.hidePostsImage
|
||||||
|
@ -158,7 +149,7 @@ class ConversationTableViewController: EnhancedTableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ConversationTableViewController: StatusTableViewCellDelegate {
|
extension ConversationTableViewController: StatusTableViewCellDelegate {
|
||||||
func statusCellCollapsedStateChanged(_ cell: BaseStatusTableViewCell) {
|
func statusCollapsedStateChanged() {
|
||||||
// causes the table view to recalculate the cell heights
|
// causes the table view to recalculate the cell heights
|
||||||
tableView.beginUpdates()
|
tableView.beginUpdates()
|
||||||
tableView.endUpdates()
|
tableView.endUpdates()
|
||||||
|
@ -168,7 +159,7 @@ extension ConversationTableViewController: StatusTableViewCellDelegate {
|
||||||
extension ConversationTableViewController: UITableViewDataSourcePrefetching {
|
extension ConversationTableViewController: UITableViewDataSourcePrefetching {
|
||||||
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
|
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
|
||||||
for indexPath in indexPaths {
|
for indexPath in indexPaths {
|
||||||
guard let status = MastodonCache.status(for: statuses[indexPath.row].id) else { continue }
|
guard let status = MastodonCache.status(for: statusIDs[indexPath.row]) else { continue }
|
||||||
ImageCache.avatars.get(status.account.avatar, completion: nil)
|
ImageCache.avatars.get(status.account.avatar, completion: nil)
|
||||||
for attachment in status.attachments {
|
for attachment in status.attachments {
|
||||||
ImageCache.attachments.get(attachment.url, completion: nil)
|
ImageCache.attachments.get(attachment.url, completion: nil)
|
||||||
|
@ -178,7 +169,7 @@ extension ConversationTableViewController: UITableViewDataSourcePrefetching {
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) {
|
func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) {
|
||||||
for indexPath in indexPaths {
|
for indexPath in indexPaths {
|
||||||
guard let status = MastodonCache.status(for: statuses[indexPath.row].id) else { continue }
|
guard let status = MastodonCache.status(for: statusIDs[indexPath.row]) else { continue }
|
||||||
ImageCache.avatars.cancel(status.account.avatar)
|
ImageCache.avatars.cancel(status.account.avatar)
|
||||||
for attachment in status.attachments {
|
for attachment in status.attachments {
|
||||||
ImageCache.attachments.cancel(attachment.url)
|
ImageCache.attachments.cancel(attachment.url)
|
||||||
|
|
|
@ -71,6 +71,16 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate {
|
||||||
modalPresentationStyle = .fullScreen
|
modalPresentationStyle = .fullScreen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init(gifData: Data?, description: String?, sourceFrame: CGRect, sourceCornerRadius: CGFloat, router: AppRouter) {
|
||||||
|
// self.router = router
|
||||||
|
// self.gifData = gifData
|
||||||
|
// self.imageDescription = description
|
||||||
|
// self.originFrame = sourceFrame
|
||||||
|
// self.originCornerRadius = sourceCornerRadius
|
||||||
|
//
|
||||||
|
// super.init(nibName: "LargeImageViewController", bundle: nil)
|
||||||
|
// }
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
required init?(coder aDecoder: NSCoder) {
|
||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
@ -162,9 +172,9 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate {
|
||||||
|
|
||||||
let prevZoomScale = self.prevZoomScale ?? scrollView.minimumZoomScale
|
let prevZoomScale = self.prevZoomScale ?? scrollView.minimumZoomScale
|
||||||
if scrollView.zoomScale <= scrollView.minimumZoomScale {
|
if scrollView.zoomScale <= scrollView.minimumZoomScale {
|
||||||
setControlsVisible(true, animated: true)
|
controlsVisible = true
|
||||||
} else if scrollView.zoomScale > prevZoomScale {
|
} else if scrollView.zoomScale > prevZoomScale {
|
||||||
setControlsVisible(false, animated: true)
|
controlsVisible = false
|
||||||
}
|
}
|
||||||
self.prevZoomScale = scrollView.zoomScale
|
self.prevZoomScale = scrollView.zoomScale
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ class NotificationsTableViewController: EnhancedTableViewController {
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: statusCell, for: indexPath) as? TimelineStatusTableViewCell else {
|
let cell = tableView.dequeueReusableCell(withIdentifier: statusCell, for: indexPath) as? TimelineStatusTableViewCell else {
|
||||||
fatalError()
|
fatalError()
|
||||||
}
|
}
|
||||||
cell.updateUI(statusID: notification.status!.id, state: group.statusState!)
|
cell.updateUI(statusID: notification.status!.id)
|
||||||
cell.delegate = self
|
cell.delegate = self
|
||||||
return cell
|
return cell
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ class NotificationsTableViewController: EnhancedTableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension NotificationsTableViewController: StatusTableViewCellDelegate {
|
extension NotificationsTableViewController: StatusTableViewCellDelegate {
|
||||||
func statusCellCollapsedStateChanged(_ cell: BaseStatusTableViewCell) {
|
func statusCollapsedStateChanged() {
|
||||||
// causes the table view to recalculate the cell heights
|
// causes the table view to recalculate the cell heights
|
||||||
tableView.beginUpdates()
|
tableView.beginUpdates()
|
||||||
tableView.endUpdates()
|
tableView.endUpdates()
|
||||||
|
|
|
@ -22,14 +22,14 @@ class ProfileTableViewController: EnhancedTableViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var pinnedStatuses: [(id: String, state: StatusState)] = [] {
|
var pinnedStatusIDs: [String] = [] {
|
||||||
didSet {
|
didSet {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.tableView.reloadData()
|
self.tableView.reloadData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var timelineSegments: [[(id: String, state: StatusState)]] = [] {
|
var timelineSegments: [TimelineSegment<Status>] = [] {
|
||||||
didSet {
|
didSet {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.tableView.reloadData()
|
self.tableView.reloadData()
|
||||||
|
@ -109,14 +109,14 @@ class ProfileTableViewController: EnhancedTableViewController {
|
||||||
guard case let .success(statuses, _) = response else { fatalError() }
|
guard case let .success(statuses, _) = response else { fatalError() }
|
||||||
|
|
||||||
MastodonCache.addAll(statuses: statuses)
|
MastodonCache.addAll(statuses: statuses)
|
||||||
self.pinnedStatuses = statuses.map { ($0.id, .unknown) }
|
self.pinnedStatusIDs = statuses.map { $0.id }
|
||||||
}
|
}
|
||||||
|
|
||||||
getStatuses() { response in
|
getStatuses() { response in
|
||||||
guard case let .success(statuses, pagination) = response else { fatalError() }
|
guard case let .success(statuses, pagination) = response else { fatalError() }
|
||||||
|
|
||||||
MastodonCache.addAll(statuses: statuses)
|
MastodonCache.addAll(statuses: statuses)
|
||||||
self.timelineSegments.append(statuses.map { ($0.id, .unknown) })
|
self.timelineSegments.append(TimelineSegment(objects: statuses))
|
||||||
|
|
||||||
self.older = pagination?.older
|
self.older = pagination?.older
|
||||||
self.newer = pagination?.newer
|
self.newer = pagination?.newer
|
||||||
|
@ -150,7 +150,7 @@ class ProfileTableViewController: EnhancedTableViewController {
|
||||||
if section == 0 {
|
if section == 0 {
|
||||||
return accountID == nil || MastodonCache.account(for: accountID) == nil ? 0 : 1
|
return accountID == nil || MastodonCache.account(for: accountID) == nil ? 0 : 1
|
||||||
} else if section == 1 {
|
} else if section == 1 {
|
||||||
return pinnedStatuses.count
|
return pinnedStatusIDs.count
|
||||||
} else {
|
} else {
|
||||||
return timelineSegments[section - 2].count
|
return timelineSegments[section - 2].count
|
||||||
}
|
}
|
||||||
|
@ -166,15 +166,15 @@ class ProfileTableViewController: EnhancedTableViewController {
|
||||||
return cell
|
return cell
|
||||||
case 1:
|
case 1:
|
||||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? TimelineStatusTableViewCell else { fatalError() }
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? TimelineStatusTableViewCell else { fatalError() }
|
||||||
let (id, state) = pinnedStatuses[indexPath.row]
|
let statusID = pinnedStatusIDs[indexPath.row]
|
||||||
cell.showPinned = true
|
cell.showPinned = true
|
||||||
cell.updateUI(statusID: id, state: state)
|
cell.updateUI(statusID: statusID)
|
||||||
cell.delegate = self
|
cell.delegate = self
|
||||||
return cell
|
return cell
|
||||||
default:
|
default:
|
||||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? TimelineStatusTableViewCell else { fatalError() }
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? TimelineStatusTableViewCell else { fatalError() }
|
||||||
let (id, state) = timelineSegments[indexPath.section - 2][indexPath.row]
|
let statusID = timelineSegments[indexPath.section - 2][indexPath.row]
|
||||||
cell.updateUI(statusID: id, state: state)
|
cell.updateUI(statusID: statusID)
|
||||||
cell.delegate = self
|
cell.delegate = self
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ class ProfileTableViewController: EnhancedTableViewController {
|
||||||
guard case let .success(newStatuses, pagination) = response else { fatalError() }
|
guard case let .success(newStatuses, pagination) = response else { fatalError() }
|
||||||
|
|
||||||
MastodonCache.addAll(statuses: newStatuses)
|
MastodonCache.addAll(statuses: newStatuses)
|
||||||
self.timelineSegments[indexPath.section - 2].append(contentsOf: newStatuses.map { ($0.id, .unknown) })
|
self.timelineSegments[indexPath.section - 2].append(objects: newStatuses)
|
||||||
|
|
||||||
self.older = pagination?.older
|
self.older = pagination?.older
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ class ProfileTableViewController: EnhancedTableViewController {
|
||||||
guard case let .success(newStatuses, pagination) = response else { fatalError() }
|
guard case let .success(newStatuses, pagination) = response else { fatalError() }
|
||||||
|
|
||||||
MastodonCache.addAll(statuses: newStatuses)
|
MastodonCache.addAll(statuses: newStatuses)
|
||||||
self.timelineSegments[0].insert(contentsOf: newStatuses.map { ($0.id, .unknown) }, at: 0)
|
self.timelineSegments[0].insertAtBeginning(objects: newStatuses)
|
||||||
|
|
||||||
self.newer = pagination?.newer
|
self.newer = pagination?.newer
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ class ProfileTableViewController: EnhancedTableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ProfileTableViewController: StatusTableViewCellDelegate {
|
extension ProfileTableViewController: StatusTableViewCellDelegate {
|
||||||
func statusCellCollapsedStateChanged(_ cell: BaseStatusTableViewCell) {
|
func statusCollapsedStateChanged() {
|
||||||
// causes the table view to recalculate the cell heights
|
// causes the table view to recalculate the cell heights
|
||||||
tableView.beginUpdates()
|
tableView.beginUpdates()
|
||||||
tableView.endUpdates()
|
tableView.endUpdates()
|
||||||
|
@ -270,7 +270,7 @@ extension ProfileTableViewController: ProfileHeaderTableViewCellDelegate {
|
||||||
extension ProfileTableViewController: UITableViewDataSourcePrefetching {
|
extension ProfileTableViewController: UITableViewDataSourcePrefetching {
|
||||||
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
|
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
|
||||||
for indexPath in indexPaths where indexPath.section > 1 {
|
for indexPath in indexPaths where indexPath.section > 1 {
|
||||||
let statusID = timelineSegments[indexPath.section - 2][indexPath.row].id
|
let statusID = timelineSegments[indexPath.section - 2][indexPath.row]
|
||||||
guard let status = MastodonCache.status(for: statusID) else { continue }
|
guard let status = MastodonCache.status(for: statusID) else { continue }
|
||||||
ImageCache.avatars.get(status.account.avatar, completion: nil)
|
ImageCache.avatars.get(status.account.avatar, completion: nil)
|
||||||
for attachment in status.attachments {
|
for attachment in status.attachments {
|
||||||
|
@ -281,7 +281,7 @@ extension ProfileTableViewController: UITableViewDataSourcePrefetching {
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) {
|
func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) {
|
||||||
for indexPath in indexPaths where indexPath.section > 1 {
|
for indexPath in indexPaths where indexPath.section > 1 {
|
||||||
let statusID = timelineSegments[indexPath.section - 2][indexPath.row].id
|
let statusID = timelineSegments[indexPath.section - 2][indexPath.row]
|
||||||
guard let status = MastodonCache.status(for: statusID) else { continue }
|
guard let status = MastodonCache.status(for: statusID) else { continue }
|
||||||
ImageCache.avatars.cancel(status.account.avatar)
|
ImageCache.avatars.cancel(status.account.avatar)
|
||||||
for attachment in status.attachments {
|
for attachment in status.attachments {
|
||||||
|
|
|
@ -54,9 +54,9 @@ class SearchTableViewController: EnhancedTableViewController {
|
||||||
cell.updateUI(hashtag: tag)
|
cell.updateUI(hashtag: tag)
|
||||||
cell.delegate = self
|
cell.delegate = self
|
||||||
return cell
|
return cell
|
||||||
case let .status(id, state):
|
case let .status(id):
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: statusCell, for: indexPath) as! TimelineStatusTableViewCell
|
let cell = tableView.dequeueReusableCell(withIdentifier: statusCell, for: indexPath) as! TimelineStatusTableViewCell
|
||||||
cell.updateUI(statusID: id, state: state)
|
cell.updateUI(statusID: id)
|
||||||
cell.delegate = self
|
cell.delegate = self
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
@ -113,16 +113,16 @@ class SearchTableViewController: EnhancedTableViewController {
|
||||||
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||||
if !results.accounts.isEmpty {
|
if !results.accounts.isEmpty {
|
||||||
snapshot.appendSections([.accounts])
|
snapshot.appendSections([.accounts])
|
||||||
snapshot.appendItems(results.accounts.map { .account($0.id) }, toSection: .accounts)
|
snapshot.appendItems(results.accounts.map { Item.account($0.id) }, toSection: .accounts)
|
||||||
MastodonCache.addAll(accounts: results.accounts)
|
MastodonCache.addAll(accounts: results.accounts)
|
||||||
}
|
}
|
||||||
if !results.hashtags.isEmpty {
|
if !results.hashtags.isEmpty {
|
||||||
snapshot.appendSections([.hashtags])
|
snapshot.appendSections([.hashtags])
|
||||||
snapshot.appendItems(results.hashtags.map { .hashtag($0) }, toSection: .hashtags)
|
snapshot.appendItems(results.hashtags.map { Item.hashtag($0) }, toSection: .hashtags)
|
||||||
}
|
}
|
||||||
if !results.statuses.isEmpty {
|
if !results.statuses.isEmpty {
|
||||||
snapshot.appendSections([.statuses])
|
snapshot.appendSections([.statuses])
|
||||||
snapshot.appendItems(results.statuses.map { .status($0.id, .unknown) }, toSection: .statuses)
|
snapshot.appendItems(results.statuses.map { Item.status($0.id) }, toSection: .statuses)
|
||||||
MastodonCache.addAll(statuses: results.statuses)
|
MastodonCache.addAll(statuses: results.statuses)
|
||||||
MastodonCache.addAll(accounts: results.statuses.map { $0.account })
|
MastodonCache.addAll(accounts: results.statuses.map { $0.account })
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ extension SearchTableViewController {
|
||||||
enum Item: Hashable {
|
enum Item: Hashable {
|
||||||
case account(String)
|
case account(String)
|
||||||
case hashtag(Hashtag)
|
case hashtag(Hashtag)
|
||||||
case status(String, StatusState)
|
case status(String)
|
||||||
}
|
}
|
||||||
|
|
||||||
class DataSource: UITableViewDiffableDataSource<Section, Item> {
|
class DataSource: UITableViewDiffableDataSource<Section, Item> {
|
||||||
|
@ -176,7 +176,7 @@ extension SearchTableViewController: UISearchBarDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SearchTableViewController: StatusTableViewCellDelegate {
|
extension SearchTableViewController: StatusTableViewCellDelegate {
|
||||||
func statusCellCollapsedStateChanged(_ cell: BaseStatusTableViewCell) {
|
func statusCollapsedStateChanged() {
|
||||||
tableView.beginUpdates()
|
tableView.beginUpdates()
|
||||||
tableView.endUpdates()
|
tableView.endUpdates()
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ class StatusActionAccountListTableViewController: EnhancedTableViewController {
|
||||||
|
|
||||||
let actionType: ActionType
|
let actionType: ActionType
|
||||||
let statusID: String
|
let statusID: String
|
||||||
var statusState: StatusState
|
|
||||||
var accountIDs: [String]? {
|
var accountIDs: [String]? {
|
||||||
didSet {
|
didSet {
|
||||||
tableView.reloadData()
|
tableView.reloadData()
|
||||||
|
@ -33,10 +32,9 @@ class StatusActionAccountListTableViewController: EnhancedTableViewController {
|
||||||
- Parameter statusID The ID of the status to show.
|
- Parameter statusID The ID of the status to show.
|
||||||
- Parameter accountIDs The accounts that will be shown. If `nil` is passed, a request will be performed to load the accounts.
|
- Parameter accountIDs The accounts that will be shown. If `nil` is passed, a request will be performed to load the accounts.
|
||||||
*/
|
*/
|
||||||
init(actionType: ActionType, statusID: String, statusState: StatusState, accountIDs: [String]?) {
|
init(actionType: ActionType, statusID: String, accountIDs: [String]?) {
|
||||||
self.actionType = actionType
|
self.actionType = actionType
|
||||||
self.statusID = statusID
|
self.statusID = statusID
|
||||||
self.statusState = statusState
|
|
||||||
self.accountIDs = accountIDs
|
self.accountIDs = accountIDs
|
||||||
|
|
||||||
super.init(style: .grouped)
|
super.init(style: .grouped)
|
||||||
|
@ -111,7 +109,7 @@ class StatusActionAccountListTableViewController: EnhancedTableViewController {
|
||||||
switch indexPath.section {
|
switch indexPath.section {
|
||||||
case 0:
|
case 0:
|
||||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: statusCell, for: indexPath) as? TimelineStatusTableViewCell else { fatalError() }
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: statusCell, for: indexPath) as? TimelineStatusTableViewCell else { fatalError() }
|
||||||
cell.updateUI(statusID: statusID, state: statusState)
|
cell.updateUI(statusID: statusID)
|
||||||
cell.delegate = self
|
cell.delegate = self
|
||||||
return cell
|
return cell
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -137,7 +135,7 @@ class StatusActionAccountListTableViewController: EnhancedTableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension StatusActionAccountListTableViewController: StatusTableViewCellDelegate {
|
extension StatusActionAccountListTableViewController: StatusTableViewCellDelegate {
|
||||||
func statusCellCollapsedStateChanged(_ cell: BaseStatusTableViewCell) {
|
func statusCollapsedStateChanged() {
|
||||||
// causes the table view to recalculate the cell heights
|
// causes the table view to recalculate the cell heights
|
||||||
tableView.beginUpdates()
|
tableView.beginUpdates()
|
||||||
tableView.endUpdates()
|
tableView.endUpdates()
|
||||||
|
|
|
@ -26,7 +26,7 @@ class TimelineTableViewController: EnhancedTableViewController {
|
||||||
|
|
||||||
var timeline: Timeline!
|
var timeline: Timeline!
|
||||||
|
|
||||||
var timelineSegments: [[(id: String, state: StatusState)]] = [] {
|
var timelineSegments: [TimelineSegment<Status>] = [] {
|
||||||
didSet {
|
didSet {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.tableView.reloadData()
|
self.tableView.reloadData()
|
||||||
|
@ -56,7 +56,7 @@ class TimelineTableViewController: EnhancedTableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
func statusID(for indexPath: IndexPath) -> String {
|
func statusID(for indexPath: IndexPath) -> String {
|
||||||
return timelineSegments[indexPath.section][indexPath.row].id
|
return timelineSegments[indexPath.section][indexPath.row]
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
|
@ -74,7 +74,7 @@ class TimelineTableViewController: EnhancedTableViewController {
|
||||||
MastodonController.client.run(request) { response in
|
MastodonController.client.run(request) { response in
|
||||||
guard case let .success(statuses, pagination) = response else { fatalError() }
|
guard case let .success(statuses, pagination) = response else { fatalError() }
|
||||||
MastodonCache.addAll(statuses: statuses)
|
MastodonCache.addAll(statuses: statuses)
|
||||||
self.timelineSegments.insert(statuses.map { ($0.id, .unknown) }, at: 0)
|
self.timelineSegments.insert(TimelineSegment(objects: statuses), at: 0)
|
||||||
self.newer = pagination?.newer
|
self.newer = pagination?.newer
|
||||||
self.older = pagination?.older
|
self.older = pagination?.older
|
||||||
}
|
}
|
||||||
|
@ -94,8 +94,7 @@ class TimelineTableViewController: EnhancedTableViewController {
|
||||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? TimelineStatusTableViewCell else { fatalError() }
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? TimelineStatusTableViewCell else { fatalError() }
|
||||||
|
|
||||||
let (id, state) = timelineSegments[indexPath.section][indexPath.row]
|
cell.updateUI(statusID: statusID(for: indexPath))
|
||||||
cell.updateUI(statusID: id, state: state)
|
|
||||||
cell.delegate = self
|
cell.delegate = self
|
||||||
|
|
||||||
return cell
|
return cell
|
||||||
|
@ -113,7 +112,7 @@ class TimelineTableViewController: EnhancedTableViewController {
|
||||||
guard case let .success(newStatuses, pagination) = response else { fatalError() }
|
guard case let .success(newStatuses, pagination) = response else { fatalError() }
|
||||||
self.older = pagination?.older
|
self.older = pagination?.older
|
||||||
MastodonCache.addAll(statuses: newStatuses)
|
MastodonCache.addAll(statuses: newStatuses)
|
||||||
self.timelineSegments[self.timelineSegments.count - 1].append(contentsOf: newStatuses.map { ($0.id, .unknown) })
|
self.timelineSegments[self.timelineSegments.count - 1].append(objects: newStatuses)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +137,7 @@ class TimelineTableViewController: EnhancedTableViewController {
|
||||||
guard case let .success(newStatuses, pagination) = response else { fatalError() }
|
guard case let .success(newStatuses, pagination) = response else { fatalError() }
|
||||||
self.newer = pagination?.newer
|
self.newer = pagination?.newer
|
||||||
MastodonCache.addAll(statuses: newStatuses)
|
MastodonCache.addAll(statuses: newStatuses)
|
||||||
self.timelineSegments[0].insert(contentsOf: newStatuses.map { ($0.id, .unknown) }, at: 0)
|
self.timelineSegments[0].insertAtBeginning(objects: newStatuses)
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.refreshControl?.endRefreshing()
|
self.refreshControl?.endRefreshing()
|
||||||
|
|
||||||
|
@ -155,7 +154,7 @@ class TimelineTableViewController: EnhancedTableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TimelineTableViewController: StatusTableViewCellDelegate {
|
extension TimelineTableViewController: StatusTableViewCellDelegate {
|
||||||
func statusCellCollapsedStateChanged(_ cell: BaseStatusTableViewCell) {
|
func statusCollapsedStateChanged() {
|
||||||
// causes the table view to recalculate the cell heights
|
// causes the table view to recalculate the cell heights
|
||||||
tableView.beginUpdates()
|
tableView.beginUpdates()
|
||||||
tableView.endUpdates()
|
tableView.endUpdates()
|
||||||
|
|
|
@ -24,8 +24,6 @@ protocol TuskerNavigationDelegate {
|
||||||
|
|
||||||
func selected(status statusID: String)
|
func selected(status statusID: String)
|
||||||
|
|
||||||
func selected(status statusID: String, state: StatusState)
|
|
||||||
|
|
||||||
func compose()
|
func compose()
|
||||||
|
|
||||||
func reply(to statusID: String)
|
func reply(to statusID: String)
|
||||||
|
@ -48,7 +46,7 @@ protocol TuskerNavigationDelegate {
|
||||||
|
|
||||||
func showFollowedByList(accountIDs: [String])
|
func showFollowedByList(accountIDs: [String])
|
||||||
|
|
||||||
func statusActionAccountList(action: StatusActionAccountListTableViewController.ActionType, statusID: String, statusState state: StatusState, accountIDs: [String]?) -> StatusActionAccountListTableViewController
|
func statusActionAccountList(action: StatusActionAccountListTableViewController.ActionType, statusID: String, accountIDs: [String]?) -> StatusActionAccountListTableViewController
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TuskerNavigationDelegate where Self: UIViewController {
|
extension TuskerNavigationDelegate where Self: UIViewController {
|
||||||
|
@ -98,18 +96,13 @@ extension TuskerNavigationDelegate where Self: UIViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
func selected(status statusID: String) {
|
func selected(status statusID: String) {
|
||||||
self.selected(status: statusID, state: .unknown)
|
|
||||||
}
|
|
||||||
|
|
||||||
func selected(status statusID: String, state: StatusState) {
|
|
||||||
// todo: is this necessary? should the conversation main status cell prevent this
|
|
||||||
// don't open if the conversation is the same as the current one
|
// don't open if the conversation is the same as the current one
|
||||||
if let conversationController = self as? ConversationTableViewController,
|
if let conversationController = self as? ConversationTableViewController,
|
||||||
conversationController.mainStatusID == statusID {
|
conversationController.mainStatusID == statusID {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
show(ConversationTableViewController(for: statusID, state: state), sender: self)
|
show(ConversationTableViewController(for: statusID), sender: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
func compose() {
|
func compose() {
|
||||||
|
@ -202,8 +195,8 @@ extension TuskerNavigationDelegate where Self: UIViewController {
|
||||||
show(vc, sender: self)
|
show(vc, sender: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
func statusActionAccountList(action: StatusActionAccountListTableViewController.ActionType, statusID: String, statusState state: StatusState, accountIDs: [String]?) -> StatusActionAccountListTableViewController {
|
func statusActionAccountList(action: StatusActionAccountListTableViewController.ActionType, statusID: String, accountIDs: [String]?) -> StatusActionAccountListTableViewController {
|
||||||
return StatusActionAccountListTableViewController(actionType: action, statusID: statusID, statusState: state, accountIDs: accountIDs)
|
return StatusActionAccountListTableViewController(actionType: action, statusID: statusID, accountIDs: accountIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ class ActionNotificationGroupTableViewCell: UITableViewCell {
|
||||||
default:
|
default:
|
||||||
fatalError()
|
fatalError()
|
||||||
}
|
}
|
||||||
let vc = delegate.statusActionAccountList(action: action, statusID: statusID, statusState: .unknown, accountIDs: accountIDs)
|
let vc = delegate.statusActionAccountList(action: action, statusID: statusID, accountIDs: accountIDs)
|
||||||
delegate.show(vc)
|
delegate.show(vc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ extension ActionNotificationGroupTableViewCell: MenuPreviewProvider {
|
||||||
default:
|
default:
|
||||||
fatalError()
|
fatalError()
|
||||||
}
|
}
|
||||||
return self.delegate?.statusActionAccountList(action: action, statusID: self.statusID, statusState: .unknown, accountIDs: accountIDs)
|
return self.delegate?.statusActionAccountList(action: action, statusID: self.statusID, accountIDs: accountIDs)
|
||||||
}, actions: {
|
}, actions: {
|
||||||
return []
|
return []
|
||||||
})
|
})
|
||||||
|
|
|
@ -11,7 +11,7 @@ import Pachyderm
|
||||||
import Combine
|
import Combine
|
||||||
|
|
||||||
protocol StatusTableViewCellDelegate: TuskerNavigationDelegate {
|
protocol StatusTableViewCellDelegate: TuskerNavigationDelegate {
|
||||||
func statusCellCollapsedStateChanged(_ cell: BaseStatusTableViewCell)
|
func statusCollapsedStateChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
class BaseStatusTableViewCell: UITableViewCell {
|
class BaseStatusTableViewCell: UITableViewCell {
|
||||||
|
@ -48,18 +48,12 @@ class BaseStatusTableViewCell: UITableViewCell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var statusState: StatusState!
|
|
||||||
var collapsible = false {
|
var collapsible = false {
|
||||||
didSet {
|
didSet {
|
||||||
collapseButton.isHidden = !collapsible
|
collapseButton.isHidden = !collapsible
|
||||||
statusState?.collapsible = collapsible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var collapsed = false {
|
|
||||||
didSet {
|
|
||||||
statusState?.collapsed = collapsed
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var collapsed = false
|
||||||
var showStatusAutomatically = false
|
var showStatusAutomatically = false
|
||||||
|
|
||||||
var avatarURL: URL?
|
var avatarURL: URL?
|
||||||
|
@ -105,12 +99,11 @@ class BaseStatusTableViewCell: UITableViewCell {
|
||||||
.sink(receiveValue: updateUI(account:))
|
.sink(receiveValue: updateUI(account:))
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateUI(statusID: String, state: StatusState) {
|
func updateUI(statusID: String) {
|
||||||
guard let status = MastodonCache.status(for: statusID) else {
|
guard let status = MastodonCache.status(for: statusID) else {
|
||||||
fatalError("Missing cached status")
|
fatalError("Missing cached status")
|
||||||
}
|
}
|
||||||
self.statusID = statusID
|
self.statusID = statusID
|
||||||
self.statusState = state
|
|
||||||
|
|
||||||
let account = status.account
|
let account = status.account
|
||||||
self.accountID = account.id
|
self.accountID = account.id
|
||||||
|
@ -126,12 +119,10 @@ class BaseStatusTableViewCell: UITableViewCell {
|
||||||
|
|
||||||
contentLabel.statusID = statusID
|
contentLabel.statusID = statusID
|
||||||
|
|
||||||
contentWarningLabel.text = status.spoilerText
|
|
||||||
contentWarningLabel.isHidden = status.spoilerText.isEmpty
|
|
||||||
|
|
||||||
if state.unknown {
|
|
||||||
collapsible = !status.spoilerText.isEmpty
|
collapsible = !status.spoilerText.isEmpty
|
||||||
var shouldCollapse = collapsible
|
var shouldCollapse = collapsible
|
||||||
|
contentWarningLabel.text = status.spoilerText
|
||||||
|
contentWarningLabel.isHidden = status.spoilerText.isEmpty
|
||||||
if !shouldCollapse,
|
if !shouldCollapse,
|
||||||
let text = contentLabel.text,
|
let text = contentLabel.text,
|
||||||
text.count > 500 {
|
text.count > 500 {
|
||||||
|
@ -142,13 +133,6 @@ class BaseStatusTableViewCell: UITableViewCell {
|
||||||
shouldCollapse = false
|
shouldCollapse = false
|
||||||
}
|
}
|
||||||
setCollapsed(shouldCollapse, animated: false)
|
setCollapsed(shouldCollapse, animated: false)
|
||||||
|
|
||||||
state.collapsible = collapsible
|
|
||||||
state.collapsed = shouldCollapse
|
|
||||||
} else {
|
|
||||||
collapsible = state.collapsible!
|
|
||||||
setCollapsed(state.collapsed!, animated: false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateStatusState(status: Status) {
|
func updateStatusState(status: Status) {
|
||||||
|
@ -198,7 +182,7 @@ class BaseStatusTableViewCell: UITableViewCell {
|
||||||
|
|
||||||
@IBAction func collapseButtonPressed() {
|
@IBAction func collapseButtonPressed() {
|
||||||
setCollapsed(!collapsed, animated: true)
|
setCollapsed(!collapsed, animated: true)
|
||||||
delegate?.statusCellCollapsedStateChanged(self)
|
delegate?.statusCollapsedStateChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
func setCollapsed(_ collapsed: Bool, animated: Bool) {
|
func setCollapsed(_ collapsed: Bool, animated: Bool) {
|
||||||
|
|
|
@ -36,8 +36,8 @@ class ConversationMainStatusTableViewCell: BaseStatusTableViewCell {
|
||||||
accessibilityElements = [profileAccessibilityElement!, contentWarningLabel!, collapseButton!, contentLabel!, totalFavoritesButton!, totalReblogsButton!, timestampAndClientLabel!, replyButton!, favoriteButton!, reblogButton!, moreButton!]
|
accessibilityElements = [profileAccessibilityElement!, contentWarningLabel!, collapseButton!, contentLabel!, totalFavoritesButton!, totalReblogsButton!, timestampAndClientLabel!, replyButton!, favoriteButton!, reblogButton!, moreButton!]
|
||||||
}
|
}
|
||||||
|
|
||||||
override func updateUI(statusID: String, state: StatusState) {
|
override func updateUI(statusID: String) {
|
||||||
super.updateUI(statusID: statusID, state: state)
|
super.updateUI(statusID: statusID)
|
||||||
guard let status = MastodonCache.status(for: statusID) else { fatalError() }
|
guard let status = MastodonCache.status(for: statusID) else { fatalError() }
|
||||||
|
|
||||||
var timestampAndClientText = ConversationMainStatusTableViewCell.dateFormatter.string(from: status.createdAt)
|
var timestampAndClientText = ConversationMainStatusTableViewCell.dateFormatter.string(from: status.createdAt)
|
||||||
|
@ -70,7 +70,7 @@ class ConversationMainStatusTableViewCell: BaseStatusTableViewCell {
|
||||||
@IBAction func totalFavoritesPressed() {
|
@IBAction func totalFavoritesPressed() {
|
||||||
if let delegate = delegate {
|
if let delegate = delegate {
|
||||||
// accounts aren't known, pass nil so the VC will load them
|
// accounts aren't known, pass nil so the VC will load them
|
||||||
let vc = delegate.statusActionAccountList(action: .favorite, statusID: statusID, statusState: statusState.copy(), accountIDs: nil)
|
let vc = delegate.statusActionAccountList(action: .favorite, statusID: statusID, accountIDs: nil)
|
||||||
vc.showInacurateCountWarning = true
|
vc.showInacurateCountWarning = true
|
||||||
delegate.show(vc)
|
delegate.show(vc)
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ class ConversationMainStatusTableViewCell: BaseStatusTableViewCell {
|
||||||
@IBAction func totalReblogsPressed() {
|
@IBAction func totalReblogsPressed() {
|
||||||
if let delegate = delegate {
|
if let delegate = delegate {
|
||||||
// accounts aren't known, pass nil so the VC will load them
|
// accounts aren't known, pass nil so the VC will load them
|
||||||
let vc = delegate.statusActionAccountList(action: .reblog, statusID: statusID, statusState: statusState.copy(), accountIDs: nil)
|
let vc = delegate.statusActionAccountList(action: .reblog, statusID: statusID, accountIDs: nil)
|
||||||
vc.showInacurateCountWarning = true
|
vc.showInacurateCountWarning = true
|
||||||
delegate.show(vc)
|
delegate.show(vc)
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell {
|
||||||
.sink(receiveValue: updateRebloggerLabel(reblogger:))
|
.sink(receiveValue: updateRebloggerLabel(reblogger:))
|
||||||
}
|
}
|
||||||
|
|
||||||
override func updateUI(statusID: String, state: StatusState) {
|
override func updateUI(statusID: String) {
|
||||||
guard var status = MastodonCache.status(for: statusID) else { fatalError("Missing cached status \(statusID)") }
|
guard var status = MastodonCache.status(for: statusID) else { fatalError("Missing cached status \(statusID)") }
|
||||||
|
|
||||||
let realStatusID: String
|
let realStatusID: String
|
||||||
|
@ -66,7 +66,7 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell {
|
||||||
realStatusID = statusID
|
realStatusID = statusID
|
||||||
}
|
}
|
||||||
|
|
||||||
super.updateUI(statusID: realStatusID, state: state)
|
super.updateUI(statusID: realStatusID)
|
||||||
|
|
||||||
updateTimestamp()
|
updateTimestamp()
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell {
|
||||||
super.setSelected(selected, animated: animated)
|
super.setSelected(selected, animated: animated)
|
||||||
|
|
||||||
if selected {
|
if selected {
|
||||||
delegate?.selected(status: statusID, state: statusState.copy())
|
delegate?.selected(status: statusID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell {
|
||||||
|
|
||||||
override func getStatusCellPreviewProviders(for location: CGPoint, sourceViewController: UIViewController) -> BaseStatusTableViewCell.PreviewProviders? {
|
override func getStatusCellPreviewProviders(for location: CGPoint, sourceViewController: UIViewController) -> BaseStatusTableViewCell.PreviewProviders? {
|
||||||
return (
|
return (
|
||||||
content: { ConversationTableViewController(for: self.statusID, state: self.statusState.copy()) },
|
content: { ConversationTableViewController(for: self.statusID) },
|
||||||
actions: { self.actionsForStatus(statusID: self.statusID) }
|
actions: { self.actionsForStatus(statusID: self.statusID) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue