@focus8/expo-acapela-tts 0.1.5 → 0.1.9

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 (33) hide show
  1. package/.eslintrc.js +0 -0
  2. package/README.md +0 -0
  3. package/android/build.gradle +7 -0
  4. package/android/libs/acattsandroid-sdk-library-release.aar +0 -0
  5. package/android/src/main/AndroidManifest.xml +0 -0
  6. package/android/src/main/java/expo/modules/acapelatts/ExpoAcapelaTtsModule.kt +72 -8
  7. package/android/src/main/jniLibs/arm64-v8a/libacattsandroid.so +0 -0
  8. package/android/src/main/jniLibs/armeabi-v7a/libacattsandroid.so +0 -0
  9. package/android/src/main/jniLibs/x86/libacattsandroid.so +0 -0
  10. package/android/src/main/jniLibs/x86_64/libacattsandroid.so +0 -0
  11. package/build/ExpoAcapelaTts.types.d.ts +0 -0
  12. package/build/ExpoAcapelaTts.types.d.ts.map +0 -0
  13. package/build/ExpoAcapelaTts.types.js +0 -0
  14. package/build/ExpoAcapelaTts.types.js.map +0 -0
  15. package/build/ExpoAcapelaTtsModule.android.d.ts +2 -0
  16. package/build/ExpoAcapelaTtsModule.android.d.ts.map +1 -1
  17. package/build/ExpoAcapelaTtsModule.android.js +0 -0
  18. package/build/ExpoAcapelaTtsModule.android.js.map +1 -1
  19. package/build/ExpoAcapelaTtsModule.d.ts +2 -0
  20. package/build/ExpoAcapelaTtsModule.d.ts.map +1 -1
  21. package/build/ExpoAcapelaTtsModule.js +6 -0
  22. package/build/ExpoAcapelaTtsModule.js.map +1 -1
  23. package/build/index.d.ts +0 -0
  24. package/build/index.d.ts.map +0 -0
  25. package/build/index.js +0 -0
  26. package/build/index.js.map +0 -0
  27. package/expo-module.config.json +0 -0
  28. package/package.json +1 -1
  29. package/src/ExpoAcapelaTts.types.ts +0 -0
  30. package/src/ExpoAcapelaTtsModule.android.ts +2 -0
  31. package/src/ExpoAcapelaTtsModule.ts +6 -0
  32. package/src/index.ts +0 -0
  33. package/tsconfig.json +0 -0
package/.eslintrc.js CHANGED
File without changes
package/README.md CHANGED
File without changes
@@ -32,6 +32,13 @@ android {
32
32
  defaultConfig {
33
33
  versionCode 1
34
34
  versionName "0.1.0"
35
+
36
+ buildConfigField "long", "ACAPELA_USER_ID", "${System.getenv('ACAPELA_USER_ID') ?: '0'}L"
37
+ buildConfigField "long", "ACAPELA_PASSWORD", "${System.getenv('ACAPELA_PASSWORD') ?: '0'}L"
38
+ buildConfigField "String", "ACAPELA_LICENSE_KEY", "\"${System.getenv('ACAPELA_LICENSE_KEY') ?: ''}\""
39
+ }
40
+ buildFeatures {
41
+ buildConfig true
35
42
  }
36
43
  lintOptions {
37
44
  abortOnError false
File without changes
@@ -1,8 +1,14 @@
1
1
  package expo.modules.acapelatts
2
2
 
3
+ import android.Manifest
4
+ import android.content.Intent
5
+ import android.content.pm.PackageManager
6
+ import android.net.Uri
3
7
  import android.os.Build
4
8
  import android.os.Environment
9
+ import android.provider.Settings
5
10
  import android.util.Log
11
+ import androidx.core.content.ContextCompat
6
12
  import com.acapelagroup.android.tts.acattsandroid
7
13
  import com.acapelagroup.android.tts.acattsandroid.iTTSEventsCallback
8
14
  import expo.modules.kotlin.modules.Module
@@ -42,9 +48,43 @@ class ExpoAcapelaTtsModule : Module(), iTTSEventsCallback {
42
48
  Events("onSpeechStart", "onSpeechEnd", "onError")
43
49
 
44
50
  Function("hasStoragePermission") {
51
+ hasStorageAccess()
52
+ }
53
+
54
+ AsyncFunction("requestStoragePermissionAsync") {
55
+ val context = appContext.reactContext ?: return@AsyncFunction false
56
+
57
+ if (hasStorageAccess()) {
58
+ logInfo("Storage permission already granted")
59
+ return@AsyncFunction true
60
+ }
61
+
45
62
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
46
- Environment.isExternalStorageManager()
63
+ // Android 11+ needs MANAGE_EXTERNAL_STORAGE via Settings intent
64
+ try {
65
+ val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).apply {
66
+ data = Uri.fromParts("package", context.packageName, null)
67
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
68
+ }
69
+ context.startActivity(intent)
70
+ logInfo("Launched MANAGE_EXTERNAL_STORAGE settings for ${context.packageName}")
71
+ } catch (e: Exception) {
72
+ // Fallback for devices that don't support the per-app intent
73
+ try {
74
+ val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION).apply {
75
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
76
+ }
77
+ context.startActivity(intent)
78
+ } catch (e2: Exception) {
79
+ logError("Failed to launch storage permission settings", e2)
80
+ return@AsyncFunction false
81
+ }
82
+ }
83
+ // User needs to grant in settings and come back - we can't wait for result
84
+ false
47
85
  } else {
86
+ // Pre-Android 11: READ_EXTERNAL_STORAGE is enough, granted via manifest on enrolled AOSP
87
+ logInfo("Pre-Android 11: storage permissions handled by manifest")
48
88
  true
49
89
  }
50
90
  }
@@ -73,11 +113,11 @@ class ExpoAcapelaTtsModule : Module(), iTTSEventsCallback {
73
113
  }
74
114
  }
75
115
 
76
- Function("setLicense") { userId: Long, password: Long, key: String ->
77
- licenseUserId = userId
78
- licensePassword = password
116
+ Function("setLicense") { userId: Double, password: Double, key: String ->
117
+ licenseUserId = userId.toLong()
118
+ licensePassword = password.toLong()
79
119
  licenseKey = key
80
- logInfo("License set")
120
+ logInfo("License set: userId=0x${java.lang.Long.toHexString(licenseUserId!!)} password=0x${java.lang.Long.toHexString(licensePassword!!)}")
81
121
  }
82
122
 
83
123
  AsyncFunction("initializeAsync") {
@@ -91,8 +131,13 @@ class ExpoAcapelaTtsModule : Module(), iTTSEventsCallback {
91
131
  return@AsyncFunction true
92
132
  }
93
133
 
94
- if (licenseUserId == null || licensePassword == null || licenseKey == null) {
95
- logWarning("Cannot initialize: license not set. Call setLicense() first.")
134
+ // Use BuildConfig values as fallback if setLicense() was not called from JS
135
+ val uid = licenseUserId ?: BuildConfig.ACAPELA_USER_ID
136
+ val pwd = licensePassword ?: BuildConfig.ACAPELA_PASSWORD
137
+ val key = licenseKey ?: BuildConfig.ACAPELA_LICENSE_KEY
138
+
139
+ if (uid == 0L || key.isNullOrEmpty()) {
140
+ logWarning("Cannot initialize: no license configured (neither via setLicense() nor BuildConfig)")
96
141
  return@AsyncFunction false
97
142
  }
98
143
 
@@ -104,7 +149,13 @@ class ExpoAcapelaTtsModule : Module(), iTTSEventsCallback {
104
149
 
105
150
  tts = acattsandroid(context, this@ExpoAcapelaTtsModule, null)
106
151
  tts!!.setLog(true)
107
- tts!!.setLicense(licenseUserId!!, licensePassword!!, licenseKey)
152
+ logInfo("setLicense userId=0x${java.lang.Long.toHexString(uid)} password=0x${java.lang.Long.toHexString(pwd)} keyLength=${key?.length}")
153
+ tts!!.setLicense(uid, pwd, key)
154
+
155
+ // Store for re-use after getVoicesList
156
+ licenseUserId = uid
157
+ licensePassword = pwd
158
+ licenseKey = key
108
159
 
109
160
  val version = tts!!.version
110
161
  logInfo("Initialized, SDK version: $version")
@@ -138,6 +189,10 @@ class ExpoAcapelaTtsModule : Module(), iTTSEventsCallback {
138
189
  }
139
190
  }
140
191
  val voicesList = tts!!.getVoicesList(voiceDirPaths) ?: emptyArray()
192
+ // Re-set license after getVoicesList as it may reset internal state
193
+ if (licenseUserId != null && licensePassword != null && licenseKey != null) {
194
+ tts!!.setLicense(licenseUserId!!, licensePassword!!, licenseKey)
195
+ }
141
196
  logInfo("Found ${voicesList.size} voices")
142
197
  for (v in voicesList) {
143
198
  logInfo(" Voice: $v")
@@ -297,6 +352,15 @@ class ExpoAcapelaTtsModule : Module(), iTTSEventsCallback {
297
352
  }
298
353
  }
299
354
 
355
+ private fun hasStorageAccess(): Boolean {
356
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
357
+ Environment.isExternalStorageManager()
358
+ } else {
359
+ val context = appContext.reactContext ?: return false
360
+ ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
361
+ }
362
+ }
363
+
300
364
  private fun extractSpeakerName(voiceFileName: String): String {
301
365
  // Voice file names like "non_kari_22k_ns.qvcu" -> "Kari"
302
366
  // Or voice names like "hq-ref-Norwegian-Kari-22khz" -> "Kari"
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -2,6 +2,8 @@ import { NativeModule } from 'expo';
2
2
  import { AcapelaVoice, ExpoAcapelaTtsModuleEvents } from './ExpoAcapelaTts.types';
3
3
  declare class ExpoAcapelaTtsModule extends NativeModule<ExpoAcapelaTtsModuleEvents> {
4
4
  isAvailable(): boolean;
5
+ hasStoragePermission(): boolean;
6
+ requestStoragePermissionAsync(): Promise<boolean>;
5
7
  addVoicePath(path: string): void;
6
8
  setLicense(userId: number, password: number, key: string): void;
7
9
  initializeAsync(): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoAcapelaTtsModule.android.d.ts","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.android.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,MAAM,CAAC;AAEzD,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC3B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,OAAO,oBAAqB,SAAQ,YAAY,CAAC,0BAA0B,CAAC;IACjF,WAAW,IAAI,OAAO;IACtB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAChC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAC/D,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IACnC,cAAc,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IACzC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IACnD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IACzC,IAAI,IAAI,IAAI;IACZ,UAAU,IAAI,OAAO;IACrB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC7B,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAClC,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CAC/B;;AAED,wBAA2E"}
1
+ {"version":3,"file":"ExpoAcapelaTtsModule.android.d.ts","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.android.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,MAAM,CAAC;AAEzD,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC3B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,OAAO,oBAAqB,SAAQ,YAAY,CAAC,0BAA0B,CAAC;IACjF,WAAW,IAAI,OAAO;IACtB,oBAAoB,IAAI,OAAO;IAC/B,6BAA6B,IAAI,OAAO,CAAC,OAAO,CAAC;IACjD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAChC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAC/D,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IACnC,cAAc,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IACzC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IACnD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IACzC,IAAI,IAAI,IAAI;IACZ,UAAU,IAAI,OAAO;IACrB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC7B,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAClC,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CAC/B;;AAED,wBAA2E"}
File without changes
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoAcapelaTtsModule.android.js","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.android.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAuBzD,eAAe,mBAAmB,CAAuB,gBAAgB,CAAC,CAAC","sourcesContent":["import { NativeModule, requireNativeModule } from 'expo';\n\nimport {\n AcapelaVoice,\n ExpoAcapelaTtsModuleEvents,\n} from './ExpoAcapelaTts.types';\n\ndeclare class ExpoAcapelaTtsModule extends NativeModule<ExpoAcapelaTtsModuleEvents> {\n isAvailable(): boolean;\n addVoicePath(path: string): void;\n setLicense(userId: number, password: number, key: string): void;\n initializeAsync(): Promise<boolean>;\n getVoicesAsync(): Promise<AcapelaVoice[]>;\n loadVoiceAsync(voiceName: string): Promise<boolean>;\n speakAsync(text: string): Promise<number>;\n stop(): void;\n isSpeaking(): boolean;\n setSpeechRate(rate: number): void;\n setPitch(pitch: number): void;\n setAudioBoost(boost: number): void;\n shutdownAsync(): Promise<void>;\n}\n\nexport default requireNativeModule<ExpoAcapelaTtsModule>('ExpoAcapelaTts');\n"]}
1
+ {"version":3,"file":"ExpoAcapelaTtsModule.android.js","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.android.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAyBzD,eAAe,mBAAmB,CAAuB,gBAAgB,CAAC,CAAC","sourcesContent":["import { NativeModule, requireNativeModule } from 'expo';\n\nimport {\n AcapelaVoice,\n ExpoAcapelaTtsModuleEvents,\n} from './ExpoAcapelaTts.types';\n\ndeclare class ExpoAcapelaTtsModule extends NativeModule<ExpoAcapelaTtsModuleEvents> {\n isAvailable(): boolean;\n hasStoragePermission(): boolean;\n requestStoragePermissionAsync(): Promise<boolean>;\n addVoicePath(path: string): void;\n setLicense(userId: number, password: number, key: string): void;\n initializeAsync(): Promise<boolean>;\n getVoicesAsync(): Promise<AcapelaVoice[]>;\n loadVoiceAsync(voiceName: string): Promise<boolean>;\n speakAsync(text: string): Promise<number>;\n stop(): void;\n isSpeaking(): boolean;\n setSpeechRate(rate: number): void;\n setPitch(pitch: number): void;\n setAudioBoost(boost: number): void;\n shutdownAsync(): Promise<void>;\n}\n\nexport default requireNativeModule<ExpoAcapelaTtsModule>('ExpoAcapelaTts');\n"]}
@@ -1,5 +1,7 @@
1
1
  declare const _default: {
2
2
  isAvailable(): boolean;
3
+ hasStoragePermission(): boolean;
4
+ requestStoragePermissionAsync(): Promise<boolean>;
3
5
  addVoicePath(_path: string): void;
4
6
  setLicense(_userId: number, _password: number, _key: string): void;
5
7
  initializeAsync(): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoAcapelaTtsModule.d.ts","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.ts"],"names":[],"mappings":";mBAEiB,OAAO;wBAGF,MAAM;wBACN,MAAM,aAAa,MAAM,QAAQ,MAAM;uBAClC,OAAO,CAAC,OAAO,CAAC;;+BAMR,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;sBAGlC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;;kBAIlC,OAAO;yBAGA,MAAM;qBACV,MAAM;0BACD,MAAM;;;;;;;AAxB9B,wBA8BE"}
1
+ {"version":3,"file":"ExpoAcapelaTtsModule.d.ts","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.ts"],"names":[],"mappings":";mBAEiB,OAAO;4BAGE,OAAO;qCAGQ,OAAO,CAAC,OAAO,CAAC;wBAGnC,MAAM;wBACN,MAAM,aAAa,MAAM,QAAQ,MAAM;uBAClC,OAAO,CAAC,OAAO,CAAC;;+BAMR,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;sBAGlC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;;kBAIlC,OAAO;yBAGA,MAAM;qBACV,MAAM;0BACD,MAAM;;;;;;;AA9B9B,wBAoCE"}
@@ -3,6 +3,12 @@ export default {
3
3
  isAvailable() {
4
4
  return false;
5
5
  },
6
+ hasStoragePermission() {
7
+ return true;
8
+ },
9
+ async requestStoragePermissionAsync() {
10
+ return true;
11
+ },
6
12
  addVoicePath(_path) { },
7
13
  setLicense(_userId, _password, _key) { },
8
14
  async initializeAsync() {
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoAcapelaTtsModule.js","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,eAAe;IACb,WAAW;QACT,OAAO,KAAK,CAAC;IACf,CAAC;IACD,YAAY,CAAC,KAAa,IAAG,CAAC;IAC9B,UAAU,CAAC,OAAe,EAAE,SAAiB,EAAE,IAAY,IAAG,CAAC;IAC/D,KAAK,CAAC,eAAe;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,cAAc;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK,CAAC,cAAc,CAAC,UAAkB;QACrC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,KAAa;QAC5B,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IACD,IAAI,KAAI,CAAC;IACT,UAAU;QACR,OAAO,KAAK,CAAC;IACf,CAAC;IACD,aAAa,CAAC,KAAa,IAAG,CAAC;IAC/B,QAAQ,CAAC,MAAc,IAAG,CAAC;IAC3B,aAAa,CAAC,MAAc,IAAG,CAAC;IAChC,KAAK,CAAC,aAAa,KAAI,CAAC;IACxB,WAAW;QACT,OAAO,EAAE,MAAM,KAAI,CAAC,EAAE,CAAC;IACzB,CAAC;IACD,eAAe,KAAI,CAAC;CACrB,CAAC","sourcesContent":["// No-op stub for non-Android platforms\nexport default {\n isAvailable(): boolean {\n return false;\n },\n addVoicePath(_path: string) {},\n setLicense(_userId: number, _password: number, _key: string) {},\n async initializeAsync(): Promise<boolean> {\n return false;\n },\n async getVoicesAsync() {\n return [];\n },\n async loadVoiceAsync(_voiceName: string): Promise<boolean> {\n return false;\n },\n async speakAsync(_text: string): Promise<number> {\n return -1;\n },\n stop() {},\n isSpeaking(): boolean {\n return false;\n },\n setSpeechRate(_rate: number) {},\n setPitch(_pitch: number) {},\n setAudioBoost(_boost: number) {},\n async shutdownAsync() {},\n addListener() {\n return { remove() {} };\n },\n removeListeners() {},\n};\n"]}
1
+ {"version":3,"file":"ExpoAcapelaTtsModule.js","sourceRoot":"","sources":["../src/ExpoAcapelaTtsModule.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,eAAe;IACb,WAAW;QACT,OAAO,KAAK,CAAC;IACf,CAAC;IACD,oBAAoB;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,KAAK,CAAC,6BAA6B;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,YAAY,CAAC,KAAa,IAAG,CAAC;IAC9B,UAAU,CAAC,OAAe,EAAE,SAAiB,EAAE,IAAY,IAAG,CAAC;IAC/D,KAAK,CAAC,eAAe;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,cAAc;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK,CAAC,cAAc,CAAC,UAAkB;QACrC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,KAAa;QAC5B,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IACD,IAAI,KAAI,CAAC;IACT,UAAU;QACR,OAAO,KAAK,CAAC;IACf,CAAC;IACD,aAAa,CAAC,KAAa,IAAG,CAAC;IAC/B,QAAQ,CAAC,MAAc,IAAG,CAAC;IAC3B,aAAa,CAAC,MAAc,IAAG,CAAC;IAChC,KAAK,CAAC,aAAa,KAAI,CAAC;IACxB,WAAW;QACT,OAAO,EAAE,MAAM,KAAI,CAAC,EAAE,CAAC;IACzB,CAAC;IACD,eAAe,KAAI,CAAC;CACrB,CAAC","sourcesContent":["// No-op stub for non-Android platforms\nexport default {\n isAvailable(): boolean {\n return false;\n },\n hasStoragePermission(): boolean {\n return true;\n },\n async requestStoragePermissionAsync(): Promise<boolean> {\n return true;\n },\n addVoicePath(_path: string) {},\n setLicense(_userId: number, _password: number, _key: string) {},\n async initializeAsync(): Promise<boolean> {\n return false;\n },\n async getVoicesAsync() {\n return [];\n },\n async loadVoiceAsync(_voiceName: string): Promise<boolean> {\n return false;\n },\n async speakAsync(_text: string): Promise<number> {\n return -1;\n },\n stop() {},\n isSpeaking(): boolean {\n return false;\n },\n setSpeechRate(_rate: number) {},\n setPitch(_pitch: number) {},\n setAudioBoost(_boost: number) {},\n async shutdownAsync() {},\n addListener() {\n return { remove() {} };\n },\n removeListeners() {},\n};\n"]}
package/build/index.d.ts CHANGED
File without changes
File without changes
package/build/index.js CHANGED
File without changes
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@focus8/expo-acapela-tts",
3
- "version": "0.1.5",
3
+ "version": "0.1.9",
4
4
  "description": "Acapela TTS integration for Expo on Android",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
File without changes
@@ -7,6 +7,8 @@ import {
7
7
 
8
8
  declare class ExpoAcapelaTtsModule extends NativeModule<ExpoAcapelaTtsModuleEvents> {
9
9
  isAvailable(): boolean;
10
+ hasStoragePermission(): boolean;
11
+ requestStoragePermissionAsync(): Promise<boolean>;
10
12
  addVoicePath(path: string): void;
11
13
  setLicense(userId: number, password: number, key: string): void;
12
14
  initializeAsync(): Promise<boolean>;
@@ -3,6 +3,12 @@ export default {
3
3
  isAvailable(): boolean {
4
4
  return false;
5
5
  },
6
+ hasStoragePermission(): boolean {
7
+ return true;
8
+ },
9
+ async requestStoragePermissionAsync(): Promise<boolean> {
10
+ return true;
11
+ },
6
12
  addVoicePath(_path: string) {},
7
13
  setLicense(_userId: number, _password: number, _key: string) {},
8
14
  async initializeAsync(): Promise<boolean> {
package/src/index.ts CHANGED
File without changes
package/tsconfig.json CHANGED
File without changes