diff --git a/app/build.gradle b/app/build.gradle
index 4f4949b7af732854e6973d38a9d3c9664d9b7816..09d7acdd575626674da13dd663424299d9519296 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -125,6 +125,9 @@ dependencies {
// implementation "com.squareup.moshi:moshi-adapters:1.5.0"
implementation "com.squareup.okhttp3:okhttp:4.9.2"
+ // JSON Converter
+ implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
+
// YAML factory
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.11.2"
diff --git a/app/src/main/java/foundation/e/apps/api/cleanapk/ApplicationDeserializer.kt b/app/src/main/java/foundation/e/apps/api/cleanapk/ApplicationDeserializer.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a62e7788c5b92febe4b326cd0b24302bfa273905
--- /dev/null
+++ b/app/src/main/java/foundation/e/apps/api/cleanapk/ApplicationDeserializer.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright ECORP SAS 2022
+ * Apps Quickly and easily install Android apps onto your device!
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package foundation.e.apps.api.cleanapk
+
+import com.google.gson.Gson
+import com.google.gson.JsonDeserializationContext
+import com.google.gson.JsonDeserializer
+import com.google.gson.JsonElement
+import foundation.e.apps.api.cleanapk.data.app.Application
+
+class ApplicationDeserializer : JsonDeserializer {
+ override fun deserialize(
+ json: JsonElement?,
+ typeOfT: java.lang.reflect.Type?,
+ context: JsonDeserializationContext?
+ ): Application {
+ val gson = Gson()
+ val application = gson.fromJson(json?.asJsonObject?.toString(), Application::class.java)
+ val lastUpdate = application.app.latest_downloaded_version
+ val lastUpdatedOn = json?.asJsonObject?.get("app")?.asJsonObject?.get(lastUpdate)
+ ?.asJsonObject?.get("update_on")?.asString ?: ""
+ application.app.updatedOn = lastUpdatedOn
+ return application
+ }
+}
diff --git a/app/src/main/java/foundation/e/apps/api/cleanapk/CleanAPKRepository.kt b/app/src/main/java/foundation/e/apps/api/cleanapk/CleanAPKRepository.kt
index 35a6495cdde17437464229fa1e6b26ce89b5cad4..9bc56e6fe410b1c407b8842027438073adf28ae0 100644
--- a/app/src/main/java/foundation/e/apps/api/cleanapk/CleanAPKRepository.kt
+++ b/app/src/main/java/foundation/e/apps/api/cleanapk/CleanAPKRepository.kt
@@ -27,7 +27,8 @@ import retrofit2.Response
import javax.inject.Inject
class CleanAPKRepository @Inject constructor(
- private val cleanAPKInterface: CleanAPKInterface
+ private val cleanAPKInterface: CleanAPKInterface,
+ private val cleanApkAppDetailApi: CleanApkAppDetailApi
) {
suspend fun getHomeScreenData(
@@ -42,7 +43,7 @@ class CleanAPKRepository @Inject constructor(
architectures: List? = null,
type: String? = null
): Response {
- return cleanAPKInterface.getAppOrPWADetailsByID(id, architectures, type)
+ return cleanApkAppDetailApi.getAppOrPWADetailsByID(id, architectures, type)
}
suspend fun searchApps(
diff --git a/app/src/main/java/foundation/e/apps/api/cleanapk/CleanApkAppDetailApi.kt b/app/src/main/java/foundation/e/apps/api/cleanapk/CleanApkAppDetailApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f6795e12ca59fd8cc3521d5e134755eb44e3cc5e
--- /dev/null
+++ b/app/src/main/java/foundation/e/apps/api/cleanapk/CleanApkAppDetailApi.kt
@@ -0,0 +1,41 @@
+/*
+ *
+ * * Copyright ECORP SAS 2022
+ * * Apps Quickly and easily install Android apps onto your device!
+ * *
+ * * This program is free software: you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation, either version 3 of the License, or
+ * * (at your option) any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program. If not, see .
+ *
+ */
+
+package foundation.e.apps.api.cleanapk
+
+import foundation.e.apps.api.cleanapk.data.app.Application
+import retrofit2.Response
+import retrofit2.http.GET
+import retrofit2.http.Query
+
+interface CleanApkAppDetailApi {
+
+ companion object {
+ // API endpoints
+ const val BASE_URL = "https://api.cleanapk.org/v2/"
+ }
+
+ @GET("apps?action=app_detail")
+ suspend fun getAppOrPWADetailsByID(
+ @Query("id") id: String,
+ @Query("architectures") architectures: List? = null,
+ @Query("type") type: String? = null
+ ): Response
+}
diff --git a/app/src/main/java/foundation/e/apps/api/cleanapk/RetrofitModule.kt b/app/src/main/java/foundation/e/apps/api/cleanapk/RetrofitModule.kt
index 2672b48f080db54d5c561824fb0259b23ca90906..e0cd5630a56c82c9ee7a6fdfe07e0af5ae2c7185 100644
--- a/app/src/main/java/foundation/e/apps/api/cleanapk/RetrofitModule.kt
+++ b/app/src/main/java/foundation/e/apps/api/cleanapk/RetrofitModule.kt
@@ -22,12 +22,15 @@ import android.os.Build
import android.util.Log
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
+import com.google.gson.Gson
+import com.google.gson.GsonBuilder
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
+import foundation.e.apps.api.cleanapk.data.app.Application
import foundation.e.apps.api.ecloud.EcloudApiInterface
import foundation.e.apps.api.exodus.ExodusTrackerApi
import foundation.e.apps.api.fdroid.FdroidApiInterface
@@ -39,6 +42,7 @@ import okhttp3.Protocol
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.jackson.JacksonConverterFactory
import retrofit2.converter.moshi.MoshiConverterFactory
import java.net.ConnectException
@@ -65,6 +69,24 @@ object RetrofitModule {
.create(CleanAPKInterface::class.java)
}
+ /**
+ * Provides an instance of Retrofit to work with CleanAPK API
+ * @return instance of [CleanApkAppDetailApi]
+ */
+ @Singleton
+ @Provides
+ fun provideCleanAPKDetailApi(
+ okHttpClient: OkHttpClient,
+ @Named("gsonCustomAdapter") gson: Gson
+ ): CleanApkAppDetailApi {
+ return Retrofit.Builder()
+ .baseUrl(CleanAPKInterface.BASE_URL)
+ .client(okHttpClient)
+ .addConverterFactory(GsonConverterFactory.create(gson))
+ .build()
+ .create(CleanApkAppDetailApi::class.java)
+ }
+
@Singleton
@Provides
fun provideExodusApi(okHttpClient: OkHttpClient, moshi: Moshi): ExodusTrackerApi {
@@ -114,6 +136,16 @@ object RetrofitModule {
.build()
}
+ @Singleton
+ @Provides
+ @Named("gsonCustomAdapter")
+ fun getGson(): Gson {
+ return GsonBuilder()
+ .registerTypeAdapter(Application::class.java, ApplicationDeserializer())
+ .enableComplexMapKeySerialization()
+ .create()
+ }
+
/**
* Used in above [provideFdroidApi].
* Reference: https://stackoverflow.com/a/69859687
diff --git a/app/src/main/java/foundation/e/apps/api/fused/data/FusedApp.kt b/app/src/main/java/foundation/e/apps/api/fused/data/FusedApp.kt
index d48829311e7cd8a9517fabd08d35d53fe9919c3c..cf911a77e4966235ebe5f0ac73ccfdfd151636d4 100644
--- a/app/src/main/java/foundation/e/apps/api/fused/data/FusedApp.kt
+++ b/app/src/main/java/foundation/e/apps/api/fused/data/FusedApp.kt
@@ -34,6 +34,7 @@ data class FusedApp(
val last_modified: String = String(),
val latest_version_code: Int = -1,
val latest_version_number: String = String(),
+ val latest_downloaded_version: String = String(),
val licence: String = String(),
val name: String = String(),
val other_images_path: List = emptyList(),
@@ -64,4 +65,5 @@ data class FusedApp(
* Issue: https://gitlab.e.foundation/e/backlog/-/issues/5136
*/
var permsFromExodus: List = LIST_OF_NULL,
+ var updatedOn: String = String()
)
diff --git a/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt b/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt
index 14aef8e7242945c603d82b71feb484fc63b0627d..bff04df8a1b337e04368934f886a8fe9253e5934 100644
--- a/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt
+++ b/app/src/main/java/foundation/e/apps/application/ApplicationFragment.kt
@@ -209,7 +209,7 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) {
binding.infoInclude.apply {
appUpdatedOn.text = getString(
R.string.updated_on,
- if (args.origin == Origin.CLEANAPK) getString(R.string.not_available) else it.last_modified
+ if (args.origin == Origin.CLEANAPK) it.updatedOn else it.last_modified
)
appRequires.text = getString(R.string.min_android_version, notAvailable)
appVersion.text = getString(