forked from organicmaps/organicmaps
[iOS] [refactoring] place page UI
This commit is contained in:
parent
c46c2e25f7
commit
b763eb5126
45 changed files with 5329 additions and 314 deletions
|
@ -760,8 +760,7 @@ using namespace std;
|
|||
|
||||
#pragma mark - MWMLocationObserver
|
||||
|
||||
- (void)onLocationUpdate:(location::GpsInfo const &)info {
|
||||
CLLocation *location = [[CLLocation alloc] initWithLatitude:info.m_latitude longitude:info.m_longitude];
|
||||
- (void)onLocationUpdate:(CLLocation *)location {
|
||||
[self.tableView.visibleCells enumerateObjectsUsingBlock:^(UITableViewCell *cell, NSUInteger idx, BOOL *stop) {
|
||||
auto const indexPath = [self.tableView indexPathForCell:cell];
|
||||
auto const §ion = [self currentSections][indexPath.section];
|
||||
|
|
|
@ -98,7 +98,7 @@ final class EditOnWebViewController: MWMViewController {
|
|||
|
||||
private func presentSharingOptions() {
|
||||
guard let url = MWMBookmarksManager.shared().webEditorUrl(forCategoryId: category.categoryId,
|
||||
language: AppInfo.shared()?.twoLetterLanguageId ?? "en") else {
|
||||
language: AppInfo.shared().twoLetterLanguageId ) else {
|
||||
assert(false, "Unexpected empty url for category \(category.title)")
|
||||
return
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ final class TagsDataSource: NSObject {
|
|||
private var maxTagsNumber: Int = 0
|
||||
|
||||
func loadTags(onComplete: @escaping (Bool) -> Void) {
|
||||
MWMBookmarksManager.shared().loadTags(withLanguage: AppInfo.shared()?.twoLetterLanguageId) { tags, maxTagsNumber in
|
||||
MWMBookmarksManager.shared().loadTags(withLanguage: AppInfo.shared().twoLetterLanguageId) { tags, maxTagsNumber in
|
||||
if let tags = tags {
|
||||
self.tagGroups = tags
|
||||
self.maxTagsNumber = maxTagsNumber
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#import "FacebookNativeAdAdapter.h"
|
||||
#import "CoreNotificationWrapper.h"
|
||||
#import "MapViewController.h"
|
||||
#import "MWMActionBarButton.h"
|
||||
#import "MWMActivityViewController.h"
|
||||
#import "MWMAlertViewController.h"
|
||||
#import "MWMAvailableAreaAffectDirection.h"
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
self.tintColor = [UIColor colorWithName:colorName];
|
||||
}
|
||||
|
||||
- (void) setBorderColorName:(NSString*) colorName {
|
||||
- (void)setBorderColorName:(NSString *)colorName {
|
||||
self.layer.borderColor = [UIColor colorWithName:colorName].CGColor;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import UIKit
|
||||
|
||||
@IBDesignable final class RatingSummaryView: UIView {
|
||||
final class RatingSummaryView: UIView {
|
||||
@IBInspectable var value: String = RatingSummaryViewSettings.Default.value {
|
||||
didSet {
|
||||
guard oldValue != value else { return }
|
||||
|
|
|
@ -25,5 +25,5 @@
|
|||
|
||||
#pragma mark - MWMLocationObserver
|
||||
|
||||
- (void)onLocationUpdate:(location::GpsInfo const &)gpsInfo { [self close:self.rightButtonAction]; }
|
||||
- (void)onLocationUpdate:(CLLocation *)location { [self close:self.rightButtonAction]; }
|
||||
@end
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#import "MapViewController.h"
|
||||
#import "SwiftBridge.h"
|
||||
#import "UIImageView+Coloring.h"
|
||||
#import "location_util.h"
|
||||
|
||||
#include "geometry/angles.hpp"
|
||||
|
||||
|
@ -339,20 +340,21 @@ BOOL defaultOrientation(CGSize const & size)
|
|||
|
||||
#pragma mark - MWMLocationObserver
|
||||
|
||||
- (void)onLocationUpdate:(location::GpsInfo const &)gpsInfo
|
||||
- (void)onLocationUpdate:(CLLocation *)location
|
||||
{
|
||||
BOOL const hasLocation = ([MWMLocationManager lastLocation] != nil);
|
||||
if (self.hasLocation != hasLocation)
|
||||
[self updateToastView];
|
||||
}
|
||||
|
||||
- (void)onHeadingUpdate:(location::CompassInfo const &)info
|
||||
- (void)onHeadingUpdate:(CLHeading *)heading
|
||||
{
|
||||
auto transform = CATransform3DIdentity;
|
||||
auto lastLocation = [MWMLocationManager lastLocation];
|
||||
if (lastLocation && self.state == MWMNavigationInfoViewStateNavigation &&
|
||||
[MWMRouter type] == MWMRouterTypePedestrian)
|
||||
{
|
||||
auto const info = location_util::compassInfoFromHeading(heading);
|
||||
auto const angle = ang::AngleTo(lastLocation.mercator,
|
||||
self.navigationInfo.pedestrianDirectionPosition.mercator);
|
||||
transform = CATransform3DMakeRotation(M_PI_2 - angle - info.m_bearing, 0, 0, 1);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <CoreApi/Framework.h>
|
||||
#import <CoreApi/MWMFrameworkHelper.h>
|
||||
#import <CoreApi/PlacePageData.h>
|
||||
|
||||
#include "drape_frontend/user_event_stream.hpp"
|
||||
|
||||
|
@ -98,6 +99,7 @@ NSString * const kHotelFacilitiesSegue = @"Map2FacilitiesSegue";
|
|||
|
||||
@property(nonatomic) BOOL needDeferFocusNotification;
|
||||
@property(nonatomic) BOOL deferredFocusValue;
|
||||
@property(nonatomic) PlacePageViewController *placePageVC;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -108,7 +110,15 @@ NSString * const kHotelFacilitiesSegue = @"Map2FacilitiesSegue";
|
|||
|
||||
#pragma mark - Map Navigation
|
||||
|
||||
- (void)dismissPlacePage { [self.controlsManager dismissPlacePage]; }
|
||||
- (void)dismissPlacePage {
|
||||
[self.placePageVC.view removeFromSuperview];
|
||||
[self.placePageVC willMoveToParentViewController:nil];
|
||||
[self.placePageVC removeFromParentViewController];
|
||||
self.placePageVC = nil;
|
||||
// [self dismissViewControllerAnimated:YES completion:nil];
|
||||
// [self.controlsManager dismissPlacePage];
|
||||
}
|
||||
|
||||
- (void)onMapObjectDeselected:(bool)switchFullScreenMode
|
||||
{
|
||||
[self dismissPlacePage];
|
||||
|
@ -127,12 +137,26 @@ NSString * const kHotelFacilitiesSegue = @"Map2FacilitiesSegue";
|
|||
}
|
||||
|
||||
- (void)onMapObjectSelected {
|
||||
self.controlsManager.hidden = NO;
|
||||
[self.controlsManager showPlacePage];
|
||||
[self dismissPlacePage];
|
||||
self.placePageVC = (PlacePageViewController *)[[UIStoryboard instance:MWMStoryboardPlacePage] instantiateInitialViewController];
|
||||
self.placePageVC.placePageData = [[PlacePageData alloc] init];
|
||||
[self addChildViewController:self.placePageVC];
|
||||
[self.view addSubview:self.placePageVC.view];
|
||||
self.placePageVC.view.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[NSLayoutConstraint activateConstraints:@[
|
||||
[self.placePageVC.view.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
|
||||
[self.placePageVC.view.leftAnchor constraintEqualToAnchor:self.view.leftAnchor],
|
||||
[self.placePageVC.view.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
|
||||
[self.placePageVC.view.rightAnchor constraintEqualToAnchor:self.view.rightAnchor]
|
||||
]];
|
||||
[self.placePageVC didMoveToParentViewController:self];
|
||||
// [self presentViewController:placePageVC animated:YES completion:nil];
|
||||
// self.controlsManager.hidden = NO;
|
||||
// [self.controlsManager showPlacePage];
|
||||
}
|
||||
|
||||
- (void)onMapObjectUpdated {
|
||||
[self.controlsManager updatePlacePage];
|
||||
// [self.controlsManager updatePlacePage];
|
||||
}
|
||||
|
||||
- (void)checkMaskedPointer:(UITouch *)touch withEvent:(df::TouchEvent &)e
|
||||
|
|
|
@ -238,7 +238,7 @@
|
|||
|
||||
#pragma mark - MWMLocationObserver implementation
|
||||
|
||||
- (void)onLocationUpdate:(location::GpsInfo const &)gpsInfo {
|
||||
- (void)onLocationUpdate:(CLLocation *)location {
|
||||
NSMutableArray<NSString *> * turnNotifications = [NSMutableArray array];
|
||||
std::vector<std::string> notifications;
|
||||
self.rm.GenerateNotifications(notifications);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#import "MWMMyPositionMode.h"
|
||||
|
||||
@protocol MWMLocationObserver;
|
||||
#import "MWMLocationObserver.h"
|
||||
|
||||
@interface MWMLocationManager : NSObject
|
||||
|
||||
|
@ -8,8 +7,8 @@
|
|||
+ (void)stop;
|
||||
+ (BOOL)isStarted;
|
||||
|
||||
+ (void)addObserver:(id<MWMLocationObserver>)observer;
|
||||
+ (void)removeObserver:(id<MWMLocationObserver>)observer;
|
||||
+ (void)addObserver:(id<MWMLocationObserver>)observer NS_SWIFT_NAME(add(observer:));
|
||||
+ (void)removeObserver:(id<MWMLocationObserver>)observer NS_SWIFT_NAME(remove(observer:));
|
||||
|
||||
+ (void)setMyPositionMode:(MWMMyPositionMode)mode;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#import "MWMRouter.h"
|
||||
#import "MapsAppDelegate.h"
|
||||
#import "SwiftBridge.h"
|
||||
#import "location_util.h"
|
||||
|
||||
#include <CoreApi/Framework.h>
|
||||
|
||||
|
@ -15,42 +16,6 @@ namespace
|
|||
using Observer = id<MWMLocationObserver>;
|
||||
using Observers = NSHashTable<Observer>;
|
||||
|
||||
location::GpsInfo gpsInfoFromLocation(CLLocation * l, location::TLocationSource source)
|
||||
{
|
||||
location::GpsInfo info;
|
||||
info.m_source = source;
|
||||
|
||||
info.m_latitude = l.coordinate.latitude;
|
||||
info.m_longitude = l.coordinate.longitude;
|
||||
info.m_timestamp = l.timestamp.timeIntervalSince1970;
|
||||
|
||||
if (l.horizontalAccuracy >= 0.0)
|
||||
info.m_horizontalAccuracy = l.horizontalAccuracy;
|
||||
|
||||
if (l.verticalAccuracy >= 0.0)
|
||||
{
|
||||
info.m_verticalAccuracy = l.verticalAccuracy;
|
||||
info.m_altitude = l.altitude;
|
||||
}
|
||||
|
||||
if (l.course >= 0.0)
|
||||
info.m_bearing = l.course;
|
||||
|
||||
if (l.speed >= 0.0)
|
||||
info.m_speedMpS = l.speed;
|
||||
return info;
|
||||
}
|
||||
|
||||
location::CompassInfo compassInfoFromHeading(CLHeading * h)
|
||||
{
|
||||
location::CompassInfo info;
|
||||
if (h.trueHeading >= 0.0)
|
||||
info.m_bearing = base::DegToRad(h.trueHeading);
|
||||
else if (h.headingAccuracy >= 0.0)
|
||||
info.m_bearing = base::DegToRad(h.magneticHeading);
|
||||
return info;
|
||||
}
|
||||
|
||||
typedef NS_OPTIONS(NSUInteger, MWMLocationFrameworkUpdate) {
|
||||
MWMLocationFrameworkUpdateNone = 0,
|
||||
MWMLocationFrameworkUpdateLocation = 1 << 0,
|
||||
|
@ -160,7 +125,7 @@ void setShowLocationAlert(BOOL needShow) {
|
|||
@property(nonatomic) GeoMode geoMode;
|
||||
@property(nonatomic) CLHeading * lastHeadingInfo;
|
||||
@property(nonatomic) CLLocation * lastLocationInfo;
|
||||
@property(nonatomic) location::TLocationError lastLocationStatus;
|
||||
@property(nonatomic) MWMLocationStatus lastLocationStatus;
|
||||
@property(nonatomic) MWMLocationPredictor * predictor;
|
||||
@property(nonatomic) Observers * observers;
|
||||
@property(nonatomic) MWMLocationFrameworkUpdate frameworkUpdateMode;
|
||||
|
@ -252,7 +217,7 @@ void setShowLocationAlert(BOOL needShow) {
|
|||
MWMLocationManager * manager = [self manager];
|
||||
if (!manager.started || !manager.lastLocationInfo ||
|
||||
manager.lastLocationInfo.horizontalAccuracy < 0 ||
|
||||
manager.lastLocationStatus != location::TLocationError::ENoError)
|
||||
manager.lastLocationStatus != MWMLocationStatusNoError)
|
||||
return nil;
|
||||
return manager.lastLocationInfo;
|
||||
}
|
||||
|
@ -260,8 +225,8 @@ void setShowLocationAlert(BOOL needShow) {
|
|||
+ (BOOL)isLocationProhibited
|
||||
{
|
||||
auto const status = [self manager].lastLocationStatus;
|
||||
return status == location::TLocationError::EDenied ||
|
||||
status == location::TLocationError::EGPSIsOff;
|
||||
return status == MWMLocationStatusDenied ||
|
||||
status == MWMLocationStatusGPSIsOff;
|
||||
}
|
||||
|
||||
+ (CLHeading *)lastHeading
|
||||
|
@ -274,10 +239,10 @@ void setShowLocationAlert(BOOL needShow) {
|
|||
|
||||
#pragma mark - Observer notifications
|
||||
|
||||
- (void)processLocationStatus:(location::TLocationError)locationError
|
||||
- (void)processLocationStatus:(MWMLocationStatus)locationError
|
||||
{
|
||||
self.lastLocationStatus = locationError;
|
||||
if (self.lastLocationStatus != location::TLocationError::ENoError)
|
||||
if (self.lastLocationStatus != MWMLocationStatusNoError)
|
||||
self.frameworkUpdateMode |= MWMLocationFrameworkUpdateStatus;
|
||||
for (Observer observer in self.observers)
|
||||
{
|
||||
|
@ -290,17 +255,17 @@ void setShowLocationAlert(BOOL needShow) {
|
|||
{
|
||||
self.lastHeadingInfo = headingInfo;
|
||||
self.frameworkUpdateMode |= MWMLocationFrameworkUpdateHeading;
|
||||
location::CompassInfo const compassInfo = compassInfoFromHeading(headingInfo);
|
||||
// location::CompassInfo const compassInfo = compassInfoFromHeading(headingInfo);
|
||||
for (Observer observer in self.observers)
|
||||
{
|
||||
if ([observer respondsToSelector:@selector(onHeadingUpdate:)])
|
||||
[observer onHeadingUpdate:compassInfo];
|
||||
[observer onHeadingUpdate:headingInfo];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)processLocationUpdate:(CLLocation *)locationInfo
|
||||
{
|
||||
if (!locationInfo || self.lastLocationStatus != location::TLocationError::ENoError)
|
||||
if (!locationInfo || self.lastLocationStatus != MWMLocationStatusNoError)
|
||||
return;
|
||||
[self onLocationUpdate:locationInfo source:self.locationSource];
|
||||
if (![self.lastLocationInfo isEqual:locationInfo])
|
||||
|
@ -309,7 +274,7 @@ void setShowLocationAlert(BOOL needShow) {
|
|||
|
||||
- (void)onLocationUpdate:(CLLocation *)locationInfo source:(location::TLocationSource)source
|
||||
{
|
||||
location::GpsInfo const gpsInfo = gpsInfoFromLocation(locationInfo, source);
|
||||
location::GpsInfo const gpsInfo = location_util::gpsInfoFromLocation(locationInfo, source);
|
||||
GpsTracker::Instance().OnLocationUpdated(gpsInfo);
|
||||
|
||||
self.lastLocationInfo = locationInfo;
|
||||
|
@ -318,23 +283,23 @@ void setShowLocationAlert(BOOL needShow) {
|
|||
for (Observer observer in self.observers)
|
||||
{
|
||||
if ([observer respondsToSelector:@selector(onLocationUpdate:)])
|
||||
[observer onLocationUpdate:gpsInfo];
|
||||
[observer onLocationUpdate:locationInfo];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Location Status
|
||||
|
||||
- (void)setLastLocationStatus:(location::TLocationError)lastLocationStatus
|
||||
- (void)setLastLocationStatus:(MWMLocationStatus)lastLocationStatus
|
||||
{
|
||||
_lastLocationStatus = lastLocationStatus;
|
||||
switch (lastLocationStatus)
|
||||
{
|
||||
case location::ENoError: break;
|
||||
case location::ENotSupported:
|
||||
case MWMLocationStatusNoError: break;
|
||||
case MWMLocationStatusNotSupported:
|
||||
[[MWMAlertViewController activeAlertController] presentLocationServiceNotSupportedAlert];
|
||||
break;
|
||||
case location::EDenied:
|
||||
case location::EGPSIsOff:
|
||||
case MWMLocationStatusDenied:
|
||||
case MWMLocationStatusGPSIsOff:
|
||||
if (needShowLocationAlert()) {
|
||||
[[MWMAlertViewController activeAlertController] presentLocationAlertWithCancelBlock:^{
|
||||
setShowLocationAlert(NO);
|
||||
|
@ -465,15 +430,15 @@ void setShowLocationAlert(BOOL needShow) {
|
|||
if (location.horizontalAccuracy < 0.)
|
||||
return;
|
||||
|
||||
self.lastLocationStatus = location::TLocationError::ENoError;
|
||||
self.lastLocationStatus = MWMLocationStatusNoError;
|
||||
self.locationSource = location::EAppleNative;
|
||||
[self processLocationUpdate:location];
|
||||
}
|
||||
|
||||
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
|
||||
{
|
||||
if (self.lastLocationStatus == location::TLocationError::ENoError && error.code == kCLErrorDenied)
|
||||
[self processLocationStatus:location::EDenied];
|
||||
if (self.lastLocationStatus == MWMLocationStatusNoError && error.code == kCLErrorDenied)
|
||||
[self processLocationStatus:MWMLocationStatusDenied];
|
||||
}
|
||||
|
||||
#pragma mark - Start / Stop
|
||||
|
@ -528,12 +493,12 @@ void setShowLocationAlert(BOOL needShow) {
|
|||
case kCLAuthorizationStatusAuthorizedAlways:
|
||||
case kCLAuthorizationStatusNotDetermined: doStart(); return YES;
|
||||
case kCLAuthorizationStatusRestricted:
|
||||
case kCLAuthorizationStatusDenied: [self processLocationStatus:location::EDenied]; break;
|
||||
case kCLAuthorizationStatusDenied: [self processLocationStatus:MWMLocationStatusDenied]; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[self processLocationStatus:location::EGPSIsOff];
|
||||
[self processLocationStatus:MWMLocationStatusGPSIsOff];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
@ -561,13 +526,13 @@ void setShowLocationAlert(BOOL needShow) {
|
|||
if (self.frameworkUpdateMode & MWMLocationFrameworkUpdateLocation)
|
||||
{
|
||||
location::GpsInfo const gpsInfo =
|
||||
gpsInfoFromLocation(self.lastLocationInfo, self.locationSource);
|
||||
location_util::gpsInfoFromLocation(self.lastLocationInfo, self.locationSource);
|
||||
f.OnLocationUpdate(gpsInfo);
|
||||
}
|
||||
if (self.frameworkUpdateMode & MWMLocationFrameworkUpdateHeading)
|
||||
f.OnCompassUpdate(compassInfoFromHeading(self.lastHeadingInfo));
|
||||
f.OnCompassUpdate(location_util::compassInfoFromHeading(self.lastHeadingInfo));
|
||||
if (self.frameworkUpdateMode & MWMLocationFrameworkUpdateStatus)
|
||||
f.OnLocationError(self.lastLocationStatus);
|
||||
f.OnLocationError((location::TLocationError)self.lastLocationStatus);
|
||||
self.frameworkUpdateMode = MWMLocationFrameworkUpdateNone;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,10 +1,21 @@
|
|||
#include "platform/location.hpp"
|
||||
//#include "platform/location.hpp"
|
||||
|
||||
typedef NS_ENUM(NSInteger, MWMLocationStatus) {
|
||||
MWMLocationStatusNoError,
|
||||
MWMLocationStatusNotSupported,
|
||||
MWMLocationStatusDenied,
|
||||
MWMLocationStatusGPSIsOff
|
||||
};
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol MWMLocationObserver<NSObject>
|
||||
|
||||
@optional
|
||||
- (void)onHeadingUpdate:(location::CompassInfo const &)compassinfo;
|
||||
- (void)onLocationUpdate:(location::GpsInfo const &)gpsInfo;
|
||||
- (void)onLocationError:(location::TLocationError)locationError;
|
||||
- (void)onHeadingUpdate:(CLHeading *)heading;
|
||||
- (void)onLocationUpdate:(CLLocation *)location;
|
||||
- (void)onLocationError:(MWMLocationStatus)locationError;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
41
iphone/Maps/Core/Location/location_util.h
Normal file
41
iphone/Maps/Core/Location/location_util.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
#pragma once
|
||||
|
||||
namespace location_util {
|
||||
|
||||
static location::GpsInfo gpsInfoFromLocation(CLLocation * l, location::TLocationSource source)
|
||||
{
|
||||
location::GpsInfo info;
|
||||
info.m_source = source;
|
||||
|
||||
info.m_latitude = l.coordinate.latitude;
|
||||
info.m_longitude = l.coordinate.longitude;
|
||||
info.m_timestamp = l.timestamp.timeIntervalSince1970;
|
||||
|
||||
if (l.horizontalAccuracy >= 0.0)
|
||||
info.m_horizontalAccuracy = l.horizontalAccuracy;
|
||||
|
||||
if (l.verticalAccuracy >= 0.0)
|
||||
{
|
||||
info.m_verticalAccuracy = l.verticalAccuracy;
|
||||
info.m_altitude = l.altitude;
|
||||
}
|
||||
|
||||
if (l.course >= 0.0)
|
||||
info.m_bearing = l.course;
|
||||
|
||||
if (l.speed >= 0.0)
|
||||
info.m_speedMpS = l.speed;
|
||||
return info;
|
||||
}
|
||||
|
||||
static location::CompassInfo compassInfoFromHeading(CLHeading * h)
|
||||
{
|
||||
location::CompassInfo info;
|
||||
if (h.trueHeading >= 0.0)
|
||||
info.m_bearing = base::DegToRad(h.trueHeading);
|
||||
else if (h.headingAccuracy >= 0.0)
|
||||
info.m_bearing = base::DegToRad(h.magneticHeading);
|
||||
return info;
|
||||
}
|
||||
|
||||
} // namespace location_util
|
|
@ -612,7 +612,7 @@ void logPointEvent(MWMRoutePoint * point, NSString * eventType)
|
|||
|
||||
#pragma mark - MWMLocationObserver
|
||||
|
||||
- (void)onLocationUpdate:(location::GpsInfo const &)info
|
||||
- (void)onLocationUpdate:(CLLocation *)location
|
||||
{
|
||||
if (![MWMRouter isRoutingActive])
|
||||
return;
|
||||
|
|
|
@ -344,10 +344,13 @@
|
|||
45FFD65D1E965EBE00DB854E /* liblocal_ads.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 45FFD65C1E965EBE00DB854E /* liblocal_ads.a */; };
|
||||
4707E4B12372FE860017DF6E /* PlacePageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4707E4AF2372FE860017DF6E /* PlacePageViewController.swift */; };
|
||||
4707E4B42372FF480017DF6E /* PlacePage.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4707E4B32372FF480017DF6E /* PlacePage.storyboard */; };
|
||||
4707E4B62375B2900017DF6E /* PlacePageInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4707E4B52375B2900017DF6E /* PlacePageInfoViewController.swift */; };
|
||||
4707E4B62375B2900017DF6E /* PlacePagePreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4707E4B52375B2900017DF6E /* PlacePagePreviewViewController.swift */; };
|
||||
470A89FD21342A9D00D72FBF /* TutorialBlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 470A89FC21342A9D00D72FBF /* TutorialBlurView.swift */; };
|
||||
470A89FF2134517600D72FBF /* BookmarksTutorialBlur.xib in Resources */ = {isa = PBXBuildFile; fileRef = 470A89FE2134517600D72FBF /* BookmarksTutorialBlur.xib */; };
|
||||
470A8A012136097000D72FBF /* SubwayTutorialBlur.xib in Resources */ = {isa = PBXBuildFile; fileRef = 470A8A002136073000D72FBF /* SubwayTutorialBlur.xib */; };
|
||||
470F0B7A23882955006AEC94 /* PlacePageReviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 470F0B7923882955006AEC94 /* PlacePageReviewViewController.swift */; };
|
||||
470F0B7D238842EA006AEC94 /* ExpandableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 470F0B7C238842EA006AEC94 /* ExpandableLabel.swift */; };
|
||||
470F0B7F2388431E006AEC94 /* StarRatingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 470F0B7E2388431E006AEC94 /* StarRatingView.swift */; };
|
||||
470F5A5B2181DE7500754295 /* PaidRouteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 470F5A592181DE7400754295 /* PaidRouteViewController.swift */; };
|
||||
470F5A5C2181DE7500754295 /* PaidRouteViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 470F5A5A2181DE7400754295 /* PaidRouteViewController.xib */; };
|
||||
470F5A7D2189BB2F00754295 /* PaidRoutePurchase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 470F5A7C2189BB2F00754295 /* PaidRoutePurchase.swift */; };
|
||||
|
@ -364,6 +367,12 @@
|
|||
471C448C2322A7C800C307EC /* SubscriptionGoToCatalogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 471C448A2322A7C800C307EC /* SubscriptionGoToCatalogViewController.swift */; };
|
||||
471C448D2322A7C800C307EC /* SubscriptionGoToCatalogViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 471C448B2322A7C800C307EC /* SubscriptionGoToCatalogViewController.xib */; };
|
||||
4726254921C27D4B00C7BAAD /* PlacePageDescriptionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4726254821C27D4B00C7BAAD /* PlacePageDescriptionViewController.swift */; };
|
||||
472848F72383F8F700176158 /* WikiDescriptionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472848F62383F8F600176158 /* WikiDescriptionViewController.swift */; };
|
||||
472848F92384CEC900176158 /* TaxiViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472848F82384CEC900176158 /* TaxiViewController.swift */; };
|
||||
472848FB238573EE00176158 /* RatingSummaryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472848FA238573EE00176158 /* RatingSummaryViewController.swift */; };
|
||||
472848FD2386A17500176158 /* AddReviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472848FC2386A17300176158 /* AddReviewViewController.swift */; };
|
||||
472848FF2386BE6E00176158 /* PlacePageReviewsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472848FE2386BE6E00176158 /* PlacePageReviewsViewController.swift */; };
|
||||
472849012388098300176158 /* MyReviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472849002388098300176158 /* MyReviewViewController.swift */; };
|
||||
47289E5A2212DFFF002ABFC0 /* EditOnWebAlertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47289E582212DFFF002ABFC0 /* EditOnWebAlertViewController.swift */; };
|
||||
47289E5B2212DFFF002ABFC0 /* EditOnWebAlertViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 47289E592212DFFF002ABFC0 /* EditOnWebAlertViewController.xib */; };
|
||||
4728F69322CF89A400E00028 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4728F69222CF89A400E00028 /* GradientView.swift */; };
|
||||
|
@ -378,6 +387,10 @@
|
|||
474AC76C2139E4F2002F9BF9 /* RemoveAdsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 474AC76A2139E4F2002F9BF9 /* RemoveAdsViewController.swift */; };
|
||||
474AC76D2139E4F2002F9BF9 /* RemoveAdsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 474AC76B2139E4F2002F9BF9 /* RemoveAdsViewController.xib */; };
|
||||
474C9F5A213FF75800369009 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 474C9F59213FF75800369009 /* StoreKit.framework */; };
|
||||
475EFDBB238FDDB200A24B4C /* CatalogSingleItemViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475EFDBA238FDDB200A24B4C /* CatalogSingleItemViewController.swift */; };
|
||||
475EFDBD239002D700A24B4C /* CatalogGalleryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475EFDBC239002D700A24B4C /* CatalogGalleryViewController.swift */; };
|
||||
475EFDBF239031CD00A24B4C /* PlacePageBookmarkViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475EFDBE239031CD00A24B4C /* PlacePageBookmarkViewController.swift */; };
|
||||
475EFDC123907DAA00A24B4C /* OpeningHoursViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475EFDC023907DAA00A24B4C /* OpeningHoursViewController.swift */; };
|
||||
4767CD9F20AAD48A00BD8166 /* Checkmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4767CD9E20AAD48A00BD8166 /* Checkmark.swift */; };
|
||||
4767CDA420AAF66B00BD8166 /* NSAttributedString+HTML.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4767CDA320AAF66B00BD8166 /* NSAttributedString+HTML.swift */; };
|
||||
4767CDA620AB1F6200BD8166 /* LeftAlignedIconButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4767CDA520AB1F6200BD8166 /* LeftAlignedIconButton.swift */; };
|
||||
|
@ -392,12 +405,17 @@
|
|||
4788738F20EE30B300F6826B /* LayersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4788738D20EE30B300F6826B /* LayersViewController.swift */; };
|
||||
4788739020EE30B300F6826B /* LayersViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4788738E20EE30B300F6826B /* LayersViewController.xib */; };
|
||||
4788739220EE326500F6826B /* VerticallyAlignedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4788739120EE326400F6826B /* VerticallyAlignedButton.swift */; };
|
||||
479388F92395A4D3006ECACC /* ActionBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 479388F82395A4D3006ECACC /* ActionBarViewController.swift */; };
|
||||
479D305722C627CB00D18278 /* MWMMegafonBannerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 479D305522C627CB00D18278 /* MWMMegafonBannerViewController.xib */; };
|
||||
479D305B22C62F4000D18278 /* MWMBookmarksBannerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 479D305922C62F4000D18278 /* MWMBookmarksBannerViewController.xib */; };
|
||||
479D306122C6634900D18278 /* MWMMegafonBannerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 479D305F22C6634900D18278 /* MWMMegafonBannerViewController.m */; };
|
||||
479D306522C664CE00D18278 /* MWMDownloadBannerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 479D306422C664CE00D18278 /* MWMDownloadBannerViewController.m */; };
|
||||
479D306822C66C8F00D18278 /* MWMBookmarksBannerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 479D306722C66C8F00D18278 /* MWMBookmarksBannerViewController.m */; };
|
||||
479EE94A2292FB03009DEBA6 /* ActivityIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 479EE9492292FB03009DEBA6 /* ActivityIndicator.swift */; };
|
||||
47A0416D238DBB6200D84E95 /* HotelPhotosViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47A0416C238DBB6200D84E95 /* HotelPhotosViewController.swift */; };
|
||||
47A0416F238DD0FD00D84E95 /* HotelDescriptionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47A0416E238DD0FD00D84E95 /* HotelDescriptionViewController.swift */; };
|
||||
47A04171238DE8AE00D84E95 /* HotelFacilitiesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47A04170238DE8AE00D84E95 /* HotelFacilitiesViewController.swift */; };
|
||||
47A04173238E989200D84E95 /* HotelReviewsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47A04172238E989200D84E95 /* HotelReviewsViewController.swift */; };
|
||||
47A65CAD2350044800DCD85F /* CoreApi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47A65CAC2350044800DCD85F /* CoreApi.framework */; };
|
||||
47A6F3C4235F47B90053FBA4 /* BookmarksSubscriptionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 47A6F3C1235F47B90053FBA4 /* BookmarksSubscriptionViewController.xib */; };
|
||||
47A6F3C5235F47B90053FBA4 /* BookmarksSubscriptionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47A6F3C2235F47B90053FBA4 /* BookmarksSubscriptionButton.swift */; };
|
||||
|
@ -439,12 +457,14 @@
|
|||
47E6CB0B2178BA3600EA102B /* SearchBannerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47E6CB092178BA3600EA102B /* SearchBannerCell.swift */; };
|
||||
47E6CB0C2178BA3600EA102B /* SearchBannerCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 47E6CB0A2178BA3600EA102B /* SearchBannerCell.xib */; };
|
||||
47E8163323B17734008FD836 /* MWMStorage+UI.m in Sources */ = {isa = PBXBuildFile; fileRef = 47E8163223B17734008FD836 /* MWMStorage+UI.m */; };
|
||||
47E98C102382C80600C800E0 /* PlacePageInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47E98C0F2382C80600C800E0 /* PlacePageInfoViewController.swift */; };
|
||||
47EF05B321504D8F00EAC269 /* RemoveAdsPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47EF05B221504D8F00EAC269 /* RemoveAdsPresentationController.swift */; };
|
||||
47F4F21323A6EC420022FD56 /* DownloadMapsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F4F21223A6EC420022FD56 /* DownloadMapsViewController.swift */; };
|
||||
47F4F21523A6F06F0022FD56 /* AvailableMapsDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F4F21423A6F06F0022FD56 /* AvailableMapsDataSource.swift */; };
|
||||
47F67D1521CAB21B0069754E /* MWMImageCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 47F67D1421CAB21B0069754E /* MWMImageCoder.m */; };
|
||||
47F6E51221F61908004580CA /* CoreNotificationWrapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 47F6E51121F61908004580CA /* CoreNotificationWrapper.mm */; };
|
||||
47F6E51721FB3C51004580CA /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F6E51621FB3C51004580CA /* Notifications.swift */; };
|
||||
47F701F6238C8A8300D18E95 /* PlacePageButtonsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F701F5238C8A8300D18E95 /* PlacePageButtonsViewController.swift */; };
|
||||
47F86CFF20C936FC00FEE291 /* TabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F86CFE20C936FC00FEE291 /* TabView.swift */; };
|
||||
47F86D0120C93D8D00FEE291 /* TabViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F86D0020C93D8D00FEE291 /* TabViewController.swift */; };
|
||||
47FA14D1230D52FC003DA979 /* PhoneNumberAuthorizationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47FA14D0230D52FC003DA979 /* PhoneNumberAuthorizationViewController.swift */; };
|
||||
|
@ -768,7 +788,7 @@
|
|||
F6E2FE461E097BA00083EBEC /* MWMDirectionView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6E2FC961E097B9F0083EBEC /* MWMDirectionView.xib */; };
|
||||
F6E2FE491E097BA00083EBEC /* MWMPlacePageData.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FC981E097B9F0083EBEC /* MWMPlacePageData.mm */; };
|
||||
F6E2FE4C1E097BA00083EBEC /* MWMPlacePageManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FC9A1E097B9F0083EBEC /* MWMPlacePageManager.mm */; };
|
||||
F6E2FE4F1E097BA00083EBEC /* MWMActionBarButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FC9F1E097B9F0083EBEC /* MWMActionBarButton.mm */; };
|
||||
F6E2FE4F1E097BA00083EBEC /* MWMActionBarButton.m in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FC9F1E097B9F0083EBEC /* MWMActionBarButton.m */; };
|
||||
F6E2FE521E097BA00083EBEC /* MWMActionBarButton.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6E2FCA01E097B9F0083EBEC /* MWMActionBarButton.xib */; };
|
||||
F6E2FE551E097BA00083EBEC /* MWMPlacePageActionBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = F6E2FCA21E097B9F0083EBEC /* MWMPlacePageActionBar.mm */; };
|
||||
F6E2FE581E097BA00083EBEC /* MWMPlacePageActionBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6E2FCA31E097B9F0083EBEC /* MWMPlacePageActionBar.xib */; };
|
||||
|
@ -1422,10 +1442,13 @@
|
|||
46F8A2EB10EB63040045521A /* MapViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = MapViewController.h; sourceTree = "<group>"; };
|
||||
4707E4AF2372FE860017DF6E /* PlacePageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlacePageViewController.swift; sourceTree = "<group>"; };
|
||||
4707E4B32372FF480017DF6E /* PlacePage.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = PlacePage.storyboard; sourceTree = "<group>"; };
|
||||
4707E4B52375B2900017DF6E /* PlacePageInfoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlacePageInfoViewController.swift; sourceTree = "<group>"; };
|
||||
4707E4B52375B2900017DF6E /* PlacePagePreviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlacePagePreviewViewController.swift; sourceTree = "<group>"; };
|
||||
470A89FC21342A9D00D72FBF /* TutorialBlurView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TutorialBlurView.swift; sourceTree = "<group>"; };
|
||||
470A89FE2134517600D72FBF /* BookmarksTutorialBlur.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BookmarksTutorialBlur.xib; sourceTree = "<group>"; };
|
||||
470A8A002136073000D72FBF /* SubwayTutorialBlur.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SubwayTutorialBlur.xib; sourceTree = "<group>"; };
|
||||
470F0B7923882955006AEC94 /* PlacePageReviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlacePageReviewViewController.swift; sourceTree = "<group>"; };
|
||||
470F0B7C238842EA006AEC94 /* ExpandableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandableLabel.swift; sourceTree = "<group>"; };
|
||||
470F0B7E2388431E006AEC94 /* StarRatingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StarRatingView.swift; sourceTree = "<group>"; };
|
||||
470F5A592181DE7400754295 /* PaidRouteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaidRouteViewController.swift; sourceTree = "<group>"; };
|
||||
470F5A5A2181DE7400754295 /* PaidRouteViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PaidRouteViewController.xib; sourceTree = "<group>"; };
|
||||
470F5A7C2189BB2F00754295 /* PaidRoutePurchase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaidRoutePurchase.swift; sourceTree = "<group>"; };
|
||||
|
@ -1443,6 +1466,12 @@
|
|||
471C448A2322A7C800C307EC /* SubscriptionGoToCatalogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionGoToCatalogViewController.swift; sourceTree = "<group>"; };
|
||||
471C448B2322A7C800C307EC /* SubscriptionGoToCatalogViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SubscriptionGoToCatalogViewController.xib; sourceTree = "<group>"; };
|
||||
4726254821C27D4B00C7BAAD /* PlacePageDescriptionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlacePageDescriptionViewController.swift; sourceTree = "<group>"; };
|
||||
472848F62383F8F600176158 /* WikiDescriptionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WikiDescriptionViewController.swift; sourceTree = "<group>"; };
|
||||
472848F82384CEC900176158 /* TaxiViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaxiViewController.swift; sourceTree = "<group>"; };
|
||||
472848FA238573EE00176158 /* RatingSummaryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RatingSummaryViewController.swift; sourceTree = "<group>"; };
|
||||
472848FC2386A17300176158 /* AddReviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddReviewViewController.swift; sourceTree = "<group>"; };
|
||||
472848FE2386BE6E00176158 /* PlacePageReviewsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlacePageReviewsViewController.swift; sourceTree = "<group>"; };
|
||||
472849002388098300176158 /* MyReviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyReviewViewController.swift; sourceTree = "<group>"; };
|
||||
47289E582212DFFF002ABFC0 /* EditOnWebAlertViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditOnWebAlertViewController.swift; sourceTree = "<group>"; };
|
||||
47289E592212DFFF002ABFC0 /* EditOnWebAlertViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EditOnWebAlertViewController.xib; sourceTree = "<group>"; };
|
||||
4728F69222CF89A400E00028 /* GradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GradientView.swift; path = CustomViews/GradientView.swift; sourceTree = "<group>"; };
|
||||
|
@ -1463,6 +1492,10 @@
|
|||
474AC76A2139E4F2002F9BF9 /* RemoveAdsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveAdsViewController.swift; sourceTree = "<group>"; };
|
||||
474AC76B2139E4F2002F9BF9 /* RemoveAdsViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RemoveAdsViewController.xib; sourceTree = "<group>"; };
|
||||
474C9F59213FF75800369009 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
|
||||
475EFDBA238FDDB200A24B4C /* CatalogSingleItemViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CatalogSingleItemViewController.swift; sourceTree = "<group>"; };
|
||||
475EFDBC239002D700A24B4C /* CatalogGalleryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CatalogGalleryViewController.swift; sourceTree = "<group>"; };
|
||||
475EFDBE239031CD00A24B4C /* PlacePageBookmarkViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlacePageBookmarkViewController.swift; sourceTree = "<group>"; };
|
||||
475EFDC023907DAA00A24B4C /* OpeningHoursViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpeningHoursViewController.swift; sourceTree = "<group>"; };
|
||||
4767CD9E20AAD48A00BD8166 /* Checkmark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkmark.swift; sourceTree = "<group>"; };
|
||||
4767CDA320AAF66B00BD8166 /* NSAttributedString+HTML.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+HTML.swift"; sourceTree = "<group>"; };
|
||||
4767CDA520AB1F6200BD8166 /* LeftAlignedIconButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftAlignedIconButton.swift; sourceTree = "<group>"; };
|
||||
|
@ -1479,6 +1512,7 @@
|
|||
4788738D20EE30B300F6826B /* LayersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayersViewController.swift; sourceTree = "<group>"; };
|
||||
4788738E20EE30B300F6826B /* LayersViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LayersViewController.xib; sourceTree = "<group>"; };
|
||||
4788739120EE326400F6826B /* VerticallyAlignedButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerticallyAlignedButton.swift; sourceTree = "<group>"; };
|
||||
479388F82395A4D3006ECACC /* ActionBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionBarViewController.swift; sourceTree = "<group>"; };
|
||||
4797A4DB226F4B2900D3A984 /* DeepLinkHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkHandler.swift; sourceTree = "<group>"; };
|
||||
479D305522C627CB00D18278 /* MWMMegafonBannerViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MWMMegafonBannerViewController.xib; sourceTree = "<group>"; };
|
||||
479D305922C62F4000D18278 /* MWMBookmarksBannerViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MWMBookmarksBannerViewController.xib; sourceTree = "<group>"; };
|
||||
|
@ -1489,6 +1523,10 @@
|
|||
479D306622C66C8F00D18278 /* MWMBookmarksBannerViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMBookmarksBannerViewController.h; sourceTree = "<group>"; };
|
||||
479D306722C66C8F00D18278 /* MWMBookmarksBannerViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MWMBookmarksBannerViewController.m; sourceTree = "<group>"; };
|
||||
479EE9492292FB03009DEBA6 /* ActivityIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ActivityIndicator.swift; path = CustomViews/ActivityIndicator.swift; sourceTree = "<group>"; };
|
||||
47A0416C238DBB6200D84E95 /* HotelPhotosViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HotelPhotosViewController.swift; sourceTree = "<group>"; };
|
||||
47A0416E238DD0FD00D84E95 /* HotelDescriptionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HotelDescriptionViewController.swift; sourceTree = "<group>"; };
|
||||
47A04170238DE8AE00D84E95 /* HotelFacilitiesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HotelFacilitiesViewController.swift; sourceTree = "<group>"; };
|
||||
47A04172238E989200D84E95 /* HotelReviewsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HotelReviewsViewController.swift; sourceTree = "<group>"; };
|
||||
47A65CAC2350044800DCD85F /* CoreApi.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CoreApi.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
47A6F3C1235F47B90053FBA4 /* BookmarksSubscriptionViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = BookmarksSubscriptionViewController.xib; sourceTree = "<group>"; };
|
||||
47A6F3C2235F47B90053FBA4 /* BookmarksSubscriptionButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarksSubscriptionButton.swift; sourceTree = "<group>"; };
|
||||
|
@ -1539,6 +1577,7 @@
|
|||
47E6CB0A2178BA3600EA102B /* SearchBannerCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SearchBannerCell.xib; sourceTree = "<group>"; };
|
||||
47E8163123B17734008FD836 /* MWMStorage+UI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MWMStorage+UI.h"; sourceTree = "<group>"; };
|
||||
47E8163223B17734008FD836 /* MWMStorage+UI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "MWMStorage+UI.m"; sourceTree = "<group>"; };
|
||||
47E98C0F2382C80600C800E0 /* PlacePageInfoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlacePageInfoViewController.swift; sourceTree = "<group>"; };
|
||||
47EF05B221504D8F00EAC269 /* RemoveAdsPresentationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveAdsPresentationController.swift; sourceTree = "<group>"; };
|
||||
47F4F21223A6EC420022FD56 /* DownloadMapsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadMapsViewController.swift; sourceTree = "<group>"; };
|
||||
47F4F21423A6F06F0022FD56 /* AvailableMapsDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvailableMapsDataSource.swift; sourceTree = "<group>"; };
|
||||
|
@ -1550,6 +1589,8 @@
|
|||
47F6E51121F61908004580CA /* CoreNotificationWrapper.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CoreNotificationWrapper.mm; sourceTree = "<group>"; };
|
||||
47F6E51321F61974004580CA /* CoreNotificationWrapper+Core.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CoreNotificationWrapper+Core.h"; sourceTree = "<group>"; };
|
||||
47F6E51621FB3C51004580CA /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
|
||||
47F701EC238C2F8400D18E95 /* location_util.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = location_util.h; sourceTree = "<group>"; };
|
||||
47F701F5238C8A8300D18E95 /* PlacePageButtonsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlacePageButtonsViewController.swift; sourceTree = "<group>"; };
|
||||
47F86CFE20C936FC00FEE291 /* TabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabView.swift; sourceTree = "<group>"; };
|
||||
47F86D0020C93D8D00FEE291 /* TabViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabViewController.swift; sourceTree = "<group>"; };
|
||||
47FA14D0230D52FC003DA979 /* PhoneNumberAuthorizationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhoneNumberAuthorizationViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -1983,7 +2024,7 @@
|
|||
F6E2FC9A1E097B9F0083EBEC /* MWMPlacePageManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMPlacePageManager.mm; sourceTree = "<group>"; };
|
||||
F6E2FC9B1E097B9F0083EBEC /* MWMPlacePageProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMPlacePageProtocol.h; sourceTree = "<group>"; };
|
||||
F6E2FC9E1E097B9F0083EBEC /* MWMActionBarButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMActionBarButton.h; sourceTree = "<group>"; };
|
||||
F6E2FC9F1E097B9F0083EBEC /* MWMActionBarButton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMActionBarButton.mm; sourceTree = "<group>"; };
|
||||
F6E2FC9F1E097B9F0083EBEC /* MWMActionBarButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWMActionBarButton.m; sourceTree = "<group>"; };
|
||||
F6E2FCA01E097B9F0083EBEC /* MWMActionBarButton.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMActionBarButton.xib; sourceTree = "<group>"; };
|
||||
F6E2FCA11E097B9F0083EBEC /* MWMPlacePageActionBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMPlacePageActionBar.h; sourceTree = "<group>"; };
|
||||
F6E2FCA21E097B9F0083EBEC /* MWMPlacePageActionBar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = MWMPlacePageActionBar.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
|
@ -2543,6 +2584,7 @@
|
|||
3404752E1E081A4600C92850 /* MWMLocationPredictor.h */,
|
||||
3404752F1E081A4600C92850 /* MWMLocationPredictor.mm */,
|
||||
3486B5031E27948F0069C126 /* MWMMyPositionMode.h */,
|
||||
47F701EC238C2F8400D18E95 /* location_util.h */,
|
||||
);
|
||||
path = Location;
|
||||
sourceTree = "<group>";
|
||||
|
@ -3437,6 +3479,15 @@
|
|||
path = Promo;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
470F0B7B238842AD006AEC94 /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
470F0B7C238842EA006AEC94 /* ExpandableLabel.swift */,
|
||||
470F0B7E2388431E006AEC94 /* StarRatingView.swift */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
470F5A7B2189BA7200754295 /* InappPurchase */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -4421,7 +4472,26 @@
|
|||
4726254821C27D4B00C7BAAD /* PlacePageDescriptionViewController.swift */,
|
||||
4707E4AF2372FE860017DF6E /* PlacePageViewController.swift */,
|
||||
4707E4B32372FF480017DF6E /* PlacePage.storyboard */,
|
||||
4707E4B52375B2900017DF6E /* PlacePageInfoViewController.swift */,
|
||||
4707E4B52375B2900017DF6E /* PlacePagePreviewViewController.swift */,
|
||||
47E98C0F2382C80600C800E0 /* PlacePageInfoViewController.swift */,
|
||||
472848F62383F8F600176158 /* WikiDescriptionViewController.swift */,
|
||||
472848F82384CEC900176158 /* TaxiViewController.swift */,
|
||||
472848FA238573EE00176158 /* RatingSummaryViewController.swift */,
|
||||
472848FC2386A17300176158 /* AddReviewViewController.swift */,
|
||||
472848FE2386BE6E00176158 /* PlacePageReviewsViewController.swift */,
|
||||
472849002388098300176158 /* MyReviewViewController.swift */,
|
||||
470F0B7923882955006AEC94 /* PlacePageReviewViewController.swift */,
|
||||
47F701F5238C8A8300D18E95 /* PlacePageButtonsViewController.swift */,
|
||||
47A0416C238DBB6200D84E95 /* HotelPhotosViewController.swift */,
|
||||
47A0416E238DD0FD00D84E95 /* HotelDescriptionViewController.swift */,
|
||||
47A04170238DE8AE00D84E95 /* HotelFacilitiesViewController.swift */,
|
||||
47A04172238E989200D84E95 /* HotelReviewsViewController.swift */,
|
||||
475EFDBA238FDDB200A24B4C /* CatalogSingleItemViewController.swift */,
|
||||
475EFDBC239002D700A24B4C /* CatalogGalleryViewController.swift */,
|
||||
475EFDBE239031CD00A24B4C /* PlacePageBookmarkViewController.swift */,
|
||||
479388F82395A4D3006ECACC /* ActionBarViewController.swift */,
|
||||
470F0B7B238842AD006AEC94 /* Views */,
|
||||
475EFDC023907DAA00A24B4C /* OpeningHoursViewController.swift */,
|
||||
);
|
||||
path = PlacePage;
|
||||
sourceTree = "<group>";
|
||||
|
@ -4460,7 +4530,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
F6E2FC9E1E097B9F0083EBEC /* MWMActionBarButton.h */,
|
||||
F6E2FC9F1E097B9F0083EBEC /* MWMActionBarButton.mm */,
|
||||
F6E2FC9F1E097B9F0083EBEC /* MWMActionBarButton.m */,
|
||||
F6E2FCA01E097B9F0083EBEC /* MWMActionBarButton.xib */,
|
||||
F6E2FCA11E097B9F0083EBEC /* MWMPlacePageActionBar.h */,
|
||||
F6E2FCA21E097B9F0083EBEC /* MWMPlacePageActionBar.mm */,
|
||||
|
@ -5303,6 +5373,7 @@
|
|||
34AB66651FC5AA330078E451 /* TransportTransitTrain.swift in Sources */,
|
||||
343064411E9FDC7300DC7665 /* SearchIndex.swift in Sources */,
|
||||
F6664BFA1E6459CB00E703C2 /* PPFacilityCell.swift in Sources */,
|
||||
475EFDBD239002D700A24B4C /* CatalogGalleryViewController.swift in Sources */,
|
||||
CDCA273F2238087700167D87 /* MWMCarPlaySearchService.mm in Sources */,
|
||||
348B926D1FF3B5E100379009 /* UIView+Animation.swift in Sources */,
|
||||
F6E2FDE91E097BA00083EBEC /* MWMObjectsCategorySelectorController.mm in Sources */,
|
||||
|
@ -5325,6 +5396,7 @@
|
|||
F6E2FDF81E097BA00083EBEC /* MWMOpeningHoursAllDayTableViewCell.mm in Sources */,
|
||||
472E3F4C2147D5700020E412 /* Subscription.swift in Sources */,
|
||||
340B33C61F3AEFDB00A8C1B4 /* MWMRouter+RouteManager.mm in Sources */,
|
||||
472848FF2386BE6E00176158 /* PlacePageReviewsViewController.swift in Sources */,
|
||||
F6E2FE191E097BA00083EBEC /* MWMOpeningHoursTimeSpanTableViewCell.mm in Sources */,
|
||||
F6E407D01FC45EF5001F7821 /* MWMDiscoveryController.mm in Sources */,
|
||||
F6E2FDEC1E097BA00083EBEC /* MWMOpeningHoursAddClosedTableViewCell.mm in Sources */,
|
||||
|
@ -5332,6 +5404,7 @@
|
|||
F6E2FE101E097BA00083EBEC /* MWMOpeningHoursTableViewCell.mm in Sources */,
|
||||
47C8789D22DF662700A772DA /* SubscriptionExpiredViewController.swift in Sources */,
|
||||
6741A9B01BF340DE002C974C /* MapsAppDelegate.mm in Sources */,
|
||||
472848FD2386A17500176158 /* AddReviewViewController.swift in Sources */,
|
||||
4719A645219CBD65009F9AA7 /* IPendingTransactionsHandler.swift in Sources */,
|
||||
34F742321E0834F400AC1FD6 /* UIViewController+Navigation.m in Sources */,
|
||||
340475811E081B3300C92850 /* iosOGLContextFactory.mm in Sources */,
|
||||
|
@ -5363,6 +5436,7 @@
|
|||
3404163C1E7BDFE000E2B6D6 /* PhotosViewController.swift in Sources */,
|
||||
47E8163323B17734008FD836 /* MWMStorage+UI.m in Sources */,
|
||||
34AB66471FC5AA330078E451 /* RouteManagerTableView.swift in Sources */,
|
||||
47E98C102382C80600C800E0 /* PlacePageInfoViewController.swift in Sources */,
|
||||
47DF72B922520CE20004AB10 /* MWMRoutingOptions.mm in Sources */,
|
||||
F6E2FE611E097BA00083EBEC /* MWMBookmarkCell.mm in Sources */,
|
||||
99B6A74E2362F5CD002C94CB /* PromoCoordinator.swift in Sources */,
|
||||
|
@ -5376,6 +5450,7 @@
|
|||
99CB34BF2369EAAC001D28AD /* TermsOfUseViewController.swift in Sources */,
|
||||
6741A9B91BF340DE002C974C /* MWMRateAlert.mm in Sources */,
|
||||
3404F48B202894EA0090E401 /* BMCViewController.swift in Sources */,
|
||||
472848FB238573EE00176158 /* RatingSummaryViewController.swift in Sources */,
|
||||
349D1ABC1E2D05EF004A2006 /* SearchBar.swift in Sources */,
|
||||
993F5511237C622700545511 /* DeepLinkCatalogueStrategy.swift in Sources */,
|
||||
34E50DF81F6FCC96008EED49 /* UGCReviewCell.swift in Sources */,
|
||||
|
@ -5412,6 +5487,7 @@
|
|||
34845DAF1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */,
|
||||
CD6E8677226774C700D1EDF7 /* CPConstants.swift in Sources */,
|
||||
F6791B141C43DF0B007A8A6E /* MWMStartButton.m in Sources */,
|
||||
47A04171238DE8AE00D84E95 /* HotelFacilitiesViewController.swift in Sources */,
|
||||
479D306522C664CE00D18278 /* MWMDownloadBannerViewController.m in Sources */,
|
||||
F6E2FEDF1E097BA00083EBEC /* MWMSearchManager+Layout.m in Sources */,
|
||||
F64D9CA01C899C350063FA30 /* MWMEditorViralAlert.mm in Sources */,
|
||||
|
@ -5420,6 +5496,7 @@
|
|||
6741A9CF1BF340DE002C974C /* MWMLocationAlert.m in Sources */,
|
||||
474AC76C2139E4F2002F9BF9 /* RemoveAdsViewController.swift in Sources */,
|
||||
34ABA62D1C2D57D500FE1BEC /* MWMInputPasswordValidator.m in Sources */,
|
||||
475EFDBB238FDDB200A24B4C /* CatalogSingleItemViewController.swift in Sources */,
|
||||
BBED27022292F6C000788143 /* BookmarksSection.mm in Sources */,
|
||||
F6E2FDA11E097BA00083EBEC /* MWMEditorAdditionalNamesTableViewController.mm in Sources */,
|
||||
999D3A67237BFA4600C5F7A8 /* SubscriptionViewBuilder.swift in Sources */,
|
||||
|
@ -5431,6 +5508,7 @@
|
|||
34ABA6171C2D185C00FE1BEC /* MWMAuthorizationOSMLoginViewController.mm in Sources */,
|
||||
991CE2DD2373145C009EB02A /* PromoAfterBookingCampaign.swift in Sources */,
|
||||
995739042355CAA30019AEE7 /* PageIndicator.swift in Sources */,
|
||||
470F0B7D238842EA006AEC94 /* ExpandableLabel.swift in Sources */,
|
||||
B33D21AF20DAF9F000BAD749 /* Toast.swift in Sources */,
|
||||
33B19C67218B481700B323A7 /* TagCollectionViewCell.swift in Sources */,
|
||||
6741A9D41BF340DE002C974C /* MWMAlertViewController.mm in Sources */,
|
||||
|
@ -5459,6 +5537,7 @@
|
|||
349D1ACF1E2E325B004A2006 /* MWMBottomMenuCollectionViewCell.m in Sources */,
|
||||
F6E2FF451E097BA00083EBEC /* SettingsTableViewLinkCell.swift in Sources */,
|
||||
34C9BD0A1C6DBCDA000DC38D /* MWMNavigationController.m in Sources */,
|
||||
472848F72383F8F700176158 /* WikiDescriptionViewController.swift in Sources */,
|
||||
CDB92CF822A5350500EC757C /* MWMDiscoveryHotelViewModel.m in Sources */,
|
||||
F6550C1F1FD81B3800352D88 /* RatingSummaryView+DefaultConfig.swift in Sources */,
|
||||
991CE2C02371D349009EB02A /* PromoCampaign.swift in Sources */,
|
||||
|
@ -5475,7 +5554,7 @@
|
|||
F6E2FD8C1E097BA00083EBEC /* MWMNoMapsView.m in Sources */,
|
||||
34D3B0361E389D05004100F9 /* MWMEditorSelectTableViewCell.m in Sources */,
|
||||
F6E2FD711E097BA00083EBEC /* MWMMapDownloaderTableViewCell.m in Sources */,
|
||||
F6E2FE4F1E097BA00083EBEC /* MWMActionBarButton.mm in Sources */,
|
||||
F6E2FE4F1E097BA00083EBEC /* MWMActionBarButton.m in Sources */,
|
||||
47F86CFF20C936FC00FEE291 /* TabView.swift in Sources */,
|
||||
34AB66741FC5AA330078E451 /* BaseRoutePreviewStatus.swift in Sources */,
|
||||
340475531E081A4600C92850 /* MWMCustomFacebookEvents.mm in Sources */,
|
||||
|
@ -5495,11 +5574,15 @@
|
|||
1DFA2F6A20D3B57400FB2C66 /* UIColor+PartnerColor.m in Sources */,
|
||||
347BFA901F27909200E5531F /* MenuArea.swift in Sources */,
|
||||
343E75981E5B1EE20041226A /* MWMCollectionViewController.m in Sources */,
|
||||
47F701F6238C8A8300D18E95 /* PlacePageButtonsViewController.swift in Sources */,
|
||||
B3E3B50220D485FA00DA8C13 /* DownloadedBookmarksDataSource.swift in Sources */,
|
||||
477D7AC7218F1515007EE2CB /* IPaidRoutePurchase.swift in Sources */,
|
||||
34E776141F14B17F003040B3 /* AvailableArea.swift in Sources */,
|
||||
475EFDC123907DAA00A24B4C /* OpeningHoursViewController.swift in Sources */,
|
||||
47A0416D238DBB6200D84E95 /* HotelPhotosViewController.swift in Sources */,
|
||||
34AB66081FC5AA320078E451 /* MWMNavigationDashboardManager.mm in Sources */,
|
||||
F6664C131E645A4100E703C2 /* MWMPPReviewCell.mm in Sources */,
|
||||
47A0416F238DD0FD00D84E95 /* HotelDescriptionViewController.swift in Sources */,
|
||||
991CE2BF2371D349009EB02A /* PromoCampaignManager.swift in Sources */,
|
||||
F6E2FE431E097BA00083EBEC /* MWMDirectionView.mm in Sources */,
|
||||
470F5A5B2181DE7500754295 /* PaidRouteViewController.swift in Sources */,
|
||||
|
@ -5608,6 +5691,7 @@
|
|||
993F550C237C622700545511 /* DeepLinkSubscriptionStrategy.swift in Sources */,
|
||||
F6E2FD6B1E097BA00083EBEC /* MWMMapDownloaderSubplaceTableViewCell.m in Sources */,
|
||||
CDCA27842245090900167D87 /* ListenerContainer.swift in Sources */,
|
||||
475EFDBF239031CD00A24B4C /* PlacePageBookmarkViewController.swift in Sources */,
|
||||
47E3C7252111E41B008B3B27 /* DimmedModalPresentationController.swift in Sources */,
|
||||
99CB34CD236B054B001D28AD /* DeepLinkInfoRouter.swift in Sources */,
|
||||
99CB34B72369E188001D28AD /* WelcomeRouter.swift in Sources */,
|
||||
|
@ -5619,6 +5703,7 @@
|
|||
34FE5A6F1F18F30F00BCA729 /* TrafficButtonArea.swift in Sources */,
|
||||
F6E2FF691E097BA00083EBEC /* MWMUnitsController.mm in Sources */,
|
||||
6741AA031BF340DE002C974C /* MWMActivityViewController.mm in Sources */,
|
||||
472849012388098300176158 /* MyReviewViewController.swift in Sources */,
|
||||
F6E2FE9D1E097BA00083EBEC /* MWMiPhonePlacePageLayoutImpl.mm in Sources */,
|
||||
CDCA27382237F1BD00167D87 /* BookmarkInfo.swift in Sources */,
|
||||
993F5509237C622700545511 /* DeepLinkHandlerStrategy.swift in Sources */,
|
||||
|
@ -5655,11 +5740,13 @@
|
|||
6741AA0B1BF340DE002C974C /* MWMMapViewControlsManager.mm in Sources */,
|
||||
F6E2FED91E097BA00083EBEC /* MWMSearchContentView.m in Sources */,
|
||||
F6BD1D211CA412920047B8E8 /* MWMOsmAuthAlert.mm in Sources */,
|
||||
472848F92384CEC900176158 /* TaxiViewController.swift in Sources */,
|
||||
34AB66321FC5AA330078E451 /* RouteManagerHeaderView.swift in Sources */,
|
||||
347040301EA6470700038379 /* BorderedButton.swift in Sources */,
|
||||
34F1ADD31F6BC09E001CE79D /* PPPReview.swift in Sources */,
|
||||
F6E2FF4B1E097BA00083EBEC /* SettingsTableViewSwitchCell.swift in Sources */,
|
||||
F6E2FE791E097BA00083EBEC /* MWMOpeningHoursLayoutHelper.mm in Sources */,
|
||||
47A04173238E989200D84E95 /* HotelReviewsViewController.swift in Sources */,
|
||||
472E3F4A2146C4CD0020E412 /* MWMPurchaseManager.mm in Sources */,
|
||||
34ABA6211C2D517500FE1BEC /* MWMInputValidator.m in Sources */,
|
||||
47C7F97521930F5300C2760C /* IInAppBilling.swift in Sources */,
|
||||
|
@ -5679,7 +5766,7 @@
|
|||
34AB66621FC5AA330078E451 /* TransportTransitSeparator.swift in Sources */,
|
||||
CDCA2743223F8D1E00167D87 /* ListItemInfo.swift in Sources */,
|
||||
B32FE74020D2844600EF7446 /* DownloadedBookmarksViewController.swift in Sources */,
|
||||
4707E4B62375B2900017DF6E /* PlacePageInfoViewController.swift in Sources */,
|
||||
4707E4B62375B2900017DF6E /* PlacePagePreviewViewController.swift in Sources */,
|
||||
340416541E7C09C200E2B6D6 /* PhotoScalingView.swift in Sources */,
|
||||
4767CDA820AB401000BD8166 /* LinkTextView.swift in Sources */,
|
||||
47289E5A2212DFFF002ABFC0 /* EditOnWebAlertViewController.swift in Sources */,
|
||||
|
@ -5696,6 +5783,7 @@
|
|||
344BEAF61F66BDC30045DC45 /* RatingSummaryViewSettings.swift in Sources */,
|
||||
F6E2FD921E097BA00083EBEC /* MWMBookmarkColorViewController.mm in Sources */,
|
||||
CD96C71C22A8113100DB7CFE /* MWMDiscoveryControllerViewModel.mm in Sources */,
|
||||
470F0B7F2388431E006AEC94 /* StarRatingView.swift in Sources */,
|
||||
F63AF5061EA6162400A1DB98 /* FilterTypeCell.swift in Sources */,
|
||||
347752881F725002000D46A3 /* UGCAddReviewRatingCell.swift in Sources */,
|
||||
47E3C7332111F4D8008B3B27 /* CoverVerticalDismissalAnimator.swift in Sources */,
|
||||
|
@ -5785,6 +5873,7 @@
|
|||
47B06E0021BAAC270094CCAD /* GeoZoneTracker.swift in Sources */,
|
||||
3404F4952028A1B80090E401 /* BMCPermissionsCell.swift in Sources */,
|
||||
340416441E7BED3900E2B6D6 /* PhotosTransitionAnimator.swift in Sources */,
|
||||
479388F92395A4D3006ECACC /* ActionBarViewController.swift in Sources */,
|
||||
34AB66261FC5AA330078E451 /* RouteManagerDimView.swift in Sources */,
|
||||
993F5514237C622700545511 /* DeepLinkStrategyFactory.swift in Sources */,
|
||||
6741AA291BF340DE002C974C /* ColorPickerView.mm in Sources */,
|
||||
|
@ -5817,6 +5906,7 @@
|
|||
F5BD29FF26AD58255766C51A /* DiscoverySpinnerCell.swift in Sources */,
|
||||
47E3C72B2111E62A008B3B27 /* FadeOutAnimatedTransitioning.swift in Sources */,
|
||||
F5BD255A0838E70EC012748E /* DiscoverySearchCell.swift in Sources */,
|
||||
470F0B7A23882955006AEC94 /* PlacePageReviewViewController.swift in Sources */,
|
||||
47C7F9732191E15A00C2760C /* InAppBilling.swift in Sources */,
|
||||
F5BD2CA4DBEFACBC48195F39 /* DiscoveryCollectionHolderCell.swift in Sources */,
|
||||
);
|
||||
|
|
98
iphone/Maps/UI/PlacePage/ActionBarViewController.swift
Normal file
98
iphone/Maps/UI/PlacePage/ActionBarViewController.swift
Normal file
|
@ -0,0 +1,98 @@
|
|||
|
||||
class ActionBarViewController: UIViewController {
|
||||
@IBOutlet var stackView: UIStackView!
|
||||
|
||||
var placePageData: PlacePageData!
|
||||
var isRoutePlanning = false
|
||||
var canAddStop = false
|
||||
|
||||
private var visibleButtons: [ActionBarButtonType] = []
|
||||
private var additionalButtons: [ActionBarButtonType] = []
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
configButton1()
|
||||
configButton2()
|
||||
configButton3()
|
||||
configButton4()
|
||||
|
||||
for buttonType in visibleButtons {
|
||||
var selected = false
|
||||
var disabled = false
|
||||
if buttonType == .bookmark {
|
||||
if let bookmarkData = placePageData.bookmarkData {
|
||||
selected = true
|
||||
disabled = bookmarkData.isEditable
|
||||
}
|
||||
}
|
||||
guard let button = ActionBarButton(delegate: self,
|
||||
buttonType: buttonType,
|
||||
partnerIndex: -1,
|
||||
isSelected: selected,
|
||||
isDisabled: disabled) else { continue }
|
||||
stackView.addArrangedSubview(button)
|
||||
}
|
||||
}
|
||||
|
||||
private func configButton1() {
|
||||
var buttons: [ActionBarButtonType] = []
|
||||
if isRoutePlanning {
|
||||
buttons.append(.routeFrom)
|
||||
}
|
||||
if placePageData.previewData.isBookingPlace {
|
||||
buttons.append(.booking)
|
||||
}
|
||||
if placePageData.sponsoredType == .partner {
|
||||
buttons.append(.partner)
|
||||
}
|
||||
if placePageData.bookingSearchUrl != nil {
|
||||
buttons.append(.bookingSearch)
|
||||
}
|
||||
if placePageData.infoData.phone != nil, AppInfo.shared().canMakeCalls {
|
||||
buttons.append(.call)
|
||||
}
|
||||
if !isRoutePlanning {
|
||||
buttons.append(.routeFrom)
|
||||
}
|
||||
|
||||
assert(buttons.count > 0)
|
||||
visibleButtons.append(buttons[0])
|
||||
if buttons.count > 1 {
|
||||
additionalButtons.append(contentsOf: buttons.suffix(from: 1))
|
||||
}
|
||||
}
|
||||
|
||||
private func configButton2() {
|
||||
var buttons: [ActionBarButtonType] = []
|
||||
if canAddStop {
|
||||
buttons.append(.routeAddStop)
|
||||
}
|
||||
buttons.append(.bookmark)
|
||||
|
||||
assert(buttons.count > 0)
|
||||
visibleButtons.append(buttons[0])
|
||||
if buttons.count > 1 {
|
||||
additionalButtons.append(contentsOf: buttons.suffix(from: 1))
|
||||
}
|
||||
}
|
||||
|
||||
private func configButton3() {
|
||||
visibleButtons.append(.routeTo)
|
||||
}
|
||||
|
||||
private func configButton4() {
|
||||
if additionalButtons.isEmpty {
|
||||
visibleButtons.append(.share)
|
||||
} else {
|
||||
additionalButtons.append(.share)
|
||||
visibleButtons.append(.more)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ActionBarViewController: ActionBarButtonDelegate {
|
||||
func tapOnButton(with type: ActionBarButtonType) {
|
||||
|
||||
}
|
||||
}
|
34
iphone/Maps/UI/PlacePage/AddReviewViewController.swift
Normal file
34
iphone/Maps/UI/PlacePage/AddReviewViewController.swift
Normal file
|
@ -0,0 +1,34 @@
|
|||
protocol AddReviewViewControllerDelegate: AnyObject {
|
||||
func didRate(_ rating: UgcSummaryRatingType)
|
||||
}
|
||||
|
||||
class AddReviewViewController: UIViewController {
|
||||
@IBOutlet var horribleButton: UIButton!
|
||||
@IBOutlet var badButton: UIButton!
|
||||
@IBOutlet var normalButton: UIButton!
|
||||
@IBOutlet var goodButton: UIButton!
|
||||
@IBOutlet var excellentButton: UIButton!
|
||||
|
||||
weak var delegate: AddReviewViewControllerDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
}
|
||||
|
||||
@IBAction func onRate(_ sender: UIButton) {
|
||||
switch sender {
|
||||
case horribleButton:
|
||||
delegate?.didRate(.horrible)
|
||||
case badButton:
|
||||
delegate?.didRate(.bad)
|
||||
case normalButton:
|
||||
delegate?.didRate(.normal)
|
||||
case goodButton:
|
||||
delegate?.didRate(.good)
|
||||
case excellentButton:
|
||||
delegate?.didRate(.excellent)
|
||||
default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
102
iphone/Maps/UI/PlacePage/CatalogGalleryViewController.swift
Normal file
102
iphone/Maps/UI/PlacePage/CatalogGalleryViewController.swift
Normal file
|
@ -0,0 +1,102 @@
|
|||
class CatalogPromoItemCell: UICollectionViewCell {
|
||||
@IBOutlet var itemImageView: UIImageView!
|
||||
@IBOutlet var titleLabel: UILabel!
|
||||
@IBOutlet var subtitleLabel: UILabel!
|
||||
@IBOutlet var proLabel: UILabel!
|
||||
@IBOutlet var proContainerView: UIView!
|
||||
|
||||
typealias OnDetails = () -> Void
|
||||
private var onDetails: OnDetails?
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
itemImageView.image = UIImage(named: "img_guide_placeholder")
|
||||
titleLabel.text = ""
|
||||
subtitleLabel.text = ""
|
||||
proLabel.text = ""
|
||||
proContainerView.isHidden = true
|
||||
onDetails = nil
|
||||
}
|
||||
|
||||
func config(promoItem: CatalogPromoItem, onDetails: @escaping OnDetails) {
|
||||
setImage(promoItem.imageUrl)
|
||||
titleLabel.text = promoItem.guideName
|
||||
subtitleLabel.text = promoItem.guideAuthor
|
||||
self.onDetails = onDetails
|
||||
guard !promoItem.categoryLabel.isEmpty else {
|
||||
proContainerView.isHidden = true
|
||||
return
|
||||
}
|
||||
proLabel.text = promoItem.categoryLabel
|
||||
if promoItem.hexColor.count == 6 {
|
||||
proContainerView.backgroundColor = UIColor(fromHexString: promoItem.hexColor)
|
||||
} else {
|
||||
proContainerView.backgroundColor = UIColor.ratingRed()
|
||||
}
|
||||
proContainerView.isHidden = false
|
||||
}
|
||||
|
||||
@IBAction func onDetails(_ sender: UIButton) {
|
||||
onDetails?()
|
||||
}
|
||||
|
||||
private func setImage(_ imageUrl: String?) {
|
||||
guard let imageUrl = imageUrl else { return }
|
||||
if let url = URL(string: imageUrl) {
|
||||
itemImageView.image = UIImage(named: "img_guide_placeholder")
|
||||
itemImageView.wi_setImage(with: url, transitionDuration: kDefaultAnimationDuration)
|
||||
} else {
|
||||
itemImageView.image = UIImage(named: "img_guide_placeholder")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol CatalogGalleryViewControllerDelegate: AnyObject {
|
||||
func promoGalleryDidSelectItemAtIndex(_ index: Int)
|
||||
func promoGalleryDidPressMore()
|
||||
}
|
||||
|
||||
class CatalogGalleryViewController: UIViewController {
|
||||
@IBOutlet var titleLabel: UILabel!
|
||||
@IBOutlet var collectionView: UICollectionView!
|
||||
|
||||
var promoData: CatalogPromoData? {
|
||||
didSet {
|
||||
guard let promoData = promoData else { return }
|
||||
collectionView?.reloadData()
|
||||
titleLabel.text = String(coreFormat: L("pp_discovery_place_related_tag_header"),
|
||||
arguments: [promoData.tagsString])
|
||||
}
|
||||
}
|
||||
weak var delegate: CatalogGalleryViewControllerDelegate?
|
||||
}
|
||||
|
||||
extension CatalogGalleryViewController: UICollectionViewDataSource {
|
||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
guard let promoData = promoData else { return 0 }
|
||||
return promoData.promoItems.count + 1
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
if indexPath.item < promoData!.promoItems.count {
|
||||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DiscoveryGuideCell", for: indexPath) as! CatalogPromoItemCell
|
||||
cell.config(promoItem: promoData!.promoItems[indexPath.item]) { [weak self] in
|
||||
self?.delegate?.promoGalleryDidSelectItemAtIndex(indexPath.item)
|
||||
}
|
||||
return cell
|
||||
} else {
|
||||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MoreCell", for: indexPath)
|
||||
return cell
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension CatalogGalleryViewController: UICollectionViewDelegate {
|
||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
if indexPath.item == promoData!.promoItems.count {
|
||||
delegate?.promoGalleryDidPressMore()
|
||||
} else {
|
||||
delegate?.promoGalleryDidSelectItemAtIndex(indexPath.item)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
protocol CatalogSingleItemViewControllerDelegate: AnyObject {
|
||||
func catalogPromoItemDidPressView()
|
||||
func catalogPromoItemDidPressMore()
|
||||
}
|
||||
|
||||
class CatalogSingleItemViewController: UIViewController {
|
||||
@IBOutlet var placeTitleLabel: UILabel!
|
||||
@IBOutlet var placeDescriptionLabel: UILabel!
|
||||
@IBOutlet var guideNameLabel: UILabel!
|
||||
@IBOutlet var guideAuthorLabel: UILabel!
|
||||
@IBOutlet var placeImageView: UIImageView!
|
||||
@IBOutlet var headerLabel: UILabel!
|
||||
|
||||
var promoItem: CatalogPromoItem? {
|
||||
didSet {
|
||||
updateViews()
|
||||
}
|
||||
}
|
||||
weak var delegate: CatalogSingleItemViewControllerDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
headerLabel.text = L("pp_discovery_place_related_header").uppercased()
|
||||
updateViews()
|
||||
}
|
||||
|
||||
private func updateViews() {
|
||||
guard let promoItem = promoItem else { return }
|
||||
placeTitleLabel.text = promoItem.placeTitle
|
||||
placeDescriptionLabel.text = promoItem.placeDescription
|
||||
guideNameLabel.text = promoItem.guideName
|
||||
guideAuthorLabel.text = promoItem.guideAuthor
|
||||
guard let url = URL(string: promoItem.imageUrl) else {
|
||||
return
|
||||
}
|
||||
placeImageView.wi_setImage(with: url)
|
||||
}
|
||||
|
||||
@IBAction func onMore(_ sender: UIButton) {
|
||||
delegate?.catalogPromoItemDidPressMore()
|
||||
}
|
||||
|
||||
@IBAction func onView(_ sender: UIButton) {
|
||||
delegate?.catalogPromoItemDidPressView()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
protocol HotelDescriptionViewControllerDelegate: AnyObject {
|
||||
func hotelDescriptionDidPressMore()
|
||||
}
|
||||
|
||||
class HotelDescriptionViewController: UIViewController {
|
||||
@IBOutlet var descriptionExpandableLabel: ExpandableLabel!
|
||||
@IBOutlet var moreButton: UIButton!
|
||||
|
||||
var hotelDescription: String? {
|
||||
didSet {
|
||||
descriptionExpandableLabel.textLabel.text = hotelDescription
|
||||
}
|
||||
}
|
||||
weak var delegate: HotelDescriptionViewControllerDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
descriptionExpandableLabel.textLabel.numberOfLines = 3
|
||||
descriptionExpandableLabel.textLabel.text = hotelDescription
|
||||
descriptionExpandableLabel.textLabel.font = UIFont.regular16()
|
||||
descriptionExpandableLabel.textLabel.textColor = UIColor.blackPrimaryText()
|
||||
descriptionExpandableLabel.expandButton.setTitleColor(UIColor.linkBlue(), for: .normal)
|
||||
descriptionExpandableLabel.expandButton.titleLabel?.font = UIFont.regular16()
|
||||
descriptionExpandableLabel.expandButton.setTitle(L("booking_show_more"), for: .normal)
|
||||
}
|
||||
|
||||
@IBAction func onMoreButton(_ sender: UIButton) {
|
||||
delegate?.hotelDescriptionDidPressMore()
|
||||
}
|
||||
}
|
64
iphone/Maps/UI/PlacePage/HotelFacilitiesViewController.swift
Normal file
64
iphone/Maps/UI/PlacePage/HotelFacilitiesViewController.swift
Normal file
|
@ -0,0 +1,64 @@
|
|||
class HotelFacilityViewController: UIViewController {
|
||||
@IBOutlet var facilityLabel: UILabel!
|
||||
var facility: String!
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
facilityLabel.text = facility
|
||||
}
|
||||
}
|
||||
|
||||
protocol HotelFacilitiesViewControllerDelegate: AnyObject {
|
||||
func facilitiesDidPressMore()
|
||||
}
|
||||
|
||||
class HotelFacilitiesViewController: UIViewController {
|
||||
@IBOutlet var stackView: UIStackView!
|
||||
|
||||
var facilities: [HotelFacility]? {
|
||||
didSet {
|
||||
updateFacilities()
|
||||
}
|
||||
}
|
||||
weak var delegate: HotelFacilitiesViewControllerDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
updateFacilities()
|
||||
}
|
||||
|
||||
private func updateFacilities() {
|
||||
guard let facilities = facilities else { return }
|
||||
|
||||
let count = min(facilities.count, 3)
|
||||
for i in 0..<count {
|
||||
addFacility(facilities[i].name)
|
||||
}
|
||||
|
||||
if facilities.count > count {
|
||||
addMoreButton()
|
||||
}
|
||||
}
|
||||
|
||||
@objc func onMoreButton(_ sender: UIButton) {
|
||||
delegate?.facilitiesDidPressMore()
|
||||
}
|
||||
|
||||
private func addFacility(_ facility: String) {
|
||||
let vc = storyboard!.instantiateViewController(ofType: HotelFacilityViewController.self)
|
||||
vc.facility = facility
|
||||
addChild(vc)
|
||||
stackView.addArrangedSubview(vc.view)
|
||||
vc.didMove(toParent: self)
|
||||
}
|
||||
|
||||
private func addMoreButton() {
|
||||
let button = UIButton()
|
||||
button.setTitle(L("booking_show_more"), for: .normal)
|
||||
button.titleLabel?.font = UIFont.regular16()
|
||||
button.setTitleColor(UIColor.linkBlue(), for: .normal)
|
||||
button.heightAnchor.constraint(equalToConstant: 44).isActive = true
|
||||
stackView.addArrangedSubview(button)
|
||||
button.addTarget(self, action: #selector(onMoreButton(_:)), for: .touchUpInside)
|
||||
}
|
||||
}
|
50
iphone/Maps/UI/PlacePage/HotelPhotosViewController.swift
Normal file
50
iphone/Maps/UI/PlacePage/HotelPhotosViewController.swift
Normal file
|
@ -0,0 +1,50 @@
|
|||
class PhotoCell: UICollectionViewCell {
|
||||
@IBOutlet var imageView: UIImageView!
|
||||
@IBOutlet var dimView: UIView!
|
||||
|
||||
func config(_ imageUrlString: String, dimmed: Bool = false) {
|
||||
guard let imageUrl = URL(string: imageUrlString) else { return }
|
||||
imageView.wi_setImage(with: imageUrl)
|
||||
dimView.isHidden = !dimmed
|
||||
}
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
imageView.wi_cancelImageRequest()
|
||||
}
|
||||
}
|
||||
|
||||
protocol HotelPhotosViewControllerDelegate: AnyObject {
|
||||
func didSelectItemAt(_ index: Int)
|
||||
}
|
||||
|
||||
class HotelPhotosViewController: UIViewController {
|
||||
@IBOutlet var collectionView: UICollectionView!
|
||||
|
||||
var photos: [HotelPhotoUrl]? {
|
||||
didSet {
|
||||
collectionView?.reloadData()
|
||||
}
|
||||
}
|
||||
weak var delegate: HotelPhotosViewControllerDelegate?
|
||||
}
|
||||
|
||||
extension HotelPhotosViewController: UICollectionViewDataSource {
|
||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
min(photos?.count ?? 0, 5)
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
let photoCell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoCell", for: indexPath) as! PhotoCell
|
||||
if let photoItem = photos?[indexPath.item] {
|
||||
photoCell.config(photoItem.thumbnail)
|
||||
}
|
||||
return photoCell
|
||||
}
|
||||
}
|
||||
|
||||
extension HotelPhotosViewController: UICollectionViewDelegate {
|
||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
delegate?.didSelectItemAt(indexPath.item)
|
||||
}
|
||||
}
|
101
iphone/Maps/UI/PlacePage/HotelReviewsViewController.swift
Normal file
101
iphone/Maps/UI/PlacePage/HotelReviewsViewController.swift
Normal file
|
@ -0,0 +1,101 @@
|
|||
class HotelReviewViewController: UIViewController {
|
||||
@IBOutlet var authorLabel: UILabel!
|
||||
@IBOutlet var dateLabel: UILabel!
|
||||
@IBOutlet var ratingLabel: UILabel!
|
||||
@IBOutlet var positiveView: UIView!
|
||||
@IBOutlet var positiveLabel: UILabel!
|
||||
@IBOutlet var negativeView: UIView!
|
||||
@IBOutlet var negativeLabel: UILabel!
|
||||
|
||||
var review: HotelReview!
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
authorLabel.text = review.author
|
||||
ratingLabel.text = NSNumber(value: review.score).stringValue
|
||||
let formatter = DateFormatter()
|
||||
formatter.dateStyle = .long
|
||||
formatter.timeStyle = .none
|
||||
dateLabel.text = formatter.string(from: review.date)
|
||||
if let positiveReview = review.pros {
|
||||
positiveLabel.text = positiveReview
|
||||
positiveView.isHidden = false
|
||||
}
|
||||
|
||||
if let negativeReview = review.cons {
|
||||
negativeLabel.text = negativeReview
|
||||
negativeView.isHidden = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol HotelReviewsViewControllerDelegate: AnyObject {
|
||||
func hotelReviewsDidPressMore()
|
||||
}
|
||||
|
||||
class HotelReviewsViewController: UIViewController {
|
||||
@IBOutlet var stackView: UIStackView!
|
||||
@IBOutlet var totalRatingLabel: UILabel!
|
||||
@IBOutlet var reviewsCountLabel: UILabel!
|
||||
|
||||
var totalScore: Float = 0 {
|
||||
didSet {
|
||||
totalRatingLabel?.text = NSNumber(value: totalScore).stringValue
|
||||
}
|
||||
}
|
||||
var reviewCount: UInt = 0 {
|
||||
didSet {
|
||||
reviewsCountLabel?.text = String(format:L("placepage_summary_rating_description"), reviewCount)
|
||||
}
|
||||
}
|
||||
var reviews: [HotelReview]? {
|
||||
didSet {
|
||||
updateReviews()
|
||||
}
|
||||
}
|
||||
|
||||
weak var delegate: HotelReviewsViewControllerDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
totalRatingLabel.text = NSNumber(value: totalScore).stringValue
|
||||
reviewsCountLabel.text = String(format:L("placepage_summary_rating_description"), reviewCount)
|
||||
updateReviews()
|
||||
}
|
||||
|
||||
private func updateReviews() {
|
||||
guard let reviews = reviews else { return }
|
||||
let count = min(reviews.count, 3)
|
||||
for i in 0..<count {
|
||||
addReview(reviews[i])
|
||||
}
|
||||
|
||||
if reviewCount > count {
|
||||
addMoreButton()
|
||||
}
|
||||
}
|
||||
|
||||
@objc func onMoreButton(_ sender: UIButton) {
|
||||
delegate?.hotelReviewsDidPressMore()
|
||||
}
|
||||
|
||||
private func addReview(_ review: HotelReview) {
|
||||
let vc = storyboard!.instantiateViewController(ofType: HotelReviewViewController.self)
|
||||
vc.review = review
|
||||
addChild(vc)
|
||||
stackView.addArrangedSubview(vc.view)
|
||||
vc.didMove(toParent: self)
|
||||
}
|
||||
|
||||
private func addMoreButton() {
|
||||
let button = UIButton()
|
||||
button.setTitle(L("reviews_on_bookingcom"), for: .normal)
|
||||
button.titleLabel?.font = UIFont.regular16()
|
||||
button.setTitleColor(UIColor.linkBlue(), for: .normal)
|
||||
button.heightAnchor.constraint(equalToConstant: 44).isActive = true
|
||||
stackView.addArrangedSubview(button)
|
||||
button.addTarget(self, action: #selector(onMoreButton(_:)), for: .touchUpInside)
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@
|
|||
#import "MWMStorage+UI.h"
|
||||
#import "SwiftBridge.h"
|
||||
#import "MWMMapViewControlsManager+AddPlace.h"
|
||||
#import "location_util.h"
|
||||
|
||||
#import <CoreApi/CoreApi.h>
|
||||
|
||||
|
@ -298,7 +299,7 @@ void RegisterEventIfPossible(eye::MapObject::Event::Type const type, place_page:
|
|||
|
||||
#pragma mark - MWMLocationObserver
|
||||
|
||||
- (void)onHeadingUpdate:(location::CompassInfo const &)info
|
||||
- (void)onHeadingUpdate:(CLHeading *)heading
|
||||
{
|
||||
auto lastLocation = [MWMLocationManager lastLocation];
|
||||
auto data = self.data;
|
||||
|
@ -310,6 +311,7 @@ void RegisterEventIfPossible(eye::MapObject::Event::Type const type, place_page:
|
|||
if (base::AlmostEqualAbs(locationMercator, dataMercator, 1e-10))
|
||||
return;
|
||||
|
||||
auto const info = location_util::compassInfoFromHeading(heading);
|
||||
auto const angle = ang::AngleTo(locationMercator, dataMercator) + info.m_bearing;
|
||||
[self.layout rotateDirectionArrowToAngle:angle];
|
||||
}
|
||||
|
@ -321,7 +323,7 @@ void RegisterEventIfPossible(eye::MapObject::Event::Type const type, place_page:
|
|||
[self.layout setSpeedAndAltitude:location_helpers::formattedSpeedAndAltitude(MWMLocationManager.lastLocation)];
|
||||
}
|
||||
|
||||
- (void)onLocationUpdate:(location::GpsInfo const &)locationInfo
|
||||
- (void)onLocationUpdate:(CLLocation *)location
|
||||
{
|
||||
[self setupSpeedAndDistance];
|
||||
}
|
||||
|
|
48
iphone/Maps/UI/PlacePage/MyReviewViewController.swift
Normal file
48
iphone/Maps/UI/PlacePage/MyReviewViewController.swift
Normal file
|
@ -0,0 +1,48 @@
|
|||
class MyReviewViewController: UIViewController {
|
||||
@IBOutlet var dateLabel: UILabel!
|
||||
@IBOutlet var expandableLabel: ExpandableLabel! {
|
||||
didSet {
|
||||
expandableLabel.textLabel.font = UIFont.regular14()
|
||||
expandableLabel.textLabel.textColor = UIColor.blackPrimaryText()
|
||||
expandableLabel.expandButton.setTitleColor(UIColor.linkBlue(), for: .normal)
|
||||
expandableLabel.expandButton.titleLabel?.font = UIFont.regular14()
|
||||
expandableLabel.expandButton.setTitle(L("placepage_more_button"), for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
@IBOutlet var ratingViews: [UIView]!
|
||||
@IBOutlet var ratingLabels: [UILabel]!
|
||||
@IBOutlet var starViews: [StarRatingView]! {
|
||||
didSet {
|
||||
starViews.forEach {
|
||||
$0.activeColor = UIColor.ratingYellow()
|
||||
$0.inactiveColor = UIColor.blackDividers()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var myReview: UgcMyReview!
|
||||
lazy var dateFormatter: DateFormatter = {
|
||||
let formatter = DateFormatter()
|
||||
formatter.dateStyle = .long
|
||||
formatter.timeStyle = .none
|
||||
return formatter
|
||||
} ()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
dateLabel.text = dateFormatter.string(from: myReview.date)
|
||||
expandableLabel.textLabel.text = myReview.text
|
||||
|
||||
for i in 0..<3 {
|
||||
if myReview.starRatings.count > i {
|
||||
let starRating = myReview.starRatings[i]
|
||||
ratingLabels[i].text = L(starRating.title)
|
||||
starViews[i].rating = Int(round(starRating.value))
|
||||
} else {
|
||||
ratingViews[i].isHidden = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
iphone/Maps/UI/PlacePage/OpeningHoursViewController.swift
Normal file
30
iphone/Maps/UI/PlacePage/OpeningHoursViewController.swift
Normal file
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// OpeningHoursViewController.swift
|
||||
// MAPS.ME
|
||||
//
|
||||
// Created by aleksey.belousov on 29/11/2019.
|
||||
// Copyright © 2019 MapsWithMe. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class OpeningHoursViewController: UIViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// MARK: - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
// Get the new view controller using segue.destination.
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,87 @@
|
|||
protocol PlacePageBookmarkViewControllerDelegate: AnyObject {
|
||||
func bookmarkDidPressEdit()
|
||||
}
|
||||
|
||||
class PlacePageBookmarkViewController: UIViewController {
|
||||
@IBOutlet var stackView: UIStackView!
|
||||
@IBOutlet var spinner: UIImageView!
|
||||
@IBOutlet var editButton: UIButton!
|
||||
@IBOutlet var expandableLabel: ExpandableLabel! {
|
||||
didSet {
|
||||
expandableLabel.textLabel.font = UIFont.regular14()
|
||||
expandableLabel.textLabel.textColor = UIColor.blackPrimaryText()
|
||||
expandableLabel.textLabel.numberOfLines = 5
|
||||
expandableLabel.expandButton.setTitleColor(UIColor.linkBlue(), for: .normal)
|
||||
expandableLabel.expandButton.titleLabel?.font = UIFont.regular14()
|
||||
expandableLabel.expandButton.setTitle(L("placepage_more_button"), for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
var bookmarkData: PlacePageBookmarkData? {
|
||||
didSet {
|
||||
updateViews()
|
||||
}
|
||||
}
|
||||
weak var delegate: PlacePageBookmarkViewControllerDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
updateViews()
|
||||
}
|
||||
|
||||
func updateViews() {
|
||||
guard let bookmarkData = bookmarkData else { return }
|
||||
editButton.isEnabled = bookmarkData.isEditable
|
||||
if let description = bookmarkData.bookmarkDescription {
|
||||
if bookmarkData.isHtmlDescription {
|
||||
setHtmlDescription(description)
|
||||
} else {
|
||||
expandableLabel.textLabel.text = description
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func setHtmlDescription(_ htmlDescription: String) {
|
||||
DispatchQueue.global().async {
|
||||
let font = UIFont.regular14()
|
||||
let color = UIColor.blackPrimaryText()
|
||||
let paragraphStyle = NSMutableParagraphStyle()
|
||||
paragraphStyle.lineSpacing = 4
|
||||
|
||||
let attributedString: NSAttributedString
|
||||
if let str = NSMutableAttributedString(htmlString: htmlDescription, baseFont: font, paragraphStyle: paragraphStyle) {
|
||||
str.addAttribute(NSAttributedString.Key.foregroundColor,
|
||||
value: color,
|
||||
range: NSRange(location: 0, length: str.length))
|
||||
attributedString = str;
|
||||
} else {
|
||||
attributedString = NSAttributedString(string: htmlDescription,
|
||||
attributes: [NSAttributedString.Key.font : font,
|
||||
NSAttributedString.Key.foregroundColor: color,
|
||||
NSAttributedString.Key.paragraphStyle: paragraphStyle])
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.expandableLabel.textLabel.attributedText = attributedString
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func startSpinner() {
|
||||
editButton.isHidden = true
|
||||
let postfix = UIColor.isNightMode() ? "dark" : "light"
|
||||
spinner.image = UIImage(named: "Spinner_" + postfix)
|
||||
spinner.isHidden = false
|
||||
spinner.startRotation()
|
||||
}
|
||||
|
||||
private func stopSpinner() {
|
||||
editButton.isHidden = false
|
||||
spinner.isHidden = true
|
||||
spinner.stopRotation()
|
||||
}
|
||||
|
||||
@IBAction func onEdit(_ sender: UIButton) {
|
||||
delegate?.bookmarkDidPressEdit()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
protocol PlacePageButtonsViewControllerDelegate: AnyObject {
|
||||
func didPressHotels()
|
||||
func didPressAddPlace()
|
||||
func didPressEditPlace()
|
||||
func didPressAddBusiness()
|
||||
}
|
||||
|
||||
class PlacePageButtonsViewController: UIViewController {
|
||||
@IBOutlet var bookingButton: UIButton!
|
||||
@IBOutlet var addPlaceButton: UIButton!
|
||||
@IBOutlet var editPlaceButton: UIButton!
|
||||
@IBOutlet var addBusinessButton: UIButton!
|
||||
|
||||
var buttonsData: PlacePageButtonsData!
|
||||
weak var delegate: PlacePageButtonsViewControllerDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
bookingButton.isHidden = !buttonsData.showHotelDescription
|
||||
addPlaceButton.isHidden = !buttonsData.showAddPlace
|
||||
editPlaceButton.isHidden = !buttonsData.showEditPlace
|
||||
addBusinessButton.isHidden = !buttonsData.showAddBusiness
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
|
||||
@IBAction func onBooking(_ sender: UIButton) {
|
||||
delegate?.didPressHotels()
|
||||
}
|
||||
|
||||
@IBAction func onAddPlace(_ sender: UIButton) {
|
||||
delegate?.didPressAddPlace()
|
||||
}
|
||||
|
||||
@IBAction func onEditPlace(_ sender: UIButton) {
|
||||
delegate?.didPressEditPlace()
|
||||
}
|
||||
|
||||
@IBAction func onAddBusiness(_ sender: UIButton) {
|
||||
delegate?.didPressAddBusiness()
|
||||
}
|
||||
}
|
|
@ -1,30 +1,174 @@
|
|||
//
|
||||
// PlacePageInfoViewController.swift
|
||||
// MAPS.ME
|
||||
//
|
||||
// Created by aleksey.belousov on 08/11/2019.
|
||||
// Copyright © 2019 MapsWithMe. All rights reserved.
|
||||
//
|
||||
class InfoItemViewController: UIViewController {
|
||||
enum Style {
|
||||
case regular
|
||||
case link
|
||||
}
|
||||
|
||||
import UIKit
|
||||
typealias TapHandler = () -> Void
|
||||
|
||||
@IBOutlet var imageView: UIImageView!
|
||||
@IBOutlet var infoLabel: UILabel!
|
||||
@IBOutlet var accessoryImage: UIImageView!
|
||||
@IBOutlet var separatorView: UIView!
|
||||
@IBOutlet var tapGestureRecognizer: UITapGestureRecognizer!
|
||||
|
||||
var tapHandler: TapHandler?
|
||||
var style: Style = .regular {
|
||||
didSet {
|
||||
switch style {
|
||||
case .regular:
|
||||
imageView?.mwm_coloring = .black
|
||||
infoLabel?.textColor = UIColor.blackPrimaryText()
|
||||
case .link:
|
||||
imageView?.mwm_coloring = .blue
|
||||
infoLabel?.textColor = UIColor.linkBlue()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func onTap(_ sender: UITapGestureRecognizer) {
|
||||
tapHandler?()
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
if style == .link {
|
||||
imageView.mwm_coloring = .blue
|
||||
infoLabel.textColor = UIColor.linkBlue()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol PlacePageInfoViewControllerDelegate: AnyObject {
|
||||
func didPressCall()
|
||||
func didPressWebsite()
|
||||
func didPressEmail()
|
||||
func didPressLocalAd()
|
||||
}
|
||||
|
||||
class PlacePageInfoViewController: UIViewController {
|
||||
private typealias TapHandler = InfoItemViewController.TapHandler
|
||||
private typealias Style = InfoItemViewController.Style
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
@IBOutlet var stackView: UIStackView!
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
private var openingHoursView: InfoItemViewController?
|
||||
private var phoneView: InfoItemViewController?
|
||||
private var websiteView: InfoItemViewController?
|
||||
private var emailView: InfoItemViewController?
|
||||
private var cuisineView: InfoItemViewController?
|
||||
private var operatorView: InfoItemViewController?
|
||||
private var wifiView: InfoItemViewController?
|
||||
private var addressView: InfoItemViewController?
|
||||
private var coordinatesView: InfoItemViewController?
|
||||
private var localAdsButton: UIButton?
|
||||
|
||||
var placePageInfoData: PlacePageInfoData!
|
||||
weak var delegate: PlacePageInfoViewControllerDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
if let openingHoursString = placePageInfoData.openingHoursString {
|
||||
openingHoursView = createInfoItem(openingHoursString, icon: UIImage(named: "ic_placepage_open_hours")) {
|
||||
|
||||
}
|
||||
openingHoursView?.accessoryImage.image = UIImage(named: "ic_arrow_gray_down")
|
||||
openingHoursView?.accessoryImage.isHidden = false
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// MARK: - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
// Get the new view controller using segue.destination.
|
||||
// Pass the selected object to the new view controller.
|
||||
if let phone = placePageInfoData.phone {
|
||||
var cellStyle: Style = .regular
|
||||
if let phoneUrl = placePageInfoData.phoneUrl, UIApplication.shared.canOpenURL(phoneUrl) {
|
||||
cellStyle = .link
|
||||
}
|
||||
phoneView = createInfoItem(phone, icon: UIImage(named: "ic_placepage_phone_number"), style: cellStyle) { [weak self] in
|
||||
self?.delegate?.didPressCall()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if let website = placePageInfoData.website {
|
||||
websiteView = createInfoItem(website, icon: UIImage(named: "ic_placepage_website"), style: .link) { [weak self] in
|
||||
self?.delegate?.didPressWebsite()
|
||||
}
|
||||
}
|
||||
|
||||
if let email = placePageInfoData.email {
|
||||
emailView = createInfoItem(email, icon: UIImage(named: "ic_placepage_email"), style: .link) { [weak self] in
|
||||
self?.delegate?.didPressEmail()
|
||||
}
|
||||
}
|
||||
|
||||
if let cuisine = placePageInfoData.cuisine {
|
||||
cuisineView = createInfoItem(cuisine, icon: UIImage(named: "ic_placepage_cuisine"))
|
||||
}
|
||||
|
||||
if let ppOperator = placePageInfoData.ppOperator {
|
||||
operatorView = createInfoItem(ppOperator, icon: UIImage(named: "ic_placepage_operator"))
|
||||
}
|
||||
|
||||
if placePageInfoData.wifiAvailable {
|
||||
wifiView = createInfoItem(L("WiFi_available"), icon: UIImage(named: "ic_placepage_wifi"))
|
||||
}
|
||||
|
||||
if let address = placePageInfoData.address {
|
||||
addressView = createInfoItem(address, icon: UIImage(named: "ic_placepage_adress"))
|
||||
}
|
||||
|
||||
if let coordinates = placePageInfoData.formattedCoordinates {
|
||||
coordinatesView = createInfoItem(coordinates, icon: UIImage(named: "ic_placepage_coordinate")) {
|
||||
|
||||
}
|
||||
coordinatesView?.accessoryImage.image = UIImage(named: "ic_placepage_change")
|
||||
coordinatesView?.accessoryImage.isHidden = false
|
||||
}
|
||||
|
||||
switch placePageInfoData.localAdsStatus {
|
||||
case .candidate:
|
||||
localAdsButton = createLocalAdsButton(L("create_campaign_button"))
|
||||
case .customer:
|
||||
localAdsButton = createLocalAdsButton(L("view_campaign_button"))
|
||||
case .notAvailable, .hidden:
|
||||
coordinatesView?.separatorView.isHidden = true
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: private
|
||||
|
||||
@objc private func onLocalAdsButton(_ sender: UIButton) {
|
||||
delegate?.didPressLocalAd()
|
||||
}
|
||||
|
||||
private func createLocalAdsButton(_ title: String) -> UIButton {
|
||||
let button = UIButton()
|
||||
button.setTitle(title, for: .normal)
|
||||
button.titleLabel?.font = UIFont.regular17()
|
||||
button.setTitleColor(UIColor.linkBlue(), for: .normal)
|
||||
button.heightAnchor.constraint(equalToConstant: 44).isActive = true
|
||||
stackView.addArrangedSubview(button)
|
||||
button.addTarget(self, action: #selector(onLocalAdsButton(_:)), for: .touchUpInside)
|
||||
return button
|
||||
}
|
||||
|
||||
private func createInfoItem(_ info: String,
|
||||
icon: UIImage?,
|
||||
style: Style = .regular,
|
||||
tapHandler: TapHandler? = nil) -> InfoItemViewController {
|
||||
let vc = storyboard!.instantiateViewController(ofType: InfoItemViewController.self)
|
||||
addToStack(vc)
|
||||
vc.imageView.image = icon
|
||||
vc.infoLabel.text = info
|
||||
vc.style = style
|
||||
vc.tapHandler = tapHandler
|
||||
return vc;
|
||||
}
|
||||
|
||||
private func addToStack(_ viewController: UIViewController) {
|
||||
addChild(viewController)
|
||||
stackView.addArrangedSubview(viewController.view)
|
||||
viewController.didMove(toParent: self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,43 +1,50 @@
|
|||
enum class EButton // Required button's order
|
||||
{
|
||||
Booking,
|
||||
BookingSearch,
|
||||
Bookmark,
|
||||
Call,
|
||||
Download,
|
||||
More,
|
||||
Opentable,
|
||||
Partner,
|
||||
RouteAddStop,
|
||||
RouteFrom,
|
||||
RouteRemoveStop,
|
||||
RouteTo,
|
||||
Share,
|
||||
AvoidToll,
|
||||
AvoidDirty,
|
||||
AvoidFerry
|
||||
};
|
||||
typedef NS_ENUM(NSInteger, MWMActionBarButtonType) {
|
||||
MWMActionBarButtonTypeBooking,
|
||||
MWMActionBarButtonTypeBookingSearch,
|
||||
MWMActionBarButtonTypeBookmark,
|
||||
MWMActionBarButtonTypeCall,
|
||||
MWMActionBarButtonTypeDownload,
|
||||
MWMActionBarButtonTypeMore,
|
||||
MWMActionBarButtonTypeOpentable,
|
||||
MWMActionBarButtonTypePartner,
|
||||
MWMActionBarButtonTypeRouteAddStop,
|
||||
MWMActionBarButtonTypeRouteFrom,
|
||||
MWMActionBarButtonTypeRouteRemoveStop,
|
||||
MWMActionBarButtonTypeRouteTo,
|
||||
MWMActionBarButtonTypeShare,
|
||||
MWMActionBarButtonTypeAvoidToll,
|
||||
MWMActionBarButtonTypeAvoidDirty,
|
||||
MWMActionBarButtonTypeAvoidFerry
|
||||
} NS_SWIFT_NAME(ActionBarButtonType);
|
||||
|
||||
NSString * titleForButton(EButton type, int partnerIndex, BOOL isSelected);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
NSString * titleForButton(MWMActionBarButtonType type, int partnerIndex, BOOL isSelected);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@class MWMActionBarButton;
|
||||
@class MWMCircularProgress;
|
||||
|
||||
NS_SWIFT_NAME(ActionBarButtonDelegate)
|
||||
@protocol MWMActionBarButtonDelegate <NSObject>
|
||||
|
||||
- (void)tapOnButtonWithType:(EButton)type;
|
||||
- (void)tapOnButtonWithType:(MWMActionBarButtonType)type;
|
||||
|
||||
@end
|
||||
|
||||
NS_SWIFT_NAME(ActionBarButton)
|
||||
@interface MWMActionBarButton : UIView
|
||||
|
||||
+ (MWMActionBarButton *)buttonWithDelegate:(id<MWMActionBarButtonDelegate>)delegate
|
||||
buttonType:(EButton)type
|
||||
buttonType:(MWMActionBarButtonType)type
|
||||
partnerIndex:(int)partnerIndex
|
||||
isSelected:(BOOL)isSelected
|
||||
isDisabled:(BOOL)isDisabled;
|
||||
|
||||
- (EButton)type;
|
||||
- (MWMActionBarButtonType)type;
|
||||
- (MWMCircularProgress *)mapDownloadProgress;
|
||||
- (int)partnerIndex;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#import "MWMActionBarButton.h"
|
||||
#import "MWMButton.h"
|
||||
#import "MWMCircularProgress.h"
|
||||
#import "MWMCircularProgress+Swift.h"
|
||||
|
||||
NSString * titleForPartner(int partnerIndex)
|
||||
{
|
||||
|
@ -10,26 +10,26 @@ NSString * titleForPartner(int partnerIndex)
|
|||
return localizedStr;
|
||||
}
|
||||
|
||||
NSString * titleForButton(EButton type, int partnerIndex, BOOL isSelected)
|
||||
NSString * titleForButton(MWMActionBarButtonType type, int partnerIndex, BOOL isSelected)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EButton::Download: return L(@"download");
|
||||
case EButton::Booking:
|
||||
case EButton::Opentable: return L(@"book_button");
|
||||
case EButton::BookingSearch: return L(@"booking_search");
|
||||
case EButton::Call: return L(@"placepage_call_button");
|
||||
case EButton::Bookmark: return L(isSelected ? @"delete" : @"save");
|
||||
case EButton::RouteFrom: return L(@"p2p_from_here");
|
||||
case EButton::RouteTo: return L(@"p2p_to_here");
|
||||
case EButton::Share: return L(@"share");
|
||||
case EButton::More: return L(@"placepage_more_button");
|
||||
case EButton::RouteAddStop: return L(@"placepage_add_stop");
|
||||
case EButton::RouteRemoveStop: return L(@"placepage_remove_stop");
|
||||
case EButton::AvoidToll: return L(@"avoid_toll_roads_placepage");
|
||||
case EButton::AvoidDirty: return L(@"avoid_unpaved_roads_placepage");
|
||||
case EButton::AvoidFerry: return L(@"avoid_ferry_crossing_placepage");
|
||||
case EButton::Partner: return titleForPartner(partnerIndex);
|
||||
case MWMActionBarButtonTypeDownload: return L(@"download");
|
||||
case MWMActionBarButtonTypeBooking:
|
||||
case MWMActionBarButtonTypeOpentable: return L(@"book_button");
|
||||
case MWMActionBarButtonTypeBookingSearch: return L(@"booking_search");
|
||||
case MWMActionBarButtonTypeCall: return L(@"placepage_call_button");
|
||||
case MWMActionBarButtonTypeBookmark: return L(isSelected ? @"delete" : @"save");
|
||||
case MWMActionBarButtonTypeRouteFrom: return L(@"p2p_from_here");
|
||||
case MWMActionBarButtonTypeRouteTo: return L(@"p2p_to_here");
|
||||
case MWMActionBarButtonTypeShare: return L(@"share");
|
||||
case MWMActionBarButtonTypeMore: return L(@"placepage_more_button");
|
||||
case MWMActionBarButtonTypeRouteAddStop: return L(@"placepage_add_stop");
|
||||
case MWMActionBarButtonTypeRouteRemoveStop: return L(@"placepage_remove_stop");
|
||||
case MWMActionBarButtonTypeAvoidToll: return L(@"avoid_toll_roads_placepage");
|
||||
case MWMActionBarButtonTypeAvoidDirty: return L(@"avoid_unpaved_roads_placepage");
|
||||
case MWMActionBarButtonTypeAvoidFerry: return L(@"avoid_ferry_crossing_placepage");
|
||||
case MWMActionBarButtonTypePartner: return titleForPartner(partnerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ UIColor * backgroundColorForPartner(int partnerIndex)
|
|||
|
||||
@interface MWMActionBarButton () <MWMCircularProgressProtocol>
|
||||
|
||||
@property(nonatomic) EButton type;
|
||||
@property(nonatomic) MWMActionBarButtonType type;
|
||||
@property(nonatomic) MWMCircularProgress * mapDownloadProgress;
|
||||
@property(nonatomic) int partnerIndex;
|
||||
@property(weak, nonatomic) IBOutlet MWMButton * button;
|
||||
|
@ -81,7 +81,7 @@ UIColor * backgroundColorForPartner(int partnerIndex)
|
|||
self.extraBackground.hidden = YES;
|
||||
switch (self.type)
|
||||
{
|
||||
case EButton::Download:
|
||||
case MWMActionBarButtonTypeDownload:
|
||||
{
|
||||
if (self.mapDownloadProgress)
|
||||
return;
|
||||
|
@ -96,7 +96,7 @@ UIColor * backgroundColorForPartner(int partnerIndex)
|
|||
[self.mapDownloadProgress setColoring:MWMButtonColoringBlue forStates:affectedStates];
|
||||
break;
|
||||
}
|
||||
case EButton::Booking:
|
||||
case MWMActionBarButtonTypeBooking:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_booking_logo"] forState:UIControlStateNormal];
|
||||
self.label.textColor = UIColor.whiteColor;
|
||||
self.backgroundColor = [UIColor bookingBackground];
|
||||
|
@ -106,7 +106,7 @@ UIColor * backgroundColorForPartner(int partnerIndex)
|
|||
self.extraBackground.hidden = NO;
|
||||
}
|
||||
break;
|
||||
case EButton::BookingSearch:
|
||||
case MWMActionBarButtonTypeBookingSearch:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_booking_search"]
|
||||
forState:UIControlStateNormal];
|
||||
self.label.textColor = UIColor.whiteColor;
|
||||
|
@ -117,7 +117,7 @@ UIColor * backgroundColorForPartner(int partnerIndex)
|
|||
self.extraBackground.hidden = NO;
|
||||
}
|
||||
break;
|
||||
case EButton::Opentable:
|
||||
case MWMActionBarButtonTypeOpentable:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_opentable"] forState:UIControlStateNormal];
|
||||
self.label.textColor = UIColor.whiteColor;
|
||||
self.backgroundColor = [UIColor opentableBackground];
|
||||
|
@ -127,46 +127,46 @@ UIColor * backgroundColorForPartner(int partnerIndex)
|
|||
self.extraBackground.hidden = NO;
|
||||
}
|
||||
break;
|
||||
case EButton::Call:
|
||||
case MWMActionBarButtonTypeCall:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_placepage_phone_number"]
|
||||
forState:UIControlStateNormal];
|
||||
break;
|
||||
case EButton::Bookmark: [self setupBookmarkButton:isSelected]; break;
|
||||
case EButton::RouteFrom:
|
||||
case MWMActionBarButtonTypeBookmark: [self setupBookmarkButton:isSelected]; break;
|
||||
case MWMActionBarButtonTypeRouteFrom:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_route_from"] forState:UIControlStateNormal];
|
||||
break;
|
||||
case EButton::RouteTo:
|
||||
case MWMActionBarButtonTypeRouteTo:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_route_to"] forState:UIControlStateNormal];
|
||||
break;
|
||||
case EButton::Share:
|
||||
case MWMActionBarButtonTypeShare:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_menu_share"] forState:UIControlStateNormal];
|
||||
break;
|
||||
case EButton::More:
|
||||
case MWMActionBarButtonTypeMore:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_placepage_more"]
|
||||
forState:UIControlStateNormal];
|
||||
break;
|
||||
case EButton::RouteAddStop:
|
||||
case MWMActionBarButtonTypeRouteAddStop:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_add_route_point"]
|
||||
forState:UIControlStateNormal];
|
||||
break;
|
||||
case EButton::RouteRemoveStop:
|
||||
case MWMActionBarButtonTypeRouteRemoveStop:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_remove_route_point"]
|
||||
forState:UIControlStateNormal];
|
||||
break;
|
||||
case EButton::Partner:
|
||||
case MWMActionBarButtonTypePartner:
|
||||
[self.button setImage:imageForPartner(self.partnerIndex) forState:UIControlStateNormal];
|
||||
self.label.textColor = textColorForPartner(self.partnerIndex);
|
||||
self.backgroundColor = backgroundColorForPartner(self.partnerIndex);
|
||||
break;
|
||||
case EButton::AvoidToll:
|
||||
case MWMActionBarButtonTypeAvoidToll:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_avoid_tolls"]
|
||||
forState:UIControlStateNormal];
|
||||
break;
|
||||
case EButton::AvoidDirty:
|
||||
case MWMActionBarButtonTypeAvoidDirty:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_avoid_dirty"]
|
||||
forState:UIControlStateNormal];
|
||||
break;
|
||||
case EButton::AvoidFerry:
|
||||
case MWMActionBarButtonTypeAvoidFerry:
|
||||
[self.button setImage:[UIImage imageNamed:@"ic_avoid_ferry"]
|
||||
forState:UIControlStateNormal];
|
||||
break;
|
||||
|
@ -175,7 +175,7 @@ UIColor * backgroundColorForPartner(int partnerIndex)
|
|||
}
|
||||
|
||||
+ (MWMActionBarButton *)buttonWithDelegate:(id<MWMActionBarButtonDelegate>)delegate
|
||||
buttonType:(EButton)type
|
||||
buttonType:(MWMActionBarButtonType)type
|
||||
partnerIndex:(int)partnerIndex
|
||||
isSelected:(BOOL)isSelected
|
||||
isDisabled:(BOOL)isDisabled
|
||||
|
@ -191,12 +191,12 @@ UIColor * backgroundColorForPartner(int partnerIndex)
|
|||
|
||||
- (void)progressButtonPressed:(MWMCircularProgress *)progress
|
||||
{
|
||||
[self.delegate tapOnButtonWithType:EButton::Download];
|
||||
[self.delegate tapOnButtonWithType:MWMActionBarButtonTypeDownload];
|
||||
}
|
||||
|
||||
- (IBAction)tap
|
||||
{
|
||||
if (self.type == EButton::Bookmark)
|
||||
if (self.type == MWMActionBarButtonTypeBookmark)
|
||||
[self setBookmarkSelected:!self.button.isSelected];
|
||||
|
||||
[self.delegate tapOnButtonWithType:self.type];
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
@interface MWMPlacePageActionBar ()<MWMActionBarButtonDelegate>
|
||||
{
|
||||
std::vector<EButton> m_visibleButtons;
|
||||
std::vector<EButton> m_additionalButtons;
|
||||
std::vector<MWMActionBarButtonType> m_visibleButtons;
|
||||
std::vector<MWMActionBarButtonType> m_additionalButtons;
|
||||
}
|
||||
|
||||
@property(nonatomic) NSLayoutConstraint * visibleConstraint;
|
||||
|
@ -49,39 +49,39 @@
|
|||
|
||||
- (void)setFirstButton:(MWMPlacePageData *)data
|
||||
{
|
||||
std::vector<EButton> buttons;
|
||||
std::vector<MWMActionBarButtonType> buttons;
|
||||
|
||||
if (self.isAreaNotDownloaded)
|
||||
{
|
||||
buttons.push_back(EButton::Download);
|
||||
buttons.push_back(MWMActionBarButtonTypeDownload);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL const isRoutePlanning =
|
||||
[MWMNavigationDashboardManager manager].state != MWMNavigationDashboardStateHidden;
|
||||
if (isRoutePlanning)
|
||||
buttons.push_back(EButton::RouteFrom);
|
||||
buttons.push_back(MWMActionBarButtonTypeRouteFrom);
|
||||
|
||||
BOOL const isBooking = [data isBooking];
|
||||
if (isBooking)
|
||||
buttons.push_back(EButton::Booking);
|
||||
buttons.push_back(MWMActionBarButtonTypeBooking);
|
||||
BOOL const isOpentable = [data isOpentable];
|
||||
if (isOpentable)
|
||||
buttons.push_back(EButton::Opentable);
|
||||
buttons.push_back(MWMActionBarButtonTypeOpentable);
|
||||
BOOL const isPartner = [data isPartner] && [data sponsoredURL] != nil;
|
||||
if (isPartner)
|
||||
buttons.push_back(EButton::Partner);
|
||||
buttons.push_back(MWMActionBarButtonTypePartner);
|
||||
BOOL const isBookingSearch = [data isBookingSearch];
|
||||
if (isBookingSearch)
|
||||
buttons.push_back(EButton::BookingSearch);
|
||||
buttons.push_back(MWMActionBarButtonTypeBookingSearch);
|
||||
|
||||
BOOL const isPhoneCallAvailable =
|
||||
[AppInfo sharedInfo].canMakeCalls && [data phoneNumber].length > 0;
|
||||
if (isPhoneCallAvailable)
|
||||
buttons.push_back(EButton::Call);
|
||||
buttons.push_back(MWMActionBarButtonTypeCall);
|
||||
|
||||
if (!isRoutePlanning)
|
||||
buttons.push_back(EButton::RouteFrom);
|
||||
buttons.push_back(MWMActionBarButtonTypeRouteFrom);
|
||||
}
|
||||
|
||||
NSAssert(!buttons.empty(), @"Missing first action bar button");
|
||||
|
@ -93,14 +93,14 @@
|
|||
|
||||
- (void)setSecondButton:(MWMPlacePageData *)data
|
||||
{
|
||||
std::vector<EButton> buttons;
|
||||
std::vector<MWMActionBarButtonType> buttons;
|
||||
BOOL const isCanAddIntermediatePoint = [MWMRouter canAddIntermediatePoint];
|
||||
BOOL const isNavigationReady =
|
||||
[MWMNavigationDashboardManager manager].state == MWMNavigationDashboardStateReady;
|
||||
if (isCanAddIntermediatePoint && isNavigationReady)
|
||||
buttons.push_back(EButton::RouteAddStop);
|
||||
buttons.push_back(MWMActionBarButtonTypeRouteAddStop);
|
||||
|
||||
buttons.push_back(EButton::Bookmark);
|
||||
buttons.push_back(MWMActionBarButtonTypeBookmark);
|
||||
|
||||
auto begin = buttons.begin();
|
||||
m_visibleButtons.push_back(*begin);
|
||||
|
@ -108,18 +108,18 @@
|
|||
std::copy(begin, buttons.end(), std::back_inserter(m_additionalButtons));
|
||||
}
|
||||
|
||||
- (void)setThirdButton { m_visibleButtons.push_back(EButton::RouteTo); }
|
||||
- (void)setThirdButton { m_visibleButtons.push_back(MWMActionBarButtonTypeRouteTo); }
|
||||
|
||||
- (void)setFourthButton
|
||||
{
|
||||
if (m_additionalButtons.empty())
|
||||
{
|
||||
m_visibleButtons.push_back(EButton::Share);
|
||||
m_visibleButtons.push_back(MWMActionBarButtonTypeShare);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_visibleButtons.push_back(EButton::More);
|
||||
m_additionalButtons.push_back(EButton::Share);
|
||||
m_visibleButtons.push_back(MWMActionBarButtonTypeMore);
|
||||
m_additionalButtons.push_back(MWMActionBarButtonTypeShare);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,8 +130,8 @@
|
|||
|
||||
for (auto const buttonType : m_visibleButtons)
|
||||
{
|
||||
auto const isSelected = (buttonType == EButton::Bookmark ? [data isBookmark] : NO);
|
||||
auto const isDisabled = (buttonType == EButton::Bookmark && [data isBookmark] && !data.isBookmarkEditable);
|
||||
auto const isSelected = (buttonType == MWMActionBarButtonTypeBookmark ? [data isBookmark] : NO);
|
||||
auto const isDisabled = (buttonType == MWMActionBarButtonTypeBookmark && [data isBookmark] && !data.isBookmarkEditable);
|
||||
auto button = [MWMActionBarButton buttonWithDelegate:self
|
||||
buttonType:buttonType
|
||||
partnerIndex:partnerIndex
|
||||
|
@ -141,7 +141,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)setSingleButton { m_visibleButtons.push_back(EButton::RouteRemoveStop); }
|
||||
- (void)setSingleButton { m_visibleButtons.push_back(MWMActionBarButtonTypeRouteRemoveStop); }
|
||||
|
||||
- (void)setButtons:(MWMPlacePageData *)data
|
||||
{
|
||||
|
@ -152,13 +152,13 @@
|
|||
} else if (roadType != RoadWarningMarkType::Count) {
|
||||
switch (roadType) {
|
||||
case RoadWarningMarkType::Toll:
|
||||
m_visibleButtons.push_back(EButton::AvoidToll);
|
||||
m_visibleButtons.push_back(MWMActionBarButtonTypeAvoidToll);
|
||||
break;
|
||||
case RoadWarningMarkType::Ferry:
|
||||
m_visibleButtons.push_back(EButton::AvoidFerry);
|
||||
m_visibleButtons.push_back(MWMActionBarButtonTypeAvoidFerry);
|
||||
break;
|
||||
case RoadWarningMarkType::Dirty:
|
||||
m_visibleButtons.push_back(EButton::AvoidDirty);
|
||||
m_visibleButtons.push_back(MWMActionBarButtonTypeAvoidDirty);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -198,7 +198,7 @@
|
|||
{
|
||||
for (MWMActionBarButton * button in self.barButtons.subviews)
|
||||
{
|
||||
if ([button type] == EButton::Download)
|
||||
if ([button type] == MWMActionBarButtonTypeDownload)
|
||||
return button.mapDownloadProgress;
|
||||
}
|
||||
}
|
||||
|
@ -218,34 +218,34 @@
|
|||
|
||||
#pragma mark - MWMActionBarButtonDelegate
|
||||
|
||||
- (void)tapOnButtonWithType:(EButton)type
|
||||
- (void)tapOnButtonWithType:(MWMActionBarButtonType)type
|
||||
{
|
||||
id<MWMActionBarProtocol> delegate = self.delegate;
|
||||
auto data = self.data;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case EButton::Download: [delegate downloadSelectedArea]; break;
|
||||
case EButton::Opentable:
|
||||
case EButton::Booking: [delegate book]; break;
|
||||
case EButton::BookingSearch: [delegate searchBookingHotels]; break;
|
||||
case EButton::Call: [delegate call]; break;
|
||||
case EButton::Bookmark:
|
||||
case MWMActionBarButtonTypeDownload: [delegate downloadSelectedArea]; break;
|
||||
case MWMActionBarButtonTypeOpentable:
|
||||
case MWMActionBarButtonTypeBooking: [delegate book]; break;
|
||||
case MWMActionBarButtonTypeBookingSearch: [delegate searchBookingHotels]; break;
|
||||
case MWMActionBarButtonTypeCall: [delegate call]; break;
|
||||
case MWMActionBarButtonTypeBookmark:
|
||||
if ([data isBookmark])
|
||||
[delegate removeBookmark];
|
||||
else
|
||||
[delegate addBookmark];
|
||||
break;
|
||||
case EButton::RouteFrom: [delegate routeFrom]; break;
|
||||
case EButton::RouteTo: [delegate routeTo]; break;
|
||||
case EButton::Share: [delegate share]; break;
|
||||
case EButton::More: [self showActionSheet]; break;
|
||||
case EButton::RouteAddStop: [delegate routeAddStop]; break;
|
||||
case EButton::RouteRemoveStop: [delegate routeRemoveStop]; break;
|
||||
case EButton::AvoidToll: [delegate avoidToll]; break;
|
||||
case EButton::AvoidDirty: [delegate avoidDirty]; break;
|
||||
case EButton::AvoidFerry: [delegate avoidFerry]; break;
|
||||
case EButton::Partner: [delegate openPartner]; break;
|
||||
case MWMActionBarButtonTypeRouteFrom: [delegate routeFrom]; break;
|
||||
case MWMActionBarButtonTypeRouteTo: [delegate routeTo]; break;
|
||||
case MWMActionBarButtonTypeShare: [delegate share]; break;
|
||||
case MWMActionBarButtonTypeMore: [self showActionSheet]; break;
|
||||
case MWMActionBarButtonTypeRouteAddStop: [delegate routeAddStop]; break;
|
||||
case MWMActionBarButtonTypeRouteRemoveStop: [delegate routeRemoveStop]; break;
|
||||
case MWMActionBarButtonTypeAvoidToll: [delegate avoidToll]; break;
|
||||
case MWMActionBarButtonTypeAvoidDirty: [delegate avoidDirty]; break;
|
||||
case MWMActionBarButtonTypeAvoidFerry: [delegate avoidFerry]; break;
|
||||
case MWMActionBarButtonTypePartner: [delegate openPartner]; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@
|
|||
NSMutableArray<NSString *> * titles = [@[] mutableCopy];
|
||||
for (auto const buttonType : m_additionalButtons)
|
||||
{
|
||||
BOOL const isSelected = buttonType == EButton::Bookmark ? [data isBookmark] : NO;
|
||||
BOOL const isSelected = buttonType == MWMActionBarButtonTypeBookmark ? [data isBookmark] : NO;
|
||||
if (NSString * title = titleForButton(buttonType, [data partnerIndex], isSelected))
|
||||
[titles addObject:title];
|
||||
else
|
||||
|
|
|
@ -1,22 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
|
||||
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15509"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="UGCAddReviewCell" id="KGk-i7-Jjw" customClass="MWMUGCAddReviewCell" propertyAccessControl="all">
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="UGCAddReviewCell" id="KGk-i7-Jjw" customClass="MWMUGCAddReviewCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="128"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="127.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="128"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="O6m-tq-AL7">
|
||||
|
@ -26,10 +23,10 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OWZ-cu-RdT">
|
||||
<rect key="frame" x="16" y="52" width="288" height="59.5"/>
|
||||
<rect key="frame" x="16" y="52" width="288" height="60"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="stA-xC-5jb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="59.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="60"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="D4Q-0A-Efb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
|
||||
|
@ -45,7 +42,7 @@
|
|||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Horrible" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7eh-cZ-bQ2">
|
||||
<rect key="frame" x="0.0" y="47.5" width="40" height="12"/>
|
||||
<rect key="frame" x="0.0" y="48" width="40" height="12"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="10"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -55,7 +52,7 @@
|
|||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="JsA-OK-Evh">
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="59.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="60"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="-19" maxX="0.0" maxY="0.0"/>
|
||||
<state key="normal" image="ic_24px_rating_horrible"/>
|
||||
<connections>
|
||||
|
@ -78,10 +75,10 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="02P-Ht-B8E">
|
||||
<rect key="frame" x="40" y="0.0" width="84" height="59.5"/>
|
||||
<rect key="frame" x="40" y="0.0" width="84" height="60"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FR5-Ym-AgZ">
|
||||
<rect key="frame" x="22" y="0.0" width="40" height="59.5"/>
|
||||
<rect key="frame" x="22" y="0.0" width="40" height="60"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZfD-kJ-Q3m">
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
|
||||
|
@ -97,13 +94,13 @@
|
|||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Bad" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HDt-VE-NRp">
|
||||
<rect key="frame" x="10.5" y="47.5" width="19" height="12"/>
|
||||
<rect key="frame" x="10.5" y="48" width="19" height="12"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="10"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ep2-Ms-SEh">
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="59.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="60"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="-19" maxX="0.0" maxY="0.0"/>
|
||||
<state key="normal" image="ic_24px_rating_bad"/>
|
||||
<connections>
|
||||
|
@ -134,7 +131,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IvZ-jc-I5F">
|
||||
<rect key="frame" x="124" y="0.0" width="40" height="59.5"/>
|
||||
<rect key="frame" x="124" y="0.0" width="40" height="60"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3W8-Mg-bTw">
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
|
||||
|
@ -150,13 +147,13 @@
|
|||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Normal" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vds-hI-dsi">
|
||||
<rect key="frame" x="2" y="47.5" width="36" height="12"/>
|
||||
<rect key="frame" x="2" y="48" width="36" height="12"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="10"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1kJ-GS-ar5">
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="59.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="60"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="-19" maxX="0.0" maxY="0.0"/>
|
||||
<state key="normal" image="ic_24px_rating_normal"/>
|
||||
<connections>
|
||||
|
@ -179,10 +176,10 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="H26-KC-z3X">
|
||||
<rect key="frame" x="164" y="0.0" width="84" height="59.5"/>
|
||||
<rect key="frame" x="164" y="0.0" width="84" height="60"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ADD-eW-XeA">
|
||||
<rect key="frame" x="22" y="0.0" width="40" height="59.5"/>
|
||||
<rect key="frame" x="22" y="0.0" width="40" height="60"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lPm-nd-4qs">
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
|
||||
|
@ -198,13 +195,13 @@
|
|||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Good" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ST3-Um-4dH">
|
||||
<rect key="frame" x="7" y="47.5" width="26.5" height="12"/>
|
||||
<rect key="frame" x="7" y="48" width="26.5" height="12"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="10"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TJy-zt-WQZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="59.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="60"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="-19" maxX="0.0" maxY="0.0"/>
|
||||
<state key="normal" image="ic_24px_rating_good"/>
|
||||
<connections>
|
||||
|
@ -235,7 +232,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gRX-L4-fra">
|
||||
<rect key="frame" x="248" y="0.0" width="40" height="59.5"/>
|
||||
<rect key="frame" x="248" y="0.0" width="40" height="60"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="U5X-iD-KyI">
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
|
||||
|
@ -251,13 +248,13 @@
|
|||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Excellent" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jqs-rm-LpL">
|
||||
<rect key="frame" x="-2.5" y="47.5" width="45" height="12"/>
|
||||
<rect key="frame" x="-2.5" y="48" width="45" height="12"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="10"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OEs-63-qBj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="59.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="60"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="-19" maxX="0.0" maxY="0.0"/>
|
||||
<state key="normal" image="ic_24px_rating_excellent"/>
|
||||
<connections>
|
||||
|
@ -328,6 +325,7 @@
|
|||
<outlet property="normalLabel" destination="vds-hI-dsi" id="gEX-i3-cw4"/>
|
||||
<outlet property="titleLabel" destination="O6m-tq-AL7" id="VZ0-JQ-m6d"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="139" y="154"/>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
<resources>
|
||||
|
|
168
iphone/Maps/UI/PlacePage/PlacePagePreviewViewController.swift
Normal file
168
iphone/Maps/UI/PlacePage/PlacePagePreviewViewController.swift
Normal file
|
@ -0,0 +1,168 @@
|
|||
class DirectionView: UIView {
|
||||
@IBOutlet var button: UIButton!
|
||||
}
|
||||
|
||||
protocol PlacePagePreviewViewControllerDelegate: AnyObject {
|
||||
func previewDidPressAddReview()
|
||||
func previewDidPressSimilarHotels()
|
||||
}
|
||||
|
||||
class PlacePagePreviewViewController: UIViewController {
|
||||
@IBOutlet var titleLabel: UILabel!
|
||||
@IBOutlet var titleContainerView: UIStackView!
|
||||
@IBOutlet var popularView: UIView!
|
||||
@IBOutlet var subtitleLabel: UILabel!
|
||||
@IBOutlet var subtitleContainerView: UIStackView!
|
||||
@IBOutlet var scheduleLabel: UILabel!
|
||||
@IBOutlet var ratingSummaryView: RatingSummaryView!
|
||||
@IBOutlet var reviewsLabel: UILabel!
|
||||
@IBOutlet var addReviewButton: UIButton! {
|
||||
didSet {
|
||||
addReviewButton.setTitle("+ \(L("leave_a_review"))", for: .normal)
|
||||
}
|
||||
}
|
||||
@IBOutlet var priceLabel: UILabel!
|
||||
@IBOutlet var discountView: UIView!
|
||||
@IBOutlet var discountLabel: UILabel!
|
||||
@IBOutlet var ugcContainerView: UIStackView!
|
||||
@IBOutlet var addressLabel: UILabel!
|
||||
@IBOutlet var addressContainerView: UIStackView!
|
||||
@IBOutlet var searchSimilarButton: UIButton!
|
||||
|
||||
@IBOutlet var titleDirectionView: DirectionView!
|
||||
@IBOutlet var subtitleDirectionView: DirectionView!
|
||||
@IBOutlet var addressDirectionView: DirectionView!
|
||||
|
||||
var directionView: DirectionView?
|
||||
|
||||
var placePagePreviewData: PlacePagePreviewData!
|
||||
weak var delegate: PlacePagePreviewViewControllerDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
if let title = placePagePreviewData.title {
|
||||
titleLabel.text = title
|
||||
directionView = titleDirectionView
|
||||
} else {
|
||||
titleContainerView.isHidden = true
|
||||
}
|
||||
if let subtitle = placePagePreviewData.subtitle {
|
||||
subtitleLabel.text = subtitle
|
||||
directionView = subtitleDirectionView
|
||||
} else {
|
||||
subtitleContainerView.isHidden = true
|
||||
}
|
||||
if let address = placePagePreviewData.address {
|
||||
addressLabel.text = address
|
||||
directionView = addressDirectionView
|
||||
} else {
|
||||
addressContainerView.isHidden = true
|
||||
}
|
||||
|
||||
if let pricing = placePagePreviewData.pricing {
|
||||
priceLabel.text = pricing
|
||||
} else {
|
||||
priceLabel.isHidden = true
|
||||
}
|
||||
popularView.isHidden = !placePagePreviewData.isPopular
|
||||
searchSimilarButton.isHidden = placePagePreviewData.hotelType == .none
|
||||
configSchedule()
|
||||
configUgc()
|
||||
ugcContainerView.isHidden = !placePagePreviewData.isBookingPlace
|
||||
|
||||
directionView?.isHidden = false
|
||||
// directionView?.button.imageView?.transform = CGAffineTransform(rotationAngle: 0.2)
|
||||
}
|
||||
|
||||
func updateUgc(_ ugcData: UgcData) {
|
||||
ugcContainerView.isHidden = false
|
||||
if let summaryRating = ugcData.summaryRating {
|
||||
ratingSummaryView.defaultConfig()
|
||||
ratingSummaryView.value = summaryRating.ratingString
|
||||
let r = summaryRating.ratingType.rawValue
|
||||
ratingSummaryView.type = MWMRatingSummaryViewValueType(rawValue: UInt(r))!
|
||||
reviewsLabel.text = String(format:L("placepage_summary_rating_description"), ugcData.ratingsCount)
|
||||
} else {
|
||||
if ugcData.isUpdateEmpty {
|
||||
ratingSummaryView.noValueImage = UIImage(named: "ic_12px_rating_normal")
|
||||
ratingSummaryView.noValueColor = UIColor.blackSecondaryText()
|
||||
reviewsLabel.text = ugcData.reviews.count == 0 ? L("placepage_no_reviews") : ""
|
||||
} else {
|
||||
ratingSummaryView.noValueImage = UIImage(named: "ic_12px_radio_on")
|
||||
ratingSummaryView.noValueColor = UIColor.linkBlue()
|
||||
reviewsLabel.text = L("placepage_reviewed")
|
||||
addReviewButton.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
addReviewButton.isHidden = !ugcData.isUpdateEmpty
|
||||
}
|
||||
|
||||
func updateBooking(_ bookingData: HotelBookingData, rooms: HotelRooms?) {
|
||||
ugcContainerView.isHidden = false
|
||||
ratingSummaryView.defaultConfig()
|
||||
ratingSummaryView.value = NSNumber(value: bookingData.score).stringValue
|
||||
let rawRating = UInt(bookingData.score / 2) + 1
|
||||
ratingSummaryView.type = MWMRatingSummaryViewValueType(rawValue: rawRating) ?? .noValue
|
||||
guard let rooms = rooms else { return }
|
||||
priceLabel.text = String(coreFormat: L("place_page_starting_from"), arguments: [rooms.minPrice])
|
||||
priceLabel.isHidden = false
|
||||
if rooms.discount > 0 {
|
||||
discountLabel.text = "-\(rooms.discount)%"
|
||||
discountView.isHidden = false
|
||||
} else if rooms.isSmartDeal {
|
||||
discountLabel.text = "%"
|
||||
discountView.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
func updateDistance(_ distance: String) {
|
||||
directionView?.button.setTitle(distance, for: .normal)
|
||||
}
|
||||
|
||||
func updateHeading(_ angle: CGFloat) {
|
||||
UIView.animate(withDuration: kDefaultAnimationDuration, delay: 0, options: [.beginFromCurrentState, .curveEaseInOut], animations: {
|
||||
self.directionView?.button.transform = CGAffineTransform(rotationAngle: angle)
|
||||
})
|
||||
}
|
||||
|
||||
@IBAction func onAddReview(_ sender: UIButton) {
|
||||
delegate?.previewDidPressAddReview()
|
||||
}
|
||||
|
||||
@IBAction func onSimilarHotels(_ sender: UIButton) {
|
||||
delegate?.previewDidPressSimilarHotels()
|
||||
}
|
||||
// MARK: private
|
||||
|
||||
private func configSchedule() {
|
||||
switch placePagePreviewData.schedule {
|
||||
case .openingHoursAllDay:
|
||||
scheduleLabel.text = L("twentyfour_seven")
|
||||
case .openingHoursOpen:
|
||||
scheduleLabel.text = L("editor_time_open")
|
||||
case .openingHoursClosed:
|
||||
scheduleLabel.text = L("closed_now")
|
||||
scheduleLabel.textColor = UIColor.red
|
||||
case .openingHoursUnknown:
|
||||
scheduleLabel.isHidden = true
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
private func configUgc() {
|
||||
ratingSummaryView.textFont = UIFont.bold12()
|
||||
ratingSummaryView.backgroundOpacity = 0.05
|
||||
ratingSummaryView.value = "-"
|
||||
|
||||
if placePagePreviewData.isBookingPlace {
|
||||
reviewsLabel.isHidden = true
|
||||
addReviewButton.isHidden = true
|
||||
} else {
|
||||
priceLabel.isHidden = true
|
||||
discountView.isHidden = true
|
||||
}
|
||||
}
|
||||
}
|
29
iphone/Maps/UI/PlacePage/PlacePageReviewViewController.swift
Normal file
29
iphone/Maps/UI/PlacePage/PlacePageReviewViewController.swift
Normal file
|
@ -0,0 +1,29 @@
|
|||
class PlacePageReviewViewController: UIViewController {
|
||||
@IBOutlet var titleLabel: UILabel!
|
||||
@IBOutlet var dateLabel: UILabel!
|
||||
@IBOutlet var expandableLabel: ExpandableLabel! {
|
||||
didSet {
|
||||
expandableLabel.textLabel.font = UIFont.regular14()
|
||||
expandableLabel.textLabel.textColor = UIColor.blackPrimaryText()
|
||||
expandableLabel.expandButton.setTitleColor(UIColor.linkBlue(), for: .normal)
|
||||
expandableLabel.expandButton.titleLabel?.font = UIFont.regular14()
|
||||
expandableLabel.expandButton.setTitle(L("placepage_more_button"), for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
var review: UgcReview!
|
||||
lazy var dateFormatter: DateFormatter = {
|
||||
let formatter = DateFormatter()
|
||||
formatter.dateStyle = .long
|
||||
formatter.timeStyle = .none
|
||||
return formatter
|
||||
} ()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
titleLabel.text = review.author
|
||||
dateLabel.text = dateFormatter.string(from: review.date)
|
||||
expandableLabel.textLabel.text = review.text
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
protocol PlacePageReviewsViewControllerDelegate: AnyObject {
|
||||
func didPressMoreReviews()
|
||||
}
|
||||
|
||||
class PlacePageReviewsViewController: UIViewController {
|
||||
@IBOutlet var stackView: UIStackView!
|
||||
|
||||
var ugcData: UgcData? {
|
||||
didSet {
|
||||
updateReviews()
|
||||
}
|
||||
}
|
||||
weak var delegate: PlacePageReviewsViewControllerDelegate?
|
||||
|
||||
lazy var myReviewViewController: MyReviewViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: MyReviewViewController.self)
|
||||
return vc
|
||||
} ()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
}
|
||||
|
||||
// MARK: private
|
||||
|
||||
private func updateReviews() {
|
||||
guard let ugcData = ugcData else { return }
|
||||
|
||||
if let myReview = ugcData.myReview {
|
||||
myReviewViewController.myReview = myReview
|
||||
addToStack(myReviewViewController)
|
||||
}
|
||||
|
||||
for i in 0..<3 {
|
||||
if i < ugcData.reviews.count {
|
||||
let review = ugcData.reviews[i]
|
||||
let vc = storyboard!.instantiateViewController(ofType: PlacePageReviewViewController.self)
|
||||
vc.review = review
|
||||
addToStack(vc)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if ugcData.reviews.count > 3 {
|
||||
createMoreReviewsButton()
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func onMoreReviewsButton(_ sender: UIButton) {
|
||||
delegate?.didPressMoreReviews()
|
||||
}
|
||||
|
||||
private func createMoreReviewsButton() {
|
||||
let button = UIButton()
|
||||
button.setTitle(L("placepage_more_reviews_button"), for: .normal)
|
||||
button.titleLabel?.font = UIFont.regular17()
|
||||
button.setTitleColor(UIColor.linkBlue(), for: .normal)
|
||||
button.heightAnchor.constraint(equalToConstant: 44).isActive = true
|
||||
stackView.addArrangedSubview(button)
|
||||
button.addTarget(self, action: #selector(onMoreReviewsButton), for: .touchUpInside)
|
||||
}
|
||||
|
||||
private func addToStack(_ viewController: UIViewController) {
|
||||
addChild(viewController)
|
||||
stackView.addArrangedSubview(viewController.view)
|
||||
viewController.didMove(toParent: self)
|
||||
}
|
||||
}
|
|
@ -1,30 +1,432 @@
|
|||
//
|
||||
// PlacePageViewController.swift
|
||||
// MAPS.ME
|
||||
//
|
||||
// Created by aleksey.belousov on 06/11/2019.
|
||||
// Copyright © 2019 MapsWithMe. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class PlacePageViewController: UIViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// MARK: - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
// Get the new view controller using segue.destination.
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
class PlacePageScrollView: UIScrollView {
|
||||
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
||||
return point.y > 0
|
||||
}
|
||||
}
|
||||
|
||||
@objc class PlacePageViewController: UIViewController {
|
||||
@IBOutlet var scrollView: UIScrollView!
|
||||
@IBOutlet var stackView: UIStackView!
|
||||
@IBOutlet var actionBarContainerView: UIView!
|
||||
|
||||
@objc var placePageData: PlacePageData!
|
||||
|
||||
var rootViewController: MapViewController {
|
||||
MapViewController.shared()
|
||||
}
|
||||
|
||||
lazy var previewViewController: PlacePagePreviewViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: PlacePagePreviewViewController.self)
|
||||
vc.placePagePreviewData = placePageData.previewData
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var catalogSingleItemViewController: CatalogSingleItemViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: CatalogSingleItemViewController.self)
|
||||
vc.view.isHidden = true
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var catalogGalleryViewController: CatalogGalleryViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: CatalogGalleryViewController.self)
|
||||
vc.view.isHidden = true
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var wikiDescriptionViewController: WikiDescriptionViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: WikiDescriptionViewController.self)
|
||||
vc.view.isHidden = true
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var bookmarkViewController: PlacePageBookmarkViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: PlacePageBookmarkViewController.self)
|
||||
vc.view.isHidden = true
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var infoViewController: PlacePageInfoViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: PlacePageInfoViewController.self)
|
||||
vc.placePageInfoData = placePageData.infoData
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var taxiViewController: TaxiViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: TaxiViewController.self)
|
||||
vc.taxiProvider = placePageData.taxiProvider
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var ratingSummaryViewController: RatingSummaryViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: RatingSummaryViewController.self)
|
||||
vc.view.isHidden = true
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var addReviewViewController: AddReviewViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: AddReviewViewController.self)
|
||||
vc.view.isHidden = true
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var reviewsViewController: PlacePageReviewsViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: PlacePageReviewsViewController.self)
|
||||
vc.view.isHidden = true
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var buttonsViewController: PlacePageButtonsViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: PlacePageButtonsViewController.self)
|
||||
vc.buttonsData = placePageData.buttonsData!
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var hotelPhotosViewController: HotelPhotosViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: HotelPhotosViewController.self)
|
||||
vc.view.isHidden = true
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var hotelDescriptionViewController: HotelDescriptionViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: HotelDescriptionViewController.self)
|
||||
vc.view.isHidden = true
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var hotelFacilitiesViewController: HotelFacilitiesViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: HotelFacilitiesViewController.self)
|
||||
vc.view.isHidden = true
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var hotelReviewsViewController: HotelReviewsViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: HotelReviewsViewController.self)
|
||||
vc.view.isHidden = true
|
||||
vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
lazy var actionBarViewController: ActionBarViewController = {
|
||||
let vc = storyboard!.instantiateViewController(ofType: ActionBarViewController.self)
|
||||
vc.placePageData = placePageData
|
||||
// vc.delegate = self
|
||||
return vc
|
||||
} ()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
addToStack(previewViewController)
|
||||
|
||||
if placePageData.isPromoCatalog {
|
||||
addToStack(catalogSingleItemViewController)
|
||||
addToStack(catalogGalleryViewController)
|
||||
placePageData.loadCatalogPromo { [weak self] in
|
||||
guard let self = self else { return }
|
||||
guard let catalogPromo = self.placePageData.catalogPromo else {
|
||||
if self.placePageData.wikiDescriptionHtml != nil {
|
||||
self.wikiDescriptionViewController.view.isHidden = false
|
||||
}
|
||||
return
|
||||
}
|
||||
if catalogPromo.promoItems.count == 1 {
|
||||
self.catalogSingleItemViewController.promoItem = catalogPromo.promoItems.first!
|
||||
self.catalogSingleItemViewController.view.isHidden = false
|
||||
} else {
|
||||
self.catalogGalleryViewController.promoData = catalogPromo
|
||||
self.catalogGalleryViewController.view.isHidden = false
|
||||
if self.placePageData.wikiDescriptionHtml != nil {
|
||||
self.wikiDescriptionViewController.view.isHidden = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addToStack(wikiDescriptionViewController)
|
||||
if let wikiDescriptionHtml = placePageData.wikiDescriptionHtml {
|
||||
wikiDescriptionViewController.descriptionHtml = wikiDescriptionHtml
|
||||
if placePageData.bookmarkData?.bookmarkDescription == nil && !placePageData.isPromoCatalog {
|
||||
wikiDescriptionViewController.view.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
addToStack(bookmarkViewController)
|
||||
if let bookmarkData = placePageData.bookmarkData {
|
||||
bookmarkViewController.bookmarkData = bookmarkData
|
||||
bookmarkViewController.view.isHidden = false
|
||||
}
|
||||
|
||||
addToStack(hotelPhotosViewController)
|
||||
addToStack(hotelDescriptionViewController)
|
||||
addToStack(hotelFacilitiesViewController)
|
||||
addToStack(hotelReviewsViewController)
|
||||
|
||||
addToStack(infoViewController)
|
||||
|
||||
if placePageData.taxiProvider != .none {
|
||||
addToStack(taxiViewController)
|
||||
}
|
||||
|
||||
if placePageData.previewData.showUgc {
|
||||
addToStack(ratingSummaryViewController)
|
||||
addToStack(addReviewViewController)
|
||||
addToStack(reviewsViewController)
|
||||
placePageData.loadUgc { [weak self] in
|
||||
if let self = self, let ugcData = self.placePageData.ugcData {
|
||||
self.previewViewController.updateUgc(ugcData)
|
||||
|
||||
if !ugcData.isTotalRatingEmpty {
|
||||
self.ratingSummaryViewController.ugcData = ugcData
|
||||
self.ratingSummaryViewController.view.isHidden = false
|
||||
}
|
||||
if ugcData.isUpdateEmpty {
|
||||
self.addReviewViewController.view.isHidden = false
|
||||
}
|
||||
if !ugcData.isEmpty {
|
||||
self.reviewsViewController.ugcData = ugcData
|
||||
self.reviewsViewController.view.isHidden = false
|
||||
}
|
||||
self.view.layoutIfNeeded()
|
||||
let previewFrame = self.scrollView.convert(self.previewViewController.view.bounds, from: self.previewViewController.view)
|
||||
UIView.animate(withDuration: kDefaultAnimationDuration) {
|
||||
self.scrollView.contentOffset = CGPoint(x: 0, y: previewFrame.maxY - self.scrollView.height)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if placePageData.buttonsData != nil {
|
||||
addToStack(buttonsViewController)
|
||||
}
|
||||
|
||||
placePageData.loadOnlineData { [weak self] in
|
||||
if let self = self, let bookingData = self.placePageData.hotelBooking {
|
||||
self.previewViewController.updateBooking(bookingData, rooms: self.placePageData.hotelRooms)
|
||||
self.stackView.layoutIfNeeded()
|
||||
UIView.animate(withDuration: kDefaultAnimationDuration) {
|
||||
if !bookingData.photos.isEmpty {
|
||||
self.hotelPhotosViewController.photos = bookingData.photos
|
||||
self.hotelPhotosViewController.view.isHidden = false
|
||||
}
|
||||
self.hotelDescriptionViewController.hotelDescription = bookingData.hotelDescription
|
||||
self.hotelDescriptionViewController.view.isHidden = false
|
||||
if bookingData.facilities.count > 0 {
|
||||
self.hotelFacilitiesViewController.facilities = bookingData.facilities
|
||||
self.hotelFacilitiesViewController.view.isHidden = false
|
||||
}
|
||||
if bookingData.reviews.count > 0 {
|
||||
self.hotelReviewsViewController.reviewCount = bookingData.scoreCount
|
||||
self.hotelReviewsViewController.totalScore = bookingData.score
|
||||
self.hotelReviewsViewController.reviews = bookingData.reviews
|
||||
self.hotelReviewsViewController.view.isHidden = false
|
||||
}
|
||||
self.stackView.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actionBarViewController.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
actionBarContainerView.addSubview(actionBarViewController.view)
|
||||
NSLayoutConstraint.activate([
|
||||
actionBarViewController.view.leadingAnchor.constraint(equalTo: actionBarContainerView.leadingAnchor),
|
||||
actionBarViewController.view.topAnchor.constraint(equalTo: actionBarContainerView.topAnchor),
|
||||
actionBarViewController.view.trailingAnchor.constraint(equalTo: actionBarContainerView.trailingAnchor),
|
||||
actionBarViewController.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
|
||||
])
|
||||
|
||||
MWMLocationManager.add(observer: self)
|
||||
if let lastLocation = MWMLocationManager.lastLocation() {
|
||||
onLocationUpdate(lastLocation)
|
||||
}
|
||||
if let lastHeading = MWMLocationManager.lastHeading() {
|
||||
onHeadingUpdate(lastHeading)
|
||||
}
|
||||
|
||||
let bgView = UIView()
|
||||
bgView.backgroundColor = UIColor.white()
|
||||
stackView.insertSubview(bgView, at: 0)
|
||||
bgView.alignToSuperview()
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
super.viewDidLayoutSubviews()
|
||||
scrollView.contentInset = UIEdgeInsets(top: scrollView.height, left: 0, bottom: 0, right: 0)
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
// let previewFrame = scrollView.convert(previewViewController.view.bounds, from: previewViewController.view)
|
||||
// UIView.animate(withDuration: kDefaultAnimationDuration) {
|
||||
// self.scrollView.contentOffset = CGPoint(x: 0, y: previewFrame.maxY - self.scrollView.height)
|
||||
// }
|
||||
}
|
||||
|
||||
// MARK: private
|
||||
|
||||
private func addToStack(_ viewController: UIViewController) {
|
||||
addChild(viewController)
|
||||
stackView.addArrangedSubview(viewController.view)
|
||||
viewController.didMove(toParent: self)
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: PlacePagePreviewViewControllerDelegate {
|
||||
func previewDidPressAddReview() {
|
||||
|
||||
}
|
||||
|
||||
func previewDidPressSimilarHotels() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: PlacePageInfoViewControllerDelegate {
|
||||
func didPressCall() {
|
||||
guard let phoneUrl = placePageData.infoData.phoneUrl,
|
||||
UIApplication.shared.canOpenURL(phoneUrl) else { return }
|
||||
UIApplication.shared.open(phoneUrl, options: [:])
|
||||
}
|
||||
|
||||
func didPressWebsite() {
|
||||
guard let website = placePageData.infoData.website,
|
||||
let url = URL(string: website) else { return }
|
||||
UIApplication.shared.open(url, options: [:])
|
||||
}
|
||||
|
||||
func didPressEmail() {
|
||||
|
||||
}
|
||||
|
||||
func didPressLocalAd() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: WikiDescriptionViewControllerDelegate {
|
||||
func didPressMore() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: TaxiViewControllerDelegate {
|
||||
func didPressOrder() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: AddReviewViewControllerDelegate {
|
||||
func didRate(_ rating: UgcSummaryRatingType) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: PlacePageReviewsViewControllerDelegate {
|
||||
func didPressMoreReviews() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: PlacePageButtonsViewControllerDelegate {
|
||||
func didPressHotels() {
|
||||
|
||||
}
|
||||
|
||||
func didPressAddPlace() {
|
||||
|
||||
}
|
||||
|
||||
func didPressEditPlace() {
|
||||
|
||||
}
|
||||
|
||||
func didPressAddBusiness() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: HotelPhotosViewControllerDelegate {
|
||||
func didSelectItemAt(_ index: Int) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: HotelDescriptionViewControllerDelegate {
|
||||
func hotelDescriptionDidPressMore() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: HotelFacilitiesViewControllerDelegate {
|
||||
func facilitiesDidPressMore() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: HotelReviewsViewControllerDelegate {
|
||||
func hotelReviewsDidPressMore() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: CatalogSingleItemViewControllerDelegate {
|
||||
func catalogPromoItemDidPressView() {
|
||||
|
||||
}
|
||||
|
||||
func catalogPromoItemDidPressMore() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: CatalogGalleryViewControllerDelegate {
|
||||
func promoGalleryDidPressMore() {
|
||||
|
||||
}
|
||||
|
||||
func promoGalleryDidSelectItemAtIndex(_ index: Int) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: PlacePageBookmarkViewControllerDelegate {
|
||||
func bookmarkDidPressEdit() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension PlacePageViewController: MWMLocationObserver {
|
||||
func onHeadingUpdate(_ heading: CLHeading) {
|
||||
if heading.trueHeading < 0 {
|
||||
return
|
||||
}
|
||||
|
||||
let rad = heading.trueHeading * Double.pi / 180
|
||||
previewViewController.updateHeading(CGFloat(rad))
|
||||
}
|
||||
|
||||
func onLocationUpdate(_ location: CLLocation) {
|
||||
let ppLocation = CLLocation(latitude: placePageData.locationCoordinate.latitude,
|
||||
longitude: placePageData.locationCoordinate.longitude)
|
||||
let distance = location.distance(from: ppLocation)
|
||||
let distanceFormatter = MKDistanceFormatter()
|
||||
distanceFormatter.unitStyle = .abbreviated
|
||||
let formattedDistance = distanceFormatter.string(fromDistance: distance)
|
||||
previewViewController.updateDistance(formattedDistance)
|
||||
}
|
||||
|
||||
func onLocationError(_ locationError: MWMLocationStatus) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
56
iphone/Maps/UI/PlacePage/RatingSummaryViewController.swift
Normal file
56
iphone/Maps/UI/PlacePage/RatingSummaryViewController.swift
Normal file
|
@ -0,0 +1,56 @@
|
|||
class RatingSummaryViewController: UIViewController {
|
||||
@IBOutlet var titleLabel: UILabel!
|
||||
@IBOutlet var countLabel: UILabel!
|
||||
@IBOutlet var ratingSummaryView: RatingSummaryView! {
|
||||
didSet {
|
||||
ratingSummaryView.horribleColor = UIColor.ratingRed()
|
||||
ratingSummaryView.badColor = UIColor.ratingOrange()
|
||||
ratingSummaryView.normalColor = UIColor.ratingYellow()
|
||||
ratingSummaryView.goodColor = UIColor.ratingLightGreen()
|
||||
ratingSummaryView.excellentColor = UIColor.ratingGreen()
|
||||
ratingSummaryView.textFont = UIFont.bold28()
|
||||
ratingSummaryView.textSize = 28
|
||||
}
|
||||
}
|
||||
@IBOutlet var ratingViews: [UIView]!
|
||||
@IBOutlet var ratingLabels: [UILabel]!
|
||||
@IBOutlet var starViews: [StarRatingView]! {
|
||||
didSet {
|
||||
starViews.forEach {
|
||||
$0.activeColor = UIColor.ratingYellow()
|
||||
$0.inactiveColor = UIColor.blackDividers()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ugcData: UgcData? {
|
||||
didSet {
|
||||
updateRating()
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
updateRating()
|
||||
}
|
||||
|
||||
private func updateRating() {
|
||||
guard let ugcData = ugcData else { return }
|
||||
|
||||
ratingSummaryView.value = ugcData.summaryRating!.ratingString
|
||||
let r = ugcData.summaryRating!.ratingType.rawValue
|
||||
ratingSummaryView.type = MWMRatingSummaryViewValueType(rawValue: UInt(r))!
|
||||
|
||||
countLabel.text = String(format:L("placepage_summary_rating_description"), ugcData.ratingsCount)
|
||||
|
||||
for i in 0..<3 {
|
||||
if ugcData.starRatings.count > i {
|
||||
let starRating = ugcData.starRatings[i]
|
||||
ratingLabels[i].text = L(starRating.title)
|
||||
starViews[i].rating = Int(round(starRating.value))
|
||||
} else {
|
||||
ratingViews[i].isHidden = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
38
iphone/Maps/UI/PlacePage/TaxiViewController.swift
Normal file
38
iphone/Maps/UI/PlacePage/TaxiViewController.swift
Normal file
|
@ -0,0 +1,38 @@
|
|||
protocol TaxiViewControllerDelegate: AnyObject {
|
||||
func didPressOrder()
|
||||
}
|
||||
|
||||
class TaxiViewController: UIViewController {
|
||||
@IBOutlet var taxiImageView: UIImageView!
|
||||
@IBOutlet var taxiNameLabel: UILabel!
|
||||
|
||||
var taxiProvider: PlacePageTaxiProvider = .none
|
||||
weak var delegate: TaxiViewControllerDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
switch taxiProvider {
|
||||
case .none:
|
||||
assertionFailure()
|
||||
case .uber:
|
||||
taxiImageView.image = UIImage(named: "icTaxiUber")
|
||||
taxiNameLabel.text = L("uber")
|
||||
case .yandex:
|
||||
taxiImageView.image = UIImage(named: "ic_taxi_logo_yandex")
|
||||
taxiNameLabel.text = L("yandex_taxi_title")
|
||||
case .maxim:
|
||||
taxiImageView.image = UIImage(named: "ic_taxi_logo_maksim")
|
||||
taxiNameLabel.text = L("maxim_taxi_title")
|
||||
case .rutaxi:
|
||||
taxiImageView.image = UIImage(named: "ic_taxi_logo_vezet")
|
||||
taxiNameLabel.text = L("vezet_taxi")
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func onOrder(_ sender: UIButton) {
|
||||
delegate?.didPressOrder()
|
||||
}
|
||||
}
|
58
iphone/Maps/UI/PlacePage/Views/ExpandableLabel.swift
Normal file
58
iphone/Maps/UI/PlacePage/Views/ExpandableLabel.swift
Normal file
|
@ -0,0 +1,58 @@
|
|||
class ExpandableLabel: UIView {
|
||||
private var stackView = UIStackView()
|
||||
var textLabel = UILabel()
|
||||
var expandButton = UIButton()
|
||||
var expanded = false
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
stackView.axis = .vertical
|
||||
stackView.alignment = .leading
|
||||
textLabel.numberOfLines = 2
|
||||
textLabel.contentMode = .topLeft
|
||||
expandButton.clipsToBounds = true
|
||||
expandButton.addTarget(self, action: #selector(onExpand(_:)), for: .touchUpInside)
|
||||
addSubview(stackView)
|
||||
|
||||
stackView.addArrangedSubview(textLabel)
|
||||
stackView.addArrangedSubview(expandButton)
|
||||
NSLayoutConstraint.activate([
|
||||
stackView.leftAnchor.constraint(equalTo: leftAnchor),
|
||||
stackView.topAnchor.constraint(equalTo: topAnchor),
|
||||
stackView.rightAnchor.constraint(equalTo: rightAnchor),
|
||||
stackView.bottomAnchor.constraint(equalTo: bottomAnchor)
|
||||
])
|
||||
}
|
||||
|
||||
@objc func onExpand(_ sender: UIButton) {
|
||||
UIView.animate(withDuration: kDefaultAnimationDuration) {
|
||||
self.textLabel.numberOfLines = 0
|
||||
self.expandButton.isHidden = true
|
||||
self.stackView.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
guard let s = textLabel.text as NSString? else { return }
|
||||
let textRect = s.boundingRect(with: size,
|
||||
options: .usesLineFragmentOrigin,
|
||||
attributes: [.font: textLabel.font!],
|
||||
context: nil)
|
||||
let lineHeight = textLabel.font.lineHeight
|
||||
if Int(lineHeight * CGFloat(textLabel.numberOfLines)) >= Int(textRect.height) {
|
||||
expandButton.isHidden = true
|
||||
}
|
||||
}
|
||||
}
|
113
iphone/Maps/UI/PlacePage/Views/StarRatingView.swift
Normal file
113
iphone/Maps/UI/PlacePage/Views/StarRatingView.swift
Normal file
|
@ -0,0 +1,113 @@
|
|||
fileprivate class StarView: UIView {
|
||||
private static let points: [CGPoint] = [
|
||||
CGPoint(x: 49.5, y: 0.0),
|
||||
CGPoint(x: 60.5, y: 35.0),
|
||||
CGPoint(x: 99.0, y: 35.0),
|
||||
CGPoint(x: 67.5, y: 58.0),
|
||||
CGPoint(x: 78.5, y: 92.0),
|
||||
CGPoint(x: 49.5, y: 71.0),
|
||||
CGPoint(x: 20.5, y: 92.0),
|
||||
CGPoint(x: 31.5, y: 58.0),
|
||||
CGPoint(x: 0.0, y: 35.0),
|
||||
CGPoint(x: 38.5, y: 35.0),
|
||||
]
|
||||
|
||||
private var path: UIBezierPath = {
|
||||
let path = UIBezierPath()
|
||||
path.move(to: StarView.points[0])
|
||||
StarView.points.suffix(from: 1).forEach {
|
||||
path.addLine(to: $0)
|
||||
}
|
||||
path.close()
|
||||
return path
|
||||
} ()
|
||||
|
||||
private var starLayer: CAShapeLayer {
|
||||
layer as! CAShapeLayer
|
||||
}
|
||||
|
||||
var color: UIColor = UIColor.orange {
|
||||
didSet {
|
||||
starLayer.fillColor = color.cgColor
|
||||
}
|
||||
}
|
||||
|
||||
override class var layerClass: AnyClass {
|
||||
CAShapeLayer.self
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
starLayer.fillRule = .evenOdd
|
||||
starLayer.fillColor = color.cgColor
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
let offset: CGFloat = 0.05
|
||||
let sx = width / 100 * CGFloat(1.0 - offset * 2)
|
||||
let sy = height / 100 * CGFloat(1.0 - offset * 2)
|
||||
|
||||
guard let newPath = path.copy() as? UIBezierPath else { return }
|
||||
let scale = CGAffineTransform(scaleX: sx, y: sy)
|
||||
let translate = CGAffineTransform(translationX: width * offset, y: height * offset)
|
||||
newPath.apply(scale.concatenating(translate))
|
||||
let boxPath = UIBezierPath(rect: bounds)
|
||||
boxPath.append(newPath)
|
||||
boxPath.usesEvenOddFillRule = true
|
||||
starLayer.path = boxPath.cgPath
|
||||
}
|
||||
}
|
||||
|
||||
class StarRatingView: UIView {
|
||||
private var starViews: [StarView] = []
|
||||
|
||||
var rating: Int = 3
|
||||
var activeColor: UIColor = UIColor.orange
|
||||
var inactiveColor: UIColor = UIColor.lightGray
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
for i in 0..<starViews.count {
|
||||
let sv = starViews[i]
|
||||
sv.color = i >= rating ? inactiveColor : activeColor
|
||||
sv.frame = CGRect(x: 18 * i, y: 0, width: 15, height: 15)
|
||||
sv.layer.cornerRadius = 3
|
||||
}
|
||||
}
|
||||
|
||||
override var intrinsicContentSize: CGSize {
|
||||
return CGSize(width: 18 * 5 - 3, height: 15)
|
||||
}
|
||||
|
||||
private func commonInit() {
|
||||
for _ in 0..<5 {
|
||||
let sv = StarView()
|
||||
sv.color = inactiveColor
|
||||
sv.clipsToBounds = true
|
||||
starViews.append(sv)
|
||||
addSubview(sv)
|
||||
}
|
||||
}
|
||||
}
|
59
iphone/Maps/UI/PlacePage/WikiDescriptionViewController.swift
Normal file
59
iphone/Maps/UI/PlacePage/WikiDescriptionViewController.swift
Normal file
|
@ -0,0 +1,59 @@
|
|||
protocol WikiDescriptionViewControllerDelegate: AnyObject {
|
||||
func didPressMore()
|
||||
}
|
||||
|
||||
class WikiDescriptionViewController: UIViewController {
|
||||
@IBOutlet var descriptionTextView: UITextView!
|
||||
@IBOutlet var moreButton: UIButton!
|
||||
|
||||
var descriptionHtml: String? {
|
||||
didSet{
|
||||
updateDescription()
|
||||
}
|
||||
}
|
||||
weak var delegate: WikiDescriptionViewControllerDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
descriptionTextView.textContainerInset = .zero
|
||||
updateDescription()
|
||||
}
|
||||
|
||||
private func updateDescription() {
|
||||
guard let descriptionHtml = descriptionHtml else { return }
|
||||
|
||||
DispatchQueue.global().async {
|
||||
let font = UIFont.regular14()
|
||||
let color = UIColor.blackPrimaryText()
|
||||
let paragraphStyle = NSMutableParagraphStyle()
|
||||
paragraphStyle.lineSpacing = 4
|
||||
|
||||
let attributedString: NSAttributedString
|
||||
if let str = NSMutableAttributedString(htmlString: descriptionHtml, baseFont: font, paragraphStyle: paragraphStyle) {
|
||||
str.addAttribute(NSAttributedString.Key.foregroundColor,
|
||||
value: color,
|
||||
range: NSRange(location: 0, length: str.length))
|
||||
attributedString = str;
|
||||
} else {
|
||||
attributedString = NSAttributedString(string: descriptionHtml,
|
||||
attributes: [NSAttributedString.Key.font : font,
|
||||
NSAttributedString.Key.foregroundColor: color,
|
||||
NSAttributedString.Key.paragraphStyle: paragraphStyle])
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
if attributedString.length > 500 {
|
||||
self.descriptionTextView.attributedText = attributedString.attributedSubstring(from: NSRange(location: 0,
|
||||
length: 500))
|
||||
} else {
|
||||
self.descriptionTextView.attributedText = attributedString
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func onMore(_ sender: UIButton) {
|
||||
delegate?.didPressMore()
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ enum Storyboard: Int {
|
|||
case categorySettings
|
||||
case drivingOptions
|
||||
case carPlay
|
||||
case placePage
|
||||
}
|
||||
|
||||
extension UIStoryboard {
|
||||
|
@ -28,6 +29,7 @@ extension UIStoryboard {
|
|||
case .categorySettings: name = "CategorySettings"
|
||||
case .drivingOptions: name = "DrivingOptions"
|
||||
case .carPlay: name = "CarPlayStoryboard"
|
||||
case .placePage: name = "PlacePage"
|
||||
}
|
||||
return UIStoryboard(name: name, bundle: nil)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue