@javascriptcommon/react-native-carplay 2.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +633 -0
- package/ios/RCTConvert+RNCarPlay.h +19 -0
- package/ios/RCTConvert+RNCarPlay.m +95 -0
- package/ios/RNCPStore.h +22 -0
- package/ios/RNCPStore.m +68 -0
- package/ios/RNCarPlay.h +32 -0
- package/ios/RNCarPlay.m +1755 -0
- package/ios/RNCarPlay.xcodeproj/project.pbxproj +300 -0
- package/lib/CarPlay.js +146 -0
- package/lib/index.js +63 -0
- package/lib/interfaces/Action.js +2 -0
- package/lib/interfaces/AlertAction.js +2 -0
- package/lib/interfaces/BarButton.js +2 -0
- package/lib/interfaces/CarColor.js +2 -0
- package/lib/interfaces/GridButton.js +2 -0
- package/lib/interfaces/Header.js +2 -0
- package/lib/interfaces/ListItem.js +2 -0
- package/lib/interfaces/ListItemUpdate.js +2 -0
- package/lib/interfaces/ListSection.js +2 -0
- package/lib/interfaces/Maneuver.js +2 -0
- package/lib/interfaces/MapButton.js +2 -0
- package/lib/interfaces/NavigationAlert.js +9 -0
- package/lib/interfaces/NavigationInfo.js +2 -0
- package/lib/interfaces/NavigationStep.js +2 -0
- package/lib/interfaces/Pane.js +2 -0
- package/lib/interfaces/PauseReason.js +11 -0
- package/lib/interfaces/Place.js +2 -0
- package/lib/interfaces/TextConfiguration.js +2 -0
- package/lib/interfaces/TimeRemainingColor.js +2 -0
- package/lib/interfaces/TravelEstimates.js +2 -0
- package/lib/interfaces/VoiceControlState.js +2 -0
- package/lib/navigation/NavigationSession.js +53 -0
- package/lib/navigation/Trip.js +19 -0
- package/lib/templates/ActionSheetTemplate.js +15 -0
- package/lib/templates/AlertTemplate.js +15 -0
- package/lib/templates/ContactTemplate.js +15 -0
- package/lib/templates/GridTemplate.js +16 -0
- package/lib/templates/InformationTemplate.js +24 -0
- package/lib/templates/ListTemplate.js +67 -0
- package/lib/templates/MapTemplate.js +115 -0
- package/lib/templates/NowPlayingTemplate.js +17 -0
- package/lib/templates/PointOfInterestTemplate.js +16 -0
- package/lib/templates/SearchTemplate.js +41 -0
- package/lib/templates/TabBarTemplate.js +26 -0
- package/lib/templates/Template.js +74 -0
- package/lib/templates/VoiceControlTemplate.js +19 -0
- package/lib/templates/android/AndroidNavigationBaseTemplate.js +29 -0
- package/lib/templates/android/MessageTemplate.js +10 -0
- package/lib/templates/android/NavigationTemplate.js +16 -0
- package/lib/templates/android/PaneTemplate.js +10 -0
- package/lib/templates/android/PlaceListMapTemplate.js +18 -0
- package/lib/templates/android/PlaceListNavigationTemplate.js +19 -0
- package/lib/templates/android/RoutePreviewNavigationTemplate.js +22 -0
- package/package.json +71 -0
- package/react-native-carplay.podspec +21 -0
- package/src/CarPlay.ts +286 -0
- package/src/index.ts +50 -0
- package/src/interfaces/Action.ts +15 -0
- package/src/interfaces/AlertAction.ts +5 -0
- package/src/interfaces/BarButton.ts +41 -0
- package/src/interfaces/CarColor.ts +1 -0
- package/src/interfaces/GridButton.ts +25 -0
- package/src/interfaces/Header.ts +16 -0
- package/src/interfaces/ListItem.ts +84 -0
- package/src/interfaces/ListItemUpdate.ts +14 -0
- package/src/interfaces/ListSection.ts +21 -0
- package/src/interfaces/Maneuver.ts +30 -0
- package/src/interfaces/MapButton.ts +27 -0
- package/src/interfaces/NavigationAlert.ts +46 -0
- package/src/interfaces/NavigationInfo.ts +19 -0
- package/src/interfaces/NavigationStep.ts +17 -0
- package/src/interfaces/Pane.ts +29 -0
- package/src/interfaces/PauseReason.ts +7 -0
- package/src/interfaces/Place.ts +12 -0
- package/src/interfaces/TextConfiguration.ts +5 -0
- package/src/interfaces/TimeRemainingColor.ts +1 -0
- package/src/interfaces/TravelEstimates.ts +39 -0
- package/src/interfaces/VoiceControlState.ts +8 -0
- package/src/navigation/NavigationSession.ts +57 -0
- package/src/navigation/Trip.ts +36 -0
- package/src/templates/ActionSheetTemplate.ts +21 -0
- package/src/templates/AlertTemplate.ts +20 -0
- package/src/templates/ContactTemplate.ts +45 -0
- package/src/templates/GridTemplate.ts +45 -0
- package/src/templates/InformationTemplate.ts +42 -0
- package/src/templates/ListTemplate.ts +167 -0
- package/src/templates/MapTemplate.ts +231 -0
- package/src/templates/NowPlayingTemplate.ts +31 -0
- package/src/templates/PointOfInterestTemplate.ts +40 -0
- package/src/templates/SearchTemplate.ts +70 -0
- package/src/templates/TabBarTemplate.ts +56 -0
- package/src/templates/Template.ts +164 -0
- package/src/templates/VoiceControlTemplate.ts +25 -0
- package/src/templates/android/AndroidNavigationBaseTemplate.ts +46 -0
- package/src/templates/android/MessageTemplate.ts +19 -0
- package/src/templates/android/NavigationTemplate.ts +50 -0
- package/src/templates/android/PaneTemplate.ts +16 -0
- package/src/templates/android/PlaceListMapTemplate.ts +64 -0
- package/src/templates/android/PlaceListNavigationTemplate.ts +57 -0
- package/src/templates/android/RoutePreviewNavigationTemplate.ts +66 -0
package/ios/RNCarPlay.m
ADDED
|
@@ -0,0 +1,1755 @@
|
|
|
1
|
+
#import "RNCarPlay.h"
|
|
2
|
+
#import <React/RCTConvert.h>
|
|
3
|
+
#import <React/RCTRootView.h>
|
|
4
|
+
|
|
5
|
+
@implementation RNCarPlay
|
|
6
|
+
{
|
|
7
|
+
bool hasListeners;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@synthesize interfaceController;
|
|
11
|
+
@synthesize window;
|
|
12
|
+
@synthesize searchResultBlock;
|
|
13
|
+
@synthesize selectedResultBlock;
|
|
14
|
+
@synthesize isNowPlayingActive;
|
|
15
|
+
|
|
16
|
+
-(void)startObserving {
|
|
17
|
+
hasListeners = YES;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
-(void)stopObserving {
|
|
21
|
+
hasListeners = NO;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
+ (NSDictionary *) getConnectedWindowInformation: (CPWindow *) window API_AVAILABLE(ios(12.0)){
|
|
25
|
+
return @{
|
|
26
|
+
@"width": @(window.bounds.size.width),
|
|
27
|
+
@"height": @(window.bounds.size.height),
|
|
28
|
+
@"scale": @(window.screen.scale)
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
+ (void) connectWithInterfaceController:(CPInterfaceController*)interfaceController window:(CPWindow*)window API_AVAILABLE(ios(12.0)){
|
|
33
|
+
RNCPStore * store = [RNCPStore sharedManager];
|
|
34
|
+
store.interfaceController = interfaceController;
|
|
35
|
+
store.window = window;
|
|
36
|
+
[store setConnected:true];
|
|
37
|
+
|
|
38
|
+
RNCarPlay *cp = [RNCarPlay allocWithZone:nil];
|
|
39
|
+
if (cp.bridge) {
|
|
40
|
+
[cp sendEventWithName:@"didConnect" body:[self getConnectedWindowInformation:window]];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
+ (void) disconnect {
|
|
45
|
+
RNCarPlay *cp = [RNCarPlay allocWithZone:nil];
|
|
46
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
47
|
+
[store setConnected:false];
|
|
48
|
+
[[store.window subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
|
49
|
+
|
|
50
|
+
if (cp.bridge) {
|
|
51
|
+
[cp sendEventWithName:@"didDisconnect" body:@{}];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
RCT_EXPORT_MODULE();
|
|
56
|
+
|
|
57
|
+
+ (id)allocWithZone:(NSZone *)zone {
|
|
58
|
+
static RNCarPlay *sharedInstance = nil;
|
|
59
|
+
static dispatch_once_t onceToken;
|
|
60
|
+
dispatch_once(&onceToken, ^{
|
|
61
|
+
sharedInstance = [super allocWithZone:zone];
|
|
62
|
+
});
|
|
63
|
+
return sharedInstance;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
- (NSArray<NSString *> *)supportedEvents
|
|
67
|
+
{
|
|
68
|
+
return @[
|
|
69
|
+
@"didConnect",
|
|
70
|
+
@"didDisconnect",
|
|
71
|
+
// interface
|
|
72
|
+
@"barButtonPressed",
|
|
73
|
+
@"backButtonPressed",
|
|
74
|
+
@"didAppear",
|
|
75
|
+
@"didDisappear",
|
|
76
|
+
@"willAppear",
|
|
77
|
+
@"willDisappear",
|
|
78
|
+
@"buttonPressed",
|
|
79
|
+
// grid
|
|
80
|
+
@"gridButtonPressed",
|
|
81
|
+
// information
|
|
82
|
+
@"actionButtonPressed",
|
|
83
|
+
// list
|
|
84
|
+
@"didSelectListItem",
|
|
85
|
+
// search
|
|
86
|
+
@"updatedSearchText",
|
|
87
|
+
@"searchButtonPressed",
|
|
88
|
+
@"selectedResult",
|
|
89
|
+
// tabbar
|
|
90
|
+
@"didSelectTemplate",
|
|
91
|
+
// nowplaying
|
|
92
|
+
@"upNextButtonPressed",
|
|
93
|
+
@"albumArtistButtonPressed",
|
|
94
|
+
// poi
|
|
95
|
+
@"didSelectPointOfInterest",
|
|
96
|
+
// map
|
|
97
|
+
@"mapButtonPressed",
|
|
98
|
+
@"didUpdatePanGestureWithTranslation",
|
|
99
|
+
@"didEndPanGestureWithVelocity",
|
|
100
|
+
@"panBeganWithDirection",
|
|
101
|
+
@"panEndedWithDirection",
|
|
102
|
+
@"panWithDirection",
|
|
103
|
+
@"didBeginPanGesture",
|
|
104
|
+
@"didDismissPanningInterface",
|
|
105
|
+
@"willDismissPanningInterface",
|
|
106
|
+
@"didShowPanningInterface",
|
|
107
|
+
@"didDismissNavigationAlert",
|
|
108
|
+
@"willDismissNavigationAlert",
|
|
109
|
+
@"didShowNavigationAlert",
|
|
110
|
+
@"willShowNavigationAlert",
|
|
111
|
+
@"didCancelNavigation",
|
|
112
|
+
@"alertActionPressed",
|
|
113
|
+
@"selectedPreviewForTrip",
|
|
114
|
+
@"startedTrip",
|
|
115
|
+
@"didSelectRowItem",
|
|
116
|
+
@"templateLoaded"
|
|
117
|
+
];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
- (dispatch_queue_t)methodQueue
|
|
121
|
+
{
|
|
122
|
+
return dispatch_get_main_queue();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
-(UIImage *)imageWithTint:(UIImage *)image andTintColor:(UIColor *)tintColor {
|
|
127
|
+
UIImage *imageNew = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
|
128
|
+
UIImageView *imageView = [[UIImageView alloc] initWithImage:imageNew];
|
|
129
|
+
imageView.tintColor = tintColor;
|
|
130
|
+
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 0.0);
|
|
131
|
+
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
|
|
132
|
+
UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
133
|
+
UIGraphicsEndImageContext();
|
|
134
|
+
return tintedImage;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
-(UIImage*)dynamicImageWithNormalImage:(UIImage*)normalImage darkImage:(UIImage*)darkImage {
|
|
138
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
139
|
+
if (normalImage == nil || darkImage == nil) {
|
|
140
|
+
return normalImage ? : darkImage;
|
|
141
|
+
}
|
|
142
|
+
if (@available(iOS 14.0, *)) {
|
|
143
|
+
UIImageAsset* imageAsset = darkImage.imageAsset;
|
|
144
|
+
|
|
145
|
+
// darkImage
|
|
146
|
+
UITraitCollection* darkImageTraitCollection = [UITraitCollection traitCollectionWithTraitsFromCollections:
|
|
147
|
+
@[[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark],
|
|
148
|
+
[UITraitCollection traitCollectionWithDisplayScale:normalImage.scale]]];
|
|
149
|
+
[imageAsset registerImage:normalImage withTraitCollection:darkImageTraitCollection];
|
|
150
|
+
|
|
151
|
+
return [imageAsset imageWithTraitCollection: store.interfaceController.carTraitCollection];
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
return normalImage;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
- (UIImage *)imageWithSize:(UIImage *)image convertToSize:(CGSize)size {
|
|
159
|
+
UIGraphicsBeginImageContext(size);
|
|
160
|
+
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
|
|
161
|
+
UIImage *destImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
162
|
+
UIGraphicsEndImageContext();
|
|
163
|
+
return destImage;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
RCT_EXPORT_METHOD(checkForConnection) {
|
|
167
|
+
if (@available(iOS 12.0, *)) {
|
|
168
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
169
|
+
if ([store isConnected] && hasListeners) {
|
|
170
|
+
[self sendEventWithName:@"didConnect" body:[RNCarPlay getConnectedWindowInformation: store.window]];
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
RCT_EXPORT_METHOD(createTemplate:(NSString *)templateId config:(NSDictionary*)config) {
|
|
176
|
+
BOOL updatingTemplate = [RCTConvert BOOL:config[@"updatingTemplate"]];
|
|
177
|
+
BOOL needsTemplateLoadedCallback = [RCTConvert BOOL:config[@"needsTemplateLoadedCallback"]];
|
|
178
|
+
if (updatingTemplate) {
|
|
179
|
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
180
|
+
[self createTemplateMethod:templateId config:config];
|
|
181
|
+
|
|
182
|
+
if (needsTemplateLoadedCallback) {
|
|
183
|
+
NSMutableDictionary *bodyDictionary = [NSMutableDictionary dictionary];
|
|
184
|
+
if (templateId) {
|
|
185
|
+
bodyDictionary[@"templateId"] = templateId;
|
|
186
|
+
}
|
|
187
|
+
[self sendEventWithName:@"templateLoaded" body:bodyDictionary];
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
} else {
|
|
191
|
+
[self createTemplateMethod:templateId config:config];
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
- (void)createTemplateMethod:(NSString *)templateId config:(NSDictionary*)config {
|
|
196
|
+
if (@available(iOS 12.0, *)) {
|
|
197
|
+
// Get the shared instance of the RNCPStore class
|
|
198
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
199
|
+
|
|
200
|
+
// Extract values from the 'config' dictionary
|
|
201
|
+
NSString *type = [RCTConvert NSString:config[@"type"]];
|
|
202
|
+
NSString *title = [RCTConvert NSString:config[@"title"]];
|
|
203
|
+
NSArray *leadingNavigationBarButtons = [self parseBarButtons:[RCTConvert NSArray:config[@"leadingNavigationBarButtons"]] templateId:templateId];
|
|
204
|
+
NSArray *trailingNavigationBarButtons = [self parseBarButtons:[RCTConvert NSArray:config[@"trailingNavigationBarButtons"]] templateId:templateId];
|
|
205
|
+
|
|
206
|
+
// Create a new CPTemplate object
|
|
207
|
+
CPTemplate *carPlayTemplate = [[CPTemplate alloc] init];
|
|
208
|
+
|
|
209
|
+
if ([type isEqualToString:@"search"]) {
|
|
210
|
+
CPSearchTemplate *searchTemplate = [[CPSearchTemplate alloc] init];
|
|
211
|
+
searchTemplate.delegate = self;
|
|
212
|
+
carPlayTemplate = searchTemplate;
|
|
213
|
+
}
|
|
214
|
+
else if ([type isEqualToString:@"grid"]) {
|
|
215
|
+
NSArray *buttons = [self parseGridButtons:[RCTConvert NSArray:config[@"buttons"]] templateId:templateId];
|
|
216
|
+
CPGridTemplate *gridTemplate = [[CPGridTemplate alloc] initWithTitle:title gridButtons:buttons];
|
|
217
|
+
[gridTemplate setLeadingNavigationBarButtons:leadingNavigationBarButtons];
|
|
218
|
+
[gridTemplate setTrailingNavigationBarButtons:trailingNavigationBarButtons];
|
|
219
|
+
carPlayTemplate = gridTemplate;
|
|
220
|
+
}
|
|
221
|
+
else if ([type isEqualToString:@"list"]) {
|
|
222
|
+
if (@available(iOS 14, *)) {
|
|
223
|
+
NSArray *sections = [self parseSections:[RCTConvert NSArray:config[@"sections"]] templateId:templateId];
|
|
224
|
+
CPListTemplate *listTemplate;
|
|
225
|
+
if (@available(iOS 15.0, *)) {
|
|
226
|
+
if ([config objectForKey:@"assistant"]) {
|
|
227
|
+
NSDictionary *assistant = [config objectForKey:@"assistant"];
|
|
228
|
+
BOOL _enabled = [assistant valueForKey:@"enabled"];
|
|
229
|
+
if (_enabled) {
|
|
230
|
+
CPAssistantCellConfiguration *conf = [[CPAssistantCellConfiguration alloc] initWithPosition:CPAssistantCellPositionTop visibility:CPAssistantCellVisibilityAlways assistantAction:CPAssistantCellActionTypePlayMedia];
|
|
231
|
+
listTemplate = [[CPListTemplate alloc] initWithTitle:title sections:sections assistantCellConfiguration:conf];
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (listTemplate == nil) {
|
|
236
|
+
// Fallback on earlier versions
|
|
237
|
+
listTemplate = [[CPListTemplate alloc] initWithTitle:title sections:sections];
|
|
238
|
+
}
|
|
239
|
+
[listTemplate setLeadingNavigationBarButtons:leadingNavigationBarButtons];
|
|
240
|
+
[listTemplate setTrailingNavigationBarButtons:trailingNavigationBarButtons];
|
|
241
|
+
if (![RCTConvert BOOL:config[@"backButtonHidden"]]) {
|
|
242
|
+
NSString *title = [RCTConvert NSString:config[@"backButtonTitle"]];
|
|
243
|
+
if (!title) {
|
|
244
|
+
title = @"Back";
|
|
245
|
+
}
|
|
246
|
+
title = [@" " stringByAppendingString:title];
|
|
247
|
+
CPBarButton *backButton = [[CPBarButton alloc] initWithTitle:title handler:^(CPBarButton * _Nonnull barButton) {
|
|
248
|
+
if (self->hasListeners) {
|
|
249
|
+
[self sendEventWithName:@"backButtonPressed" body:@{@"templateId":templateId}];
|
|
250
|
+
}
|
|
251
|
+
[self popTemplate:false];
|
|
252
|
+
}];
|
|
253
|
+
[listTemplate setBackButton:backButton];
|
|
254
|
+
}
|
|
255
|
+
if (config[@"emptyViewTitleVariants"]) {
|
|
256
|
+
listTemplate.emptyViewTitleVariants = [RCTConvert NSArray:config[@"emptyViewTitleVariants"]];
|
|
257
|
+
}
|
|
258
|
+
if (config[@"emptyViewSubtitleVariants"]) {
|
|
259
|
+
listTemplate.emptyViewSubtitleVariants = [RCTConvert NSArray:config[@"emptyViewSubtitleVariants"]];
|
|
260
|
+
}
|
|
261
|
+
listTemplate.delegate = self;
|
|
262
|
+
carPlayTemplate = listTemplate;
|
|
263
|
+
} else {
|
|
264
|
+
NSArray *sections = [self parseSections:[RCTConvert NSArray:config[@"sections"]] templateId:templateId];
|
|
265
|
+
CPListTemplate *listTemplate = [[CPListTemplate alloc] initWithTitle:title sections:sections];
|
|
266
|
+
[listTemplate setLeadingNavigationBarButtons:leadingNavigationBarButtons];
|
|
267
|
+
[listTemplate setTrailingNavigationBarButtons:trailingNavigationBarButtons];
|
|
268
|
+
listTemplate.delegate = self;
|
|
269
|
+
carPlayTemplate = listTemplate;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else if ([type isEqualToString:@"map"]) {
|
|
273
|
+
CPMapTemplate *mapTemplate = [[CPMapTemplate alloc] init];
|
|
274
|
+
|
|
275
|
+
[self applyConfigForMapTemplate:mapTemplate templateId:templateId config:config];
|
|
276
|
+
[mapTemplate setLeadingNavigationBarButtons:leadingNavigationBarButtons];
|
|
277
|
+
[mapTemplate setTrailingNavigationBarButtons:trailingNavigationBarButtons];
|
|
278
|
+
[mapTemplate setUserInfo:@{ @"templateId": templateId }];
|
|
279
|
+
mapTemplate.mapDelegate = self;
|
|
280
|
+
|
|
281
|
+
carPlayTemplate = mapTemplate;
|
|
282
|
+
} else if ([type isEqualToString:@"voicecontrol"]) {
|
|
283
|
+
CPVoiceControlTemplate *voiceTemplate = [[CPVoiceControlTemplate alloc] initWithVoiceControlStates: [self parseVoiceControlStates:config[@"voiceControlStates"]]];
|
|
284
|
+
carPlayTemplate = voiceTemplate;
|
|
285
|
+
} else if ([type isEqualToString:@"nowplaying"]) {
|
|
286
|
+
if (@available(iOS 14, *)) {
|
|
287
|
+
CPNowPlayingTemplate *nowPlayingTemplate = [CPNowPlayingTemplate sharedTemplate];
|
|
288
|
+
[nowPlayingTemplate setAlbumArtistButtonEnabled:[RCTConvert BOOL:config[@"albumArtistButtonEnabled"]]];
|
|
289
|
+
[nowPlayingTemplate setUpNextTitle:[RCTConvert NSString:config[@"upNextButtonTitle"]]];
|
|
290
|
+
[nowPlayingTemplate setUpNextButtonEnabled:[RCTConvert BOOL:config[@"upNextButtonEnabled"]]];
|
|
291
|
+
NSMutableArray<CPNowPlayingButton *> *buttons = [NSMutableArray new];
|
|
292
|
+
NSArray<NSDictionary*> *_buttons = [RCTConvert NSDictionaryArray:config[@"buttons"]];
|
|
293
|
+
|
|
294
|
+
NSDictionary *buttonImagesNamesMapping = @{
|
|
295
|
+
@"heart": @"HeartIcon",
|
|
296
|
+
@"heart-outlined": @"HeartOutlinedIcon",
|
|
297
|
+
@"clock": @"ClockNowIcon",
|
|
298
|
+
@"arrow-down-circle": @"ArrowDownCircleIcon",
|
|
299
|
+
@"md-close": @"CloseIcon",
|
|
300
|
+
@"repeat": @"RepeatIcon",
|
|
301
|
+
@"shuffle": @"ShuffleIcon"
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
for (NSDictionary *_button in _buttons) {
|
|
305
|
+
NSString *id = [RCTConvert NSString:_button[@"id"]];
|
|
306
|
+
NSString *imageName = [RCTConvert NSString:_button[@"imageName"]];
|
|
307
|
+
BOOL selected = [RCTConvert BOOL:_button[@"selected"]];
|
|
308
|
+
NSDictionary *body = @{@"templateId":templateId, @"id": id};
|
|
309
|
+
UIImage *buttonImage = [UIImage imageNamed:buttonImagesNamesMapping[imageName]];
|
|
310
|
+
if (buttonImage) {
|
|
311
|
+
CPNowPlayingButton *button = [CPNowPlayingImageButton.alloc initWithImage:buttonImage handler:^(CPNowPlayingImageButton *b) {
|
|
312
|
+
if (self->hasListeners) {
|
|
313
|
+
[self sendEventWithName:@"buttonPressed" body:body];
|
|
314
|
+
}
|
|
315
|
+
}];
|
|
316
|
+
button.selected = selected;
|
|
317
|
+
[buttons addObject:button];
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
[nowPlayingTemplate updateNowPlayingButtons:buttons];
|
|
321
|
+
carPlayTemplate = nowPlayingTemplate;
|
|
322
|
+
}
|
|
323
|
+
} else if ([type isEqualToString:@"tabbar"]) {
|
|
324
|
+
if (@available(iOS 14, *)) {
|
|
325
|
+
CPTabBarTemplate *tabBarTemplate = [[CPTabBarTemplate alloc] initWithTemplates:[self parseTemplatesFrom:config]];
|
|
326
|
+
tabBarTemplate.delegate = self;
|
|
327
|
+
carPlayTemplate = tabBarTemplate;
|
|
328
|
+
}
|
|
329
|
+
} else if ([type isEqualToString:@"contact"]) {
|
|
330
|
+
if (@available(iOS 14, *)) {
|
|
331
|
+
NSString *nm = [RCTConvert NSString:config[@"name"]];
|
|
332
|
+
UIImage *img = [RCTConvert UIImage:config[@"image"]];
|
|
333
|
+
CPContact *contact = [[CPContact alloc] initWithName:nm image:img];
|
|
334
|
+
[contact setSubtitle:config[@"subtitle"]];
|
|
335
|
+
[contact setActions:[self parseButtons:config[@"actions"] templateId:templateId]];
|
|
336
|
+
CPContactTemplate *contactTemplate = [[CPContactTemplate alloc] initWithContact:contact];
|
|
337
|
+
carPlayTemplate = contactTemplate;
|
|
338
|
+
}
|
|
339
|
+
} else if ([type isEqualToString:@"actionsheet"]) {
|
|
340
|
+
NSString *title = [RCTConvert NSString:config[@"title"]];
|
|
341
|
+
NSString *message = [RCTConvert NSString:config[@"message"]];
|
|
342
|
+
NSMutableArray<CPAlertAction *> *actions = [NSMutableArray new];
|
|
343
|
+
NSArray<NSDictionary*> *_actions = [RCTConvert NSDictionaryArray:config[@"actions"]];
|
|
344
|
+
for (NSDictionary *_action in _actions) {
|
|
345
|
+
CPAlertAction *action = [[CPAlertAction alloc] initWithTitle:[RCTConvert NSString:_action[@"title"]] style:[RCTConvert CPAlertActionStyle:_action[@"style"]] handler:^(CPAlertAction *a) {
|
|
346
|
+
if (self->hasListeners) {
|
|
347
|
+
[self sendEventWithName:@"actionButtonPressed" body:@{@"templateId":templateId, @"id": _action[@"id"] }];
|
|
348
|
+
}
|
|
349
|
+
}];
|
|
350
|
+
[actions addObject:action];
|
|
351
|
+
}
|
|
352
|
+
CPActionSheetTemplate *actionSheetTemplate = [[CPActionSheetTemplate alloc] initWithTitle:title message:message actions:actions];
|
|
353
|
+
carPlayTemplate = actionSheetTemplate;
|
|
354
|
+
} else if ([type isEqualToString:@"alert"]) {
|
|
355
|
+
NSMutableArray<CPAlertAction *> *actions = [NSMutableArray new];
|
|
356
|
+
NSArray<NSDictionary*> *_actions = [RCTConvert NSDictionaryArray:config[@"actions"]];
|
|
357
|
+
for (NSDictionary *_action in _actions) {
|
|
358
|
+
CPAlertAction *action = [[CPAlertAction alloc] initWithTitle:[RCTConvert NSString:_action[@"title"]] style:[RCTConvert CPAlertActionStyle:_action[@"style"]] handler:^(CPAlertAction *a) {
|
|
359
|
+
if (self->hasListeners) {
|
|
360
|
+
[self sendEventWithName:@"actionButtonPressed" body:@{@"templateId":templateId, @"id": _action[@"id"] }];
|
|
361
|
+
}
|
|
362
|
+
}];
|
|
363
|
+
[actions addObject:action];
|
|
364
|
+
}
|
|
365
|
+
NSArray<NSString*>* titleVariants = [RCTConvert NSArray:config[@"titleVariants"]];
|
|
366
|
+
CPAlertTemplate *alertTemplate = [[CPAlertTemplate alloc] initWithTitleVariants:titleVariants actions:actions];
|
|
367
|
+
carPlayTemplate = alertTemplate;
|
|
368
|
+
} else if ([type isEqualToString:@"poi"]) {
|
|
369
|
+
if (@available(iOS 14, *)) {
|
|
370
|
+
NSString *title = [RCTConvert NSString:config[@"title"]];
|
|
371
|
+
NSMutableArray<__kindof CPPointOfInterest *> * items = [NSMutableArray new];
|
|
372
|
+
NSUInteger selectedIndex = 0;
|
|
373
|
+
|
|
374
|
+
NSArray<NSDictionary*> *_items = [RCTConvert NSDictionaryArray:config[@"items"]];
|
|
375
|
+
for (NSDictionary *_item in _items) {
|
|
376
|
+
CPPointOfInterest *poi = [RCTConvert CPPointOfInterest:_item];
|
|
377
|
+
[poi setUserInfo:_item];
|
|
378
|
+
[items addObject:poi];
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
CPPointOfInterestTemplate *poiTemplate = [[CPPointOfInterestTemplate alloc] initWithTitle:title pointsOfInterest:items selectedIndex:selectedIndex];
|
|
382
|
+
poiTemplate.pointOfInterestDelegate = self;
|
|
383
|
+
carPlayTemplate = poiTemplate;
|
|
384
|
+
}
|
|
385
|
+
} else if ([type isEqualToString:@"information"]) {
|
|
386
|
+
if (@available(iOS 14, *)) {
|
|
387
|
+
NSString *title = [RCTConvert NSString:config[@"title"]];
|
|
388
|
+
CPInformationTemplateLayout layout = [RCTConvert BOOL:config[@"leading"]] ? CPInformationTemplateLayoutLeading : CPInformationTemplateLayoutTwoColumn;
|
|
389
|
+
NSMutableArray<__kindof CPInformationItem *> * items = [NSMutableArray new];
|
|
390
|
+
NSMutableArray<__kindof CPTextButton *> * actions = [NSMutableArray new];
|
|
391
|
+
|
|
392
|
+
NSArray<NSDictionary*> *_items = [RCTConvert NSDictionaryArray:config[@"items"]];
|
|
393
|
+
for (NSDictionary *_item in _items) {
|
|
394
|
+
[items addObject:[[CPInformationItem alloc] initWithTitle:_item[@"title"] detail:_item[@"detail"]]];
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
NSArray<NSDictionary*> *_actions = [RCTConvert NSDictionaryArray:config[@"actions"]];
|
|
398
|
+
for (NSDictionary *_action in _actions) {
|
|
399
|
+
CPTextButton *action = [[CPTextButton alloc] initWithTitle:_action[@"title"] textStyle:CPTextButtonStyleNormal handler:^(__kindof CPTextButton * _Nonnull contactButton) {
|
|
400
|
+
if (self->hasListeners) {
|
|
401
|
+
[self sendEventWithName:@"actionButtonPressed" body:@{@"templateId":templateId, @"id": _action[@"id"] }];
|
|
402
|
+
}
|
|
403
|
+
}];
|
|
404
|
+
[actions addObject:action];
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
CPInformationTemplate *informationTemplate = [[CPInformationTemplate alloc] initWithTitle:title layout:layout items:items actions:actions];
|
|
408
|
+
carPlayTemplate = informationTemplate;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (@available(iOS 14, *)) {
|
|
413
|
+
if (config[@"tabSystemItem"]) {
|
|
414
|
+
carPlayTemplate.tabSystemItem = [RCTConvert NSInteger:config[@"tabSystemItem"]];
|
|
415
|
+
}
|
|
416
|
+
if (config[@"tabSystemImageName"]) {
|
|
417
|
+
carPlayTemplate.tabImage = [UIImage systemImageNamed:[RCTConvert NSString:config[@"tabSystemImageName"]]];
|
|
418
|
+
}
|
|
419
|
+
if (config[@"tabImage"]) {
|
|
420
|
+
carPlayTemplate.tabImage = [RCTConvert UIImage:config[@"tabImage"]];
|
|
421
|
+
}
|
|
422
|
+
if (config[@"tabImageName"]) {
|
|
423
|
+
NSDictionary *tabImagesNamesMapping = @{
|
|
424
|
+
@"home": @"HomeIcon",
|
|
425
|
+
@"clock": @"ClockTabIcon",
|
|
426
|
+
@"search": @"SearchIcon",
|
|
427
|
+
@"music": @"MusicIcon",
|
|
428
|
+
};
|
|
429
|
+
NSString *imageName = [RCTConvert NSString:config[@"tabImageName"]];
|
|
430
|
+
carPlayTemplate.tabImage = [UIImage imageNamed: tabImagesNamesMapping[imageName]];
|
|
431
|
+
}
|
|
432
|
+
if (config[@"tabTitle"]) {
|
|
433
|
+
carPlayTemplate.tabTitle = [RCTConvert NSString:config[@"tabTitle"]];
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
[carPlayTemplate setUserInfo:@{ @"templateId": templateId }];
|
|
438
|
+
[store setTemplate:templateId template:carPlayTemplate];
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
RCT_EXPORT_METHOD(createTrip:(NSString*)tripId config:(NSDictionary*)config) {
|
|
443
|
+
if (@available(iOS 12.0, *)) {
|
|
444
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
445
|
+
CPTrip *trip = [self parseTrip:config];
|
|
446
|
+
NSMutableDictionary *userInfo = trip.userInfo;
|
|
447
|
+
if (!userInfo) {
|
|
448
|
+
userInfo = [[NSMutableDictionary alloc] init];
|
|
449
|
+
trip.userInfo = userInfo;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
[userInfo setValue:tripId forKey:@"id"];
|
|
453
|
+
[store setTrip:tripId trip:trip];
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
RCT_EXPORT_METHOD(updateTravelEstimatesForTrip:(NSString*)templateId tripId:(NSString*)tripId travelEstimates:(NSDictionary*)travelEstimates timeRemainingColor:(NSUInteger*)timeRemainingColor) {
|
|
458
|
+
if (@available(iOS 12.0, *)) {
|
|
459
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
460
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
461
|
+
if (template) {
|
|
462
|
+
CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
|
|
463
|
+
CPTrip *trip = [[RNCPStore sharedManager] findTripById:tripId];
|
|
464
|
+
if (trip) {
|
|
465
|
+
CPTravelEstimates *estimates = [self parseTravelEstimates:travelEstimates];
|
|
466
|
+
[mapTemplate updateTravelEstimates:estimates forTrip:trip withTimeRemainingColor:(CPTimeRemainingColor) timeRemainingColor];
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
RCT_REMAP_METHOD(startNavigationSession,
|
|
473
|
+
templateId:(NSString *)templateId
|
|
474
|
+
tripId:(NSString *)tripId
|
|
475
|
+
startNavigationSessionWithResolver:(RCTPromiseResolveBlock)resolve
|
|
476
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
477
|
+
if (@available(iOS 12.0, *)) {
|
|
478
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
479
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
480
|
+
if (template) {
|
|
481
|
+
CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
|
|
482
|
+
CPTrip *trip = [[RNCPStore sharedManager] findTripById:tripId];
|
|
483
|
+
if (trip) {
|
|
484
|
+
CPNavigationSession *navigationSession = [mapTemplate startNavigationSessionForTrip:trip];
|
|
485
|
+
[store setNavigationSession:tripId navigationSession:navigationSession];
|
|
486
|
+
resolve(@{ @"tripId": tripId, @"navigationSessionId": tripId });
|
|
487
|
+
}
|
|
488
|
+
} else {
|
|
489
|
+
reject(@"template_not_found", @"Template not found in store", nil);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
RCT_EXPORT_METHOD(updateManeuversNavigationSession:(NSString*)navigationSessionId maneuvers:(NSArray*)maneuvers) {
|
|
495
|
+
if (@available(iOS 12.0, *)) {
|
|
496
|
+
CPNavigationSession* navigationSession = [[RNCPStore sharedManager] findNavigationSessionById:navigationSessionId];
|
|
497
|
+
if (navigationSession) {
|
|
498
|
+
NSMutableArray<CPManeuver*>* upcomingManeuvers = [NSMutableArray array];
|
|
499
|
+
for (NSDictionary *maneuver in maneuvers) {
|
|
500
|
+
[upcomingManeuvers addObject:[self parseManeuver:maneuver]];
|
|
501
|
+
}
|
|
502
|
+
[navigationSession setUpcomingManeuvers:upcomingManeuvers];
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
RCT_EXPORT_METHOD(updateTravelEstimatesNavigationSession:(NSString*)navigationSessionId maneuverIndex:(NSUInteger)maneuverIndex travelEstimates:(NSDictionary*)travelEstimates) {
|
|
508
|
+
if (@available(iOS 12.0, *)) {
|
|
509
|
+
CPNavigationSession* navigationSession = [[RNCPStore sharedManager] findNavigationSessionById:navigationSessionId];
|
|
510
|
+
if (navigationSession) {
|
|
511
|
+
CPManeuver *maneuver = [[navigationSession upcomingManeuvers] objectAtIndex:maneuverIndex];
|
|
512
|
+
if (maneuver) {
|
|
513
|
+
[navigationSession updateTravelEstimates:[self parseTravelEstimates:travelEstimates] forManeuver:maneuver];
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
RCT_EXPORT_METHOD(pauseNavigationSession:(NSString*)navigationSessionId reason:(NSUInteger*)reason description:(NSString*)description) {
|
|
520
|
+
if (@available(iOS 12.0, *)) {
|
|
521
|
+
CPNavigationSession* navigationSession = [[RNCPStore sharedManager] findNavigationSessionById:navigationSessionId];
|
|
522
|
+
if (navigationSession) {
|
|
523
|
+
[navigationSession pauseTripForReason:(CPTripPauseReason) reason description:description];
|
|
524
|
+
} else {
|
|
525
|
+
NSLog(@"Could not find session");
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
RCT_EXPORT_METHOD(cancelNavigationSession:(NSString*)navigationSessionId) {
|
|
531
|
+
if (@available(iOS 12.0, *)) {
|
|
532
|
+
CPNavigationSession* navigationSession = [[RNCPStore sharedManager] findNavigationSessionById:navigationSessionId];
|
|
533
|
+
if (navigationSession) {
|
|
534
|
+
[navigationSession cancelTrip];
|
|
535
|
+
} else {
|
|
536
|
+
NSLog(@"Could not cancel. No session found.");
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
RCT_EXPORT_METHOD(finishNavigationSession:(NSString*)navigationSessionId) {
|
|
542
|
+
if (@available(iOS 12.0, *)) {
|
|
543
|
+
CPNavigationSession* navigationSession = [[RNCPStore sharedManager] findNavigationSessionById:navigationSessionId];
|
|
544
|
+
if (navigationSession) {
|
|
545
|
+
[navigationSession finishTrip];
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
RCT_EXPORT_METHOD(setRootTemplate:(NSString *)templateId animated:(BOOL)animated) {
|
|
551
|
+
if (@available(iOS 12.0, *)) {
|
|
552
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
553
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
554
|
+
|
|
555
|
+
store.interfaceController.delegate = self;
|
|
556
|
+
|
|
557
|
+
if (template) {
|
|
558
|
+
if (@available(iOS 14, *)) {
|
|
559
|
+
[store.interfaceController setRootTemplate:template animated:animated completion:^(BOOL done, NSError * _Nullable err) {
|
|
560
|
+
if (err) {
|
|
561
|
+
NSLog(@"error - setRootTemplate %@", err);
|
|
562
|
+
}
|
|
563
|
+
}];
|
|
564
|
+
} else {
|
|
565
|
+
[store.interfaceController setRootTemplate:template animated:animated];
|
|
566
|
+
}
|
|
567
|
+
} else {
|
|
568
|
+
NSLog(@"Failed to find template %@", template);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
RCT_EXPORT_METHOD(pushTemplate:(NSString *)templateId animated:(BOOL)animated) {
|
|
574
|
+
if (@available(iOS 12.0, *)) {
|
|
575
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
576
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
577
|
+
if (template) {
|
|
578
|
+
if (@available(iOS 14, *)) {
|
|
579
|
+
[store.interfaceController pushTemplate:template animated:animated completion:^(BOOL done, NSError * _Nullable err) {
|
|
580
|
+
if (err) {
|
|
581
|
+
NSLog(@"error - pushTemplate %@", err);
|
|
582
|
+
}
|
|
583
|
+
}];
|
|
584
|
+
} else {
|
|
585
|
+
[store.interfaceController pushTemplate:template animated:animated];
|
|
586
|
+
}
|
|
587
|
+
} else {
|
|
588
|
+
NSLog(@"Failed to find template %@", template);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
RCT_EXPORT_METHOD(popToTemplate:(NSString *)templateId animated:(BOOL)animated) {
|
|
594
|
+
if (@available(iOS 12.0, *)) {
|
|
595
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
596
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
597
|
+
if (template) {
|
|
598
|
+
if (@available(iOS 14, *)) {
|
|
599
|
+
[store.interfaceController popToTemplate:template animated:animated completion:^(BOOL done, NSError * _Nullable err) {
|
|
600
|
+
if (err) {
|
|
601
|
+
NSLog(@"error - popToTemplate %@", err);
|
|
602
|
+
}
|
|
603
|
+
}];
|
|
604
|
+
} else {
|
|
605
|
+
[store.interfaceController popToTemplate:template animated:animated];
|
|
606
|
+
}
|
|
607
|
+
} else {
|
|
608
|
+
NSLog(@"Failed to find template %@", template);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
RCT_EXPORT_METHOD(popToRootTemplate:(BOOL)animated) {
|
|
614
|
+
if (@available(iOS 12.0, *)) {
|
|
615
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
616
|
+
if (@available(iOS 14, *)) {
|
|
617
|
+
[store.interfaceController popToRootTemplateAnimated:animated completion:^(BOOL done, NSError * _Nullable err) {
|
|
618
|
+
if (err) {
|
|
619
|
+
NSLog(@"error - popToRootTemplate %@", err);
|
|
620
|
+
}
|
|
621
|
+
}];
|
|
622
|
+
} else {
|
|
623
|
+
[store.interfaceController popToRootTemplateAnimated:animated];
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
RCT_EXPORT_METHOD(popTemplate:(BOOL)animated) {
|
|
629
|
+
if (@available(iOS 12.0, *)) {
|
|
630
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
631
|
+
if (@available(iOS 14, *)) {
|
|
632
|
+
[store.interfaceController popTemplateAnimated:animated completion:^(BOOL done, NSError * _Nullable err) {
|
|
633
|
+
if (err) {
|
|
634
|
+
NSLog(@"error - popTemplate %@", err);
|
|
635
|
+
}
|
|
636
|
+
}];
|
|
637
|
+
} else {
|
|
638
|
+
[store.interfaceController popTemplateAnimated:animated];
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
RCT_EXPORT_METHOD(presentTemplate:(NSString *)templateId animated:(BOOL)animated) {
|
|
644
|
+
if (@available(iOS 12.0, *)) {
|
|
645
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
646
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
647
|
+
if (template) {
|
|
648
|
+
if (@available(iOS 14, *)) {
|
|
649
|
+
[store.interfaceController presentTemplate:template animated:animated completion:^(BOOL done, NSError * _Nullable err) {
|
|
650
|
+
if (err) {
|
|
651
|
+
NSLog(@"error - presentTemplate %@", err);
|
|
652
|
+
}
|
|
653
|
+
}];
|
|
654
|
+
} else {
|
|
655
|
+
[store.interfaceController presentTemplate:template animated:animated];
|
|
656
|
+
}
|
|
657
|
+
} else {
|
|
658
|
+
NSLog(@"Failed to find template %@", template);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
RCT_EXPORT_METHOD(dismissTemplate:(BOOL)animated) {
|
|
664
|
+
if (@available(iOS 12.0, *)) {
|
|
665
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
666
|
+
[store.interfaceController dismissTemplateAnimated:animated];
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
RCT_EXPORT_METHOD(updateListTemplate:(NSString*)templateId config:(NSDictionary*)config) {
|
|
671
|
+
if (@available(iOS 14, *)) {
|
|
672
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
673
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
674
|
+
if (template && [template isKindOfClass:[CPListTemplate class]]) {
|
|
675
|
+
CPListTemplate *listTemplate = (CPListTemplate *)template;
|
|
676
|
+
if (config[@"leadingNavigationBarButtons"]) {
|
|
677
|
+
NSArray *leadingNavigationBarButtons = [self parseBarButtons:[RCTConvert NSArray:config[@"leadingNavigationBarButtons"]] templateId:templateId];
|
|
678
|
+
[listTemplate setLeadingNavigationBarButtons:leadingNavigationBarButtons];
|
|
679
|
+
}
|
|
680
|
+
if (config[@"trailingNavigationBarButtons"]) {
|
|
681
|
+
NSArray *trailingNavigationBarButtons = [self parseBarButtons:[RCTConvert NSArray:config[@"trailingNavigationBarButtons"]] templateId:templateId];
|
|
682
|
+
[listTemplate setTrailingNavigationBarButtons:trailingNavigationBarButtons];
|
|
683
|
+
}
|
|
684
|
+
if (config[@"emptyViewTitleVariants"]) {
|
|
685
|
+
listTemplate.emptyViewTitleVariants = [RCTConvert NSArray:config[@"emptyViewTitleVariants"]];
|
|
686
|
+
}
|
|
687
|
+
if (config[@"emptyViewSubtitleVariants"]) {
|
|
688
|
+
NSLog(@"%@", [RCTConvert NSArray:config[@"emptyViewSubtitleVariants"]]);
|
|
689
|
+
listTemplate.emptyViewSubtitleVariants = [RCTConvert NSArray:config[@"emptyViewSubtitleVariants"]];
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
RCT_EXPORT_METHOD(updateTabBarTemplates:(NSString *)templateId templates:(NSDictionary*)config) {
|
|
696
|
+
if (@available(iOS 14, *)) {
|
|
697
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
698
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
699
|
+
if (template) {
|
|
700
|
+
CPTabBarTemplate *tabBarTemplate = (CPTabBarTemplate*) template;
|
|
701
|
+
[tabBarTemplate updateTemplates:[self parseTemplatesFrom:config]];
|
|
702
|
+
} else {
|
|
703
|
+
NSLog(@"Failed to find template %@", template);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
RCT_EXPORT_METHOD(updateListTemplateSections:(NSString *)templateId sections:(NSArray*)sections) {
|
|
710
|
+
if (@available(iOS 12.0, *)) {
|
|
711
|
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
712
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
713
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
714
|
+
if (template) {
|
|
715
|
+
CPListTemplate *listTemplate = (CPListTemplate*) template;
|
|
716
|
+
[self parseSections:sections templateId:templateId completion:^(NSArray<CPListSection*> *parsedSections) {
|
|
717
|
+
[listTemplate updateSections:parsedSections];
|
|
718
|
+
}];
|
|
719
|
+
} else {
|
|
720
|
+
NSLog(@"Failed to find template %@", template);
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
RCT_EXPORT_METHOD(updateListTemplateItem:(NSString *)templateId config:(NSDictionary*)config) {
|
|
727
|
+
if (@available(iOS 14, *)) {
|
|
728
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
729
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
730
|
+
if (template) {
|
|
731
|
+
CPListTemplate *listTemplate = (CPListTemplate*) template;
|
|
732
|
+
NSInteger sectionIndex = [RCTConvert NSInteger:config[@"sectionIndex"]];
|
|
733
|
+
if (sectionIndex >= 0 && sectionIndex >= listTemplate.sections.count) {
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
CPListSection *section = listTemplate.sections[sectionIndex];
|
|
737
|
+
NSInteger index = [RCTConvert NSInteger:config[@"itemIndex"]];
|
|
738
|
+
if (index >= 0 && index >= section.items.count) {
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
CPListItem *item = (CPListItem *)section.items[index];
|
|
742
|
+
if (item) {
|
|
743
|
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
744
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
745
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
746
|
+
if (template) {
|
|
747
|
+
CPListTemplate *listTemplate = (CPListTemplate*) template;
|
|
748
|
+
NSInteger sectionIndex = [RCTConvert NSInteger:config[@"sectionIndex"]];
|
|
749
|
+
if (sectionIndex >= 0 && sectionIndex >= listTemplate.sections.count) {
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
CPListSection *section = listTemplate.sections[sectionIndex];
|
|
753
|
+
NSInteger index = [RCTConvert NSInteger:config[@"itemIndex"]];
|
|
754
|
+
if (index >= 0 && index >= section.items.count) {
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
CPListItem *item = (CPListItem *)section.items[index];
|
|
758
|
+
if (item) {
|
|
759
|
+
NSString *imgUrl = [RCTConvert NSString:config[@"imgUrl"]];
|
|
760
|
+
if (imgUrl) {
|
|
761
|
+
NSURL *url = [NSURL URLWithString:imgUrl];
|
|
762
|
+
if (url) {
|
|
763
|
+
NSData *imageData = [NSData dataWithContentsOfURL:url];
|
|
764
|
+
if (imageData) {
|
|
765
|
+
UIImage *image = [[UIImage alloc] initWithData:imageData];
|
|
766
|
+
if (image) {
|
|
767
|
+
[item setImage:image];
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
});
|
|
775
|
+
if (config[@"image"]) {
|
|
776
|
+
[item setImage:[RCTConvert UIImage:config[@"image"]]];
|
|
777
|
+
}
|
|
778
|
+
if (config[@"text"]) {
|
|
779
|
+
[item setText:[RCTConvert NSString:config[@"text"]]];
|
|
780
|
+
}
|
|
781
|
+
if (config[@"detailText"]) {
|
|
782
|
+
[item setDetailText:[RCTConvert NSString:config[@"detailText"]]];
|
|
783
|
+
}
|
|
784
|
+
BOOL isPlaying = [RCTConvert BOOL:config[@"isPlaying"]];
|
|
785
|
+
if (isPlaying) {
|
|
786
|
+
[item setPlayingIndicatorLocation:CPListItemPlayingIndicatorLocationTrailing];
|
|
787
|
+
[item setPlaying:YES];
|
|
788
|
+
} else {
|
|
789
|
+
[item setPlaying:NO];
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
} else {
|
|
793
|
+
NSLog(@"Failed to find template %@", template);
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
RCT_EXPORT_METHOD(updateListTemplateRowItems:(NSString *)templateId config:(NSDictionary*)config) {
|
|
799
|
+
if (@available(iOS 14, *)) {
|
|
800
|
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
801
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
802
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
803
|
+
if (template) {
|
|
804
|
+
CPListTemplate *listTemplate = (CPListTemplate*) template;
|
|
805
|
+
NSInteger sectionIndex = [RCTConvert NSInteger:config[@"sectionIndex"]];
|
|
806
|
+
if (sectionIndex >= listTemplate.sections.count) {
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
CPListSection *section = listTemplate.sections[sectionIndex];
|
|
810
|
+
NSInteger index = [RCTConvert NSInteger:config[@"itemIndex"]];
|
|
811
|
+
if (index >= section.items.count) {
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
CPListImageRowItem *item = (CPListImageRowItem *)section.items[index];
|
|
815
|
+
if (item) {
|
|
816
|
+
if(config[@"rowItems"]) {
|
|
817
|
+
UIImage *placeholder = [UIImage imageNamed: @"Placeholder"];
|
|
818
|
+
NSArray *_rowItems = [RCTConvert NSArray:config[@"rowItems"]];
|
|
819
|
+
NSMutableArray *loadedRowItemsImages = [[NSMutableArray alloc] init];
|
|
820
|
+
|
|
821
|
+
for (id rowItem in _rowItems) {
|
|
822
|
+
if (rowItem[@"imgUrl"]) {
|
|
823
|
+
UIImage *image = nil;
|
|
824
|
+
NSString *imgUrl = rowItem[@"imgUrl"];
|
|
825
|
+
NSURL *url = [NSURL URLWithString:imgUrl];
|
|
826
|
+
if (url) {
|
|
827
|
+
NSData *imageData = [NSData dataWithContentsOfURL:url];
|
|
828
|
+
if (imageData) {
|
|
829
|
+
UIImage *imageCopy = [[UIImage alloc] initWithData:imageData];
|
|
830
|
+
if (imageCopy) {
|
|
831
|
+
image = imageCopy;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
if (!image && placeholder) image = placeholder;
|
|
836
|
+
if ([rowItem[@"isArtist"] boolValue]) {
|
|
837
|
+
image = [self imageWithRoundedCornersSize:100 usingImage:image];
|
|
838
|
+
}
|
|
839
|
+
if (image) {
|
|
840
|
+
[loadedRowItemsImages addObject:image];
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
while ([loadedRowItemsImages count] < 9) {
|
|
846
|
+
if (placeholder) [loadedRowItemsImages addObject:placeholder];
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
[item updateImages:loadedRowItemsImages];
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
} else {
|
|
853
|
+
NSLog(@"Failed to find template %@", template);
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
RCT_EXPORT_METHOD(updateInformationTemplateItems:(NSString *)templateId items:(NSArray*)items) {
|
|
860
|
+
if (@available(iOS 14, *)) {
|
|
861
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
862
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
863
|
+
if (template) {
|
|
864
|
+
CPInformationTemplate *informationTemplate = (CPInformationTemplate*) template;
|
|
865
|
+
informationTemplate.items = [self parseInformationItems:items];
|
|
866
|
+
} else {
|
|
867
|
+
NSLog(@"Failed to find template %@", template);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
RCT_EXPORT_METHOD(updateInformationTemplateActions:(NSString *)templateId items:(NSArray*)actions) {
|
|
873
|
+
if (@available(iOS 14, *)) {
|
|
874
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
875
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
876
|
+
if (template) {
|
|
877
|
+
CPInformationTemplate *informationTemplate = (CPInformationTemplate*) template;
|
|
878
|
+
informationTemplate.actions = [self parseInformationActions:actions templateId:templateId];
|
|
879
|
+
} else {
|
|
880
|
+
NSLog(@"Failed to find template %@", template);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
RCT_EXPORT_METHOD(getMaximumListItemCount:(NSString *)templateId
|
|
886
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
887
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
888
|
+
if (@available(iOS 14, *)) {
|
|
889
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
890
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
891
|
+
if (template) {
|
|
892
|
+
CPListTemplate *listTemplate = (CPListTemplate*) template;
|
|
893
|
+
resolve(@(CPListTemplate.maximumItemCount));
|
|
894
|
+
} else {
|
|
895
|
+
NSLog(@"Failed to find template %@", template);
|
|
896
|
+
reject(@"template_not_found", @"Template not found in store", nil);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
RCT_EXPORT_METHOD(getMaximumListSectionCount:(NSString *)templateId
|
|
902
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
903
|
+
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
904
|
+
if (@available(iOS 14, *)) {
|
|
905
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
906
|
+
CPTemplate *template = [store findTemplateById:templateId];
|
|
907
|
+
if (template) {
|
|
908
|
+
CPListTemplate *listTemplate = (CPListTemplate*) template;
|
|
909
|
+
resolve(@(CPListTemplate.maximumSectionCount));
|
|
910
|
+
} else {
|
|
911
|
+
NSLog(@"Failed to find template %@", template);
|
|
912
|
+
reject(@"template_not_found", @"Template not found in store", nil);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
RCT_EXPORT_METHOD(updateMapTemplateConfig:(NSString *)templateId config:(NSDictionary*)config) {
|
|
918
|
+
if (@available(iOS 12.0, *)) {
|
|
919
|
+
CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
|
|
920
|
+
if (template) {
|
|
921
|
+
CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
|
|
922
|
+
[self applyConfigForMapTemplate:mapTemplate templateId:templateId config:config];
|
|
923
|
+
} else {
|
|
924
|
+
NSLog(@"Failed to find template %@", template);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
RCT_EXPORT_METHOD(showPanningInterface:(NSString *)templateId animated:(BOOL)animated) {
|
|
930
|
+
if (@available(iOS 12.0, *)) {
|
|
931
|
+
CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
|
|
932
|
+
if (template) {
|
|
933
|
+
CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
|
|
934
|
+
[mapTemplate showPanningInterfaceAnimated:animated];
|
|
935
|
+
} else {
|
|
936
|
+
NSLog(@"Failed to find template %@", template);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
RCT_EXPORT_METHOD(dismissPanningInterface:(NSString *)templateId animated:(BOOL)animated) {
|
|
942
|
+
if (@available(iOS 12.0, *)) {
|
|
943
|
+
CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
|
|
944
|
+
if (template) {
|
|
945
|
+
CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
|
|
946
|
+
[mapTemplate dismissPanningInterfaceAnimated:animated];
|
|
947
|
+
} else {
|
|
948
|
+
NSLog(@"Failed to find template %@", template);
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
RCT_EXPORT_METHOD(enableNowPlaying:(BOOL)enable) {
|
|
954
|
+
if (@available(iOS 14, *)) {
|
|
955
|
+
if (enable && !isNowPlayingActive) {
|
|
956
|
+
[CPNowPlayingTemplate.sharedTemplate addObserver:self];
|
|
957
|
+
} else if (!enable && isNowPlayingActive) {
|
|
958
|
+
[CPNowPlayingTemplate.sharedTemplate removeObserver:self];
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
RCT_EXPORT_METHOD(hideTripPreviews:(NSString*)templateId) {
|
|
964
|
+
if (@available(iOS 12.0, *)) {
|
|
965
|
+
CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
|
|
966
|
+
if (template) {
|
|
967
|
+
CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
|
|
968
|
+
[mapTemplate hideTripPreviews];
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
RCT_EXPORT_METHOD(showTripPreviews:(NSString*)templateId tripIds:(NSArray*)tripIds tripConfiguration:(NSDictionary*)tripConfiguration) {
|
|
974
|
+
if (@available(iOS 12.0, *)) {
|
|
975
|
+
CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
|
|
976
|
+
NSMutableArray *trips = [[NSMutableArray alloc] init];
|
|
977
|
+
|
|
978
|
+
for (NSString *tripId in tripIds) {
|
|
979
|
+
CPTrip *trip = [[RNCPStore sharedManager] findTripById:tripId];
|
|
980
|
+
if (trip) {
|
|
981
|
+
[trips addObject:trip];
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
if (template) {
|
|
986
|
+
CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
|
|
987
|
+
[mapTemplate showTripPreviews:trips textConfiguration:[self parseTripPreviewTextConfiguration:tripConfiguration]];
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
RCT_EXPORT_METHOD(showRouteChoicesPreviewForTrip:(NSString*)templateId tripId:(NSString*)tripId tripConfiguration:(NSDictionary*)tripConfiguration) {
|
|
993
|
+
if (@available(iOS 12.0, *)) {
|
|
994
|
+
CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
|
|
995
|
+
CPTrip *trip = [[RNCPStore sharedManager] findTripById:tripId];
|
|
996
|
+
|
|
997
|
+
if (template) {
|
|
998
|
+
CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
|
|
999
|
+
[mapTemplate showRouteChoicesPreviewForTrip:trip textConfiguration:[self parseTripPreviewTextConfiguration:tripConfiguration]];
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
RCT_EXPORT_METHOD(presentNavigationAlert:(NSString*)templateId json:(NSDictionary*)json animated:(BOOL)animated) {
|
|
1005
|
+
if (@available(iOS 12.0, *)) {
|
|
1006
|
+
CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
|
|
1007
|
+
if (template) {
|
|
1008
|
+
CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
|
|
1009
|
+
[mapTemplate presentNavigationAlert:[self parseNavigationAlert:json templateId:templateId] animated:animated];
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
RCT_EXPORT_METHOD(dismissNavigationAlert:(NSString*)templateId animated:(BOOL)animated) {
|
|
1015
|
+
if (@available(iOS 12.0, *)) {
|
|
1016
|
+
CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
|
|
1017
|
+
if (template) {
|
|
1018
|
+
CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
|
|
1019
|
+
[mapTemplate dismissNavigationAlertAnimated:YES completion:^(BOOL completion) {
|
|
1020
|
+
[self sendTemplateEventWithName:template name:@"didDismissNavigationAlert"];
|
|
1021
|
+
}];
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
RCT_EXPORT_METHOD(activateVoiceControlState:(NSString*)templateId identifier:(NSString*)identifier) {
|
|
1027
|
+
if (@available(iOS 12.0, *)) {
|
|
1028
|
+
CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
|
|
1029
|
+
if (template) {
|
|
1030
|
+
CPVoiceControlTemplate *voiceTemplate = (CPVoiceControlTemplate*) template;
|
|
1031
|
+
[voiceTemplate activateVoiceControlStateWithIdentifier:identifier];
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
RCT_EXPORT_METHOD(reactToUpdatedSearchText:(NSArray *)items) {
|
|
1037
|
+
if (@available(iOS 12.0, *)) {
|
|
1038
|
+
NSArray *sectionsItems = [self parseListItems:items startIndex:0 templateId:nil];
|
|
1039
|
+
|
|
1040
|
+
if (self.searchResultBlock) {
|
|
1041
|
+
self.searchResultBlock(sectionsItems);
|
|
1042
|
+
self.searchResultBlock = nil;
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
RCT_EXPORT_METHOD(reactToSelectedResult:(BOOL)status) {
|
|
1048
|
+
if (self.selectedResultBlock) {
|
|
1049
|
+
self.selectedResultBlock();
|
|
1050
|
+
self.selectedResultBlock = nil;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:(NSArray*) mapButtonConfig) {
|
|
1055
|
+
if (@available(iOS 12.0, *)) {
|
|
1056
|
+
CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
|
|
1057
|
+
if (template) {
|
|
1058
|
+
CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
|
|
1059
|
+
NSArray *mapButtons = [RCTConvert NSArray:mapButtonConfig];
|
|
1060
|
+
NSMutableArray *result = [NSMutableArray array];
|
|
1061
|
+
for (NSDictionary *mapButton in mapButtons) {
|
|
1062
|
+
NSString *_id = [mapButton objectForKey:@"id"];
|
|
1063
|
+
[result addObject:[RCTConvert CPMapButton:mapButton withHandler:^(CPMapButton * _Nonnull mapButton) {
|
|
1064
|
+
[self sendTemplateEventWithName:mapTemplate name:@"mapButtonPressed" json:@{ @"id": _id }];
|
|
1065
|
+
}]];
|
|
1066
|
+
}
|
|
1067
|
+
[mapTemplate setMapButtons:result];
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
# pragma parsers
|
|
1073
|
+
|
|
1074
|
+
- (void) applyConfigForMapTemplate:(CPMapTemplate*)mapTemplate templateId:(NSString*)templateId config:(NSDictionary*)config API_AVAILABLE(ios(12.0)) {
|
|
1075
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
1076
|
+
|
|
1077
|
+
if ([config objectForKey:@"guidanceBackgroundColor"]) {
|
|
1078
|
+
[mapTemplate setGuidanceBackgroundColor:[RCTConvert UIColor:config[@"guidanceBackgroundColor"]]];
|
|
1079
|
+
} else if (@available(iOS 14, *)) {
|
|
1080
|
+
[mapTemplate setGuidanceBackgroundColor:UIColor.systemGray5Color];
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
if ([config objectForKey:@"tripEstimateStyle"]) {
|
|
1084
|
+
[mapTemplate setTripEstimateStyle:[RCTConvert CPTripEstimateStyle:config[@"tripEstimateStyle"]]];
|
|
1085
|
+
}
|
|
1086
|
+
else {
|
|
1087
|
+
[mapTemplate setTripEstimateStyle:CPTripEstimateStyleDark];
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
if ([config objectForKey:@"leadingNavigationBarButtons"]){
|
|
1091
|
+
NSArray *leadingNavigationBarButtons = [self parseBarButtons:[RCTConvert NSArray:config[@"leadingNavigationBarButtons"]] templateId:templateId];
|
|
1092
|
+
[mapTemplate setLeadingNavigationBarButtons:leadingNavigationBarButtons];
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
if ([config objectForKey:@"trailingNavigationBarButtons"]){
|
|
1096
|
+
NSArray *trailingNavigationBarButtons = [self parseBarButtons:[RCTConvert NSArray:config[@"trailingNavigationBarButtons"]] templateId:templateId];
|
|
1097
|
+
[mapTemplate setTrailingNavigationBarButtons:trailingNavigationBarButtons];
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
if ([config objectForKey:@"mapButtons"]) {
|
|
1101
|
+
NSArray *mapButtons = [RCTConvert NSArray:config[@"mapButtons"]];
|
|
1102
|
+
NSMutableArray *result = [NSMutableArray array];
|
|
1103
|
+
for (NSDictionary *mapButton in mapButtons) {
|
|
1104
|
+
NSString *_id = [mapButton objectForKey:@"id"];
|
|
1105
|
+
[result addObject:[RCTConvert CPMapButton:mapButton withHandler:^(CPMapButton * _Nonnull mapButton) {
|
|
1106
|
+
[self sendTemplateEventWithName:mapTemplate name:@"mapButtonPressed" json:@{ @"id": _id }];
|
|
1107
|
+
}]];
|
|
1108
|
+
}
|
|
1109
|
+
[mapTemplate setMapButtons:result];
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
if ([config objectForKey:@"automaticallyHidesNavigationBar"]) {
|
|
1113
|
+
[mapTemplate setAutomaticallyHidesNavigationBar:[RCTConvert BOOL:config[@"automaticallyHidesNavigationBar"]]];
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
if ([config objectForKey:@"hidesButtonsWithNavigationBar"]) {
|
|
1117
|
+
[mapTemplate setHidesButtonsWithNavigationBar:[RCTConvert BOOL:config[@"hidesButtonsWithNavigationBar"]]];
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
if ([config objectForKey:@"render"]) {
|
|
1121
|
+
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:self.bridge moduleName:templateId initialProperties:@{}];
|
|
1122
|
+
[rootView setFrame:store.window.frame];
|
|
1123
|
+
[[store.window subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
|
1124
|
+
[store.window addSubview:rootView];
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
- (NSArray<__kindof CPTemplate*>*) parseTemplatesFrom:(NSDictionary*)config API_AVAILABLE(ios(12.0)) {
|
|
1129
|
+
RNCPStore *store = [RNCPStore sharedManager];
|
|
1130
|
+
NSMutableArray<__kindof CPTemplate*> *templates = [NSMutableArray new];
|
|
1131
|
+
NSArray<NSDictionary*> *tpls = [RCTConvert NSDictionaryArray:config[@"templates"]];
|
|
1132
|
+
for (NSDictionary *tpl in tpls) {
|
|
1133
|
+
CPTemplate *templ = [store findTemplateById:tpl[@"id"]];
|
|
1134
|
+
// @todo UITabSystemItem
|
|
1135
|
+
[templates addObject:templ];
|
|
1136
|
+
}
|
|
1137
|
+
return templates;
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
- (NSArray<CPButton*>*) parseButtons:(NSArray*)buttons templateId:(NSString *)templateId API_AVAILABLE(ios(14.0)) {
|
|
1141
|
+
NSMutableArray *result = [NSMutableArray array];
|
|
1142
|
+
for (NSDictionary *button in buttons) {
|
|
1143
|
+
CPButton *_button;
|
|
1144
|
+
NSString *_id = [button objectForKey:@"id"];
|
|
1145
|
+
NSString *type = [button objectForKey:@"type"];
|
|
1146
|
+
if ([type isEqualToString:@"call"]) {
|
|
1147
|
+
_button = [[CPContactCallButton alloc] initWithHandler:^(__kindof CPButton * _Nonnull contactButton) {
|
|
1148
|
+
if (self->hasListeners) {
|
|
1149
|
+
[self sendEventWithName:@"buttonPressed" body:@{@"id": _id, @"templateId":templateId}];
|
|
1150
|
+
}
|
|
1151
|
+
}];
|
|
1152
|
+
} else if ([type isEqualToString:@"message"]) {
|
|
1153
|
+
_button = [[CPContactMessageButton alloc] initWithPhoneOrEmail:[button objectForKey:@"phoneOrEmail"]];
|
|
1154
|
+
} else if ([type isEqualToString:@"directions"]) {
|
|
1155
|
+
_button = [[CPContactDirectionsButton alloc] initWithHandler:^(__kindof CPButton * _Nonnull contactButton) {
|
|
1156
|
+
if (self->hasListeners) {
|
|
1157
|
+
[self sendEventWithName:@"buttonPressed" body:@{@"id": _id, @"templateId":templateId}];
|
|
1158
|
+
}
|
|
1159
|
+
}];
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
BOOL _disabled = [button objectForKey:@"disabled"];
|
|
1163
|
+
[_button setEnabled:!_disabled];
|
|
1164
|
+
|
|
1165
|
+
NSString *_title = [button objectForKey:@"title"];
|
|
1166
|
+
[_button setTitle:_title];
|
|
1167
|
+
|
|
1168
|
+
[result addObject:_button];
|
|
1169
|
+
}
|
|
1170
|
+
return result;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
- (NSArray<CPBarButton*>*) parseBarButtons:(NSArray*)barButtons templateId:(NSString *)templateId API_AVAILABLE(ios(12.0)) {
|
|
1174
|
+
NSMutableArray *result = [NSMutableArray array];
|
|
1175
|
+
for (NSDictionary *barButton in barButtons) {
|
|
1176
|
+
CPBarButtonType _type;
|
|
1177
|
+
NSString *_id = [barButton objectForKey:@"id"];
|
|
1178
|
+
NSString *type = [barButton objectForKey:@"type"];
|
|
1179
|
+
if (type && [type isEqualToString:@"image"]) {
|
|
1180
|
+
_type = CPBarButtonTypeImage;
|
|
1181
|
+
} else {
|
|
1182
|
+
_type = CPBarButtonTypeText;
|
|
1183
|
+
}
|
|
1184
|
+
CPBarButton *_barButton = [[CPBarButton alloc] initWithType:_type handler:^(CPBarButton * _Nonnull barButton) {
|
|
1185
|
+
if (self->hasListeners) {
|
|
1186
|
+
[self sendEventWithName:@"barButtonPressed" body:@{@"id": _id, @"templateId":templateId}];
|
|
1187
|
+
}
|
|
1188
|
+
}];
|
|
1189
|
+
BOOL _disabled = [barButton objectForKey:@"disabled"];
|
|
1190
|
+
[_barButton setEnabled:!_disabled];
|
|
1191
|
+
|
|
1192
|
+
if (_type == CPBarButtonTypeText) {
|
|
1193
|
+
NSString *_title = [barButton objectForKey:@"title"];
|
|
1194
|
+
[_barButton setTitle:_title];
|
|
1195
|
+
} else if (_type == CPBarButtonTypeImage) {
|
|
1196
|
+
UIImage *_image = [RCTConvert UIImage:[barButton objectForKey:@"image"]];
|
|
1197
|
+
[_barButton setImage:_image];
|
|
1198
|
+
}
|
|
1199
|
+
[result addObject:_barButton];
|
|
1200
|
+
}
|
|
1201
|
+
return result;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
- (NSArray<CPListSection*>*)parseSections:(NSArray*)sections templateId:(NSString *)templateId API_AVAILABLE(ios(12.0)) {
|
|
1205
|
+
NSMutableArray *result = [NSMutableArray array];
|
|
1206
|
+
int index = 0;
|
|
1207
|
+
for (NSDictionary *section in sections) {
|
|
1208
|
+
NSArray *items = [section objectForKey:@"items"];
|
|
1209
|
+
NSString *_sectionIndexTitle = [section objectForKey:@"sectionIndexTitle"];
|
|
1210
|
+
NSString *_header = [section objectForKey:@"header"];
|
|
1211
|
+
NSArray *_items = [self parseListItems:items startIndex:index templateId:templateId];
|
|
1212
|
+
CPListSection *_section = [[CPListSection alloc] initWithItems:_items header:_header sectionIndexTitle:_sectionIndexTitle];
|
|
1213
|
+
[result addObject:_section];
|
|
1214
|
+
int count = (int) [items count];
|
|
1215
|
+
index = index + count;
|
|
1216
|
+
}
|
|
1217
|
+
return result;
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
- (void)parseSections:(NSArray*)sections
|
|
1221
|
+
templateId:(NSString *)templateId
|
|
1222
|
+
completion:(void (^)(NSArray<CPListSection*> *parsedSections))completion API_AVAILABLE(ios(12.0)) {
|
|
1223
|
+
|
|
1224
|
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
1225
|
+
NSArray<CPListSection*> *parsedSections = [self parseSections:sections templateId:templateId];
|
|
1226
|
+
if (completion) {
|
|
1227
|
+
completion(parsedSections);
|
|
1228
|
+
}
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
|
|
1233
|
+
- (NSArray<CPListItem*>*)parseListItems:(NSArray*)items startIndex:(int)startIndex templateId:(NSString *)templateId API_AVAILABLE(ios(12.0)) {
|
|
1234
|
+
NSMutableArray *_items = [NSMutableArray array];
|
|
1235
|
+
int index = startIndex;
|
|
1236
|
+
UIImage *placeholder = [UIImage imageNamed: @"Placeholder"];
|
|
1237
|
+
for (NSDictionary *item in items) {
|
|
1238
|
+
NSString *_detailText = [RCTConvert NSString:item[@"detailText"]];
|
|
1239
|
+
NSString *_text = [RCTConvert NSString:item[@"text"]];
|
|
1240
|
+
UIImage *image = nil;
|
|
1241
|
+
NSArray *_rowItems = [item objectForKey:@"rowItems"];
|
|
1242
|
+
BOOL isPlaying = [RCTConvert BOOL:item[@"isPlaying"]];
|
|
1243
|
+
BOOL onlyText = [RCTConvert BOOL:item[@"onlyText"]];
|
|
1244
|
+
|
|
1245
|
+
if(item[@"rowItems"] && templateId) {
|
|
1246
|
+
if (@available(iOS 14.0, *)) {
|
|
1247
|
+
|
|
1248
|
+
NSMutableArray *loadedRowItems = [[NSMutableArray alloc] init];
|
|
1249
|
+
NSMutableArray *loadedRowItemsImages = [[NSMutableArray alloc] init];
|
|
1250
|
+
|
|
1251
|
+
for (id rowItem in _rowItems) {
|
|
1252
|
+
UIImage *image = nil;
|
|
1253
|
+
if (rowItem[@"imgUrl"]) {
|
|
1254
|
+
NSString *imgUrl = rowItem[@"imgUrl"];
|
|
1255
|
+
NSURL *url = [NSURL URLWithString:imgUrl];
|
|
1256
|
+
if (url) {
|
|
1257
|
+
NSData *imageData = [NSData dataWithContentsOfURL:url];
|
|
1258
|
+
if (imageData) {
|
|
1259
|
+
UIImage *imageCopy = [[UIImage alloc] initWithData:imageData];
|
|
1260
|
+
if (imageCopy) {
|
|
1261
|
+
image = imageCopy;
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
if (!image && placeholder) image = placeholder;
|
|
1266
|
+
if ([rowItem[@"isArtist"] boolValue]) {
|
|
1267
|
+
image = [self imageWithRoundedCornersSize:100 usingImage:image];
|
|
1268
|
+
}
|
|
1269
|
+
if (image) {
|
|
1270
|
+
[loadedRowItems addObject:rowItem];
|
|
1271
|
+
[loadedRowItemsImages addObject:image];
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
while ([loadedRowItemsImages count] < 9) {
|
|
1277
|
+
if (placeholder) [loadedRowItemsImages addObject:placeholder];
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
CPListImageRowItem *_imageRowItem = [[CPListImageRowItem alloc] initWithText:_text images:loadedRowItemsImages];
|
|
1281
|
+
|
|
1282
|
+
_imageRowItem.listImageRowHandler = ^(CPListImageRowItem *item, NSInteger index, dispatch_block_t completionBlock) {
|
|
1283
|
+
NSMutableDictionary *bodyDictionary = [NSMutableDictionary dictionary];
|
|
1284
|
+
|
|
1285
|
+
NSNumber *indexNumber = @(index);
|
|
1286
|
+
|
|
1287
|
+
bodyDictionary[@"index"] = indexNumber;
|
|
1288
|
+
|
|
1289
|
+
if (templateId) {
|
|
1290
|
+
bodyDictionary[@"templateId"] = templateId;
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
[self sendEventWithName:@"didSelectRowItem" body:bodyDictionary];
|
|
1294
|
+
|
|
1295
|
+
if (completionBlock) {
|
|
1296
|
+
completionBlock();
|
|
1297
|
+
}
|
|
1298
|
+
};
|
|
1299
|
+
|
|
1300
|
+
[_imageRowItem setUserInfo:@{ @"index": @(index) }];
|
|
1301
|
+
[_items addObject:_imageRowItem];
|
|
1302
|
+
index = index + 1;
|
|
1303
|
+
continue;
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
if (item[@"imgUrl"]) {
|
|
1308
|
+
NSString *imgUrl = [RCTConvert NSString:item[@"imgUrl"]];
|
|
1309
|
+
if (imgUrl) {
|
|
1310
|
+
NSURL *url = [NSURL URLWithString:imgUrl];
|
|
1311
|
+
if (url) {
|
|
1312
|
+
NSData *imageData = [NSData dataWithContentsOfURL:url];
|
|
1313
|
+
if (imageData) {
|
|
1314
|
+
UIImage *imageCopy = [[UIImage alloc] initWithData:imageData];
|
|
1315
|
+
if (imageCopy) {
|
|
1316
|
+
image = imageCopy;
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
NSDictionary *listItemsImagesNamesMapping = @{
|
|
1324
|
+
@"play-shuffle": @"PlayShuffleIcon"
|
|
1325
|
+
};
|
|
1326
|
+
|
|
1327
|
+
if (item[@"imageName"]) {
|
|
1328
|
+
NSString *imageName = [RCTConvert NSString:item[@"imageName"]];
|
|
1329
|
+
if (imageName) {
|
|
1330
|
+
NSString *nativeImageName = listItemsImagesNamesMapping[imageName];
|
|
1331
|
+
if (nativeImageName) {
|
|
1332
|
+
UIImage *imageCopy = [UIImage imageNamed:nativeImageName];
|
|
1333
|
+
if (imageCopy) {
|
|
1334
|
+
image = imageCopy;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
if (!image && !onlyText && placeholder) image = placeholder;
|
|
1341
|
+
|
|
1342
|
+
if ([item[@"isArtist"] boolValue]) {
|
|
1343
|
+
image = [self imageWithRoundedCornersSize:100 usingImage:image];
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
CPListItem *_item = [[CPListItem alloc] initWithText:_text detailText:_detailText image:image];
|
|
1347
|
+
if (@available(iOS 14, *)) {
|
|
1348
|
+
if (isPlaying) {
|
|
1349
|
+
[_item setPlayingIndicatorLocation:CPListItemPlayingIndicatorLocationTrailing];
|
|
1350
|
+
[_item setPlaying:isPlaying];
|
|
1351
|
+
}
|
|
1352
|
+
if ([item objectForKey:@"showsDisclosureIndicator"]) {
|
|
1353
|
+
BOOL showsDisclosureIndicator = [RCTConvert BOOL:[item objectForKey:@"showsDisclosureIndicator"]];
|
|
1354
|
+
if (showsDisclosureIndicator) {
|
|
1355
|
+
[_item setAccessoryType:CPListItemAccessoryTypeDisclosureIndicator];
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
[_item setUserInfo:@{ @"index": @(index) }];
|
|
1360
|
+
[_items addObject:_item];
|
|
1361
|
+
index = index + 1;
|
|
1362
|
+
}
|
|
1363
|
+
return _items;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
- (UIImage *)imageWithRoundedCornersSize:(float)cornerRadius usingImage:(UIImage *)original {
|
|
1367
|
+
CGSize imageSize = original.size;
|
|
1368
|
+
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);
|
|
1369
|
+
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, imageSize.width, imageSize.height) cornerRadius:cornerRadius];
|
|
1370
|
+
[path addClip];
|
|
1371
|
+
[original drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
|
|
1372
|
+
UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
1373
|
+
UIGraphicsEndImageContext();
|
|
1374
|
+
return roundedImage;
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
|
|
1378
|
+
- (NSArray<CPInformationItem*>*)parseInformationItems:(NSArray*)items API_AVAILABLE(ios(14.0)){
|
|
1379
|
+
NSMutableArray *_items = [NSMutableArray array];
|
|
1380
|
+
for (NSDictionary *item in items) {
|
|
1381
|
+
[_items addObject:[[CPInformationItem alloc] initWithTitle:item[@"title"] detail:item[@"detail"]]];
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
return _items;
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
- (NSArray<CPTextButton*>*)parseInformationActions:(NSArray*)actions templateId:(NSString *)templateId API_AVAILABLE(ios(14.0)){
|
|
1388
|
+
NSMutableArray *_actions = [NSMutableArray array];
|
|
1389
|
+
for (NSDictionary *action in actions) {
|
|
1390
|
+
CPTextButton *_action = [[CPTextButton alloc] initWithTitle:action[@"title"] textStyle:CPTextButtonStyleNormal handler:^(__kindof CPTextButton * _Nonnull contactButton) {
|
|
1391
|
+
if (self->hasListeners) {
|
|
1392
|
+
[self sendEventWithName:@"actionButtonPressed" body:@{@"templateId":templateId, @"id": action[@"id"] }];
|
|
1393
|
+
}
|
|
1394
|
+
}];
|
|
1395
|
+
[_actions addObject:_action];
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
return _actions;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
- (NSArray<CPGridButton*>*)parseGridButtons:(NSArray*)buttons templateId:(NSString*)templateId API_AVAILABLE(ios(12.0)) {
|
|
1402
|
+
NSMutableArray *result = [NSMutableArray array];
|
|
1403
|
+
int index = 0;
|
|
1404
|
+
for (NSDictionary *button in buttons) {
|
|
1405
|
+
NSString *_id = [button objectForKey:@"id"];
|
|
1406
|
+
NSArray<NSString*> *_titleVariants = [button objectForKey:@"titleVariants"];
|
|
1407
|
+
UIImage *_image = [RCTConvert UIImage:[button objectForKey:@"image"]];
|
|
1408
|
+
CPGridButton *_button = [[CPGridButton alloc] initWithTitleVariants:_titleVariants image:_image handler:^(CPGridButton * _Nonnull barButton) {
|
|
1409
|
+
if (self->hasListeners) {
|
|
1410
|
+
[self sendEventWithName:@"gridButtonPressed" body:@{@"id": _id, @"templateId":templateId, @"index": @(index) }];
|
|
1411
|
+
}
|
|
1412
|
+
}];
|
|
1413
|
+
BOOL _disabled = [button objectForKey:@"disabled"];
|
|
1414
|
+
[_button setEnabled:!_disabled];
|
|
1415
|
+
[result addObject:_button];
|
|
1416
|
+
index = index + 1;
|
|
1417
|
+
}
|
|
1418
|
+
return result;
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
- (CPTravelEstimates*)parseTravelEstimates: (NSDictionary*)json API_AVAILABLE(ios(12.0)) {
|
|
1422
|
+
NSString *units = [RCTConvert NSString:json[@"distanceUnits"]];
|
|
1423
|
+
double value = [RCTConvert double:json[@"distanceRemaining"]];
|
|
1424
|
+
|
|
1425
|
+
NSUnit *unit = [NSUnitLength kilometers];
|
|
1426
|
+
if (units && [units isEqualToString: @"meters"]) {
|
|
1427
|
+
unit = [NSUnitLength meters];
|
|
1428
|
+
}
|
|
1429
|
+
else if (units && [units isEqualToString: @"miles"]) {
|
|
1430
|
+
unit = [NSUnitLength miles];
|
|
1431
|
+
}
|
|
1432
|
+
else if (units && [units isEqualToString: @"feet"]) {
|
|
1433
|
+
unit = [NSUnitLength feet];
|
|
1434
|
+
}
|
|
1435
|
+
else if (units && [units isEqualToString: @"yards"]) {
|
|
1436
|
+
unit = [NSUnitLength yards];
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
NSMeasurement *distance = [[NSMeasurement alloc] initWithDoubleValue:value unit:unit];
|
|
1440
|
+
double time = [RCTConvert double:json[@"timeRemaining"]];
|
|
1441
|
+
|
|
1442
|
+
return [[CPTravelEstimates alloc] initWithDistanceRemaining:distance timeRemaining:time];
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
- (CPManeuver*)parseManeuver:(NSDictionary*)json API_AVAILABLE(ios(12.0)) {
|
|
1446
|
+
CPManeuver* maneuver = [[CPManeuver alloc] init];
|
|
1447
|
+
|
|
1448
|
+
if ([json objectForKey:@"junctionImage"]) {
|
|
1449
|
+
UIImage *junctionImage = [RCTConvert UIImage:json[@"junctionImage"]];
|
|
1450
|
+
[maneuver setJunctionImage:[self imageWithTint:junctionImage andTintColor:[UIColor whiteColor]]];
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
if ([json objectForKey:@"initialTravelEstimates"]) {
|
|
1454
|
+
CPTravelEstimates* travelEstimates = [self parseTravelEstimates:json[@"initialTravelEstimates"]];
|
|
1455
|
+
[maneuver setInitialTravelEstimates:travelEstimates];
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
if ([json objectForKey:@"symbolImage"]) {
|
|
1459
|
+
UIImage *symbolImage = [RCTConvert UIImage:json[@"symbolImage"]];
|
|
1460
|
+
|
|
1461
|
+
if ([json objectForKey:@"resizeSymbolImage"]) {
|
|
1462
|
+
NSString *resizeType = [RCTConvert NSString:json[@"resizeSymbolImage"]];
|
|
1463
|
+
if ([resizeType isEqualToString: @"primary"]) {
|
|
1464
|
+
symbolImage = [self imageWithSize:symbolImage convertToSize:CGSizeMake(100, 100)];
|
|
1465
|
+
}
|
|
1466
|
+
if ([resizeType isEqualToString: @"secondary"]) {
|
|
1467
|
+
symbolImage = [self imageWithSize:symbolImage convertToSize:CGSizeMake(50, 50)];
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
BOOL shouldTint = [RCTConvert BOOL:json[@"tintSymbolImage"]];
|
|
1472
|
+
if ([json objectForKey:@"tintSymbolImage"]) {
|
|
1473
|
+
UIColor *tintColor = [RCTConvert UIColor:json[@"tintSymbolImage"]];
|
|
1474
|
+
UIImage *darkImage = symbolImage;
|
|
1475
|
+
UIImage *lightImage = [self imageWithTint:symbolImage andTintColor:tintColor];
|
|
1476
|
+
symbolImage = [self dynamicImageWithNormalImage:lightImage darkImage:darkImage];
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
|
|
1480
|
+
[maneuver setSymbolImage:symbolImage];
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
if ([json objectForKey:@"instructionVariants"]) {
|
|
1484
|
+
[maneuver setInstructionVariants:[RCTConvert NSStringArray:json[@"instructionVariants"]]];
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
return maneuver;
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
- (CPTripPreviewTextConfiguration*)parseTripPreviewTextConfiguration:(NSDictionary*)json API_AVAILABLE(ios(12.0)) {
|
|
1491
|
+
return [[CPTripPreviewTextConfiguration alloc] initWithStartButtonTitle:[RCTConvert NSString:json[@"startButtonTitle"]] additionalRoutesButtonTitle:[RCTConvert NSString:json[@"additionalRoutesButtonTitle"]] overviewButtonTitle:[RCTConvert NSString:json[@"overviewButtonTitle"]]];
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
- (CPTrip*)parseTrip:(NSDictionary*)config API_AVAILABLE(ios(12.0)) {
|
|
1495
|
+
if ([config objectForKey:@"config"]) {
|
|
1496
|
+
config = [config objectForKey:@"config"];
|
|
1497
|
+
}
|
|
1498
|
+
MKMapItem *origin = [RCTConvert MKMapItem:config[@"origin"]];
|
|
1499
|
+
MKMapItem *destination = [RCTConvert MKMapItem:config[@"destination"]];
|
|
1500
|
+
NSMutableArray *routeChoices = [NSMutableArray array];
|
|
1501
|
+
if ([config objectForKey:@"routeChoices"]) {
|
|
1502
|
+
NSInteger index = 0;
|
|
1503
|
+
for (NSDictionary *routeChoice in [RCTConvert NSArray:config[@"routeChoices"]]) {
|
|
1504
|
+
CPRouteChoice *cpRouteChoice = [RCTConvert CPRouteChoice:routeChoice];
|
|
1505
|
+
NSMutableDictionary *userInfo = cpRouteChoice.userInfo;
|
|
1506
|
+
if (!userInfo) {
|
|
1507
|
+
userInfo = [[NSMutableDictionary alloc] init];
|
|
1508
|
+
cpRouteChoice.userInfo = userInfo;
|
|
1509
|
+
}
|
|
1510
|
+
[userInfo setValue:[NSNumber numberWithInteger:index] forKey:@"index"];
|
|
1511
|
+
[routeChoices addObject:cpRouteChoice];
|
|
1512
|
+
index++;
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
return [[CPTrip alloc] initWithOrigin:origin destination:destination routeChoices:routeChoices];
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
- (CPNavigationAlert*)parseNavigationAlert:(NSDictionary*)json templateId:(NSString*)templateId API_AVAILABLE(ios(12.0)) {
|
|
1519
|
+
CPImageSet *imageSet;
|
|
1520
|
+
if ([json objectForKey:@"lightImage"] && [json objectForKey:@"darkImage"]) {
|
|
1521
|
+
imageSet = [[CPImageSet alloc] initWithLightContentImage:[RCTConvert UIImage:json[@"lightImage"]] darkContentImage:[RCTConvert UIImage:json[@"darkImage"]]];
|
|
1522
|
+
}
|
|
1523
|
+
CPAlertAction *secondaryAction = [json objectForKey:@"secondaryAction"] ? [self parseAlertAction:json[@"secondaryAction"] body:@{ @"templateId": templateId, @"secondary": @(YES) }] : nil;
|
|
1524
|
+
|
|
1525
|
+
return [[CPNavigationAlert alloc] initWithTitleVariants:[RCTConvert NSStringArray:json[@"titleVariants"]] subtitleVariants:[RCTConvert NSStringArray:json[@"subtitleVariants"]] imageSet:imageSet primaryAction:[self parseAlertAction:json[@"primaryAction"] body:@{ @"templateId": templateId, @"primary": @(YES) }] secondaryAction:secondaryAction duration:[RCTConvert double:json[@"duration"]]];
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
- (CPAlertAction*)parseAlertAction:(NSDictionary*)json body:(NSDictionary*)body API_AVAILABLE(ios(12.0)) {
|
|
1529
|
+
return [[CPAlertAction alloc] initWithTitle:[RCTConvert NSString:json[@"title"]] style:(CPAlertActionStyle) [RCTConvert NSUInteger:json[@"style"]] handler:^(CPAlertAction * _Nonnull action) {
|
|
1530
|
+
if (self->hasListeners) {
|
|
1531
|
+
[self sendEventWithName:@"alertActionPressed" body:body];
|
|
1532
|
+
}
|
|
1533
|
+
}];
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
- (NSArray<CPVoiceControlState*>*)parseVoiceControlStates:(NSArray<NSDictionary*>*)items API_AVAILABLE(ios(12.0)) {
|
|
1537
|
+
NSMutableArray<CPVoiceControlState*>* res = [NSMutableArray array];
|
|
1538
|
+
for (NSDictionary *item in items) {
|
|
1539
|
+
[res addObject:[self parseVoiceControlState:item]];
|
|
1540
|
+
}
|
|
1541
|
+
return res;
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
- (CPVoiceControlState*)parseVoiceControlState:(NSDictionary*)json API_AVAILABLE(ios(12.0)) {
|
|
1545
|
+
return [[CPVoiceControlState alloc] initWithIdentifier:[RCTConvert NSString:json[@"identifier"]] titleVariants:[RCTConvert NSStringArray:json[@"titleVariants"]] image:[RCTConvert UIImage:json[@"image"]] repeats:[RCTConvert BOOL:json[@"repeats"]]];
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
- (NSString*)panDirectionToString:(CPPanDirection)panDirection API_AVAILABLE(ios(12.0)) {
|
|
1549
|
+
switch (panDirection) {
|
|
1550
|
+
case CPPanDirectionUp: return @"up";
|
|
1551
|
+
case CPPanDirectionRight: return @"right";
|
|
1552
|
+
case CPPanDirectionDown: return @"down";
|
|
1553
|
+
case CPPanDirectionLeft: return @"left";
|
|
1554
|
+
case CPPanDirectionNone: return @"none";
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
- (NSDictionary*)navigationAlertToJson:(CPNavigationAlert*)navigationAlert dismissalContext:(CPNavigationAlertDismissalContext)dismissalContext API_AVAILABLE(ios(12.0)) {
|
|
1559
|
+
NSString *dismissalCtx = @"none";
|
|
1560
|
+
if (dismissalContext) {
|
|
1561
|
+
switch (dismissalContext) {
|
|
1562
|
+
case CPNavigationAlertDismissalContextTimeout:
|
|
1563
|
+
dismissalCtx = @"timeout";
|
|
1564
|
+
break;
|
|
1565
|
+
case CPNavigationAlertDismissalContextSystemDismissed:
|
|
1566
|
+
dismissalCtx = @"system";
|
|
1567
|
+
break;
|
|
1568
|
+
case CPNavigationAlertDismissalContextUserDismissed:
|
|
1569
|
+
dismissalCtx = @"user";
|
|
1570
|
+
break;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
return @{
|
|
1575
|
+
@"todo": @(YES),
|
|
1576
|
+
@"reason": dismissalCtx
|
|
1577
|
+
};
|
|
1578
|
+
}
|
|
1579
|
+
- (NSDictionary*)navigationAlertToJson:(CPNavigationAlert*)navigationAlert API_AVAILABLE(ios(12.0)) {
|
|
1580
|
+
return @{ @"todo": @(YES) };
|
|
1581
|
+
// NSMutableDictionary *res = [[NSMutableDictionary alloc] init];
|
|
1582
|
+
// return @{
|
|
1583
|
+
// };
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1586
|
+
- (void)sendTemplateEventWithName:(CPTemplate *)template name:(NSString*)name API_AVAILABLE(ios(12.0)) {
|
|
1587
|
+
[self sendTemplateEventWithName:template name:name json:@{}];
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
- (void)sendTemplateEventWithName:(CPTemplate *)template name:(NSString*)name json:(NSDictionary*)json API_AVAILABLE(ios(12.0)) {
|
|
1591
|
+
NSMutableDictionary *body = [[NSMutableDictionary alloc] initWithDictionary:json];
|
|
1592
|
+
NSDictionary *userInfo = [template userInfo];
|
|
1593
|
+
[body setObject:[userInfo objectForKey:@"templateId"] forKey:@"templateId"];
|
|
1594
|
+
if (hasListeners) {
|
|
1595
|
+
[self sendEventWithName:name body:body];
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
|
|
1600
|
+
# pragma MapTemplate
|
|
1601
|
+
|
|
1602
|
+
- (void)mapTemplate:(CPMapTemplate *)mapTemplate selectedPreviewForTrip:(CPTrip *)trip usingRouteChoice:(CPRouteChoice *)routeChoice API_AVAILABLE(ios(12.0)) {
|
|
1603
|
+
NSDictionary *userInfo = trip.userInfo;
|
|
1604
|
+
NSString *tripId = [userInfo valueForKey:@"id"];
|
|
1605
|
+
|
|
1606
|
+
NSDictionary *routeUserInfo = routeChoice.userInfo;
|
|
1607
|
+
NSString *routeIndex = [routeUserInfo valueForKey:@"index"];
|
|
1608
|
+
[self sendTemplateEventWithName:mapTemplate name:@"selectedPreviewForTrip" json:@{ @"tripId": tripId, @"routeIndex": routeIndex}];
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
- (void)mapTemplate:(CPMapTemplate *)mapTemplate startedTrip:(CPTrip *)trip usingRouteChoice:(CPRouteChoice *)routeChoice API_AVAILABLE(ios(12.0)) {
|
|
1612
|
+
NSDictionary *userInfo = trip.userInfo;
|
|
1613
|
+
NSString *tripId = [userInfo valueForKey:@"id"];
|
|
1614
|
+
|
|
1615
|
+
NSDictionary *routeUserInfo = routeChoice.userInfo;
|
|
1616
|
+
NSString *routeIndex = [routeUserInfo valueForKey:@"index"];
|
|
1617
|
+
|
|
1618
|
+
[self sendTemplateEventWithName:mapTemplate name:@"startedTrip" json:@{ @"tripId": tripId, @"routeIndex": routeIndex}];
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
- (void)mapTemplateDidCancelNavigation:(CPMapTemplate *)mapTemplate API_AVAILABLE(ios(12.0)) {
|
|
1622
|
+
[self sendTemplateEventWithName:mapTemplate name:@"didCancelNavigation"];
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
//- (BOOL)mapTemplate:(CPMapTemplate *)mapTemplate shouldShowNotificationForManeuver:(CPManeuver *)maneuver {
|
|
1626
|
+
// // @todo
|
|
1627
|
+
//}
|
|
1628
|
+
//- (BOOL)mapTemplate:(CPMapTemplate *)mapTemplate shouldUpdateNotificationForManeuver:(CPManeuver *)maneuver withTravelEstimates:(CPTravelEstimates *)travelEstimates {
|
|
1629
|
+
// // @todo
|
|
1630
|
+
//}
|
|
1631
|
+
//- (BOOL)mapTemplate:(CPMapTemplate *)mapTemplate shouldShowNotificationForNavigationAlert:(CPNavigationAlert *)navigationAlert {
|
|
1632
|
+
// // @todo
|
|
1633
|
+
//}
|
|
1634
|
+
|
|
1635
|
+
- (void)mapTemplate:(CPMapTemplate *)mapTemplate willShowNavigationAlert:(CPNavigationAlert *)navigationAlert API_AVAILABLE(ios(12.0)) {
|
|
1636
|
+
[self sendTemplateEventWithName:mapTemplate name:@"willShowNavigationAlert" json:[self navigationAlertToJson:navigationAlert]];
|
|
1637
|
+
}
|
|
1638
|
+
- (void)mapTemplate:(CPMapTemplate *)mapTemplate didShowNavigationAlert:(CPNavigationAlert *)navigationAlert API_AVAILABLE(ios(12.0)) {
|
|
1639
|
+
[self sendTemplateEventWithName:mapTemplate name:@"didShowNavigationAlert" json:[self navigationAlertToJson:navigationAlert]];
|
|
1640
|
+
}
|
|
1641
|
+
- (void)mapTemplate:(CPMapTemplate *)mapTemplate willDismissNavigationAlert:(CPNavigationAlert *)navigationAlert dismissalContext:(CPNavigationAlertDismissalContext)dismissalContext API_AVAILABLE(ios(12.0)) {
|
|
1642
|
+
[self sendTemplateEventWithName:mapTemplate name:@"willDismissNavigationAlert" json:[self navigationAlertToJson:navigationAlert dismissalContext:dismissalContext]];
|
|
1643
|
+
}
|
|
1644
|
+
- (void)mapTemplate:(CPMapTemplate *)mapTemplate didDismissNavigationAlert:(CPNavigationAlert *)navigationAlert dismissalContext:(CPNavigationAlertDismissalContext)dismissalContext API_AVAILABLE(ios(12.0)) {
|
|
1645
|
+
[self sendTemplateEventWithName:mapTemplate name:@"didDismissNavigationAlert" json:[self navigationAlertToJson:navigationAlert dismissalContext:dismissalContext]];
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
- (void)mapTemplateDidShowPanningInterface:(CPMapTemplate *)mapTemplate API_AVAILABLE(ios(12.0)) {
|
|
1649
|
+
[self sendTemplateEventWithName:mapTemplate name:@"didShowPanningInterface"];
|
|
1650
|
+
}
|
|
1651
|
+
- (void)mapTemplateWillDismissPanningInterface:(CPMapTemplate *)mapTemplate API_AVAILABLE(ios(12.0)) {
|
|
1652
|
+
[self sendTemplateEventWithName:mapTemplate name:@"willDismissPanningInterface"];
|
|
1653
|
+
}
|
|
1654
|
+
- (void)mapTemplateDidDismissPanningInterface:(CPMapTemplate *)mapTemplate API_AVAILABLE(ios(12.0)) {
|
|
1655
|
+
[self sendTemplateEventWithName:mapTemplate name:@"didDismissPanningInterface"];
|
|
1656
|
+
}
|
|
1657
|
+
- (void)mapTemplateDidBeginPanGesture:(CPMapTemplate *)mapTemplate API_AVAILABLE(ios(12.0)) {
|
|
1658
|
+
[self sendTemplateEventWithName:mapTemplate name:@"didBeginPanGesture"];
|
|
1659
|
+
}
|
|
1660
|
+
- (void)mapTemplate:(CPMapTemplate *)mapTemplate panWithDirection:(CPPanDirection)direction API_AVAILABLE(ios(12.0)) {
|
|
1661
|
+
[self sendTemplateEventWithName:mapTemplate name:@"panWithDirection" json:@{ @"direction": [self panDirectionToString:direction] }];
|
|
1662
|
+
}
|
|
1663
|
+
- (void)mapTemplate:(CPMapTemplate *)mapTemplate panBeganWithDirection:(CPPanDirection)direction API_AVAILABLE(ios(12.0)) {
|
|
1664
|
+
[self sendTemplateEventWithName:mapTemplate name:@"panBeganWithDirection" json:@{ @"direction": [self panDirectionToString:direction] }];
|
|
1665
|
+
}
|
|
1666
|
+
- (void)mapTemplate:(CPMapTemplate *)mapTemplate panEndedWithDirection:(CPPanDirection)direction API_AVAILABLE(ios(12.0)) {
|
|
1667
|
+
[self sendTemplateEventWithName:mapTemplate name:@"panEndedWithDirection" json:@{ @"direction": [self panDirectionToString:direction] }];
|
|
1668
|
+
}
|
|
1669
|
+
- (void)mapTemplate:(CPMapTemplate *)mapTemplate didEndPanGestureWithVelocity:(CGPoint)velocity API_AVAILABLE(ios(12.0)) {
|
|
1670
|
+
[self sendTemplateEventWithName:mapTemplate name:@"didEndPanGestureWithVelocity" json:@{ @"velocity": @{ @"x": @(velocity.x), @"y": @(velocity.y) }}];
|
|
1671
|
+
}
|
|
1672
|
+
- (void)mapTemplate:(CPMapTemplate *)mapTemplate didUpdatePanGestureWithTranslation:(CGPoint)translation velocity:(CGPoint)velocity API_AVAILABLE(ios(12.0)) {
|
|
1673
|
+
[self sendTemplateEventWithName:mapTemplate name:@"didUpdatePanGestureWithTranslation" json:@{ @"translation": @{ @"x": @(translation.x), @"y": @(translation.y) }, @"velocity": @{ @"x": @(velocity.x), @"y": @(velocity.y) }}];
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
|
|
1677
|
+
|
|
1678
|
+
# pragma SearchTemplate
|
|
1679
|
+
|
|
1680
|
+
- (void)searchTemplate:(CPSearchTemplate *)searchTemplate selectedResult:(CPListItem *)item completionHandler:(void (^)(void))completionHandler API_AVAILABLE(ios(12.0)) {
|
|
1681
|
+
NSNumber* index = [item.userInfo objectForKey:@"index"];
|
|
1682
|
+
[self sendTemplateEventWithName:searchTemplate name:@"selectedResult" json:@{ @"index": index }];
|
|
1683
|
+
self.selectedResultBlock = completionHandler;
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
- (void)searchTemplateSearchButtonPressed:(CPSearchTemplate *)searchTemplate API_AVAILABLE(ios(12.0)) {
|
|
1687
|
+
[self sendTemplateEventWithName:searchTemplate name:@"searchButtonPressed"];
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
- (void)searchTemplate:(CPSearchTemplate *)searchTemplate updatedSearchText:(NSString *)searchText completionHandler:(void (^)(NSArray<CPListItem *> * _Nonnull))completionHandler API_AVAILABLE(ios(12.0)) {
|
|
1691
|
+
[self sendTemplateEventWithName:searchTemplate name:@"updatedSearchText" json:@{ @"searchText": searchText }];
|
|
1692
|
+
self.searchResultBlock = completionHandler;
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
# pragma ListTemplate
|
|
1696
|
+
|
|
1697
|
+
- (void)listTemplate:(CPListTemplate *)listTemplate didSelectListItem:(CPListItem *)item completionHandler:(void (^)(void))completionHandler API_AVAILABLE(ios(12.0)) {
|
|
1698
|
+
if (listTemplate && item) {
|
|
1699
|
+
NSNumber* index = [item.userInfo objectForKey:@"index"];
|
|
1700
|
+
[self sendTemplateEventWithName:listTemplate name:@"didSelectListItem" json:@{ @"index": index }];
|
|
1701
|
+
self.selectedResultBlock = completionHandler;
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
# pragma TabBarTemplate
|
|
1706
|
+
|
|
1707
|
+
- (void)tabBarTemplate:(CPTabBarTemplate *)tabBarTemplate didSelectTemplate:(__kindof CPTemplate *)selectedTemplate API_AVAILABLE(ios(14.0)){
|
|
1708
|
+
if (tabBarTemplate && selectedTemplate) {
|
|
1709
|
+
NSString* selectedTemplateId = [[selectedTemplate userInfo] objectForKey:@"templateId"];
|
|
1710
|
+
[self sendTemplateEventWithName:tabBarTemplate name:@"didSelectTemplate" json:@{@"selectedTemplateId":selectedTemplateId}];
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1714
|
+
# pragma PointOfInterest
|
|
1715
|
+
-(void)pointOfInterestTemplate:(CPPointOfInterestTemplate *)pointOfInterestTemplate didChangeMapRegion:(MKCoordinateRegion)region API_AVAILABLE(ios(14.0)){
|
|
1716
|
+
// noop
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
-(void)pointOfInterestTemplate:(CPPointOfInterestTemplate *)pointOfInterestTemplate didSelectPointOfInterest:(CPPointOfInterest *)pointOfInterest API_AVAILABLE(ios(14.0)){
|
|
1720
|
+
[self sendTemplateEventWithName:pointOfInterestTemplate name:@"didSelectPointOfInterest" json:[pointOfInterest userInfo]];
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
# pragma InterfaceController
|
|
1724
|
+
|
|
1725
|
+
- (void)templateDidAppear:(CPTemplate *)aTemplate animated:(BOOL)animated API_AVAILABLE(ios(12.0)) {
|
|
1726
|
+
[self sendTemplateEventWithName:aTemplate name:@"didAppear" json:@{ @"animated": @(animated) }];
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1729
|
+
- (void)templateDidDisappear:(CPTemplate *)aTemplate animated:(BOOL)animated API_AVAILABLE(ios(12.0)) {
|
|
1730
|
+
[self sendTemplateEventWithName:aTemplate name:@"didDisappear" json:@{ @"animated": @(animated) }];
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
- (void)templateWillAppear:(CPTemplate *)aTemplate animated:(BOOL)animated API_AVAILABLE(ios(12.0)) {
|
|
1734
|
+
[self sendTemplateEventWithName:aTemplate name:@"willAppear" json:@{ @"animated": @(animated) }];
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
- (void)templateWillDisappear:(CPTemplate *)aTemplate animated:(BOOL)animated API_AVAILABLE(ios(12.0)) {
|
|
1738
|
+
[self sendTemplateEventWithName:aTemplate name:@"willDisappear" json:@{ @"animated": @(animated) }];
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
# pragma NowPlaying
|
|
1742
|
+
|
|
1743
|
+
- (void)nowPlayingTemplateUpNextButtonTapped:(CPNowPlayingTemplate *)nowPlayingTemplate API_AVAILABLE(ios(14.0)){
|
|
1744
|
+
if (nowPlayingTemplate) {
|
|
1745
|
+
[self sendTemplateEventWithName:nowPlayingTemplate name:@"upNextButtonPressed"];
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
- (void)nowPlayingTemplateAlbumArtistButtonTapped:(CPNowPlayingTemplate *)nowPlayingTemplate API_AVAILABLE(ios(14.0)){
|
|
1750
|
+
if (nowPlayingTemplate) {
|
|
1751
|
+
[self sendTemplateEventWithName:nowPlayingTemplate name:@"albumArtistButtonPressed"];
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
@end
|