Replace CoreData.StatusEdit by Mastodon.Entity.StatusEdit
This commit is contained in:
parent
12ed4a70cd
commit
1806f9a350
|
@ -571,6 +571,7 @@ private extension SceneCoordinator {
|
|||
//MARK: - Loading
|
||||
|
||||
public extension SceneCoordinator {
|
||||
@MainActor
|
||||
func showLoading() {
|
||||
guard let rootViewController else { return }
|
||||
|
||||
|
|
|
@ -670,19 +670,30 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte
|
|||
|
||||
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, statusMetricView: StatusMetricView, showEditHistory button: UIButton) {
|
||||
Task {
|
||||
|
||||
|
||||
await coordinator.showLoading()
|
||||
|
||||
let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil)
|
||||
guard let item = await self.item(from: source),
|
||||
case let .status(status) = item else {
|
||||
assertionFailure("only works for status data provider")
|
||||
return
|
||||
}
|
||||
|
||||
guard let status = status.object(in: context.managedObjectContext) else {
|
||||
return await coordinator.hideLoading()
|
||||
}
|
||||
|
||||
do {
|
||||
let edits = try await context.apiService.getHistory(forStatusID: status.id, authenticationBox: authContext.mastodonAuthenticationBox).value
|
||||
|
||||
guard let status = status.object(in: context.managedObjectContext),
|
||||
let edits = status.editHistory?.sorted(by: { $0.createdAt > $1.createdAt }) else { return }
|
||||
await coordinator.hideLoading()
|
||||
|
||||
let viewModel = StatusEditHistoryViewModel(status: status, edits: edits, appContext: context, authContext: authContext)
|
||||
_ = await coordinator.present(scene: .editHistory(viewModel: viewModel), from: self, transition: .show)
|
||||
let viewModel = StatusEditHistoryViewModel(status: status, edits: edits, appContext: context, authContext: authContext)
|
||||
_ = await coordinator.present(scene: .editHistory(viewModel: viewModel), from: self, transition: .show)
|
||||
} catch {
|
||||
await coordinator.hideLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import CoreDataStack
|
|||
import MetaTextKit
|
||||
import MastodonCore
|
||||
import MastodonUI
|
||||
import MastodonSDK
|
||||
|
||||
extension PollOptionView {
|
||||
public func configure(pollOption option: PollOption) {
|
||||
|
@ -103,7 +104,7 @@ extension PollOptionView {
|
|||
}
|
||||
|
||||
extension PollOptionView {
|
||||
public func configure(historyPollOption option: StatusEdit.Poll.Option) {
|
||||
public func configure(historyPollOption option: Mastodon.Entity.StatusEdit.Poll.Option) {
|
||||
// background
|
||||
viewModel.roundedBackgroundViewColor = SystemTheme.systemElevatedBackgroundColor
|
||||
// metaContent
|
||||
|
|
|
@ -72,7 +72,7 @@ class StatusEditHistoryTableViewCell: UITableViewCell {
|
|||
NSLayoutConstraint.activate(constraints)
|
||||
}
|
||||
|
||||
func configure(status: Status, statusEdit: StatusEdit, dateText: String) {
|
||||
func configure(status: Status, statusEdit: Mastodon.Entity.StatusEdit, dateText: String) {
|
||||
dateLabel.text = dateText
|
||||
statusHistoryView.statusView.configure(status: status, statusEdit: statusEdit)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ class StatusEditHistoryViewController: UIViewController {
|
|||
|
||||
private let tableView: UITableView
|
||||
|
||||
var tableViewDataSource: UITableViewDiffableDataSource<Int, StatusEdit>?
|
||||
var tableViewDataSource: UITableViewDiffableDataSource<Int, Mastodon.Entity.StatusEdit>?
|
||||
var viewModel: StatusEditHistoryViewModel
|
||||
private let dateFormatter: DateFormatter
|
||||
|
||||
|
@ -28,7 +28,7 @@ class StatusEditHistoryViewController: UIViewController {
|
|||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
let tableViewDataSource = UITableViewDiffableDataSource<Int, StatusEdit>(tableView: tableView) {tableView, indexPath, itemIdentifier in
|
||||
let tableViewDataSource = UITableViewDiffableDataSource<Int, Mastodon.Entity.StatusEdit>(tableView: tableView) {tableView, indexPath, itemIdentifier in
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: StatusEditHistoryTableViewCell.identifier, for: indexPath) as? StatusEditHistoryTableViewCell else {
|
||||
fatalError("Wrong cell")
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ class StatusEditHistoryViewController: UIViewController {
|
|||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Int, StatusEdit>()
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Int, Mastodon.Entity.StatusEdit>()
|
||||
snapshot.appendSections([0])
|
||||
snapshot.appendItems(viewModel.edits)
|
||||
|
||||
|
|
|
@ -5,10 +5,11 @@ import CoreDataStack
|
|||
import MastodonCore
|
||||
import MastodonUI
|
||||
import UIKit
|
||||
import MastodonSDK
|
||||
|
||||
struct StatusEditHistoryViewModel {
|
||||
let status: Status
|
||||
let edits: [StatusEdit]
|
||||
let edits: [Mastodon.Entity.StatusEdit]
|
||||
|
||||
let appContext: AppContext
|
||||
let authContext: AuthContext
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import MastodonSDK
|
||||
|
||||
extension Mastodon.Entity.StatusEdit: Hashable, Equatable {
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(createdAt)
|
||||
hasher.combine(content)
|
||||
}
|
||||
|
||||
public static func == (lhs: Mastodon.Entity.StatusEdit, rhs: Mastodon.Entity.StatusEdit) -> Bool {
|
||||
lhs.createdAt == rhs.createdAt && lhs.content == rhs.content
|
||||
}
|
||||
}
|
|
@ -8,8 +8,9 @@
|
|||
import Foundation
|
||||
import CoreData
|
||||
import CoreDataStack
|
||||
import MastodonSDK
|
||||
|
||||
public enum PollItem: Hashable {
|
||||
case option(record: ManagedObjectRecord<PollOption>)
|
||||
case history(option: StatusEdit.Poll.Option)
|
||||
case history(option: Mastodon.Entity.StatusEdit.Poll.Option)
|
||||
}
|
||||
|
|
|
@ -14,11 +14,23 @@ extension Mastodon.Entity {
|
|||
/// [Document](https://docs.joinmastodon.org/entities/statusedit/)
|
||||
public class StatusEdit: Codable {
|
||||
public class Poll: Codable {
|
||||
public class Option: Codable {
|
||||
public class Option: Codable, Hashable {
|
||||
public let title: String
|
||||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(title)
|
||||
}
|
||||
|
||||
public static func == (lhs: Mastodon.Entity.StatusEdit.Poll.Option, rhs: Mastodon.Entity.StatusEdit.Poll.Option) -> Bool {
|
||||
lhs.title == rhs.title
|
||||
}
|
||||
}
|
||||
public let options: [Option]
|
||||
public let title: String?
|
||||
|
||||
// public static func == (lhs: Mastodon.Entity.StatusEdit.Poll, rhs: Mastodon.Entity.StatusEdit.Poll) -> Bool {
|
||||
// lhs.title == rhs.title && lhs.options == rhs.options
|
||||
// }
|
||||
}
|
||||
|
||||
public let content: String
|
||||
|
@ -40,5 +52,6 @@ extension Mastodon.Entity {
|
|||
case mediaAttachments = "media_attachments"
|
||||
case emojis
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import CoreDataStack
|
|||
import Photos
|
||||
import AlamofireImage
|
||||
import MastodonCore
|
||||
import MastodonSDK
|
||||
|
||||
extension MediaView {
|
||||
public class Configuration: Hashable {
|
||||
|
@ -243,3 +244,82 @@ extension MediaView {
|
|||
return configurations
|
||||
}
|
||||
}
|
||||
|
||||
extension MediaView {
|
||||
public static func configuration(status: Mastodon.Entity.StatusEdit) -> [MediaView.Configuration] {
|
||||
func aspectRatio(from attachment: Mastodon.Entity.Attachment) -> CGSize {
|
||||
guard let width = attachment.meta?.width, let height = attachment.meta?.height else {
|
||||
return .zero
|
||||
}
|
||||
return CGSize(width: width, height: height)
|
||||
}
|
||||
|
||||
func videoInfo(from attachment: Mastodon.Entity.Attachment) -> MediaView.Configuration.VideoInfo {
|
||||
MediaView.Configuration.VideoInfo(
|
||||
aspectRadio: aspectRatio(from: attachment),
|
||||
assetURL: attachment.remoteURL,
|
||||
previewURL: attachment.previewURL,
|
||||
altDescription: attachment.description,
|
||||
durationMS: {
|
||||
guard let duration = attachment.meta?.duration else {
|
||||
return 0
|
||||
}
|
||||
return Int(duration)
|
||||
}()
|
||||
)
|
||||
}
|
||||
|
||||
let attachments = status.mediaAttachments ?? []
|
||||
let configurations = attachments.enumerated().compactMap { (idx, attachment) -> MediaView.Configuration? in
|
||||
let configuration: MediaView.Configuration? = {
|
||||
switch attachment.attachmentKind {
|
||||
case .image:
|
||||
let info = MediaView.Configuration.ImageInfo(
|
||||
aspectRadio: aspectRatio(from: attachment),
|
||||
assetURL: attachment.remoteURL,
|
||||
altDescription: attachment.description
|
||||
)
|
||||
return .init(
|
||||
info: .image(info: info),
|
||||
blurhash: attachment.blurhash,
|
||||
index: idx,
|
||||
total: attachments.count
|
||||
)
|
||||
case .video:
|
||||
let info = videoInfo(from: attachment)
|
||||
return .init(
|
||||
info: .video(info: info),
|
||||
blurhash: attachment.blurhash,
|
||||
index: idx,
|
||||
total: attachments.count
|
||||
)
|
||||
case .gifv:
|
||||
let info = videoInfo(from: attachment)
|
||||
return .init(
|
||||
info: .gif(info: info),
|
||||
blurhash: attachment.blurhash,
|
||||
index: idx,
|
||||
total: attachments.count
|
||||
)
|
||||
case .audio:
|
||||
let info = videoInfo(from: attachment)
|
||||
return .init(
|
||||
info: .video(info: info),
|
||||
blurhash: attachment.blurhash,
|
||||
index: idx,
|
||||
total: attachments.count
|
||||
)
|
||||
case .none:
|
||||
return nil
|
||||
} // end switch
|
||||
}()
|
||||
|
||||
configuration?.load()
|
||||
configuration?.isReveal = true
|
||||
|
||||
return configuration
|
||||
}
|
||||
|
||||
return configurations
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ extension StatusView {
|
|||
|
||||
extension StatusView {
|
||||
|
||||
public func configure(status: Status, statusEdit: StatusEdit) {
|
||||
public func configure(status: Status, statusEdit: Mastodon.Entity.StatusEdit) {
|
||||
viewModel.objects.insert(status)
|
||||
if let reblog = status.reblog {
|
||||
viewModel.objects.insert(reblog)
|
||||
|
@ -313,7 +313,7 @@ extension StatusView {
|
|||
}
|
||||
}
|
||||
|
||||
private func configureContent(statusEdit: StatusEdit, status: Status) {
|
||||
private func configureContent(statusEdit: Mastodon.Entity.StatusEdit, status: Status) {
|
||||
statusEdit.spoilerText.map {
|
||||
viewModel.spoilerContent = PlaintextMetaContent(string: $0)
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ extension StatusView {
|
|||
viewModel.language = (status.reblog ?? status).language
|
||||
// content
|
||||
do {
|
||||
let content = MastodonContent(content: statusEdit.content, emojis: statusEdit.emojis.asDictionary)
|
||||
let content = MastodonContent(content: statusEdit.content, emojis: statusEdit.emojis?.asDictionary ?? [:])
|
||||
let metaContent = try MastodonMetaContent.convert(document: content)
|
||||
viewModel.content = metaContent
|
||||
viewModel.isCurrentlyTranslating = false
|
||||
|
@ -385,7 +385,14 @@ extension StatusView {
|
|||
viewModel.mediaViewConfigurations = configurations
|
||||
}
|
||||
|
||||
private func configurePollHistory(statusEdit: StatusEdit) {
|
||||
private func configureMedia(status: Mastodon.Entity.StatusEdit) {
|
||||
viewModel.isMediaSensitive = status.sensitive
|
||||
|
||||
let configurations = MediaView.configuration(status: status)
|
||||
viewModel.mediaViewConfigurations = configurations
|
||||
}
|
||||
|
||||
private func configurePollHistory(statusEdit: Mastodon.Entity.StatusEdit) {
|
||||
guard let poll = statusEdit.poll else { return }
|
||||
|
||||
let pollItems = poll.options.map { PollItem.history(option: $0) }
|
||||
|
|
Loading…
Reference in New Issue