@iternio/react-native-auto-play 0.0.4 → 0.0.5
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/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAutoPlay.kt +1 -9
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMapTemplate.kt +42 -22
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/AndroidAutoTemplate.kt +21 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/Parser.kt +58 -25
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/utils/BitmapCache.kt +60 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/utils/SymbolFont.kt +16 -31
- package/ios/hybrid/HybridMapTemplate.swift +25 -16
- package/lib/specs/MapTemplate.nitro.d.ts +5 -2
- package/lib/templates/MapTemplate.d.ts +4 -6
- package/lib/templates/MapTemplate.js +6 -0
- package/nitrogen/generated/android/ReactNativeAutoPlayOnLoad.cpp +0 -2
- package/nitrogen/generated/android/c++/JHybridMapTemplateSpec.cpp +27 -25
- package/nitrogen/generated/android/c++/JHybridMapTemplateSpec.hpp +3 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMapTemplateSpec.kt +9 -1
- package/nitrogen/generated/ios/ReactNativeAutoPlay-Swift-Cxx-Bridge.cpp +0 -8
- package/nitrogen/generated/ios/ReactNativeAutoPlay-Swift-Cxx-Bridge.hpp +0 -34
- package/nitrogen/generated/ios/ReactNativeAutoPlay-Swift-Cxx-Umbrella.hpp +0 -3
- package/nitrogen/generated/ios/c++/HybridMapTemplateSpecSwift.hpp +16 -9
- package/nitrogen/generated/ios/swift/HybridMapTemplateSpec.swift +3 -1
- package/nitrogen/generated/ios/swift/HybridMapTemplateSpec_cxx.swift +26 -5
- package/nitrogen/generated/shared/c++/HybridMapTemplateSpec.cpp +2 -0
- package/nitrogen/generated/shared/c++/HybridMapTemplateSpec.hpp +7 -5
- package/package.json +1 -1
- package/src/specs/MapTemplate.nitro.ts +9 -2
- package/src/templates/MapTemplate.ts +9 -5
- package/nitrogen/generated/android/c++/JFunc_void_AutoText_std__optional_AutoText_.hpp +0 -82
- package/nitrogen/generated/android/c++/JNavigationAlertCallbacks.hpp +0 -91
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_AutoText_std__optional_AutoText_.kt +0 -80
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NavigationAlertCallbacks.kt +0 -45
- package/nitrogen/generated/ios/swift/Func_void_AutoText_std__optional_AutoText_.swift +0 -47
- package/nitrogen/generated/ios/swift/NavigationAlertCallbacks.swift +0 -74
- package/nitrogen/generated/shared/c++/NavigationAlertCallbacks.hpp +0 -82
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAutoPlay.kt
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
package com.margelo.nitro.swe.iternio.reactnativeautoplay
|
|
2
2
|
|
|
3
|
-
import androidx.car.app.Screen
|
|
4
3
|
import com.facebook.react.bridge.UiThreadUtil
|
|
5
4
|
import com.margelo.nitro.core.Promise
|
|
6
5
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.template.AndroidAutoTemplate
|
|
@@ -138,15 +137,8 @@ class HybridAutoPlay : HybridAutoPlaySpec() {
|
|
|
138
137
|
?: throw IllegalArgumentException("pushTemplate failed, screenManager not found")
|
|
139
138
|
|
|
140
139
|
val result = ThreadUtil.postOnUiAndAwait {
|
|
141
|
-
|
|
140
|
+
val topMessageScreen = AndroidAutoTemplate.getTopMessageTemplate()
|
|
142
141
|
|
|
143
|
-
if (screenManager.screenStack.isNotEmpty()) {
|
|
144
|
-
screenManager.top.marker?.let {
|
|
145
|
-
if (AndroidAutoTemplate.hasTemplate<MessageTemplate>(it)) {
|
|
146
|
-
topMessageScreen = screenManager.top
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
142
|
val screen = AndroidAutoScreen(context, templateId, template.parse())
|
|
151
143
|
screenManager.push(screen)
|
|
152
144
|
|
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMapTemplate.kt
CHANGED
|
@@ -8,36 +8,50 @@ import com.margelo.nitro.swe.iternio.reactnativeautoplay.template.RoutePreviewTe
|
|
|
8
8
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.template.TripPreviewTemplate
|
|
9
9
|
|
|
10
10
|
class HybridMapTemplate : HybridMapTemplateSpec() {
|
|
11
|
+
var navigationAlert: NitroNavigationAlert? = null
|
|
12
|
+
|
|
11
13
|
override fun createMapTemplate(config: MapTemplateConfig) {
|
|
12
|
-
val context =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
)
|
|
14
|
+
val context = AndroidAutoSession.getCarContext(config.id) ?: throw IllegalArgumentException(
|
|
15
|
+
"createMapTemplate failed, carContext found"
|
|
16
|
+
)
|
|
16
17
|
|
|
17
18
|
val template = MapTemplate(context, config, initNavigationManager = true)
|
|
18
19
|
AndroidAutoTemplate.setTemplate(config.id, template)
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
override fun showNavigationAlert(
|
|
22
|
-
templateId: String,
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
templateId: String, alert: NitroNavigationAlert
|
|
24
|
+
) {
|
|
25
|
+
val alertConfig = alert.copy(onDidDismiss = { reason ->
|
|
26
|
+
navigationAlert = null
|
|
27
|
+
alert.onDidDismiss?.let { it(reason) }
|
|
28
|
+
})
|
|
25
29
|
val template = AndroidAutoTemplate.getTemplate<MapTemplate>(templateId)
|
|
26
|
-
template.showAlert(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
update = { title, subtitle ->
|
|
37
|
-
val config = alert.copy(title = title, subtitle = subtitle)
|
|
38
|
-
template.showAlert(config)
|
|
30
|
+
template.showAlert(alertConfig)
|
|
31
|
+
navigationAlert = alertConfig
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
override fun updateNavigationAlert(
|
|
35
|
+
templateId: String, navigationAlertId: Double, title: AutoText, subtitle: AutoText?
|
|
36
|
+
) {
|
|
37
|
+
navigationAlert?.let {
|
|
38
|
+
if (it.id != navigationAlertId) {
|
|
39
|
+
return
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
+
val navigationAlert = it.copy(title = title, subtitle = subtitle)
|
|
42
|
+
val template = AndroidAutoTemplate.getTemplate<MapTemplate>(templateId)
|
|
43
|
+
template.showAlert(navigationAlert)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
override fun dismissNavigationAlert(
|
|
48
|
+
templateId: String, navigationAlertId: Double
|
|
49
|
+
) {
|
|
50
|
+
val carContext = AndroidAutoSession.getCarContext(AndroidAutoSession.ROOT_SESSION)
|
|
51
|
+
?: throw IllegalArgumentException(
|
|
52
|
+
"dismissNavigationAlert failed, carContext found"
|
|
53
|
+
)
|
|
54
|
+
carContext.getCarService(AppManager::class.java).dismissAlert(navigationAlertId.toInt())
|
|
41
55
|
}
|
|
42
56
|
|
|
43
57
|
override fun showTripSelector(
|
|
@@ -67,8 +81,14 @@ class HybridMapTemplate : HybridMapTemplateSpec() {
|
|
|
67
81
|
)
|
|
68
82
|
|
|
69
83
|
UiThreadUtil.runOnUiThread {
|
|
70
|
-
|
|
84
|
+
val topMessageTemplate = AndroidAutoTemplate.getTopMessageTemplate()
|
|
85
|
+
|
|
71
86
|
screenManager.push(screen)
|
|
87
|
+
|
|
88
|
+
topMessageTemplate?.let {
|
|
89
|
+
// make sure any visible message template is still on top of the trip selector
|
|
90
|
+
screenManager.push(topMessageTemplate)
|
|
91
|
+
}
|
|
72
92
|
}
|
|
73
93
|
|
|
74
94
|
return TripSelectorCallback { id: String ->
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package com.margelo.nitro.swe.iternio.reactnativeautoplay.template
|
|
2
2
|
|
|
3
3
|
import androidx.car.app.CarContext
|
|
4
|
+
import androidx.car.app.Screen
|
|
4
5
|
import androidx.car.app.model.Template
|
|
5
6
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.AndroidAutoScreen
|
|
6
7
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.NitroAction
|
|
@@ -56,5 +57,25 @@ abstract class AndroidAutoTemplate<T>(val context: CarContext, var config: T) {
|
|
|
56
57
|
}
|
|
57
58
|
return null
|
|
58
59
|
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* returns the top screen hosting a MessageTemplate, null in case none is available
|
|
63
|
+
*/
|
|
64
|
+
fun getTopMessageTemplate(): Screen? {
|
|
65
|
+
val screenManager = AndroidAutoScreen.getScreenManager()
|
|
66
|
+
?: throw IllegalArgumentException("getMessageTemplate failed, screenManager not found")
|
|
67
|
+
|
|
68
|
+
var topMessageScreen: Screen? = null
|
|
69
|
+
|
|
70
|
+
if (screenManager.screenStack.isNotEmpty()) {
|
|
71
|
+
screenManager.top.marker?.let {
|
|
72
|
+
if (hasTemplate<MessageTemplate>(it)) {
|
|
73
|
+
topMessageScreen = screenManager.top
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return topMessageScreen
|
|
79
|
+
}
|
|
59
80
|
}
|
|
60
81
|
}
|
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/Parser.kt
CHANGED
|
@@ -35,7 +35,6 @@ import androidx.car.app.navigation.model.TravelEstimate
|
|
|
35
35
|
import androidx.core.graphics.createBitmap
|
|
36
36
|
import androidx.core.graphics.drawable.IconCompat
|
|
37
37
|
import androidx.core.graphics.drawable.toBitmap
|
|
38
|
-
import com.facebook.common.references.CloseableReference
|
|
39
38
|
import com.facebook.datasource.DataSources
|
|
40
39
|
import com.facebook.drawee.backends.pipeline.Fresco
|
|
41
40
|
import com.facebook.imagepipeline.image.CloseableBitmap
|
|
@@ -71,7 +70,9 @@ import com.margelo.nitro.swe.iternio.reactnativeautoplay.TrafficSide
|
|
|
71
70
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.TravelEstimates
|
|
72
71
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.TurnType
|
|
73
72
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.Variant_GlyphImage_AssetImage
|
|
73
|
+
import com.margelo.nitro.swe.iternio.reactnativeautoplay.utils.BitmapCache
|
|
74
74
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.utils.SymbolFont
|
|
75
|
+
import com.margelo.nitro.swe.iternio.reactnativeautoplay.utils.get
|
|
75
76
|
import java.text.SimpleDateFormat
|
|
76
77
|
import java.util.Calendar
|
|
77
78
|
import java.util.Locale
|
|
@@ -238,7 +239,30 @@ object Parser {
|
|
|
238
239
|
}
|
|
239
240
|
|
|
240
241
|
fun parseImages(context: CarContext, images: List<NitroImage>): CarIcon {
|
|
241
|
-
return CarIcon.Builder(
|
|
242
|
+
return CarIcon.Builder(imageFromNitroImages(context, images)).build()
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
fun imageFromNitroImages(
|
|
246
|
+
context: CarContext, images: List<NitroImage>
|
|
247
|
+
): IconCompat {
|
|
248
|
+
val bitmaps = images.map {
|
|
249
|
+
parseImageToBitmap(
|
|
250
|
+
context, it.asFirstOrNull(), it.asSecondOrNull()
|
|
251
|
+
)!!
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
val height = bitmaps.maxOf { it.height }
|
|
255
|
+
val width = bitmaps.maxOf { it.width }
|
|
256
|
+
val totalWidth = width * images.size
|
|
257
|
+
|
|
258
|
+
val bitmap = createBitmap(totalWidth, height)
|
|
259
|
+
val canvas = Canvas(bitmap)
|
|
260
|
+
|
|
261
|
+
bitmaps.forEachIndexed { index, it ->
|
|
262
|
+
canvas.drawBitmap(it, (index * width).toFloat(), 0f, null)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return IconCompat.createWithBitmap(bitmap)
|
|
242
266
|
}
|
|
243
267
|
|
|
244
268
|
const val PLACEHOLDER_DISTANCE = "{distance}"
|
|
@@ -481,47 +505,55 @@ object Parser {
|
|
|
481
505
|
)
|
|
482
506
|
}
|
|
483
507
|
|
|
484
|
-
fun parseAssetImage(context: CarContext,
|
|
485
|
-
|
|
486
|
-
|
|
508
|
+
fun parseAssetImage(context: CarContext, assetImage: AssetImage): Bitmap? {
|
|
509
|
+
var bitmap = BitmapCache.get(context, assetImage)
|
|
510
|
+
|
|
511
|
+
if (bitmap != null) {
|
|
512
|
+
return bitmap
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
val source = ImageSource(context, assetImage.uri)
|
|
516
|
+
val imageRequest = ImageRequestBuilder.newBuilderWithSource(source.uri).disableDiskCache()
|
|
517
|
+
.disableMemoryCache().build()
|
|
518
|
+
|
|
487
519
|
val dataSource = Fresco.getImagePipeline().fetchDecodedImage(imageRequest, context)
|
|
488
520
|
val result = DataSources.waitForFinalResult(dataSource)
|
|
489
521
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
bitmap = drawable?.toBitmap(
|
|
500
|
-
width = image.width, height = image.height, Bitmap.Config.ARGB_8888
|
|
501
|
-
)
|
|
502
|
-
}
|
|
503
|
-
} finally {
|
|
504
|
-
CloseableReference.closeSafely(closeableRef)
|
|
522
|
+
val image = result?.get()
|
|
523
|
+
try {
|
|
524
|
+
if (image is CloseableBitmap) {
|
|
525
|
+
bitmap = image.underlyingBitmap.copy(Bitmap.Config.ARGB_8888, false)
|
|
526
|
+
} else if (image is CloseableXml) {
|
|
527
|
+
val drawable = image.buildDrawable()
|
|
528
|
+
bitmap = drawable?.toBitmap(
|
|
529
|
+
width = image.width, height = image.height, Bitmap.Config.ARGB_8888
|
|
530
|
+
)
|
|
505
531
|
}
|
|
532
|
+
} finally {
|
|
533
|
+
image?.close()
|
|
534
|
+
result?.close()
|
|
535
|
+
dataSource.close()
|
|
506
536
|
}
|
|
507
537
|
|
|
508
538
|
if (bitmap == null) {
|
|
509
539
|
return null
|
|
510
540
|
}
|
|
511
541
|
|
|
512
|
-
|
|
513
|
-
val tintColor =
|
|
514
|
-
if (context.isDarkMode) image.color.darkColor else image.color.lightColor
|
|
542
|
+
assetImage.color?.get(context)?.let { color ->
|
|
515
543
|
val result = createBitmap(bitmap.width, bitmap.height)
|
|
516
544
|
val canvas = Canvas(result)
|
|
517
545
|
val paint = Paint()
|
|
518
546
|
|
|
519
|
-
paint.colorFilter = PorterDuffColorFilter(
|
|
547
|
+
paint.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
|
|
520
548
|
canvas.drawBitmap(bitmap, 0f, 0f, paint)
|
|
521
549
|
|
|
550
|
+
BitmapCache.put(context, assetImage, result)
|
|
551
|
+
|
|
522
552
|
return result
|
|
523
553
|
}
|
|
524
554
|
|
|
555
|
+
BitmapCache.put(context, assetImage, bitmap)
|
|
556
|
+
|
|
525
557
|
return bitmap
|
|
526
558
|
}
|
|
527
559
|
|
|
@@ -622,7 +654,8 @@ object Parser {
|
|
|
622
654
|
setRoundaboutExitNumber(it.toInt())
|
|
623
655
|
}
|
|
624
656
|
nitroManeuver.angle?.let { roundaboutExitAngle ->
|
|
625
|
-
val angle =
|
|
657
|
+
val angle =
|
|
658
|
+
((180 - roundaboutExitAngle) % 360).toInt().let { if (it == 0) 360 else it }
|
|
626
659
|
setRoundaboutExitAngle(angle)
|
|
627
660
|
}
|
|
628
661
|
}
|
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/utils/BitmapCache.kt
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
package com.margelo.nitro.swe.iternio.reactnativeautoplay.utils
|
|
2
|
+
|
|
3
|
+
import android.graphics.Bitmap
|
|
4
|
+
import android.util.LruCache
|
|
5
|
+
import androidx.car.app.CarContext
|
|
6
|
+
import com.margelo.nitro.swe.iternio.reactnativeautoplay.AssetImage
|
|
7
|
+
import com.margelo.nitro.swe.iternio.reactnativeautoplay.GlyphImage
|
|
8
|
+
import com.margelo.nitro.swe.iternio.reactnativeautoplay.NitroColor
|
|
9
|
+
|
|
10
|
+
object BitmapCache {
|
|
11
|
+
private val maxMemory = Runtime.getRuntime().maxMemory().toInt()
|
|
12
|
+
private val cacheSize = minOf(maxMemory / 8, 8388608) //limit cache to 8 megabyte
|
|
13
|
+
|
|
14
|
+
private val bitmapCache = object : LruCache<String, Bitmap>(cacheSize) {
|
|
15
|
+
override fun sizeOf(key: String, bitmap: Bitmap): Int {
|
|
16
|
+
return bitmap.byteCount
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
fun get(context: CarContext, image: GlyphImage): Bitmap? {
|
|
21
|
+
val key = image.cacheKey(context)
|
|
22
|
+
return get(key)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
fun put(context: CarContext, image: GlyphImage, bitmap: Bitmap) {
|
|
26
|
+
val key = image.cacheKey(context)
|
|
27
|
+
put(key, bitmap)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
fun get(context: CarContext, image: AssetImage): Bitmap? {
|
|
31
|
+
val key = image.cacheKey(context)
|
|
32
|
+
return get(key)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
fun put(context: CarContext, image: AssetImage, bitmap: Bitmap) {
|
|
36
|
+
val key = image.cacheKey(context)
|
|
37
|
+
put(key, bitmap)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private fun get(key: String): Bitmap? {
|
|
41
|
+
synchronized(bitmapCache) {
|
|
42
|
+
return bitmapCache.get(key)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private fun put(key: String, bitmap: Bitmap) {
|
|
47
|
+
synchronized(bitmapCache) {
|
|
48
|
+
bitmapCache.put(key, bitmap)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
fun NitroColor.get(context: CarContext): Int =
|
|
54
|
+
if (context.isDarkMode) this.darkColor.toInt() else this.lightColor.toInt()
|
|
55
|
+
|
|
56
|
+
fun AssetImage.cacheKey(context: CarContext): String =
|
|
57
|
+
this.color?.let { "${this.uri}/${it.get(context)}" } ?: run { this.uri }
|
|
58
|
+
|
|
59
|
+
fun GlyphImage.cacheKey(context: CarContext): String =
|
|
60
|
+
"$glyph/${color.get(context)}/${backgroundColor.get(context)}/$fontScale"
|
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/utils/SymbolFont.kt
CHANGED
|
@@ -22,7 +22,7 @@ object SymbolFont {
|
|
|
22
22
|
|
|
23
23
|
private var typeface: Typeface? = null
|
|
24
24
|
|
|
25
|
-
fun loadFont(context: Context) {
|
|
25
|
+
private fun loadFont(context: Context) {
|
|
26
26
|
if (typeface != null) {
|
|
27
27
|
return
|
|
28
28
|
}
|
|
@@ -30,12 +30,12 @@ object SymbolFont {
|
|
|
30
30
|
typeface = ResourcesCompat.getFont(context, R.font.materialsymbolsoutlined_regular)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
fun imageFromGlyph(
|
|
33
|
+
private fun imageFromGlyph(
|
|
34
34
|
context: Context,
|
|
35
35
|
glyph: Double,
|
|
36
|
-
color: Int
|
|
37
|
-
backgroundColor: Int
|
|
38
|
-
cornerRadius: Float = 8f,
|
|
36
|
+
color: Int,
|
|
37
|
+
backgroundColor: Int,
|
|
38
|
+
cornerRadius: Float = 8f, //TODO: make accessible and add it to GlyphImage.cacheKey
|
|
39
39
|
fontScale: Float,
|
|
40
40
|
): Bitmap? {
|
|
41
41
|
loadFont(context)
|
|
@@ -88,39 +88,24 @@ object SymbolFont {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
fun imageFromNitroImage(context: CarContext, image: GlyphImage): Bitmap? {
|
|
91
|
-
|
|
92
|
-
val backgroundColor =
|
|
93
|
-
if (context.isDarkMode) image.backgroundColor.darkColor else image.backgroundColor.lightColor
|
|
91
|
+
var bitmap = BitmapCache.get(context, image)
|
|
94
92
|
|
|
95
|
-
|
|
93
|
+
if (bitmap != null) {
|
|
94
|
+
return bitmap
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
bitmap = imageFromGlyph(
|
|
96
98
|
context = context,
|
|
97
99
|
glyph = image.glyph,
|
|
98
|
-
color = color.
|
|
99
|
-
backgroundColor = backgroundColor.
|
|
100
|
+
color = image.color.get(context),
|
|
101
|
+
backgroundColor = image.backgroundColor.get(context),
|
|
100
102
|
fontScale = (image.fontScale ?: 1.0).toFloat()
|
|
101
103
|
)
|
|
102
|
-
}
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
): IconCompat {
|
|
107
|
-
val bitmaps = images.map {
|
|
108
|
-
Parser.parseImageToBitmap(
|
|
109
|
-
context, it.asFirstOrNull(), it.asSecondOrNull()
|
|
110
|
-
)!!
|
|
105
|
+
bitmap?.let {
|
|
106
|
+
BitmapCache.put(context, image, it)
|
|
111
107
|
}
|
|
112
108
|
|
|
113
|
-
|
|
114
|
-
val width = bitmaps.maxOf { it.width }
|
|
115
|
-
val totalWidth = width * images.size
|
|
116
|
-
|
|
117
|
-
val bitmap = createBitmap(totalWidth, height)
|
|
118
|
-
val canvas = Canvas(bitmap)
|
|
119
|
-
|
|
120
|
-
bitmaps.forEachIndexed { index, it ->
|
|
121
|
-
canvas.drawBitmap(it, (index * width).toFloat(), 0f, null)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return IconCompat.createWithBitmap(bitmap)
|
|
109
|
+
return bitmap
|
|
125
110
|
}
|
|
126
111
|
}
|
|
@@ -30,28 +30,37 @@ class HybridMapTemplate: HybridMapTemplateSpec {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
func showNavigationAlert(templateId: String, alert: NitroNavigationAlert)
|
|
33
|
-
throws
|
|
33
|
+
throws
|
|
34
34
|
{
|
|
35
|
-
var mapTemplate: MapTemplate?
|
|
36
|
-
|
|
37
35
|
try RootModule.withAutoPlayTemplate(templateId: templateId) {
|
|
38
36
|
(template: MapTemplate) in
|
|
39
37
|
template.showAlert(alertConfig: alert)
|
|
40
|
-
mapTemplate = template
|
|
41
38
|
}
|
|
39
|
+
}
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
41
|
+
func updateNavigationAlert(
|
|
42
|
+
templateId: String,
|
|
43
|
+
navigationAlertId: Double,
|
|
44
|
+
title: AutoText,
|
|
45
|
+
subtitle: AutoText?
|
|
46
|
+
) throws {
|
|
47
|
+
try RootModule.withAutoPlayTemplate(templateId: templateId) {
|
|
48
|
+
(template: MapTemplate) in
|
|
49
|
+
template.updateNavigationAlert(
|
|
50
|
+
alertId: navigationAlertId,
|
|
51
|
+
title: title,
|
|
52
|
+
subtitle: subtitle
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
func dismissNavigationAlert(templateId: String, navigationAlertId: Double)
|
|
58
|
+
throws
|
|
59
|
+
{
|
|
60
|
+
try RootModule.withAutoPlayTemplate(templateId: templateId) {
|
|
61
|
+
(template: MapTemplate) in
|
|
62
|
+
template.dismissNavigationAlert(alertId: navigationAlertId)
|
|
63
|
+
}
|
|
55
64
|
}
|
|
56
65
|
|
|
57
66
|
func showTripSelector(
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
-
import type {
|
|
2
|
+
import type { NitroMapTemplateConfig, TripSelectorCallback, VisibleTravelEstimate } from '../templates/MapTemplate';
|
|
3
|
+
import type { AutoText } from '../types/Text';
|
|
3
4
|
import type { TripConfig, TripPoint, TripPreviewTextConfiguration, TripsConfig } from '../types/Trip';
|
|
4
5
|
import type { NitroNavigationAlert } from '../utils/NitroAlert';
|
|
5
6
|
import type { NitroManeuver } from '../utils/NitroManeuver';
|
|
@@ -12,7 +13,9 @@ export interface MapTemplate extends HybridObject<{
|
|
|
12
13
|
ios: 'swift';
|
|
13
14
|
}> {
|
|
14
15
|
createMapTemplate(config: MapTemplateConfig): void;
|
|
15
|
-
showNavigationAlert(templateId: string, alert: NitroNavigationAlert):
|
|
16
|
+
showNavigationAlert(templateId: string, alert: NitroNavigationAlert): void;
|
|
17
|
+
updateNavigationAlert(templateId: string, navigationAlertId: number, title: AutoText, subtitle?: AutoText): void;
|
|
18
|
+
dismissNavigationAlert(templateId: string, navigationAlertId: number): void;
|
|
16
19
|
showTripSelector(templateId: string, trips: Array<TripsConfig>, selectedTripId: string | undefined, textConfig: TripPreviewTextConfiguration, onTripSelected: (tripId: string, routeId: string) => void, onTripStarted: (tripId: string, routeId: string) => void, onBackPressed: () => void, mapButtons: Array<NitroMapButton>): TripSelectorCallback;
|
|
17
20
|
hideTripSelector(templateId: string): void;
|
|
18
21
|
setTemplateMapButtons(templateId: string, buttons?: Array<NitroMapButton>): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { type AutoText
|
|
2
|
+
import { type AutoText } from '..';
|
|
3
3
|
import type { ActionButtonAndroid, MapButton, MapPanButton } from '../types/Button';
|
|
4
4
|
import type { AutoManeuver } from '../types/Maneuver';
|
|
5
5
|
import type { ColorScheme, RootComponentInitialProps } from '../types/RootComponent';
|
|
@@ -16,10 +16,6 @@ export type VisibleTravelEstimate = 'first' | 'last';
|
|
|
16
16
|
export type HeaderActionsAndroidMap<T> = Array<ActionButtonAndroid<T>> & {
|
|
17
17
|
length: 1 | 2 | 3 | 4;
|
|
18
18
|
};
|
|
19
|
-
export interface NavigationAlertCallbacks {
|
|
20
|
-
dismiss: CleanupCallback;
|
|
21
|
-
update: (title: AutoText, subtitle?: AutoText) => void;
|
|
22
|
-
}
|
|
23
19
|
export interface NitroMapTemplateConfig extends TemplateConfig, NitroBaseMapTemplateConfig {
|
|
24
20
|
/**
|
|
25
21
|
* show either the next or final step travel estimates, defaults to final step so last
|
|
@@ -112,7 +108,9 @@ export declare class MapTemplate extends Template<MapTemplateConfig, MapTemplate
|
|
|
112
108
|
* ⚠️ updating an existing alert is currently broken on Android Automotive, it brings up a new alert for each call
|
|
113
109
|
* @returns a callback to dismiss or update the navigation alert
|
|
114
110
|
*/
|
|
115
|
-
showAlert(alert: NavigationAlert):
|
|
111
|
+
showAlert(alert: NavigationAlert): void;
|
|
112
|
+
updateAlert(alertId: number, title: AutoText, subtitle?: AutoText): void;
|
|
113
|
+
dismissAlert(alertId: number): void;
|
|
116
114
|
/**
|
|
117
115
|
* @namespace Android brings up a custom trip selector mimicking the CarPlay trip selector as close as possible
|
|
118
116
|
* @namespace iOS brings up the stock CarPlay trip selector
|
|
@@ -51,6 +51,12 @@ export class MapTemplate extends Template {
|
|
|
51
51
|
showAlert(alert) {
|
|
52
52
|
return HybridMapTemplate.showNavigationAlert(this.id, NitroAlertUtil.convert(alert));
|
|
53
53
|
}
|
|
54
|
+
updateAlert(alertId, title, subtitle) {
|
|
55
|
+
HybridMapTemplate.updateNavigationAlert(this.id, alertId, title, subtitle);
|
|
56
|
+
}
|
|
57
|
+
dismissAlert(alertId) {
|
|
58
|
+
HybridMapTemplate.dismissNavigationAlert(this.id, alertId);
|
|
59
|
+
}
|
|
54
60
|
/**
|
|
55
61
|
* @namespace Android brings up a custom trip selector mimicking the CarPlay trip selector as close as possible
|
|
56
62
|
* @namespace iOS brings up the stock CarPlay trip selector
|
|
@@ -32,7 +32,6 @@
|
|
|
32
32
|
#include "JHybridInformationTemplateSpec.hpp"
|
|
33
33
|
#include "JHybridListTemplateSpec.hpp"
|
|
34
34
|
#include "JHybridMapTemplateSpec.hpp"
|
|
35
|
-
#include "JFunc_void_AutoText_std__optional_AutoText_.hpp"
|
|
36
35
|
#include "JFunc_void_Point_std__optional_Point_.hpp"
|
|
37
36
|
#include "JFunc_void_Point_double.hpp"
|
|
38
37
|
#include "JFunc_void_Point.hpp"
|
|
@@ -69,7 +68,6 @@ int initialize(JavaVM* vm) {
|
|
|
69
68
|
margelo::nitro::swe::iternio::reactnativeautoplay::JHybridInformationTemplateSpec::registerNatives();
|
|
70
69
|
margelo::nitro::swe::iternio::reactnativeautoplay::JHybridListTemplateSpec::registerNatives();
|
|
71
70
|
margelo::nitro::swe::iternio::reactnativeautoplay::JHybridMapTemplateSpec::registerNatives();
|
|
72
|
-
margelo::nitro::swe::iternio::reactnativeautoplay::JFunc_void_AutoText_std__optional_AutoText__cxx::registerNatives();
|
|
73
71
|
margelo::nitro::swe::iternio::reactnativeautoplay::JFunc_void_Point_std__optional_Point__cxx::registerNatives();
|
|
74
72
|
margelo::nitro::swe::iternio::reactnativeautoplay::JFunc_void_Point_double_cxx::registerNatives();
|
|
75
73
|
margelo::nitro::swe::iternio::reactnativeautoplay::JFunc_void_Point_cxx::registerNatives();
|
|
@@ -7,14 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
#include "JHybridMapTemplateSpec.hpp"
|
|
9
9
|
|
|
10
|
-
// Forward declaration of `NavigationAlertCallbacks` to properly resolve imports.
|
|
11
|
-
namespace margelo::nitro::swe::iternio::reactnativeautoplay { struct NavigationAlertCallbacks; }
|
|
12
|
-
// Forward declaration of `AutoText` to properly resolve imports.
|
|
13
|
-
namespace margelo::nitro::swe::iternio::reactnativeautoplay { struct AutoText; }
|
|
14
|
-
// Forward declaration of `Distance` to properly resolve imports.
|
|
15
|
-
namespace margelo::nitro::swe::iternio::reactnativeautoplay { struct Distance; }
|
|
16
|
-
// Forward declaration of `DistanceUnits` to properly resolve imports.
|
|
17
|
-
namespace margelo::nitro::swe::iternio::reactnativeautoplay { enum class DistanceUnits; }
|
|
18
10
|
// Forward declaration of `TripSelectorCallback` to properly resolve imports.
|
|
19
11
|
namespace margelo::nitro::swe::iternio::reactnativeautoplay { struct TripSelectorCallback; }
|
|
20
12
|
// Forward declaration of `MapTemplateConfig` to properly resolve imports.
|
|
@@ -45,6 +37,12 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay { enum class NitroAl
|
|
|
45
37
|
namespace margelo::nitro::swe::iternio::reactnativeautoplay { enum class NitroButtonStyle; }
|
|
46
38
|
// Forward declaration of `NitroNavigationAlert` to properly resolve imports.
|
|
47
39
|
namespace margelo::nitro::swe::iternio::reactnativeautoplay { struct NitroNavigationAlert; }
|
|
40
|
+
// Forward declaration of `AutoText` to properly resolve imports.
|
|
41
|
+
namespace margelo::nitro::swe::iternio::reactnativeautoplay { struct AutoText; }
|
|
42
|
+
// Forward declaration of `Distance` to properly resolve imports.
|
|
43
|
+
namespace margelo::nitro::swe::iternio::reactnativeautoplay { struct Distance; }
|
|
44
|
+
// Forward declaration of `DistanceUnits` to properly resolve imports.
|
|
45
|
+
namespace margelo::nitro::swe::iternio::reactnativeautoplay { enum class DistanceUnits; }
|
|
48
46
|
// Forward declaration of `NavigationAlertAction` to properly resolve imports.
|
|
49
47
|
namespace margelo::nitro::swe::iternio::reactnativeautoplay { struct NavigationAlertAction; }
|
|
50
48
|
// Forward declaration of `AlertActionStyle` to properly resolve imports.
|
|
@@ -94,25 +92,16 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay { enum class Maneuve
|
|
|
94
92
|
// Forward declaration of `TripConfig` to properly resolve imports.
|
|
95
93
|
namespace margelo::nitro::swe::iternio::reactnativeautoplay { struct TripConfig; }
|
|
96
94
|
|
|
97
|
-
#include "NavigationAlertCallbacks.hpp"
|
|
98
|
-
#include "JNavigationAlertCallbacks.hpp"
|
|
99
|
-
#include <functional>
|
|
100
|
-
#include "JFunc_void.hpp"
|
|
101
|
-
#include "AutoText.hpp"
|
|
102
|
-
#include <optional>
|
|
103
|
-
#include "JFunc_void_AutoText_std__optional_AutoText_.hpp"
|
|
104
|
-
#include "JAutoText.hpp"
|
|
105
|
-
#include <string>
|
|
106
|
-
#include "Distance.hpp"
|
|
107
|
-
#include "JDistance.hpp"
|
|
108
|
-
#include "DistanceUnits.hpp"
|
|
109
|
-
#include "JDistanceUnits.hpp"
|
|
110
95
|
#include "TripSelectorCallback.hpp"
|
|
111
96
|
#include "JTripSelectorCallback.hpp"
|
|
97
|
+
#include <string>
|
|
98
|
+
#include <functional>
|
|
112
99
|
#include "JFunc_void_std__string.hpp"
|
|
113
100
|
#include "MapTemplateConfig.hpp"
|
|
114
101
|
#include "JMapTemplateConfig.hpp"
|
|
102
|
+
#include <optional>
|
|
115
103
|
#include "JFunc_void_std__optional_bool_.hpp"
|
|
104
|
+
#include "JFunc_void.hpp"
|
|
116
105
|
#include "VisibleTravelEstimate.hpp"
|
|
117
106
|
#include "JVisibleTravelEstimate.hpp"
|
|
118
107
|
#include "Point.hpp"
|
|
@@ -148,6 +137,12 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay { struct TripConfig;
|
|
|
148
137
|
#include "JFunc_void_bool.hpp"
|
|
149
138
|
#include "NitroNavigationAlert.hpp"
|
|
150
139
|
#include "JNitroNavigationAlert.hpp"
|
|
140
|
+
#include "AutoText.hpp"
|
|
141
|
+
#include "JAutoText.hpp"
|
|
142
|
+
#include "Distance.hpp"
|
|
143
|
+
#include "JDistance.hpp"
|
|
144
|
+
#include "DistanceUnits.hpp"
|
|
145
|
+
#include "JDistanceUnits.hpp"
|
|
151
146
|
#include "NavigationAlertAction.hpp"
|
|
152
147
|
#include "JNavigationAlertAction.hpp"
|
|
153
148
|
#include "AlertActionStyle.hpp"
|
|
@@ -237,10 +232,17 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
237
232
|
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JMapTemplateConfig> /* config */)>("createMapTemplate");
|
|
238
233
|
method(_javaPart, JMapTemplateConfig::fromCpp(config));
|
|
239
234
|
}
|
|
240
|
-
|
|
241
|
-
static const auto method = javaClassStatic()->getMethod<
|
|
242
|
-
|
|
243
|
-
|
|
235
|
+
void JHybridMapTemplateSpec::showNavigationAlert(const std::string& templateId, const NitroNavigationAlert& alert) {
|
|
236
|
+
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* templateId */, jni::alias_ref<JNitroNavigationAlert> /* alert */)>("showNavigationAlert");
|
|
237
|
+
method(_javaPart, jni::make_jstring(templateId), JNitroNavigationAlert::fromCpp(alert));
|
|
238
|
+
}
|
|
239
|
+
void JHybridMapTemplateSpec::updateNavigationAlert(const std::string& templateId, double navigationAlertId, const AutoText& title, const std::optional<AutoText>& subtitle) {
|
|
240
|
+
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* templateId */, double /* navigationAlertId */, jni::alias_ref<JAutoText> /* title */, jni::alias_ref<JAutoText> /* subtitle */)>("updateNavigationAlert");
|
|
241
|
+
method(_javaPart, jni::make_jstring(templateId), navigationAlertId, JAutoText::fromCpp(title), subtitle.has_value() ? JAutoText::fromCpp(subtitle.value()) : nullptr);
|
|
242
|
+
}
|
|
243
|
+
void JHybridMapTemplateSpec::dismissNavigationAlert(const std::string& templateId, double navigationAlertId) {
|
|
244
|
+
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* templateId */, double /* navigationAlertId */)>("dismissNavigationAlert");
|
|
245
|
+
method(_javaPart, jni::make_jstring(templateId), navigationAlertId);
|
|
244
246
|
}
|
|
245
247
|
TripSelectorCallback JHybridMapTemplateSpec::showTripSelector(const std::string& templateId, const std::vector<TripsConfig>& trips, const std::optional<std::string>& selectedTripId, const TripPreviewTextConfiguration& textConfig, const std::function<void(const std::string& /* tripId */, const std::string& /* routeId */)>& onTripSelected, const std::function<void(const std::string& /* tripId */, const std::string& /* routeId */)>& onTripStarted, const std::function<void()>& onBackPressed, const std::vector<NitroMapButton>& mapButtons) {
|
|
246
248
|
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JTripSelectorCallback>(jni::alias_ref<jni::JString> /* templateId */, jni::alias_ref<jni::JArrayClass<JTripsConfig>> /* trips */, jni::alias_ref<jni::JString> /* selectedTripId */, jni::alias_ref<JTripPreviewTextConfiguration> /* textConfig */, jni::alias_ref<JFunc_void_std__string_std__string::javaobject> /* onTripSelected */, jni::alias_ref<JFunc_void_std__string_std__string::javaobject> /* onTripStarted */, jni::alias_ref<JFunc_void::javaobject> /* onBackPressed */, jni::alias_ref<jni::JArrayClass<JNitroMapButton>> /* mapButtons */)>("showTripSelector_cxx");
|