Skip to content

Commit ee3fef6

Browse files
committed
ignore
1 parent 89efd0f commit ee3fef6

7 files changed

Lines changed: 176 additions & 5 deletions

File tree

app/src/github/java/in/hridayan/ashell/settings/data/repository/GoogleAuthRepositoryImpl.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ import androidx.credentials.CustomCredential
88
import androidx.credentials.GetCredentialRequest
99
import androidx.credentials.GetCredentialResponse
1010
import androidx.credentials.exceptions.GetCredentialException
11+
import androidx.credentials.exceptions.NoCredentialException
1112
import com.google.android.libraries.identity.googleid.GetGoogleIdOption
1213
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
1314
import dagger.hilt.android.qualifiers.ApplicationContext
1415
import `in`.hridayan.ashell.settings.data.SettingsKeys
16+
import `in`.hridayan.ashell.settings.domain.exception.NoGoogleAccountException
1517
import `in`.hridayan.ashell.settings.domain.model.GoogleUserState
1618
import `in`.hridayan.ashell.settings.domain.repository.GoogleAuthRepository
1719
import `in`.hridayan.ashell.settings.domain.repository.SettingsRepository
@@ -129,6 +131,9 @@ class GoogleAuthRepositoryImpl @Inject constructor(
129131
Result.failure(error)
130132
}
131133

134+
} catch (e: NoCredentialException) {
135+
Log.e(TAG, "signIn: No Google accounts found on device")
136+
Result.failure(NoGoogleAccountException())
132137
} catch (e: GetCredentialException) {
133138
Log.e(TAG, "signIn: Credential error", e)
134139
Result.failure(e)

app/src/main/java/in/hridayan/ashell/core/presentation/components/dialog/DialogKey.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ sealed class DialogKey {
3939
data class BackupDestination(val backupType: BackupType) : DialogKey()
4040
object RestoreSource : DialogKey()
4141
object ConfirmGoogleSignOut : DialogKey()
42+
object NoGoogleAccount : DialogKey()
4243
}
4344

4445
sealed class Pair {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package `in`.hridayan.ashell.settings.domain.exception
2+
3+
class NoGoogleAccountException : Exception("No Google account found on device")
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
@file:OptIn(ExperimentalMaterial3ExpressiveApi::class)
2+
3+
package `in`.hridayan.ashell.settings.presentation.components.dialog
4+
5+
import androidx.compose.foundation.layout.Arrangement
6+
import androidx.compose.foundation.layout.Column
7+
import androidx.compose.foundation.layout.Row
8+
import androidx.compose.foundation.layout.Spacer
9+
import androidx.compose.foundation.layout.fillMaxWidth
10+
import androidx.compose.foundation.layout.height
11+
import androidx.compose.foundation.layout.padding
12+
import androidx.compose.foundation.layout.widthIn
13+
import androidx.compose.material3.CardDefaults
14+
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
15+
import androidx.compose.material3.Icon
16+
import androidx.compose.material3.MaterialTheme
17+
import androidx.compose.material3.Surface
18+
import androidx.compose.material3.Text
19+
import androidx.compose.runtime.Composable
20+
import androidx.compose.ui.Alignment
21+
import androidx.compose.ui.Modifier
22+
import androidx.compose.ui.res.painterResource
23+
import androidx.compose.ui.res.stringResource
24+
import androidx.compose.ui.text.style.TextAlign
25+
import androidx.compose.ui.unit.dp
26+
import androidx.compose.ui.window.Dialog
27+
import androidx.compose.ui.window.DialogProperties
28+
import `in`.hridayan.ashell.R
29+
import `in`.hridayan.ashell.core.presentation.components.card.CustomCard
30+
import `in`.hridayan.ashell.core.presentation.components.haptic.withHaptic
31+
import `in`.hridayan.ashell.core.presentation.components.text.AutoResizeableText
32+
import `in`.hridayan.ashell.core.presentation.theme.CustomCardShape
33+
34+
@Composable
35+
fun NoGoogleAccountDialog(
36+
modifier: Modifier = Modifier,
37+
onDismiss: () -> Unit,
38+
onAddAccount: () -> Unit
39+
) {
40+
Dialog(
41+
onDismissRequest = { onDismiss() },
42+
properties = DialogProperties(dismissOnClickOutside = true)
43+
) {
44+
Surface(
45+
shape = MaterialTheme.shapes.extraLarge,
46+
tonalElevation = 8.dp,
47+
color = MaterialTheme.colorScheme.surfaceContainer
48+
) {
49+
Column(
50+
modifier = modifier
51+
.padding(24.dp)
52+
.widthIn(min = 280.dp)
53+
) {
54+
Text(
55+
text = stringResource(R.string.no_google_account_title),
56+
style = MaterialTheme.typography.titleLarge,
57+
color = MaterialTheme.colorScheme.primary,
58+
textAlign = TextAlign.Center,
59+
modifier = Modifier
60+
.fillMaxWidth()
61+
.align(Alignment.CenterHorizontally)
62+
)
63+
64+
Spacer(modifier = Modifier.height(16.dp))
65+
66+
Text(
67+
text = stringResource(R.string.no_google_account_message),
68+
style = MaterialTheme.typography.bodyMedium,
69+
color = MaterialTheme.colorScheme.onSurfaceVariant,
70+
textAlign = TextAlign.Center,
71+
modifier = Modifier.fillMaxWidth()
72+
)
73+
74+
Spacer(modifier = Modifier.height(24.dp))
75+
76+
CustomCard(
77+
modifier = Modifier.fillMaxWidth(),
78+
onClick = withHaptic {
79+
onAddAccount()
80+
onDismiss()
81+
},
82+
shape = CustomCardShape(50),
83+
colors = CardDefaults.cardColors(
84+
containerColor = MaterialTheme.colorScheme.primaryContainer,
85+
contentColor = MaterialTheme.colorScheme.onPrimaryContainer
86+
)
87+
) {
88+
Row(
89+
modifier = Modifier
90+
.fillMaxWidth()
91+
.padding(horizontal = 20.dp, vertical = 15.dp),
92+
verticalAlignment = Alignment.CenterVertically,
93+
horizontalArrangement = Arrangement.Center
94+
) {
95+
Icon(
96+
painter = painterResource(R.drawable.ic_add),
97+
contentDescription = null,
98+
modifier = Modifier.padding(end = 10.dp)
99+
)
100+
AutoResizeableText(
101+
text = stringResource(R.string.add_account),
102+
style = MaterialTheme.typography.titleMediumEmphasized
103+
)
104+
}
105+
}
106+
107+
Spacer(modifier = Modifier.height(8.dp))
108+
109+
CustomCard(
110+
modifier = Modifier.fillMaxWidth(),
111+
onClick = withHaptic {
112+
onDismiss()
113+
},
114+
shape = CustomCardShape(50),
115+
colors = CardDefaults.cardColors(
116+
containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,
117+
contentColor = MaterialTheme.colorScheme.onSurfaceVariant
118+
)
119+
) {
120+
Text(
121+
text = stringResource(R.string.cancel),
122+
style = MaterialTheme.typography.labelLarge,
123+
textAlign = TextAlign.Center,
124+
modifier = Modifier
125+
.fillMaxWidth()
126+
.padding(vertical = 15.dp)
127+
)
128+
}
129+
}
130+
}
131+
}
132+
}

app/src/main/java/in/hridayan/ashell/settings/presentation/page/backup/screens/BackupAndRestoreScreen.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import androidx.compose.ui.res.stringResource
4242
import androidx.compose.ui.text.font.FontWeight
4343
import androidx.compose.ui.unit.dp
4444
import androidx.core.net.toUri
45+
import android.provider.Settings
4546
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
4647
import `in`.hridayan.ashell.R
4748
import `in`.hridayan.ashell.core.common.LocalDialogManager
@@ -61,6 +62,7 @@ import `in`.hridayan.ashell.settings.domain.model.LastBackupData
6162
import `in`.hridayan.ashell.settings.presentation.components.dialog.BackupDestinationDialog
6263
import `in`.hridayan.ashell.settings.presentation.components.dialog.CloudOperationDialog
6364
import `in`.hridayan.ashell.settings.presentation.components.dialog.GoogleSignOutConfirmationDialog
65+
import `in`.hridayan.ashell.settings.presentation.components.dialog.NoGoogleAccountDialog
6466
import `in`.hridayan.ashell.settings.presentation.components.dialog.ResetSettingsDialog
6567
import `in`.hridayan.ashell.settings.presentation.components.dialog.RestoreBackupDialog
6668
import `in`.hridayan.ashell.settings.presentation.components.dialog.RestoreSourceDialog
@@ -183,6 +185,8 @@ fun BackupAndRestoreScreen(
183185
backupAndRestoreViewModel.uiEvent.collect { event ->
184186
when (event) {
185187
is SettingsUiEvent.ShowToast -> showToast(context, event.message)
188+
is SettingsUiEvent.ShowDialog -> dialogManager.show(event.key)
189+
is SettingsUiEvent.Navigate -> navController.navigate(event.route)
186190
else -> {}
187191
}
188192
}
@@ -373,6 +377,18 @@ fun BackupAndRestoreScreen(
373377
)
374378
}
375379
}
380+
381+
DialogKey.Settings.NoGoogleAccount.createDialog { dialogViewModel ->
382+
NoGoogleAccountDialog(
383+
onDismiss = { dialogViewModel.dismiss() },
384+
onAddAccount = {
385+
val intent = android.content.Intent(Settings.ACTION_ADD_ACCOUNT).apply {
386+
putExtra(Settings.EXTRA_ACCOUNT_TYPES, arrayOf("com.google"))
387+
}
388+
context.startActivity(intent)
389+
}
390+
)
391+
}
376392
}
377393

