From 7b81e2cc093c288fd20041e30206cb08f15fe127 Mon Sep 17 00:00:00 2001 From: maxrave-dev Date: Sun, 22 Dec 2024 17:21:14 +0700 Subject: [PATCH] Fix login function --- .../maxrave/simpmusic/data/db/DatabaseDao.kt | 2 +- .../data/repository/MainRepository.kt | 2 +- .../com/maxrave/simpmusic/ui/MainActivity.kt | 3 +- .../ui/fragment/login/LogInFragment.kt | 21 +- .../simpmusic/ui/screen/home/SettingScreen.kt | 351 ++++++++++-------- .../simpmusic/viewModel/LogInViewModel.kt | 15 - .../simpmusic/viewModel/SettingsViewModel.kt | 67 ++-- .../simpmusic/viewModel/SharedViewModel.kt | 1 + app/src/main/res/values-vi/strings.xml | 15 +- 9 files changed, 272 insertions(+), 205 deletions(-) diff --git a/app/src/main/java/com/maxrave/simpmusic/data/db/DatabaseDao.kt b/app/src/main/java/com/maxrave/simpmusic/data/db/DatabaseDao.kt index 6de527ff..ccec739c 100644 --- a/app/src/main/java/com/maxrave/simpmusic/data/db/DatabaseDao.kt +++ b/app/src/main/java/com/maxrave/simpmusic/data/db/DatabaseDao.kt @@ -481,7 +481,7 @@ interface DatabaseDao { suspend fun updateGoogleAccountUsed( isUsed: Boolean, email: String, - ) + ): Int @Query("DELETE FROM googleaccountentity WHERE email = :email") suspend fun deleteGoogleAccount(email: String) diff --git a/app/src/main/java/com/maxrave/simpmusic/data/repository/MainRepository.kt b/app/src/main/java/com/maxrave/simpmusic/data/repository/MainRepository.kt index 91db6fe4..c2d7b140 100644 --- a/app/src/main/java/com/maxrave/simpmusic/data/repository/MainRepository.kt +++ b/app/src/main/java/com/maxrave/simpmusic/data/repository/MainRepository.kt @@ -639,7 +639,7 @@ class MainRepository( suspend fun updateGoogleAccountUsed( email: String, isUsed: Boolean, - ) = withContext(Dispatchers.IO) { localDataSource.updateGoogleAccountUsed(email, isUsed) } + ): Flow = flow { emit(localDataSource.updateGoogleAccountUsed(email, isUsed)) }.flowOn(Dispatchers.IO) suspend fun insertFollowedArtistSingleAndAlbum(followedArtistSingleAndAlbum: FollowedArtistSingleAndAlbum) = withContext(Dispatchers.IO) { diff --git a/app/src/main/java/com/maxrave/simpmusic/ui/MainActivity.kt b/app/src/main/java/com/maxrave/simpmusic/ui/MainActivity.kt index ff876260..49e96cf5 100644 --- a/app/src/main/java/com/maxrave/simpmusic/ui/MainActivity.kt +++ b/app/src/main/java/com/maxrave/simpmusic/ui/MainActivity.kt @@ -685,8 +685,9 @@ class MainActivity : AppCompatActivity() { private fun checkForUpdate() { viewModel.checkForUpdate() viewModel.githubResponse.observe(this) { response -> - if (response != null && !this.isInPictureInPictureMode) { + if (response != null && !this.isInPictureInPictureMode && !viewModel.showedUpdateDialog) { if (response.tagName != getString(R.string.version_name)) { + viewModel.showedUpdateDialog = true val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault()) val outputFormat = SimpleDateFormat("dd MMM yyyy HH:mm:ss", Locale.getDefault()) diff --git a/app/src/main/java/com/maxrave/simpmusic/ui/fragment/login/LogInFragment.kt b/app/src/main/java/com/maxrave/simpmusic/ui/fragment/login/LogInFragment.kt index 39dd30c1..7d8686d9 100644 --- a/app/src/main/java/com/maxrave/simpmusic/ui/fragment/login/LogInFragment.kt +++ b/app/src/main/java/com/maxrave/simpmusic/ui/fragment/login/LogInFragment.kt @@ -72,7 +72,7 @@ class LogInFragment : Fragment() { ) { if (url == Config.YOUTUBE_MUSIC_MAIN_URL) { CookieManager.getInstance().getCookie(url)?.let { - viewModel.saveCookie(it) + settingsViewModel.addAccount(it) } WebStorage.getInstance().deleteAllData() @@ -84,18 +84,13 @@ class LogInFragment : Fragment() { binding.webView.clearFormData() binding.webView.clearHistory() binding.webView.clearSslPreferences() - viewModel.status.observe(this@LogInFragment) { - if (it) { - settingsViewModel.addAccount() - Toast - .makeText( - requireContext(), - R.string.login_success, - Toast.LENGTH_SHORT, - ).show() - findNavController().navigateUp() - } - } + Toast + .makeText( + requireContext(), + R.string.login_success, + Toast.LENGTH_SHORT, + ).show() + findNavController().navigateUp() } } } diff --git a/app/src/main/java/com/maxrave/simpmusic/ui/screen/home/SettingScreen.kt b/app/src/main/java/com/maxrave/simpmusic/ui/screen/home/SettingScreen.kt index fce9d0ef..a29a9e13 100644 --- a/app/src/main/java/com/maxrave/simpmusic/ui/screen/home/SettingScreen.kt +++ b/app/src/main/java/com/maxrave/simpmusic/ui/screen/home/SettingScreen.kt @@ -75,6 +75,7 @@ import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.withLink import androidx.compose.ui.unit.dp +import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import androidx.media3.common.util.UnstableApi @@ -96,12 +97,14 @@ import com.maxrave.simpmusic.data.dataStore.DataStoreManager.Settings.TRUE import com.maxrave.simpmusic.extension.bytesToMB import com.maxrave.simpmusic.extension.navigateSafe import com.maxrave.simpmusic.ui.component.ActionButton +import com.maxrave.simpmusic.ui.component.CenterLoadingBox import com.maxrave.simpmusic.ui.component.EndOfPage import com.maxrave.simpmusic.ui.component.RippleIconButton import com.maxrave.simpmusic.ui.component.SettingItem import com.maxrave.simpmusic.ui.theme.DarkColors import com.maxrave.simpmusic.ui.theme.md_theme_dark_primary import com.maxrave.simpmusic.ui.theme.typo +import com.maxrave.simpmusic.utils.LocalResource import com.maxrave.simpmusic.viewModel.SettingAlertState import com.maxrave.simpmusic.viewModel.SettingBasicAlertState import com.maxrave.simpmusic.viewModel.SettingsViewModel @@ -180,7 +183,6 @@ fun SettingScreen( val fraction by viewModel.fraction.collectAsStateWithLifecycle() val githubResponse by viewModel.githubResponse.collectAsStateWithLifecycle() val lastCheckUpdate by viewModel.lastCheckForUpdate.collectAsStateWithLifecycle() - val googleAccounts by viewModel.googleAccounts.collectAsStateWithLifecycle() val usingProxy by viewModel.usingProxy.collectAsStateWithLifecycle() val proxyType by viewModel.proxyType.collectAsStateWithLifecycle() val proxyHost by viewModel.proxyHost.collectAsStateWithLifecycle() @@ -394,18 +396,21 @@ fun SettingScreen( viewModel.setAlertData( SettingAlertState( title = context.getString(R.string.video_quality), - selectOne = SettingAlertState.SelectData( - listSelect = VIDEO_QUALITY.items.map { item -> - (item.toString() == videoQuality) to item.toString() + selectOne = + SettingAlertState.SelectData( + listSelect = + VIDEO_QUALITY.items.map { item -> + (item.toString() == videoQuality) to item.toString() + }, + ), + confirm = + context.getString(R.string.change) to { state -> + viewModel.changeVideoQuality(state.selectOne?.getSelected() ?: "") }, - ), - confirm = context.getString(R.string.change) to { state -> - viewModel.changeVideoQuality(state.selectOne?.getSelected() ?: "") - }, - dismiss = context.getString(R.string.cancel) - ) + dismiss = context.getString(R.string.cancel), + ), ) - } + }, ) SettingItem( title = stringResource(R.string.send_back_listening_data_to_google), @@ -430,35 +435,43 @@ fun SettingScreen( Column { SettingItem( title = stringResource(R.string.proxy_type), - subtitle = when (proxyType) { - DataStoreManager.Settings.ProxyType.PROXY_TYPE_HTTP -> stringResource(R.string.http) - DataStoreManager.Settings.ProxyType.PROXY_TYPE_SOCKS -> stringResource(R.string.socks) - }, + subtitle = + when (proxyType) { + DataStoreManager.Settings.ProxyType.PROXY_TYPE_HTTP -> stringResource(R.string.http) + DataStoreManager.Settings.ProxyType.PROXY_TYPE_SOCKS -> stringResource(R.string.socks) + }, onClick = { viewModel.setAlertData( SettingAlertState( title = context.getString(R.string.proxy_type), - selectOne = SettingAlertState.SelectData( - listSelect = listOf( - (proxyType == DataStoreManager.Settings.ProxyType.PROXY_TYPE_HTTP) to context.getString(R.string.http), - (proxyType == DataStoreManager.Settings.ProxyType.PROXY_TYPE_SOCKS) to context.getString(R.string.socks), + selectOne = + SettingAlertState.SelectData( + listSelect = + listOf( + (proxyType == DataStoreManager.Settings.ProxyType.PROXY_TYPE_HTTP) to + context.getString( + R.string.http, + ), + (proxyType == DataStoreManager.Settings.ProxyType.PROXY_TYPE_SOCKS) to + context.getString(R.string.socks), + ), ), - ), - confirm = context.getString(R.string.change) to { state -> - viewModel.setProxy( - if (state.selectOne?.getSelected() == context.getString(R.string.socks)) { - DataStoreManager.Settings.ProxyType.PROXY_TYPE_SOCKS - } else { - DataStoreManager.Settings.ProxyType.PROXY_TYPE_HTTP - }, - proxyHost, - proxyPort, - ) - }, + confirm = + context.getString(R.string.change) to { state -> + viewModel.setProxy( + if (state.selectOne?.getSelected() == context.getString(R.string.socks)) { + DataStoreManager.Settings.ProxyType.PROXY_TYPE_SOCKS + } else { + DataStoreManager.Settings.ProxyType.PROXY_TYPE_HTTP + }, + proxyHost, + proxyPort, + ) + }, dismiss = context.getString(R.string.cancel), - ) + ), ) - } + }, ) SettingItem( title = stringResource(R.string.proxy_host), @@ -468,24 +481,26 @@ fun SettingScreen( SettingAlertState( title = context.getString(R.string.proxy_host), message = context.getString(R.string.proxy_host_message), - textField = SettingAlertState.TextFieldData( - label = context.getString(R.string.proxy_host), - value = proxyHost, - verifyCodeBlock = { - (it.toHttpUrlOrNull() != null) to context.getString(R.string.invalid_host) + textField = + SettingAlertState.TextFieldData( + label = context.getString(R.string.proxy_host), + value = proxyHost, + verifyCodeBlock = { + (it.toHttpUrlOrNull() != null) to context.getString(R.string.invalid_host) + }, + ), + confirm = + context.getString(R.string.change) to { state -> + viewModel.setProxy( + proxyType, + state.textField?.value ?: "", + proxyPort, + ) }, - ), - confirm = context.getString(R.string.change) to { state -> - viewModel.setProxy( - proxyType, - state.textField?.value ?: "", - proxyPort, - ) - }, dismiss = context.getString(R.string.cancel), - ) + ), ) - } + }, ) SettingItem( title = stringResource(R.string.proxy_port), @@ -495,24 +510,26 @@ fun SettingScreen( SettingAlertState( title = context.getString(R.string.proxy_port), message = context.getString(R.string.proxy_port_message), - textField = SettingAlertState.TextFieldData( - label = context.getString(R.string.proxy_port), - value = proxyPort.toString(), - verifyCodeBlock = { - (it.toIntOrNull() != null) to context.getString(R.string.invalid_port) + textField = + SettingAlertState.TextFieldData( + label = context.getString(R.string.proxy_port), + value = proxyPort.toString(), + verifyCodeBlock = { + (it.toIntOrNull() != null) to context.getString(R.string.invalid_port) + }, + ), + confirm = + context.getString(R.string.change) to { state -> + viewModel.setProxy( + proxyType, + proxyHost, + state.textField?.value?.toIntOrNull() ?: 0, + ) }, - ), - confirm = context.getString(R.string.change) to { state -> - viewModel.setProxy( - proxyType, - proxyHost, - state.textField?.value?.toIntOrNull() ?: 0, - ) - }, dismiss = context.getString(R.string.cancel), - ) + ), ) - } + }, ) } } @@ -1139,7 +1156,7 @@ fun SettingScreen( title = { Text( text = alertBasicState.title, - style = typo.titleSmall + style = typo.titleSmall, ) }, text = { @@ -1180,14 +1197,26 @@ fun SettingScreen( tonalElevation = AlertDialogDefaults.TonalElevation, shadowElevation = 1.dp, ) { + val googleAccounts by viewModel.googleAccounts.collectAsStateWithLifecycle( + minActiveState = Lifecycle.State.RESUMED, + ) + LaunchedEffect(googleAccounts) { + Log.w( + "SettingScreen", + "LaunchedEffect: ${googleAccounts.data?.map { + it.name to it.isUsed + }}", + ) + } LazyColumn(modifier = Modifier.padding(8.dp)) { item { Box(modifier = Modifier.fillMaxWidth().height(48.dp)) { IconButton( onClick = { showYouTubeAccountDialog = false }, - colors = IconButtonDefaults.iconButtonColors().copy( - contentColor = Color.White - ), + colors = + IconButtonDefaults.iconButtonColors().copy( + contentColor = Color.White, + ), modifier = Modifier.align(Alignment.CenterStart).fillMaxHeight(), ) { Icon(Icons.Outlined.Close, null, tint = Color.White) @@ -1195,91 +1224,107 @@ fun SettingScreen( Text( stringResource(R.string.youtube_account), style = typo.titleMedium, - modifier = Modifier.align(Alignment.Center) - .wrapContentHeight(align = Alignment.CenterVertically) - .wrapContentWidth() + modifier = + Modifier + .align(Alignment.Center) + .wrapContentHeight(align = Alignment.CenterVertically) + .wrapContentWidth(), ) } } - items(googleAccounts ?: emptyList(), key = { it.email + it.name + it.cache }) { - Row( - modifier = Modifier.padding(vertical = 8.dp) - .clickable { - viewModel.setUsedAccount(it) - }, - verticalAlignment = Alignment.CenterVertically, - ) { - Spacer(Modifier.width(24.dp)) - AsyncImage( - model = - ImageRequest - .Builder(LocalContext.current) - .data(it.thumbnailUrl) - .crossfade(550) - .build(), - placeholder = painterResource(R.drawable.baseline_people_alt_24), - error = painterResource(R.drawable.baseline_people_alt_24), - contentDescription = it.name, - modifier = Modifier.size(48.dp) - .clip(CircleShape) - ) - Spacer(Modifier.width(12.dp)) - Column(Modifier.weight(1f)) { - Text(it.name, style = typo.labelMedium) - Text(it.email, style = typo.bodySmall) - } - Spacer(Modifier.width(12.dp)) - AnimatedVisibility(it.isUsed) { + if (googleAccounts is LocalResource.Success) { + val data = googleAccounts.data + if (data.isNullOrEmpty()) { + item { Text( - stringResource(R.string.signed_in), - style = typo.bodySmall, - maxLines = 2, + stringResource(R.string.no_account), + style = typo.bodyMedium, textAlign = TextAlign.Center, - modifier = Modifier.widthIn(0.dp, 64.dp) + modifier = Modifier.padding(12.dp).fillMaxWidth(), ) } - Spacer(Modifier.width(24.dp)) + } else { + items(data) { + Row( + modifier = + Modifier + .padding(vertical = 8.dp) + .clickable { + viewModel.setUsedAccount(it) + }, + verticalAlignment = Alignment.CenterVertically, + ) { + Spacer(Modifier.width(24.dp)) + AsyncImage( + model = + ImageRequest + .Builder(LocalContext.current) + .data(it.thumbnailUrl) + .crossfade(550) + .build(), + placeholder = painterResource(R.drawable.baseline_people_alt_24), + error = painterResource(R.drawable.baseline_people_alt_24), + contentDescription = it.name, + modifier = + Modifier + .size(48.dp) + .clip(CircleShape), + ) + Spacer(Modifier.width(12.dp)) + Column(Modifier.weight(1f)) { + Text(it.name, style = typo.labelMedium) + Text(it.email, style = typo.bodySmall) + } + Spacer(Modifier.width(12.dp)) + AnimatedVisibility(it.isUsed) { + Text( + stringResource(R.string.signed_in), + style = typo.bodySmall, + maxLines = 2, + textAlign = TextAlign.Center, + modifier = Modifier.widthIn(0.dp, 64.dp), + ) + } + Spacer(Modifier.width(24.dp)) + } + } } - } - if (googleAccounts.isNullOrEmpty()) { + } else { item { - Text( - stringResource(R.string.no_account), - style = typo.bodyMedium, - textAlign = TextAlign.Center, - modifier = Modifier.padding(12.dp).fillMaxWidth(), - ) + CenterLoadingBox(Modifier.fillMaxWidth().height(54.dp)) } } item { Column { ActionButton( icon = painterResource(R.drawable.baseline_people_alt_24), - text = R.string.guest + text = R.string.guest, ) { viewModel.setUsedAccount(null) showYouTubeAccountDialog = false } ActionButton( icon = painterResource(R.drawable.baseline_close_24), - text = R.string.log_out + text = R.string.log_out, ) { viewModel.setBasicAlertData( SettingBasicAlertState( title = context.getString(R.string.warning), message = context.getString(R.string.log_out_warning), - confirm = context.getString(R.string.log_out) to { - viewModel.logOutAllYouTube() - showYouTubeAccountDialog = false - }, - dismiss = context.getString(R.string.cancel) - ) + confirm = + context.getString(R.string.log_out) to { + viewModel.logOutAllYouTube() + showYouTubeAccountDialog = false + }, + dismiss = context.getString(R.string.cancel), + ), ) } ActionButton( icon = painterResource(R.drawable.baseline_playlist_add_24), - text = R.string.add_an_account + text = R.string.add_an_account, ) { + showYouTubeAccountDialog = false navController.navigateSafe(R.id.action_global_logInFragment) } } @@ -1297,7 +1342,7 @@ fun SettingScreen( title = { Text( text = alertState.title, - style = typo.titleSmall + style = typo.titleSmall, ) }, text = { @@ -1355,24 +1400,27 @@ fun SettingScreen( viewModel.setAlertData( alertState.copy( selectOne = - alertState.selectOne.copy( - listSelect = - alertState.selectOne.listSelect.toMutableList().map { - if (it == item) { - true to it.second - } else { - false to it.second - } - }, - ), + alertState.selectOne.copy( + listSelect = + alertState.selectOne.listSelect.toMutableList().map { + if (it == item) { + true to it.second + } else { + false to it.second + } + }, + ), ), ) } Row( - Modifier.padding(vertical = 4.dp).clickable { - onSelect.invoke() - }.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically) { + Modifier + .padding(vertical = 4.dp) + .clickable { + onSelect.invoke() + }.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + ) { RadioButton( selected = item.first, onClick = { @@ -1393,24 +1441,27 @@ fun SettingScreen( viewModel.setAlertData( alertState.copy( multipleSelect = - alertState.multipleSelect.copy( - listSelect = - alertState.multipleSelect.listSelect.toMutableList().map { - if (it == item) { - !it.first to it.second - } else { - it - } - }, - ), + alertState.multipleSelect.copy( + listSelect = + alertState.multipleSelect.listSelect.toMutableList().map { + if (it == item) { + !it.first to it.second + } else { + it + } + }, + ), ), ) } Row( - Modifier.padding(vertical = 4.dp).clickable { - onCheck.invoke() - }.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically) { + Modifier + .padding(vertical = 4.dp) + .clickable { + onCheck.invoke() + }.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + ) { Checkbox( checked = item.first, onCheckedChange = { diff --git a/app/src/main/java/com/maxrave/simpmusic/viewModel/LogInViewModel.kt b/app/src/main/java/com/maxrave/simpmusic/viewModel/LogInViewModel.kt index cbcc2f49..18d13bec 100644 --- a/app/src/main/java/com/maxrave/simpmusic/viewModel/LogInViewModel.kt +++ b/app/src/main/java/com/maxrave/simpmusic/viewModel/LogInViewModel.kt @@ -1,12 +1,10 @@ package com.maxrave.simpmusic.viewModel import android.app.Application -import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import com.maxrave.simpmusic.viewModel.base.BaseViewModel -import kotlinx.coroutines.delay import kotlinx.coroutines.launch class LogInViewModel( @@ -15,22 +13,9 @@ class LogInViewModel( override val tag: String get() = "LogInViewModel" - private val _status: MutableLiveData = MutableLiveData(false) - var status: LiveData = _status - private val _spotifyStatus: MutableLiveData = MutableLiveData(false) var spotifyStatus: LiveData = _spotifyStatus - fun saveCookie(cookie: String) { - viewModelScope.launch { - Log.d("LogInViewModel", "saveCookie: $cookie") - dataStoreManager.setCookie(cookie) - dataStoreManager.setLoggedIn(true) - delay(1000) - _status.postValue(true) - } - } - fun saveSpotifySpdc(cookie: String) { viewModelScope.launch { cookie diff --git a/app/src/main/java/com/maxrave/simpmusic/viewModel/SettingsViewModel.kt b/app/src/main/java/com/maxrave/simpmusic/viewModel/SettingsViewModel.kt index 81f67249..25d0d9f3 100644 --- a/app/src/main/java/com/maxrave/simpmusic/viewModel/SettingsViewModel.kt +++ b/app/src/main/java/com/maxrave/simpmusic/viewModel/SettingsViewModel.kt @@ -34,6 +34,7 @@ import com.maxrave.simpmusic.extension.zipInputStream import com.maxrave.simpmusic.extension.zipOutputStream import com.maxrave.simpmusic.service.SimpleMediaService import com.maxrave.simpmusic.service.test.download.DownloadUtils +import com.maxrave.simpmusic.utils.LocalResource import com.maxrave.simpmusic.viewModel.base.BaseViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -779,22 +780,18 @@ class SettingsViewModel( } } - private var _googleAccounts: MutableStateFlow?> = - MutableStateFlow(null) - val googleAccounts: MutableStateFlow?> = _googleAccounts - - private var _loading: MutableStateFlow = MutableStateFlow(false) - val loading: MutableStateFlow = _loading + private var _googleAccounts: MutableStateFlow>> = + MutableStateFlow(LocalResource.Loading()) + val googleAccounts: StateFlow>> = _googleAccounts fun getAllGoogleAccount() { Log.w("getAllGoogleAccount", "getAllGoogleAccount: Go to function") viewModelScope.launch { - _loading.value = true - mainRepository.getGoogleAccounts().collect { accounts -> + _googleAccounts.emit(LocalResource.Loading()) + mainRepository.getGoogleAccounts().collectLatest { accounts -> Log.w("getAllGoogleAccount", "getAllGoogleAccount: $accounts") if (!accounts.isNullOrEmpty()) { - _googleAccounts.value = accounts as ArrayList - _loading.value = false + _googleAccounts.emit(LocalResource.Success(accounts)) } else { if (loggedIn.value == DataStoreManager.TRUE) { mainRepository.getAccountInfo().collect { @@ -817,25 +814,34 @@ class SettingsViewModel( delay(500) getAllGoogleAccount() } else { - _googleAccounts.value = null - _loading.value = false + _googleAccounts.emit(LocalResource.Success(emptyList())) } } } else { - _googleAccounts.value = null - _loading.value = false + _googleAccounts.emit(LocalResource.Success(emptyList())) } } } } } - fun addAccount() { + fun addAccount(cookie: String) { viewModelScope.launch { + dataStoreManager.setCookie(cookie) + dataStoreManager.setLoggedIn(true) mainRepository.getAccountInfo().collect { accountInfo -> + Log.d("getAllGoogleAccount", "addAccount: $accountInfo") if (accountInfo != null) { - googleAccounts.value?.forEach { - mainRepository.updateGoogleAccountUsed(it.email, false) + runBlocking { + mainRepository.getGoogleAccounts().singleOrNull()?.forEach { + Log.d("getAllGoogleAccount", "set used: $it start") + mainRepository + .updateGoogleAccountUsed(it.email, false) + .singleOrNull() + ?.let { + Log.w("getAllGoogleAccount", "set used: $it") + } + } } dataStoreManager.putString("AccountName", accountInfo.name) dataStoreManager.putString( @@ -864,20 +870,35 @@ class SettingsViewModel( fun setUsedAccount(acc: GoogleAccountEntity?) { viewModelScope.launch { if (acc != null) { - googleAccounts.value?.forEach { - mainRepository.updateGoogleAccountUsed(it.email, false) + googleAccounts.value.data?.forEach { + mainRepository + .updateGoogleAccountUsed(it.email, false) + .singleOrNull() + ?.let { + Log.w("getAllGoogleAccount", "set used: $it") + } } dataStoreManager.putString("AccountName", acc.name) dataStoreManager.putString("AccountThumbUrl", acc.thumbnailUrl) - mainRepository.updateGoogleAccountUsed(acc.email, true) + mainRepository + .updateGoogleAccountUsed(acc.email, true) + .singleOrNull() + ?.let { + Log.w("getAllGoogleAccount", "set used: $it") + } dataStoreManager.setCookie(acc.cache ?: "") dataStoreManager.setLoggedIn(true) delay(500) getAllGoogleAccount() getLoggedIn() } else { - googleAccounts.value?.forEach { - mainRepository.updateGoogleAccountUsed(it.email, false) + googleAccounts.value.data?.forEach { + mainRepository + .updateGoogleAccountUsed(it.email, false) + .singleOrNull() + ?.let { + Log.w("getAllGoogleAccount", "set used: $it") + } } dataStoreManager.putString("AccountName", "") dataStoreManager.putString("AccountThumbUrl", "") @@ -892,7 +913,7 @@ class SettingsViewModel( fun logOutAllYouTube() { viewModelScope.launch { - googleAccounts.value?.forEach { account -> + googleAccounts.value.data?.forEach { account -> mainRepository.deleteGoogleAccount(account.email) } dataStoreManager.putString("AccountName", "") diff --git a/app/src/main/java/com/maxrave/simpmusic/viewModel/SharedViewModel.kt b/app/src/main/java/com/maxrave/simpmusic/viewModel/SharedViewModel.kt index ee007ca7..a9ebbf75 100644 --- a/app/src/main/java/com/maxrave/simpmusic/viewModel/SharedViewModel.kt +++ b/app/src/main/java/com/maxrave/simpmusic/viewModel/SharedViewModel.kt @@ -95,6 +95,7 @@ class SharedViewModel( var isFirstLiked: Boolean = false var isFirstMiniplayer: Boolean = false var isFirstSuggestions: Boolean = false + var showedUpdateDialog: Boolean = false var showOrHideMiniplayer: MutableSharedFlow = MutableSharedFlow() override val tag = "SharedViewModel" diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index b619cd72..2e08c8ec 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -1,6 +1,5 @@ - You can also find us with: electronic dance music 2023 edm top electronic dance songs 2023 edm songs edm music 2023 electronic dance music best electro dance music popular edm songs top edm songs edm songs 2023 edm music top edm songs 2023 top electronic dance songs edm 2023 popular edm songs 2023 best electro dance music 2023 No matter how your day is, you can always listen to good music: 1. EDM Hits Playlist - Popular EDM Hits in 2023 - We would like to keep you with us many years from now on! So, in the next year, you could find our playlist like this: EDM 2024 ♫ Top EDM Songs 2024 Bài hát • %1$s Danh sách phát • %1$s Album • %1$s @@ -357,4 +356,18 @@ Đang cập nhật Đi tới trang đăng nhập YouTube Music hiện tại đang yêu cầu đăng nhập để nghe nhạc trực tuyến, cũng như các thực thể Piped đôi khi không hoạt động. Bạn nên đăng nhập vào YouTube để có trải nghiệm nghe nhạc tốt nhất với SimpMusic. + Cache của Spotify Canvas + Xoá bộ nhớ cache của Spotify Canvas + Proxy + Sử dụng Proxy để vượt qua trình chặn nội dung + Loại Proxy + HTTP + Socks + Máy chủ proxy + Máy chủ không hợp lệ + Cổng proxy + Cổng không hợp lệ + Hãy nhập máy chủ Proxy của bạn + Hãy nhập cổng Proxy của bạn + 5 giây