@javascriptcommon/react-native-carplay 2.3.11 → 2.4.1-beta.0

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.
Files changed (134) hide show
  1. package/android/build.gradle +110 -0
  2. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  3. package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  4. package/android/gradle.properties +20 -0
  5. package/android/gradlew +234 -0
  6. package/android/gradlew.bat +89 -0
  7. package/android/src/main/AndroidManifest.xml +30 -0
  8. package/android/src/main/AndroidManifestNew.xml +30 -0
  9. package/android/src/main/java/org/birkir/carplay/CarPlayModule.kt +321 -0
  10. package/android/src/main/java/org/birkir/carplay/CarPlayPackage.kt +18 -0
  11. package/android/src/main/java/org/birkir/carplay/CarPlayService.kt +35 -0
  12. package/android/src/main/java/org/birkir/carplay/CarPlaySession.kt +126 -0
  13. package/android/src/main/java/org/birkir/carplay/parser/Ext.kt +11 -0
  14. package/android/src/main/java/org/birkir/carplay/parser/Parser.kt +18 -0
  15. package/android/src/main/java/org/birkir/carplay/parser/RCTGridTemplate.kt +28 -0
  16. package/android/src/main/java/org/birkir/carplay/parser/RCTListTemplate.kt +64 -0
  17. package/android/src/main/java/org/birkir/carplay/parser/RCTMapTemplate.kt +128 -0
  18. package/android/src/main/java/org/birkir/carplay/parser/RCTMessageTemplate.kt +28 -0
  19. package/android/src/main/java/org/birkir/carplay/parser/RCTPaneTemplate.kt +24 -0
  20. package/android/src/main/java/org/birkir/carplay/parser/RCTSearchTemplate.kt +41 -0
  21. package/android/src/main/java/org/birkir/carplay/parser/RCTTabTemplate.kt +157 -0
  22. package/android/src/main/java/org/birkir/carplay/parser/RCTTemplate.kt +419 -0
  23. package/android/src/main/java/org/birkir/carplay/parser/TemplateParser.kt +35 -0
  24. package/android/src/main/java/org/birkir/carplay/screens/CarScreen.kt +76 -0
  25. package/android/src/main/java/org/birkir/carplay/screens/CarScreenContext.kt +10 -0
  26. package/android/src/main/java/org/birkir/carplay/utils/EventEmitter.kt +167 -0
  27. package/android/src/main/java/org/birkir/carplay/utils/VirtualRenderer.kt +75 -0
  28. package/ios/RCTConvert+RNCarPlay.h +7 -8
  29. package/ios/RCTConvert+RNCarPlay.m +3 -2
  30. package/ios/RNCarPlay.h +11 -14
  31. package/ios/RNCarPlay.m +749 -945
  32. package/ios/RNCarPlayViewController.h +10 -0
  33. package/ios/RNCarPlayViewController.m +50 -0
  34. package/lib/CarPlay.d.ts +183 -0
  35. package/lib/CarPlay.d.ts.map +1 -0
  36. package/lib/index.d.ts +44 -0
  37. package/lib/index.d.ts.map +1 -0
  38. package/lib/interfaces/Action.d.ts +13 -0
  39. package/lib/interfaces/Action.d.ts.map +1 -0
  40. package/lib/interfaces/AlertAction.d.ts +6 -0
  41. package/lib/interfaces/AlertAction.d.ts.map +1 -0
  42. package/lib/interfaces/BarButton.d.ts +39 -0
  43. package/lib/interfaces/BarButton.d.ts.map +1 -0
  44. package/lib/interfaces/CarColor.d.ts +2 -0
  45. package/lib/interfaces/CarColor.d.ts.map +1 -0
  46. package/lib/interfaces/GridButton.d.ts +24 -0
  47. package/lib/interfaces/GridButton.d.ts.map +1 -0
  48. package/lib/interfaces/Header.d.ts +15 -0
  49. package/lib/interfaces/Header.d.ts.map +1 -0
  50. package/lib/interfaces/ListItem.d.ts +90 -0
  51. package/lib/interfaces/ListItem.d.ts.map +1 -0
  52. package/lib/interfaces/ListItemUpdate.d.ts +15 -0
  53. package/lib/interfaces/ListItemUpdate.d.ts.map +1 -0
  54. package/lib/interfaces/ListSection.d.ts +21 -0
  55. package/lib/interfaces/ListSection.d.ts.map +1 -0
  56. package/lib/interfaces/Maneuver.d.ts +31 -0
  57. package/lib/interfaces/Maneuver.d.ts.map +1 -0
  58. package/lib/interfaces/MapButton.d.ts +27 -0
  59. package/lib/interfaces/MapButton.d.ts.map +1 -0
  60. package/lib/interfaces/NavigationAlert.d.ts +44 -0
  61. package/lib/interfaces/NavigationAlert.d.ts.map +1 -0
  62. package/lib/interfaces/NavigationInfo.d.ts +17 -0
  63. package/lib/interfaces/NavigationInfo.d.ts.map +1 -0
  64. package/lib/interfaces/NavigationStep.d.ts +17 -0
  65. package/lib/interfaces/NavigationStep.d.ts.map +1 -0
  66. package/lib/interfaces/Pane.d.ts +29 -0
  67. package/lib/interfaces/Pane.d.ts.map +1 -0
  68. package/lib/interfaces/PauseReason.d.ts +8 -0
  69. package/lib/interfaces/PauseReason.d.ts.map +1 -0
  70. package/lib/interfaces/Place.d.ts +11 -0
  71. package/lib/interfaces/Place.d.ts.map +1 -0
  72. package/lib/interfaces/TextConfiguration.d.ts +6 -0
  73. package/lib/interfaces/TextConfiguration.d.ts.map +1 -0
  74. package/lib/interfaces/TimeRemainingColor.d.ts +2 -0
  75. package/lib/interfaces/TimeRemainingColor.d.ts.map +1 -0
  76. package/lib/interfaces/TravelEstimates.d.ts +37 -0
  77. package/lib/interfaces/TravelEstimates.d.ts.map +1 -0
  78. package/lib/interfaces/VoiceControlState.d.ts +8 -0
  79. package/lib/interfaces/VoiceControlState.d.ts.map +1 -0
  80. package/lib/navigation/NavigationSession.d.ts +18 -0
  81. package/lib/navigation/NavigationSession.d.ts.map +1 -0
  82. package/lib/navigation/Trip.d.ts +22 -0
  83. package/lib/navigation/Trip.d.ts.map +1 -0
  84. package/lib/templates/ActionSheetTemplate.d.ts +18 -0
  85. package/lib/templates/ActionSheetTemplate.d.ts.map +1 -0
  86. package/lib/templates/AlertTemplate.d.ts +17 -0
  87. package/lib/templates/AlertTemplate.d.ts.map +1 -0
  88. package/lib/templates/ContactTemplate.d.ts +36 -0
  89. package/lib/templates/ContactTemplate.d.ts.map +1 -0
  90. package/lib/templates/GridTemplate.d.ts +38 -0
  91. package/lib/templates/GridTemplate.d.ts.map +1 -0
  92. package/lib/templates/InformationTemplate.d.ts +28 -0
  93. package/lib/templates/InformationTemplate.d.ts.map +1 -0
  94. package/lib/templates/ListTemplate.d.ts +127 -0
  95. package/lib/templates/ListTemplate.d.ts.map +1 -0
  96. package/lib/templates/ListTemplate.js +24 -16
  97. package/lib/templates/MapTemplate.d.ts +171 -0
  98. package/lib/templates/MapTemplate.d.ts.map +1 -0
  99. package/lib/templates/NowPlayingTemplate.d.ts +31 -0
  100. package/lib/templates/NowPlayingTemplate.d.ts.map +1 -0
  101. package/lib/templates/PointOfInterestTemplate.d.ts +33 -0
  102. package/lib/templates/PointOfInterestTemplate.d.ts.map +1 -0
  103. package/lib/templates/SearchTemplate.d.ts +32 -0
  104. package/lib/templates/SearchTemplate.d.ts.map +1 -0
  105. package/lib/templates/SearchTemplate.js +2 -2
  106. package/lib/templates/TabBarTemplate.d.ts +27 -0
  107. package/lib/templates/TabBarTemplate.d.ts.map +1 -0
  108. package/lib/templates/Template.d.ts +82 -0
  109. package/lib/templates/Template.d.ts.map +1 -0
  110. package/lib/templates/VoiceControlTemplate.d.ts +18 -0
  111. package/lib/templates/VoiceControlTemplate.d.ts.map +1 -0
  112. package/lib/templates/android/AndroidNavigationBaseTemplate.d.ts +19 -0
  113. package/lib/templates/android/AndroidNavigationBaseTemplate.d.ts.map +1 -0
  114. package/lib/templates/android/MessageTemplate.d.ts +16 -0
  115. package/lib/templates/android/MessageTemplate.d.ts.map +1 -0
  116. package/lib/templates/android/NavigationTemplate.d.ts +44 -0
  117. package/lib/templates/android/NavigationTemplate.d.ts.map +1 -0
  118. package/lib/templates/android/PaneTemplate.d.ts +13 -0
  119. package/lib/templates/android/PaneTemplate.d.ts.map +1 -0
  120. package/lib/templates/android/PlaceListMapTemplate.d.ts +58 -0
  121. package/lib/templates/android/PlaceListMapTemplate.d.ts.map +1 -0
  122. package/lib/templates/android/PlaceListNavigationTemplate.d.ts +51 -0
  123. package/lib/templates/android/PlaceListNavigationTemplate.d.ts.map +1 -0
  124. package/lib/templates/android/RoutePreviewNavigationTemplate.d.ts +60 -0
  125. package/lib/templates/android/RoutePreviewNavigationTemplate.d.ts.map +1 -0
  126. package/package.json +3 -3
  127. package/react-native-carplay.podspec +3 -3
  128. package/src/CarPlay.ts +28 -16
  129. package/src/interfaces/ListItem.ts +14 -8
  130. package/src/interfaces/ListSection.ts +1 -1
  131. package/src/templates/ListTemplate.ts +64 -44
  132. package/src/templates/NowPlayingTemplate.ts +10 -3
  133. package/src/templates/SearchTemplate.ts +2 -2
  134. package/README.md +0 -633
package/ios/RNCarPlay.m CHANGED
@@ -1,4 +1,5 @@
1
1
  #import "RNCarPlay.h"
2
+ #import "RNCarPlayViewController.h"
2
3
  #import <React/RCTConvert.h>
3
4
  #import <React/RCTRootView.h>
4
5
 
@@ -21,7 +22,7 @@
21
22
  hasListeners = NO;
22
23
  }
23
24
 
24
- + (NSDictionary *) getConnectedWindowInformation: (CPWindow *) window API_AVAILABLE(ios(12.0)){
25
+ + (NSDictionary *) getConnectedWindowInformation: (CPWindow *) window {
25
26
  return @{
26
27
  @"width": @(window.bounds.size.width),
27
28
  @"height": @(window.bounds.size.height),
@@ -29,12 +30,11 @@
29
30
  };
30
31
  }
31
32
 
32
- + (void) connectWithInterfaceController:(CPInterfaceController*)interfaceController window:(CPWindow*)window API_AVAILABLE(ios(12.0)){
33
+ + (void) connectWithInterfaceController:(CPInterfaceController*)interfaceController window:(CPWindow*)window {
33
34
  RNCPStore * store = [RNCPStore sharedManager];
34
35
  store.interfaceController = interfaceController;
35
36
  store.window = window;
36
37
  [store setConnected:true];
37
-
38
38
  RNCarPlay *cp = [RNCarPlay allocWithZone:nil];
39
39
  if (cp.bridge) {
40
40
  [cp sendEventWithName:@"didConnect" body:[self getConnectedWindowInformation:window]];
@@ -45,7 +45,7 @@
45
45
  RNCarPlay *cp = [RNCarPlay allocWithZone:nil];
46
46
  RNCPStore *store = [RNCPStore sharedManager];
47
47
  [store setConnected:false];
48
- [[store.window subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
48
+ store.window.rootViewController = nil;
49
49
 
50
50
  if (cp.bridge) {
51
51
  [cp sendEventWithName:@"didDisconnect" body:@{}];
@@ -68,6 +68,7 @@ RCT_EXPORT_MODULE();
68
68
  return @[
69
69
  @"didConnect",
70
70
  @"didDisconnect",
71
+ @"didPressMenuItem",
71
72
  // interface
72
73
  @"barButtonPressed",
73
74
  @"backButtonPressed",
@@ -82,6 +83,7 @@ RCT_EXPORT_MODULE();
82
83
  @"actionButtonPressed",
83
84
  // list
84
85
  @"didSelectListItem",
86
+ @"didSelectListItemRowImage",
85
87
  // search
86
88
  @"updatedSearchText",
87
89
  @"searchButtonPressed",
@@ -112,8 +114,6 @@ RCT_EXPORT_MODULE();
112
114
  @"alertActionPressed",
113
115
  @"selectedPreviewForTrip",
114
116
  @"startedTrip",
115
- @"didSelectRowItem",
116
- @"templateLoaded"
117
117
  ];
118
118
  }
119
119
 
@@ -156,315 +156,329 @@ RCT_EXPORT_MODULE();
156
156
  }
157
157
 
158
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;
159
+ UIGraphicsImageRendererFormat *renderFormat = [UIGraphicsImageRendererFormat defaultFormat];
160
+ renderFormat.opaque = NO;
161
+ UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size format:renderFormat];
162
+
163
+ UIImage *resizedImage = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
164
+ [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
165
+ }];
166
+ return resizedImage;
164
167
  }
165
168
 
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]];
169
+ - (void)updateItemImageWithURL:(CPListItem *)item imgUrl:(NSString *)imgUrlString placeholderImage:(UIImage *)placeholderImage {
170
+ dispatch_async(dispatch_get_main_queue(), ^{
171
+ [item setImage:placeholderImage];
172
+ });
173
+
174
+ NSURL *imgUrl = [NSURL URLWithString:imgUrlString];
175
+
176
+ NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:imgUrl completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
177
+ if (data) {
178
+ UIImage *image = [UIImage imageWithData:data];
179
+ dispatch_async(dispatch_get_main_queue(), ^{
180
+ [item setImage:image];
181
+ });
182
+ } else {
183
+ NSLog(@"Failed to load image from URL: %@", imgUrl);
171
184
  }
172
- }
185
+ }];
186
+ [task resume];
173
187
  }
174
188
 
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];
189
+ - (void)updateListRowItemImageWithURL:(CPListImageRowItem *)item imgUrl:(NSString *)imgUrlString index:(int)index placeholderImage:(UIImage *)placeholderImage {
190
+ dispatch_async(dispatch_get_main_queue(), ^{
191
+ NSMutableArray* newImages = [item.gridImages mutableCopy];
192
+
193
+ @try {
194
+ newImages[index] = placeholderImage;
195
+ }
196
+ @catch (NSException *exception) {
197
+ // Best effort updating the array
198
+ NSLog(@"Failed to update images array of CPListImageRowItem");
199
+ }
200
+
201
+ [item updateImages:newImages];
202
+ });
203
+
204
+ NSURL *imgUrl = [NSURL URLWithString:imgUrlString];
205
+
206
+ NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:imgUrl completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
207
+ if (data) {
208
+ UIImage *image = [UIImage imageWithData:data];
181
209
 
182
- if (needsTemplateLoadedCallback) {
183
- NSMutableDictionary *bodyDictionary = [NSMutableDictionary dictionary];
184
- if (templateId) {
185
- bodyDictionary[@"templateId"] = templateId;
210
+ dispatch_async(dispatch_get_main_queue(), ^{
211
+ NSMutableArray* newImages = [item.gridImages mutableCopy];
212
+
213
+ @try {
214
+ newImages[index] = image;
186
215
  }
187
- [self sendEventWithName:@"templateLoaded" body:bodyDictionary];
188
- }
189
- });
190
- } else {
191
- [self createTemplateMethod:templateId config:config];
216
+ @catch (NSException *exception) {
217
+ // Best effort updating the array
218
+ NSLog(@"Failed to update images array of CPListImageRowItem");
219
+ }
220
+
221
+ [item updateImages:newImages];
222
+ });
223
+ } else {
224
+ NSLog(@"Failed to load image for CPListImageRowItem from URL: %@", imgUrl);
225
+ }
226
+ }];
227
+ [task resume];
228
+ }
229
+
230
+ RCT_EXPORT_METHOD(checkForConnection) {
231
+ RNCPStore *store = [RNCPStore sharedManager];
232
+ if ([store isConnected] && hasListeners) {
233
+ [self sendEventWithName:@"didConnect" body:[RNCarPlay getConnectedWindowInformation: store.window]];
192
234
  }
193
235
  }
194
236
 
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"]];
237
+ RCT_EXPORT_METHOD(createTemplate:(NSString *)templateId config:(NSDictionary*)config callback:(id)callback) {
238
+ // Get the shared instance of the RNCPStore class
239
+ RNCPStore *store = [RNCPStore sharedManager];
240
+
241
+ // Extract values from the 'config' dictionary
242
+ NSString *type = [RCTConvert NSString:config[@"type"]];
243
+ NSString *title = [RCTConvert NSString:config[@"title"]];
244
+ NSArray *leadingNavigationBarButtons = [self parseBarButtons:[RCTConvert NSArray:config[@"leadingNavigationBarButtons"]] templateId:templateId];
245
+ NSArray *trailingNavigationBarButtons = [self parseBarButtons:[RCTConvert NSArray:config[@"trailingNavigationBarButtons"]] templateId:templateId];
246
+
247
+ // Create a new CPTemplate object
248
+ CPTemplate *carPlayTemplate = [[CPTemplate alloc] init];
249
+
250
+ if ([type isEqualToString:@"search"]) {
251
+ CPSearchTemplate *searchTemplate = [[CPSearchTemplate alloc] init];
252
+ searchTemplate.delegate = self;
253
+ carPlayTemplate = searchTemplate;
254
+ }
255
+ else if ([type isEqualToString:@"grid"]) {
256
+ NSArray *buttons = [self parseGridButtons:[RCTConvert NSArray:config[@"buttons"]] templateId:templateId];
257
+ CPGridTemplate *gridTemplate = [[CPGridTemplate alloc] initWithTitle:title gridButtons:buttons];
258
+ [gridTemplate setLeadingNavigationBarButtons:leadingNavigationBarButtons];
259
+ [gridTemplate setTrailingNavigationBarButtons:trailingNavigationBarButtons];
260
+ carPlayTemplate = gridTemplate;
261
+ }
262
+ else if ([type isEqualToString:@"list"]) {
263
+ NSArray *sections = [self parseSections:[RCTConvert NSArray:config[@"sections"]] templateId:templateId];
264
+ CPListTemplate *listTemplate;
265
+ if (@available(iOS 15.0, *)) {
266
+ if ([config objectForKey:@"assistant"]) {
267
+ NSDictionary *assistant = [config objectForKey:@"assistant"];
268
+ BOOL _enabled = [assistant valueForKey:@"enabled"];
269
+ if (_enabled) {
270
+ CPAssistantCellConfiguration *conf = [[CPAssistantCellConfiguration alloc] initWithPosition:[RCTConvert CPAssistantCellPosition:[config valueForKey:@"position"]] visibility:[RCTConvert CPAssistantCellVisibility:[config valueForKey:@"visibility"]] assistantAction:[RCTConvert CPAssistantCellActionType:[config valueForKey:@"visibility"]]];
271
+ listTemplate = [[CPListTemplate alloc] initWithTitle:title sections:sections assistantCellConfiguration:conf];
260
272
  }
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
273
  }
271
274
  }
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"] }];
275
+ if (listTemplate == nil) {
276
+ // Fallback on earlier versions
277
+ listTemplate = [[CPListTemplate alloc] initWithTitle:title sections:sections];
278
+ }
279
+ [listTemplate setLeadingNavigationBarButtons:leadingNavigationBarButtons];
280
+ [listTemplate setTrailingNavigationBarButtons:trailingNavigationBarButtons];
281
+ if (![RCTConvert BOOL:config[@"backButtonHidden"]]) {
282
+ if (@available(iOS 14.0, *)) {
283
+ CPBarButton *backButton = [[CPBarButton alloc] initWithTitle:@" Back" handler:^(CPBarButton * _Nonnull barButton) {
284
+ if (hasListeners) {
285
+ [self sendEventWithName:@"backButtonPressed" body:@{@"templateId":templateId}];
348
286
  }
287
+ [self popTemplate:false];
349
288
  }];
350
- [actions addObject:action];
289
+ [listTemplate setBackButton:backButton];
351
290
  }
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];
291
+ }
292
+ if (config[@"emptyViewTitleVariants"]) {
293
+ if (@available(iOS 14.0, *)) {
294
+ listTemplate.emptyViewTitleVariants = [RCTConvert NSArray:config[@"emptyViewTitleVariants"]];
364
295
  }
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;
296
+ }
297
+ if (config[@"emptyViewSubtitleVariants"]) {
298
+ if (@available(iOS 14.0, *)) {
299
+ listTemplate.emptyViewSubtitleVariants = [RCTConvert NSArray:config[@"emptyViewSubtitleVariants"]];
384
300
  }
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
- }
301
+ }
302
+ listTemplate.delegate = self;
303
+ carPlayTemplate = listTemplate;
304
+ }
305
+ else if ([type isEqualToString:@"map"]) {
306
+ CPMapTemplate *mapTemplate = [[CPMapTemplate alloc] init];
307
+
308
+ [self applyConfigForMapTemplate:mapTemplate templateId:templateId config:config];
309
+ [mapTemplate setLeadingNavigationBarButtons:leadingNavigationBarButtons];
310
+ [mapTemplate setTrailingNavigationBarButtons:trailingNavigationBarButtons];
311
+ [mapTemplate setUserInfo:@{ @"templateId": templateId }];
312
+ mapTemplate.mapDelegate = self;
313
+
314
+ carPlayTemplate = mapTemplate;
315
+ } else if ([type isEqualToString:@"voicecontrol"]) {
316
+ CPVoiceControlTemplate *voiceTemplate = [[CPVoiceControlTemplate alloc] initWithVoiceControlStates: [self parseVoiceControlStates:config[@"voiceControlStates"]]];
317
+ carPlayTemplate = voiceTemplate;
318
+ } else if ([type isEqualToString:@"nowplaying"]) {
319
+ CPNowPlayingTemplate *nowPlayingTemplate = [CPNowPlayingTemplate sharedTemplate];
320
+ [nowPlayingTemplate setAlbumArtistButtonEnabled:[RCTConvert BOOL:config[@"albumArtistButtonEnabled"]]];
321
+ [nowPlayingTemplate setUpNextTitle:[RCTConvert NSString:config[@"upNextButtonTitle"]]];
322
+ [nowPlayingTemplate setUpNextButtonEnabled:[RCTConvert BOOL:config[@"upNextButtonEnabled"]]];
323
+ NSMutableArray<CPNowPlayingButton *> *buttons = [NSMutableArray new];
324
+ NSArray<NSDictionary*> *_buttons = [RCTConvert NSDictionaryArray:config[@"buttons"]];
325
+
326
+ NSDictionary *buttonTypeMapping = @{
327
+ @"shuffle": CPNowPlayingShuffleButton.class,
328
+ @"add-to-library": CPNowPlayingAddToLibraryButton.class,
329
+ @"more": CPNowPlayingMoreButton.class,
330
+ @"playback": CPNowPlayingPlaybackRateButton.class,
331
+ @"repeat": CPNowPlayingRepeatButton.class,
332
+ @"image": CPNowPlayingImageButton.class
333
+ };
334
+
335
+ for (NSDictionary *_button in _buttons) {
336
+ NSString *buttonType = [RCTConvert NSString:_button[@"type"]];
337
+ NSDictionary *body = @{@"templateId":templateId, @"id": _button[@"id"] };
338
+ Class buttonClass = buttonTypeMapping[buttonType];
339
+ if (buttonClass) {
340
+ CPNowPlayingButton *button;
396
341
 
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) {
342
+ if ([buttonType isEqualToString:@"image"]) {
343
+ UIImage *_image = [RCTConvert UIImage:[_button objectForKey:@"image"]];
344
+ button = [[CPNowPlayingImageButton alloc] initWithImage:_image handler:^(__kindof CPNowPlayingImageButton * _Nonnull) {
400
345
  if (self->hasListeners) {
401
- [self sendEventWithName:@"actionButtonPressed" body:@{@"templateId":templateId, @"id": _action[@"id"] }];
346
+ [self sendEventWithName:@"buttonPressed" body:body];
347
+ }
348
+ }];
349
+ } else {
350
+ button = [[buttonClass alloc] initWithHandler:^(__kindof CPNowPlayingButton * _Nonnull) {
351
+ if (self->hasListeners) {
352
+ [self sendEventWithName:@"buttonPressed" body:body];
402
353
  }
403
354
  }];
404
- [actions addObject:action];
405
355
  }
406
356
 
407
- CPInformationTemplate *informationTemplate = [[CPInformationTemplate alloc] initWithTitle:title layout:layout items:items actions:actions];
408
- carPlayTemplate = informationTemplate;
357
+ [buttons addObject:button];
409
358
  }
410
359
  }
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
- }
360
+ [nowPlayingTemplate updateNowPlayingButtons:buttons];
361
+ carPlayTemplate = nowPlayingTemplate;
362
+ } else if ([type isEqualToString:@"tabbar"]) {
363
+ CPTabBarTemplate *tabBarTemplate = [[CPTabBarTemplate alloc] initWithTemplates:[self parseTemplatesFrom:config]];
364
+ tabBarTemplate.delegate = self;
365
+ carPlayTemplate = tabBarTemplate;
366
+ } else if ([type isEqualToString:@"contact"]) {
367
+ NSString *nm = [RCTConvert NSString:config[@"name"]];
368
+ UIImage *img = [RCTConvert UIImage:config[@"image"]];
369
+ CPContact *contact = [[CPContact alloc] initWithName:nm image:img];
370
+ [contact setSubtitle:config[@"subtitle"]];
371
+ [contact setActions:[self parseButtons:config[@"actions"] templateId:templateId]];
372
+ CPContactTemplate *contactTemplate = [[CPContactTemplate alloc] initWithContact:contact];
373
+ carPlayTemplate = contactTemplate;
374
+ } else if ([type isEqualToString:@"actionsheet"]) {
375
+ NSString *title = [RCTConvert NSString:config[@"title"]];
376
+ NSString *message = [RCTConvert NSString:config[@"message"]];
377
+ NSMutableArray<CPAlertAction *> *actions = [NSMutableArray new];
378
+ NSArray<NSDictionary*> *_actions = [RCTConvert NSDictionaryArray:config[@"actions"]];
379
+ for (NSDictionary *_action in _actions) {
380
+ CPAlertAction *action = [[CPAlertAction alloc] initWithTitle:[RCTConvert NSString:_action[@"title"]] style:[RCTConvert CPAlertActionStyle:_action[@"style"]] handler:^(CPAlertAction *a) {
381
+ if (self->hasListeners) {
382
+ [self sendEventWithName:@"actionButtonPressed" body:@{@"templateId":templateId, @"id": _action[@"id"] }];
383
+ }
384
+ }];
385
+ [actions addObject:action];
435
386
  }
436
-
437
- [carPlayTemplate setUserInfo:@{ @"templateId": templateId }];
438
- [store setTemplate:templateId template:carPlayTemplate];
387
+ CPActionSheetTemplate *actionSheetTemplate = [[CPActionSheetTemplate alloc] initWithTitle:title message:message actions:actions];
388
+ carPlayTemplate = actionSheetTemplate;
389
+ } else if ([type isEqualToString:@"alert"]) {
390
+ NSMutableArray<CPAlertAction *> *actions = [NSMutableArray new];
391
+ NSArray<NSDictionary*> *_actions = [RCTConvert NSDictionaryArray:config[@"actions"]];
392
+ for (NSDictionary *_action in _actions) {
393
+ CPAlertAction *action = [[CPAlertAction alloc] initWithTitle:[RCTConvert NSString:_action[@"title"]] style:[RCTConvert CPAlertActionStyle:_action[@"style"]] handler:^(CPAlertAction *a) {
394
+ if (self->hasListeners) {
395
+ [self sendEventWithName:@"actionButtonPressed" body:@{@"templateId":templateId, @"id": _action[@"id"] }];
396
+ }
397
+ }];
398
+ [actions addObject:action];
399
+ }
400
+ NSArray<NSString*>* titleVariants = [RCTConvert NSArray:config[@"titleVariants"]];
401
+ CPAlertTemplate *alertTemplate = [[CPAlertTemplate alloc] initWithTitleVariants:titleVariants actions:actions];
402
+ carPlayTemplate = alertTemplate;
403
+ } else if ([type isEqualToString:@"poi"]) {
404
+ NSString *title = [RCTConvert NSString:config[@"title"]];
405
+ NSMutableArray<__kindof CPPointOfInterest *> * items = [NSMutableArray new];
406
+ NSUInteger selectedIndex = 0;
407
+
408
+ NSArray<NSDictionary*> *_items = [RCTConvert NSDictionaryArray:config[@"items"]];
409
+ for (NSDictionary *_item in _items) {
410
+ CPPointOfInterest *poi = [RCTConvert CPPointOfInterest:_item];
411
+ [poi setUserInfo:_item];
412
+ [items addObject:poi];
413
+ }
414
+
415
+ CPPointOfInterestTemplate *poiTemplate = [[CPPointOfInterestTemplate alloc] initWithTitle:title pointsOfInterest:items selectedIndex:selectedIndex];
416
+ poiTemplate.pointOfInterestDelegate = self;
417
+ carPlayTemplate = poiTemplate;
418
+ } else if ([type isEqualToString:@"information"]) {
419
+ NSString *title = [RCTConvert NSString:config[@"title"]];
420
+ CPInformationTemplateLayout layout = [RCTConvert BOOL:config[@"leading"]] ? CPInformationTemplateLayoutLeading : CPInformationTemplateLayoutTwoColumn;
421
+ NSMutableArray<__kindof CPInformationItem *> * items = [NSMutableArray new];
422
+ NSMutableArray<__kindof CPTextButton *> * actions = [NSMutableArray new];
423
+
424
+ NSArray<NSDictionary*> *_items = [RCTConvert NSDictionaryArray:config[@"items"]];
425
+ for (NSDictionary *_item in _items) {
426
+ [items addObject:[[CPInformationItem alloc] initWithTitle:_item[@"title"] detail:_item[@"detail"]]];
427
+ }
428
+
429
+ NSArray<NSDictionary*> *_actions = [RCTConvert NSDictionaryArray:config[@"actions"]];
430
+ for (NSDictionary *_action in _actions) {
431
+ CPTextButton *action = [[CPTextButton alloc] initWithTitle:_action[@"title"] textStyle:CPTextButtonStyleNormal handler:^(__kindof CPTextButton * _Nonnull contactButton) {
432
+ if (self->hasListeners) {
433
+ [self sendEventWithName:@"actionButtonPressed" body:@{@"templateId":templateId, @"id": _action[@"id"] }];
434
+ }
435
+ }];
436
+ [actions addObject:action];
437
+ }
438
+
439
+ CPInformationTemplate *informationTemplate = [[CPInformationTemplate alloc] initWithTitle:title layout:layout items:items actions:actions];
440
+ carPlayTemplate = informationTemplate;
439
441
  }
442
+
443
+ if (config[@"tabSystemItem"]) {
444
+ carPlayTemplate.tabSystemItem = [RCTConvert NSInteger:config[@"tabSystemItem"]];
445
+ }
446
+ if (config[@"tabSystemImageName"]) {
447
+ carPlayTemplate.tabImage = [UIImage systemImageNamed:[RCTConvert NSString:config[@"tabSystemImageName"]]];
448
+ }
449
+ if (config[@"tabImage"]) {
450
+ carPlayTemplate.tabImage = [RCTConvert UIImage:config[@"tabImage"]];
451
+ }
452
+ if (config[@"tabTitle"]) {
453
+ carPlayTemplate.tabTitle = [RCTConvert NSString:config[@"tabTitle"]];
454
+ }
455
+
456
+ [carPlayTemplate setUserInfo:@{ @"templateId": templateId }];
457
+ [store setTemplate:templateId template:carPlayTemplate];
440
458
  }
441
459
 
442
460
  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];
461
+ RNCPStore *store = [RNCPStore sharedManager];
462
+ CPTrip *trip = [self parseTrip:config];
463
+ NSMutableDictionary *userInfo = trip.userInfo;
464
+ if (!userInfo) {
465
+ userInfo = [[NSMutableDictionary alloc] init];
466
+ trip.userInfo = userInfo;
454
467
  }
468
+
469
+ [userInfo setValue:tripId forKey:@"id"];
470
+ [store setTrip:tripId trip:trip];
455
471
  }
456
472
 
457
473
  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
- }
474
+ RNCPStore *store = [RNCPStore sharedManager];
475
+ CPTemplate *template = [store findTemplateById:templateId];
476
+ if (template) {
477
+ CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
478
+ CPTrip *trip = [[RNCPStore sharedManager] findTripById:tripId];
479
+ if (trip) {
480
+ CPTravelEstimates *estimates = [self parseTravelEstimates:travelEstimates];
481
+ [mapTemplate updateTravelEstimates:estimates forTrip:trip withTimeRemainingColor:(CPTimeRemainingColor) timeRemainingColor];
468
482
  }
469
483
  }
470
484
  }
@@ -474,573 +488,438 @@ RCT_REMAP_METHOD(startNavigationSession,
474
488
  tripId:(NSString *)tripId
475
489
  startNavigationSessionWithResolver:(RCTPromiseResolveBlock)resolve
476
490
  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);
491
+ RNCPStore *store = [RNCPStore sharedManager];
492
+ CPTemplate *template = [store findTemplateById:templateId];
493
+ if (template) {
494
+ CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
495
+ CPTrip *trip = [[RNCPStore sharedManager] findTripById:tripId];
496
+ if (trip) {
497
+ CPNavigationSession *navigationSession = [mapTemplate startNavigationSessionForTrip:trip];
498
+ [store setNavigationSession:tripId navigationSession:navigationSession];
499
+ resolve(@{ @"tripId": tripId, @"navigationSessionId": tripId });
490
500
  }
501
+ } else {
502
+ reject(@"template_not_found", @"Template not found in store", nil);
491
503
  }
492
504
  }
493
505
 
494
506
  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];
507
+ CPNavigationSession* navigationSession = [[RNCPStore sharedManager] findNavigationSessionById:navigationSessionId];
508
+ if (navigationSession) {
509
+ NSMutableArray<CPManeuver*>* upcomingManeuvers = [NSMutableArray array];
510
+ for (NSDictionary *maneuver in maneuvers) {
511
+ [upcomingManeuvers addObject:[self parseManeuver:maneuver]];
503
512
  }
513
+ [navigationSession setUpcomingManeuvers:upcomingManeuvers];
504
514
  }
505
515
  }
506
516
 
507
517
  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
- }
518
+ CPNavigationSession* navigationSession = [[RNCPStore sharedManager] findNavigationSessionById:navigationSessionId];
519
+ if (navigationSession) {
520
+ CPManeuver *maneuver = [[navigationSession upcomingManeuvers] objectAtIndex:maneuverIndex];
521
+ if (maneuver) {
522
+ [navigationSession updateTravelEstimates:[self parseTravelEstimates:travelEstimates] forManeuver:maneuver];
515
523
  }
516
524
  }
517
525
  }
518
526
 
519
527
  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
- }
528
+ CPNavigationSession* navigationSession = [[RNCPStore sharedManager] findNavigationSessionById:navigationSessionId];
529
+ if (navigationSession) {
530
+ [navigationSession pauseTripForReason:(CPTripPauseReason) reason description:description];
531
+ } else {
532
+ NSLog(@"Could not find session");
527
533
  }
528
534
  }
529
535
 
530
536
  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
- }
537
+ CPNavigationSession* navigationSession = [[RNCPStore sharedManager] findNavigationSessionById:navigationSessionId];
538
+ if (navigationSession) {
539
+ [navigationSession cancelTrip];
540
+ } else {
541
+ NSLog(@"Could not cancel. No session found.");
538
542
  }
539
543
  }
540
544
 
541
545
  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
- }
546
+ CPNavigationSession* navigationSession = [[RNCPStore sharedManager] findNavigationSessionById:navigationSessionId];
547
+ if (navigationSession) {
548
+ [navigationSession finishTrip];
547
549
  }
548
550
  }
549
551
 
550
552
  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
- }
553
+ RNCPStore *store = [RNCPStore sharedManager];
554
+ CPTemplate *template = [store findTemplateById:templateId];
555
+
556
+ store.interfaceController.delegate = self;
557
+
558
+ if (template) {
559
+ [store.interfaceController setRootTemplate:template animated:animated completion:^(BOOL done, NSError * _Nullable err) {
560
+ NSLog(@"error %@", err);
561
+ // noop
562
+ }];
563
+ } else {
564
+ NSLog(@"Failed to find template %@", template);
570
565
  }
571
566
  }
572
567
 
573
568
  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
- }
569
+ RNCPStore *store = [RNCPStore sharedManager];
570
+ CPTemplate *template = [store findTemplateById:templateId];
571
+ if (template) {
572
+ [store.interfaceController pushTemplate:template animated:animated completion:^(BOOL done, NSError * _Nullable err) {
573
+ NSLog(@"error %@", err);
574
+ // noop
575
+ }];
576
+ } else {
577
+ NSLog(@"Failed to find template %@", template);
590
578
  }
591
579
  }
592
580
 
593
581
  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
- }
582
+ RNCPStore *store = [RNCPStore sharedManager];
583
+ CPTemplate *template = [store findTemplateById:templateId];
584
+ if (template) {
585
+ [store.interfaceController popToTemplate:template animated:animated completion:^(BOOL done, NSError * _Nullable err) {
586
+ NSLog(@"error %@", err);
587
+ // noop
588
+ }];
589
+ } else {
590
+ NSLog(@"Failed to find template %@", template);
610
591
  }
611
592
  }
612
593
 
613
594
  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
- }
595
+ RNCPStore *store = [RNCPStore sharedManager];
596
+ [store.interfaceController popToRootTemplateAnimated:animated completion:^(BOOL done, NSError * _Nullable err) {
597
+ NSLog(@"error %@", err);
598
+ // noop
599
+ }];
626
600
  }
627
601
 
628
602
  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
- }
603
+ RNCPStore *store = [RNCPStore sharedManager];
604
+ [store.interfaceController popTemplateAnimated:animated completion:^(BOOL done, NSError * _Nullable err) {
605
+ NSLog(@"error %@", err);
606
+ // noop
607
+ }];
641
608
  }
642
609
 
643
610
  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
- }
611
+ RNCPStore *store = [RNCPStore sharedManager];
612
+ CPTemplate *template = [store findTemplateById:templateId];
613
+ if (template) {
614
+ [store.interfaceController presentTemplate:template animated:animated completion:^(BOOL done, NSError * _Nullable err) {
615
+ NSLog(@"error %@", err);
616
+ // noop
617
+ }];
618
+ } else {
619
+ NSLog(@"Failed to find template %@", template);
660
620
  }
661
621
  }
662
622
 
663
623
  RCT_EXPORT_METHOD(dismissTemplate:(BOOL)animated) {
664
- if (@available(iOS 12.0, *)) {
665
- RNCPStore *store = [RNCPStore sharedManager];
666
- [store.interfaceController dismissTemplateAnimated:animated];
667
- }
624
+ RNCPStore *store = [RNCPStore sharedManager];
625
+ [store.interfaceController dismissTemplateAnimated:animated];
668
626
  }
669
627
 
670
628
  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
- }
629
+ RNCPStore *store = [RNCPStore sharedManager];
630
+ CPTemplate *template = [store findTemplateById:templateId];
631
+ if (template && [template isKindOfClass:[CPListTemplate class]]) {
632
+ CPListTemplate *listTemplate = (CPListTemplate *)template;
633
+ if (config[@"leadingNavigationBarButtons"]) {
634
+ NSArray *leadingNavigationBarButtons = [self parseBarButtons:[RCTConvert NSArray:config[@"leadingNavigationBarButtons"]] templateId:templateId];
635
+ [listTemplate setLeadingNavigationBarButtons:leadingNavigationBarButtons];
636
+ }
637
+ if (config[@"trailingNavigationBarButtons"]) {
638
+ NSArray *trailingNavigationBarButtons = [self parseBarButtons:[RCTConvert NSArray:config[@"trailingNavigationBarButtons"]] templateId:templateId];
639
+ [listTemplate setTrailingNavigationBarButtons:trailingNavigationBarButtons];
640
+ }
641
+ if (config[@"emptyViewTitleVariants"]) {
642
+ listTemplate.emptyViewTitleVariants = [RCTConvert NSArray:config[@"emptyViewTitleVariants"]];
643
+ }
644
+ if (config[@"emptyViewSubtitleVariants"]) {
645
+ NSLog(@"%@", [RCTConvert NSArray:config[@"emptyViewSubtitleVariants"]]);
646
+ listTemplate.emptyViewSubtitleVariants = [RCTConvert NSArray:config[@"emptyViewSubtitleVariants"]];
691
647
  }
692
648
  }
693
649
  }
694
650
 
695
651
  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
- }
652
+ RNCPStore *store = [RNCPStore sharedManager];
653
+ CPTemplate *template = [store findTemplateById:templateId];
654
+ if (template) {
655
+ CPTabBarTemplate *tabBarTemplate = (CPTabBarTemplate*) template;
656
+ [tabBarTemplate updateTemplates:[self parseTemplatesFrom:config]];
657
+ } else {
658
+ NSLog(@"Failed to find template %@", template);
705
659
  }
706
660
  }
707
661
 
708
662
 
709
663
  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
- });
664
+ RNCPStore *store = [RNCPStore sharedManager];
665
+ CPTemplate *template = [store findTemplateById:templateId];
666
+ if (template) {
667
+ CPListTemplate *listTemplate = (CPListTemplate*) template;
668
+ [listTemplate updateSections:[self parseSections:sections templateId:templateId]];
669
+ } else {
670
+ NSLog(@"Failed to find template %@", template);
723
671
  }
724
672
  }
725
673
 
726
674
  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);
675
+ RNCPStore *store = [RNCPStore sharedManager];
676
+ CPTemplate *template = [store findTemplateById:templateId];
677
+ if (template) {
678
+ CPListTemplate *listTemplate = (CPListTemplate*) template;
679
+ NSInteger sectionIndex = [RCTConvert NSInteger:config[@"sectionIndex"]];
680
+ if (sectionIndex >= listTemplate.sections.count) {
681
+ NSLog(@"Failed to update item at section %d, sections size is %d", index, listTemplate.sections.count);
682
+ return;
794
683
  }
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
- });
684
+ CPListSection *section = listTemplate.sections[sectionIndex];
685
+ NSInteger index = [RCTConvert NSInteger:config[@"itemIndex"]];
686
+ if (index >= section.items.count) {
687
+ NSLog(@"Failed to update item at index %d, section size is %d", index, section.items.count);
688
+ return;
689
+ }
690
+ CPListItem *item = (CPListItem *)section.items[index];
691
+ if (config[@"imgUrl"]) {
692
+ NSString *imgUrlString = [RCTConvert NSString:config[@"imgUrl"]];
693
+ [self updateItemImageWithURL:item imgUrl:imgUrlString];
694
+ }
695
+ if (config[@"image"]) {
696
+ [item setImage:[RCTConvert UIImage:config[@"image"]]];
697
+ }
698
+ if (config[@"text"]) {
699
+ [item setText:[RCTConvert NSString:config[@"text"]]];
700
+ }
701
+ if (config[@"detailText"]) {
702
+ [item setDetailText:[RCTConvert NSString:config[@"detailText"]]];
703
+ }
704
+ if (config[@"isPlaying"]) {
705
+ [item setPlaying:[RCTConvert BOOL:config[@"isPlaying"]]];
706
+ }
707
+ if (@available(iOS 14.0, *) && config[@"playbackProgress"]) {
708
+ [item setPlaybackProgress:[RCTConvert CGFloat:config[@"playbackProgress"]]];
709
+ }
710
+ if (@available(iOS 14.0, *) && config[@"accessoryImage"]) {
711
+ [item setAccessoryImage:[RCTConvert UIImage:config[@"accessoryImage"]]];
712
+ }
713
+ } else {
714
+ NSLog(@"Failed to find template %@", template);
856
715
  }
857
716
  }
858
717
 
859
718
  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
- }
719
+ RNCPStore *store = [RNCPStore sharedManager];
720
+ CPTemplate *template = [store findTemplateById:templateId];
721
+ if (template) {
722
+ CPInformationTemplate *informationTemplate = (CPInformationTemplate*) template;
723
+ informationTemplate.items = [self parseInformationItems:items];
724
+ } else {
725
+ NSLog(@"Failed to find template %@", template);
869
726
  }
870
727
  }
871
728
 
872
729
  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
- }
730
+ RNCPStore *store = [RNCPStore sharedManager];
731
+ CPTemplate *template = [store findTemplateById:templateId];
732
+ if (template) {
733
+ CPInformationTemplate *informationTemplate = (CPInformationTemplate*) template;
734
+ informationTemplate.actions = [self parseInformationActions:actions templateId:templateId];
735
+ } else {
736
+ NSLog(@"Failed to find template %@", template);
882
737
  }
883
738
  }
884
739
 
885
740
  RCT_EXPORT_METHOD(getMaximumListItemCount:(NSString *)templateId
886
741
  resolver:(RCTPromiseResolveBlock)resolve
887
742
  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
- }
743
+ RNCPStore *store = [RNCPStore sharedManager];
744
+ CPTemplate *template = [store findTemplateById:templateId];
745
+ if (template) {
746
+ CPListTemplate *listTemplate = (CPListTemplate*) template;
747
+ resolve(@(CPListTemplate.maximumItemCount));
748
+ } else {
749
+ NSLog(@"Failed to find template %@", template);
750
+ reject(@"template_not_found", @"Template not found in store", nil);
751
+ }
752
+ }
753
+
754
+ RCT_EXPORT_METHOD(getMaximumListItemImageSize:(NSString *)templateId
755
+ resolver:(RCTPromiseResolveBlock)resolve
756
+ rejecter:(RCTPromiseRejectBlock)reject) {
757
+ RNCPStore *store = [RNCPStore sharedManager];
758
+ CPTemplate *template = [store findTemplateById:templateId];
759
+ if (template) {
760
+ CPListTemplate *listTemplate = (CPListTemplate*) template;
761
+ NSDictionary *sizeDict = @{
762
+ @"width": @(CPListItem.maximumImageSize.width),
763
+ @"height": @(CPListItem.maximumImageSize.height)
764
+ };
765
+ resolve(sizeDict);
766
+ } else {
767
+ NSLog(@"Failed to find template %@", template);
768
+ reject(@"template_not_found", @"Template not found in store", nil);
898
769
  }
899
770
  }
900
771
 
901
772
  RCT_EXPORT_METHOD(getMaximumListSectionCount:(NSString *)templateId
902
773
  resolver:(RCTPromiseResolveBlock)resolve
903
774
  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
- }
775
+ RNCPStore *store = [RNCPStore sharedManager];
776
+ CPTemplate *template = [store findTemplateById:templateId];
777
+ if (template) {
778
+ CPListTemplate *listTemplate = (CPListTemplate*) template;
779
+ resolve(@(CPListTemplate.maximumSectionCount));
780
+ } else {
781
+ NSLog(@"Failed to find template %@", template);
782
+ reject(@"template_not_found", @"Template not found in store", nil);
783
+ }
784
+ }
785
+
786
+ RCT_EXPORT_METHOD(getMaximumNumberOfGridImages:(NSString *)templateId
787
+ resolver:(RCTPromiseResolveBlock)resolve
788
+ rejecter:(RCTPromiseRejectBlock)reject) {
789
+ RNCPStore *store = [RNCPStore sharedManager];
790
+ CPTemplate *template = [store findTemplateById:templateId];
791
+ if (template) {
792
+ CPListTemplate *listTemplate = (CPListTemplate*) template;
793
+ resolve(@(CPMaximumNumberOfGridImages));
794
+ } else {
795
+ NSLog(@"Failed to find template %@", template);
796
+ reject(@"template_not_found", @"Template not found in store", nil);
797
+ }
798
+ }
799
+
800
+ RCT_EXPORT_METHOD(getMaximumListImageRowItemImageSize:(NSString *)templateId
801
+ resolver:(RCTPromiseResolveBlock)resolve
802
+ rejecter:(RCTPromiseRejectBlock)reject) {
803
+ RNCPStore *store = [RNCPStore sharedManager];
804
+ CPTemplate *template = [store findTemplateById:templateId];
805
+ if (template) {
806
+ CPListTemplate *listTemplate = (CPListTemplate*) template;
807
+ NSDictionary *sizeDict = @{
808
+ @"width": @(CPListImageRowItem.maximumImageSize.width),
809
+ @"height": @(CPListImageRowItem.maximumImageSize.height)
810
+ };
811
+ resolve(sizeDict);
812
+ } else {
813
+ NSLog(@"Failed to find template %@", template);
814
+ reject(@"template_not_found", @"Template not found in store", nil);
914
815
  }
915
816
  }
916
817
 
917
818
  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
- }
819
+ CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
820
+ if (template) {
821
+ CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
822
+ [self applyConfigForMapTemplate:mapTemplate templateId:templateId config:config];
823
+ } else {
824
+ NSLog(@"Failed to find template %@", template);
926
825
  }
927
826
  }
928
827
 
929
828
  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
- }
829
+ CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
830
+ if (template) {
831
+ CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
832
+ [mapTemplate showPanningInterfaceAnimated:animated];
833
+ } else {
834
+ NSLog(@"Failed to find template %@", template);
938
835
  }
939
836
  }
940
837
 
941
838
  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
- }
839
+ CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
840
+ if (template) {
841
+ CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
842
+ [mapTemplate dismissPanningInterfaceAnimated:animated];
843
+ } else {
844
+ NSLog(@"Failed to find template %@", template);
950
845
  }
951
846
  }
952
847
 
953
848
  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
- }
849
+ if (enable && !isNowPlayingActive) {
850
+ [CPNowPlayingTemplate.sharedTemplate addObserver:self];
851
+ } else if (!enable && isNowPlayingActive) {
852
+ [CPNowPlayingTemplate.sharedTemplate removeObserver:self];
960
853
  }
961
854
  }
962
855
 
963
856
  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
- }
857
+ CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
858
+ if (template) {
859
+ CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
860
+ [mapTemplate hideTripPreviews];
970
861
  }
971
862
  }
972
863
 
973
864
  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]];
865
+ CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
866
+ NSMutableArray *trips = [[NSMutableArray alloc] init];
867
+
868
+ for (NSString *tripId in tripIds) {
869
+ CPTrip *trip = [[RNCPStore sharedManager] findTripById:tripId];
870
+ if (trip) {
871
+ [trips addObject:trip];
988
872
  }
989
873
  }
874
+
875
+ if (template) {
876
+ CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
877
+ [mapTemplate showTripPreviews:trips textConfiguration:[self parseTripPreviewTextConfiguration:tripConfiguration]];
878
+ }
990
879
  }
991
880
 
992
881
  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
- }
882
+ CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
883
+ CPTrip *trip = [[RNCPStore sharedManager] findTripById:tripId];
884
+
885
+ if (template) {
886
+ CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
887
+ [mapTemplate showRouteChoicesPreviewForTrip:trip textConfiguration:[self parseTripPreviewTextConfiguration:tripConfiguration]];
1001
888
  }
1002
889
  }
1003
890
 
1004
891
  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
- }
892
+ CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
893
+ if (template) {
894
+ CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
895
+ [mapTemplate presentNavigationAlert:[self parseNavigationAlert:json templateId:templateId] animated:animated];
1011
896
  }
1012
897
  }
1013
898
 
1014
899
  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
- }
900
+ CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
901
+ if (template) {
902
+ CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
903
+ [mapTemplate dismissNavigationAlertAnimated:YES completion:^(BOOL completion) {
904
+ [self sendTemplateEventWithName:template name:@"didDismissNavigationAlert"];
905
+ }];
1023
906
  }
1024
907
  }
1025
908
 
1026
909
  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
- }
910
+ CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
911
+ if (template) {
912
+ CPVoiceControlTemplate *voiceTemplate = (CPVoiceControlTemplate*) template;
913
+ [voiceTemplate activateVoiceControlStateWithIdentifier:identifier];
1033
914
  }
1034
915
  }
1035
916
 
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
- }
917
+ RCT_EXPORT_METHOD(reactToUpdatedSearchText:(NSArray *)items templateId:(NSString *)templateId) {
918
+ NSArray *sectionsItems = [self parseListItems:items startIndex:0 templateId:templateId];
919
+
920
+ if (self.searchResultBlock) {
921
+ self.searchResultBlock(sectionsItems);
922
+ self.searchResultBlock = nil;
1044
923
  }
1045
924
  }
1046
925
 
@@ -1052,31 +931,30 @@ RCT_EXPORT_METHOD(reactToSelectedResult:(BOOL)status) {
1052
931
  }
1053
932
 
1054
933
  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];
934
+ CPTemplate *template = [[RNCPStore sharedManager] findTemplateById:templateId];
935
+ if (template) {
936
+ CPMapTemplate *mapTemplate = (CPMapTemplate*) template;
937
+ NSArray *mapButtons = [RCTConvert NSArray:mapButtonConfig];
938
+ NSMutableArray *result = [NSMutableArray array];
939
+ for (NSDictionary *mapButton in mapButtons) {
940
+ NSString *_id = [mapButton objectForKey:@"id"];
941
+ [result addObject:[RCTConvert CPMapButton:mapButton withHandler:^(CPMapButton * _Nonnull mapButton) {
942
+ [self sendTemplateEventWithName:mapTemplate name:@"mapButtonPressed" json:@{ @"id": _id }];
943
+ }]];
1068
944
  }
945
+ [mapTemplate setMapButtons:result];
1069
946
  }
1070
947
  }
1071
948
 
1072
949
  # pragma parsers
1073
950
 
1074
- - (void) applyConfigForMapTemplate:(CPMapTemplate*)mapTemplate templateId:(NSString*)templateId config:(NSDictionary*)config API_AVAILABLE(ios(12.0)) {
951
+ - (void) applyConfigForMapTemplate:(CPMapTemplate*)mapTemplate templateId:(NSString*)templateId config:(NSDictionary*)config {
1075
952
  RNCPStore *store = [RNCPStore sharedManager];
1076
953
 
1077
954
  if ([config objectForKey:@"guidanceBackgroundColor"]) {
1078
955
  [mapTemplate setGuidanceBackgroundColor:[RCTConvert UIColor:config[@"guidanceBackgroundColor"]]];
1079
- } else if (@available(iOS 14, *)) {
956
+ }
957
+ else {
1080
958
  [mapTemplate setGuidanceBackgroundColor:UIColor.systemGray5Color];
1081
959
  }
1082
960
 
@@ -1119,13 +997,12 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1119
997
 
1120
998
  if ([config objectForKey:@"render"]) {
1121
999
  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];
1000
+ RNCarPlayViewController *viewController = [[RNCarPlayViewController alloc] initWithRootView:rootView];
1001
+ store.window.rootViewController = viewController;
1125
1002
  }
1126
1003
  }
1127
1004
 
1128
- - (NSArray<__kindof CPTemplate*>*) parseTemplatesFrom:(NSDictionary*)config API_AVAILABLE(ios(12.0)) {
1005
+ - (NSArray<__kindof CPTemplate*>*) parseTemplatesFrom:(NSDictionary*)config {
1129
1006
  RNCPStore *store = [RNCPStore sharedManager];
1130
1007
  NSMutableArray<__kindof CPTemplate*> *templates = [NSMutableArray new];
1131
1008
  NSArray<NSDictionary*> *tpls = [RCTConvert NSDictionaryArray:config[@"templates"]];
@@ -1137,7 +1014,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1137
1014
  return templates;
1138
1015
  }
1139
1016
 
1140
- - (NSArray<CPButton*>*) parseButtons:(NSArray*)buttons templateId:(NSString *)templateId API_AVAILABLE(ios(14.0)) {
1017
+ - (NSArray<CPButton*>*) parseButtons:(NSArray*)buttons templateId:(NSString *)templateId {
1141
1018
  NSMutableArray *result = [NSMutableArray array];
1142
1019
  for (NSDictionary *button in buttons) {
1143
1020
  CPButton *_button;
@@ -1170,7 +1047,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1170
1047
  return result;
1171
1048
  }
1172
1049
 
1173
- - (NSArray<CPBarButton*>*) parseBarButtons:(NSArray*)barButtons templateId:(NSString *)templateId API_AVAILABLE(ios(12.0)) {
1050
+ - (NSArray<CPBarButton*>*) parseBarButtons:(NSArray*)barButtons templateId:(NSString *)templateId {
1174
1051
  NSMutableArray *result = [NSMutableArray array];
1175
1052
  for (NSDictionary *barButton in barButtons) {
1176
1053
  CPBarButtonType _type;
@@ -1201,7 +1078,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1201
1078
  return result;
1202
1079
  }
1203
1080
 
1204
- - (NSArray<CPListSection*>*)parseSections:(NSArray*)sections templateId:(NSString *)templateId API_AVAILABLE(ios(12.0)) {
1081
+ - (NSArray<CPListSection*>*)parseSections:(NSArray*)sections templateId:(NSString *)templateId {
1205
1082
  NSMutableArray *result = [NSMutableArray array];
1206
1083
  int index = 0;
1207
1084
  for (NSDictionary *section in sections) {
@@ -1217,165 +1094,104 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1217
1094
  return result;
1218
1095
  }
1219
1096
 
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)) {
1097
+ - (NSArray<CPSelectableListItem>*)parseListItems:(NSArray*)items startIndex:(int)startIndex templateId:(NSString *)templateId {
1234
1098
  NSMutableArray *_items = [NSMutableArray array];
1235
- int index = startIndex;
1236
- UIImage *placeholder = [UIImage imageNamed: @"Placeholder"];
1099
+ int listIndex = startIndex;
1237
1100
  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"]];
1101
+ BOOL _showsDisclosureIndicator = [[item objectForKey:@"showsDisclosureIndicator"] isEqualToNumber:[NSNumber numberWithInt:1]];
1102
+ NSString *_detailText = [item objectForKey:@"detailText"];
1103
+ NSString *_text = [item objectForKey:@"text"];
1104
+ NSObject *_imageObj = [item objectForKey:@"image"];
1244
1105
 
1245
- if(item[@"rowItems"] && templateId) {
1106
+ NSArray *_imageItems = [item objectForKey:@"images"];
1107
+ NSArray *_imageUrls = [item objectForKey:@"imgUrls"];
1108
+
1109
+ if (_imageItems == nil && _imageUrls == nil) {
1110
+ UIImage *_image = [RCTConvert UIImage:_imageObj];
1111
+ CPListItem *_item;
1246
1112
  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
- }
1113
+ CPListItemAccessoryType accessoryType = _showsDisclosureIndicator ? CPListItemAccessoryTypeDisclosureIndicator : CPListItemAccessoryTypeNone;
1114
+ _item = [[CPListItem alloc] initWithText:_text detailText:_detailText image:_image accessoryImage:nil accessoryType:accessoryType];
1115
+ } else {
1116
+ _item = [[CPListItem alloc] initWithText:_text detailText:_detailText image:_image showsDisclosureIndicator:_showsDisclosureIndicator];
1117
+ }
1118
+ if ([item objectForKey:@"isPlaying"]) {
1119
+ [_item setPlaying:[RCTConvert BOOL:[item objectForKey:@"isPlaying"]]];
1120
+ }
1121
+ if (item[@"imgUrl"]) {
1122
+ NSString *imgUrlString = [RCTConvert NSString:item[@"imgUrl"]];
1123
+ UIImage *placeholderImage
1124
+ if ([item objectForKey:@"placeholderImage"] != nil) {
1125
+ placeholderImage = [RCTConvert UIImage:[item objectForKey:@"placeholderImage"]];
1274
1126
  }
1275
-
1276
- while ([loadedRowItemsImages count] < 9) {
1277
- if (placeholder) [loadedRowItemsImages addObject:placeholder];
1127
+ [self updateItemImageWithURL:_item imgUrl:imgUrlString placeholderImage:placeholderImage];
1128
+ }
1129
+ [_item setUserInfo:@{ @"index": @(listIndex) }];
1130
+ [_items addObject:_item];
1131
+ } else {
1132
+ // parse images
1133
+ NSMutableArray * _images = [NSMutableArray array];
1134
+
1135
+ if (_imageItems != nil) {
1136
+ NSArray* slicedArray = [_imageItems subarrayWithRange:NSMakeRange(0, MIN(CPMaximumNumberOfGridImages, _imageItems.count))];
1137
+
1138
+ for (NSObject *imageObj in slicedArray){
1139
+ UIImage *_image = [RCTConvert UIImage:imageObj];
1140
+ [_images addObject:_image];
1278
1141
  }
1142
+ }
1143
+ if (@available(iOS 14.0, *)) {
1279
1144
 
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;
1145
+ CPListImageRowItem *_item;
1146
+ if (_images.count > 0)
1147
+ {
1148
+ _item = [[CPListImageRowItem alloc] initWithText:_text images:_images];
1149
+ }
1150
+ else
1151
+ {
1152
+ // Show only as much images as allowed.
1153
+ NSArray* _slicedArray = [_imageUrls subarrayWithRange:NSMakeRange(0, MIN(CPMaximumNumberOfGridImages, _imageUrls.count))];//
1288
1154
 
1289
- if (templateId) {
1290
- bodyDictionary[@"templateId"] = templateId;
1155
+ // create array with empty UI images, that will be replaced later
1156
+ NSMutableArray *_imagesArray = [NSMutableArray arrayWithCapacity:_slicedArray.count];
1157
+ for (NSUInteger i = 0; i < _slicedArray.count; i++) {
1158
+ [_imagesArray addObject:[[UIImage alloc] init]];
1291
1159
  }
1160
+ _item = [[CPListImageRowItem alloc] initWithText:_text images:_imagesArray];
1292
1161
 
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;
1162
+ NSArray *_placeholderImages = [item objectForKey:@"placeholderImages"];
1163
+ int _index = 0;
1164
+ for (NSString* imgUrl in _slicedArray) {
1165
+ UIImage *placeholderImage;
1166
+ if (_placeholderImages != nil) {
1167
+ placeholderImage = [RCTConvert UIImage:_placeholderImages[_index]];
1317
1168
  }
1169
+ [self updateListRowItemImageWithURL:_item imgUrl:imgUrl index:_index placeholderImage:placeholderImage];
1170
+ _index++;
1318
1171
  }
1319
1172
  }
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;
1173
+
1174
+ [_item setListImageRowHandler:^(CPListImageRowItem * _Nonnull item, NSInteger index, dispatch_block_t _Nonnull completionBlock) {
1175
+ // Find the current template
1176
+ RNCPStore *store = [RNCPStore sharedManager];
1177
+ CPTemplate *template = [store findTemplateById:templateId];
1178
+ if (template) {
1179
+ [self sendTemplateEventWithName:template name:@"didSelectListItemRowImage" json:@{ @"index": @(listIndex), @"imageIndex": @(index)}];
1335
1180
  }
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
- }
1181
+ }];
1182
+
1183
+ [_item setUserInfo:@{ @"index": @(listIndex) }];
1184
+ [_items addObject:_item];
1357
1185
  }
1186
+
1358
1187
  }
1359
- [_item setUserInfo:@{ @"index": @(index) }];
1360
- [_items addObject:_item];
1361
- index = index + 1;
1188
+ listIndex = listIndex + 1;
1362
1189
  }
1363
1190
  return _items;
1364
1191
  }
1365
1192
 
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
1193
 
1378
- - (NSArray<CPInformationItem*>*)parseInformationItems:(NSArray*)items API_AVAILABLE(ios(14.0)){
1194
+ - (NSArray<CPInformationItem*>*)parseInformationItems:(NSArray*)items {
1379
1195
  NSMutableArray *_items = [NSMutableArray array];
1380
1196
  for (NSDictionary *item in items) {
1381
1197
  [_items addObject:[[CPInformationItem alloc] initWithTitle:item[@"title"] detail:item[@"detail"]]];
@@ -1384,7 +1200,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1384
1200
  return _items;
1385
1201
  }
1386
1202
 
1387
- - (NSArray<CPTextButton*>*)parseInformationActions:(NSArray*)actions templateId:(NSString *)templateId API_AVAILABLE(ios(14.0)){
1203
+ - (NSArray<CPTextButton*>*)parseInformationActions:(NSArray*)actions templateId:(NSString *)templateId {
1388
1204
  NSMutableArray *_actions = [NSMutableArray array];
1389
1205
  for (NSDictionary *action in actions) {
1390
1206
  CPTextButton *_action = [[CPTextButton alloc] initWithTitle:action[@"title"] textStyle:CPTextButtonStyleNormal handler:^(__kindof CPTextButton * _Nonnull contactButton) {
@@ -1398,7 +1214,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1398
1214
  return _actions;
1399
1215
  }
1400
1216
 
1401
- - (NSArray<CPGridButton*>*)parseGridButtons:(NSArray*)buttons templateId:(NSString*)templateId API_AVAILABLE(ios(12.0)) {
1217
+ - (NSArray<CPGridButton*>*)parseGridButtons:(NSArray*)buttons templateId:(NSString*)templateId {
1402
1218
  NSMutableArray *result = [NSMutableArray array];
1403
1219
  int index = 0;
1404
1220
  for (NSDictionary *button in buttons) {
@@ -1418,7 +1234,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1418
1234
  return result;
1419
1235
  }
1420
1236
 
1421
- - (CPTravelEstimates*)parseTravelEstimates: (NSDictionary*)json API_AVAILABLE(ios(12.0)) {
1237
+ - (CPTravelEstimates*)parseTravelEstimates: (NSDictionary*)json {
1422
1238
  NSString *units = [RCTConvert NSString:json[@"distanceUnits"]];
1423
1239
  double value = [RCTConvert double:json[@"distanceRemaining"]];
1424
1240
 
@@ -1442,7 +1258,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1442
1258
  return [[CPTravelEstimates alloc] initWithDistanceRemaining:distance timeRemaining:time];
1443
1259
  }
1444
1260
 
1445
- - (CPManeuver*)parseManeuver:(NSDictionary*)json API_AVAILABLE(ios(12.0)) {
1261
+ - (CPManeuver*)parseManeuver:(NSDictionary*)json {
1446
1262
  CPManeuver* maneuver = [[CPManeuver alloc] init];
1447
1263
 
1448
1264
  if ([json objectForKey:@"junctionImage"]) {
@@ -1457,15 +1273,12 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1457
1273
 
1458
1274
  if ([json objectForKey:@"symbolImage"]) {
1459
1275
  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
- }
1276
+
1277
+ if ([json objectForKey:@"symbolImageSize"]) {
1278
+ NSDictionary *size = [RCTConvert NSDictionary:json[@"symbolImageSize"]];
1279
+ double width = [RCTConvert double:size[@"width"]];
1280
+ double height = [RCTConvert double:size[@"height"]];
1281
+ symbolImage = [self imageWithSize:symbolImage convertToSize:CGSizeMake(width, height)];
1469
1282
  }
1470
1283
 
1471
1284
  BOOL shouldTint = [RCTConvert BOOL:json[@"tintSymbolImage"]];
@@ -1487,11 +1300,11 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1487
1300
  return maneuver;
1488
1301
  }
1489
1302
 
1490
- - (CPTripPreviewTextConfiguration*)parseTripPreviewTextConfiguration:(NSDictionary*)json API_AVAILABLE(ios(12.0)) {
1303
+ - (CPTripPreviewTextConfiguration*)parseTripPreviewTextConfiguration:(NSDictionary*)json {
1491
1304
  return [[CPTripPreviewTextConfiguration alloc] initWithStartButtonTitle:[RCTConvert NSString:json[@"startButtonTitle"]] additionalRoutesButtonTitle:[RCTConvert NSString:json[@"additionalRoutesButtonTitle"]] overviewButtonTitle:[RCTConvert NSString:json[@"overviewButtonTitle"]]];
1492
1305
  }
1493
1306
 
1494
- - (CPTrip*)parseTrip:(NSDictionary*)config API_AVAILABLE(ios(12.0)) {
1307
+ - (CPTrip*)parseTrip:(NSDictionary*)config {
1495
1308
  if ([config objectForKey:@"config"]) {
1496
1309
  config = [config objectForKey:@"config"];
1497
1310
  }
@@ -1515,7 +1328,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1515
1328
  return [[CPTrip alloc] initWithOrigin:origin destination:destination routeChoices:routeChoices];
1516
1329
  }
1517
1330
 
1518
- - (CPNavigationAlert*)parseNavigationAlert:(NSDictionary*)json templateId:(NSString*)templateId API_AVAILABLE(ios(12.0)) {
1331
+ - (CPNavigationAlert*)parseNavigationAlert:(NSDictionary*)json templateId:(NSString*)templateId {
1519
1332
  CPImageSet *imageSet;
1520
1333
  if ([json objectForKey:@"lightImage"] && [json objectForKey:@"darkImage"]) {
1521
1334
  imageSet = [[CPImageSet alloc] initWithLightContentImage:[RCTConvert UIImage:json[@"lightImage"]] darkContentImage:[RCTConvert UIImage:json[@"darkImage"]]];
@@ -1525,7 +1338,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1525
1338
  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
1339
  }
1527
1340
 
1528
- - (CPAlertAction*)parseAlertAction:(NSDictionary*)json body:(NSDictionary*)body API_AVAILABLE(ios(12.0)) {
1341
+ - (CPAlertAction*)parseAlertAction:(NSDictionary*)json body:(NSDictionary*)body {
1529
1342
  return [[CPAlertAction alloc] initWithTitle:[RCTConvert NSString:json[@"title"]] style:(CPAlertActionStyle) [RCTConvert NSUInteger:json[@"style"]] handler:^(CPAlertAction * _Nonnull action) {
1530
1343
  if (self->hasListeners) {
1531
1344
  [self sendEventWithName:@"alertActionPressed" body:body];
@@ -1533,7 +1346,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1533
1346
  }];
1534
1347
  }
1535
1348
 
1536
- - (NSArray<CPVoiceControlState*>*)parseVoiceControlStates:(NSArray<NSDictionary*>*)items API_AVAILABLE(ios(12.0)) {
1349
+ - (NSArray<CPVoiceControlState*>*)parseVoiceControlStates:(NSArray<NSDictionary*>*)items {
1537
1350
  NSMutableArray<CPVoiceControlState*>* res = [NSMutableArray array];
1538
1351
  for (NSDictionary *item in items) {
1539
1352
  [res addObject:[self parseVoiceControlState:item]];
@@ -1541,11 +1354,11 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1541
1354
  return res;
1542
1355
  }
1543
1356
 
1544
- - (CPVoiceControlState*)parseVoiceControlState:(NSDictionary*)json API_AVAILABLE(ios(12.0)) {
1357
+ - (CPVoiceControlState*)parseVoiceControlState:(NSDictionary*)json {
1545
1358
  return [[CPVoiceControlState alloc] initWithIdentifier:[RCTConvert NSString:json[@"identifier"]] titleVariants:[RCTConvert NSStringArray:json[@"titleVariants"]] image:[RCTConvert UIImage:json[@"image"]] repeats:[RCTConvert BOOL:json[@"repeats"]]];
1546
1359
  }
1547
1360
 
1548
- - (NSString*)panDirectionToString:(CPPanDirection)panDirection API_AVAILABLE(ios(12.0)) {
1361
+ - (NSString*)panDirectionToString:(CPPanDirection)panDirection {
1549
1362
  switch (panDirection) {
1550
1363
  case CPPanDirectionUp: return @"up";
1551
1364
  case CPPanDirectionRight: return @"right";
@@ -1555,7 +1368,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1555
1368
  }
1556
1369
  }
1557
1370
 
1558
- - (NSDictionary*)navigationAlertToJson:(CPNavigationAlert*)navigationAlert dismissalContext:(CPNavigationAlertDismissalContext)dismissalContext API_AVAILABLE(ios(12.0)) {
1371
+ - (NSDictionary*)navigationAlertToJson:(CPNavigationAlert*)navigationAlert dismissalContext:(CPNavigationAlertDismissalContext)dismissalContext {
1559
1372
  NSString *dismissalCtx = @"none";
1560
1373
  if (dismissalContext) {
1561
1374
  switch (dismissalContext) {
@@ -1576,18 +1389,18 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1576
1389
  @"reason": dismissalCtx
1577
1390
  };
1578
1391
  }
1579
- - (NSDictionary*)navigationAlertToJson:(CPNavigationAlert*)navigationAlert API_AVAILABLE(ios(12.0)) {
1392
+ - (NSDictionary*)navigationAlertToJson:(CPNavigationAlert*)navigationAlert {
1580
1393
  return @{ @"todo": @(YES) };
1581
1394
  // NSMutableDictionary *res = [[NSMutableDictionary alloc] init];
1582
1395
  // return @{
1583
1396
  // };
1584
1397
  }
1585
1398
 
1586
- - (void)sendTemplateEventWithName:(CPTemplate *)template name:(NSString*)name API_AVAILABLE(ios(12.0)) {
1399
+ - (void)sendTemplateEventWithName:(CPTemplate *)template name:(NSString*)name {
1587
1400
  [self sendTemplateEventWithName:template name:name json:@{}];
1588
1401
  }
1589
1402
 
1590
- - (void)sendTemplateEventWithName:(CPTemplate *)template name:(NSString*)name json:(NSDictionary*)json API_AVAILABLE(ios(12.0)) {
1403
+ - (void)sendTemplateEventWithName:(CPTemplate *)template name:(NSString*)name json:(NSDictionary*)json {
1591
1404
  NSMutableDictionary *body = [[NSMutableDictionary alloc] initWithDictionary:json];
1592
1405
  NSDictionary *userInfo = [template userInfo];
1593
1406
  [body setObject:[userInfo objectForKey:@"templateId"] forKey:@"templateId"];
@@ -1599,7 +1412,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1599
1412
 
1600
1413
  # pragma MapTemplate
1601
1414
 
1602
- - (void)mapTemplate:(CPMapTemplate *)mapTemplate selectedPreviewForTrip:(CPTrip *)trip usingRouteChoice:(CPRouteChoice *)routeChoice API_AVAILABLE(ios(12.0)) {
1415
+ - (void)mapTemplate:(CPMapTemplate *)mapTemplate selectedPreviewForTrip:(CPTrip *)trip usingRouteChoice:(CPRouteChoice *)routeChoice {
1603
1416
  NSDictionary *userInfo = trip.userInfo;
1604
1417
  NSString *tripId = [userInfo valueForKey:@"id"];
1605
1418
 
@@ -1608,7 +1421,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1608
1421
  [self sendTemplateEventWithName:mapTemplate name:@"selectedPreviewForTrip" json:@{ @"tripId": tripId, @"routeIndex": routeIndex}];
1609
1422
  }
1610
1423
 
1611
- - (void)mapTemplate:(CPMapTemplate *)mapTemplate startedTrip:(CPTrip *)trip usingRouteChoice:(CPRouteChoice *)routeChoice API_AVAILABLE(ios(12.0)) {
1424
+ - (void)mapTemplate:(CPMapTemplate *)mapTemplate startedTrip:(CPTrip *)trip usingRouteChoice:(CPRouteChoice *)routeChoice {
1612
1425
  NSDictionary *userInfo = trip.userInfo;
1613
1426
  NSString *tripId = [userInfo valueForKey:@"id"];
1614
1427
 
@@ -1618,7 +1431,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1618
1431
  [self sendTemplateEventWithName:mapTemplate name:@"startedTrip" json:@{ @"tripId": tripId, @"routeIndex": routeIndex}];
1619
1432
  }
1620
1433
 
1621
- - (void)mapTemplateDidCancelNavigation:(CPMapTemplate *)mapTemplate API_AVAILABLE(ios(12.0)) {
1434
+ - (void)mapTemplateDidCancelNavigation:(CPMapTemplate *)mapTemplate {
1622
1435
  [self sendTemplateEventWithName:mapTemplate name:@"didCancelNavigation"];
1623
1436
  }
1624
1437
 
@@ -1632,44 +1445,44 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1632
1445
  // // @todo
1633
1446
  //}
1634
1447
 
1635
- - (void)mapTemplate:(CPMapTemplate *)mapTemplate willShowNavigationAlert:(CPNavigationAlert *)navigationAlert API_AVAILABLE(ios(12.0)) {
1448
+ - (void)mapTemplate:(CPMapTemplate *)mapTemplate willShowNavigationAlert:(CPNavigationAlert *)navigationAlert {
1636
1449
  [self sendTemplateEventWithName:mapTemplate name:@"willShowNavigationAlert" json:[self navigationAlertToJson:navigationAlert]];
1637
1450
  }
1638
- - (void)mapTemplate:(CPMapTemplate *)mapTemplate didShowNavigationAlert:(CPNavigationAlert *)navigationAlert API_AVAILABLE(ios(12.0)) {
1451
+ - (void)mapTemplate:(CPMapTemplate *)mapTemplate didShowNavigationAlert:(CPNavigationAlert *)navigationAlert {
1639
1452
  [self sendTemplateEventWithName:mapTemplate name:@"didShowNavigationAlert" json:[self navigationAlertToJson:navigationAlert]];
1640
1453
  }
1641
- - (void)mapTemplate:(CPMapTemplate *)mapTemplate willDismissNavigationAlert:(CPNavigationAlert *)navigationAlert dismissalContext:(CPNavigationAlertDismissalContext)dismissalContext API_AVAILABLE(ios(12.0)) {
1454
+ - (void)mapTemplate:(CPMapTemplate *)mapTemplate willDismissNavigationAlert:(CPNavigationAlert *)navigationAlert dismissalContext:(CPNavigationAlertDismissalContext)dismissalContext {
1642
1455
  [self sendTemplateEventWithName:mapTemplate name:@"willDismissNavigationAlert" json:[self navigationAlertToJson:navigationAlert dismissalContext:dismissalContext]];
1643
1456
  }
1644
- - (void)mapTemplate:(CPMapTemplate *)mapTemplate didDismissNavigationAlert:(CPNavigationAlert *)navigationAlert dismissalContext:(CPNavigationAlertDismissalContext)dismissalContext API_AVAILABLE(ios(12.0)) {
1457
+ - (void)mapTemplate:(CPMapTemplate *)mapTemplate didDismissNavigationAlert:(CPNavigationAlert *)navigationAlert dismissalContext:(CPNavigationAlertDismissalContext)dismissalContext {
1645
1458
  [self sendTemplateEventWithName:mapTemplate name:@"didDismissNavigationAlert" json:[self navigationAlertToJson:navigationAlert dismissalContext:dismissalContext]];
1646
1459
  }
1647
1460
 
1648
- - (void)mapTemplateDidShowPanningInterface:(CPMapTemplate *)mapTemplate API_AVAILABLE(ios(12.0)) {
1461
+ - (void)mapTemplateDidShowPanningInterface:(CPMapTemplate *)mapTemplate {
1649
1462
  [self sendTemplateEventWithName:mapTemplate name:@"didShowPanningInterface"];
1650
1463
  }
1651
- - (void)mapTemplateWillDismissPanningInterface:(CPMapTemplate *)mapTemplate API_AVAILABLE(ios(12.0)) {
1464
+ - (void)mapTemplateWillDismissPanningInterface:(CPMapTemplate *)mapTemplate {
1652
1465
  [self sendTemplateEventWithName:mapTemplate name:@"willDismissPanningInterface"];
1653
1466
  }
1654
- - (void)mapTemplateDidDismissPanningInterface:(CPMapTemplate *)mapTemplate API_AVAILABLE(ios(12.0)) {
1467
+ - (void)mapTemplateDidDismissPanningInterface:(CPMapTemplate *)mapTemplate {
1655
1468
  [self sendTemplateEventWithName:mapTemplate name:@"didDismissPanningInterface"];
1656
1469
  }
1657
- - (void)mapTemplateDidBeginPanGesture:(CPMapTemplate *)mapTemplate API_AVAILABLE(ios(12.0)) {
1470
+ - (void)mapTemplateDidBeginPanGesture:(CPMapTemplate *)mapTemplate {
1658
1471
  [self sendTemplateEventWithName:mapTemplate name:@"didBeginPanGesture"];
1659
1472
  }
1660
- - (void)mapTemplate:(CPMapTemplate *)mapTemplate panWithDirection:(CPPanDirection)direction API_AVAILABLE(ios(12.0)) {
1473
+ - (void)mapTemplate:(CPMapTemplate *)mapTemplate panWithDirection:(CPPanDirection)direction {
1661
1474
  [self sendTemplateEventWithName:mapTemplate name:@"panWithDirection" json:@{ @"direction": [self panDirectionToString:direction] }];
1662
1475
  }
1663
- - (void)mapTemplate:(CPMapTemplate *)mapTemplate panBeganWithDirection:(CPPanDirection)direction API_AVAILABLE(ios(12.0)) {
1476
+ - (void)mapTemplate:(CPMapTemplate *)mapTemplate panBeganWithDirection:(CPPanDirection)direction {
1664
1477
  [self sendTemplateEventWithName:mapTemplate name:@"panBeganWithDirection" json:@{ @"direction": [self panDirectionToString:direction] }];
1665
1478
  }
1666
- - (void)mapTemplate:(CPMapTemplate *)mapTemplate panEndedWithDirection:(CPPanDirection)direction API_AVAILABLE(ios(12.0)) {
1479
+ - (void)mapTemplate:(CPMapTemplate *)mapTemplate panEndedWithDirection:(CPPanDirection)direction {
1667
1480
  [self sendTemplateEventWithName:mapTemplate name:@"panEndedWithDirection" json:@{ @"direction": [self panDirectionToString:direction] }];
1668
1481
  }
1669
- - (void)mapTemplate:(CPMapTemplate *)mapTemplate didEndPanGestureWithVelocity:(CGPoint)velocity API_AVAILABLE(ios(12.0)) {
1482
+ - (void)mapTemplate:(CPMapTemplate *)mapTemplate didEndPanGestureWithVelocity:(CGPoint)velocity {
1670
1483
  [self sendTemplateEventWithName:mapTemplate name:@"didEndPanGestureWithVelocity" json:@{ @"velocity": @{ @"x": @(velocity.x), @"y": @(velocity.y) }}];
1671
1484
  }
1672
- - (void)mapTemplate:(CPMapTemplate *)mapTemplate didUpdatePanGestureWithTranslation:(CGPoint)translation velocity:(CGPoint)velocity API_AVAILABLE(ios(12.0)) {
1485
+ - (void)mapTemplate:(CPMapTemplate *)mapTemplate didUpdatePanGestureWithTranslation:(CGPoint)translation velocity:(CGPoint)velocity {
1673
1486
  [self sendTemplateEventWithName:mapTemplate name:@"didUpdatePanGestureWithTranslation" json:@{ @"translation": @{ @"x": @(translation.x), @"y": @(translation.y) }, @"velocity": @{ @"x": @(velocity.x), @"y": @(velocity.y) }}];
1674
1487
  }
1675
1488
 
@@ -1677,79 +1490,70 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1677
1490
 
1678
1491
  # pragma SearchTemplate
1679
1492
 
1680
- - (void)searchTemplate:(CPSearchTemplate *)searchTemplate selectedResult:(CPListItem *)item completionHandler:(void (^)(void))completionHandler API_AVAILABLE(ios(12.0)) {
1493
+ - (void)searchTemplate:(CPSearchTemplate *)searchTemplate selectedResult:(CPListItem *)item completionHandler:(void (^)(void))completionHandler {
1681
1494
  NSNumber* index = [item.userInfo objectForKey:@"index"];
1682
1495
  [self sendTemplateEventWithName:searchTemplate name:@"selectedResult" json:@{ @"index": index }];
1683
1496
  self.selectedResultBlock = completionHandler;
1684
1497
  }
1685
1498
 
1686
- - (void)searchTemplateSearchButtonPressed:(CPSearchTemplate *)searchTemplate API_AVAILABLE(ios(12.0)) {
1499
+ - (void)searchTemplateSearchButtonPressed:(CPSearchTemplate *)searchTemplate {
1687
1500
  [self sendTemplateEventWithName:searchTemplate name:@"searchButtonPressed"];
1688
1501
  }
1689
1502
 
1690
- - (void)searchTemplate:(CPSearchTemplate *)searchTemplate updatedSearchText:(NSString *)searchText completionHandler:(void (^)(NSArray<CPListItem *> * _Nonnull))completionHandler API_AVAILABLE(ios(12.0)) {
1503
+ - (void)searchTemplate:(CPSearchTemplate *)searchTemplate updatedSearchText:(NSString *)searchText completionHandler:(void (^)(NSArray<CPListItem *> * _Nonnull))completionHandler {
1691
1504
  [self sendTemplateEventWithName:searchTemplate name:@"updatedSearchText" json:@{ @"searchText": searchText }];
1692
1505
  self.searchResultBlock = completionHandler;
1693
1506
  }
1694
1507
 
1695
1508
  # pragma ListTemplate
1696
1509
 
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
- }
1510
+ - (void)listTemplate:(CPListTemplate *)listTemplate didSelectListItem:(CPListItem *)item completionHandler:(void (^)(void))completionHandler {
1511
+ NSNumber* index = [item.userInfo objectForKey:@"index"];
1512
+ [self sendTemplateEventWithName:listTemplate name:@"didSelectListItem" json:@{ @"index": index }];
1513
+ self.selectedResultBlock = completionHandler;
1703
1514
  }
1704
1515
 
1705
1516
  # 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
- }
1517
+ - (void)tabBarTemplate:(CPTabBarTemplate *)tabBarTemplate didSelectTemplate:(__kindof CPTemplate *)selectedTemplate {
1518
+ NSString* selectedTemplateId = [[selectedTemplate userInfo] objectForKey:@"templateId"];
1519
+ [self sendTemplateEventWithName:tabBarTemplate name:@"didSelectTemplate" json:@{@"selectedTemplateId":selectedTemplateId}];
1712
1520
  }
1713
1521
 
1714
1522
  # pragma PointOfInterest
1715
- -(void)pointOfInterestTemplate:(CPPointOfInterestTemplate *)pointOfInterestTemplate didChangeMapRegion:(MKCoordinateRegion)region API_AVAILABLE(ios(14.0)){
1523
+ -(void)pointOfInterestTemplate:(CPPointOfInterestTemplate *)pointOfInterestTemplate didChangeMapRegion:(MKCoordinateRegion)region {
1716
1524
  // noop
1717
1525
  }
1718
1526
 
1719
- -(void)pointOfInterestTemplate:(CPPointOfInterestTemplate *)pointOfInterestTemplate didSelectPointOfInterest:(CPPointOfInterest *)pointOfInterest API_AVAILABLE(ios(14.0)){
1527
+ -(void)pointOfInterestTemplate:(CPPointOfInterestTemplate *)pointOfInterestTemplate didSelectPointOfInterest:(CPPointOfInterest *)pointOfInterest {
1720
1528
  [self sendTemplateEventWithName:pointOfInterestTemplate name:@"didSelectPointOfInterest" json:[pointOfInterest userInfo]];
1721
1529
  }
1722
1530
 
1723
1531
  # pragma InterfaceController
1724
1532
 
1725
- - (void)templateDidAppear:(CPTemplate *)aTemplate animated:(BOOL)animated API_AVAILABLE(ios(12.0)) {
1533
+ - (void)templateDidAppear:(CPTemplate *)aTemplate animated:(BOOL)animated {
1726
1534
  [self sendTemplateEventWithName:aTemplate name:@"didAppear" json:@{ @"animated": @(animated) }];
1727
1535
  }
1728
1536
 
1729
- - (void)templateDidDisappear:(CPTemplate *)aTemplate animated:(BOOL)animated API_AVAILABLE(ios(12.0)) {
1537
+ - (void)templateDidDisappear:(CPTemplate *)aTemplate animated:(BOOL)animated {
1730
1538
  [self sendTemplateEventWithName:aTemplate name:@"didDisappear" json:@{ @"animated": @(animated) }];
1731
1539
  }
1732
1540
 
1733
- - (void)templateWillAppear:(CPTemplate *)aTemplate animated:(BOOL)animated API_AVAILABLE(ios(12.0)) {
1541
+ - (void)templateWillAppear:(CPTemplate *)aTemplate animated:(BOOL)animated {
1734
1542
  [self sendTemplateEventWithName:aTemplate name:@"willAppear" json:@{ @"animated": @(animated) }];
1735
1543
  }
1736
1544
 
1737
- - (void)templateWillDisappear:(CPTemplate *)aTemplate animated:(BOOL)animated API_AVAILABLE(ios(12.0)) {
1545
+ - (void)templateWillDisappear:(CPTemplate *)aTemplate animated:(BOOL)animated {
1738
1546
  [self sendTemplateEventWithName:aTemplate name:@"willDisappear" json:@{ @"animated": @(animated) }];
1739
1547
  }
1740
1548
 
1741
1549
  # pragma NowPlaying
1742
1550
 
1743
- - (void)nowPlayingTemplateUpNextButtonTapped:(CPNowPlayingTemplate *)nowPlayingTemplate API_AVAILABLE(ios(14.0)){
1744
- if (nowPlayingTemplate) {
1745
- [self sendTemplateEventWithName:nowPlayingTemplate name:@"upNextButtonPressed"];
1746
- }
1551
+ - (void)nowPlayingTemplateUpNextButtonTapped:(CPNowPlayingTemplate *)nowPlayingTemplate {
1552
+ [self sendTemplateEventWithName:nowPlayingTemplate name:@"upNextButtonPressed"];
1747
1553
  }
1748
1554
 
1749
- - (void)nowPlayingTemplateAlbumArtistButtonTapped:(CPNowPlayingTemplate *)nowPlayingTemplate API_AVAILABLE(ios(14.0)){
1750
- if (nowPlayingTemplate) {
1751
- [self sendTemplateEventWithName:nowPlayingTemplate name:@"albumArtistButtonPressed"];
1752
- }
1555
+ - (void)nowPlayingTemplateAlbumArtistButtonTapped:(CPNowPlayingTemplate *)nowPlayingTemplate {
1556
+ [self sendTemplateEventWithName:nowPlayingTemplate name:@"albumArtistButtonPressed"];
1753
1557
  }
1754
1558
 
1755
1559
  @end