Skip to content

Commit

Permalink
Add translation service for Android
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinX8 committed Feb 6, 2023
1 parent 7b2ea24 commit 59ad332
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 15 deletions.
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -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"
}
}
Expand Down
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 3 additions & 3 deletions lib/logger/logger.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
25 changes: 20 additions & 5 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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';
Expand All @@ -38,11 +36,28 @@ Future<void> 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<Locale> 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<bool>(true);
Expand All @@ -58,7 +73,7 @@ Future<void> 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));
Expand Down
24 changes: 22 additions & 2 deletions lib/sentiment_analysis.dart
Original file line number Diff line number Diff line change
@@ -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 = '<START>';
final String pad = '<PAD>';
Expand All @@ -22,9 +26,11 @@ class SentimentAnalysis {

SentimentAnalysis();

SentimentAnalysis.isolate(int iAddress, Map<String, int> dict) {
SentimentAnalysis.isolate(
int iAddress, Map<String, int> dict, int translate) {
sInterpreter = Interpreter.fromAddress(iAddress);
dictionary = dict;
_translate = translate;
}

Future<void> init() async {
Expand All @@ -51,7 +57,21 @@ class SentimentAnalysis {
log('Dictionary loaded successfully');
}

double classify(String rawText) {
Future<double> 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<List<double>>
// of shape [1, 256].
List<List<double>> input = tokenizeInputText(rawText);
Expand Down
3 changes: 2 additions & 1 deletion lib/sentiment_db.dart
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,9 @@ class IsolateStartRequest {
class TfParams {
final int iAddress;
final Map<String, int> dict;
final int translate;

TfParams(this.iAddress, this.dict);
TfParams(this.iAddress, this.dict, this.translate);
}

class TfliteRequest extends IsolateStartRequest {
Expand Down
14 changes: 14 additions & 0 deletions lib/ui/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,20 @@ class SettingsPage {
title: const Text('Use Dynamic Theme')),
],
),
SettingsSection(
title: const Text('Translation'),
tiles: <SettingsTile>[
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(
Expand Down
26 changes: 25 additions & 1 deletion pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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"
2 changes: 2 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 59ad332

Please sign in to comment.