forked from organicmaps/organicmaps-tmp
[MAPSME-4213] [ios] Added banners support to search.
This commit is contained in:
parent
4dd4bd9c0a
commit
d09064eff5
13 changed files with 306 additions and 51 deletions
|
@ -26,6 +26,7 @@
|
|||
#import "MWMPlacePageCellUpdateProtocol.h"
|
||||
#import "MWMPushNotifications.h"
|
||||
#import "MWMRouter.h"
|
||||
#import "MWMSearchItemType.h"
|
||||
#import "MWMSearchNoResults.h"
|
||||
#import "MWMSettings.h"
|
||||
#import "MWMTableViewCell.h"
|
||||
|
|
|
@ -18,6 +18,7 @@ final class BannersCache: NSObject {
|
|||
private var requests: [BannerType : Banner] = [:]
|
||||
private var completion: Completion?
|
||||
private var loadStates: [LoadState]!
|
||||
private var cacheOnly = false
|
||||
|
||||
private func onCompletion(isAsync: Bool) {
|
||||
guard let completion = completion else { return }
|
||||
|
@ -43,8 +44,9 @@ final class BannersCache: NSObject {
|
|||
self.completion = nil
|
||||
}
|
||||
|
||||
func get(coreBanners: [CoreBanner], completion: @escaping Completion) {
|
||||
func get(coreBanners: [CoreBanner], completion: @escaping Completion, cacheOnly: Bool) {
|
||||
self.completion = completion
|
||||
self.cacheOnly = cacheOnly
|
||||
loadStates = coreBanners.map { coreBanner in
|
||||
let bannerType = BannerType(type: coreBanner.mwmType, id: coreBanner.bannerID)
|
||||
if let banner = cache[bannerType], (!banner.isPossibleToReload || banner.isNeedToRetain) {
|
||||
|
@ -93,7 +95,9 @@ final class BannersCache: NSObject {
|
|||
}
|
||||
cache[bannerType] = banner
|
||||
requests[bannerType] = nil
|
||||
onCompletion(isAsync: true)
|
||||
if !cacheOnly {
|
||||
onCompletion(isAsync: true)
|
||||
}
|
||||
}
|
||||
|
||||
private func setError(bannerType: BannerType) {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#import "MWMBanner.h"
|
||||
#import "MWMSearchFilterViewController.h"
|
||||
#import "MWMSearchItemType.h"
|
||||
#import "MWMSearchObserver.h"
|
||||
|
||||
#include "search/result.hpp"
|
||||
|
@ -13,7 +15,11 @@
|
|||
|
||||
+ (void)showResult:(search::Result const &)result;
|
||||
|
||||
+ (search::Result const &)resultAtIndex:(NSUInteger)index;
|
||||
+ (MWMSearchItemType)resultTypeWithIndex:(NSUInteger)index;
|
||||
+ (NSUInteger)containerIndexWithIndex:(NSUInteger)index;
|
||||
+ (search::Result const &)resultWithContainerIndex:(NSUInteger)index;
|
||||
+ (id<MWMBanner>)adWithContainerIndex:(NSUInteger)index;
|
||||
|
||||
+ (void)update;
|
||||
+ (void)clear;
|
||||
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
#import "MWMSearch.h"
|
||||
#import <Crashlytics/Crashlytics.h>
|
||||
#import "MWMCommon.h"
|
||||
#import "MWMAlertViewController.h"
|
||||
#import "MWMBannerHelpers.h"
|
||||
#import "MWMCommon.h"
|
||||
#import "MWMLocationManager.h"
|
||||
#import "MWMSearchHotelsFilterViewController.h"
|
||||
#import "SwiftBridge.h"
|
||||
|
||||
#include "Framework.h"
|
||||
|
||||
#include "partners_api/ads_engine.hpp"
|
||||
|
||||
#include "search/everywhere_search_params.hpp"
|
||||
#include "search/hotels_classifier.hpp"
|
||||
#include "search/query_saver.hpp"
|
||||
|
@ -37,6 +41,10 @@ using TObservers = NSHashTable<__kindof TObserver>;
|
|||
|
||||
@property(nonatomic) BOOL viewportResultsEmpty;
|
||||
|
||||
@property(nonatomic) MWMSearchIndex * itemsIndex;
|
||||
|
||||
@property(nonatomic) MWMSearchBanners * banners;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MWMSearch
|
||||
|
@ -97,6 +105,7 @@ using TObservers = NSHashTable<__kindof TObserver>;
|
|||
{
|
||||
self->m_everywhereResults = results;
|
||||
self.suggestionsCount = results.GetSuggestsCount();
|
||||
[self updateItemsIndex];
|
||||
[self onSearchResultsUpdated];
|
||||
}
|
||||
};
|
||||
|
@ -208,30 +217,48 @@ using TObservers = NSHashTable<__kindof TObserver>;
|
|||
}
|
||||
|
||||
+ (void)showResult:(search::Result const &)result { GetFramework().ShowSearchResult(result); }
|
||||
|
||||
+ (search::Result const &)resultAtIndex:(NSUInteger)index
|
||||
+ (search::Result const &)resultWithContainerIndex:(NSUInteger)index
|
||||
{
|
||||
return [MWMSearch manager]->m_everywhereResults.GetResult(index);
|
||||
}
|
||||
|
||||
+ (id<MWMBanner>)adWithContainerIndex:(NSUInteger)index
|
||||
{
|
||||
return [[MWMSearch manager].banners bannerAtIndex:index];
|
||||
}
|
||||
|
||||
+ (MWMSearchItemType)resultTypeWithIndex:(NSUInteger)index
|
||||
{
|
||||
auto itemsIndex = [MWMSearch manager].itemsIndex;
|
||||
return [itemsIndex resultTypeWithIndex:index];
|
||||
}
|
||||
|
||||
+ (NSUInteger)containerIndexWithIndex:(NSUInteger)index
|
||||
{
|
||||
auto itemsIndex = [MWMSearch manager].itemsIndex;
|
||||
return [itemsIndex resultContainerIndexWithIndex:index];
|
||||
}
|
||||
|
||||
+ (void)update { [[MWMSearch manager] update]; }
|
||||
|
||||
+ (void)reset
|
||||
{
|
||||
MWMSearch * manager = [MWMSearch manager];
|
||||
auto manager = [MWMSearch manager];
|
||||
manager.lastSearchStamp++;
|
||||
GetFramework().CancelAllSearches();
|
||||
manager.everywhereSearchCompleted = NO;
|
||||
manager.viewportSearchCompleted = NO;
|
||||
if (manager->m_filterQuery != manager->m_everywhereParams.m_query)
|
||||
manager.isHotelResults = NO;
|
||||
manager.suggestionsCount = 0;
|
||||
[manager onSearchResultsUpdated];
|
||||
}
|
||||
|
||||
+ (void)clear
|
||||
{
|
||||
[MWMSearch manager]->m_everywhereResults.Clear();
|
||||
auto manager = [MWMSearch manager];
|
||||
manager->m_everywhereResults.Clear();
|
||||
manager.suggestionsCount = 0;
|
||||
[manager updateItemsIndex];
|
||||
[self reset];
|
||||
}
|
||||
|
||||
|
@ -248,9 +275,7 @@ using TObservers = NSHashTable<__kindof TObserver>;
|
|||
}
|
||||
|
||||
+ (NSUInteger)suggestionsCount { return [MWMSearch manager].suggestionsCount; }
|
||||
|
||||
+ (NSUInteger)resultsCount { return [MWMSearch manager]->m_everywhereResults.GetCount(); }
|
||||
|
||||
+ (NSUInteger)resultsCount { return [MWMSearch manager].itemsIndex.count; }
|
||||
+ (BOOL)isHotelResults { return [MWMSearch manager].isHotelResults; }
|
||||
|
||||
#pragma mark - Filters
|
||||
|
@ -270,6 +295,40 @@ using TObservers = NSHashTable<__kindof TObserver>;
|
|||
MWMSearch * manager = [MWMSearch manager];
|
||||
manager.filter = nil;
|
||||
[manager update];
|
||||
[manager onSearchCompleted];
|
||||
}
|
||||
|
||||
- (void)updateItemsIndex
|
||||
{
|
||||
auto resultsCount = self->m_everywhereResults.GetCount();
|
||||
auto itemsIndex = [[MWMSearchIndex alloc] initWithSuggestionsCount:self.suggestionsCount
|
||||
resultsCount:resultsCount];
|
||||
auto bannersCache = [MWMBannersCache cache];
|
||||
if (resultsCount > 0)
|
||||
{
|
||||
auto const & adsEngine = GetFramework().GetAdsEngine();
|
||||
if (adsEngine.HasSearchBanner())
|
||||
{
|
||||
self.banners = [[MWMSearchBanners alloc] initWithSearchIndex:itemsIndex];
|
||||
__weak auto weakSelf = self;
|
||||
[bannersCache
|
||||
getWithCoreBanners:banner_helpers::MatchPriorityBanners(adsEngine.GetSearchBanners())
|
||||
completion:^(id<MWMBanner> ad, BOOL isAsync) {
|
||||
__strong auto self = weakSelf;
|
||||
if (!self)
|
||||
return;
|
||||
NSAssert(isAsync == NO, @"Banner is not from cache!");
|
||||
[self.banners add:ad];
|
||||
}
|
||||
cacheOnly:YES];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.banners = nil;
|
||||
}
|
||||
[itemsIndex build];
|
||||
self.itemsIndex = itemsIndex;
|
||||
}
|
||||
|
||||
#pragma mark - Notifications
|
||||
|
|
6
iphone/Maps/Core/Search/MWMSearchItemType.h
Normal file
6
iphone/Maps/Core/Search/MWMSearchItemType.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
typedef NS_ENUM(NSUInteger, MWMSearchItemType) {
|
||||
// Order == priority.
|
||||
MWMSearchItemTypeRegular,
|
||||
MWMSearchItemTypeMopub,
|
||||
MWMSearchItemTypeSuggestion
|
||||
};
|
36
iphone/Maps/Core/Search/SearchBanners.swift
Normal file
36
iphone/Maps/Core/Search/SearchBanners.swift
Normal file
|
@ -0,0 +1,36 @@
|
|||
@objc(MWMSearchBanners)
|
||||
final class SearchBanners: NSObject {
|
||||
private var banners: [MWMBanner] = []
|
||||
|
||||
weak var searchIndex: SearchIndex?
|
||||
|
||||
init(searchIndex: SearchIndex) {
|
||||
self.searchIndex = searchIndex
|
||||
super.init()
|
||||
}
|
||||
|
||||
func add(_ banner: MWMBanner) {
|
||||
guard let searchIndex = searchIndex else { return }
|
||||
banners.append(banner)
|
||||
let type: MWMSearchItemType
|
||||
let prefferedPosition: Int
|
||||
switch banner.mwmType {
|
||||
case .mopub:
|
||||
type = .mopub
|
||||
prefferedPosition = 2
|
||||
default:
|
||||
assert(false, "Unsupported banner type")
|
||||
type = .regular
|
||||
prefferedPosition = 0
|
||||
}
|
||||
searchIndex.addItem(type: type, prefferedPosition: prefferedPosition, containerIndex: banners.count - 1)
|
||||
}
|
||||
|
||||
func banner(atIndex index: Int) -> MWMBanner {
|
||||
return banners[index]
|
||||
}
|
||||
|
||||
deinit {
|
||||
banners.forEach { BannersCache.cache.bannerIsOutOfScreen(coreBanner: $0) }
|
||||
}
|
||||
}
|
85
iphone/Maps/Core/Search/SearchIndex.swift
Normal file
85
iphone/Maps/Core/Search/SearchIndex.swift
Normal file
|
@ -0,0 +1,85 @@
|
|||
@objc(MWMSearchIndex)
|
||||
final class SearchIndex: NSObject {
|
||||
fileprivate struct Item {
|
||||
let type: MWMSearchItemType
|
||||
let containerIndex: Int
|
||||
}
|
||||
|
||||
fileprivate struct PositionItem {
|
||||
let item: Item
|
||||
var position: Int
|
||||
}
|
||||
|
||||
private var positionItems: [PositionItem] = []
|
||||
private var items: [Item] = []
|
||||
|
||||
var count: Int {
|
||||
return items.count
|
||||
}
|
||||
|
||||
init(suggestionsCount: Int, resultsCount: Int) {
|
||||
for index in 0..<resultsCount {
|
||||
let type: MWMSearchItemType = index < suggestionsCount ? .suggestion : .regular
|
||||
positionItems.append(PositionItem(item: Item(type: type, containerIndex: index), position: index))
|
||||
}
|
||||
super.init()
|
||||
}
|
||||
|
||||
func addItem(type: MWMSearchItemType, prefferedPosition: Int, containerIndex: Int) {
|
||||
assert(type != .suggestion && type != .regular)
|
||||
positionItems.append(PositionItem(item: Item(type: type, containerIndex: containerIndex), position: prefferedPosition))
|
||||
}
|
||||
|
||||
func build() {
|
||||
positionItems.sort(by: >)
|
||||
var itemsDict: [Int: Item] = [:]
|
||||
positionItems.forEach { item in
|
||||
var position = item.position
|
||||
while itemsDict[position] != nil {
|
||||
position += 1
|
||||
}
|
||||
itemsDict[position] = item.item
|
||||
}
|
||||
|
||||
items.removeAll()
|
||||
let keys = itemsDict.keys.sorted()
|
||||
for index in 0..<keys.count {
|
||||
let key = keys[index]
|
||||
if index == key {
|
||||
items.append(itemsDict[key]!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func resultType(index: Int) -> MWMSearchItemType {
|
||||
return items[index].type
|
||||
}
|
||||
|
||||
func resultContainerIndex(index: Int) -> Int {
|
||||
return items[index].containerIndex
|
||||
}
|
||||
}
|
||||
|
||||
extension SearchIndex.PositionItem: Equatable {
|
||||
static func ==(lhs: SearchIndex.PositionItem, rhs: SearchIndex.PositionItem) -> Bool {
|
||||
let lhsCache = lhs.item
|
||||
let rhsCache = rhs.item
|
||||
return lhsCache.type == rhsCache.type &&
|
||||
lhs.position == rhs.position &&
|
||||
lhsCache.containerIndex == rhsCache.containerIndex
|
||||
}
|
||||
}
|
||||
|
||||
extension SearchIndex.PositionItem: Comparable {
|
||||
static func <(lhs: SearchIndex.PositionItem, rhs: SearchIndex.PositionItem) -> Bool {
|
||||
let lhsCache = lhs.item
|
||||
let rhsCache = rhs.item
|
||||
guard lhsCache.type == rhsCache.type else {
|
||||
return lhsCache.type.rawValue < rhsCache.type.rawValue
|
||||
}
|
||||
guard lhs.position == rhs.position else {
|
||||
return lhs.position > rhs.position
|
||||
}
|
||||
return lhsCache.containerIndex < rhsCache.containerIndex
|
||||
}
|
||||
}
|
|
@ -157,6 +157,9 @@
|
|||
342CC5F21C2D7730005F3FE5 /* MWMAuthorizationLoginViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 342CC5F01C2D7730005F3FE5 /* MWMAuthorizationLoginViewController.mm */; };
|
||||
342EE4111C43DAA7009F6A49 /* MWMAuthorizationWebViewLoginViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 342EE4101C43DAA7009F6A49 /* MWMAuthorizationWebViewLoginViewController.mm */; };
|
||||
342EE4121C43DAA7009F6A49 /* MWMAuthorizationWebViewLoginViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 342EE4101C43DAA7009F6A49 /* MWMAuthorizationWebViewLoginViewController.mm */; };
|
||||
343064401E9FDC7300DC7665 /* SearchIndex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3430643F1E9FDC7300DC7665 /* SearchIndex.swift */; };
|
||||
343064411E9FDC7300DC7665 /* SearchIndex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3430643F1E9FDC7300DC7665 /* SearchIndex.swift */; };
|
||||
343064421E9FDC7300DC7665 /* SearchIndex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3430643F1E9FDC7300DC7665 /* SearchIndex.swift */; };
|
||||
3432E1781E49B3A2008477E9 /* Bolts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3432E1771E49B3A2008477E9 /* Bolts.framework */; };
|
||||
3432E1791E49B3A2008477E9 /* Bolts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3432E1771E49B3A2008477E9 /* Bolts.framework */; };
|
||||
3432E17A1E49B3A2008477E9 /* Bolts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3432E1771E49B3A2008477E9 /* Bolts.framework */; };
|
||||
|
@ -302,6 +305,9 @@
|
|||
3490D2E11CE9DD2500D0B838 /* MWMSideButtonsView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3490D2DC1CE9DD2500D0B838 /* MWMSideButtonsView.mm */; };
|
||||
3490D2E21CE9DD2500D0B838 /* MWMSideButtonsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3490D2DD1CE9DD2500D0B838 /* MWMSideButtonsView.xib */; };
|
||||
3490D2E31CE9DD2500D0B838 /* MWMSideButtonsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3490D2DD1CE9DD2500D0B838 /* MWMSideButtonsView.xib */; };
|
||||
34926BE61EA4C2A700DCF14C /* SearchBanners.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34926BE51EA4C2A700DCF14C /* SearchBanners.swift */; };
|
||||
34926BE71EA4C2A700DCF14C /* SearchBanners.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34926BE51EA4C2A700DCF14C /* SearchBanners.swift */; };
|
||||
34926BE81EA4C2A700DCF14C /* SearchBanners.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34926BE51EA4C2A700DCF14C /* SearchBanners.swift */; };
|
||||
34943BB61E26222300B14F84 /* WelcomeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34943BB51E26222300B14F84 /* WelcomeProtocol.swift */; };
|
||||
34943BB71E26222300B14F84 /* WelcomeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34943BB51E26222300B14F84 /* WelcomeProtocol.swift */; };
|
||||
34943BB81E26222300B14F84 /* WelcomeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34943BB51E26222300B14F84 /* WelcomeProtocol.swift */; };
|
||||
|
@ -1619,11 +1625,13 @@
|
|||
341C2A5A1B720B8A00AD41A1 /* MWMAPIBarView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMAPIBarView.xib; sourceTree = "<group>"; };
|
||||
341F09831C20138100F18AC5 /* libpugixml.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpugixml.a; path = "../../../omim-xcode-build/Debug/libpugixml.a"; sourceTree = "<group>"; };
|
||||
34201E0B1DC0E33100D24118 /* libtracking.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtracking.a; path = "../../../omim-xcode-build/Debug/libtracking.a"; sourceTree = "<group>"; };
|
||||
342639461EA0FDB30025EB89 /* MWMSearchItemType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMSearchItemType.h; sourceTree = "<group>"; };
|
||||
3427AF0B1E49E3A500D466DB /* MWMConsts.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MWMConsts.h; sourceTree = "<group>"; };
|
||||
342CC5EF1C2D7730005F3FE5 /* MWMAuthorizationLoginViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMAuthorizationLoginViewController.h; sourceTree = "<group>"; };
|
||||
342CC5F01C2D7730005F3FE5 /* MWMAuthorizationLoginViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMAuthorizationLoginViewController.mm; sourceTree = "<group>"; };
|
||||
342EE40F1C43DAA7009F6A49 /* MWMAuthorizationWebViewLoginViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMAuthorizationWebViewLoginViewController.h; sourceTree = "<group>"; };
|
||||
342EE4101C43DAA7009F6A49 /* MWMAuthorizationWebViewLoginViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMAuthorizationWebViewLoginViewController.mm; sourceTree = "<group>"; };
|
||||
3430643F1E9FDC7300DC7665 /* SearchIndex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchIndex.swift; sourceTree = "<group>"; };
|
||||
3432E1771E49B3A2008477E9 /* Bolts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Bolts.framework; sourceTree = "<group>"; };
|
||||
343E75951E5B1EE20041226A /* MWMCollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMCollectionViewController.h; sourceTree = "<group>"; };
|
||||
343E75961E5B1EE20041226A /* MWMCollectionViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMCollectionViewController.mm; sourceTree = "<group>"; };
|
||||
|
@ -1714,6 +1722,7 @@
|
|||
3490D2DB1CE9DD2500D0B838 /* MWMSideButtonsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMSideButtonsView.h; sourceTree = "<group>"; };
|
||||
3490D2DC1CE9DD2500D0B838 /* MWMSideButtonsView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMSideButtonsView.mm; sourceTree = "<group>"; };
|
||||
3490D2DD1CE9DD2500D0B838 /* MWMSideButtonsView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MWMSideButtonsView.xib; sourceTree = "<group>"; };
|
||||
34926BE51EA4C2A700DCF14C /* SearchBanners.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchBanners.swift; sourceTree = "<group>"; };
|
||||
34943BB51E26222300B14F84 /* WelcomeProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeProtocol.swift; sourceTree = "<group>"; };
|
||||
34943BB91E2626B200B14F84 /* WelcomePageController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomePageController.swift; sourceTree = "<group>"; };
|
||||
3497A9361B5CF8A900F51E55 /* MWMNavigationDashboardManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWMNavigationDashboardManager.h; sourceTree = "<group>"; };
|
||||
|
@ -2784,6 +2793,9 @@
|
|||
3404753C1E081A4600C92850 /* MWMSearch.h */,
|
||||
3404753D1E081A4600C92850 /* MWMSearch.mm */,
|
||||
3404753E1E081A4600C92850 /* MWMSearchObserver.h */,
|
||||
3430643F1E9FDC7300DC7665 /* SearchIndex.swift */,
|
||||
342639461EA0FDB30025EB89 /* MWMSearchItemType.h */,
|
||||
34926BE51EA4C2A700DCF14C /* SearchBanners.swift */,
|
||||
);
|
||||
path = Search;
|
||||
sourceTree = "<group>";
|
||||
|
@ -5069,6 +5081,7 @@
|
|||
F6E2FE1E1E097BA00083EBEC /* MWMOpeningHoursCommon.mm in Sources */,
|
||||
F6BC1E521ACBF98600EF0360 /* MWMFacebookAlert.mm in Sources */,
|
||||
F6E2FF5C1E097BA00083EBEC /* MWMRecentTrackSettingsController.mm in Sources */,
|
||||
343064401E9FDC7300DC7665 /* SearchIndex.swift in Sources */,
|
||||
F6664BF91E6459CB00E703C2 /* PPFacilityCell.swift in Sources */,
|
||||
F6E2FDE81E097BA00083EBEC /* MWMObjectsCategorySelectorController.mm in Sources */,
|
||||
F64F199D1AB81A00006EAF7E /* MWMDefaultAlert.mm in Sources */,
|
||||
|
@ -5291,6 +5304,7 @@
|
|||
F6E2FDA31E097BA00083EBEC /* MWMCuisineEditorViewController.mm in Sources */,
|
||||
346EDADB1B9F0E35004F8DB5 /* MWMMultilineLabel.mm in Sources */,
|
||||
34D3B0291E389D05004100F9 /* MWMEditorAdditionalNameTableViewCell.mm in Sources */,
|
||||
34926BE61EA4C2A700DCF14C /* SearchBanners.swift in Sources */,
|
||||
34D4FA621E26572D003F53EF /* FirstLaunchController.swift in Sources */,
|
||||
34C9BD041C6DB693000DC38D /* MWMViewController.mm in Sources */,
|
||||
3404165B1E7C29AE00E2B6D6 /* PhotosInteractionAnimator.swift in Sources */,
|
||||
|
@ -5359,6 +5373,7 @@
|
|||
F6E2FE1F1E097BA00083EBEC /* MWMOpeningHoursCommon.mm in Sources */,
|
||||
3454D7B91E07F045004AF2AD /* CALayer+RuntimeAttributes.mm in Sources */,
|
||||
F6E2FF5D1E097BA00083EBEC /* MWMRecentTrackSettingsController.mm in Sources */,
|
||||
343064411E9FDC7300DC7665 /* SearchIndex.swift in Sources */,
|
||||
F6664BFA1E6459CB00E703C2 /* PPFacilityCell.swift in Sources */,
|
||||
F6E2FDE91E097BA00083EBEC /* MWMObjectsCategorySelectorController.mm in Sources */,
|
||||
6741A9A81BF340DE002C974C /* MWMFacebookAlert.mm in Sources */,
|
||||
|
@ -5581,6 +5596,7 @@
|
|||
34C9BD051C6DB693000DC38D /* MWMViewController.mm in Sources */,
|
||||
F6E2FDA41E097BA00083EBEC /* MWMCuisineEditorViewController.mm in Sources */,
|
||||
3454D7CB1E07F045004AF2AD /* UIColor+MapsMeColor.mm in Sources */,
|
||||
34926BE71EA4C2A700DCF14C /* SearchBanners.swift in Sources */,
|
||||
34D3B02A1E389D05004100F9 /* MWMEditorAdditionalNameTableViewCell.mm in Sources */,
|
||||
340475711E081A4600C92850 /* MWMSettings.mm in Sources */,
|
||||
3404165C1E7C29AE00E2B6D6 /* PhotosInteractionAnimator.swift in Sources */,
|
||||
|
@ -5649,6 +5665,7 @@
|
|||
F6E2FE201E097BA00083EBEC /* MWMOpeningHoursCommon.mm in Sources */,
|
||||
849CF6891DE842290024A8A5 /* MWMFacebookAlert.mm in Sources */,
|
||||
F6E2FF5E1E097BA00083EBEC /* MWMRecentTrackSettingsController.mm in Sources */,
|
||||
343064421E9FDC7300DC7665 /* SearchIndex.swift in Sources */,
|
||||
F6664BFB1E6459CB00E703C2 /* PPFacilityCell.swift in Sources */,
|
||||
F6E2FDEA1E097BA00083EBEC /* MWMObjectsCategorySelectorController.mm in Sources */,
|
||||
849CF68A1DE842290024A8A5 /* MWMDefaultAlert.mm in Sources */,
|
||||
|
@ -5871,6 +5888,7 @@
|
|||
3454D7C31E07F045004AF2AD /* NSString+Categories.mm in Sources */,
|
||||
34D4FA641E26572D003F53EF /* FirstLaunchController.swift in Sources */,
|
||||
34D3B02B1E389D05004100F9 /* MWMEditorAdditionalNameTableViewCell.mm in Sources */,
|
||||
34926BE81EA4C2A700DCF14C /* SearchBanners.swift in Sources */,
|
||||
849CF7371DE842290024A8A5 /* MWMTaxiCollectionLayout.mm in Sources */,
|
||||
3454D7C61E07F045004AF2AD /* UIButton+Orientation.mm in Sources */,
|
||||
3404165D1E7C29AE00E2B6D6 /* PhotosInteractionAnimator.swift in Sources */,
|
||||
|
|
|
@ -6,6 +6,7 @@ enum AdBannerState: Int {
|
|||
case unset
|
||||
case compact
|
||||
case detailed
|
||||
case search
|
||||
|
||||
func config() -> (priority: UILayoutPriority, numberOfTitleLines: Int, numberOfBodyLines: Int) {
|
||||
switch self {
|
||||
|
@ -15,15 +16,24 @@ enum AdBannerState: Int {
|
|||
case .compact:
|
||||
return alternative(iPhone: (priority: UILayoutPriorityDefaultLow, numberOfTitleLines: 1, numberOfBodyLines: 2),
|
||||
iPad: (priority: UILayoutPriorityDefaultHigh, numberOfTitleLines: 0, numberOfBodyLines: 0))
|
||||
case .search:
|
||||
return (priority: UILayoutPriorityDefaultLow, numberOfTitleLines: 2, numberOfBodyLines: 0)
|
||||
case .detailed:
|
||||
return (priority: UILayoutPriorityDefaultHigh, numberOfTitleLines: 0, numberOfBodyLines: 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc(MWMAdBannerContainerType)
|
||||
enum AdBannerContainerType: Int {
|
||||
case placePage
|
||||
case search
|
||||
}
|
||||
|
||||
@objc(MWMAdBanner)
|
||||
final class AdBanner: UITableViewCell {
|
||||
@IBOutlet private var detailedModeConstraints: [NSLayoutConstraint]!
|
||||
@IBOutlet private weak var adCallToActionButtonCompactLeading: NSLayoutConstraint!
|
||||
@IBOutlet private weak var adIconImageView: UIImageView!
|
||||
@IBOutlet private weak var adTitleLabel: UILabel!
|
||||
@IBOutlet private weak var adBodyLabel: UILabel!
|
||||
|
@ -37,6 +47,9 @@ final class AdBanner: UITableViewCell {
|
|||
adTitleLabel.numberOfLines = config.numberOfTitleLines
|
||||
adBodyLabel.numberOfLines = config.numberOfBodyLines
|
||||
detailedModeConstraints.forEach { $0.priority = config.priority }
|
||||
if state == .search {
|
||||
adCallToActionButtonCompactLeading.priority = UILayoutPriorityDefaultHigh
|
||||
}
|
||||
setNeedsLayout()
|
||||
UIView.animate(withDuration: kDefaultAnimationDuration) { self.layoutIfNeeded() }
|
||||
refreshBannerIfNeeded()
|
||||
|
@ -51,8 +64,14 @@ final class AdBanner: UITableViewCell {
|
|||
|
||||
private var nativeAd: MWMBanner?
|
||||
|
||||
func config(ad: MWMBanner) {
|
||||
state = alternative(iPhone: AdBannerState.compact, iPad: AdBannerState.detailed)
|
||||
func config(ad: MWMBanner, containerType: AdBannerContainerType) {
|
||||
switch containerType {
|
||||
case .placePage:
|
||||
state = alternative(iPhone: .compact, iPad: .detailed)
|
||||
case .search:
|
||||
state = .search
|
||||
}
|
||||
|
||||
nativeAd = ad
|
||||
switch ad.mwmType {
|
||||
case .none:
|
||||
|
@ -90,7 +109,12 @@ final class AdBanner: UITableViewCell {
|
|||
|
||||
private func configFBBanner(ad: FBNativeAd) {
|
||||
ad.unregisterView()
|
||||
let adCallToActionButtons = [adCallToActionButtonCompact!, adCallToActionButtonDetailed!]
|
||||
let adCallToActionButtons: [UIView]
|
||||
if (state == .search) {
|
||||
adCallToActionButtons = [self]
|
||||
} else {
|
||||
adCallToActionButtons = [adCallToActionButtonCompact, adCallToActionButtonDetailed]
|
||||
}
|
||||
ad.registerView(forInteraction: self, with: nil, withClickableViews: adCallToActionButtons)
|
||||
|
||||
ad.icon?.loadAsync { [weak self] image in
|
||||
|
@ -109,7 +133,7 @@ final class AdBanner: UITableViewCell {
|
|||
let config = state.config()
|
||||
adTitleLabel.numberOfLines = config.numberOfTitleLines
|
||||
adBodyLabel.numberOfLines = config.numberOfBodyLines
|
||||
adCallToActionButtons.forEach { $0.setTitle(ad.callToAction, for: .normal) }
|
||||
[adCallToActionButtonCompact, adCallToActionButtonDetailed].forEach { $0.setTitle(ad.callToAction, for: .normal) }
|
||||
}
|
||||
|
||||
private func configRBBanner(ad: MTRGNativeAd) {
|
||||
|
@ -168,6 +192,7 @@ final class AdBanner: UITableViewCell {
|
|||
clickableView = adCallToActionButtonCompact
|
||||
case .compact: clickableView = adCallToActionButtonCompact
|
||||
case .detailed: clickableView = adCallToActionButtonDetailed
|
||||
case .search: clickableView = self
|
||||
}
|
||||
ad.register(clickableView, with: UIViewController.topViewController())
|
||||
}
|
||||
|
|
|
@ -142,6 +142,7 @@
|
|||
<connections>
|
||||
<outlet property="adBodyLabel" destination="Ev3-yY-ql1" id="xw6-9k-OYn"/>
|
||||
<outlet property="adCallToActionButtonCompact" destination="9qA-JC-fkn" id="2AF-5i-Wey"/>
|
||||
<outlet property="adCallToActionButtonCompactLeading" destination="5CH-Fo-S70" id="Vdl-uS-6Gd"/>
|
||||
<outlet property="adCallToActionButtonDetailed" destination="NKM-3R-3g1" id="diP-AI-tNi"/>
|
||||
<outlet property="adIconImageView" destination="EuF-Rm-DHQ" id="Edf-Ak-VAy"/>
|
||||
<outlet property="adTitleLabel" destination="kIR-cO-v6L" id="OOh-tX-yBM"/>
|
||||
|
|
|
@ -113,7 +113,8 @@ using namespace place_page;
|
|||
self->m_previewRows.push_back(PreviewRows::Banner);
|
||||
if (isAsync)
|
||||
self.bannerIsReadyCallback();
|
||||
}];
|
||||
}
|
||||
cacheOnly:NO];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -235,7 +235,7 @@ array<Class, 8> const kPreviewCells = {{[_MWMPPPTitle class], [_MWMPPPExternalTi
|
|||
return c;
|
||||
case PreviewRows::Banner:
|
||||
auto bannerCell = static_cast<MWMAdBanner *>(c);
|
||||
[bannerCell configWithAd:data.nativeAd];
|
||||
[bannerCell configWithAd:data.nativeAd containerType:MWMAdBannerContainerTypePlacePage];
|
||||
self.cachedBannerCell = bannerCell;
|
||||
return bannerCell;
|
||||
}
|
||||
|
|
|
@ -48,19 +48,7 @@
|
|||
tableView.rowHeight = UITableViewAutomaticDimension;
|
||||
[tableView registerWithCellClass:[MWMSearchSuggestionCell class]];
|
||||
[tableView registerWithCellClass:[MWMSearchCommonCell class]];
|
||||
}
|
||||
|
||||
- (Class)cellClassForIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
size_t const numSuggests = [MWMSearch suggestionsCount];
|
||||
if (numSuggests > 0 && indexPath.row < numSuggests)
|
||||
return [MWMSearchSuggestionCell class];
|
||||
return [MWMSearchCommonCell class];
|
||||
}
|
||||
|
||||
- (search::Result const &)searchResultForIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return [MWMSearch resultAtIndex:indexPath.row];
|
||||
[tableView registerWithCellClass:[MWMAdBanner class]];
|
||||
}
|
||||
|
||||
- (void)reloadData { [self.tableView reloadData]; }
|
||||
|
@ -86,41 +74,66 @@
|
|||
- (UITableViewCell *)tableView:(UITableView *)tableView
|
||||
cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
Class cls = [self cellClassForIndexPath:indexPath];
|
||||
auto cell = [tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath];
|
||||
if (cls == [MWMSearchSuggestionCell class])
|
||||
auto const row = indexPath.row;
|
||||
auto const containerIndex = [MWMSearch containerIndexWithIndex:row];
|
||||
switch ([MWMSearch resultTypeWithIndex:row])
|
||||
{
|
||||
auto tCell = static_cast<MWMSearchSuggestionCell *>(cell);
|
||||
[tCell config:[self searchResultForIndexPath:indexPath]];
|
||||
tCell.isLastCell = indexPath.row == [MWMSearch suggestionsCount] - 1;
|
||||
}
|
||||
else if (cls == [MWMSearchCommonCell class])
|
||||
case MWMSearchItemTypeRegular:
|
||||
{
|
||||
auto tCell = static_cast<MWMSearchCommonCell *>(cell);
|
||||
[tCell config:[self searchResultForIndexPath:indexPath]];
|
||||
auto cell = static_cast<MWMSearchSuggestionCell *>([tableView
|
||||
dequeueReusableCellWithCellClass:[MWMSearchCommonCell class]
|
||||
indexPath:indexPath]);
|
||||
auto result = [MWMSearch resultWithContainerIndex:containerIndex];
|
||||
[cell config:result];
|
||||
return cell;
|
||||
}
|
||||
case MWMSearchItemTypeMopub:
|
||||
{
|
||||
auto cell = static_cast<MWMAdBanner *>(
|
||||
[tableView dequeueReusableCellWithCellClass:[MWMAdBanner class] indexPath:indexPath]);
|
||||
auto ad = [MWMSearch adWithContainerIndex:containerIndex];
|
||||
[cell configWithAd:ad containerType:MWMAdBannerContainerTypeSearch];
|
||||
return cell;
|
||||
}
|
||||
case MWMSearchItemTypeSuggestion:
|
||||
{
|
||||
auto cell = static_cast<MWMSearchSuggestionCell *>([tableView
|
||||
dequeueReusableCellWithCellClass:[MWMSearchSuggestionCell class]
|
||||
indexPath:indexPath]);
|
||||
auto suggestion = [MWMSearch resultWithContainerIndex:containerIndex];
|
||||
[cell config:suggestion];
|
||||
cell.isLastCell = row == [MWMSearch suggestionsCount] - 1;
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDelegate
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
Class cls = [self cellClassForIndexPath:indexPath];
|
||||
id<MWMSearchTableViewProtocol> delegate = self.delegate;
|
||||
search::Result const & result = [self searchResultForIndexPath:indexPath];
|
||||
if (cls == [MWMSearchSuggestionCell class])
|
||||
auto const row = indexPath.row;
|
||||
auto const containerIndex = [MWMSearch containerIndexWithIndex:row];
|
||||
switch ([MWMSearch resultTypeWithIndex:row])
|
||||
{
|
||||
NSString * suggestionString = @(result.GetSuggestionString());
|
||||
case MWMSearchItemTypeRegular:
|
||||
{
|
||||
MWMSearchTextField * textField = delegate.searchTextField;
|
||||
[MWMSearch saveQuery:textField.text forInputLocale:textField.textInputMode.primaryLanguage];
|
||||
auto result = [MWMSearch resultWithContainerIndex:containerIndex];
|
||||
[delegate processSearchWithResult:result];
|
||||
break;
|
||||
}
|
||||
case MWMSearchItemTypeMopub: break;
|
||||
case MWMSearchItemTypeSuggestion:
|
||||
{
|
||||
auto suggestion = [MWMSearch resultWithContainerIndex:containerIndex];
|
||||
NSString * suggestionString = @(suggestion.GetSuggestionString());
|
||||
[Statistics logEvent:kStatEventName(kStatSearch, kStatSelectResult)
|
||||
withParameters:@{kStatValue : suggestionString, kStatScreen : kStatSearch}];
|
||||
[delegate searchText:suggestionString forInputLocale:nil];
|
||||
}
|
||||
else if (cls == [MWMSearchCommonCell class])
|
||||
{
|
||||
MWMSearchTextField * textField = delegate.searchTextField;
|
||||
[MWMSearch saveQuery:textField.text forInputLocale:textField.textInputMode.primaryLanguage];
|
||||
[delegate processSearchWithResult:result];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue