diff --git a/.gitignore b/.gitignore
index 401db12..8d35027 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,6 +29,7 @@ project.xcworkspace
# Android/IJ
#
+build/
.classpath
.cxx
.gradle
diff --git a/README.md b/README.md
index ad2fb37..5952ffe 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,51 @@
# expo-stt
-Unofficial Speech To Text module for Expo which supported iOS and Android
+- Unofficial Speech To Text module for Expo which supported iOS and Android
+- Forked [anhtuank7c/expo-stt](https://github.com/anhtuank7c/expo-stt)
+- Migrated [react-native-voice functionality](https://github.com/react-native-voice/voice) on [crossplatformkorea/expo-stt](https://github.com/crossplatformkorea/expo-stt), which is forked from [anhtuank7c/expo-stt](https://github.com/anhtuank7c/expo-stt)
+- Currently, [anhtuank7c/expo-stt](https://github.com/anhtuank7c/expo-stt) has a separate Google voice recognition modal. Instead, I migrated the [react-native-voice](https://github.com/react-native-voice/voice) code onto [crossplatformkorea/expo-stt](https://github.com/crossplatformkorea/expo-stt), which was created with the [expo module](https://docs.expo.dev/modules/overview), to use the built-in microphone like [react-native-voice](https://github.com/react-native-voice/voice).
-So sorry that I am unemployed and don't have much money to spend more time to make this module work also for web.
+# Sequence Diagram
-If you still want to support web platform, please follow this article https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API
+Below is a sequence diagram explaining how each module, including SpeechRecognizer, works.
-![Demo speech to text](demo.png "Demo Speech To Text")
+![Sequence Diagram](sequence-diagram.png)
+
+And below is the [mermaid](https://mermaid.js.org) code to create the above diagram.
+
+```mermaid
+
+sequenceDiagram
+ participant User
+ participant ExpoSttModule
+ participant SpeechRecognizer
+ participant ReactNative as React Native Module
-# API documentation
+ User->>ExpoSttModule: startSpeech()
+ ExpoSttModule->>SpeechRecognizer: createSpeechRecognizer()
+ ExpoSttModule->>SpeechRecognizer: startListening()
+ SpeechRecognizer-->>ExpoSttModule: onReadyForSpeech
-- [Documentation for the main branch](https://github.com/expo/expo/blob/main/docs/pages/versions/unversioned/sdk/stt.md)
-- [Documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/stt/)
+ User->>SpeechRecognizer: User starts speaking
+ SpeechRecognizer-->>ExpoSttModule: onBeginningOfSpeech
+ ExpoSttModule->>ReactNative: sendEvent(onSpeechStart)
-# Installation in managed Expo projects
+ User->>SpeechRecognizer: User finishes speaking
+ SpeechRecognizer-->>ExpoSttModule: onEndOfSpeech
+ ExpoSttModule->>ReactNative: sendEvent(onSpeechEnd)
-For [managed](https://docs.expo.dev/versions/latest/introduction/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](#api-documentation). If you follow the link and there is no documentation available then this library is not yet usable within managed projects — it is likely to be included in an upcoming Expo SDK release.
+ SpeechRecognizer-->>ExpoSttModule: onResults
+ ExpoSttModule->>ReactNative: sendEvent(onSpeechResult)
-# Installation in bare React Native projects
+ alt SpeechRecognizer encounters an error
+ SpeechRecognizer-->>ExpoSttModule: onError
+ ExpoSttModule->>ReactNative: sendEvent(onSpeechError)
+ end
+```
+
+# Demo
-For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
+![Demo speech to text](demo.png "Demo Speech To Text")
### Add the package to your npm dependencies
@@ -39,6 +65,7 @@ npx expo prebuild --clean
### Configure for iOS (Bare React Native project only)
Run `npx pod-install` after installing the npm package.
+
## Add missing permissions for iOS
Add following key to plugins of `app.json` in Expo project
@@ -68,6 +95,7 @@ For Bare React Native project, you need to add these key to `Info.plist` in `ios
## Usage
Register some listeners
+
```
import * as ExpoStt from 'expo-stt';
@@ -82,10 +110,6 @@ Register some listeners
setSpokenText(value.join());
});
- const onSpeechCancelled = ExpoStt.addOnSpeechCancelledListener(() => {
- setRecognizing(false);
- });
-
const onSpeechError = ExpoStt.addOnSpeechErrorListener(({ cause }) => {
setError(cause);
setRecognizing(false);
@@ -98,7 +122,6 @@ Register some listeners
return () => {
onSpeechStart.remove();
onSpeechResult.remove();
- onSpeechCancelled.remove();
onSpeechError.remove();
onSpeechEnd.remove();
};
@@ -107,21 +130,14 @@ Register some listeners
There are some functions available to call such as:
-* ExpoStt.startSpeech()
-* ExpoStt.stopSpeech()
-* ExpoStt.cancelSpeech()
-* ExpoStt.destroySpeech()
-* ExpoStt.requestRecognitionPermission()
-* ExpoStt.checkRecognitionPermission()
+- ExpoStt.startSpeech()
+- ExpoStt.stopSpeech()
+- ExpoStt.destroySpeech()
+- ExpoStt.requestRecognitionPermission()
+- ExpoStt.checkRecognitionPermission()
Take a look into `example/App.tsx` for completed example
# Contributing
-Contributions are very welcome! Please refer to guidelines described in the [contributing guide]( https://github.com/expo/expo#contributing).
-
-## Author
-
-I am looking for a job as a React native developer, remote work is preferred.
-
-Check out my CV: https://anhtuank7c.github.io
+Contributions are very welcome! Please refer to guidelines described in the [contributing guide](https://github.com/expo/expo#contributing).
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 2166eec..c70917b 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -1,2 +1,8 @@
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/android/src/main/java/expo/modules/stt/ExpoSttModule.kt b/android/src/main/java/expo/modules/stt/ExpoSttModule.kt
index d886cda..3a119cb 100644
--- a/android/src/main/java/expo/modules/stt/ExpoSttModule.kt
+++ b/android/src/main/java/expo/modules/stt/ExpoSttModule.kt
@@ -1,41 +1,43 @@
package expo.modules.stt
import android.util.Log
-import expo.modules.kotlin.activityresult.AppContextActivityResultLauncher
import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.*
+import android.speech.SpeechRecognizer
+import android.speech.RecognizerIntent
+import android.content.Intent
+import android.speech.RecognitionListener
+import android.os.Bundle
+import expo.modules.kotlin.exception.CodedException
+import android.Manifest
+import android.content.pm.PackageManager
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
-class ExpoSttModule : Module() {
- private lateinit var voiceRecognizer: AppContextActivityResultLauncher
+class ExpoSttModule : Module(), RecognitionListener {
private var isRecognizing: Boolean = false
+ private var speech: SpeechRecognizer? = null
companion object {
- const val onSpeechResult = "onSpeechResult"
- const val onSpeechError = "onSpeechError"
- const val onSpeechCancelled = "onSpeechCancelled"
const val onSpeechStart = "onSpeechStart"
+ const val onSpeechResult = "onSpeechResult"
+ const val onPartialResults = "onPartialResults"
const val onSpeechEnd = "onSpeechEnd"
+ const val onSpeechError = "onSpeechError"
const val TAG = "ExpoStt"
}
override fun definition() = ModuleDefinition {
Name(TAG)
- /**
- * We don't need any permission for Recognizer on Android
- * Just act like iOS one to unify the APIs
- */
+ Events(onSpeechStart, onSpeechResult, onPartialResults, onSpeechEnd, onSpeechError)
+
AsyncFunction("requestRecognitionPermission") {
- return@AsyncFunction mapOf(
- "status" to "granted",
- "expires" to "never",
- "granted" to true,
- "canAskAgain" to true
- )
+ requestRecognitionPermission()
}
AsyncFunction("checkRecognitionPermission") {
@@ -48,30 +50,28 @@ class ExpoSttModule : Module() {
}
Function("startSpeech") {
+ if (!isPermissionGranted()) {
+ requestRecognitionPermission()
+ return@Function false
+ }
+
if (isRecognizing) {
sendEvent(onSpeechError, mapOf("cause" to "Speech recognition already started!"))
return@Function false
}
-
- isRecognizing = true
- sendEvent(onSpeechStart)
- val options = VoiceRecognizerContractOptions(Locale.getDefault())
+
+ if (speech != null) {
+ speech?.destroy()
+ speech = null
+ }
+
CoroutineScope(Dispatchers.Main).launch {
- when (val result = voiceRecognizer.launch(options)) {
- is VoiceRecognizerContractResult.Success -> {
- isRecognizing = false
- sendEvent(onSpeechResult, mapOf("value" to result.value))
- sendEvent(onSpeechEnd)
- }
- is VoiceRecognizerContractResult.Cancelled -> {
- isRecognizing = false
- sendEvent(onSpeechCancelled)
- }
- is VoiceRecognizerContractResult.Error -> {
- isRecognizing = false
- sendEvent(onSpeechError, mapOf("cause" to result.cause))
- }
- }
+ speech = SpeechRecognizer.createSpeechRecognizer(appContext.reactContext)
+ speech?.setRecognitionListener(this@ExpoSttModule)
+ val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
+ intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault())
+
+ speech?.startListening(intent)
}
return@Function true
}
@@ -82,24 +82,112 @@ class ExpoSttModule : Module() {
* A bit different compare to iOS APIs
*/
Function("stopSpeech") {
+ if (speech != null) {
+ speech?.stopListening()
+ }
+ isRecognizing = false
Log.d(TAG, "Stop Voice Recognizer")
- }
- Function("cancelSpeech") {
- Log.d(TAG, "Cancel Voice Recognizer")
+ return@Function null as Any
}
Function("destroySpeech") {
+ if (speech != null) {
+ speech?.destroy()
+ }
+ isRecognizing = false
Log.d(TAG, "Destroy Voice Recognizer")
+
+ return@Function null as Any
+ }
+
+ }
+
+ private fun requestRecognitionPermission() {
+ val currentActivity = appContext.currentActivity ?: throw CodedException("Activity is null")
+ val permission = Manifest.permission.RECORD_AUDIO
+ val isGranted = ContextCompat.checkSelfPermission(currentActivity, permission) == PackageManager.PERMISSION_GRANTED
+
+ if (!isGranted) {
+ ActivityCompat.requestPermissions(currentActivity, arrayOf(permission), 1)
+ }
+
+ mapOf(
+ "status" to if (isGranted) "granted" else "denied",
+ "expires" to "never",
+ "granted" to isGranted,
+ "canAskAgain" to true
+ )
+ }
+
+ private fun isPermissionGranted(): Boolean {
+ val permission = Manifest.permission.RECORD_AUDIO
+ val res = appContext.reactContext?.checkCallingOrSelfPermission(permission)
+ return res == PackageManager.PERMISSION_GRANTED
+ }
+
+ override fun onReadyForSpeech(params: Bundle?) {
+ Log.d(TAG, "onReadyForSpeech")
+ }
+
+ override fun onBeginningOfSpeech() {
+ isRecognizing = true
+ sendEvent(onSpeechStart)
+ Log.d(TAG, "onBeginningOfSpeech")
+ }
+
+ override fun onResults(results: Bundle?) {
+ isRecognizing = false
+ val matches = results?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
+
+ if (matches != null) {
+ sendEvent(onSpeechResult, mapOf("results" to matches))
+ } else {
+ sendEvent(onSpeechError, mapOf("errorMessage" to "No speech results"))
}
- RegisterActivityContracts {
- voiceRecognizer =
- registerForActivityResult(VoiceRecognizerContract()) { _, _ ->
- Log.d(TAG, "handleResultUponActivityDestruction")
- }
+ Log.d(TAG, "onResults $matches")
+ }
+
+ override fun onPartialResults(partialResults: Bundle?) {
+ val matches = partialResults?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
+ // Log.d(TAG, "onPartialResults $matches")
+ }
+
+ override fun onEndOfSpeech() {
+ isRecognizing = false
+ sendEvent(onSpeechEnd)
+ Log.d(TAG, "onEndOfSpeech")
+ }
+
+ override fun onError(error: Int) {
+ isRecognizing = false
+ val errorMessage = when (error) {
+ SpeechRecognizer.ERROR_AUDIO -> "Audio recording error"
+ SpeechRecognizer.ERROR_CLIENT -> "Client side error"
+ SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS -> "Insufficient permissions"
+ SpeechRecognizer.ERROR_NETWORK -> "Network error"
+ SpeechRecognizer.ERROR_NETWORK_TIMEOUT -> "Network timeout"
+ SpeechRecognizer.ERROR_NO_MATCH -> "No match"
+ SpeechRecognizer.ERROR_RECOGNIZER_BUSY -> "RecognitionService busy"
+ SpeechRecognizer.ERROR_SERVER -> "Error from server"
+ SpeechRecognizer.ERROR_SPEECH_TIMEOUT -> "No speech input"
+ else -> "Unknown error"
}
+
+ sendEvent(onSpeechError, mapOf("errorMessage" to errorMessage))
+ Log.d(TAG, "onError: $error $errorMessage")
+ }
+
+ override fun onBufferReceived(buffer: ByteArray?) {
+ Log.d(TAG, "onBufferReceived")
+ }
+
+ override fun onRmsChanged(rmsdB: Float) {
+ // Log.d(TAG, "onRmsChanged: $rmsdB")
+ }
- Events(onSpeechResult, onSpeechError, onSpeechEnd, onSpeechStart, onSpeechCancelled)
+ override fun onEvent(eventType: Int, params: Bundle?) {
+ Log.d(TAG, "onEvent: $eventType")
}
}
diff --git a/build/ExpoStt.types.d.ts b/build/ExpoStt.types.d.ts
deleted file mode 100644
index 8800f97..0000000
--- a/build/ExpoStt.types.d.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-export type OnSpeechResultEventPayload = {
- value: string[];
-};
-export type OnSpeechErrorEventPayload = {
- cause: string;
-};
-export declare enum ReactEvents {
- onSpeechStart = "onSpeechStart",
- onSpeechEnd = "onSpeechEnd",
- onSpeechError = "onSpeechError",
- onSpeechResult = "onSpeechResult",
- onSpeechCancelled = "onSpeechCancelled"
-}
-//# sourceMappingURL=ExpoStt.types.d.ts.map
\ No newline at end of file
diff --git a/build/ExpoStt.types.d.ts.map b/build/ExpoStt.types.d.ts.map
deleted file mode 100644
index 79a2a73..0000000
--- a/build/ExpoStt.types.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"ExpoStt.types.d.ts","sourceRoot":"","sources":["../src/ExpoStt.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,0BAA0B,GAAG;IACvC,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AACF,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AACF,oBAAY,WAAW;IACrB,aAAa,kBAAkB;IAC/B,WAAW,gBAAgB;IAC3B,aAAa,kBAAkB;IAC/B,cAAc,mBAAmB;IACjC,iBAAiB,sBAAsB;CACxC"}
\ No newline at end of file
diff --git a/build/ExpoStt.types.js b/build/ExpoStt.types.js
deleted file mode 100644
index fa5c309..0000000
--- a/build/ExpoStt.types.js
+++ /dev/null
@@ -1,9 +0,0 @@
-export var ReactEvents;
-(function (ReactEvents) {
- ReactEvents["onSpeechStart"] = "onSpeechStart";
- ReactEvents["onSpeechEnd"] = "onSpeechEnd";
- ReactEvents["onSpeechError"] = "onSpeechError";
- ReactEvents["onSpeechResult"] = "onSpeechResult";
- ReactEvents["onSpeechCancelled"] = "onSpeechCancelled";
-})(ReactEvents || (ReactEvents = {}));
-//# sourceMappingURL=ExpoStt.types.js.map
\ No newline at end of file
diff --git a/build/ExpoStt.types.js.map b/build/ExpoStt.types.js.map
deleted file mode 100644
index 3c943cb..0000000
--- a/build/ExpoStt.types.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"ExpoStt.types.js","sourceRoot":"","sources":["../src/ExpoStt.types.ts"],"names":[],"mappings":"AAMA,MAAM,CAAN,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,8CAA+B,CAAA;IAC/B,0CAA2B,CAAA;IAC3B,8CAA+B,CAAA;IAC/B,gDAAiC,CAAA;IACjC,sDAAuC,CAAA;AACzC,CAAC,EANW,WAAW,KAAX,WAAW,QAMtB","sourcesContent":["export type OnSpeechResultEventPayload = {\n value: string[];\n};\nexport type OnSpeechErrorEventPayload = {\n cause: string;\n};\nexport enum ReactEvents {\n onSpeechStart = \"onSpeechStart\",\n onSpeechEnd = \"onSpeechEnd\",\n onSpeechError = \"onSpeechError\",\n onSpeechResult = \"onSpeechResult\",\n onSpeechCancelled = \"onSpeechCancelled\",\n}\n"]}
\ No newline at end of file
diff --git a/build/ExpoSttModule.d.ts b/build/ExpoSttModule.d.ts
deleted file mode 100644
index 024cc3d..0000000
--- a/build/ExpoSttModule.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-declare const _default: any;
-export default _default;
-//# sourceMappingURL=ExpoSttModule.d.ts.map
\ No newline at end of file
diff --git a/build/ExpoSttModule.d.ts.map b/build/ExpoSttModule.d.ts.map
deleted file mode 100644
index 916b38c..0000000
--- a/build/ExpoSttModule.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"ExpoSttModule.d.ts","sourceRoot":"","sources":["../src/ExpoSttModule.ts"],"names":[],"mappings":";AAIA,wBAA8C"}
\ No newline at end of file
diff --git a/build/ExpoSttModule.js b/build/ExpoSttModule.js
deleted file mode 100644
index 58fdf32..0000000
--- a/build/ExpoSttModule.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import { requireNativeModule } from "expo-modules-core";
-// It loads the native module object from the JSI or falls back to
-// the bridge module (from NativeModulesProxy) if the remote debugger is on.
-export default requireNativeModule("ExpoStt");
-//# sourceMappingURL=ExpoSttModule.js.map
\ No newline at end of file
diff --git a/build/ExpoSttModule.js.map b/build/ExpoSttModule.js.map
deleted file mode 100644
index 98984e9..0000000
--- a/build/ExpoSttModule.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"ExpoSttModule.js","sourceRoot":"","sources":["../src/ExpoSttModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,kEAAkE;AAClE,4EAA4E;AAC5E,eAAe,mBAAmB,CAAC,SAAS,CAAC,CAAC","sourcesContent":["import { requireNativeModule } from \"expo-modules-core\";\n\n// It loads the native module object from the JSI or falls back to\n// the bridge module (from NativeModulesProxy) if the remote debugger is on.\nexport default requireNativeModule(\"ExpoStt\");\n"]}
\ No newline at end of file
diff --git a/build/index.d.ts b/build/index.d.ts
deleted file mode 100644
index 7d65514..0000000
--- a/build/index.d.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Subscription, PermissionResponse } from "expo-modules-core";
-import { OnSpeechResultEventPayload, OnSpeechErrorEventPayload, ReactEvents } from "./ExpoStt.types";
-export declare function startSpeech(): boolean;
-export declare function stopSpeech(): void;
-export declare function cancelSpeech(): void;
-export declare function destroySpeech(): void;
-export declare function requestRecognitionPermission(): Promise;
-export declare function checkRecognitionPermission(): Promise;
-export declare function addOnSpeechStartListener(listener: () => void): Subscription;
-export declare function addOnSpeechEndListener(listener: () => void): Subscription;
-export declare function addOnSpeechCancelledListener(listener: () => void): Subscription;
-export declare function addOnSpeechResultListener(listener: (event: OnSpeechResultEventPayload) => void): Subscription;
-export declare function addOnSpeechErrorListener(listener: (event: OnSpeechErrorEventPayload) => void): Subscription;
-export { OnSpeechResultEventPayload, OnSpeechErrorEventPayload, ReactEvents };
-//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/build/index.d.ts.map b/build/index.d.ts.map
deleted file mode 100644
index bc04c7e..0000000
--- a/build/index.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAGzB,wBAAgB,WAAW,IAAI,OAAO,CAErC;AACD,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AACD,wBAAgB,YAAY,IAAI,IAAI,CAEnC;AACD,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AACD,wBAAgB,4BAA4B,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAE1E;AACD,wBAAgB,0BAA0B,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAExE;AAID,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,YAAY,CAE3E;AACD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,YAAY,CAEzE;AACD,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,IAAI,GACnB,YAAY,CAEd;AACD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,GACpD,YAAY,CAKd;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,IAAI,GACnD,YAAY,CAKd;AAED,OAAO,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,WAAW,EAAE,CAAC"}
\ No newline at end of file
diff --git a/build/index.js b/build/index.js
deleted file mode 100644
index 6709a0e..0000000
--- a/build/index.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import { NativeModulesProxy, EventEmitter, } from "expo-modules-core";
-// Import the native module. On web, it will be resolved to ExpoStt.web.ts
-// and on native platforms to ExpoStt.ts
-import { ReactEvents, } from "./ExpoStt.types";
-import ExpoSttModule from "./ExpoSttModule";
-export function startSpeech() {
- return ExpoSttModule.startSpeech();
-}
-export function stopSpeech() {
- return ExpoSttModule.stopSpeech();
-}
-export function cancelSpeech() {
- return ExpoSttModule.cancelSpeech();
-}
-export function destroySpeech() {
- return ExpoSttModule.destroySpeech();
-}
-export function requestRecognitionPermission() {
- return ExpoSttModule.requestRecognitionPermission();
-}
-export function checkRecognitionPermission() {
- return ExpoSttModule.checkRecognitionPermission();
-}
-const emitter = new EventEmitter(ExpoSttModule ?? NativeModulesProxy.ExpoStt);
-export function addOnSpeechStartListener(listener) {
- return emitter.addListener(ReactEvents.onSpeechStart, listener);
-}
-export function addOnSpeechEndListener(listener) {
- return emitter.addListener(ReactEvents.onSpeechEnd, listener);
-}
-export function addOnSpeechCancelledListener(listener) {
- return emitter.addListener(ReactEvents.onSpeechCancelled, listener);
-}
-export function addOnSpeechResultListener(listener) {
- return emitter.addListener(ReactEvents.onSpeechResult, listener);
-}
-export function addOnSpeechErrorListener(listener) {
- return emitter.addListener(ReactEvents.onSpeechError, listener);
-}
-export { ReactEvents };
-//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/build/index.js.map b/build/index.js.map
deleted file mode 100644
index a0cd2e6..0000000
--- a/build/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,YAAY,GAGb,MAAM,mBAAmB,CAAC;AAE3B,0EAA0E;AAC1E,wCAAwC;AACxC,OAAO,EAGL,WAAW,GACZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,WAAW;IACzB,OAAO,aAAa,CAAC,WAAW,EAAE,CAAC;AACrC,CAAC;AACD,MAAM,UAAU,UAAU;IACxB,OAAO,aAAa,CAAC,UAAU,EAAE,CAAC;AACpC,CAAC;AACD,MAAM,UAAU,YAAY;IAC1B,OAAO,aAAa,CAAC,YAAY,EAAE,CAAC;AACtC,CAAC;AACD,MAAM,UAAU,aAAa;IAC3B,OAAO,aAAa,CAAC,aAAa,EAAE,CAAC;AACvC,CAAC;AACD,MAAM,UAAU,4BAA4B;IAC1C,OAAO,aAAa,CAAC,4BAA4B,EAAE,CAAC;AACtD,CAAC;AACD,MAAM,UAAU,0BAA0B;IACxC,OAAO,aAAa,CAAC,0BAA0B,EAAE,CAAC;AACpD,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,aAAa,IAAI,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAE9E,MAAM,UAAU,wBAAwB,CAAC,QAAoB;IAC3D,OAAO,OAAO,CAAC,WAAW,CAAO,WAAW,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;AACxE,CAAC;AACD,MAAM,UAAU,sBAAsB,CAAC,QAAoB;IACzD,OAAO,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AAChE,CAAC;AACD,MAAM,UAAU,4BAA4B,CAC1C,QAAoB;IAEpB,OAAO,OAAO,CAAC,WAAW,CAAO,WAAW,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;AAC5E,CAAC;AACD,MAAM,UAAU,yBAAyB,CACvC,QAAqD;IAErD,OAAO,OAAO,CAAC,WAAW,CACxB,WAAW,CAAC,cAAc,EAC1B,QAAQ,CACT,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,QAAoD;IAEpD,OAAO,OAAO,CAAC,WAAW,CACxB,WAAW,CAAC,aAAa,EACzB,QAAQ,CACT,CAAC;AACJ,CAAC;AAED,OAAO,EAAyD,WAAW,EAAE,CAAC","sourcesContent":["import {\n NativeModulesProxy,\n EventEmitter,\n Subscription,\n PermissionResponse,\n} from \"expo-modules-core\";\n\n// Import the native module. On web, it will be resolved to ExpoStt.web.ts\n// and on native platforms to ExpoStt.ts\nimport {\n OnSpeechResultEventPayload,\n OnSpeechErrorEventPayload,\n ReactEvents,\n} from \"./ExpoStt.types\";\nimport ExpoSttModule from \"./ExpoSttModule\";\n\nexport function startSpeech(): boolean {\n return ExpoSttModule.startSpeech();\n}\nexport function stopSpeech(): void {\n return ExpoSttModule.stopSpeech();\n}\nexport function cancelSpeech(): void {\n return ExpoSttModule.cancelSpeech();\n}\nexport function destroySpeech(): void {\n return ExpoSttModule.destroySpeech();\n}\nexport function requestRecognitionPermission(): Promise {\n return ExpoSttModule.requestRecognitionPermission();\n}\nexport function checkRecognitionPermission(): Promise {\n return ExpoSttModule.checkRecognitionPermission();\n}\n\nconst emitter = new EventEmitter(ExpoSttModule ?? NativeModulesProxy.ExpoStt);\n\nexport function addOnSpeechStartListener(listener: () => void): Subscription {\n return emitter.addListener(ReactEvents.onSpeechStart, listener);\n}\nexport function addOnSpeechEndListener(listener: () => void): Subscription {\n return emitter.addListener(ReactEvents.onSpeechEnd, listener);\n}\nexport function addOnSpeechCancelledListener(\n listener: () => void\n): Subscription {\n return emitter.addListener(ReactEvents.onSpeechCancelled, listener);\n}\nexport function addOnSpeechResultListener(\n listener: (event: OnSpeechResultEventPayload) => void\n): Subscription {\n return emitter.addListener(\n ReactEvents.onSpeechResult,\n listener\n );\n}\n\nexport function addOnSpeechErrorListener(\n listener: (event: OnSpeechErrorEventPayload) => void\n): Subscription {\n return emitter.addListener(\n ReactEvents.onSpeechError,\n listener\n );\n}\n\nexport { OnSpeechResultEventPayload, OnSpeechErrorEventPayload, ReactEvents };\n"]}
\ No newline at end of file
diff --git a/bun.lockb b/bun.lockb
new file mode 100755
index 0000000..bc53f88
Binary files /dev/null and b/bun.lockb differ
diff --git a/example/App.tsx b/example/App.tsx
index 4e5f953..49605f6 100644
--- a/example/App.tsx
+++ b/example/App.tsx
@@ -50,10 +50,6 @@ export default function App() {
setSpokenText(value.join());
});
- const onSpeechCancelled = ExpoStt.addOnSpeechCancelledListener(() => {
- setRecognizing(false);
- });
-
const onSpeechError = ExpoStt.addOnSpeechErrorListener(({ cause }) => {
setError(cause);
setRecognizing(false);
@@ -66,7 +62,6 @@ export default function App() {
return () => {
onSpeechStart.remove();
onSpeechResult.remove();
- onSpeechCancelled.remove();
onSpeechError.remove();
onSpeechEnd.remove();
};
@@ -95,12 +90,6 @@ export default function App() {
title="Stop speech"
onPress={() => ExpoStt.stopSpeech()}
/>
-