mastodon-ios/Mastodon/Protocol/StatusProvider/StatusProvider+StatusTableV...

208 lines
9.0 KiB
Swift
Raw Normal View History

//
// StatusProvider+StatusTableViewCellDelegate.swift
// Mastodon
//
// Created by sxiaojian on 2021/2/8.
//
import os.log
import UIKit
import Combine
import CoreData
import CoreDataStack
import MastodonSDK
import ActiveLabel
2021-04-01 08:39:15 +02:00
// MARK: - StatusViewDelegate
extension StatusTableViewCellDelegate where Self: StatusProvider {
func statusTableViewCell(_ cell: StatusTableViewCell, statusView: StatusView, headerInfoLabelDidPressed label: UILabel) {
StatusProviderFacade.coordinateToStatusAuthorProfileScene(for: .secondary, provider: self, cell: cell)
}
func statusTableViewCell(_ cell: StatusTableViewCell, statusView: StatusView, avatarButtonDidPressed button: UIButton) {
StatusProviderFacade.coordinateToStatusAuthorProfileScene(for: .primary, provider: self, cell: cell)
}
}
// MARK: - ActionToolbarContainerDelegate
extension StatusTableViewCellDelegate where Self: StatusProvider {
2021-03-15 11:19:45 +01:00
func statusTableViewCell(_ cell: StatusTableViewCell, actionToolbarContainer: ActionToolbarContainer, reblogButtonDidPressed sender: UIButton) {
StatusProviderFacade.responseToStatusReblogAction(provider: self, cell: cell)
2021-03-09 08:18:43 +01:00
}
func statusTableViewCell(_ cell: StatusTableViewCell, actionToolbarContainer: ActionToolbarContainer, likeButtonDidPressed sender: UIButton) {
StatusProviderFacade.responseToStatusLikeAction(provider: self, cell: cell)
}
func statusTableViewCell(_ cell: StatusTableViewCell, statusView: StatusView, contentWarningActionButtonPressed button: UIButton) {
guard let diffableDataSource = self.tableViewDiffableDataSource else { return }
guard let item = item(for: cell, indexPath: nil) else { return }
switch item {
case .homeTimelineIndex(_, let attribute):
attribute.isStatusTextSensitive = false
2021-04-01 08:39:15 +02:00
case .status(_, let attribute):
attribute.isStatusTextSensitive = false
default:
return
}
var snapshot = diffableDataSource.snapshot()
snapshot.reloadItems([item])
diffableDataSource.apply(snapshot)
}
}
// MARK: - MosciaImageViewContainerDelegate
extension StatusTableViewCellDelegate where Self: StatusProvider {
func statusTableViewCell(_ cell: StatusTableViewCell, mosaicImageViewContainer: MosaicImageViewContainer, didTapImageView imageView: UIImageView, atIndex index: Int) {
}
func statusTableViewCell(_ cell: StatusTableViewCell, mosaicImageViewContainer: MosaicImageViewContainer, contentWarningOverlayViewDidPressed contentWarningOverlayView: ContentWarningOverlayView) {
statusTableViewCell(cell, contentWarningOverlayViewDidPressed: contentWarningOverlayView)
2021-03-11 08:10:41 +01:00
}
2021-03-11 12:06:15 +01:00
func statusTableViewCell(_ cell: StatusTableViewCell, playerContainerView: PlayerContainerView, contentWarningOverlayViewDidPressed contentWarningOverlayView: ContentWarningOverlayView) {
contentWarningOverlayView.isUserInteractionEnabled = false
statusTableViewCell(cell, contentWarningOverlayViewDidPressed: contentWarningOverlayView)
}
func statusTableViewCell(_ cell: StatusTableViewCell, contentWarningOverlayViewDidPressed contentWarningOverlayView: ContentWarningOverlayView) {
guard let diffableDataSource = self.tableViewDiffableDataSource else { return }
guard let item = item(for: cell, indexPath: nil) else { return }
switch item {
case .homeTimelineIndex(_, let attribute):
attribute.isStatusSensitive = false
2021-04-01 08:39:15 +02:00
case .status(_, let attribute):
attribute.isStatusSensitive = false
default:
return
}
2021-03-11 12:06:15 +01:00
contentWarningOverlayView.isUserInteractionEnabled = false
var snapshot = diffableDataSource.snapshot()
snapshot.reloadItems([item])
UIView.animate(withDuration: 0.33) {
2021-03-11 12:06:15 +01:00
contentWarningOverlayView.blurVisualEffectView.effect = nil
contentWarningOverlayView.vibrancyVisualEffectView.alpha = 0.0
} completion: { _ in
diffableDataSource.apply(snapshot, animatingDifferences: false, completion: nil)
}
}
}
// MARK: - PollTableView
extension StatusTableViewCellDelegate where Self: StatusProvider {
2021-03-05 08:53:36 +01:00
func statusTableViewCell(_ cell: StatusTableViewCell, statusView: StatusView, pollVoteButtonPressed button: UIButton) {
guard let activeMastodonAuthenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else { return }
2021-04-01 08:39:15 +02:00
status(for: cell, indexPath: nil)
2021-03-05 08:53:36 +01:00
.receive(on: DispatchQueue.main)
.setFailureType(to: Error.self)
2021-04-01 08:39:15 +02:00
.compactMap { status -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Poll>, Error>? in
guard let status = (status?.reblog ?? status) else { return nil }
guard let poll = status.poll else { return nil }
2021-03-05 08:53:36 +01:00
let votedOptions = poll.options.filter { ($0.votedBy ?? Set()).contains(where: { $0.id == activeMastodonAuthenticationBox.userID }) }
let choices = votedOptions.map { $0.index.intValue }
2021-04-01 08:39:15 +02:00
let domain = poll.status.domain
2021-03-05 08:53:36 +01:00
button.isEnabled = false
return self.context.apiService.vote(
domain: domain,
pollID: poll.id,
pollObjectID: poll.objectID,
choices: choices,
mastodonAuthenticationBox: activeMastodonAuthenticationBox
)
}
.switchToLatest()
.sink(receiveCompletion: { completion in
switch completion {
case .failure(let error):
// TODO: handle error
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: multiple vote fail: %s", ((#file as NSString).lastPathComponent), #line, #function, error.localizedDescription)
button.isEnabled = true
case .finished:
break
}
}, receiveValue: { response in
// do nothing
})
.store(in: &context.disposeBag)
}
func statusTableViewCell(_ cell: StatusTableViewCell, pollTableView: PollTableView, didSelectRowAt indexPath: IndexPath) {
2021-03-05 06:41:48 +01:00
guard let activeMastodonAuthenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else { return }
guard let activeMastodonAuthentication = context.authenticationService.activeMastodonAuthentication.value else { return }
guard let diffableDataSource = cell.statusView.pollTableViewDataSource else { return }
let item = diffableDataSource.itemIdentifier(for: indexPath)
2021-03-10 12:12:53 +01:00
guard case let .opion(objectID, _) = item else { return }
guard let option = managedObjectContext.object(with: objectID) as? PollOption else { return }
2021-03-05 08:53:36 +01:00
let poll = option.poll
2021-03-05 06:41:48 +01:00
let pollObjectID = option.poll.objectID
2021-04-01 08:39:15 +02:00
let domain = poll.status.domain
2021-03-05 08:53:36 +01:00
if poll.multiple {
var votedOptions = poll.options.filter { ($0.votedBy ?? Set()).contains(where: { $0.id == activeMastodonAuthenticationBox.userID }) }
if votedOptions.contains(option) {
votedOptions.remove(option)
} else {
votedOptions.insert(option)
}
let choices = votedOptions.map { $0.index.intValue }
context.apiService.vote(
pollObjectID: option.poll.objectID,
mastodonUserObjectID: activeMastodonAuthentication.user.objectID,
choices: choices
)
.handleEvents(receiveOutput: { _ in
// TODO: add haptic
})
.receive(on: DispatchQueue.main)
.sink { completion in
// Do nothing
} receiveValue: { _ in
// Do nothing
}
.store(in: &context.disposeBag)
} else {
2021-03-05 06:41:48 +01:00
let choices = [option.index.intValue]
context.apiService.vote(
2021-03-05 08:53:36 +01:00
pollObjectID: pollObjectID,
mastodonUserObjectID: activeMastodonAuthentication.user.objectID,
choices: [option.index.intValue]
)
2021-03-05 06:41:48 +01:00
.handleEvents(receiveOutput: { _ in
// TODO: add haptic
})
.flatMap { pollID -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Poll>, Error> in
return self.context.apiService.vote(
domain: domain,
pollID: pollID,
pollObjectID: pollObjectID,
choices: choices,
mastodonAuthenticationBox: activeMastodonAuthenticationBox
)
}
.receive(on: DispatchQueue.main)
.sink { completion in
2021-03-05 06:41:48 +01:00
} receiveValue: { response in
print(response.value)
}
.store(in: &context.disposeBag)
}
}
}