diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/DirectCallActivity.kt b/demo-app/src/main/kotlin/io/getstream/video/android/DirectCallActivity.kt index c2d0393b34..0d3da53a37 100644 --- a/demo-app/src/main/kotlin/io/getstream/video/android/DirectCallActivity.kt +++ b/demo-app/src/main/kotlin/io/getstream/video/android/DirectCallActivity.kt @@ -112,7 +112,6 @@ class DirectCallActivity : ComponentActivity() { } is CancelCall -> { lifecycleScope.launch { - val test = call.reject() call.leave() finish() } diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/data/repositories/GoogleAccountRepository.kt b/demo-app/src/main/kotlin/io/getstream/video/android/data/repositories/GoogleAccountRepository.kt index 4d86f86bc3..9e327ebc0f 100644 --- a/demo-app/src/main/kotlin/io/getstream/video/android/data/repositories/GoogleAccountRepository.kt +++ b/demo-app/src/main/kotlin/io/getstream/video/android/data/repositories/GoogleAccountRepository.kt @@ -21,6 +21,7 @@ import android.util.Log import com.google.android.gms.auth.GoogleAuthUtil 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.squareup.moshi.JsonAdapter import com.squareup.moshi.Moshi import com.squareup.moshi.adapter @@ -29,7 +30,6 @@ import dagger.hilt.android.qualifiers.ApplicationContext import io.getstream.video.android.data.dto.GetGoogleAccountsResponseDto import io.getstream.video.android.data.dto.asDomainModel import io.getstream.video.android.models.GoogleAccount -import io.getstream.video.android.util.GoogleSignInHelper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.tasks.await import kotlinx.coroutines.withContext @@ -40,6 +40,7 @@ import javax.inject.Inject class GoogleAccountRepository @Inject constructor( @ApplicationContext private val context: Context, + private val googleSignInClient: GoogleSignInClient, ) { private val baseUrl = "https://people.googleapis.com/v1/people:listDirectoryPeople" @@ -76,8 +77,7 @@ class GoogleAccountRepository @Inject constructor( } private suspend fun signInSilently(): Boolean { - val gsc = GoogleSignInHelper.getGoogleSignInClient(context) - val task = gsc.silentSignIn() + val task = googleSignInClient.silentSignIn() return if (task.isSuccessful) { Log.d("Google Silent Sign In", "Successful") diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/di/AppModule.kt b/demo-app/src/main/kotlin/io/getstream/video/android/di/AppModule.kt index fe3e20bca3..01404b2319 100644 --- a/demo-app/src/main/kotlin/io/getstream/video/android/di/AppModule.kt +++ b/demo-app/src/main/kotlin/io/getstream/video/android/di/AppModule.kt @@ -17,10 +17,15 @@ package io.getstream.video.android.di import android.content.Context +import com.google.android.gms.auth.api.signin.GoogleSignIn +import com.google.android.gms.auth.api.signin.GoogleSignInClient +import com.google.android.gms.auth.api.signin.GoogleSignInOptions +import com.google.android.gms.common.api.Scope import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent +import io.getstream.video.android.R import io.getstream.video.android.data.repositories.GoogleAccountRepository import io.getstream.video.android.datastore.delegate.StreamUserDataStore import javax.inject.Singleton @@ -35,8 +40,20 @@ object AppModule { return StreamUserDataStore.instance() } + @Provides + @Singleton + fun provideGoogleSignInClient( + @ApplicationContext context: Context, + ): GoogleSignInClient = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) + .requestEmail() + .requestIdToken(context.getString(R.string.default_web_client_id)) + .requestScopes(Scope("https://www.googleapis.com/auth/directory.readonly")) + .build() + .let { gso -> GoogleSignIn.getClient(context, gso) } + @Provides fun provideGoogleAccountRepository( @ApplicationContext context: Context, - ) = GoogleAccountRepository(context) + googleSignInClient: GoogleSignInClient, + ) = GoogleAccountRepository(context, googleSignInClient) } diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/models/StreamUser.kt b/demo-app/src/main/kotlin/io/getstream/video/android/models/StreamUser.kt deleted file mode 100644 index 1dbb21bc8a..0000000000 --- a/demo-app/src/main/kotlin/io/getstream/video/android/models/StreamUser.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2014-2023 Stream.io Inc. All rights reserved. - * - * Licensed under the Stream License; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://github.com/GetStream/stream-video-android/blob/main/LICENSE - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.getstream.video.android.models - -data class StreamUser( - val email: String, - val id: String, - val name: String, - val avatarUrl: String?, - val isFavorite: Boolean, -) diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/ui/join/CallJoinScreen.kt b/demo-app/src/main/kotlin/io/getstream/video/android/ui/join/CallJoinScreen.kt index 40b257c74a..1e6d07e2ec 100644 --- a/demo-app/src/main/kotlin/io/getstream/video/android/ui/join/CallJoinScreen.kt +++ b/demo-app/src/main/kotlin/io/getstream/video/android/ui/join/CallJoinScreen.kt @@ -75,6 +75,8 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel +import com.google.android.gms.auth.api.signin.GoogleSignIn +import com.google.android.gms.auth.api.signin.GoogleSignInOptions import io.getstream.video.android.BuildConfig import io.getstream.video.android.R import io.getstream.video.android.compose.theme.VideoTheme @@ -82,6 +84,7 @@ import io.getstream.video.android.compose.ui.components.avatar.UserAvatar import io.getstream.video.android.datastore.delegate.StreamUserDataStore import io.getstream.video.android.mock.StreamPreviewDataUtils import io.getstream.video.android.mock.previewUsers +import io.getstream.video.android.model.User import io.getstream.video.android.tooling.util.StreamFlavors import io.getstream.video.android.ui.theme.Colors import io.getstream.video.android.ui.theme.StreamButton @@ -95,6 +98,8 @@ fun CallJoinScreen( navigateToBarcodeScanner: () -> Unit = {}, ) { val uiState by callJoinViewModel.uiState.collectAsState(CallJoinUiState.Nothing) + val user by callJoinViewModel.user.collectAsState(initial = null) + var isSignOutDialogVisible by remember { mutableStateOf(false) } val isLoggedOut by callJoinViewModel.isLoggedOut.collectAsState(initial = false) @@ -111,8 +116,8 @@ fun CallJoinScreen( horizontalAlignment = Alignment.CenterHorizontally, ) { CallJoinHeader( + user = user, onAvatarLongClick = { isSignOutDialogVisible = true }, - callJoinViewModel = callJoinViewModel, onDirectCallClick = navigateToDirectCallJoin, onSignOutClick = { callJoinViewModel.autoLogInAfterLogOut = false @@ -173,13 +178,11 @@ private fun HandleCallJoinUiState( @OptIn(ExperimentalFoundationApi::class) @Composable private fun CallJoinHeader( - callJoinViewModel: CallJoinViewModel = hiltViewModel(), + user: User?, onAvatarLongClick: () -> Unit, onDirectCallClick: () -> Unit, onSignOutClick: () -> Unit, ) { - val user by callJoinViewModel.user.collectAsState(initial = null) - Row( modifier = Modifier .fillMaxWidth() @@ -442,7 +445,13 @@ private fun CallJoinScreenPreview() { VideoTheme { StreamUserDataStore.install(LocalContext.current) CallJoinScreen( - callJoinViewModel = CallJoinViewModel(StreamUserDataStore.instance()), + callJoinViewModel = CallJoinViewModel( + dataStore = StreamUserDataStore.instance(), + googleSignInClient = GoogleSignIn.getClient( + LocalContext.current, + GoogleSignInOptions.Builder().build(), + ), + ), navigateToCallLobby = {}, navigateUpToLogin = {}, navigateToDirectCallJoin = {}, diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/ui/join/CallJoinViewModel.kt b/demo-app/src/main/kotlin/io/getstream/video/android/ui/join/CallJoinViewModel.kt index b122a2e7df..826ff4d0e9 100644 --- a/demo-app/src/main/kotlin/io/getstream/video/android/ui/join/CallJoinViewModel.kt +++ b/demo-app/src/main/kotlin/io/getstream/video/android/ui/join/CallJoinViewModel.kt @@ -18,7 +18,7 @@ package io.getstream.video.android.ui.join import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.google.firebase.auth.FirebaseAuth +import com.google.android.gms.auth.api.signin.GoogleSignInClient import dagger.hilt.android.lifecycle.HiltViewModel import io.getstream.chat.android.client.ChatClient import io.getstream.video.android.core.Call @@ -43,6 +43,7 @@ import javax.inject.Inject @HiltViewModel class CallJoinViewModel @Inject constructor( private val dataStore: StreamUserDataStore, + private val googleSignInClient: GoogleSignInClient, ) : ViewModel() { val user: Flow = dataStore.user val isLoggedOut = dataStore.user.map { it == null } @@ -97,7 +98,7 @@ class CallJoinViewModel @Inject constructor( fun logOut() { viewModelScope.launch { - FirebaseAuth.getInstance().signOut() + googleSignInClient.signOut() dataStore.clear() StreamVideo.instance().logOut() ChatClient.instance().disconnect(true).enqueue() diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/ui/lobby/CallLobbyScreen.kt b/demo-app/src/main/kotlin/io/getstream/video/android/ui/lobby/CallLobbyScreen.kt index 5703b8979b..5d6c0ac4dc 100644 --- a/demo-app/src/main/kotlin/io/getstream/video/android/ui/lobby/CallLobbyScreen.kt +++ b/demo-app/src/main/kotlin/io/getstream/video/android/ui/lobby/CallLobbyScreen.kt @@ -59,6 +59,8 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.SavedStateHandle +import com.google.android.gms.auth.api.signin.GoogleSignIn +import com.google.android.gms.auth.api.signin.GoogleSignInOptions import io.getstream.video.android.BuildConfig import io.getstream.video.android.R import io.getstream.video.android.compose.theme.VideoTheme @@ -322,6 +324,10 @@ private fun CallLobbyScreenPreview() { mapOf("cid" to "default:123"), ), dataStore = StreamUserDataStore.instance(), + googleSignInClient = GoogleSignIn.getClient( + LocalContext.current, + GoogleSignInOptions.Builder().build(), + ), ), ) {} } diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/ui/lobby/CallLobbyViewModel.kt b/demo-app/src/main/kotlin/io/getstream/video/android/ui/lobby/CallLobbyViewModel.kt index a56c6e4465..a9e804e270 100644 --- a/demo-app/src/main/kotlin/io/getstream/video/android/ui/lobby/CallLobbyViewModel.kt +++ b/demo-app/src/main/kotlin/io/getstream/video/android/ui/lobby/CallLobbyViewModel.kt @@ -20,7 +20,7 @@ import android.util.Log import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.google.firebase.auth.FirebaseAuth +import com.google.android.gms.auth.api.signin.GoogleSignInClient import dagger.hilt.android.lifecycle.HiltViewModel import io.getstream.chat.android.client.ChatClient import io.getstream.video.android.core.Call @@ -49,6 +49,7 @@ import javax.inject.Inject class CallLobbyViewModel @Inject constructor( savedStateHandle: SavedStateHandle, private val dataStore: StreamUserDataStore, + private val googleSignInClient: GoogleSignInClient, ) : ViewModel() { private val cid: String = checkNotNull(savedStateHandle["cid"]) @@ -167,7 +168,7 @@ class CallLobbyViewModel @Inject constructor( fun signOut() { viewModelScope.launch { - FirebaseAuth.getInstance().signOut() + googleSignInClient.signOut() dataStore.clear() StreamVideo.instance().logOut() ChatClient.instance().disconnect(true).enqueue() diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/ui/login/LoginScreen.kt b/demo-app/src/main/kotlin/io/getstream/video/android/ui/login/LoginScreen.kt index 74ee02b6ed..a4e45c7e4b 100644 --- a/demo-app/src/main/kotlin/io/getstream/video/android/ui/login/LoginScreen.kt +++ b/demo-app/src/main/kotlin/io/getstream/video/android/ui/login/LoginScreen.kt @@ -72,7 +72,6 @@ import io.getstream.video.android.ui.theme.Colors import io.getstream.video.android.ui.theme.LinkText import io.getstream.video.android.ui.theme.LinkTextData import io.getstream.video.android.ui.theme.StreamButton -import io.getstream.video.android.util.GoogleSignInHelper import io.getstream.video.android.util.UserHelper /** @@ -344,9 +343,7 @@ private fun HandleLoginUiStates( LaunchedEffect(key1 = loginUiState) { when (loginUiState) { is LoginUiState.GoogleSignIn -> { - signInLauncher.launch( - GoogleSignInHelper.getGoogleSignInClient(context).signInIntent, - ) + signInLauncher.launch(loginUiState.signInIntent) } is LoginUiState.SignInComplete -> { diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/ui/login/LoginViewModel.kt b/demo-app/src/main/kotlin/io/getstream/video/android/ui/login/LoginViewModel.kt index fdfe8fff14..6c061443dd 100644 --- a/demo-app/src/main/kotlin/io/getstream/video/android/ui/login/LoginViewModel.kt +++ b/demo-app/src/main/kotlin/io/getstream/video/android/ui/login/LoginViewModel.kt @@ -16,8 +16,10 @@ package io.getstream.video.android.ui.login +import android.content.Intent import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.google.android.gms.auth.api.signin.GoogleSignInClient import dagger.hilt.android.lifecycle.HiltViewModel import io.getstream.log.streamLog import io.getstream.video.android.API_KEY @@ -48,6 +50,7 @@ import javax.inject.Inject @HiltViewModel class LoginViewModel @Inject constructor( private val dataStore: StreamUserDataStore, + private val googleSignInClient: GoogleSignInClient, private val googleAccountRepository: GoogleAccountRepository, ) : ViewModel() { var autoLogIn: Boolean = true @@ -57,7 +60,11 @@ class LoginViewModel @Inject constructor( .flatMapLatest { event -> when (event) { is LoginEvent.Loading -> flowOf(LoginUiState.Loading) - is LoginEvent.GoogleSignIn -> flowOf(LoginUiState.GoogleSignIn) + is LoginEvent.GoogleSignIn -> flowOf( + LoginUiState.GoogleSignIn( + signInIntent = googleSignInClient.signInIntent, + ), + ) is LoginEvent.SignInSuccess -> signInSuccess(event.userId) is LoginEvent.SignInFailure -> flowOf( LoginUiState.SignInFailure(event.errorMessage), @@ -138,10 +145,10 @@ sealed interface LoginUiState { object Loading : LoginUiState - object GoogleSignIn : LoginUiState - object AlreadyLoggedIn : LoginUiState + data class GoogleSignIn(val signInIntent: Intent) : LoginUiState + data class SignInComplete(val tokenResponse: TokenResponse) : LoginUiState data class SignInFailure(val errorMessage: String) : LoginUiState diff --git a/demo-app/src/main/kotlin/io/getstream/video/android/util/GoogleSignInHelper.kt b/demo-app/src/main/kotlin/io/getstream/video/android/util/GoogleSignInHelper.kt deleted file mode 100644 index 0a7399064b..0000000000 --- a/demo-app/src/main/kotlin/io/getstream/video/android/util/GoogleSignInHelper.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2014-2023 Stream.io Inc. All rights reserved. - * - * Licensed under the Stream License; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://github.com/GetStream/stream-video-android/blob/main/LICENSE - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.getstream.video.android.util - -import android.content.Context -import com.google.android.gms.auth.api.signin.GoogleSignIn -import com.google.android.gms.auth.api.signin.GoogleSignInClient -import com.google.android.gms.auth.api.signin.GoogleSignInOptions -import com.google.android.gms.common.api.Scope -import io.getstream.video.android.R - -object GoogleSignInHelper { - fun getGoogleSignInClient(context: Context): GoogleSignInClient { - val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) - .requestEmail() - .requestIdToken(context.getString(R.string.default_web_client_id)) - .requestScopes(Scope("https://www.googleapis.com/auth/directory.readonly")) - .build() - - return GoogleSignIn.getClient(context, gso) - } -}