Make sync request works as initial sync
This commit is contained in:
parent
a7eecdffae
commit
058f1704fa
Binary file not shown.
|
@ -3,6 +3,7 @@
|
||||||
<words>
|
<words>
|
||||||
<w>coroutine</w>
|
<w>coroutine</w>
|
||||||
<w>moshi</w>
|
<w>moshi</w>
|
||||||
|
<w>synchronizer</w>
|
||||||
</words>
|
</words>
|
||||||
</dictionary>
|
</dictionary>
|
||||||
</component>
|
</component>
|
|
@ -3,14 +3,45 @@ package im.vector.riotredesign.features.home
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
|
import im.vector.matrix.android.api.Matrix
|
||||||
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
|
import im.vector.matrix.android.api.failure.Failure
|
||||||
|
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 kotlinx.android.synthetic.main.activity_home.*
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
class HomeActivity : RiotActivity() {
|
class HomeActivity : RiotActivity() {
|
||||||
|
|
||||||
|
private val matrix by inject<Matrix>()
|
||||||
|
private val synchronizer = matrix.currentSession?.synchronizer()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_home)
|
setContentView(R.layout.activity_home)
|
||||||
|
synchronizeButton.setOnClickListener { synchronize() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun synchronize() {
|
||||||
|
synchronizeButton.visibility = View.GONE
|
||||||
|
loadingView.visibility = View.VISIBLE
|
||||||
|
synchronizer?.synchronize(object : MatrixCallback<SyncResponse> {
|
||||||
|
override fun onSuccess(data: SyncResponse?) {
|
||||||
|
synchronizeButton.visibility = View.VISIBLE
|
||||||
|
loadingView.visibility = View.GONE
|
||||||
|
Toast.makeText(this@HomeActivity, "Success", Toast.LENGTH_LONG).show()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(failure: Failure) {
|
||||||
|
synchronizeButton.visibility = View.VISIBLE
|
||||||
|
loadingView.visibility = View.GONE
|
||||||
|
Toast.makeText(this@HomeActivity, failure.toString(), Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@ import android.view.View
|
||||||
import android.widget.Toast
|
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.session.Session
|
||||||
import im.vector.matrix.android.api.auth.data.Credentials
|
|
||||||
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
||||||
|
import im.vector.matrix.android.api.failure.Failure
|
||||||
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 im.vector.riotredesign.features.home.HomeActivity
|
import im.vector.riotredesign.features.home.HomeActivity
|
||||||
|
@ -17,10 +17,8 @@ import org.koin.android.ext.android.inject
|
||||||
class LoginActivity : RiotActivity() {
|
class LoginActivity : RiotActivity() {
|
||||||
|
|
||||||
private val matrix by inject<Matrix>()
|
private val matrix by inject<Matrix>()
|
||||||
|
|
||||||
private val homeServerConnectionConfig = HomeServerConnectionConfig("https://matrix.org/")
|
private val homeServerConnectionConfig = HomeServerConnectionConfig("https://matrix.org/")
|
||||||
private val session = matrix.createSession(homeServerConnectionConfig)
|
private val authenticator = matrix.authenticator()
|
||||||
private val authenticator = session.authenticator()
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -32,8 +30,9 @@ class LoginActivity : RiotActivity() {
|
||||||
val login = loginField.text.trim().toString()
|
val login = loginField.text.trim().toString()
|
||||||
val password = passwordField.text.trim().toString()
|
val password = passwordField.text.trim().toString()
|
||||||
progressBar.visibility = View.VISIBLE
|
progressBar.visibility = View.VISIBLE
|
||||||
authenticator.authenticate(login, password, object : MatrixCallback<Credentials> {
|
authenticator.authenticate(homeServerConnectionConfig, login, password, object : MatrixCallback<Session> {
|
||||||
override fun onSuccess(data: Credentials?) {
|
override fun onSuccess(data: Session?) {
|
||||||
|
matrix.currentSession = data
|
||||||
goToHomeScreen()
|
goToHomeScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,20 +7,34 @@
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:context=".features.login.LoginActivity">
|
tools:context=".features.login.LoginActivity">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
<TextView
|
android:id="@+id/loadingView"
|
||||||
android:text="activity_home"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/synchronizeButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="Synchronize"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</android.support.constraint.ConstraintLayout>
|
|
@ -57,11 +57,9 @@ dependencies {
|
||||||
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
|
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
|
||||||
implementation 'com.squareup.okio:okio:1.15.0'
|
implementation 'com.squareup.okio:okio:1.15.0'
|
||||||
|
|
||||||
implementation "com.squareup.moshi:moshi-kotlin:$moshi_version"
|
|
||||||
implementation "com.squareup.moshi:moshi-adapters:$moshi_version"
|
implementation "com.squareup.moshi:moshi-adapters:$moshi_version"
|
||||||
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"
|
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"
|
||||||
|
|
||||||
|
|
||||||
// Paging
|
// Paging
|
||||||
implementation "android.arch.paging:runtime:1.0.1"
|
implementation "android.arch.paging:runtime:1.0.1"
|
||||||
|
|
||||||
|
@ -69,6 +67,10 @@ dependencies {
|
||||||
implementation "org.koin:koin-core:$koin_version"
|
implementation "org.koin:koin-core:$koin_version"
|
||||||
implementation "org.koin:koin-core-ext:$koin_version"
|
implementation "org.koin:koin-core-ext:$koin_version"
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||||
|
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||||
|
|
|
@ -4,47 +4,64 @@
|
||||||
"_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",
|
"_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",
|
||||||
"entities": [
|
"entities": [
|
||||||
{
|
{
|
||||||
"id": "1:637433444018824383",
|
"id": "3:213989653016909134",
|
||||||
"lastPropertyId": "6:2515822585258942903",
|
"lastPropertyId": "6:8192129106205548340",
|
||||||
"name": "Credentials",
|
"name": "Credentials",
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
"id": "1:6211403495341530846",
|
"id": "1:3516672544602138732",
|
||||||
"name": "id"
|
"name": "id"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "2:1774175862476960436",
|
"id": "2:8457998089049891725",
|
||||||
|
"indexId": "1:7573100044105293219",
|
||||||
"name": "userId"
|
"name": "userId"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "3:5757014528669120452",
|
"id": "3:878535388660167894",
|
||||||
"name": "homeServer"
|
"name": "homeServer"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "4:6085081322264805865",
|
"id": "4:7030303501035684102",
|
||||||
"name": "accessToken"
|
"name": "accessToken"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "5:5476767963007280768",
|
"id": "5:7193051897929077560",
|
||||||
"name": "refreshToken"
|
"name": "refreshToken"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "6:2515822585258942903",
|
"id": "6:8192129106205548340",
|
||||||
"name": "deviceId"
|
"name": "deviceId"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"lastEntityId": "1:637433444018824383",
|
"lastEntityId": "3:213989653016909134",
|
||||||
"lastIndexId": "0:0",
|
"lastIndexId": "1:7573100044105293219",
|
||||||
"lastRelationId": "0:0",
|
"lastRelationId": "0:0",
|
||||||
"lastSequenceId": "0:0",
|
"lastSequenceId": "0:0",
|
||||||
"modelVersion": 4,
|
"modelVersion": 4,
|
||||||
"modelVersionParserMinimum": 4,
|
"modelVersionParserMinimum": 4,
|
||||||
"retiredEntityUids": [],
|
"retiredEntityUids": [
|
||||||
|
637433444018824383,
|
||||||
|
5577202525246066978
|
||||||
|
],
|
||||||
"retiredIndexUids": [],
|
"retiredIndexUids": [],
|
||||||
"retiredPropertyUids": [],
|
"retiredPropertyUids": [
|
||||||
|
6211403495341530846,
|
||||||
|
1774175862476960436,
|
||||||
|
5757014528669120452,
|
||||||
|
6085081322264805865,
|
||||||
|
5476767963007280768,
|
||||||
|
2515822585258942903,
|
||||||
|
1374359365665650669,
|
||||||
|
2615322165288227076,
|
||||||
|
8258973118557394726,
|
||||||
|
4167129800901721265,
|
||||||
|
4654729568692986907,
|
||||||
|
958528673818813300
|
||||||
|
],
|
||||||
"retiredRelationUids": [],
|
"retiredRelationUids": [],
|
||||||
"version": 1
|
"version": 1
|
||||||
}
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
{
|
||||||
|
"_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": "3:213989653016909134",
|
||||||
|
"lastPropertyId": "6:8192129106205548340",
|
||||||
|
"name": "Credentials",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"id": "1:3516672544602138732",
|
||||||
|
"name": "id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2:8457998089049891725",
|
||||||
|
"name": "userId"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3:878535388660167894",
|
||||||
|
"name": "homeServer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4:7030303501035684102",
|
||||||
|
"name": "accessToken"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5:7193051897929077560",
|
||||||
|
"name": "refreshToken"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6:8192129106205548340",
|
||||||
|
"name": "deviceId"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"relations": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastEntityId": "3:213989653016909134",
|
||||||
|
"lastIndexId": "0:0",
|
||||||
|
"lastRelationId": "0:0",
|
||||||
|
"lastSequenceId": "0:0",
|
||||||
|
"modelVersion": 4,
|
||||||
|
"modelVersionParserMinimum": 4,
|
||||||
|
"retiredEntityUids": [
|
||||||
|
637433444018824383,
|
||||||
|
5577202525246066978
|
||||||
|
],
|
||||||
|
"retiredIndexUids": [],
|
||||||
|
"retiredPropertyUids": [
|
||||||
|
6211403495341530846,
|
||||||
|
1774175862476960436,
|
||||||
|
5757014528669120452,
|
||||||
|
6085081322264805865,
|
||||||
|
5476767963007280768,
|
||||||
|
2515822585258942903,
|
||||||
|
1374359365665650669,
|
||||||
|
2615322165288227076,
|
||||||
|
8258973118557394726,
|
||||||
|
4167129800901721265,
|
||||||
|
4654729568692986907,
|
||||||
|
958528673818813300
|
||||||
|
],
|
||||||
|
"retiredRelationUids": [],
|
||||||
|
"version": 1
|
||||||
|
}
|
|
@ -1,21 +1,42 @@
|
||||||
package im.vector.matrix.android.api
|
package im.vector.matrix.android.api
|
||||||
|
|
||||||
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
import android.content.Context
|
||||||
import im.vector.matrix.android.internal.DefaultSession
|
import im.vector.matrix.android.BuildConfig
|
||||||
|
import im.vector.matrix.android.api.auth.Authenticator
|
||||||
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
import im.vector.matrix.android.api.thread.MainThreadExecutor
|
||||||
|
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 org.koin.standalone.KoinComponent
|
||||||
import org.koin.standalone.StandAloneContext.loadKoinModules
|
import org.koin.standalone.StandAloneContext.loadKoinModules
|
||||||
|
import org.koin.standalone.inject
|
||||||
|
import timber.log.Timber
|
||||||
|
import timber.log.Timber.DebugTree
|
||||||
|
import java.util.concurrent.Executor
|
||||||
|
|
||||||
class Matrix(matrixOptions: MatrixOptions) {
|
|
||||||
|
class Matrix(matrixOptions: MatrixOptions) : KoinComponent {
|
||||||
|
|
||||||
|
private val authenticator by inject<Authenticator>()
|
||||||
|
|
||||||
|
var currentSession: Session? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val matrixModule = MatrixModule(matrixOptions)
|
val matrixModule = MatrixModule(matrixOptions)
|
||||||
val networkModule = NetworkModule()
|
val networkModule = NetworkModule()
|
||||||
loadKoinModules(listOf(matrixModule, networkModule))
|
val authModule = AuthModule(matrixOptions.context)
|
||||||
|
loadKoinModules(listOf(matrixModule, networkModule, authModule))
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
Timber.plant(DebugTree())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createSession(homeServerConnectionConfig: HomeServerConnectionConfig): Session {
|
fun authenticator(): Authenticator {
|
||||||
return DefaultSession(homeServerConnectionConfig)
|
return authenticator
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class MatrixOptions(val context: Context,
|
||||||
|
val mainExecutor: Executor = MainThreadExecutor())
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
package im.vector.matrix.android.api
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import im.vector.matrix.android.api.thread.MainThreadExecutor
|
|
||||||
import java.util.concurrent.Executor
|
|
||||||
|
|
||||||
data class MatrixOptions(val context: Context,
|
|
||||||
val mainExecutor: Executor = MainThreadExecutor())
|
|
|
@ -1,11 +0,0 @@
|
||||||
package im.vector.matrix.android.api
|
|
||||||
|
|
||||||
import im.vector.matrix.android.api.auth.Authenticator
|
|
||||||
|
|
||||||
interface Session {
|
|
||||||
|
|
||||||
fun authenticator(): Authenticator
|
|
||||||
|
|
||||||
fun close()
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,11 +1,12 @@
|
||||||
package im.vector.matrix.android.api.auth
|
package im.vector.matrix.android.api.auth
|
||||||
|
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
import im.vector.matrix.android.api.auth.data.Credentials
|
|
||||||
|
|
||||||
interface Authenticator {
|
interface Authenticator {
|
||||||
|
|
||||||
fun authenticate(login: String, password: String, callback: MatrixCallback<Credentials>): Cancelable
|
fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig, login: String, password: String, callback: MatrixCallback<Session>): Cancelable
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package im.vector.matrix.android.api.auth
|
package im.vector.matrix.android.api.auth
|
||||||
|
|
||||||
import im.vector.matrix.android.api.auth.data.Credentials
|
import im.vector.matrix.android.internal.auth.data.Credentials
|
||||||
|
|
||||||
interface CredentialsStore {
|
interface CredentialsStore {
|
||||||
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
package im.vector.matrix.android.api.auth.data
|
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
|
||||||
import com.squareup.moshi.JsonClass
|
|
||||||
import io.objectbox.annotation.Entity
|
|
||||||
import io.objectbox.annotation.Id
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@JsonClass(generateAdapter = true)
|
|
||||||
data class Credentials(@Id var id: Long = 0,
|
|
||||||
@Json(name = "user_id") val userId: String,
|
|
||||||
@Json(name = "home_server") val homeServer: String,
|
|
||||||
@Json(name = "access_token") val accessToken: String,
|
|
||||||
@Json(name = "refresh_token") val refreshToken: String?,
|
|
||||||
@Json(name = "device_id") val deviceId: String?)
|
|
|
@ -1,31 +1,17 @@
|
||||||
package im.vector.matrix.android.api.events
|
package im.vector.matrix.android.api.events
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
data class Event(
|
data class Event(
|
||||||
@Json(name = "event_id") val eventId: String,
|
@Json(name = "type") val type: String,
|
||||||
@Json(name = "type") val type: EventType,
|
@Json(name = "event_id") val eventId: String? = null,
|
||||||
@Json(name = "content") val content: String,
|
@Json(name = "content") val content: Map<String, Any>? = null,
|
||||||
@Json(name = "origin_server_ts") val originServerTs: Long,
|
@Json(name = "prev_content") val prevContent: Map<String, Any>? = null,
|
||||||
@Json(name = "prev_content") val prevContent: String? = null,
|
@Json(name = "origin_server_ts") val originServerTs: Long? = null,
|
||||||
@Json(name = "sender") val sender: String? = null,
|
@Json(name = "sender") val sender: String? = null,
|
||||||
@Json(name = "state_key") val stateKey: String? = null,
|
@Json(name = "state_key") val stateKey: String? = null,
|
||||||
@Json(name = "room_id") val roomId: String? = null,
|
@Json(name = "room_id") val roomId: String? = null,
|
||||||
@Json(name = "unsigned_data") val unsignedData: UnsignedData? = null
|
@Json(name = "unsigned_data") val unsignedData: UnsignedData? = null
|
||||||
) {
|
)
|
||||||
|
|
||||||
inline fun <reified T> content(): T? {
|
|
||||||
val moshi = Moshi.Builder().build()
|
|
||||||
return moshi.adapter<T>(T::class.java).fromJson(content)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <reified T> prevContent(): T? {
|
|
||||||
if (prevContent == null) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
val moshi = Moshi.Builder().build()
|
|
||||||
return moshi.adapter<T>(T::class.java).fromJson(prevContent)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package im.vector.matrix.android.api.events
|
||||||
|
|
||||||
|
class EventContent : HashMap<Any, Any>()
|
|
@ -40,5 +40,4 @@ enum class EventType {
|
||||||
@Json(name ="m.room.related_groups") STATE_RELATED_GROUPS,
|
@Json(name ="m.room.related_groups") STATE_RELATED_GROUPS,
|
||||||
@Json(name ="m.room.pinned_events") STATE_PINNED_EVENT
|
@Json(name ="m.room.pinned_events") STATE_PINNED_EVENT
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
package im.vector.matrix.android.api.events
|
package im.vector.matrix.android.api.events
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
data class UnsignedData(
|
data class UnsignedData(
|
||||||
@Json(name = "age") val age: Int,
|
@Json(name = "age") val age: Int,
|
||||||
@Json(name = "redacted_because") val redactedEvent: Event? = null,
|
@Json(name = "redacted_because") val redactedEvent: Event? = null,
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package im.vector.matrix.android.api.session
|
||||||
|
|
||||||
|
import im.vector.matrix.android.internal.events.sync.Synchronizer
|
||||||
|
|
||||||
|
interface Session {
|
||||||
|
|
||||||
|
fun synchronizer(): Synchronizer
|
||||||
|
|
||||||
|
fun close()
|
||||||
|
|
||||||
|
}
|
|
@ -1,37 +0,0 @@
|
||||||
package im.vector.matrix.android.internal
|
|
||||||
|
|
||||||
import im.vector.matrix.android.api.Session
|
|
||||||
import im.vector.matrix.android.api.auth.Authenticator
|
|
||||||
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
|
||||||
import im.vector.matrix.android.internal.auth.LoginModule
|
|
||||||
import org.koin.core.scope.Scope
|
|
||||||
import org.koin.standalone.KoinComponent
|
|
||||||
import org.koin.standalone.StandAloneContext
|
|
||||||
import org.koin.standalone.getKoin
|
|
||||||
import org.koin.standalone.inject
|
|
||||||
|
|
||||||
class DefaultSession(val homeServerConnectionConfig: HomeServerConnectionConfig) : Session, KoinComponent {
|
|
||||||
|
|
||||||
private val authenticator by inject<Authenticator>()
|
|
||||||
private val scope: Scope
|
|
||||||
|
|
||||||
init {
|
|
||||||
val loginModule = LoginModule(homeServerConnectionConfig)
|
|
||||||
StandAloneContext.loadKoinModules(listOf(loginModule))
|
|
||||||
scope = getKoin().createScope(SCOPE)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun authenticator(): Authenticator {
|
|
||||||
return authenticator
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun close() {
|
|
||||||
scope.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val SCOPE: String = "session"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
package im.vector.matrix.android.internal.auth
|
package im.vector.matrix.android.internal.auth
|
||||||
|
|
||||||
import im.vector.matrix.android.api.auth.data.Credentials
|
import im.vector.matrix.android.internal.auth.data.Credentials
|
||||||
import im.vector.matrix.android.internal.auth.data.PasswordLoginParams
|
import im.vector.matrix.android.internal.auth.data.PasswordLoginParams
|
||||||
import im.vector.matrix.android.internal.network.NetworkConstants
|
import im.vector.matrix.android.internal.network.NetworkConstants
|
||||||
import kotlinx.coroutines.Deferred
|
import kotlinx.coroutines.Deferred
|
||||||
|
@ -11,7 +11,7 @@ import retrofit2.http.POST
|
||||||
/**
|
/**
|
||||||
* The login REST API.
|
* The login REST API.
|
||||||
*/
|
*/
|
||||||
interface LoginApi {
|
interface AuthAPI {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pass params to the server for the current login phase.
|
* Pass params to the server for the current login phase.
|
|
@ -0,0 +1,39 @@
|
||||||
|
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.CredentialsStore
|
||||||
|
import im.vector.matrix.android.internal.auth.data.Credentials
|
||||||
|
import im.vector.matrix.android.internal.auth.data.MyObjectBox
|
||||||
|
import im.vector.matrix.android.internal.auth.db.ObjectBoxCredentialsStore
|
||||||
|
import io.objectbox.Box
|
||||||
|
import io.objectbox.BoxStore
|
||||||
|
import org.koin.dsl.context.ModuleDefinition
|
||||||
|
import org.koin.dsl.module.Module
|
||||||
|
import org.koin.dsl.module.module
|
||||||
|
|
||||||
|
private const val AUTH_BOX_STORE = "AUTH_BOX_STORE"
|
||||||
|
|
||||||
|
class AuthModule(private val context: Context) : Module {
|
||||||
|
|
||||||
|
override fun invoke(): ModuleDefinition = module {
|
||||||
|
|
||||||
|
single {
|
||||||
|
DefaultAuthenticator(get(), get(), get(), get()) as Authenticator
|
||||||
|
}
|
||||||
|
|
||||||
|
single(name = AUTH_BOX_STORE) {
|
||||||
|
MyObjectBox.builder().androidContext(context).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
single {
|
||||||
|
val boxStore = get(name = AUTH_BOX_STORE) as BoxStore
|
||||||
|
boxStore.boxFor(Credentials::class.java) as Box<Credentials>
|
||||||
|
}
|
||||||
|
|
||||||
|
single {
|
||||||
|
ObjectBoxCredentialsStore(get()) as CredentialsStore
|
||||||
|
}
|
||||||
|
|
||||||
|
}.invoke()
|
||||||
|
}
|
|
@ -2,36 +2,49 @@ package im.vector.matrix.android.internal.auth
|
||||||
|
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.auth.Authenticator
|
import im.vector.matrix.android.api.auth.Authenticator
|
||||||
import im.vector.matrix.android.api.auth.CredentialsStore
|
import im.vector.matrix.android.api.auth.CredentialsStore
|
||||||
import im.vector.matrix.android.api.auth.data.Credentials
|
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
import im.vector.matrix.android.internal.session.DefaultSession
|
||||||
import im.vector.matrix.android.internal.util.map
|
import im.vector.matrix.android.internal.auth.data.Credentials
|
||||||
import im.vector.matrix.android.internal.auth.data.PasswordLoginParams
|
import im.vector.matrix.android.internal.auth.data.PasswordLoginParams
|
||||||
import im.vector.matrix.android.internal.network.executeRequest
|
import im.vector.matrix.android.internal.network.executeRequest
|
||||||
import im.vector.matrix.android.internal.util.CancelableCoroutine
|
import im.vector.matrix.android.internal.util.CancelableCoroutine
|
||||||
|
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||||
|
import im.vector.matrix.android.internal.util.map
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import retrofit2.Retrofit
|
||||||
|
|
||||||
class DefaultAuthenticator(private val loginApi: LoginApi,
|
class DefaultAuthenticator(private val retrofitBuilder: Retrofit.Builder,
|
||||||
private val jsonMapper: Moshi,
|
private val jsonMapper: Moshi,
|
||||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||||
private val credentialsStore: CredentialsStore) : Authenticator {
|
private val credentialsStore: CredentialsStore) : Authenticator {
|
||||||
|
|
||||||
override fun authenticate(login: String, password: String, callback: MatrixCallback<Credentials>): Cancelable {
|
override fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig, login: String, password: String, callback: MatrixCallback<Session>): Cancelable {
|
||||||
|
val authAPI = buildAuthAPI(homeServerConnectionConfig)
|
||||||
val job = GlobalScope.launch(coroutineDispatchers.main) {
|
val job = GlobalScope.launch(coroutineDispatchers.main) {
|
||||||
val loginParams = PasswordLoginParams.userIdentifier(login, password, "Mobile")
|
val loginParams = PasswordLoginParams.userIdentifier(login, password, "Mobile")
|
||||||
val loginResult = executeRequest<Credentials> {
|
val loginResult = executeRequest<Credentials> {
|
||||||
apiCall = loginApi.login(loginParams)
|
apiCall = authAPI.login(loginParams)
|
||||||
moshi = jsonMapper
|
moshi = jsonMapper
|
||||||
dispatcher = coroutineDispatchers.io
|
dispatcher = coroutineDispatchers.io
|
||||||
}.map {
|
}.map {
|
||||||
it?.apply { credentialsStore.save(it) }
|
it?.apply { credentialsStore.save(it) }
|
||||||
|
}.map {
|
||||||
|
DefaultSession(homeServerConnectionConfig)
|
||||||
}
|
}
|
||||||
loginResult.either({ callback.onFailure(it) }, { callback.onSuccess(it) })
|
loginResult.either({ callback.onFailure(it) }, { callback.onSuccess(it) })
|
||||||
}
|
}
|
||||||
return CancelableCoroutine(job)
|
return CancelableCoroutine(job)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
|
||||||
|
val retrofit = retrofitBuilder.baseUrl(homeServerConnectionConfig.hsUri).build()
|
||||||
|
return retrofit.create(AuthAPI::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,33 +0,0 @@
|
||||||
package im.vector.matrix.android.internal.auth
|
|
||||||
|
|
||||||
import im.vector.matrix.android.api.auth.Authenticator
|
|
||||||
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
|
||||||
import im.vector.matrix.android.internal.DefaultSession
|
|
||||||
import org.koin.dsl.context.ModuleDefinition
|
|
||||||
import org.koin.dsl.module.Module
|
|
||||||
import org.koin.dsl.module.module
|
|
||||||
import retrofit2.Retrofit
|
|
||||||
|
|
||||||
class LoginModule(private val connectionConfig: HomeServerConnectionConfig) : Module {
|
|
||||||
|
|
||||||
override fun invoke(): ModuleDefinition = module {
|
|
||||||
scope(DefaultSession.SCOPE) {
|
|
||||||
Retrofit.Builder()
|
|
||||||
.client(get())
|
|
||||||
.baseUrl(connectionConfig.hsUri)
|
|
||||||
.addConverterFactory(get())
|
|
||||||
.addCallAdapterFactory(get())
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
scope(DefaultSession.SCOPE) {
|
|
||||||
val retrofit: Retrofit = get()
|
|
||||||
retrofit.create(LoginApi::class.java)
|
|
||||||
}
|
|
||||||
|
|
||||||
scope(DefaultSession.SCOPE) {
|
|
||||||
DefaultAuthenticator(get(), get(), get(), get()) as Authenticator
|
|
||||||
}
|
|
||||||
|
|
||||||
}.invoke()
|
|
||||||
}
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package im.vector.matrix.android.internal.auth.data
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
import io.objectbox.annotation.Entity
|
||||||
|
import io.objectbox.annotation.Id
|
||||||
|
import io.objectbox.annotation.Index
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
data class Credentials(
|
||||||
|
@Id var id: Long = 0,
|
||||||
|
@Index @Json(name = "user_id") val userId: String,
|
||||||
|
@Json(name = "home_server") val homeServer: String,
|
||||||
|
@Json(name = "access_token") val accessToken: String,
|
||||||
|
@Json(name = "refresh_token") val refreshToken: String?,
|
||||||
|
@Json(name = "device_id") val deviceId: String?)
|
|
@ -1,18 +0,0 @@
|
||||||
package im.vector.matrix.android.internal.auth.db
|
|
||||||
|
|
||||||
import im.vector.matrix.android.api.auth.CredentialsStore
|
|
||||||
import im.vector.matrix.android.api.auth.data.Credentials
|
|
||||||
|
|
||||||
class InMemoryCredentialsStore : CredentialsStore {
|
|
||||||
|
|
||||||
var credentials: Credentials? = null
|
|
||||||
|
|
||||||
override fun get(): Credentials? {
|
|
||||||
return credentials
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun save(credentials: Credentials) {
|
|
||||||
this.credentials = credentials.copy()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
package im.vector.matrix.android.internal.auth.db
|
package im.vector.matrix.android.internal.auth.db
|
||||||
|
|
||||||
import im.vector.matrix.android.api.auth.CredentialsStore
|
import im.vector.matrix.android.api.auth.CredentialsStore
|
||||||
import im.vector.matrix.android.api.auth.data.Credentials
|
import im.vector.matrix.android.internal.auth.data.Credentials
|
||||||
import io.objectbox.Box
|
import io.objectbox.Box
|
||||||
|
|
||||||
class ObjectBoxCredentialsStore(private val box: Box<Credentials>) : CredentialsStore {
|
class ObjectBoxCredentialsStore(private val box: Box<Credentials>) : CredentialsStore {
|
||||||
|
@ -11,7 +11,7 @@ class ObjectBoxCredentialsStore(private val box: Box<Credentials>) : Credentials
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun get(): Credentials? {
|
override fun get(): Credentials? {
|
||||||
return box.all.firstOrNull()
|
return box.all.lastOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,13 +1,7 @@
|
||||||
package im.vector.matrix.android.internal.di
|
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.auth.CredentialsStore
|
|
||||||
import im.vector.matrix.android.api.auth.data.Credentials
|
|
||||||
import im.vector.matrix.android.api.auth.data.MyObjectBox
|
|
||||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||||
import im.vector.matrix.android.internal.auth.db.ObjectBoxCredentialsStore
|
|
||||||
import io.objectbox.Box
|
|
||||||
import io.objectbox.BoxStore
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.IO
|
import kotlinx.coroutines.IO
|
||||||
import kotlinx.coroutines.asCoroutineDispatcher
|
import kotlinx.coroutines.asCoroutineDispatcher
|
||||||
|
@ -23,19 +17,5 @@ class MatrixModule(private val options: MatrixOptions) : Module {
|
||||||
single {
|
single {
|
||||||
MatrixCoroutineDispatchers(io = Dispatchers.IO, computation = Dispatchers.IO, main = options.mainExecutor.asCoroutineDispatcher())
|
MatrixCoroutineDispatchers(io = Dispatchers.IO, computation = Dispatchers.IO, main = options.mainExecutor.asCoroutineDispatcher())
|
||||||
}
|
}
|
||||||
|
|
||||||
single {
|
|
||||||
MyObjectBox.builder().androidContext(options.context).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
val boxStore = get() as BoxStore
|
|
||||||
boxStore.boxFor(Credentials::class.java) as Box<Credentials>
|
|
||||||
}
|
|
||||||
|
|
||||||
single {
|
|
||||||
ObjectBoxCredentialsStore(get()) as CredentialsStore
|
|
||||||
}
|
|
||||||
|
|
||||||
}.invoke()
|
}.invoke()
|
||||||
}
|
}
|
|
@ -10,9 +10,12 @@ import org.koin.dsl.module.Module
|
||||||
import org.koin.dsl.module.module
|
import org.koin.dsl.module.module
|
||||||
import retrofit2.CallAdapter
|
import retrofit2.CallAdapter
|
||||||
import retrofit2.Converter
|
import retrofit2.Converter
|
||||||
|
import retrofit2.Retrofit
|
||||||
import retrofit2.converter.moshi.MoshiConverterFactory
|
import retrofit2.converter.moshi.MoshiConverterFactory
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class NetworkModule() : Module {
|
class NetworkModule : Module {
|
||||||
|
|
||||||
override fun invoke(): ModuleDefinition = module {
|
override fun invoke(): ModuleDefinition = module {
|
||||||
|
|
||||||
|
@ -21,17 +24,23 @@ class NetworkModule() : Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
single {
|
single {
|
||||||
HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY }
|
val logger = HttpLoggingInterceptor.Logger { message -> Timber.v(message) }
|
||||||
|
HttpLoggingInterceptor(logger).apply { level = HttpLoggingInterceptor.Level.BODY }
|
||||||
}
|
}
|
||||||
|
|
||||||
single {
|
single {
|
||||||
OkHttpClient.Builder()
|
OkHttpClient.Builder()
|
||||||
|
.connectTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.readTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.writeTimeout(30, TimeUnit.SECONDS)
|
||||||
.addInterceptor(get() as AccessTokenInterceptor)
|
.addInterceptor(get() as AccessTokenInterceptor)
|
||||||
.addInterceptor(get() as HttpLoggingInterceptor)
|
.addInterceptor(get() as HttpLoggingInterceptor)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
single { Moshi.Builder().build() }
|
single {
|
||||||
|
Moshi.Builder().build()
|
||||||
|
}
|
||||||
|
|
||||||
single {
|
single {
|
||||||
MoshiConverterFactory.create(get()) as Converter.Factory
|
MoshiConverterFactory.create(get()) as Converter.Factory
|
||||||
|
@ -41,6 +50,12 @@ class NetworkModule() : Module {
|
||||||
CoroutineCallAdapterFactory() as CallAdapter.Factory
|
CoroutineCallAdapterFactory() as CallAdapter.Factory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
factory {
|
||||||
|
Retrofit.Builder()
|
||||||
|
.client(get())
|
||||||
|
.addConverterFactory(get())
|
||||||
|
.addCallAdapterFactory(get())
|
||||||
|
}
|
||||||
|
|
||||||
}.invoke()
|
}.invoke()
|
||||||
}
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package im.vector.matrix.android.internal.di
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
||||||
|
import im.vector.matrix.android.internal.session.DefaultSession
|
||||||
|
import org.koin.dsl.context.ModuleDefinition
|
||||||
|
import org.koin.dsl.module.Module
|
||||||
|
import org.koin.dsl.module.module
|
||||||
|
import retrofit2.Retrofit
|
||||||
|
|
||||||
|
class SessionModule(private val connectionConfig: HomeServerConnectionConfig) : Module {
|
||||||
|
|
||||||
|
override fun invoke(): ModuleDefinition = module {
|
||||||
|
scope(DefaultSession.SCOPE) {
|
||||||
|
val retrofitBuilder = get() as Retrofit.Builder
|
||||||
|
retrofitBuilder
|
||||||
|
.baseUrl(connectionConfig.hsUri)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}.invoke()
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package im.vector.matrix.android.internal.events.sync
|
package im.vector.matrix.android.internal.events.sync
|
||||||
|
|
||||||
import im.vector.matrix.android.internal.network.NetworkConstants
|
|
||||||
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.network.NetworkConstants
|
||||||
import kotlinx.coroutines.Deferred
|
import kotlinx.coroutines.Deferred
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
|
@ -10,6 +10,6 @@ import retrofit2.http.QueryMap
|
||||||
interface SyncAPI {
|
interface SyncAPI {
|
||||||
|
|
||||||
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "sync")
|
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "sync")
|
||||||
fun sync(@QueryMap params: Map<String, Any>): Deferred<Response<SyncResponse>>
|
fun sync(@QueryMap params: Map<String, String>): Deferred<Response<SyncResponse>>
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package im.vector.matrix.android.internal.events.sync
|
||||||
|
|
||||||
|
import im.vector.matrix.android.internal.session.DefaultSession
|
||||||
|
import org.koin.dsl.context.ModuleDefinition
|
||||||
|
import org.koin.dsl.module.Module
|
||||||
|
import org.koin.dsl.module.module
|
||||||
|
import retrofit2.Retrofit
|
||||||
|
|
||||||
|
class SyncModule : Module {
|
||||||
|
|
||||||
|
override fun invoke(): ModuleDefinition = module {
|
||||||
|
|
||||||
|
scope(DefaultSession.SCOPE) {
|
||||||
|
val retrofit: Retrofit = get()
|
||||||
|
retrofit.create(SyncAPI::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
scope(DefaultSession.SCOPE) {
|
||||||
|
Synchronizer(get(), get(), get())
|
||||||
|
}
|
||||||
|
|
||||||
|
}.invoke()
|
||||||
|
}
|
|
@ -1,11 +1,32 @@
|
||||||
package im.vector.matrix.android.internal.events.sync
|
package im.vector.matrix.android.internal.events.sync
|
||||||
|
|
||||||
class Synchronizer(private val syncAPI: SyncAPI) {
|
import com.squareup.moshi.Moshi
|
||||||
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
fun synchronize() {
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
|
import im.vector.matrix.android.internal.events.sync.data.SyncResponse
|
||||||
|
import im.vector.matrix.android.internal.network.executeRequest
|
||||||
|
import im.vector.matrix.android.internal.util.CancelableCoroutine
|
||||||
|
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class Synchronizer(private val syncAPI: SyncAPI,
|
||||||
|
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||||
|
private val jsonMapper: Moshi) {
|
||||||
|
|
||||||
|
fun synchronize(callback: MatrixCallback<SyncResponse>): Cancelable {
|
||||||
|
val job = GlobalScope.launch(coroutineDispatchers.main) {
|
||||||
|
val params = HashMap<String, String>()
|
||||||
|
params["timeout"] = "0"
|
||||||
|
params["filter"] = "{}"
|
||||||
|
val syncResponse = executeRequest<SyncResponse> {
|
||||||
|
apiCall = syncAPI.sync(params)
|
||||||
|
moshi = jsonMapper
|
||||||
|
dispatcher = coroutineDispatchers.io
|
||||||
|
}
|
||||||
|
syncResponse.either({ callback.onFailure(it) }, { callback.onSuccess(it) })
|
||||||
|
}
|
||||||
|
return CancelableCoroutine(job)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
|
||||||
// SyncResponse represents the request response for server sync v2.
|
// SyncResponse represents the request response for server sync v2.
|
||||||
|
@ -9,36 +10,36 @@ data class SyncResponse(
|
||||||
/**
|
/**
|
||||||
* The user private data.
|
* The user private data.
|
||||||
*/
|
*/
|
||||||
val accountData: Map<String, Any> = emptyMap(),
|
@Json(name = "account_data") val accountData: Map<String, Any>? = emptyMap(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The opaque token for the end.
|
* The opaque token for the end.
|
||||||
*/
|
*/
|
||||||
val nextBatch: String? = null,
|
@Json(name = "next_batch") val nextBatch: String? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The updates to the presence status of other users.
|
* The updates to the presence status of other users.
|
||||||
*/
|
*/
|
||||||
val presence: PresenceSyncResponse? = null,
|
@Json(name = "presence") val presence: PresenceSyncResponse? = null,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Data directly sent to one of user's devices.
|
* Data directly sent to one of user's devices.
|
||||||
*/
|
*/
|
||||||
val toDevice: ToDeviceSyncResponse? = null,
|
@Json(name = "to_device") val toDevice: ToDeviceSyncResponse? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of rooms.
|
* List of rooms.
|
||||||
*/
|
*/
|
||||||
val rooms: RoomsSyncResponse? = null,
|
@Json(name = "rooms") val rooms: RoomsSyncResponse? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Devices list update
|
* Devices list update
|
||||||
*/
|
*/
|
||||||
val deviceLists: DeviceListResponse? = null,
|
@Json(name = "device_lists") val deviceLists: DeviceListResponse? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One time keys management
|
* One time keys management
|
||||||
*/
|
*/
|
||||||
val deviceOneTimeKeysCount: DeviceOneTimeKeysCountSyncResponse? = null
|
@Json(name = "device_one_time_keys_count") val deviceOneTimeKeysCount: DeviceOneTimeKeysCountSyncResponse? = null
|
||||||
|
|
||||||
)
|
)
|
|
@ -0,0 +1,38 @@
|
||||||
|
package im.vector.matrix.android.internal.session
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
||||||
|
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.Synchronizer
|
||||||
|
import org.koin.core.scope.Scope
|
||||||
|
import org.koin.standalone.KoinComponent
|
||||||
|
import org.koin.standalone.StandAloneContext
|
||||||
|
import org.koin.standalone.getKoin
|
||||||
|
import org.koin.standalone.inject
|
||||||
|
|
||||||
|
class DefaultSession(homeServerConnectionConfig: HomeServerConnectionConfig) : Session, KoinComponent {
|
||||||
|
|
||||||
|
private val synchronizer by inject<Synchronizer>()
|
||||||
|
private val scope: Scope
|
||||||
|
|
||||||
|
init {
|
||||||
|
val sessionModule = SessionModule(homeServerConnectionConfig)
|
||||||
|
val syncModule = SyncModule()
|
||||||
|
StandAloneContext.loadKoinModules(listOf(sessionModule, syncModule))
|
||||||
|
scope = getKoin().createScope(SCOPE)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun synchronizer(): Synchronizer {
|
||||||
|
return synchronizer
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
scope.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val SCOPE: String = "session"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue