[{{mminutes}}:{{sseconds}}] X
Пользователь приглашает вас присоединиться к открытой игре игре с друзьями .
MapInteractor
(0)       Используют 3 человека

Комментарии

Ни одного комментария.
Написать тут
Описание:
MapInteractor
Автор:
majorpein
Создан:
9 ноября 2020 в 11:43
Публичный:
Нет
Тип словаря:
Слова
Текст для игры будет составляться из слов, перемешанных в случайном порядке.
Содержание:
import Delivery_Club_Models
import Delivery_Club_Analytics
import Delivery_Club_Managers
import Delivery_Club_VIP
import Delivery_Club_Remote_Config
private enum Constants {
static let defaultZoom = Float(15)
static let defaultRadius = 1200
static let throttleDelay = 500
static let maximumNumberOfVendors = 50
}
final class MapInteractor<MapRestaurantsManager: RestaurantOnMapManagerProtocol> {
private let restaurantsManager: RestaurantOnMapManagerProtocol
private let throttler: ThrottlerProtocol
private let router: MapRouterProtocol
private let presenter: MapPresenterProtocol
private let analytics: MapAnalyticsAdapterProtocol
private let accountManager: DCAccountManager
private let locationPermissionFlow: LocationPermissionFlow
private let deviceLocationProvider: DeviceLocationProviderProtocol
private let remoteConfig: RemoteFeaturesDataProtocol
private let input: MapInput
private var restaurants: [RestaurantOnMap] = []
private var zoom: Float = Constants.defaultZoom
private var isGeoAvailable: Bool {
remoteConfig.dev(.takeawayMapGeo)
}
private var userPosition: Location {
guard isGeoAvailable, let coordinate = deviceLocationProvider.deviceLocationIfAllowed?.coordinate else {
return input.userPosition
}
return Location(latitude: coordinate.latitude, longitude: coordinate.longitude)
}
init(
restaurantsManager: RestaurantOnMapManagerProtocol,
throttler: ThrottlerProtocol,
router: MapRouterProtocol,
presenter: MapPresenterProtocol,
analytics: MapAnalyticsAdapterProtocol,
accountManager: DCAccountManager,
locationPermissionFlow: LocationPermissionFlow,
deviceLocationProvider: DeviceLocationProviderProtocol,
remoteConfig: RemoteFeaturesDataProtocol,
input: MapInput) {
self.restaurantsManager = restaurantsManager
self.throttler = throttler
self.router = router
self.presenter = presenter
self.analytics = analytics
self.accountManager = accountManager
self.locationPermissionFlow = locationPermissionFlow
self.deviceLocationProvider = deviceLocationProvider
self.remoteConfig = remoteConfig
self.input = input
}
private func selectRestaurant(at indexToSelect: Int?) {
restaurants.indices.forEach { index in
restaurants[index].isSelected = index == indexToSelect
}
}
private func loadRestaurants(for position: Location, radius: Int, shouldSendAnalytics: Bool) {
let parameters = RestaurantOnMapRequest.Parameters(
lat: position.latitude,
long: position.longitude,
radius: radius)
let request = RestaurantOnMapRequest(parameters: parameters)
restaurantsManager.getRestaurantsOnMap(request) { [weak self] result in
guard let self = self else { return }
switch result {
case .success(let restaurants):
let restaurantsToShow = Array(
restaurants
.filter { $0.opened }
.prefix(Constants.maximumNumberOfVendors))
let selectedVendorId = self.restaurants.first { $0.isSelected }?.vendorId
self.restaurants = restaurantsToShow.map {
var service = $0
if service.vendorId == selectedVendorId {
service.isSelected = true
}
return service
}
self.presenter.presentRestaurants(
self.restaurants,
userPosition: self.userPosition,
zoom: self.zoom,
shouldSendAnalytics: shouldSendAnalytics)
if shouldSendAnalytics {
self.analytics.trackMapTagComplete(
availableVendors: self.restaurants.count,
source: "",
carouselName: "",
fastFilterList: [])
}
case .failure:
break
}
}
}
}
extension MapInteractor: MapInteractorProtocol {
func viewDidLoad() {
presenter.presentMap(for: input.userPosition, zoom: zoom)
loadRestaurants(for: input.userPosition, radius: Constants.defaultRadius, shouldSendAnalytics: true)
guard isGeoAvailable else { return }
locationPermissionFlow.startFlow { [weak self] isPermissionGranted in
self?.presenter.presentGeo(isPermissionGranted)
}
}
func mapGeoIsUnavailable() {
deviceLocationProvider.requestDeviceLocation { [weak self] result in
switch result {
case .success(let location):
let position = Location(
latitude: location.coordinate.latitude,
longitude: location.coordinate.longitude
)
self?.presenter.centerMap(on: position)
case .failure:
break
}
}
}
func didTapBackButton() {
router.dismiss()
}
func didTapGeoUnavailableButton() {
locationPermissionFlow.askForPermission { [weak self] isPermissionGranted in
self?.presenter.presentGeo(isPermissionGranted)
}
}
func didSelectPin(with id: Int, pinsOnScreenCount: Int) {
guard let index = restaurants.firstIndex(where: { $0.vendorId == id }) else { return }
selectRestaurant(at: index)
presenter.presentRestaurants(
restaurants,
userPosition: userPosition,
zoom: zoom,
shouldSendAnalytics: false
)
trackPinClick(at: index, availableVendors: pinsOnScreenCount)
}
func didSelectRestaurant(serviceId: Int, vendorId: Int) {
let entryPoint = AnalyticEntryPoint(
source: DC_AMP_VALUE_MAP_TAG,
carouselName: input.entryPoint.carouselName,
fastFilterList: input.entryPoint.fastFilterList
)
router.openRestaurant(serviceId, vendorId: vendorId, deliveryType: .takeAway, entryPoint: entryPoint)
guard let index = restaurants.firstIndex(where: { $0.vendorId == vendorId }) else { return }
trackVendorClick(at: index)
}
func didMove(to position: Location, zoom: Float, radius: Int) {
presenter.presentRestaurantsIfNeeded(
restaurants,
userPosition: userPosition,
zoomBefore: self.zoom,
zoomAfter: zoom
)
self.zoom = zoom
throttler.throttle(delay: .milliseconds(Constants.throttleDelay)) { [weak self] in
self?.loadRestaurants(for: position, radius: radius, shouldSendAnalytics: false)
}
}
func didReload(pinsOnScreenCount: Int) {
trackMapTagComplete(availableVendors: pinsOnScreenCount)
}
}
extension MapInteractor {
private func trackMapTagComplete(availableVendors: Int) {
analytics.trackMapTagComplete(
availableVendors: availableVendors,
source: input.entryPoint.source ?? DC_AMP_VALUE_CATALOG,
carouselName: input.entryPoint.carouselName,
fastFilterList: input.entryPoint.fastFilterList
)
}
private func trackPinClick(at index: Int, availableVendors: Int) {
guard let restaurant = restaurants[safe: index] else { return }
analytics.trackPinClick(
availableVendors: availableVendors,
isVendorActive: restaurant.description.opened,
source: input.entryPoint.source ?? DC_AMP_VALUE_CATALOG,
carouselName: input.entryPoint.carouselName,
fastFilterList: input.entryPoint.fastFilterList
)
}
private func trackVendorClick(at index: Int) {
guard let restaurant = restaurants[safe: index] else { return }
analytics.trackVendorClick(
restaurant: restaurant,
position: index,
isAuthorized: accountManager.isAuth(),
carouselName: input.entryPoint.carouselName,
isFromCarouselPage: input.entryPoint.carouselName != nil,
source: DC_AMP_VALUE_MAP_TAG,
filters: input.entryPoint.fastFilterList
)
}
}

Связаться
Выделить
Выделите фрагменты страницы, относящиеся к вашему сообщению
Скрыть сведения
Скрыть всю личную информацию
Отмена