metatext/Views/CompositionInputAccessoryView.swift

164 lines
5.8 KiB
Swift
Raw Normal View History

2020-12-16 01:39:38 +00:00
// Copyright © 2020 Metabolist. All rights reserved.
2021-01-01 23:31:39 +00:00
import AVFoundation
2020-12-16 01:39:38 +00:00
import Combine
2021-01-01 00:49:59 +00:00
import Mastodon
2020-12-16 01:39:38 +00:00
import UIKit
import ViewModels
2021-01-01 00:49:59 +00:00
final class CompositionInputAccessoryView: UIView {
let visibilityButton = UIButton()
let addButton = UIButton()
let contentWarningButton = UIButton(type: .system)
2020-12-16 01:39:38 +00:00
private let viewModel: CompositionViewModel
2021-01-01 00:49:59 +00:00
private let parentViewModel: NewStatusViewModel
private let stackView = UIStackView()
2020-12-16 01:39:38 +00:00
private var cancellables = Set<AnyCancellable>()
2021-01-01 00:49:59 +00:00
init(viewModel: CompositionViewModel, parentViewModel: NewStatusViewModel) {
2020-12-16 01:39:38 +00:00
self.viewModel = viewModel
2021-01-01 00:49:59 +00:00
self.parentViewModel = parentViewModel
2020-12-16 01:39:38 +00:00
super.init(frame: .zero)
initialSetup()
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var intrinsicContentSize: CGSize {
stackView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
}
}
private extension CompositionInputAccessoryView {
2021-01-01 00:49:59 +00:00
// swiftlint:disable:next function_body_length
2020-12-16 01:39:38 +00:00
func initialSetup() {
autoresizingMask = .flexibleHeight
backgroundColor = .secondarySystemFill
addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.spacing = .defaultSpacing
let mediaButton = UIButton()
stackView.addArrangedSubview(mediaButton)
mediaButton.setImage(
UIImage(
systemName: "photo",
withConfiguration: UIImage.SymbolConfiguration(scale: .medium)),
for: .normal)
2021-01-01 00:49:59 +00:00
mediaButton.addAction(UIAction { [weak self] _ in
guard let self = self else { return }
self.parentViewModel.presentMediaPicker(viewModel: self.viewModel)
},
for: .touchUpInside)
2020-12-16 01:39:38 +00:00
2021-01-03 22:37:06 +00:00
let cameraButton = UIButton()
2021-01-01 23:31:39 +00:00
#if !IS_SHARE_EXTENSION
if AVCaptureDevice.authorizationStatus(for: .video) != .restricted {
stackView.addArrangedSubview(cameraButton)
cameraButton.setImage(
UIImage(
systemName: "camera",
withConfiguration: UIImage.SymbolConfiguration(scale: .medium)),
for: .normal)
cameraButton.addAction(UIAction { [weak self] _ in
guard let self = self else { return }
self.parentViewModel.presentCamera(viewModel: self.viewModel)
},
for: .touchUpInside)
}
#endif
2020-12-16 01:39:38 +00:00
let pollButton = UIButton()
stackView.addArrangedSubview(pollButton)
pollButton.setImage(
UIImage(
systemName: "chart.bar.xaxis",
withConfiguration: UIImage.SymbolConfiguration(scale: .medium)),
for: .normal)
2021-01-01 00:49:59 +00:00
stackView.addArrangedSubview(visibilityButton)
visibilityButton.showsMenuAsPrimaryAction = true
visibilityButton.menu = UIMenu(children: Status.Visibility.allCasesExceptUnknown.reversed().map { visibility in
UIAction(
title: visibility.title ?? "",
image: UIImage(systemName: visibility.systemImageName),
discoverabilityTitle: visibility.description) { [weak self] _ in
self?.parentViewModel.visibility = visibility
}
})
stackView.addArrangedSubview(contentWarningButton)
contentWarningButton.setTitle(
NSLocalizedString("status.content-warning-abbreviation", comment: ""),
for: .normal)
contentWarningButton.addAction(
UIAction { [weak self] _ in self?.viewModel.displayContentWarning.toggle() },
for: .touchUpInside)
2020-12-16 01:39:38 +00:00
2021-01-01 00:49:59 +00:00
stackView.addArrangedSubview(UIView())
2020-12-16 01:39:38 +00:00
2021-01-04 01:15:50 +00:00
let charactersLabel = UILabel()
stackView.addArrangedSubview(charactersLabel)
charactersLabel.font = .preferredFont(forTextStyle: .callout)
2020-12-16 01:39:38 +00:00
stackView.addArrangedSubview(addButton)
addButton.setImage(
UIImage(
systemName: "plus.circle.fill",
withConfiguration: UIImage.SymbolConfiguration(scale: .medium)),
for: .normal)
2021-01-01 00:49:59 +00:00
addButton.addAction(UIAction { [weak self] _ in
guard let self = self else { return }
self.parentViewModel.insert(after: self.viewModel)
}, for: .touchUpInside)
2021-01-04 01:15:50 +00:00
viewModel.$canAddAttachment.sink {
mediaButton.isEnabled = $0
cameraButton.isEnabled = $0
}
.store(in: &cancellables)
viewModel.$remainingCharacters.sink {
charactersLabel.text = String($0)
charactersLabel.textColor = $0 < 0 ? .systemRed : .label
}
.store(in: &cancellables)
2021-01-03 22:37:06 +00:00
2021-01-01 00:49:59 +00:00
viewModel.$isPostable
.sink { [weak self] in self?.addButton.isEnabled = $0 }
.store(in: &cancellables)
2020-12-16 01:39:38 +00:00
2021-01-01 00:49:59 +00:00
parentViewModel.$visibility
.sink { [weak self] in
self?.visibilityButton.setImage(UIImage(systemName: $0.systemImageName), for: .normal)
}
.store(in: &cancellables)
for button in [mediaButton, pollButton, visibilityButton, contentWarningButton, addButton] {
2020-12-16 01:39:38 +00:00
button.heightAnchor.constraint(greaterThanOrEqualToConstant: .minimumButtonDimension).isActive = true
button.widthAnchor.constraint(greaterThanOrEqualToConstant: .minimumButtonDimension).isActive = true
}
NSLayoutConstraint.activate([
2021-01-01 00:49:59 +00:00
stackView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
2020-12-16 01:39:38 +00:00
stackView.topAnchor.constraint(equalTo: topAnchor),
2021-01-01 00:49:59 +00:00
stackView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
2020-12-16 01:39:38 +00:00
stackView.bottomAnchor.constraint(equalTo: bottomAnchor)
])
}
}