Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f67de73 authored by moezbhatti's avatar moezbhatti Committed by Moez Bhatti
Browse files

Sync starred contacts and groups

parent 28cad9bb
Loading
Loading
Loading
Loading
+8 −29
Original line number Diff line number Diff line
@@ -20,8 +20,6 @@ package com.moez.QKSMS.extensions

import android.database.Cursor
import io.reactivex.Flowable
import io.reactivex.Maybe
import io.reactivex.subjects.MaybeSubject

fun Cursor.forEach(closeOnComplete: Boolean = true, method: (Cursor) -> Unit = {}) {
    moveToPosition(-1)
@@ -41,21 +39,6 @@ fun <T> Cursor.map(map: (Cursor) -> T): List<T> {
    }
}

fun <T> Cursor.mapWhile(map: (Cursor) -> T, predicate: (T) -> Boolean): ArrayList<T> {
    val result = ArrayList<T>()

    moveToPosition(-1)
    while (moveToNext()) {
        val item = map(this)

        if (!predicate(item)) break

        result.add(item)
    }

    return result
}

/**
 * We're using this simple implementation with .range() because of the
 * complexities of dealing with Backpressure with a Cursor. We can't simply
@@ -72,18 +55,14 @@ fun Cursor.asFlowable(): Flowable<Cursor> {
            .doOnComplete { close() }
}

fun Cursor.asMaybe(): Maybe<Cursor> {
    val subject = MaybeSubject.create<Cursor>()
/**
 * Dumps the contents of the cursor as a CSV string
 */
fun Cursor.dump(): String {
    val lines = mutableListOf<String>()

    if (moveToFirst()) {
        subject.onSuccess(this)
    } else {
        subject.onError(IndexOutOfBoundsException("The cursor has no items"))
    }
    lines += columnNames.joinToString(",")
    forEach { lines += (0 until columnCount).joinToString(",", transform = ::getString) }

    subject.doOnComplete { close() }
    return subject
    return lines.joinToString("\n")
}


+52 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com>
 *
 * This file is part of QKSMS.
 *
 * QKSMS 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.
 *
 * QKSMS 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 QKSMS.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.moez.QKSMS.mapper

import android.content.Context
import android.database.Cursor
import android.provider.ContactsContract
import com.moez.QKSMS.model.ContactGroup
import javax.inject.Inject

class CursorToContactGroupImpl @Inject constructor(
    private val context: Context
) : CursorToContactGroup {

    companion object {
        private val URI = ContactsContract.Groups.CONTENT_URI
        private val PROJECTION = arrayOf(
                ContactsContract.Groups._ID,
                ContactsContract.Groups.TITLE)
        private const val SELECTION = "${ContactsContract.Groups.AUTO_ADD}=0 " +
                "AND ${ContactsContract.Groups.DELETED}=0 " +
                "AND ${ContactsContract.Groups.FAVORITES}=0"

        private const val ID = 0
        private const val TITLE = 1
    }

    override fun map(from: Cursor): ContactGroup {
        return ContactGroup(from.getLong(ID), from.getString(TITLE))
    }

    override fun getContactGroupsCursor(): Cursor? {
        return context.contentResolver.query(URI, PROJECTION, SELECTION, null, null)
    }

}
+52 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com>
 *
 * This file is part of QKSMS.
 *
 * QKSMS 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.
 *
 * QKSMS 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 QKSMS.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.moez.QKSMS.mapper

import android.content.Context
import android.database.Cursor
import android.provider.ContactsContract
import javax.inject.Inject

class CursorToContactGroupMemberImpl @Inject constructor(
    private val context: Context
) : CursorToContactGroupMember {

    companion object {
        private val URI = ContactsContract.Data.CONTENT_URI
        private val PROJECTION = arrayOf(
                ContactsContract.Data.LOOKUP_KEY,
                ContactsContract.Data.DATA1)

        private const val SELECTION = "${ContactsContract.Data.MIMETYPE}=?"
        private val SELECTION_ARGS = arrayOf(
                ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE)

        private const val LOOKUP_KEY = 0
        private const val GROUP_ID = 1
    }

    override fun map(from: Cursor): CursorToContactGroupMember.GroupMember {
        return CursorToContactGroupMember.GroupMember(from.getString(LOOKUP_KEY), from.getLong(GROUP_ID))
    }

    override fun getGroupMembersCursor(): Cursor? {
        return context.contentResolver.query(URI, PROJECTION, SELECTION, SELECTION_ARGS, null)
    }

}
+5 −2
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ class CursorToContactImpl @Inject constructor(
                Phone.TYPE,
                Phone.LABEL,
                Phone.DISPLAY_NAME,
                Phone.STARRED,
                Phone.CONTACT_LAST_UPDATED_TIMESTAMP
        )

@@ -47,7 +48,8 @@ class CursorToContactImpl @Inject constructor(
        const val COLUMN_TYPE = 2
        const val COLUMN_LABEL = 3
        const val COLUMN_DISPLAY_NAME = 4
        const val CONTACT_LAST_UPDATED = 5
        const val COLUMN_STARRED = 5
        const val CONTACT_LAST_UPDATED = 6
    }

    override fun map(from: Cursor) = Contact().apply {
@@ -58,6 +60,7 @@ class CursorToContactImpl @Inject constructor(
                type = Phone.getTypeLabel(context.resources, from.getInt(COLUMN_TYPE),
                        from.getString(COLUMN_LABEL)).toString()
        ))
        starred = from.getInt(COLUMN_STARRED) != 0
        lastUpdate = from.getLong(CONTACT_LAST_UPDATED)
    }

+13 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import io.realm.Sort
class QkRealmMigration : RealmMigration {

    companion object {
        const val SCHEMA_VERSION: Long = 8
        const val SCHEMA_VERSION: Long = 9
    }

    override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
@@ -118,6 +118,18 @@ class QkRealmMigration : RealmMigration {
            version++
        }

        if (version == 8L) {
            realm.schema.create("ContactGroup")
                    .addField("id", Long::class.java, FieldAttribute.PRIMARY_KEY, FieldAttribute.REQUIRED)
                    .addField("title", String::class.java, FieldAttribute.REQUIRED)
                    .addRealmListField("contacts", realm.schema.get("Contact"))

            realm.schema.get("Contact")
                    ?.addField("starred", Boolean::class.java, FieldAttribute.REQUIRED)

            version++
        }

        check(version >= newVersion) { "Migration missing from v$oldVersion to v$newVersion" }
    }

Loading