Add button to conversation table view to collapse/expand all posts
This needs a refactor once StatusTableViewCell and ConversationMainStatusTableViewCell are merged. See #54
This commit is contained in:
parent
da6ff67a51
commit
8fb3b211b6
|
@ -28,6 +28,7 @@
|
||||||
D60A548F21ED515800F1F87C /* GMImagePicker.h in Headers */ = {isa = PBXBuildFile; fileRef = D60A548D21ED515800F1F87C /* GMImagePicker.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
D60A548F21ED515800F1F87C /* GMImagePicker.h in Headers */ = {isa = PBXBuildFile; fileRef = D60A548D21ED515800F1F87C /* GMImagePicker.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
D60A549221ED515800F1F87C /* GMImagePicker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D60A548B21ED515800F1F87C /* GMImagePicker.framework */; };
|
D60A549221ED515800F1F87C /* GMImagePicker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D60A548B21ED515800F1F87C /* GMImagePicker.framework */; };
|
||||||
D60A549321ED515800F1F87C /* GMImagePicker.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D60A548B21ED515800F1F87C /* GMImagePicker.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
D60A549321ED515800F1F87C /* GMImagePicker.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D60A548B21ED515800F1F87C /* GMImagePicker.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
|
D60BAFB82383921D00EED893 /* StatusCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60BAFB72383921D00EED893 /* StatusCell.swift */; };
|
||||||
D60C07E421E8176B0057FAA8 /* ComposeMediaView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D60C07E321E8176B0057FAA8 /* ComposeMediaView.xib */; };
|
D60C07E421E8176B0057FAA8 /* ComposeMediaView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D60C07E321E8176B0057FAA8 /* ComposeMediaView.xib */; };
|
||||||
D61099B42144B0CC00432DC2 /* Pachyderm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D61099AB2144B0CC00432DC2 /* Pachyderm.framework */; };
|
D61099B42144B0CC00432DC2 /* Pachyderm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D61099AB2144B0CC00432DC2 /* Pachyderm.framework */; };
|
||||||
D61099BB2144B0CC00432DC2 /* PachydermTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61099BA2144B0CC00432DC2 /* PachydermTests.swift */; };
|
D61099BB2144B0CC00432DC2 /* PachydermTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61099BA2144B0CC00432DC2 /* PachydermTests.swift */; };
|
||||||
|
@ -287,6 +288,7 @@
|
||||||
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>"; };
|
||||||
|
D60BAFB72383921D00EED893 /* StatusCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusCell.swift; sourceTree = "<group>"; };
|
||||||
D60C07E321E8176B0057FAA8 /* ComposeMediaView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ComposeMediaView.xib; sourceTree = "<group>"; };
|
D60C07E321E8176B0057FAA8 /* ComposeMediaView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ComposeMediaView.xib; sourceTree = "<group>"; };
|
||||||
D61099AB2144B0CC00432DC2 /* Pachyderm.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pachyderm.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
D61099AB2144B0CC00432DC2 /* Pachyderm.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pachyderm.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
D61099AD2144B0CC00432DC2 /* Pachyderm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Pachyderm.h; sourceTree = "<group>"; };
|
D61099AD2144B0CC00432DC2 /* Pachyderm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Pachyderm.h; sourceTree = "<group>"; };
|
||||||
|
@ -831,6 +833,7 @@
|
||||||
D6BED173212667E900F02DA0 /* StatusTableViewCell.swift */,
|
D6BED173212667E900F02DA0 /* StatusTableViewCell.swift */,
|
||||||
D663625C2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib */,
|
D663625C2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib */,
|
||||||
D663625E2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift */,
|
D663625E2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift */,
|
||||||
|
D60BAFB72383921D00EED893 /* StatusCell.swift */,
|
||||||
);
|
);
|
||||||
path = Status;
|
path = Status;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1597,6 +1600,7 @@
|
||||||
D679C09F215850EF00DA27FE /* XCBActions.swift in Sources */,
|
D679C09F215850EF00DA27FE /* XCBActions.swift in Sources */,
|
||||||
D6DD353F22F502EC00A9563A /* Preferences+Notification.swift in Sources */,
|
D6DD353F22F502EC00A9563A /* Preferences+Notification.swift in Sources */,
|
||||||
D63661C02381C144004B9E16 /* PreferencesNavigationController.swift in Sources */,
|
D63661C02381C144004B9E16 /* PreferencesNavigationController.swift in Sources */,
|
||||||
|
D60BAFB82383921D00EED893 /* StatusCell.swift in Sources */,
|
||||||
D6AEBB4523216AF800E5038B /* FollowAccountActivity.swift in Sources */,
|
D6AEBB4523216AF800E5038B /* FollowAccountActivity.swift in Sources */,
|
||||||
D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */,
|
D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */,
|
||||||
D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */,
|
D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */,
|
||||||
|
|
|
@ -12,6 +12,9 @@ import Pachyderm
|
||||||
|
|
||||||
class ConversationTableViewController: EnhancedTableViewController {
|
class ConversationTableViewController: EnhancedTableViewController {
|
||||||
|
|
||||||
|
static let showPostsImage = UIImage(systemName: "eye.fill")!
|
||||||
|
static let hidePostsImage = UIImage(systemName: "eye.slash.fill")!
|
||||||
|
|
||||||
var mainStatusID: String!
|
var mainStatusID: String!
|
||||||
var statusIDs: [String] = [] {
|
var statusIDs: [String] = [] {
|
||||||
didSet {
|
didSet {
|
||||||
|
@ -21,6 +24,9 @@ class ConversationTableViewController: EnhancedTableViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var showStatusesAutomatically = false
|
||||||
|
var visibilityBarButtonItem: UIBarButtonItem!
|
||||||
|
|
||||||
init(for mainStatusID: String) {
|
init(for mainStatusID: String) {
|
||||||
self.mainStatusID = mainStatusID
|
self.mainStatusID = mainStatusID
|
||||||
|
|
||||||
|
@ -42,6 +48,9 @@ class ConversationTableViewController: EnhancedTableViewController {
|
||||||
|
|
||||||
tableView.prefetchDataSource = self
|
tableView.prefetchDataSource = self
|
||||||
|
|
||||||
|
visibilityBarButtonItem = UIBarButtonItem(image: ConversationTableViewController.showPostsImage, style: .plain, target: self, action: #selector(toggleVisibilityButtonPressed))
|
||||||
|
navigationItem.rightBarButtonItem = visibilityBarButtonItem
|
||||||
|
|
||||||
statusIDs = [mainStatusID]
|
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!)") }
|
||||||
|
@ -89,11 +98,13 @@ class ConversationTableViewController: EnhancedTableViewController {
|
||||||
if statusID == 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.updateUI(statusID: statusID)
|
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? StatusTableViewCell else { fatalError() }
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? StatusTableViewCell else { fatalError() }
|
||||||
|
cell.showStatusAutomatically = showStatusesAutomatically
|
||||||
cell.updateUI(statusID: statusID)
|
cell.updateUI(statusID: statusID)
|
||||||
cell.delegate = self
|
cell.delegate = self
|
||||||
return cell
|
return cell
|
||||||
|
@ -116,6 +127,24 @@ class ConversationTableViewController: EnhancedTableViewController {
|
||||||
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
|
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
|
||||||
return (tableView.cellForRow(at: indexPath) as? TableViewSwipeActionProvider)?.trailingSwipeActionsConfiguration()
|
return (tableView.cellForRow(at: indexPath) as? TableViewSwipeActionProvider)?.trailingSwipeActionsConfiguration()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func toggleVisibilityButtonPressed() {
|
||||||
|
showStatusesAutomatically = !showStatusesAutomatically
|
||||||
|
|
||||||
|
for cell in tableView.visibleCells {
|
||||||
|
guard var cell = cell as? UITableViewCell & StatusCell,
|
||||||
|
cell.collapsible else { continue }
|
||||||
|
cell.showStatusAutomatically = showStatusesAutomatically
|
||||||
|
cell.setCollapsed(!showStatusesAutomatically, animated: false)
|
||||||
|
}
|
||||||
|
statusCollapsedStateChanged()
|
||||||
|
|
||||||
|
if showStatusesAutomatically {
|
||||||
|
visibilityBarButtonItem.image = ConversationTableViewController.hidePostsImage
|
||||||
|
} else {
|
||||||
|
visibilityBarButtonItem.image = ConversationTableViewController.showPostsImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import UIKit
|
||||||
import Combine
|
import Combine
|
||||||
import Pachyderm
|
import Pachyderm
|
||||||
|
|
||||||
class ConversationMainStatusTableViewCell: UITableViewCell {
|
class ConversationMainStatusTableViewCell: UITableViewCell, StatusCell {
|
||||||
|
|
||||||
static let dateFormatter: DateFormatter = {
|
static let dateFormatter: DateFormatter = {
|
||||||
let formatter = DateFormatter()
|
let formatter = DateFormatter()
|
||||||
|
@ -69,6 +69,8 @@ class ConversationMainStatusTableViewCell: UITableViewCell {
|
||||||
}
|
}
|
||||||
var collapsed = false
|
var collapsed = false
|
||||||
|
|
||||||
|
var showStatusAutomatically = false
|
||||||
|
|
||||||
var avatarURL: URL?
|
var avatarURL: URL?
|
||||||
|
|
||||||
var statusUpdater: Cancellable?
|
var statusUpdater: Cancellable?
|
||||||
|
@ -136,9 +138,15 @@ class ConversationMainStatusTableViewCell: UITableViewCell {
|
||||||
contentLabel.statusID = statusID
|
contentLabel.statusID = statusID
|
||||||
|
|
||||||
collapsible = !status.spoilerText.isEmpty
|
collapsible = !status.spoilerText.isEmpty
|
||||||
setCollapsed(collapsible, animated: false)
|
var shouldCollapse = collapsible
|
||||||
contentWarningLabel.text = status.spoilerText
|
contentWarningLabel.text = status.spoilerText
|
||||||
contentWarningLabel.isHidden = status.spoilerText.isEmpty
|
contentWarningLabel.isHidden = status.spoilerText.isEmpty
|
||||||
|
|
||||||
|
if collapsible && showStatusAutomatically {
|
||||||
|
shouldCollapse = false
|
||||||
|
}
|
||||||
|
|
||||||
|
setCollapsed(shouldCollapse, animated: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateStatusState(status: Status) {
|
private func updateStatusState(status: Status) {
|
||||||
|
@ -189,6 +197,7 @@ class ConversationMainStatusTableViewCell: UITableViewCell {
|
||||||
ImageCache.avatars.cancel(url)
|
ImageCache.avatars.cancel(url)
|
||||||
}
|
}
|
||||||
attachmentsView.subviews.forEach { $0.removeFromSuperview() }
|
attachmentsView.subviews.forEach { $0.removeFromSuperview() }
|
||||||
|
showStatusAutomatically = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func accountPressed() {
|
@objc func accountPressed() {
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
//
|
||||||
|
// StatusCell.swift
|
||||||
|
// Tusker
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 11/18/19.
|
||||||
|
// Copyright © 2019 Shadowfacts. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
protocol StatusCell {
|
||||||
|
var collapsible: Bool { get }
|
||||||
|
var showStatusAutomatically: Bool { get set }
|
||||||
|
|
||||||
|
func setCollapsed(_ collapsed: Bool, animated: Bool)
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ protocol StatusTableViewCellDelegate: TuskerNavigationDelegate {
|
||||||
func statusCollapsedStateChanged()
|
func statusCollapsedStateChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
class StatusTableViewCell: UITableViewCell {
|
class StatusTableViewCell: UITableViewCell, StatusCell {
|
||||||
|
|
||||||
static let relativeDateFormatter: RelativeDateTimeFormatter = {
|
static let relativeDateFormatter: RelativeDateTimeFormatter = {
|
||||||
let formatter = RelativeDateTimeFormatter()
|
let formatter = RelativeDateTimeFormatter()
|
||||||
|
@ -68,6 +68,8 @@ class StatusTableViewCell: UITableViewCell {
|
||||||
}
|
}
|
||||||
var collapsed = false
|
var collapsed = false
|
||||||
|
|
||||||
|
var showStatusAutomatically = false
|
||||||
|
|
||||||
var avatarURL: URL?
|
var avatarURL: URL?
|
||||||
var updateTimestampWorkItem: DispatchWorkItem?
|
var updateTimestampWorkItem: DispatchWorkItem?
|
||||||
var attachmentDataTasks: [URLSessionDataTask] = []
|
var attachmentDataTasks: [URLSessionDataTask] = []
|
||||||
|
@ -149,17 +151,23 @@ class StatusTableViewCell: UITableViewCell {
|
||||||
contentLabel.statusID = status.id
|
contentLabel.statusID = status.id
|
||||||
|
|
||||||
collapsible = !status.spoilerText.isEmpty
|
collapsible = !status.spoilerText.isEmpty
|
||||||
setCollapsed(collapsible, animated: false)
|
var shouldCollapse = collapsible
|
||||||
contentWarningLabel.text = status.spoilerText
|
contentWarningLabel.text = status.spoilerText
|
||||||
contentWarningLabel.isHidden = status.spoilerText.isEmpty
|
contentWarningLabel.isHidden = status.spoilerText.isEmpty
|
||||||
|
|
||||||
if !collapsed,
|
if !shouldCollapse,
|
||||||
let text = contentLabel.text,
|
let text = contentLabel.text,
|
||||||
text.count > 500 {
|
text.count > 500 {
|
||||||
collapsible = true
|
collapsible = true
|
||||||
setCollapsed(true, animated: false)
|
shouldCollapse = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if collapsible && showStatusAutomatically {
|
||||||
|
shouldCollapse = false
|
||||||
|
}
|
||||||
|
|
||||||
|
setCollapsed(shouldCollapse, animated: false)
|
||||||
|
|
||||||
let pinned = status.pinned ?? false
|
let pinned = status.pinned ?? false
|
||||||
pinImageView.isHidden = !(pinned && showPinned)
|
pinImageView.isHidden = !(pinned && showPinned)
|
||||||
timestampLabel.isHidden = !pinImageView.isHidden
|
timestampLabel.isHidden = !pinImageView.isHidden
|
||||||
|
@ -240,6 +248,7 @@ class StatusTableViewCell: UITableViewCell {
|
||||||
updateTimestampWorkItem?.cancel()
|
updateTimestampWorkItem?.cancel()
|
||||||
updateTimestampWorkItem = nil
|
updateTimestampWorkItem = nil
|
||||||
attachmentsView.attachmentViews.allObjects.forEach { $0.removeFromSuperview() }
|
attachmentsView.attachmentViews.allObjects.forEach { $0.removeFromSuperview() }
|
||||||
|
showStatusAutomatically = false
|
||||||
showPinned = false
|
showPinned = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue