Bookmark action

This commit is contained in:
Justin Mazzocchi 2020-12-01 15:53:14 -08:00
parent 32541e68e1
commit b5f80237b0
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
5 changed files with 47 additions and 9 deletions

View file

@ -124,6 +124,7 @@
"report.target-%@" = "Reporting %@"; "report.target-%@" = "Reporting %@";
"report.forward.hint" = "The account is from another server. Send an anonymized copy of the report there as well?"; "report.forward.hint" = "The account is from another server. Send an anonymized copy of the report there as well?";
"report.forward-%@" = "Forward report to %@"; "report.forward-%@" = "Forward report to %@";
"status.bookmark" = "Bookmark";
"status.reblogged-by" = "%@ boosted"; "status.reblogged-by" = "%@ boosted";
"status.pinned-post" = "Pinned post"; "status.pinned-post" = "Pinned post";
"status.show-more" = "Show More"; "status.show-more" = "Show More";
@ -132,6 +133,7 @@
"status.poll.time-left" = "%@ left"; "status.poll.time-left" = "%@ left";
"status.poll.refresh" = "Refresh"; "status.poll.refresh" = "Refresh";
"status.poll.closed" = "Closed"; "status.poll.closed" = "Closed";
"status.unbookmark" = "Unbookmark";
"status.visibility.public" = "Public"; "status.visibility.public" = "Public";
"status.visibility.unlisted" = "Unlisted"; "status.visibility.unlisted" = "Unlisted";
"status.visibility.private" = "Private"; "status.visibility.private" = "Private";

View file

@ -8,6 +8,8 @@ public enum StatusEndpoint {
case status(id: Status.Id) case status(id: Status.Id)
case favourite(id: Status.Id) case favourite(id: Status.Id)
case unfavourite(id: Status.Id) case unfavourite(id: Status.Id)
case bookmark(id: Status.Id)
case unbookmark(id: Status.Id)
} }
extension StatusEndpoint: Endpoint { extension StatusEndpoint: Endpoint {
@ -25,6 +27,10 @@ extension StatusEndpoint: Endpoint {
return [id, "favourite"] return [id, "favourite"]
case let .unfavourite(id): case let .unfavourite(id):
return [id, "unfavourite"] return [id, "unfavourite"]
case let .bookmark(id):
return [id, "bookmark"]
case let .unbookmark(id):
return [id, "unbookmark"]
} }
} }
@ -32,7 +38,7 @@ extension StatusEndpoint: Endpoint {
switch self { switch self {
case .status: case .status:
return .get return .get
case .favourite, .unfavourite: case .favourite, .unfavourite, .bookmark, .unbookmark:
return .post return .post
} }
} }

View file

@ -40,6 +40,14 @@ public extension StatusService {
.eraseToAnyPublisher() .eraseToAnyPublisher()
} }
func toggleBookmarked() -> AnyPublisher<Never, Error> {
mastodonAPIClient.request(status.displayStatus.bookmarked
? StatusEndpoint.unbookmark(id: status.displayStatus.id)
: StatusEndpoint.bookmark(id: status.displayStatus.id))
.flatMap(contentDatabase.insert(status:))
.eraseToAnyPublisher()
}
func rebloggedByService() -> AccountListService { func rebloggedByService() -> AccountListService {
AccountListService( AccountListService(
endpoint: .rebloggedBy(id: status.id), endpoint: .rebloggedBy(id: status.id),

View file

@ -107,6 +107,8 @@ public extension StatusViewModel {
var favorited: Bool { statusService.status.displayStatus.favourited } var favorited: Bool { statusService.status.displayStatus.favourited }
var bookmarked: Bool { statusService.status.displayStatus.bookmarked }
var sensitive: Bool { statusService.status.displayStatus.sensitive } var sensitive: Bool { statusService.status.displayStatus.sensitive }
var sharingURL: URL? { statusService.status.displayStatus.url } var sharingURL: URL? { statusService.status.displayStatus.url }
@ -205,6 +207,13 @@ public extension StatusViewModel {
.eraseToAnyPublisher()) .eraseToAnyPublisher())
} }
func toggleBookmarked() {
eventsSubject.send(
statusService.toggleBookmarked()
.map { _ in .ignorableOutput }
.eraseToAnyPublisher())
}
func attachmentSelected(viewModel: AttachmentViewModel) { func attachmentSelected(viewModel: AttachmentViewModel) {
eventsSubject.send(Just(.attachment(viewModel, self)).setFailureType(to: Error.self).eraseToAnyPublisher()) eventsSubject.send(Just(.attachment(viewModel, self)).setFailureType(to: Error.self).eraseToAnyPublisher())
} }

View file

@ -3,6 +3,7 @@
// swiftlint:disable file_length // swiftlint:disable file_length
import Kingfisher import Kingfisher
import UIKit import UIKit
import ViewModels
final class StatusView: UIView { final class StatusView: UIView {
let avatarImageView = AnimatedImageView() let avatarImageView = AnimatedImageView()
@ -206,14 +207,6 @@ private extension StatusView {
for: .touchUpInside) for: .touchUpInside)
menuButton.showsMenuAsPrimaryAction = true menuButton.showsMenuAsPrimaryAction = true
menuButton.menu = UIMenu(children: [
UIAction(
title: NSLocalizedString("report", comment: ""),
image: UIImage(systemName: "flag"),
attributes: .destructive) { [weak self] _ in
self?.statusConfiguration.viewModel.reportStatus()
}
])
for button in actionButtons { for button in actionButtons {
button.titleLabel?.font = .preferredFont(forTextStyle: .footnote) button.titleLabel?.font = .preferredFont(forTextStyle: .footnote)
@ -272,6 +265,8 @@ private extension StatusView {
let isContextParent = viewModel.configuration.isContextParent let isContextParent = viewModel.configuration.isContextParent
let mutableDisplayName = NSMutableAttributedString(string: viewModel.displayName) let mutableDisplayName = NSMutableAttributedString(string: viewModel.displayName)
menuButton.menu = menu(viewModel: viewModel)
avatarImageView.kf.setImage(with: viewModel.avatarURL) avatarImageView.kf.setImage(with: viewModel.avatarURL)
sideStackView.isHidden = isContextParent sideStackView.isHidden = isContextParent
@ -396,6 +391,24 @@ private extension StatusView {
} }
// swiftlint:enable function_body_length // swiftlint:enable function_body_length
func menu(viewModel: StatusViewModel) -> UIMenu {
UIMenu(children: [
UIAction(
title: viewModel.bookmarked
? NSLocalizedString("status.unbookmark", comment: "")
: NSLocalizedString("status.bookmark", comment: ""),
image: UIImage(systemName: "bookmark")) { _ in
viewModel.toggleBookmarked()
},
UIAction(
title: NSLocalizedString("report", comment: ""),
image: UIImage(systemName: "flag"),
attributes: .destructive) { _ in
viewModel.reportStatus()
}
])
}
func setButtonImages(scale: UIImage.SymbolScale) { func setButtonImages(scale: UIImage.SymbolScale) {
replyButton.setImage(UIImage(systemName: "bubble.right", replyButton.setImage(UIImage(systemName: "bubble.right",
withConfiguration: UIImage.SymbolConfiguration(scale: scale)), for: .normal) withConfiguration: UIImage.SymbolConfiguration(scale: scale)), for: .normal)