diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java b/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java
index aafc968785..d69656d28b 100644
--- a/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java
+++ b/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java
@@ -81,6 +81,8 @@ import androidx.constraintlayout.widget.Group;
import androidx.lifecycle.Observer;
import androidx.preference.PreferenceManager;
+import com.google.android.material.textfield.TextInputLayout;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -125,6 +127,8 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
private SwitchCompat swLanguageToolAuto;
private SwitchCompat swLanguageToolPicky;
private EditText etLanguageTool;
+ private EditText etLanguageToolUser;
+ private TextInputLayout tilLanguageToolKey;
private ImageButton ibLanguageTool;
private SwitchCompat swDeepL;
private TextView tvDeepLPrivacy;
@@ -248,7 +252,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
"sort_answers", "shortcuts", "fts",
"classification", "class_min_probability", "class_min_difference",
"language",
- "lt_enabled", "lt_auto", "lt_picky", "lt_uri",
+ "lt_enabled", "lt_auto", "lt_picky", "lt_uri", "lt_user", "lt_key",
"deepl_enabled",
"vt_enabled", "vt_apikey",
"send_enabled", "send_host",
@@ -340,6 +344,8 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
swLanguageToolAuto = view.findViewById(R.id.swLanguageToolAuto);
swLanguageToolPicky = view.findViewById(R.id.swLanguageToolPicky);
etLanguageTool = view.findViewById(R.id.etLanguageTool);
+ etLanguageToolUser = view.findViewById(R.id.etLanguageToolUser);
+ tilLanguageToolKey = view.findViewById(R.id.tilLanguageToolKey);
ibLanguageTool = view.findViewById(R.id.ibLanguageTool);
swDeepL = view.findViewById(R.id.swDeepL);
tvDeepLPrivacy = view.findViewById(R.id.tvDeepLPrivacy);
@@ -699,6 +705,48 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
}
});
+ etLanguageToolUser.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ // Do nothing
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ // Do nothing
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ String apikey = s.toString().trim();
+ if (TextUtils.isEmpty(apikey))
+ prefs.edit().remove("lt_user").apply();
+ else
+ prefs.edit().putString("lt_user", apikey).apply();
+ }
+ });
+
+ tilLanguageToolKey.getEditText().addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ // Do nothing
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ // Do nothing
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ String apikey = s.toString().trim();
+ if (TextUtils.isEmpty(apikey))
+ prefs.edit().remove("lt_key").apply();
+ else
+ prefs.edit().putString("lt_key", apikey).apply();
+ }
+ });
+
ibLanguageTool.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -1932,7 +1980,11 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
if ("last_cleanup".equals(key))
setLastCleanup(prefs.getLong(key, -1));
- if ("lt_uri".equals(key) || "vt_apikey".equals(key) || "send_host".equals(key))
+ if ("lt_uri".equals(key) ||
+ "lt_user".equals(key) ||
+ "lt_key".equals(key) ||
+ "vt_apikey".equals(key) ||
+ "send_host".equals(key))
return;
if ("global_keywords".equals(key))
@@ -2084,6 +2136,8 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
swLanguageToolPicky.setChecked(prefs.getBoolean("lt_picky", false));
swLanguageToolPicky.setEnabled(swLanguageTool.isChecked());
etLanguageTool.setText(prefs.getString("lt_uri", null));
+ etLanguageToolUser.setText(prefs.getString("lt_user", null));
+ tilLanguageToolKey.getEditText().setText(prefs.getString("lt_key", null));
swDeepL.setChecked(prefs.getBoolean("deepl_enabled", false));
swVirusTotal.setChecked(prefs.getBoolean("vt_enabled", false));
etVirusTotal.setText(prefs.getString("vt_apikey", null));
diff --git a/app/src/main/java/eu/faircode/email/LanguageTool.java b/app/src/main/java/eu/faircode/email/LanguageTool.java
index d34646b205..23bb2f36d4 100644
--- a/app/src/main/java/eu/faircode/email/LanguageTool.java
+++ b/app/src/main/java/eu/faircode/email/LanguageTool.java
@@ -21,6 +21,7 @@ package eu.faircode.email;
import android.content.Context;
import android.content.SharedPreferences;
+import android.net.Uri;
import android.os.Build;
import android.text.Editable;
import android.text.Spanned;
@@ -67,10 +68,16 @@ public class LanguageTool {
if (TextUtils.isEmpty(text))
return new ArrayList<>();
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ boolean lt_picky = prefs.getBoolean("lt_picky", false);
+ String lt_uri = prefs.getString("lt_uri", LT_URI);
+ String lt_user = prefs.getString("lt_user", null);
+ String lt_key = prefs.getString("lt_key", null);
+
// https://languagetool.org/http-api/swagger-ui/#!/default/post_check
- String request =
- "text=" + URLEncoder.encode(text.toString(), StandardCharsets.UTF_8.name()) +
- "&language=auto";
+ Uri.Builder builder = new Uri.Builder()
+ .appendQueryParameter("text", text.toString())
+ .appendQueryParameter("language", "auto");
// curl -X GET --header 'Accept: application/json' 'https://api.languagetool.org/v2/languages'
JSONArray jlanguages;
@@ -91,21 +98,22 @@ public class LanguageTool {
}
if (code != null)
- request += "&preferredVariants=" + code;
-
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
- boolean lt_picky = prefs.getBoolean("lt_picky", false);
+ builder.appendQueryParameter("preferredVariants", code);
if (lt_picky)
- request += "&level=picky";
+ builder.appendQueryParameter("level", "picky");
- String uri = prefs.getString("lt_uri", LT_URI);
- if (!uri.endsWith("/"))
- uri += '/';
+ if (!TextUtils.isEmpty(lt_user))
+ builder.appendQueryParameter("username", lt_user);
+ if (!TextUtils.isEmpty(lt_key))
+ builder.appendQueryParameter("apiKey", lt_key);
+
+ Uri uri = Uri.parse(lt_uri).buildUpon().appendPath("check").build();
+ String request = builder.build().toString().substring(1);
Log.i("LT locale=" + locale + " uri=" + uri + " request=" + request);
- URL url = new URL(uri + "check");
+ URL url = new URL(uri.toString());
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
@@ -130,6 +138,7 @@ public class LanguageTool {
} catch (Throwable ex) {
Log.w(ex);
}
+ Log.w("LT " + error);
throw new FileNotFoundException(error);
}
diff --git a/app/src/main/res/layout/fragment_options_misc.xml b/app/src/main/res/layout/fragment_options_misc.xml
index 5ebb9084c7..5d031e614a 100644
--- a/app/src/main/res/layout/fragment_options_misc.xml
+++ b/app/src/main/res/layout/fragment_options_misc.xml
@@ -379,6 +379,39 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLanguageToolPicky" />
+
+
+
+
+
+
+
+ app:layout_constraintTop_toBottomOf="@id/tilLanguageToolKey" />
System
LanguageTool integration
Check paragraph after a new line
+ Username (optional)
+ API key (optional)
DeepL integration
VirusTotal integration
Send integration