@iternio/react-native-auto-play 0.5.14-beta.1 → 0.6.1
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/README.md +270 -36
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/AndroidAutoSession.kt +5 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMapTemplate.kt +9 -2
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/NativeBackdrop.kt +40 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/VirtualRenderer.kt +52 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/GridTemplate.kt +47 -13
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/Parser.kt +69 -15
- package/ios/Types.swift +3 -0
- package/ios/extensions/UIImage+Toggle.swift +5 -2
- package/ios/hybrid/HybridAutoPlay.swift +28 -16
- package/ios/hybrid/HybridMapTemplate.swift +22 -5
- package/ios/scenes/AutoPlayInterfaceController.swift +261 -72
- package/ios/templates/AutoPlayMapPanelDelegate.swift +190 -0
- package/ios/templates/AutoPlayTemplate.swift +24 -2
- package/ios/templates/GridTemplate.swift +57 -57
- package/ios/templates/InformationTemplate.swift +84 -9
- package/ios/templates/ListTemplate.swift +66 -11
- package/ios/templates/MapTemplate.swift +83 -68
- package/ios/templates/MessageTemplate.swift +72 -6
- package/ios/templates/Parser.swift +564 -69
- package/ios/templates/SearchTemplate.swift +1 -1
- package/ios/templates/TemplateStore.swift +5 -15
- package/ios/utils/SymbolFont.swift +13 -28
- package/jest.js +2 -0
- package/lib/Constants.d.ts +4 -0
- package/lib/Constants.js +6 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.web.d.ts +73 -0
- package/lib/index.web.js +72 -1
- package/lib/specs/MapTemplate.nitro.d.ts +3 -1
- package/lib/templates/GridTemplate.d.ts +23 -3
- package/lib/templates/GridTemplate.js +8 -0
- package/lib/templates/InformationTemplate.d.ts +38 -12
- package/lib/templates/ListTemplate.d.ts +16 -47
- package/lib/templates/MapTemplate.d.ts +26 -2
- package/lib/templates/MapTemplate.js +16 -2
- package/lib/templates/MessageTemplate.d.ts +52 -11
- package/lib/templates/MessageTemplate.js +1 -1
- package/lib/types/Image.d.ts +6 -1
- package/lib/utils/NitroColor.d.ts +1 -0
- package/lib/utils/NitroColor.js +8 -0
- package/lib/utils/NitroImage.js +1 -1
- package/lib/utils/NitroManeuver.js +1 -3
- package/lib/utils/NitroOptionsPanel.d.ts +103 -0
- package/lib/utils/NitroOptionsPanel.js +63 -0
- package/lib/utils/NitroSection.d.ts +89 -2
- package/lib/utils/NitroSection.js +49 -2
- package/lib-cjs/AutoPlayHeadlessJsTask.js +16 -0
- package/lib-cjs/Constants.js +9 -0
- package/lib-cjs/components/MapTemplateContext.js +10 -0
- package/lib-cjs/components/SafeAreaInsetsContext.js +21 -0
- package/lib-cjs/components/SafeAreaView.js +22 -0
- package/lib-cjs/components/WindowInformationWrapper.js +20 -0
- package/lib-cjs/hooks/useAndroidAutoTelemetry.js +115 -0
- package/lib-cjs/hooks/useFocusedEffect.js +35 -0
- package/lib-cjs/hooks/useMapTemplate.js +13 -0
- package/lib-cjs/hooks/useSafeAreaInsets.js +9 -0
- package/lib-cjs/hooks/useVoiceInput.js +42 -0
- package/lib-cjs/hybrid/HybridAndroidAutoTelemetry.js +4 -0
- package/lib-cjs/hybrid/HybridAndroidWindowInformation.js +4 -0
- package/lib-cjs/hybrid/HybridAutoPlay.js +5 -0
- package/lib-cjs/hybrid/HybridVoice.js +61 -0
- package/lib-cjs/index.js +76 -0
- package/lib-cjs/index.web.js +98 -0
- package/lib-cjs/scenes/AutoPlayCluster.js +140 -0
- package/lib-cjs/scenes/CarPlayDashboardScene.js +100 -0
- package/lib-cjs/specs/AndroidAutoTelemetry.nitro.js +2 -0
- package/lib-cjs/specs/AndroidAutomotive.nitro.js +16 -0
- package/lib-cjs/specs/AndroidWindowInformation.nitro.js +2 -0
- package/lib-cjs/specs/AutoPlay.nitro.js +2 -0
- package/lib-cjs/specs/CarPlayDashboard.nitro.js +2 -0
- package/lib-cjs/specs/Cluster.nitro.js +2 -0
- package/lib-cjs/specs/GridTemplate.nitro.js +2 -0
- package/lib-cjs/specs/InformationTemplate.nitro.js +2 -0
- package/lib-cjs/specs/ListTemplate.nitro.js +2 -0
- package/lib-cjs/specs/MapTemplate.nitro.js +2 -0
- package/lib-cjs/specs/MessageTemplate.nitro.js +2 -0
- package/lib-cjs/specs/SearchTemplate.nitro.js +2 -0
- package/lib-cjs/specs/SignInTemplate.nitro.js +2 -0
- package/lib-cjs/specs/Voice.nitro.js +2 -0
- package/lib-cjs/templates/GridTemplate.js +41 -0
- package/lib-cjs/templates/InformationTemplate.js +49 -0
- package/lib-cjs/templates/ListTemplate.js +33 -0
- package/lib-cjs/templates/MapTemplate.js +168 -0
- package/lib-cjs/templates/MessageTemplate.js +50 -0
- package/lib-cjs/templates/SearchTemplate.js +32 -0
- package/lib-cjs/templates/SignInTemplate.js +55 -0
- package/lib-cjs/templates/Template.js +40 -0
- package/lib-cjs/types/Button.js +12 -0
- package/lib-cjs/types/Event.js +2 -0
- package/lib-cjs/types/Image.js +2 -0
- package/lib-cjs/types/Maneuver.js +77 -0
- package/lib-cjs/types/RootComponent.js +2 -0
- package/lib-cjs/types/SignInMethod.js +22 -0
- package/lib-cjs/types/Telemetry.js +24 -0
- package/lib-cjs/types/Text.js +8 -0
- package/lib-cjs/types/Trip.js +2 -0
- package/lib-cjs/types/Voice.js +2 -0
- package/lib-cjs/utils/ErrorUtil.js +34 -0
- package/lib-cjs/utils/NitroAction.js +129 -0
- package/lib-cjs/utils/NitroAlert.js +19 -0
- package/lib-cjs/utils/NitroAttributedString.js +14 -0
- package/lib-cjs/utils/NitroColor.js +32 -0
- package/lib-cjs/utils/NitroGrid.js +12 -0
- package/lib-cjs/utils/NitroImage.js +97 -0
- package/lib-cjs/utils/NitroManeuver.js +79 -0
- package/lib-cjs/utils/NitroMapButton.js +33 -0
- package/lib-cjs/utils/NitroOptionsPanel.js +66 -0
- package/lib-cjs/utils/NitroSection.js +112 -0
- package/nitrogen/generated/android/ReactNativeAutoPlay+autolinking.cmake +1 -0
- package/nitrogen/generated/android/c++/JChargingConnector.hpp +79 -0
- package/nitrogen/generated/android/c++/JGridImageSize.hpp +64 -0
- package/nitrogen/generated/android/c++/JGridTemplateConfig.hpp +7 -1
- package/nitrogen/generated/android/c++/JHybridGridTemplateSpec.cpp +4 -0
- package/nitrogen/generated/android/c++/JHybridInformationTemplateSpec.cpp +12 -0
- package/nitrogen/generated/android/c++/JHybridListTemplateSpec.cpp +12 -0
- package/nitrogen/generated/android/c++/JHybridMapTemplateSpec.cpp +78 -3
- package/nitrogen/generated/android/c++/JHybridMapTemplateSpec.hpp +2 -1
- package/nitrogen/generated/android/c++/JHybridSearchTemplateSpec.cpp +12 -0
- package/nitrogen/generated/android/c++/JInformationTemplateConfig.hpp +6 -0
- package/nitrogen/generated/android/c++/JListImageType.hpp +67 -0
- package/nitrogen/generated/android/c++/JListTemplateConfig.hpp +6 -0
- package/nitrogen/generated/android/c++/JNitroChargerLocation.hpp +115 -0
- package/nitrogen/generated/android/c++/JNitroChargerOutlet.hpp +82 -0
- package/nitrogen/generated/android/c++/JNitroColor.hpp +8 -4
- package/nitrogen/generated/android/c++/JNitroOptionsPanelChargerSection.hpp +112 -0
- package/nitrogen/generated/android/c++/JNitroOptionsPanelConfig.hpp +157 -0
- package/nitrogen/generated/android/c++/JNitroOptionsPanelGridSection.hpp +102 -0
- package/nitrogen/generated/android/c++/JNitroOptionsPanelSection.cpp +30 -0
- package/nitrogen/generated/android/c++/JNitroOptionsPanelSection.hpp +129 -0
- package/nitrogen/generated/android/c++/JNitroRow.hpp +33 -3
- package/nitrogen/generated/android/c++/JNitroSection.hpp +6 -0
- package/nitrogen/generated/android/c++/JSearchTemplateConfig.hpp +6 -0
- package/nitrogen/generated/android/c++/JWaypointCoordinate.hpp +65 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/ChargingConnector.kt +30 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/GridImageSize.kt +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/GridTemplateConfig.kt +9 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMapTemplateSpec.kt +5 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/ListImageType.kt +26 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroChargerLocation.kt +90 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroChargerOutlet.kt +70 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroColor.kt +9 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroOptionsPanelChargerSection.kt +61 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroOptionsPanelConfig.kt +61 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroOptionsPanelGridSection.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroOptionsPanelSection.kt +75 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroRow.kt +36 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/WaypointCoordinate.kt +61 -0
- package/nitrogen/generated/ios/ReactNativeAutoPlay-Swift-Cxx-Bridge.hpp +174 -0
- package/nitrogen/generated/ios/ReactNativeAutoPlay-Swift-Cxx-Umbrella.hpp +27 -0
- package/nitrogen/generated/ios/c++/HybridGridTemplateSpecSwift.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridInformationTemplateSpecSwift.hpp +9 -0
- package/nitrogen/generated/ios/c++/HybridListTemplateSpecSwift.hpp +9 -0
- package/nitrogen/generated/ios/c++/HybridMapTemplateSpecSwift.hpp +47 -1
- package/nitrogen/generated/ios/c++/HybridSearchTemplateSpecSwift.hpp +9 -0
- package/nitrogen/generated/ios/swift/ChargingConnector.swift +68 -0
- package/nitrogen/generated/ios/swift/GridImageSize.swift +48 -0
- package/nitrogen/generated/ios/swift/GridTemplateConfig.swift +12 -1
- package/nitrogen/generated/ios/swift/HybridMapTemplateSpec.swift +2 -1
- package/nitrogen/generated/ios/swift/HybridMapTemplateSpec_cxx.swift +31 -4
- package/nitrogen/generated/ios/swift/ListImageType.swift +52 -0
- package/nitrogen/generated/ios/swift/NitroChargerLocation.swift +161 -0
- package/nitrogen/generated/ios/swift/NitroChargerOutlet.swift +65 -0
- package/nitrogen/generated/ios/swift/NitroColor.swift +20 -2
- package/nitrogen/generated/ios/swift/NitroOptionsPanelChargerSection.swift +64 -0
- package/nitrogen/generated/ios/swift/NitroOptionsPanelConfig.swift +94 -0
- package/nitrogen/generated/ios/swift/NitroOptionsPanelGridSection.swift +53 -0
- package/nitrogen/generated/ios/swift/NitroOptionsPanelSection.swift +32 -0
- package/nitrogen/generated/ios/swift/NitroRow.swift +81 -1
- package/nitrogen/generated/ios/swift/WaypointCoordinate.swift +52 -0
- package/nitrogen/generated/shared/c++/ChargingConnector.hpp +104 -0
- package/nitrogen/generated/shared/c++/GridImageSize.hpp +84 -0
- package/nitrogen/generated/shared/c++/GridTemplateConfig.hpp +8 -1
- package/nitrogen/generated/shared/c++/HybridMapTemplateSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridMapTemplateSpec.hpp +5 -1
- package/nitrogen/generated/shared/c++/ListImageType.hpp +88 -0
- package/nitrogen/generated/shared/c++/NitroChargerLocation.hpp +131 -0
- package/nitrogen/generated/shared/c++/NitroChargerOutlet.hpp +98 -0
- package/nitrogen/generated/shared/c++/NitroColor.hpp +7 -3
- package/nitrogen/generated/shared/c++/NitroOptionsPanelChargerSection.hpp +98 -0
- package/nitrogen/generated/shared/c++/NitroOptionsPanelConfig.hpp +107 -0
- package/nitrogen/generated/shared/c++/NitroOptionsPanelGridSection.hpp +91 -0
- package/nitrogen/generated/shared/c++/NitroRow.hpp +39 -2
- package/nitrogen/generated/shared/c++/WaypointCoordinate.hpp +91 -0
- package/package.json +7 -3
- package/src/Constants.ts +9 -0
- package/src/index.ts +1 -0
- package/src/index.web.ts +166 -0
- package/src/specs/MapTemplate.nitro.ts +3 -1
- package/src/templates/GridTemplate.ts +38 -3
- package/src/templates/InformationTemplate.ts +60 -29
- package/src/templates/ListTemplate.ts +27 -55
- package/src/templates/MapTemplate.ts +60 -2
- package/src/templates/MessageTemplate.ts +71 -24
- package/src/types/Image.ts +6 -1
- package/src/utils/NitroColor.ts +10 -1
- package/src/utils/NitroImage.ts +1 -5
- package/src/utils/NitroManeuver.ts +1 -4
- package/src/utils/NitroOptionsPanel.ts +218 -0
- package/src/utils/NitroSection.ts +160 -5
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
package com.margelo.nitro.swe.iternio.reactnativeautoplay.template
|
|
2
2
|
|
|
3
3
|
import androidx.car.app.CarContext
|
|
4
|
+
import androidx.car.app.annotations.ExperimentalCarApi
|
|
4
5
|
import androidx.car.app.model.GridItem
|
|
6
|
+
import androidx.car.app.model.GridSection
|
|
5
7
|
import androidx.car.app.model.GridTemplate
|
|
6
8
|
import androidx.car.app.model.ItemList
|
|
9
|
+
import androidx.car.app.model.SectionedItemTemplate
|
|
7
10
|
import androidx.car.app.model.Template
|
|
8
11
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.GridTemplateConfig
|
|
12
|
+
import com.margelo.nitro.swe.iternio.reactnativeautoplay.GridImageSize
|
|
9
13
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.NitroAction
|
|
10
14
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.NitroGridButton
|
|
11
15
|
|
|
16
|
+
@OptIn(ExperimentalCarApi::class)
|
|
12
17
|
class GridTemplate(context: CarContext, config: GridTemplateConfig) :
|
|
13
18
|
AndroidAutoTemplate<GridTemplateConfig>(context, config) {
|
|
14
19
|
|
|
@@ -18,7 +23,33 @@ class GridTemplate(context: CarContext, config: GridTemplateConfig) :
|
|
|
18
23
|
override val autoDismissMs = config.autoDismissMs
|
|
19
24
|
|
|
20
25
|
override fun parse(): Template {
|
|
21
|
-
val
|
|
26
|
+
val imageSize = config.imageSize
|
|
27
|
+
val template = when {
|
|
28
|
+
// SectionedItemTemplate (needed for per-item imageSize) is not a valid content
|
|
29
|
+
// template for MapWithContentTemplate, so imageSize is ignored while mapConfig is set.
|
|
30
|
+
config.mapConfig != null -> createGridTemplate()
|
|
31
|
+
imageSize == null || imageSize == GridImageSize.UNSET -> createGridTemplate()
|
|
32
|
+
else -> createSizedGridTemplate(imageSize)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return Parser.parseMapWithContentConfig(context, config.mapConfig, template)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private fun createGridTemplate(): Template = GridTemplate.Builder().apply {
|
|
39
|
+
setHeader(Parser.parseHeader(context, config.title, config.headerActions))
|
|
40
|
+
|
|
41
|
+
if (config.buttons.isEmpty()) {
|
|
42
|
+
setLoading(true)
|
|
43
|
+
return@apply
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
setSingleList(ItemList.Builder().apply {
|
|
47
|
+
config.buttons.forEach { button -> addItem(createGridItem(button)) }
|
|
48
|
+
}.build())
|
|
49
|
+
}.build()
|
|
50
|
+
|
|
51
|
+
private fun createSizedGridTemplate(imageSize: GridImageSize): Template =
|
|
52
|
+
SectionedItemTemplate.Builder().apply {
|
|
22
53
|
setHeader(Parser.parseHeader(context, config.title, config.headerActions))
|
|
23
54
|
|
|
24
55
|
if (config.buttons.isEmpty()) {
|
|
@@ -26,20 +57,23 @@ class GridTemplate(context: CarContext, config: GridTemplateConfig) :
|
|
|
26
57
|
return@apply
|
|
27
58
|
}
|
|
28
59
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
setTitle(Parser.parseText(button.title))
|
|
33
|
-
setOnClickListener(button.onPress)
|
|
34
|
-
button.image.let { image ->
|
|
35
|
-
setImage(Parser.parseImage(context, image))
|
|
36
|
-
}
|
|
37
|
-
}.build())
|
|
38
|
-
}
|
|
60
|
+
addSection(GridSection.Builder().apply {
|
|
61
|
+
setItemSize(imageSize.toItemSize())
|
|
62
|
+
config.buttons.forEach { button -> addItem(createGridItem(button)) }
|
|
39
63
|
}.build())
|
|
40
64
|
}.build()
|
|
41
65
|
|
|
42
|
-
|
|
66
|
+
private fun createGridItem(button: NitroGridButton): GridItem = GridItem.Builder().apply {
|
|
67
|
+
setTitle(Parser.parseText(button.title))
|
|
68
|
+
setOnClickListener(button.onPress)
|
|
69
|
+
setImage(Parser.parseImage(context, button.image))
|
|
70
|
+
}.build()
|
|
71
|
+
|
|
72
|
+
private fun GridImageSize.toItemSize(): Int = when (this) {
|
|
73
|
+
GridImageSize.LARGE -> GridSection.ITEM_SIZE_LARGE
|
|
74
|
+
GridImageSize.MEDIUM -> GridSection.ITEM_SIZE_MEDIUM
|
|
75
|
+
GridImageSize.SMALL -> GridSection.ITEM_SIZE_SMALL
|
|
76
|
+
GridImageSize.UNSET -> error("An unset grid image size has no item size")
|
|
43
77
|
}
|
|
44
78
|
|
|
45
79
|
override fun setTemplateHeaderActions(headerActions: Array<NitroAction>?) {
|
|
@@ -72,4 +106,4 @@ class GridTemplate(context: CarContext, config: GridTemplateConfig) :
|
|
|
72
106
|
config = config.copy(buttons = buttons)
|
|
73
107
|
super.applyConfigUpdate()
|
|
74
108
|
}
|
|
75
|
-
}
|
|
109
|
+
}
|
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/Parser.kt
CHANGED
|
@@ -36,6 +36,7 @@ import androidx.car.app.navigation.model.TravelEstimate
|
|
|
36
36
|
import androidx.core.graphics.createBitmap
|
|
37
37
|
import androidx.core.graphics.drawable.IconCompat
|
|
38
38
|
import androidx.core.graphics.drawable.toBitmap
|
|
39
|
+
import androidx.core.net.toUri
|
|
39
40
|
import com.facebook.datasource.DataSources
|
|
40
41
|
import com.facebook.drawee.backends.pipeline.Fresco
|
|
41
42
|
import com.facebook.imagepipeline.image.CloseableBitmap
|
|
@@ -51,6 +52,7 @@ import com.margelo.nitro.swe.iternio.reactnativeautoplay.DurationWithTimeZone
|
|
|
51
52
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.ForkType
|
|
52
53
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.GlyphImage
|
|
53
54
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.KeepType
|
|
55
|
+
import com.margelo.nitro.swe.iternio.reactnativeautoplay.ListImageType
|
|
54
56
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.ListTemplateConfig
|
|
55
57
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.ManeuverType
|
|
56
58
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.NitroAction
|
|
@@ -81,9 +83,12 @@ import java.util.Calendar
|
|
|
81
83
|
import java.util.Locale
|
|
82
84
|
import java.util.TimeZone
|
|
83
85
|
import kotlin.math.abs
|
|
84
|
-
import androidx.core.net.toUri
|
|
85
86
|
|
|
86
87
|
object Parser {
|
|
88
|
+
// IMAGE_TYPE_MEDIUM was added to androidx.car.app in 1.8.0. Keep the protocol value here
|
|
89
|
+
// while this library continues to depend on 1.7.0.
|
|
90
|
+
private const val ROW_IMAGE_TYPE_MEDIUM = 16
|
|
91
|
+
|
|
87
92
|
const val TAG = "Parser"
|
|
88
93
|
|
|
89
94
|
fun parseHeader(
|
|
@@ -177,7 +182,11 @@ object Parser {
|
|
|
177
182
|
}.build()
|
|
178
183
|
}
|
|
179
184
|
|
|
180
|
-
fun parseAction(
|
|
185
|
+
fun parseAction(
|
|
186
|
+
context: CarContext,
|
|
187
|
+
action: NitroAction,
|
|
188
|
+
useParkedOnlyClickListener: Boolean = false
|
|
189
|
+
): Action {
|
|
181
190
|
if (action.type == NitroActionType.APPICON) {
|
|
182
191
|
return Action.APP_ICON
|
|
183
192
|
}
|
|
@@ -214,11 +223,21 @@ object Parser {
|
|
|
214
223
|
}
|
|
215
224
|
|
|
216
225
|
fun parseImage(context: CarContext, image: Variant_GlyphImage_AssetImage_RemoteImage): CarIcon {
|
|
217
|
-
return parseImage(
|
|
226
|
+
return parseImage(
|
|
227
|
+
context,
|
|
228
|
+
image.asFirstOrNull(),
|
|
229
|
+
image.asSecondOrNull(),
|
|
230
|
+
image.asThirdOrNull()
|
|
231
|
+
)
|
|
218
232
|
}
|
|
219
233
|
|
|
220
234
|
fun parseImage(context: CarContext, image: NitroImage): CarIcon {
|
|
221
|
-
return parseImage(
|
|
235
|
+
return parseImage(
|
|
236
|
+
context,
|
|
237
|
+
image.asFirstOrNull(),
|
|
238
|
+
image.asSecondOrNull(),
|
|
239
|
+
image.asThirdOrNull()
|
|
240
|
+
)
|
|
222
241
|
}
|
|
223
242
|
|
|
224
243
|
fun parseImage(
|
|
@@ -229,8 +248,19 @@ object Parser {
|
|
|
229
248
|
): CarIcon {
|
|
230
249
|
val bitmap = parseImageToBitmap(context, glyphImage, assetImage, remoteImage)
|
|
231
250
|
|
|
251
|
+
// the tint recolors every opaque pixel, so it would also fill the background drawn in SymbolFont
|
|
252
|
+
val hasGlyphBackground =
|
|
253
|
+
glyphImage != null && (glyphImage.backgroundColor.get(context) ushr 24) != 0
|
|
254
|
+
|
|
255
|
+
val applyDefaultTint = !hasGlyphBackground && (glyphImage?.color?.isDefault
|
|
256
|
+
?: assetImage?.color?.isDefault ?: remoteImage?.color?.isDefault ?: false)
|
|
257
|
+
|
|
232
258
|
bitmap?.let {
|
|
233
|
-
return CarIcon.Builder(IconCompat.createWithBitmap(it)).
|
|
259
|
+
return CarIcon.Builder(IconCompat.createWithBitmap(it)).apply {
|
|
260
|
+
if (applyDefaultTint) {
|
|
261
|
+
setTint(CarColor.DEFAULT)
|
|
262
|
+
}
|
|
263
|
+
}.build()
|
|
234
264
|
}
|
|
235
265
|
|
|
236
266
|
// remote images might fail to load so we provide some placeholder then
|
|
@@ -397,7 +427,13 @@ object Parser {
|
|
|
397
427
|
addText(parseText(detailedText))
|
|
398
428
|
}
|
|
399
429
|
row.image?.let { image ->
|
|
400
|
-
|
|
430
|
+
val parsedImage = parseImage(context, image)
|
|
431
|
+
val imageType = row.imageType
|
|
432
|
+
if (imageType == null) {
|
|
433
|
+
setImage(parsedImage)
|
|
434
|
+
} else {
|
|
435
|
+
setImage(parsedImage, imageType.toRowImageType())
|
|
436
|
+
}
|
|
401
437
|
}
|
|
402
438
|
row.browsable?.let { browsable ->
|
|
403
439
|
setBrowsable(browsable)
|
|
@@ -426,6 +462,14 @@ object Parser {
|
|
|
426
462
|
}.build()
|
|
427
463
|
}
|
|
428
464
|
|
|
465
|
+
private fun ListImageType.toRowImageType(): Int = when (this) {
|
|
466
|
+
ListImageType.LARGE -> Row.IMAGE_TYPE_LARGE
|
|
467
|
+
ListImageType.MEDIUM -> ROW_IMAGE_TYPE_MEDIUM
|
|
468
|
+
ListImageType.SMALL -> Row.IMAGE_TYPE_SMALL
|
|
469
|
+
ListImageType.EXTRA_SMALL -> Row.IMAGE_TYPE_EXTRA_SMALL
|
|
470
|
+
ListImageType.ICON -> Row.IMAGE_TYPE_ICON
|
|
471
|
+
}
|
|
472
|
+
|
|
429
473
|
fun formatToTimestamp(time: DurationWithTimeZone): String {
|
|
430
474
|
val calendar = Calendar.getInstance().apply {
|
|
431
475
|
add(Calendar.SECOND, time.seconds.toInt())
|
|
@@ -591,10 +635,14 @@ object Parser {
|
|
|
591
635
|
private fun fetchSync(context: CarContext, imageRequest: ImageRequest): Bitmap? {
|
|
592
636
|
val dataSource = try {
|
|
593
637
|
Fresco.getImagePipeline().fetchDecodedImage(imageRequest, context)
|
|
594
|
-
} catch (_: Exception) {
|
|
638
|
+
} catch (_: Exception) {
|
|
639
|
+
return null
|
|
640
|
+
}
|
|
595
641
|
val result = try {
|
|
596
642
|
DataSources.waitForFinalResult(dataSource)
|
|
597
|
-
} catch (_: Exception) {
|
|
643
|
+
} catch (_: Exception) {
|
|
644
|
+
dataSource.close(); return null
|
|
645
|
+
}
|
|
598
646
|
val image = result?.get()
|
|
599
647
|
try {
|
|
600
648
|
if (image is CloseableBitmap) {
|
|
@@ -602,10 +650,14 @@ object Parser {
|
|
|
602
650
|
// whose backing bitmap has already been recycled or failed to allocate;
|
|
603
651
|
// copy() can also throw (e.g., OOM on very large remote images). Either
|
|
604
652
|
// way we return null so the caller falls back to a placeholder icon.
|
|
605
|
-
return image.underlyingBitmap
|
|
653
|
+
return image.underlyingBitmap.copy(Bitmap.Config.ARGB_8888, false)
|
|
606
654
|
} else if (image is CloseableXml) {
|
|
607
655
|
val drawable = image.buildDrawable()
|
|
608
|
-
return drawable?.toBitmap(
|
|
656
|
+
return drawable?.toBitmap(
|
|
657
|
+
width = image.width,
|
|
658
|
+
height = image.height,
|
|
659
|
+
Bitmap.Config.ARGB_8888
|
|
660
|
+
)
|
|
609
661
|
}
|
|
610
662
|
} catch (_: Exception) {
|
|
611
663
|
// Any decode/copy failure (OOM, recycled bitmap, invalid config, …) should
|
|
@@ -740,10 +792,12 @@ object Parser {
|
|
|
740
792
|
}
|
|
741
793
|
nitroManeuver.angle?.let { roundaboutExitAngle ->
|
|
742
794
|
if (nitroManeuver.trafficSide == TrafficSide.LEFT) {
|
|
743
|
-
val angle = ((180 + roundaboutExitAngle) % 360).toInt()
|
|
795
|
+
val angle = ((180 + roundaboutExitAngle) % 360).toInt()
|
|
796
|
+
.let { if (it == 0) 360 else it }
|
|
744
797
|
setRoundaboutExitAngle(angle)
|
|
745
798
|
} else {
|
|
746
|
-
val angle = ((180 - roundaboutExitAngle) % 360).toInt()
|
|
799
|
+
val angle = ((180 - roundaboutExitAngle) % 360).toInt()
|
|
800
|
+
.let { if (it == 0) 360 else it }
|
|
747
801
|
setRoundaboutExitAngle(angle)
|
|
748
802
|
}
|
|
749
803
|
}
|
|
@@ -822,7 +876,7 @@ object Parser {
|
|
|
822
876
|
mapConfig.mapButtons?.let { mapButtons ->
|
|
823
877
|
setMapController(
|
|
824
878
|
MapController.Builder().apply {
|
|
825
|
-
setMapActionStrip(
|
|
879
|
+
setMapActionStrip(parseMapActions(context, mapButtons)).build()
|
|
826
880
|
setPanModeListener { isInPanMode ->
|
|
827
881
|
mapConfig.onDidChangePanningInterface?.let {
|
|
828
882
|
it(isInPanMode)
|
|
@@ -832,8 +886,8 @@ object Parser {
|
|
|
832
886
|
)
|
|
833
887
|
}
|
|
834
888
|
mapConfig.headerActions?.let { headerActions ->
|
|
835
|
-
setActionStrip(
|
|
889
|
+
setActionStrip(parseMapHeaderActions(context, headerActions))
|
|
836
890
|
}
|
|
837
891
|
}.build()
|
|
838
892
|
}
|
|
839
|
-
}
|
|
893
|
+
}
|
package/ios/Types.swift
CHANGED
|
@@ -10,9 +10,12 @@ import UIKit
|
|
|
10
10
|
extension UIImage {
|
|
11
11
|
static func makeToggleImage(
|
|
12
12
|
enabled: Bool,
|
|
13
|
-
maximumImageSize: CGSize
|
|
13
|
+
maximumImageSize: CGSize,
|
|
14
|
+
traitCollection: UITraitCollection
|
|
14
15
|
) -> UIImage {
|
|
15
|
-
let
|
|
16
|
+
let format = UIGraphicsImageRendererFormat()
|
|
17
|
+
format.scale = traitCollection.displayScale
|
|
18
|
+
let renderer = UIGraphicsImageRenderer(size: maximumImageSize, format: format)
|
|
16
19
|
return renderer.image { ctx in
|
|
17
20
|
// Draw the track as a pill, centered vertically
|
|
18
21
|
let trackHeight = maximumImageSize.height * 0.5
|
|
@@ -160,7 +160,7 @@ class HybridAutoPlay: HybridAutoPlaySpec {
|
|
|
160
160
|
templateId: templateId
|
|
161
161
|
)
|
|
162
162
|
|
|
163
|
-
let carPlayTemplate = template.getTemplate()
|
|
163
|
+
let carPlayTemplate = try template.getTemplate()
|
|
164
164
|
|
|
165
165
|
if carPlayTemplate is CPMapTemplate {
|
|
166
166
|
try await MainActor.run {
|
|
@@ -192,23 +192,35 @@ class HybridAutoPlay: HybridAutoPlaySpec {
|
|
|
192
192
|
|
|
193
193
|
await template.invalidate()
|
|
194
194
|
|
|
195
|
-
let
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
carPlayTemplate,
|
|
204
|
-
animated: animated
|
|
195
|
+
if #available(iOS 27.0, *), let panel = template.getPanel() as? CPMapPanel {
|
|
196
|
+
/// since only the top most panel gets a panelDidHide call when pressing the close button
|
|
197
|
+
/// we hide it globaly to avoid orphaned panels on the navigation stack
|
|
198
|
+
panel.showsCloseButton = false
|
|
199
|
+
|
|
200
|
+
try await interfaceController.pushPanel(
|
|
201
|
+
panel,
|
|
202
|
+
templateId: templateId
|
|
205
203
|
)
|
|
206
204
|
}
|
|
207
205
|
else {
|
|
208
|
-
let
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
206
|
+
let carPlayTemplate = try template.getTemplate()
|
|
207
|
+
|
|
208
|
+
if carPlayTemplate is CPAlertTemplate {
|
|
209
|
+
let animated = try await !interfaceController.dismissTemplate(
|
|
210
|
+
animated: false
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
let _ = try await interfaceController.presentTemplate(
|
|
214
|
+
carPlayTemplate,
|
|
215
|
+
animated: animated
|
|
216
|
+
)
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
let _ = try await interfaceController.pushTemplate(
|
|
220
|
+
carPlayTemplate,
|
|
221
|
+
animated: true
|
|
222
|
+
)
|
|
223
|
+
}
|
|
212
224
|
}
|
|
213
225
|
|
|
214
226
|
if let autoDismissMs = template.autoDismissMs {
|
|
@@ -217,7 +229,7 @@ class HybridAutoPlay: HybridAutoPlaySpec {
|
|
|
217
229
|
nanoseconds: UInt64(autoDismissMs) * 1_000_000
|
|
218
230
|
)
|
|
219
231
|
|
|
220
|
-
if interfaceController.
|
|
232
|
+
if interfaceController.isTopEntry(templateId: templateId)
|
|
221
233
|
|| interfaceController.interfaceController
|
|
222
234
|
.presentedTemplate?.id == templateId
|
|
223
235
|
{
|
|
@@ -147,11 +147,15 @@ class HybridMapTemplate: HybridMapTemplateSpec {
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
func startNavigation(templateId: String, trip: TripConfig) throws {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
func startNavigation(templateId: String, trip: TripConfig) throws -> Promise<Void> {
|
|
151
|
+
return Promise.async {
|
|
152
|
+
try await MainActor.run {
|
|
153
|
+
try RootModule.withAutoPlayTemplate(templateId: templateId) {
|
|
154
|
+
(template: MapTemplate) in
|
|
155
|
+
let trip = Parser.parseTrip(tripConfig: trip)
|
|
156
|
+
template.startNavigation(trip: trip)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
155
159
|
}
|
|
156
160
|
}
|
|
157
161
|
|
|
@@ -168,4 +172,17 @@ class HybridMapTemplate: HybridMapTemplateSpec {
|
|
|
168
172
|
template.setManeuverState(state: state)
|
|
169
173
|
}
|
|
170
174
|
}
|
|
175
|
+
|
|
176
|
+
func updateOptionsPanel(templateId: String, config: NitroOptionsPanelConfig?) throws
|
|
177
|
+
-> Promise<Void>
|
|
178
|
+
{
|
|
179
|
+
return Promise.async {
|
|
180
|
+
try await MainActor.run {
|
|
181
|
+
try RootModule.withAutoPlayTemplate(templateId: templateId) {
|
|
182
|
+
(template: MapTemplate) in
|
|
183
|
+
template.updateOptionsPanel(config: config)
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
171
188
|
}
|