Skip to content

Commit

Permalink
feat: cải thiện hiệu suất ứng dụng
Browse files Browse the repository at this point in the history
  • Loading branch information
nqmgaming committed Dec 8, 2024
1 parent 99cad73 commit b8d5aac
Show file tree
Hide file tree
Showing 25 changed files with 229 additions and 106 deletions.
23 changes: 23 additions & 0 deletions app/src/main/java/com/pwhs/quickmem/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.pwhs.quickmem.core.datastore.AppManager
import com.pwhs.quickmem.core.datastore.TokenManager
import com.pwhs.quickmem.presentation.StandardScaffold
import com.pwhs.quickmem.ui.theme.QuickMemTheme
import com.ramcosta.composedestinations.DestinationsNavHost
Expand All @@ -18,11 +22,15 @@ import com.ramcosta.composedestinations.generated.destinations.ExploreScreenDest
import com.ramcosta.composedestinations.generated.destinations.HomeScreenDestination
import com.ramcosta.composedestinations.generated.destinations.LibraryScreenDestination
import com.ramcosta.composedestinations.generated.destinations.ProfileScreenDestination
import com.ramcosta.composedestinations.generated.destinations.WelcomeScreenDestination
import com.ramcosta.composedestinations.rememberNavHostEngine
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
@Inject lateinit var tokenManager: TokenManager
@Inject lateinit var appManager: AppManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
Expand All @@ -38,6 +46,21 @@ class MainActivity : ComponentActivity() {

val newBackStackEntry by navController.currentBackStackEntryAsState()
val route = newBackStackEntry?.destination?.route
// check token valid when user already logged in
val token = tokenManager.accessToken.collectAsState(initial = null)
val isLogged = appManager.isLoggedIn.collectAsState(initial = false)
LaunchedEffect(key1 = token.value, key2 = isLogged.value) {
if(isLogged.value && token.value == null) {
appManager.clearAllData()
navController.navigate(WelcomeScreenDestination) {
popUpTo(NavGraphs.root) {
saveState = false
}
launchSingleTop = true
restoreState = false
}
}
}
StandardScaffold(
navController = navController,
showBottomBar = route in listOf(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.pwhs.quickmem.core.data.enums

enum class UserStatus(val status: String) {
ACTIVE(status = "ACTIVE"),
INACTIVE(status = "INACTIVE"),
BLOCKED(status = "BLOCKED"),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.pwhs.quickmem.core.interceptor

import android.content.Context
import com.pwhs.quickmem.core.datastore.TokenManager
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.runBlocking
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
import javax.inject.Inject

class AuthInterceptor @Inject constructor(
private val context: Context,
private val tokenManager: TokenManager,
) : Interceptor {

override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val response = chain.proceed(addAuthorizationHeader(request))

if (response.code == 401) {
synchronized(this) {
val newToken = runBlocking { refreshToken() }
return if (newToken != null) {
chain.proceed(addAuthorizationHeader(request, newToken))
} else {
// Log out the user
runBlocking { tokenManager.clearTokens() }
response
}
}
}

return response
}

private fun addAuthorizationHeader(request: Request, token: String? = null): Request {
val accessToken = token ?: runBlocking { tokenManager.accessToken.firstOrNull() } ?: ""
return request.newBuilder()
.header("Authorization", accessToken)
.build()
}

private suspend fun refreshToken(): String? {
// Call the refresh token API
return null
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.pwhs.quickmem.data.dto.auth

import com.google.gson.annotations.SerializedName
import com.pwhs.quickmem.core.data.enums.UserStatus

data class AuthResponseDto(
@SerializedName("id")
Expand All @@ -27,4 +28,10 @@ data class AuthResponseDto(
val isVerified: Boolean? = null,
@SerializedName("coin")
val coin: Int? = null,
@SerializedName("bannedAt")
val bannedAt: String? = null,
@SerializedName("userStatus")
val userStatus: String? = null,
@SerializedName("bannedReason")
val bannedReason: String? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,11 @@ data class GetUserProfileResponseDto(
@SerializedName("createdAt")
val createdAt: String,
@SerializedName("updatedAt")
val updatedAt: String
val updatedAt: String,
@SerializedName("bannedAt")
val bannedAt: String? = null,
@SerializedName("userStatus")
val userStatus: String? = null,
@SerializedName("bannedReason")
val bannedReason: String? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,9 @@ fun AuthResponseDto.toModel() = AuthResponseModel(
accessToken = accessToken,
refreshToken = refreshToken,
provider = provider,
isVerified = isVerified
isVerified = isVerified,
coin = coin,
bannedAt = bannedAt,
userStatus = userStatus,
bannedReason = bannedReason
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ fun GetUserProfileResponseDto.toModel() = GetUserProfileResponseModel(
avatarUrl = avatarUrl,
createdAt = createdAt,
updatedAt = updatedAt,
coin = coin
coin = coin,
bannedReason = bannedReason,
bannedAt = bannedAt,
userStatus = userStatus
)

fun GetUserProfileResponseModel.toDto() = GetUserProfileResponseDto(
Expand All @@ -24,5 +27,8 @@ fun GetUserProfileResponseModel.toDto() = GetUserProfileResponseDto(
avatarUrl = avatarUrl,
createdAt = createdAt,
updatedAt = updatedAt,
coin = coin
coin = coin,
bannedReason = bannedReason,
bannedAt = bannedAt,
userStatus = userStatus
)
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ import com.pwhs.quickmem.domain.model.users.UpdateCoinResponseModel
import com.pwhs.quickmem.domain.model.users.UserDetailResponseModel
import com.pwhs.quickmem.domain.repository.AuthRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flow
import retrofit2.HttpException
import timber.log.Timber
import javax.inject.Inject

Expand Down Expand Up @@ -92,6 +94,13 @@ class AuthRepositoryImpl @Inject constructor(
try {
val response = apiService.signUp(signUpRequestModel.toDto())
emit(Resources.Success(response.toModel()))
} catch (e: HttpException) {
if (e.code() == 409) {
emit(Resources.Error("User zalready exists"))
} else {
Timber.e(e)
emit(Resources.Error(e.toString()))
}
} catch (e: Exception) {
Timber.e(e)
emit(Resources.Error(e.toString()))
Expand Down Expand Up @@ -338,24 +347,23 @@ class AuthRepositoryImpl @Inject constructor(
username: String,
page: Int?
): Flow<PagingData<SearchUserResponseModel>> {
return flow {
if (token.isEmpty()) {
return@flow
}
Pager(
config = PagingConfig(
pageSize = 10,
enablePlaceholders = false
),
pagingSourceFactory = {
UserPagingSource(
userRemoteDataResource,
token,
username
)
}
).flow
if (token.isEmpty()) {
return emptyFlow()
}
return Pager(
config = PagingConfig(
pageSize = 10,
enablePlaceholders = false
),
pagingSourceFactory = {
UserPagingSource(
userRemoteDataResource,
token,
username
)
}
).flow

}

override suspend fun getUserProfile(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.pwhs.quickmem.domain.model.classes.UpdateClassRequestModel
import com.pwhs.quickmem.domain.model.classes.UpdateClassResponseModel
import com.pwhs.quickmem.domain.repository.ClassRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flow
import timber.log.Timber
import javax.inject.Inject
Expand Down Expand Up @@ -147,24 +148,22 @@ class ClassRepositoryImpl @Inject constructor(
title: String,
page: Int?
): Flow<PagingData<GetClassByOwnerResponseModel>> {
return flow {
if (token.isEmpty()) {
return@flow
}
Pager(
config = PagingConfig(
pageSize = 10,
enablePlaceholders = false
),
pagingSourceFactory = {
ClassPagingSource(
classRemoteDataSource,
token,
title
)
}
).flow
if (token.isEmpty()) {
return emptyFlow()
}
return Pager(
config = PagingConfig(
pageSize = 10,
enablePlaceholders = false
),
pagingSourceFactory = {
ClassPagingSource(
classRemoteDataSource,
token,
title
)
}
).flow
}

override suspend fun getClassByCode(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.pwhs.quickmem.domain.model.folder.UpdateFolderRequestModel
import com.pwhs.quickmem.domain.model.folder.UpdateFolderResponseModel
import com.pwhs.quickmem.domain.repository.FolderRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flow
import timber.log.Timber
import javax.inject.Inject
Expand Down Expand Up @@ -160,24 +161,22 @@ class FolderRepositoryImpl @Inject constructor(
title: String,
page: Int?
): Flow<PagingData<GetFolderResponseModel>> {
return flow {
if (token.isEmpty()) {
return@flow
}
Pager(
config = PagingConfig(
pageSize = 20,
enablePlaceholders = false
),
pagingSourceFactory = {
FolderPagingSource(
folderRemoteDataSource = folderRemoteDataSource,
token = token,
title = title
)
}
).flow
if (token.isEmpty()) {
return emptyFlow()
}
return Pager(
config = PagingConfig(
pageSize = 20,
enablePlaceholders = false
),
pagingSourceFactory = {
FolderPagingSource(
folderRemoteDataSource = folderRemoteDataSource,
token = token,
title = title
)
}
).flow
}

override suspend fun getFolderByLinkCode(
Expand Down
Loading

0 comments on commit b8d5aac

Please sign in to comment.