Ph0tonic/SDP_Projet

View on GitHub
app/src/main/java/ch/epfl/sdp/utils/Auth.kt

Summary

Maintainability
A
0 mins
Test Coverage
D
66%
package ch.epfl.sdp.utils

import android.app.Activity
import android.content.Intent
import android.util.Log
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import ch.epfl.sdp.MainApplication
import ch.epfl.sdp.R
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions

object Auth : ViewModel() {

    private const val RC_SIGN_IN = 9001
    private var onLoginCallback: MutableList<(Boolean) -> Unit> = mutableListOf()

    val loggedIn: MutableLiveData<Boolean> = MutableLiveData<Boolean>(false)
    val email: MutableLiveData<String> by lazy { MutableLiveData<String>() }
    val profileImageURL: MutableLiveData<String> by lazy { MutableLiveData<String>() }
    val name: MutableLiveData<String> by lazy { MutableLiveData<String>() }
    val accountId: MutableLiveData<String> by lazy { MutableLiveData<String>() }

    init {
        GoogleSignIn.getLastSignedInAccount(MainApplication.applicationContext())
                .runCatching { updateLoginStateFromAccount(this!!) }
    }

    private fun createGoogleSignClient(): GoogleSignInClient {
        val context = MainApplication.applicationContext()
        val gso = GoogleSignInOptions
                .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(context.getString(R.string.google_signin_key))
                .requestEmail()
                .build()
        return GoogleSignIn.getClient(context, gso)
    }

    /**
     *  Allow to launch the connect from a Fragment or anActivity
     *  Need to override onActivityResult and call Auth.onActivityResult
     */
    fun login(fragment: Fragment, callback: ((success: Boolean) -> Unit)? = null) {
        callback?.let { onLoginCallback.add(it) }
        fragment.startActivityForResult(createGoogleSignClient().signInIntent, RC_SIGN_IN)
    }

    fun login(activity: Activity, callback: ((success: Boolean) -> Unit)? = null) {
        callback?.let { onLoginCallback.add(it) }
        activity.startActivityForResult(createGoogleSignClient().signInIntent, RC_SIGN_IN)
    }

    fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == RC_SIGN_IN) {
            val context = MainApplication.applicationContext()
            GoogleSignIn.getSignedInAccountFromIntent(data)
                    .addOnSuccessListener {
                        updateLoginStateFromAccount(it)
                        onLoginCallback.forEach { it(true) }
                        onLoginCallback.clear()
                    }.addOnFailureListener {
                        Toast.makeText(context, context.getString(R.string.sign_in_error), Toast.LENGTH_SHORT).show()
                        onLoginCallback.forEach { it(false) }
                        onLoginCallback.clear()
                    }
        }
    }

    fun logout() {
        createGoogleSignClient().signOut().addOnSuccessListener {
            val context = MainApplication.applicationContext()
            loggedIn.postValue(false)
            Toast.makeText(context, context.getString(R.string.sign_out_success), Toast.LENGTH_SHORT).show()
        }
    }

    private fun updateLoginStateFromAccount(account: GoogleSignInAccount) {
        email.value = account.email
        name.value = account.displayName
        profileImageURL.value = account.photoUrl.toString()
        loggedIn.value = true
        accountId.value = account.id
    }
}