expo-speech 11.6.0 → 12.0.0
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/CHANGELOG.md +15 -0
- package/android/build.gradle +7 -95
- package/android/src/main/java/expo/modules/speech/SpeechModule.kt +3 -3
- package/build/ExponentSpeech.web.d.ts +0 -1
- package/build/ExponentSpeech.web.d.ts.map +1 -1
- package/build/ExponentSpeech.web.js +5 -8
- package/build/ExponentSpeech.web.js.map +1 -1
- package/build/Speech.d.ts.map +1 -1
- package/build/Speech.js +5 -6
- package/build/Speech.js.map +1 -1
- package/ios/ExpoSpeech.podspec +1 -1
- package/package.json +2 -2
- package/src/Speech/ExponentSpeech.web.ts +5 -8
- package/src/Speech/Speech.ts +5 -7
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,21 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 12.0.0 — 2024-04-18
|
|
14
|
+
|
|
15
|
+
### 💡 Others
|
|
16
|
+
|
|
17
|
+
- drop unused web `name` property. ([#27437](https://github.com/expo/expo/pull/27437) by [@EvanBacon](https://github.com/EvanBacon))
|
|
18
|
+
- Removed deprecated backward compatible Gradle settings. ([#28083](https://github.com/expo/expo/pull/28083) by [@kudo](https://github.com/kudo))
|
|
19
|
+
- Removed the usage of the legacy EventEmitter. ([#28195](https://github.com/expo/expo/pull/28195) by [@tsapeta](https://github.com/tsapeta))
|
|
20
|
+
|
|
21
|
+
## 11.7.0 — 2023-11-14
|
|
22
|
+
|
|
23
|
+
### 🛠 Breaking changes
|
|
24
|
+
|
|
25
|
+
- Bumped iOS deployment target to 13.4. ([#25063](https://github.com/expo/expo/pull/25063) by [@gabrieldonadel](https://github.com/gabrieldonadel))
|
|
26
|
+
- On `Android` bump `compileSdkVersion` and `targetSdkVersion` to `34`. ([#24708](https://github.com/expo/expo/pull/24708) by [@alanjhughes](https://github.com/alanjhughes))
|
|
27
|
+
|
|
13
28
|
## 11.6.0 — 2023-10-17
|
|
14
29
|
|
|
15
30
|
### 🛠 Breaking changes
|
package/android/build.gradle
CHANGED
|
@@ -1,107 +1,19 @@
|
|
|
1
1
|
apply plugin: 'com.android.library'
|
|
2
|
-
apply plugin: 'kotlin-android'
|
|
3
|
-
apply plugin: 'maven-publish'
|
|
4
2
|
|
|
5
3
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '
|
|
4
|
+
version = '12.0.0'
|
|
7
5
|
|
|
8
6
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
useExpoPublishing()
|
|
15
|
-
useCoreDependencies()
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
buildscript {
|
|
20
|
-
// Simple helper that allows the root project to override versions declared by this library.
|
|
21
|
-
ext.safeExtGet = { prop, fallback ->
|
|
22
|
-
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Ensures backward compatibility
|
|
26
|
-
ext.getKotlinVersion = {
|
|
27
|
-
if (ext.has("kotlinVersion")) {
|
|
28
|
-
ext.kotlinVersion()
|
|
29
|
-
} else {
|
|
30
|
-
ext.safeExtGet("kotlinVersion", "1.8.10")
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
repositories {
|
|
35
|
-
mavenCentral()
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
dependencies {
|
|
39
|
-
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Remove this if and it's contents, when support for SDK49 is dropped
|
|
44
|
-
if (!safeExtGet("expoProvidesDefaultConfig", false)) {
|
|
45
|
-
afterEvaluate {
|
|
46
|
-
publishing {
|
|
47
|
-
publications {
|
|
48
|
-
release(MavenPublication) {
|
|
49
|
-
from components.release
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
repositories {
|
|
53
|
-
maven {
|
|
54
|
-
url = mavenLocal().url
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
7
|
+
apply from: expoModulesCorePlugin
|
|
8
|
+
applyKotlinExpoModulesCorePlugin()
|
|
9
|
+
useCoreDependencies()
|
|
10
|
+
useDefaultAndroidSdkVersions()
|
|
11
|
+
useExpoPublishing()
|
|
60
12
|
|
|
61
13
|
android {
|
|
62
|
-
// Remove this if and it's contents, when support for SDK49 is dropped
|
|
63
|
-
if (!safeExtGet("expoProvidesDefaultConfig", false)) {
|
|
64
|
-
compileSdkVersion safeExtGet("compileSdkVersion", 33)
|
|
65
|
-
|
|
66
|
-
defaultConfig {
|
|
67
|
-
minSdkVersion safeExtGet("minSdkVersion", 23)
|
|
68
|
-
targetSdkVersion safeExtGet("targetSdkVersion", 33)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
publishing {
|
|
72
|
-
singleVariant("release") {
|
|
73
|
-
withSourcesJar()
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
lintOptions {
|
|
78
|
-
abortOnError false
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
|
|
83
|
-
if (agpVersion.tokenize('.')[0].toInteger() < 8) {
|
|
84
|
-
compileOptions {
|
|
85
|
-
sourceCompatibility JavaVersion.VERSION_11
|
|
86
|
-
targetCompatibility JavaVersion.VERSION_11
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
kotlinOptions {
|
|
90
|
-
jvmTarget = JavaVersion.VERSION_11.majorVersion
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
14
|
namespace "expo.modules.speech"
|
|
95
15
|
defaultConfig {
|
|
96
16
|
versionCode 18
|
|
97
|
-
versionName "
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
dependencies {
|
|
102
|
-
// Remove this if and it's contents, when support for SDK49 is dropped
|
|
103
|
-
if (!safeExtGet("expoProvidesDefaultConfig", false)) {
|
|
104
|
-
implementation project(':expo-modules-core')
|
|
105
|
-
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
|
|
17
|
+
versionName "12.0.0"
|
|
106
18
|
}
|
|
107
19
|
}
|
|
@@ -36,11 +36,11 @@ class SpeechModule : Module() {
|
|
|
36
36
|
textToSpeech.shutdown()
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
AsyncFunction("isSpeaking") {
|
|
39
|
+
AsyncFunction<Boolean>("isSpeaking") {
|
|
40
40
|
textToSpeech.isSpeaking
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
AsyncFunction("getVoices") {
|
|
43
|
+
AsyncFunction<List<VoiceRecord>>("getVoices") {
|
|
44
44
|
val nativeVoices = try {
|
|
45
45
|
textToSpeech.voices.toList()
|
|
46
46
|
} catch (_: Exception) {
|
|
@@ -63,7 +63,7 @@ class SpeechModule : Module() {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
AsyncFunction("stop") {
|
|
66
|
+
AsyncFunction<Unit>("stop") {
|
|
67
67
|
textToSpeech.stop()
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SpeechOptions, WebVoice } from './Speech.types';
|
|
2
2
|
declare const _default: {
|
|
3
|
-
readonly name: string;
|
|
4
3
|
speak(id: string, text: string, options: SpeechOptions): Promise<SpeechSynthesisUtterance>;
|
|
5
4
|
getVoices(): Promise<WebVoice[]>;
|
|
6
5
|
isSpeaking(): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExponentSpeech.web.d.ts","sourceRoot":"","sources":["../src/Speech/ExponentSpeech.web.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAgB,MAAM,gBAAgB,CAAC
|
|
1
|
+
{"version":3,"file":"ExponentSpeech.web.d.ts","sourceRoot":"","sources":["../src/Speech/ExponentSpeech.web.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAgB,MAAM,gBAAgB,CAAC;;cAwBrD,MAAM,QAAQ,MAAM,WAAW,aAAa,GAAG,OAAO,CAAC,wBAAwB,CAAC;iBAiE7E,OAAO,CAAC,QAAQ,EAAE,CAAC;kBAYlB,OAAO,CAAC,OAAO,CAAC;YAGtB,OAAO,CAAC,IAAI,CAAC;aAGZ,OAAO,CAAC,IAAI,CAAC;cAGZ,OAAO,CAAC,IAAI,CAAC;;;AAvF/B,wBA2FE"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DeviceEventEmitter, CodedError } from 'expo-modules-core';
|
|
2
2
|
import { VoiceQuality } from './Speech.types';
|
|
3
3
|
//https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance/text
|
|
4
4
|
const MAX_SPEECH_INPUT_LENGTH = 32767;
|
|
@@ -18,9 +18,6 @@ async function getVoices() {
|
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
export default {
|
|
21
|
-
get name() {
|
|
22
|
-
return 'ExponentSpeech';
|
|
23
|
-
},
|
|
24
21
|
async speak(id, text, options) {
|
|
25
22
|
if (text.length > MAX_SPEECH_INPUT_LENGTH) {
|
|
26
23
|
throw new CodedError('ERR_SPEECH_INPUT_LENGTH', 'Speech input text is too long! Limit of input length is: ' + MAX_SPEECH_INPUT_LENGTH);
|
|
@@ -57,16 +54,16 @@ export default {
|
|
|
57
54
|
message.onboundary = options.onBoundary;
|
|
58
55
|
}
|
|
59
56
|
message.onstart = (nativeEvent) => {
|
|
60
|
-
|
|
57
|
+
DeviceEventEmitter.emit('Exponent.speakingStarted', { id, nativeEvent });
|
|
61
58
|
};
|
|
62
59
|
message.onend = (nativeEvent) => {
|
|
63
|
-
|
|
60
|
+
DeviceEventEmitter.emit('Exponent.speakingDone', { id, nativeEvent });
|
|
64
61
|
};
|
|
65
62
|
message.onpause = (nativeEvent) => {
|
|
66
|
-
|
|
63
|
+
DeviceEventEmitter.emit('Exponent.speakingStopped', { id, nativeEvent });
|
|
67
64
|
};
|
|
68
65
|
message.onerror = (nativeEvent) => {
|
|
69
|
-
|
|
66
|
+
DeviceEventEmitter.emit('Exponent.speakingError', { id, nativeEvent });
|
|
70
67
|
};
|
|
71
68
|
message.text = text;
|
|
72
69
|
window.speechSynthesis.speak(message);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExponentSpeech.web.js","sourceRoot":"","sources":["../src/Speech/ExponentSpeech.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ExponentSpeech.web.js","sourceRoot":"","sources":["../src/Speech/ExponentSpeech.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEnE,OAAO,EAA2B,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEvE,gFAAgF;AAChF,MAAM,uBAAuB,GAAG,KAAK,CAAC;AAEtC,KAAK,UAAU,SAAS;IACtB,OAAO,IAAI,OAAO,CAAyB,CAAC,OAAO,EAAE,EAAE;QACrD,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,SAAS,EAAE,CAAC;QAElD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,CAAC;YAChB,OAAO;QACT,CAAC;QAED,6EAA6E;QAC7E,mDAAmD;QACnD,MAAM,CAAC,eAAe,CAAC,eAAe,GAAG;YACvC,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,SAAS,EAAE,CAAC;YAClD,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,eAAe;IACb,KAAK,CAAC,KAAK,CAAC,EAAU,EAAE,IAAY,EAAE,OAAsB;QAC1D,IAAI,IAAI,CAAC,MAAM,GAAG,uBAAuB,EAAE,CAAC;YAC1C,MAAM,IAAI,UAAU,CAClB,yBAAyB,EACzB,2DAA2D,GAAG,uBAAuB,CACtF,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,wBAAwB,EAAE,CAAC;QAE/C,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QAC9B,CAAC;QACD,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACtC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAChC,CAAC;QACD,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACzC,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC;QAClC,CAAC;QACD,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACvC,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAClC,CAAC;QACD,IAAI,aAAa,IAAI,OAAO,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;YAC5D,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACxF,CAAC;QACD,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK;gBACX,MAAM,CACJ,IAAI,CAAC,GAAG,CACN,CAAC,EACD,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,KAAK,CAAC,CAC9D,CACF,CAAC;QACN,CAAC;QACD,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;YAC3C,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACtC,CAAC;QACD,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YACzC,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAClC,CAAC;QACD,IAAI,OAAO,OAAO,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;YAC7C,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QAC1C,CAAC;QAED,OAAO,CAAC,OAAO,GAAG,CAAC,WAAiC,EAAE,EAAE;YACtD,kBAAkB,CAAC,IAAI,CAAC,0BAA0B,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;QAC3E,CAAC,CAAC;QACF,OAAO,CAAC,KAAK,GAAG,CAAC,WAAiC,EAAE,EAAE;YACpD,kBAAkB,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;QACxE,CAAC,CAAC;QACF,OAAO,CAAC,OAAO,GAAG,CAAC,WAAiC,EAAE,EAAE;YACtD,kBAAkB,CAAC,IAAI,CAAC,0BAA0B,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;QAC3E,CAAC,CAAC;QACF,OAAO,CAAC,OAAO,GAAG,CAAC,WAAsC,EAAE,EAAE;YAC3D,kBAAkB,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;QACzE,CAAC,CAAC;QAEF,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;QAEpB,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEtC,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,KAAK,CAAC,SAAS;QACb,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC5B,UAAU,EAAE,KAAK,CAAC,QAAQ;YAC1B,OAAO,EAAE,YAAY,CAAC,OAAO;YAC7B,SAAS,EAAE,KAAK,CAAC,OAAO;YACxB,QAAQ,EAAE,KAAK,CAAC,IAAI;YACpB,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;SACzB,CAAC,CAAC,CAAC;IACN,CAAC;IACD,KAAK,CAAC,UAAU;QACd,OAAO,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC;IACzC,CAAC;IACD,KAAK,CAAC,IAAI;QACR,OAAO,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;IACzC,CAAC;IACD,KAAK,CAAC,KAAK;QACT,OAAO,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IACxC,CAAC;IACD,KAAK,CAAC,MAAM;QACV,OAAO,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;IACzC,CAAC;IACD,oBAAoB,EAAE,uBAAuB;CAC9C,CAAC","sourcesContent":["import { DeviceEventEmitter, CodedError } from 'expo-modules-core';\n\nimport { SpeechOptions, WebVoice, VoiceQuality } from './Speech.types';\n\n//https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance/text\nconst MAX_SPEECH_INPUT_LENGTH = 32767;\n\nasync function getVoices(): Promise<SpeechSynthesisVoice[]> {\n return new Promise<SpeechSynthesisVoice[]>((resolve) => {\n const voices = window.speechSynthesis.getVoices();\n\n if (voices.length > 0) {\n resolve(voices);\n return;\n }\n\n // when a page loads it takes some amount of time to populate the voices list\n // see https://stackoverflow.com/a/52005323/4337317\n window.speechSynthesis.onvoiceschanged = function () {\n const voices = window.speechSynthesis.getVoices();\n resolve(voices);\n };\n });\n}\n\nexport default {\n async speak(id: string, text: string, options: SpeechOptions): Promise<SpeechSynthesisUtterance> {\n if (text.length > MAX_SPEECH_INPUT_LENGTH) {\n throw new CodedError(\n 'ERR_SPEECH_INPUT_LENGTH',\n 'Speech input text is too long! Limit of input length is: ' + MAX_SPEECH_INPUT_LENGTH\n );\n }\n\n const message = new SpeechSynthesisUtterance();\n\n if (typeof options.rate === 'number') {\n message.rate = options.rate;\n }\n if (typeof options.pitch === 'number') {\n message.pitch = options.pitch;\n }\n if (typeof options.language === 'string') {\n message.lang = options.language;\n }\n if (typeof options.volume === 'number') {\n message.volume = options.volume;\n }\n if ('_voiceIndex' in options && options._voiceIndex != null) {\n const voices = await getVoices();\n message.voice = voices[Math.min(voices.length - 1, Math.max(0, options._voiceIndex))];\n }\n if (typeof options.voice === 'string') {\n const voices = await getVoices();\n message.voice =\n voices[\n Math.max(\n 0,\n voices.findIndex((voice) => voice.voiceURI === options.voice)\n )\n ];\n }\n if (typeof options.onResume === 'function') {\n message.onresume = options.onResume;\n }\n if (typeof options.onMark === 'function') {\n message.onmark = options.onMark;\n }\n if (typeof options.onBoundary === 'function') {\n message.onboundary = options.onBoundary;\n }\n\n message.onstart = (nativeEvent: SpeechSynthesisEvent) => {\n DeviceEventEmitter.emit('Exponent.speakingStarted', { id, nativeEvent });\n };\n message.onend = (nativeEvent: SpeechSynthesisEvent) => {\n DeviceEventEmitter.emit('Exponent.speakingDone', { id, nativeEvent });\n };\n message.onpause = (nativeEvent: SpeechSynthesisEvent) => {\n DeviceEventEmitter.emit('Exponent.speakingStopped', { id, nativeEvent });\n };\n message.onerror = (nativeEvent: SpeechSynthesisErrorEvent) => {\n DeviceEventEmitter.emit('Exponent.speakingError', { id, nativeEvent });\n };\n\n message.text = text;\n\n window.speechSynthesis.speak(message);\n\n return message;\n },\n async getVoices(): Promise<WebVoice[]> {\n const voices = await getVoices();\n return voices.map((voice) => ({\n identifier: voice.voiceURI,\n quality: VoiceQuality.Default,\n isDefault: voice.default,\n language: voice.lang,\n localService: voice.localService,\n name: voice.name,\n voiceURI: voice.voiceURI,\n }));\n },\n async isSpeaking(): Promise<boolean> {\n return window.speechSynthesis.speaking;\n },\n async stop(): Promise<void> {\n return window.speechSynthesis.cancel();\n },\n async pause(): Promise<void> {\n return window.speechSynthesis.pause();\n },\n async resume(): Promise<void> {\n return window.speechSynthesis.resume();\n },\n maxSpeechInputLength: MAX_SPEECH_INPUT_LENGTH,\n};\n"]}
|
package/build/Speech.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Speech.d.ts","sourceRoot":"","sources":["../src/Speech/Speech.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Speech.d.ts","sourceRoot":"","sources":["../src/Speech/Speech.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAEnG,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AA8D7E;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,QAK9D;AAGD;;;GAGG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAKhE;AAGD;;;;GAIG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAExD;AAGD;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAE1C;AAGD;;GAEG;AACH,wBAAsB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAK3C;AAGD;;;GAGG;AACH,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAM5C;AAeD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAgE,CAAC"}
|
package/build/Speech.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { UnavailabilityError
|
|
1
|
+
import { UnavailabilityError } from 'expo-modules-core';
|
|
2
2
|
import ExponentSpeech from './ExponentSpeech';
|
|
3
3
|
import { VoiceQuality } from './Speech.types';
|
|
4
|
-
const SpeechEventEmitter = new EventEmitter(ExponentSpeech);
|
|
5
4
|
export { VoiceQuality };
|
|
6
5
|
const _CALLBACKS = {};
|
|
7
6
|
let _nextCallbackId = 1;
|
|
@@ -122,14 +121,14 @@ export async function resume() {
|
|
|
122
121
|
return ExponentSpeech.resume();
|
|
123
122
|
}
|
|
124
123
|
function setSpeakingListener(eventName, callback) {
|
|
125
|
-
const listenerCount =
|
|
124
|
+
const listenerCount = ExponentSpeech.listenerCount(eventName);
|
|
126
125
|
if (listenerCount > 0) {
|
|
127
|
-
|
|
126
|
+
ExponentSpeech.removeAllListeners(eventName);
|
|
128
127
|
}
|
|
129
|
-
|
|
128
|
+
ExponentSpeech.addListener(eventName, callback);
|
|
130
129
|
}
|
|
131
130
|
function removeSpeakingListener(eventName) {
|
|
132
|
-
|
|
131
|
+
ExponentSpeech.removeAllListeners(eventName);
|
|
133
132
|
}
|
|
134
133
|
// @needsAudit
|
|
135
134
|
/**
|
package/build/Speech.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Speech.js","sourceRoot":"","sources":["../src/Speech/Speech.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"Speech.js","sourceRoot":"","sources":["../src/Speech/Speech.ts"],"names":[],"mappings":"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","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\n\nimport ExponentSpeech from './ExponentSpeech';\nimport { SpeechOptions, SpeechEventCallback, VoiceQuality, Voice, WebVoice } from './Speech.types';\n\nexport { SpeechOptions, SpeechEventCallback, VoiceQuality, Voice, WebVoice };\n\nconst _CALLBACKS = {};\nlet _nextCallbackId = 1;\nlet _didSetListeners = false;\n\nfunction _unregisterListenersIfNeeded() {\n if (Object.keys(_CALLBACKS).length === 0) {\n removeSpeakingListener('Exponent.speakingStarted');\n removeSpeakingListener('Exponent.speakingWillSayNextString');\n removeSpeakingListener('Exponent.speakingDone');\n removeSpeakingListener('Exponent.speakingStopped');\n removeSpeakingListener('Exponent.speakingError');\n _didSetListeners = false;\n }\n}\n\nfunction _registerListenersIfNeeded() {\n if (_didSetListeners) return;\n _didSetListeners = true;\n setSpeakingListener('Exponent.speakingStarted', ({ id }) => {\n const options = _CALLBACKS[id];\n if (options && options.onStart) {\n options.onStart();\n }\n });\n setSpeakingListener('Exponent.speakingWillSayNextString', ({ id, charIndex, charLength }) => {\n const options = _CALLBACKS[id];\n if (options && options.onBoundary) {\n options.onBoundary({\n charIndex,\n charLength,\n });\n }\n });\n setSpeakingListener('Exponent.speakingDone', ({ id }) => {\n const options = _CALLBACKS[id];\n if (options && options.onDone) {\n options.onDone();\n }\n delete _CALLBACKS[id];\n _unregisterListenersIfNeeded();\n });\n setSpeakingListener('Exponent.speakingStopped', ({ id }) => {\n const options = _CALLBACKS[id];\n if (options && options.onStopped) {\n options.onStopped();\n }\n delete _CALLBACKS[id];\n _unregisterListenersIfNeeded();\n });\n setSpeakingListener('Exponent.speakingError', ({ id, error }) => {\n const options = _CALLBACKS[id];\n if (options && options.onError) {\n options.onError(new Error(error));\n }\n delete _CALLBACKS[id];\n _unregisterListenersIfNeeded();\n });\n}\n\n// @needsAudit\n/**\n * Speak out loud the text given options. Calling this when another text is being spoken adds\n * an utterance to queue.\n * @param text The text to be spoken. Cannot be longer than [`Speech.maxSpeechInputLength`](#speechmaxspeechinputlength).\n * @param options A `SpeechOptions` object.\n */\nexport function speak(text: string, options: SpeechOptions = {}) {\n const id = _nextCallbackId++;\n _CALLBACKS[id] = options;\n _registerListenersIfNeeded();\n ExponentSpeech.speak(String(id), text, options);\n}\n\n// @needsAudit\n/**\n * Returns list of all available voices.\n * @return List of `Voice` objects.\n */\nexport async function getAvailableVoicesAsync(): Promise<Voice[]> {\n if (!ExponentSpeech.getVoices) {\n throw new UnavailabilityError('Speech', 'getVoices');\n }\n return ExponentSpeech.getVoices();\n}\n\n//@needsAudit\n/**\n * Determine whether the Text-to-speech utility is currently speaking. Will return `true` if speaker\n * is paused.\n * @return Returns a Promise that fulfils with a boolean, `true` if speaking, `false` if not.\n */\nexport async function isSpeakingAsync(): Promise<boolean> {\n return ExponentSpeech.isSpeaking();\n}\n\n// @needsAudit\n/**\n * Interrupts current speech and deletes all in queue.\n */\nexport async function stop(): Promise<void> {\n return ExponentSpeech.stop();\n}\n\n// @needsAudit\n/**\n * Pauses current speech. This method is not available on Android.\n */\nexport async function pause(): Promise<void> {\n if (!ExponentSpeech.pause) {\n throw new UnavailabilityError('Speech', 'pause');\n }\n return ExponentSpeech.pause();\n}\n\n// @needsAudit\n/**\n * Resumes speaking previously paused speech or does nothing if there's none. This method is not\n * available on Android.\n */\nexport async function resume(): Promise<void> {\n if (!ExponentSpeech.resume) {\n throw new UnavailabilityError('Speech', 'resume');\n }\n\n return ExponentSpeech.resume();\n}\n\nfunction setSpeakingListener(eventName, callback) {\n const listenerCount = ExponentSpeech.listenerCount(eventName);\n if (listenerCount > 0) {\n ExponentSpeech.removeAllListeners(eventName);\n }\n ExponentSpeech.addListener(eventName, callback);\n}\n\nfunction removeSpeakingListener(eventName) {\n ExponentSpeech.removeAllListeners(eventName);\n}\n\n// @needsAudit\n/**\n * Maximum possible text length acceptable by `Speech.speak()` method. It is platform-dependent.\n * On iOS, this returns `Number.MAX_VALUE`.\n */\nexport const maxSpeechInputLength: number = ExponentSpeech.maxSpeechInputLength || Number.MAX_VALUE;\n"]}
|
package/ios/ExpoSpeech.podspec
CHANGED
|
@@ -10,7 +10,7 @@ Pod::Spec.new do |s|
|
|
|
10
10
|
s.license = package['license']
|
|
11
11
|
s.author = package['author']
|
|
12
12
|
s.homepage = package['homepage']
|
|
13
|
-
s.platform = :ios, '13.
|
|
13
|
+
s.platform = :ios, '13.4'
|
|
14
14
|
s.swift_version = '5.4'
|
|
15
15
|
s.source = { git: 'https://github.com/expo/expo.git' }
|
|
16
16
|
s.static_framework = true
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-speech",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.0.0",
|
|
4
4
|
"description": "Provides text-to-speech functionality.",
|
|
5
5
|
"main": "build/Speech.js",
|
|
6
6
|
"types": "build/Speech.d.ts",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"expo": "*"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "4165b8d72e1b9a1889c2767534cc619e21468110"
|
|
46
46
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DeviceEventEmitter, CodedError } from 'expo-modules-core';
|
|
2
2
|
|
|
3
3
|
import { SpeechOptions, WebVoice, VoiceQuality } from './Speech.types';
|
|
4
4
|
|
|
@@ -24,9 +24,6 @@ async function getVoices(): Promise<SpeechSynthesisVoice[]> {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export default {
|
|
27
|
-
get name(): string {
|
|
28
|
-
return 'ExponentSpeech';
|
|
29
|
-
},
|
|
30
27
|
async speak(id: string, text: string, options: SpeechOptions): Promise<SpeechSynthesisUtterance> {
|
|
31
28
|
if (text.length > MAX_SPEECH_INPUT_LENGTH) {
|
|
32
29
|
throw new CodedError(
|
|
@@ -74,16 +71,16 @@ export default {
|
|
|
74
71
|
}
|
|
75
72
|
|
|
76
73
|
message.onstart = (nativeEvent: SpeechSynthesisEvent) => {
|
|
77
|
-
|
|
74
|
+
DeviceEventEmitter.emit('Exponent.speakingStarted', { id, nativeEvent });
|
|
78
75
|
};
|
|
79
76
|
message.onend = (nativeEvent: SpeechSynthesisEvent) => {
|
|
80
|
-
|
|
77
|
+
DeviceEventEmitter.emit('Exponent.speakingDone', { id, nativeEvent });
|
|
81
78
|
};
|
|
82
79
|
message.onpause = (nativeEvent: SpeechSynthesisEvent) => {
|
|
83
|
-
|
|
80
|
+
DeviceEventEmitter.emit('Exponent.speakingStopped', { id, nativeEvent });
|
|
84
81
|
};
|
|
85
82
|
message.onerror = (nativeEvent: SpeechSynthesisErrorEvent) => {
|
|
86
|
-
|
|
83
|
+
DeviceEventEmitter.emit('Exponent.speakingError', { id, nativeEvent });
|
|
87
84
|
};
|
|
88
85
|
|
|
89
86
|
message.text = text;
|
package/src/Speech/Speech.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { UnavailabilityError
|
|
1
|
+
import { UnavailabilityError } from 'expo-modules-core';
|
|
2
2
|
|
|
3
3
|
import ExponentSpeech from './ExponentSpeech';
|
|
4
4
|
import { SpeechOptions, SpeechEventCallback, VoiceQuality, Voice, WebVoice } from './Speech.types';
|
|
5
5
|
|
|
6
|
-
const SpeechEventEmitter = new EventEmitter(ExponentSpeech);
|
|
7
|
-
|
|
8
6
|
export { SpeechOptions, SpeechEventCallback, VoiceQuality, Voice, WebVoice };
|
|
9
7
|
|
|
10
8
|
const _CALLBACKS = {};
|
|
@@ -135,15 +133,15 @@ export async function resume(): Promise<void> {
|
|
|
135
133
|
}
|
|
136
134
|
|
|
137
135
|
function setSpeakingListener(eventName, callback) {
|
|
138
|
-
const listenerCount =
|
|
136
|
+
const listenerCount = ExponentSpeech.listenerCount(eventName);
|
|
139
137
|
if (listenerCount > 0) {
|
|
140
|
-
|
|
138
|
+
ExponentSpeech.removeAllListeners(eventName);
|
|
141
139
|
}
|
|
142
|
-
|
|
140
|
+
ExponentSpeech.addListener(eventName, callback);
|
|
143
141
|
}
|
|
144
142
|
|
|
145
143
|
function removeSpeakingListener(eventName) {
|
|
146
|
-
|
|
144
|
+
ExponentSpeech.removeAllListeners(eventName);
|
|
147
145
|
}
|
|
148
146
|
|
|
149
147
|
// @needsAudit
|