Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP/Don't Merge] Migrated Profile from Rxjava to Retroift & added MVVM Architecture (part 1) #6082

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this should I provide kdoc here? and if yes kdoc should I link the common apps API endpoint doc or provide a CURL link here?

@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
Loading