Don't use publisher for most properties in NotificationView (IOS-192)
Timestamp and A11y are still missing (and A11y is broken atm)
This commit is contained in:
parent
ab2f54307f
commit
018cf54084
|
@ -73,7 +73,6 @@ extension NotificationSection {
|
|||
viewModel: NotificationTableViewCell.ViewModel,
|
||||
configuration: Configuration
|
||||
) {
|
||||
cell.notificationView.viewModel.context = context
|
||||
cell.notificationView.viewModel.authContext = configuration.authContext
|
||||
|
||||
StatusSection.setupStatusPollDataSource(
|
||||
|
|
|
@ -64,23 +64,32 @@ extension NotificationView {
|
|||
let author = notification.account
|
||||
|
||||
// author avatar
|
||||
viewModel.authorAvatarImageURL = author.avatarImageURL()
|
||||
let configuration = AvatarImageView.Configuration(url: author.avatarImageURL())
|
||||
avatarButton.avatarImageView.configure(configuration: configuration)
|
||||
avatarButton.avatarImageView.configure(cornerConfiguration: .init(corner: .fixed(radius: 12)))
|
||||
|
||||
// author name
|
||||
let metaAuthorName: MetaContent
|
||||
do {
|
||||
let content = MastodonContent(content: author.displayNameWithFallback, emojis: author.emojis.asDictionary)
|
||||
viewModel.authorName = try MastodonMetaContent.convert(document: content)
|
||||
metaAuthorName = try MastodonMetaContent.convert(document: content)
|
||||
} catch {
|
||||
assertionFailure(error.localizedDescription)
|
||||
viewModel.authorName = PlaintextMetaContent(string: author.displayNameWithFallback)
|
||||
metaAuthorName = PlaintextMetaContent(string: author.displayNameWithFallback)
|
||||
}
|
||||
authorNameLabel.configure(content: metaAuthorName)
|
||||
|
||||
// username
|
||||
let metaUsername = PlaintextMetaContent(string: "@\(author.acct)")
|
||||
authorUsernameLabel.configure(content: metaUsername)
|
||||
|
||||
viewModel.authorUsername = author.acct
|
||||
viewModel.timestamp = notification.entity.createdAt
|
||||
|
||||
viewModel.visibility = notification.entity.status?.mastodonVisibility ?? ._other("")
|
||||
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) {
|
||||
self.viewModel.type = type
|
||||
|
||||
|
@ -92,64 +101,81 @@ extension NotificationView {
|
|||
}
|
||||
return metaContent
|
||||
}
|
||||
|
||||
|
||||
switch type {
|
||||
case .follow:
|
||||
self.viewModel.notificationIndicatorText = createMetaContent(
|
||||
notificationIndicatorText = createMetaContent(
|
||||
text: L10n.Scene.Notification.NotificationDescription.followedYou,
|
||||
emojis: author.emojis.asDictionary
|
||||
)
|
||||
case .followRequest:
|
||||
self.viewModel.notificationIndicatorText = createMetaContent(
|
||||
notificationIndicatorText = createMetaContent(
|
||||
text: L10n.Scene.Notification.NotificationDescription.requestToFollowYou,
|
||||
emojis: author.emojis.asDictionary
|
||||
)
|
||||
case .mention:
|
||||
self.viewModel.notificationIndicatorText = createMetaContent(
|
||||
notificationIndicatorText = createMetaContent(
|
||||
text: L10n.Scene.Notification.NotificationDescription.mentionedYou,
|
||||
emojis: author.emojis.asDictionary
|
||||
)
|
||||
case .reblog:
|
||||
self.viewModel.notificationIndicatorText = createMetaContent(
|
||||
notificationIndicatorText = createMetaContent(
|
||||
text: L10n.Scene.Notification.NotificationDescription.rebloggedYourPost,
|
||||
emojis: author.emojis.asDictionary
|
||||
)
|
||||
case .favourite:
|
||||
self.viewModel.notificationIndicatorText = createMetaContent(
|
||||
notificationIndicatorText = createMetaContent(
|
||||
text: L10n.Scene.Notification.NotificationDescription.favoritedYourPost,
|
||||
emojis: author.emojis.asDictionary
|
||||
)
|
||||
case .poll:
|
||||
self.viewModel.notificationIndicatorText = createMetaContent(
|
||||
notificationIndicatorText = createMetaContent(
|
||||
text: L10n.Scene.Notification.NotificationDescription.pollHasEnded,
|
||||
emojis: author.emojis.asDictionary
|
||||
)
|
||||
case .status:
|
||||
self.viewModel.notificationIndicatorText = createMetaContent(
|
||||
notificationIndicatorText = createMetaContent(
|
||||
text: .empty,
|
||||
emojis: author.emojis.asDictionary
|
||||
)
|
||||
case ._other:
|
||||
self.viewModel.notificationIndicatorText = nil
|
||||
notificationIndicatorText = nil
|
||||
}
|
||||
} else {
|
||||
self.viewModel.notificationIndicatorText = nil
|
||||
notificationIndicatorText = nil
|
||||
}
|
||||
|
||||
|
||||
if let notificationIndicatorText {
|
||||
notificationTypeIndicatorLabel.configure(content: notificationIndicatorText)
|
||||
} else {
|
||||
notificationTypeIndicatorLabel.reset()
|
||||
}
|
||||
|
||||
if let me = viewModel.authContext?.mastodonAuthenticationBox.authentication.account() {
|
||||
viewModel.isMyself = (author == me)
|
||||
|
||||
let isMyself = (author == me)
|
||||
let isMuting: Bool
|
||||
let isBlocking: Bool
|
||||
|
||||
if let relationship = notification.relationship {
|
||||
viewModel.isMuting = relationship.muting
|
||||
viewModel.isBlocking = relationship.blocking || relationship.domainBlocking
|
||||
viewModel.isFollowed = relationship.following
|
||||
isMuting = relationship.muting
|
||||
isBlocking = relationship.blocking || relationship.domainBlocking
|
||||
} else {
|
||||
viewModel.isMuting = false
|
||||
viewModel.isBlocking = false
|
||||
viewModel.isFollowed = false
|
||||
isMuting = false
|
||||
isBlocking = false
|
||||
}
|
||||
|
||||
let menuContext = NotificationView.AuthorMenuContext(name: metaAuthorName.string, isMuting: isMuting, isBlocking: isBlocking, isMyself: isMyself)
|
||||
let (menu, actions) = setupAuthorMenu(menuContext: menuContext)
|
||||
menuButton.menu = menu
|
||||
authorActions = actions
|
||||
menuButton.showsMenuAsPrimaryAction = true
|
||||
|
||||
menuButton.isHidden = menuContext.isMyself
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
viewModel.followRequestState = notification.followRequestState
|
||||
viewModel.transientFollowRequestState = notification.transientFollowRequestState
|
||||
}
|
||||
|
|
|
@ -21,25 +21,15 @@ extension NotificationView {
|
|||
public final class ViewModel: ObservableObject {
|
||||
public var disposeBag = Set<AnyCancellable>()
|
||||
|
||||
@Published public var context: AppContext?
|
||||
@Published public var authContext: AuthContext?
|
||||
|
||||
@Published public var type: MastodonNotificationType?
|
||||
@Published public var notificationIndicatorText: MetaContent?
|
||||
|
||||
@Published public var authorAvatarImageURL: URL?
|
||||
@Published public var authorName: MetaContent?
|
||||
@Published public var authorUsername: String?
|
||||
|
||||
@Published public var isMyself = false
|
||||
@Published public var isMuting = false
|
||||
@Published public var isBlocking = false
|
||||
@Published public var isTranslated = false
|
||||
@Published public var isFollowed = false
|
||||
|
||||
|
||||
@Published public var timestamp: Date?
|
||||
|
||||
@Published public var visibility: MastodonVisibility = .public
|
||||
|
||||
@Published public var followRequestState = MastodonFollowRequestState(state: .none)
|
||||
@Published public var transientFollowRequestState = MastodonFollowRequestState(state: .none)
|
||||
|
@ -54,12 +44,8 @@ extension NotificationView {
|
|||
extension NotificationView.ViewModel {
|
||||
func bind(notificationView: NotificationView) {
|
||||
bindAuthor(notificationView: notificationView)
|
||||
bindAuthorMenu(notificationView: notificationView)
|
||||
bindFollowRequest(notificationView: notificationView)
|
||||
|
||||
$context
|
||||
.assign(to: \.context, on: notificationView.statusView.viewModel)
|
||||
.store(in: &disposeBag)
|
||||
$authContext
|
||||
.assign(to: \.authContext, on: notificationView.statusView.viewModel)
|
||||
.store(in: &disposeBag)
|
||||
|
@ -69,33 +55,6 @@ extension NotificationView.ViewModel {
|
|||
}
|
||||
|
||||
private func bindAuthor(notificationView: NotificationView) {
|
||||
// avatar
|
||||
|
||||
$authorAvatarImageURL
|
||||
.sink { url in
|
||||
let configuration = AvatarImageView.Configuration(url: url)
|
||||
notificationView.avatarButton.avatarImageView.configure(configuration: configuration)
|
||||
notificationView.avatarButton.avatarImageView.configure(cornerConfiguration: .init(corner: .fixed(radius: 12)))
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
// name
|
||||
$authorName
|
||||
.sink { metaContent in
|
||||
let metaContent = metaContent ?? PlaintextMetaContent(string: " ")
|
||||
notificationView.authorNameLabel.configure(content: metaContent)
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
// username
|
||||
$authorUsername
|
||||
.map { text -> String in
|
||||
guard let text = text else { return "" }
|
||||
return "@\(text)"
|
||||
}
|
||||
.sink { username in
|
||||
let metaContent = PlaintextMetaContent(string: username)
|
||||
notificationView.authorUsernameLabel.configure(content: metaContent)
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
// timestamp
|
||||
let formattedTimestamp = Publishers.CombineLatest(
|
||||
$timestamp,
|
||||
|
@ -112,23 +71,6 @@ extension NotificationView.ViewModel {
|
|||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
$visibility
|
||||
.sink { visibility in
|
||||
notificationView.visibilityIconImageView.image = visibility.image
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
// notification type indicator
|
||||
$notificationIndicatorText
|
||||
.sink { text in
|
||||
if let text = text {
|
||||
notificationView.notificationTypeIndicatorLabel.configure(content: text)
|
||||
} else {
|
||||
notificationView.notificationTypeIndicatorLabel.reset()
|
||||
}
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
Publishers.CombineLatest4(
|
||||
$authorName,
|
||||
$authorUsername,
|
||||
|
@ -197,30 +139,6 @@ extension NotificationView.ViewModel {
|
|||
.store(in: &disposeBag)
|
||||
}
|
||||
|
||||
private func bindAuthorMenu(notificationView: NotificationView) {
|
||||
Publishers.CombineLatest4(
|
||||
$authorName,
|
||||
$isMuting,
|
||||
$isBlocking,
|
||||
$isMyself
|
||||
)
|
||||
.sink { [weak self] authorName, isMuting, isBlocking, isMyself in
|
||||
guard let name = authorName?.string else {
|
||||
notificationView.menuButton.menu = nil
|
||||
return
|
||||
}
|
||||
|
||||
let menuContext = NotificationView.AuthorMenuContext(name: name, isMuting: isMuting, isBlocking: isBlocking, isMyself: isMyself)
|
||||
let (menu, actions) = notificationView.setupAuthorMenu(menuContext: menuContext)
|
||||
notificationView.menuButton.menu = menu
|
||||
notificationView.authorActions = actions
|
||||
notificationView.menuButton.showsMenuAsPrimaryAction = true
|
||||
|
||||
notificationView.menuButton.isHidden = menuContext.isMyself
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
}
|
||||
|
||||
private func bindFollowRequest(notificationView: NotificationView) {
|
||||
Publishers.CombineLatest(
|
||||
$followRequestState,
|
||||
|
|
|
@ -181,7 +181,7 @@ public final class NotificationView: UIView {
|
|||
disposeBag.removeAll()
|
||||
|
||||
viewModel.authContext = nil
|
||||
viewModel.authorAvatarImageURL = nil
|
||||
avatarButton.avatarImageView.image = nil
|
||||
avatarButton.avatarImageView.cancelTask()
|
||||
|
||||
authorContainerViewBottomPaddingView.isHidden = true
|
||||
|
|
Loading…
Reference in New Issue