forked from shadowfacts/Tusker
Show expand thread indicator when there are additional replies to an
intermediate post in thread authored by a single person
This commit is contained in:
parent
d3187ce2c4
commit
4a95ccccdb
|
@ -115,9 +115,9 @@ class ConversationTableViewController: EnhancedTableViewController {
|
||||||
|
|
||||||
return cell
|
return cell
|
||||||
|
|
||||||
case let .expandThread(childThreads: childThreads):
|
case let .expandThread(childThreads: childThreads, inline: inline):
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "expandThreadCell", for: indexPath) as! ExpandThreadTableViewCell
|
let cell = tableView.dequeueReusableCell(withIdentifier: "expandThreadCell", for: indexPath) as! ExpandThreadTableViewCell
|
||||||
cell.updateUI(childThreads: childThreads)
|
cell.updateUI(childThreads: childThreads, inline: inline)
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -314,8 +314,10 @@ class ConversationTableViewController: EnhancedTableViewController {
|
||||||
let sameAuthorStatuses = currentNode.children.filter({ $0.status.account.id == node.status.account.id })
|
let sameAuthorStatuses = currentNode.children.filter({ $0.status.account.id == node.status.account.id })
|
||||||
if sameAuthorStatuses.count == 1 {
|
if sameAuthorStatuses.count == 1 {
|
||||||
next = sameAuthorStatuses[0]
|
next = sameAuthorStatuses[0]
|
||||||
|
let nonSameAuthorChildren = currentNode.children.filter { $0.status.id != sameAuthorStatuses[0].status.id }
|
||||||
|
snapshot.appendItems([.expandThread(childThreads: nonSameAuthorChildren, inline: true)])
|
||||||
} else {
|
} else {
|
||||||
snapshot.appendItems([.expandThread(childThreads: currentNode.children)])
|
snapshot.appendItems([.expandThread(childThreads: currentNode.children, inline: false)])
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -399,14 +401,14 @@ extension ConversationTableViewController {
|
||||||
}
|
}
|
||||||
enum Item: Hashable {
|
enum Item: Hashable {
|
||||||
case status(id: String, state: StatusState)
|
case status(id: String, state: StatusState)
|
||||||
case expandThread(childThreads: [ConversationNode])
|
case expandThread(childThreads: [ConversationNode], inline: Bool)
|
||||||
|
|
||||||
static func == (lhs: Item, rhs: Item) -> Bool {
|
static func == (lhs: Item, rhs: Item) -> Bool {
|
||||||
switch (lhs, rhs) {
|
switch (lhs, rhs) {
|
||||||
case let (.status(id: a, state: _), .status(id: b, state: _)):
|
case let (.status(id: a, state: _), .status(id: b, state: _)):
|
||||||
return a == b
|
return a == b
|
||||||
case let (.expandThread(childThreads: a), .expandThread(childThreads: b)):
|
case let (.expandThread(childThreads: a, inline: aInline), .expandThread(childThreads: b, inline: bInline)):
|
||||||
return zip(a, b).allSatisfy { $0.status.id == $1.status.id }
|
return zip(a, b).allSatisfy { $0.status.id == $1.status.id } && aInline == bInline
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -417,9 +419,10 @@ extension ConversationTableViewController {
|
||||||
case let .status(id: id, state: _):
|
case let .status(id: id, state: _):
|
||||||
hasher.combine("status")
|
hasher.combine("status")
|
||||||
hasher.combine(id)
|
hasher.combine(id)
|
||||||
case let .expandThread(childThreads: children):
|
case let .expandThread(childThreads: children, inline: inline):
|
||||||
hasher.combine("expandThread")
|
hasher.combine("expandThread")
|
||||||
hasher.combine(children.map(\.status.id))
|
hasher.combine(children.map(\.status.id))
|
||||||
|
hasher.combine(inline)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,34 +10,49 @@ import UIKit
|
||||||
|
|
||||||
class ExpandThreadTableViewCell: UITableViewCell {
|
class ExpandThreadTableViewCell: UITableViewCell {
|
||||||
|
|
||||||
|
@IBOutlet weak var stackViewLeadingConstraint: NSLayoutConstraint!
|
||||||
@IBOutlet weak var avatarContainerView: UIView!
|
@IBOutlet weak var avatarContainerView: UIView!
|
||||||
@IBOutlet weak var avatarContainerWidthConstraint: NSLayoutConstraint!
|
@IBOutlet weak var avatarContainerWidthConstraint: NSLayoutConstraint!
|
||||||
@IBOutlet weak var replyCountLabel: UILabel!
|
@IBOutlet weak var replyCountLabel: UILabel!
|
||||||
var avatarImageViews: [UIImageView] = []
|
private var threadLinkView: UIView!
|
||||||
|
private var threadLinkViewFullHeightConstraint: NSLayoutConstraint!
|
||||||
|
private var threadLinkViewShortHeightConstraint: NSLayoutConstraint!
|
||||||
|
private var avatarImageViews: [UIImageView] = []
|
||||||
|
|
||||||
private var avatarRequests: [ImageCache.Request] = []
|
private var avatarRequests: [ImageCache.Request] = []
|
||||||
|
|
||||||
override func awakeFromNib() {
|
override func awakeFromNib() {
|
||||||
super.awakeFromNib()
|
super.awakeFromNib()
|
||||||
|
|
||||||
let prevThreadLinkView = UIView()
|
threadLinkView = UIView()
|
||||||
prevThreadLinkView.translatesAutoresizingMaskIntoConstraints = false
|
threadLinkView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
prevThreadLinkView.backgroundColor = tintColor.withAlphaComponent(0.5)
|
threadLinkView.backgroundColor = tintColor.withAlphaComponent(0.5)
|
||||||
prevThreadLinkView.layer.cornerRadius = 2.5
|
threadLinkView.layer.cornerRadius = 2.5
|
||||||
prevThreadLinkView.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
|
addSubview(threadLinkView)
|
||||||
contentView.addSubview(prevThreadLinkView)
|
threadLinkViewFullHeightConstraint = threadLinkView.bottomAnchor.constraint(equalTo: bottomAnchor)
|
||||||
|
threadLinkViewShortHeightConstraint = threadLinkView.bottomAnchor.constraint(equalTo: avatarContainerView.topAnchor, constant: -2)
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
prevThreadLinkView.widthAnchor.constraint(equalToConstant: 5),
|
threadLinkView.widthAnchor.constraint(equalToConstant: 5),
|
||||||
prevThreadLinkView.centerXAnchor.constraint(equalTo: leadingAnchor, constant: 16 + 25),
|
threadLinkView.centerXAnchor.constraint(equalTo: leadingAnchor, constant: 25 + 16 /* system spacing */),
|
||||||
prevThreadLinkView.topAnchor.constraint(equalTo: topAnchor),
|
threadLinkView.topAnchor.constraint(equalTo: topAnchor),
|
||||||
prevThreadLinkView.bottomAnchor.constraint(equalTo: avatarContainerView.topAnchor, constant: -2),
|
threadLinkViewFullHeightConstraint,
|
||||||
])
|
])
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateUI(childThreads: [ConversationNode]) {
|
func updateUI(childThreads: [ConversationNode], inline: Bool) {
|
||||||
let format = NSLocalizedString("expand threads count", comment: "expand conversation threads button label")
|
stackViewLeadingConstraint.constant = inline ? 50 + 4 : 0
|
||||||
|
threadLinkView.layer.maskedCorners = inline ? [] : [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
|
||||||
|
threadLinkViewFullHeightConstraint.isActive = inline
|
||||||
|
threadLinkViewShortHeightConstraint.isActive = !inline
|
||||||
|
|
||||||
|
let format: String
|
||||||
|
if inline {
|
||||||
|
format = NSLocalizedString("expand threads inline count", comment: "expnad converstaion threads inline button label")
|
||||||
|
} else {
|
||||||
|
format = NSLocalizedString("expand threads count", comment: "expand conversation threads button label")
|
||||||
|
}
|
||||||
replyCountLabel.text = String.localizedStringWithFormat(format, childThreads.count)
|
replyCountLabel.text = String.localizedStringWithFormat(format, childThreads.count)
|
||||||
|
|
||||||
let accounts = childThreads.map(\.status.account).uniques().prefix(3)
|
let accounts = childThreads.map(\.status.account).uniques().prefix(3)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="iOS"/>
|
<deployment identifier="iOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
@ -62,6 +62,7 @@
|
||||||
<outlet property="avatarContainerView" destination="eFB-F1-d3A" id="xGo-40-nn7"/>
|
<outlet property="avatarContainerView" destination="eFB-F1-d3A" id="xGo-40-nn7"/>
|
||||||
<outlet property="avatarContainerWidthConstraint" destination="tiI-Rj-gjh" id="34n-ev-EKi"/>
|
<outlet property="avatarContainerWidthConstraint" destination="tiI-Rj-gjh" id="34n-ev-EKi"/>
|
||||||
<outlet property="replyCountLabel" destination="Dcm-ll-GeE" id="E4m-xk-DiQ"/>
|
<outlet property="replyCountLabel" destination="Dcm-ll-GeE" id="E4m-xk-DiQ"/>
|
||||||
|
<outlet property="stackViewLeadingConstraint" destination="iD5-Av-ORS" id="Try-cG-8uA"/>
|
||||||
</connections>
|
</connections>
|
||||||
<point key="canvasLocation" x="132" y="132"/>
|
<point key="canvasLocation" x="132" y="132"/>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
|
|
|
@ -61,6 +61,22 @@
|
||||||
<string>%u replies</string>
|
<string>%u replies</string>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>expand threads inline count</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSStringLocalizedFormatKey</key>
|
||||||
|
<string>%#@replies@</string>
|
||||||
|
<key>replies</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSStringFormatSpecTypeKey</key>
|
||||||
|
<string>NSStringPluralRuleType</string>
|
||||||
|
<key>NSStringFormatValueTypeKey</key>
|
||||||
|
<string>u</string>
|
||||||
|
<key>one</key>
|
||||||
|
<string>1 more reply</string>
|
||||||
|
<key>other</key>
|
||||||
|
<string>%u more replies</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
<key>favorites count</key>
|
<key>favorites count</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSStringLocalizedFormatKey</key>
|
<key>NSStringLocalizedFormatKey</key>
|
||||||
|
|
Loading…
Reference in New Issue