From 25eb2305b22c7a7306fee7bb66fd14041a48963e Mon Sep 17 00:00:00 2001 From: Bnyro Date: Tue, 8 Oct 2024 18:33:21 +0200 Subject: [PATCH] fix: vcard export of partial birthday/anniversary dates (closes #406) --- .../6.json | 178 ++++++++++++++++++ .../com/bnyro/contacts/util/VcardHelper.kt | 27 +-- 2 files changed, 193 insertions(+), 12 deletions(-) create mode 100644 app/schemas/com.bnyro.contacts.data.database.AppDatabase/6.json diff --git a/app/schemas/com.bnyro.contacts.data.database.AppDatabase/6.json b/app/schemas/com.bnyro.contacts.data.database.AppDatabase/6.json new file mode 100644 index 00000000..668ea914 --- /dev/null +++ b/app/schemas/com.bnyro.contacts.data.database.AppDatabase/6.json @@ -0,0 +1,178 @@ +{ + "formatVersion": 1, + "database": { + "version": 6, + "identityHash": "45dcecae89c80128ab3c91537794287f", + "entities": [ + { + "tableName": "localContacts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `displayName` TEXT, `firstName` TEXT, `surName` TEXT, `nickName` TEXT, `title` TEXT, `organization` TEXT, `favorite` INTEGER NOT NULL DEFAULT 0)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "firstName", + "columnName": "firstName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "surName", + "columnName": "surName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "nickName", + "columnName": "nickName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "organization", + "columnName": "organization", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "favorite", + "columnName": "favorite", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "valuableTypes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `contactId` INTEGER NOT NULL, `category` INTEGER NOT NULL, `value` TEXT NOT NULL, `type` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "contactId", + "columnName": "contactId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "category", + "columnName": "category", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "localSms", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `address` TEXT NOT NULL, `body` TEXT NOT NULL, `timestamp` INTEGER NOT NULL, `threadId` INTEGER NOT NULL, `type` INTEGER NOT NULL, `simNumber` INTEGER DEFAULT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "body", + "columnName": "body", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "threadId", + "columnName": "threadId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "simNumber", + "columnName": "simNumber", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "NULL" + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "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, '45dcecae89c80128ab3c91537794287f')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bnyro/contacts/util/VcardHelper.kt b/app/src/main/java/com/bnyro/contacts/util/VcardHelper.kt index 65ac0ea0..2877fbfc 100644 --- a/app/src/main/java/com/bnyro/contacts/util/VcardHelper.kt +++ b/app/src/main/java/com/bnyro/contacts/util/VcardHelper.kt @@ -17,7 +17,7 @@ import ezvcard.property.Birthday import ezvcard.property.FormattedName import ezvcard.property.Photo import ezvcard.property.StructuredName -import java.util.Date +import ezvcard.util.PartialDate object VcardHelper { fun exportVcard(contacts: List): String { @@ -77,19 +77,16 @@ object VcardHelper { contact.events .filter { it.value.isNotBlank() } .forEach { event -> - when (event.type) { - ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY -> { - CalendarUtils.dateToMillis(event.value)?.let { time -> - birthday = Birthday(Date(time)) + when (event.type) { + ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY -> { + birthday = Birthday(PartialDate.parse(event.value)) } - } - ContactsContract.CommonDataKinds.Event.TYPE_ANNIVERSARY -> { - CalendarUtils.dateToMillis(event.value)?.let { time -> - anniversary = Anniversary(Date(time)) + + ContactsContract.CommonDataKinds.Event.TYPE_ANNIVERSARY -> { + anniversary = Anniversary(PartialDate.parse(event.value)) } } } - } (contact.photo ?: contact.thumbnail)?.let { val photo = Photo(ImageHelper.bitmapToByteArray(it), ImageType.PNG) addPhoto(photo) @@ -148,12 +145,18 @@ object VcardHelper { }, events = it.anniversaries.map { anniversary -> ValueWithType( - CalendarUtils.millisToDate(anniversary.date.time, formatter = CalendarUtils.isoDateFormat), + CalendarUtils.millisToDate( + anniversary.date.time, + formatter = CalendarUtils.isoDateFormat + ), ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY ) } + it.birthdays.map { birthday -> ValueWithType( - CalendarUtils.millisToDate(birthday.date.time, formatter = CalendarUtils.isoDateFormat), + CalendarUtils.millisToDate( + birthday.date.time, + formatter = CalendarUtils.isoDateFormat + ), ContactsContract.CommonDataKinds.Event.TYPE_ANNIVERSARY ) },