Add intent filters so LibreMail handles mailto: (ACTION_VIEW / SENDTO) and email SEND / SEND_MULTIPLE intents, opening a prefilled compose screen. - MailtoParser: pure RFC 6068 parser (multiple recipients, to/cc/bcc/ subject/body, percent-encoding; preserves a literal '+'); JVM-tested. - IntentComposeParser: builds a ComposePrefill from a mailto: URI or the EXTRA_EMAIL/CC/BCC/SUBJECT/TEXT share extras. - MainActivity parses the launch/new intent and hands a one-shot prefill to the NavHost (guarded against config-change duplication). - Compose form gains a Bcc field; Routes carry cc/bcc/body deep-link args. - bcc wired end-to-end: OutgoingMessage, SMTP + Graph senders, and outbox + drafts persistence via Room migration v9 -> v10. - Multi-account send is served by the existing From picker on compose. Default mail app: Android exposes no public RoleManager email role, so the intent filters are what make LibreMail appear on the system "Open by default" / default-apps screen where the platform/OEM supports it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
523 lines
16 KiB
JSON
523 lines
16 KiB
JSON
{
|
|
"formatVersion": 1,
|
|
"database": {
|
|
"version": 10,
|
|
"identityHash": "aff2afe197ff1b0b41630e5a165d09f3",
|
|
"entities": [
|
|
{
|
|
"tableName": "accounts",
|
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `email` TEXT NOT NULL, `displayName` TEXT NOT NULL, `authType` TEXT NOT NULL, `imap_host` TEXT NOT NULL, `imap_port` INTEGER NOT NULL, `imap_security` TEXT NOT NULL, `smtp_host` TEXT NOT NULL, `smtp_port` INTEGER NOT NULL, `smtp_security` TEXT NOT NULL, PRIMARY KEY(`id`))",
|
|
"fields": [
|
|
{
|
|
"fieldPath": "id",
|
|
"columnName": "id",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "email",
|
|
"columnName": "email",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "displayName",
|
|
"columnName": "displayName",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "authType",
|
|
"columnName": "authType",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "imap.host",
|
|
"columnName": "imap_host",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "imap.port",
|
|
"columnName": "imap_port",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "imap.security",
|
|
"columnName": "imap_security",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "smtp.host",
|
|
"columnName": "smtp_host",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "smtp.port",
|
|
"columnName": "smtp_port",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "smtp.security",
|
|
"columnName": "smtp_security",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
}
|
|
],
|
|
"primaryKey": {
|
|
"autoGenerate": false,
|
|
"columnNames": [
|
|
"id"
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"tableName": "account_settings",
|
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`accountId` TEXT NOT NULL, `signature` TEXT NOT NULL, `signatureEnabled` INTEGER NOT NULL, `notificationsEnabled` INTEGER NOT NULL, PRIMARY KEY(`accountId`), FOREIGN KEY(`accountId`) REFERENCES `accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
|
"fields": [
|
|
{
|
|
"fieldPath": "accountId",
|
|
"columnName": "accountId",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "signature",
|
|
"columnName": "signature",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "signatureEnabled",
|
|
"columnName": "signatureEnabled",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "notificationsEnabled",
|
|
"columnName": "notificationsEnabled",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
}
|
|
],
|
|
"primaryKey": {
|
|
"autoGenerate": false,
|
|
"columnNames": [
|
|
"accountId"
|
|
]
|
|
},
|
|
"foreignKeys": [
|
|
{
|
|
"table": "accounts",
|
|
"onDelete": "CASCADE",
|
|
"onUpdate": "NO ACTION",
|
|
"columns": [
|
|
"accountId"
|
|
],
|
|
"referencedColumns": [
|
|
"id"
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"tableName": "messages",
|
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `accountId` TEXT NOT NULL, `sender` TEXT NOT NULL, `senderEmail` TEXT NOT NULL, `subject` TEXT NOT NULL, `snippet` TEXT NOT NULL, `body` TEXT NOT NULL, `isHtml` INTEGER NOT NULL, `timestampMillis` INTEGER NOT NULL, `isRead` INTEGER NOT NULL, `isStarred` INTEGER NOT NULL, `folder` TEXT NOT NULL DEFAULT 'INBOX', `inInbox` INTEGER NOT NULL, `bodyFetched` INTEGER NOT NULL, PRIMARY KEY(`id`))",
|
|
"fields": [
|
|
{
|
|
"fieldPath": "id",
|
|
"columnName": "id",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "accountId",
|
|
"columnName": "accountId",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "sender",
|
|
"columnName": "sender",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "senderEmail",
|
|
"columnName": "senderEmail",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "subject",
|
|
"columnName": "subject",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "snippet",
|
|
"columnName": "snippet",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "body",
|
|
"columnName": "body",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "isHtml",
|
|
"columnName": "isHtml",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "timestampMillis",
|
|
"columnName": "timestampMillis",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "isRead",
|
|
"columnName": "isRead",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "isStarred",
|
|
"columnName": "isStarred",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "folder",
|
|
"columnName": "folder",
|
|
"affinity": "TEXT",
|
|
"notNull": true,
|
|
"defaultValue": "'INBOX'"
|
|
},
|
|
{
|
|
"fieldPath": "inInbox",
|
|
"columnName": "inInbox",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "bodyFetched",
|
|
"columnName": "bodyFetched",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
}
|
|
],
|
|
"primaryKey": {
|
|
"autoGenerate": false,
|
|
"columnNames": [
|
|
"id"
|
|
]
|
|
},
|
|
"indices": [
|
|
{
|
|
"name": "index_messages_accountId",
|
|
"unique": false,
|
|
"columnNames": [
|
|
"accountId"
|
|
],
|
|
"orders": [],
|
|
"createSql": "CREATE INDEX IF NOT EXISTS `index_messages_accountId` ON `${TABLE_NAME}` (`accountId`)"
|
|
},
|
|
{
|
|
"name": "index_messages_timestampMillis",
|
|
"unique": false,
|
|
"columnNames": [
|
|
"timestampMillis"
|
|
],
|
|
"orders": [],
|
|
"createSql": "CREATE INDEX IF NOT EXISTS `index_messages_timestampMillis` ON `${TABLE_NAME}` (`timestampMillis`)"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"tableName": "credentials",
|
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`accountId` TEXT NOT NULL, `encryptedSecret` TEXT NOT NULL, PRIMARY KEY(`accountId`))",
|
|
"fields": [
|
|
{
|
|
"fieldPath": "accountId",
|
|
"columnName": "accountId",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "encryptedSecret",
|
|
"columnName": "encryptedSecret",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
}
|
|
],
|
|
"primaryKey": {
|
|
"autoGenerate": false,
|
|
"columnNames": [
|
|
"accountId"
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"tableName": "attachments",
|
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`messageId` TEXT NOT NULL, `partIndex` INTEGER NOT NULL, `filename` TEXT NOT NULL, `mimeType` TEXT NOT NULL, `sizeBytes` INTEGER NOT NULL, PRIMARY KEY(`messageId`, `partIndex`), FOREIGN KEY(`messageId`) REFERENCES `messages`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
|
"fields": [
|
|
{
|
|
"fieldPath": "messageId",
|
|
"columnName": "messageId",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "partIndex",
|
|
"columnName": "partIndex",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "filename",
|
|
"columnName": "filename",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "mimeType",
|
|
"columnName": "mimeType",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "sizeBytes",
|
|
"columnName": "sizeBytes",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
}
|
|
],
|
|
"primaryKey": {
|
|
"autoGenerate": false,
|
|
"columnNames": [
|
|
"messageId",
|
|
"partIndex"
|
|
]
|
|
},
|
|
"indices": [
|
|
{
|
|
"name": "index_attachments_messageId",
|
|
"unique": false,
|
|
"columnNames": [
|
|
"messageId"
|
|
],
|
|
"orders": [],
|
|
"createSql": "CREATE INDEX IF NOT EXISTS `index_attachments_messageId` ON `${TABLE_NAME}` (`messageId`)"
|
|
}
|
|
],
|
|
"foreignKeys": [
|
|
{
|
|
"table": "messages",
|
|
"onDelete": "CASCADE",
|
|
"onUpdate": "NO ACTION",
|
|
"columns": [
|
|
"messageId"
|
|
],
|
|
"referencedColumns": [
|
|
"id"
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"tableName": "outbox",
|
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `accountId` TEXT NOT NULL, `toAddresses` TEXT NOT NULL, `ccAddresses` TEXT NOT NULL, `bccAddresses` TEXT NOT NULL DEFAULT '', `subject` TEXT NOT NULL, `body` TEXT NOT NULL, `createdAt` INTEGER NOT NULL, `lastError` TEXT, PRIMARY KEY(`id`))",
|
|
"fields": [
|
|
{
|
|
"fieldPath": "id",
|
|
"columnName": "id",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "accountId",
|
|
"columnName": "accountId",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "toAddresses",
|
|
"columnName": "toAddresses",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "ccAddresses",
|
|
"columnName": "ccAddresses",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "bccAddresses",
|
|
"columnName": "bccAddresses",
|
|
"affinity": "TEXT",
|
|
"notNull": true,
|
|
"defaultValue": "''"
|
|
},
|
|
{
|
|
"fieldPath": "subject",
|
|
"columnName": "subject",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "body",
|
|
"columnName": "body",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "createdAt",
|
|
"columnName": "createdAt",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "lastError",
|
|
"columnName": "lastError",
|
|
"affinity": "TEXT"
|
|
}
|
|
],
|
|
"primaryKey": {
|
|
"autoGenerate": false,
|
|
"columnNames": [
|
|
"id"
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"tableName": "drafts",
|
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `accountId` TEXT, `toAddresses` TEXT NOT NULL, `ccAddresses` TEXT NOT NULL, `bccAddresses` TEXT NOT NULL DEFAULT '', `subject` TEXT NOT NULL, `body` TEXT NOT NULL, `updatedAt` INTEGER NOT NULL, `attachments` TEXT NOT NULL, PRIMARY KEY(`id`))",
|
|
"fields": [
|
|
{
|
|
"fieldPath": "id",
|
|
"columnName": "id",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "accountId",
|
|
"columnName": "accountId",
|
|
"affinity": "TEXT"
|
|
},
|
|
{
|
|
"fieldPath": "toAddresses",
|
|
"columnName": "toAddresses",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "ccAddresses",
|
|
"columnName": "ccAddresses",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "bccAddresses",
|
|
"columnName": "bccAddresses",
|
|
"affinity": "TEXT",
|
|
"notNull": true,
|
|
"defaultValue": "''"
|
|
},
|
|
{
|
|
"fieldPath": "subject",
|
|
"columnName": "subject",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "body",
|
|
"columnName": "body",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "updatedAt",
|
|
"columnName": "updatedAt",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "attachments",
|
|
"columnName": "attachments",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
}
|
|
],
|
|
"primaryKey": {
|
|
"autoGenerate": false,
|
|
"columnNames": [
|
|
"id"
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"tableName": "folders",
|
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`accountId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `displayName` TEXT NOT NULL, `role` TEXT NOT NULL, `selectable` INTEGER NOT NULL, `sortOrder` INTEGER NOT NULL, PRIMARY KEY(`accountId`, `fullName`))",
|
|
"fields": [
|
|
{
|
|
"fieldPath": "accountId",
|
|
"columnName": "accountId",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "fullName",
|
|
"columnName": "fullName",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "displayName",
|
|
"columnName": "displayName",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "role",
|
|
"columnName": "role",
|
|
"affinity": "TEXT",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "selectable",
|
|
"columnName": "selectable",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
},
|
|
{
|
|
"fieldPath": "sortOrder",
|
|
"columnName": "sortOrder",
|
|
"affinity": "INTEGER",
|
|
"notNull": true
|
|
}
|
|
],
|
|
"primaryKey": {
|
|
"autoGenerate": false,
|
|
"columnNames": [
|
|
"accountId",
|
|
"fullName"
|
|
]
|
|
}
|
|
}
|
|
],
|
|
"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, 'aff2afe197ff1b0b41630e5a165d09f3')"
|
|
]
|
|
}
|
|
} |