2022-01-27 14:23:39 +01:00
|
|
|
//
|
|
|
|
// NotificationView+Configuration.swift
|
|
|
|
// Mastodon
|
|
|
|
//
|
|
|
|
// Created by MainasuK on 2022-1-21.
|
|
|
|
//
|
|
|
|
|
|
|
|
import UIKit
|
|
|
|
import Combine
|
|
|
|
import MastodonUI
|
|
|
|
import CoreDataStack
|
|
|
|
import MetaTextKit
|
|
|
|
import MastodonMeta
|
|
|
|
import Meta
|
|
|
|
import MastodonAsset
|
2022-10-08 07:43:06 +02:00
|
|
|
import MastodonCore
|
2022-01-27 14:23:39 +01:00
|
|
|
import MastodonLocalization
|
|
|
|
import class CoreDataStack.Notification
|
2023-11-22 12:32:04 +01:00
|
|
|
import MastodonSDK
|
2022-01-27 14:23:39 +01:00
|
|
|
|
|
|
|
extension NotificationView {
|
2023-11-22 12:32:04 +01:00
|
|
|
public func configure(feed: MastodonFeed) {
|
|
|
|
guard
|
|
|
|
let notification = feed.notification,
|
|
|
|
let managedObjectContext = viewModel.context?.managedObjectContext
|
|
|
|
else {
|
2022-01-27 14:23:39 +01:00
|
|
|
assertionFailure()
|
|
|
|
return
|
|
|
|
}
|
2023-11-22 12:32:04 +01:00
|
|
|
|
|
|
|
MastodonNotification.fromEntity(notification, using: managedObjectContext).map(configure(notification:))
|
2022-01-27 14:23:39 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension NotificationView {
|
2023-11-22 12:32:04 +01:00
|
|
|
public func configure(notification: MastodonNotification) {
|
2022-06-30 09:02:24 +02:00
|
|
|
viewModel.objects.insert(notification)
|
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
configureAuthor(notification: notification)
|
2023-11-22 12:32:04 +01:00
|
|
|
|
|
|
|
switch notification.entity.type {
|
2022-06-28 13:00:39 +02:00
|
|
|
case .follow:
|
|
|
|
setAuthorContainerBottomPaddingViewDisplay()
|
|
|
|
case .followRequest:
|
|
|
|
setFollowRequestAdaptiveMarginContainerViewDisplay()
|
|
|
|
case .mention, .status:
|
|
|
|
if let status = notification.status {
|
2022-01-27 14:23:39 +01:00
|
|
|
statusView.configure(status: status)
|
|
|
|
setStatusViewDisplay()
|
2022-06-28 13:00:39 +02:00
|
|
|
}
|
|
|
|
case .reblog, .favourite, .poll:
|
|
|
|
if let status = notification.status {
|
2022-01-27 14:23:39 +01:00
|
|
|
quoteStatusView.configure(status: status)
|
|
|
|
setQuoteStatusViewDisplay()
|
|
|
|
}
|
2022-06-28 13:00:39 +02:00
|
|
|
case ._other:
|
2022-01-27 14:23:39 +01:00
|
|
|
setAuthorContainerBottomPaddingViewDisplay()
|
2022-06-28 13:00:39 +02:00
|
|
|
assertionFailure()
|
2022-01-27 14:23:39 +01:00
|
|
|
}
|
2022-06-28 13:00:39 +02:00
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension NotificationView {
|
2023-11-22 12:32:04 +01:00
|
|
|
private func configureAuthor(notification: MastodonNotification) {
|
2022-01-27 14:23:39 +01:00
|
|
|
let author = notification.account
|
|
|
|
// author avatar
|
|
|
|
|
|
|
|
Publishers.CombineLatest(
|
|
|
|
author.publisher(for: \.avatar),
|
|
|
|
UserDefaults.shared.publisher(for: \.preferredStaticAvatar)
|
|
|
|
)
|
|
|
|
.map { _ in author.avatarImageURL() }
|
|
|
|
.assign(to: \.authorAvatarImageURL, on: viewModel)
|
|
|
|
.store(in: &disposeBag)
|
|
|
|
|
|
|
|
// author name
|
|
|
|
Publishers.CombineLatest(
|
|
|
|
author.publisher(for: \.displayName),
|
|
|
|
author.publisher(for: \.emojis)
|
|
|
|
)
|
|
|
|
.map { _, emojis in
|
|
|
|
do {
|
|
|
|
let content = MastodonContent(content: author.displayNameWithFallback, emojis: emojis.asDictionary)
|
|
|
|
let metaContent = try MastodonMetaContent.convert(document: content)
|
|
|
|
return metaContent
|
|
|
|
} catch {
|
|
|
|
assertionFailure(error.localizedDescription)
|
|
|
|
return PlaintextMetaContent(string: author.displayNameWithFallback)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.assign(to: \.authorName, on: viewModel)
|
|
|
|
.store(in: &disposeBag)
|
|
|
|
// author username
|
|
|
|
author.publisher(for: \.acct)
|
|
|
|
.map { $0 as String? }
|
|
|
|
.assign(to: \.authorUsername, on: viewModel)
|
|
|
|
.store(in: &disposeBag)
|
|
|
|
// timestamp
|
2023-11-22 12:32:04 +01:00
|
|
|
viewModel.timestamp = notification.entity.createdAt
|
2023-08-28 12:58:46 +02:00
|
|
|
|
2023-11-22 12:32:04 +01:00
|
|
|
viewModel.visibility = notification.entity.status?.mastodonVisibility ?? ._other("")
|
2023-08-28 12:58:46 +02:00
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
// notification type indicator
|
2023-11-22 12:32:04 +01:00
|
|
|
Publishers.CombineLatest(
|
2022-01-27 14:23:39 +01:00
|
|
|
author.publisher(for: \.displayName),
|
|
|
|
author.publisher(for: \.emojis)
|
|
|
|
)
|
2023-11-22 12:32:04 +01:00
|
|
|
.sink { [weak self] _, emojis in
|
2022-01-27 14:23:39 +01:00
|
|
|
guard let self = self else { return }
|
2023-11-22 12:32:04 +01:00
|
|
|
guard let type = MastodonNotificationType(rawValue: notification.entity.type.rawValue) else {
|
2022-01-27 14:23:39 +01:00
|
|
|
self.viewModel.notificationIndicatorText = nil
|
|
|
|
return
|
|
|
|
}
|
2022-11-09 22:33:54 +01:00
|
|
|
self.viewModel.type = type
|
2022-01-29 12:51:40 +01:00
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
func createMetaContent(text: String, emojis: MastodonContent.Emojis) -> MetaContent {
|
|
|
|
let content = MastodonContent(content: text, emojis: emojis)
|
|
|
|
guard let metaContent = try? MastodonMetaContent.convert(document: content) else {
|
|
|
|
return PlaintextMetaContent(string: text)
|
|
|
|
}
|
|
|
|
return metaContent
|
|
|
|
}
|
2022-01-29 12:51:40 +01:00
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
// TODO: fix the i18n. The subject should assert place at the string beginning
|
|
|
|
switch type {
|
|
|
|
case .follow:
|
|
|
|
self.viewModel.notificationIndicatorText = createMetaContent(
|
2022-02-15 07:45:34 +01:00
|
|
|
text: L10n.Scene.Notification.NotificationDescription.followedYou,
|
2022-01-27 14:23:39 +01:00
|
|
|
emojis: emojis.asDictionary
|
|
|
|
)
|
|
|
|
case .followRequest:
|
|
|
|
self.viewModel.notificationIndicatorText = createMetaContent(
|
2022-02-15 07:45:34 +01:00
|
|
|
text: L10n.Scene.Notification.NotificationDescription.requestToFollowYou,
|
2022-01-27 14:23:39 +01:00
|
|
|
emojis: emojis.asDictionary
|
|
|
|
)
|
|
|
|
case .mention:
|
|
|
|
self.viewModel.notificationIndicatorText = createMetaContent(
|
2022-02-15 07:45:34 +01:00
|
|
|
text: L10n.Scene.Notification.NotificationDescription.mentionedYou,
|
2022-01-27 14:23:39 +01:00
|
|
|
emojis: emojis.asDictionary
|
|
|
|
)
|
|
|
|
case .reblog:
|
|
|
|
self.viewModel.notificationIndicatorText = createMetaContent(
|
2022-02-15 07:45:34 +01:00
|
|
|
text: L10n.Scene.Notification.NotificationDescription.rebloggedYourPost,
|
2022-01-27 14:23:39 +01:00
|
|
|
emojis: emojis.asDictionary
|
|
|
|
)
|
|
|
|
case .favourite:
|
|
|
|
self.viewModel.notificationIndicatorText = createMetaContent(
|
2022-02-15 07:45:34 +01:00
|
|
|
text: L10n.Scene.Notification.NotificationDescription.favoritedYourPost,
|
2022-01-27 14:23:39 +01:00
|
|
|
emojis: emojis.asDictionary
|
|
|
|
)
|
|
|
|
case .poll:
|
|
|
|
self.viewModel.notificationIndicatorText = createMetaContent(
|
2022-02-15 07:45:34 +01:00
|
|
|
text: L10n.Scene.Notification.NotificationDescription.pollHasEnded,
|
2022-01-27 14:23:39 +01:00
|
|
|
emojis: emojis.asDictionary
|
|
|
|
)
|
|
|
|
case .status:
|
|
|
|
self.viewModel.notificationIndicatorText = createMetaContent(
|
2022-11-18 10:54:40 +01:00
|
|
|
text: .empty,
|
2022-01-27 14:23:39 +01:00
|
|
|
emojis: emojis.asDictionary
|
|
|
|
)
|
|
|
|
case ._other:
|
|
|
|
self.viewModel.notificationIndicatorText = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.store(in: &disposeBag)
|
2022-10-09 14:07:57 +02:00
|
|
|
|
|
|
|
let authContext = viewModel.authContext
|
2022-01-27 14:23:39 +01:00
|
|
|
// isMuting
|
2022-10-09 14:07:57 +02:00
|
|
|
author.publisher(for: \.mutingBy)
|
|
|
|
.map { mutingBy in
|
|
|
|
guard let authContext = authContext else { return false }
|
|
|
|
return mutingBy.contains(where: {
|
|
|
|
$0.id == authContext.mastodonAuthenticationBox.userID
|
|
|
|
&& $0.domain == authContext.mastodonAuthenticationBox.domain
|
|
|
|
})
|
|
|
|
}
|
|
|
|
.assign(to: \.isMuting, on: viewModel)
|
|
|
|
.store(in: &disposeBag)
|
2022-01-27 14:23:39 +01:00
|
|
|
// isBlocking
|
2022-10-09 14:07:57 +02:00
|
|
|
author.publisher(for: \.blockingBy)
|
|
|
|
.map { blockingBy in
|
|
|
|
guard let authContext = authContext else { return false }
|
|
|
|
return blockingBy.contains(where: {
|
|
|
|
$0.id == authContext.mastodonAuthenticationBox.userID
|
|
|
|
&& $0.domain == authContext.mastodonAuthenticationBox.domain
|
|
|
|
})
|
|
|
|
}
|
|
|
|
.assign(to: \.isBlocking, on: viewModel)
|
|
|
|
.store(in: &disposeBag)
|
2023-06-02 18:18:11 +02:00
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
// isMyself
|
2022-10-09 14:07:57 +02:00
|
|
|
Publishers.CombineLatest(
|
2022-01-27 14:23:39 +01:00
|
|
|
author.publisher(for: \.domain),
|
|
|
|
author.publisher(for: \.id)
|
|
|
|
)
|
2022-10-09 14:07:57 +02:00
|
|
|
.map { domain, id in
|
|
|
|
guard let authContext = authContext else { return false }
|
|
|
|
return authContext.mastodonAuthenticationBox.domain == domain
|
|
|
|
&& authContext.mastodonAuthenticationBox.userID == id
|
2022-01-27 14:23:39 +01:00
|
|
|
}
|
|
|
|
.assign(to: \.isMyself, on: viewModel)
|
|
|
|
.store(in: &disposeBag)
|
2023-06-02 18:18:11 +02:00
|
|
|
|
2022-06-30 09:02:24 +02:00
|
|
|
// follow request state
|
2023-11-22 12:32:04 +01:00
|
|
|
viewModel.followRequestState = notification.followRequestState
|
|
|
|
viewModel.transientFollowRequestState = notification.transientFollowRequestState
|
2023-06-02 18:18:11 +02:00
|
|
|
|
|
|
|
// Following
|
|
|
|
author.publisher(for: \.followingBy)
|
|
|
|
.map { [weak viewModel] followingBy in
|
|
|
|
guard let viewModel = viewModel else { return false }
|
|
|
|
guard let authContext = viewModel.authContext else { return false }
|
|
|
|
return followingBy.contains(where: {
|
|
|
|
$0.id == authContext.mastodonAuthenticationBox.userID && $0.domain == authContext.mastodonAuthenticationBox.domain
|
|
|
|
})
|
|
|
|
}
|
|
|
|
.assign(to: \.isFollowed, on: viewModel)
|
|
|
|
.store(in: &disposeBag)
|
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
}
|
|
|
|
}
|