Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
|
|
@ -0,0 +1,244 @@
|
|||
protocol ActionBarViewControllerDelegate: AnyObject {
|
||||
func actionBar(_ actionBar: ActionBarViewController, didPressButton type: ActionBarButtonType)
|
||||
}
|
||||
|
||||
final class ActionBarViewController: UIViewController {
|
||||
@IBOutlet var stackView: UIStackView!
|
||||
private(set) var downloadButton: ActionBarButton? = nil
|
||||
private(set) var bookmarkButton: ActionBarButton? = nil
|
||||
private var popoverSourceView: UIView? {
|
||||
stackView.arrangedSubviews.last
|
||||
}
|
||||
|
||||
var placePageData: PlacePageData!
|
||||
var isRoutePlanning = false
|
||||
var canAddStop = false
|
||||
|
||||
private var visibleButtons: [ActionBarButtonType] = []
|
||||
private var additionalButtons: [ActionBarButtonType] = []
|
||||
|
||||
weak var delegate: ActionBarViewControllerDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
configureButtons()
|
||||
}
|
||||
|
||||
// MARK: - Private methods
|
||||
|
||||
private func configureButtons() {
|
||||
if placePageData.isRoutePoint {
|
||||
visibleButtons.append(.routeRemoveStop)
|
||||
} else if placePageData.roadType != .none {
|
||||
switch placePageData.roadType {
|
||||
case .toll:
|
||||
visibleButtons.append(.avoidToll)
|
||||
case .ferry:
|
||||
visibleButtons.append(.avoidFerry)
|
||||
case .dirty:
|
||||
visibleButtons.append(.avoidDirty)
|
||||
default:
|
||||
fatalError()
|
||||
}
|
||||
} else {
|
||||
configButton1()
|
||||
configButton2()
|
||||
configButton3()
|
||||
configButton4()
|
||||
}
|
||||
|
||||
setupButtonsState()
|
||||
}
|
||||
|
||||
private func configButton1() {
|
||||
if let mapNodeAttributes = placePageData.mapNodeAttributes {
|
||||
switch mapNodeAttributes.nodeStatus {
|
||||
case .onDiskOutOfDate, .onDisk, .undefined:
|
||||
break
|
||||
case .downloading, .applying, .inQueue, .error, .notDownloaded, .partly:
|
||||
visibleButtons.append(.download)
|
||||
return
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
var buttons: [ActionBarButtonType] = []
|
||||
switch placePageData.objectType {
|
||||
case .POI, .bookmark, .track:
|
||||
if isRoutePlanning {
|
||||
buttons.append(.routeFrom)
|
||||
}
|
||||
let hasAnyPhones = !(placePageData.infoData?.phones ?? []).isEmpty
|
||||
if hasAnyPhones, AppInfo.shared().canMakeCalls {
|
||||
buttons.append(.call)
|
||||
}
|
||||
if !isRoutePlanning {
|
||||
buttons.append(.routeFrom)
|
||||
}
|
||||
case .trackRecording:
|
||||
break
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
|
||||
guard !buttons.isEmpty else { return }
|
||||
visibleButtons.append(buttons[0])
|
||||
if buttons.count > 1 {
|
||||
additionalButtons.append(contentsOf: buttons.suffix(from: 1))
|
||||
}
|
||||
}
|
||||
|
||||
private func configButton2() {
|
||||
var buttons: [ActionBarButtonType] = []
|
||||
switch placePageData.objectType {
|
||||
case .POI, .bookmark:
|
||||
if canAddStop {
|
||||
buttons.append(.routeAddStop)
|
||||
}
|
||||
buttons.append(.bookmark)
|
||||
case .track:
|
||||
if canAddStop {
|
||||
buttons.append(.routeAddStop)
|
||||
}
|
||||
buttons.append(.track)
|
||||
case .trackRecording:
|
||||
buttons.append(.notSaveTrackRecording)
|
||||
buttons.append(.saveTrackRecording)
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
assert(buttons.count > 0)
|
||||
|
||||
visibleButtons.append(buttons[0])
|
||||
if buttons.count > 1 {
|
||||
additionalButtons.append(contentsOf: buttons.suffix(from: 1))
|
||||
}
|
||||
}
|
||||
|
||||
private func configButton3() {
|
||||
switch placePageData.objectType {
|
||||
case .POI, .bookmark, .track:
|
||||
visibleButtons.append(.routeTo)
|
||||
case .trackRecording:
|
||||
break
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
private func configButton4() {
|
||||
guard !additionalButtons.isEmpty else { return }
|
||||
additionalButtons.count == 1 ? visibleButtons.append(additionalButtons[0]) : visibleButtons.append(.more)
|
||||
}
|
||||
|
||||
private func setupButtonsState() {
|
||||
for buttonType in visibleButtons {
|
||||
let (selected, enabled) = buttonState(buttonType)
|
||||
let button = ActionBarButton(delegate: self,
|
||||
buttonType: buttonType,
|
||||
isSelected: selected,
|
||||
isEnabled: enabled)
|
||||
stackView.addArrangedSubview(button)
|
||||
switch buttonType {
|
||||
case .download:
|
||||
downloadButton = button
|
||||
updateDownloadButtonState(placePageData.mapNodeAttributes!.nodeStatus)
|
||||
case .bookmark:
|
||||
bookmarkButton = button
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func buttonState(_ buttonType: ActionBarButtonType) -> (selected: Bool, enabled: Bool) {
|
||||
var selected = false
|
||||
let enabled = true
|
||||
switch buttonType {
|
||||
case .bookmark:
|
||||
selected = placePageData.bookmarkData != nil
|
||||
case .track:
|
||||
selected = placePageData.trackData != nil
|
||||
default:
|
||||
break
|
||||
}
|
||||
return (selected, enabled)
|
||||
}
|
||||
|
||||
private func showMore() {
|
||||
let actionSheet = UIAlertController(title: placePageData.previewData.title,
|
||||
message: placePageData.previewData.subtitle,
|
||||
preferredStyle: .actionSheet)
|
||||
for button in additionalButtons {
|
||||
let (selected, enabled) = buttonState(button)
|
||||
let action = UIAlertAction(title: titleForButton(button, selected),
|
||||
style: .default,
|
||||
handler: { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
self.delegate?.actionBar(self, didPressButton: button)
|
||||
})
|
||||
action.isEnabled = enabled
|
||||
actionSheet.addAction(action)
|
||||
}
|
||||
actionSheet.addAction(UIAlertAction(title: L("cancel"), style: .cancel))
|
||||
if let popover = actionSheet.popoverPresentationController, let sourceView = stackView.arrangedSubviews.last {
|
||||
popover.sourceView = sourceView
|
||||
popover.sourceRect = sourceView.bounds
|
||||
}
|
||||
present(actionSheet, animated: true)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Public methods
|
||||
|
||||
func resetButtons() {
|
||||
stackView.arrangedSubviews.forEach {
|
||||
stackView.removeArrangedSubview($0)
|
||||
$0.removeFromSuperview()
|
||||
}
|
||||
visibleButtons.removeAll()
|
||||
additionalButtons.removeAll()
|
||||
downloadButton = nil
|
||||
bookmarkButton = nil
|
||||
configureButtons()
|
||||
}
|
||||
|
||||
func updateDownloadButtonState(_ nodeStatus: MapNodeStatus) {
|
||||
guard let downloadButton = downloadButton, let mapNodeAttributes = placePageData.mapNodeAttributes else { return }
|
||||
switch mapNodeAttributes.nodeStatus {
|
||||
case .downloading:
|
||||
downloadButton.mapDownloadProgress?.state = .progress
|
||||
case .applying, .inQueue:
|
||||
downloadButton.mapDownloadProgress?.state = .spinner
|
||||
case .error:
|
||||
downloadButton.mapDownloadProgress?.state = .failed
|
||||
case .onDisk, .undefined, .onDiskOutOfDate:
|
||||
downloadButton.mapDownloadProgress?.state = .completed
|
||||
case .notDownloaded, .partly:
|
||||
downloadButton.mapDownloadProgress?.state = .normal
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
func updateBookmarkButtonState(isSelected: Bool) {
|
||||
guard let bookmarkButton else { return }
|
||||
if !isSelected && BookmarksManager.shared().hasRecentlyDeletedBookmark() {
|
||||
bookmarkButton.setBookmarkButtonState(.recover)
|
||||
return
|
||||
}
|
||||
bookmarkButton.setBookmarkButtonState(isSelected ? .delete : .save)
|
||||
}
|
||||
}
|
||||
|
||||
extension ActionBarViewController: ActionBarButtonDelegate {
|
||||
func tapOnButton(with type: ActionBarButtonType) {
|
||||
switch type {
|
||||
case .more:
|
||||
showMore()
|
||||
default:
|
||||
delegate?.actionBar(self, didPressButton: type)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue