diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6e613d4aeb..307a193514 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ For support you can use [the contact form](https://contact.faircode.eu/?product=
### Next version
* Added option to configure number of widget subject lines
+* Added remembering last used folder for contacts
* Small improvements and minor bug fixes
* Updated [translations](https://crowdin.com/project/open-source-email)
diff --git a/app/schemas/eu.faircode.email.DB/275.json b/app/schemas/eu.faircode.email.DB/275.json
new file mode 100644
index 0000000000..440064c9f8
--- /dev/null
+++ b/app/schemas/eu.faircode.email.DB/275.json
@@ -0,0 +1,2931 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 275,
+ "identityHash": "84e6e92317c8d62c0d6e9876ab31a8c7",
+ "entities": [
+ {
+ "tableName": "identity",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `uuid` TEXT NOT NULL, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `account` INTEGER NOT NULL, `display` TEXT, `color` INTEGER, `signature` TEXT, `host` TEXT NOT NULL, `starttls` INTEGER NOT NULL, `insecure` INTEGER NOT NULL, `port` INTEGER NOT NULL, `auth_type` INTEGER NOT NULL, `provider` TEXT, `user` TEXT NOT NULL, `password` TEXT NOT NULL, `certificate` INTEGER NOT NULL, `certificate_alias` TEXT, `realm` TEXT, `fingerprint` TEXT, `use_ip` INTEGER NOT NULL, `ehlo` TEXT, `synchronize` INTEGER NOT NULL, `primary` INTEGER NOT NULL, `self` INTEGER NOT NULL, `sender_extra` INTEGER NOT NULL, `sender_extra_name` INTEGER NOT NULL, `reply_extra_name` INTEGER NOT NULL, `sender_extra_regex` TEXT, `replyto` TEXT, `cc` TEXT, `bcc` TEXT, `internal` TEXT, `unicode` INTEGER NOT NULL, `octetmime` INTEGER NOT NULL, `plain_only` INTEGER NOT NULL, `sign_default` INTEGER NOT NULL, `encrypt_default` INTEGER NOT NULL, `encrypt` INTEGER NOT NULL, `delivery_receipt` INTEGER NOT NULL, `read_receipt` INTEGER NOT NULL, `store_sent` INTEGER NOT NULL, `sent_folder` INTEGER, `sign_key` INTEGER, `sign_key_alias` TEXT, `tbd` INTEGER, `state` TEXT, `error` TEXT, `last_connected` INTEGER, `max_size` INTEGER, `last_modified` INTEGER, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "email",
+ "columnName": "email",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "account",
+ "columnName": "account",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "display",
+ "columnName": "display",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "signature",
+ "columnName": "signature",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "host",
+ "columnName": "host",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "encryption",
+ "columnName": "starttls",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "insecure",
+ "columnName": "insecure",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "port",
+ "columnName": "port",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "auth_type",
+ "columnName": "auth_type",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "provider",
+ "columnName": "provider",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "user",
+ "columnName": "user",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "password",
+ "columnName": "password",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "certificate",
+ "columnName": "certificate",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "certificate_alias",
+ "columnName": "certificate_alias",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "realm",
+ "columnName": "realm",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "fingerprint",
+ "columnName": "fingerprint",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "use_ip",
+ "columnName": "use_ip",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ehlo",
+ "columnName": "ehlo",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "synchronize",
+ "columnName": "synchronize",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "primary",
+ "columnName": "primary",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "self",
+ "columnName": "self",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "sender_extra",
+ "columnName": "sender_extra",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "sender_extra_name",
+ "columnName": "sender_extra_name",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "reply_extra_name",
+ "columnName": "reply_extra_name",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "sender_extra_regex",
+ "columnName": "sender_extra_regex",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "replyto",
+ "columnName": "replyto",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "cc",
+ "columnName": "cc",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "bcc",
+ "columnName": "bcc",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "internal",
+ "columnName": "internal",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "unicode",
+ "columnName": "unicode",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "octetmime",
+ "columnName": "octetmime",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "plain_only",
+ "columnName": "plain_only",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "sign_default",
+ "columnName": "sign_default",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "encrypt_default",
+ "columnName": "encrypt_default",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "encrypt",
+ "columnName": "encrypt",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "delivery_receipt",
+ "columnName": "delivery_receipt",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "read_receipt",
+ "columnName": "read_receipt",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "store_sent",
+ "columnName": "store_sent",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "sent_folder",
+ "columnName": "sent_folder",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "sign_key",
+ "columnName": "sign_key",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "sign_key_alias",
+ "columnName": "sign_key_alias",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "tbd",
+ "columnName": "tbd",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "error",
+ "columnName": "error",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "last_connected",
+ "columnName": "last_connected",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "max_size",
+ "columnName": "max_size",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "last_modified",
+ "columnName": "last_modified",
+ "affinity": "INTEGER",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_identity_account",
+ "unique": false,
+ "columnNames": [
+ "account"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_identity_account` ON `${TABLE_NAME}` (`account`)"
+ },
+ {
+ "name": "index_identity_account_email",
+ "unique": false,
+ "columnNames": [
+ "account",
+ "email"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_identity_account_email` ON `${TABLE_NAME}` (`account`, `email`)"
+ }
+ ],
+ "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, `uuid` TEXT NOT NULL, `pop` INTEGER NOT NULL, `host` TEXT NOT NULL, `starttls` INTEGER NOT NULL, `insecure` INTEGER NOT NULL, `port` INTEGER NOT NULL, `auth_type` INTEGER NOT NULL, `provider` TEXT, `user` TEXT NOT NULL, `password` TEXT NOT NULL, `certificate` INTEGER NOT NULL, `certificate_alias` TEXT, `realm` TEXT, `fingerprint` TEXT, `name` TEXT, `category` TEXT, `signature` TEXT, `color` INTEGER, `calendar` TEXT, `synchronize` INTEGER NOT NULL, `ondemand` INTEGER NOT NULL, `poll_exempted` INTEGER NOT NULL, `primary` INTEGER NOT NULL, `notify` INTEGER NOT NULL, `browse` INTEGER NOT NULL, `leave_on_server` INTEGER NOT NULL, `client_delete` INTEGER NOT NULL, `leave_deleted` INTEGER NOT NULL, `leave_on_device` INTEGER NOT NULL, `max_messages` INTEGER, `auto_seen` INTEGER NOT NULL, `separator` INTEGER, `swipe_left` INTEGER, `swipe_right` INTEGER, `move_to` INTEGER, `poll_interval` INTEGER NOT NULL, `keep_alive_noop` INTEGER NOT NULL, `keep_alive_ok` INTEGER NOT NULL, `keep_alive_failed` INTEGER NOT NULL, `keep_alive_succeeded` INTEGER NOT NULL, `partial_fetch` INTEGER NOT NULL, `raw_fetch` INTEGER NOT NULL, `ignore_size` INTEGER NOT NULL, `use_date` INTEGER NOT NULL, `use_received` INTEGER NOT NULL, `prefix` TEXT, `unicode` INTEGER NOT NULL, `conditions` TEXT, `quota_usage` INTEGER, `quota_limit` INTEGER, `created` INTEGER, `tbd` INTEGER, `thread` INTEGER, `state` TEXT, `warning` TEXT, `error` TEXT, `last_connected` INTEGER, `backoff_until` INTEGER, `max_size` INTEGER, `capabilities` TEXT, `capability_idle` INTEGER, `capability_utf8` INTEGER, `capability_uidl` INTEGER, `last_modified` INTEGER, `order` INTEGER)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "protocol",
+ "columnName": "pop",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "host",
+ "columnName": "host",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "encryption",
+ "columnName": "starttls",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "insecure",
+ "columnName": "insecure",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "port",
+ "columnName": "port",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "auth_type",
+ "columnName": "auth_type",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "provider",
+ "columnName": "provider",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "user",
+ "columnName": "user",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "password",
+ "columnName": "password",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "certificate",
+ "columnName": "certificate",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "certificate_alias",
+ "columnName": "certificate_alias",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "realm",
+ "columnName": "realm",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "fingerprint",
+ "columnName": "fingerprint",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "category",
+ "columnName": "category",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "signature",
+ "columnName": "signature",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "calendar",
+ "columnName": "calendar",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "synchronize",
+ "columnName": "synchronize",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ondemand",
+ "columnName": "ondemand",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "poll_exempted",
+ "columnName": "poll_exempted",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "primary",
+ "columnName": "primary",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notify",
+ "columnName": "notify",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "browse",
+ "columnName": "browse",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "leave_on_server",
+ "columnName": "leave_on_server",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "client_delete",
+ "columnName": "client_delete",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "leave_deleted",
+ "columnName": "leave_deleted",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "leave_on_device",
+ "columnName": "leave_on_device",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "max_messages",
+ "columnName": "max_messages",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "auto_seen",
+ "columnName": "auto_seen",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "_separator",
+ "columnName": "separator",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "swipe_left",
+ "columnName": "swipe_left",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "swipe_right",
+ "columnName": "swipe_right",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "move_to",
+ "columnName": "move_to",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "poll_interval",
+ "columnName": "poll_interval",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "keep_alive_noop",
+ "columnName": "keep_alive_noop",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "keep_alive_ok",
+ "columnName": "keep_alive_ok",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "keep_alive_failed",
+ "columnName": "keep_alive_failed",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "keep_alive_succeeded",
+ "columnName": "keep_alive_succeeded",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "partial_fetch",
+ "columnName": "partial_fetch",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "raw_fetch",
+ "columnName": "raw_fetch",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ignore_size",
+ "columnName": "ignore_size",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "use_date",
+ "columnName": "use_date",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "use_received",
+ "columnName": "use_received",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "prefix",
+ "columnName": "prefix",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "unicode",
+ "columnName": "unicode",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "conditions",
+ "columnName": "conditions",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "quota_usage",
+ "columnName": "quota_usage",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "quota_limit",
+ "columnName": "quota_limit",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "created",
+ "columnName": "created",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "tbd",
+ "columnName": "tbd",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "thread",
+ "columnName": "thread",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "warning",
+ "columnName": "warning",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "error",
+ "columnName": "error",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "last_connected",
+ "columnName": "last_connected",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "backoff_until",
+ "columnName": "backoff_until",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "max_size",
+ "columnName": "max_size",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "capabilities",
+ "columnName": "capabilities",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "capability_idle",
+ "columnName": "capability_idle",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "capability_utf8",
+ "columnName": "capability_utf8",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "capability_uidl",
+ "columnName": "capability_uidl",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "last_modified",
+ "columnName": "last_modified",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "order",
+ "columnName": "order",
+ "affinity": "INTEGER",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_account_synchronize",
+ "unique": false,
+ "columnNames": [
+ "synchronize"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_account_synchronize` ON `${TABLE_NAME}` (`synchronize`)"
+ },
+ {
+ "name": "index_account_category",
+ "unique": false,
+ "columnNames": [
+ "category"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_account_category` ON `${TABLE_NAME}` (`category`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "folder",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `account` INTEGER, `parent` INTEGER, `uidv` INTEGER, `modseq` INTEGER, `namespace` TEXT, `separator` INTEGER, `name` TEXT NOT NULL, `type` TEXT NOT NULL, `inherited_type` TEXT, `subtype` TEXT, `level` INTEGER NOT NULL, `local` INTEGER NOT NULL, `synchronize` INTEGER NOT NULL, `poll` INTEGER NOT NULL, `poll_factor` INTEGER NOT NULL, `poll_count` INTEGER NOT NULL, `download` INTEGER NOT NULL, `auto_classify` INTEGER NOT NULL, `auto_classify_source` INTEGER NOT NULL, `auto_classify_target` INTEGER NOT NULL, `subscribed` INTEGER, `sync_days` INTEGER NOT NULL, `keep_days` INTEGER NOT NULL, `auto_delete` INTEGER NOT NULL, `auto_add` INTEGER, `display` TEXT, `color` INTEGER, `hide` INTEGER NOT NULL, `hide_seen` INTEGER NOT NULL, `collapsed` INTEGER NOT NULL, `unified` INTEGER NOT NULL, `navigation` INTEGER NOT NULL, `count_unread` INTEGER NOT NULL, `notify` INTEGER NOT NULL, `total` INTEGER, `keywords` TEXT, `selected_last` INTEGER NOT NULL, `selected_count` INTEGER NOT NULL, `initialize` INTEGER NOT NULL, `tbc` INTEGER, `tbd` INTEGER, `rename` TEXT, `state` TEXT, `sync_state` TEXT, `read_only` INTEGER NOT NULL, `selectable` INTEGER NOT NULL, `inferiors` INTEGER NOT NULL, `error` TEXT, `last_sync` INTEGER, `last_sync_foreground` INTEGER, `last_sync_count` INTEGER, `order` INTEGER, 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": "parent",
+ "columnName": "parent",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uidv",
+ "columnName": "uidv",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "modseq",
+ "columnName": "modseq",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "namespace",
+ "columnName": "namespace",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "separator",
+ "columnName": "separator",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "inherited_type",
+ "columnName": "inherited_type",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "subtype",
+ "columnName": "subtype",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "level",
+ "columnName": "level",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "local",
+ "columnName": "local",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "synchronize",
+ "columnName": "synchronize",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "poll",
+ "columnName": "poll",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "poll_factor",
+ "columnName": "poll_factor",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "poll_count",
+ "columnName": "poll_count",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "download",
+ "columnName": "download",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "auto_classify",
+ "columnName": "auto_classify",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "auto_classify_source",
+ "columnName": "auto_classify_source",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "auto_classify_target",
+ "columnName": "auto_classify_target",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subscribed",
+ "columnName": "subscribed",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "sync_days",
+ "columnName": "sync_days",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "keep_days",
+ "columnName": "keep_days",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "auto_delete",
+ "columnName": "auto_delete",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "auto_add",
+ "columnName": "auto_add",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "display",
+ "columnName": "display",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "hide",
+ "columnName": "hide",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "hide_seen",
+ "columnName": "hide_seen",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "collapsed",
+ "columnName": "collapsed",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "unified",
+ "columnName": "unified",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "navigation",
+ "columnName": "navigation",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "count_unread",
+ "columnName": "count_unread",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notify",
+ "columnName": "notify",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "total",
+ "columnName": "total",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "keywords",
+ "columnName": "keywords",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "selected_last",
+ "columnName": "selected_last",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "selected_count",
+ "columnName": "selected_count",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "initialize",
+ "columnName": "initialize",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "tbc",
+ "columnName": "tbc",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "tbd",
+ "columnName": "tbd",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "rename",
+ "columnName": "rename",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "sync_state",
+ "columnName": "sync_state",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "read_only",
+ "columnName": "read_only",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "selectable",
+ "columnName": "selectable",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "inferiors",
+ "columnName": "inferiors",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "error",
+ "columnName": "error",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "last_sync",
+ "columnName": "last_sync",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "last_sync_foreground",
+ "columnName": "last_sync_foreground",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "last_sync_count",
+ "columnName": "last_sync_count",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "order",
+ "columnName": "order",
+ "affinity": "INTEGER",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_folder_account_name",
+ "unique": true,
+ "columnNames": [
+ "account",
+ "name"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_folder_account_name` ON `${TABLE_NAME}` (`account`, `name`)"
+ },
+ {
+ "name": "index_folder_account",
+ "unique": false,
+ "columnNames": [
+ "account"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_folder_account` ON `${TABLE_NAME}` (`account`)"
+ },
+ {
+ "name": "index_folder_name",
+ "unique": false,
+ "columnNames": [
+ "name"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_folder_name` ON `${TABLE_NAME}` (`name`)"
+ },
+ {
+ "name": "index_folder_type",
+ "unique": false,
+ "columnNames": [
+ "type"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_folder_type` ON `${TABLE_NAME}` (`type`)"
+ },
+ {
+ "name": "index_folder_unified",
+ "unique": false,
+ "columnNames": [
+ "unified"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_folder_unified` ON `${TABLE_NAME}` (`unified`)"
+ }
+ ],
+ "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 NOT NULL, `folder` INTEGER NOT NULL, `identity` INTEGER, `extra` TEXT, `replying` INTEGER, `forwarding` INTEGER, `uid` INTEGER, `uidl` TEXT, `msgid` TEXT, `hash` TEXT, `references` TEXT, `deliveredto` TEXT, `inreplyto` TEXT, `wasforwardedfrom` TEXT, `thread` TEXT, `priority` INTEGER, `importance` INTEGER, `sensitivity` INTEGER, `auto_submitted` INTEGER, `receipt` INTEGER, `receipt_request` INTEGER, `receipt_to` TEXT, `bimi_selector` TEXT, `signedby` TEXT, `tls` INTEGER, `dkim` INTEGER, `spf` INTEGER, `dmarc` INTEGER, `mx` INTEGER, `blocklist` INTEGER, `from_domain` INTEGER, `reply_domain` INTEGER, `avatar` TEXT, `sender` TEXT, `return_path` TEXT, `smtp_from` TEXT, `submitter` TEXT, `from` TEXT, `to` TEXT, `cc` TEXT, `bcc` TEXT, `reply` TEXT, `list_post` TEXT, `unsubscribe` TEXT, `autocrypt` TEXT, `headers` TEXT, `infrastructure` TEXT, `raw` INTEGER, `subject` TEXT, `size` INTEGER, `total` INTEGER, `attachments` INTEGER NOT NULL, `content` INTEGER NOT NULL, `language` TEXT, `plain_only` INTEGER, `resend` INTEGER, `encrypt` INTEGER, `ui_encrypt` INTEGER, `verified` INTEGER NOT NULL, `preview` TEXT, `notes` TEXT, `notes_color` INTEGER, `signature` INTEGER NOT NULL, `sent` INTEGER, `received` INTEGER NOT NULL, `stored` INTEGER NOT NULL, `recent` INTEGER NOT NULL, `seen` INTEGER NOT NULL, `answered` INTEGER NOT NULL, `flagged` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `flags` TEXT, `keywords` TEXT, `labels` TEXT, `fts` INTEGER NOT NULL, `auto_classified` INTEGER NOT NULL, `notifying` INTEGER NOT NULL, `ui_seen` INTEGER NOT NULL, `ui_answered` INTEGER NOT NULL, `ui_flagged` INTEGER NOT NULL, `ui_deleted` INTEGER NOT NULL, `ui_hide` INTEGER NOT NULL, `ui_found` INTEGER NOT NULL, `ui_ignored` INTEGER NOT NULL, `ui_silent` INTEGER NOT NULL, `ui_local_only` INTEGER NOT NULL, `ui_browsed` INTEGER NOT NULL, `ui_busy` INTEGER, `ui_snoozed` INTEGER, `ui_unsnoozed` INTEGER NOT NULL, `show_images` INTEGER NOT NULL, `show_full` INTEGER NOT NULL, `color` INTEGER, `revision` INTEGER, `revisions` INTEGER, `warning` TEXT, `error` TEXT, `last_attempt` INTEGER, 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 SET NULL , FOREIGN KEY(`replying`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE SET NULL , FOREIGN KEY(`forwarding`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE SET NULL )",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "account",
+ "columnName": "account",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "folder",
+ "columnName": "folder",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "identity",
+ "columnName": "identity",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "extra",
+ "columnName": "extra",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "replying",
+ "columnName": "replying",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "forwarding",
+ "columnName": "forwarding",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uidl",
+ "columnName": "uidl",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "msgid",
+ "columnName": "msgid",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "hash",
+ "columnName": "hash",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "references",
+ "columnName": "references",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "deliveredto",
+ "columnName": "deliveredto",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "inreplyto",
+ "columnName": "inreplyto",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "wasforwardedfrom",
+ "columnName": "wasforwardedfrom",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "thread",
+ "columnName": "thread",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "priority",
+ "columnName": "priority",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "importance",
+ "columnName": "importance",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "sensitivity",
+ "columnName": "sensitivity",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "auto_submitted",
+ "columnName": "auto_submitted",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "dsn",
+ "columnName": "receipt",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "receipt_request",
+ "columnName": "receipt_request",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "receipt_to",
+ "columnName": "receipt_to",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "bimi_selector",
+ "columnName": "bimi_selector",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "signedby",
+ "columnName": "signedby",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "tls",
+ "columnName": "tls",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "dkim",
+ "columnName": "dkim",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "spf",
+ "columnName": "spf",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "dmarc",
+ "columnName": "dmarc",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "mx",
+ "columnName": "mx",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "blocklist",
+ "columnName": "blocklist",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "from_domain",
+ "columnName": "from_domain",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "reply_domain",
+ "columnName": "reply_domain",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "avatar",
+ "columnName": "avatar",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "sender",
+ "columnName": "sender",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "return_path",
+ "columnName": "return_path",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "smtp_from",
+ "columnName": "smtp_from",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "submitter",
+ "columnName": "submitter",
+ "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": "list_post",
+ "columnName": "list_post",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "unsubscribe",
+ "columnName": "unsubscribe",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "autocrypt",
+ "columnName": "autocrypt",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "headers",
+ "columnName": "headers",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "infrastructure",
+ "columnName": "infrastructure",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "raw",
+ "columnName": "raw",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "size",
+ "columnName": "size",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "total",
+ "columnName": "total",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "attachments",
+ "columnName": "attachments",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "content",
+ "columnName": "content",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "language",
+ "columnName": "language",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "plain_only",
+ "columnName": "plain_only",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "resend",
+ "columnName": "resend",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "encrypt",
+ "columnName": "encrypt",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "ui_encrypt",
+ "columnName": "ui_encrypt",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "verified",
+ "columnName": "verified",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "preview",
+ "columnName": "preview",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "notes",
+ "columnName": "notes",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "notes_color",
+ "columnName": "notes_color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "signature",
+ "columnName": "signature",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "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": "recent",
+ "columnName": "recent",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "seen",
+ "columnName": "seen",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "answered",
+ "columnName": "answered",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "flagged",
+ "columnName": "flagged",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "deleted",
+ "columnName": "deleted",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "flags",
+ "columnName": "flags",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "keywords",
+ "columnName": "keywords",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "labels",
+ "columnName": "labels",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "fts",
+ "columnName": "fts",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "auto_classified",
+ "columnName": "auto_classified",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notifying",
+ "columnName": "notifying",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ui_seen",
+ "columnName": "ui_seen",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ui_answered",
+ "columnName": "ui_answered",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ui_flagged",
+ "columnName": "ui_flagged",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ui_deleted",
+ "columnName": "ui_deleted",
+ "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": "ui_ignored",
+ "columnName": "ui_ignored",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ui_silent",
+ "columnName": "ui_silent",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ui_local_only",
+ "columnName": "ui_local_only",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ui_browsed",
+ "columnName": "ui_browsed",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "ui_busy",
+ "columnName": "ui_busy",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "ui_snoozed",
+ "columnName": "ui_snoozed",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "ui_unsnoozed",
+ "columnName": "ui_unsnoozed",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "show_images",
+ "columnName": "show_images",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "show_full",
+ "columnName": "show_full",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "revision",
+ "columnName": "revision",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "revisions",
+ "columnName": "revisions",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "warning",
+ "columnName": "warning",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "error",
+ "columnName": "error",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "last_attempt",
+ "columnName": "last_attempt",
+ "affinity": "INTEGER",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_message_account",
+ "unique": false,
+ "columnNames": [
+ "account"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_account` ON `${TABLE_NAME}` (`account`)"
+ },
+ {
+ "name": "index_message_folder",
+ "unique": false,
+ "columnNames": [
+ "folder"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_folder` ON `${TABLE_NAME}` (`folder`)"
+ },
+ {
+ "name": "index_message_identity",
+ "unique": false,
+ "columnNames": [
+ "identity"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_identity` ON `${TABLE_NAME}` (`identity`)"
+ },
+ {
+ "name": "index_message_replying",
+ "unique": false,
+ "columnNames": [
+ "replying"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_replying` ON `${TABLE_NAME}` (`replying`)"
+ },
+ {
+ "name": "index_message_forwarding",
+ "unique": false,
+ "columnNames": [
+ "forwarding"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_forwarding` ON `${TABLE_NAME}` (`forwarding`)"
+ },
+ {
+ "name": "index_message_folder_uid",
+ "unique": true,
+ "columnNames": [
+ "folder",
+ "uid"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_message_folder_uid` ON `${TABLE_NAME}` (`folder`, `uid`)"
+ },
+ {
+ "name": "index_message_inreplyto",
+ "unique": false,
+ "columnNames": [
+ "inreplyto"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_inreplyto` ON `${TABLE_NAME}` (`inreplyto`)"
+ },
+ {
+ "name": "index_message_msgid",
+ "unique": false,
+ "columnNames": [
+ "msgid"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_msgid` ON `${TABLE_NAME}` (`msgid`)"
+ },
+ {
+ "name": "index_message_thread",
+ "unique": false,
+ "columnNames": [
+ "thread"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_thread` ON `${TABLE_NAME}` (`thread`)"
+ },
+ {
+ "name": "index_message_sender",
+ "unique": false,
+ "columnNames": [
+ "sender"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_sender` ON `${TABLE_NAME}` (`sender`)"
+ },
+ {
+ "name": "index_message_received",
+ "unique": false,
+ "columnNames": [
+ "received"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_received` ON `${TABLE_NAME}` (`received`)"
+ },
+ {
+ "name": "index_message_subject",
+ "unique": false,
+ "columnNames": [
+ "subject"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_subject` ON `${TABLE_NAME}` (`subject`)"
+ },
+ {
+ "name": "index_message_ui_seen",
+ "unique": false,
+ "columnNames": [
+ "ui_seen"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_ui_seen` ON `${TABLE_NAME}` (`ui_seen`)"
+ },
+ {
+ "name": "index_message_ui_flagged",
+ "unique": false,
+ "columnNames": [
+ "ui_flagged"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_ui_flagged` ON `${TABLE_NAME}` (`ui_flagged`)"
+ },
+ {
+ "name": "index_message_ui_hide",
+ "unique": false,
+ "columnNames": [
+ "ui_hide"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_ui_hide` ON `${TABLE_NAME}` (`ui_hide`)"
+ },
+ {
+ "name": "index_message_ui_found",
+ "unique": false,
+ "columnNames": [
+ "ui_found"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_ui_found` ON `${TABLE_NAME}` (`ui_found`)"
+ },
+ {
+ "name": "index_message_ui_ignored",
+ "unique": false,
+ "columnNames": [
+ "ui_ignored"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_ui_ignored` ON `${TABLE_NAME}` (`ui_ignored`)"
+ },
+ {
+ "name": "index_message_ui_browsed",
+ "unique": false,
+ "columnNames": [
+ "ui_browsed"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_ui_browsed` ON `${TABLE_NAME}` (`ui_browsed`)"
+ },
+ {
+ "name": "index_message_ui_snoozed",
+ "unique": false,
+ "columnNames": [
+ "ui_snoozed"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_message_ui_snoozed` ON `${TABLE_NAME}` (`ui_snoozed`)"
+ }
+ ],
+ "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": "SET NULL",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "identity"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ },
+ {
+ "table": "message",
+ "onDelete": "SET NULL",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "replying"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ },
+ {
+ "table": "message",
+ "onDelete": "SET NULL",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "forwarding"
+ ],
+ "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, `subsequence` INTEGER, `name` TEXT, `type` TEXT NOT NULL, `disposition` TEXT, `cid` TEXT, `related` INTEGER, `encryption` INTEGER, `size` INTEGER, `progress` INTEGER, `available` INTEGER NOT NULL, `media_uri` TEXT, `error` TEXT, 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": "subsequence",
+ "columnName": "subsequence",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "disposition",
+ "columnName": "disposition",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "cid",
+ "columnName": "cid",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "related",
+ "columnName": "related",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "encryption",
+ "columnName": "encryption",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "size",
+ "columnName": "size",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "progress",
+ "columnName": "progress",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "available",
+ "columnName": "available",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "media_uri",
+ "columnName": "media_uri",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "error",
+ "columnName": "error",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_attachment_message",
+ "unique": false,
+ "columnNames": [
+ "message"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_attachment_message` ON `${TABLE_NAME}` (`message`)"
+ },
+ {
+ "name": "index_attachment_message_sequence_subsequence",
+ "unique": true,
+ "columnNames": [
+ "message",
+ "sequence",
+ "subsequence"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_attachment_message_sequence_subsequence` ON `${TABLE_NAME}` (`message`, `sequence`, `subsequence`)"
+ },
+ {
+ "name": "index_attachment_message_cid",
+ "unique": false,
+ "columnNames": [
+ "message",
+ "cid"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_attachment_message_cid` ON `${TABLE_NAME}` (`message`, `cid`)"
+ }
+ ],
+ "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, `account` INTEGER, `folder` INTEGER NOT NULL, `message` INTEGER, `name` TEXT NOT NULL, `args` TEXT NOT NULL, `created` INTEGER NOT NULL, `tries` INTEGER NOT NULL, `state` TEXT, `error` TEXT, 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": "account",
+ "columnName": "account",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "folder",
+ "columnName": "folder",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "message",
+ "columnName": "message",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "args",
+ "columnName": "args",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "created",
+ "columnName": "created",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "tries",
+ "columnName": "tries",
+ "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_operation_account",
+ "unique": false,
+ "columnNames": [
+ "account"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_operation_account` ON `${TABLE_NAME}` (`account`)"
+ },
+ {
+ "name": "index_operation_folder",
+ "unique": false,
+ "columnNames": [
+ "folder"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_operation_folder` ON `${TABLE_NAME}` (`folder`)"
+ },
+ {
+ "name": "index_operation_message",
+ "unique": false,
+ "columnNames": [
+ "message"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_operation_message` ON `${TABLE_NAME}` (`message`)"
+ },
+ {
+ "name": "index_operation_name",
+ "unique": false,
+ "columnNames": [
+ "name"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_operation_name` ON `${TABLE_NAME}` (`name`)"
+ },
+ {
+ "name": "index_operation_state",
+ "unique": false,
+ "columnNames": [
+ "state"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_operation_state` ON `${TABLE_NAME}` (`state`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "folder",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "folder"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ },
+ {
+ "table": "message",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "message"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "contact",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `account` INTEGER NOT NULL, `identity` INTEGER, `folder` INTEGER, `type` INTEGER NOT NULL, `email` TEXT NOT NULL, `name` TEXT, `group` TEXT, `avatar` TEXT, `times_contacted` INTEGER NOT NULL, `first_contacted` INTEGER NOT NULL, `last_contacted` INTEGER NOT NULL, `state` INTEGER NOT NULL, 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": true
+ },
+ {
+ "fieldPath": "identity",
+ "columnName": "identity",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "folder",
+ "columnName": "folder",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "email",
+ "columnName": "email",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "group",
+ "columnName": "group",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "avatar",
+ "columnName": "avatar",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "times_contacted",
+ "columnName": "times_contacted",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "first_contacted",
+ "columnName": "first_contacted",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "last_contacted",
+ "columnName": "last_contacted",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "state",
+ "columnName": "state",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_contact_account_type_email",
+ "unique": true,
+ "columnNames": [
+ "account",
+ "type",
+ "email"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_contact_account_type_email` ON `${TABLE_NAME}` (`account`, `type`, `email`)"
+ },
+ {
+ "name": "index_contact_email",
+ "unique": false,
+ "columnNames": [
+ "email"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_contact_email` ON `${TABLE_NAME}` (`email`)"
+ },
+ {
+ "name": "index_contact_name",
+ "unique": false,
+ "columnNames": [
+ "name"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_contact_name` ON `${TABLE_NAME}` (`name`)"
+ },
+ {
+ "name": "index_contact_avatar",
+ "unique": false,
+ "columnNames": [
+ "avatar"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_contact_avatar` ON `${TABLE_NAME}` (`avatar`)"
+ },
+ {
+ "name": "index_contact_times_contacted",
+ "unique": false,
+ "columnNames": [
+ "times_contacted"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_contact_times_contacted` ON `${TABLE_NAME}` (`times_contacted`)"
+ },
+ {
+ "name": "index_contact_last_contacted",
+ "unique": false,
+ "columnNames": [
+ "last_contacted"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_contact_last_contacted` ON `${TABLE_NAME}` (`last_contacted`)"
+ },
+ {
+ "name": "index_contact_state",
+ "unique": false,
+ "columnNames": [
+ "state"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_contact_state` ON `${TABLE_NAME}` (`state`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "account",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "account"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "certificate",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `fingerprint` TEXT NOT NULL, `intermediate` INTEGER NOT NULL, `email` TEXT NOT NULL, `subject` TEXT, `after` INTEGER, `before` INTEGER, `data` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "fingerprint",
+ "columnName": "fingerprint",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "intermediate",
+ "columnName": "intermediate",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "email",
+ "columnName": "email",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "after",
+ "columnName": "after",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "before",
+ "columnName": "before",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "data",
+ "columnName": "data",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_certificate_fingerprint_email",
+ "unique": true,
+ "columnNames": [
+ "fingerprint",
+ "email"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_certificate_fingerprint_email` ON `${TABLE_NAME}` (`fingerprint`, `email`)"
+ },
+ {
+ "name": "index_certificate_email",
+ "unique": false,
+ "columnNames": [
+ "email"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_certificate_email` ON `${TABLE_NAME}` (`email`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "answer",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `uuid` TEXT NOT NULL, `name` TEXT NOT NULL, `label` TEXT, `group` TEXT, `standard` INTEGER NOT NULL, `receipt` INTEGER NOT NULL, `favorite` INTEGER NOT NULL, `snippet` INTEGER NOT NULL, `hide` INTEGER NOT NULL, `external` INTEGER NOT NULL, `color` INTEGER, `text` TEXT NOT NULL, `applied` INTEGER NOT NULL, `last_applied` INTEGER)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "label",
+ "columnName": "label",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "group",
+ "columnName": "group",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "standard",
+ "columnName": "standard",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "receipt",
+ "columnName": "receipt",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "favorite",
+ "columnName": "favorite",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "snippet",
+ "columnName": "snippet",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "hide",
+ "columnName": "hide",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "external",
+ "columnName": "external",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "text",
+ "columnName": "text",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "applied",
+ "columnName": "applied",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "last_applied",
+ "columnName": "last_applied",
+ "affinity": "INTEGER",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_answer_label",
+ "unique": true,
+ "columnNames": [
+ "label"
+ ],
+ "orders": [],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_answer_label` ON `${TABLE_NAME}` (`label`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "rule",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `uuid` TEXT NOT NULL, `folder` INTEGER NOT NULL, `name` TEXT NOT NULL, `order` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `daily` INTEGER NOT NULL, `stop` INTEGER NOT NULL, `condition` TEXT NOT NULL, `action` TEXT NOT NULL, `applied` INTEGER NOT NULL, `last_applied` INTEGER, FOREIGN KEY(`folder`) REFERENCES `folder`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "uuid",
+ "columnName": "uuid",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "folder",
+ "columnName": "folder",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "order",
+ "columnName": "order",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "enabled",
+ "columnName": "enabled",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "daily",
+ "columnName": "daily",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "stop",
+ "columnName": "stop",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "condition",
+ "columnName": "condition",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "action",
+ "columnName": "action",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "applied",
+ "columnName": "applied",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "last_applied",
+ "columnName": "last_applied",
+ "affinity": "INTEGER",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_rule_folder",
+ "unique": false,
+ "columnNames": [
+ "folder"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_rule_folder` ON `${TABLE_NAME}` (`folder`)"
+ },
+ {
+ "name": "index_rule_order",
+ "unique": false,
+ "columnNames": [
+ "order"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_rule_order` ON `${TABLE_NAME}` (`order`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "folder",
+ "onDelete": "CASCADE",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "folder"
+ ],
+ "referencedColumns": [
+ "id"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "search",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `account_uuid` TEXT, `folder_name` TEXT, `name` TEXT NOT NULL, `order` INTEGER, `color` INTEGER, `data` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "account_uuid",
+ "columnName": "account_uuid",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "folder_name",
+ "columnName": "folder_name",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "order",
+ "columnName": "order",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "data",
+ "columnName": "data",
+ "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, `type` INTEGER NOT NULL, `account` INTEGER, `folder` INTEGER, `message` INTEGER, `data` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "time",
+ "columnName": "time",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "account",
+ "columnName": "account",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "folder",
+ "columnName": "folder",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "message",
+ "columnName": "message",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "data",
+ "columnName": "data",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_log_time",
+ "unique": false,
+ "columnNames": [
+ "time"
+ ],
+ "orders": [],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_log_time` ON `${TABLE_NAME}` (`time`)"
+ }
+ ],
+ "foreignKeys": []
+ }
+ ],
+ "views": [
+ {
+ "viewName": "account_view",
+ "createSql": "CREATE VIEW `${VIEW_NAME}` AS SELECT id, pop, name, category, color, synchronize, notify, leave_deleted, auto_seen, created FROM account"
+ },
+ {
+ "viewName": "identity_view",
+ "createSql": "CREATE VIEW `${VIEW_NAME}` AS SELECT id, name, email, account, display, color, synchronize FROM identity"
+ },
+ {
+ "viewName": "folder_view",
+ "createSql": "CREATE VIEW `${VIEW_NAME}` AS SELECT id, account, name, type, inherited_type, display, color, unified, notify, read_only FROM folder"
+ }
+ ],
+ "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, '84e6e92317c8d62c0d6e9876ab31a8c7')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/assets/CHANGELOG.md b/app/src/main/assets/CHANGELOG.md
index 6e613d4aeb..307a193514 100644
--- a/app/src/main/assets/CHANGELOG.md
+++ b/app/src/main/assets/CHANGELOG.md
@@ -9,6 +9,7 @@ For support you can use [the contact form](https://contact.faircode.eu/?product=
### Next version
* Added option to configure number of widget subject lines
+* Added remembering last used folder for contacts
* Small improvements and minor bug fixes
* Updated [translations](https://crowdin.com/project/open-source-email)
diff --git a/app/src/main/java/eu/faircode/email/DB.java b/app/src/main/java/eu/faircode/email/DB.java
index fc6d0248a9..fa0f61ea09 100644
--- a/app/src/main/java/eu/faircode/email/DB.java
+++ b/app/src/main/java/eu/faircode/email/DB.java
@@ -68,7 +68,7 @@ import javax.mail.internet.InternetAddress;
// https://developer.android.com/topic/libraries/architecture/room.html
@Database(
- version = 274,
+ version = 275,
entities = {
EntityIdentity.class,
EntityAccount.class,
@@ -2781,6 +2781,12 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `answer` ADD COLUMN `label` TEXT");
db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_answer_label` ON `answer` (`label`)");
}
+ }).addMigrations(new Migration(274, 275) {
+ @Override
+ public void migrate(@NonNull SupportSQLiteDatabase db) {
+ logMigration(startVersion, endVersion);
+ db.execSQL("ALTER TABLE `contact` ADD COLUMN `folder` INTEGER");
+ }
}).addMigrations(new Migration(998, 999) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
diff --git a/app/src/main/java/eu/faircode/email/DaoContact.java b/app/src/main/java/eu/faircode/email/DaoContact.java
index 99f419e8a0..8dd37bb694 100644
--- a/app/src/main/java/eu/faircode/email/DaoContact.java
+++ b/app/src/main/java/eu/faircode/email/DaoContact.java
@@ -105,6 +105,12 @@ public interface DaoContact {
@Update
int updateContact(EntityContact contact);
+ @Query("UPDATE contact SET folder = :folder WHERE id=:id")
+ int setContactFolder(long id, Long folder);
+
+ @Query("UPDATE contact SET folder = NULL")
+ int clearContactFolders();
+
@Query("DELETE FROM contact WHERE id = :id")
int deleteContact(long id);
diff --git a/app/src/main/java/eu/faircode/email/EntityContact.java b/app/src/main/java/eu/faircode/email/EntityContact.java
index 37d29ecdb6..6263147208 100644
--- a/app/src/main/java/eu/faircode/email/EntityContact.java
+++ b/app/src/main/java/eu/faircode/email/EntityContact.java
@@ -80,6 +80,7 @@ public class EntityContact implements Serializable {
@NonNull
public Long account;
public Long identity; // no foreign key, no index
+ public Long folder; // last used
@NonNull
public int type;
@NonNull
diff --git a/app/src/main/java/eu/faircode/email/EntityOperation.java b/app/src/main/java/eu/faircode/email/EntityOperation.java
index d175d2d7af..6f30aa3c37 100644
--- a/app/src/main/java/eu/faircode/email/EntityOperation.java
+++ b/app/src/main/java/eu/faircode/email/EntityOperation.java
@@ -47,6 +47,8 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
+import javax.mail.internet.InternetAddress;
+
@Entity(
tableName = EntityOperation.TABLE_NAME,
foreignKeys = {
@@ -230,6 +232,16 @@ public class EntityOperation {
if (source == null || target == null || source.id.equals(target.id))
return;
+ if (message.from != null && message.from.length == 1 &&
+ EntityFolder.USER.equals(target.type)) {
+ String email = ((InternetAddress) message.from[0]).getAddress();
+ if (!TextUtils.isEmpty(email)) {
+ EntityContact contact = db.contact().getContact(target.account, EntityContact.TYPE_FROM, email);
+ if (contact != null)
+ db.contact().setContactFolder(contact.id, target.id);
+ }
+ }
+
if (EntityFolder.JUNK.equals(target.type) &&
Objects.equals(source.account, target.account)) {
Boolean noblock = (Boolean) jargs.opt(3);
diff --git a/app/src/main/java/eu/faircode/email/FragmentDialogAnswerButton.java b/app/src/main/java/eu/faircode/email/FragmentDialogAnswerButton.java
new file mode 100644
index 0000000000..5feae57a7f
--- /dev/null
+++ b/app/src/main/java/eu/faircode/email/FragmentDialogAnswerButton.java
@@ -0,0 +1,108 @@
+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 .
+
+ Copyright 2018-2023 by Marcel Bokhorst (M66B)
+*/
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.preference.PreferenceManager;
+
+public class FragmentDialogAnswerButton extends FragmentDialogBase {
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+ final Context context = getContext();
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+
+ final String[] values = getResources().getStringArray(R.array.answerValues);
+
+ final View dview = LayoutInflater.from(context).inflate(R.layout.dialog_answer_button, null);
+ Spinner spAnswerActionSingle = dview.findViewById(R.id.spAnswerActionSingle);
+ Spinner spAnswerActionLong = dview.findViewById(R.id.spAnswerActionLong);
+ TextView tvAnswerActionWarning = dview.findViewById(R.id.tvAnswerActionWarning);
+
+ AdapterView.OnItemSelectedListener onSelected = new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ String s = values[spAnswerActionSingle.getSelectedItemPosition()];
+ String l = values[spAnswerActionLong.getSelectedItemPosition()];
+ tvAnswerActionWarning.setVisibility(
+ "menu".equals(s) || "menu".equals(l)
+ ? View.GONE : View.VISIBLE);
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ // Do nothing
+ }
+ };
+
+ spAnswerActionSingle.setOnItemSelectedListener(onSelected);
+ spAnswerActionLong.setOnItemSelectedListener(onSelected);
+
+ String answer_default = prefs.getString("answer_single", "menu");
+ for (int pos = 0; pos < values.length; pos++)
+ if (values[pos].equals(answer_default)) {
+ spAnswerActionSingle.setSelection(pos);
+ break;
+ }
+
+ boolean reply_all = prefs.getBoolean("reply_all", false);
+ String answer_action = prefs.getString("answer_action", reply_all ? "reply_all" : "reply");
+ for (int pos = 0; pos < values.length; pos++)
+ if (values[pos].equals(answer_action)) {
+ spAnswerActionLong.setSelection(pos);
+ break;
+ }
+
+ tvAnswerActionWarning.setVisibility(View.GONE);
+
+ return new AlertDialog.Builder(getContext())
+ .setView(dview)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putString("answer_single", values[spAnswerActionSingle.getSelectedItemPosition()]).apply();
+ editor.putString("answer_action", values[spAnswerActionLong.getSelectedItemPosition()]).apply();
+ sendResult(Activity.RESULT_OK);
+ }
+ })
+ .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ sendResult(Activity.RESULT_CANCELED);
+ }
+ })
+ .create();
+ }
+}
diff --git a/app/src/main/java/eu/faircode/email/FragmentDialogFolder.java b/app/src/main/java/eu/faircode/email/FragmentDialogFolder.java
index 59d26fea93..903a072323 100644
--- a/app/src/main/java/eu/faircode/email/FragmentDialogFolder.java
+++ b/app/src/main/java/eu/faircode/email/FragmentDialogFolder.java
@@ -63,8 +63,12 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
+
+import javax.mail.internet.InternetAddress;
public class FragmentDialogFolder extends FragmentDialogBase {
private int result = 0;
@@ -84,6 +88,12 @@ public class FragmentDialogFolder extends FragmentDialogBase {
final long[] disabled = aargs.getLongArray("disabled");
final boolean cancopy = aargs.getBoolean("cancopy");
+ long[] messages = null;
+ if (aargs.containsKey("message"))
+ messages = new long[]{aargs.getLong("message")};
+ else if (aargs.containsKey("messages"))
+ messages = aargs.getLongArray("messages");
+
final Context context = getContext();
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
final InputMethodManager imm = Helper.getSystemService(context, InputMethodManager.class);
@@ -220,6 +230,7 @@ public class FragmentDialogFolder extends FragmentDialogBase {
public void run() {
try {
db.folder().resetSelectedCount(account);
+ db.contact().clearContactFolders();
} catch (Throwable ex) {
Log.e(ex);
}
@@ -305,6 +316,8 @@ public class FragmentDialogFolder extends FragmentDialogBase {
Bundle args = new Bundle();
args.putLong("account", account);
args.putLongArray("disabled", disabled);
+ if (messages != null)
+ args.putLongArray("messages", messages);
new SimpleTask() {
@Override
@@ -323,13 +336,58 @@ public class FragmentDialogFolder extends FragmentDialogBase {
protected Data onExecute(Context context, Bundle args) {
long account = args.getLong("account");
long[] disabled = args.getLongArray("disabled");
+ long[] messages = args.getLongArray("messages");
+
+ List favorites = new ArrayList<>();
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ boolean suggest_received = prefs.getBoolean("suggest_received", false);
DB db = DB.getInstance(context);
+ Map frequency = new HashMap<>();
+ if (suggest_received &&
+ messages != null && messages.length < 100) {
+ for (Long id : messages) {
+ EntityMessage message = db.message().getMessage(id);
+ if (message != null && message.from != null && message.from[0] != null) {
+ String email = ((InternetAddress) message.from[0]).getAddress();
+ if (!TextUtils.isEmpty(email)) {
+ EntityContact contact =
+ db.contact().getContact(message.account, EntityContact.TYPE_FROM, email);
+ if (contact != null && contact.folder != null) {
+ Integer freq = frequency.get(contact.folder);
+ freq = (freq == null ? 1 : freq + 1);
+ frequency.put(contact.folder, freq);
+ }
+ }
+ }
+ }
+ }
+
+ List fs = new ArrayList<>(frequency.keySet());
+ Collections.sort(fs, new Comparator() {
+ @Override
+ public int compare(Long f1, Long f2) {
+ return -Integer.compare(frequency.get(f1), frequency.get(f2));
+ }
+ });
+ for (long fid : fs) {
+ EntityFolder f = db.folder().getFolder(fid);
+ if (f != null)
+ favorites.add(f);
+ }
+
+ List ffolders = db.folder().getFavoriteFolders(account, 3, disabled);
+ if (ffolders != null)
+ for (EntityFolder folder : ffolders)
+ if (!frequency.containsKey(folder.id))
+ favorites.add(folder);
+
Data data = new Data();
data.account = db.account().getAccount(account);
data.folders = db.folder().getFoldersEx(account);
- data.favorites = db.folder().getFavoriteFolders(account, 3, disabled);
+ data.favorites = favorites;
return data;
}
diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java
index a47f8da923..d71e92be00 100644
--- a/app/src/main/java/eu/faircode/email/FragmentMessages.java
+++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java
@@ -3588,6 +3588,9 @@ public class FragmentMessages extends FragmentBase
} else if (itemId == R.id.menu_reply_answer) {
onMenuAnswer(message);
return true;
+ } else if (itemId == R.id.menu_settings) {
+ onMenuAnswerSettings();
+ return true;
}
return false;
}
@@ -3728,6 +3731,11 @@ public class FragmentMessages extends FragmentBase
}.execute(getContext(), getViewLifecycleOwner(), new Bundle(), "message:answer");
}
+ private void onMenuAnswerSettings() {
+ FragmentDialogAnswerButton fragment = new FragmentDialogAnswerButton();
+ fragment.show(getParentFragmentManager(), "dialog:answer");
+ }
+
private void onMore() {
Bundle args = new Bundle();
args.putLongArray("ids", getSelection());
@@ -4404,6 +4412,7 @@ public class FragmentMessages extends FragmentBase
args.putBoolean("copy", copy);
args.putBoolean("cancopy", true);
args.putLongArray("disabled", Helper.toLongArray(disabled));
+ args.putLongArray("messages", getSelection());
FragmentDialogFolder fragment = new FragmentDialogFolder();
fragment.setArguments(args);
diff --git a/app/src/main/res/layout/dialog_answer_button.xml b/app/src/main/res/layout/dialog_answer_button.xml
new file mode 100644
index 0000000000..5700535a65
--- /dev/null
+++ b/app/src/main/res/layout/dialog_answer_button.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/menu/popup_reply.xml b/app/src/main/res/menu/popup_reply.xml
index 1f70a54ba8..c0075257d3 100644
--- a/app/src/main/res/menu/popup_reply.xml
+++ b/app/src/main/res/menu/popup_reply.xml
@@ -56,4 +56,11 @@
android:title="@string/title_reply_template">
+
+ -
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f4ff9449b8..55412bfb63 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -441,8 +441,11 @@
Show reminders
Delay sending messages
Add shared files to a new draft
+ Answer button settings
Short pressing on the answer button will:
Long pressing on the answer button will:
+ The answer button actions can also be configured in the send settings tab page
+ Not all actions are possible without a selection menu!
Show non-obtrusive send delayed icon
Automatically save a draft after every paragraph
diff --git a/metadata/en-US/changelogs/2054.txt b/metadata/en-US/changelogs/2054.txt
index 7aba28ad1b..bdc37eb666 100644
--- a/metadata/en-US/changelogs/2054.txt
+++ b/metadata/en-US/changelogs/2054.txt
@@ -9,6 +9,7 @@ Rahonavis
Next version
* Added option to configure number of widget subject lines
+* Added remembering last used folder for contacts
* Small improvements and minor bug fixes
* Updated translations