@iternio/react-native-auto-play 0.3.13 → 0.3.14
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 +1 -43
- package/ReactNativeAutoPlay.podspec +4 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/utils/SymbolFont.kt +30 -29
- package/android/src/main/res/font/materialsymbolsoutlined_regular.ttf +0 -0
- package/ios/Assets/MaterialSymbolsOutlined-Regular.ttf +0 -0
- package/ios/utils/SymbolFont.swift +44 -44
- package/lib/HybridAutoPlay.d.ts +2 -0
- package/lib/HybridAutoPlay.js +2 -0
- package/lib/hooks/useIsAutoPlayFocused.d.ts +7 -0
- package/lib/hooks/useIsAutoPlayFocused.js +20 -0
- package/lib/hybrid/HybridVoice.d.ts +12 -0
- package/lib/hybrid/HybridVoice.js +13 -0
- package/lib/hybrid.d.ts +2 -0
- package/lib/hybrid.js +2 -0
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/specs/AutomotivePermissionRequestTemplate.d.ts +11 -0
- package/lib/specs/AutomotivePermissionRequestTemplate.js +1 -0
- package/lib/specs/AutomotivePermissionRequestTemplate.nitro.d.ts +11 -0
- package/lib/specs/AutomotivePermissionRequestTemplate.nitro.js +1 -0
- package/lib/specs/Voice.nitro.d.ts +51 -0
- package/lib/specs/Voice.nitro.js +1 -0
- package/lib/templates/AutomotivePermissionRequestTemplate.d.ts +23 -0
- package/lib/templates/AutomotivePermissionRequestTemplate.js +18 -0
- package/lib/types/Glyphmap.d.ts +4105 -0
- package/lib/types/Glyphmap.js +4105 -0
- package/lib/types/Image.d.ts +4 -33
- package/lib/types/Maneuver.d.ts +10 -2
- package/lib/types/Voice.d.ts +15 -0
- package/lib/types/Voice.js +1 -0
- package/lib/utils/NitroImage.d.ts +2 -23
- package/lib/utils/NitroImage.js +3 -57
- package/nitrogen/generated/android/c++/JGlyphImage.hpp +1 -6
- package/nitrogen/generated/android/c++/JNitroImage.hpp +1 -1
- package/nitrogen/generated/android/c++/JVariant_GlyphImage_AssetImage_RemoteImage.hpp +1 -1
- package/nitrogen/generated/android/c++/JVariant_PreferredImageLane_ImageLane.hpp +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/GlyphImage.kt +2 -5
- package/nitrogen/generated/ios/c++/HybridCarPlayDashboardSpecSwift.hpp +1 -1
- package/nitrogen/generated/ios/swift/GlyphImage.swift +2 -7
- package/nitrogen/generated/shared/c++/GlyphImage.hpp +1 -6
- package/package.json +3 -2
- package/src/index.ts +0 -1
- package/src/types/Glyphmap.ts +4107 -0
- package/src/types/Image.ts +18 -53
- package/src/types/Maneuver.ts +10 -3
- package/src/utils/NitroImage.ts +5 -66
package/README.md
CHANGED
|
@@ -304,49 +304,7 @@ When using build variants, Android Studio may not be aware of the selected varia
|
|
|
304
304
|
To work around this and allow for debugging or enhancing the Android Automotive-specific implementation, you can temporarily set the automotive flags in your `gradle.properties` file or your default `.env` file before running a Gradle sync.
|
|
305
305
|
|
|
306
306
|
## Icons
|
|
307
|
-
The library
|
|
308
|
-
|
|
309
|
-
### Setup
|
|
310
|
-
|
|
311
|
-
1. Add a `.ttf` font file to your native projects:
|
|
312
|
-
- **iOS** — add `<name>.ttf` to your app bundle (no `UIAppFonts` entry needed — the library registers it via CoreText automatically).
|
|
313
|
-
- **Android** — place `<name>.ttf` in `res/font/`.
|
|
314
|
-
|
|
315
|
-
For cross-platform compatibility use **lowercase names with underscores only** (e.g. `material_symbols`).
|
|
316
|
-
|
|
317
|
-
2. Register the font and an optional glyph map at startup:
|
|
318
|
-
|
|
319
|
-
```ts
|
|
320
|
-
import { setIconFont } from '@iternio/react-native-auto-play';
|
|
321
|
-
import { glyphMap } from './assets/Glyphmap';
|
|
322
|
-
|
|
323
|
-
setIconFont('material_symbols', glyphMap);
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
3. Use glyph images by name or code point:
|
|
327
|
-
|
|
328
|
-
```ts
|
|
329
|
-
{ type: 'glyph', name: 'directions_car' }
|
|
330
|
-
{ type: 'glyph', codepoint: 0xe531 }
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
`setIconFont` must be called once before the first glyph is used (subsequent calls are ignored). If no font is registered, the library throws an error when a glyph image is rendered.
|
|
334
|
-
|
|
335
|
-
### Type-safe glyph names
|
|
336
|
-
|
|
337
|
-
To get autocompletion and type checking for glyph names, create a declaration file in your app (e.g. `autoplay-glyphs.d.ts`):
|
|
338
|
-
|
|
339
|
-
```ts
|
|
340
|
-
import type { GlyphName } from './assets/Glyphmap';
|
|
341
|
-
|
|
342
|
-
declare module '@iternio/react-native-auto-play' {
|
|
343
|
-
interface AutoPlayGlyphMap extends Record<GlyphName, number> {}
|
|
344
|
-
}
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
Without this augmentation, `name` accepts any `string`. With it, only keys from your glyph map are allowed and you get full autocompletion.
|
|
348
|
-
|
|
349
|
-
The example app uses [Material Symbols](https://fonts.google.com/icons). See `apps/example/assets/symbolFont/` for the glyph map generation script.
|
|
307
|
+
The library is using [Material Symbols](https://fonts.google.com/icons) for iconography. The font is bundled with the library, so no extra setup is required. You can use these icons on both Android Auto and CarPlay.
|
|
350
308
|
|
|
351
309
|
It is also possible to use custom bundled images (e.g. PNG, WEBP or Vector Drawables). Make sure to add them to your native projects.
|
|
352
310
|
- iOS: Add to your `Images.xcassets`
|
|
@@ -25,6 +25,10 @@ Pod::Spec.new do |s|
|
|
|
25
25
|
# react helpers like RCTConvert
|
|
26
26
|
s.public_header_files = Array(s.attributes_hash['public_header_files']) + ["ios/ReactHelpers/*.h"]
|
|
27
27
|
|
|
28
|
+
s.resource_bundles = {
|
|
29
|
+
"ReactNativeAutoPlay" => ['ios/Assets/**/*.ttf']
|
|
30
|
+
}
|
|
31
|
+
|
|
28
32
|
s.pod_target_xcconfig = {
|
|
29
33
|
# C++ compiler flags, mainly for folly.
|
|
30
34
|
"GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) FOLLY_NO_CONFIG FOLLY_CFG_NO_COROUTINES"
|
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/utils/SymbolFont.kt
CHANGED
|
@@ -10,36 +10,39 @@ import android.graphics.Typeface
|
|
|
10
10
|
import androidx.car.app.CarContext
|
|
11
11
|
import androidx.core.content.res.ResourcesCompat
|
|
12
12
|
import androidx.core.graphics.createBitmap
|
|
13
|
-
import
|
|
13
|
+
import androidx.core.graphics.drawable.IconCompat
|
|
14
14
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.GlyphImage
|
|
15
|
+
import com.margelo.nitro.swe.iternio.reactnativeautoplay.NitroImage
|
|
16
|
+
import com.margelo.nitro.swe.iternio.reactnativeautoplay.BuildConfig
|
|
17
|
+
import com.margelo.nitro.swe.iternio.reactnativeautoplay.R
|
|
18
|
+
import com.margelo.nitro.swe.iternio.reactnativeautoplay.template.Parser
|
|
15
19
|
|
|
16
20
|
object SymbolFont {
|
|
17
|
-
|
|
18
|
-
private var cachedTypeface: Typeface? = null
|
|
21
|
+
const val TAG = "SymbolFont"
|
|
19
22
|
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
cachedTypeface = tf
|
|
29
|
-
return tf
|
|
23
|
+
private var typeface: Typeface? = null
|
|
24
|
+
|
|
25
|
+
private fun loadFont(context: Context) {
|
|
26
|
+
if (typeface != null) {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
typeface = ResourcesCompat.getFont(context, R.font.materialsymbolsoutlined_regular)
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
private fun imageFromGlyph(
|
|
33
34
|
context: Context,
|
|
34
|
-
|
|
35
|
+
glyph: Double,
|
|
35
36
|
color: Int,
|
|
36
37
|
backgroundColor: Int,
|
|
37
38
|
cornerRadius: Float = 8f, //TODO: make accessible and add it to GlyphImage.cacheKey
|
|
39
|
+
fontScale: Float,
|
|
38
40
|
): Bitmap? {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
loadFont(context)
|
|
42
|
+
|
|
43
|
+
val font = typeface ?: run {
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
43
46
|
|
|
44
47
|
val virtualScreenDensity = context.resources.displayMetrics.density
|
|
45
48
|
val scale = BuildConfig.SCALE_FACTOR * virtualScreenDensity
|
|
@@ -56,8 +59,6 @@ object SymbolFont {
|
|
|
56
59
|
}
|
|
57
60
|
canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, paint)
|
|
58
61
|
|
|
59
|
-
val fontScale = (glyphImage.fontScale ?: 1.0).toFloat()
|
|
60
|
-
|
|
61
62
|
// Setup text paint
|
|
62
63
|
paint.reset()
|
|
63
64
|
paint = Paint().apply {
|
|
@@ -69,7 +70,7 @@ object SymbolFont {
|
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
// Get the character from codepoint
|
|
72
|
-
val codepoint =
|
|
73
|
+
val codepoint = glyph.toInt()
|
|
73
74
|
val text = String(Character.toChars(codepoint))
|
|
74
75
|
|
|
75
76
|
// Measure text
|
|
@@ -93,13 +94,13 @@ object SymbolFont {
|
|
|
93
94
|
return bitmap
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
bitmap =
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
97
|
+
bitmap = imageFromGlyph(
|
|
98
|
+
context = context,
|
|
99
|
+
glyph = image.glyph,
|
|
100
|
+
color = image.color.get(context),
|
|
101
|
+
backgroundColor = image.backgroundColor.get(context),
|
|
102
|
+
fontScale = (image.fontScale ?: 1.0).toFloat()
|
|
103
|
+
)
|
|
103
104
|
|
|
104
105
|
bitmap?.let {
|
|
105
106
|
BitmapCache.put(context, image, it)
|
|
@@ -107,4 +108,4 @@ object SymbolFont {
|
|
|
107
108
|
|
|
108
109
|
return bitmap
|
|
109
110
|
}
|
|
110
|
-
}
|
|
111
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -9,65 +9,67 @@ import CoreText
|
|
|
9
9
|
import UIKit
|
|
10
10
|
|
|
11
11
|
class SymbolFont {
|
|
12
|
-
private static
|
|
13
|
-
private static var cachedPSName: String?
|
|
12
|
+
private static let defaultCanvasSize = 32
|
|
14
13
|
|
|
15
|
-
private static
|
|
16
|
-
|
|
17
|
-
return cachedPSName
|
|
18
|
-
}
|
|
14
|
+
private static var isRegistered = false
|
|
15
|
+
private static var fontName: String?
|
|
19
16
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
static func loadFont() {
|
|
18
|
+
let podBundle = Bundle(for: SymbolFont.self)
|
|
19
|
+
|
|
20
|
+
guard
|
|
21
|
+
let bundleURL = podBundle.url(
|
|
22
|
+
forResource: "ReactNativeAutoPlay",
|
|
23
|
+
withExtension: "bundle"
|
|
24
|
+
),
|
|
25
|
+
let resourceBundle = Bundle(url: bundleURL),
|
|
26
|
+
let fontURL = resourceBundle.url(
|
|
27
|
+
forResource: "MaterialSymbolsOutlined-Regular",
|
|
28
|
+
withExtension: "ttf"
|
|
29
|
+
)
|
|
30
|
+
else {
|
|
31
|
+
return
|
|
23
32
|
}
|
|
24
33
|
|
|
25
|
-
guard let fontData = try? Data(contentsOf:
|
|
34
|
+
guard let fontData = try? Data(contentsOf: fontURL) as CFData,
|
|
26
35
|
let provider = CGDataProvider(data: fontData),
|
|
27
36
|
let font = CGFont(provider)
|
|
28
37
|
else {
|
|
29
|
-
return
|
|
38
|
+
return
|
|
30
39
|
}
|
|
31
40
|
|
|
32
41
|
var error: Unmanaged<CFError>?
|
|
33
42
|
CTFontManagerRegisterGraphicsFont(font, &error)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
guard let psName = font.fullName as? String else {
|
|
37
|
-
return nil
|
|
43
|
+
if let error = error?.takeUnretainedValue() {
|
|
44
|
+
print("Failed to register font: \(error)")
|
|
38
45
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
cachedPSName = psName
|
|
42
|
-
return psName
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
private static func uiFont(for glyphImage: GlyphImage, size: CGFloat, fontScale: CGFloat) -> UIFont? {
|
|
46
|
-
let pointSize = size * fontScale
|
|
47
|
-
|
|
48
|
-
guard let psName = loadFont(named: glyphImage.fontName) else {
|
|
49
|
-
return nil
|
|
46
|
+
else {
|
|
47
|
+
print("Font \(font.fullName as String? ?? "unknown") registered")
|
|
50
48
|
}
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
SymbolFont.fontName = font.fullName as? String
|
|
51
|
+
SymbolFont.isRegistered = true
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
// creates a single color UIImage
|
|
56
55
|
static func imageFromGlyph(
|
|
57
|
-
|
|
56
|
+
glyph: Double,
|
|
58
57
|
foregroundColor: UIColor,
|
|
59
58
|
backgroundColor: UIColor,
|
|
60
59
|
size: CGFloat,
|
|
61
60
|
fontScale: CGFloat
|
|
62
61
|
) -> UIImage? {
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
if !SymbolFont.isRegistered {
|
|
63
|
+
SymbolFont.loadFont()
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
guard let
|
|
66
|
+
guard let fontName = SymbolFont.fontName,
|
|
67
|
+
let font = UIFont(name: fontName, size: size * fontScale)
|
|
68
|
+
else {
|
|
68
69
|
return nil
|
|
69
70
|
}
|
|
70
|
-
|
|
71
|
+
|
|
72
|
+
let codepoint = String(UnicodeScalar(UInt32(glyph))!)
|
|
71
73
|
let canvasSize = CGSize(width: size, height: size)
|
|
72
74
|
let rect = CGRect(origin: .zero, size: canvasSize)
|
|
73
75
|
|
|
@@ -97,14 +99,14 @@ class SymbolFont {
|
|
|
97
99
|
let y = (canvasSize.height - textSize.height) / 2
|
|
98
100
|
attrString.draw(at: CGPoint(x: x, y: y))
|
|
99
101
|
|
|
100
|
-
let
|
|
102
|
+
let image = UIGraphicsGetImageFromCurrentImageContext()
|
|
101
103
|
UIGraphicsEndImageContext()
|
|
102
104
|
|
|
103
|
-
return
|
|
105
|
+
return image
|
|
104
106
|
}
|
|
105
107
|
|
|
106
108
|
static func imageFromGlyph(
|
|
107
|
-
|
|
109
|
+
glyph: Double,
|
|
108
110
|
size: CGFloat,
|
|
109
111
|
foregroundColor: NitroColor,
|
|
110
112
|
backgroundColor: NitroColor,
|
|
@@ -113,7 +115,7 @@ class SymbolFont {
|
|
|
113
115
|
) -> UIImage? {
|
|
114
116
|
guard
|
|
115
117
|
let lightImage = imageFromGlyph(
|
|
116
|
-
|
|
118
|
+
glyph: glyph,
|
|
117
119
|
foregroundColor: Parser.doubleToColor(
|
|
118
120
|
value: foregroundColor.lightColor
|
|
119
121
|
),
|
|
@@ -124,7 +126,7 @@ class SymbolFont {
|
|
|
124
126
|
fontScale: fontScale
|
|
125
127
|
),
|
|
126
128
|
let darkImage = imageFromGlyph(
|
|
127
|
-
|
|
129
|
+
glyph: glyph,
|
|
128
130
|
foregroundColor: Parser.doubleToColor(
|
|
129
131
|
value: foregroundColor.darkColor
|
|
130
132
|
),
|
|
@@ -165,8 +167,6 @@ class SymbolFont {
|
|
|
165
167
|
) -> UIImage? {
|
|
166
168
|
guard let image else { return nil }
|
|
167
169
|
|
|
168
|
-
let fontScale = image.fontScale ?? 1.0
|
|
169
|
-
|
|
170
170
|
if noImageAsset {
|
|
171
171
|
let foregroundColor = Parser.doubleToColor(
|
|
172
172
|
value: traitCollection.userInterfaceStyle == .light
|
|
@@ -180,21 +180,21 @@ class SymbolFont {
|
|
|
180
180
|
)
|
|
181
181
|
|
|
182
182
|
return SymbolFont.imageFromGlyph(
|
|
183
|
-
|
|
183
|
+
glyph: image.glyph,
|
|
184
184
|
foregroundColor: foregroundColor,
|
|
185
185
|
backgroundColor: backgroundColor,
|
|
186
186
|
size: size,
|
|
187
|
-
fontScale: fontScale
|
|
187
|
+
fontScale: image.fontScale ?? 1.0
|
|
188
188
|
)
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
return SymbolFont.imageFromGlyph(
|
|
192
|
-
|
|
192
|
+
glyph: image.glyph,
|
|
193
193
|
size: size,
|
|
194
194
|
foregroundColor: image.color,
|
|
195
195
|
backgroundColor: image.backgroundColor,
|
|
196
|
-
fontScale: fontScale,
|
|
196
|
+
fontScale: image.fontScale ?? 1.0,
|
|
197
197
|
traitCollection: traitCollection
|
|
198
|
-
)
|
|
198
|
+
)!
|
|
199
199
|
}
|
|
200
200
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A hook to determine if the CarPlay/Android Auto screen is currently focused (visible).
|
|
3
|
+
*
|
|
4
|
+
* @param moduleName The name of the module to listen to.
|
|
5
|
+
* @returns `true` if the screen is focused, `false` otherwise.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useIsAutoPlayFocused(moduleName: string): boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { HybridAutoPlay } from '..';
|
|
3
|
+
/**
|
|
4
|
+
* A hook to determine if the CarPlay/Android Auto screen is currently focused (visible).
|
|
5
|
+
*
|
|
6
|
+
* @param moduleName The name of the module to listen to.
|
|
7
|
+
* @returns `true` if the screen is focused, `false` otherwise.
|
|
8
|
+
*/
|
|
9
|
+
export function useIsAutoPlayFocused(moduleName) {
|
|
10
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
const remove = HybridAutoPlay.addListenerRenderState(moduleName, (state) => {
|
|
13
|
+
setIsFocused(state === 'didAppear');
|
|
14
|
+
});
|
|
15
|
+
return () => {
|
|
16
|
+
remove();
|
|
17
|
+
};
|
|
18
|
+
}, [moduleName]);
|
|
19
|
+
return isFocused;
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { VoiceInputOptions, VoiceInputResult } from '../types/Voice';
|
|
2
|
+
type StartVoiceInput = {
|
|
3
|
+
(options: VoiceInputOptions & Required<Pick<VoiceInputOptions, 'onChunk'>>): Promise<void>;
|
|
4
|
+
(options?: Omit<VoiceInputOptions, 'onChunk'>): Promise<VoiceInputResult>;
|
|
5
|
+
};
|
|
6
|
+
export declare const HybridVoice: {
|
|
7
|
+
hasVoiceInputPermission: () => boolean;
|
|
8
|
+
requestVoiceInputPermission: () => Promise<boolean>;
|
|
9
|
+
startVoiceInput: StartVoiceInput;
|
|
10
|
+
stopVoiceInput: () => void;
|
|
11
|
+
};
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { NitroModules } from 'react-native-nitro-modules';
|
|
2
|
+
const _native = NitroModules.createHybridObject('Voice');
|
|
3
|
+
const startVoiceInput = (async (options) => {
|
|
4
|
+
const { onChunk, silenceThresholdMs, maxDurationMs, listeningText, preferSpeechToText } = options ?? {};
|
|
5
|
+
const result = await _native.startVoiceInput(silenceThresholdMs, maxDurationMs, listeningText, preferSpeechToText, onChunk);
|
|
6
|
+
return onChunk !== undefined ? undefined : result;
|
|
7
|
+
});
|
|
8
|
+
export const HybridVoice = {
|
|
9
|
+
hasVoiceInputPermission: () => _native.hasVoiceInputPermission(),
|
|
10
|
+
requestVoiceInputPermission: () => _native.requestVoiceInputPermission(),
|
|
11
|
+
startVoiceInput,
|
|
12
|
+
stopVoiceInput: () => _native.stopVoiceInput(),
|
|
13
|
+
};
|
package/lib/hybrid.d.ts
ADDED
package/lib/hybrid.js
ADDED
package/lib/index.d.ts
CHANGED
|
@@ -43,4 +43,3 @@ export * from './types/Trip';
|
|
|
43
43
|
export type { AlertPriority, NavigationAlert as Alert, NavigationAlertAction as AlertAction, } from './utils/NitroAlert';
|
|
44
44
|
export type { ThemedColor } from './utils/NitroColor';
|
|
45
45
|
export type { GridButton } from './utils/NitroGrid';
|
|
46
|
-
export { setIconFont } from './utils/NitroImage';
|
package/lib/index.js
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
+
import type { NitroAutomotivePermissionRequestTemplateConfig } from '../templates/AutomotivePermissionRequestTemplate';
|
|
3
|
+
import type { NitroTemplateConfig } from './AutoPlay.nitro';
|
|
4
|
+
interface AutomotivePermissionRequestTemplateConfig extends NitroTemplateConfig, NitroAutomotivePermissionRequestTemplateConfig {
|
|
5
|
+
}
|
|
6
|
+
export interface AutomotivePermissionRequestTemplate extends HybridObject<{
|
|
7
|
+
android: 'kotlin';
|
|
8
|
+
}> {
|
|
9
|
+
createAutomotivePermissionRequestTemplate(config: AutomotivePermissionRequestTemplateConfig): void;
|
|
10
|
+
}
|
|
11
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
+
import type { NitroAutomotivePermissionRequestTemplateConfig } from '../templates/AutomotivePermissionRequestTemplate';
|
|
3
|
+
import type { NitroTemplateConfig } from './AutoPlay.nitro';
|
|
4
|
+
interface AutomotivePermissionRequestTemplateConfig extends NitroTemplateConfig, NitroAutomotivePermissionRequestTemplateConfig {
|
|
5
|
+
}
|
|
6
|
+
export interface AutomotivePermissionRequestTemplate extends HybridObject<{
|
|
7
|
+
android: 'kotlin';
|
|
8
|
+
}> {
|
|
9
|
+
createAutomotivePermissionRequestTemplate(config: AutomotivePermissionRequestTemplateConfig): void;
|
|
10
|
+
}
|
|
11
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
+
import type { VoiceInputChunk, VoiceInputResult } from '../types/Voice';
|
|
3
|
+
export interface Voice extends HybridObject<{
|
|
4
|
+
android: 'kotlin';
|
|
5
|
+
ios: 'swift';
|
|
6
|
+
}> {
|
|
7
|
+
/**
|
|
8
|
+
* Returns true if all permissions required for voice input are granted.
|
|
9
|
+
* On iOS: checks both microphone and speech recognition authorization.
|
|
10
|
+
* On Android: checks RECORD_AUDIO permission.
|
|
11
|
+
*/
|
|
12
|
+
hasVoiceInputPermission(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Request all permissions required for voice input.
|
|
15
|
+
* On iOS: requests microphone permission then speech recognition authorization.
|
|
16
|
+
* On Android: requests RECORD_AUDIO via car context when connected, otherwise
|
|
17
|
+
* via the React Native application context.
|
|
18
|
+
* Returns true only if all required permissions were granted.
|
|
19
|
+
*/
|
|
20
|
+
requestVoiceInputPermission(): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* Start an in-app voice session.
|
|
23
|
+
*
|
|
24
|
+
* When preferSpeechToText is true:
|
|
25
|
+
* iOS — streams audio buffers into SFSpeechRecognizer during recording;
|
|
26
|
+
* onChunk fires with partial transcription results; resolves with
|
|
27
|
+
* { transcription } or falls back to { audio } if unavailable.
|
|
28
|
+
* Android — checks SpeechRecognizer availability upfront; if available it
|
|
29
|
+
* owns the mic and streams partial results via onChunk; if not
|
|
30
|
+
* available falls back to PCM recording.
|
|
31
|
+
*
|
|
32
|
+
* When preferSpeechToText is false (default):
|
|
33
|
+
* Both platforms record raw PCM; onChunk fires with audio chunks;
|
|
34
|
+
* resolves with { audio }.
|
|
35
|
+
*
|
|
36
|
+
* @param silenceThresholdMs ms of silence before auto-stop (default 1500)
|
|
37
|
+
* @param maxDurationMs hard cap on recording duration (default 10000)
|
|
38
|
+
* @param listeningText iOS only — text shown on CPVoiceControlTemplate
|
|
39
|
+
* @param preferSpeechToText request STT transcription instead of raw PCM
|
|
40
|
+
* @param onChunk optional streaming callback; when set the
|
|
41
|
+
* promise resolves with an empty VoiceInputResult
|
|
42
|
+
*/
|
|
43
|
+
startVoiceInput(silenceThresholdMs?: number, maxDurationMs?: number, listeningText?: string, preferSpeechToText?: boolean, onChunk?: (chunk: VoiceInputChunk) => void): Promise<VoiceInputResult>;
|
|
44
|
+
/**
|
|
45
|
+
* Stop the active voice session early.
|
|
46
|
+
* For PCM mode: resolves startVoiceInput with audio captured so far.
|
|
47
|
+
* For STT mode: finalises the recognition request.
|
|
48
|
+
* No-op if no session is active.
|
|
49
|
+
*/
|
|
50
|
+
stopVoiceInput(): void;
|
|
51
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CustomActionButtonAndroid } from '../types/Button';
|
|
2
|
+
import type { AutoText } from '../types/Text';
|
|
3
|
+
import { type NitroAction } from '../utils/NitroAction';
|
|
4
|
+
import { type HeaderActions, Template, type TemplateConfig } from './Template';
|
|
5
|
+
export interface NitroAutomotivePermissionRequestTemplateConfig extends TemplateConfig {
|
|
6
|
+
headerActions?: Array<NitroAction>;
|
|
7
|
+
title: AutoText;
|
|
8
|
+
actions: Array<NitroAction>;
|
|
9
|
+
}
|
|
10
|
+
export type AutomotivePermissionRequestTemplateConfig = Omit<NitroAutomotivePermissionRequestTemplateConfig, 'headerActions' | 'buttons'> & {
|
|
11
|
+
/**
|
|
12
|
+
* action buttons, usually at the the top right on Android and a top bar on iOS
|
|
13
|
+
*/
|
|
14
|
+
headerActions?: HeaderActions<AutomotivePermissionRequestTemplate>;
|
|
15
|
+
actions: [CustomActionButtonAndroid<AutomotivePermissionRequestTemplate>] | [
|
|
16
|
+
CustomActionButtonAndroid<AutomotivePermissionRequestTemplate>,
|
|
17
|
+
CustomActionButtonAndroid<AutomotivePermissionRequestTemplate>
|
|
18
|
+
];
|
|
19
|
+
};
|
|
20
|
+
export declare class AutomotivePermissionRequestTemplate extends Template<AutomotivePermissionRequestTemplateConfig, HeaderActions<AutomotivePermissionRequestTemplate>> {
|
|
21
|
+
private template;
|
|
22
|
+
constructor(config: AutomotivePermissionRequestTemplateConfig);
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { NitroModules } from 'react-native-nitro-modules';
|
|
2
|
+
import { NitroActionUtil } from '../utils/NitroAction';
|
|
3
|
+
import { Template, } from './Template';
|
|
4
|
+
const HybridAutomotivePermissionRequestTemplate = NitroModules.createHybridObject('AutomotivePermissionRequestTemplate');
|
|
5
|
+
export class AutomotivePermissionRequestTemplate extends Template {
|
|
6
|
+
template = this;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
super(config);
|
|
9
|
+
const { headerActions, actions, ...rest } = config;
|
|
10
|
+
const nitroConfig = {
|
|
11
|
+
...rest,
|
|
12
|
+
id: this.id,
|
|
13
|
+
headerActions: NitroActionUtil.convert(this.template, headerActions),
|
|
14
|
+
actions: NitroActionUtil.convert(this.template, actions),
|
|
15
|
+
};
|
|
16
|
+
HybridAutomotivePermissionRequestTemplate.createAutomotivePermissionRequestTemplate(nitroConfig);
|
|
17
|
+
}
|
|
18
|
+
}
|