[MAPSME-4971] [ios] Added Cian support to place page.

This commit is contained in:
Ilya Grechuhin 2017-07-24 17:01:28 +03:00 committed by Roman Kuznetsov
parent 3847fc0a73
commit da7362e943
10 changed files with 686 additions and 10 deletions

View file

@ -275,6 +275,21 @@
3476B8E01BFDD33A00874594 /* tts-how-to-set-up-voice-img in Resources */ = {isa = PBXBuildFile; fileRef = 3476B8DF1BFDD33A00874594 /* tts-how-to-set-up-voice-img */; };
3476B8E11BFDD33A00874594 /* tts-how-to-set-up-voice-img in Resources */ = {isa = PBXBuildFile; fileRef = 3476B8DF1BFDD33A00874594 /* tts-how-to-set-up-voice-img */; };
347A4C5E1C4E76C9006BA66E /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 340DC82B1C4E72C700EAA2CC /* liboauthcpp.a */; };
347E1A881F1F5DD7002BF7A8 /* CianItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347E1A871F1F5DD7002BF7A8 /* CianItemModel.swift */; };
347E1A891F1F5DD7002BF7A8 /* CianItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347E1A871F1F5DD7002BF7A8 /* CianItemModel.swift */; };
347E1A8A1F1F5DD7002BF7A8 /* CianItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347E1A871F1F5DD7002BF7A8 /* CianItemModel.swift */; };
347E1A8D1F1F71F1002BF7A8 /* PPCianCarouselCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347E1A8C1F1F71F1002BF7A8 /* PPCianCarouselCell.swift */; };
347E1A8E1F1F71F1002BF7A8 /* PPCianCarouselCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347E1A8C1F1F71F1002BF7A8 /* PPCianCarouselCell.swift */; };
347E1A8F1F1F71F1002BF7A8 /* PPCianCarouselCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347E1A8C1F1F71F1002BF7A8 /* PPCianCarouselCell.swift */; };
347E1A911F1F72AD002BF7A8 /* PPCianCarouselCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 347E1A901F1F72AD002BF7A8 /* PPCianCarouselCell.xib */; };
347E1A921F1F72AD002BF7A8 /* PPCianCarouselCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 347E1A901F1F72AD002BF7A8 /* PPCianCarouselCell.xib */; };
347E1A931F1F72AD002BF7A8 /* PPCianCarouselCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 347E1A901F1F72AD002BF7A8 /* PPCianCarouselCell.xib */; };
347E1A961F1F7404002BF7A8 /* CianElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347E1A941F1F7404002BF7A8 /* CianElement.swift */; };
347E1A971F1F7404002BF7A8 /* CianElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347E1A941F1F7404002BF7A8 /* CianElement.swift */; };
347E1A981F1F7404002BF7A8 /* CianElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 347E1A941F1F7404002BF7A8 /* CianElement.swift */; };
347E1A991F1F7404002BF7A8 /* CianElement.xib in Resources */ = {isa = PBXBuildFile; fileRef = 347E1A951F1F7404002BF7A8 /* CianElement.xib */; };
347E1A9A1F1F7404002BF7A8 /* CianElement.xib in Resources */ = {isa = PBXBuildFile; fileRef = 347E1A951F1F7404002BF7A8 /* CianElement.xib */; };
347E1A9B1F1F7404002BF7A8 /* CianElement.xib in Resources */ = {isa = PBXBuildFile; fileRef = 347E1A951F1F7404002BF7A8 /* CianElement.xib */; };
34845DAE1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DAD1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift */; };
34845DAF1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DAD1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift */; };
34845DB01E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34845DAD1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift */; };
@ -1811,6 +1826,11 @@
347526FB1DC0B00F00918CF5 /* common-release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "common-release.xcconfig"; path = "../../xcode/common-release.xcconfig"; sourceTree = "<group>"; };
3476B8D51BFDD30B00874594 /* tts-how-to-set-up-voice.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = "tts-how-to-set-up-voice.html"; path = "../../data/tts-how-to-set-up-voice.html"; sourceTree = "<group>"; };
3476B8DF1BFDD33A00874594 /* tts-how-to-set-up-voice-img */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "tts-how-to-set-up-voice-img"; path = "../../data/tts-how-to-set-up-voice-img"; sourceTree = "<group>"; };
347E1A871F1F5DD7002BF7A8 /* CianItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CianItemModel.swift; sourceTree = "<group>"; };
347E1A8C1F1F71F1002BF7A8 /* PPCianCarouselCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PPCianCarouselCell.swift; sourceTree = "<group>"; };
347E1A901F1F72AD002BF7A8 /* PPCianCarouselCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PPCianCarouselCell.xib; sourceTree = "<group>"; };
347E1A941F1F7404002BF7A8 /* CianElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CianElement.swift; sourceTree = "<group>"; };
347E1A951F1F7404002BF7A8 /* CianElement.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CianElement.xib; sourceTree = "<group>"; };
348320CC1B6A2C52007EC039 /* MWMNavigationViewProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMNavigationViewProtocol.h; sourceTree = "<group>"; };
34845DAD1E1649F6003D55B9 /* DownloaderNoResultsEmbedViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloaderNoResultsEmbedViewController.swift; sourceTree = "<group>"; };
34845DB11E165E24003D55B9 /* SearchNoResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchNoResultsViewController.swift; sourceTree = "<group>"; };
@ -3199,6 +3219,18 @@
path = Components;
sourceTree = "<group>";
};
347E1A861F1F5DD7002BF7A8 /* Cian */ = {
isa = PBXGroup;
children = (
347E1A871F1F5DD7002BF7A8 /* CianItemModel.swift */,
347E1A8C1F1F71F1002BF7A8 /* PPCianCarouselCell.swift */,
347E1A901F1F72AD002BF7A8 /* PPCianCarouselCell.xib */,
347E1A941F1F7404002BF7A8 /* CianElement.swift */,
347E1A951F1F7404002BF7A8 /* CianElement.xib */,
);
path = Cian;
sourceTree = "<group>";
};
3486B5041E27A4B50069C126 /* Notifications */ = {
isa = PBXGroup;
children = (
@ -4074,6 +4106,7 @@
F6E2FCA81E097B9F0083EBEC /* Content */ = {
isa = PBXGroup;
children = (
347E1A861F1F5DD7002BF7A8 /* Cian */,
34EE259B1EFA681000F870AB /* ViatorCells */,
F68BDF181EF80DCC0009BB81 /* UGC */,
346DB81C1E5C4F6700E3123E /* Gallery */,
@ -4761,6 +4794,7 @@
F6E2FF201E097BA00083EBEC /* MWMSearchTabbedViewController.xib in Resources */,
F6E2FF291E097BA00083EBEC /* MWMSearchTabButtonsView.xib in Resources */,
F6E2FF411E097BA00083EBEC /* MWMSearchTableViewController.xib in Resources */,
347E1A911F1F72AD002BF7A8 /* PPCianCarouselCell.xib in Resources */,
F6E2FEED1E097BA00083EBEC /* MWMSearchView.xib in Resources */,
3490D2E21CE9DD2500D0B838 /* MWMSideButtonsView.xib in Resources */,
346DB82A1E5C4F6700E3123E /* GalleryCell.xib in Resources */,
@ -4785,6 +4819,7 @@
4A23D15F1B8B4DD700D4EB6F /* resources-xxhdpi_clear in Resources */,
4A7D89C81B2EBF3B00AC843E /* resources-xxhdpi_dark in Resources */,
340E1EF41E2F614400CE49BF /* SearchFilters.storyboard in Resources */,
347E1A991F1F7404002BF7A8 /* CianElement.xib in Resources */,
F682249E1E5B105900BC1C18 /* PPHotelDescriptionCell.xib in Resources */,
340E1EF71E2F614400CE49BF /* Settings.storyboard in Resources */,
5605022F1B6211E100169CAD /* sound-strings in Resources */,
@ -4939,6 +4974,7 @@
F6E2FF421E097BA00083EBEC /* MWMSearchTableViewController.xib in Resources */,
F6E2FEEE1E097BA00083EBEC /* MWMSearchView.xib in Resources */,
3490D2E31CE9DD2500D0B838 /* MWMSideButtonsView.xib in Resources */,
347E1A921F1F72AD002BF7A8 /* PPCianCarouselCell.xib in Resources */,
346DB82B1E5C4F6700E3123E /* GalleryCell.xib in Resources */,
F6E2FE2E1E097BA00083EBEC /* MWMStreetEditorEditTableViewCell.xib in Resources */,
F68FCB8D1DA7BD20007CC7D7 /* RoutePreviewTaxiCell.xib in Resources */,
@ -4963,6 +4999,7 @@
6741A94D1BF340DE002C974C /* resources-xxhdpi_clear in Resources */,
6741A9551BF340DE002C974C /* resources-xxhdpi_dark in Resources */,
340E1EF51E2F614400CE49BF /* SearchFilters.storyboard in Resources */,
347E1A9A1F1F7404002BF7A8 /* CianElement.xib in Resources */,
F682249F1E5B105900BC1C18 /* PPHotelDescriptionCell.xib in Resources */,
340E1EF81E2F614400CE49BF /* Settings.storyboard in Resources */,
6741A9421BF340DE002C974C /* sound-strings in Resources */,
@ -5117,6 +5154,7 @@
F6E2FF221E097BA00083EBEC /* MWMSearchTabbedViewController.xib in Resources */,
F6E2FF2B1E097BA00083EBEC /* MWMSearchTabButtonsView.xib in Resources */,
F6E2FF431E097BA00083EBEC /* MWMSearchTableViewController.xib in Resources */,
347E1A931F1F72AD002BF7A8 /* PPCianCarouselCell.xib in Resources */,
F6E2FEEF1E097BA00083EBEC /* MWMSearchView.xib in Resources */,
849CF6471DE842290024A8A5 /* MWMSideButtonsView.xib in Resources */,
346DB82C1E5C4F6700E3123E /* GalleryCell.xib in Resources */,
@ -5141,6 +5179,7 @@
849CF61A1DE842290024A8A5 /* resources-xhdpi_dark in Resources */,
849CF5FC1DE842290024A8A5 /* resources-xxhdpi_clear in Resources */,
849CF6061DE842290024A8A5 /* resources-xxhdpi_dark in Resources */,
347E1A9B1F1F7404002BF7A8 /* CianElement.xib in Resources */,
340E1EF61E2F614400CE49BF /* SearchFilters.storyboard in Resources */,
340E1EF91E2F614400CE49BF /* Settings.storyboard in Resources */,
849CF5EA1DE842290024A8A5 /* sound-strings in Resources */,
@ -5296,6 +5335,7 @@
F6E2FF5C1E097BA00083EBEC /* MWMRecentTrackSettingsController.mm in Sources */,
343064401E9FDC7300DC7665 /* SearchIndex.swift in Sources */,
F6664BF91E6459CB00E703C2 /* PPFacilityCell.swift in Sources */,
347E1A8D1F1F71F1002BF7A8 /* PPCianCarouselCell.swift in Sources */,
F6E2FDE81E097BA00083EBEC /* MWMObjectsCategorySelectorController.mm in Sources */,
F64F199D1AB81A00006EAF7E /* MWMDefaultAlert.mm in Sources */,
F6150E431EFA52E9000B955D /* UGCSpecificReviewCell.swift in Sources */,
@ -5322,6 +5362,7 @@
34F4073D1E9E1AFF00E57AC0 /* MPNativeAd+MWM.mm in Sources */,
F69018B81E9E601400B3C10B /* MWMAutoupdateController.mm in Sources */,
560634F21B78806100F3D670 /* MWMTextToSpeech.mm in Sources */,
347E1A961F1F7404002BF7A8 /* CianElement.swift in Sources */,
F6E2FECF1E097BA00083EBEC /* MWMSearchFilterViewController.mm in Sources */,
34D4FA661E265749003F53EF /* WhatsNewController.swift in Sources */,
34D3B01A1E389D05004100F9 /* MWMButtonCell.mm in Sources */,
@ -5389,6 +5430,7 @@
34943BB61E26222300B14F84 /* WelcomeProtocol.swift in Sources */,
F6E2FD5E1E097BA00083EBEC /* MWMMapDownloaderLargeCountryTableViewCell.mm in Sources */,
F6558DA11E642CC0002203AE /* MWMFacilitiesController.mm in Sources */,
347E1A881F1F5DD7002BF7A8 /* CianItemModel.swift in Sources */,
F6E2FF471E097BA00083EBEC /* SettingsTableViewSelectableCell.swift in Sources */,
349D1ACE1E2E325B004A2006 /* MWMBottomMenuCollectionViewCell.mm in Sources */,
F6E2FF261E097BA00083EBEC /* MWMSearchTabButtonsView.mm in Sources */,
@ -5610,6 +5652,7 @@
F6E2FF5D1E097BA00083EBEC /* MWMRecentTrackSettingsController.mm in Sources */,
343064411E9FDC7300DC7665 /* SearchIndex.swift in Sources */,
F6664BFA1E6459CB00E703C2 /* PPFacilityCell.swift in Sources */,
347E1A8E1F1F71F1002BF7A8 /* PPCianCarouselCell.swift in Sources */,
F6E2FDE91E097BA00083EBEC /* MWMObjectsCategorySelectorController.mm in Sources */,
6741A9A81BF340DE002C974C /* MWMFacebookAlert.mm in Sources */,
F6150E441EFA52E9000B955D /* UGCSpecificReviewCell.swift in Sources */,
@ -5636,6 +5679,7 @@
34F4073E1E9E1AFF00E57AC0 /* MPNativeAd+MWM.mm in Sources */,
6741A9B61BF340DE002C974C /* MWMTextToSpeech.mm in Sources */,
F6E2FED01E097BA00083EBEC /* MWMSearchFilterViewController.mm in Sources */,
347E1A971F1F7404002BF7A8 /* CianElement.swift in Sources */,
34D4FA671E265749003F53EF /* WhatsNewController.swift in Sources */,
34D3B01B1E389D05004100F9 /* MWMButtonCell.mm in Sources */,
3486B5161E27AD3B0069C126 /* Framework.cpp in Sources */,
@ -5703,6 +5747,7 @@
F6E2FF271E097BA00083EBEC /* MWMSearchTabButtonsView.mm in Sources */,
F6558DA21E642CC0002203AE /* MWMFacilitiesController.mm in Sources */,
349D1ACF1E2E325B004A2006 /* MWMBottomMenuCollectionViewCell.mm in Sources */,
347E1A891F1F5DD7002BF7A8 /* CianItemModel.swift in Sources */,
F6E2FF451E097BA00083EBEC /* SettingsTableViewLinkCell.swift in Sources */,
34C9BD0A1C6DBCDA000DC38D /* MWMNavigationController.mm in Sources */,
F6E2FE311E097BA00083EBEC /* MWMStreetEditorViewController.mm in Sources */,
@ -5924,6 +5969,7 @@
F6E2FF5E1E097BA00083EBEC /* MWMRecentTrackSettingsController.mm in Sources */,
343064421E9FDC7300DC7665 /* SearchIndex.swift in Sources */,
F6664BFB1E6459CB00E703C2 /* PPFacilityCell.swift in Sources */,
347E1A8F1F1F71F1002BF7A8 /* PPCianCarouselCell.swift in Sources */,
F6E2FDEA1E097BA00083EBEC /* MWMObjectsCategorySelectorController.mm in Sources */,
849CF68A1DE842290024A8A5 /* MWMDefaultAlert.mm in Sources */,
F6150E451EFA52E9000B955D /* UGCSpecificReviewCell.swift in Sources */,
@ -5950,6 +5996,7 @@
34F4073F1E9E1AFF00E57AC0 /* MPNativeAd+MWM.mm in Sources */,
849CF69D1DE842290024A8A5 /* MWMInputLoginValidator.mm in Sources */,
F6E2FED11E097BA00083EBEC /* MWMSearchFilterViewController.mm in Sources */,
347E1A981F1F7404002BF7A8 /* CianElement.swift in Sources */,
34D4FA681E265749003F53EF /* WhatsNewController.swift in Sources */,
34D3B01C1E389D05004100F9 /* MWMButtonCell.mm in Sources */,
3486B5171E27AD3B0069C126 /* Framework.cpp in Sources */,
@ -6017,6 +6064,7 @@
34943BB81E26222300B14F84 /* WelcomeProtocol.swift in Sources */,
F6E2FD601E097BA00083EBEC /* MWMMapDownloaderLargeCountryTableViewCell.mm in Sources */,
F6558DA31E642CC0002203AE /* MWMFacilitiesController.mm in Sources */,
347E1A8A1F1F5DD7002BF7A8 /* CianItemModel.swift in Sources */,
F6E2FF491E097BA00083EBEC /* SettingsTableViewSelectableCell.swift in Sources */,
349D1AD01E2E325B004A2006 /* MWMBottomMenuCollectionViewCell.mm in Sources */,
F6E2FF281E097BA00083EBEC /* MWMSearchTabButtonsView.mm in Sources */,

View file

@ -10,6 +10,7 @@
@class MWMPlacePageData;
@class MWMUGCReviewVM;
@class MWMCianItemModel;
namespace ugc
{
@ -72,6 +73,7 @@ enum class HotelReviewsRow
enum class SpecialProject
{
Viator,
Cian
};
enum class MetainfoRows
@ -120,20 +122,22 @@ enum class OpeningHours
};
using NewSectionsAreReady = void (^)(NSRange const & range, MWMPlacePageData * data, BOOL isSection);
using BannerIsReady = void (^)();
using CianIsReady = void (^)(NSArray<MWMCianItemModel *> * items);
} // namespace place_page
@class MWMGalleryItemModel;
@class MWMViatorItemModel;
@class MWMCianItemModel;
@protocol MWMBanner;
/// ViewModel for place page.
@interface MWMPlacePageData : NSObject<MWMActionBarSharedData>
@property(copy, nonatomic) place_page::NewSectionsAreReady sectionsAreReadyCallback;
@property(copy, nonatomic) place_page::BannerIsReady bannerIsReadyCallback;
@property(copy, nonatomic) MWMVoidBlock bannerIsReadyCallback;
@property(copy, nonatomic) place_page::CianIsReady cianIsReadyCallback;
// ready callback will be called from main queue.
- (instancetype)initWithPlacePageInfo:(place_page::Info const &)info;
@ -172,6 +176,9 @@ using BannerIsReady = void (^)();
- (void)fillOnlineViatorSection;
- (NSArray<MWMViatorItemModel *> *)viatorItems;
// CIAN
- (void)fillOnlineCianSection;
// UGC
- (MWMUGCReviewVM *)reviewViewModel;
- (std::vector<ugc::Review> const &)ugcReviews;
@ -223,6 +230,7 @@ using BannerIsReady = void (^)();
- (BOOL)isBooking;
- (BOOL)isOpentable;
- (BOOL)isViator;
- (BOOL)isCian;
- (BOOL)isBookingSearch;
- (BOOL)isHTMLDescription;
- (BOOL)isMyPosition;

View file

@ -57,6 +57,8 @@ using namespace place_page;
std::vector<UGCRow> m_ugcRows;
booking::HotelInfo m_hotelInfo;
uint64_t m_cianRequestId;
}
- (instancetype)initWithPlacePageInfo:(Info const &)info
@ -135,8 +137,9 @@ using namespace place_page;
NSAssert(!m_previewRows.empty(), @"Preview row's can't be empty!");
m_previewRows.push_back(PreviewRows::Space);
if (network_policy::CanUseNetwork() && ![MWMSettings adForbidden] && m_info.HasBanner() &&
![self isViator])
![self isViator] && ![self isCian])
{
__weak auto wSelf = self;
[[MWMBannersCache cache]
@ -284,6 +287,59 @@ using namespace place_page;
});
}
- (void)fillOnlineCianSection
{
if (![self isCian])
return;
[self insertSpecialProjectsSectionWithProject:SpecialProject::Cian];
if (Platform::ConnectionStatus() == Platform::EConnectionType::CONNECTION_NONE)
return;
network_policy::CallPartnersApi([self](platform::NetworkPolicy const & canUseNetwork) {
auto api = GetFramework().GetCianApi(canUseNetwork);
if (!api)
return;
m_cianRequestId = api->GetRentNearby([self latLon],
[self](std::vector<cian::RentPlace> const & places, uint64_t const requestId)
{
if (self->m_cianRequestId != requestId)
return;
NSMutableArray<MWMCianItemModel *> * items = [@[] mutableCopy];
for (auto const & p : places)
{
auto const & offers = p.m_offers;
NSCAssert(!offers.empty(), @"Cian misses offers for place.");
if (offers.empty())
continue;
auto const & firstOffer = offers.front();
auto pageURL = [NSURL URLWithString:@(firstOffer.m_url.c_str())];
if (!pageURL)
continue;
auto item = [[MWMCianItemModel alloc] initWithRoomsCount:firstOffer.m_roomsCount
priceRur:firstOffer.m_priceRur
pageURL:pageURL
address:@(firstOffer.m_address.c_str())];
[items addObject:item];
}
dispatch_async(dispatch_get_main_queue(), [items, self] {
self.cianIsReadyCallback(items);
});
},
[self](int code, uint64_t const requestId)
{
if (self->m_cianRequestId != requestId)
return;
dispatch_async(dispatch_get_main_queue(), [self] {
self.cianIsReadyCallback(@[]);
});
});
});
}
- (void)fillOnlineBookingSections
{
if (!self.isBooking)
@ -716,6 +772,7 @@ using namespace place_page;
- (BOOL)isBooking { return m_info.GetSponsoredType() == SponsoredType::Booking; }
- (BOOL)isOpentable { return m_info.GetSponsoredType() == SponsoredType::Opentable; }
- (BOOL)isViator { return m_info.GetSponsoredType() == SponsoredType::Viator; }
- (BOOL)isCian { return m_info.GetSponsoredType() == SponsoredType::Cian; }
- (BOOL)isBookingSearch { return !m_info.GetBookingSearchUrl().empty(); }
- (BOOL)isMyPosition { return m_info.IsMyPosition(); }
- (BOOL)isHTMLDescription { return strings::IsHTML(m_info.GetBookmarkData().GetDescription()); }

View file

@ -264,7 +264,13 @@ void logPointEvent(MWMRoutePoint * pt, NSString * eventType)
- (void)shouldDestroyLayout { self.layout = nil; }
- (void)shouldClose { GetFramework().DeactivateMapSelection(true); }
- (BOOL)isExpandedOnShow { return self.data.isViator; }
- (BOOL)isExpandedOnShow
{
auto data = self.data;
return data.isViator || data.isCian;
}
- (void)onExpanded
{
if (self.isSponsoredOpenLogged)

View file

@ -0,0 +1,174 @@
final class CianElement : UICollectionViewCell {
enum State {
case pending(onButtonAction: () -> Void)
case offer(model: CianItemModel?, onButtonAction: (CianItemModel?) -> Void)
case error(onButtonAction: () -> Void)
}
@IBOutlet private var contentViews: [UIView]!
@IBOutlet private weak var pendingView: UIView!
@IBOutlet private weak var offerView: UIView!
@IBOutlet private weak var more: UIButton!
@IBOutlet private weak var price: UILabel! {
didSet {
price.font = UIFont.medium14()
price.textColor = UIColor.linkBlue()
}
}
@IBOutlet private weak var descr: UILabel! {
didSet {
descr.font = UIFont.medium14()
descr.textColor = UIColor.blackPrimaryText()
}
}
@IBOutlet private weak var address: UILabel! {
didSet {
address.font = UIFont.regular12()
address.textColor = UIColor.blackSecondaryText()
}
}
@IBOutlet private weak var details: UIButton! {
didSet {
details.setTitleColor(UIColor.linkBlue(), for: .normal)
details.setBackgroundColor(UIColor.blackOpaque(), for: .normal)
}
}
private var isLastCell = false {
didSet {
more.isHidden = !isLastCell
price.isHidden = isLastCell
descr.isHidden = isLastCell
address.isHidden = isLastCell
details.isHidden = isLastCell
}
}
@IBOutlet private weak var pendingSpinnerView: UIImageView! {
didSet {
pendingSpinnerView.tintColor = UIColor.linkBlue()
}
}
@IBOutlet private weak var pendingTitleTopOffset: NSLayoutConstraint!
@IBOutlet private weak var pendingTitle: UILabel! {
didSet {
pendingTitle.font = UIFont.medium14()
pendingTitle.textColor = UIColor.blackPrimaryText()
pendingTitle.text = L("preloader_cian_title")
}
}
@IBOutlet private weak var pendingDescription: UILabel! {
didSet {
pendingDescription.font = UIFont.regular12()
pendingDescription.textColor = UIColor.blackSecondaryText()
pendingDescription.text = L("preloader_cian_message")
}
}
@IBAction func onButtonAction() {
switch state! {
case let .pending(action): action()
case let .offer(model, action): action(model)
case let .error(action): action()
}
}
var state: State! {
didSet {
setupAppearance()
setNeedsLayout()
contentViews.forEach { $0.isHidden = false }
let visibleView: UIView
var pendingSpinnerViewAlpha: CGFloat = 1
switch state! {
case .pending:
visibleView = pendingView
configPending()
case let .offer(model, _):
visibleView = offerView
configOffer(model: model)
case .error:
pendingSpinnerViewAlpha = 0
visibleView = pendingView
configError()
}
UIView.animate(withDuration: kDefaultAnimationDuration,
animations: {
self.pendingSpinnerView.alpha = pendingSpinnerViewAlpha
self.contentViews.forEach { $0.alpha = 0 }
visibleView.alpha = 1
self.layoutIfNeeded()
}, completion: { _ in
self.contentViews.forEach { $0.isHidden = true }
visibleView.isHidden = false
})
}
}
private var isSpinning = false {
didSet {
let animationKey = "SpinnerAnimation"
if isSpinning {
let animation = CABasicAnimation(keyPath: "transform.rotation.z")
animation.fromValue = NSNumber(value: 0)
animation.toValue = NSNumber(value: 2 * Double.pi)
animation.duration = 0.8
animation.repeatCount = Float.infinity
pendingSpinnerView.layer.add(animation, forKey: animationKey)
} else {
pendingSpinnerView.layer.removeAnimation(forKey: animationKey)
}
}
}
private func setupAppearance() {
backgroundColor = UIColor.white()
layer.cornerRadius = 6
layer.borderWidth = 1
layer.borderColor = UIColor.blackDividers().cgColor
}
private func configPending() {
isSpinning = true
details.setTitle(L("preloader_cian_button"), for: .normal)
pendingTitleTopOffset.priority = UILayoutPriorityDefaultLow
}
private func configError() {
isSpinning = false
details.setTitle(L("preloader_cian_button"), for: .normal)
pendingTitleTopOffset.priority = UILayoutPriorityDefaultHigh
}
private func configOffer(model: CianItemModel?) {
isSpinning = false
if let model = model {
isLastCell = false
let priceFormatter = NumberFormatter()
priceFormatter.usesGroupingSeparator = true
if let priceString = priceFormatter.string(from: NSNumber(value: model.priceRur)) {
price.text = "\(priceString) \(L("rub_month"))"
} else {
price.isHidden = true
}
let descrFormat = L("room").replacingOccurrences(of: "%s", with: "%@")
descr.text = String(format: descrFormat, arguments:["\(model.roomsCount)"])
address.text = model.address
details.setTitle(L("details"), for: .normal)
} else {
isLastCell = true
more.setBackgroundImage(UIColor.isNightMode() ? #imageLiteral(resourceName: "btn_float_more_dark") : #imageLiteral(resourceName: "btn_float_more_light"), for: .normal)
backgroundColor = UIColor.clear
layer.borderColor = UIColor.clear.cgColor
}
}
}

View file

@ -0,0 +1,167 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
<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"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" contentMode="center" reuseIdentifier="CianElement" id="M3h-Po-OZ2" customClass="CianElement" customModule="cm_beta" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="359" height="136"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="359" height="136"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="R2W-is-Sf4">
<rect key="frame" x="0.0" y="0.0" width="359" height="84"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="id6-AH-H9j">
<rect key="frame" x="149.5" y="38" width="60" height="60"/>
<constraints>
<constraint firstAttribute="width" constant="60" id="IsD-NU-jC0"/>
<constraint firstAttribute="width" secondItem="id6-AH-H9j" secondAttribute="height" multiplier="1:1" id="awE-Lv-XH6"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
<connections>
<action selector="onButtonAction" destination="M3h-Po-OZ2" eventType="touchUpInside" id="UZ2-Xs-jFs"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="370 000 ₽/мес." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uEh-dd-pal">
<rect key="frame" x="12" y="12" width="335" height="14.5"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3-комн. кв, 215 м²" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1xd-1l-F1k">
<rect key="frame" x="12" y="30.5" width="335" height="17"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="4 hours" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qgX-Wx-Mv7">
<rect key="frame" x="12" y="51.5" width="335" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="uEh-dd-pal" firstAttribute="top" secondItem="R2W-is-Sf4" secondAttribute="top" constant="12" id="0Lv-tX-jvl"/>
<constraint firstAttribute="trailing" secondItem="1xd-1l-F1k" secondAttribute="trailing" constant="12" id="7aI-4e-kBF"/>
<constraint firstItem="qgX-Wx-Mv7" firstAttribute="top" secondItem="1xd-1l-F1k" secondAttribute="bottom" constant="4" id="BRa-ep-j27"/>
<constraint firstItem="1xd-1l-F1k" firstAttribute="top" secondItem="uEh-dd-pal" secondAttribute="bottom" constant="4" id="BW5-Uu-LYC"/>
<constraint firstItem="qgX-Wx-Mv7" firstAttribute="leading" secondItem="R2W-is-Sf4" secondAttribute="leading" constant="12" id="Be3-IH-cbd"/>
<constraint firstAttribute="trailing" secondItem="qgX-Wx-Mv7" secondAttribute="trailing" constant="12" id="Fh5-aY-6vZ"/>
<constraint firstAttribute="trailing" secondItem="uEh-dd-pal" secondAttribute="trailing" constant="12" id="aZW-4Q-ddT"/>
<constraint firstItem="1xd-1l-F1k" firstAttribute="leading" secondItem="R2W-is-Sf4" secondAttribute="leading" constant="12" id="bKq-2Q-zSl"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="qgX-Wx-Mv7" secondAttribute="bottom" id="j5h-7y-MWw"/>
<constraint firstItem="uEh-dd-pal" firstAttribute="leading" secondItem="R2W-is-Sf4" secondAttribute="leading" constant="12" id="xCA-IE-FEs"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kn4-Ib-zJ0">
<rect key="frame" x="0.0" y="0.0" width="359" height="84"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wFD-SC-Cp3">
<rect key="frame" x="0.0" y="7" width="359" height="71.5"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic24PxSpinner" translatesAutoresizingMaskIntoConstraints="NO" id="71a-Dw-JIt">
<rect key="frame" x="167" y="0.0" width="24" height="24"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="width" constant="24" id="TvY-TT-UE3"/>
<constraint firstAttribute="height" constant="24" id="oHc-Go-jJr"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WXZ-8d-bkC">
<rect key="frame" x="0.0" y="36" width="359" height="17"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qs4-kW-kiT">
<rect key="frame" x="0.0" y="57" width="359" height="14.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="WXZ-8d-bkC" secondAttribute="trailing" id="6fC-SI-oPu"/>
<constraint firstItem="WXZ-8d-bkC" firstAttribute="top" secondItem="wFD-SC-Cp3" secondAttribute="top" priority="250" id="F84-HV-lEa"/>
<constraint firstItem="WXZ-8d-bkC" firstAttribute="leading" secondItem="wFD-SC-Cp3" secondAttribute="leading" id="FBt-gj-wRw"/>
<constraint firstItem="qs4-kW-kiT" firstAttribute="top" secondItem="WXZ-8d-bkC" secondAttribute="bottom" constant="4" id="GBu-s4-0g4"/>
<constraint firstItem="71a-Dw-JIt" firstAttribute="top" secondItem="wFD-SC-Cp3" secondAttribute="top" priority="500" identifier="topPendingSpinner" id="aLX-u2-pTz"/>
<constraint firstAttribute="bottom" secondItem="qs4-kW-kiT" secondAttribute="bottom" id="cGc-6o-H4Q"/>
<constraint firstItem="WXZ-8d-bkC" firstAttribute="top" secondItem="71a-Dw-JIt" secondAttribute="bottom" constant="12" id="g77-WF-Hw7"/>
<constraint firstItem="71a-Dw-JIt" firstAttribute="centerX" secondItem="wFD-SC-Cp3" secondAttribute="centerX" identifier="centerPendingSpinner" id="gPh-4z-DL6"/>
<constraint firstAttribute="trailing" secondItem="qs4-kW-kiT" secondAttribute="trailing" id="gPi-5Z-wkw"/>
<constraint firstItem="qs4-kW-kiT" firstAttribute="leading" secondItem="wFD-SC-Cp3" secondAttribute="leading" id="iHe-t3-hr4"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="wFD-SC-Cp3" firstAttribute="leading" secondItem="kn4-Ib-zJ0" secondAttribute="leading" id="JcD-GE-MYz"/>
<constraint firstAttribute="trailing" secondItem="wFD-SC-Cp3" secondAttribute="trailing" id="VDj-oc-LHk"/>
<constraint firstItem="wFD-SC-Cp3" firstAttribute="centerY" secondItem="kn4-Ib-zJ0" secondAttribute="centerY" id="cL8-aA-Zrg"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9Fh-ba-07y">
<rect key="frame" x="0.0" y="92" width="359" height="44"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="bzP-y6-5of"/>
</constraints>
<state key="normal" title="Button"/>
<connections>
<action selector="onButtonAction" destination="M3h-Po-OZ2" eventType="touchUpInside" id="55y-0U-n4N"/>
</connections>
</button>
</subviews>
</view>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="kn4-Ib-zJ0" firstAttribute="top" secondItem="M3h-Po-OZ2" secondAttribute="top" id="0Ka-Hc-cQp"/>
<constraint firstAttribute="trailing" secondItem="R2W-is-Sf4" secondAttribute="trailing" id="4WN-aq-2LI"/>
<constraint firstItem="id6-AH-H9j" firstAttribute="centerY" secondItem="M3h-Po-OZ2" secondAttribute="centerY" id="4sT-eH-I6T"/>
<constraint firstAttribute="trailing" secondItem="9Fh-ba-07y" secondAttribute="trailing" id="86Q-eA-QPL"/>
<constraint firstItem="R2W-is-Sf4" firstAttribute="leading" secondItem="M3h-Po-OZ2" secondAttribute="leading" id="IyY-jn-Oo3"/>
<constraint firstItem="kn4-Ib-zJ0" firstAttribute="leading" secondItem="M3h-Po-OZ2" secondAttribute="leading" id="NKP-12-cA2"/>
<constraint firstItem="9Fh-ba-07y" firstAttribute="leading" secondItem="M3h-Po-OZ2" secondAttribute="leading" id="Owb-m1-eXn"/>
<constraint firstItem="9Fh-ba-07y" firstAttribute="top" secondItem="R2W-is-Sf4" secondAttribute="bottom" constant="8" id="XoP-TP-0vI"/>
<constraint firstItem="R2W-is-Sf4" firstAttribute="top" secondItem="M3h-Po-OZ2" secondAttribute="top" id="YIF-er-YjM"/>
<constraint firstAttribute="bottom" secondItem="9Fh-ba-07y" secondAttribute="bottom" id="ZZL-IH-9aB"/>
<constraint firstItem="id6-AH-H9j" firstAttribute="centerX" secondItem="M3h-Po-OZ2" secondAttribute="centerX" id="fW1-aZ-Wf5"/>
<constraint firstAttribute="trailing" secondItem="kn4-Ib-zJ0" secondAttribute="trailing" id="gGM-zs-IN0"/>
<constraint firstItem="9Fh-ba-07y" firstAttribute="top" secondItem="kn4-Ib-zJ0" secondAttribute="bottom" constant="8" id="zOJ-sz-Igp"/>
</constraints>
<connections>
<outlet property="address" destination="qgX-Wx-Mv7" id="e49-3B-GAx"/>
<outlet property="descr" destination="1xd-1l-F1k" id="KhV-pr-C3K"/>
<outlet property="details" destination="9Fh-ba-07y" id="dHf-Nj-K9g"/>
<outlet property="more" destination="id6-AH-H9j" id="ckh-cS-xmJ"/>
<outlet property="offerView" destination="R2W-is-Sf4" id="gKM-Xm-lzP"/>
<outlet property="pendingDescription" destination="qs4-kW-kiT" id="aav-TU-fRL"/>
<outlet property="pendingSpinnerView" destination="71a-Dw-JIt" id="jgt-P8-5pA"/>
<outlet property="pendingTitle" destination="WXZ-8d-bkC" id="wId-fi-ceF"/>
<outlet property="pendingTitleTopOffset" destination="F84-HV-lEa" id="Qn8-vt-Vjg"/>
<outlet property="pendingView" destination="kn4-Ib-zJ0" id="OQh-kH-Nda"/>
<outlet property="price" destination="uEh-dd-pal" id="Vxg-yi-Zu8"/>
<outletCollection property="contentViews" destination="R2W-is-Sf4" collectionClass="NSMutableArray" id="3wv-Mx-ff5"/>
<outletCollection property="contentViews" destination="kn4-Ib-zJ0" collectionClass="NSMutableArray" id="llM-Co-3Ta"/>
</connections>
<point key="canvasLocation" x="42.5" y="118"/>
</collectionViewCell>
</objects>
<resources>
<image name="ic24PxSpinner" width="24" height="24"/>
</resources>
</document>

View file

@ -0,0 +1,14 @@
@objc(MWMCianItemModel)
final class CianItemModel: NSObject {
let roomsCount: UInt
let priceRur: UInt
let pageURL: URL
let address: String
init(roomsCount: UInt, priceRur: UInt, pageURL: URL, address: String) {
self.roomsCount = roomsCount
self.priceRur = priceRur
self.pageURL = pageURL
self.address = address
}
}

View file

@ -0,0 +1,106 @@
@objc(MWMPPCianCarouselCell)
final class PPCianCarouselCell: MWMTableViewCell {
@IBOutlet private weak var title: UILabel! {
didSet {
title.text = L("subtitle_rent")
title.font = UIFont.bold14()
title.textColor = UIColor.blackSecondaryText()
}
}
@IBOutlet private weak var more: UIButton! {
didSet {
more.setImage(#imageLiteral(resourceName: "logo_cian"), for: .normal)
more.titleLabel?.font = UIFont.regular17()
more.setTitleColor(UIColor.linkBlue(), for: .normal)
}
}
@IBOutlet private weak var collectionView: UICollectionView!
var data: [CianItemModel]? {
didSet {
updateCollectionView { [weak self] in
self?.collectionView.reloadSections(IndexSet(integer: 0))
}
}
}
fileprivate let kMaximumNumberOfElements = 5
fileprivate var delegate: MWMPlacePageButtonsProtocol?
func config(delegate d: MWMPlacePageButtonsProtocol?) {
delegate = d
collectionView.contentOffset = .zero
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(cellClass: CianElement.self)
collectionView.reloadData()
isSeparatorHidden = true
backgroundColor = UIColor.clear
}
fileprivate func isLastCell(_ indexPath: IndexPath) -> Bool {
return indexPath.item == collectionView.numberOfItems(inSection: indexPath.section) - 1
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
updateCollectionView(nil)
}
private func updateCollectionView(_ updates: (() -> Void)?) {
guard let sv = superview else { return }
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
let screenSize = { sv.size.width - layout.sectionInset.left - layout.sectionInset.right }
let itemHeight: CGFloat = 136
let itemWidth: CGFloat
if let data = data {
if data.isEmpty {
itemWidth = screenSize()
} else {
itemWidth = 160
}
} else {
itemWidth = screenSize()
}
layout.itemSize = CGSize(width: itemWidth, height: itemHeight)
collectionView.performBatchUpdates(updates, completion: nil)
}
@IBAction
fileprivate func onMore() {
delegate?.openSponsoredURL(nil)
}
}
extension PPCianCarouselCell: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withCellClass: CianElement.self,
indexPath: indexPath) as! CianElement
if let data = data {
if data.isEmpty {
cell.state = .error(onButtonAction: onMore)
} else {
let model = isLastCell(indexPath) ? nil : data[indexPath.item]
cell.state = .offer(model: model,
onButtonAction: { [unowned self] model in
self.delegate?.openSponsoredURL(model?.pageURL)
})
}
} else {
cell.state = .pending(onButtonAction: onMore)
}
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let data = data {
if data.isEmpty {
return 1
} else {
return min(data.count, kMaximumNumberOfElements) + 1
}
} else {
return 1
}
}
}

View file

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<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 clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="Sg7-wE-7Ir" customClass="MWMPPCianCarouselCell">
<rect key="frame" x="0.0" y="0.0" width="375" height="189"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Sg7-wE-7Ir" id="aSG-gb-Vaa">
<rect key="frame" x="0.0" y="0.0" width="375" height="188.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="АРЕНДА" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NuY-qA-4Ql">
<rect key="frame" x="12" y="8" width="57" height="24"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IOV-53-Iu8">
<rect key="frame" x="283" y="-4" width="84" height="48"/>
<inset key="contentEdgeInsets" minX="8" minY="8" maxX="8" maxY="8"/>
<state key="normal" image="logo_cian"/>
<connections>
<action selector="onMore" destination="Sg7-wE-7Ir" eventType="touchUpInside" id="dnJ-Bo-GZI"/>
</connections>
</button>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="none" translatesAutoresizingMaskIntoConstraints="NO" id="5Cw-QQ-VRc">
<rect key="frame" x="0.0" y="48" width="375" height="136"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" priority="900" constant="136" id="BgC-ps-kiz"/>
</constraints>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="8" minimumInteritemSpacing="8" id="KiF-3P-pUG">
<size key="itemSize" width="160" height="136"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="4" minY="0.0" maxX="4" maxY="0.0"/>
</collectionViewFlowLayout>
</collectionView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="IOV-53-Iu8" secondAttribute="trailing" constant="8" id="Ds4-FQ-jlE"/>
<constraint firstItem="NuY-qA-4Ql" firstAttribute="leading" secondItem="aSG-gb-Vaa" secondAttribute="leading" constant="12" id="Nla-eg-pwx"/>
<constraint firstItem="5Cw-QQ-VRc" firstAttribute="leading" secondItem="aSG-gb-Vaa" secondAttribute="leading" id="Nlk-Ll-dRR"/>
<constraint firstItem="NuY-qA-4Ql" firstAttribute="top" secondItem="aSG-gb-Vaa" secondAttribute="top" constant="8" id="Q2k-bj-mpj"/>
<constraint firstItem="IOV-53-Iu8" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="NuY-qA-4Ql" secondAttribute="trailing" constant="4" id="S4Z-Wf-UEB"/>
<constraint firstItem="5Cw-QQ-VRc" firstAttribute="top" secondItem="NuY-qA-4Ql" secondAttribute="bottom" constant="16" id="XAJ-ca-Jjm"/>
<constraint firstItem="IOV-53-Iu8" firstAttribute="centerY" secondItem="NuY-qA-4Ql" secondAttribute="centerY" id="eVg-i4-sM7"/>
<constraint firstAttribute="trailing" secondItem="5Cw-QQ-VRc" secondAttribute="trailing" id="qgf-Dc-kSN"/>
<constraint firstAttribute="bottom" secondItem="5Cw-QQ-VRc" secondAttribute="bottom" constant="4.5" id="yac-xe-eNm"/>
</constraints>
</tableViewCellContentView>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<connections>
<outlet property="collectionView" destination="5Cw-QQ-VRc" id="IdD-9L-EmF"/>
<outlet property="more" destination="IOV-53-Iu8" id="dPs-eC-7ds"/>
<outlet property="title" destination="NuY-qA-4Ql" id="tdT-p5-qIJ"/>
</connections>
<point key="canvasLocation" x="41.5" y="86.5"/>
</tableViewCell>
</objects>
<resources>
<image name="logo_cian" width="68" height="32"/>
</resources>
</document>

View file

@ -61,6 +61,7 @@ map<MetainfoRows, Class> const kMetaInfoCells = {
@property(weak, nonatomic) MWMPlacePageTaxiCell * taxiCell;
@property(weak, nonatomic) MWMPPViatorCarouselCell * viatorCell;
@property(weak, nonatomic) MWMPPCianCarouselCell * cianCell;
@property(nonatomic) BOOL buttonsSectionEnabled;
@ -98,6 +99,7 @@ map<MetainfoRows, Class> const kMetaInfoCells = {
[tv registerWithCellClass:[MWMPPHotelDescriptionCell class]];
[tv registerWithCellClass:[MWMPPHotelCarouselCell class]];
[tv registerWithCellClass:[MWMPPViatorCarouselCell class]];
[tv registerWithCellClass:[MWMPPCianCarouselCell class]];
[tv registerWithCellClass:[MWMPPReviewHeaderCell class]];
[tv registerWithCellClass:[MWMPPReviewCell class]];
[tv registerWithCellClass:[MWMPPFacilityCell class]];
@ -121,6 +123,7 @@ map<MetainfoRows, Class> const kMetaInfoCells = {
dispatch_async(dispatch_get_main_queue(), ^{
[data fillOnlineBookingSections];
[data fillOnlineViatorSection];
[data fillOnlineCianSection];
});
}
@ -405,12 +408,27 @@ map<MetainfoRows, Class> const kMetaInfoCells = {
}
case Sections::SpecialProjects:
{
Class cls = [MWMPPViatorCarouselCell class];
auto c = static_cast<MWMPPViatorCarouselCell *>(
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
[c configWith:data.viatorItems delegate:delegate];
self.viatorCell = c;
return c;
switch (data.specialProjectRows[indexPath.row])
{
case SpecialProject::Viator:
{
Class cls = [MWMPPViatorCarouselCell class];
auto c = static_cast<MWMPPViatorCarouselCell *>(
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
[c configWith:data.viatorItems delegate:delegate];
self.viatorCell = c;
return c;
}
case SpecialProject::Cian:
{
Class cls = [MWMPPCianCarouselCell class];
auto c = static_cast<MWMPPCianCarouselCell *>(
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
[c configWithDelegate:delegate];
self.cianCell = c;
return c;
}
}
}
case Sections::HotelPhotos:
{
@ -659,6 +677,10 @@ map<MetainfoRows, Class> const kMetaInfoCells = {
[self.previewLayoutHelper insertRowAtTheEnd];
};
data.cianIsReadyCallback = ^(NSArray<MWMCianItemModel *> * items) {
self.cianCell.data = items;
};
[self.actionBar configureWithData:data];
[self.previewLayoutHelper configWithData:data];
auto const & metaInfo = data.metainfoRows;