Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
package com.teampatch.core.data.di

import com.teampatch.core.data.di.annotation.CoroutineDispatcher
import com.teampatch.core.data.di.annotation.DispatcherContext
import com.teampatch.core.data.di.annotation.DispatchersContext
import com.teampatch.core.data.di.annotation.HarmonyDispatcher
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob

@Module
@InstallIn(SingletonComponent::class)
internal object CoroutineModule {

@CoroutineDispatcher(DispatcherContext.Default)
@HarmonyDispatcher(DispatchersContext.Default)
@Provides
fun providesDefaultCoroutine(): CoroutineScope = CoroutineScope(context = SupervisorJob() + Dispatchers.Default)
fun providesDefaultCoroutine(): CoroutineDispatcher = Dispatchers.Default

@CoroutineDispatcher(DispatcherContext.IO)
@HarmonyDispatcher(DispatchersContext.IO)
@Provides
fun providesIoCoroutine(): CoroutineScope = CoroutineScope(context = SupervisorJob() + Dispatchers.IO)

@CoroutineDispatcher(DispatcherContext.Main)
@Provides
fun providesMainCoroutine(): CoroutineScope = CoroutineScope(context = SupervisorJob() + Dispatchers.Main)
fun providesIoCoroutine(): CoroutineDispatcher = Dispatchers.IO
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import javax.inject.Qualifier

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class CoroutineDispatcher(val dispatcherContext: DispatcherContext)
annotation class HarmonyDispatcher(val dispatchersContext: DispatchersContext)

enum class DispatcherContext {
enum class DispatchersContext {
Default,
IO,
Main,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.teampatch.core.data.model

data class MediaStoreInfo(
val displayName: String,
val mimType: String,
val size: Long,
)
Original file line number Diff line number Diff line change
@@ -1,28 +1,71 @@
package com.teampatch.core.data.repository.local

import android.content.Context
import android.net.Uri
import android.webkit.MimeTypeMap
import androidx.core.net.toUri
import com.harmony.core.database.dao.UserDao
import com.harmony.core.database.model.UserEntity
import com.teampatch.core.data.di.annotation.DispatchersContext
import com.teampatch.core.data.di.annotation.HarmonyDispatcher
import com.teampatch.core.data.mapper.MEMBER
import com.teampatch.core.data.mapper.VIP
import com.teampatch.core.data.mapper.toDomain
import com.teampatch.core.data.utils.getMediaStoreInfo
import com.teampatch.core.domain.entity.SocialLoginHelper
import com.teampatch.core.domain.model.Role
import com.teampatch.core.domain.model.User
import com.teampatch.core.domain.repository.UserRepository
import dagger.hilt.android.qualifiers.ApplicationContext
import java.io.File
import java.io.FileOutputStream
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext

internal class LocalUserRepositoryImpl @Inject constructor(
private val userDao: UserDao,
private val socialLoginHelper: SocialLoginHelper,
@ApplicationContext private val appContext: Context,
@HarmonyDispatcher(DispatchersContext.IO) private val ioDispatcher: CoroutineDispatcher,
) : UserRepository {

private val profileImageFolder: File by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
File("${appContext.dataDir.absolutePath}/profile_image")
.also { it.mkdirs() }
}

override fun getUserInfo(): Flow<User> = userDao.getMyUserData().map {
it.toDomain()
}

override suspend fun editProfile(name: String?, profileImageUri: String?) {
val processedProfileImageUri: Uri? = profileImageUri?.toUri()?.let {
withContext(ioDispatcher) {
val contentResolver = appContext.contentResolver
val mediaStoreInfo = contentResolver.getMediaStoreInfo(it)
val mimeTypeMap = MimeTypeMap.getSingleton()
val fileExtension = mimeTypeMap.getExtensionFromMimeType(mediaStoreInfo?.mimType)

contentResolver.openInputStream(it)?.use { profileImageInputStream ->
val file = File.createTempFile("profile_image", ".$fileExtension", profileImageFolder)
FileOutputStream(file).use {
it.write(profileImageInputStream.readBytes())
}
file.toUri()
}
}
}

val userEntity = userDao.getMyUserData().first()
val updateUserEntity = userEntity.copy(
name = name ?: userEntity.name,
profileImageUri = processedProfileImageUri?.toString() ?: userEntity.profileImageUri
)
userDao.updateUser(updateUserEntity)
}

override suspend fun addUserProfile(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.teampatch.core.data.utils

import android.content.ContentResolver
import android.net.Uri
import android.provider.MediaStore
import com.teampatch.core.data.model.MediaStoreInfo

internal fun ContentResolver.getMediaStoreInfo(uri: Uri): MediaStoreInfo? {
query(
uri,
arrayOf(
MediaStore.MediaColumns.DISPLAY_NAME,
MediaStore.MediaColumns.MIME_TYPE,
MediaStore.MediaColumns.SIZE
),
null,
null,
null
)?.use { cursor ->
cursor.moveToFirst()
val fileName = cursor.getString(0)
val fileMediaType = cursor.getString(1)
val fileSize = cursor.getLong(2)

return MediaStoreInfo(
displayName = fileName,
mimType = fileMediaType,
size = fileSize
)
}

return null
}