Skip to content

Commit

Permalink
Migrated from Rxjava to Retroift, added MVVM Architecture.
Browse files Browse the repository at this point in the history
  • Loading branch information
neeldoshii committed Dec 26, 2024
1 parent f1e8e48 commit 614892c
Show file tree
Hide file tree
Showing 10 changed files with 302 additions and 203 deletions.
17 changes: 16 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,26 @@ dependencies {
implementation 'com.karumi:dexter:5.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

def lifecycle_version = "2.8.7"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// ViewModel utilities for Compose
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"

// Lifecycles only (without ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
// Lifecycle utilities for Compose
implementation "androidx.lifecycle:lifecycle-runtime-compose:$lifecycle_version"

// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"

// Annotation processor
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// Jetpack Compose
def composeBom = platform('androidx.compose:compose-bom:2024.11.00')

implementation "androidx.activity:activity-compose:1.9.3"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.4"
implementation (composeBom)
implementation "androidx.compose.runtime:runtime"
implementation "androidx.compose.ui:ui"
Expand Down
29 changes: 29 additions & 0 deletions app/src/main/java/fr/free/nrw/commons/di/NetworkingModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import fr.free.nrw.commons.media.PageMediaInterface
import fr.free.nrw.commons.media.WikidataMediaInterface
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
import fr.free.nrw.commons.mwapi.UserInterface
import fr.free.nrw.commons.network.APIService
import fr.free.nrw.commons.notification.NotificationInterface
import fr.free.nrw.commons.review.ReviewInterface
import fr.free.nrw.commons.upload.UploadInterface
Expand All @@ -42,6 +43,8 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.logging.HttpLoggingInterceptor.Level
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import timber.log.Timber
import java.io.File
import java.util.concurrent.TimeUnit
Expand Down Expand Up @@ -295,6 +298,32 @@ class NetworkingModule {
fun provideLanguageWikipediaSite(): WikiSite =
WikiSite.forDefaultLocaleLanguageCode()

@Provides
@Named("tool_wmflabs_base_url")
fun provideToolWmflabsBaseUrl() : HttpUrl =
"https://tools.wmflabs.org/commons-android-app/tool-commons-android-app/".toHttpUrlOrNull()!!

@Singleton
@Provides
@Named("tool_wmflabs_retrofit")
fun provideToolWmflabsBaseUrlRetrofit(
@Named("tool_wmflabs_base_url") baseUrl: HttpUrl,
okHttpClient: OkHttpClient
) : Retrofit {
return Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
// .addCallAdapterFactory(CoroutineCallAdapterFactory())
.build()
}

@Provides
@Singleton
fun provideAPIService(
@Named("tool_wmflabs_retrofit") retrofit: Retrofit
): APIService = retrofit.create(APIService::class.java)

companion object {
private const val WIKIDATA_SPARQL_QUERY_URL = "https://query.wikidata.org/sparql"
private const val TOOLS_FORGE_URL =
Expand Down
23 changes: 23 additions & 0 deletions app/src/main/java/fr/free/nrw/commons/network/APIService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package fr.free.nrw.commons.network

import fr.free.nrw.commons.profile.model.AchievementResponse
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Query


interface APIService {

// https://tools.wmflabs.org/commons-android-app/tool-commons-android-app/uploadsbyuser.py?user=Devanonymous
@GET("uploadsbyuser.py")
suspend fun getImageUploadCount(
@Query("user") username : String
) : Response<Int>


// https://tools.wmflabs.org/commons-android-app/tool-commons-android-app//feedback.py?user=Devanonymous
@GET("feedback.py")
suspend fun getUserAchievements(
@Query("user") username: String
) : Response<AchievementResponse>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package fr.free.nrw.commons.profile.achievements

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import fr.free.nrw.commons.profile.model.UserAchievements
import fr.free.nrw.commons.repository.ProfileRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

class AchievementViewModel @Inject constructor(
private val repository: ProfileRepository
) : ViewModel() {

private val _achievements = MutableStateFlow(UserAchievements(
LevelController.LevelInfo.LEVEL_1,
articlesUsingImagesCount = 0,
thanksReceivedCount = 0,
featuredImagesCount = 0,
qualityImagesCount = 0,
imagesUploadedCount = 0,
revertedCount = 0,
uniqueImagesCount = 0,
imagesEditedBySomeoneElseCount = 0
)
)
val achievements : StateFlow<UserAchievements> = _achievements

private val _loading = MutableStateFlow(true)
val loading : StateFlow<Boolean> = _loading

fun getUserAchievements(username: String){
viewModelScope.launch {
repository.getUserLevel(username = username).collect {
_loading.value = false
_achievements.value = it
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package fr.free.nrw.commons.profile.achievements

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import javax.inject.Inject
import javax.inject.Provider

/**
* This class extends the ViewModelProvider.Factory and creates a ViewModelFactory class
* for AchievementViewModel
*/
class AchievementViewModelFactory @Inject constructor(
private val viewModelProvider: Provider<AchievementViewModel>
): ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(AchievementViewModel::class.java)) {
(@Suppress("UNCHECKED_CAST")
return viewModelProvider.get() as T)
} else {
throw IllegalArgumentException("Unknown class name")
}
}
}
Loading

0 comments on commit 614892c

Please sign in to comment.