diff --git a/app/schemas/eu.faircode.email.DB/7.json b/app/schemas/eu.faircode.email.DB/7.json
new file mode 100644
index 0000000000..a660d8fb69
--- /dev/null
+++ b/app/schemas/eu.faircode.email.DB/7.json
@@ -0,0 +1,891 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 7,
+ "identityHash": "78658430615109b7c163e62ed1ad0a48",
+ "entities": [
+ {
+ "tableName": "identity",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `replyto` TEXT, `account` INTEGER NOT NULL, `host` TEXT NOT NULL, `port` INTEGER NOT NULL, `starttls` INTEGER NOT NULL, `user` TEXT NOT NULL, `password` TEXT NOT NULL, `auth_type` INTEGER NOT NULL, `primary` INTEGER NOT NULL, `synchronize` INTEGER NOT NULL, `store_sent` INTEGER NOT NULL, `state` TEXT, `error` TEXT, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "email",
+ "columnName": "email",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "replyto",
+ "columnName": "replyto",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "account",
+ "columnName": "account",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "host",
+ "columnName": "host",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "port",
+ "columnName": "port",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "starttls",
+ "columnName": "starttls",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "user",
+ "columnName": "user",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "password",
+ "columnName": "password",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "auth_type",
+ "columnName": "auth_type",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "primary",
+ "columnName": "primary",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "synchronize",
+ "columnName": "synchronize",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "store_sent",
+ "columnName": "store_sent",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "error",
+ "columnName": "error",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_identity_account",
+ "unique": false,
+ "columnNames": [
+ "account"
+ ],
+ "createSql": "CREATE INDEX `index_identity_account` ON `${TABLE_NAME}` (`account`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "account",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "account"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "account",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT, `host` TEXT NOT NULL, `port` INTEGER NOT NULL, `user` TEXT NOT NULL, `password` TEXT NOT NULL, `auth_type` INTEGER NOT NULL, `primary` INTEGER NOT NULL, `synchronize` INTEGER NOT NULL, `store_sent` INTEGER NOT NULL, `poll_interval` INTEGER NOT NULL, `seen_until` INTEGER, `state` TEXT, `error` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "host",
+ "columnName": "host",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "port",
+ "columnName": "port",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "user",
+ "columnName": "user",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "password",
+ "columnName": "password",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "auth_type",
+ "columnName": "auth_type",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "primary",
+ "columnName": "primary",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "synchronize",
+ "columnName": "synchronize",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "store_sent",
+ "columnName": "store_sent",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "poll_interval",
+ "columnName": "poll_interval",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "seen_until",
+ "columnName": "seen_until",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "error",
+ "columnName": "error",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "folder",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `account` INTEGER, `name` TEXT NOT NULL, `type` TEXT NOT NULL, `synchronize` INTEGER NOT NULL, `after` INTEGER NOT NULL, `state` TEXT, `error` TEXT, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "account",
+ "columnName": "account",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "synchronize",
+ "columnName": "synchronize",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "after",
+ "columnName": "after",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "error",
+ "columnName": "error",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_folder_account_name",
+ "unique": true,
+ "columnNames": [
+ "account",
+ "name"
+ ],
+ "createSql": "CREATE UNIQUE INDEX `index_folder_account_name` ON `${TABLE_NAME}` (`account`, `name`)"
+ },
+ {
+ "name": "index_folder_account",
+ "unique": false,
+ "columnNames": [
+ "account"
+ ],
+ "createSql": "CREATE INDEX `index_folder_account` ON `${TABLE_NAME}` (`account`)"
+ },
+ {
+ "name": "index_folder_name",
+ "unique": false,
+ "columnNames": [
+ "name"
+ ],
+ "createSql": "CREATE INDEX `index_folder_name` ON `${TABLE_NAME}` (`name`)"
+ },
+ {
+ "name": "index_folder_type",
+ "unique": false,
+ "columnNames": [
+ "type"
+ ],
+ "createSql": "CREATE INDEX `index_folder_type` ON `${TABLE_NAME}` (`type`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "account",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "account"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "message",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `account` INTEGER, `folder` INTEGER NOT NULL, `identity` INTEGER, `replying` INTEGER, `uid` INTEGER, `msgid` TEXT, `references` TEXT, `inreplyto` TEXT, `thread` TEXT, `from` TEXT, `to` TEXT, `cc` TEXT, `bcc` TEXT, `reply` TEXT, `subject` TEXT, `sent` INTEGER, `received` INTEGER NOT NULL, `stored` INTEGER NOT NULL, `seen` INTEGER NOT NULL, `ui_seen` INTEGER NOT NULL, `ui_hide` INTEGER NOT NULL, `ui_found` INTEGER NOT NULL, `error` TEXT, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`folder`) REFERENCES `folder`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`identity`) REFERENCES `identity`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`replying`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "account",
+ "columnName": "account",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "folder",
+ "columnName": "folder",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "identity",
+ "columnName": "identity",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "replying",
+ "columnName": "replying",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "msgid",
+ "columnName": "msgid",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "references",
+ "columnName": "references",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "inreplyto",
+ "columnName": "inreplyto",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "thread",
+ "columnName": "thread",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "from",
+ "columnName": "from",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "to",
+ "columnName": "to",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "cc",
+ "columnName": "cc",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "bcc",
+ "columnName": "bcc",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "reply",
+ "columnName": "reply",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "sent",
+ "columnName": "sent",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "received",
+ "columnName": "received",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "stored",
+ "columnName": "stored",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "seen",
+ "columnName": "seen",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ui_seen",
+ "columnName": "ui_seen",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ui_hide",
+ "columnName": "ui_hide",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ui_found",
+ "columnName": "ui_found",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "error",
+ "columnName": "error",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_message_account",
+ "unique": false,
+ "columnNames": [
+ "account"
+ ],
+ "createSql": "CREATE INDEX `index_message_account` ON `${TABLE_NAME}` (`account`)"
+ },
+ {
+ "name": "index_message_folder",
+ "unique": false,
+ "columnNames": [
+ "folder"
+ ],
+ "createSql": "CREATE INDEX `index_message_folder` ON `${TABLE_NAME}` (`folder`)"
+ },
+ {
+ "name": "index_message_identity",
+ "unique": false,
+ "columnNames": [
+ "identity"
+ ],
+ "createSql": "CREATE INDEX `index_message_identity` ON `${TABLE_NAME}` (`identity`)"
+ },
+ {
+ "name": "index_message_replying",
+ "unique": false,
+ "columnNames": [
+ "replying"
+ ],
+ "createSql": "CREATE INDEX `index_message_replying` ON `${TABLE_NAME}` (`replying`)"
+ },
+ {
+ "name": "index_message_folder_uid",
+ "unique": true,
+ "columnNames": [
+ "folder",
+ "uid"
+ ],
+ "createSql": "CREATE UNIQUE INDEX `index_message_folder_uid` ON `${TABLE_NAME}` (`folder`, `uid`)"
+ },
+ {
+ "name": "index_message_msgid_folder",
+ "unique": true,
+ "columnNames": [
+ "msgid",
+ "folder"
+ ],
+ "createSql": "CREATE UNIQUE INDEX `index_message_msgid_folder` ON `${TABLE_NAME}` (`msgid`, `folder`)"
+ },
+ {
+ "name": "index_message_thread",
+ "unique": false,
+ "columnNames": [
+ "thread"
+ ],
+ "createSql": "CREATE INDEX `index_message_thread` ON `${TABLE_NAME}` (`thread`)"
+ },
+ {
+ "name": "index_message_received",
+ "unique": false,
+ "columnNames": [
+ "received"
+ ],
+ "createSql": "CREATE INDEX `index_message_received` ON `${TABLE_NAME}` (`received`)"
+ },
+ {
+ "name": "index_message_ui_seen",
+ "unique": false,
+ "columnNames": [
+ "ui_seen"
+ ],
+ "createSql": "CREATE INDEX `index_message_ui_seen` ON `${TABLE_NAME}` (`ui_seen`)"
+ },
+ {
+ "name": "index_message_ui_hide",
+ "unique": false,
+ "columnNames": [
+ "ui_hide"
+ ],
+ "createSql": "CREATE INDEX `index_message_ui_hide` ON `${TABLE_NAME}` (`ui_hide`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "account",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "account"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ },
+ {
+ "table": "folder",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "folder"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ },
+ {
+ "table": "identity",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "identity"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ },
+ {
+ "table": "message",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "replying"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "attachment",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `message` INTEGER NOT NULL, `sequence` INTEGER NOT NULL, `name` TEXT, `type` TEXT NOT NULL, `size` INTEGER, `progress` INTEGER, `available` INTEGER NOT NULL, FOREIGN KEY(`message`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "message",
+ "columnName": "message",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "sequence",
+ "columnName": "sequence",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "size",
+ "columnName": "size",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "progress",
+ "columnName": "progress",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "available",
+ "columnName": "available",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_attachment_message",
+ "unique": false,
+ "columnNames": [
+ "message"
+ ],
+ "createSql": "CREATE INDEX `index_attachment_message` ON `${TABLE_NAME}` (`message`)"
+ },
+ {
+ "name": "index_attachment_message_sequence",
+ "unique": true,
+ "columnNames": [
+ "message",
+ "sequence"
+ ],
+ "createSql": "CREATE UNIQUE INDEX `index_attachment_message_sequence` ON `${TABLE_NAME}` (`message`, `sequence`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "message",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "message"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "operation",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `folder` INTEGER NOT NULL, `message` INTEGER NOT NULL, `name` TEXT NOT NULL, `args` TEXT NOT NULL, `created` INTEGER NOT NULL, FOREIGN KEY(`folder`) REFERENCES `folder`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`message`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "folder",
+ "columnName": "folder",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "message",
+ "columnName": "message",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "args",
+ "columnName": "args",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "created",
+ "columnName": "created",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_operation_folder",
+ "unique": false,
+ "columnNames": [
+ "folder"
+ ],
+ "createSql": "CREATE INDEX `index_operation_folder` ON `${TABLE_NAME}` (`folder`)"
+ },
+ {
+ "name": "index_operation_message",
+ "unique": false,
+ "columnNames": [
+ "message"
+ ],
+ "createSql": "CREATE INDEX `index_operation_message` ON `${TABLE_NAME}` (`message`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "folder",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "folder"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ },
+ {
+ "table": "message",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "message"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "answer",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `text` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "text",
+ "columnName": "text",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "log",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `time` INTEGER NOT NULL, `data` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "time",
+ "columnName": "time",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "data",
+ "columnName": "data",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_log_time",
+ "unique": false,
+ "columnNames": [
+ "time"
+ ],
+ "createSql": "CREATE INDEX `index_log_time` ON `${TABLE_NAME}` (`time`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"78658430615109b7c163e62ed1ad0a48\")"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/eu/faircode/email/AdapterLog.java b/app/src/main/java/eu/faircode/email/AdapterLog.java
new file mode 100644
index 0000000000..2f7b0a7fcf
--- /dev/null
+++ b/app/src/main/java/eu/faircode/email/AdapterLog.java
@@ -0,0 +1,162 @@
+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.
+
+ NetGuard 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 NetGuard. If not, see .
+
+ Copyright 2018 by Marcel Bokhorst (M66B)
+*/
+
+import android.content.Context;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.DiffUtil;
+import androidx.recyclerview.widget.ListUpdateCallback;
+import androidx.recyclerview.widget.RecyclerView;
+
+public class AdapterLog extends RecyclerView.Adapter {
+ private Context context;
+
+ private List all = new ArrayList<>();
+ private List filtered = new ArrayList<>();
+
+ private static final DateFormat DF = SimpleDateFormat.getTimeInstance();
+
+ public class ViewHolder extends RecyclerView.ViewHolder {
+ View itemView;
+ TextView tvTime;
+ TextView tvData;
+
+ ViewHolder(View itemView) {
+ super(itemView);
+
+ this.itemView = itemView;
+ tvTime = itemView.findViewById(R.id.tvTime);
+ tvData = itemView.findViewById(R.id.tvData);
+ }
+
+ private void bindTo(EntityLog log) {
+ tvTime.setText(DF.format(log.time));
+ tvData.setText(log.data);
+ }
+ }
+
+
+ AdapterLog(Context context) {
+ this.context = context;
+ setHasStableIds(true);
+ }
+
+ public void set(@NonNull List logs) {
+ Log.i(Helper.TAG, "Set logs=" + logs.size());
+
+ all.clear();
+ all.addAll(logs);
+
+ DiffUtil.DiffResult diff = DiffUtil.calculateDiff(new MessageDiffCallback(filtered, all));
+
+ filtered.clear();
+ filtered.addAll(all);
+
+ diff.dispatchUpdatesTo(new ListUpdateCallback() {
+ @Override
+ public void onInserted(int position, int count) {
+ Log.i(Helper.TAG, "Inserted @" + position + " #" + count);
+ }
+
+ @Override
+ public void onRemoved(int position, int count) {
+ Log.i(Helper.TAG, "Removed @" + position + " #" + count);
+ }
+
+ @Override
+ public void onMoved(int fromPosition, int toPosition) {
+ Log.i(Helper.TAG, "Moved " + fromPosition + ">" + toPosition);
+ }
+
+ @Override
+ public void onChanged(int position, int count, Object payload) {
+ Log.i(Helper.TAG, "Changed @" + position + " #" + count);
+ }
+ });
+ diff.dispatchUpdatesTo(this);
+ }
+
+ private class MessageDiffCallback extends DiffUtil.Callback {
+ private List prev;
+ private List next;
+
+ MessageDiffCallback(List prev, List next) {
+ this.prev = prev;
+ this.next = next;
+ }
+
+ @Override
+ public int getOldListSize() {
+ return prev.size();
+ }
+
+ @Override
+ public int getNewListSize() {
+ return next.size();
+ }
+
+ @Override
+ public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
+ EntityLog l1 = prev.get(oldItemPosition);
+ EntityLog l2 = next.get(newItemPosition);
+ return l1.id.equals(l2.id);
+ }
+
+ @Override
+ public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
+ EntityLog l1 = prev.get(oldItemPosition);
+ EntityLog l2 = next.get(newItemPosition);
+ return l1.equals(l2);
+ }
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return filtered.get(position).id;
+ }
+
+ @Override
+ public int getItemCount() {
+ return filtered.size();
+ }
+
+ @Override
+ @NonNull
+ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_log, parent, false));
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+ EntityLog log = filtered.get(position);
+ holder.bindTo(log);
+ }
+}
diff --git a/app/src/main/java/eu/faircode/email/DB.java b/app/src/main/java/eu/faircode/email/DB.java
index 24cdf8da29..00bdda86a8 100644
--- a/app/src/main/java/eu/faircode/email/DB.java
+++ b/app/src/main/java/eu/faircode/email/DB.java
@@ -45,7 +45,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase;
// https://developer.android.com/topic/libraries/architecture/room.html
@Database(
- version = 6,
+ version = 7,
entities = {
EntityIdentity.class,
EntityAccount.class,
@@ -54,6 +54,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase;
EntityAttachment.class,
EntityOperation.class,
EntityAnswer.class,
+ EntityLog.class
}
)
@@ -73,6 +74,8 @@ public abstract class DB extends RoomDatabase {
public abstract DaoAnswer answer();
+ public abstract DaoLog log();
+
private static DB sInstance;
private static final String DB_NAME = "email";
@@ -150,6 +153,14 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `message` ADD COLUMN `ui_found` INTEGER NOT NULL DEFAULT 0");
}
})
+ .addMigrations(new Migration(6, 7) {
+ @Override
+ public void migrate(SupportSQLiteDatabase db) {
+ Log.i(Helper.TAG, "DB migration from version " + startVersion + " to " + endVersion);
+ db.execSQL("CREATE TABLE IF NOT EXISTS `log` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `time` INTEGER NOT NULL, `data` TEXT NOT NULL)");
+ db.execSQL("CREATE INDEX `index_log_time` ON `log` (`time`)");
+ }
+ })
.build();
}
diff --git a/app/src/main/java/eu/faircode/email/DaoLog.java b/app/src/main/java/eu/faircode/email/DaoLog.java
new file mode 100644
index 0000000000..66f58801c0
--- /dev/null
+++ b/app/src/main/java/eu/faircode/email/DaoLog.java
@@ -0,0 +1,36 @@
+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.
+
+ NetGuard 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 NetGuard. If not, see .
+
+ Copyright 2018 by Marcel Bokhorst (M66B)
+*/
+
+import java.util.List;
+
+import androidx.lifecycle.LiveData;
+import androidx.room.Dao;
+import androidx.room.Insert;
+import androidx.room.Query;
+
+@Dao
+public interface DaoLog {
+ @Query("SELECT * FROM log ORDER BY time DESC LIMIT 500")
+ LiveData> liveLogs();
+
+ @Insert
+ long insertLog(EntityLog log);
+}
diff --git a/app/src/main/java/eu/faircode/email/EntityLog.java b/app/src/main/java/eu/faircode/email/EntityLog.java
new file mode 100644
index 0000000000..b8ddf4b0cc
--- /dev/null
+++ b/app/src/main/java/eu/faircode/email/EntityLog.java
@@ -0,0 +1,64 @@
+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.
+
+ NetGuard 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 NetGuard. If not, see .
+
+ Copyright 2018 by Marcel Bokhorst (M66B)
+*/
+
+import android.content.Context;
+
+import java.util.Date;
+
+import androidx.annotation.NonNull;
+import androidx.room.Entity;
+import androidx.room.Index;
+import androidx.room.PrimaryKey;
+
+@Entity(
+ tableName = EntityLog.TABLE_NAME,
+ foreignKeys = {
+ },
+ indices = {
+ @Index(value = {"time"})
+ }
+)
+public class EntityLog {
+ static final String TABLE_NAME = "log";
+
+ @PrimaryKey(autoGenerate = true)
+ public Long id;
+ @NonNull
+ public Long time;
+ @NonNull
+ public String data;
+
+ static void log(Context context, String data) {
+ EntityLog entry = new EntityLog();
+ entry.time = new Date().getTime();
+ entry.data = data;
+ DB.getInstance(context).log().insertLog(entry);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof EntityLog) {
+ EntityLog other = (EntityLog) obj;
+ return (this.time.equals(other.time) && this.data.equals(other.data));
+ } else
+ return false;
+ }
+}
diff --git a/app/src/main/java/eu/faircode/email/FragmentAbout.java b/app/src/main/java/eu/faircode/email/FragmentAbout.java
index bbcb0a7a2f..941d1a7454 100644
--- a/app/src/main/java/eu/faircode/email/FragmentAbout.java
+++ b/app/src/main/java/eu/faircode/email/FragmentAbout.java
@@ -39,8 +39,13 @@ import javax.mail.Address;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentTransaction;
public class FragmentAbout extends FragmentEx {
+ private TextView tvVersion;
+ private Button btnLog;
+ private Button btnDebugInfo;
+
@Override
@Nullable
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@@ -48,11 +53,21 @@ public class FragmentAbout extends FragmentEx {
View view = inflater.inflate(R.layout.fragment_about, container, false);
- TextView tvVersion = view.findViewById(R.id.tvVersion);
- final Button btnDebugInfo = view.findViewById(R.id.btnDebugInfo);
+ tvVersion = view.findViewById(R.id.tvVersion);
+ btnLog = view.findViewById(R.id.btnLog);
+ btnDebugInfo = view.findViewById(R.id.btnDebugInfo);
tvVersion.setText(getString(R.string.title_version, BuildConfig.VERSION_NAME));
+ btnLog.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
+ fragmentTransaction.replace(R.id.content_frame, new FragmentLogs()).addToBackStack("logs");
+ fragmentTransaction.commit();
+ }
+ });
+
btnDebugInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
diff --git a/app/src/main/java/eu/faircode/email/FragmentLogs.java b/app/src/main/java/eu/faircode/email/FragmentLogs.java
new file mode 100644
index 0000000000..279d0d139a
--- /dev/null
+++ b/app/src/main/java/eu/faircode/email/FragmentLogs.java
@@ -0,0 +1,91 @@
+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.
+
+ NetGuard 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 NetGuard. If not, see .
+
+ Copyright 2018 by Marcel Bokhorst (M66B)
+*/
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ProgressBar;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.constraintlayout.widget.Group;
+import androidx.lifecycle.Observer;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+public class FragmentLogs extends FragmentEx {
+ private RecyclerView rvLog;
+ private ProgressBar pbWait;
+ private Group grpReady;
+
+ private AdapterLog adapter;
+
+ @Override
+ @Nullable
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ setSubtitle(R.string.title_log);
+
+ View view = inflater.inflate(R.layout.fragment_logs, container, false);
+
+ // Get controls
+ rvLog = view.findViewById(R.id.rvLog);
+ pbWait = view.findViewById(R.id.pbWait);
+ grpReady = view.findViewById(R.id.grpReady);
+
+ // Wire controls
+
+ rvLog.setHasFixedSize(false);
+ LinearLayoutManager llm = new LinearLayoutManager(getContext());
+ rvLog.setLayoutManager(llm);
+
+ adapter = new AdapterLog(getContext());
+ rvLog.setAdapter(adapter);
+
+ // Initialize
+ grpReady.setVisibility(View.GONE);
+ pbWait.setVisibility(View.VISIBLE);
+
+ return view;
+ }
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ DB db = DB.getInstance(getContext());
+ db.log().liveLogs().observe(getViewLifecycleOwner(), new Observer>() {
+ @Override
+ public void onChanged(List logs) {
+ if (logs == null)
+ logs = new ArrayList<>();
+
+ adapter.set(logs);
+
+ pbWait.setVisibility(View.GONE);
+ grpReady.setVisibility(View.VISIBLE);
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
index b90d430d9f..727984723b 100644
--- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
+++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
@@ -358,6 +358,8 @@ public class ServiceSynchronize extends LifecycleService {
// MailConnectException
// - on connectity problems when connecting to store
+ EntityLog.log(this, ex.toString());
+
if (!(ex instanceof MailConnectException) &&
!(ex instanceof FolderClosedException) &&
!(ex instanceof IllegalStateException) &&
@@ -1433,7 +1435,10 @@ public class ServiceSynchronize extends LifecycleService {
@Override
public void onAvailable(Network network) {
- Log.i(Helper.TAG, "Network available " + network);
+ ConnectivityManager cm = getSystemService(ConnectivityManager.class);
+ NetworkInfo ni = cm.getNetworkInfo(network);
+ Log.i(Helper.TAG, "Network available " + network + " " + ni);
+ EntityLog.log(ServiceSynchronize.this, "Network available " + network + " " + ni);
if (running)
Log.i(Helper.TAG, "Service already running");
@@ -1453,14 +1458,16 @@ public class ServiceSynchronize extends LifecycleService {
@Override
public void onLost(Network network) {
Log.i(Helper.TAG, "Network lost " + network);
+ EntityLog.log(ServiceSynchronize.this, "Network lost " + network);
if (running) {
Log.i(Helper.TAG, "Service running");
ConnectivityManager cm = getSystemService(ConnectivityManager.class);
- NetworkInfo ni = cm.getActiveNetworkInfo();
- Log.i(Helper.TAG, "Network active=" + (ni == null ? null : ni.toString()));
- if (ni == null || !ni.isConnected()) {
- Log.i(Helper.TAG, "Network disconnected=" + ni);
+ NetworkInfo ani = cm.getActiveNetworkInfo();
+ Log.i(Helper.TAG, "Network active=" + (ani == null ? null : ani.toString()));
+ if (ani == null || !ani.isConnected()) {
+ EntityLog.log(ServiceSynchronize.this, "Network disconnected=" + ani);
+ Log.i(Helper.TAG, "Network disconnected=" + ani);
running = false;
lifecycle.submit(new Runnable() {
@Override
@@ -1475,6 +1482,7 @@ public class ServiceSynchronize extends LifecycleService {
}
private void start() {
+ EntityLog.log(ServiceSynchronize.this, "Start");
state = new ServiceState();
main = new Thread(new Runnable() {
@@ -1530,6 +1538,8 @@ public class ServiceSynchronize extends LifecycleService {
threads.add(t);
}
+ EntityLog.log(ServiceSynchronize.this, "Started");
+
// Stop monitoring accounts
for (Thread t : threads)
join(t);
@@ -1539,6 +1549,8 @@ public class ServiceSynchronize extends LifecycleService {
lbm.unregisterReceiver(outboxReceiver);
Log.i(Helper.TAG, outbox.name + " unlisten operations");
db.folder().setFolderState(outbox.id, null);
+
+ EntityLog.log(ServiceSynchronize.this, "Exited");
} catch (Throwable ex) {
// Fail-safe
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
@@ -1551,6 +1563,7 @@ public class ServiceSynchronize extends LifecycleService {
private void stop(boolean disconnected) {
if (main != null) {
+ EntityLog.log(ServiceSynchronize.this, "Stop disconnected=" + disconnected);
synchronized (state) {
state.running = false;
state.disconnected = disconnected;
@@ -1562,6 +1575,8 @@ public class ServiceSynchronize extends LifecycleService {
join(main);
main = null;
+
+ EntityLog.log(ServiceSynchronize.this, "Stopped");
}
}
diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml
index 36cc09a8ee..72e04bc4b1 100644
--- a/app/src/main/res/layout/fragment_about.xml
+++ b/app/src/main/res/layout/fragment_about.xml
@@ -47,6 +47,19 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvCopyright" />
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_logs.xml b/app/src/main/res/layout/fragment_logs.xml
new file mode 100644
index 0000000000..c794a653f0
--- /dev/null
+++ b/app/src/main/res/layout/fragment_logs.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/item_log.xml b/app/src/main/res/layout/item_log.xml
new file mode 100644
index 0000000000..0c50dae55d
--- /dev/null
+++ b/app/src/main/res/layout/item_log.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-af/strings.xml b/app/src/main/res/values-af/strings.xml
index 501cea391a..71f6f61ed8 100644
--- a/app/src/main/res/values-af/strings.xml
+++ b/app/src/main/res/values-af/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-ar-rBH/strings.xml b/app/src/main/res/values-ar-rBH/strings.xml
index a6fe36ce31..cc10098b57 100644
--- a/app/src/main/res/values-ar-rBH/strings.xml
+++ b/app/src/main/res/values-ar-rBH/strings.xml
@@ -190,6 +190,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-ar-rEG/strings.xml b/app/src/main/res/values-ar-rEG/strings.xml
index a6fe36ce31..cc10098b57 100644
--- a/app/src/main/res/values-ar-rEG/strings.xml
+++ b/app/src/main/res/values-ar-rEG/strings.xml
@@ -190,6 +190,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-ar-rSA/strings.xml b/app/src/main/res/values-ar-rSA/strings.xml
index a6fe36ce31..cc10098b57 100644
--- a/app/src/main/res/values-ar-rSA/strings.xml
+++ b/app/src/main/res/values-ar-rSA/strings.xml
@@ -190,6 +190,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-ar-rYE/strings.xml b/app/src/main/res/values-ar-rYE/strings.xml
index a6fe36ce31..cc10098b57 100644
--- a/app/src/main/res/values-ar-rYE/strings.xml
+++ b/app/src/main/res/values-ar-rYE/strings.xml
@@ -190,6 +190,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index a6fe36ce31..cc10098b57 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -190,6 +190,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 501cea391a..71f6f61ed8 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 524035ec19..2476bb8e69 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -182,6 +182,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index 51842c3d8a..d819be3491 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -174,6 +174,7 @@
Alle pro funktioner er aktiveret
Alle pro funktioner aktiveret
Ugyldigt svar
+ Log
Debugging info
Beskriv venligst problemet og angiv tidspunkt for problemet:
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index a9b1d263b4..7c7b78ee33 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -76,7 +76,7 @@
Konto wählen
Anweisungen
Speichere gesendete Nachrichten (nur bei Bedarf aktivieren)
- Keep-alive interval (minutes)
+ Keep-alive-Intervall (Minuten)
Synchronisiere (empfange E-Mails)
Synchronisiere (sende E-Mails)
Primär (Standard-Konto)
@@ -151,7 +151,7 @@
Entwurf gespeichert
Nachricht senden\u2026
Suche
- Search sender/subject/text
+ Absender/Betreff/Text durchsuchen
Suche „%1$s“
Standardantworten
Antwort Name
@@ -174,6 +174,7 @@
Alle Premium Funktionen sind aktiviert
Alle Premium Funktionen aktiviert
Ungültige Antwort
+ Log
Debuginformationen
Bitte beschreiben Sie das Problem und zu welchem Zeitpunkt dieses aufgetreten ist:
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index 501cea391a..71f6f61ed8 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml
index 501cea391a..71f6f61ed8 100644
--- a/app/src/main/res/values-en/strings.xml
+++ b/app/src/main/res/values-en/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml
index 501cea391a..71f6f61ed8 100644
--- a/app/src/main/res/values-es-rES/strings.xml
+++ b/app/src/main/res/values-es-rES/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 501cea391a..71f6f61ed8 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index f1f04bfa13..3302c2cc88 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -174,6 +174,7 @@
Toutes les fonctionnalités Pro sont activées
Toutes les fonctionnalités Pro activées
Réponse non valide
+ Log
Information de débogage
Veuillez décrire le problème et indiquer l\'heure à laquelle il est survenu :
diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml
index 9a53cb578e..1a150a33ab 100644
--- a/app/src/main/res/values-he/strings.xml
+++ b/app/src/main/res/values-he/strings.xml
@@ -182,6 +182,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 501cea391a..71f6f61ed8 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 239fc3d141..09fe1f9478 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Informazioni di debug
Si prega di descrivere il problema ed indicare il momento in cui è avvenuto:
diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml
index 9a53cb578e..1a150a33ab 100644
--- a/app/src/main/res/values-iw/strings.xml
+++ b/app/src/main/res/values-iw/strings.xml
@@ -182,6 +182,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 8b9910bc76..0cea958af8 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -170,6 +170,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index 8b9910bc76..0cea958af8 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -170,6 +170,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml
index 501cea391a..71f6f61ed8 100644
--- a/app/src/main/res/values-nb/strings.xml
+++ b/app/src/main/res/values-nb/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 501cea391a..71f6f61ed8 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-no/strings.xml b/app/src/main/res/values-no/strings.xml
index 501cea391a..71f6f61ed8 100644
--- a/app/src/main/res/values-no/strings.xml
+++ b/app/src/main/res/values-no/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index d95fd4cacf..46bef068e3 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -84,7 +84,7 @@
Wybierz konto
Instrukcje
Zachowuj wysłane wiadomości (włącz tylko gdy potrzebne)
- Keep-alive interval (minutes)
+ Interwał utrzymywania aktywności (minuty)
Synchronizuj (odbierz wiadomości)
Synchronizuj (wyślij wiadomości)
Podstawowe (domyślne konto)
@@ -104,7 +104,7 @@
Usunąć tożsamość bezpowrotnie?
Synchronizuj (odbierz wiadomości)
Synchronizuj (dni)
- Unified inbox
+ Wspólna skrzynka odbiorcza
Odebrane
Wysłane
Archiwum
@@ -113,7 +113,7 @@
Spam
Wysłane
Użytkownik
- Folders primary account
+ Podstawowe konto folderów
Wątek wiadomości
Brak wiadomości
link
@@ -132,7 +132,7 @@
Archiwum
Odpowiedz
Przenoszenie wiadomości do %1$s
- No viewer app available for %1$s
+ Brak aplikacji do podglądu %1$s
Załącznik zapisany
Usunąć wiadomość bezpowrotnie?
Zgłosić wiadomość jako spam?
@@ -159,11 +159,11 @@
Szkic zapisany
Wysyłanie wiadomości
Szukaj
- Search sender/subject/text
+ Wyszukaj nadawcę/temat/tekst
Szukam \'%1$s\'
Standardowa odpowiedź
- Answer name
- Answer text
+ Nazwa odpowiedzi
+ Tekst odpowiedzi
DW/UDW
Załącznik
Synchronizuj
@@ -173,7 +173,7 @@
Połączony
Synchronizowanie
Zamykanie
- Swipe left to trash; swipe right to archive (if available); long press to mark read/unread
+ Przesuń w lewo do kosza; przesuń w prawo do archiwum (jeśli są dostępne); długie naciśnięcie, aby oznaczyć przeczytane/nieprzeczytane
Rozumiem
Jest to funkcja pro
List funkcji pro
@@ -182,6 +182,7 @@
Wszystkie funkcje pro są aktywowane
Wszystkie funkcje pro aktywne
Nieprawidłowa odpowiedź
+ Log
Info debugowania
Opisz proszę problem i wskaż moment jego wystąpienia:
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 367dd05a57..1d02711bce 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Informações de depuração
Por favor, descreva o problema e indique o momento em que ocorrera:
diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml
index 501cea391a..71f6f61ed8 100644
--- a/app/src/main/res/values-pt-rPT/strings.xml
+++ b/app/src/main/res/values-pt-rPT/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index 7fbf6fa6ea..25c04eac73 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -178,6 +178,7 @@
Sunt activate toate caracteristicile Pro
Au fost activate toate caracteristicile Pro
Răspunsul nu este valid
+ Log
Depanare
Va rog sa descrieți problema și să indicați momentul când s-a produs:
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 524035ec19..2476bb8e69 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -182,6 +182,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index ebd6438297..a6179f980d 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -178,6 +178,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml
index 501cea391a..71f6f61ed8 100644
--- a/app/src/main/res/values-sv-rSE/strings.xml
+++ b/app/src/main/res/values-sv-rSE/strings.xml
@@ -174,6 +174,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 501cea391a..9b4c50c7ad 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -1,179 +1,180 @@
- Copyright Ⓒ 2018 by M. Bokhorst
- Service
- Notifications
- Errors
+ Telif hakkı Ⓒ 2018 M. Bokhorst \'a aittir
+ Hizmet
+ Bildirimler
+ Hatalar
- - Synchronizing %1$d account
- - Synchronizing %1$d accounts
+ - %1$d Hesap senkronize ediliyor
+ - %1$d Hesap senkronize ediliyor
- - %1$d operation pending
- - %1$d operations pending
+ - %1$d işlem beklemede
+ - %1$d işlem beklemede
- - %1$d new message
- - %1$d new messages
+ - %1$d yeni ileti
+ - %1$d yeni ileti
- - %1$d unsent message
- - %1$d unsent messages
+ - %1$d gönderilmemiş ileti
+ - %1$d gönderilmemiş ileti
- \'%1$s\' failed
- Setup
- Standard replies
- Operations
- Legend
- FAQ
- Pro features
- Privacy
- About
- Other apps
- End-user license agreement
- I agree
- I disagree
- Version %1$s
- Accounts
- Identities
- Edit account
- Edit identity
- Edit folder
- Setup
- Manage accounts
- To receive email
- Manage identities
- To send email
- Grant permissions
- To autocomplete addresses (optional)
- To do
- Done
- Dark theme
- Advanced options
- Use WebView to show external links
- Instead of Chrome Custom Tabs
- Remove HTML formatting from messages
- Compress IMAP data
- Debug
- Select …
- Your name
- Your email address
- Reply to address
- Optional
- Linked account
- Account name
- Used to differentiate folders
+ \'%1$s\' başarısız oldu
+ Kurulum
+ Standart cevaplar
+ İşlemler
+ Açıklamalar
+ SSS
+ Pro özellikleri
+ Gizlilik
+ Hakkında
+ Diğer uygulamalar
+ Son Kullanıcı Lisans Sözleşmesi
+ Kabul ediyorum
+ Kabul etmiyorum
+ Sürüm %1$s
+ Hesaplar
+ Kimlikler
+ Hesabı Düzenle
+ Kimliği düzenle
+ Klasörü düzenle
+ Kurulum
+ Hesapları Yönet
+ E-posta almak için
+ Kimlikleri Yönet
+ E-posta göndermek için
+ İzin Ver
+ Adresleri otomatik tamamlamak için (isteğe bağlı)
+ Yapılacak
+ Bitti
+ Koyu Tema
+ Gelişmiş ayarlar
+ Dış bağlantıları göstermek için WebView kullanın
+ Chrome Özel Sekmeler yerine
+ HTML biçimlendirmesini iletilerden kaldır
+ IMAP verilerini sıkıştır
+ Hata ayıklama
+ Seçin …
+ Adınız
+ E-posta adresiniz
+ Yanıtlama adresi
+ İsteğe bağlı
+ Bağlı hesap
+ Hesap adı
+ Klasörleri ayırt etmek için kullanılır
IMAP
SMTP
- Provider
- Custom
- Host name
+ Sağlayıcı
+ Özel
+ Sunucu adı
STARTTLS
- Port number
- User name
- Password
- Select account
- Instructions
- Store sent messages (enable if needed only)
- Keep-alive interval (minutes)
- Synchronize (receive messages)
- Synchronize (send messages)
- Primary (default account)
- Primary (default identity)
- Check
- Name missing
- Email address missing
- Account missing
- Host name missing
- Port number missing
- User name missing
- Password missing
- Drafts folder missing
- IDLE not supported
- UIDPLUS not supported
- Delete this account permanently?
- Delete this identity permanently?
- Synchronize (receive messages)
- Synchronize (days)
- Unified inbox
- Inbox
- Outbox
- Archive
- Drafts
- Trash
+ Port numarası
+ Kullanıcı adı
+ Şifre
+ Hesap seç
+ Talimatlar
+ Gönderilen iletileri kaydet (yalnızca gerekliyse etkinleştir)
+ Canlı tutma aralığı (dakika)
+ Senkronize et (iletileri al)
+ Senkronize et (iletileri gönder)
+ Birincil (varsayılan hesap)
+ Birincil (varsayılan kimlik)
+ Kontrol et
+ İsim eksik
+ E-posta adresi eksik
+ Hesap bilgisi eksik
+ Sunucu adı eksik
+ Port numarası eksik
+ Kullanıcı adı eksik
+ Parola Eksik
+ Taslaklar klasörü eksik
+ IDLE desteklenmiyor
+ UIDPLUS desteklenmiyor
+ Bu hesabı kalıcı olarak sil?
+ Bu kimliği kalıcı olarak sil?
+ Senkronize et (iletileri al)
+ Senkronize (günler)
+ Birleştirilmiş gelen kutusu
+ Gelen kutusu
+ Giden Kutusu
+ Arşiv
+ Taslaklar
+ Çöp Kutusu
Spam
- Sent
- User
- Folders primary account
- Message thread
- No messages
- link
- image
- Show images
- Re: %1$s
- Fwd: %1$s
- Show thread
- Mark read
- Mark unread
- Forward
- Reply to all
- Trash
+ Gönderilen
+ Kullanıcı
+ Klasörler birincil hesap
+ İleti dizisi
+ İleti yok
+ bağlantı
+ resim
+ Resimleri göster
+ Ynt: %1$s
+ İlet: %1$s
+ Konuyu göster
+ Okundu olarak işaretle
+ Okunmadı olarak işaretle
+ İlet
+ Tümünü yanıtla
+ Çöp Kutusu
Spam
- Move
- Archive
- Reply
- Moving message to %1$s
- No viewer app available for %1$s
- Attachment saved
- Delete message permanently?
- Report message as spam?
- Compose
- From:
- To:
- Reply to:
+ Taşı
+ Arşivle
+ Yanıtla
+ İleti şuraya taşınıyor %1$s
+ %1$s için kullanılabilir hiçbir görüntüleme uygulaması yok
+ Ek kaydedildi
+ İletiyi kalıcı olarak sil?
+ İletiyi spam olarak raporla?
+ Oluştur
+ Gönderen:
+ Alıcı:
+ Yanıt adresi:
CC:
BCC:
- Subject:
- Your message
- Save
- Send
- Show CC/BCC
- Add attachment
- OpenPGP not available
- Encrypted message not found
- Encrypt
- Decrypt
- Sender missing
- Recipient missing
- Attachments still loading
- Draft trashed
- Draft saved
- Sending message
- Search
- Search sender/subject/text
- Searching \'%1$s\'
- Standard reply
- Answer name
- Answer text
+ Konu:
+ Mesajınız
+ Kaydet
+ Gönder
+ CC/BCC göster
+ Ek ekle
+ OpenPGP mevcut değil
+ Şifreli ileti bulunamadı
+ Şifrele
+ Şifre çöz
+ Gönderici Eksik
+ Alıcı eksik
+ Ekler hala yükleniyor
+ Taslak çöp kutusuna atıldı
+ Taslak kaydedildi
+ İleti gönderiliyor
+ Ara
+ Gönderen/konu/metin ara
+ \'%1$s\' aranıyor
+ Standart yanıt
+ Yanıt adı
+ Yanıt metni
CC/BCC
- Attachment
- Synchronize
- Primary
- Disconnected
- Connecting
- Connected
- Synchronizing
- Closing
- Swipe left to trash; swipe right to archive (if available); long press to mark read/unread
- Understood
- This is a pro feature
- List of pro features
- Buy
- Buying pro features will allow you to use all current and future pro features and will keep this app maintained and supported
- All pro features are activated
- All pro features activated
- Invalid response
- Debug info
- Please describe the problem and indicate the time of the problem:
+ Ek
+ Senkronize et
+ Birincil
+ Bağlantı kesildi
+ Bağlanıyor
+ Bağlandı
+ Senkronize ediliyor
+ Kapatılıyor
+ Silmek için sola kaydırın; arşivlemek (mümkün ise) için sağa kaydırın; okundu/okunmadı işaretlemek için uzun basın
+ Anlaşıldı
+ Bu Pro özelliğidir
+ Pro özelliklerin listesi
+ Satın al
+ Pro özelliklerin satın alınması, mevcut ve gelecekteki tüm pro özelliklerin kullanılmasına izin verecek ve bu uygulamayı ayakta tutup destekleyecek
+ Tüm pro özellikleri etkinleştirildi
+ Tüm pro özellikleri etkinleştirildi
+ Geçersiz yanıt
+ Log
+ Hata ayıklama bilgisi
+ Lütfen sorunu açıklayın ve sorunun zamanını belirtin:
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 524035ec19..2476bb8e69 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -182,6 +182,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index 8b9910bc76..0cea958af8 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -170,6 +170,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index abcf5d7b1e..4f7bf10f39 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -170,6 +170,7 @@
专业版功能已激活
专业版功能已激活
无效的响应
+ Log
调试信息
请描述问题及问题发生的时间:
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 8b9910bc76..0cea958af8 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -170,6 +170,7 @@
All pro features are activated
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem:
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 90aae04cb8..e886ef6ce4 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -207,6 +207,7 @@
All pro features activated
Invalid response
+ Log
Debug info
Please describe the problem and indicate the time of the problem: