@javascriptcommon/react-native-carplay 2.4.4 → 2.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ios/RNCarPlay.m CHANGED
@@ -84,6 +84,7 @@ RCT_EXPORT_MODULE();
84
84
  // list
85
85
  @"didSelectListItem",
86
86
  @"didSelectListItemRowImage",
87
+ @"scrollToBottom",
87
88
  // search
88
89
  @"updatedSearchText",
89
90
  @"searchButtonPressed",
@@ -167,9 +168,11 @@ RCT_EXPORT_MODULE();
167
168
  }
168
169
 
169
170
  - (void)updateItemImageWithURL:(CPListItem *)item imgUrl:(NSString *)imgUrlString placeholderImage:(UIImage *)placeholderImage {
170
- dispatch_async(dispatch_get_main_queue(), ^{
171
- [item setImage:placeholderImage];
172
- });
171
+ if (placeholderImage != nil) {
172
+ dispatch_async(dispatch_get_main_queue(), ^{
173
+ [item setImage:placeholderImage];
174
+ });
175
+ }
173
176
 
174
177
  NSURL *imgUrl = [NSURL URLWithString:imgUrlString];
175
178
 
@@ -186,20 +189,22 @@ RCT_EXPORT_MODULE();
186
189
  [task resume];
187
190
  }
188
191
 
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
- });
192
+ - (void)updateListRowItemImageWithURL:(CPListImageRowItem *)item imgUrl:(NSString *)imgUrlString index:(int)index placeholderImage:(UIImage *)placeholderImage {
193
+ if (placeholderImage != nil) {
194
+ dispatch_async(dispatch_get_main_queue(), ^{
195
+ NSMutableArray* newImages = [item.gridImages mutableCopy];
196
+
197
+ @try {
198
+ newImages[index] = placeholderImage;
199
+ }
200
+ @catch (NSException *exception) {
201
+ // Best effort updating the array
202
+ NSLog(@"Failed to update images array of CPListImageRowItem");
203
+ }
204
+
205
+ [item updateImages:newImages];
206
+ });
207
+ }
203
208
 
204
209
  NSURL *imgUrl = [NSURL URLWithString:imgUrlString];
205
210
 
@@ -453,7 +458,14 @@ RCT_EXPORT_METHOD(createTemplate:(NSString *)templateId config:(NSDictionary*)co
453
458
  carPlayTemplate.tabTitle = [RCTConvert NSString:config[@"tabTitle"]];
454
459
  }
455
460
 
456
- [carPlayTemplate setUserInfo:@{ @"templateId": templateId }];
461
+ // Set userInfo with templateId and optional scrollBottomThreshold for list templates
462
+ NSMutableDictionary *userInfo = [@{ @"templateId": templateId } mutableCopy];
463
+ if ([type isEqualToString:@"list"] && config[@"scrollBottomThreshold"]) {
464
+ userInfo[@"scrollBottomThreshold"] = [RCTConvert NSNumber:config[@"scrollBottomThreshold"]];
465
+ } else if ([type isEqualToString:@"list"]) {
466
+ userInfo[@"scrollBottomThreshold"] = @(5); // default threshold
467
+ }
468
+ [carPlayTemplate setUserInfo:userInfo];
457
469
  [store setTemplate:templateId template:carPlayTemplate];
458
470
  }
459
471
 
@@ -690,7 +702,11 @@ RCT_EXPORT_METHOD(updateListTemplateItem:(NSString *)templateId config:(NSDictio
690
702
  CPListItem *item = (CPListItem *)section.items[index];
691
703
  if (config[@"imgUrl"]) {
692
704
  NSString *imgUrlString = [RCTConvert NSString:config[@"imgUrl"]];
693
- [self updateItemImageWithURL:item imgUrl:imgUrlString];
705
+ UIImage *placeholderImage;
706
+ if (config[@"placeholderImage"] != nil) {
707
+ placeholderImage = [RCTConvert UIImage:config[@"placeholderImage"]];
708
+ }
709
+ [self updateItemImageWithURL:item imgUrl:imgUrlString placeholderImage:placeholderImage];
694
710
  }
695
711
  if (config[@"image"]) {
696
712
  [item setImage:[RCTConvert UIImage:config[@"image"]]];
@@ -1120,7 +1136,7 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1120
1136
  }
1121
1137
  if (item[@"imgUrl"]) {
1122
1138
  NSString *imgUrlString = [RCTConvert NSString:item[@"imgUrl"]];
1123
- UIImage *placeholderImage
1139
+ UIImage *placeholderImage;
1124
1140
  if ([item objectForKey:@"placeholderImage"] != nil) {
1125
1141
  placeholderImage = [RCTConvert UIImage:[item objectForKey:@"placeholderImage"]];
1126
1142
  }
@@ -1162,9 +1178,12 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1162
1178
  NSArray *_placeholderImages = [item objectForKey:@"placeholderImages"];
1163
1179
  int _index = 0;
1164
1180
  for (NSString* imgUrl in _slicedArray) {
1165
- UIImage *placeholderImage;
1166
- if (_placeholderImages != nil) {
1167
- placeholderImage = [RCTConvert UIImage:_placeholderImages[_index]];
1181
+ UIImage *placeholderImage = nil;
1182
+ if (_placeholderImages != nil && _index < _placeholderImages.count) {
1183
+ id placeholderImageObj = _placeholderImages[_index];
1184
+ if (placeholderImageObj != nil && placeholderImageObj != [NSNull null]) {
1185
+ placeholderImage = [RCTConvert UIImage:placeholderImageObj];
1186
+ }
1168
1187
  }
1169
1188
  [self updateListRowItemImageWithURL:_item imgUrl:imgUrl index:_index placeholderImage:placeholderImage];
1170
1189
  _index++;
@@ -1511,6 +1530,35 @@ RCT_EXPORT_METHOD(updateMapTemplateMapButtons:(NSString*) templateId mapButtons:
1511
1530
  NSNumber* index = [item.userInfo objectForKey:@"index"];
1512
1531
  [self sendTemplateEventWithName:listTemplate name:@"didSelectListItem" json:@{ @"index": index }];
1513
1532
  self.selectedResultBlock = completionHandler;
1533
+
1534
+ // Check if we should trigger scroll to bottom callback for infinite scroll
1535
+ NSDictionary *templateUserInfo = [listTemplate userInfo];
1536
+ NSNumber *scrollBottomThreshold = [templateUserInfo objectForKey:@"scrollBottomThreshold"];
1537
+
1538
+ if (scrollBottomThreshold) {
1539
+ // Calculate total number of items across all sections
1540
+ NSInteger totalItems = 0;
1541
+ for (CPListSection *section in listTemplate.sections) {
1542
+ totalItems += section.items.count;
1543
+ }
1544
+
1545
+ // Get the current index
1546
+ NSInteger currentIndex = [index integerValue];
1547
+
1548
+ // Calculate remaining items
1549
+ NSInteger remainingItems = totalItems - currentIndex - 1;
1550
+
1551
+ // If we're within the threshold from the end, fire the event
1552
+ if (remainingItems <= [scrollBottomThreshold integerValue]) {
1553
+ NSString *templateId = [templateUserInfo objectForKey:@"templateId"];
1554
+ if (self->hasListeners && templateId) {
1555
+ [self sendEventWithName:@"scrollToBottom" body:@{
1556
+ @"templateId": templateId,
1557
+ @"remainingItems": @(remainingItems)
1558
+ }];
1559
+ }
1560
+ }
1561
+ }
1514
1562
  }
1515
1563
 
1516
1564
  # pragma TabBarTemplate
@@ -66,6 +66,22 @@ export interface ListTemplateConfig extends TemplateConfig {
66
66
  * Fired when the back button is pressed
67
67
  */
68
68
  onBackButtonPressed?(): void;
69
+ /**
70
+ * Fired when user scrolls close to the bottom of the list.
71
+ * Useful for implementing infinite scroll / pagination.
72
+ * @param e Object with remainingItems count
73
+ * @namespace iOS
74
+ */
75
+ onScrollToBottom?(e: {
76
+ templateId: string;
77
+ remainingItems: number;
78
+ }): void;
79
+ /**
80
+ * Number of items from the bottom that triggers onScrollToBottom callback.
81
+ * @default 5
82
+ * @namespace iOS
83
+ */
84
+ scrollBottomThreshold?: number;
69
85
  /**
70
86
  * Option to hide back button
71
87
  * @default false
@@ -1 +1 @@
1
- {"version":3,"file":"ListTemplate.d.ts","sourceRoot":"","sources":["../../src/templates/ListTemplate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACxD;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB;;;;;;;;;;OAUG;IACH,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC;;;;;;;;;;OAUG;IACH,yBAAyB,CAAC,EAAE,MAAM,EAAE,CAAC;IACrC;;;;;OAKG;IACH,YAAY,CAAC,CAAC,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1E;;;;;OAKG;IACH,oBAAoB,CAAC,CAAC,IAAI,EAAE;QAC1B,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElB;;OAEG;IACH,mBAAmB,CAAC,IAAI,IAAI,CAAC;IAE7B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;OAIG;IACH,SAAS,CAAC,EAAE;QACV,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,KAAK,GAAG,QAAQ,CAAC;QAC3B,UAAU,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;QACzC,MAAM,EAAE,WAAW,GAAG,WAAW,CAAC;KACnC,CAAC;IACF;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC;IAC1C;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;CACrE;AAED;;;;;;;;GAQG;AACH,qBAAa,YAAa,SAAQ,QAAQ,CAAC,kBAAkB,CAAC;IAWzC,MAAM,EAAE,kBAAkB;IAV7C,IAAW,IAAI,IAAI,MAAM,CAExB;IAED,IAAI,QAAQ;;MAIX;gBAEkB,MAAM,EAAE,kBAAkB;IA2BtC,cAAc,aAAc,WAAW,EAAE,UAG9C;IAEK,sBAAsB,WAAY,cAAc,UAMrD;IAEK,uBAAuB;IAIvB,0BAA0B;IAI1B,2BAA2B;IAI3B,4BAA4B;IAI5B,mCAAmC;CAG3C"}
1
+ {"version":3,"file":"ListTemplate.d.ts","sourceRoot":"","sources":["../../src/templates/ListTemplate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACxD;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB;;;;;;;;;;OAUG;IACH,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC;;;;;;;;;;OAUG;IACH,yBAAyB,CAAC,EAAE,MAAM,EAAE,CAAC;IACrC;;;;;OAKG;IACH,YAAY,CAAC,CAAC,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1E;;;;;OAKG;IACH,oBAAoB,CAAC,CAAC,IAAI,EAAE;QAC1B,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElB;;OAEG;IACH,mBAAmB,CAAC,IAAI,IAAI,CAAC;IAE7B;;;;;OAKG;IACH,gBAAgB,CAAC,CAAC,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAE3E;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;OAIG;IACH,SAAS,CAAC,EAAE;QACV,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,KAAK,GAAG,QAAQ,CAAC;QAC3B,UAAU,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;QACzC,MAAM,EAAE,WAAW,GAAG,WAAW,CAAC;KACnC,CAAC;IACF;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC;IAC1C;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;CACrE;AAED;;;;;;;;GAQG;AACH,qBAAa,YAAa,SAAQ,QAAQ,CAAC,kBAAkB,CAAC;IAWzC,MAAM,EAAE,kBAAkB;IAV7C,IAAW,IAAI,IAAI,MAAM,CAExB;IAED,IAAI,QAAQ;;MAIX;gBAEkB,MAAM,EAAE,kBAAkB;IAoCtC,cAAc,aAAc,WAAW,EAAE,UAG9C;IAEK,sBAAsB,WAAY,cAAc,UAMrD;IAEK,uBAAuB;IAIvB,0BAA0B;IAI1B,2BAA2B;IAI3B,4BAA4B;IAI5B,mCAAmC;CAG3C"}
@@ -44,6 +44,11 @@ class ListTemplate extends Template_1.Template {
44
44
  });
45
45
  }
46
46
  });
47
+ CarPlay_1.CarPlay.emitter.addListener('scrollToBottom', (e) => {
48
+ if (config.onScrollToBottom && e.templateId === this.id) {
49
+ config.onScrollToBottom(e);
50
+ }
51
+ });
47
52
  }
48
53
  updateSections = (sections) => {
49
54
  this.config.sections = sections;
@@ -1 +1 @@
1
- {"version":3,"file":"Template.d.ts","sourceRoot":"","sources":["../../src/templates/Template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAY,MAAM,cAAc,CAAC;AAE7D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAKpD,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,SAAS,EAAE,CAAC;IAC1C;;;;;OAKG;IACH,4BAA4B,CAAC,EAAE,SAAS,EAAE,CAAC;IAC3C;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,YAAY,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAClC;;;OAGG;IACH,eAAe,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACrC;;;OAGG;IACH,WAAW,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACjC;;;OAGG;IACH,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAEpC;;;OAGG;IACH,kBAAkB,CAAC,CAAC,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;CAC9C;AAED,qBAAa,QAAQ,CAAC,CAAC;IAUF,MAAM,EAAE,cAAc,GAAG,CAAC;IAT7C,IAAW,IAAI,IAAI,MAAM,CAExB;IACM,EAAE,EAAG,MAAM,CAAC;IAEnB,IAAW,QAAQ,OAElB;gBAEkB,MAAM,EAAE,cAAc,GAAG,CAAC;IAiD7C,cAAc,WAAY,CAAC,UAGzB;IAGK,WAAW,CAAC,MAAM,EAAE,GAAG;CAiB/B"}
1
+ {"version":3,"file":"Template.d.ts","sourceRoot":"","sources":["../../src/templates/Template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAY,MAAM,cAAc,CAAC;AAE7D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAKpD,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,SAAS,EAAE,CAAC;IAC1C;;;;;OAKG;IACH,4BAA4B,CAAC,EAAE,SAAS,EAAE,CAAC;IAC3C;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,YAAY,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAClC;;;OAGG;IACH,eAAe,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACrC;;;OAGG;IACH,WAAW,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACjC;;;OAGG;IACH,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAEpC;;;OAGG;IACH,kBAAkB,CAAC,CAAC,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;CAC9C;AAED,qBAAa,QAAQ,CAAC,CAAC;IAUF,MAAM,EAAE,cAAc,GAAG,CAAC;IAT7C,IAAW,IAAI,IAAI,MAAM,CAExB;IACM,EAAE,EAAG,MAAM,CAAC;IAEnB,IAAW,QAAQ,OAElB;gBAEkB,MAAM,EAAE,cAAc,GAAG,CAAC;IAiD7C,cAAc,WAAY,CAAC,UAGzB;IAGK,WAAW,CAAC,MAAM,EAAE,GAAG;CAyB/B"}
@@ -57,13 +57,21 @@ class Template {
57
57
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
58
58
  function traverse(obj) {
59
59
  for (const i in obj) {
60
- if (obj[i] !== null && typeof obj[i] === 'object') {
61
- traverse(obj[i]);
60
+ if (String(i).match(/[Ii]mages$/)) {
61
+ console.log('array parsing', i, obj[i]);
62
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ obj[i] = obj[i].map((asset) => resolveAssetSource(asset));
65
+ console.log('array parsed', i, obj[i]);
62
66
  }
63
- if (String(i).match(/[Ii]mage$/)) {
67
+ else if (String(i).match(/[Ii]mage$/)) {
68
+ console.log('single image parsing', i, obj[i]);
64
69
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
65
70
  obj[i] = resolveAssetSource(obj[i]);
66
71
  }
72
+ else if (obj[i] !== null && typeof obj[i] === 'object') {
73
+ traverse(obj[i]);
74
+ }
67
75
  }
68
76
  }
69
77
  const result = JSON.parse(JSON.stringify(config));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@javascriptcommon/react-native-carplay",
3
- "version": "2.4.4",
3
+ "version": "2.4.7",
4
4
  "description": "CarPlay for React Native",
5
5
  "main": "lib/index.js",
6
6
  "react-native": "src/index.ts",
@@ -69,6 +69,21 @@ export interface ListTemplateConfig extends TemplateConfig {
69
69
  */
70
70
  onBackButtonPressed?(): void;
71
71
 
72
+ /**
73
+ * Fired when user scrolls close to the bottom of the list.
74
+ * Useful for implementing infinite scroll / pagination.
75
+ * @param e Object with remainingItems count
76
+ * @namespace iOS
77
+ */
78
+ onScrollToBottom?(e: { templateId: string; remainingItems: number }): void;
79
+
80
+ /**
81
+ * Number of items from the bottom that triggers onScrollToBottom callback.
82
+ * @default 5
83
+ * @namespace iOS
84
+ */
85
+ scrollBottomThreshold?: number;
86
+
72
87
  /**
73
88
  * Option to hide back button
74
89
  * @default false
@@ -150,6 +165,15 @@ export class ListTemplate extends Template<ListTemplateConfig> {
150
165
  }
151
166
  },
152
167
  );
168
+
169
+ CarPlay.emitter.addListener(
170
+ 'scrollToBottom',
171
+ (e: { templateId: string; remainingItems: number }) => {
172
+ if (config.onScrollToBottom && e.templateId === this.id) {
173
+ config.onScrollToBottom(e);
174
+ }
175
+ },
176
+ );
153
177
  }
154
178
 
155
179
  public updateSections = (sections: ListSection[]) => {
@@ -148,13 +148,21 @@ export class Template<P> {
148
148
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
149
149
  function traverse(obj: any) {
150
150
  for (const i in obj) {
151
- if (obj[i] !== null && typeof obj[i] === 'object') {
152
- traverse(obj[i]);
151
+ if (String(i).match(/[Ii]mages$/)) {
152
+ console.log('array parsing', i, obj[i])
153
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
154
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
155
+ obj[i] = obj[i].map((asset: any) => resolveAssetSource(asset));
156
+ console.log('array parsed', i, obj[i])
153
157
  }
154
- if (String(i).match(/[Ii]mage$/)) {
158
+ else if (String(i).match(/[Ii]mage$/)) {
159
+ console.log('single image parsing', i, obj[i])
155
160
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
156
161
  obj[i] = resolveAssetSource(obj[i]);
157
162
  }
163
+ else if (obj[i] !== null && typeof obj[i] === 'object') {
164
+ traverse(obj[i]);
165
+ }
158
166
  }
159
167
  }
160
168
  const result = JSON.parse(JSON.stringify(config));