Added integrations settings tab page

pull/214/head
M66B 10 months ago
parent 9f05f54dc5
commit caf90aac6f

@ -82,6 +82,7 @@ public class FragmentOptions extends FragmentBase {
R.layout.fragment_options_privacy,
R.layout.fragment_options_encryption,
R.layout.fragment_options_notifications,
R.layout.fragment_options_integrations,
R.layout.fragment_options_misc,
R.layout.fragment_options_backup
};
@ -96,6 +97,7 @@ public class FragmentOptions extends FragmentBase {
R.string.title_advanced_section_privacy,
R.string.title_advanced_section_encryption,
R.string.title_advanced_section_notifications,
R.string.title_advanced_caption_integrations,
R.string.title_advanced_section_misc,
R.string.title_advanced_section_backup
};
@ -110,6 +112,7 @@ public class FragmentOptions extends FragmentBase {
R.drawable.twotone_account_circle_24,
R.drawable.twotone_lock_24,
R.drawable.twotone_notifications_24,
R.drawable.twotone_extension_24,
R.drawable.twotone_more_24,
R.drawable.twotone_save_alt_24
};
@ -124,6 +127,7 @@ public class FragmentOptions extends FragmentBase {
"privacy",
"encryption",
"notifications",
"integrations",
"misc",
"backup"
));
@ -529,8 +533,10 @@ public class FragmentOptions extends FragmentBase {
case 8:
return new FragmentOptionsNotifications();
case 9:
return new FragmentOptionsMisc();
return new FragmentOptionsIntegrations();
case 10:
return new FragmentOptionsMisc();
case 11:
return new FragmentOptionsBackup();
default:
throw new IllegalArgumentException();

@ -0,0 +1,602 @@
package eu.faircode.email;
/*
This file is part of FairEmail.
FairEmail is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FairEmail is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018-2023 by Marcel Bokhorst (M66B)
*/
import android.app.ActivityManager;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.SwitchCompat;
import androidx.cardview.widget.CardView;
import androidx.preference.PreferenceManager;
import com.google.android.material.textfield.TextInputLayout;
import java.text.NumberFormat;
public class FragmentOptionsIntegrations extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener {
private View view;
private ImageButton ibHelp;
private SwitchCompat swLanguageTool;
private TextView tvLanguageToolPrivacy;
private SwitchCompat swLanguageToolSentence;
private SwitchCompat swLanguageToolAuto;
private SwitchCompat swLanguageToolPicky;
private SwitchCompat swLanguageToolHighlight;
private SwitchCompat swLanguageToolDescription;
private EditText etLanguageTool;
private EditText etLanguageToolUser;
private TextInputLayout tilLanguageToolKey;
private ImageButton ibLanguageTool;
private SwitchCompat swDeepL;
private TextView tvDeepLPrivacy;
private ImageButton ibDeepL;
private SwitchCompat swVirusTotal;
private TextView tvVirusTotalPrivacy;
private TextInputLayout tilVirusTotal;
private ImageButton ibVirusTotal;
private SwitchCompat swSend;
private EditText etSend;
private ImageButton ibSend;
private SwitchCompat swOpenAi;
private TextView tvOpenAiPrivacy;
private EditText etOpenAi;
private TextInputLayout tilOpenAi;
private EditText etOpenAiModel;
private TextView tvOpenAiTemperature;
private SeekBar sbOpenAiTemperature;
private SwitchCompat swOpenAiModeration;
private ImageButton ibOpenAi;
private CardView cardVirusTotal;
private CardView cardSend;
private CardView cardOpenAi;
private NumberFormat NF = NumberFormat.getNumberInstance();
private final static String[] RESET_OPTIONS = new String[]{
"lt_enabled", "lt_sentence", "lt_auto", "lt_picky", "lt_highlight", "lt_description", "lt_uri", "lt_user", "lt_key",
"deepl_enabled",
"vt_enabled", "vt_apikey",
"send_enabled", "send_host", "send_dlimit", "send_tlimit",
"openai_enabled", "openai_uri", "openai_apikey", "openai_model", "openai_temperature", "openai_moderation"
};
@Override
@Nullable
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
setSubtitle(R.string.title_setup);
setHasOptionsMenu(true);
view = inflater.inflate(R.layout.fragment_options_integrations, container, false);
// Get controls
ibHelp = view.findViewById(R.id.ibHelp);
swLanguageTool = view.findViewById(R.id.swLanguageTool);
tvLanguageToolPrivacy = view.findViewById(R.id.tvLanguageToolPrivacy);
swLanguageToolSentence = view.findViewById(R.id.swLanguageToolSentence);
swLanguageToolAuto = view.findViewById(R.id.swLanguageToolAuto);
swLanguageToolPicky = view.findViewById(R.id.swLanguageToolPicky);
swLanguageToolHighlight = view.findViewById(R.id.swLanguageToolHighlight);
swLanguageToolDescription = view.findViewById(R.id.swLanguageToolDescription);
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);
ibDeepL = view.findViewById(R.id.ibDeepL);
swVirusTotal = view.findViewById(R.id.swVirusTotal);
tvVirusTotalPrivacy = view.findViewById(R.id.tvVirusTotalPrivacy);
tilVirusTotal = view.findViewById(R.id.tilVirusTotal);
ibVirusTotal = view.findViewById(R.id.ibVirusTotal);
swSend = view.findViewById(R.id.swSend);
etSend = view.findViewById(R.id.etSend);
ibSend = view.findViewById(R.id.ibSend);
swOpenAi = view.findViewById(R.id.swOpenAi);
tvOpenAiPrivacy = view.findViewById(R.id.tvOpenAiPrivacy);
etOpenAi = view.findViewById(R.id.etOpenAi);
tilOpenAi = view.findViewById(R.id.tilOpenAi);
etOpenAiModel = view.findViewById(R.id.etOpenAiModel);
tvOpenAiTemperature = view.findViewById(R.id.tvOpenAiTemperature);
sbOpenAiTemperature = view.findViewById(R.id.sbOpenAiTemperature);
swOpenAiModeration = view.findViewById(R.id.swOpenAiModeration);
ibOpenAi = view.findViewById(R.id.ibOpenAi);
cardVirusTotal = view.findViewById(R.id.cardVirusTotal);
cardSend = view.findViewById(R.id.cardSend);
cardOpenAi = view.findViewById(R.id.cardOpenAi);
setOptions();
// Wire controls
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
ibHelp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.view(v.getContext(), Helper.getSupportUri(v.getContext(), "Options:misc"), false);
}
});
swLanguageTool.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("lt_enabled", checked).apply();
swLanguageToolSentence.setEnabled(checked);
swLanguageToolAuto.setEnabled(checked);
swLanguageToolPicky.setEnabled(checked);
swLanguageToolHighlight.setEnabled(checked);
swLanguageToolDescription.setEnabled(checked);
}
});
tvLanguageToolPrivacy.getPaint().setUnderlineText(true);
tvLanguageToolPrivacy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.view(v.getContext(), Uri.parse(Helper.LT_PRIVACY_URI), true);
}
});
swLanguageToolSentence.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("lt_sentence", checked).apply();
}
});
swLanguageToolAuto.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("lt_auto", checked).apply();
}
});
swLanguageToolPicky.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("lt_picky", checked).apply();
}
});
swLanguageToolHighlight.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("lt_highlight", checked).apply();
}
});
swLanguageToolDescription.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("lt_description", checked).apply();
}
});
etLanguageTool.setHint(LanguageTool.LT_URI);
etLanguageTool.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_uri").apply();
else
prefs.edit().putString("lt_uri", apikey).apply();
}
});
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) {
Helper.viewFAQ(v.getContext(), 180);
}
});
tvDeepLPrivacy.getPaint().setUnderlineText(true);
tvDeepLPrivacy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.view(v.getContext(), Uri.parse(DeepL.PRIVACY_URI), true);
}
});
swDeepL.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("deepl_enabled", checked).apply();
}
});
ibDeepL.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DeepL.FragmentDialogDeepL fragment = new DeepL.FragmentDialogDeepL();
fragment.show(getParentFragmentManager(), "deepl:configure");
}
});
swVirusTotal.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("vt_enabled", checked).apply();
}
});
tvVirusTotalPrivacy.getPaint().setUnderlineText(true);
tvVirusTotalPrivacy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.view(v.getContext(), Uri.parse(VirusTotal.URI_PRIVACY), true);
}
});
tilVirusTotal.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("vt_apikey").apply();
else
prefs.edit().putString("vt_apikey", apikey).apply();
}
});
ibVirusTotal.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.viewFAQ(v.getContext(), 181);
}
});
swSend.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("send_enabled", checked).apply();
}
});
etSend.setHint(Send.DEFAULT_SERVER);
etSend.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("send_host").apply();
else
prefs.edit().putString("send_host", apikey).apply();
}
});
ibSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.viewFAQ(v.getContext(), 183);
}
});
swOpenAi.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("openai_enabled", checked).apply();
etOpenAiModel.setEnabled(checked);
sbOpenAiTemperature.setEnabled(checked);
swOpenAiModeration.setEnabled(checked);
}
});
tvOpenAiPrivacy.getPaint().setUnderlineText(true);
tvOpenAiPrivacy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.view(v.getContext(), Uri.parse(BuildConfig.OPENAI_PRIVACY), true);
}
});
etOpenAi.setHint(BuildConfig.OPENAI_ENDPOINT);
etOpenAi.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("openai_uri").apply();
else
prefs.edit().putString("openai_uri", apikey).apply();
}
});
tilOpenAi.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("openai_apikey").apply();
else
prefs.edit().putString("openai_apikey", apikey).apply();
}
});
etOpenAiModel.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 model = s.toString().trim();
if (TextUtils.isEmpty(model))
prefs.edit().remove("openai_model").apply();
else
prefs.edit().putString("openai_model", model).apply();
}
});
sbOpenAiTemperature.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float temp = progress / 10f;
prefs.edit().putFloat("openai_temperature", temp).apply();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// Do nothing
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Do nothing
}
});
swOpenAiModeration.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("openai_moderation", checked).apply();
}
});
ibOpenAi.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.viewFAQ(v.getContext(), 190);
}
});
// Initialize
FragmentDialogTheme.setBackground(getContext(), view, false);
cardVirusTotal.setVisibility(BuildConfig.PLAY_STORE_RELEASE ? View.GONE : View.VISIBLE);
cardSend.setVisibility(BuildConfig.PLAY_STORE_RELEASE ? View.GONE : View.VISIBLE);
cardOpenAi.setVisibility(TextUtils.isEmpty(BuildConfig.OPENAI_ENDPOINT) ? View.GONE : View.VISIBLE);
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
return view;
}
@Override
public void onDestroyView() {
PreferenceManager.getDefaultSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this);
super.onDestroyView();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if ("lt_uri".equals(key) ||
"lt_user".equals(key) ||
"lt_key".equals(key) ||
"vt_apikey".equals(key) ||
"send_host".equals(key) ||
"openai_uri".equals(key) ||
"openai_apikey".equals(key) ||
"openai_model".equals(key))
return;
getMainHandler().removeCallbacks(update);
getMainHandler().postDelayed(update, FragmentOptions.DELAY_SETOPTIONS);
}
private Runnable update = new RunnableEx("misc") {
@Override
protected void delegate() {
setOptions();
}
};
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_options, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_default) {
FragmentOptions.reset(getContext(), RESET_OPTIONS, null);
return true;
}
return super.onOptionsItemSelected(item);
}
private void setOptions() {
try {
if (view == null || getContext() == null)
return;
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
swLanguageTool.setChecked(prefs.getBoolean("lt_enabled", false));
swLanguageToolSentence.setChecked(prefs.getBoolean("lt_sentence", false));
swLanguageToolSentence.setEnabled(swLanguageTool.isChecked());
swLanguageToolAuto.setChecked(prefs.getBoolean("lt_auto", true));
swLanguageToolAuto.setEnabled(swLanguageTool.isChecked());
swLanguageToolPicky.setChecked(prefs.getBoolean("lt_picky", false));
swLanguageToolPicky.setEnabled(swLanguageTool.isChecked());
swLanguageToolHighlight.setChecked(prefs.getBoolean("lt_highlight", !BuildConfig.PLAY_STORE_RELEASE));
swLanguageToolHighlight.setEnabled(swLanguageTool.isChecked());
swLanguageToolDescription.setChecked(prefs.getBoolean("lt_description", false));
swLanguageToolDescription.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));
tilVirusTotal.getEditText().setText(prefs.getString("vt_apikey", null));
swSend.setChecked(prefs.getBoolean("send_enabled", false));
etSend.setText(prefs.getString("send_host", null));
swOpenAi.setChecked(prefs.getBoolean("openai_enabled", false));
etOpenAi.setText(prefs.getString("openai_uri", null));
tilOpenAi.getEditText().setText(prefs.getString("openai_apikey", null));
etOpenAiModel.setText(prefs.getString("openai_model", null));
etOpenAiModel.setEnabled(swOpenAi.isChecked());
float temperature = prefs.getFloat("openai_temperature", 0.5f);
tvOpenAiTemperature.setText(getString(R.string.title_advanced_openai_temperature, NF.format(temperature)));
sbOpenAiTemperature.setProgress(Math.round(temperature * 10));
sbOpenAiTemperature.setEnabled(swOpenAi.isChecked());
swOpenAiModeration.setChecked(prefs.getBoolean("openai_moderation", false));
swOpenAiModeration.setEnabled(swOpenAi.isChecked());
} catch (Throwable ex) {
Log.e(ex);
}
}
}

@ -82,8 +82,6 @@ import androidx.lifecycle.Observer;
import androidx.preference.PreferenceManager;
import androidx.work.WorkManager;
import com.google.android.material.textfield.TextInputLayout;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@ -108,6 +106,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
private View view;
private ImageButton ibHelp;
private SwitchCompat swPowerMenu;
private SwitchCompat swSendSelf;
private SwitchCompat swExternalSearch;
@ -147,37 +146,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
private TextView tvLastCleanup;
private TextView tvSdcard;
private SwitchCompat swLanguageTool;
private TextView tvLanguageToolPrivacy;
private SwitchCompat swLanguageToolSentence;
private SwitchCompat swLanguageToolAuto;
private SwitchCompat swLanguageToolPicky;
private SwitchCompat swLanguageToolHighlight;
private SwitchCompat swLanguageToolDescription;
private EditText etLanguageTool;
private EditText etLanguageToolUser;
private TextInputLayout tilLanguageToolKey;
private ImageButton ibLanguageTool;
private SwitchCompat swDeepL;
private TextView tvDeepLPrivacy;
private ImageButton ibDeepL;
private SwitchCompat swVirusTotal;
private TextView tvVirusTotalPrivacy;
private TextInputLayout tilVirusTotal;
private ImageButton ibVirusTotal;
private SwitchCompat swSend;
private EditText etSend;
private ImageButton ibSend;
private SwitchCompat swOpenAi;
private TextView tvOpenAiPrivacy;
private EditText etOpenAi;
private TextInputLayout tilOpenAi;
private EditText etOpenAiModel;
private TextView tvOpenAiTemperature;
private SeekBar sbOpenAiTemperature;
private SwitchCompat swOpenAiModeration;
private ImageButton ibOpenAi;
private CardView cardAdvanced;
private SwitchCompat swWatchdog;
private SwitchCompat swExperiments;
@ -286,9 +254,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
private Group grpAnnouncements;
private Group grpTest;
private CardView cardVirusTotal;
private CardView cardSend;
private CardView cardOpenAi;
private CardView cardDebug;
private NumberFormat NF = NumberFormat.getNumberInstance();
@ -301,11 +266,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
"classification", "class_min_probability", "class_min_difference",
"show_filtered", "haptic_feedback",
"language",
"lt_enabled", "lt_sentence", "lt_auto", "lt_picky", "lt_highlight", "lt_description", "lt_uri", "lt_user", "lt_key",
"deepl_enabled",
"vt_enabled", "vt_apikey",
"send_enabled", "send_host", "send_dlimit", "send_tlimit",
"openai_enabled", "openai_uri", "openai_apikey", "openai_model", "openai_temperature", "openai_moderation",
"updates", "weekly", "beta", "show_changelog", "announcements",
"crash_reports", "cleanup_attachments",
"watchdog", "experiments", "main_log", "main_log_memory", "protocol", "log_level", "debug", "leak_canary",
@ -420,37 +380,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
tvLastCleanup = view.findViewById(R.id.tvLastCleanup);
tvSdcard = view.findViewById(R.id.tvSdcard);
swLanguageTool = view.findViewById(R.id.swLanguageTool);
tvLanguageToolPrivacy = view.findViewById(R.id.tvLanguageToolPrivacy);
swLanguageToolSentence = view.findViewById(R.id.swLanguageToolSentence);
swLanguageToolAuto = view.findViewById(R.id.swLanguageToolAuto);
swLanguageToolPicky = view.findViewById(R.id.swLanguageToolPicky);
swLanguageToolHighlight = view.findViewById(R.id.swLanguageToolHighlight);
swLanguageToolDescription = view.findViewById(R.id.swLanguageToolDescription);
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);
ibDeepL = view.findViewById(R.id.ibDeepL);
swVirusTotal = view.findViewById(R.id.swVirusTotal);
tvVirusTotalPrivacy = view.findViewById(R.id.tvVirusTotalPrivacy);
tilVirusTotal = view.findViewById(R.id.tilVirusTotal);
ibVirusTotal = view.findViewById(R.id.ibVirusTotal);
swSend = view.findViewById(R.id.swSend);
etSend = view.findViewById(R.id.etSend);
ibSend = view.findViewById(R.id.ibSend);
swOpenAi = view.findViewById(R.id.swOpenAi);
tvOpenAiPrivacy = view.findViewById(R.id.tvOpenAiPrivacy);
etOpenAi = view.findViewById(R.id.etOpenAi);
tilOpenAi = view.findViewById(R.id.tilOpenAi);
etOpenAiModel = view.findViewById(R.id.etOpenAiModel);
tvOpenAiTemperature = view.findViewById(R.id.tvOpenAiTemperature);
sbOpenAiTemperature = view.findViewById(R.id.sbOpenAiTemperature);
swOpenAiModeration = view.findViewById(R.id.swOpenAiModeration);
ibOpenAi = view.findViewById(R.id.ibOpenAi);
cardAdvanced = view.findViewById(R.id.cardAdvanced);
swWatchdog = view.findViewById(R.id.swWatchdog);
swExperiments = view.findViewById(R.id.swExperiments);
@ -559,9 +488,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
grpAnnouncements = view.findViewById(R.id.grpAnnouncements);
grpTest = view.findViewById(R.id.grpTest);
cardVirusTotal = view.findViewById(R.id.cardVirusTotal);
cardSend = view.findViewById(R.id.cardSend);
cardOpenAi = view.findViewById(R.id.cardOpenAi);
cardDebug = view.findViewById(R.id.cardDebug);
setOptions();
@ -924,345 +850,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
}
});
swLanguageTool.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("lt_enabled", checked).apply();
swLanguageToolSentence.setEnabled(checked);
swLanguageToolAuto.setEnabled(checked);
swLanguageToolPicky.setEnabled(checked);
swLanguageToolHighlight.setEnabled(checked);
swLanguageToolDescription.setEnabled(checked);
}
});
tvLanguageToolPrivacy.getPaint().setUnderlineText(true);
tvLanguageToolPrivacy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.view(v.getContext(), Uri.parse(Helper.LT_PRIVACY_URI), true);
}
});
swLanguageToolSentence.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("lt_sentence", checked).apply();
}
});
swLanguageToolAuto.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("lt_auto", checked).apply();
}
});
swLanguageToolPicky.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("lt_picky", checked).apply();
}
});
swLanguageToolHighlight.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("lt_highlight", checked).apply();
}
});
swLanguageToolDescription.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("lt_description", checked).apply();
}
});
etLanguageTool.setHint(LanguageTool.LT_URI);
etLanguageTool.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_uri").apply();
else
prefs.edit().putString("lt_uri", apikey).apply();
}
});
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) {
Helper.viewFAQ(v.getContext(), 180);
}
});
tvDeepLPrivacy.getPaint().setUnderlineText(true);
tvDeepLPrivacy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.view(v.getContext(), Uri.parse(DeepL.PRIVACY_URI), true);
}
});
swDeepL.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("deepl_enabled", checked).apply();
}
});
ibDeepL.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DeepL.FragmentDialogDeepL fragment = new DeepL.FragmentDialogDeepL();
fragment.show(getParentFragmentManager(), "deepl:configure");
}
});
swVirusTotal.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("vt_enabled", checked).apply();
}
});
tvVirusTotalPrivacy.getPaint().setUnderlineText(true);
tvVirusTotalPrivacy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.view(v.getContext(), Uri.parse(VirusTotal.URI_PRIVACY), true);
}
});
tilVirusTotal.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("vt_apikey").apply();
else
prefs.edit().putString("vt_apikey", apikey).apply();
}
});
ibVirusTotal.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.viewFAQ(v.getContext(), 181);
}
});
swSend.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("send_enabled", checked).apply();
}
});
etSend.setHint(Send.DEFAULT_SERVER);
etSend.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("send_host").apply();
else
prefs.edit().putString("send_host", apikey).apply();
}
});
ibSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.viewFAQ(v.getContext(), 183);
}
});
swOpenAi.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("openai_enabled", checked).apply();
}
});
tvOpenAiPrivacy.getPaint().setUnderlineText(true);
tvOpenAiPrivacy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.view(v.getContext(), Uri.parse(BuildConfig.OPENAI_PRIVACY), true);
}
});
etOpenAi.setHint(BuildConfig.OPENAI_ENDPOINT);
etOpenAi.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("openai_uri").apply();
else
prefs.edit().putString("openai_uri", apikey).apply();
}
});
tilOpenAi.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("openai_apikey").apply();
else
prefs.edit().putString("openai_apikey", apikey).apply();
}
});
etOpenAiModel.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 model = s.toString().trim();
if (TextUtils.isEmpty(model))
prefs.edit().remove("openai_model").apply();
else
prefs.edit().putString("openai_model", model).apply();
}
});
sbOpenAiTemperature.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float temp = progress / 10f;
prefs.edit().putFloat("openai_temperature", temp).apply();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// Do nothing
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Do nothing
}
});
swOpenAiModeration.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("openai_moderation", checked).apply();
}
});
ibOpenAi.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.viewFAQ(v.getContext(), 190);
}
});
swWatchdog.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
@ -2395,9 +1982,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
grpBitbucket.setVisibility(View.GONE);
grpAnnouncements.setVisibility(TextUtils.isEmpty(BuildConfig.ANNOUNCEMENT_URI)
? View.GONE : View.VISIBLE);
cardVirusTotal.setVisibility(BuildConfig.PLAY_STORE_RELEASE ? View.GONE : View.VISIBLE);
cardSend.setVisibility(BuildConfig.PLAY_STORE_RELEASE ? View.GONE : View.VISIBLE);
cardOpenAi.setVisibility(TextUtils.isEmpty(BuildConfig.OPENAI_ENDPOINT) ? View.GONE : View.VISIBLE);
grpTest.setVisibility(BuildConfig.TEST_RELEASE ? View.VISIBLE : View.GONE);
setLastCleanup(prefs.getLong("last_cleanup", -1));
@ -2492,15 +2076,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
if ("last_daily".equals(key))
tvLastDaily.setText(new Date(prefs.getLong(key, 0)).toString());
if ("lt_uri".equals(key) ||
"lt_user".equals(key) ||
"lt_key".equals(key) ||
"vt_apikey".equals(key) ||
"send_host".equals(key) ||
"openai_uri".equals(key) ||
"openai_apikey".equals(key) ||
"openai_model".equals(key) ||
"viewport_height".equals(key))
if ("viewport_height".equals(key))
return;
if ("global_keywords".equals(key))
@ -2690,35 +2266,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
if (selected >= 0)
spLanguage.setSelection(selected);
swLanguageTool.setChecked(prefs.getBoolean("lt_enabled", false));
swLanguageToolSentence.setChecked(prefs.getBoolean("lt_sentence", false));
swLanguageToolSentence.setEnabled(swLanguageTool.isChecked());
swLanguageToolAuto.setChecked(prefs.getBoolean("lt_auto", true));
swLanguageToolAuto.setEnabled(swLanguageTool.isChecked());
swLanguageToolPicky.setChecked(prefs.getBoolean("lt_picky", false));
swLanguageToolPicky.setEnabled(swLanguageTool.isChecked());
swLanguageToolHighlight.setChecked(prefs.getBoolean("lt_highlight", !BuildConfig.PLAY_STORE_RELEASE));
swLanguageToolHighlight.setEnabled(swLanguageTool.isChecked());
swLanguageToolDescription.setChecked(prefs.getBoolean("lt_description", false));
swLanguageToolDescription.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));
tilVirusTotal.getEditText().setText(prefs.getString("vt_apikey", null));
swSend.setChecked(prefs.getBoolean("send_enabled", false));
etSend.setText(prefs.getString("send_host", null));
swOpenAi.setChecked(prefs.getBoolean("openai_enabled", false));
etOpenAi.setText(prefs.getString("openai_uri", null));
tilOpenAi.getEditText().setText(prefs.getString("openai_apikey", null));
etOpenAiModel.setText(prefs.getString("openai_model", null));
float temperature = prefs.getFloat("openai_temperature", 0.5f);
tvOpenAiTemperature.setText(getString(R.string.title_advanced_openai_temperature, NF.format(temperature)));
sbOpenAiTemperature.setProgress(Math.round(temperature * 10));
swOpenAiModeration.setChecked(prefs.getBoolean("openai_moderation", false));
swWatchdog.setChecked(prefs.getBoolean("watchdog", true));
swMainLog.setChecked(prefs.getBoolean("main_log", true));
swMainLogMem.setChecked(prefs.getBoolean("main_log_memory", false));

