feat: add poll option reorder supports
This commit is contained in:
parent
0e84b4c164
commit
135e88c650
|
@ -15,9 +15,18 @@ protocol ComposeStatusPollOptionAppendEntryCollectionViewCellDelegate: class {
|
||||||
final class ComposeStatusPollOptionAppendEntryCollectionViewCell: UICollectionViewCell {
|
final class ComposeStatusPollOptionAppendEntryCollectionViewCell: UICollectionViewCell {
|
||||||
|
|
||||||
let pollOptionView = PollOptionView()
|
let pollOptionView = PollOptionView()
|
||||||
|
let reorderBarImageView: UIImageView = {
|
||||||
|
let imageView = UIImageView()
|
||||||
|
imageView.contentMode = .scaleAspectFit
|
||||||
|
imageView.image = UIImage(systemName: "line.horizontal.3")?.withConfiguration(UIImage.SymbolConfiguration(pointSize: 20, weight: .regular)).withRenderingMode(.alwaysTemplate)
|
||||||
|
imageView.tintColor = Asset.Colors.Label.secondary.color
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
let singleTagGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer
|
let singleTagGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer
|
||||||
|
|
||||||
|
weak var delegate: ComposeStatusPollOptionAppendEntryCollectionViewCellDelegate?
|
||||||
|
|
||||||
override var isHighlighted: Bool {
|
override var isHighlighted: Bool {
|
||||||
didSet {
|
didSet {
|
||||||
pollOptionView.roundedBackgroundView.backgroundColor = isHighlighted ? Asset.Colors.Background.secondarySystemBackground.color : Asset.Colors.Background.systemBackground.color
|
pollOptionView.roundedBackgroundView.backgroundColor = isHighlighted ? Asset.Colors.Background.secondarySystemBackground.color : Asset.Colors.Background.systemBackground.color
|
||||||
|
@ -25,7 +34,9 @@ final class ComposeStatusPollOptionAppendEntryCollectionViewCell: UICollectionVi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
weak var delegate: ComposeStatusPollOptionAppendEntryCollectionViewCellDelegate?
|
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
||||||
|
return pollOptionView.frame.contains(point)
|
||||||
|
}
|
||||||
|
|
||||||
override func prepareForReuse() {
|
override func prepareForReuse() {
|
||||||
super.prepareForReuse()
|
super.prepareForReuse()
|
||||||
|
@ -53,10 +64,18 @@ extension ComposeStatusPollOptionAppendEntryCollectionViewCell {
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
pollOptionView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
pollOptionView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||||
pollOptionView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
pollOptionView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||||
pollOptionView.trailingAnchor.constraint(equalTo: contentView.readableContentGuide.trailingAnchor),
|
|
||||||
pollOptionView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
pollOptionView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
reorderBarImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
contentView.addSubview(reorderBarImageView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
reorderBarImageView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||||
|
reorderBarImageView.leadingAnchor.constraint(equalTo: pollOptionView.trailingAnchor, constant: ComposeStatusPollOptionCollectionViewCell.reorderHandlerImageLeadingMargin),
|
||||||
|
reorderBarImageView.trailingAnchor.constraint(equalTo: contentView.readableContentGuide.trailingAnchor),
|
||||||
|
reorderBarImageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||||
|
])
|
||||||
|
|
||||||
pollOptionView.checkmarkImageView.isHidden = true
|
pollOptionView.checkmarkImageView.isHidden = true
|
||||||
pollOptionView.checkmarkBackgroundView.isHidden = true
|
pollOptionView.checkmarkBackgroundView.isHidden = true
|
||||||
pollOptionView.optionPercentageLabel.isHidden = true
|
pollOptionView.optionPercentageLabel.isHidden = true
|
||||||
|
@ -68,6 +87,8 @@ extension ComposeStatusPollOptionAppendEntryCollectionViewCell {
|
||||||
|
|
||||||
pollOptionView.addGestureRecognizer(singleTagGestureRecognizer)
|
pollOptionView.addGestureRecognizer(singleTagGestureRecognizer)
|
||||||
singleTagGestureRecognizer.addTarget(self, action: #selector(ComposeStatusPollOptionAppendEntryCollectionViewCell.singleTagGestureRecognizerHandler(_:)))
|
singleTagGestureRecognizer.addTarget(self, action: #selector(ComposeStatusPollOptionAppendEntryCollectionViewCell.singleTagGestureRecognizerHandler(_:)))
|
||||||
|
|
||||||
|
reorderBarImageView.isHidden = true
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupBorderColor() {
|
private func setupBorderColor() {
|
||||||
|
|
|
@ -16,16 +16,29 @@ protocol ComposeStatusPollOptionCollectionViewCellDelegate: class {
|
||||||
|
|
||||||
final class ComposeStatusPollOptionCollectionViewCell: UICollectionViewCell {
|
final class ComposeStatusPollOptionCollectionViewCell: UICollectionViewCell {
|
||||||
|
|
||||||
|
static let reorderHandlerImageLeadingMargin: CGFloat = 11
|
||||||
|
|
||||||
var disposeBag = Set<AnyCancellable>()
|
var disposeBag = Set<AnyCancellable>()
|
||||||
weak var delegate: ComposeStatusPollOptionCollectionViewCellDelegate?
|
weak var delegate: ComposeStatusPollOptionCollectionViewCellDelegate?
|
||||||
|
|
||||||
let pollOptionView = PollOptionView()
|
let pollOptionView = PollOptionView()
|
||||||
|
let reorderBarImageView: UIImageView = {
|
||||||
|
let imageView = UIImageView()
|
||||||
|
imageView.contentMode = .scaleAspectFit
|
||||||
|
imageView.image = UIImage(systemName: "line.horizontal.3")?.withConfiguration(UIImage.SymbolConfiguration(pointSize: 20, weight: .regular)).withRenderingMode(.alwaysTemplate)
|
||||||
|
imageView.tintColor = Asset.Colors.Label.secondary.color
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
let singleTagGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer
|
let singleTagGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer
|
||||||
|
|
||||||
private var pollOptionSubscription: AnyCancellable?
|
private var pollOptionSubscription: AnyCancellable?
|
||||||
let pollOption = PassthroughSubject<String, Never>()
|
let pollOption = PassthroughSubject<String, Never>()
|
||||||
|
|
||||||
|
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
||||||
|
return pollOptionView.frame.contains(point)
|
||||||
|
}
|
||||||
|
|
||||||
override func prepareForReuse() {
|
override func prepareForReuse() {
|
||||||
super.prepareForReuse()
|
super.prepareForReuse()
|
||||||
|
|
||||||
|
@ -53,10 +66,18 @@ extension ComposeStatusPollOptionCollectionViewCell {
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
pollOptionView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
pollOptionView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||||
pollOptionView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
pollOptionView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||||
pollOptionView.trailingAnchor.constraint(equalTo: contentView.readableContentGuide.trailingAnchor),
|
|
||||||
pollOptionView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
pollOptionView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
reorderBarImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
contentView.addSubview(reorderBarImageView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
reorderBarImageView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||||
|
reorderBarImageView.leadingAnchor.constraint(equalTo: pollOptionView.trailingAnchor, constant: ComposeStatusPollOptionCollectionViewCell.reorderHandlerImageLeadingMargin),
|
||||||
|
reorderBarImageView.trailingAnchor.constraint(equalTo: contentView.readableContentGuide.trailingAnchor),
|
||||||
|
reorderBarImageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||||
|
])
|
||||||
|
|
||||||
pollOptionView.checkmarkImageView.isHidden = true
|
pollOptionView.checkmarkImageView.isHidden = true
|
||||||
pollOptionView.optionPercentageLabel.isHidden = true
|
pollOptionView.optionPercentageLabel.isHidden = true
|
||||||
pollOptionView.optionTextField.text = nil
|
pollOptionView.optionTextField.text = nil
|
||||||
|
|
|
@ -150,9 +150,6 @@ extension ComposeViewController {
|
||||||
])
|
])
|
||||||
|
|
||||||
collectionView.delegate = self
|
collectionView.delegate = self
|
||||||
// Note: do not allow reorder due to the images display order following the upload time
|
|
||||||
// let longPressReorderGesture = UILongPressGestureRecognizer(target: self, action: #selector(ComposeViewController.longPressReorderGestureHandler(_:)))
|
|
||||||
// collectionView.addGestureRecognizer(longPressReorderGesture)
|
|
||||||
viewModel.setupDiffableDataSource(
|
viewModel.setupDiffableDataSource(
|
||||||
for: collectionView,
|
for: collectionView,
|
||||||
dependency: self,
|
dependency: self,
|
||||||
|
@ -162,6 +159,8 @@ extension ComposeViewController {
|
||||||
composeStatusNewPollOptionCollectionViewCellDelegate: self,
|
composeStatusNewPollOptionCollectionViewCellDelegate: self,
|
||||||
composeStatusPollExpiresOptionCollectionViewCellDelegate: self
|
composeStatusPollExpiresOptionCollectionViewCellDelegate: self
|
||||||
)
|
)
|
||||||
|
let longPressReorderGesture = UILongPressGestureRecognizer(target: self, action: #selector(ComposeViewController.longPressReorderGestureHandler(_:)))
|
||||||
|
collectionView.addGestureRecognizer(longPressReorderGesture)
|
||||||
|
|
||||||
// respond scrollView overlap change
|
// respond scrollView overlap change
|
||||||
view.layoutIfNeeded()
|
view.layoutIfNeeded()
|
||||||
|
@ -389,13 +388,20 @@ extension ComposeViewController {
|
||||||
dismiss(animated: true, completion: nil)
|
dismiss(animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do not allow reorder image due to image display order following the update time
|
// seealso: ComposeViewModel.setupDiffableDataSource(…)
|
||||||
@objc private func longPressReorderGestureHandler(_ sender: UILongPressGestureRecognizer) {
|
@objc private func longPressReorderGestureHandler(_ sender: UILongPressGestureRecognizer) {
|
||||||
switch(sender.state) {
|
switch(sender.state) {
|
||||||
case .began:
|
case .began:
|
||||||
guard let selectedIndexPath = collectionView.indexPathForItem(at: sender.location(in: collectionView)) else {
|
guard let selectedIndexPath = collectionView.indexPathForItem(at: sender.location(in: collectionView)),
|
||||||
|
let cell = collectionView.cellForItem(at: selectedIndexPath) as? ComposeStatusPollOptionCollectionViewCell else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
// check if pressing reorder bar no not
|
||||||
|
let locationInCell = sender.location(in: cell)
|
||||||
|
guard cell.reorderBarImageView.frame.contains(locationInCell) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
|
collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
|
||||||
case .changed:
|
case .changed:
|
||||||
guard let selectedIndexPath = collectionView.indexPathForItem(at: sender.location(in: collectionView)),
|
guard let selectedIndexPath = collectionView.indexPathForItem(at: sender.location(in: collectionView)),
|
||||||
|
@ -403,19 +409,20 @@ extension ComposeViewController {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
guard let item = diffableDataSource.itemIdentifier(for: selectedIndexPath),
|
guard let item = diffableDataSource.itemIdentifier(for: selectedIndexPath),
|
||||||
case .attachment = item else {
|
case .pollOption = item else {
|
||||||
collectionView.cancelInteractiveMovement()
|
collectionView.cancelInteractiveMovement()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
collectionView.updateInteractiveMovementTargetPosition(sender.location(in: collectionView))
|
var position = sender.location(in: collectionView)
|
||||||
|
position.x = collectionView.frame.width * 0.5
|
||||||
|
collectionView.updateInteractiveMovementTargetPosition(position)
|
||||||
case .ended:
|
case .ended:
|
||||||
collectionView.endInteractiveMovement()
|
collectionView.endInteractiveMovement()
|
||||||
default:
|
default:
|
||||||
collectionView.cancelInteractiveMovement()
|
collectionView.cancelInteractiveMovement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,8 +578,8 @@ extension ComposeViewController: ComposeToolbarViewDelegate {
|
||||||
viewModel.isPollComposing.value.toggle()
|
viewModel.isPollComposing.value.toggle()
|
||||||
|
|
||||||
// setup initial poll option if needs
|
// setup initial poll option if needs
|
||||||
if viewModel.isPollComposing.value, viewModel.pollAttributes.value.isEmpty {
|
if viewModel.isPollComposing.value, viewModel.pollOptionAttributes.value.isEmpty {
|
||||||
viewModel.pollAttributes.value = [ComposeStatusItem.ComposePollOptionAttribute(), ComposeStatusItem.ComposePollOptionAttribute()]
|
viewModel.pollOptionAttributes.value = [ComposeStatusItem.ComposePollOptionAttribute(), ComposeStatusItem.ComposePollOptionAttribute()]
|
||||||
}
|
}
|
||||||
|
|
||||||
if viewModel.isPollComposing.value {
|
if viewModel.isPollComposing.value {
|
||||||
|
@ -708,7 +715,7 @@ extension ComposeViewController: ComposeStatusPollOptionCollectionViewCellDelega
|
||||||
guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return }
|
guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return }
|
||||||
guard case let .pollOption(attribute) = item else { return }
|
guard case let .pollOption(attribute) = item else { return }
|
||||||
|
|
||||||
var pollAttributes = viewModel.pollAttributes.value
|
var pollAttributes = viewModel.pollOptionAttributes.value
|
||||||
guard let index = pollAttributes.firstIndex(of: attribute) else { return }
|
guard let index = pollAttributes.firstIndex(of: attribute) else { return }
|
||||||
|
|
||||||
// mark previous (fallback to next) item of removed middle poll option become first responder
|
// mark previous (fallback to next) item of removed middle poll option become first responder
|
||||||
|
@ -741,7 +748,7 @@ extension ComposeViewController: ComposeStatusPollOptionCollectionViewCellDelega
|
||||||
pollAttributes.remove(at: index)
|
pollAttributes.remove(at: index)
|
||||||
|
|
||||||
// update data source
|
// update data source
|
||||||
viewModel.pollAttributes.value = pollAttributes
|
viewModel.pollOptionAttributes.value = pollAttributes
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle keyboard return event for poll option input
|
// handle keyboard return event for poll option input
|
||||||
|
|
|
@ -31,26 +31,26 @@ extension ComposeViewModel {
|
||||||
composeStatusPollExpiresOptionCollectionViewCellDelegate: composeStatusPollExpiresOptionCollectionViewCellDelegate
|
composeStatusPollExpiresOptionCollectionViewCellDelegate: composeStatusPollExpiresOptionCollectionViewCellDelegate
|
||||||
)
|
)
|
||||||
|
|
||||||
// Note: do not allow reorder due to the images display order following the upload time
|
diffableDataSource.reorderingHandlers.canReorderItem = { item in
|
||||||
// diffableDataSource.reorderingHandlers.canReorderItem = { item in
|
switch item {
|
||||||
// switch item {
|
case .pollOption: return true
|
||||||
// case .attachment: return true
|
default: return false
|
||||||
// default: return false
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// }
|
// update reordered data source
|
||||||
// diffableDataSource.reorderingHandlers.didReorder = { [weak self] transaction in
|
diffableDataSource.reorderingHandlers.didReorder = { [weak self] transaction in
|
||||||
// guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
//
|
|
||||||
// let items = transaction.finalSnapshot.itemIdentifiers
|
let items = transaction.finalSnapshot.itemIdentifiers
|
||||||
// var attachmentServices: [MastodonAttachmentService] = []
|
var pollOptionAttributes: [ComposeStatusItem.ComposePollOptionAttribute] = []
|
||||||
// for item in items {
|
for item in items {
|
||||||
// guard case let .attachment(attachmentService) = item else { continue }
|
guard case let .pollOption(attribute) = item else { continue }
|
||||||
// attachmentServices.append(attachmentService)
|
pollOptionAttributes.append(attribute)
|
||||||
// }
|
}
|
||||||
// self.attachmentServices.value = attachmentServices
|
self.pollOptionAttributes.value = pollOptionAttributes
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
|
|
||||||
self.diffableDataSource = diffableDataSource
|
self.diffableDataSource = diffableDataSource
|
||||||
var snapshot = NSDiffableDataSourceSnapshot<ComposeStatusSection, ComposeStatusItem>()
|
var snapshot = NSDiffableDataSourceSnapshot<ComposeStatusSection, ComposeStatusItem>()
|
||||||
|
|
|
@ -55,7 +55,7 @@ extension ComposeViewModel.PublishState {
|
||||||
}
|
}
|
||||||
let pollOptions: [String]? = {
|
let pollOptions: [String]? = {
|
||||||
guard viewModel.isPollComposing.value else { return nil }
|
guard viewModel.isPollComposing.value else { return nil }
|
||||||
return viewModel.pollAttributes.value.map { attribute in attribute.option.value }
|
return viewModel.pollOptionAttributes.value.map { attribute in attribute.option.value }
|
||||||
}()
|
}()
|
||||||
let pollExpiresIn: Int? = {
|
let pollExpiresIn: Int? = {
|
||||||
guard viewModel.isPollComposing.value else { return nil }
|
guard viewModel.isPollComposing.value else { return nil }
|
||||||
|
|
|
@ -52,7 +52,7 @@ final class ComposeViewModel {
|
||||||
let attachmentServices = CurrentValueSubject<[MastodonAttachmentService], Never>([])
|
let attachmentServices = CurrentValueSubject<[MastodonAttachmentService], Never>([])
|
||||||
|
|
||||||
// polls
|
// polls
|
||||||
let pollAttributes = CurrentValueSubject<[ComposeStatusItem.ComposePollOptionAttribute], Never>([])
|
let pollOptionAttributes = CurrentValueSubject<[ComposeStatusItem.ComposePollOptionAttribute], Never>([])
|
||||||
let pollExpiresOptionAttribute = ComposeStatusItem.ComposePollExpiresOptionAttribute()
|
let pollExpiresOptionAttribute = ComposeStatusItem.ComposePollExpiresOptionAttribute()
|
||||||
|
|
||||||
init(
|
init(
|
||||||
|
@ -105,7 +105,7 @@ final class ComposeViewModel {
|
||||||
.map { services in
|
.map { services in
|
||||||
services.allSatisfy { $0.uploadStateMachineSubject.value is MastodonAttachmentService.UploadState.Finish }
|
services.allSatisfy { $0.uploadStateMachineSubject.value is MastodonAttachmentService.UploadState.Finish }
|
||||||
}
|
}
|
||||||
let isPollAttributeAllValid = pollAttributes
|
let isPollAttributeAllValid = pollOptionAttributes
|
||||||
.map { pollAttributes in
|
.map { pollAttributes in
|
||||||
pollAttributes.allSatisfy { attribute -> Bool in
|
pollAttributes.allSatisfy { attribute -> Bool in
|
||||||
!attribute.option.value.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
|
!attribute.option.value.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
|
||||||
|
@ -177,7 +177,7 @@ final class ComposeViewModel {
|
||||||
Publishers.CombineLatest3(
|
Publishers.CombineLatest3(
|
||||||
attachmentServices.eraseToAnyPublisher(),
|
attachmentServices.eraseToAnyPublisher(),
|
||||||
isPollComposing.eraseToAnyPublisher(),
|
isPollComposing.eraseToAnyPublisher(),
|
||||||
pollAttributes.eraseToAnyPublisher()
|
pollOptionAttributes.eraseToAnyPublisher()
|
||||||
)
|
)
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] attachmentServices, isPollComposing, pollAttributes in
|
.sink { [weak self] attachmentServices, isPollComposing, pollAttributes in
|
||||||
|
@ -240,7 +240,7 @@ final class ComposeViewModel {
|
||||||
}
|
}
|
||||||
.store(in: &disposeBag)
|
.store(in: &disposeBag)
|
||||||
|
|
||||||
pollAttributes
|
pollOptionAttributes
|
||||||
.sink { [weak self] pollAttributes in
|
.sink { [weak self] pollAttributes in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
pollAttributes.forEach { $0.delegate = self }
|
pollAttributes.forEach { $0.delegate = self }
|
||||||
|
@ -268,10 +268,10 @@ final class ComposeViewModel {
|
||||||
|
|
||||||
extension ComposeViewModel {
|
extension ComposeViewModel {
|
||||||
func createNewPollOptionIfPossible() {
|
func createNewPollOptionIfPossible() {
|
||||||
guard pollAttributes.value.count < 4 else { return }
|
guard pollOptionAttributes.value.count < 4 else { return }
|
||||||
|
|
||||||
let attribute = ComposeStatusItem.ComposePollOptionAttribute()
|
let attribute = ComposeStatusItem.ComposePollOptionAttribute()
|
||||||
pollAttributes.value = pollAttributes.value + [attribute]
|
pollOptionAttributes.value = pollOptionAttributes.value + [attribute]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,6 +287,6 @@ extension ComposeViewModel: MastodonAttachmentServiceDelegate {
|
||||||
extension ComposeViewModel: ComposePollAttributeDelegate {
|
extension ComposeViewModel: ComposePollAttributeDelegate {
|
||||||
func composePollAttribute(_ attribute: ComposeStatusItem.ComposePollOptionAttribute, pollOptionDidChange: String?) {
|
func composePollAttribute(_ attribute: ComposeStatusItem.ComposePollOptionAttribute, pollOptionDidChange: String?) {
|
||||||
// trigger update
|
// trigger update
|
||||||
pollAttributes.value = pollAttributes.value
|
pollOptionAttributes.value = pollOptionAttributes.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue