Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed PointOfInterest template and added openUrl #153

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/example/ios/CarScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.birkir.carplay">

<uses-permission android:name="androidx.car.app.NAVIGATION_TEMPLATES" />
<uses-permission android:name="androidx.car.app.MAP_TEMPLATES" />
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application>
<service
android:name=".CarPlayService"
android:exported="true">
<intent-filter>
<action android:name="org.birkir.carplay.APP_RELOAD" />
</intent-filter>
<intent-filter>
<action android:name="androidx.car.app.CarAppService" />
<category android:name="androidx.car.app.category.NAVIGATION" />
</intent-filter>
<intent-filter>
<action android:name="androidx.car.app.action.NAVIGATE" />
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="geo" />
</intent-filter>
</service>
<meta-data
android:name="androidx.car.app.minCarApiLevel"
android:value="1" />
</application>
</manifest>
</manifest>
Original file line number Diff line number Diff line change
@@ -1,30 +1,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.birkir.carplay">

<uses-permission android:name="androidx.car.app.NAVIGATION_TEMPLATES" />
<uses-permission android:name="androidx.car.app.MAP_TEMPLATES" />
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application>
<service
android:name=".CarPlayService"
android:exported="true">
<intent-filter>
<action android:name="org.birkir.carplay.APP_RELOAD" />
</intent-filter>
<intent-filter>
<action android:name="androidx.car.app.CarAppService" />
<category android:name="androidx.car.app.category.NAVIGATION" />
</intent-filter>
<intent-filter>
<action android:name="androidx.car.app.action.NAVIGATE" />
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="geo" />
</intent-filter>
</service>
<meta-data
android:name="androidx.car.app.minCarApiLevel"
android:value="1" />
</application>
</manifest>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -71,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
Expand All @@ -94,7 +96,22 @@ class CarPlayModule internal constructor(private val reactContext: ReactApplicat

@ReactMethod
fun checkForConnection() {
eventEmitter?.didConnect()
if (::carContext.isInitialized){
eventEmitter?.didConnect()
}
}

@ReactMethod
fun openUrl(url: String) {
Log.d(TAG, "openUrl $url")
}

@ReactMethod
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(url))
carContext.startCarApp(intent)
}

@ReactMethod
Expand All @@ -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) {
Expand Down Expand Up @@ -163,6 +181,13 @@ class CarPlayModule internal constructor(private val reactContext: ReactApplicat
}
}

@ReactMethod
fun popToRootTemplate(animated: Boolean?) {
handler.post {
screenManager?.popTo("root");
}
}

@ReactMethod
fun popTemplate(animated: Boolean?) {
handler.post {
Expand Down Expand Up @@ -272,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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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())

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -59,7 +58,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.
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
13 changes: 0 additions & 13 deletions packages/react-native-carplay/ios/RCTConvert+RNCarPlay.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions packages/react-native-carplay/ios/RNCPStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native-carplay/ios/RNCarPlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<CPListSection*>*) parseSections:(NSArray*)sections;

Expand Down
Loading