mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-25 17:50:59 +00:00
Mark media sensitive
This commit is contained in:
parent
943c0028da
commit
846c7987dc
6 changed files with 87 additions and 2 deletions
|
@ -45,6 +45,7 @@
|
||||||
"cancel" = "Cancel";
|
"cancel" = "Cancel";
|
||||||
"compose.attachment.uploading" = "Uploading";
|
"compose.attachment.uploading" = "Uploading";
|
||||||
"compose.prompt" = "What's on your mind?";
|
"compose.prompt" = "What's on your mind?";
|
||||||
|
"compose.mark-media-sensitive" = "Mark media as sensitive";
|
||||||
"error" = "Error";
|
"error" = "Error";
|
||||||
"favorites" = "Favorites";
|
"favorites" = "Favorites";
|
||||||
"registration.review-terms-of-use-and-privacy-policy-%@" = "Please review %@'s Terms of Use and Privacy Policy to continue";
|
"registration.review-terms-of-use-and-privacy-policy-%@" = "Please review %@'s Terms of Use and Privacy Policy to continue";
|
||||||
|
|
|
@ -22,18 +22,21 @@ public extension StatusEndpoint {
|
||||||
public let spoilerText: String
|
public let spoilerText: String
|
||||||
public let mediaIds: [Attachment.Id]
|
public let mediaIds: [Attachment.Id]
|
||||||
public let visibility: Status.Visibility
|
public let visibility: Status.Visibility
|
||||||
|
public let sensitive: Bool
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
inReplyToId: Status.Id?,
|
inReplyToId: Status.Id?,
|
||||||
text: String,
|
text: String,
|
||||||
spoilerText: String,
|
spoilerText: String,
|
||||||
mediaIds: [Attachment.Id],
|
mediaIds: [Attachment.Id],
|
||||||
visibility: Status.Visibility) {
|
visibility: Status.Visibility,
|
||||||
|
sensitive: Bool) {
|
||||||
self.inReplyToId = inReplyToId
|
self.inReplyToId = inReplyToId
|
||||||
self.text = text
|
self.text = text
|
||||||
self.spoilerText = spoilerText
|
self.spoilerText = spoilerText
|
||||||
self.mediaIds = mediaIds
|
self.mediaIds = mediaIds
|
||||||
self.visibility = visibility
|
self.visibility = visibility
|
||||||
|
self.sensitive = sensitive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,6 +60,10 @@ extension StatusEndpoint.Components {
|
||||||
params["in_reply_to_id"] = inReplyToId
|
params["in_reply_to_id"] = inReplyToId
|
||||||
params["visibility"] = visibility.rawValue
|
params["visibility"] = visibility.rawValue
|
||||||
|
|
||||||
|
if sensitive {
|
||||||
|
params["sensitive"] = true
|
||||||
|
}
|
||||||
|
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,8 @@
|
||||||
D05936EA25AA3F3D00754FDF /* EditAttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936E825AA3F3D00754FDF /* EditAttachmentView.swift */; };
|
D05936EA25AA3F3D00754FDF /* EditAttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936E825AA3F3D00754FDF /* EditAttachmentView.swift */; };
|
||||||
D05936F425AA66A600754FDF /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936F325AA66A600754FDF /* UIView+Extensions.swift */; };
|
D05936F425AA66A600754FDF /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936F325AA66A600754FDF /* UIView+Extensions.swift */; };
|
||||||
D05936F525AA66A600754FDF /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936F325AA66A600754FDF /* UIView+Extensions.swift */; };
|
D05936F525AA66A600754FDF /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936F325AA66A600754FDF /* UIView+Extensions.swift */; };
|
||||||
|
D05936FF25AA94EA00754FDF /* MarkAttachmentsSensitiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936FE25AA94EA00754FDF /* MarkAttachmentsSensitiveView.swift */; };
|
||||||
|
D059370025AA94EA00754FDF /* MarkAttachmentsSensitiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936FE25AA94EA00754FDF /* MarkAttachmentsSensitiveView.swift */; };
|
||||||
D0625E59250F092900502611 /* StatusListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0625E58250F092900502611 /* StatusListCell.swift */; };
|
D0625E59250F092900502611 /* StatusListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0625E58250F092900502611 /* StatusListCell.swift */; };
|
||||||
D0625E5D250F0B5C00502611 /* StatusContentConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0625E5C250F0B5C00502611 /* StatusContentConfiguration.swift */; };
|
D0625E5D250F0B5C00502611 /* StatusContentConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0625E5C250F0B5C00502611 /* StatusContentConfiguration.swift */; };
|
||||||
D06BC5E625202AD90079541D /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06BC5E525202AD90079541D /* ProfileViewController.swift */; };
|
D06BC5E625202AD90079541D /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06BC5E525202AD90079541D /* ProfileViewController.swift */; };
|
||||||
|
@ -193,6 +195,7 @@
|
||||||
D05936DD25A937EC00754FDF /* EditThumbnailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditThumbnailView.swift; sourceTree = "<group>"; };
|
D05936DD25A937EC00754FDF /* EditThumbnailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditThumbnailView.swift; sourceTree = "<group>"; };
|
||||||
D05936E825AA3F3D00754FDF /* EditAttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditAttachmentView.swift; sourceTree = "<group>"; };
|
D05936E825AA3F3D00754FDF /* EditAttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditAttachmentView.swift; sourceTree = "<group>"; };
|
||||||
D05936F325AA66A600754FDF /* UIView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = "<group>"; };
|
D05936F325AA66A600754FDF /* UIView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = "<group>"; };
|
||||||
|
D05936FE25AA94EA00754FDF /* MarkAttachmentsSensitiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkAttachmentsSensitiveView.swift; sourceTree = "<group>"; };
|
||||||
D0625E58250F092900502611 /* StatusListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusListCell.swift; sourceTree = "<group>"; };
|
D0625E58250F092900502611 /* StatusListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusListCell.swift; sourceTree = "<group>"; };
|
||||||
D0625E5C250F0B5C00502611 /* StatusContentConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusContentConfiguration.swift; sourceTree = "<group>"; };
|
D0625E5C250F0B5C00502611 /* StatusContentConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusContentConfiguration.swift; sourceTree = "<group>"; };
|
||||||
D0666A2124C677B400F3F04B /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
D0666A2124C677B400F3F04B /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -464,6 +467,7 @@
|
||||||
D0B8510B25259E56004E0744 /* LoadMoreCell.swift */,
|
D0B8510B25259E56004E0744 /* LoadMoreCell.swift */,
|
||||||
D0E569DF252931B100FA1D72 /* LoadMoreContentConfiguration.swift */,
|
D0E569DF252931B100FA1D72 /* LoadMoreContentConfiguration.swift */,
|
||||||
D0E569DA2529319100FA1D72 /* LoadMoreView.swift */,
|
D0E569DA2529319100FA1D72 /* LoadMoreView.swift */,
|
||||||
|
D05936FE25AA94EA00754FDF /* MarkAttachmentsSensitiveView.swift */,
|
||||||
D03B1B29253818F3008F964B /* MediaPreferencesView.swift */,
|
D03B1B29253818F3008F964B /* MediaPreferencesView.swift */,
|
||||||
D0FCC10F259C4F20000B67DF /* NewStatusView.swift */,
|
D0FCC10F259C4F20000B67DF /* NewStatusView.swift */,
|
||||||
D036AA0B254B612B009094DF /* NotificationContentConfiguration.swift */,
|
D036AA0B254B612B009094DF /* NotificationContentConfiguration.swift */,
|
||||||
|
@ -797,6 +801,7 @@
|
||||||
D0849C7F25903C4900A5EBCC /* Status+Extensions.swift in Sources */,
|
D0849C7F25903C4900A5EBCC /* Status+Extensions.swift in Sources */,
|
||||||
D0625E59250F092900502611 /* StatusListCell.swift in Sources */,
|
D0625E59250F092900502611 /* StatusListCell.swift in Sources */,
|
||||||
D0E569DB2529319100FA1D72 /* LoadMoreView.swift in Sources */,
|
D0E569DB2529319100FA1D72 /* LoadMoreView.swift in Sources */,
|
||||||
|
D05936FF25AA94EA00754FDF /* MarkAttachmentsSensitiveView.swift in Sources */,
|
||||||
D0C7D49D24F7616A001EBDBB /* PostingReadingPreferencesView.swift in Sources */,
|
D0C7D49D24F7616A001EBDBB /* PostingReadingPreferencesView.swift in Sources */,
|
||||||
D0B5FE9B251583DB00478838 /* ProfileCollection+Extensions.swift in Sources */,
|
D0B5FE9B251583DB00478838 /* ProfileCollection+Extensions.swift in Sources */,
|
||||||
D0C7D49E24F7616A001EBDBB /* SecondaryNavigationView.swift in Sources */,
|
D0C7D49E24F7616A001EBDBB /* SecondaryNavigationView.swift in Sources */,
|
||||||
|
@ -872,6 +877,7 @@
|
||||||
D08E52EF257D757100FA2C5F /* CompositionView.swift in Sources */,
|
D08E52EF257D757100FA2C5F /* CompositionView.swift in Sources */,
|
||||||
D0CE9F88258B076900E3A6B6 /* AttachmentUploadView.swift in Sources */,
|
D0CE9F88258B076900E3A6B6 /* AttachmentUploadView.swift in Sources */,
|
||||||
D08E52C7257C7AEE00FA2C5F /* ShareErrorViewController.swift in Sources */,
|
D08E52C7257C7AEE00FA2C5F /* ShareErrorViewController.swift in Sources */,
|
||||||
|
D059370025AA94EA00754FDF /* MarkAttachmentsSensitiveView.swift in Sources */,
|
||||||
D015B14425A812F6006D88A8 /* PlayerCache.swift in Sources */,
|
D015B14425A812F6006D88A8 /* PlayerCache.swift in Sources */,
|
||||||
D05936F525AA66A600754FDF /* UIView+Extensions.swift in Sources */,
|
D05936F525AA66A600754FDF /* UIView+Extensions.swift in Sources */,
|
||||||
D015B13F25A812EC006D88A8 /* PlayerView.swift in Sources */,
|
D015B13F25A812EC006D88A8 /* PlayerView.swift in Sources */,
|
||||||
|
|
|
@ -11,6 +11,7 @@ public final class CompositionViewModel: AttachmentsRenderingViewModel, Observab
|
||||||
@Published public var text = ""
|
@Published public var text = ""
|
||||||
@Published public var contentWarning = ""
|
@Published public var contentWarning = ""
|
||||||
@Published public var displayContentWarning = false
|
@Published public var displayContentWarning = false
|
||||||
|
@Published public var sensitive = false
|
||||||
@Published public private(set) var attachmentViewModels = [AttachmentViewModel]()
|
@Published public private(set) var attachmentViewModels = [AttachmentViewModel]()
|
||||||
@Published public private(set) var attachmentUpload: AttachmentUpload?
|
@Published public private(set) var attachmentUpload: AttachmentUpload?
|
||||||
@Published public private(set) var isPostable = false
|
@Published public private(set) var isPostable = false
|
||||||
|
@ -45,6 +46,7 @@ public final class CompositionViewModel: AttachmentsRenderingViewModel, Observab
|
||||||
.combineLatest($displayContentWarning, $contentWarning)
|
.combineLatest($displayContentWarning, $contentWarning)
|
||||||
.map { Self.maxCharacters - ($0 + ($1 ? $2.count : 0)) }
|
.map { Self.maxCharacters - ($0 + ($1 ? $2.count : 0)) }
|
||||||
.assign(to: &$remainingCharacters)
|
.assign(to: &$remainingCharacters)
|
||||||
|
$displayContentWarning.filter { $0 }.assign(to: &$sensitive)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func attachmentSelected(viewModel: AttachmentViewModel) {
|
public func attachmentSelected(viewModel: AttachmentViewModel) {
|
||||||
|
@ -72,7 +74,8 @@ public extension CompositionViewModel {
|
||||||
text: text,
|
text: text,
|
||||||
spoilerText: displayContentWarning ? contentWarning : "",
|
spoilerText: displayContentWarning ? contentWarning : "",
|
||||||
mediaIds: attachmentViewModels.map(\.attachment.id),
|
mediaIds: attachmentViewModels.map(\.attachment.id),
|
||||||
visibility: visibility)
|
visibility: visibility,
|
||||||
|
sensitive: sensitive)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cancelUpload() {
|
func cancelUpload() {
|
||||||
|
|
|
@ -12,6 +12,7 @@ final class CompositionView: UIView {
|
||||||
let textViewPlaceholder = UILabel()
|
let textViewPlaceholder = UILabel()
|
||||||
let attachmentsView = AttachmentsView()
|
let attachmentsView = AttachmentsView()
|
||||||
let attachmentUploadView: AttachmentUploadView
|
let attachmentUploadView: AttachmentUploadView
|
||||||
|
let markAttachmentsSensitiveView: MarkAttachmentsSensitiveView
|
||||||
|
|
||||||
private let viewModel: CompositionViewModel
|
private let viewModel: CompositionViewModel
|
||||||
private let parentViewModel: NewStatusViewModel
|
private let parentViewModel: NewStatusViewModel
|
||||||
|
@ -22,6 +23,7 @@ final class CompositionView: UIView {
|
||||||
self.parentViewModel = parentViewModel
|
self.parentViewModel = parentViewModel
|
||||||
|
|
||||||
attachmentUploadView = AttachmentUploadView(viewModel: viewModel)
|
attachmentUploadView = AttachmentUploadView(viewModel: viewModel)
|
||||||
|
markAttachmentsSensitiveView = MarkAttachmentsSensitiveView(viewModel: viewModel)
|
||||||
|
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
|
|
||||||
|
@ -99,6 +101,7 @@ private extension CompositionView {
|
||||||
|
|
||||||
stackView.addArrangedSubview(attachmentsView)
|
stackView.addArrangedSubview(attachmentsView)
|
||||||
stackView.addArrangedSubview(attachmentUploadView)
|
stackView.addArrangedSubview(attachmentUploadView)
|
||||||
|
stackView.addArrangedSubview(markAttachmentsSensitiveView)
|
||||||
|
|
||||||
textView.text = viewModel.text
|
textView.text = viewModel.text
|
||||||
spoilerTextField.text = viewModel.contentWarning
|
spoilerTextField.text = viewModel.contentWarning
|
||||||
|
@ -135,6 +138,7 @@ private extension CompositionView {
|
||||||
.sink { [weak self] in
|
.sink { [weak self] in
|
||||||
self?.attachmentsView.viewModel = self?.viewModel
|
self?.attachmentsView.viewModel = self?.viewModel
|
||||||
self?.attachmentsView.isHidden = $0.isEmpty
|
self?.attachmentsView.isHidden = $0.isEmpty
|
||||||
|
self?.markAttachmentsSensitiveView.isHidden = $0.isEmpty
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
|
64
Views/MarkAttachmentsSensitiveView.swift
Normal file
64
Views/MarkAttachmentsSensitiveView.swift
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright © 2021 Metabolist. All rights reserved.
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import UIKit
|
||||||
|
import ViewModels
|
||||||
|
|
||||||
|
final class MarkAttachmentsSensitiveView: UIView {
|
||||||
|
private let label = UILabel()
|
||||||
|
private let sensitiveSwitch = UISwitch()
|
||||||
|
private let viewModel: CompositionViewModel
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
init(viewModel: CompositionViewModel) {
|
||||||
|
self.viewModel = viewModel
|
||||||
|
|
||||||
|
super.init(frame: .zero)
|
||||||
|
|
||||||
|
initialSetup()
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(*, unavailable)
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension MarkAttachmentsSensitiveView {
|
||||||
|
func initialSetup() {
|
||||||
|
addSubview(label)
|
||||||
|
label.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
label.adjustsFontForContentSizeCategory = true
|
||||||
|
label.font = .preferredFont(forTextStyle: .callout)
|
||||||
|
label.textColor = .secondaryLabel
|
||||||
|
label.text = NSLocalizedString("compose.mark-media-sensitive", comment: "")
|
||||||
|
label.textAlignment = .right
|
||||||
|
|
||||||
|
addSubview(sensitiveSwitch)
|
||||||
|
sensitiveSwitch.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
sensitiveSwitch.addAction(
|
||||||
|
UIAction { [weak self] _ in
|
||||||
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
self.viewModel.sensitive = self.sensitiveSwitch.isOn
|
||||||
|
},
|
||||||
|
for: .valueChanged)
|
||||||
|
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
label.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
|
||||||
|
label.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
|
||||||
|
label.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor),
|
||||||
|
sensitiveSwitch.leadingAnchor.constraint(equalTo: label.trailingAnchor, constant: .defaultSpacing),
|
||||||
|
sensitiveSwitch.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
|
||||||
|
sensitiveSwitch.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
|
||||||
|
sensitiveSwitch.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
|
||||||
|
])
|
||||||
|
|
||||||
|
viewModel.$sensitive
|
||||||
|
.sink { [weak self] in self?.sensitiveSwitch.setOn($0, animated: true) }
|
||||||
|
.store(in: &cancellables)
|
||||||
|
viewModel.$displayContentWarning
|
||||||
|
.sink { [weak self] in self?.sensitiveSwitch.isEnabled = !$0 }
|
||||||
|
.store(in: &cancellables)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue