feat: add state for visibility menu in compose scene
This commit is contained in:
parent
43b67a4cc3
commit
2669caeec2
|
@ -368,6 +368,7 @@ extension ComposeViewController {
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
let image = type.image(interfaceStyle: self.traitCollection.userInterfaceStyle)
|
let image = type.image(interfaceStyle: self.traitCollection.userInterfaceStyle)
|
||||||
self.composeToolbarView.visibilityButton.setImage(image, for: .normal)
|
self.composeToolbarView.visibilityButton.setImage(image, for: .normal)
|
||||||
|
self.composeToolbarView.activeVisibilityType.value = type
|
||||||
}
|
}
|
||||||
.store(in: &disposeBag)
|
.store(in: &disposeBag)
|
||||||
|
|
||||||
|
@ -676,7 +677,7 @@ extension ComposeViewController: TextEditorViewTextAttributesDelegate {
|
||||||
updateAttributedString attributedString: NSAttributedString,
|
updateAttributedString attributedString: NSAttributedString,
|
||||||
completion: @escaping (NSAttributedString?) -> Void
|
completion: @escaping (NSAttributedString?) -> Void
|
||||||
) {
|
) {
|
||||||
// FIXME: needs O(1) update completion to fix profermance issue
|
// FIXME: needs O(1) update completion to fix performance issue
|
||||||
DispatchQueue.global().async {
|
DispatchQueue.global().async {
|
||||||
let string = attributedString.string
|
let string = attributedString.string
|
||||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: update: %s", ((#file as NSString).lastPathComponent), #line, #function, string)
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: update: %s", ((#file as NSString).lastPathComponent), #line, #function, string)
|
||||||
|
@ -1291,7 +1292,8 @@ extension ComposeViewController {
|
||||||
case togglePoll
|
case togglePoll
|
||||||
case toggleContentWarning
|
case toggleContentWarning
|
||||||
case selectVisibilityPublic
|
case selectVisibilityPublic
|
||||||
case selectVisibilityUnlisted
|
// TODO: remove selectVisibilityUnlisted from codebase
|
||||||
|
// case selectVisibilityUnlisted
|
||||||
case selectVisibilityPrivate
|
case selectVisibilityPrivate
|
||||||
case selectVisibilityDirect
|
case selectVisibilityDirect
|
||||||
|
|
||||||
|
@ -1305,7 +1307,7 @@ extension ComposeViewController {
|
||||||
case .togglePoll: return L10n.Scene.Compose.Keyboard.togglePoll
|
case .togglePoll: return L10n.Scene.Compose.Keyboard.togglePoll
|
||||||
case .toggleContentWarning: return L10n.Scene.Compose.Keyboard.toggleContentWarning
|
case .toggleContentWarning: return L10n.Scene.Compose.Keyboard.toggleContentWarning
|
||||||
case .selectVisibilityPublic: return L10n.Scene.Compose.Keyboard.selectVisibilityEntry(L10n.Scene.Compose.Visibility.public)
|
case .selectVisibilityPublic: return L10n.Scene.Compose.Keyboard.selectVisibilityEntry(L10n.Scene.Compose.Visibility.public)
|
||||||
case .selectVisibilityUnlisted: return L10n.Scene.Compose.Keyboard.selectVisibilityEntry(L10n.Scene.Compose.Visibility.unlisted)
|
// case .selectVisibilityUnlisted: return L10n.Scene.Compose.Keyboard.selectVisibilityEntry(L10n.Scene.Compose.Visibility.unlisted)
|
||||||
case .selectVisibilityPrivate: return L10n.Scene.Compose.Keyboard.selectVisibilityEntry(L10n.Scene.Compose.Visibility.private)
|
case .selectVisibilityPrivate: return L10n.Scene.Compose.Keyboard.selectVisibilityEntry(L10n.Scene.Compose.Visibility.private)
|
||||||
case .selectVisibilityDirect: return L10n.Scene.Compose.Keyboard.selectVisibilityEntry(L10n.Scene.Compose.Visibility.direct)
|
case .selectVisibilityDirect: return L10n.Scene.Compose.Keyboard.selectVisibilityEntry(L10n.Scene.Compose.Visibility.direct)
|
||||||
}
|
}
|
||||||
|
@ -1322,9 +1324,9 @@ extension ComposeViewController {
|
||||||
case .togglePoll: return "p" // + shift + command
|
case .togglePoll: return "p" // + shift + command
|
||||||
case .toggleContentWarning: return "c" // + shift + command
|
case .toggleContentWarning: return "c" // + shift + command
|
||||||
case .selectVisibilityPublic: return "1" // + command
|
case .selectVisibilityPublic: return "1" // + command
|
||||||
case .selectVisibilityUnlisted: return "2" // + command
|
// case .selectVisibilityUnlisted: return "2" // + command
|
||||||
case .selectVisibilityPrivate: return "3" // + command
|
case .selectVisibilityPrivate: return "2" // + command
|
||||||
case .selectVisibilityDirect: return "4" // + command
|
case .selectVisibilityDirect: return "3" // + command
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1338,7 +1340,7 @@ extension ComposeViewController {
|
||||||
case .togglePoll: return [.shift, .command]
|
case .togglePoll: return [.shift, .command]
|
||||||
case .toggleContentWarning: return [.shift, .command]
|
case .toggleContentWarning: return [.shift, .command]
|
||||||
case .selectVisibilityPublic: return [.command]
|
case .selectVisibilityPublic: return [.command]
|
||||||
case .selectVisibilityUnlisted: return [.command]
|
// case .selectVisibilityUnlisted: return [.command]
|
||||||
case .selectVisibilityPrivate: return [.command]
|
case .selectVisibilityPrivate: return [.command]
|
||||||
case .selectVisibilityDirect: return [.command]
|
case .selectVisibilityDirect: return [.command]
|
||||||
}
|
}
|
||||||
|
@ -1390,8 +1392,8 @@ extension ComposeViewController {
|
||||||
composeToolbarView.contentWarningButton.sendActions(for: .touchUpInside)
|
composeToolbarView.contentWarningButton.sendActions(for: .touchUpInside)
|
||||||
case .selectVisibilityPublic:
|
case .selectVisibilityPublic:
|
||||||
viewModel.selectedStatusVisibility.value = .public
|
viewModel.selectedStatusVisibility.value = .public
|
||||||
case .selectVisibilityUnlisted:
|
// case .selectVisibilityUnlisted:
|
||||||
viewModel.selectedStatusVisibility.value = .unlisted
|
// viewModel.selectedStatusVisibility.value = .unlisted
|
||||||
case .selectVisibilityPrivate:
|
case .selectVisibilityPrivate:
|
||||||
viewModel.selectedStatusVisibility.value = .private
|
viewModel.selectedStatusVisibility.value = .private
|
||||||
case .selectVisibilityDirect:
|
case .selectVisibilityDirect:
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
import os.log
|
import os.log
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import Combine
|
||||||
import MastodonSDK
|
import MastodonSDK
|
||||||
|
|
||||||
protocol ComposeToolbarViewDelegate: AnyObject {
|
protocol ComposeToolbarViewDelegate: AnyObject {
|
||||||
|
@ -19,6 +20,8 @@ protocol ComposeToolbarViewDelegate: AnyObject {
|
||||||
|
|
||||||
final class ComposeToolbarView: UIView {
|
final class ComposeToolbarView: UIView {
|
||||||
|
|
||||||
|
var disposeBag = Set<AnyCancellable>()
|
||||||
|
|
||||||
static let toolbarButtonSize: CGSize = CGSize(width: 44, height: 44)
|
static let toolbarButtonSize: CGSize = CGSize(width: 44, height: 44)
|
||||||
static let toolbarHeight: CGFloat = 44
|
static let toolbarHeight: CGFloat = 44
|
||||||
|
|
||||||
|
@ -76,6 +79,8 @@ final class ComposeToolbarView: UIView {
|
||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
let activeVisibilityType = CurrentValueSubject<VisibilitySelectionType, Never>(.public)
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
_init()
|
_init()
|
||||||
|
@ -142,6 +147,15 @@ extension ComposeToolbarView {
|
||||||
visibilityButton.showsMenuAsPrimaryAction = true
|
visibilityButton.showsMenuAsPrimaryAction = true
|
||||||
|
|
||||||
updateToolbarButtonUserInterfaceStyle()
|
updateToolbarButtonUserInterfaceStyle()
|
||||||
|
|
||||||
|
// update menu when selected visibility type changed
|
||||||
|
activeVisibilityType
|
||||||
|
.receive(on: RunLoop.main)
|
||||||
|
.sink { [weak self] type in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.visibilityButton.menu = self.createVisibilityContextMenu(interfaceStyle: self.traitCollection.userInterfaceStyle)
|
||||||
|
}
|
||||||
|
.store(in: &disposeBag)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||||
|
@ -161,14 +175,15 @@ extension ComposeToolbarView {
|
||||||
|
|
||||||
enum VisibilitySelectionType: String, CaseIterable {
|
enum VisibilitySelectionType: String, CaseIterable {
|
||||||
case `public`
|
case `public`
|
||||||
case unlisted
|
// TODO: remove unlisted option from codebase
|
||||||
|
// case unlisted
|
||||||
case `private`
|
case `private`
|
||||||
case direct
|
case direct
|
||||||
|
|
||||||
var title: String {
|
var title: String {
|
||||||
switch self {
|
switch self {
|
||||||
case .public: return L10n.Scene.Compose.Visibility.public
|
case .public: return L10n.Scene.Compose.Visibility.public
|
||||||
case .unlisted: return L10n.Scene.Compose.Visibility.unlisted
|
// case .unlisted: return L10n.Scene.Compose.Visibility.unlisted
|
||||||
case .private: return L10n.Scene.Compose.Visibility.private
|
case .private: return L10n.Scene.Compose.Visibility.private
|
||||||
case .direct: return L10n.Scene.Compose.Visibility.direct
|
case .direct: return L10n.Scene.Compose.Visibility.direct
|
||||||
}
|
}
|
||||||
|
@ -181,7 +196,7 @@ extension ComposeToolbarView {
|
||||||
case .light: return UIImage(systemName: "person.3", withConfiguration: UIImage.SymbolConfiguration(pointSize: 15, weight: .medium))!
|
case .light: return UIImage(systemName: "person.3", withConfiguration: UIImage.SymbolConfiguration(pointSize: 15, weight: .medium))!
|
||||||
default: return UIImage(systemName: "person.3.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 15, weight: .medium))!
|
default: return UIImage(systemName: "person.3.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 15, weight: .medium))!
|
||||||
}
|
}
|
||||||
case .unlisted: return UIImage(systemName: "eye.slash", withConfiguration: UIImage.SymbolConfiguration(pointSize: 18, weight: .regular))!
|
// case .unlisted: return UIImage(systemName: "eye.slash", withConfiguration: UIImage.SymbolConfiguration(pointSize: 18, weight: .regular))!
|
||||||
case .private: return UIImage(systemName: "person.crop.circle.badge.plus", withConfiguration: UIImage.SymbolConfiguration(pointSize: 18, weight: .regular))!
|
case .private: return UIImage(systemName: "person.crop.circle.badge.plus", withConfiguration: UIImage.SymbolConfiguration(pointSize: 18, weight: .regular))!
|
||||||
case .direct: return UIImage(systemName: "at", withConfiguration: UIImage.SymbolConfiguration(pointSize: 19, weight: .regular))!
|
case .direct: return UIImage(systemName: "at", withConfiguration: UIImage.SymbolConfiguration(pointSize: 19, weight: .regular))!
|
||||||
}
|
}
|
||||||
|
@ -190,7 +205,7 @@ extension ComposeToolbarView {
|
||||||
func imageNameForTimeline() -> String {
|
func imageNameForTimeline() -> String {
|
||||||
switch self {
|
switch self {
|
||||||
case .public: return "person.3"
|
case .public: return "person.3"
|
||||||
case .unlisted: return "eye.slash"
|
// case .unlisted: return "eye.slash"
|
||||||
case .private: return "person.crop.circle.badge.plus"
|
case .private: return "person.crop.circle.badge.plus"
|
||||||
case .direct: return "at"
|
case .direct: return "at"
|
||||||
}
|
}
|
||||||
|
@ -199,7 +214,7 @@ extension ComposeToolbarView {
|
||||||
var visibility: Mastodon.Entity.Status.Visibility {
|
var visibility: Mastodon.Entity.Status.Visibility {
|
||||||
switch self {
|
switch self {
|
||||||
case .public: return .public
|
case .public: return .public
|
||||||
case .unlisted: return .unlisted
|
// case .unlisted: return .unlisted
|
||||||
case .private: return .private
|
case .private: return .private
|
||||||
case .direct: return .direct
|
case .direct: return .direct
|
||||||
}
|
}
|
||||||
|
@ -268,7 +283,8 @@ extension ComposeToolbarView {
|
||||||
|
|
||||||
private func createVisibilityContextMenu(interfaceStyle: UIUserInterfaceStyle) -> UIMenu {
|
private func createVisibilityContextMenu(interfaceStyle: UIUserInterfaceStyle) -> UIMenu {
|
||||||
let children: [UIMenuElement] = VisibilitySelectionType.allCases.map { type in
|
let children: [UIMenuElement] = VisibilitySelectionType.allCases.map { type in
|
||||||
UIAction(title: type.title, image: type.image(interfaceStyle: interfaceStyle), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak self] action in
|
let state: UIMenuElement.State = activeVisibilityType.value == type ? .on : .off
|
||||||
|
return UIAction(title: type.title, image: type.image(interfaceStyle: interfaceStyle), identifier: nil, discoverabilityTitle: nil, attributes: [], state: state) { [weak self] action in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: visibilitySelectionType: %s", ((#file as NSString).lastPathComponent), #line, #function, type.rawValue)
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: visibilitySelectionType: %s", ((#file as NSString).lastPathComponent), #line, #function, type.rawValue)
|
||||||
self.delegate?.composeToolbarView(self, visibilityButtonDidPressed: self.visibilityButton, visibilitySelectionType: type)
|
self.delegate?.composeToolbarView(self, visibilityButtonDidPressed: self.visibilityButton, visibilitySelectionType: type)
|
||||||
|
|
Loading…
Reference in New Issue