@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.
Files changed (46) hide show
  1. package/README.md +1 -43
  2. package/ReactNativeAutoPlay.podspec +4 -0
  3. package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/utils/SymbolFont.kt +30 -29
  4. package/android/src/main/res/font/materialsymbolsoutlined_regular.ttf +0 -0
  5. package/ios/Assets/MaterialSymbolsOutlined-Regular.ttf +0 -0
  6. package/ios/utils/SymbolFont.swift +44 -44
  7. package/lib/HybridAutoPlay.d.ts +2 -0
  8. package/lib/HybridAutoPlay.js +2 -0
  9. package/lib/hooks/useIsAutoPlayFocused.d.ts +7 -0
  10. package/lib/hooks/useIsAutoPlayFocused.js +20 -0
  11. package/lib/hybrid/HybridVoice.d.ts +12 -0
  12. package/lib/hybrid/HybridVoice.js +13 -0
  13. package/lib/hybrid.d.ts +2 -0
  14. package/lib/hybrid.js +2 -0
  15. package/lib/index.d.ts +0 -1
  16. package/lib/index.js +0 -1
  17. package/lib/specs/AutomotivePermissionRequestTemplate.d.ts +11 -0
  18. package/lib/specs/AutomotivePermissionRequestTemplate.js +1 -0
  19. package/lib/specs/AutomotivePermissionRequestTemplate.nitro.d.ts +11 -0
  20. package/lib/specs/AutomotivePermissionRequestTemplate.nitro.js +1 -0
  21. package/lib/specs/Voice.nitro.d.ts +51 -0
  22. package/lib/specs/Voice.nitro.js +1 -0
  23. package/lib/templates/AutomotivePermissionRequestTemplate.d.ts +23 -0
  24. package/lib/templates/AutomotivePermissionRequestTemplate.js +18 -0
  25. package/lib/types/Glyphmap.d.ts +4105 -0
  26. package/lib/types/Glyphmap.js +4105 -0
  27. package/lib/types/Image.d.ts +4 -33
  28. package/lib/types/Maneuver.d.ts +10 -2
  29. package/lib/types/Voice.d.ts +15 -0
  30. package/lib/types/Voice.js +1 -0
  31. package/lib/utils/NitroImage.d.ts +2 -23
  32. package/lib/utils/NitroImage.js +3 -57
  33. package/nitrogen/generated/android/c++/JGlyphImage.hpp +1 -6
  34. package/nitrogen/generated/android/c++/JNitroImage.hpp +1 -1
  35. package/nitrogen/generated/android/c++/JVariant_GlyphImage_AssetImage_RemoteImage.hpp +1 -1
  36. package/nitrogen/generated/android/c++/JVariant_PreferredImageLane_ImageLane.hpp +1 -1
  37. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/GlyphImage.kt +2 -5
  38. package/nitrogen/generated/ios/c++/HybridCarPlayDashboardSpecSwift.hpp +1 -1
  39. package/nitrogen/generated/ios/swift/GlyphImage.swift +2 -7
  40. package/nitrogen/generated/shared/c++/GlyphImage.hpp +1 -6
  41. package/package.json +3 -2
  42. package/src/index.ts +0 -1
  43. package/src/types/Glyphmap.ts +4107 -0
  44. package/src/types/Image.ts +18 -53
  45. package/src/types/Maneuver.ts +10 -3
  46. 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 does **not** bundle any icon font the consuming app must provide one.
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"
@@ -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 com.margelo.nitro.swe.iternio.reactnativeautoplay.BuildConfig
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
- private var cachedFontName: String? = null
18
- private var cachedTypeface: Typeface? = null
21
+ const val TAG = "SymbolFont"
19
22
 
