Move identity changing button
This commit is contained in:
parent
127fef7078
commit
664acc097c
|
@ -28,6 +28,11 @@ final class NewStatusViewController: UIViewController {
|
|||
self.viewModel = viewModel
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
NotificationCenter.default.publisher(for: UIResponder.keyboardDidChangeFrameNotification)
|
||||
.merge(with: NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification))
|
||||
.sink { [weak self] in self?.adjustContentInset(notification: $0) }
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
|
@ -66,7 +71,10 @@ final class NewStatusViewController: UIViewController {
|
|||
activityIndicatorView.centerYAnchor.constraint(equalTo: scrollView.centerYAnchor)
|
||||
])
|
||||
|
||||
setupBarButtonItems(identityContext: viewModel.identityContext)
|
||||
navigationItem.leftBarButtonItem = UIBarButtonItem(
|
||||
systemItem: .cancel,
|
||||
primaryAction: UIAction { [weak self] _ in self?.dismiss() })
|
||||
navigationItem.rightBarButtonItem = postButton
|
||||
|
||||
postButton.primaryAction = UIAction(title: NSLocalizedString("post", comment: "")) { [weak self] _ in
|
||||
self?.viewModel.post()
|
||||
|
@ -84,11 +92,6 @@ final class NewStatusViewController: UIViewController {
|
|||
}
|
||||
#endif
|
||||
|
||||
NotificationCenter.default.publisher(for: UIResponder.keyboardDidChangeFrameNotification)
|
||||
.merge(with: NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification))
|
||||
.sink { [weak self] in self?.adjustContentInset(notification: $0) }
|
||||
.store(in: &cancellables)
|
||||
|
||||
setupViewModelBindings()
|
||||
}
|
||||
}
|
||||
|
@ -150,6 +153,8 @@ private extension NewStatusViewController {
|
|||
presentAttachmentEditor(
|
||||
attachmentViewModel: attachmentViewModel,
|
||||
compositionViewModel: compositionViewModel)
|
||||
case let .changeIdentity(identity):
|
||||
changeIdentity(identity)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,9 +239,6 @@ private extension NewStatusViewController {
|
|||
viewModel.$compositionViewModels
|
||||
.sink { [weak self] in self?.set(compositionViewModels: $0) }
|
||||
.store(in: &cancellables)
|
||||
viewModel.$identityContext
|
||||
.sink { [weak self] in self?.setupBarButtonItems(identityContext: $0) }
|
||||
.store(in: &cancellables)
|
||||
viewModel.$postingState
|
||||
.sink { [weak self] in self?.apply(postingState: $0) }
|
||||
.store(in: &cancellables)
|
||||
|
@ -250,18 +252,6 @@ private extension NewStatusViewController {
|
|||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func setupBarButtonItems(identityContext: IdentityContext) {
|
||||
let cancelButton = UIBarButtonItem(
|
||||
systemItem: .cancel,
|
||||
primaryAction: UIAction { [weak self] _ in self?.dismiss() })
|
||||
|
||||
navigationItem.leftBarButtonItem = cancelButton
|
||||
navigationItem.titleView = viewModel.canChangeIdentity
|
||||
? changeIdentityButton(identityContext: identityContext)
|
||||
: nil
|
||||
navigationItem.rightBarButtonItem = postButton
|
||||
}
|
||||
|
||||
func presentMediaPicker(compositionViewModel: CompositionViewModel) {
|
||||
mediaSelections.first().sink { [weak self] results in
|
||||
guard let self = self, let result = results.first else { return }
|
||||
|
@ -422,44 +412,6 @@ private extension NewStatusViewController {
|
|||
}
|
||||
}
|
||||
|
||||
func changeIdentityButton(identityContext: IdentityContext) -> UIButton {
|
||||
let changeIdentityButton = UIButton()
|
||||
let downsampled = KingfisherOptionsInfo.downsampled(
|
||||
dimension: .barButtonItemDimension,
|
||||
scaleFactor: UIScreen.main.scale)
|
||||
|
||||
let menuItems = viewModel.authenticatedIdentities
|
||||
.filter { $0.id != identityContext.identity.id }
|
||||
.map { identity in
|
||||
UIDeferredMenuElement { completion in
|
||||
let action = UIAction(title: identity.handle) { [weak self] _ in
|
||||
self?.changeIdentity(identity)
|
||||
}
|
||||
|
||||
if let image = identity.image {
|
||||
KingfisherManager.shared.retrieveImage(with: image, options: downsampled) {
|
||||
if case let .success(value) = $0 {
|
||||
action.image = value.image
|
||||
}
|
||||
|
||||
completion([action])
|
||||
}
|
||||
} else {
|
||||
completion([action])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
changeIdentityButton.kf.setImage(
|
||||
with: identityContext.identity.image,
|
||||
for: .normal,
|
||||
options: downsampled)
|
||||
changeIdentityButton.showsMenuAsPrimaryAction = true
|
||||
changeIdentityButton.menu = UIMenu(children: menuItems)
|
||||
|
||||
return changeIdentityButton
|
||||
}
|
||||
|
||||
func changeIdentity(_ identity: Identity) {
|
||||
if viewModel.compositionViewModels.contains(where: { !$0.attachmentViewModels.isEmpty }) {
|
||||
let alertController = UIAlertController(
|
||||
|
|
|
@ -67,6 +67,10 @@ public final class NewStatusViewModel: ObservableObject {
|
|||
|
||||
allIdentitiesService.authenticatedIdentitiesPublisher()
|
||||
.assignErrorsToAlertItem(to: \.alertItem, on: self)
|
||||
.combineLatest($identityContext)
|
||||
.map { authenticatedIdentities, currentIdentity in
|
||||
authenticatedIdentities.filter { $0.id != currentIdentity.identity.id }
|
||||
}
|
||||
.assign(to: &$authenticatedIdentities)
|
||||
$compositionViewModels.flatMap { Publishers.MergeMany($0.map(\.$isPostable)) }
|
||||
.receive(on: DispatchQueue.main) // hack to punt to next run loop, consider refactoring
|
||||
|
@ -87,6 +91,7 @@ public extension NewStatusViewModel {
|
|||
case presentDocumentPicker(CompositionViewModel)
|
||||
case presentEmojiPicker(Int)
|
||||
case editAttachment(AttachmentViewModel, CompositionViewModel)
|
||||
case changeIdentity(Identity)
|
||||
}
|
||||
|
||||
enum PostingState {
|
||||
|
@ -159,6 +164,10 @@ public extension NewStatusViewModel {
|
|||
|
||||
post(viewModel: unposted, inReplyToId: inReplyToViewModel?.id)
|
||||
}
|
||||
|
||||
func changeIdentity(_ identity: Identity) {
|
||||
eventsSubject.send(.changeIdentity(identity))
|
||||
}
|
||||
}
|
||||
|
||||
private extension NewStatusViewModel {
|
||||
|
|
|
@ -6,7 +6,8 @@ import UIKit
|
|||
import ViewModels
|
||||
|
||||
final class CompositionView: UIView {
|
||||
let avatarImageView = UIImageView()
|
||||
let avatarImageView = AnimatedImageView()
|
||||
let changeIdentityButton = UIButton()
|
||||
let spoilerTextField = UITextField()
|
||||
let textView = UITextView()
|
||||
let textViewPlaceholder = UILabel()
|
||||
|
@ -64,6 +65,13 @@ private extension CompositionView {
|
|||
avatarImageView.clipsToBounds = true
|
||||
avatarImageView.setContentHuggingPriority(.required, for: .horizontal)
|
||||
|
||||
changeIdentityButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
avatarImageView.addSubview(changeIdentityButton)
|
||||
avatarImageView.isUserInteractionEnabled = true
|
||||
changeIdentityButton.setBackgroundImage(.highlightedButtonBackground, for: .highlighted)
|
||||
changeIdentityButton.showsMenuAsPrimaryAction = true
|
||||
changeIdentityButton.menu = changeIdentityMenu(identities: parentViewModel.authenticatedIdentities)
|
||||
|
||||
let stackView = UIStackView()
|
||||
|
||||
addSubview(stackView)
|
||||
|
@ -179,6 +187,10 @@ private extension CompositionView {
|
|||
.sink { [weak self] in self?.avatarImageView.kf.setImage(with: $0) }
|
||||
.store(in: &cancellables)
|
||||
|
||||
parentViewModel.$authenticatedIdentities
|
||||
.sink { [weak self] in self?.changeIdentityButton.menu = self?.changeIdentityMenu(identities: $0) }
|
||||
.store(in: &cancellables)
|
||||
|
||||
viewModel.$attachmentViewModels
|
||||
.receive(on: RunLoop.main)
|
||||
.sink { [weak self] attachmentViewModels in
|
||||
|
@ -209,6 +221,10 @@ private extension CompositionView {
|
|||
avatarImageView.topAnchor.constraint(equalTo: guide.topAnchor),
|
||||
avatarImageView.leadingAnchor.constraint(equalTo: guide.leadingAnchor),
|
||||
avatarImageView.bottomAnchor.constraint(lessThanOrEqualTo: guide.bottomAnchor),
|
||||
changeIdentityButton.leadingAnchor.constraint(equalTo: avatarImageView.leadingAnchor),
|
||||
changeIdentityButton.topAnchor.constraint(equalTo: avatarImageView.topAnchor),
|
||||
changeIdentityButton.bottomAnchor.constraint(equalTo: avatarImageView.bottomAnchor),
|
||||
changeIdentityButton.trailingAnchor.constraint(equalTo: avatarImageView.trailingAnchor),
|
||||
stackView.leadingAnchor.constraint(equalTo: avatarImageView.trailingAnchor, constant: .defaultSpacing),
|
||||
stackView.topAnchor.constraint(greaterThanOrEqualTo: guide.topAnchor),
|
||||
stackView.bottomAnchor.constraint(lessThanOrEqualTo: guide.bottomAnchor),
|
||||
|
@ -228,4 +244,30 @@ private extension CompositionView {
|
|||
|
||||
NSLayoutConstraint.activate(constraints)
|
||||
}
|
||||
|
||||
func changeIdentityMenu(identities: [Identity]) -> UIMenu {
|
||||
UIMenu(children: identities.map { identity in
|
||||
UIDeferredMenuElement { completion in
|
||||
let action = UIAction(title: identity.handle) { [weak self] _ in
|
||||
self?.parentViewModel.changeIdentity(identity)
|
||||
}
|
||||
|
||||
if let image = identity.image {
|
||||
KingfisherManager.shared.retrieveImage(
|
||||
with: image,
|
||||
options: KingfisherOptionsInfo.downsampled(
|
||||
dimension: .barButtonItemDimension,
|
||||
scaleFactor: UIScreen.main.scale)) {
|
||||
if case let .success(value) = $0 {
|
||||
action.image = value.image
|
||||
}
|
||||
|
||||
completion([action])
|
||||
}
|
||||
} else {
|
||||
completion([action])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue