diff --git a/android/build.gradle b/android/build.gradle index 8b607dc..255df3f 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.7.20' + ext.kotlin_version = '1.8.10' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.1.3' + classpath 'com.android.tools.build:gradle:7.4.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index cb24abd..dcf0f19 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip diff --git a/lib/logger/logger.dart b/lib/logger/logger.dart index 5299fe0..0b24bb8 100644 --- a/lib/logger/logger.dart +++ b/lib/logger/logger.dart @@ -90,15 +90,15 @@ class SentenceLogger { SentenceLogger._sentence.clear(); } - void addAppEntry() { + void addAppEntry() async { log(getSentence()); if (getSentence().length < 6) { clearSentence(); return; } String name = _lastUsedApp; - var analyser = SentimentAnalysis.isolate(_tfp.iAddress, _tfp.dict); - double score = analyser.classify(getSentence()); + var analyser = SentimentAnalysis.isolate(_tfp.iAddress, _tfp.dict, _tfp.translate); + double score = await analyser.classify(getSentence()); log(score.toString()); clearSentence(); diff --git a/lib/main.dart b/lib/main.dart index 5e403e4..04e7d15 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,7 +3,6 @@ import 'dart:async'; import 'dart:io'; import 'dart:isolate'; -import 'package:file_saver/file_saver.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/services.dart'; import 'package:flutter_foreground_task/flutter_foreground_task.dart'; @@ -20,7 +19,6 @@ import 'package:negate/ui/settings.dart'; import 'package:path_provider/path_provider.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:path/path.dart' as p; -import 'package:permission_handler/permission_handler.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:system_tray/system_tray.dart'; import 'package:dynamic_color/dynamic_color.dart'; @@ -38,11 +36,28 @@ Future main() async { final dbString = p.join(dbFolder.path, 'db.sqlite'); final rPort = ReceivePort(); + var prefs = await SharedPreferences.getInstance(); + int translate = 0; var analyser = SentimentAnalysis(); await analyser.init(); - var tfp = TfParams(analyser.sInterpreter.address, analyser.dictionary); + if (prefs.getBool('translate') == null) { + final List systemLocales = WidgetsBinding.instance.window.locales; + log(systemLocales.toString()); + if (systemLocales.length > 1 || systemLocales.where((locale) => !locale.languageCode.contains('en')).isNotEmpty) { + prefs.setBool('translate', true); + } + } else { + if (prefs.getBool('translate')!) { + if (Platform.isAndroid || Platform.isIOS) { + translate = 2; + } else { + //Desktop translation not implemented + translate = 1; + } + } + } + var tfp = TfParams(analyser.sInterpreter.address, analyser.dictionary, translate); - var prefs = await SharedPreferences.getInstance(); if (prefs.getBool('dynamic_theme') == null) { prefs.setBool('dynamic_theme', true); getIt.registerSingleton(true); @@ -58,7 +73,7 @@ Future main() async { prefs.getString('blacklist') == null ? prefs.setString('blacklist', LoggerFactory.getLoggerRegex().pattern) : null; - + if (Platform.isAndroid || Platform.isIOS) { LoggerFactory.startLoggerFactory( TfliteRequest(rPort.sendPort, dbString, tfp, prefs)); diff --git a/lib/sentiment_analysis.dart b/lib/sentiment_analysis.dart index 13f55d1..18fe22b 100644 --- a/lib/sentiment_analysis.dart +++ b/lib/sentiment_analysis.dart @@ -1,15 +1,19 @@ import 'dart:developer'; import 'package:flutter/services.dart'; +import 'package:google_mlkit_language_id/google_mlkit_language_id.dart'; +import 'package:google_mlkit_translation/google_mlkit_translation.dart'; import 'package:tflite_flutter/tflite_flutter.dart'; class SentimentAnalysis { // name of the model file final _modelFile = 'text_classification.tflite'; final _vocabFile = 'text_classification_vocab.txt'; + final _languageIdentifier = LanguageIdentifier(confidenceThreshold: 0.5); // Maximum length of sentence final int _sentenceLen = 256; + int _translate = 0; final String start = ''; final String pad = ''; @@ -22,9 +26,11 @@ class SentimentAnalysis { SentimentAnalysis(); - SentimentAnalysis.isolate(int iAddress, Map dict) { + SentimentAnalysis.isolate( + int iAddress, Map dict, int translate) { sInterpreter = Interpreter.fromAddress(iAddress); dictionary = dict; + _translate = translate; } Future init() async { @@ -51,7 +57,21 @@ class SentimentAnalysis { log('Dictionary loaded successfully'); } - double classify(String rawText) { + Future classify(String rawText) async { + if (_translate == 2) { + log(rawText); + final String response = + await _languageIdentifier.identifyLanguage(rawText); + log('language is : $response'); + if (response != 'und' && response != 'en') { + final onDeviceTranslator = OnDeviceTranslator( + sourceLanguage: TranslateLanguage.values + .firstWhere((element) => element.bcpCode == response), + targetLanguage: TranslateLanguage.english); + rawText = await onDeviceTranslator.translateText(rawText); + log(rawText); + } + } // tokenizeInputText returns List> // of shape [1, 256]. List> input = tokenizeInputText(rawText); diff --git a/lib/sentiment_db.dart b/lib/sentiment_db.dart index 4e09ed6..29a74c6 100644 --- a/lib/sentiment_db.dart +++ b/lib/sentiment_db.dart @@ -299,8 +299,9 @@ class IsolateStartRequest { class TfParams { final int iAddress; final Map dict; + final int translate; - TfParams(this.iAddress, this.dict); + TfParams(this.iAddress, this.dict, this.translate); } class TfliteRequest extends IsolateStartRequest { diff --git a/lib/ui/settings.dart b/lib/ui/settings.dart index 6cc1beb..56da4d7 100644 --- a/lib/ui/settings.dart +++ b/lib/ui/settings.dart @@ -48,6 +48,20 @@ class SettingsPage { title: const Text('Use Dynamic Theme')), ], ), + SettingsSection( + title: const Text('Translation'), + tiles: [ + SettingsTile.switchTile( + activeSwitchColor: + Theme.of(context).colorScheme.primary, + leading: const Icon(Icons.format_paint), + initialValue: prefs.data?.getBool('translate'), + onToggle: (value) => setState(() { + prefs.data?.setBool('translate', value); + }), + title: const Text('Use Google Translate for non-english text')), + ] + ), SettingsSection(title: const Text('Database'), tiles: < SettingsTile>[ SettingsTile.navigation( diff --git a/pubspec.lock b/pubspec.lock index e03c284..099d516 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -448,6 +448,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + google_mlkit_commons: + dependency: transitive + description: + name: google_mlkit_commons + sha256: af63771903947d5523d9e991a939a4b8bf994f11661c9b9c8a71d7d3997115f8 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + google_mlkit_language_id: + dependency: "direct main" + description: + name: google_mlkit_language_id + sha256: "939d8df92a347c6d4125c21869bf87d565d44186c7b033e3fdbd94f3451cc291" + url: "https://pub.dev" + source: hosted + version: "0.5.0" + google_mlkit_translation: + dependency: "direct main" + description: + name: google_mlkit_translation + sha256: cb560795ceca016df7e6718285a3c974be8df054b99bc042f311ba68dacd9170 + url: "https://pub.dev" + source: hosted + version: "0.5.0" graphs: dependency: transitive description: @@ -1119,5 +1143,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=2.19.0 <4.0.0" + dart: ">=2.19.0 <3.0.0" flutter: ">=3.4.0-17.0.pre" diff --git a/pubspec.yaml b/pubspec.yaml index f0140fe..b9beb8e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -64,6 +64,8 @@ dependencies: settings_ui: ^2.0.2 flutter_markdown: ^0.6.13 file_picker: ^5.2.5 + google_mlkit_language_id: ^0.5.0 + google_mlkit_translation: ^0.5.0 dev_dependencies: drift_dev: ^2.4.0