20
- private fun loadTypeface(context: Context, fontName: String): Typeface? {
21
- if (fontName == cachedFontName) return cachedTypeface
22
- val id = context.resources.getIdentifier(
23
- fontName.lowercase(), "font", context.packageName
24
- )
25
- if (id == 0) return null
26
- val tf = ResourcesCompat.getFont(context, id) ?: return null
27
- cachedFontName = fontName
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
- glyphImage: GlyphImage,
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
- val font =
40
- loadTypeface(context, glyphImage.fontName) ?: run {
41
- return null
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 = glyphImage.glyph.toInt()
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
- imageFromGlyph(
98
- context = context,
99
- glyphImage = image,
100
- color = image.color.get(context),
101
- backgroundColor = image.backgroundColor.get(context),
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
+ }
@@ -9,65 +9,67 @@ import CoreText
9
9
  import UIKit
10
10
 
11
11
  class SymbolFont {
12
- private static var cachedFontName: String?
13
- private static var cachedPSName: String?
12
+ private static let defaultCanvasSize = 32
14
13
 
15
- private static func loadFont(named fontName: String) -> String? {
16
- if fontName == cachedFontName {
17
- return cachedPSName
18
- }
14
+ private static var isRegistered = false
15
+ private static var fontName: String?
19
16
 
20
- guard let url = Bundle.main.url(forResource: fontName, withExtension: "ttf") else {
21
- print("[AutoPlay] \(fontName).ttf not found in the app bundle — glyph images will not render.")
22
- return nil
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: url) as CFData,
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 nil
38
+ return
30
39
  }
31
40
 
32
41
  var error: Unmanaged<CFError>?
33
42
  CTFontManagerRegisterGraphicsFont(font, &error)
34
- // Ignore already-registered errors (e.g. hot reload)
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
- cachedFontName = fontName
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
- return UIFont(name: psName, size: pointSize)
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
- glyphImage: GlyphImage,
56
+ glyph: Double,
58
57
  foregroundColor: UIColor,
59
58
  backgroundColor: UIColor,
60
59
  size: CGFloat,
61
60
  fontScale: CGFloat
62
61
  ) -> UIImage? {
63
- guard let font = uiFont(for: glyphImage, size: size, fontScale: fontScale) else {
64
- return nil
62
+ if !SymbolFont.isRegistered {
63
+ SymbolFont.loadFont()
65
64
  }
66
65
 
67
- guard let scalar = UnicodeScalar(UInt32(glyphImage.glyph)) else {
66
+ guard let fontName = SymbolFont.fontName,
67
+ let font = UIFont(name: fontName, size: size * fontScale)
68
+ else {
68
69
  return nil
69
70
  }
70
- let codepoint = String(Character(scalar))
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 uiImage = UIGraphicsGetImageFromCurrentImageContext()
102
+ let image = UIGraphicsGetImageFromCurrentImageContext()
101
103
  UIGraphicsEndImageContext()
102
104
 
103
- return uiImage
105
+ return image
104
106
  }
105
107
 
106
108
  static func imageFromGlyph(
107
- glyphImage: GlyphImage,
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
- glyphImage: glyphImage,
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
- glyphImage: glyphImage,
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
- glyphImage: image,
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
- glyphImage: image,
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,2 @@
1
+ import type { AutoPlay } from './specs/AutoPlay.nitro';
2
+ export declare const HybridAutoPlay: AutoPlay;
@@ -0,0 +1,2 @@
1
+ import { NitroModules } from 'react-native-nitro-modules';
2
+ export const HybridAutoPlay = NitroModules.createHybridObject('AutoPlay');
@@ -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
+ };
@@ -0,0 +1,2 @@
1
+ import type { AutoPlay as NitroAutoPlay } from './specs/AutoPlay.nitro';
2
+ export declare const HybridAutoPlay: NitroAutoPlay;
package/lib/hybrid.js ADDED
@@ -0,0 +1,2 @@
1
+ import { NitroModules } from 'react-native-nitro-modules';
2
+ export const HybridAutoPlay = NitroModules.createHybridObject('AutoPlay');
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
@@ -45,4 +45,3 @@ export * from './types/SignInMethod';
45
45
  export * from './types/Telemetry';
46
46
  export * from './types/Text';
47
47
  export * from './types/Trip';
48
- export { setIconFont } from './utils/NitroImage';
@@ -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,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
+ }