Notification timestamps
This commit is contained in:
parent
95845057c5
commit
1f590ddf09
|
@ -198,6 +198,7 @@ extension ContentDatabase {
|
||||||
t.column("id", .text).primaryKey(onConflict: .replace)
|
t.column("id", .text).primaryKey(onConflict: .replace)
|
||||||
t.column("type", .text).notNull()
|
t.column("type", .text).notNull()
|
||||||
t.column("accountId", .text).notNull().references("accountRecord", onDelete: .cascade)
|
t.column("accountId", .text).notNull().references("accountRecord", onDelete: .cascade)
|
||||||
|
t.column("createdAt", .datetime).notNull()
|
||||||
t.column("statusId").references("statusRecord", onDelete: .cascade)
|
t.column("statusId").references("statusRecord", onDelete: .cascade)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ struct NotificationRecord: ContentDatabaseRecord, Hashable {
|
||||||
let id: String
|
let id: String
|
||||||
let type: MastodonNotification.NotificationType
|
let type: MastodonNotification.NotificationType
|
||||||
let accountId: Account.Id
|
let accountId: Account.Id
|
||||||
|
let createdAt: Date
|
||||||
let statusId: Status.Id?
|
let statusId: Status.Id?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ extension NotificationRecord {
|
||||||
static let id = Column(CodingKeys.id)
|
static let id = Column(CodingKeys.id)
|
||||||
static let type = Column(CodingKeys.type)
|
static let type = Column(CodingKeys.type)
|
||||||
static let accountId = Column(CodingKeys.accountId)
|
static let accountId = Column(CodingKeys.accountId)
|
||||||
|
static let createdAt = Column(CodingKeys.createdAt)
|
||||||
static let statusId = Column(CodingKeys.statusId)
|
static let statusId = Column(CodingKeys.statusId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +28,7 @@ extension NotificationRecord {
|
||||||
id = notification.id
|
id = notification.id
|
||||||
type = notification.type
|
type = notification.type
|
||||||
accountId = notification.account.id
|
accountId = notification.account.id
|
||||||
|
createdAt = notification.createdAt
|
||||||
statusId = notification.status?.id
|
statusId = notification.status?.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ extension MastodonNotification {
|
||||||
id: info.record.id,
|
id: info.record.id,
|
||||||
type: info.record.type,
|
type: info.record.type,
|
||||||
account: .init(info: info.accountInfo),
|
account: .init(info: info.accountInfo),
|
||||||
|
createdAt: info.record.createdAt,
|
||||||
status: status)
|
status: status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,18 @@ public struct MastodonNotification: Codable, Hashable {
|
||||||
public let id: Id
|
public let id: Id
|
||||||
public let type: NotificationType
|
public let type: NotificationType
|
||||||
public let account: Account
|
public let account: Account
|
||||||
|
public let createdAt: Date
|
||||||
public let status: Status?
|
public let status: Status?
|
||||||
|
|
||||||
public init(id: String, type: MastodonNotification.NotificationType, account: Account, status: Status?) {
|
public init(id: String,
|
||||||
|
type: MastodonNotification.NotificationType,
|
||||||
|
account: Account,
|
||||||
|
createdAt: Date,
|
||||||
|
status: Status?) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.type = type
|
self.type = type
|
||||||
self.account = account
|
self.account = account
|
||||||
|
self.createdAt = createdAt
|
||||||
self.status = status
|
self.status = status
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,8 @@ public extension NotificationViewModel {
|
||||||
notificationService.notification.type
|
notificationService.notification.type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var time: String? { notificationService.notification.createdAt.timeAgo }
|
||||||
|
|
||||||
func accountSelected() {
|
func accountSelected() {
|
||||||
eventsSubject.send(
|
eventsSubject.send(
|
||||||
Just(.navigation(
|
Just(.navigation(
|
||||||
|
|
|
@ -10,6 +10,7 @@ final class NotificationView: UIView {
|
||||||
private let avatarImageView = AnimatedImageView()
|
private let avatarImageView = AnimatedImageView()
|
||||||
private let avatarButton = UIButton()
|
private let avatarButton = UIButton()
|
||||||
private let typeLabel = UILabel()
|
private let typeLabel = UILabel()
|
||||||
|
private let timeLabel = UILabel()
|
||||||
private let displayNameLabel = UILabel()
|
private let displayNameLabel = UILabel()
|
||||||
private let accountLabel = UILabel()
|
private let accountLabel = UILabel()
|
||||||
private let statusBodyView = StatusBodyView()
|
private let statusBodyView = StatusBodyView()
|
||||||
|
@ -75,24 +76,29 @@ private extension NotificationView {
|
||||||
func initialSetup() {
|
func initialSetup() {
|
||||||
let containerStackView = UIStackView()
|
let containerStackView = UIStackView()
|
||||||
let sideStackView = UIStackView()
|
let sideStackView = UIStackView()
|
||||||
|
let typeTimeStackView = UIStackView()
|
||||||
let mainStackView = UIStackView()
|
let mainStackView = UIStackView()
|
||||||
|
|
||||||
addSubview(containerStackView)
|
addSubview(containerStackView)
|
||||||
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
containerStackView.spacing = .defaultSpacing
|
containerStackView.spacing = .defaultSpacing
|
||||||
|
containerStackView.alignment = .top
|
||||||
|
|
||||||
sideStackView.axis = .vertical
|
sideStackView.axis = .vertical
|
||||||
sideStackView.alignment = .trailing
|
sideStackView.alignment = .trailing
|
||||||
sideStackView.spacing = .compactSpacing
|
sideStackView.spacing = .compactSpacing
|
||||||
sideStackView.addArrangedSubview(iconImageView)
|
sideStackView.addArrangedSubview(iconImageView)
|
||||||
sideStackView.addArrangedSubview(avatarImageView)
|
sideStackView.addArrangedSubview(avatarImageView)
|
||||||
sideStackView.addArrangedSubview(UIView())
|
|
||||||
containerStackView.addArrangedSubview(sideStackView)
|
containerStackView.addArrangedSubview(sideStackView)
|
||||||
|
|
||||||
|
typeTimeStackView.spacing = .compactSpacing
|
||||||
|
typeTimeStackView.alignment = .top
|
||||||
|
|
||||||
mainStackView.axis = .vertical
|
mainStackView.axis = .vertical
|
||||||
mainStackView.spacing = .compactSpacing
|
mainStackView.spacing = .compactSpacing
|
||||||
mainStackView.addArrangedSubview(typeLabel)
|
typeTimeStackView.addArrangedSubview(typeLabel)
|
||||||
mainStackView.addSubview(UIView())
|
typeTimeStackView.addArrangedSubview(timeLabel)
|
||||||
|
mainStackView.addArrangedSubview(typeTimeStackView)
|
||||||
mainStackView.addArrangedSubview(statusBodyView)
|
mainStackView.addArrangedSubview(statusBodyView)
|
||||||
mainStackView.addArrangedSubview(displayNameLabel)
|
mainStackView.addArrangedSubview(displayNameLabel)
|
||||||
mainStackView.addArrangedSubview(accountLabel)
|
mainStackView.addArrangedSubview(accountLabel)
|
||||||
|
@ -121,6 +127,12 @@ private extension NotificationView {
|
||||||
typeLabel.adjustsFontForContentSizeCategory = true
|
typeLabel.adjustsFontForContentSizeCategory = true
|
||||||
typeLabel.numberOfLines = 0
|
typeLabel.numberOfLines = 0
|
||||||
|
|
||||||
|
timeLabel.font = .preferredFont(forTextStyle: .subheadline)
|
||||||
|
timeLabel.adjustsFontForContentSizeCategory = true
|
||||||
|
timeLabel.textColor = .secondaryLabel
|
||||||
|
timeLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||||
|
timeLabel.setContentHuggingPriority(.required, for: .horizontal)
|
||||||
|
|
||||||
statusBodyView.alpha = 0.5
|
statusBodyView.alpha = 0.5
|
||||||
statusBodyView.isUserInteractionEnabled = false
|
statusBodyView.isUserInteractionEnabled = false
|
||||||
|
|
||||||
|
@ -205,6 +217,8 @@ private extension NotificationView {
|
||||||
accountLabel.isHidden = true
|
accountLabel.isHidden = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timeLabel.text = viewModel.time
|
||||||
|
|
||||||
iconImageView.image = UIImage(
|
iconImageView.image = UIImage(
|
||||||
systemName: viewModel.type.systemImageName,
|
systemName: viewModel.type.systemImageName,
|
||||||
withConfiguration: UIImage.SymbolConfiguration(scale: .medium))
|
withConfiguration: UIImage.SymbolConfiguration(scale: .medium))
|
||||||
|
|
Loading…
Reference in New Issue