Added unicode account option

pull/209/head
M66B 3 years ago
parent d05dbf0411
commit c2b2016680

File diff suppressed because it is too large Load Diff

@ -269,7 +269,7 @@ public class ActivityEML extends ActivityBase {
if (is == null)
throw new FileNotFoundException(uri.toString());
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(false);
Session isession = Session.getInstance(props, null);
MimeMessage imessage = new MimeMessage(isession, is);
@ -665,12 +665,12 @@ public class ActivityEML extends ActivityBase {
if (is == null)
throw new FileNotFoundException(uri.toString());
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(false);
Session isession = Session.getInstance(props, null);
MimeMessage imessage = new MimeMessage(isession, is);
try (EmailService iservice = new EmailService(
context, account.getProtocol(), account.realm, account.encryption, account.insecure, true)) {
context, account.getProtocol(), account.realm, account.encryption, account.insecure, account.unicode, true)) {
iservice.setPartialFetch(account.partial_fetch);
iservice.setIgnoreBodyStructureSize(account.ignore_size);
iservice.connect(account);

@ -2840,7 +2840,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
for (EntityAttachment attachment : attachments)
if (attachment.available && "message/rfc822".equals(attachment.getMimeType()))
try (FileInputStream fis = new FileInputStream(attachment.getFile(context))) {
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(false);
Session isession = Session.getInstance(props, null);
MimeMessage imessage = new MimeMessage(isession, fis);
MessageHelper helper = new MessageHelper(imessage, context);

@ -500,7 +500,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
EntityLog.log(context, "Boundary server connecting account=" + account.name);
state.iservice = new EmailService(
context, account.getProtocol(), account.realm, account.encryption, account.insecure,
context, account.getProtocol(), account.realm, account.encryption, account.insecure, account.unicode,
EmailService.PURPOSE_SEARCH, debug || BuildConfig.DEBUG);
state.iservice.setPartialFetch(account.partial_fetch);
state.iservice.setIgnoreBodyStructureSize(account.ignore_size);

@ -1164,7 +1164,7 @@ class Core {
db.message().setMessageMsgId(message.id, message.msgid);
}
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(account.unicode);
Session isession = Session.getInstance(props, null);
Flags flags = ifolder.getPermanentFlags();
@ -1461,7 +1461,7 @@ class Core {
imessage.writeTo(os);
}
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(account.unicode);
Session isession = Session.getInstance(props, null);
Message icopy;

@ -71,7 +71,7 @@ import io.requery.android.database.sqlite.SQLiteDatabase;
// https://developer.android.com/topic/libraries/architecture/room.html
@Database(
version = 241,
version = 242,
entities = {
EntityIdentity.class,
EntityAccount.class,
@ -2418,6 +2418,13 @@ public abstract class DB extends RoomDatabase {
db.execSQL("DROP VIEW `folder_view`");
db.execSQL("CREATE VIEW IF NOT EXISTS `folder_view` AS " + TupleFolderView.query);
}
}).addMigrations(new Migration(241, 242) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
logMigration(startVersion, endVersion);
db.execSQL("ALTER TABLE `account` ADD COLUMN `unicode` INTEGER NOT NULL DEFAULT 0");
}
}).addMigrations(new Migration(998, 999) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {

@ -168,18 +168,18 @@ public class EmailService implements AutoCloseable {
// Prevent instantiation
}
EmailService(Context context, String protocol, String realm, int encryption, boolean insecure, boolean debug) throws NoSuchProviderException {
this(context, protocol, realm, encryption, insecure, PURPOSE_USE, debug);
EmailService(Context context, String protocol, String realm, int encryption, boolean insecure, boolean unicode, boolean debug) throws NoSuchProviderException {
this(context, protocol, realm, encryption, insecure, unicode, PURPOSE_USE, debug);
}
EmailService(Context context, String protocol, String realm, int encryption, boolean insecure, int purpose, boolean debug) throws NoSuchProviderException {
EmailService(Context context, String protocol, String realm, int encryption, boolean insecure, boolean unicode, int purpose, boolean debug) throws NoSuchProviderException {
this.context = context.getApplicationContext();
this.protocol = protocol;
this.insecure = insecure;
this.purpose = purpose;
this.debug = debug;
properties = MessageHelper.getSessionProperties();
properties = MessageHelper.getSessionProperties(unicode);
long now = new Date().getTime();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
@ -324,10 +324,6 @@ public class EmailService implements AutoCloseable {
properties.put("mail." + protocol + ".rsetbeforequit", Boolean.toString(keep));
}
void setUnicode(boolean value) {
properties.put("mail.mime.allowutf8", Boolean.toString(value));
}
void set8BitMime(boolean value) {
// https://datatracker.ietf.org/doc/html/rfc6532
properties.put("mail." + protocol + ".allow8bitmime", Boolean.toString(value));

@ -144,6 +144,8 @@ public class EntityAccount extends EntityOrder implements Serializable {
@NonNull
public Boolean use_received = false; // Received header
public String prefix; // namespace, obsolete
@NonNull
public Boolean unicode = false;
public String conditions;
@ -307,6 +309,7 @@ public class EntityAccount extends EntityOrder implements Serializable {
json.put("ignore_size", ignore_size);
json.put("use_date", use_date);
json.put("use_received", use_received);
json.put("unicode", unicode);
json.put("conditions", conditions);
// not prefix
// not created
@ -396,6 +399,7 @@ public class EntityAccount extends EntityOrder implements Serializable {
account.ignore_size = json.optBoolean("ignore_size", false);
account.use_date = json.optBoolean("use_date", false);
account.use_received = json.optBoolean("use_received", false);
account.unicode = json.optBoolean("unicode", false);
account.conditions = json.optString("conditions", null);
return account;
@ -434,6 +438,7 @@ public class EntityAccount extends EntityOrder implements Serializable {
this.ignore_size == other.ignore_size &&
this.use_date == other.use_date &&
this.use_received == other.use_received &&
this.unicode == other.unicode &&
Objects.equals(this.conditions, other.conditions) &&
Objects.equals(this.quota_usage, other.quota_usage) &&
Objects.equals(this.quota_limit, other.quota_limit) &&

@ -125,6 +125,7 @@ public class FragmentAccount extends FragmentBase {
private CheckBox cbPartialFetch;
private CheckBox cbIgnoreSize;
private RadioGroup rgDate;
private CheckBox cbUnicode;
private CheckBox cbUnmetered;
private Button btnCheck;
@ -235,6 +236,7 @@ public class FragmentAccount extends FragmentBase {
cbPartialFetch = view.findViewById(R.id.cbPartialFetch);
cbIgnoreSize = view.findViewById(R.id.cbIgnoreSize);
rgDate = view.findViewById(R.id.rgDate);
cbUnicode = view.findViewById(R.id.cbUnicode);
cbUnmetered = view.findViewById(R.id.cbUnmeteredOnly);
btnCheck = view.findViewById(R.id.btnCheck);
@ -675,6 +677,7 @@ public class FragmentAccount extends FragmentBase {
args.putString("certificate", certificate);
args.putString("realm", etRealm.getText().toString());
args.putString("fingerprint", cbTrust.isChecked() ? (String) cbTrust.getTag() : null);
args.putBoolean("unicode", cbUnicode.isChecked());
new SimpleTask<CheckResult>() {
@Override
@ -719,6 +722,7 @@ public class FragmentAccount extends FragmentBase {
String certificate = args.getString("certificate");
String realm = args.getString("realm");
String fingerprint = args.getString("fingerprint");
boolean unicode = args.getBoolean("unicode");
int semi = host.indexOf(':');
if (semi > 0 && host.indexOf(':', semi + 1) < 0)
@ -745,7 +749,7 @@ public class FragmentAccount extends FragmentBase {
// Check IMAP server / get folders
String protocol = "imap" + (encryption == EmailService.ENCRYPTION_SSL ? "s" : "");
try (EmailService iservice = new EmailService(
context, protocol, realm, encryption, insecure,
context, protocol, realm, encryption, insecure, unicode,
EmailService.PURPOSE_CHECK, true)) {
iservice.connect(
host, Integer.parseInt(port),
@ -899,6 +903,7 @@ public class FragmentAccount extends FragmentBase {
args.putBoolean("ignore_size", cbIgnoreSize.isChecked());
args.putBoolean("use_date", rgDate.getCheckedRadioButtonId() == R.id.radio_date_header);
args.putBoolean("use_received", rgDate.getCheckedRadioButtonId() == R.id.radio_received_header);
args.putBoolean("unicode", cbUnicode.isChecked());
args.putBoolean("unmetered", cbUnmetered.isChecked());
args.putSerializable("drafts", drafts);
@ -970,6 +975,7 @@ public class FragmentAccount extends FragmentBase {
boolean ignore_size = args.getBoolean("ignore_size");
boolean use_date = args.getBoolean("use_date");
boolean use_received = args.getBoolean("use_received");
boolean unicode = args.getBoolean("unicode");
boolean unmetered = args.getBoolean("unmetered");
EntityFolder drafts = (EntityFolder) args.getSerializable("drafts");
@ -1077,6 +1083,8 @@ public class FragmentAccount extends FragmentBase {
return true;
if (!Objects.equals(account.use_received, use_received))
return true;
if (!Objects.equals(account.unicode, unicode))
return true;
if (unmetered != jconditions.optBoolean("unmetered"))
return true;
if (account.error != null && account.synchronize)
@ -1139,7 +1147,7 @@ public class FragmentAccount extends FragmentBase {
if (check) {
String protocol = "imap" + (encryption == EmailService.ENCRYPTION_SSL ? "s" : "");
try (EmailService iservice = new EmailService(
context, protocol, realm, encryption, insecure,
context, protocol, realm, encryption, insecure, unicode,
EmailService.PURPOSE_CHECK, true)) {
iservice.connect(
host, Integer.parseInt(port),
@ -1220,6 +1228,8 @@ public class FragmentAccount extends FragmentBase {
account.use_date = use_date;
account.use_received = use_received;
account.unicode = unicode;
jconditions.put("unmetered", unmetered);
account.conditions = jconditions.toString();
@ -1580,6 +1590,7 @@ public class FragmentAccount extends FragmentBase {
etInterval.setText(account == null ? "" : Long.toString(account.poll_interval));
cbPartialFetch.setChecked(account == null ? true : account.partial_fetch);
cbIgnoreSize.setChecked(account == null ? false : account.ignore_size);
cbUnicode.setChecked(account == null ? false : account.unicode);
cbUnmetered.setChecked(jcondition.optBoolean("unmetered"));
if (account != null && account.use_date)

@ -3368,7 +3368,7 @@ public class FragmentCompose extends FragmentBase {
}
// Build message
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(false);
Session isession = Session.getInstance(props, null);
MimeMessage imessage = new MimeMessage(isession);
MessageHelper.build(context, draft, attachments, identity, true, imessage);
@ -3720,7 +3720,7 @@ public class FragmentCompose extends FragmentBase {
}
// Build message to sign
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(false);
Session isession = Session.getInstance(props, null);
MimeMessage imessage = new MimeMessage(isession);
MessageHelper.build(context, draft, attachments, identity, true, imessage);
@ -6405,7 +6405,7 @@ public class FragmentCompose extends FragmentBase {
// Check size
if (identity != null && identity.max_size != null)
try {
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(false);
if (identity.unicode)
props.put("mail.mime.allowutf8", "true");
Session isession = Session.getInstance(props, null);

@ -1270,7 +1270,7 @@ public class FragmentFolders extends FragmentBase {
String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy";
SimpleDateFormat df = new SimpleDateFormat(PATTERN_ASCTIME, Locale.US);
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(false);
Session isession = Session.getInstance(props, null);
// https://www.ietf.org/rfc/rfc4155.txt (Appendix A)

@ -468,7 +468,7 @@ public class FragmentGmail extends FragmentBase {
String aprotocol = (pop ? (inbound.starttls ? "pop3" : "pop3s") : (inbound.starttls ? "imap" : "imaps"));
int aencryption = (inbound.starttls ? EmailService.ENCRYPTION_STARTTLS : EmailService.ENCRYPTION_SSL);
try (EmailService aservice = new EmailService(
context, aprotocol, null, aencryption, false,
context, aprotocol, null, aencryption, false, false,
EmailService.PURPOSE_CHECK, true)) {
aservice.connect(
inbound.host, inbound.port,
@ -486,7 +486,7 @@ public class FragmentGmail extends FragmentBase {
String iprotocol = (provider.smtp.starttls ? "smtp" : "smtps");
int iencryption = (provider.smtp.starttls ? EmailService.ENCRYPTION_STARTTLS : EmailService.ENCRYPTION_SSL);
try (EmailService iservice = new EmailService(
context, iprotocol, null, iencryption, false,
context, iprotocol, null, iencryption, false, false,
EmailService.PURPOSE_CHECK, true)) {
iservice.connect(
provider.smtp.host, provider.smtp.port,

@ -950,7 +950,7 @@ public class FragmentIdentity extends FragmentBase {
// Create transport
String protocol = (encryption == EmailService.ENCRYPTION_SSL ? "smtps" : "smtp");
try (EmailService iservice = new EmailService(
context, protocol, realm, encryption, insecure,
context, protocol, realm, encryption, insecure, unicode,
EmailService.PURPOSE_CHECK, true)) {
iservice.setUseIp(use_ip, ehlo);
iservice.connect(

@ -8115,7 +8115,7 @@ public class FragmentMessages extends FragmentBase
} else {
// Decode message
MessageHelper.MessageParts parts;
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(false);
Session isession = Session.getInstance(props, null);
MimeMessage imessage;
try (InputStream fis = new FileInputStream(plain)) {
@ -8814,7 +8814,7 @@ public class FragmentMessages extends FragmentBase
boolean duplicate = args.getBoolean("duplicate");
// Decode message
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(false);
Session isession = Session.getInstance(props, null);
MimeMessage imessage = new MimeMessage(isession, is);
MessageHelper helper = new MessageHelper(imessage, context);
@ -8927,7 +8927,7 @@ public class FragmentMessages extends FragmentBase
for (EntityAttachment remote : remotes)
if ("message/rfc822".equals(remote.getMimeType()))
try {
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(false);
Session isession = Session.getInstance(props, null);
MimeMessage imessage;

@ -700,7 +700,7 @@ public class FragmentOAuth extends FragmentBase {
EntityLog.log(context, "Trying username=" + alt);
try {
try (EmailService aservice = new EmailService(
context, aprotocol, null, aencryption, false,
context, aprotocol, null, aencryption, false, false,
EmailService.PURPOSE_CHECK, true)) {
aservice.connect(
inbound.host, inbound.port,
@ -709,7 +709,7 @@ public class FragmentOAuth extends FragmentBase {
null, null);
}
try (EmailService iservice = new EmailService(
context, iprotocol, null, iencryption, false,
context, iprotocol, null, iencryption, false, false,
EmailService.PURPOSE_CHECK, true)) {
iservice.connect(
provider.smtp.host, provider.smtp.port,
@ -770,7 +770,7 @@ public class FragmentOAuth extends FragmentBase {
Log.i("OAuth checking IMAP/POP3 provider=" + provider.id);
try (EmailService aservice = new EmailService(
context, aprotocol, null, aencryption, false,
context, aprotocol, null, aencryption, false, false,
EmailService.PURPOSE_CHECK, true)) {
aservice.connect(
inbound.host, inbound.port,
@ -789,7 +789,7 @@ public class FragmentOAuth extends FragmentBase {
Log.i("OAuth checking SMTP provider=" + provider.id);
try (EmailService iservice = new EmailService(
context, iprotocol, null, iencryption, false,
context, iprotocol, null, iencryption, false, false,
EmailService.PURPOSE_CHECK, true)) {
iservice.connect(
provider.smtp.host, provider.smtp.port,

@ -505,7 +505,7 @@ public class FragmentPop extends FragmentBase {
if (check) {
String protocol = "pop3" + (encryption == EmailService.ENCRYPTION_SSL ? "s" : "");
try (EmailService iservice = new EmailService(
context, protocol, null, encryption, insecure,
context, protocol, null, encryption, insecure, false,
EmailService.PURPOSE_CHECK, true)) {
iservice.connect(
host, Integer.parseInt(port),

@ -365,7 +365,8 @@ public class FragmentQuickSetup extends FragmentBase {
String aprotocol = (provider.imap.starttls ? "imap" : "imaps");
int aencryption = (provider.imap.starttls ? EmailService.ENCRYPTION_STARTTLS : EmailService.ENCRYPTION_SSL);
try (EmailService iservice = new EmailService(
context, aprotocol, null, aencryption, false, EmailService.PURPOSE_CHECK, true)) {
context, aprotocol, null, aencryption, false, false,
EmailService.PURPOSE_CHECK, true)) {
List<Throwable> exceptions = new ArrayList<>();
for (int i = 0; i < users.size(); i++) {
user = users.get(i);
@ -473,7 +474,7 @@ public class FragmentQuickSetup extends FragmentBase {
String iprotocol = (provider.smtp.starttls ? "smtp" : "smtps");
int iencryption = (provider.smtp.starttls ? EmailService.ENCRYPTION_STARTTLS : EmailService.ENCRYPTION_SSL);
try (EmailService iservice = new EmailService(
context, iprotocol, null, iencryption, false,
context, iprotocol, null, iencryption, false, false,
EmailService.PURPOSE_CHECK, true)) {
iservice.setUseIp(provider.useip, null);
try {

@ -268,11 +268,12 @@ public class MessageHelper {
System.setProperty("fairemail.uid_command", Boolean.toString(uid_command));
}
static Properties getSessionProperties() {
static Properties getSessionProperties(boolean unicode) {
Properties props = new Properties();
// MIME
props.put("mail.mime.allowutf8", "false"); // SMTPTransport, MimeMessage
// https://javaee.github.io/javamail/docs/api/javax/mail/internet/package-summary.html
props.put("mail.mime.allowutf8", Boolean.toString(unicode)); // SMTPTransport, MimeMessage
props.put("mail.mime.address.strict", "false");
return props;
@ -1366,7 +1367,7 @@ public class MessageHelper {
reportHeaders = new InternetHeaders(apart.part.getInputStream());
break;
} else if ("message/rfc822".equalsIgnoreCase(apart.attachment.type)) {
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(false);
Session isession = Session.getInstance(props, null);
MimeMessage amessage = new MimeMessage(isession, apart.part.getInputStream());
reportHeaders = amessage.getHeaders();
@ -3622,7 +3623,7 @@ public class MessageHelper {
if ("message/rfc822".equals(local.type))
try (FileInputStream fis = new FileInputStream(local.getFile(context))) {
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(false);
Session isession = Session.getInstance(props, null);
MimeMessage imessage = new MimeMessage(isession, fis);
MessageHelper helper = new MessageHelper(imessage, context);
@ -4543,7 +4544,7 @@ public class MessageHelper {
if (bis.available() == 0)
throw new IOException("NIL");
Properties props = MessageHelper.getSessionProperties();
Properties props = MessageHelper.getSessionProperties(false);
Session isession = Session.getInstance(props, null);
Log.w("Decoding raw message");

@ -558,10 +558,7 @@ public class ServiceSend extends ServiceBase implements SharedPreferences.OnShar
db.message().setMessageSent(message.id, message.sent);
// Create message
Properties props = MessageHelper.getSessionProperties();
// https://javaee.github.io/javamail/docs/api/javax/mail/internet/package-summary.html
if (ident.unicode)
props.put("mail.mime.allowutf8", "true");
Properties props = MessageHelper.getSessionProperties(ident.unicode);
Session isession = Session.getInstance(props, null);
MimeMessage imessage = MessageHelper.from(this, message, ident, isession, true);
@ -671,10 +668,9 @@ public class ServiceSend extends ServiceBase implements SharedPreferences.OnShar
long start, end;
Long max_size = null;
EmailService iservice = new EmailService(
this, ident.getProtocol(), ident.realm, ident.encryption, ident.insecure, debug);
this, ident.getProtocol(), ident.realm, ident.encryption, ident.insecure, ident.unicode, debug);
try {
iservice.setUseIp(ident.use_ip, ident.ehlo);
iservice.setUnicode(ident.unicode);
iservice.set8BitMime(ident.octetmime);
// 0=Read receipt

@ -1507,7 +1507,7 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
boolean debug = (prefs.getBoolean("debug", false) || BuildConfig.DEBUG);
final EmailService iservice = new EmailService(
this, account.getProtocol(), account.realm, account.encryption, account.insecure, debug);
this, account.getProtocol(), account.realm, account.encryption, account.insecure, account.unicode, debug);
iservice.setPartialFetch(account.partial_fetch);
iservice.setIgnoreBodyStructureSize(account.ignore_size);
if (account.protocol != EntityAccount.TYPE_IMAP)

@ -296,10 +296,10 @@
android:layout_marginTop="12dp"
android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp"
app:drawableTint="?android:attr/textColorLink"
android:text="@string/title_setup_app_password"
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/tvCaseSensitive" />
@ -310,10 +310,10 @@
android:layout_marginTop="12dp"
android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp"
app:drawableTint="?android:attr/textColorLink"
android:text="@string/title_password_storage"
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/tvAppPassword" />
@ -678,6 +678,15 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/rgDate" />
<CheckBox
android:id="@+id/cbUnicode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_identity_unicode"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvDateRemark" />
<CheckBox
android:id="@+id/cbUnmeteredOnly"
android:layout_width="wrap_content"
@ -685,7 +694,7 @@
android:layout_marginTop="12dp"
android:text="@string/title_unmetered_only"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvDateRemark" />
app:layout_constraintTop_toBottomOf="@id/cbUnicode" />
<!-- check -->
@ -1013,10 +1022,10 @@
android:backgroundTint="?attr/colorInfoBackground"
android:drawableEnd="@drawable/twotone_support_24"
android:drawablePadding="6dp"
app:drawableTint="?attr/colorInfoForeground"
android:text="@string/menu_faq"
android:textColor="?attr/colorInfoForeground"
android:textStyle="bold"
app:drawableTint="?attr/colorInfoForeground"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbTrust" />
@ -1028,10 +1037,10 @@
android:backgroundTint="?attr/colorInfoBackground"
android:drawableEnd="@drawable/twotone_help_24"
android:drawablePadding="6dp"
app:drawableTint="?attr/colorInfoForeground"
android:text="@string/title_setup_help"
android:textColor="?attr/colorInfoForeground"
android:textStyle="bold"
app:drawableTint="?attr/colorInfoForeground"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbTrust" />
@ -1087,7 +1096,7 @@
cbAutoSeen,
tvInterval,etInterval,tvIntervalRemark,
cbPartialFetch,tvPartialFetchRemark,cbIgnoreSize,rgDate,tvDateRemark,
cbUnmeteredOnly" />
cbUnicode,cbUnmeteredOnly" />
<androidx.constraintlayout.widget.Group
android:id="@+id/grpFolders"

Loading…
Cancel
Save