co-maps/iphone/Maps/UI/BottomMenu/Menu/BottomMenuPresenter.swift

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

179 lines
5.5 KiB
Swift
Raw Normal View History

2025-11-22 13:58:55 +01:00
protocol BottomMenuPresenterProtocol: UITableViewDelegate, UITableViewDataSource {
func onClosePressed()
func cellToHighlightIndexPath() -> IndexPath?
func setCellHighlighted(_ highlighted: Bool)
}
class BottomMenuPresenter: NSObject {
enum CellType: Int, CaseIterable {
case addPlace
case recordTrack
case share
case donate
case downloadMaps
case settings
case help
}
enum Sections: Int {
case layers
case items
}
private weak var view: BottomMenuViewProtocol?
private let interactor: BottomMenuInteractorProtocol
private let sections: [Sections]
private var menuCells: [CellType]
private let trackRecorder = TrackRecordingManager.shared
private var cellToHighlight: CellType?
init(view: BottomMenuViewProtocol,
interactor: BottomMenuInteractorProtocol,
sections: [Sections]) {
self.view = view
self.interactor = interactor
self.sections = sections
self.menuCells = []
self.cellToHighlight = Self.getCellToHighlight()
super.init()
}
private static func getCellToHighlight() -> CellType? {
let featureToHighlightData = DeepLinkHandler.shared.getInAppFeatureHighlightData()
guard let featureToHighlightData, featureToHighlightData.urlType == .menu else { return nil }
switch featureToHighlightData.feature {
case .trackRecorder: return .recordTrack
default: return nil
}
}
}
extension BottomMenuPresenter: BottomMenuPresenterProtocol {
func onClosePressed() {
interactor.close()
}
func cellToHighlightIndexPath() -> IndexPath? {
// Highlighting is enabled only for the .items section.
guard let cellToHighlight,
let sectionIndex = sections.firstIndex(of: .items),
let cellIndex = menuCells.firstIndex(of: cellToHighlight) else { return nil }
return IndexPath(row: cellIndex, section: sectionIndex)
}
func setCellHighlighted(_ highlighted: Bool) {
cellToHighlight = nil
}
}
//MARK: -- UITableViewDataSource
extension BottomMenuPresenter {
func numberOfSections(in tableView: UITableView) -> Int {
sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch sections[section] {
case .layers:
return 1
case .items:
let leftButtonType = Settings.leftButtonType
menuCells = CellType.allCases.filter { cell in
if cell == .donate {
return false
} else if leftButtonType == .addPlace, cell == .addPlace {
return false
} else if leftButtonType == .recordTrack, cell == .recordTrack {
return false
} else if leftButtonType == .help, cell == .help {
return false
} else if leftButtonType == .settings, cell == .settings {
return false
}
return true
}
return menuCells.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch sections[indexPath.section] {
case .layers:
let cell = tableView.dequeueReusableCell(cell: BottomMenuLayersCell.self)!
cell.onClose = { [weak self] in self?.onClosePressed() }
if sections.count > 1 {
cell.addSeparator(.bottom)
}
return cell
case .items:
let cell = tableView.dequeueReusableCell(cell: BottomMenuItemCell.self)!
switch menuCells[indexPath.row] {
case .addPlace:
let enabled = MWMNavigationDashboardManager.shared().state == .hidden && FrameworkHelper.canEditMapAtViewportCenter()
cell.configure(imageName: "plus",
title: L("placepage_add_place_button"),
enabled: enabled)
case .recordTrack:
cell.configure(imageName: "track", title: L("start_track_recording"))
case .downloadMaps:
cell.configure(imageName: "ic_menu_download",
title: L("download_maps"),
badgeCount: MapsAppDelegate.theApp().badgeNumber())
case .donate:
cell.configure(imageName: "ic_menu_donate",
title: L("donate"))
case .help:
cell.configure(imageName: "help",
title: L("help"))
case .settings:
cell.configure(imageName: "gearshape.fill",
title: L("settings"))
case .share:
cell.configure(imageName: "square.and.arrow.up",
title: L("share_my_location"))
}
return cell
}
}
}
//MARK: -- UITableViewDelegate
extension BottomMenuPresenter {
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if let cell = tableView.cellForRow(at: indexPath) as? BottomMenuItemCell {
return cell.isEnabled ? indexPath : nil
}
return indexPath
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
switch sections[indexPath.section] {
case .layers:
return;
case .items:
switch menuCells[indexPath.row] {
case .addPlace:
interactor.addPlace()
case .recordTrack:
interactor.toggleTrackRecording()
case .downloadMaps:
interactor.downloadMaps()
case .donate:
interactor.donate()
case .help:
interactor.openHelp()
case .settings:
interactor.openSettings()
case .share:
if let cell = tableView.cellForRow(at: indexPath) as? BottomMenuItemCell {
interactor.shareLocation(cell: cell)
}
}
}
}
}