From 834be43e9a308861f208e321b8e5691484e06704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raul=20Fern=C3=A1ndez=20Garc=C3=ADa?= Date: Mon, 22 Jun 2020 10:29:49 +0200 Subject: [PATCH 1/2] Token feature + Record Activity, cannot cast Activity[] --- .../datasource/local/CommonLocalDataSource.kt | 2 +- .../remote/CommonRemoteDataSource.kt | 18 +++++++-- .../datasource/remote/RemoteDataSource.kt | 1 + .../data/datasource/remote/TokenFeature.kt | 40 +++++++++++++++++++ .../data/repository/CommonRepository.kt | 15 +++++-- .../data/repository/Repository.kt | 1 + .../multiplatform/domain/model/Activity.kt | 10 +++++ .../ui/presenter/RecordPresenter.kt | 11 ++++- .../rewardingstub/multiplatform/ui/app/App.kt | 2 +- .../ui/view/activity/AuthActivity.kt | 10 +++-- .../ui/view/activity/RecordActivity.kt | 10 ++++- app/src/main/res/layout/activity_record.xml | 6 +-- 12 files changed, 108 insertions(+), 18 deletions(-) create mode 100644 app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/remote/TokenFeature.kt create mode 100644 app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/domain/model/Activity.kt diff --git a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/local/CommonLocalDataSource.kt b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/local/CommonLocalDataSource.kt index c1eafd7..4d7c621 100644 --- a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/local/CommonLocalDataSource.kt +++ b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/local/CommonLocalDataSource.kt @@ -21,7 +21,7 @@ class CommonLocalDataSource(private val settings: Settings) : LocalDataSource { override suspend fun saveToken(registerDataResponse: RegisterDataResponse): Either { return try { - settings.putString(ACCESS_TOKEN, Json.stringify(RegisterDataResponse.serializer(), registerDataResponse)) + settings.putString(ACCESS_TOKEN, registerDataResponse.token)//Json.stringify(RegisterDataResponse.serializer(), registerDataResponse)) Either.Right(Success) } catch (e: Exception) { Either.Left(Error.TokenNotSaved) diff --git a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/remote/CommonRemoteDataSource.kt b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/remote/CommonRemoteDataSource.kt index 82ff219..e8789c1 100644 --- a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/remote/CommonRemoteDataSource.kt +++ b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/remote/CommonRemoteDataSource.kt @@ -1,5 +1,6 @@ package com.worldline.helios.rewardingstub.multiplatform.data.datasource.remote +import com.worldline.helios.rewardingstub.multiplatform.data.datasource.local.LocalDataSource import com.worldline.helios.rewardingstub.multiplatform.domain.model.* import io.ktor.client.HttpClient import io.ktor.client.features.ClientRequestException @@ -11,15 +12,17 @@ import io.ktor.client.features.logging.Logging import io.ktor.client.features.logging.SIMPLE import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.get +import io.ktor.client.request.header import io.ktor.client.request.post import io.ktor.http.HttpStatusCode import io.ktor.http.takeFrom import io.ktor.util.date.GMTDate -class CommonRemoteDataSource : RemoteDataSource { +class CommonRemoteDataSource(localDataSource: LocalDataSource) : RemoteDataSource { companion object { const val END_POINT_HELIOS = "https://devel3.tempos21.com" + private const val TOKEN_HEADER = "Authorization" } private val client = HttpClient { @@ -38,6 +41,11 @@ class CommonRemoteDataSource : RemoteDataSource { install(JsonFeature) { serializer = KotlinxSerializer() } + + install(TokenFeature) { + tokenHeaderName = TOKEN_HEADER + tokenProvider = localDataSource + } } override suspend fun registerUser(userID: String, context: String): Either = execute { @@ -52,7 +60,8 @@ class CommonRemoteDataSource : RemoteDataSource { client.post { call("/hrm-api/activities/record") val json = io.ktor.client.features.json.defaultSerializer() - body = json.write(Activity(action = action, date = date)) + body = json.write(arrayOf(Activity(action = action, date = date))) + //header("Authorization", "Bearer " + token ) } } @@ -76,8 +85,9 @@ class CommonRemoteDataSource : RemoteDataSource { private fun HttpRequestBuilder.call(path: String) { url { - takeFrom(END_POINT) - encodedPath = "$path&appid=$API_KEY" + takeFrom(END_POINT_HELIOS) + //encodedPath = "$path&appid=$API_KEY" + encodedPath = "$path" } } } diff --git a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/remote/RemoteDataSource.kt b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/remote/RemoteDataSource.kt index 415c599..5b68315 100644 --- a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/remote/RemoteDataSource.kt +++ b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/remote/RemoteDataSource.kt @@ -5,4 +5,5 @@ import com.worldline.helios.rewardingstub.multiplatform.data.datasource.remote.* interface RemoteDataSource { suspend fun registerUser(userID: String, context: String): Either + suspend fun registerActivity(action: String, date: String): Either } diff --git a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/remote/TokenFeature.kt b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/remote/TokenFeature.kt new file mode 100644 index 0000000..6c23b1b --- /dev/null +++ b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/datasource/remote/TokenFeature.kt @@ -0,0 +1,40 @@ +package com.worldline.helios.rewardingstub.multiplatform.data.datasource.remote + +import com.worldline.helios.rewardingstub.multiplatform.data.datasource.local.LocalDataSource +import io.ktor.client.HttpClient +import io.ktor.client.features.HttpClientFeature +import io.ktor.client.request.HttpRequestPipeline +import io.ktor.client.request.header +import io.ktor.util.AttributeKey + +class TokenFeature private constructor( + private val tokenHeaderName: String, + private val tokenProvider: LocalDataSource +) { + + class Config { + var tokenHeaderName: String? = null + var tokenProvider: LocalDataSource? = null + fun build() = TokenFeature( + tokenHeaderName ?: throw IllegalArgumentException("HeaderName should be contain"), + tokenProvider ?: throw IllegalArgumentException("TokenProvider should be contain") + ) + } + + companion object Feature : HttpClientFeature { + override val key = AttributeKey("TokenFeature") + + override fun prepare(block: Config.() -> Unit) = Config().apply(block).build() + + override fun install(feature: TokenFeature, scope: HttpClient) { + scope.requestPipeline.intercept(HttpRequestPipeline.State) { + feature.tokenProvider.getToken().apply { + this.fold( + error = {}, + success = { context.header(feature.tokenHeaderName, "Bearer $it") } + ) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/repository/CommonRepository.kt b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/repository/CommonRepository.kt index 7d848ef..b8ec783 100644 --- a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/repository/CommonRepository.kt +++ b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/repository/CommonRepository.kt @@ -1,5 +1,6 @@ package com.worldline.helios.rewardingstub.multiplatform.data.repository +import com.worldline.helios.rewardingstub.multiplatform.data.datasource.local.CommonLocalDataSource import com.worldline.helios.rewardingstub.multiplatform.data.datasource.local.LocalDataSource import com.worldline.helios.rewardingstub.multiplatform.data.datasource.remote.RegisterDataResponse import com.worldline.helios.rewardingstub.multiplatform.data.datasource.remote.RemoteDataSource @@ -10,15 +11,23 @@ class CommonRepository( private val local: LocalDataSource ) : Repository { - override suspend fun registerUser(userID: String, context: String): Either = - remote.registerUser(userID, context) + override suspend fun registerUser(userID: String, heliosContext: String): Either = + remote.registerUser(userID, heliosContext) .flatMap {registerDataResponse -> local.saveToken(registerDataResponse.success) .flatMap { registerDataResponse } } + + override suspend fun registerActivity(action: String, date: String): Either = + remote.registerActivity(action, date) + override suspend fun getToken(): Either { - return local.getToken() + return try { + local.getToken() + } catch (e: Exception) { + Either.Left(Error.IO(e.message ?: "")) + } } override suspend fun removeToken(): Either { diff --git a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/repository/Repository.kt b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/repository/Repository.kt index a61db1c..7df6feb 100644 --- a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/repository/Repository.kt +++ b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/data/repository/Repository.kt @@ -8,6 +8,7 @@ import com.worldline.helios.rewardingstub.multiplatform.domain.model.Success interface Repository { suspend fun registerUser(userID: String, heliosContext: String): Either + suspend fun registerActivity(action: String, date: String): Either suspend fun removeToken(): Either suspend fun getToken(): Either } diff --git a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/domain/model/Activity.kt b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/domain/model/Activity.kt new file mode 100644 index 0000000..e5aaddf --- /dev/null +++ b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/domain/model/Activity.kt @@ -0,0 +1,10 @@ +package com.worldline.helios.rewardingstub.multiplatform.domain.model + +import io.ktor.util.date.GMTDate +import kotlinx.serialization.Serializable + +@Serializable +data class Activity ( + val action: String, + val date: String +) diff --git a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/ui/presenter/RecordPresenter.kt b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/ui/presenter/RecordPresenter.kt index 5e32284..7930aad 100644 --- a/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/ui/presenter/RecordPresenter.kt +++ b/app/src/commonMain/kotlin/com/worldline/helios/rewardingstub/multiplatform/ui/presenter/RecordPresenter.kt @@ -15,8 +15,17 @@ class RecordPresenter( override fun attach() { } + + fun registerActivity(action: String, date: String) { + scope.launch { + execute { repository.registerActivity(action, date) }.fold( + error = { println("error") }, + success = { view.showSuccess() } + ) + } } +} interface RecordView : View { - + fun showSuccess() } diff --git a/app/src/main/java/com/worldline/helios/rewardingstub/multiplatform/ui/app/App.kt b/app/src/main/java/com/worldline/helios/rewardingstub/multiplatform/ui/app/App.kt index 546b169..9b3ea51 100644 --- a/app/src/main/java/com/worldline/helios/rewardingstub/multiplatform/ui/app/App.kt +++ b/app/src/main/java/com/worldline/helios/rewardingstub/multiplatform/ui/app/App.kt @@ -38,7 +38,7 @@ val domainModule = Kodein.Module("domainModule") { } val dataModule = Kodein.Module("dataModule") { - bind() with singleton { CommonRemoteDataSource() } + bind() with singleton { CommonRemoteDataSource(localDataSource = instance()) } bind() with singleton { val context: Context = instance() CommonLocalDataSource(AndroidSettings(context.getSharedPreferences("bd", Context.MODE_PRIVATE))) diff --git a/app/src/main/java/com/worldline/helios/rewardingstub/multiplatform/ui/view/activity/AuthActivity.kt b/app/src/main/java/com/worldline/helios/rewardingstub/multiplatform/ui/view/activity/AuthActivity.kt index a718e1b..84d3835 100644 --- a/app/src/main/java/com/worldline/helios/rewardingstub/multiplatform/ui/view/activity/AuthActivity.kt +++ b/app/src/main/java/com/worldline/helios/rewardingstub/multiplatform/ui/view/activity/AuthActivity.kt @@ -2,10 +2,8 @@ package com.worldline.helios.rewardingstub.multiplatform.ui.view.activity import android.content.Context import android.content.Intent -import android.os.Bundle -import android.widget.Button +import android.widget.Toast import com.worldline.helios.rewardingstub.multiplatform.R -import com.worldline.helios.rewardingstub.multiplatform.domain.model.Forecast import com.worldline.helios.rewardingstub.multiplatform.ui.app.ACTIVITY_MODULE import com.worldline.helios.rewardingstub.multiplatform.ui.presenter.AuthPresenter import com.worldline.helios.rewardingstub.multiplatform.ui.presenter.AuthView @@ -46,7 +44,13 @@ class AuthActivity : RootActivity(), AuthView { override fun registerListeners() { // Do nothing + button_sendAuth.setOnClickListener() { v -> + presenter.registerUser(userID = editUserID.text.toString(), context = editContext.text.toString()); + } + } + override fun showSuccess() { + Toast.makeText(applicationContext,"User registered.",Toast.LENGTH_SHORT).show() } } diff --git a/app/src/main/java/com/worldline/helios/rewardingstub/multiplatform/ui/view/activity/RecordActivity.kt b/app/src/main/java/com/worldline/helios/rewardingstub/multiplatform/ui/view/activity/RecordActivity.kt index 91107ce..b2d02ed 100644 --- a/app/src/main/java/com/worldline/helios/rewardingstub/multiplatform/ui/view/activity/RecordActivity.kt +++ b/app/src/main/java/com/worldline/helios/rewardingstub/multiplatform/ui/view/activity/RecordActivity.kt @@ -2,12 +2,12 @@ package com.worldline.helios.rewardingstub.multiplatform.ui.view.activity import android.content.Context import android.content.Intent -import android.widget.Button +import android.widget.Toast import com.worldline.helios.rewardingstub.multiplatform.R -import com.worldline.helios.rewardingstub.multiplatform.domain.model.Forecast import com.worldline.helios.rewardingstub.multiplatform.ui.app.ACTIVITY_MODULE import com.worldline.helios.rewardingstub.multiplatform.ui.presenter.RecordPresenter import com.worldline.helios.rewardingstub.multiplatform.ui.presenter.RecordView +import kotlinx.android.synthetic.main.activity_auth.* import kotlinx.android.synthetic.main.activity_record.* import org.kodein.di.Kodein import org.kodein.di.generic.bind @@ -40,7 +40,13 @@ class RecordActivity : RootActivity(), RecordView { override fun registerListeners() { // Do nothing + button_sendActivity.setOnClickListener() { v -> + presenter.registerActivity(action = editAction.text.toString(), date = editDate.text.toString()); + } + } + override fun showSuccess() { + Toast.makeText(applicationContext,"Activity registered.", Toast.LENGTH_SHORT).show() } } diff --git a/app/src/main/res/layout/activity_record.xml b/app/src/main/res/layout/activity_record.xml index eb03cca..9f4d4c3 100644 --- a/app/src/main/res/layout/activity_record.xml +++ b/app/src/main/res/layout/activity_record.xml @@ -21,7 +21,7 @@ app:layout_constraintTop_toTopOf="parent">