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
Expand Up @@ -13,7 +13,10 @@ interface RepoDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(repo: RepoEntity)

@Query("DELETE FROM repositories WHERE id = :id")
suspend fun delete(id: Int)

@Query("SELECT * FROM repositories")
fun getAll(): Flow<List<RepoEntity>>

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ interface RepoLocalDataSource {
suspend fun save(repo: RepoEntity)

fun getAll(): Flow<List<RepoEntity>>

suspend fun delete(id: Int)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ class RepoLocalDataSourceImpl(

override fun getAll(): Flow<List<RepoEntity>> =
dao.getAll()

override suspend fun delete(id: Int) {
dao.delete(id)
}
}
14 changes: 12 additions & 2 deletions app/src/main/java/com/delecrode/devhub/data/mapper/UserMapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package com.delecrode.devhub.data.mapper

import com.delecrode.devhub.data.model.dto.UserForFirebaseDto
import com.delecrode.devhub.data.model.dto.UserForGitDto
import com.delecrode.devhub.domain.model.UserAuth
import com.delecrode.devhub.domain.model.UserForFirebase
import com.delecrode.devhub.domain.model.UserForGit
import com.google.firebase.auth.FirebaseUser

fun UserForGitDto.toUserDomain(): UserForGit {
fun UserForGitDto.toUserGitDomain(): UserForGit {
return UserForGit(
login = login,
avatar_url = avatar_url,
Expand All @@ -17,10 +19,18 @@ fun UserForGitDto.toUserDomain(): UserForGit {
}


fun UserForFirebaseDto.toUserDomain(): UserForFirebase{
fun UserForFirebaseDto.toUserFirebaseDomain(): UserForFirebase{
return UserForFirebase(
fullName = fullName,
username = username,
email = email
)
}

fun FirebaseUser.toUserAuthDomain(): UserAuth =
UserAuth(
uid = uid,
email = email
)


Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ data class UserForFirebaseDto(
val fullName: String = "",
val username: String = "",
val email: String = ""
)
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.delecrode.devhub.data.remote.firebase

import android.util.Log
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import kotlin.coroutines.resume
Expand Down Expand Up @@ -43,4 +44,21 @@ class FirebaseAuth(
fun signOut() {
auth.signOut()
}

suspend fun forgotPassword(email: String) {
Log.i("ForgotPasswordScreen", "forgotPassword: $email")
suspendCoroutine<Unit> { cont ->
auth.sendPasswordResetEmail(email)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
cont.resume(Unit)
} else {
cont.resumeWithException(
task.exception ?: Exception("Erro ao enviar e-mail de recuperação")
)
}
}
}
}

}
Original file line number Diff line number Diff line change
@@ -1,47 +1,48 @@
package com.delecrode.devhub.data.repository

import com.delecrode.devhub.data.local.dataStore.AuthLocalDataSource
import com.delecrode.devhub.data.mapper.toUserAuthDomain
import com.delecrode.devhub.data.remote.firebase.FirebaseAuth
import com.delecrode.devhub.data.remote.firebase.UserExtraData
import com.delecrode.devhub.domain.model.RegisterUser
import com.delecrode.devhub.domain.model.UserAuth
import com.delecrode.devhub.domain.repository.AuthRepository
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException
import com.google.firebase.auth.FirebaseAuthInvalidUserException
import com.google.firebase.auth.FirebaseAuthUserCollisionException
import com.google.firebase.auth.FirebaseAuthWeakPasswordException
import com.google.firebase.auth.FirebaseUser
import com.delecrode.devhub.utils.Result
import com.delecrode.devhub.utils.mapAuthError
import com.delecrode.devhub.utils.mapSignUpError

class AuthRepositoryImpl(
private val authDataSource: FirebaseAuth,
private val userExtraDataSource: UserExtraData,
private val authLocalDataSource: AuthLocalDataSource
) : AuthRepository {

override suspend fun signIn(email: String, password: String): FirebaseUser {
try {
val response = authDataSource.signIn(email, password)
authLocalDataSource.saveUID(response?.uid ?: "")
return response ?: throw Exception("Erro ao recuperar usuário após login")
override suspend fun signIn(
email: String,
password: String
): Result<UserAuth> {
return try {
val firebaseUser = authDataSource.signIn(email, password)
?: return Result.Error("Erro ao autenticar usuário")
authLocalDataSource.saveUID(firebaseUser.uid)

Result.Success(firebaseUser.toUserAuthDomain())

} catch (e: Exception) {
val errorMessage = when (e) {
is FirebaseAuthInvalidUserException -> "Usuário não encontrado."
is FirebaseAuthInvalidCredentialsException -> "Senha incorreta ou e-mail inválido."
is FirebaseAuthUserCollisionException -> "Este e-mail já está em uso."
is FirebaseAuthWeakPasswordException -> "A senha deve ter pelo menos 6 caracteres."
else -> e.message ?: "Erro desconhecido ao fazer login"
}
throw Exception(errorMessage)
Result.Error(mapAuthError(e))
}
}


override suspend fun signUp(
name: String,
username: String,
email: String,
password: String
): Boolean {
try {
val uid = authDataSource.signUp(email, password) ?: return false
): Result<Unit> {
return try {
val uid = authDataSource.signUp(email, password)
?: return Result.Error("Erro ao criar conta")

val userData = RegisterUser(
fullName = name,
Expand All @@ -51,18 +52,24 @@ class AuthRepositoryImpl(

userExtraDataSource.saveUserData(uid, userData)

return true
Result.Success(Unit)

} catch (e: Exception) {
val errorMessage = when (e) {
is FirebaseAuthUserCollisionException -> "Este e-mail já está em uso."
is FirebaseAuthWeakPasswordException -> "A senha deve ter pelo menos 6 caracteres."
is FirebaseAuthInvalidCredentialsException -> "E-mail inválido."
else -> e.message ?: "Erro desconhecido ao cadastrar"
}
throw Exception(errorMessage)
Result.Error(mapSignUpError(e))
}
}

override suspend fun forgotPassword(email: String): Result<Unit> {
return try {
authDataSource.forgotPassword(email)
Result.Success(Unit)

} catch (e: Exception) {
Result.Error(mapAuthError(e))
}
}


override suspend fun signOut() {
authDataSource.signOut()
authLocalDataSource.clearUID()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,51 +11,67 @@ import com.delecrode.devhub.domain.model.Languages
import com.delecrode.devhub.domain.model.RepoDetail
import com.delecrode.devhub.domain.model.RepoFav
import com.delecrode.devhub.domain.repository.RepoRepository
import com.delecrode.devhub.utils.Result
import com.delecrode.devhub.utils.mapHttpError
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import java.io.IOException

class RepoRepositoryImpl(val repoApi: RepoApiService, private val localDataSource: RepoLocalDataSource, private val authLocalDataSource: AuthLocalDataSource) : RepoRepository {
class RepoRepositoryImpl(
val repoApi: RepoApiService,
private val localDataSource: RepoLocalDataSource,
private val authLocalDataSource: AuthLocalDataSource
) : RepoRepository {

override suspend fun save(repo: RepoFav) {
localDataSource.save(repo.toEntity())
}

override suspend fun delete(id: Int){
localDataSource.delete(id)
}

override fun getAll(): Flow<List<RepoFav>> =
localDataSource.getAll()
.map { list -> list.map { it.toDomain() } }

override fun getUserName(): Flow<String?> =
authLocalDataSource.getUserName()

override suspend fun getRepoDetail(owner: String, repo: String): RepoDetail {
try {
override suspend fun getRepoDetail(owner: String, repo: String): Result<RepoDetail> {
return try {
val response = repoApi.getRepoDetail(owner, repo)
if (response.isSuccessful) {
val body = response.body()
if (body != null) {
return body.toRepoDetailDomain()
} else {
throw Exception("Resposta vazia do servidor")
}
?: return Result.Error("Dados do repositório indisponíveis")
Result.Success(body.toRepoDetailDomain())
} else {
throw Exception("Erro na requisição ${response.code()}")
Result.Error(mapHttpError(response.code()))
}
} catch (e: Exception) {
throw e
} catch (e: IOException) {
Result.Error("Sem conexão com a internet")
}
}

override suspend fun getLanguagesRepo(owner: String, repo: String) : Languages{
override suspend fun getLanguagesRepo(
owner: String,
repo: String
): Result<Languages> {
return try {
val response = repoApi.getRepoLanguages(owner, repo)

if (response.isSuccessful) {
val body = response.body()
body?.toLanguagesDomain() ?: Languages(emptyList())
?: return Result.Error("Linguagens indisponíveis")

Result.Success(body.toLanguagesDomain())
} else {
Languages(emptyList())
Result.Error(mapHttpError(response.code()))
}
} catch (e: Exception) {
Languages(emptyList())

} catch (e: IOException) {
Result.Error("Sem conexão com a internet")
}
}

}
Loading