forked from zelo72/mastodon-ios
feat: add post publish validate state binding
This commit is contained in:
parent
b8e062c92e
commit
3eb2b916a7
|
@ -44,12 +44,32 @@ extension ComposeStatusItem {
|
|||
}
|
||||
}
|
||||
|
||||
protocol ComposeStatusItemDelegate: class {
|
||||
func composePollAttribute(_ attribute: ComposeStatusItem.ComposePollAttribute, pollOptionDidChange: String?)
|
||||
}
|
||||
|
||||
extension ComposeStatusItem {
|
||||
final class ComposePollAttribute: Equatable, Hashable {
|
||||
private let id = UUID()
|
||||
|
||||
var disposeBag = Set<AnyCancellable>()
|
||||
weak var delegate: ComposeStatusItemDelegate?
|
||||
|
||||
let option = CurrentValueSubject<String, Never>("")
|
||||
|
||||
init() {
|
||||
option
|
||||
.sink { [weak self] option in
|
||||
guard let self = self else { return }
|
||||
self.delegate?.composePollAttribute(self, pollOptionDidChange: option)
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
}
|
||||
|
||||
deinit {
|
||||
disposeBag.removeAll()
|
||||
}
|
||||
|
||||
static func == (lhs: ComposePollAttribute, rhs: ComposePollAttribute) -> Bool {
|
||||
return lhs.id == rhs.id &&
|
||||
lhs.option.value == rhs.option.value
|
||||
|
|
|
@ -629,7 +629,6 @@ extension ComposeViewController: PHPickerViewControllerDelegate {
|
|||
pickerResult: result,
|
||||
initalAuthenticationBox: viewModel.activeAuthenticationBox.value
|
||||
)
|
||||
service.delegate = viewModel
|
||||
return service
|
||||
}
|
||||
viewModel.attachmentServices.value = viewModel.attachmentServices.value + attachmentServices
|
||||
|
@ -649,7 +648,6 @@ extension ComposeViewController: UIImagePickerControllerDelegate & UINavigationC
|
|||
image: image,
|
||||
initalAuthenticationBox: viewModel.activeAuthenticationBox.value
|
||||
)
|
||||
attachmentService.delegate = viewModel
|
||||
viewModel.attachmentServices.value = viewModel.attachmentServices.value + [attachmentService]
|
||||
}
|
||||
|
||||
|
@ -673,7 +671,6 @@ extension ComposeViewController: UIDocumentPickerDelegate {
|
|||
imageData: imageData,
|
||||
initalAuthenticationBox: viewModel.activeAuthenticationBox.value
|
||||
)
|
||||
attachmentService.delegate = viewModel
|
||||
viewModel.attachmentServices.value = viewModel.attachmentServices.value + [attachmentService]
|
||||
} catch {
|
||||
os_log("%{public}s[%{public}ld], %{public}s: %s", ((#file as NSString).lastPathComponent), #line, #function, error.localizedDescription)
|
||||
|
|
|
@ -104,19 +104,48 @@ final class ComposeViewModel {
|
|||
.map { services in
|
||||
services.allSatisfy { $0.uploadStateMachineSubject.value is MastodonAttachmentService.UploadState.Finish }
|
||||
}
|
||||
Publishers.CombineLatest4(
|
||||
let isPollAttributeAllValid = pollAttributes
|
||||
.map { pollAttributes in
|
||||
pollAttributes.allSatisfy { attribute -> Bool in
|
||||
!attribute.option.value.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
|
||||
}
|
||||
}
|
||||
|
||||
let isPublishBarButtonItemEnabledPrecondition1 = Publishers.CombineLatest4(
|
||||
isComposeContentEmpty.eraseToAnyPublisher(),
|
||||
isComposeContentValid.eraseToAnyPublisher(),
|
||||
isMediaEmpty.eraseToAnyPublisher(),
|
||||
isMediaUploadAllSuccess.eraseToAnyPublisher()
|
||||
)
|
||||
.map { isComposeContentEmpty, isComposeContentValid, isMediaEmpty, isMediaUploadAllSuccess in
|
||||
.map { isComposeContentEmpty, isComposeContentValid, isMediaEmpty, isMediaUploadAllSuccess -> Bool in
|
||||
if isMediaEmpty {
|
||||
return isComposeContentValid && !isComposeContentEmpty
|
||||
} else {
|
||||
return isComposeContentValid && isMediaUploadAllSuccess
|
||||
}
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
let isPublishBarButtonItemEnabledPrecondition2 = Publishers.CombineLatest4(
|
||||
isComposeContentEmpty.eraseToAnyPublisher(),
|
||||
isComposeContentValid.eraseToAnyPublisher(),
|
||||
isPollComposing.eraseToAnyPublisher(),
|
||||
isPollAttributeAllValid.eraseToAnyPublisher()
|
||||
)
|
||||
.map { isComposeContentEmpty, isComposeContentValid, isPollComposing, isPollAttributeAllValid -> Bool in
|
||||
if isPollComposing {
|
||||
return isComposeContentValid && !isComposeContentEmpty && isPollAttributeAllValid
|
||||
} else {
|
||||
return isComposeContentValid && !isComposeContentEmpty
|
||||
}
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
Publishers.CombineLatest(
|
||||
isPublishBarButtonItemEnabledPrecondition1,
|
||||
isPublishBarButtonItemEnabledPrecondition2
|
||||
)
|
||||
.map { $0 && $1 }
|
||||
.assign(to: \.value, on: isPublishBarButtonItemEnabled)
|
||||
.store(in: &disposeBag)
|
||||
|
||||
|
@ -201,6 +230,22 @@ final class ComposeViewModel {
|
|||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
// bind delegate
|
||||
attachmentServices
|
||||
.sink { [weak self] attachmentServices in
|
||||
guard let self = self else { return }
|
||||
attachmentServices.forEach { $0.delegate = self }
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
pollAttributes
|
||||
.sink { [weak self] pollAttributes in
|
||||
guard let self = self else { return }
|
||||
pollAttributes.forEach { $0.delegate = self }
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
// bind compose toolbar UI state
|
||||
Publishers.CombineLatest(
|
||||
isPollComposing.eraseToAnyPublisher(),
|
||||
attachmentServices.eraseToAnyPublisher()
|
||||
|
@ -235,3 +280,11 @@ extension ComposeViewModel: MastodonAttachmentServiceDelegate {
|
|||
attachmentServices.value = attachmentServices.value
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - ComposeStatusAttributeDelegate
|
||||
extension ComposeViewModel: ComposeStatusItemDelegate {
|
||||
func composePollAttribute(_ attribute: ComposeStatusItem.ComposePollAttribute, pollOptionDidChange: String?) {
|
||||
// trigger update
|
||||
pollAttributes.value = pollAttributes.value
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue