Skip to content

Commit

Permalink
Post cell cleanup (IOS-232) and other fixes (#1272)
Browse files Browse the repository at this point in the history
* Replace icons with SF Symbols (IOS-232)

* Remove visibility-icon from Status (IOS-232)

* Use relative time formatter and switch position of timestamp/user (IOS-232)

* Set TimelineSelector-Button-Position (IOS-232)

Shouldn't switch now any longer. Also: Refactoring.

* Fix position of the Home-icon in TabBar (IOS-232)

TIL: Don't set an empty string, otherwise the position of the TabBarItem-icon breaks
  • Loading branch information
zeitschlag authored Apr 16, 2024
1 parent 6b32e5e commit b120d32
Show file tree
Hide file tree
Showing 16 changed files with 40 additions and 192 deletions.
18 changes: 8 additions & 10 deletions Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media

lazy var timelineSelectorButton = {
let button = UIButton(type: .custom)

button.setAttributedTitle(
.init(string: "Following", attributes: [
.init(string: L10n.Scene.HomeTimeline.TimelineMenu.following, attributes: [
.font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold))
]),
for: .normal)
Expand All @@ -61,15 +62,12 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media
config.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0)
config.imagePadding = 8
config.image = UIImage(systemName: "chevron.down.circle.fill", withConfiguration: imageConfiguration)
config.imagePlacement = .trailing
return config
}()

button.semanticContentAttribute =
UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft ?
.forceLeftToRight :
.forceRightToLeft
button.showsMenuAsPrimaryAction = true
button.menu = generateTimeSelectorMenu()
button.menu = generateTimelineSelectorMenu()
return button
}()

Expand Down Expand Up @@ -105,7 +103,7 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media
var timelinePillHiddenTopAnchor: NSLayoutConstraint?


private func generateTimeSelectorMenu() -> UIMenu {
private func generateTimelineSelectorMenu() -> UIMenu {
let showFollowingAction = UIAction(title: L10n.Scene.HomeTimeline.TimelineMenu.following, image: .init(systemName: "house")) { [weak self] _ in
guard let self, let viewModel = self.viewModel else { return }

Expand All @@ -120,7 +118,7 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media
for: .normal)

timelineSelectorButton.sizeToFit()
timelineSelectorButton.menu = generateTimeSelectorMenu()
timelineSelectorButton.menu = generateTimelineSelectorMenu()
}

let showLocalTimelineAction = UIAction(title: L10n.Scene.HomeTimeline.TimelineMenu.localCommunity, image: .init(systemName: "building.2")) { [weak self] action in
Expand All @@ -134,7 +132,7 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media
]),
for: .normal)
timelineSelectorButton.sizeToFit()
timelineSelectorButton.menu = generateTimeSelectorMenu()
timelineSelectorButton.menu = generateTimelineSelectorMenu()
}

if let viewModel {
Expand All @@ -157,7 +155,7 @@ extension HomeTimelineViewController {
override func viewDidLoad() {
super.viewDidLoad()

title = ""
title = nil
view.backgroundColor = .secondarySystemBackground

viewModel?.$displaySettingBarButtonItem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ extension NotificationView {
let metaUsername = PlaintextMetaContent(string: "@\(author.acct)")
authorUsernameLabel.configure(content: metaUsername)

let visibility = notification.entity.status?.mastodonVisibility ?? ._other("")
visibilityIconImageView.image = visibility.image

// notification type indicator
let notificationIndicatorText: MetaContent?
if let type = MastodonNotificationType(rawValue: notification.entity.type.rawValue) {
Expand Down Expand Up @@ -218,7 +215,7 @@ extension NotificationView {
.sink { [weak self] now in
guard let self, let type = MastodonNotificationType(rawValue: notification.entity.type.rawValue) else { return }

let formattedTimestamp = now.localizedTimeAgo(since: notification.entity.createdAt)
let formattedTimestamp = notification.entity.createdAt.localizedAbbreviatedSlowedTimeAgoSinceNow
dateLabel.configure(content: PlaintextMetaContent(string: formattedTimestamp))

self.accessibilityLabel = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,6 @@ public final class NotificationView: UIView {
// timestamp
public let dateLabel = MetaLabel(style: .statusUsername)

public let dateTrailingDotLabel: MetaLabel = {
let label = MetaLabel(style: .statusUsername)
label.configure(content: PlaintextMetaContent(string: "·"))
return label
}()

let visibilityIconImageView: UIImageView = {
let imageView = UIImageView()
imageView.tintColor = Asset.Colors.Label.secondary.color
imageView.contentMode = .scaleAspectFit
imageView.image = Mastodon.Entity.Status.Visibility.public.image.withRenderingMode(.alwaysTemplate)
return imageView
}()

public let menuButton: UIButton = {
let button = HitTestExpandedButton(type: .system)
button.tintColor = Asset.Colors.Label.secondary.color
Expand Down Expand Up @@ -280,29 +266,18 @@ extension NotificationView {
authrMetaContainer.addArrangedSubview(authorSecondaryMetaContainer)
authrMetaContainer.setCustomSpacing(4, after: authorSecondaryMetaContainer)

authorSecondaryMetaContainer.addArrangedSubview(authorUsernameLabel)
authorUsernameLabel.setContentHuggingPriority(.required - 1, for: .vertical)
authorUsernameLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)

authorSecondaryMetaContainer.addArrangedSubview(usernameTrialingDotLabel)
usernameTrialingDotLabel.setContentCompressionResistancePriority(.required, for: .horizontal)

authorSecondaryMetaContainer.addArrangedSubview(dateLabel)
dateLabel.setContentHuggingPriority(.required - 1, for: .horizontal)
dateLabel.setContentCompressionResistancePriority(.required - 1, for: .horizontal)

authorSecondaryMetaContainer.addArrangedSubview(dateTrailingDotLabel)
dateTrailingDotLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
authorSecondaryMetaContainer.addArrangedSubview(usernameTrialingDotLabel)
usernameTrialingDotLabel.setContentCompressionResistancePriority(.required, for: .horizontal)

authorSecondaryMetaContainer.addArrangedSubview(authorUsernameLabel)
authorUsernameLabel.setContentHuggingPriority(.required - 1, for: .vertical)
authorUsernameLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)

authorSecondaryMetaContainer.addArrangedSubview(visibilityIconImageView)
NSLayoutConstraint.activate([
visibilityIconImageView.heightAnchor.constraint(equalTo: authorUsernameLabel.heightAnchor),
visibilityIconImageView.widthAnchor.constraint(equalTo: visibilityIconImageView.heightAnchor),
])

authorSecondaryMetaContainer.addArrangedSubview(UIView())

authorSecondaryMetaContainer.setCustomSpacing(0, after: visibilityIconImageView)

// authorContainerViewBottomPaddingView
authorContainerViewBottomPaddingView.translatesAutoresizingMaskIntoConstraints = false
Expand Down

This file was deleted.

Binary file not shown.

This file was deleted.

Binary file not shown.

This file was deleted.

Binary file not shown.
3 changes: 0 additions & 3 deletions MastodonSDK/Sources/MastodonAsset/Generated/Assets.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ public typealias AssetImageTypeAlias = ImageAsset.Image
// swiftlint:disable identifier_name line_length nesting type_body_length type_name
public enum Asset {
public enum Arrow {
public static let `repeat` = ImageAsset(name: "Arrow/repeat")
public static let repeatSmall = ImageAsset(name: "Arrow/repeat.small")
public static let squareAndArrowUp = ImageAsset(name: "Arrow/square.and.arrow.up")
}
public enum Asset {
Expand Down Expand Up @@ -111,7 +109,6 @@ public enum Asset {
public static let systemOrange = ColorAsset(name: "Colors/system.orange")
}
public enum Communication {
public static let bubbleLeftAndBubbleRight = ImageAsset(name: "Communication/bubble.left.and.bubble.right")
public static let share = ImageAsset(name: "Communication/share")
}
public enum Connectivity {
Expand Down
39 changes: 5 additions & 34 deletions MastodonSDK/Sources/MastodonUI/Extension/Date.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,51 +15,22 @@ extension Date {

public static let relativeTimestampFormatter: RelativeDateTimeFormatter = {
let formatter = RelativeDateTimeFormatter()
formatter.locale = Locale.autoupdatingCurrent
formatter.dateTimeStyle = .numeric
formatter.unitsStyle = .full
formatter.unitsStyle = .abbreviated
return formatter
}()

public static let abbreviatedDateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium // e.g. Nov 23, 1937
formatter.timeStyle = .none // none
return formatter
}()

public var localizedSlowedTimeAgoSinceNow: String {
return self.localizedTimeAgo(since: Date(), isSlowed: true, isAbbreviated: false)
}

public var localizedTimeAgoSinceNow: String {
return self.localizedTimeAgo(since: Date())
}

public func localizedTimeAgo(since date: Date, isSlowed: Bool = false, isAbbreviated: Bool = false) -> String {
let earlierDate = date < self ? date : self
let latestDate = earlierDate == date ? self : date

if isSlowed, earlierDate.timeIntervalSince(latestDate) >= -60 {
return L10n.Common.Controls.Timeline.Timestamp.now
} else {
if isAbbreviated {
return latestDate.localizedShortTimeAgo(since: earlierDate)
} else {
if earlierDate.timeIntervalSince(latestDate) < -(7 * 24 * 60 * 60) {
let currentYear = Date.calendar.dateComponents([.year], from: Date())
let earlierDateYear = Date.calendar.dateComponents([.year], from: earlierDate)
if currentYear.year! > earlierDateYear.year! {
return earlierDate.formatted(.dateTime.year().month(.abbreviated).day())
} else {
return earlierDate.formatted(.dateTime.month(.abbreviated).day())
}
} else {
return Date.relativeTimestampFormatter.localizedString(for: earlierDate, relativeTo: latestDate)
}
}
}
public var localizedAbbreviatedSlowedTimeAgoSinceNow: String {
return Date.relativeTimestampFormatter.localizedString(for: self, relativeTo: Date())
}

}

extension Date {
Expand Down
37 changes: 5 additions & 32 deletions MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,6 @@ public class StatusAuthorView: UIStackView {
// timestamp
public let dateLabel = MetaLabel(style: .statusUsername)

public let dateTrailingDotLabel: MetaLabel = {
let label = MetaLabel(style: .statusUsername)
label.configure(content: PlaintextMetaContent(string: "·"))
return label
}()

let visibilityIconImageView: UIImageView = {
let imageView = UIImageView()
imageView.tintColor = Asset.Colors.Label.secondary.color
imageView.contentMode = .scaleAspectFit
imageView.image = Mastodon.Entity.Status.Visibility.public.image
return imageView
}()

public let menuButton: UIButton = {
let button = HitTestExpandedButton(type: .system)
button.expandEdgeInsets = UIEdgeInsets(top: -20, left: -10, bottom: -10, right: -10)
Expand Down Expand Up @@ -150,8 +136,6 @@ extension StatusAuthorView {

// dateLabel
dateLabel.isUserInteractionEnabled = false

visibilityIconImageView.isUserInteractionEnabled = false
}
}

Expand Down Expand Up @@ -306,27 +290,16 @@ extension StatusAuthorView {
authorSecondaryMetaContainer.spacing = 4
authorMetaContainer.addArrangedSubview(authorSecondaryMetaContainer)

authorSecondaryMetaContainer.addArrangedSubview(authorUsernameLabel)
authorUsernameLabel.setContentHuggingPriority(.required - 1, for: .vertical)
authorUsernameLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)

authorSecondaryMetaContainer.addArrangedSubview(usernameTrialingDotLabel)
usernameTrialingDotLabel.setContentCompressionResistancePriority(.required, for: .horizontal)

authorSecondaryMetaContainer.addArrangedSubview(dateLabel)
dateLabel.setContentHuggingPriority(.required - 1, for: .horizontal)
dateLabel.setContentCompressionResistancePriority(.required - 1, for: .horizontal)

authorSecondaryMetaContainer.addArrangedSubview(dateTrailingDotLabel)
dateTrailingDotLabel.setContentCompressionResistancePriority(.required, for: .horizontal)

authorSecondaryMetaContainer.addArrangedSubview(visibilityIconImageView)
NSLayoutConstraint.activate([
visibilityIconImageView.heightAnchor.constraint(equalTo: authorUsernameLabel.heightAnchor),
visibilityIconImageView.widthAnchor.constraint(equalTo: visibilityIconImageView.heightAnchor),
])
authorSecondaryMetaContainer.addArrangedSubview(usernameTrialingDotLabel)
usernameTrialingDotLabel.setContentCompressionResistancePriority(.required, for: .horizontal)

authorSecondaryMetaContainer.setCustomSpacing(0, after: visibilityIconImageView)
authorSecondaryMetaContainer.addArrangedSubview(authorUsernameLabel)
authorUsernameLabel.setContentHuggingPriority(.required - 1, for: .vertical)
authorUsernameLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)

authorSecondaryMetaContainer.addArrangedSubview(UIView())
}
Expand Down
18 changes: 3 additions & 15 deletions MastodonSDK/Sources/MastodonUI/View/Content/StatusMetricView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,9 @@ public final class StatusMetricView: UIView {
return stackView
}()

public let reblogButton: StatusMetricRowView = {
let button = StatusMetricRowView(iconImage: Asset.Arrow.repeat.image, text: L10n.Common.Controls.Status.Buttons.reblogsTitle, detailText: "")
return button
}()

// favorite meter
public let favoriteButton: StatusMetricRowView = {
let button = StatusMetricRowView(iconImage: UIImage(systemName: "star"), text: L10n.Common.Controls.Status.Buttons.favoritesTitle, detailText: "")
return button
}()

public let editHistoryButton: StatusMetricRowView = {
let button = StatusMetricRowView(iconImage: Asset.Scene.EditHistory.edit.image, text: L10n.Common.Controls.Status.Buttons.editHistoryTitle)
return button
}()
public let reblogButton = StatusMetricRowView(iconImage: UIImage(systemName: "arrow.2.squarepath")!, text: L10n.Common.Controls.Status.Buttons.reblogsTitle, detailText: "")
public let favoriteButton = StatusMetricRowView(iconImage: UIImage(systemName: "star"), text: L10n.Common.Controls.Status.Buttons.favoritesTitle, detailText: "")
public let editHistoryButton = StatusMetricRowView(iconImage: Asset.Scene.EditHistory.edit.image, text: L10n.Common.Controls.Status.Buttons.editHistoryTitle)

public override init(frame: CGRect) {
super.init(frame: frame)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,10 @@ extension StatusView {
// timestamp
viewModel.timestampFormatter = { (date: Date, isEdited: Bool) in
if isEdited {
return L10n.Common.Controls.Status.editedAtTimestampPrefix(date.localizedSlowedTimeAgoSinceNow)
return L10n.Common.Controls.Status.editedAtTimestampPrefix(date.localizedAbbreviatedSlowedTimeAgoSinceNow)
} else {
return date.localizedAbbreviatedSlowedTimeAgoSinceNow
}
return date.localizedSlowedTimeAgoSinceNow
}
viewModel.timestamp = timestamp
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ extension StatusView.ViewModel {
case .none:
return
case .repost(let info):
statusView.headerIconImageView.image = Asset.Arrow.repeatSmall.image.withRenderingMode(.alwaysTemplate)
statusView.headerIconImageView.image = UIImage(systemName: "repeat")!.withRenderingMode(.alwaysTemplate)
statusView.headerInfoLabel.configure(content: info.header)
statusView.setHeaderDisplay()
case .reply(let info):
Expand Down Expand Up @@ -293,17 +293,10 @@ extension StatusView.ViewModel {
.store(in: &disposeBag)

$timestampText
.sink { [weak self] text in
guard let _ = self else { return }
.sink { text in
authorView.dateLabel.configure(content: PlaintextMetaContent(string: text))
}
.store(in: &disposeBag)

$visibility
.sink { visibility in
authorView.visibilityIconImageView.image = visibility.image
}
.store(in: &disposeBag)
}

private func bindContent(statusView: StatusView) {
Expand Down
Loading

0 comments on commit b120d32

Please sign in to comment.