chore: update status timeline margin
This commit is contained in:
parent
b52f969c05
commit
a1b9ac8394
|
@ -482,7 +482,6 @@
|
||||||
DBB45B5627B39FC9002DC5A7 /* MediaPreviewVideoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B5527B39FC9002DC5A7 /* MediaPreviewVideoViewController.swift */; };
|
DBB45B5627B39FC9002DC5A7 /* MediaPreviewVideoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B5527B39FC9002DC5A7 /* MediaPreviewVideoViewController.swift */; };
|
||||||
DBB45B5927B39FE4002DC5A7 /* MediaPreviewVideoViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B5827B39FE4002DC5A7 /* MediaPreviewVideoViewModel.swift */; };
|
DBB45B5927B39FE4002DC5A7 /* MediaPreviewVideoViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B5827B39FE4002DC5A7 /* MediaPreviewVideoViewModel.swift */; };
|
||||||
DBB45B5B27B3A109002DC5A7 /* MediaPreviewTransitionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B5A27B3A109002DC5A7 /* MediaPreviewTransitionViewController.swift */; };
|
DBB45B5B27B3A109002DC5A7 /* MediaPreviewTransitionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B5A27B3A109002DC5A7 /* MediaPreviewTransitionViewController.swift */; };
|
||||||
DBB45B5E27B4EB22002DC5A7 /* AdaptiveMarginStatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B5D27B4EB22002DC5A7 /* AdaptiveMarginStatusTableViewCell.swift */; };
|
|
||||||
DBB45B6027B50A4F002DC5A7 /* RecommendAccountItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B5F27B50A4F002DC5A7 /* RecommendAccountItem.swift */; };
|
DBB45B6027B50A4F002DC5A7 /* RecommendAccountItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B5F27B50A4F002DC5A7 /* RecommendAccountItem.swift */; };
|
||||||
DBB45B6227B51112002DC5A7 /* SuggestionAccountViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B6127B51112002DC5A7 /* SuggestionAccountViewModel+Diffable.swift */; };
|
DBB45B6227B51112002DC5A7 /* SuggestionAccountViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB45B6127B51112002DC5A7 /* SuggestionAccountViewModel+Diffable.swift */; };
|
||||||
DBB525082611EAC0002F1F29 /* Tabman in Frameworks */ = {isa = PBXBuildFile; productRef = DBB525072611EAC0002F1F29 /* Tabman */; };
|
DBB525082611EAC0002F1F29 /* Tabman in Frameworks */ = {isa = PBXBuildFile; productRef = DBB525072611EAC0002F1F29 /* Tabman */; };
|
||||||
|
@ -1230,7 +1229,6 @@
|
||||||
DBB45B5527B39FC9002DC5A7 /* MediaPreviewVideoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPreviewVideoViewController.swift; sourceTree = "<group>"; };
|
DBB45B5527B39FC9002DC5A7 /* MediaPreviewVideoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPreviewVideoViewController.swift; sourceTree = "<group>"; };
|
||||||
DBB45B5827B39FE4002DC5A7 /* MediaPreviewVideoViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPreviewVideoViewModel.swift; sourceTree = "<group>"; };
|
DBB45B5827B39FE4002DC5A7 /* MediaPreviewVideoViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPreviewVideoViewModel.swift; sourceTree = "<group>"; };
|
||||||
DBB45B5A27B3A109002DC5A7 /* MediaPreviewTransitionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPreviewTransitionViewController.swift; sourceTree = "<group>"; };
|
DBB45B5A27B3A109002DC5A7 /* MediaPreviewTransitionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPreviewTransitionViewController.swift; sourceTree = "<group>"; };
|
||||||
DBB45B5D27B4EB22002DC5A7 /* AdaptiveMarginStatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdaptiveMarginStatusTableViewCell.swift; sourceTree = "<group>"; };
|
|
||||||
DBB45B5F27B50A4F002DC5A7 /* RecommendAccountItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendAccountItem.swift; sourceTree = "<group>"; };
|
DBB45B5F27B50A4F002DC5A7 /* RecommendAccountItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendAccountItem.swift; sourceTree = "<group>"; };
|
||||||
DBB45B6127B51112002DC5A7 /* SuggestionAccountViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SuggestionAccountViewModel+Diffable.swift"; sourceTree = "<group>"; };
|
DBB45B6127B51112002DC5A7 /* SuggestionAccountViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SuggestionAccountViewModel+Diffable.swift"; sourceTree = "<group>"; };
|
||||||
DBB5250D2611EBAF002F1F29 /* ProfileSegmentedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileSegmentedViewController.swift; sourceTree = "<group>"; };
|
DBB5250D2611EBAF002F1F29 /* ProfileSegmentedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileSegmentedViewController.swift; sourceTree = "<group>"; };
|
||||||
|
@ -1745,7 +1743,6 @@
|
||||||
DBE3CDBA261C427900430CC6 /* TimelineHeaderTableViewCell.swift */,
|
DBE3CDBA261C427900430CC6 /* TimelineHeaderTableViewCell.swift */,
|
||||||
DB6B750327300B4000C70B6E /* TimelineFooterTableViewCell.swift */,
|
DB6B750327300B4000C70B6E /* TimelineFooterTableViewCell.swift */,
|
||||||
DB02CDAA26256A9500D0A2AF /* ThreadReplyLoaderTableViewCell.swift */,
|
DB02CDAA26256A9500D0A2AF /* ThreadReplyLoaderTableViewCell.swift */,
|
||||||
DBB45B5D27B4EB22002DC5A7 /* AdaptiveMarginStatusTableViewCell.swift */,
|
|
||||||
);
|
);
|
||||||
path = TableviewCell;
|
path = TableviewCell;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -3841,7 +3838,6 @@
|
||||||
DBA465952696E387002B41DB /* AppPreference.swift in Sources */,
|
DBA465952696E387002B41DB /* AppPreference.swift in Sources */,
|
||||||
2D8434F525FF465D00EECE90 /* HomeTimelineNavigationBarTitleViewModel.swift in Sources */,
|
2D8434F525FF465D00EECE90 /* HomeTimelineNavigationBarTitleViewModel.swift in Sources */,
|
||||||
DB938F0F2624119800E5B6C1 /* ThreadViewModel+LoadThreadState.swift in Sources */,
|
DB938F0F2624119800E5B6C1 /* ThreadViewModel+LoadThreadState.swift in Sources */,
|
||||||
DBB45B5E27B4EB22002DC5A7 /* AdaptiveMarginStatusTableViewCell.swift in Sources */,
|
|
||||||
DB6180F226391CF40018D199 /* MediaPreviewImageViewModel.swift in Sources */,
|
DB6180F226391CF40018D199 /* MediaPreviewImageViewModel.swift in Sources */,
|
||||||
DBA5E7A3263AD0A3004598BB /* PhotoLibraryService.swift in Sources */,
|
DBA5E7A3263AD0A3004598BB /* PhotoLibraryService.swift in Sources */,
|
||||||
DBD5B1F627BCD3D200BD6B38 /* SuggestionAccountTableViewCell+ViewModel.swift in Sources */,
|
DBD5B1F627BCD3D200BD6B38 /* SuggestionAccountTableViewCell+ViewModel.swift in Sources */,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<key>AppShared.xcscheme_^#shared#^_</key>
|
<key>AppShared.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>29</integer>
|
<integer>19</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>CoreDataStack.xcscheme_^#shared#^_</key>
|
<key>CoreDataStack.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
|
@ -97,7 +97,7 @@
|
||||||
<key>MastodonIntent.xcscheme_^#shared#^_</key>
|
<key>MastodonIntent.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>28</integer>
|
<integer>20</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>MastodonIntents.xcscheme_^#shared#^_</key>
|
<key>MastodonIntents.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
|
@ -117,7 +117,7 @@
|
||||||
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
|
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>30</integer>
|
<integer>18</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>SuppressBuildableAutocreation</key>
|
<key>SuppressBuildableAutocreation</key>
|
||||||
|
|
|
@ -36,7 +36,7 @@ extension NotificationTableViewCell {
|
||||||
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): did layout for new cell")
|
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): did layout for new cell")
|
||||||
|
|
||||||
notificationView.statusView.frame.size.width = tableView.frame.width - containerViewHorizontalMargin
|
notificationView.statusView.frame.size.width = tableView.frame.width - containerViewHorizontalMargin
|
||||||
notificationView.quoteStatusView.frame.size.width = tableView.frame.width - StatusView.containerLayoutMargin.left - StatusView.containerLayoutMargin.right - containerViewHorizontalMargin
|
notificationView.quoteStatusView.frame.size.width = tableView.frame.width - 2 * StatusView.containerLayoutMargin - containerViewHorizontalMargin
|
||||||
}
|
}
|
||||||
|
|
||||||
switch viewModel.value {
|
switch viewModel.value {
|
||||||
|
|
|
@ -26,9 +26,6 @@ final class UserTimelineViewController: UIViewController, NeedsDependency, Media
|
||||||
|
|
||||||
lazy var tableView: UITableView = {
|
lazy var tableView: UITableView = {
|
||||||
let tableView = UITableView()
|
let tableView = UITableView()
|
||||||
tableView.register(StatusTableViewCell.self, forCellReuseIdentifier: String(describing: StatusTableViewCell.self))
|
|
||||||
tableView.register(TimelineBottomLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self))
|
|
||||||
tableView.register(TimelineHeaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineHeaderTableViewCell.self))
|
|
||||||
tableView.rowHeight = UITableView.automaticDimension
|
tableView.rowHeight = UITableView.automaticDimension
|
||||||
tableView.estimatedRowHeight = 100
|
tableView.estimatedRowHeight = 100
|
||||||
tableView.separatorStyle = .none
|
tableView.separatorStyle = .none
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
//
|
|
||||||
// AdaptiveMarginStatusTableViewCell.swift
|
|
||||||
// Mastodon
|
|
||||||
//
|
|
||||||
// Created by MainasuK on 2022-2-10.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import MastodonUI
|
|
||||||
|
|
||||||
protocol AdaptiveContainerMarginTableViewCell: UITableViewCell {
|
|
||||||
associatedtype ContainerView: UIView
|
|
||||||
static var containerViewMarginForRegularHorizontalSizeClass: CGFloat { get }
|
|
||||||
var containerView: ContainerView { get }
|
|
||||||
var containerViewLeadingLayoutConstraint: NSLayoutConstraint! { get set }
|
|
||||||
var containerViewTrailingLayoutConstraint: NSLayoutConstraint! { get set }
|
|
||||||
}
|
|
||||||
|
|
||||||
extension AdaptiveContainerMarginTableViewCell {
|
|
||||||
|
|
||||||
static var containerViewMarginForRegularHorizontalSizeClass: CGFloat { 64 }
|
|
||||||
|
|
||||||
func setupContainerViewMarginConstraints() {
|
|
||||||
containerViewLeadingLayoutConstraint = containerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
|
|
||||||
containerViewTrailingLayoutConstraint = contentView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateContainerViewMarginConstraints() {
|
|
||||||
guard traitCollection.userInterfaceIdiom != .phone,
|
|
||||||
traitCollection.horizontalSizeClass == .regular
|
|
||||||
else {
|
|
||||||
containerViewLeadingLayoutConstraint.constant = 0
|
|
||||||
containerViewTrailingLayoutConstraint.constant = 0
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
containerViewLeadingLayoutConstraint.constant = Self.containerViewMarginForRegularHorizontalSizeClass
|
|
||||||
containerViewTrailingLayoutConstraint.constant = Self.containerViewMarginForRegularHorizontalSizeClass
|
|
||||||
}
|
|
||||||
|
|
||||||
var containerViewHorizontalMargin: CGFloat {
|
|
||||||
containerViewLeadingLayoutConstraint.constant + containerViewTrailingLayoutConstraint.constant
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -28,20 +28,6 @@ final class StatusTableViewCell: UITableViewCell {
|
||||||
var containerViewLeadingLayoutConstraint: NSLayoutConstraint!
|
var containerViewLeadingLayoutConstraint: NSLayoutConstraint!
|
||||||
var containerViewTrailingLayoutConstraint: NSLayoutConstraint!
|
var containerViewTrailingLayoutConstraint: NSLayoutConstraint!
|
||||||
|
|
||||||
// var isFiltered: Bool = false {
|
|
||||||
// didSet {
|
|
||||||
// configure(isFiltered: isFiltered)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let filteredLabel: UILabel = {
|
|
||||||
// let label = UILabel()
|
|
||||||
// label.textColor = Asset.Colors.Label.secondary.color
|
|
||||||
// label.text = L10n.Common.Controls.Timeline.filtered
|
|
||||||
// label.font = .preferredFont(forTextStyle: .body)
|
|
||||||
// return label
|
|
||||||
// }()
|
|
||||||
//
|
|
||||||
override func prepareForReuse() {
|
override func prepareForReuse() {
|
||||||
super.prepareForReuse()
|
super.prepareForReuse()
|
||||||
|
|
||||||
|
@ -71,7 +57,6 @@ extension StatusTableViewCell {
|
||||||
statusView.translatesAutoresizingMaskIntoConstraints = false
|
statusView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
contentView.addSubview(statusView)
|
contentView.addSubview(statusView)
|
||||||
setupContainerViewMarginConstraints()
|
setupContainerViewMarginConstraints()
|
||||||
updateContainerViewMarginConstraints()
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
statusView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16),
|
statusView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16),
|
||||||
containerViewLeadingLayoutConstraint,
|
containerViewLeadingLayoutConstraint,
|
||||||
|
@ -79,6 +64,7 @@ extension StatusTableViewCell {
|
||||||
statusView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
statusView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||||
])
|
])
|
||||||
statusView.setup(style: .inline)
|
statusView.setup(style: .inline)
|
||||||
|
updateContainerViewMarginConstraints()
|
||||||
|
|
||||||
separatorLine.translatesAutoresizingMaskIntoConstraints = false
|
separatorLine.translatesAutoresizingMaskIntoConstraints = false
|
||||||
contentView.addSubview(separatorLine)
|
contentView.addSubview(separatorLine)
|
||||||
|
|
|
@ -58,7 +58,6 @@ extension StatusThreadRootTableViewCell {
|
||||||
statusView.translatesAutoresizingMaskIntoConstraints = false
|
statusView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
contentView.addSubview(statusView)
|
contentView.addSubview(statusView)
|
||||||
setupContainerViewMarginConstraints()
|
setupContainerViewMarginConstraints()
|
||||||
updateContainerViewMarginConstraints()
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
statusView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16),
|
statusView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16),
|
||||||
containerViewLeadingLayoutConstraint,
|
containerViewLeadingLayoutConstraint,
|
||||||
|
@ -66,6 +65,7 @@ extension StatusThreadRootTableViewCell {
|
||||||
statusView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
statusView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||||
])
|
])
|
||||||
statusView.setup(style: .plain)
|
statusView.setup(style: .plain)
|
||||||
|
updateContainerViewMarginConstraints()
|
||||||
|
|
||||||
separatorLine.translatesAutoresizingMaskIntoConstraints = false
|
separatorLine.translatesAutoresizingMaskIntoConstraints = false
|
||||||
contentView.addSubview(separatorLine)
|
contentView.addSubview(separatorLine)
|
||||||
|
@ -108,7 +108,6 @@ extension StatusThreadRootTableViewCell {
|
||||||
statusView.mediaGridContainerView,
|
statusView.mediaGridContainerView,
|
||||||
statusView.pollTableView,
|
statusView.pollTableView,
|
||||||
statusView.pollStatusStackView,
|
statusView.pollStatusStackView,
|
||||||
statusView.statusVisibilityView,
|
|
||||||
statusView.actionToolbarContainer,
|
statusView.actionToolbarContainer,
|
||||||
statusView.statusMetricView
|
statusView.statusMetricView
|
||||||
]
|
]
|
||||||
|
@ -123,10 +122,6 @@ extension StatusThreadRootTableViewCell {
|
||||||
elements.removeAll(where: { $0 === statusView.contentMetaText.textView })
|
elements.removeAll(where: { $0 === statusView.contentMetaText.textView })
|
||||||
}
|
}
|
||||||
|
|
||||||
if statusView.statusVisibilityView.isHidden {
|
|
||||||
elements.removeAll(where: { $0 === statusView.statusVisibilityView })
|
|
||||||
}
|
|
||||||
|
|
||||||
if statusView.viewModel.pollItems.isEmpty {
|
if statusView.viewModel.pollItems.isEmpty {
|
||||||
elements.removeAll(where: { $0 === statusView.pollTableView })
|
elements.removeAll(where: { $0 === statusView.pollTableView })
|
||||||
elements.removeAll(where: { $0 === statusView.pollStatusStackView })
|
elements.removeAll(where: { $0 === statusView.pollStatusStackView })
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
//
|
||||||
|
// AdaptiveMarginStatusTableViewCell.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by MainasuK on 2022-2-18.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
public protocol AdaptiveContainerView: UIView {
|
||||||
|
func updateContainerViewComponentsLayoutMarginsRelativeArrangementBehavior(isEnabled: Bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol AdaptiveContainerMarginTableViewCell: UITableViewCell {
|
||||||
|
associatedtype ContainerView: AdaptiveContainerView
|
||||||
|
static var containerViewMarginForRegularHorizontalSizeClass: CGFloat { get }
|
||||||
|
var containerView: ContainerView { get }
|
||||||
|
var containerViewLeadingLayoutConstraint: NSLayoutConstraint! { get set }
|
||||||
|
var containerViewTrailingLayoutConstraint: NSLayoutConstraint! { get set }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AdaptiveContainerMarginTableViewCell {
|
||||||
|
|
||||||
|
public static var containerViewMarginForRegularHorizontalSizeClass: CGFloat { 64 }
|
||||||
|
|
||||||
|
public func setupContainerViewMarginConstraints() {
|
||||||
|
containerViewLeadingLayoutConstraint = containerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
|
||||||
|
containerViewTrailingLayoutConstraint = contentView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateContainerViewMarginConstraints() {
|
||||||
|
func setupContainerForPhone() {
|
||||||
|
containerView.updateContainerViewComponentsLayoutMarginsRelativeArrangementBehavior(isEnabled: true) // add inner margin for phone
|
||||||
|
containerViewLeadingLayoutConstraint.constant = 0 // remove outer margin for phone
|
||||||
|
containerViewTrailingLayoutConstraint.constant = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
switch traitCollection.userInterfaceIdiom {
|
||||||
|
case .phone:
|
||||||
|
setupContainerForPhone()
|
||||||
|
default:
|
||||||
|
guard traitCollection.horizontalSizeClass == .regular else {
|
||||||
|
setupContainerForPhone()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
containerView.updateContainerViewComponentsLayoutMarginsRelativeArrangementBehavior(isEnabled: false) // remove margin for iPad
|
||||||
|
containerViewLeadingLayoutConstraint.constant = Self.containerViewMarginForRegularHorizontalSizeClass // add outer margin for iPad
|
||||||
|
containerViewTrailingLayoutConstraint.constant = Self.containerViewMarginForRegularHorizontalSizeClass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var containerViewHorizontalMargin: CGFloat {
|
||||||
|
containerViewLeadingLayoutConstraint.constant + containerViewTrailingLayoutConstraint.constant
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
//
|
||||||
|
// AdaptiveMarginContainerView.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by MainasuK on 2022-2-18.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
public final class AdaptiveMarginContainerView: UIView {
|
||||||
|
|
||||||
|
public var margin: CGFloat = 0 {
|
||||||
|
didSet { updateConstraints() }
|
||||||
|
}
|
||||||
|
|
||||||
|
public var contentView: UIView? {
|
||||||
|
didSet {
|
||||||
|
guard let contentView = contentView else { return }
|
||||||
|
guard contentView.superview == nil else { return }
|
||||||
|
|
||||||
|
contentView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
addSubview(contentView)
|
||||||
|
|
||||||
|
let _leadingLayoutConstraint = contentView.leadingAnchor.constraint(equalTo: leadingAnchor)
|
||||||
|
let _trailingLayoutConstraint = trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
|
||||||
|
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
contentView.topAnchor.constraint(equalTo: topAnchor),
|
||||||
|
_leadingLayoutConstraint,
|
||||||
|
_trailingLayoutConstraint,
|
||||||
|
contentView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||||
|
])
|
||||||
|
|
||||||
|
leadingLayoutConstraint = _leadingLayoutConstraint
|
||||||
|
trailingLayoutConstraint = _trailingLayoutConstraint
|
||||||
|
|
||||||
|
updateConstraints()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var leadingLayoutConstraint: NSLayoutConstraint?
|
||||||
|
var trailingLayoutConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AdaptiveMarginContainerView {
|
||||||
|
|
||||||
|
public override func updateConstraints() {
|
||||||
|
super.updateConstraints()
|
||||||
|
|
||||||
|
leadingLayoutConstraint?.constant = margin
|
||||||
|
trailingLayoutConstraint?.constant = margin
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ public final class MediaView: UIView {
|
||||||
formatter.allowedUnits = [.minute, .second]
|
formatter.allowedUnits = [.minute, .second]
|
||||||
return formatter
|
return formatter
|
||||||
}()
|
}()
|
||||||
|
public static let placeholderImage = UIImage.placeholder(color: .systemGray6)
|
||||||
|
|
||||||
public let container = TouchBlockingView()
|
public let container = TouchBlockingView()
|
||||||
|
|
||||||
|
@ -154,7 +155,10 @@ extension MediaView {
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] isReveal, previewImage, blurhashImage in
|
.sink { [weak self] isReveal, previewImage, blurhashImage in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
let image = isReveal ? (previewImage ?? blurhashImage) : blurhashImage
|
|
||||||
|
let image = isReveal ?
|
||||||
|
(previewImage ?? blurhashImage ?? MediaView.placeholderImage) :
|
||||||
|
(blurhashImage ?? MediaView.placeholderImage)
|
||||||
self.imageView.image = image
|
self.imageView.image = image
|
||||||
}
|
}
|
||||||
.store(in: &configuration.disposeBag)
|
.store(in: &configuration.disposeBag)
|
||||||
|
@ -204,30 +208,6 @@ extension MediaView {
|
||||||
assetURL: info.previewURL
|
assetURL: info.previewURL
|
||||||
)
|
)
|
||||||
bindImage(configuration: configuration, info: imageInfo)
|
bindImage(configuration: configuration, info: imageInfo)
|
||||||
|
|
||||||
// indicatorBlurEffectView.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
// imageView.addSubview(indicatorBlurEffectView)
|
|
||||||
// NSLayoutConstraint.activate([
|
|
||||||
// imageView.trailingAnchor.constraint(equalTo: indicatorBlurEffectView.trailingAnchor, constant: 11),
|
|
||||||
// imageView.bottomAnchor.constraint(equalTo: indicatorBlurEffectView.bottomAnchor, constant: 8),
|
|
||||||
// ])
|
|
||||||
// setupIndicatorViewHierarchy()
|
|
||||||
|
|
||||||
// playerIndicatorLabel.attributedText = {
|
|
||||||
// let imageAttachment = NSTextAttachment(image: UIImage(systemName: "play.fill")!)
|
|
||||||
// let imageAttributedString = AttributedString(NSAttributedString(attachment: imageAttachment))
|
|
||||||
// let duration: String = {
|
|
||||||
// guard let durationMS = info.durationMS else { return "" }
|
|
||||||
// let timeInterval = TimeInterval(durationMS / 1000)
|
|
||||||
// guard timeInterval > 0 else { return "" }
|
|
||||||
// guard let text = MediaView.durationFormatter.string(from: timeInterval) else { return "" }
|
|
||||||
// return " \(text)"
|
|
||||||
// }()
|
|
||||||
// let textAttributedString = AttributedString("\(duration)")
|
|
||||||
// var attributedString = imageAttributedString + textAttributedString
|
|
||||||
// attributedString.foregroundColor = .secondaryLabel
|
|
||||||
// return NSAttributedString(attributedString)
|
|
||||||
// }()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func layoutBlurhash() {
|
private func layoutBlurhash() {
|
||||||
|
|
|
@ -136,7 +136,7 @@ public final class NotificationView: UIView {
|
||||||
extension NotificationView {
|
extension NotificationView {
|
||||||
private func _init() {
|
private func _init() {
|
||||||
// container: V - [ author container | (authorContainerViewBottomPaddingView) | statusView | quoteStatusView ]
|
// container: V - [ author container | (authorContainerViewBottomPaddingView) | statusView | quoteStatusView ]
|
||||||
containerStackView.layoutMargins = StatusView.containerLayoutMargin
|
// containerStackView.layoutMargins = StatusView.containerLayoutMargin
|
||||||
|
|
||||||
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
addSubview(containerStackView)
|
addSubview(containerStackView)
|
||||||
|
@ -228,9 +228,9 @@ extension NotificationView {
|
||||||
containerStackView.addArrangedSubview(quoteStatusViewContainerView)
|
containerStackView.addArrangedSubview(quoteStatusViewContainerView)
|
||||||
quoteStatusViewContainerView.layoutMargins = UIEdgeInsets(
|
quoteStatusViewContainerView.layoutMargins = UIEdgeInsets(
|
||||||
top: 0,
|
top: 0,
|
||||||
left: StatusView.containerLayoutMargin.left,
|
left: StatusView.containerLayoutMargin,
|
||||||
bottom: 16,
|
bottom: 16,
|
||||||
right: StatusView.containerLayoutMargin.right
|
right: StatusView.containerLayoutMargin
|
||||||
)
|
)
|
||||||
|
|
||||||
quoteBackgroundView.layoutMargins = UIEdgeInsets(top: 16, left: 0, bottom: 0, right: 0)
|
quoteBackgroundView.layoutMargins = UIEdgeInsets(top: 16, left: 0, bottom: 0, right: 0)
|
||||||
|
@ -297,6 +297,13 @@ extension NotificationView {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - AdaptiveContainerView
|
||||||
|
extension NotificationView: AdaptiveContainerView {
|
||||||
|
public func updateContainerViewComponentsLayoutMarginsRelativeArrangementBehavior(isEnabled: Bool) {
|
||||||
|
statusView.updateContainerViewComponentsLayoutMarginsRelativeArrangementBehavior(isEnabled: isEnabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension NotificationView {
|
extension NotificationView {
|
||||||
public typealias AuthorMenuContext = StatusView.AuthorMenuContext
|
public typealias AuthorMenuContext = StatusView.AuthorMenuContext
|
||||||
|
|
||||||
|
|
|
@ -71,8 +71,8 @@ extension StatusMetricView {
|
||||||
addSubview(containerStackView)
|
addSubview(containerStackView)
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
containerStackView.topAnchor.constraint(equalTo: topAnchor, constant: 8),
|
containerStackView.topAnchor.constraint(equalTo: topAnchor, constant: 8),
|
||||||
containerStackView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
|
containerStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||||
containerStackView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
|
containerStackView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||||
bottomAnchor.constraint(equalTo: containerStackView.bottomAnchor, constant: 12),
|
bottomAnchor.constraint(equalTo: containerStackView.bottomAnchor, constant: 12),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -24,19 +24,15 @@ public protocol StatusViewDelegate: AnyObject {
|
||||||
func statusView(_ statusView: StatusView, actionToolbarContainer: ActionToolbarContainer, buttonDidPressed button: UIButton, action: ActionToolbarContainer.Action)
|
func statusView(_ statusView: StatusView, actionToolbarContainer: ActionToolbarContainer, buttonDidPressed button: UIButton, action: ActionToolbarContainer.Action)
|
||||||
func statusView(_ statusView: StatusView, menuButton button: UIButton, didSelectAction action: MastodonMenu.Action)
|
func statusView(_ statusView: StatusView, menuButton button: UIButton, didSelectAction action: MastodonMenu.Action)
|
||||||
func statusView(_ statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView)
|
func statusView(_ statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView)
|
||||||
// func statusView(_ statusView: StatusView, spoilerBannerViewDidPressed bannerView: SpoilerBannerView)
|
|
||||||
func statusView(_ statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaSensitiveButtonDidPressed button: UIButton)
|
func statusView(_ statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaSensitiveButtonDidPressed button: UIButton)
|
||||||
|
|
||||||
// a11y
|
// a11y
|
||||||
func statusView(_ statusView: StatusView, accessibilityActivate: Void)
|
func statusView(_ statusView: StatusView, accessibilityActivate: Void)
|
||||||
|
|
||||||
// func statusView(_ statusView: StatusView, contentWarningOverlayViewDidPressed contentWarningOverlayView: ContentWarningOverlayView)
|
|
||||||
// func statusView(_ statusView: StatusView, playerContainerView: PlayerContainerView, contentWarningOverlayViewDidPressed contentWarningOverlayView: ContentWarningOverlayView)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class StatusView: UIView {
|
public final class StatusView: UIView {
|
||||||
|
|
||||||
public static let containerLayoutMargin = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
|
public static let containerLayoutMargin: CGFloat = 16
|
||||||
|
|
||||||
let logger = Logger(subsystem: "StatusView", category: "View")
|
let logger = Logger(subsystem: "StatusView", category: "View")
|
||||||
|
|
||||||
|
@ -61,6 +57,7 @@ public final class StatusView: UIView {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// header
|
// header
|
||||||
|
let headerAdaptiveMarginContainerView = AdaptiveMarginContainerView()
|
||||||
public let headerContainerView = UIView()
|
public let headerContainerView = UIView()
|
||||||
|
|
||||||
// header icon
|
// header icon
|
||||||
|
@ -75,6 +72,7 @@ public final class StatusView: UIView {
|
||||||
let headerInfoLabel = MetaLabel(style: .statusHeader)
|
let headerInfoLabel = MetaLabel(style: .statusHeader)
|
||||||
|
|
||||||
// author
|
// author
|
||||||
|
let authorAdaptiveMarginContainerView = AdaptiveMarginContainerView()
|
||||||
let authorContainerView: UIStackView = {
|
let authorContainerView: UIStackView = {
|
||||||
let stackView = UIStackView()
|
let stackView = UIStackView()
|
||||||
stackView.axis = .horizontal
|
stackView.axis = .horizontal
|
||||||
|
@ -122,6 +120,7 @@ public final class StatusView: UIView {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// content
|
// content
|
||||||
|
let contentAdaptiveMarginContainerView = AdaptiveMarginContainerView()
|
||||||
let contentContainer = UIStackView()
|
let contentContainer = UIStackView()
|
||||||
public let contentMetaText: MetaText = {
|
public let contentMetaText: MetaText = {
|
||||||
let metaText = MetaText()
|
let metaText = MetaText()
|
||||||
|
@ -160,7 +159,8 @@ public final class StatusView: UIView {
|
||||||
public let mediaGridContainerView = MediaGridContainerView()
|
public let mediaGridContainerView = MediaGridContainerView()
|
||||||
|
|
||||||
// poll
|
// poll
|
||||||
public let pollContainerView = UIStackView()
|
let pollAdaptiveMarginContainerView = AdaptiveMarginContainerView()
|
||||||
|
let pollContainerView = UIStackView()
|
||||||
public let pollTableView: UITableView = {
|
public let pollTableView: UITableView = {
|
||||||
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
|
||||||
tableView.register(PollOptionTableViewCell.self, forCellReuseIdentifier: String(describing: PollOptionTableViewCell.self))
|
tableView.register(PollOptionTableViewCell.self, forCellReuseIdentifier: String(describing: PollOptionTableViewCell.self))
|
||||||
|
@ -214,16 +214,12 @@ public final class StatusView: UIView {
|
||||||
return indicatorView
|
return indicatorView
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// visibility
|
|
||||||
public let statusVisibilityView = StatusVisibilityView()
|
|
||||||
|
|
||||||
// spoiler banner
|
|
||||||
// public let spoilerBannerView = SpoilerBannerView()
|
|
||||||
|
|
||||||
// toolbar
|
// toolbar
|
||||||
|
let actionToolbarAdaptiveMarginContainerView = AdaptiveMarginContainerView()
|
||||||
public let actionToolbarContainer = ActionToolbarContainer()
|
public let actionToolbarContainer = ActionToolbarContainer()
|
||||||
|
|
||||||
// metric
|
// metric
|
||||||
|
let statusMetricViewAdaptiveMarginContainerView = AdaptiveMarginContainerView()
|
||||||
public let statusMetricView = StatusMetricView()
|
public let statusMetricView = StatusMetricView()
|
||||||
|
|
||||||
// filter hint
|
// filter hint
|
||||||
|
@ -252,13 +248,12 @@ public final class StatusView: UIView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
headerContainerView.isHidden = true
|
setHeaderDisplay(isDisplay: false)
|
||||||
contentSensitiveeToggleButton.isHidden = true
|
setContentSensitiveeToggleButtonDisplay(isDisplay: false)
|
||||||
setSpoilerOverlayViewHidden(isHidden: true)
|
setSpoilerOverlayViewHidden(isHidden: true)
|
||||||
mediaContainerView.isHidden = true
|
setMediaDisplay(isDisplay: false)
|
||||||
pollContainerView.isHidden = true
|
setPollDisplay(isDisplay: false)
|
||||||
statusVisibilityView.isHidden = true
|
setFilterHintLabelDisplay(isDisplay: false)
|
||||||
filterHintLabel.isHidden = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override init(frame: CGRect) {
|
public override init(frame: CGRect) {
|
||||||
|
@ -323,12 +318,6 @@ extension StatusView {
|
||||||
])
|
])
|
||||||
pollTableView.delegate = self
|
pollTableView.delegate = self
|
||||||
pollVoteButton.addTarget(self, action: #selector(StatusView.pollVoteButtonDidPressed(_:)), for: .touchUpInside)
|
pollVoteButton.addTarget(self, action: #selector(StatusView.pollVoteButtonDidPressed(_:)), for: .touchUpInside)
|
||||||
|
|
||||||
// statusSpoilerBannerView
|
|
||||||
// let spoilerBannerViewTapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer
|
|
||||||
// spoilerBannerView.addGestureRecognizer(spoilerBannerViewTapGestureRecognizer)
|
|
||||||
// spoilerBannerViewTapGestureRecognizer.addTarget(self, action: #selector(StatusView.spoilerBannerViewTapGestureRecognizerHandler(_:)))
|
|
||||||
|
|
||||||
// toolbar
|
// toolbar
|
||||||
actionToolbarContainer.delegate = self
|
actionToolbarContainer.delegate = self
|
||||||
}
|
}
|
||||||
|
@ -362,11 +351,6 @@ extension StatusView {
|
||||||
delegate?.statusView(self, spoilerOverlayViewDidPressed: spoilerOverlayView)
|
delegate?.statusView(self, spoilerOverlayViewDidPressed: spoilerOverlayView)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @objc private func spoilerBannerViewTapGestureRecognizerHandler(_ sender: UITapGestureRecognizer) {
|
|
||||||
// logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)")
|
|
||||||
// delegate?.statusView(self, spoilerBannerViewDidPressed: spoilerBannerView)
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension StatusView {
|
extension StatusView {
|
||||||
|
@ -408,22 +392,23 @@ extension StatusView.Style {
|
||||||
|
|
||||||
private func base(statusView: StatusView) {
|
private func base(statusView: StatusView) {
|
||||||
// container: V - [ header container | author container | content container | media container | pollTableView | actionToolbarContainer ]
|
// container: V - [ header container | author container | content container | media container | pollTableView | actionToolbarContainer ]
|
||||||
statusView.containerStackView.layoutMargins = StatusView.containerLayoutMargin
|
|
||||||
|
|
||||||
// header container: H - [ icon | label ]
|
// header container: H - [ icon | label ]
|
||||||
statusView.headerContainerView.preservesSuperviewLayoutMargins = true
|
statusView.headerAdaptiveMarginContainerView.contentView = statusView.headerContainerView
|
||||||
statusView.containerStackView.addArrangedSubview(statusView.headerContainerView)
|
statusView.headerAdaptiveMarginContainerView.margin = StatusView.containerLayoutMargin
|
||||||
|
statusView.containerStackView.addArrangedSubview(statusView.headerAdaptiveMarginContainerView)
|
||||||
|
|
||||||
statusView.headerIconImageView.translatesAutoresizingMaskIntoConstraints = false
|
statusView.headerIconImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
statusView.headerInfoLabel.translatesAutoresizingMaskIntoConstraints = false
|
statusView.headerInfoLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||||
statusView.headerContainerView.addSubview(statusView.headerIconImageView)
|
statusView.headerContainerView.addSubview(statusView.headerIconImageView)
|
||||||
statusView.headerContainerView.addSubview(statusView.headerInfoLabel)
|
statusView.headerContainerView.addSubview(statusView.headerInfoLabel)
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
statusView.headerIconImageView.leadingAnchor.constraint(equalTo: statusView.headerContainerView.layoutMarginsGuide.leadingAnchor),
|
statusView.headerIconImageView.leadingAnchor.constraint(equalTo: statusView.headerContainerView.leadingAnchor),
|
||||||
statusView.headerIconImageView.heightAnchor.constraint(equalTo: statusView.headerInfoLabel.heightAnchor, multiplier: 1.0).priority(.required - 1),
|
statusView.headerIconImageView.heightAnchor.constraint(equalTo: statusView.headerInfoLabel.heightAnchor, multiplier: 1.0).priority(.required - 1),
|
||||||
statusView.headerIconImageView.widthAnchor.constraint(equalTo: statusView.headerIconImageView.heightAnchor, multiplier: 1.0).priority(.required - 1),
|
statusView.headerIconImageView.widthAnchor.constraint(equalTo: statusView.headerIconImageView.heightAnchor, multiplier: 1.0).priority(.required - 1),
|
||||||
statusView.headerInfoLabel.topAnchor.constraint(equalTo: statusView.headerContainerView.topAnchor),
|
statusView.headerInfoLabel.topAnchor.constraint(equalTo: statusView.headerContainerView.topAnchor),
|
||||||
statusView.headerInfoLabel.leadingAnchor.constraint(equalTo: statusView.headerIconImageView.trailingAnchor, constant: 6),
|
statusView.headerInfoLabel.leadingAnchor.constraint(equalTo: statusView.headerIconImageView.trailingAnchor, constant: 6),
|
||||||
statusView.headerInfoLabel.trailingAnchor.constraint(equalTo: statusView.headerContainerView.layoutMarginsGuide.trailingAnchor),
|
statusView.headerInfoLabel.trailingAnchor.constraint(equalTo: statusView.headerContainerView.trailingAnchor),
|
||||||
statusView.headerInfoLabel.bottomAnchor.constraint(equalTo: statusView.headerContainerView.bottomAnchor),
|
statusView.headerInfoLabel.bottomAnchor.constraint(equalTo: statusView.headerContainerView.bottomAnchor),
|
||||||
statusView.headerInfoLabel.centerYAnchor.constraint(equalTo: statusView.headerIconImageView.centerYAnchor),
|
statusView.headerInfoLabel.centerYAnchor.constraint(equalTo: statusView.headerIconImageView.centerYAnchor),
|
||||||
])
|
])
|
||||||
|
@ -434,9 +419,10 @@ extension StatusView.Style {
|
||||||
statusView.headerIconImageView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
statusView.headerIconImageView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
||||||
|
|
||||||
// author container: H - [ avatarButton | author meta container | contentWarningToggleButton ]
|
// author container: H - [ avatarButton | author meta container | contentWarningToggleButton ]
|
||||||
statusView.authorContainerView.preservesSuperviewLayoutMargins = true
|
statusView.authorAdaptiveMarginContainerView.contentView = statusView.authorContainerView
|
||||||
statusView.authorContainerView.isLayoutMarginsRelativeArrangement = true
|
statusView.authorAdaptiveMarginContainerView.margin = StatusView.containerLayoutMargin
|
||||||
statusView.containerStackView.addArrangedSubview(statusView.authorContainerView)
|
statusView.containerStackView.addArrangedSubview(statusView.authorAdaptiveMarginContainerView)
|
||||||
|
|
||||||
UIContentSizeCategory.publisher
|
UIContentSizeCategory.publisher
|
||||||
.sink { category in
|
.sink { category in
|
||||||
statusView.authorContainerView.axis = category > .accessibilityLarge ? .vertical : .horizontal
|
statusView.authorContainerView.axis = category > .accessibilityLarge ? .vertical : .horizontal
|
||||||
|
@ -514,9 +500,9 @@ extension StatusView.Style {
|
||||||
statusView.contentContainer.distribution = .fill
|
statusView.contentContainer.distribution = .fill
|
||||||
statusView.contentContainer.alignment = .top
|
statusView.contentContainer.alignment = .top
|
||||||
|
|
||||||
statusView.contentContainer.preservesSuperviewLayoutMargins = true
|
statusView.contentAdaptiveMarginContainerView.contentView = statusView.contentContainer
|
||||||
statusView.contentContainer.isLayoutMarginsRelativeArrangement = true
|
statusView.contentAdaptiveMarginContainerView.margin = StatusView.containerLayoutMargin
|
||||||
statusView.containerStackView.addArrangedSubview(statusView.contentContainer)
|
statusView.containerStackView.addArrangedSubview(statusView.contentAdaptiveMarginContainerView)
|
||||||
statusView.contentContainer.setContentHuggingPriority(.required - 1, for: .vertical)
|
statusView.contentContainer.setContentHuggingPriority(.required - 1, for: .vertical)
|
||||||
statusView.contentContainer.setContentCompressionResistancePriority(.required - 1, for: .vertical)
|
statusView.contentContainer.setContentCompressionResistancePriority(.required - 1, for: .vertical)
|
||||||
|
|
||||||
|
@ -533,7 +519,12 @@ extension StatusView.Style {
|
||||||
])
|
])
|
||||||
|
|
||||||
// media container: V - [ mediaGridContainerView ]
|
// media container: V - [ mediaGridContainerView ]
|
||||||
|
statusView.mediaContainerView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
statusView.containerStackView.addArrangedSubview(statusView.mediaContainerView)
|
statusView.containerStackView.addArrangedSubview(statusView.mediaContainerView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
statusView.mediaContainerView.leadingAnchor.constraint(equalTo: statusView.containerStackView.leadingAnchor),
|
||||||
|
statusView.mediaContainerView.trailingAnchor.constraint(equalTo: statusView.containerStackView.trailingAnchor),
|
||||||
|
])
|
||||||
|
|
||||||
statusView.mediaGridContainerView.translatesAutoresizingMaskIntoConstraints = false
|
statusView.mediaGridContainerView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
statusView.mediaContainerView.addSubview(statusView.mediaGridContainerView)
|
statusView.mediaContainerView.addSubview(statusView.mediaGridContainerView)
|
||||||
|
@ -545,10 +536,10 @@ extension StatusView.Style {
|
||||||
])
|
])
|
||||||
|
|
||||||
// pollContainerView: V - [ pollTableView | pollStatusStackView ]
|
// pollContainerView: V - [ pollTableView | pollStatusStackView ]
|
||||||
|
statusView.pollAdaptiveMarginContainerView.contentView = statusView.pollContainerView
|
||||||
|
statusView.pollAdaptiveMarginContainerView.margin = StatusView.containerLayoutMargin
|
||||||
statusView.pollContainerView.axis = .vertical
|
statusView.pollContainerView.axis = .vertical
|
||||||
statusView.pollContainerView.preservesSuperviewLayoutMargins = true
|
statusView.containerStackView.addArrangedSubview(statusView.pollAdaptiveMarginContainerView)
|
||||||
statusView.pollContainerView.isLayoutMarginsRelativeArrangement = true
|
|
||||||
statusView.containerStackView.addArrangedSubview(statusView.pollContainerView)
|
|
||||||
|
|
||||||
// pollTableView
|
// pollTableView
|
||||||
statusView.pollContainerView.addArrangedSubview(statusView.pollTableView)
|
statusView.pollContainerView.addArrangedSubview(statusView.pollTableView)
|
||||||
|
@ -567,18 +558,11 @@ extension StatusView.Style {
|
||||||
statusView.pollCountdownLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
statusView.pollCountdownLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
||||||
statusView.pollVoteButton.setContentHuggingPriority(.defaultHigh + 3, for: .horizontal)
|
statusView.pollVoteButton.setContentHuggingPriority(.defaultHigh + 3, for: .horizontal)
|
||||||
|
|
||||||
// statusVisibilityView
|
|
||||||
statusView.statusVisibilityView.preservesSuperviewLayoutMargins = true
|
|
||||||
statusView.containerStackView.addArrangedSubview(statusView.statusVisibilityView)
|
|
||||||
|
|
||||||
// spoilerBannerView
|
|
||||||
// statusView.spoilerBannerView.preservesSuperviewLayoutMargins = true
|
|
||||||
// statusView.containerStackView.addArrangedSubview(statusView.spoilerBannerView)
|
|
||||||
|
|
||||||
// action toolbar
|
// action toolbar
|
||||||
|
statusView.actionToolbarAdaptiveMarginContainerView.contentView = statusView.actionToolbarContainer
|
||||||
|
statusView.actionToolbarAdaptiveMarginContainerView.margin = StatusView.containerLayoutMargin
|
||||||
statusView.actionToolbarContainer.configure(for: .inline)
|
statusView.actionToolbarContainer.configure(for: .inline)
|
||||||
statusView.actionToolbarContainer.preservesSuperviewLayoutMargins = true
|
statusView.containerStackView.addArrangedSubview(statusView.actionToolbarAdaptiveMarginContainerView)
|
||||||
statusView.containerStackView.addArrangedSubview(statusView.actionToolbarContainer)
|
|
||||||
|
|
||||||
// filterHintLabel
|
// filterHintLabel
|
||||||
statusView.filterHintLabel.translatesAutoresizingMaskIntoConstraints = false
|
statusView.filterHintLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
@ -591,8 +575,6 @@ extension StatusView.Style {
|
||||||
|
|
||||||
func inline(statusView: StatusView) {
|
func inline(statusView: StatusView) {
|
||||||
base(statusView: statusView)
|
base(statusView: statusView)
|
||||||
|
|
||||||
statusView.statusVisibilityView.removeFromSuperview()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func plain(statusView: StatusView) {
|
func plain(statusView: StatusView) {
|
||||||
|
@ -600,8 +582,10 @@ extension StatusView.Style {
|
||||||
base(statusView: statusView) // override the base style
|
base(statusView: statusView) // override the base style
|
||||||
|
|
||||||
// statusMetricView
|
// statusMetricView
|
||||||
statusView.statusMetricView.layoutMargins = StatusView.containerLayoutMargin
|
statusView.statusMetricViewAdaptiveMarginContainerView.contentView = statusView.statusMetricView
|
||||||
statusView.containerStackView.addArrangedSubview(statusView.statusMetricView)
|
statusView.statusMetricViewAdaptiveMarginContainerView.margin = StatusView.containerLayoutMargin
|
||||||
|
statusView.containerStackView.addArrangedSubview(statusView.statusMetricViewAdaptiveMarginContainerView)
|
||||||
|
|
||||||
UIContentSizeCategory.publisher
|
UIContentSizeCategory.publisher
|
||||||
.sink { category in
|
.sink { category in
|
||||||
statusView.statusMetricView.containerStackView.axis = category > .accessibilityLarge ? .vertical : .horizontal
|
statusView.statusMetricView.containerStackView.axis = category > .accessibilityLarge ? .vertical : .horizontal
|
||||||
|
@ -614,16 +598,14 @@ extension StatusView.Style {
|
||||||
base(statusView: statusView) // override the base style
|
base(statusView: statusView) // override the base style
|
||||||
|
|
||||||
statusView.menuButton.removeFromSuperview()
|
statusView.menuButton.removeFromSuperview()
|
||||||
statusView.statusVisibilityView.removeFromSuperview()
|
statusView.actionToolbarAdaptiveMarginContainerView.removeFromSuperview()
|
||||||
statusView.actionToolbarContainer.removeFromSuperview()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func notification(statusView: StatusView) {
|
func notification(statusView: StatusView) {
|
||||||
base(statusView: statusView) // override the base style
|
base(statusView: statusView) // override the base style
|
||||||
|
|
||||||
statusView.headerContainerView.removeFromSuperview()
|
statusView.headerAdaptiveMarginContainerView.removeFromSuperview()
|
||||||
statusView.authorContainerView.removeFromSuperview()
|
statusView.authorAdaptiveMarginContainerView.removeFromSuperview()
|
||||||
statusView.statusVisibilityView.removeFromSuperview()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func notificationQuote(statusView: StatusView) {
|
func notificationQuote(statusView: StatusView) {
|
||||||
|
@ -632,8 +614,7 @@ extension StatusView.Style {
|
||||||
statusView.contentContainer.layoutMargins.bottom = 16 // fix contentText align to edge issue
|
statusView.contentContainer.layoutMargins.bottom = 16 // fix contentText align to edge issue
|
||||||
statusView.contentSensitiveeToggleButton.removeFromSuperview()
|
statusView.contentSensitiveeToggleButton.removeFromSuperview()
|
||||||
statusView.menuButton.removeFromSuperview()
|
statusView.menuButton.removeFromSuperview()
|
||||||
statusView.statusVisibilityView.removeFromSuperview()
|
statusView.actionToolbarAdaptiveMarginContainerView.removeFromSuperview()
|
||||||
statusView.actionToolbarContainer.removeFromSuperview()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func composeStatusReplica(statusView: StatusView) {
|
func composeStatusReplica(statusView: StatusView) {
|
||||||
|
@ -641,9 +622,7 @@ extension StatusView.Style {
|
||||||
|
|
||||||
statusView.avatarButton.isUserInteractionEnabled = false
|
statusView.avatarButton.isUserInteractionEnabled = false
|
||||||
statusView.menuButton.removeFromSuperview()
|
statusView.menuButton.removeFromSuperview()
|
||||||
statusView.statusVisibilityView.removeFromSuperview()
|
statusView.actionToolbarAdaptiveMarginContainerView.removeFromSuperview()
|
||||||
// statusView.spoilerBannerView.removeFromSuperview()
|
|
||||||
statusView.actionToolbarContainer.removeFromSuperview()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func composeStatusAuthor(statusView: StatusView) {
|
func composeStatusAuthor(statusView: StatusView) {
|
||||||
|
@ -653,24 +632,22 @@ extension StatusView.Style {
|
||||||
statusView.menuButton.removeFromSuperview()
|
statusView.menuButton.removeFromSuperview()
|
||||||
statusView.usernameTrialingDotLabel.removeFromSuperview()
|
statusView.usernameTrialingDotLabel.removeFromSuperview()
|
||||||
statusView.dateLabel.removeFromSuperview()
|
statusView.dateLabel.removeFromSuperview()
|
||||||
statusView.contentContainer.removeFromSuperview()
|
statusView.contentAdaptiveMarginContainerView.removeFromSuperview()
|
||||||
statusView.spoilerOverlayView.removeFromSuperview()
|
statusView.spoilerOverlayView.removeFromSuperview()
|
||||||
statusView.mediaContainerView.removeFromSuperview()
|
statusView.mediaContainerView.removeFromSuperview()
|
||||||
statusView.pollContainerView.removeFromSuperview()
|
statusView.pollAdaptiveMarginContainerView.removeFromSuperview()
|
||||||
statusView.statusVisibilityView.removeFromSuperview()
|
statusView.actionToolbarAdaptiveMarginContainerView.removeFromSuperview()
|
||||||
// statusView.spoilerBannerView.removeFromSuperview()
|
|
||||||
statusView.actionToolbarContainer.removeFromSuperview()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension StatusView {
|
extension StatusView {
|
||||||
func setHeaderDisplay() {
|
func setHeaderDisplay(isDisplay: Bool = true) {
|
||||||
headerContainerView.isHidden = false
|
headerAdaptiveMarginContainerView.isHidden = !isDisplay
|
||||||
}
|
}
|
||||||
|
|
||||||
func setContentSensitiveeToggleButtonDisplay() {
|
func setContentSensitiveeToggleButtonDisplay(isDisplay: Bool = true) {
|
||||||
contentSensitiveeToggleButton.isHidden = false
|
contentSensitiveeToggleButton.isHidden = !isDisplay
|
||||||
}
|
}
|
||||||
|
|
||||||
func setSpoilerOverlayViewHidden(isHidden: Bool) {
|
func setSpoilerOverlayViewHidden(isHidden: Bool) {
|
||||||
|
@ -678,31 +655,35 @@ extension StatusView {
|
||||||
spoilerOverlayView.setComponentHidden(isHidden)
|
spoilerOverlayView.setComponentHidden(isHidden)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setMediaDisplay() {
|
func setMediaDisplay(isDisplay: Bool = true) {
|
||||||
mediaContainerView.isHidden = false
|
mediaContainerView.isHidden = !isDisplay
|
||||||
}
|
}
|
||||||
|
|
||||||
func setPollDisplay() {
|
func setPollDisplay(isDisplay: Bool = true) {
|
||||||
pollContainerView.isHidden = false
|
pollAdaptiveMarginContainerView.isHidden = !isDisplay
|
||||||
}
|
}
|
||||||
|
|
||||||
func setVisibilityDisplay() {
|
func setFilterHintLabelDisplay(isDisplay: Bool = true) {
|
||||||
statusVisibilityView.isHidden = false
|
filterHintLabel.isHidden = !isDisplay
|
||||||
}
|
}
|
||||||
|
|
||||||
func setFilterHintLabelDisplay() {
|
// container width
|
||||||
filterHintLabel.isHidden = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// content text Width
|
|
||||||
public var contentMaxLayoutWidth: CGFloat {
|
public var contentMaxLayoutWidth: CGFloat {
|
||||||
let inset = contentLayoutInset
|
return frame.width
|
||||||
return frame.width - inset.left - inset.right
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var contentLayoutInset: UIEdgeInsets {
|
}
|
||||||
// TODO: adaptive iPad regular horizontal size class
|
|
||||||
return .zero
|
// MARK: - AdaptiveContainerView
|
||||||
|
extension StatusView: AdaptiveContainerView {
|
||||||
|
public func updateContainerViewComponentsLayoutMarginsRelativeArrangementBehavior(isEnabled: Bool) {
|
||||||
|
let margin = isEnabled ? StatusView.containerLayoutMargin : .zero
|
||||||
|
headerAdaptiveMarginContainerView.margin = margin
|
||||||
|
authorAdaptiveMarginContainerView.margin = margin
|
||||||
|
contentAdaptiveMarginContainerView.margin = margin
|
||||||
|
pollAdaptiveMarginContainerView.margin = margin
|
||||||
|
actionToolbarAdaptiveMarginContainerView.margin = margin
|
||||||
|
statusMetricViewAdaptiveMarginContainerView.margin = margin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,9 +49,6 @@ public final class ActionToolbarContainer: UIView {
|
||||||
extension ActionToolbarContainer {
|
extension ActionToolbarContainer {
|
||||||
|
|
||||||
private func _init() {
|
private func _init() {
|
||||||
container.preservesSuperviewLayoutMargins = true
|
|
||||||
container.isLayoutMarginsRelativeArrangement = true
|
|
||||||
|
|
||||||
container.translatesAutoresizingMaskIntoConstraints = false
|
container.translatesAutoresizingMaskIntoConstraints = false
|
||||||
addSubview(container)
|
addSubview(container)
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
|
|
Loading…
Reference in New Issue