diff --git a/.gitmodules b/.gitmodules index a77f950..470936f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "knex-expo-sqlite-dialect"] path = knex-expo-sqlite-dialect url = https://github.com/expo/knex-expo-sqlite-dialect.git +[submodule "whisper_android"] + path = whisper_android + url = https://github.com/vilassn/whisper_android.git diff --git a/.vscode/settings.json b/.vscode/settings.json index 7a73a41..8f2b711 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,2 +1,3 @@ { + "java.compile.nullAnalysis.mode": "disabled" } \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle index 1565e0d..75bca16 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -21,11 +21,13 @@ react { /* Folders */ // The root of your project, i.e. where "package.json" lives. Default is '../..' - // root = file("../../") + root = file("../../") // The folder where the react-native NPM package is. Default is ../../node_modules/react-native // reactNativeDir = file("../../node_modules/react-native") // The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen // codegenDir = file("../../node_modules/@react-native/codegen") + + // the sub-project for whisper-native /* Variants */ // The list of variants to that are debuggable. For those we're going to diff --git a/android/app/src/main/java/com/anonymous/translationterrace/MainActivity.kt b/android/app/src/main/java/com/anonymous/translationterrace/MainActivity.kt deleted file mode 100644 index 23b216f..0000000 --- a/android/app/src/main/java/com/anonymous/translationterrace/MainActivity.kt +++ /dev/null @@ -1,65 +0,0 @@ -package com.anonymous.translationterrace -import expo.modules.splashscreen.SplashScreenManager - -import android.os.Build -import android.os.Bundle - -import com.facebook.react.ReactActivity -import com.facebook.react.ReactActivityDelegate -import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled -import com.facebook.react.defaults.DefaultReactActivityDelegate - -import expo.modules.ReactActivityDelegateWrapper - -class MainActivity : ReactActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - // Set the theme to AppTheme BEFORE onCreate to support - // coloring the background, status bar, and navigation bar. - // This is required for expo-splash-screen. - // setTheme(R.style.AppTheme); - // @generated begin expo-splashscreen - expo prebuild (DO NOT MODIFY) sync-f3ff59a738c56c9a6119210cb55f0b613eb8b6af - SplashScreenManager.registerOnActivity(this) - // @generated end expo-splashscreen - super.onCreate(null) - } - - /** - * Returns the name of the main component registered from JavaScript. This is used to schedule - * rendering of the component. - */ - override fun getMainComponentName(): String = "main" - - /** - * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] - * which allows you to enable New Architecture with a single boolean flags [fabricEnabled] - */ - override fun createReactActivityDelegate(): ReactActivityDelegate { - return ReactActivityDelegateWrapper( - this, - BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, - object : DefaultReactActivityDelegate( - this, - mainComponentName, - fabricEnabled - ){}) - } - - /** - * Align the back button behavior with Android S - * where moving root activities to background instead of finishing activities. - * @see onBackPressed - */ - override fun invokeDefaultOnBackPressed() { - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { - if (!moveTaskToBack(false)) { - // For non-root activities, use the default implementation to finish them. - super.invokeDefaultOnBackPressed() - } - return - } - - // Use the default back button implementation on Android S - // because it's doing more than [Activity.moveTaskToBack] in fact. - super.invokeDefaultOnBackPressed() - } -} diff --git a/android/app/src/main/java/com/anonymous/translationterrace/MainApplication.kt b/android/app/src/main/java/com/anonymous/translationterrace/MainApplication.kt deleted file mode 100644 index bac822b..0000000 --- a/android/app/src/main/java/com/anonymous/translationterrace/MainApplication.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.anonymous.translationterrace - -import android.app.Application -import android.content.res.Configuration - -import com.facebook.react.PackageList -import com.facebook.react.ReactApplication -import com.facebook.react.ReactNativeHost -import com.facebook.react.ReactPackage -import com.facebook.react.ReactHost -import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load -import com.facebook.react.defaults.DefaultReactNativeHost -import com.facebook.react.soloader.OpenSourceMergedSoMapping -import com.facebook.soloader.SoLoader - -import expo.modules.ApplicationLifecycleDispatcher -import expo.modules.ReactNativeHostWrapper - -class MainApplication : Application(), ReactApplication { - - override val reactNativeHost: ReactNativeHost = ReactNativeHostWrapper( - this, - object : DefaultReactNativeHost(this) { - override fun getPackages(): List { - val packages = PackageList(this).packages - // Packages that cannot be autolinked yet can be added manually here, for example: - // packages.add(new MyReactNativePackage()); - return packages - } - - override fun getJSMainModuleName(): String = ".expo/.virtual-metro-entry" - - override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG - - override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED - override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED - } - ) - - override val reactHost: ReactHost - get() = ReactNativeHostWrapper.createReactHost(applicationContext, reactNativeHost) - - override fun onCreate() { - super.onCreate() - SoLoader.init(this, OpenSourceMergedSoMapping) - if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { - // If you opted-in for the New Architecture, we load the native entry point for this app. - load() - } - ApplicationLifecycleDispatcher.onApplicationCreate(this) - } - - override fun onConfigurationChanged(newConfig: Configuration) { - super.onConfigurationChanged(newConfig) - ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig) - } -} diff --git a/android/app/src/main/java/com/nativewhisperengine/NativeWhisperModule.java b/android/app/src/main/java/com/nativewhisperengine/NativeWhisperModule.java new file mode 100644 index 0000000..fac3369 --- /dev/null +++ b/android/app/src/main/java/com/nativewhisperengine/NativeWhisperModule.java @@ -0,0 +1,46 @@ +package com.nativewhisperengine; + +// react-native turbo spec +import com.nativewhisperengine.NativeWhisperEngineSpec; + +// inherent context +import android.content.Context; +import com.facebook.react.bridge.ReactApplicationContext; + +// packages we'll be using. +import com.whispertflite.engine.WhisperEngine; + +public class NativeWhisperModule extends NativeLocalStorageSpec { + + public static final String NAME = "NativeLocalStorage"; + + public NativeLocalStorageModule(ReactApplicationContext reactContext) { + super(reactContext); + } + + @Override + public String getName() { + return NAME; + } + + @Override + public void setItem(String value, String key) { + SharedPreferences sharedPref = getReactApplicationContext().getSharedPreferences("my_prefs", Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPref.edit(); + editor.putString(key, value); + editor.apply(); + } + + @Override + public String getItem(String key) { + SharedPreferences sharedPref = getReactApplicationContext().getSharedPreferences("my_prefs", Context.MODE_PRIVATE); + String username = sharedPref.getString(key, null); + return username; + } + + @Override + public void removeItem(String key) { + SharedPreferences sharedPref = getReactApplicationContext().getSharedPreferences("my_prefs", Context.MODE_PRIVATE); + sharedPref.edit().remove(key).apply(); + } +} \ No newline at end of file diff --git a/android/app/src/main/java/com/nativewhisperengine/NativeWhisperPackage.java b/android/app/src/main/java/com/nativewhisperengine/NativeWhisperPackage.java new file mode 100644 index 0000000..8282f3b --- /dev/null +++ b/android/app/src/main/java/com/nativewhisperengine/NativeWhisperPackage.java @@ -0,0 +1,41 @@ +package com.nativewhisperengine; + +import com.facebook.react.BaseReactPackage; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.module.model.ReactModuleInfo; +import com.facebook.react.module.model.ReactModuleInfoProvider; + +import java.util.HashMap; +import java.util.Map; + +public class NativeWhisperPackage extends BaseReactPackage { + + @Override + public NativeModule getModule(String name, ReactApplicationContext reactContext) { + if (name.equals(NativeWhisperModule.NAME)) { + return new NativeWhisperModule(reactContext); + } else { + return null; + } + } + + @Override + public ReactModuleInfoProvider getReactModuleInfoProvider() { + return new ReactModuleInfoProvider() { + @Override + public Map getReactModuleInfos() { + Map map = new HashMap<>(); + map.put(NativeWhisperModule.NAME, new ReactModuleInfo( + NativeWhisperModule.NAME, // name + NativeWhisperModule.NAME, // className + false, // canOverrideExistingModule + false, // needsEagerInit + false, // isCXXModule + true // isTurboModule + )); + return map; + } + }; + } +} \ No newline at end of file diff --git a/package.json b/package.json index 6868c9e..d662921 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,14 @@ "sqlite3": "^5.1.7", "whisper.rn": "^0.3.9" }, + "codegenConfig": { + "name": "NativeWhisperEngineSpec", + "type": "modules", + "jsSrcsDir": "specs", + "android": { + "javaPackageName": "com.nativewhisperengine" + } + }, "jest": { "preset": "jest-expo", "testPathIgnorePatterns": [ diff --git a/specs/WhisperEngine.ts b/specs/WhisperEngine.ts new file mode 100644 index 0000000..1bda15c --- /dev/null +++ b/specs/WhisperEngine.ts @@ -0,0 +1,11 @@ +import type {TurboModule} from 'react-native'; +import {TurboModuleRegistry} from 'react-native'; + +export interface Spec extends TurboModule { + loadWhisper(path: string): void; + translate() : void; +} + +export default TurboModuleRegistry.getEnforcing( + 'NativeWhisperEngine', +); \ No newline at end of file diff --git a/whisper_android b/whisper_android new file mode 160000 index 0000000..08b766a --- /dev/null +++ b/whisper_android @@ -0,0 +1 @@ +Subproject commit 08b766af195510e1ac6ede69cb152d8ca9ebb37e