Migrate to realm + better insertion
This commit is contained in:
parent
95fd7190e4
commit
b79d23ad24
Binary file not shown.
|
@ -8,9 +8,12 @@ import android.widget.Toast
|
||||||
import im.vector.matrix.android.api.Matrix
|
import im.vector.matrix.android.api.Matrix
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
import im.vector.matrix.android.api.failure.Failure
|
import im.vector.matrix.android.api.failure.Failure
|
||||||
|
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||||
import im.vector.matrix.android.internal.events.sync.data.SyncResponse
|
import im.vector.matrix.android.internal.events.sync.data.SyncResponse
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.platform.RiotActivity
|
import im.vector.riotredesign.core.platform.RiotActivity
|
||||||
|
import io.realm.RealmChangeListener
|
||||||
|
import io.realm.RealmResults
|
||||||
import kotlinx.android.synthetic.main.activity_home.*
|
import kotlinx.android.synthetic.main.activity_home.*
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
|
@ -18,6 +21,7 @@ class HomeActivity : RiotActivity() {
|
||||||
|
|
||||||
private val matrix by inject<Matrix>()
|
private val matrix by inject<Matrix>()
|
||||||
private val synchronizer = matrix.currentSession?.synchronizer()
|
private val synchronizer = matrix.currentSession?.synchronizer()
|
||||||
|
private val realmHolder = matrix.currentSession?.realmInstanceHolder()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -32,8 +36,6 @@ class HomeActivity : RiotActivity() {
|
||||||
override fun onSuccess(data: SyncResponse?) {
|
override fun onSuccess(data: SyncResponse?) {
|
||||||
synchronizeButton.visibility = View.VISIBLE
|
synchronizeButton.visibility = View.VISIBLE
|
||||||
loadingView.visibility = View.GONE
|
loadingView.visibility = View.GONE
|
||||||
Toast.makeText(this@HomeActivity, "Success", Toast.LENGTH_LONG).show()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(failure: Failure) {
|
override fun onFailure(failure: Failure) {
|
||||||
|
@ -42,10 +44,17 @@ class HomeActivity : RiotActivity() {
|
||||||
Toast.makeText(this@HomeActivity, failure.toString(), Toast.LENGTH_LONG).show()
|
Toast.makeText(this@HomeActivity, failure.toString(), Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
if (realmHolder != null) {
|
||||||
|
val results = realmHolder.realm.where(EventEntity::class.java).equalTo("chunk.room.roomId", "!UlckfcnwgLKswCmUbe:matrix.org").findAll()
|
||||||
|
results.addChangeListener(RealmChangeListener<RealmResults<EventEntity>> {
|
||||||
|
Toast.makeText(this@HomeActivity, "Room events data changed", Toast.LENGTH_LONG).show()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun newIntent(context: Context): Intent {
|
fun newIntent(context: Context): Intent {
|
||||||
return Intent(context, HomeActivity::class.java)
|
return Intent(context, HomeActivity::class.java)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply plugin: 'kotlin-kapt'
|
apply plugin: 'kotlin-kapt'
|
||||||
apply plugin: 'io.objectbox'
|
apply plugin: 'realm-android'
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ buildscript {
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "io.objectbox:objectbox-gradle-plugin:2.2.0"
|
classpath "io.realm:realm-gradle-plugin:5.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,194 +0,0 @@
|
||||||
{
|
|
||||||
"_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.",
|
|
||||||
"_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.",
|
|
||||||
"_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",
|
|
||||||
"entities": [
|
|
||||||
{
|
|
||||||
"id": "6:5991986256653472999",
|
|
||||||
"lastPropertyId": "6:5675340775405504775",
|
|
||||||
"name": "Credentials",
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"id": "1:904844404428661340",
|
|
||||||
"name": "id"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "2:4962733318674873893",
|
|
||||||
"name": "userId"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "3:6496111157191804406",
|
|
||||||
"name": "homeServer"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "4:6583709765305423919",
|
|
||||||
"name": "accessToken"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "5:865976960498370870",
|
|
||||||
"name": "refreshToken"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "6:5675340775405504775",
|
|
||||||
"name": "deviceId"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relations": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "7:6920598293865885979",
|
|
||||||
"lastPropertyId": "3:5795529890406591571",
|
|
||||||
"name": "ObjectBoxSessionParams",
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"id": "1:7073183456619398402",
|
|
||||||
"name": "credentialsJson"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "2:8905537494398356078",
|
|
||||||
"name": "homeServerConnectionConfigJson"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "3:5795529890406591571",
|
|
||||||
"name": "id"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relations": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "8:1761107158737061066",
|
|
||||||
"lastPropertyId": "3:787896491046945850",
|
|
||||||
"name": "RoomEntity",
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"id": "1:7021996505563941556",
|
|
||||||
"name": "id"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "2:1269026517652311997",
|
|
||||||
"name": "membership"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "3:787896491046945850",
|
|
||||||
"name": "roomId"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relations": [
|
|
||||||
{
|
|
||||||
"id": "1:5345919940124619772",
|
|
||||||
"name": "chunks"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "9:6019404356061358330",
|
|
||||||
"lastPropertyId": "3:3869954049926012588",
|
|
||||||
"name": "ChunkEntity",
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"id": "1:3461196015528391821",
|
|
||||||
"name": "id"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "2:4852790652764050720",
|
|
||||||
"name": "prevToken"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "3:3869954049926012588",
|
|
||||||
"name": "nextToken"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relations": [
|
|
||||||
{
|
|
||||||
"id": "2:5944867505344991328",
|
|
||||||
"name": "events"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "10:7579750767964019860",
|
|
||||||
"lastPropertyId": "6:6069780711726222192",
|
|
||||||
"name": "EventEntity",
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"id": "1:3170318841756889053",
|
|
||||||
"name": "id"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "2:6651269605038929561",
|
|
||||||
"name": "type"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "3:470436998712759552",
|
|
||||||
"name": "content"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "4:1820638541606769650",
|
|
||||||
"name": "eventId"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "5:4423270757987421556",
|
|
||||||
"name": "prevContent"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "6:6069780711726222192",
|
|
||||||
"name": "stateKey"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relations": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastEntityId": "10:7579750767964019860",
|
|
||||||
"lastIndexId": "4:1616715309690181473",
|
|
||||||
"lastRelationId": "2:5944867505344991328",
|
|
||||||
"lastSequenceId": "0:0",
|
|
||||||
"modelVersion": 4,
|
|
||||||
"modelVersionParserMinimum": 4,
|
|
||||||
"retiredEntityUids": [
|
|
||||||
637433444018824383,
|
|
||||||
5577202525246066978,
|
|
||||||
213989653016909134,
|
|
||||||
826321009570992494,
|
|
||||||
1775102368193732759
|
|
||||||
],
|
|
||||||
"retiredIndexUids": [
|
|
||||||
7573100044105293219,
|
|
||||||
7664899561635023422,
|
|
||||||
762622607983996029,
|
|
||||||
1616715309690181473
|
|
||||||
],
|
|
||||||
"retiredPropertyUids": [
|
|
||||||
6211403495341530846,
|
|
||||||
1774175862476960436,
|
|
||||||
5757014528669120452,
|
|
||||||
6085081322264805865,
|
|
||||||
5476767963007280768,
|
|
||||||
2515822585258942903,
|
|
||||||
1374359365665650669,
|
|
||||||
2615322165288227076,
|
|
||||||
8258973118557394726,
|
|
||||||
4167129800901721265,
|
|
||||||
4654729568692986907,
|
|
||||||
958528673818813300,
|
|
||||||
3516672544602138732,
|
|
||||||
8457998089049891725,
|
|
||||||
878535388660167894,
|
|
||||||
7030303501035684102,
|
|
||||||
7193051897929077560,
|
|
||||||
8192129106205548340,
|
|
||||||
7632656533038841948,
|
|
||||||
1390065349267803135,
|
|
||||||
6024884732066241356,
|
|
||||||
3502558420506448922,
|
|
||||||
3999645739247298623,
|
|
||||||
8488502568193639300,
|
|
||||||
594512591943458255,
|
|
||||||
5113574037182501000,
|
|
||||||
4929796643260285955,
|
|
||||||
5690571528511905880,
|
|
||||||
1811444397594387116,
|
|
||||||
8817556524159529201
|
|
||||||
],
|
|
||||||
"retiredRelationUids": [],
|
|
||||||
"version": 1
|
|
||||||
}
|
|
|
@ -1,112 +0,0 @@
|
||||||
{
|
|
||||||
"_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.",
|
|
||||||
"_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.",
|
|
||||||
"_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",
|
|
||||||
"entities": [
|
|
||||||
{
|
|
||||||
"id": "6:5991986256653472999",
|
|
||||||
"lastPropertyId": "6:5675340775405504775",
|
|
||||||
"name": "Credentials",
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"id": "1:904844404428661340",
|
|
||||||
"name": "id"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "2:4962733318674873893",
|
|
||||||
"name": "userId"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "3:6496111157191804406",
|
|
||||||
"name": "homeServer"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "4:6583709765305423919",
|
|
||||||
"name": "accessToken"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "5:865976960498370870",
|
|
||||||
"name": "refreshToken"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "6:5675340775405504775",
|
|
||||||
"name": "deviceId"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relations": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "7:6920598293865885979",
|
|
||||||
"lastPropertyId": "3:5795529890406591571",
|
|
||||||
"name": "ObjectBoxSessionParams",
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"id": "1:7073183456619398402",
|
|
||||||
"name": "credentialsJson"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "2:8905537494398356078",
|
|
||||||
"name": "homeServerConnectionConfigJson"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "3:5795529890406591571",
|
|
||||||
"name": "id"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relations": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastEntityId": "7:6920598293865885979",
|
|
||||||
"lastIndexId": "4:1616715309690181473",
|
|
||||||
"lastRelationId": "0:0",
|
|
||||||
"lastSequenceId": "0:0",
|
|
||||||
"modelVersion": 4,
|
|
||||||
"modelVersionParserMinimum": 4,
|
|
||||||
"retiredEntityUids": [
|
|
||||||
637433444018824383,
|
|
||||||
5577202525246066978,
|
|
||||||
213989653016909134,
|
|
||||||
826321009570992494,
|
|
||||||
1775102368193732759
|
|
||||||
],
|
|
||||||
"retiredIndexUids": [
|
|
||||||
7573100044105293219,
|
|
||||||
7664899561635023422,
|
|
||||||
762622607983996029,
|
|
||||||
1616715309690181473
|
|
||||||
],
|
|
||||||
"retiredPropertyUids": [
|
|
||||||
6211403495341530846,
|
|
||||||
1774175862476960436,
|
|
||||||
5757014528669120452,
|
|
||||||
6085081322264805865,
|
|
||||||
5476767963007280768,
|
|
||||||
2515822585258942903,
|
|
||||||
1374359365665650669,
|
|
||||||
2615322165288227076,
|
|
||||||
8258973118557394726,
|
|
||||||
4167129800901721265,
|
|
||||||
4654729568692986907,
|
|
||||||
958528673818813300,
|
|
||||||
3516672544602138732,
|
|
||||||
8457998089049891725,
|
|
||||||
878535388660167894,
|
|
||||||
7030303501035684102,
|
|
||||||
7193051897929077560,
|
|
||||||
8192129106205548340,
|
|
||||||
7632656533038841948,
|
|
||||||
1390065349267803135,
|
|
||||||
6024884732066241356,
|
|
||||||
3502558420506448922,
|
|
||||||
3999645739247298623,
|
|
||||||
8488502568193639300,
|
|
||||||
594512591943458255,
|
|
||||||
5113574037182501000,
|
|
||||||
4929796643260285955,
|
|
||||||
5690571528511905880,
|
|
||||||
1811444397594387116,
|
|
||||||
8817556524159529201
|
|
||||||
],
|
|
||||||
"retiredRelationUids": [],
|
|
||||||
"version": 1
|
|
||||||
}
|
|
|
@ -7,6 +7,7 @@ import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.internal.auth.AuthModule
|
import im.vector.matrix.android.internal.auth.AuthModule
|
||||||
import im.vector.matrix.android.internal.di.MatrixModule
|
import im.vector.matrix.android.internal.di.MatrixModule
|
||||||
import im.vector.matrix.android.internal.di.NetworkModule
|
import im.vector.matrix.android.internal.di.NetworkModule
|
||||||
|
import io.realm.Realm
|
||||||
import org.koin.standalone.KoinComponent
|
import org.koin.standalone.KoinComponent
|
||||||
import org.koin.standalone.StandAloneContext.loadKoinModules
|
import org.koin.standalone.StandAloneContext.loadKoinModules
|
||||||
import org.koin.standalone.inject
|
import org.koin.standalone.inject
|
||||||
|
@ -21,9 +22,10 @@ class Matrix(matrixOptions: MatrixOptions) : KoinComponent {
|
||||||
var currentSession: Session? = null
|
var currentSession: Session? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
Realm.init(matrixOptions.context)
|
||||||
val matrixModule = MatrixModule(matrixOptions)
|
val matrixModule = MatrixModule(matrixOptions)
|
||||||
val networkModule = NetworkModule()
|
val networkModule = NetworkModule()
|
||||||
val authModule = AuthModule(matrixOptions.context)
|
val authModule = AuthModule()
|
||||||
loadKoinModules(listOf(matrixModule, networkModule, authModule))
|
loadKoinModules(listOf(matrixModule, networkModule, authModule))
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
Timber.plant(DebugTree())
|
Timber.plant(DebugTree())
|
||||||
|
|
|
@ -9,7 +9,7 @@ import im.vector.matrix.android.internal.legacy.util.JsonUtils
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class Event(
|
data class Event(
|
||||||
@Json(name = "type") val type: String,
|
@Json(name = "type") val type: String,
|
||||||
@Json(name = "event_id") val eventId: String? = null,
|
@Json(name = "event_id") val eventId: String?,
|
||||||
@Json(name = "content") val content: Map<String, Any>? = null,
|
@Json(name = "content") val content: Map<String, Any>? = null,
|
||||||
@Json(name = "prev_content") val prevContent: Map<String, Any>? = null,
|
@Json(name = "prev_content") val prevContent: Map<String, Any>? = null,
|
||||||
@Json(name = "origin_server_ts") val originServerTs: Long? = null,
|
@Json(name = "origin_server_ts") val originServerTs: Long? = null,
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
package im.vector.matrix.android.api.events
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
package im.vector.matrix.android.api.session
|
package im.vector.matrix.android.api.session
|
||||||
|
|
||||||
|
import im.vector.matrix.android.internal.database.RealmInstanceHolder
|
||||||
import im.vector.matrix.android.internal.events.sync.Synchronizer
|
import im.vector.matrix.android.internal.events.sync.Synchronizer
|
||||||
|
|
||||||
interface Session {
|
interface Session {
|
||||||
|
|
||||||
fun synchronizer(): Synchronizer
|
fun synchronizer(): Synchronizer
|
||||||
|
|
||||||
|
// Visible for testing request directly. Will be deleted
|
||||||
|
fun realmInstanceHolder(): RealmInstanceHolder
|
||||||
|
|
||||||
fun close()
|
fun close()
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,19 +1,14 @@
|
||||||
package im.vector.matrix.android.internal.auth
|
package im.vector.matrix.android.internal.auth
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import im.vector.matrix.android.api.auth.Authenticator
|
import im.vector.matrix.android.api.auth.Authenticator
|
||||||
import im.vector.matrix.android.internal.auth.db.ObjectBoxSessionParams
|
import im.vector.matrix.android.internal.auth.db.RealmSessionParamsStore
|
||||||
import im.vector.matrix.android.internal.auth.db.ObjectBoxSessionParamsMapper
|
import im.vector.matrix.android.internal.auth.db.SessionParamsMapper
|
||||||
import im.vector.matrix.android.internal.auth.db.ObjectBoxSessionParamsStore
|
import io.realm.RealmConfiguration
|
||||||
import io.objectbox.Box
|
|
||||||
import io.objectbox.BoxStore
|
|
||||||
import org.koin.dsl.context.ModuleDefinition
|
import org.koin.dsl.context.ModuleDefinition
|
||||||
import org.koin.dsl.module.Module
|
import org.koin.dsl.module.Module
|
||||||
import org.koin.dsl.module.module
|
import org.koin.dsl.module.module
|
||||||
|
|
||||||
private const val AUTH_BOX_STORE = "AUTH_BOX_STORE"
|
class AuthModule : Module {
|
||||||
|
|
||||||
class AuthModule(private val context: Context) : Module {
|
|
||||||
|
|
||||||
override fun invoke(): ModuleDefinition = module {
|
override fun invoke(): ModuleDefinition = module {
|
||||||
|
|
||||||
|
@ -21,18 +16,10 @@ class AuthModule(private val context: Context) : Module {
|
||||||
DefaultAuthenticator(get(), get(), get()) as Authenticator
|
DefaultAuthenticator(get(), get(), get()) as Authenticator
|
||||||
}
|
}
|
||||||
|
|
||||||
single(name = AUTH_BOX_STORE) {
|
|
||||||
MyObjectBox.builder().androidContext(context).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
single {
|
single {
|
||||||
val boxStore = get(name = AUTH_BOX_STORE) as BoxStore
|
val mapper = SessionParamsMapper((get()))
|
||||||
boxStore.boxFor(ObjectBoxSessionParams::class.java) as Box<ObjectBoxSessionParams>
|
val realmConfiguration = RealmConfiguration.Builder().name("matrix-sdk-auth").deleteRealmIfMigrationNeeded().build()
|
||||||
}
|
RealmSessionParamsStore(mapper, realmConfiguration) as SessionParamsStore
|
||||||
|
|
||||||
single {
|
|
||||||
ObjectBoxSessionParamsStore(ObjectBoxSessionParamsMapper((get())), get()) as SessionParamsStore
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}.invoke()
|
}.invoke()
|
||||||
|
|
|
@ -2,13 +2,9 @@ package im.vector.matrix.android.internal.auth.data
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import io.objectbox.annotation.Entity
|
|
||||||
import io.objectbox.annotation.Id
|
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
@Entity
|
|
||||||
data class Credentials(
|
data class Credentials(
|
||||||
@Id var id: Long = 0,
|
|
||||||
@Json(name = "user_id") val userId: String,
|
@Json(name = "user_id") val userId: String,
|
||||||
@Json(name = "home_server") val homeServer: String,
|
@Json(name = "home_server") val homeServer: String,
|
||||||
@Json(name = "access_token") val accessToken: String,
|
@Json(name = "access_token") val accessToken: String,
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
package im.vector.matrix.android.internal.auth.db
|
|
||||||
|
|
||||||
import io.objectbox.annotation.Entity
|
|
||||||
import io.objectbox.annotation.Id
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
data class ObjectBoxSessionParams(
|
|
||||||
val credentialsJson: String,
|
|
||||||
val homeServerConnectionConfigJson: String,
|
|
||||||
@Id var id: Long = 0
|
|
||||||
)
|
|
|
@ -1,21 +0,0 @@
|
||||||
package im.vector.matrix.android.internal.auth.db
|
|
||||||
|
|
||||||
import im.vector.matrix.android.internal.auth.SessionParamsStore
|
|
||||||
import im.vector.matrix.android.internal.auth.data.SessionParams
|
|
||||||
import io.objectbox.Box
|
|
||||||
|
|
||||||
class ObjectBoxSessionParamsStore(private val mapper: ObjectBoxSessionParamsMapper,
|
|
||||||
private val box: Box<ObjectBoxSessionParams>) : SessionParamsStore {
|
|
||||||
|
|
||||||
override fun save(sessionParams: SessionParams) {
|
|
||||||
val objectBoxSessionParams = mapper.map(sessionParams)
|
|
||||||
objectBoxSessionParams?.let {
|
|
||||||
box.put(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun get(): SessionParams? {
|
|
||||||
return box.all.map { mapper.map(it) }.lastOrNull()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package im.vector.matrix.android.internal.auth.db
|
||||||
|
|
||||||
|
import im.vector.matrix.android.internal.auth.SessionParamsStore
|
||||||
|
import im.vector.matrix.android.internal.auth.data.SessionParams
|
||||||
|
import io.realm.Realm
|
||||||
|
import io.realm.RealmConfiguration
|
||||||
|
|
||||||
|
class RealmSessionParamsStore(private val mapper: SessionParamsMapper,
|
||||||
|
private val realmConfiguration: RealmConfiguration) : SessionParamsStore {
|
||||||
|
|
||||||
|
override fun save(sessionParams: SessionParams) {
|
||||||
|
val entity = mapper.map(sessionParams)
|
||||||
|
if (entity != null) {
|
||||||
|
val realm = Realm.getInstance(realmConfiguration)
|
||||||
|
realm.executeTransaction {
|
||||||
|
it.insert(entity)
|
||||||
|
}
|
||||||
|
realm.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun get(): SessionParams? {
|
||||||
|
val realm = Realm.getInstance(realmConfiguration)
|
||||||
|
val sessionParams = realm
|
||||||
|
.where(SessionParamsEntity::class.java)
|
||||||
|
.findAll()
|
||||||
|
.map { mapper.map(it) }
|
||||||
|
.lastOrNull()
|
||||||
|
realm.close()
|
||||||
|
return sessionParams
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package im.vector.matrix.android.internal.auth.db
|
||||||
|
|
||||||
|
import io.realm.RealmObject
|
||||||
|
|
||||||
|
open class SessionParamsEntity(
|
||||||
|
var credentialsJson: String = "",
|
||||||
|
var homeServerConnectionConfigJson: String = ""
|
||||||
|
) : RealmObject()
|
|
@ -5,24 +5,24 @@ import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
||||||
import im.vector.matrix.android.internal.auth.data.Credentials
|
import im.vector.matrix.android.internal.auth.data.Credentials
|
||||||
import im.vector.matrix.android.internal.auth.data.SessionParams
|
import im.vector.matrix.android.internal.auth.data.SessionParams
|
||||||
|
|
||||||
class ObjectBoxSessionParamsMapper(moshi: Moshi) {
|
class SessionParamsMapper(moshi: Moshi) {
|
||||||
|
|
||||||
private val credentialsAdapter = moshi.adapter(Credentials::class.java)
|
private val credentialsAdapter = moshi.adapter(Credentials::class.java)
|
||||||
private val homeServerConnectionConfigAdapter = moshi.adapter(HomeServerConnectionConfig::class.java)
|
private val homeServerConnectionConfigAdapter = moshi.adapter(HomeServerConnectionConfig::class.java)
|
||||||
|
|
||||||
fun map(objectBoxSessionParams: ObjectBoxSessionParams?): SessionParams? {
|
fun map(entity: SessionParamsEntity?): SessionParams? {
|
||||||
if (objectBoxSessionParams == null) {
|
if (entity == null) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
val credentials = credentialsAdapter.fromJson(objectBoxSessionParams.credentialsJson)
|
val credentials = credentialsAdapter.fromJson(entity.credentialsJson)
|
||||||
val homeServerConnectionConfig = homeServerConnectionConfigAdapter.fromJson(objectBoxSessionParams.homeServerConnectionConfigJson)
|
val homeServerConnectionConfig = homeServerConnectionConfigAdapter.fromJson(entity.homeServerConnectionConfigJson)
|
||||||
if (credentials == null || homeServerConnectionConfig == null) {
|
if (credentials == null || homeServerConnectionConfig == null) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return SessionParams(credentials, homeServerConnectionConfig)
|
return SessionParams(credentials, homeServerConnectionConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun map(sessionParams: SessionParams?): ObjectBoxSessionParams? {
|
fun map(sessionParams: SessionParams?): SessionParamsEntity? {
|
||||||
if (sessionParams == null) {
|
if (sessionParams == null) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class ObjectBoxSessionParamsMapper(moshi: Moshi) {
|
||||||
if (credentialsJson == null || homeServerConnectionConfigJson == null) {
|
if (credentialsJson == null || homeServerConnectionConfigJson == null) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return ObjectBoxSessionParams(credentialsJson, homeServerConnectionConfigJson)
|
return SessionParamsEntity(credentialsJson, homeServerConnectionConfigJson)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package im.vector.matrix.android.internal.database
|
||||||
|
|
||||||
|
import io.realm.Realm
|
||||||
|
import io.realm.RealmConfiguration
|
||||||
|
|
||||||
|
class RealmInstanceHolder(realmConfiguration: RealmConfiguration) {
|
||||||
|
|
||||||
|
val realm = Realm.getInstance(realmConfiguration)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ object EventMapper {
|
||||||
|
|
||||||
fun map(event: Event): EventEntity {
|
fun map(event: Event): EventEntity {
|
||||||
val eventEntity = EventEntity()
|
val eventEntity = EventEntity()
|
||||||
eventEntity.eventId = event.eventId
|
eventEntity.eventId = event.eventId!!
|
||||||
eventEntity.content = adapter.toJson(event.content)
|
eventEntity.content = adapter.toJson(event.content)
|
||||||
eventEntity.prevContent = adapter.toJson(event.prevContent)
|
eventEntity.prevContent = adapter.toJson(event.prevContent)
|
||||||
eventEntity.stateKey = event.stateKey
|
eventEntity.stateKey = event.stateKey
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
package im.vector.matrix.android.internal.database.model
|
package im.vector.matrix.android.internal.database.model
|
||||||
|
|
||||||
import io.objectbox.annotation.Entity
|
import io.realm.RealmList
|
||||||
import io.objectbox.annotation.Id
|
import io.realm.RealmObject
|
||||||
import io.objectbox.relation.ToMany
|
import io.realm.RealmResults
|
||||||
|
import io.realm.annotations.LinkingObjects
|
||||||
|
|
||||||
@Entity
|
open class ChunkEntity(var prevToken: String? = null,
|
||||||
class ChunkEntity {
|
var nextToken: String? = null,
|
||||||
@Id var id: Long = 0
|
var isLimited: Boolean = true,
|
||||||
var prevToken: String? = null
|
var events: RealmList<EventEntity> = RealmList()
|
||||||
var nextToken: String? = null
|
) : RealmObject() {
|
||||||
lateinit var events: ToMany<EventEntity>
|
|
||||||
|
@LinkingObjects("chunks")
|
||||||
|
val room: RealmResults<RoomEntity>? = null
|
||||||
|
|
||||||
|
companion object
|
||||||
}
|
}
|
|
@ -1,14 +1,18 @@
|
||||||
package im.vector.matrix.android.internal.database.model
|
package im.vector.matrix.android.internal.database.model
|
||||||
|
|
||||||
import io.objectbox.annotation.Entity
|
import io.realm.RealmObject
|
||||||
import io.objectbox.annotation.Id
|
import io.realm.RealmResults
|
||||||
|
import io.realm.annotations.LinkingObjects
|
||||||
|
import io.realm.annotations.PrimaryKey
|
||||||
|
|
||||||
@Entity
|
open class EventEntity(@PrimaryKey var eventId: String = "",
|
||||||
class EventEntity {
|
var type: String = "",
|
||||||
@Id var id: Long = 0
|
var content: String = "",
|
||||||
lateinit var type: String
|
var prevContent: String? = null,
|
||||||
lateinit var content: String
|
|
||||||
var eventId: String? = null
|
|
||||||
var prevContent: String? = null
|
|
||||||
var stateKey: String? = null
|
var stateKey: String? = null
|
||||||
|
) : RealmObject() {
|
||||||
|
|
||||||
|
@LinkingObjects("events")
|
||||||
|
val chunk: RealmResults<ChunkEntity>? = null
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,18 +1,20 @@
|
||||||
package im.vector.matrix.android.internal.database.model
|
package im.vector.matrix.android.internal.database.model
|
||||||
|
|
||||||
import io.objectbox.annotation.Convert
|
import io.realm.RealmList
|
||||||
import io.objectbox.annotation.Entity
|
import io.realm.RealmObject
|
||||||
import io.objectbox.annotation.Id
|
import io.realm.annotations.Ignore
|
||||||
import io.objectbox.converter.PropertyConverter
|
import io.realm.annotations.PrimaryKey
|
||||||
import io.objectbox.relation.ToMany
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
@Entity
|
open class RoomEntity : RealmObject() {
|
||||||
class RoomEntity {
|
|
||||||
@Id var id: Long = 0
|
@PrimaryKey var roomId: String = ""
|
||||||
@Convert(converter = MembershipConverter::class, dbType = String::class)
|
var chunks: RealmList<ChunkEntity> = RealmList()
|
||||||
var membership: Membership = Membership.NONE
|
private var membershipStr: String = Membership.NONE.name
|
||||||
lateinit var roomId: String
|
|
||||||
lateinit var chunks: ToMany<ChunkEntity>
|
@delegate:Ignore var membership: Membership by Delegates.observable(Membership.valueOf(membershipStr)) { _, _, newValue ->
|
||||||
|
membershipStr = newValue.name
|
||||||
|
}
|
||||||
|
|
||||||
companion object;
|
companion object;
|
||||||
|
|
||||||
|
@ -24,14 +26,3 @@ class RoomEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MembershipConverter : PropertyConverter<RoomEntity.Membership, String> {
|
|
||||||
|
|
||||||
override fun convertToDatabaseValue(entityProperty: RoomEntity.Membership?): String? {
|
|
||||||
return entityProperty?.name
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun convertToEntityProperty(databaseValue: String?): RoomEntity.Membership? {
|
|
||||||
return databaseValue?.let { RoomEntity.Membership.valueOf(databaseValue) }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package im.vector.matrix.android.internal.database.model
|
||||||
|
|
||||||
|
import io.realm.RealmObject
|
||||||
|
import io.realm.annotations.PrimaryKey
|
||||||
|
|
||||||
|
open class SyncEntity(var nextBatch: String? = null,
|
||||||
|
@PrimaryKey var id: Long = 0
|
||||||
|
) : RealmObject()
|
|
@ -1,21 +1,18 @@
|
||||||
package im.vector.matrix.android.internal.database.query
|
package im.vector.matrix.android.internal.database.query
|
||||||
|
|
||||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||||
import im.vector.matrix.android.internal.database.model.RoomEntity_
|
import io.realm.Realm
|
||||||
import io.objectbox.Box
|
|
||||||
|
|
||||||
fun RoomEntity.Companion.getForId(roomBox: Box<RoomEntity>, roomId: String): RoomEntity? {
|
fun RoomEntity.Companion.getForId(realm: Realm, roomId: String): RoomEntity? {
|
||||||
return roomBox
|
return realm.where<RoomEntity>(RoomEntity::class.java)
|
||||||
.query()
|
.equalTo("roomId", roomId)
|
||||||
.equal(RoomEntity_.roomId, roomId)
|
.findFirst()
|
||||||
.build()
|
|
||||||
.findUnique()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun RoomEntity.Companion.getAll(roomBox: Box<RoomEntity>, membership: RoomEntity.Membership? = null): List<RoomEntity> {
|
fun RoomEntity.Companion.getAll(realm: Realm, membership: RoomEntity.Membership? = null): List<RoomEntity> {
|
||||||
val query = roomBox.query()
|
val query = realm.where(RoomEntity::class.java)
|
||||||
if (membership != null) {
|
if (membership != null) {
|
||||||
query.filter { it.membership == membership }
|
query.equalTo("membership", membership.name)
|
||||||
}
|
}
|
||||||
return query.build().find()
|
return query.findAll()
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@ package im.vector.matrix.android.internal.di
|
||||||
import im.vector.matrix.android.api.MatrixOptions
|
import im.vector.matrix.android.api.MatrixOptions
|
||||||
import im.vector.matrix.android.api.thread.MainThreadExecutor
|
import im.vector.matrix.android.api.thread.MainThreadExecutor
|
||||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||||
|
import io.realm.Realm
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.IO
|
import kotlinx.coroutines.IO
|
||||||
import kotlinx.coroutines.asCoroutineDispatcher
|
import kotlinx.coroutines.asCoroutineDispatcher
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package im.vector.matrix.android.internal.di
|
package im.vector.matrix.android.internal.di
|
||||||
|
|
||||||
import im.vector.matrix.android.internal.auth.data.SessionParams
|
import im.vector.matrix.android.internal.auth.data.SessionParams
|
||||||
|
import im.vector.matrix.android.internal.database.RealmInstanceHolder
|
||||||
import im.vector.matrix.android.internal.legacy.MXDataHandler
|
import im.vector.matrix.android.internal.legacy.MXDataHandler
|
||||||
import im.vector.matrix.android.internal.legacy.MXSession
|
import im.vector.matrix.android.internal.legacy.MXSession
|
||||||
import im.vector.matrix.android.internal.legacy.data.store.MXFileStore
|
import im.vector.matrix.android.internal.legacy.data.store.MXFileStore
|
||||||
import im.vector.matrix.android.internal.session.DefaultSession
|
import im.vector.matrix.android.internal.session.DefaultSession
|
||||||
|
import io.realm.RealmConfiguration
|
||||||
import org.koin.dsl.context.ModuleDefinition
|
import org.koin.dsl.context.ModuleDefinition
|
||||||
import org.koin.dsl.module.Module
|
import org.koin.dsl.module.Module
|
||||||
import org.koin.dsl.module.module
|
import org.koin.dsl.module.module
|
||||||
|
@ -14,6 +16,14 @@ class SessionModule(private val sessionParams: SessionParams) : Module {
|
||||||
|
|
||||||
override fun invoke(): ModuleDefinition = module(override = true) {
|
override fun invoke(): ModuleDefinition = module(override = true) {
|
||||||
|
|
||||||
|
scope(DefaultSession.SCOPE) {
|
||||||
|
RealmConfiguration.Builder().name(sessionParams.credentials.userId).deleteRealmIfMigrationNeeded().build()
|
||||||
|
}
|
||||||
|
|
||||||
|
scope(DefaultSession.SCOPE) {
|
||||||
|
RealmInstanceHolder(get())
|
||||||
|
}
|
||||||
|
|
||||||
scope(DefaultSession.SCOPE) {
|
scope(DefaultSession.SCOPE) {
|
||||||
val retrofitBuilder = get() as Retrofit.Builder
|
val retrofitBuilder = get() as Retrofit.Builder
|
||||||
retrofitBuilder
|
retrofitBuilder
|
||||||
|
|
|
@ -3,64 +3,114 @@ package im.vector.matrix.android.internal.events.sync
|
||||||
import im.vector.matrix.android.api.events.Event
|
import im.vector.matrix.android.api.events.Event
|
||||||
import im.vector.matrix.android.internal.database.mapper.EventMapper
|
import im.vector.matrix.android.internal.database.mapper.EventMapper
|
||||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
|
||||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||||
import im.vector.matrix.android.internal.database.query.getForId
|
import im.vector.matrix.android.internal.database.query.getForId
|
||||||
|
import im.vector.matrix.android.internal.events.sync.data.InvitedRoomSync
|
||||||
import im.vector.matrix.android.internal.events.sync.data.RoomSync
|
import im.vector.matrix.android.internal.events.sync.data.RoomSync
|
||||||
import io.objectbox.Box
|
import io.realm.Realm
|
||||||
import io.objectbox.BoxStore
|
import io.realm.RealmConfiguration
|
||||||
|
|
||||||
|
|
||||||
class RoomSyncHandler(
|
class RoomSyncHandler(private val realmConfiguration: RealmConfiguration) {
|
||||||
boxStore: BoxStore
|
|
||||||
) {
|
|
||||||
|
|
||||||
private val eventBox: Box<EventEntity> = boxStore.boxFor(EventEntity::class.java)
|
sealed class HandlingStrategy {
|
||||||
private val chunkBox: Box<ChunkEntity> = boxStore.boxFor(ChunkEntity::class.java)
|
data class JOINED(val data: Map<String, RoomSync>) : HandlingStrategy()
|
||||||
private val roomBox: Box<RoomEntity> = boxStore.boxFor(RoomEntity::class.java)
|
data class INVITED(val data: Map<String, InvitedRoomSync>) : HandlingStrategy()
|
||||||
|
data class LEFT(val data: Map<String, RoomSync>) : HandlingStrategy()
|
||||||
fun handleJoinedRooms(roomSyncByRoom: Map<String, RoomSync>?) {
|
|
||||||
if (roomSyncByRoom == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val roomEntities = ArrayList<RoomEntity>()
|
|
||||||
roomSyncByRoom.forEach {
|
|
||||||
val roomEntity = handleJoinedRoom(it.key, it.value)
|
|
||||||
roomEntities.add(roomEntity)
|
|
||||||
}
|
|
||||||
roomBox.put(roomEntities)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleJoinedRoom(roomId: String, roomSync: RoomSync): RoomEntity {
|
fun handleRoomSync(handlingStrategy: HandlingStrategy) {
|
||||||
val roomEntity = RoomEntity.getForId(roomBox, roomId) ?: RoomEntity().apply { this.roomId = roomId }
|
val realm = Realm.getInstance(realmConfiguration)
|
||||||
|
realm.executeTransaction { realmInstance ->
|
||||||
|
val roomEntities = when (handlingStrategy) {
|
||||||
|
is HandlingStrategy.JOINED -> handlingStrategy.data.map { handleJoinedRoom(realm, it.key, it.value) }
|
||||||
|
is HandlingStrategy.INVITED -> handlingStrategy.data.map { handleInvitedRoom(realm, it.key, it.value) }
|
||||||
|
is HandlingStrategy.LEFT -> handlingStrategy.data.map { handleLeftRoom(it.key, it.value) }
|
||||||
|
}
|
||||||
|
realmInstance.insertOrUpdate(roomEntities)
|
||||||
|
}
|
||||||
|
realm.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// PRIVATE METHODS *****************************************************************************
|
||||||
|
|
||||||
|
private fun handleJoinedRoom(realm: Realm,
|
||||||
|
roomId: String,
|
||||||
|
roomSync: RoomSync): RoomEntity {
|
||||||
|
|
||||||
|
val roomEntity = RoomEntity.getForId(realm, roomId)
|
||||||
|
?: RoomEntity().apply { this.roomId = roomId }
|
||||||
|
|
||||||
if (roomEntity.membership == RoomEntity.Membership.INVITED) {
|
if (roomEntity.membership == RoomEntity.Membership.INVITED) {
|
||||||
roomEntity.chunks
|
roomEntity.chunks.deleteAllFromRealm()
|
||||||
.map { it.events }
|
|
||||||
.forEach { eventBox.remove(it) }
|
|
||||||
chunkBox.remove(roomEntity.chunks)
|
|
||||||
}
|
|
||||||
roomEntity.membership = RoomEntity.Membership.JOINED
|
|
||||||
if (roomSync.timeline != null) {
|
|
||||||
val chunkEntity = eventListToChunk(roomSync.timeline.events, roomSync.timeline.prevBatch)
|
|
||||||
roomEntity.chunks.add(chunkEntity)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roomSync.state != null) {
|
roomEntity.membership = RoomEntity.Membership.JOINED
|
||||||
val chunkEntity = eventListToChunk(roomSync.state.events)
|
if (roomSync.state != null && roomSync.state.events.isNotEmpty()) {
|
||||||
|
val chunkEntity = eventListToChunk(realm, roomId, roomSync.state.events)
|
||||||
|
if (!roomEntity.chunks.contains(chunkEntity)) {
|
||||||
roomEntity.chunks.add(chunkEntity)
|
roomEntity.chunks.add(chunkEntity)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (roomSync.timeline != null && roomSync.timeline.events.isNotEmpty()) {
|
||||||
|
val chunkEntity = eventListToChunk(realm, roomId, roomSync.timeline.events, roomSync.timeline.prevToken, isLimited = roomSync.timeline.limited)
|
||||||
|
if (!roomEntity.chunks.contains(chunkEntity)) {
|
||||||
|
roomEntity.chunks.add(chunkEntity)
|
||||||
|
}
|
||||||
|
}
|
||||||
return roomEntity
|
return roomEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun eventListToChunk(eventList: List<Event>,
|
private fun handleInvitedRoom(realm: Realm,
|
||||||
|
roomId: String,
|
||||||
|
roomSync:
|
||||||
|
InvitedRoomSync): RoomEntity {
|
||||||
|
val roomEntity = RoomEntity()
|
||||||
|
roomEntity.roomId = roomId
|
||||||
|
roomEntity.membership = RoomEntity.Membership.INVITED
|
||||||
|
if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) {
|
||||||
|
val chunkEntity = eventListToChunk(realm, roomId, roomSync.inviteState.events)
|
||||||
|
if (!roomEntity.chunks.contains(chunkEntity)) {
|
||||||
|
roomEntity.chunks.add(chunkEntity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return roomEntity
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO : handle it
|
||||||
|
private fun handleLeftRoom(roomId: String,
|
||||||
|
roomSync: RoomSync): RoomEntity {
|
||||||
|
return RoomEntity().apply {
|
||||||
|
this.roomId = roomId
|
||||||
|
this.membership = RoomEntity.Membership.LEFT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun eventListToChunk(realm: Realm,
|
||||||
|
roomId: String,
|
||||||
|
eventList: List<Event>,
|
||||||
prevToken: String? = null,
|
prevToken: String? = null,
|
||||||
nextToken: String? = null): ChunkEntity {
|
nextToken: String? = null,
|
||||||
val chunkEntity = ChunkEntity()
|
isLimited: Boolean = true): ChunkEntity {
|
||||||
|
|
||||||
|
val chunkEntity = if (!isLimited) {
|
||||||
|
realm.where(ChunkEntity::class.java).equalTo("room.roomId", roomId).isNull("nextToken").and().isNotNull("prevToken").findAll().lastOrNull()
|
||||||
|
} else {
|
||||||
|
realm.where(ChunkEntity::class.java).`in`("events.eventId", eventList.map { it.eventId }.toTypedArray()).findFirst()
|
||||||
|
} ?: ChunkEntity()
|
||||||
|
|
||||||
chunkEntity.prevToken = prevToken
|
chunkEntity.prevToken = prevToken
|
||||||
chunkEntity.nextToken = nextToken
|
chunkEntity.nextToken = nextToken
|
||||||
eventList
|
chunkEntity.isLimited = isLimited
|
||||||
.map { event -> EventMapper.map(event) }
|
eventList.forEach { event ->
|
||||||
.forEach { chunkEntity.events.add(it) }
|
val eventEntity = EventMapper.map(event).let {
|
||||||
|
realm.copyToRealmOrUpdate(it)
|
||||||
|
}
|
||||||
|
if (!chunkEntity.events.contains(eventEntity)) {
|
||||||
|
chunkEntity.events.add(eventEntity)
|
||||||
|
}
|
||||||
|
}
|
||||||
return chunkEntity
|
return chunkEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,9 @@ class SyncResponseHandler(
|
||||||
|
|
||||||
if (syncResponse.rooms != null) {
|
if (syncResponse.rooms != null) {
|
||||||
// joined rooms events
|
// joined rooms events
|
||||||
roomSyncHandler.handleJoinedRooms(syncResponse.rooms.join)
|
roomSyncHandler.handleRoomSync(RoomSyncHandler.HandlingStrategy.JOINED(syncResponse.rooms.join))
|
||||||
|
roomSyncHandler.handleRoomSync(RoomSyncHandler.HandlingStrategy.INVITED(syncResponse.rooms.invite))
|
||||||
|
roomSyncHandler.handleRoomSync(RoomSyncHandler.HandlingStrategy.LEFT(syncResponse.rooms.leave))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package im.vector.matrix.android.internal.events.sync
|
package im.vector.matrix.android.internal.events.sync
|
||||||
|
|
||||||
|
import arrow.core.Either
|
||||||
|
import arrow.core.flatMap
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
|
import im.vector.matrix.android.api.failure.Failure
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
import im.vector.matrix.android.internal.events.sync.data.SyncResponse
|
import im.vector.matrix.android.internal.events.sync.data.SyncResponse
|
||||||
import im.vector.matrix.android.internal.legacy.rest.model.filter.FilterBody
|
import im.vector.matrix.android.internal.legacy.rest.model.filter.FilterBody
|
||||||
|
@ -16,6 +19,8 @@ class Synchronizer(private val syncAPI: SyncAPI,
|
||||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||||
private val syncResponseHandler: SyncResponseHandler) {
|
private val syncResponseHandler: SyncResponseHandler) {
|
||||||
|
|
||||||
|
private var token: String? = null
|
||||||
|
|
||||||
fun synchronize(callback: MatrixCallback<SyncResponse>): Cancelable {
|
fun synchronize(callback: MatrixCallback<SyncResponse>): Cancelable {
|
||||||
val job = GlobalScope.launch(coroutineDispatchers.main) {
|
val job = GlobalScope.launch(coroutineDispatchers.main) {
|
||||||
val syncOrFailure = synchronize()
|
val syncOrFailure = synchronize()
|
||||||
|
@ -28,13 +33,23 @@ class Synchronizer(private val syncAPI: SyncAPI,
|
||||||
val params = HashMap<String, String>()
|
val params = HashMap<String, String>()
|
||||||
val filterBody = FilterBody()
|
val filterBody = FilterBody()
|
||||||
FilterUtil.enableLazyLoading(filterBody, true)
|
FilterUtil.enableLazyLoading(filterBody, true)
|
||||||
params["timeout"] = "0"
|
var timeout = 0
|
||||||
|
if (token != null) {
|
||||||
|
params["since"] = token as String
|
||||||
|
timeout = 30
|
||||||
|
}
|
||||||
|
params["timeout"] = timeout.toString()
|
||||||
params["filter"] = filterBody.toJSONString()
|
params["filter"] = filterBody.toJSONString()
|
||||||
executeRequest<SyncResponse> {
|
executeRequest<SyncResponse> {
|
||||||
apiCall = syncAPI.sync(params)
|
apiCall = syncAPI.sync(params)
|
||||||
}.map {
|
}.flatMap {
|
||||||
|
token = it?.nextBatch
|
||||||
|
try {
|
||||||
syncResponseHandler.handleResponse(it, null, false)
|
syncResponseHandler.handleResponse(it, null, false)
|
||||||
it
|
Either.right(it)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
Either.Left(Failure.Unknown(exception))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package im.vector.matrix.android.internal.events.sync.data
|
package im.vector.matrix.android.internal.events.sync.data
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
// InvitedRoomSync represents a room invitation during server sync v2.
|
// InvitedRoomSync represents a room invitation during server sync v2.
|
||||||
|
@ -28,5 +29,5 @@ data class InvitedRoomSync(
|
||||||
* and one from the archived 'state'. If the client joins the room then the current state will be given as a delta against the
|
* and one from the archived 'state'. If the client joins the room then the current state will be given as a delta against the
|
||||||
* archived 'state' not the 'invite_state'.
|
* archived 'state' not the 'invite_state'.
|
||||||
*/
|
*/
|
||||||
val inviteState: RoomInviteState? = null
|
@Json(name = "invite_state") val inviteState: RoomInviteState? = null
|
||||||
)
|
)
|
|
@ -16,6 +16,7 @@
|
||||||
package im.vector.matrix.android.internal.events.sync.data
|
package im.vector.matrix.android.internal.events.sync.data
|
||||||
|
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import im.vector.matrix.android.api.events.Event
|
import im.vector.matrix.android.api.events.Event
|
||||||
|
|
||||||
|
@ -26,5 +27,5 @@ data class RoomInviteState(
|
||||||
/**
|
/**
|
||||||
* List of state events (array of MXEvent).
|
* List of state events (array of MXEvent).
|
||||||
*/
|
*/
|
||||||
val events: List<Event> = emptyList()
|
@Json(name = "events") val events: List<Event> = emptyList()
|
||||||
)
|
)
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package im.vector.matrix.android.internal.events.sync.data
|
package im.vector.matrix.android.internal.events.sync.data
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
// RoomSync represents the response for a room during server sync v2.
|
// RoomSync represents the response for a room during server sync v2.
|
||||||
|
@ -23,26 +24,26 @@ data class RoomSync(
|
||||||
/**
|
/**
|
||||||
* The state updates for the room.
|
* The state updates for the room.
|
||||||
*/
|
*/
|
||||||
val state: RoomSyncState? = null,
|
@Json(name = "state") val state: RoomSyncState? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The timeline of messages and state changes in the room.
|
* The timeline of messages and state changes in the room.
|
||||||
*/
|
*/
|
||||||
val timeline: RoomSyncTimeline? = null,
|
@Json(name = "timeline") val timeline: RoomSyncTimeline? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ephemeral events in the room that aren't recorded in the timeline or state of the room (e.g. typing, receipts).
|
* The ephemeral events in the room that aren't recorded in the timeline or state of the room (e.g. typing, receipts).
|
||||||
*/
|
*/
|
||||||
val ephemeral: RoomSyncEphemeral? = null,
|
@Json(name = "ephemeral") val ephemeral: RoomSyncEphemeral? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The account data events for the room (e.g. tags).
|
* The account data events for the room (e.g. tags).
|
||||||
*/
|
*/
|
||||||
val accountData: RoomSyncAccountData? = null,
|
@Json(name = "account_data") val accountData: RoomSyncAccountData? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The notification counts for the room.
|
* The notification counts for the room.
|
||||||
*/
|
*/
|
||||||
val unreadNotifications: RoomSyncUnreadNotifications? = null
|
@Json(name = "unread_notifications") val unreadNotifications: RoomSyncUnreadNotifications? = null
|
||||||
|
|
||||||
)
|
)
|
|
@ -1,5 +1,6 @@
|
||||||
package im.vector.matrix.android.internal.events.sync.data
|
package im.vector.matrix.android.internal.events.sync.data
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import im.vector.matrix.android.api.events.Event
|
import im.vector.matrix.android.api.events.Event
|
||||||
|
|
||||||
|
@ -8,5 +9,5 @@ data class RoomSyncAccountData(
|
||||||
/**
|
/**
|
||||||
* List of account data events (array of Event).
|
* List of account data events (array of Event).
|
||||||
*/
|
*/
|
||||||
val events: List<Event>? = null
|
@Json(name = "events") val events: List<Event>? = null
|
||||||
)
|
)
|
|
@ -1,6 +1,7 @@
|
||||||
package im.vector.matrix.android.internal.events.sync.data
|
package im.vector.matrix.android.internal.events.sync.data
|
||||||
|
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import im.vector.matrix.android.api.events.Event
|
import im.vector.matrix.android.api.events.Event
|
||||||
|
|
||||||
|
@ -10,5 +11,5 @@ data class RoomSyncEphemeral(
|
||||||
/**
|
/**
|
||||||
* List of ephemeral events (array of Event).
|
* List of ephemeral events (array of Event).
|
||||||
*/
|
*/
|
||||||
val events: List<Event>? = null
|
@Json(name = "events") val events: List<Event>? = null
|
||||||
)
|
)
|
|
@ -1,6 +1,7 @@
|
||||||
package im.vector.matrix.android.internal.events.sync.data
|
package im.vector.matrix.android.internal.events.sync.data
|
||||||
|
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import im.vector.matrix.android.api.events.Event
|
import im.vector.matrix.android.api.events.Event
|
||||||
|
|
||||||
|
@ -11,15 +12,15 @@ data class RoomSyncTimeline(
|
||||||
/**
|
/**
|
||||||
* List of events (array of Event).
|
* List of events (array of Event).
|
||||||
*/
|
*/
|
||||||
val events: List<Event> = emptyList(),
|
@Json(name = "events") val events: List<Event> = emptyList(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Boolean which tells whether there are more events on the server
|
* Boolean which tells whether there are more events on the server
|
||||||
*/
|
*/
|
||||||
val limited: Boolean = false,
|
@Json(name = "limited") val limited: Boolean = false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the batch was limited then this is a token that can be supplied to the server to retrieve more events
|
* If the batch was limited then this is a token that can be supplied to the server to retrieve more events
|
||||||
*/
|
*/
|
||||||
val prevBatch: String? = null
|
@Json(name = "prev_batch") val prevToken: String? = null
|
||||||
)
|
)
|
|
@ -1,6 +1,7 @@
|
||||||
package im.vector.matrix.android.internal.events.sync.data
|
package im.vector.matrix.android.internal.events.sync.data
|
||||||
|
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import im.vector.matrix.android.api.events.Event
|
import im.vector.matrix.android.api.events.Event
|
||||||
|
|
||||||
|
@ -12,14 +13,14 @@ data class RoomSyncUnreadNotifications(
|
||||||
/**
|
/**
|
||||||
* List of account data events (array of Event).
|
* List of account data events (array of Event).
|
||||||
*/
|
*/
|
||||||
val events: List<Event>? = null,
|
@Json(name = "events") val events: List<Event>? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of unread messages that match the push notification rules.
|
* The number of unread messages that match the push notification rules.
|
||||||
*/
|
*/
|
||||||
val notificationCount: Int? = null,
|
@Json(name = "notification_count") val notificationCount: Int? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of highlighted unread messages (subset of notifications).
|
* The number of highlighted unread messages (subset of notifications).
|
||||||
*/
|
*/
|
||||||
val highlightCount: Int? = null)
|
@Json(name = "highlight_count") val highlightCount: Int? = null)
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package im.vector.matrix.android.internal.events.sync.data
|
package im.vector.matrix.android.internal.events.sync.data
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
// RoomsSyncResponse represents the rooms list in server sync v2 response.
|
// RoomsSyncResponse represents the rooms list in server sync v2 response.
|
||||||
|
@ -23,15 +24,15 @@ data class RoomsSyncResponse(
|
||||||
/**
|
/**
|
||||||
* Joined rooms: keys are rooms ids.
|
* Joined rooms: keys are rooms ids.
|
||||||
*/
|
*/
|
||||||
val join: Map<String, RoomSync> = emptyMap(),
|
@Json(name = "join") val join: Map<String, RoomSync> = emptyMap(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invitations. The rooms that the user has been invited to: keys are rooms ids.
|
* Invitations. The rooms that the user has been invited to: keys are rooms ids.
|
||||||
*/
|
*/
|
||||||
val invite: Map<String, InvitedRoomSync> = emptyMap(),
|
@Json(name = "invite") val invite: Map<String, InvitedRoomSync> = emptyMap(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Left rooms. The rooms that the user has left or been banned from: keys are rooms ids.
|
* Left rooms. The rooms that the user has left or been banned from: keys are rooms ids.
|
||||||
*/
|
*/
|
||||||
val leave: Map<String, RoomSync> = emptyMap()
|
@Json(name = "leave") val leave: Map<String, RoomSync> = emptyMap()
|
||||||
)
|
)
|
|
@ -2,6 +2,7 @@ package im.vector.matrix.android.internal.session
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.internal.auth.data.SessionParams
|
import im.vector.matrix.android.internal.auth.data.SessionParams
|
||||||
|
import im.vector.matrix.android.internal.database.RealmInstanceHolder
|
||||||
import im.vector.matrix.android.internal.di.SessionModule
|
import im.vector.matrix.android.internal.di.SessionModule
|
||||||
import im.vector.matrix.android.internal.events.sync.SyncModule
|
import im.vector.matrix.android.internal.events.sync.SyncModule
|
||||||
import im.vector.matrix.android.internal.events.sync.Synchronizer
|
import im.vector.matrix.android.internal.events.sync.Synchronizer
|
||||||
|
@ -13,6 +14,7 @@ import org.koin.standalone.inject
|
||||||
|
|
||||||
class DefaultSession(sessionParams: SessionParams) : Session, KoinComponent {
|
class DefaultSession(sessionParams: SessionParams) : Session, KoinComponent {
|
||||||
|
|
||||||
|
private val realmInstanceHolder by inject<RealmInstanceHolder>()
|
||||||
private val synchronizer by inject<Synchronizer>()
|
private val synchronizer by inject<Synchronizer>()
|
||||||
private val scope: Scope
|
private val scope: Scope
|
||||||
|
|
||||||
|
@ -27,7 +29,12 @@ class DefaultSession(sessionParams: SessionParams) : Session, KoinComponent {
|
||||||
return synchronizer
|
return synchronizer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun realmInstanceHolder(): RealmInstanceHolder {
|
||||||
|
return realmInstanceHolder
|
||||||
|
}
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
|
realmInstanceHolder.realm.close()
|
||||||
scope.close()
|
scope.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue