mirror of https://github.com/M66B/FairEmail.git
Added identity linked account
This commit is contained in:
parent
d844734627
commit
a5af366b03
|
@ -0,0 +1,700 @@
|
|||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 7,
|
||||
"identityHash": "74b765c4ee277861c68851c33a596610",
|
||||
"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, `primary` INTEGER NOT NULL, `synchronize` 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": "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": "primary",
|
||||
"columnName": "primary",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "synchronize",
|
||||
"columnName": "synchronize",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"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, `primary` INTEGER NOT NULL, `synchronize` INTEGER NOT NULL, `seen_until` INTEGER)",
|
||||
"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": "primary",
|
||||
"columnName": "primary",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "synchronize",
|
||||
"columnName": "synchronize",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "seen_until",
|
||||
"columnName": "seen_until",
|
||||
"affinity": "INTEGER",
|
||||
"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, 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
|
||||
}
|
||||
],
|
||||
"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, `body` TEXT, `sent` INTEGER, `received` INTEGER NOT NULL, `seen` INTEGER NOT NULL, `ui_seen` INTEGER NOT NULL, `ui_hide` INTEGER NOT NULL, 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": "body",
|
||||
"columnName": "body",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "sent",
|
||||
"columnName": "sent",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "received",
|
||||
"columnName": "received",
|
||||
"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
|
||||
}
|
||||
],
|
||||
"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_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, `content` BLOB, 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": "content",
|
||||
"columnName": "content",
|
||||
"affinity": "BLOB",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"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, `message` INTEGER NOT NULL, `name` TEXT NOT NULL, `args` 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": "name",
|
||||
"columnName": "name",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "args",
|
||||
"columnName": "args",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id"
|
||||
],
|
||||
"autoGenerate": true
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_operation_message",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"message"
|
||||
],
|
||||
"createSql": "CREATE INDEX `index_operation_message` ON `${TABLE_NAME}` (`message`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "message",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"message"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"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, \"74b765c4ee277861c68851c33a596610\")"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -44,15 +44,15 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHolder> {
|
||||
private Context context;
|
||||
|
||||
private List<EntityIdentity> all = new ArrayList<>();
|
||||
private List<EntityIdentity> filtered = new ArrayList<>();
|
||||
private List<TupleIdentityEx> all = new ArrayList<>();
|
||||
private List<TupleIdentityEx> filtered = new ArrayList<>();
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||
View itemView;
|
||||
ImageView ivPrimary;
|
||||
TextView tvName;
|
||||
ImageView ivSync;
|
||||
TextView tvHost;
|
||||
TextView tvAccount;
|
||||
TextView tvEmail;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
|
@ -62,7 +62,7 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
|
|||
ivPrimary = itemView.findViewById(R.id.ivPrimary);
|
||||
tvName = itemView.findViewById(R.id.tvName);
|
||||
ivSync = itemView.findViewById(R.id.ivSync);
|
||||
tvHost = itemView.findViewById(R.id.tvHost);
|
||||
tvAccount = itemView.findViewById(R.id.tvAccount);
|
||||
tvEmail = itemView.findViewById(R.id.tvEmail);
|
||||
}
|
||||
|
||||
|
@ -74,12 +74,12 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
|
|||
itemView.setOnClickListener(null);
|
||||
}
|
||||
|
||||
private void bindTo(EntityIdentity identity) {
|
||||
private void bindTo(TupleIdentityEx identity) {
|
||||
ivPrimary.setVisibility(identity.primary ? View.VISIBLE : View.GONE);
|
||||
tvName.setText(identity.name);
|
||||
ivSync.setVisibility(identity.synchronize ? View.VISIBLE : View.INVISIBLE);
|
||||
tvHost.setText(String.format("%s:%d", identity.host, identity.port));
|
||||
tvEmail.setText(identity.email);
|
||||
tvAccount.setText(identity.accountName);
|
||||
tvEmail.setText(String.format("%s@%s:%d", identity.email, identity.host, identity.port));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,7 +87,7 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
|
|||
int pos = getAdapterPosition();
|
||||
if (pos == RecyclerView.NO_POSITION)
|
||||
return;
|
||||
EntityIdentity identity = filtered.get(pos);
|
||||
TupleIdentityEx identity = filtered.get(pos);
|
||||
|
||||
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
|
||||
lbm.sendBroadcast(
|
||||
|
@ -101,15 +101,15 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
|
|||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
public void set(@NonNull List<EntityIdentity> identities) {
|
||||
public void set(@NonNull List<TupleIdentityEx> identities) {
|
||||
Log.i(Helper.TAG, "Set identities=" + identities.size());
|
||||
|
||||
final Collator collator = Collator.getInstance(Locale.getDefault());
|
||||
collator.setStrength(Collator.SECONDARY); // Case insensitive, process accents etc
|
||||
|
||||
Collections.sort(identities, new Comparator<EntityIdentity>() {
|
||||
Collections.sort(identities, new Comparator<TupleIdentityEx>() {
|
||||
@Override
|
||||
public int compare(EntityIdentity i1, EntityIdentity i2) {
|
||||
public int compare(TupleIdentityEx i1, TupleIdentityEx i2) {
|
||||
return collator.compare(i1.host, i2.host);
|
||||
}
|
||||
});
|
||||
|
@ -147,10 +147,10 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
|
|||
}
|
||||
|
||||
private class MessageDiffCallback extends DiffUtil.Callback {
|
||||
private List<EntityIdentity> prev;
|
||||
private List<EntityIdentity> next;
|
||||
private List<TupleIdentityEx> prev;
|
||||
private List<TupleIdentityEx> next;
|
||||
|
||||
MessageDiffCallback(List<EntityIdentity> prev, List<EntityIdentity> next) {
|
||||
MessageDiffCallback(List<TupleIdentityEx> prev, List<TupleIdentityEx> next) {
|
||||
this.prev = prev;
|
||||
this.next = next;
|
||||
}
|
||||
|
@ -167,15 +167,15 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
|
|||
|
||||
@Override
|
||||
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
|
||||
EntityIdentity i1 = prev.get(oldItemPosition);
|
||||
EntityIdentity i2 = next.get(newItemPosition);
|
||||
TupleIdentityEx i1 = prev.get(oldItemPosition);
|
||||
TupleIdentityEx i2 = next.get(newItemPosition);
|
||||
return i1.id.equals(i2.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
|
||||
EntityIdentity i1 = prev.get(oldItemPosition);
|
||||
EntityIdentity i2 = next.get(newItemPosition);
|
||||
TupleIdentityEx i1 = prev.get(oldItemPosition);
|
||||
TupleIdentityEx i2 = next.get(newItemPosition);
|
||||
return i1.equals(i2);
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ public class AdapterIdentity extends RecyclerView.Adapter<AdapterIdentity.ViewHo
|
|||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
holder.unwire();
|
||||
|
||||
EntityIdentity identity = filtered.get(position);
|
||||
TupleIdentityEx identity = filtered.get(position);
|
||||
holder.bindTo(identity);
|
||||
|
||||
holder.wire();
|
||||
|
|
|
@ -60,8 +60,6 @@ public class ApplicationEx extends Application {
|
|||
draft.ui_hide = false;
|
||||
draft.id = db.message().insertMessage(draft);
|
||||
|
||||
EntityOperation.queue(ApplicationEx.this, draft, EntityOperation.ADD);
|
||||
|
||||
Log.w(Helper.TAG, "Crash info stored as draft");
|
||||
}
|
||||
} catch (Throwable e1) {
|
||||
|
|
|
@ -44,6 +44,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase;
|
|||
// https://developer.android.com/topic/libraries/architecture/room.html
|
||||
|
||||
@Database(
|
||||
version = 7,
|
||||
entities = {
|
||||
EntityIdentity.class,
|
||||
EntityAccount.class,
|
||||
|
@ -51,9 +52,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase;
|
|||
EntityMessage.class,
|
||||
EntityAttachment.class,
|
||||
EntityOperation.class
|
||||
},
|
||||
version = 6,
|
||||
exportSchema = true
|
||||
}
|
||||
)
|
||||
|
||||
@TypeConverters({DB.Converters.class})
|
||||
|
@ -86,11 +85,19 @@ public abstract class DB extends RoomDatabase {
|
|||
|
||||
private static DB migrate(RoomDatabase.Builder<DB> builder) {
|
||||
return builder
|
||||
.addCallback(new Callback() {
|
||||
@Override
|
||||
public void onOpen(SupportSQLiteDatabase db) {
|
||||
Log.i(Helper.TAG, "Database version=" + db.getVersion());
|
||||
super.onOpen(db);
|
||||
}
|
||||
})
|
||||
.addMigrations(MIGRATION_1_2)
|
||||
.addMigrations(MIGRATION_2_3)
|
||||
.addMigrations(MIGRATION_3_4)
|
||||
.addMigrations(MIGRATION_4_5)
|
||||
.addMigrations(MIGRATION_5_6)
|
||||
.addMigrations(MIGRATION_6_7)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -142,6 +149,29 @@ public abstract class DB extends RoomDatabase {
|
|||
}
|
||||
};
|
||||
|
||||
private static final Migration MIGRATION_6_7 = new Migration(6, 7) {
|
||||
@Override
|
||||
public void migrate(SupportSQLiteDatabase db) {
|
||||
Log.i(Helper.TAG, "DB migration from version " + startVersion + " to " + endVersion);
|
||||
db.execSQL("DROP TABLE `identity`");
|
||||
db.execSQL("CREATE TABLE `identity`" +
|
||||
" (`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" +
|
||||
", `primary` INTEGER NOT NULL" +
|
||||
", `synchronize` INTEGER NOT NULL" +
|
||||
", FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE)");
|
||||
db.execSQL("CREATE INDEX `index_identity_account` ON `identity` (`account`)");
|
||||
}
|
||||
};
|
||||
|
||||
public static class Converters {
|
||||
@TypeConverter
|
||||
public static String[] fromStringArray(String value) {
|
||||
|
|
|
@ -45,9 +45,6 @@ public interface DaoAccount {
|
|||
@Query("SELECT * FROM account WHERE id = :id")
|
||||
LiveData<EntityAccount> liveAccount(long id);
|
||||
|
||||
@Query("SELECT * FROM account ORDER BY id LIMIT 1")
|
||||
LiveData<EntityAccount> liveFirstAccount();
|
||||
|
||||
@Query("SELECT" +
|
||||
" (SELECT COUNT(*) FROM account WHERE synchronize) AS accounts" +
|
||||
", (SELECT COUNT(*) FROM operation" +
|
||||
|
|
|
@ -30,8 +30,9 @@ import androidx.room.Update;
|
|||
|
||||
@Dao
|
||||
public interface DaoIdentity {
|
||||
@Query("SELECT * FROM identity")
|
||||
LiveData<List<EntityIdentity>> liveIdentities();
|
||||
@Query("SELECT identity.*, account.name AS accountName FROM identity" +
|
||||
" JOIN account ON account.id = identity.account")
|
||||
LiveData<List<TupleIdentityEx>> liveIdentities();
|
||||
|
||||
@Query("SELECT * FROM identity WHERE synchronize = :synchronize")
|
||||
LiveData<List<EntityIdentity>> liveIdentities(boolean synchronize);
|
||||
|
@ -42,9 +43,6 @@ public interface DaoIdentity {
|
|||
@Query("SELECT * FROM identity WHERE id = :id")
|
||||
LiveData<EntityIdentity> liveIdentity(long id);
|
||||
|
||||
@Query("SELECT * FROM identity ORDER BY id LIMIT 1")
|
||||
LiveData<EntityIdentity> liveFirstIdentity();
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
long insertIdentity(EntityIdentity identity);
|
||||
|
||||
|
|
|
@ -62,4 +62,9 @@ public class EntityAccount {
|
|||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + (primary ? " ★" : "");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,11 +21,19 @@ package eu.faircode.email;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.ForeignKey;
|
||||
import androidx.room.Index;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
import static androidx.room.ForeignKey.CASCADE;
|
||||
|
||||
@Entity(
|
||||
tableName = EntityIdentity.TABLE_NAME,
|
||||
foreignKeys = {
|
||||
@ForeignKey(childColumns = "account", entity = EntityAccount.class, parentColumns = "id", onDelete = CASCADE)
|
||||
},
|
||||
indices = {
|
||||
@Index(value = {"account"})
|
||||
}
|
||||
)
|
||||
public class EntityIdentity {
|
||||
|
@ -39,6 +47,8 @@ public class EntityIdentity {
|
|||
public String email;
|
||||
public String replyto;
|
||||
@NonNull
|
||||
public Long account;
|
||||
@NonNull
|
||||
public String host; // SMTP
|
||||
@NonNull
|
||||
public Integer port;
|
||||
|
@ -60,6 +70,7 @@ public class EntityIdentity {
|
|||
return (this.name.equals(other.name) &&
|
||||
this.email.equals(other.email) &&
|
||||
(this.replyto == null ? other.replyto == null : this.replyto.equals(other.replyto)) &&
|
||||
this.account.equals(other.account) &&
|
||||
this.host.equals(other.host) &&
|
||||
this.port.equals(other.port) &&
|
||||
this.starttls.equals(other.starttls) &&
|
||||
|
|
|
@ -90,9 +90,9 @@ public class FragmentIdentities extends FragmentEx {
|
|||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
// Observe identities
|
||||
DB.getInstance(getContext()).identity().liveIdentities().observe(getViewLifecycleOwner(), new Observer<List<EntityIdentity>>() {
|
||||
DB.getInstance(getContext()).identity().liveIdentities().observe(getViewLifecycleOwner(), new Observer<List<TupleIdentityEx>>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable List<EntityIdentity> identities) {
|
||||
public void onChanged(@Nullable List<TupleIdentityEx> identities) {
|
||||
adapter.set(identities);
|
||||
|
||||
pbWait.setVisibility(View.GONE);
|
||||
|
|
|
@ -62,10 +62,11 @@ import androidx.loader.content.Loader;
|
|||
public class FragmentIdentity extends FragmentEx {
|
||||
private List<Provider> providers;
|
||||
|
||||
private Spinner spProfile;
|
||||
private EditText etName;
|
||||
private EditText etEmail;
|
||||
private EditText etReplyTo;
|
||||
private Spinner spProfile;
|
||||
private Spinner spAccount;
|
||||
private EditText etHost;
|
||||
private CheckBox cbStartTls;
|
||||
private EditText etPort;
|
||||
|
@ -96,10 +97,11 @@ public class FragmentIdentity extends FragmentEx {
|
|||
providers.add(0, new Provider(getString(R.string.title_custom)));
|
||||
|
||||
// Get controls
|
||||
spProfile = view.findViewById(R.id.spProvider);
|
||||
etName = view.findViewById(R.id.etName);
|
||||
etEmail = view.findViewById(R.id.etEmail);
|
||||
etReplyTo = view.findViewById(R.id.etReplyTo);
|
||||
spProfile = view.findViewById(R.id.spProvider);
|
||||
spAccount = view.findViewById(R.id.spAccount);
|
||||
etHost = view.findViewById(R.id.etHost);
|
||||
cbStartTls = view.findViewById(R.id.cbStartTls);
|
||||
etPort = view.findViewById(R.id.etPort);
|
||||
|
@ -128,13 +130,6 @@ public class FragmentIdentity extends FragmentEx {
|
|||
}
|
||||
});
|
||||
|
||||
cbStartTls.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
|
||||
etPort.setHint(checked ? "587" : "465");
|
||||
}
|
||||
});
|
||||
|
||||
spProfile.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
|
@ -151,9 +146,16 @@ public class FragmentIdentity extends FragmentEx {
|
|||
}
|
||||
});
|
||||
|
||||
ArrayAdapter<Provider> adapter = new ArrayAdapter<>(getContext(), R.layout.spinner_item, providers);
|
||||
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
|
||||
spProfile.setAdapter(adapter);
|
||||
ArrayAdapter<Provider> adapterProfile = new ArrayAdapter<>(getContext(), R.layout.spinner_item, providers);
|
||||
adapterProfile.setDropDownViewResource(R.layout.spinner_dropdown_item);
|
||||
spProfile.setAdapter(adapterProfile);
|
||||
|
||||
cbStartTls.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
|
||||
etPort.setHint(checked ? "587" : "465");
|
||||
}
|
||||
});
|
||||
|
||||
cbSynchronize.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
|
@ -168,11 +170,14 @@ public class FragmentIdentity extends FragmentEx {
|
|||
btnSave.setEnabled(false);
|
||||
pbCheck.setVisibility(View.VISIBLE);
|
||||
|
||||
EntityAccount account = (EntityAccount) spAccount.getSelectedItem();
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putLong("id", id);
|
||||
args.putString("name", etName.getText().toString());
|
||||
args.putString("email", etEmail.getText().toString());
|
||||
args.putString("replyto", etReplyTo.getText().toString());
|
||||
args.putLong("account", account == null ? -1 : account.id);
|
||||
args.putString("host", etHost.getText().toString());
|
||||
args.putBoolean("starttls", cbStartTls.isChecked());
|
||||
args.putString("port", etPort.getText().toString());
|
||||
|
@ -230,10 +235,12 @@ public class FragmentIdentity extends FragmentEx {
|
|||
Bundle args = getArguments();
|
||||
long id = (args == null ? -1 : args.getLong("id", -1));
|
||||
|
||||
// Observer
|
||||
DB.getInstance(getContext()).identity().liveIdentity(id).observe(getViewLifecycleOwner(), new Observer<EntityIdentity>() {
|
||||
final DB db = DB.getInstance(getContext());
|
||||
|
||||
// Observe identity
|
||||
db.identity().liveIdentity(id).observe(getViewLifecycleOwner(), new Observer<EntityIdentity>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable EntityIdentity identity) {
|
||||
public void onChanged(@Nullable final EntityIdentity identity) {
|
||||
etName.setText(identity == null ? null : identity.name);
|
||||
etEmail.setText(identity == null ? null : identity.email);
|
||||
etReplyTo.setText(identity == null ? null : identity.replyto);
|
||||
|
@ -245,6 +252,29 @@ public class FragmentIdentity extends FragmentEx {
|
|||
cbSynchronize.setChecked(identity == null ? true : identity.synchronize);
|
||||
cbPrimary.setChecked(identity == null ? true : identity.primary);
|
||||
cbPrimary.setEnabled(identity == null ? true : identity.synchronize);
|
||||
|
||||
db.account().liveAccounts().removeObservers(getViewLifecycleOwner());
|
||||
db.account().liveAccounts().observe(getViewLifecycleOwner(), new Observer<List<EntityAccount>>() {
|
||||
@Override
|
||||
public void onChanged(List<EntityAccount> accounts) {
|
||||
|
||||
EntityAccount unselected = new EntityAccount();
|
||||
unselected.id = -1L;
|
||||
unselected.name = "";
|
||||
unselected.primary = false;
|
||||
accounts.add(0, unselected);
|
||||
|
||||
ArrayAdapter<EntityAccount> adapterAccount = new ArrayAdapter<>(getContext(), R.layout.spinner_item, accounts);
|
||||
adapterAccount.setDropDownViewResource(R.layout.spinner_dropdown_item);
|
||||
spAccount.setAdapter(adapterAccount);
|
||||
|
||||
for (int pos = 0; pos < accounts.size(); pos++)
|
||||
if (accounts.get(pos).id == (identity == null ? -1 : identity.account)) {
|
||||
spAccount.setSelection(pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -264,21 +294,30 @@ public class FragmentIdentity extends FragmentEx {
|
|||
public Throwable loadInBackground() {
|
||||
try {
|
||||
long id = args.getLong("id");
|
||||
String name = args.getString("name");
|
||||
String email = args.getString("email");
|
||||
String replyto = args.getString("replyto");
|
||||
long account = args.getLong("account");
|
||||
String host = args.getString("host");
|
||||
boolean starttls = args.getBoolean("starttls");
|
||||
String port = args.getString("port");
|
||||
String user = args.getString("user");
|
||||
String password = args.getString("password");
|
||||
|
||||
if (TextUtils.isEmpty(name))
|
||||
throw new IllegalArgumentException(getContext().getString(R.string.title_no_name));
|
||||
if (TextUtils.isEmpty(email))
|
||||
throw new IllegalArgumentException(getContext().getString(R.string.title_no_email));
|
||||
if (account < 0)
|
||||
throw new IllegalArgumentException(getContext().getString(R.string.title_no_account));
|
||||
if (TextUtils.isEmpty(host))
|
||||
throw new Throwable(getContext().getString(R.string.title_no_host));
|
||||
throw new IllegalArgumentException(getContext().getString(R.string.title_no_host));
|
||||
if (TextUtils.isEmpty(port))
|
||||
throw new Throwable(getContext().getString(R.string.title_no_port));
|
||||
throw new IllegalArgumentException(getContext().getString(R.string.title_no_port));
|
||||
if (TextUtils.isEmpty(user))
|
||||
throw new Throwable(getContext().getString(R.string.title_no_user));
|
||||
throw new IllegalArgumentException(getContext().getString(R.string.title_no_user));
|
||||
if (TextUtils.isEmpty(password))
|
||||
throw new Throwable(getContext().getString(R.string.title_no_password));
|
||||
throw new IllegalArgumentException(getContext().getString(R.string.title_no_password));
|
||||
|
||||
if (TextUtils.isEmpty(replyto))
|
||||
replyto = null;
|
||||
|
@ -288,9 +327,10 @@ public class FragmentIdentity extends FragmentEx {
|
|||
boolean update = (identity != null);
|
||||
if (identity == null)
|
||||
identity = new EntityIdentity();
|
||||
identity.name = Objects.requireNonNull(args.getString("name"));
|
||||
identity.email = Objects.requireNonNull(args.getString("email"));
|
||||
identity.name = name;
|
||||
identity.email = email;
|
||||
identity.replyto = replyto;
|
||||
identity.account = account;
|
||||
identity.host = Objects.requireNonNull(host);
|
||||
identity.port = Integer.parseInt(port);
|
||||
identity.starttls = starttls;
|
||||
|
@ -299,12 +339,6 @@ public class FragmentIdentity extends FragmentEx {
|
|||
identity.synchronize = args.getBoolean("synchronize");
|
||||
identity.primary = (identity.synchronize && args.getBoolean("primary"));
|
||||
|
||||
if (TextUtils.isEmpty(identity.name))
|
||||
throw new IllegalArgumentException(getContext().getString(R.string.title_no_name));
|
||||
|
||||
if (TextUtils.isEmpty(identity.email))
|
||||
throw new IllegalArgumentException(getContext().getString(R.string.title_no_email));
|
||||
|
||||
// Check SMTP server
|
||||
if (identity.synchronize) {
|
||||
Properties props = MessageHelper.getSessionProperties();
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package eu.faircode.email;
|
||||
|
||||
public class TupleIdentityEx extends EntityIdentity {
|
||||
public String accountName;
|
||||
}
|
|
@ -75,6 +75,26 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvReplyTo" />
|
||||
|
||||
|
||||
<!--- linked account -->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAccount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/title_account_linked"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/etReplyTo" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spAccount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvAccount" />
|
||||
|
||||
<!--- provider -->
|
||||
|
||||
<TextView
|
||||
|
@ -85,7 +105,7 @@
|
|||
android:text="@string/title_provider"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/etReplyTo" />
|
||||
app:layout_constraintTop_toBottomOf="@id/spAccount" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spProvider"
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="Name"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/ivSync"
|
||||
|
@ -42,6 +44,8 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="host"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintEnd_toStartOf="@+id/tvUser"
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="Name"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
|
|
|
@ -21,7 +21,9 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall"
|
||||
android:text="Menu item"
|
||||
android:textAppearance="?android:attr/textAppearanceListItemSmall"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
android:layout_marginEnd="6dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:ellipsize="start"
|
||||
android:singleLine="true"
|
||||
android:text="Name"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/ivMessages"
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="Name"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/ivSync"
|
||||
|
@ -38,27 +40,29 @@
|
|||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvHost"
|
||||
android:id="@+id/tvAccount"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:text="host"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="account"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintEnd_toStartOf="@+id/tvUser"
|
||||
app:layout_constraintEnd_toStartOf="@+id/tvEmail"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/ivSync" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvEmail"
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:text="user"
|
||||
android:text="user@host"
|
||||
android:textAlignment="textEnd"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/tvHost"
|
||||
app:layout_constraintStart_toEndOf="@id/tvAccount"
|
||||
app:layout_constraintTop_toBottomOf="@id/ivSync" />
|
||||
|
||||
<View
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
<string name="title_email">Your email address</string>
|
||||
<string name="title_reply_to">Reply to address</string>
|
||||
<string name="title_optional">Optional</string>
|
||||
<string name="title_account_linked">Linked account</string>
|
||||
<string name="title_account_name">Account name</string>
|
||||
<string name="title_account_name_hint">Used to differentiate folders</string>
|
||||
<string name="title_imap">IMAP</string>
|
||||
|
@ -58,8 +59,9 @@
|
|||
<string name="title_synchronize_identity">Synchronize (send messages)</string>
|
||||
<string name="title_primary_account">Primary (used to store drafts)</string>
|
||||
<string name="title_primary_identity">Primary (default identity)</string>
|
||||
<string name="title_no_name">Name mandatory</string>
|
||||
<string name="title_no_email">Email address mandatory</string>
|
||||
<string name="title_no_name">Name missing</string>
|
||||
<string name="title_no_email">Email address missing</string>
|
||||
<string name="title_no_account">Account missing</string>
|
||||
<string name="title_no_host">Host name missing</string>
|
||||
<string name="title_no_port">Port number missing</string>
|
||||
<string name="title_no_user">User name missing</string>
|
||||
|
|
Loading…
Reference in New Issue