378394
@Composable

app/src/main/java/in/hridayan/ashell/settings/presentation/page/backup/viewmodel/BackupAndRestoreViewModel.kt

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import androidx.lifecycle.viewModelScope
99
import dagger.hilt.android.lifecycle.HiltViewModel
1010
import dagger.hilt.android.qualifiers.ApplicationContext
1111
import `in`.hridayan.ashell.R
12+
import `in`.hridayan.ashell.core.presentation.components.dialog.DialogKey
1213
import `in`.hridayan.ashell.settings.data.SettingsKeys
14+
import `in`.hridayan.ashell.settings.domain.exception.NoGoogleAccountException
1315
import `in`.hridayan.ashell.settings.domain.model.BackupType
1416
import `in`.hridayan.ashell.settings.domain.model.DriveAuthEvent
1517
import `in`.hridayan.ashell.settings.domain.model.GoogleUserState
@@ -234,11 +236,19 @@ class BackupAndRestoreViewModel @Inject constructor(
234236
},
235237
onFailure = { error ->
236238
Log.e(TAG, "signInWithGoogle: failed — ${error.message}")
237-
_uiEvent.emit(
238-
SettingsUiEvent.ShowToast(
239-
context.getString(R.string.sign_in_failed)
240-
)
241-
)
239+
if (error is NoGoogleAccountException) {
240+
viewModelScope.launch {
241+
_uiEvent.emit(SettingsUiEvent.ShowDialog(DialogKey.Settings.NoGoogleAccount))
242+
}
243+
} else {
244+
viewModelScope.launch {
245+
_uiEvent.emit(
246+
SettingsUiEvent.ShowToast(
247+
context.getString(R.string.sign_in_failed)
248+
)
249+
)
250+
}
251+
}
242252
}
243253
)
244254
}

app/src/main/res/values/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,10 @@
526526
<string name="wireless_debugging_important_notice">Please note that the left part of the Wireless Debugging option is clickable. Tapping on it will open the Wireless Debugging Pairing menu.</string>
527527
<string name="Z_A" translatable="false">Z → A</string>
528528

529+
<string name="no_google_account_title">No Google Account</string>
530+
<string name="no_google_account_message">No Google account was found on this device. Would you like to add one to use cloud backups?</string>
531+
<string name="add_account">Add account</string>
532+
529533
/**
530534
* Changelogs
531535
* Created by DP-Hridayan

0 commit comments

Comments
 (0)