From 0d86a21212686cdc8c6d2d26d5d41dc57d2dccc3 Mon Sep 17 00:00:00 2001 From: blanck Date: Sun, 5 Nov 2023 16:59:10 +0100 Subject: [PATCH 01/19] add openUrl and scene delegate --- packages/react-native-carplay/ios/RNCPStore.h | 2 ++ packages/react-native-carplay/ios/RNCarPlay.h | 2 +- packages/react-native-carplay/ios/RNCarPlay.m | 16 ++++++++++++++-- packages/react-native-carplay/src/CarPlay.ts | 19 ++++++++++++++----- .../src/templates/PointOfInterestTemplate.ts | 2 +- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/packages/react-native-carplay/ios/RNCPStore.h b/packages/react-native-carplay/ios/RNCPStore.h index 488d3f99..b27d6d00 100644 --- a/packages/react-native-carplay/ios/RNCPStore.h +++ b/packages/react-native-carplay/ios/RNCPStore.h @@ -4,10 +4,12 @@ @interface RNCPStore : NSObject { CPInterfaceController *interfaceController; CPWindow *window; + CPTemplateApplicationScene *scene; } @property (nonatomic, retain) CPInterfaceController *interfaceController; @property (nonatomic, retain) CPWindow *window; +@property (nonatomic, retain) CPTemplateApplicationScene *scene; + (id)sharedManager; - (CPTemplate*) findTemplateById: (NSString*)templateId; diff --git a/packages/react-native-carplay/ios/RNCarPlay.h b/packages/react-native-carplay/ios/RNCarPlay.h index 09115c8e..2362f3af 100644 --- a/packages/react-native-carplay/ios/RNCarPlay.h +++ b/packages/react-native-carplay/ios/RNCarPlay.h @@ -22,7 +22,7 @@ typedef void(^SelectedResultBlock)(void); @property (nonatomic, copy) SelectedResultBlock selectedResultBlock; @property (nonatomic) BOOL isNowPlayingActive; -+ (void) connectWithInterfaceController:(CPInterfaceController*)interfaceController window:(CPWindow*)window; ++ (void) connectWithInterfaceController:(CPInterfaceController*)interfaceController window:(CPWindow*)window scene:(CPTemplateApplicationScene*)scene; + (void) disconnect; - (NSArray*) parseSections:(NSArray*)sections; diff --git a/packages/react-native-carplay/ios/RNCarPlay.m b/packages/react-native-carplay/ios/RNCarPlay.m index 5bc6833b..550a87d1 100644 --- a/packages/react-native-carplay/ios/RNCarPlay.m +++ b/packages/react-native-carplay/ios/RNCarPlay.m @@ -29,10 +29,11 @@ + (NSDictionary *) getConnectedWindowInformation: (CPWindow *) window { }; } -+ (void) connectWithInterfaceController:(CPInterfaceController*)interfaceController window:(CPWindow*)window { ++ (void) connectWithInterfaceController:(CPInterfaceController*)interfaceController window:(CPWindow*)window scene:(CPTemplateApplicationScene*)scene { RNCPStore * store = [RNCPStore sharedManager]; store.interfaceController = interfaceController; store.window = window; + store.scene = scene; [store setConnected:true]; RNCarPlay *cp = [RNCarPlay allocWithZone:nil]; if (cp.bridge) { @@ -186,7 +187,18 @@ - (void)updateItemImageWithURL:(CPListItem *)item imgUrl:(NSString *)imgUrlStrin } } -RCT_EXPORT_METHOD(createTemplate:(NSString *)templateId config:(NSDictionary*)config) { +RCT_EXPORT_METHOD(openUrl:(NSString *)url) { + RNCPStore *store = [RNCPStore sharedManager]; + CPTemplateApplicationScene *templateApplicationScene = store.scene; + NSURL *URL = [NSURL URLWithString:url]; + [templateApplicationScene openURL:URL options:NULL completionHandler:^(BOOL success) { + if (success) { + NSLog(@"Opened url %@", url); + } + }]; +} + +RCT_EXPORT_METHOD(createTemplate:(NSString *)templateId config:(NSDictionary*)config callback:(NSString *)callback) { // Get the shared instance of the RNCPStore class RNCPStore *store = [RNCPStore sharedManager]; diff --git a/packages/react-native-carplay/src/CarPlay.ts b/packages/react-native-carplay/src/CarPlay.ts index 4694d0ae..dfa0c491 100644 --- a/packages/react-native-carplay/src/CarPlay.ts +++ b/packages/react-native-carplay/src/CarPlay.ts @@ -45,6 +45,7 @@ export interface InternalCarPlay extends NativeModule { createTrip(id: string, config: TripConfig): void; updateInformationTemplateItems(id: string, config: unknown): void; updateInformationTemplateActions(id: string, config: unknown): void; + openUrl(url: string): void; createTemplate(id: string, config: unknown, callback?: unknown): void; updateTemplate(id: string, config: unknown): void; invalidate(id: string): void; @@ -157,11 +158,11 @@ export class CarPlayInterface { callback(); }); }); - this.emitter.addListener('didPressMenuItem', e => { - if (e?.title === 'Reload Android Auto') { - this.bridge.reload(); - } - }); + // this.emitter.addListener('didPressMenuItem', e => { + // if (e?.title === 'Reload Android Auto') { + // this.bridge.reload(); + // } + // }); // check if already connected this will fire any 'didConnect' events // if a connected is already present. @@ -273,6 +274,14 @@ export class CarPlayInterface { public enableNowPlaying(enable = true) { return this.bridge.enableNowPlaying(enable); } + + /** + * Open url on Car device + * @param url A Boolean value that indicates whether the system use now playing template. + */ + public openUrl(url) { + return this.bridge.openUrl(url); + } } export const CarPlay = new CarPlayInterface(); diff --git a/packages/react-native-carplay/src/templates/PointOfInterestTemplate.ts b/packages/react-native-carplay/src/templates/PointOfInterestTemplate.ts index f53ea3b6..f4b1dda0 100644 --- a/packages/react-native-carplay/src/templates/PointOfInterestTemplate.ts +++ b/packages/react-native-carplay/src/templates/PointOfInterestTemplate.ts @@ -34,7 +34,7 @@ export class PointOfInterestTemplate extends Template Date: Tue, 7 Nov 2023 11:04:06 +0100 Subject: [PATCH 02/19] fix poi template --- .../ios/RCTConvert+RNCarPlay.m | 13 -- packages/react-native-carplay/ios/RNCarPlay.m | 117 ++++++++++++++++-- packages/react-native-carplay/src/CarPlay.ts | 2 + .../src/templates/PointOfInterestTemplate.ts | 22 +++- 4 files changed, 128 insertions(+), 26 deletions(-) diff --git a/packages/react-native-carplay/ios/RCTConvert+RNCarPlay.m b/packages/react-native-carplay/ios/RCTConvert+RNCarPlay.m index fecec95d..b58ed45b 100644 --- a/packages/react-native-carplay/ios/RCTConvert+RNCarPlay.m +++ b/packages/react-native-carplay/ios/RCTConvert+RNCarPlay.m @@ -71,19 +71,6 @@ + (CPRouteChoice*)CPRouteChoice:(id)json { return [[CPRouteChoice alloc] initWithSummaryVariants:[RCTConvert NSStringArray:json[@"additionalInformationVariants"]] additionalInformationVariants:[RCTConvert NSStringArray:json[@"selectionSummaryVariants"]] selectionSummaryVariants:[RCTConvert NSStringArray:json[@"summaryVariants"]]]; } -+ (CPPointOfInterest*)CPPointOfInterest:(id)json { - MKMapItem *location = [RCTConvert MKMapItem:json[@"location"]]; - NSString *title = [RCTConvert NSString:json[@"title"]]; - NSString *subtitle = [RCTConvert NSString:json[@"subtitle"]]; - NSString *summary = [RCTConvert NSString:json[@"summary"]]; - NSString *detailTitle = [RCTConvert NSString:json[@"detailTitle"]]; - NSString *detailSubtitle = [RCTConvert NSString:json[@"detailSubtitle"]]; - NSString *detailSummary = [RCTConvert NSString:json[@"detailSummary"]]; - - CPPointOfInterest *poi = [[CPPointOfInterest alloc] initWithLocation:location title:title subtitle:subtitle summary:summary detailTitle:detailTitle detailSubtitle:detailSubtitle detailSummary:detailSummary pinImage:nil]; - return poi; -} - + (CPAlertActionStyle)CPAlertActionStyle:(NSString*) json { if ([json isEqualToString:@"cancel"]) { return CPAlertActionStyleCancel; diff --git a/packages/react-native-carplay/ios/RNCarPlay.m b/packages/react-native-carplay/ios/RNCarPlay.m index 550a87d1..9c524e4b 100644 --- a/packages/react-native-carplay/ios/RNCarPlay.m +++ b/packages/react-native-carplay/ios/RNCarPlay.m @@ -93,6 +93,7 @@ + (id)allocWithZone:(NSZone *)zone { @"albumArtistButtonPressed", // poi @"didSelectPointOfInterest", + @"didChangeMapRegion", // map @"mapButtonPressed", @"didUpdatePanGestureWithTranslation", @@ -180,6 +181,67 @@ - (void)updateItemImageWithURL:(CPListItem *)item imgUrl:(NSString *)imgUrlStrin [task resume]; } +- (NSArray *)createPointsOfInterestFromItems:(NSArray *)items withTemplateId:(NSString *)templateId { + NSMutableArray *result = [NSMutableArray array]; + + for (NSDictionary *item in items) { + MKMapItem *location = [RCTConvert MKMapItem:item[@"location"]]; + UIImage *image = [RCTConvert UIImage:item[@"pinImage"]]; + UIImage *selectedImage = [RCTConvert UIImage:item[@"selectedPinImage"]]; + NSString *title = [RCTConvert NSString:item[@"title"]]; + NSString *subtitle = [RCTConvert NSString:item[@"subtitle"]]; + NSString *summary = [RCTConvert NSString:item[@"summary"]]; + NSString *detailTitle = [RCTConvert NSString:item[@"detailTitle"]]; + NSString *detailSubtitle = [RCTConvert NSString:item[@"detailSubtitle"]]; + NSString *detailSummary = [RCTConvert NSString:item[@"detailSummary"]]; + + CPPointOfInterest *poi = [[CPPointOfInterest alloc] initWithLocation:location + title:title + subtitle:subtitle + summary:summary + detailTitle:detailTitle + detailSubtitle:detailSubtitle + detailSummary:detailSummary + pinImage:image + selectedPinImage:selectedImage]; + + if ([item objectForKey:@"primaryButton"]) { + NSString *primaryButtonText = [RCTConvert NSString:item[@"primaryButton"]]; + CPTextButton *primaryButton = [[CPTextButton alloc] initWithTitle:primaryButtonText + textStyle:CPTextButtonStyleConfirm + handler:^(CPTextButton * _Nonnull primaryButton) { + if (self->hasListeners) { + [self sendEventWithName:@"actionButtonPressed" + body:@{@"templateId":templateId, + @"id": @"primary", + @"item": item}]; + } + }]; + [poi setPrimaryButton:primaryButton]; + } + + if ([item objectForKey:@"secondaryButton"]) { + NSString *secondaryButtonText = [RCTConvert NSString:item[@"secondaryButton"]]; + CPTextButton *secondaryButton = [[CPTextButton alloc] initWithTitle:secondaryButtonText + textStyle:CPTextButtonStyleNormal + handler:^(CPTextButton * _Nonnull secondaryButton) { + if (self->hasListeners) { + [self sendEventWithName:@"actionButtonPressed" + body:@{@"templateId":templateId, + @"id": @"secondary", + @"item": item}]; + } + }]; + [poi setSecondaryButton:secondaryButton]; + } + + [poi setUserInfo:item]; + [result addObject:poi]; + } + + return [result copy]; +} + RCT_EXPORT_METHOD(checkForConnection) { RNCPStore *store = [RNCPStore sharedManager]; if ([store isConnected] && hasListeners) { @@ -354,18 +416,16 @@ - (void)updateItemImageWithURL:(CPListItem *)item imgUrl:(NSString *)imgUrlStrin carPlayTemplate = alertTemplate; } else if ([type isEqualToString:@"poi"]) { NSString *title = [RCTConvert NSString:config[@"title"]]; - NSMutableArray<__kindof CPPointOfInterest *> * items = [NSMutableArray new]; - NSUInteger selectedIndex = 0; + NSUInteger selectedIndex = NSNotFound; + NSArray *items = [RCTConvert NSDictionaryArray:config[@"items"]]; + NSArray *poiItems = [self createPointsOfInterestFromItems:items withTemplateId:templateId]; - NSArray *_items = [RCTConvert NSDictionaryArray:config[@"items"]]; - for (NSDictionary *_item in _items) { - CPPointOfInterest *poi = [RCTConvert CPPointOfInterest:_item]; - [poi setUserInfo:_item]; - [items addObject:poi]; - } - - CPPointOfInterestTemplate *poiTemplate = [[CPPointOfInterestTemplate alloc] initWithTitle:title pointsOfInterest:items selectedIndex:selectedIndex]; + CPPointOfInterestTemplate *poiTemplate = [[CPPointOfInterestTemplate alloc] initWithTitle:title pointsOfInterest:poiItems selectedIndex:selectedIndex]; poiTemplate.pointOfInterestDelegate = self; + + [poiTemplate setLeadingNavigationBarButtons:leadingNavigationBarButtons]; + [poiTemplate setTrailingNavigationBarButtons:trailingNavigationBarButtons]; + carPlayTemplate = poiTemplate; } else if ([type isEqualToString:@"information"]) { NSString *title = [RCTConvert NSString:config[@"title"]]; @@ -661,6 +721,31 @@ - (void)updateItemImageWithURL:(CPListItem *)item imgUrl:(NSString *)imgUrlStrin } } +RCT_EXPORT_METHOD(setPointsOfInterest:(NSString *)templateId items:(NSArray*)items) { + RNCPStore *store = [RNCPStore sharedManager]; + CPTemplate *template = [store findTemplateById:templateId]; + if (template) { + CPPointOfInterestTemplate *poiTemplate = (CPPointOfInterestTemplate*) template; + NSUInteger selectedIndex = NSNotFound; + NSArray *poiItems = [self createPointsOfInterestFromItems:items withTemplateId:templateId]; + + [poiTemplate setPointsOfInterest:poiItems selectedIndex:selectedIndex]; + } else { + NSLog(@"Failed to find template %@", template); + } +} + +RCT_EXPORT_METHOD(setPointOfInterestTitle:(NSString *)templateId title:(NSString*)title) { + RNCPStore *store = [RNCPStore sharedManager]; + CPTemplate *template = [store findTemplateById:templateId]; + if (template) { + CPPointOfInterestTemplate *poiTemplate = (CPPointOfInterestTemplate*) template; + [poiTemplate setTitle:title]; + } else { + NSLog(@"Failed to find template %@", template); + } +} + RCT_EXPORT_METHOD(updateInformationTemplateItems:(NSString *)templateId items:(NSArray*)items) { RNCPStore *store = [RNCPStore sharedManager]; CPTemplate *template = [store findTemplateById:templateId]; @@ -1349,8 +1434,16 @@ - (void)tabBarTemplate:(CPTabBarTemplate *)tabBarTemplate didSelectTemplate:(__k } # pragma PointOfInterest --(void)pointOfInterestTemplate:(CPPointOfInterestTemplate *)pointOfInterestTemplate didChangeMapRegion:(MKCoordinateRegion)region { - // noop +-(void)pointOfInterestTemplate:(CPPointOfInterestTemplate *)pointOfInterestTemplate + didChangeMapRegion:(MKCoordinateRegion)region { + NSDictionary *regionDictionary = @{ + @"latitude": @(region.center.latitude), + @"longitude": @(region.center.longitude), + @"latitudeDelta": @(region.span.latitudeDelta), + @"longitudeDelta": @(region.span.longitudeDelta) + }; + + [self sendTemplateEventWithName:pointOfInterestTemplate name:@"didChangeMapRegion" json:regionDictionary]; } -(void)pointOfInterestTemplate:(CPPointOfInterestTemplate *)pointOfInterestTemplate didSelectPointOfInterest:(CPPointOfInterest *)pointOfInterest { diff --git a/packages/react-native-carplay/src/CarPlay.ts b/packages/react-native-carplay/src/CarPlay.ts index dfa0c491..eb20b400 100644 --- a/packages/react-native-carplay/src/CarPlay.ts +++ b/packages/react-native-carplay/src/CarPlay.ts @@ -45,6 +45,8 @@ export interface InternalCarPlay extends NativeModule { createTrip(id: string, config: TripConfig): void; updateInformationTemplateItems(id: string, config: unknown): void; updateInformationTemplateActions(id: string, config: unknown): void; + setPointsOfInterest(id: string, config: unknown): void; + setPointOfInterestTitle(id: string, title: string): void; openUrl(url: string): void; createTemplate(id: string, config: unknown, callback?: unknown): void; updateTemplate(id: string, config: unknown): void; diff --git a/packages/react-native-carplay/src/templates/PointOfInterestTemplate.ts b/packages/react-native-carplay/src/templates/PointOfInterestTemplate.ts index f4b1dda0..cb03781c 100644 --- a/packages/react-native-carplay/src/templates/PointOfInterestTemplate.ts +++ b/packages/react-native-carplay/src/templates/PointOfInterestTemplate.ts @@ -1,4 +1,11 @@ import { Template, TemplateConfig } from './Template'; +import { ImageSourcePropType } from 'react-native'; +import { CarPlay } from '../CarPlay'; + +export interface PointOfInterestAction { + id: string; + title: string; +} export interface PointOfInterestItem { id: string; @@ -6,12 +13,15 @@ export interface PointOfInterestItem { latitude: number; longitude: number; }; + pinImage?: ImageSourcePropType; + selectedPinImage?: ImageSourcePropType; title: string; subtitle?: string; summary?: string; detailTitle?: string; detailSubtitle?: string; detailSummary?: string; + primaryButton?: string; } export interface PointOfInterestTemplateConfig extends TemplateConfig { @@ -24,6 +34,7 @@ export interface PointOfInterestTemplateConfig extends TemplateConfig { latitudeDelta: number; longitudeDelta: number; }): void; + onActionButtonPressed?(e: { id: string; templateId: string, item: PointOfInterestItem }): void; } export class PointOfInterestTemplate extends Template { @@ -31,10 +42,19 @@ export class PointOfInterestTemplate extends Template { + this.config.items = items; + return CarPlay.bridge.setPointsOfInterest(this.id, this.parseConfig(items)); + }; + public setPointOfInterestTitle = (title: string) => { + return CarPlay.bridge.setPointOfInterestTitle(this.id, title); + }; + get eventMap() { return { didSelectPointOfInterest: 'onPointOfInterestSelect', - //didChangeMapRegion: 'onChangeMapRegion', + didChangeMapRegion: 'onChangeMapRegion', + actionButtonPressed: 'onActionButtonPressed', }; } } From 7d6f2b1e77f3c9e23b050345bf07b8db405d59df Mon Sep 17 00:00:00 2001 From: blanck Date: Wed, 8 Nov 2023 08:20:38 +0100 Subject: [PATCH 03/19] code cleanup --- packages/react-native-carplay/ios/RNCarPlay.m | 43 ++++++------------- packages/react-native-carplay/src/CarPlay.ts | 7 +-- .../src/templates/PointOfInterestTemplate.ts | 6 +-- 3 files changed, 14 insertions(+), 42 deletions(-) diff --git a/packages/react-native-carplay/ios/RNCarPlay.m b/packages/react-native-carplay/ios/RNCarPlay.m index 9c524e4b..f359ba77 100644 --- a/packages/react-native-carplay/ios/RNCarPlay.m +++ b/packages/react-native-carplay/ios/RNCarPlay.m @@ -195,50 +195,32 @@ - (void)updateItemImageWithURL:(CPListItem *)item imgUrl:(NSString *)imgUrlStrin NSString *detailSubtitle = [RCTConvert NSString:item[@"detailSubtitle"]]; NSString *detailSummary = [RCTConvert NSString:item[@"detailSummary"]]; - CPPointOfInterest *poi = [[CPPointOfInterest alloc] initWithLocation:location - title:title - subtitle:subtitle - summary:summary - detailTitle:detailTitle - detailSubtitle:detailSubtitle - detailSummary:detailSummary - pinImage:image - selectedPinImage:selectedImage]; + CPPointOfInterest *poi = [[CPPointOfInterest alloc] initWithLocation:location title:title subtitle:subtitle summary:summary detailTitle:detailTitle detailSubtitle:detailSubtitle detailSummary:detailSummary pinImage:image selectedPinImage:selectedImage]; if ([item objectForKey:@"primaryButton"]) { NSString *primaryButtonText = [RCTConvert NSString:item[@"primaryButton"]]; - CPTextButton *primaryButton = [[CPTextButton alloc] initWithTitle:primaryButtonText - textStyle:CPTextButtonStyleConfirm - handler:^(CPTextButton * _Nonnull primaryButton) { - if (self->hasListeners) { - [self sendEventWithName:@"actionButtonPressed" - body:@{@"templateId":templateId, - @"id": @"primary", - @"item": item}]; - } - }]; + CPTextButton *primaryButton = [[CPTextButton alloc] initWithTitle:primaryButtonText textStyle:CPTextButtonStyleConfirm handler:^(CPTextButton * _Nonnull primaryButton) { + if (self->hasListeners) { + [self sendEventWithName:@"actionButtonPressed" body:@{@"templateId":templateId, @"id": @"primary", @"item": item}]; + } + }]; [poi setPrimaryButton:primaryButton]; } if ([item objectForKey:@"secondaryButton"]) { NSString *secondaryButtonText = [RCTConvert NSString:item[@"secondaryButton"]]; - CPTextButton *secondaryButton = [[CPTextButton alloc] initWithTitle:secondaryButtonText - textStyle:CPTextButtonStyleNormal - handler:^(CPTextButton * _Nonnull secondaryButton) { - if (self->hasListeners) { - [self sendEventWithName:@"actionButtonPressed" - body:@{@"templateId":templateId, - @"id": @"secondary", - @"item": item}]; - } - }]; + CPTextButton *secondaryButton = [[CPTextButton alloc] initWithTitle:secondaryButtonText textStyle:CPTextButtonStyleNormal handler:^(CPTextButton * _Nonnull secondaryButton) { + if (self->hasListeners) { + [self sendEventWithName:@"actionButtonPressed" body:@{@"templateId":templateId, @"id": @"secondary", @"item": item}]; + } + }]; [poi setSecondaryButton:secondaryButton]; } [poi setUserInfo:item]; [result addObject:poi]; } - + return [result copy]; } @@ -255,7 +237,6 @@ - (void)updateItemImageWithURL:(CPListItem *)item imgUrl:(NSString *)imgUrlStrin NSURL *URL = [NSURL URLWithString:url]; [templateApplicationScene openURL:URL options:NULL completionHandler:^(BOOL success) { if (success) { - NSLog(@"Opened url %@", url); } }]; } diff --git a/packages/react-native-carplay/src/CarPlay.ts b/packages/react-native-carplay/src/CarPlay.ts index eb20b400..13af80cb 100644 --- a/packages/react-native-carplay/src/CarPlay.ts +++ b/packages/react-native-carplay/src/CarPlay.ts @@ -160,11 +160,6 @@ export class CarPlayInterface { callback(); }); }); - // this.emitter.addListener('didPressMenuItem', e => { - // if (e?.title === 'Reload Android Auto') { - // this.bridge.reload(); - // } - // }); // check if already connected this will fire any 'didConnect' events // if a connected is already present. @@ -279,7 +274,7 @@ export class CarPlayInterface { /** * Open url on Car device - * @param url A Boolean value that indicates whether the system use now playing template. + * @param url A string value with the URL to open on the device (example maps:// and comgooglemaps://) */ public openUrl(url) { return this.bridge.openUrl(url); diff --git a/packages/react-native-carplay/src/templates/PointOfInterestTemplate.ts b/packages/react-native-carplay/src/templates/PointOfInterestTemplate.ts index cb03781c..3a0e6d54 100644 --- a/packages/react-native-carplay/src/templates/PointOfInterestTemplate.ts +++ b/packages/react-native-carplay/src/templates/PointOfInterestTemplate.ts @@ -2,11 +2,6 @@ import { Template, TemplateConfig } from './Template'; import { ImageSourcePropType } from 'react-native'; import { CarPlay } from '../CarPlay'; -export interface PointOfInterestAction { - id: string; - title: string; -} - export interface PointOfInterestItem { id: string; location: { @@ -22,6 +17,7 @@ export interface PointOfInterestItem { detailSubtitle?: string; detailSummary?: string; primaryButton?: string; + secondaryButton?: string; } export interface PointOfInterestTemplateConfig extends TemplateConfig { From 1c5eb320dd7b25237d795a837381589e387e7c33 Mon Sep 17 00:00:00 2001 From: blanck Date: Wed, 8 Nov 2023 08:40:45 +0100 Subject: [PATCH 04/19] update example with scene --- apps/example/ios/CarScene.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/example/ios/CarScene.swift b/apps/example/ios/CarScene.swift index a55c8b96..4f048b91 100644 --- a/apps/example/ios/CarScene.swift +++ b/apps/example/ios/CarScene.swift @@ -4,7 +4,7 @@ import CarPlay class CarSceneDelegate: UIResponder, CPTemplateApplicationSceneDelegate { func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene, didConnect interfaceController: CPInterfaceController) { - RNCarPlay.connect(with: interfaceController, window: templateApplicationScene.carWindow); + RNCarPlay.connect(with: interfaceController, window: templateApplicationScene.carWindow, scene: templateApplicationScene); } func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene, didDisconnectInterfaceController interfaceController: CPInterfaceController) { From f11dd5734bd2eb4046f01923c246da3fe219c584 Mon Sep 17 00:00:00 2001 From: blanck Date: Fri, 10 Nov 2023 18:51:39 +0100 Subject: [PATCH 05/19] android auto updates --- .../java/org/birkir/carplay/CarPlayModule.kt | 27 ++++++++++++++++++- .../org/birkir/carplay/parser/RCTTemplate.kt | 19 ++++++++++++- .../org/birkir/carplay/screens/CarScreen.kt | 2 +- packages/react-native-carplay/src/CarPlay.ts | 20 ++++++++++++++ .../src/templates/Template.ts | 2 +- .../android/AndroidNavigationBaseTemplate.ts | 4 +++ .../src/templates/android/PaneTemplate.ts | 8 ++++++ 7 files changed, 78 insertions(+), 4 deletions(-) diff --git a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt index ef6aa04d..8c4de278 100644 --- a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt +++ b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt @@ -4,6 +4,7 @@ import android.content.Intent import android.os.Handler import android.os.Looper import android.util.Log +import android.net.Uri import androidx.activity.OnBackPressedCallback import androidx.car.app.AppManager import androidx.car.app.CarContext @@ -97,6 +98,22 @@ class CarPlayModule internal constructor(private val reactContext: ReactApplicat eventEmitter?.didConnect() } + @ReactMethod + fun openUrl(url: String) { + Log.d(TAG, "openUrl $url") + } + + @ReactMethod + fun navigateTo(latitude: Double, longitude: Double, name: String, app: String){ + var url = "geo:0,0?q=${latitude},${longitude}(${name})" + Log.d(TAG, "navigateTo $url") + val intent = Intent(CarContext.ACTION_NAVIGATE, Uri.parse("geo:0,0?q=${latitude},${longitude}(${name})")) + if (app != null) { + intent.setPackage(app) + } + carContext.startCarApp(intent) + } + @ReactMethod fun createTemplate(templateId: String, config: ReadableMap, callback: Callback?) { handler.post { @@ -118,9 +135,10 @@ class CarPlayModule internal constructor(private val reactContext: ReactApplicat @ReactMethod fun updateTemplate(templateId: String, config: ReadableMap) { + Log.d(TAG, "updateTemplate for $templateId") handler.post { carTemplates[templateId] = config; - val screen = carScreens[name] + val screen = carScreens[templateId] if (screen != null) { val carScreenContext = carScreenContexts[screen]; if (carScreenContext != null) { @@ -163,6 +181,13 @@ class CarPlayModule internal constructor(private val reactContext: ReactApplicat } } + @ReactMethod + fun popToRootTemplate(animated: Boolean?) { + handler.post { + Log.d(TAG, "popToRootTemplate not supported") + } + } + @ReactMethod fun popTemplate(animated: Boolean?) { handler.post { diff --git a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/parser/RCTTemplate.kt b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/parser/RCTTemplate.kt index 01dbabd3..4986856e 100644 --- a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/parser/RCTTemplate.kt +++ b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/parser/RCTTemplate.kt @@ -6,6 +6,7 @@ import android.graphics.Bitmap import android.text.Spannable import android.text.SpannableString import android.util.Log +import android.graphics.Color import androidx.car.app.CarContext import androidx.car.app.model.Action import androidx.car.app.model.Action.FLAG_IS_PERSISTENT @@ -167,7 +168,13 @@ abstract class RCTTemplate( item.getString("text")?.let { setTitle(it) } item.getString("detailText")?.let { addText(it) } item.getMap("image")?.let { setImage(parseCarIcon(it)) } + item.getMap("location")?.let { setMetadata( + Metadata.Builder() + .setPlace(parsePlace(it)) + .build() + )} if (item.hasKey("browsable") && item.getBoolean("browsable")) { + setBrowsable(true) setOnClickListener { eventEmitter.didSelectListItem( id, @@ -211,7 +218,17 @@ abstract class RCTTemplate( ) ) PlaceMarker.Builder().apply { - setIcon(parseCarIcon(props.getMap("icon")!!), PlaceMarker.TYPE_IMAGE) + props.getMap("icon")?.let { + setIcon(parseCarIcon(props.getMap("icon")!!), PlaceMarker.TYPE_IMAGE) + } + props.getString("color")?.let { + setColor( + CarColor.createCustom( + Color.parseColor(props.getString("color")), + Color.parseColor(props.getString("color")) + ) + ) + } builder.setMarker(this.build()) } diff --git a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/screens/CarScreen.kt b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/screens/CarScreen.kt index 1ae84b17..eaaa42f3 100644 --- a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/screens/CarScreen.kt +++ b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/screens/CarScreen.kt @@ -59,7 +59,7 @@ class CarScreen(carContext: CarContext) : Screen(carContext) { Log.d(TAG, "onGetTemplate for $marker") return template ?: PaneTemplate.Builder( Pane.Builder().setLoading(true).build() - ).setTitle("RNCarPlay loading...").build() + ).setTitle("Loading...").build() // @todo allow set the loading title by translatable resource. } diff --git a/packages/react-native-carplay/src/CarPlay.ts b/packages/react-native-carplay/src/CarPlay.ts index 13af80cb..b9a6e4bd 100644 --- a/packages/react-native-carplay/src/CarPlay.ts +++ b/packages/react-native-carplay/src/CarPlay.ts @@ -83,6 +83,7 @@ export interface InternalCarPlay extends NativeModule { activateVoiceControlState(id: string, identifier: string): void; // Android reload(): void; + navigateTo(latitude: number, longitude: number, name: string): void; toast(message: string, duration: number): void; alert(config: { id: number; @@ -279,6 +280,25 @@ export class CarPlayInterface { public openUrl(url) { return this.bridge.openUrl(url); } + + /** + * Navigate to location on Android Auto device + * @param latitude A double value with the latitude of location + * @param longitude A double value with the longitude of location + * @param name A string value with the name of location to open on the device + */ + public navigateTo(latitude, longitude, name) { + return this.bridge.navigateTo(latitude, longitude, name); + } + + /** + * Show toast message on Android Auto + * @param message A string value with the message to show + * @param duration A integer value with the number of milliseconds to display toast + */ + public toast(message, duration) { + return this.bridge.toast(message, duration); + } } export const CarPlay = new CarPlayInterface(); diff --git a/packages/react-native-carplay/src/templates/Template.ts b/packages/react-native-carplay/src/templates/Template.ts index d39678f4..0858c313 100644 --- a/packages/react-native-carplay/src/templates/Template.ts +++ b/packages/react-native-carplay/src/templates/Template.ts @@ -139,7 +139,7 @@ export class Template

{ } updateTemplate = (config: P) => { - console.log('LETSGO!', config, this.type); + //console.log('LETSGO!', config, this.type); CarPlay.bridge.updateTemplate(this.id, this.parseConfig({ type: this.type, ...config })); }; diff --git a/packages/react-native-carplay/src/templates/android/AndroidNavigationBaseTemplate.ts b/packages/react-native-carplay/src/templates/android/AndroidNavigationBaseTemplate.ts index 5f6c067d..5d7b0755 100644 --- a/packages/react-native-carplay/src/templates/android/AndroidNavigationBaseTemplate.ts +++ b/packages/react-native-carplay/src/templates/android/AndroidNavigationBaseTemplate.ts @@ -12,6 +12,8 @@ export interface AndroidNavigationBaseTemplateConfig extends TemplateConfig { onDidShowPanningInterface?(): void; onDidDismissPanningInterface?(): void; + onItemSelect?(item: { index: number }): Promise; + onBackButtonPressed?(): void; } export class AndroidNavigationBaseTemplate< @@ -21,6 +23,8 @@ export class AndroidNavigationBaseTemplate< return { didShowPanningInterface: 'onDidShowPanningInterface', didDismissPanningInterface: 'onDidDismissPanningInterface', + didSelectListItem: 'onItemSelect', + backButtonPressed: 'onBackButtonPressed', }; } diff --git a/packages/react-native-carplay/src/templates/android/PaneTemplate.ts b/packages/react-native-carplay/src/templates/android/PaneTemplate.ts index 993c393f..4013dd0b 100644 --- a/packages/react-native-carplay/src/templates/android/PaneTemplate.ts +++ b/packages/react-native-carplay/src/templates/android/PaneTemplate.ts @@ -7,10 +7,18 @@ export interface PaneTemplateConfig extends TemplateConfig { headerAction?: HeaderAction; actions?: Action[]; title?: string; + onButtonPressed?(e: { id: string; templateId: string }): void; + onBackButtonPressed?(): void; } export class PaneTemplate extends Template { public get type(): string { return 'pane'; } + get eventMap() { + return { + buttonPressed: 'onButtonPressed', + backButtonPressed: 'onBackButtonPressed', + }; + } } From 528d5ea797096ac2502dd4ee08d91a5778c35a83 Mon Sep 17 00:00:00 2001 From: blanck Date: Sat, 11 Nov 2023 11:33:55 +0100 Subject: [PATCH 06/19] fix peer dependencies warning --- packages/react-native-carplay/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-native-carplay/package.json b/packages/react-native-carplay/package.json index e4b5a65d..beaf4c56 100644 --- a/packages/react-native-carplay/package.json +++ b/packages/react-native-carplay/package.json @@ -39,8 +39,8 @@ }, "homepage": "https://github.com/birkir/react-native-carplay#readme", "peerDependencies": { - "react": "^17.0.2 || ^18.0.0", - "react-native": "^0.60.0" + "react": ">=17.0.2", + "react-native": ">=0.60.0" }, "peerDependenciesMeta": { "react": { From 69dfa0b2884cfce6c2e998319a2627e0d059ed1d Mon Sep 17 00:00:00 2001 From: blanck Date: Sat, 11 Nov 2023 11:38:38 +0100 Subject: [PATCH 07/19] fix peer dependencies warning --- packages/react-native-carplay/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-native-carplay/package.json b/packages/react-native-carplay/package.json index beaf4c56..95629c6e 100644 --- a/packages/react-native-carplay/package.json +++ b/packages/react-native-carplay/package.json @@ -39,8 +39,8 @@ }, "homepage": "https://github.com/birkir/react-native-carplay#readme", "peerDependencies": { - "react": ">=17.0.2", - "react-native": ">=0.60.0" + "react": "*", + "react-native": "*" }, "peerDependenciesMeta": { "react": { From 9165aa6f037657ff4be6866a964711a6885dac8c Mon Sep 17 00:00:00 2001 From: blanck Date: Sun, 12 Nov 2023 22:21:51 +0100 Subject: [PATCH 08/19] fix checkForConnection event --- .../android/src/main/java/org/birkir/carplay/CarPlayModule.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt index 8c4de278..a19cd058 100644 --- a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt +++ b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt @@ -95,7 +95,9 @@ class CarPlayModule internal constructor(private val reactContext: ReactApplicat @ReactMethod fun checkForConnection() { - eventEmitter?.didConnect() + if (::carContext.isInitialized){ + eventEmitter?.didConnect() + } } @ReactMethod From 285827dbbd8427509c42e7ba653f77ef4ee31010 Mon Sep 17 00:00:00 2001 From: blanck Date: Mon, 13 Nov 2023 00:39:21 +0100 Subject: [PATCH 09/19] fix navigateTo package --- .../src/main/java/org/birkir/carplay/CarPlayModule.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt index a19cd058..83f4fc9a 100644 --- a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt +++ b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt @@ -106,13 +106,10 @@ class CarPlayModule internal constructor(private val reactContext: ReactApplicat } @ReactMethod - fun navigateTo(latitude: Double, longitude: Double, name: String, app: String){ + fun navigateTo(latitude: Double, longitude: Double, name: String){ var url = "geo:0,0?q=${latitude},${longitude}(${name})" Log.d(TAG, "navigateTo $url") - val intent = Intent(CarContext.ACTION_NAVIGATE, Uri.parse("geo:0,0?q=${latitude},${longitude}(${name})")) - if (app != null) { - intent.setPackage(app) - } + val intent = Intent(CarContext.ACTION_NAVIGATE, Uri.parse(url)) carContext.startCarApp(intent) } From c1829fa7125569f069a8655a0ebe05ce623bbb64 Mon Sep 17 00:00:00 2001 From: blanck Date: Fri, 17 Nov 2023 02:04:52 +0100 Subject: [PATCH 10/19] fix selectedPinImage and information button style --- packages/react-native-carplay/ios/RNCarPlay.m | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/react-native-carplay/ios/RNCarPlay.m b/packages/react-native-carplay/ios/RNCarPlay.m index f359ba77..392d2cd1 100644 --- a/packages/react-native-carplay/ios/RNCarPlay.m +++ b/packages/react-native-carplay/ios/RNCarPlay.m @@ -187,7 +187,6 @@ - (void)updateItemImageWithURL:(CPListItem *)item imgUrl:(NSString *)imgUrlStrin for (NSDictionary *item in items) { MKMapItem *location = [RCTConvert MKMapItem:item[@"location"]]; UIImage *image = [RCTConvert UIImage:item[@"pinImage"]]; - UIImage *selectedImage = [RCTConvert UIImage:item[@"selectedPinImage"]]; NSString *title = [RCTConvert NSString:item[@"title"]]; NSString *subtitle = [RCTConvert NSString:item[@"subtitle"]]; NSString *summary = [RCTConvert NSString:item[@"summary"]]; @@ -195,7 +194,16 @@ - (void)updateItemImageWithURL:(CPListItem *)item imgUrl:(NSString *)imgUrlStrin NSString *detailSubtitle = [RCTConvert NSString:item[@"detailSubtitle"]]; NSString *detailSummary = [RCTConvert NSString:item[@"detailSummary"]]; - CPPointOfInterest *poi = [[CPPointOfInterest alloc] initWithLocation:location title:title subtitle:subtitle summary:summary detailTitle:detailTitle detailSubtitle:detailSubtitle detailSummary:detailSummary pinImage:image selectedPinImage:selectedImage]; + CPPointOfInterest *poi = [[CPPointOfInterest alloc] initWithLocation:location title:title subtitle:subtitle summary:summary detailTitle:detailTitle detailSubtitle:detailSubtitle detailSummary:detailSummary pinImage:image]; + + if ([item objectForKey:@"selectedPinImage"]) { + UIImage *selectedImage = [RCTConvert UIImage:item[@"selectedPinImage"]]; + if (@available(iOS 16.0, *)) { + [poi setSelectedPinImage: selectedImage]; + } else { + // Fallback on earlier versions + } + } if ([item objectForKey:@"primaryButton"]) { NSString *primaryButtonText = [RCTConvert NSString:item[@"primaryButton"]]; @@ -216,7 +224,7 @@ - (void)updateItemImageWithURL:(CPListItem *)item imgUrl:(NSString *)imgUrlStrin }]; [poi setSecondaryButton:secondaryButton]; } - + [poi setUserInfo:item]; [result addObject:poi]; } @@ -421,7 +429,8 @@ - (void)updateItemImageWithURL:(CPListItem *)item imgUrl:(NSString *)imgUrlStrin NSArray *_actions = [RCTConvert NSDictionaryArray:config[@"actions"]]; for (NSDictionary *_action in _actions) { - CPTextButton *action = [[CPTextButton alloc] initWithTitle:_action[@"title"] textStyle:CPTextButtonStyleNormal handler:^(__kindof CPTextButton * _Nonnull contactButton) { + CPTextButtonStyle buttonStyle = [_action[@"visibility"] isEqualToString:@"primary"] ? CPTextButtonStyleConfirm : CPTextButtonStyleNormal; + CPTextButton *action = [[CPTextButton alloc] initWithTitle:_action[@"title"] textStyle:buttonStyle handler:^(__kindof CPTextButton * _Nonnull contactButton) { if (self->hasListeners) { [self sendEventWithName:@"actionButtonPressed" body:@{@"templateId":templateId, @"id": _action[@"id"] }]; } From d45b2d7dd1be2acbc3b834ac0af78ab12f5268f9 Mon Sep 17 00:00:00 2001 From: blanck Date: Fri, 17 Nov 2023 18:39:21 +0100 Subject: [PATCH 11/19] remove manifest declarations --- .../android/src/main/AndroidManifest.xml | 6 +----- .../android/src/main/AndroidManifestNew.xml | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/react-native-carplay/android/src/main/AndroidManifest.xml b/packages/react-native-carplay/android/src/main/AndroidManifest.xml index 90a976d3..e82197dd 100644 --- a/packages/react-native-carplay/android/src/main/AndroidManifest.xml +++ b/packages/react-native-carplay/android/src/main/AndroidManifest.xml @@ -1,11 +1,7 @@ - - - - - + \ No newline at end of file diff --git a/packages/react-native-carplay/android/src/main/AndroidManifestNew.xml b/packages/react-native-carplay/android/src/main/AndroidManifestNew.xml index 90a976d3..e82197dd 100644 --- a/packages/react-native-carplay/android/src/main/AndroidManifestNew.xml +++ b/packages/react-native-carplay/android/src/main/AndroidManifestNew.xml @@ -1,11 +1,7 @@ - - - - - + \ No newline at end of file From 7656e17ac482889405d34ecb4a59ead901098161 Mon Sep 17 00:00:00 2001 From: blanck Date: Sat, 18 Nov 2023 11:12:23 +0100 Subject: [PATCH 12/19] remove manifest scheme --- .../android/src/main/AndroidManifest.xml | 6 +----- .../android/src/main/AndroidManifestNew.xml | 7 ++----- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/react-native-carplay/android/src/main/AndroidManifest.xml b/packages/react-native-carplay/android/src/main/AndroidManifest.xml index e82197dd..4b86f780 100644 --- a/packages/react-native-carplay/android/src/main/AndroidManifest.xml +++ b/packages/react-native-carplay/android/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ + - - - - - + - - - - - + Date: Sun, 19 Nov 2023 00:41:54 +0100 Subject: [PATCH 13/19] fix setCarContext parser error --- .../src/main/java/org/birkir/carplay/CarPlayModule.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt index 83f4fc9a..5cd6c27f 100644 --- a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt +++ b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt @@ -72,7 +72,8 @@ class CarPlayModule internal constructor(private val reactContext: ReactApplicat } fun setCarContext(carContext: CarContext, currentCarScreen: CarScreen) { - parser = Parser(carContext, CarScreenContext("", eventEmitter!!, carScreens)); + // @todo Parser will crash if phone app is not open when launching car app + // parser = Parser(carContext, CarScreenContext("", eventEmitter!!, carScreens)); this.carContext = carContext this.currentCarScreen = currentCarScreen screenManager = currentCarScreen.screenManager @@ -296,7 +297,7 @@ class CarPlayModule internal constructor(private val reactContext: ReactApplicat private fun createScreen(templateId: String): CarScreen? { val config = carTemplates[templateId]; - if (config != null) { + if (config != null && ::carContext.isInitialized) { val screen = CarScreen(carContext) screen.marker = templateId; From 05b69e9eeb6bc916b9f6f81a7111e46cae6efe82 Mon Sep 17 00:00:00 2001 From: blanck Date: Thu, 23 Nov 2023 07:52:35 +0100 Subject: [PATCH 14/19] fix listtemplate action button event for android --- .../src/main/java/org/birkir/carplay/utils/EventEmitter.kt | 6 ++++++ .../react-native-carplay/src/templates/ListTemplate.ts | 7 +++++++ .../src/templates/android/AndroidNavigationBaseTemplate.ts | 2 ++ 3 files changed, 15 insertions(+) diff --git a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/utils/EventEmitter.kt b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/utils/EventEmitter.kt index 586b3549..a06ba60f 100644 --- a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/utils/EventEmitter.kt +++ b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/utils/EventEmitter.kt @@ -97,6 +97,12 @@ class EventEmitter( }) } + fun actionButtonPressed(templateId: String?) { + emit(ActionButtonPressed, Arguments.createMap().apply { + templateId?.let { putString("templateId", templateId) } + }) + } + fun didSelectListItem(id: String, index: Int) { emit(DidSelectListItem, Arguments.createMap().apply { putString("id", id) diff --git a/packages/react-native-carplay/src/templates/ListTemplate.ts b/packages/react-native-carplay/src/templates/ListTemplate.ts index 1567dfa3..bba60686 100644 --- a/packages/react-native-carplay/src/templates/ListTemplate.ts +++ b/packages/react-native-carplay/src/templates/ListTemplate.ts @@ -57,6 +57,12 @@ export interface ListTemplateConfig extends TemplateConfig { */ onBackButtonPressed?(): void; + /** + * Fired when action button is pressed + * @namespace Android + */ + onButtonPressed?(): void; + /** * Option to hide back button * @default false @@ -110,6 +116,7 @@ export class ListTemplate extends Template { get eventMap() { return { backButtonPressed: 'onBackButtonPressed', + buttonPressed: 'onButtonPressed', }; } diff --git a/packages/react-native-carplay/src/templates/android/AndroidNavigationBaseTemplate.ts b/packages/react-native-carplay/src/templates/android/AndroidNavigationBaseTemplate.ts index 5d7b0755..bfda5d53 100644 --- a/packages/react-native-carplay/src/templates/android/AndroidNavigationBaseTemplate.ts +++ b/packages/react-native-carplay/src/templates/android/AndroidNavigationBaseTemplate.ts @@ -14,6 +14,7 @@ export interface AndroidNavigationBaseTemplateConfig extends TemplateConfig { onDidDismissPanningInterface?(): void; onItemSelect?(item: { index: number }): Promise; onBackButtonPressed?(): void; + onButtonPressed?(): void; } export class AndroidNavigationBaseTemplate< @@ -25,6 +26,7 @@ export class AndroidNavigationBaseTemplate< didDismissPanningInterface: 'onDidDismissPanningInterface', didSelectListItem: 'onItemSelect', backButtonPressed: 'onBackButtonPressed', + buttonPressed: 'onButtonPressed', }; } From 96b227bc5b88f87cd29abc2b150a4659495fdfb3 Mon Sep 17 00:00:00 2001 From: blanck Date: Thu, 23 Nov 2023 07:52:49 +0100 Subject: [PATCH 15/19] clean out manifest --- .../android/src/main/AndroidManifest.xml | 7 ------- .../android/src/main/AndroidManifestNew.xml | 8 -------- 2 files changed, 15 deletions(-) diff --git a/packages/react-native-carplay/android/src/main/AndroidManifest.xml b/packages/react-native-carplay/android/src/main/AndroidManifest.xml index 4b86f780..1d2b4cb4 100644 --- a/packages/react-native-carplay/android/src/main/AndroidManifest.xml +++ b/packages/react-native-carplay/android/src/main/AndroidManifest.xml @@ -10,13 +10,6 @@ - - - - - \ No newline at end of file diff --git a/packages/react-native-carplay/android/src/main/AndroidManifestNew.xml b/packages/react-native-carplay/android/src/main/AndroidManifestNew.xml index 8b59b619..1d2b4cb4 100644 --- a/packages/react-native-carplay/android/src/main/AndroidManifestNew.xml +++ b/packages/react-native-carplay/android/src/main/AndroidManifestNew.xml @@ -10,14 +10,6 @@ - - - - - - \ No newline at end of file From 7d9d4d1ddd04c2cbc2f951ec324ccd98132cb3ae Mon Sep 17 00:00:00 2001 From: blanck Date: Sun, 26 Nov 2023 20:55:30 +0100 Subject: [PATCH 16/19] fix android auto popToRootTemplate --- .../android/src/main/java/org/birkir/carplay/CarPlayModule.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt index 5cd6c27f..6ac957df 100644 --- a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt +++ b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlayModule.kt @@ -184,7 +184,7 @@ class CarPlayModule internal constructor(private val reactContext: ReactApplicat @ReactMethod fun popToRootTemplate(animated: Boolean?) { handler.post { - Log.d(TAG, "popToRootTemplate not supported") + screenManager?.popTo("root"); } } From a7adc8808583af7d8d71e9196443fb23470158d4 Mon Sep 17 00:00:00 2001 From: blanck Date: Sun, 26 Nov 2023 20:55:54 +0100 Subject: [PATCH 17/19] fix didDisconnect event for AA --- .../src/main/java/org/birkir/carplay/CarPlaySession.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlaySession.kt b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlaySession.kt index 2235853b..751bd2d7 100644 --- a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlaySession.kt +++ b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/CarPlaySession.kt @@ -22,6 +22,7 @@ import com.facebook.react.modules.appregistry.AppRegistry import com.facebook.react.modules.core.TimingModule import com.facebook.react.modules.debug.DevSettingsModule import org.birkir.carplay.screens.CarScreen +import org.birkir.carplay.utils.EventEmitter class CarPlaySession(private val reactInstanceManager: ReactInstanceManager) : Session(), DefaultLifecycleObserver { @@ -94,9 +95,9 @@ class CarPlaySession(private val reactInstanceManager: ReactInstanceManager) : S override fun onDestroy(owner: LifecycleOwner) { Log.i(TAG, "onDestroy") - val context = carContext - // stop services here, if any - } + var eventEmitter: EventEmitter? = EventEmitter(reactInstanceManager.currentReactContext!!) + eventEmitter?.didDisconnect() +} override fun onNewIntent(intent: Intent) { // handle intents From bcbbcc269c80a998fbdb976d5f134d48a04a8cfe Mon Sep 17 00:00:00 2001 From: blanck Date: Mon, 27 Nov 2023 17:35:21 +0100 Subject: [PATCH 18/19] remove manifest info to avoid rejection from play store --- .../react-native-carplay/android/src/main/AndroidManifest.xml | 2 -- .../android/src/main/AndroidManifestNew.xml | 2 -- 2 files changed, 4 deletions(-) diff --git a/packages/react-native-carplay/android/src/main/AndroidManifest.xml b/packages/react-native-carplay/android/src/main/AndroidManifest.xml index 1d2b4cb4..2e755b73 100644 --- a/packages/react-native-carplay/android/src/main/AndroidManifest.xml +++ b/packages/react-native-carplay/android/src/main/AndroidManifest.xml @@ -1,7 +1,5 @@ - - - - Date: Tue, 28 Nov 2023 02:39:46 +0100 Subject: [PATCH 19/19] fix PlaceListMapTemplate require surface --- .../src/main/java/org/birkir/carplay/screens/CarScreen.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/screens/CarScreen.kt b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/screens/CarScreen.kt index eaaa42f3..e2e979f3 100644 --- a/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/screens/CarScreen.kt +++ b/packages/react-native-carplay/android/src/main/java/org/birkir/carplay/screens/CarScreen.kt @@ -37,7 +37,6 @@ class CarScreen(carContext: CarContext) : Screen(carContext) { // allow MapTemplate, NavigationTemplate and PlaceListMapTemplate val isSurfaceTemplate = template is MapTemplate || template is NavigationTemplate - || template is PlaceListMapTemplate || template is PlaceListNavigationTemplate || template is RoutePreviewNavigationTemplate