@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,13h-2V7h-6V5c0,-0.28 -0.22,-0.5 -0.5,-0.5s-0.5,0.22 -0.5,0.5v2H4l0.01,2.12C5.76,9.8 7,11.51 7,13.5c0,1.99 -1.25,3.7 -3,4.38V20h2.12c0.68,-1.75 2.39,-3 4.38,-3 1.99,0 3.7,1.25 4.38,3H17v-6h2c0.28,0 0.5,-0.22 0.5,-0.5s-0.22,-0.5 -0.5,-0.5z"
android:strokeAlpha="0.3"
android:fillAlpha="0.3"/>
<path
android:fillColor="@android:color/white"
android:pathData="M19,11L19,7c0,-1.1 -0.9,-2 -2,-2h-4c0,-1.38 -1.12,-2.5 -2.5,-2.5S8,3.62 8,5L4,5c-1.1,0 -1.99,0.9 -1.99,2v3.8h0.29c1.49,0 2.7,1.21 2.7,2.7s-1.21,2.7 -2.7,2.7L2,16.2L2,20c0,1.1 0.9,2 2,2h3.8v-0.3c0,-1.49 1.21,-2.7 2.7,-2.7s2.7,1.21 2.7,2.7v0.3L17,22c1.1,0 2,-0.9 2,-2v-4c1.38,0 2.5,-1.12 2.5,-2.5S20.38,11 19,11zM19,14h-2v6h-2.12c-0.68,-1.75 -2.39,-3 -4.38,-3 -1.99,0 -3.7,1.25 -4.38,3L4,20v-2.12c1.75,-0.68 3,-2.39 3,-4.38 0,-1.99 -1.24,-3.7 -2.99,-4.38L4,7h6L10,5c0,-0.28 0.22,-0.5 0.5,-0.5s0.5,0.22 0.5,0.5v2h6v6h2c0.28,0 0.5,0.22 0.5,0.5s-0.22,0.5 -0.5,0.5z"/>
</vector>

@ -0,0 +1,619 @@
<?xml version="1.0" encoding="utf-8"?>
<eu.faircode.email.ScrollViewEx xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingStart="6dp"
android:paddingTop="12dp"
android:paddingEnd="6dp"
android:paddingBottom="0dp"
android:scrollbarStyle="outsideOverlay"
tools:context=".ActivitySetup">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="24dp">
<TextView
android:id="@+id/tvDefault"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:gravity="center_vertical"
android:minHeight="36dp"
android:text="@string/title_advanced_default"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorPrimary"
android:textStyle="italic"
app:layout_constraintEnd_toStartOf="@+id/ibHelp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/ibHelp"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="3dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:padding="6dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/tvDefault"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/tvDefault"
app:srcCompat="@drawable/twotone_help_24" />
<androidx.cardview.widget.CardView
android:id="@+id/cardLanguageTool"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="3dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="?attr/colorCardBackground"
app:cardCornerRadius="6dp"
app:cardElevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvDefault">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:paddingVertical="12dp">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swLanguageTool"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/title_advanced_lt"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:switchPadding="12dp" />
<TextView
android:id="@+id/tvLanguageToolHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/title_advanced_privacy_risk"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?attr/colorWarning"
app:drawableTint="?attr/colorWarning"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLanguageTool" />
<TextView
android:id="@+id/tvLanguageToolPrivacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp"
android:text="@string/title_privacy_policy"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorLink"
app:drawableTint="?android:attr/textColorLink"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvLanguageToolHint" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swLanguageToolSentence"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_lt_sentence"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvLanguageToolPrivacy"
app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swLanguageToolAuto"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_lt_auto"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLanguageToolSentence"
app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swLanguageToolPicky"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_translate_formal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLanguageToolAuto"
app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swLanguageToolHighlight"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_lt_highlight"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLanguageToolPicky"
app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swLanguageToolDescription"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_lt_description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLanguageToolHighlight"
app:switchPadding="12dp" />
<EditText
android:id="@+id/etLanguageTool"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:inputType="textUri"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLanguageToolDescription" />
<EditText
android:id="@+id/etLanguageToolUser"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:hint="@string/title_advanced_lt_user"
android:inputType="textEmailAddress"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etLanguageTool" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilLanguageToolKey"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
app:endIconMode="password_toggle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/etLanguageToolUser">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/title_advanced_lt_key"
android:inputType="textPassword"
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/tvLanguageTool"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:autoLink="web"
android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp"
android:text="https://languagetool.org"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorLink"
app:drawableTint="?android:attr/textColorLink"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tilLanguageToolKey" />
<ImageButton
android:id="@+id/ibLanguageTool"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:contentDescription="@string/title_info"
android:tooltipText="@string/title_info"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvLanguageTool"
app:srcCompat="@drawable/twotone_info_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardDeepL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="3dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="?attr/colorCardBackground"
app:cardCornerRadius="6dp"
app:cardElevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardLanguageTool">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:paddingVertical="12dp">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swDeepL"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/title_advanced_deepl"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:switchPadding="12dp" />
<TextView
android:id="@+id/tvDeepLHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/title_advanced_privacy_risk"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?attr/colorWarning"
app:drawableTint="?attr/colorWarning"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swDeepL" />
<TextView
android:id="@+id/tvDeepLPrivacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp"
android:text="@string/title_privacy_policy"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorLink"
app:drawableTint="?android:attr/textColorLink"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvDeepLHint" />
<ImageButton
android:id="@+id/ibDeepL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:contentDescription="@string/title_translate_configure"
android:tooltipText="@string/title_translate_configure"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvDeepLPrivacy"
app:srcCompat="@drawable/twotone_settings_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardVirusTotal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="3dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="?attr/colorCardBackground"
app:cardCornerRadius="6dp"
app:cardElevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardDeepL">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:paddingVertical="12dp">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swVirusTotal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/title_advanced_virus_total"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:switchPadding="12dp" />
<TextView
android:id="@+id/tvVirusTotalHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/title_advanced_privacy_risk"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?attr/colorWarning"
app:drawableTint="?attr/colorWarning"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swVirusTotal" />
<TextView
android:id="@+id/tvVirusTotalPrivacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp"
android:text="@string/title_privacy_policy"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorLink"
app:drawableTint="?android:attr/textColorLink"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvVirusTotalHint" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilVirusTotal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
app:endIconMode="password_toggle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvVirusTotalPrivacy">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="API key"
android:inputType="textPassword"
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
</com.google.android.material.textfield.TextInputLayout>
<ImageButton
android:id="@+id/ibVirusTotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:contentDescription="@string/title_info"
android:tooltipText="@string/title_info"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tilVirusTotal"
app:srcCompat="@drawable/twotone_info_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardSend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="3dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="?attr/colorCardBackground"
app:cardCornerRadius="6dp"
app:cardElevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardVirusTotal">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:paddingVertical="12dp">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swSend"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/title_advanced_send"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:switchPadding="12dp" />
<EditText
android:id="@+id/etSend"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:hint="wss://send.vis.ee/api/ws"
android:inputType="textUri"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swSend" />
<ImageButton
android:id="@+id/ibSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:contentDescription="@string/title_info"
android:tooltipText="@string/title_info"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etSend"
app:srcCompat="@drawable/twotone_info_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardOpenAi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="3dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="?attr/colorCardBackground"
app:cardCornerRadius="6dp"
app:cardElevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardSend">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:paddingVertical="12dp">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swOpenAi"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/title_advanced_openai"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:switchPadding="12dp" />
<TextView
android:id="@+id/tvOpenAiHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/title_advanced_privacy_risk"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?attr/colorWarning"
app:drawableTint="?attr/colorWarning"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swOpenAi" />
<TextView
android:id="@+id/tvOpenAiPrivacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp"
android:text="@string/title_privacy_policy"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorLink"
app:drawableTint="?android:attr/textColorLink"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvOpenAiHint" />
<EditText
android:id="@+id/etOpenAi"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:hint="https://api.openai.com/"
android:inputType="textUri"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvOpenAiPrivacy" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilOpenAi"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
app:endIconMode="password_toggle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/etOpenAi">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="API key"
android:inputType="textPassword"
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/tvOpenAiModel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_openai_model"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tilOpenAi" />
<EditText
android:id="@+id/etOpenAiModel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:hint="gpt-3.5-turbo"
android:inputType="text"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvOpenAiModel" />
<TextView
android:id="@+id/tvOpenAiTemperature"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="48dp"
android:text="@string/title_advanced_openai_temperature"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etOpenAiModel" />
<SeekBar
android:id="@+id/sbOpenAiTemperature"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:max="20"
android:min="0"
android:progress="10"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvOpenAiTemperature" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swOpenAiModeration"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_openai_moderation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/sbOpenAiTemperature"
app:switchPadding="12dp" />
<ImageButton
android:id="@+id/ibOpenAi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:contentDescription="@string/title_info"
android:tooltipText="@string/title_info"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swOpenAiModeration"
app:srcCompat="@drawable/twotone_info_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</eu.faircode.email.ScrollViewEx>

@ -643,604 +643,6 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardIntegration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="3dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="?attr/colorCardBackground"
app:cardCornerRadius="6dp"
app:cardElevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardGeneral">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:paddingVertical="12dp">
<TextView
android:id="@+id/tvCaptionIntegration"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/title_advanced_caption_integrations"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardLanguageTool"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="3dp"
android:layout_marginTop="12dp"
app:cardBackgroundColor="?attr/colorCardBackground"
app:cardCornerRadius="6dp"
app:cardElevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardIntegration">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:paddingVertical="12dp">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swLanguageTool"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/title_advanced_lt"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:switchPadding="12dp" />
<TextView
android:id="@+id/tvLanguageToolHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/title_advanced_privacy_risk"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?attr/colorWarning"
app:drawableTint="?attr/colorWarning"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLanguageTool" />
<TextView
android:id="@+id/tvLanguageToolPrivacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp"
android:text="@string/title_privacy_policy"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorLink"
app:drawableTint="?android:attr/textColorLink"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvLanguageToolHint" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swLanguageToolSentence"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_lt_sentence"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvLanguageToolPrivacy"
app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swLanguageToolAuto"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_lt_auto"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLanguageToolSentence"
app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swLanguageToolPicky"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_translate_formal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLanguageToolAuto"
app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swLanguageToolHighlight"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_lt_highlight"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLanguageToolPicky"
app:switchPadding="12dp" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swLanguageToolDescription"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_lt_description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLanguageToolHighlight"
app:switchPadding="12dp" />
<EditText
android:id="@+id/etLanguageTool"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:inputType="textUri"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swLanguageToolDescription" />
<EditText
android:id="@+id/etLanguageToolUser"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:hint="@string/title_advanced_lt_user"
android:inputType="textEmailAddress"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etLanguageTool" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilLanguageToolKey"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
app:endIconMode="password_toggle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/etLanguageToolUser">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/title_advanced_lt_key"
android:inputType="textPassword"
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/tvLanguageTool"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:autoLink="web"
android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp"
android:text="https://languagetool.org"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorLink"
app:drawableTint="?android:attr/textColorLink"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tilLanguageToolKey" />
<ImageButton
android:id="@+id/ibLanguageTool"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:contentDescription="@string/title_info"
android:tooltipText="@string/title_info"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvLanguageTool"
app:srcCompat="@drawable/twotone_info_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardDeepL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="3dp"
android:layout_marginTop="12dp"
app:cardBackgroundColor="?attr/colorCardBackground"
app:cardCornerRadius="6dp"
app:cardElevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardLanguageTool">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:paddingVertical="12dp">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swDeepL"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/title_advanced_deepl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:switchPadding="12dp" />
<TextView
android:id="@+id/tvDeepLHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/title_advanced_privacy_risk"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?attr/colorWarning"
app:drawableTint="?attr/colorWarning"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swDeepL" />
<TextView
android:id="@+id/tvDeepLPrivacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp"
android:text="@string/title_privacy_policy"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorLink"
app:drawableTint="?android:attr/textColorLink"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvDeepLHint" />
<ImageButton
android:id="@+id/ibDeepL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:contentDescription="@string/title_translate_configure"
android:tooltipText="@string/title_translate_configure"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvDeepLPrivacy"
app:srcCompat="@drawable/twotone_settings_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardVirusTotal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="3dp"
android:layout_marginTop="12dp"
app:cardBackgroundColor="?attr/colorCardBackground"
app:cardCornerRadius="6dp"
app:cardElevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardDeepL">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:paddingVertical="12dp">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swVirusTotal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/title_advanced_virus_total"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:switchPadding="12dp" />
<TextView
android:id="@+id/tvVirusTotalHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/title_advanced_privacy_risk"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?attr/colorWarning"
app:drawableTint="?attr/colorWarning"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swVirusTotal" />
<TextView
android:id="@+id/tvVirusTotalPrivacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp"
android:text="@string/title_privacy_policy"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorLink"
app:drawableTint="?android:attr/textColorLink"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvVirusTotalHint" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilVirusTotal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
app:endIconMode="password_toggle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvVirusTotalPrivacy">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="API key"
android:inputType="textPassword"
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
</com.google.android.material.textfield.TextInputLayout>
<ImageButton
android:id="@+id/ibVirusTotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:contentDescription="@string/title_info"
android:tooltipText="@string/title_info"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tilVirusTotal"
app:srcCompat="@drawable/twotone_info_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardSend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="3dp"
android:layout_marginTop="12dp"
app:cardBackgroundColor="?attr/colorCardBackground"
app:cardCornerRadius="6dp"
app:cardElevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardVirusTotal">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:paddingVertical="12dp">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swSend"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/title_advanced_send"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:switchPadding="12dp" />
<EditText
android:id="@+id/etSend"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:hint="wss://send.vis.ee/api/ws"
android:inputType="textUri"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swSend" />
<ImageButton
android:id="@+id/ibSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:contentDescription="@string/title_info"
android:tooltipText="@string/title_info"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etSend"
app:srcCompat="@drawable/twotone_info_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardOpenAi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="3dp"
android:layout_marginTop="12dp"
app:cardBackgroundColor="?attr/colorCardBackground"
app:cardCornerRadius="6dp"
app:cardElevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardSend">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:paddingVertical="12dp">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swOpenAi"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/title_advanced_openai"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:switchPadding="12dp" />
<TextView
android:id="@+id/tvOpenAiHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/title_advanced_privacy_risk"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?attr/colorWarning"
app:drawableTint="?attr/colorWarning"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swOpenAi" />
<TextView
android:id="@+id/tvOpenAiPrivacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp"
android:text="@string/title_privacy_policy"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorLink"
app:drawableTint="?android:attr/textColorLink"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvOpenAiHint" />
<EditText
android:id="@+id/etOpenAi"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:hint="https://api.openai.com/"
android:inputType="textUri"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvOpenAiPrivacy" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilOpenAi"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
app:endIconMode="password_toggle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/etOpenAi">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="API key"
android:inputType="textPassword"
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/tvOpenAiModel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_openai_model"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tilOpenAi" />
<EditText
android:id="@+id/etOpenAiModel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:hint="gpt-3.5-turbo"
android:inputType="text"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvOpenAiModel" />
<TextView
android:id="@+id/tvOpenAiTemperature"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="48dp"
android:text="@string/title_advanced_openai_temperature"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etOpenAiModel" />
<SeekBar
android:id="@+id/sbOpenAiTemperature"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:max="20"
android:min="0"
android:progress="10"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvOpenAiTemperature" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/swOpenAiModeration"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_openai_moderation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/sbOpenAiTemperature"
app:switchPadding="12dp" />
<ImageButton
android:id="@+id/ibOpenAi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:contentDescription="@string/title_info"
android:tooltipText="@string/title_info"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swOpenAiModeration"
app:srcCompat="@drawable/twotone_info_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardAdvanced"
android:layout_width="match_parent"
@ -1252,7 +654,7 @@
app:cardElevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardOpenAi">
app:layout_constraintTop_toBottomOf="@id/cardGeneral">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"

Loading…
Cancel
Save