guarda info basica de perfiles para uso offline. Por ahora, se utiliza la info del usuario actual para mostrarla en ajustes
This commit is contained in:
parent
381274a1b6
commit
fb92a69fae
@ -1,12 +1,13 @@
|
||||
package com.isolaatti.auth
|
||||
|
||||
import com.isolaatti.auth.data.AuthRepositoryImpl
|
||||
import com.isolaatti.settings.data.KeyValueDao
|
||||
import com.isolaatti.auth.data.UserInfoRepositoryImpl
|
||||
import com.isolaatti.auth.data.local.TokenStorage
|
||||
import com.isolaatti.auth.data.local.UserInfoDao
|
||||
import com.isolaatti.auth.data.remote.AuthApi
|
||||
import com.isolaatti.auth.domain.AuthRepository
|
||||
import com.isolaatti.auth.domain.UserInfoRepository
|
||||
import com.isolaatti.connectivity.RetrofitClient
|
||||
import com.isolaatti.database.AppDatabase
|
||||
import com.isolaatti.settings.domain.UserIdSetting
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
@ -25,4 +26,9 @@ class Module {
|
||||
fun provideAuthRepository(tokenStorage: TokenStorage, authApi: AuthApi, userIdSetting: UserIdSetting): AuthRepository {
|
||||
return AuthRepositoryImpl(tokenStorage, authApi, userIdSetting)
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideUserInfoRepository(userIdSetting: UserIdSetting, userInfoDao: UserInfoDao): UserInfoRepository {
|
||||
return UserInfoRepositoryImpl(userIdSetting, userInfoDao)
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,6 @@
|
||||
package com.isolaatti.auth.data
|
||||
|
||||
import com.isolaatti.BuildConfig
|
||||
import com.isolaatti.settings.data.KeyValueDao
|
||||
import com.isolaatti.settings.data.KeyValueEntity
|
||||
import com.isolaatti.auth.data.remote.AuthTokenDto
|
||||
import com.isolaatti.auth.data.local.TokenStorage
|
||||
import com.isolaatti.auth.data.remote.AuthApi
|
||||
@ -10,8 +8,12 @@ import com.isolaatti.auth.data.remote.Credential
|
||||
import com.isolaatti.auth.domain.AuthRepository
|
||||
import com.isolaatti.settings.domain.UserIdSetting
|
||||
import com.isolaatti.utils.Resource
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.last
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.awaitResponse
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -51,8 +53,15 @@ class AuthRepositoryImpl @Inject constructor(
|
||||
return tokenStorage.token
|
||||
}
|
||||
|
||||
override fun getUserId(): Flow<Int?> = flow {
|
||||
emit(userIdSetting.getUserId())
|
||||
override fun getUserId(): Flow<Int?> {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val currentUserId = userIdSetting.getUserIdAsync()
|
||||
if(currentUserId == null) {
|
||||
validateSession()
|
||||
}
|
||||
}
|
||||
|
||||
return userIdSetting.getUserId()
|
||||
}
|
||||
|
||||
override suspend fun setToken(sessionDto: AuthTokenDto) {
|
||||
@ -60,4 +69,17 @@ class AuthRepositoryImpl @Inject constructor(
|
||||
userIdSetting.setUserId(sessionDto.userId)
|
||||
}
|
||||
|
||||
private suspend fun validateSession() {
|
||||
val token = tokenStorage.token?.token
|
||||
|
||||
if(token != null) {
|
||||
try {
|
||||
val response = authApi.validateTokenUrl(token).awaitResponse()
|
||||
if(response.isSuccessful) {
|
||||
response.body()?.userId?.let { userIdSetting.setUserId(it) }
|
||||
}
|
||||
} catch(_: Exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.isolaatti.auth.data
|
||||
|
||||
import com.isolaatti.auth.data.local.UserInfoDao
|
||||
import com.isolaatti.auth.domain.UserInfo
|
||||
import com.isolaatti.auth.domain.UserInfoRepository
|
||||
import com.isolaatti.settings.data.KeyValueDao
|
||||
import com.isolaatti.settings.domain.UserIdSetting
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emitAll
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.last
|
||||
import kotlinx.coroutines.flow.map
|
||||
import javax.inject.Inject
|
||||
|
||||
class UserInfoRepositoryImpl @Inject constructor(private val userIdSetting: UserIdSetting, private val userInfoDao: UserInfoDao) : UserInfoRepository {
|
||||
override fun getCurrentUserInfo(): Flow<UserInfo> = flow {
|
||||
val currentUserId = userIdSetting.getUserIdAsync()
|
||||
if (currentUserId != null) {
|
||||
emitAll(userInfoDao.getUserInfo(currentUserId).map { UserInfo.fromEntity(it) })
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.isolaatti.auth.data.local
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface UserInfoDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun setUserInfo(userInfoEntity: UserInfoEntity)
|
||||
|
||||
@Query("SELECT * FROM user_info WHERE id = :id LIMIT 1")
|
||||
fun getUserInfo(id: Int): Flow<UserInfoEntity>
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.isolaatti.auth.data.local
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "user_info")
|
||||
data class UserInfoEntity(
|
||||
@PrimaryKey val id: Int,
|
||||
val username: String,
|
||||
val displayName: String,
|
||||
)
|
||||
@ -1,6 +1,7 @@
|
||||
package com.isolaatti.auth.domain
|
||||
|
||||
import com.isolaatti.auth.data.remote.AuthTokenDto
|
||||
import com.isolaatti.auth.data.remote.AuthTokenVerificationDto
|
||||
import com.isolaatti.utils.Resource
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
|
||||
15
app/src/main/java/com/isolaatti/auth/domain/UserInfo.kt
Normal file
15
app/src/main/java/com/isolaatti/auth/domain/UserInfo.kt
Normal file
@ -0,0 +1,15 @@
|
||||
package com.isolaatti.auth.domain
|
||||
|
||||
import com.isolaatti.auth.data.local.UserInfoEntity
|
||||
import com.isolaatti.utils.UrlGen
|
||||
|
||||
data class UserInfo(val id: Int, val username: String, val displayName: String) {
|
||||
|
||||
val imageUrl get() = UrlGen.userProfileImage(id, false)
|
||||
|
||||
companion object {
|
||||
fun fromEntity(userInfoEntity: UserInfoEntity): UserInfo {
|
||||
return UserInfo(userInfoEntity.id, userInfoEntity.username, userInfoEntity.displayName)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.isolaatti.auth.domain
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface UserInfoRepository {
|
||||
fun getCurrentUserInfo(): Flow<UserInfo>
|
||||
}
|
||||
@ -14,6 +14,10 @@ import com.isolaatti.settings.domain.UserIdSetting
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.last
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -38,35 +42,35 @@ class BottomSheetPostOptionsViewModel @Inject constructor(private val userIdSett
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
when(options) {
|
||||
POST_OPTIONS -> {
|
||||
userIdSetting.getUserId()?.let { userId ->
|
||||
userIdSetting.getUserId().onEach { userId ->
|
||||
_options.postValue(
|
||||
Options.getPostsOptions(
|
||||
userOwned = userId == payload?.userId,
|
||||
savable = false,
|
||||
snapshotAble = false)
|
||||
userOwned = userId == payload?.userId,
|
||||
savable = false,
|
||||
snapshotAble = false)
|
||||
)
|
||||
_callerId = callerId
|
||||
_payload = payload
|
||||
}
|
||||
}.flowOn(Dispatchers.IO).launchIn(this)
|
||||
}
|
||||
COMMENT_OPTIONS -> {
|
||||
userIdSetting.getUserId()?.let { userId ->
|
||||
userIdSetting.getUserId().onEach { userId ->
|
||||
_options.postValue(
|
||||
Options.getCommentOptions(
|
||||
userOwned = userId == payload?.userId,
|
||||
savable = false,
|
||||
snapshotAble = false)
|
||||
userOwned = userId == payload?.userId,
|
||||
savable = false,
|
||||
snapshotAble = false)
|
||||
)
|
||||
_callerId = callerId
|
||||
_payload = payload
|
||||
}
|
||||
}.flowOn(Dispatchers.IO).launchIn(this)
|
||||
}
|
||||
PROFILE_PHOTO_OPTIONS -> {
|
||||
userIdSetting.getUserId()?.let { userId ->
|
||||
userIdSetting.getUserId().onEach { userId ->
|
||||
_options.postValue(Options.getProfilePhotoOptions(userOwned = userId == payload?.userId,))
|
||||
_callerId = callerId
|
||||
_payload = payload
|
||||
}
|
||||
}.flowOn(Dispatchers.IO).launchIn(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,11 +2,14 @@ package com.isolaatti.database
|
||||
|
||||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import com.isolaatti.auth.data.local.UserInfoDao
|
||||
import com.isolaatti.auth.data.local.UserInfoEntity
|
||||
import com.isolaatti.settings.data.KeyValueDao
|
||||
import com.isolaatti.settings.data.KeyValueEntity
|
||||
|
||||
@Database(entities = [KeyValueEntity::class], version = 1)
|
||||
@Database(entities = [KeyValueEntity::class, UserInfoEntity::class], version = 2)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun keyValueDao(): KeyValueDao
|
||||
abstract fun userInfoDao(): UserInfoDao
|
||||
|
||||
}
|
||||
@ -15,6 +15,8 @@ class Module {
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideAppDatabase(@ApplicationContext applicationContext: Context): AppDatabase {
|
||||
return Room.databaseBuilder(applicationContext, AppDatabase::class.java, "database.db").build()
|
||||
return Room.databaseBuilder(applicationContext, AppDatabase::class.java, "database.db")
|
||||
.fallbackToDestructiveMigration()
|
||||
.build()
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
package com.isolaatti.profile
|
||||
|
||||
import com.isolaatti.auth.data.local.UserInfoDao
|
||||
import com.isolaatti.connectivity.RetrofitClient
|
||||
import com.isolaatti.database.AppDatabase
|
||||
import com.isolaatti.profile.data.remote.ProfileApi
|
||||
import com.isolaatti.profile.data.repository.ProfileRepositoryImpl
|
||||
import com.isolaatti.profile.domain.ProfileRepository
|
||||
@ -18,7 +20,14 @@ class Module {
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideProfileRepository(profileApi: ProfileApi): ProfileRepository {
|
||||
return ProfileRepositoryImpl(profileApi)
|
||||
fun provideUserInfoDao(database: AppDatabase): UserInfoDao {
|
||||
return database.userInfoDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideProfileRepository(profileApi: ProfileApi, userInfoDao: UserInfoDao): ProfileRepository {
|
||||
return ProfileRepositoryImpl(profileApi, userInfoDao)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
package com.isolaatti.profile.data.repository
|
||||
|
||||
import android.util.Log
|
||||
import com.isolaatti.auth.data.local.UserInfoDao
|
||||
import com.isolaatti.auth.data.local.UserInfoEntity
|
||||
import com.isolaatti.images.common.domain.entity.Image
|
||||
import com.isolaatti.profile.data.remote.ProfileApi
|
||||
import com.isolaatti.profile.data.remote.UpdateProfileDto
|
||||
@ -12,13 +14,17 @@ import kotlinx.coroutines.flow.flow
|
||||
import retrofit2.awaitResponse
|
||||
import javax.inject.Inject
|
||||
|
||||
class ProfileRepositoryImpl @Inject constructor(private val profileApi: ProfileApi) : ProfileRepository {
|
||||
class ProfileRepositoryImpl @Inject constructor(
|
||||
private val profileApi: ProfileApi,
|
||||
private val userInfoDao: UserInfoDao) : ProfileRepository {
|
||||
override fun getProfile(userId: Int): Flow<Resource<UserProfile>> = flow {
|
||||
try {
|
||||
val result = profileApi.userProfile(userId).awaitResponse()
|
||||
if(result.isSuccessful) {
|
||||
val dto = result.body()
|
||||
if(dto != null) {
|
||||
userInfoDao.setUserInfo(UserInfoEntity(userId, dto.uniqueUsername, dto.name))
|
||||
|
||||
emit(Resource.Success(UserProfile.fromDto(dto)))
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -4,12 +4,16 @@ import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface KeyValueDao {
|
||||
@Query("SELECT value FROM key_values WHERE id = :key")
|
||||
suspend fun getValue(key: String): String
|
||||
fun getValue(key: String): Flow<String>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun setValue(entity: KeyValueEntity)
|
||||
|
||||
@Query("SELECT value FROM key_values WHERE id = :key")
|
||||
suspend fun getValueAsync(key: String): String?
|
||||
}
|
||||
@ -1,13 +1,18 @@
|
||||
package com.isolaatti.settings.data
|
||||
|
||||
import com.isolaatti.settings.domain.SettingsRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class SettingsRepositoryImpl(private val keyValueDao: KeyValueDao) : SettingsRepository {
|
||||
override suspend fun setKeyValue(key: String, value: String) {
|
||||
keyValueDao.setValue(KeyValueEntity(key, value))
|
||||
}
|
||||
|
||||
override suspend fun getKeyValue(key: String): String? {
|
||||
override fun getKeyValue(key: String): Flow<String?> {
|
||||
return keyValueDao.getValue(key)
|
||||
}
|
||||
|
||||
override suspend fun getKeyValueAsync(key: String): String? {
|
||||
return keyValueDao.getValueAsync(key)
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,10 @@
|
||||
package com.isolaatti.settings.domain
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface SettingsRepository {
|
||||
suspend fun setKeyValue(key: String, value: String)
|
||||
suspend fun getKeyValue(key: String): String?
|
||||
fun getKeyValue(key: String): Flow<String?>
|
||||
|
||||
suspend fun getKeyValueAsync(key: String): String?
|
||||
}
|
||||
@ -2,11 +2,16 @@ package com.isolaatti.settings.domain
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import javax.inject.Inject
|
||||
|
||||
class UserIdSetting @Inject constructor(private val settingsRepository: SettingsRepository) {
|
||||
suspend fun getUserId(): Int? {
|
||||
return settingsRepository.getKeyValue(KEY_USER_ID)?.toIntOrNull()
|
||||
fun getUserId(): Flow<Int?> {
|
||||
return settingsRepository.getKeyValue(KEY_USER_ID).map { it?.toIntOrNull() }
|
||||
}
|
||||
|
||||
suspend fun getUserIdAsync(): Int? {
|
||||
return settingsRepository.getKeyValueAsync(KEY_USER_ID)?.toIntOrNull()
|
||||
}
|
||||
|
||||
suspend fun setUserId(userId: Int) {
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
package com.isolaatti.settings.presentation
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.isolaatti.auth.domain.UserInfo
|
||||
import com.isolaatti.auth.domain.UserInfoRepository
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class SettingsViewModel @Inject constructor(private val userInfoRepository: UserInfoRepository) : ViewModel() {
|
||||
val userInfo: MutableLiveData<UserInfo> = MutableLiveData()
|
||||
fun getUserInfo() {
|
||||
viewModelScope.launch {
|
||||
userInfoRepository.getCurrentUserInfo().onEach {
|
||||
userInfo.postValue(it)
|
||||
}.flowOn(Dispatchers.IO).launchIn(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,11 +5,17 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import coil.load
|
||||
import com.isolaatti.databinding.FragmentSettingsBinding
|
||||
import com.isolaatti.settings.presentation.SettingsViewModel
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class SettingsFragment : Fragment() {
|
||||
private lateinit var binding: FragmentSettingsBinding
|
||||
private val viewModel: SettingsViewModel by viewModels()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@ -25,6 +31,16 @@ class SettingsFragment : Fragment() {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
setupListeners()
|
||||
setupObservers()
|
||||
viewModel.getUserInfo()
|
||||
}
|
||||
|
||||
private fun setupObservers() {
|
||||
viewModel.userInfo.observe(viewLifecycleOwner) {
|
||||
binding.textViewUsername.text = "@${it.username}"
|
||||
binding.textViewDisplayName.text = it.displayName
|
||||
binding.profileImageView.load(it.imageUrl)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupListeners() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user