@iternio/react-native-auto-play 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/android/build.gradle +4 -2
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/AutoPlayError.kt +4 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridSignInTemplate.kt +23 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/SignInWithGoogleActivity.kt +79 -27
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/SignInTemplate.kt +35 -21
- package/lib/specs/SignInTemplate.nitro.d.ts +1 -0
- package/lib/templates/SignInTemplate.d.ts +5 -0
- package/lib/templates/SignInTemplate.js +7 -0
- package/lib-cjs/templates/SignInTemplate.js +7 -0
- package/nitrogen/generated/android/c++/JHybridSignInTemplateSpec.cpp +5 -0
- package/nitrogen/generated/android/c++/JHybridSignInTemplateSpec.hpp +1 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridSignInTemplateSpec.kt +4 -0
- package/nitrogen/generated/shared/c++/HybridSignInTemplateSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridSignInTemplateSpec.hpp +1 -0
- package/package.json +1 -1
- package/src/specs/SignInTemplate.nitro.ts +1 -0
- package/src/templates/SignInTemplate.ts +8 -0
package/README.md
CHANGED
|
@@ -682,7 +682,7 @@ Below is a concise overview of the most important props per template. Optional p
|
|
|
682
682
|
|
|
683
683
|
| Prop | Type | Required | Notes |
|
|
684
684
|
| --- | --- | --- | --- |
|
|
685
|
-
| `signInMethod` | `SignInMethod` | ✅ | The sign-in method configuration. Can be QRSignIn, PinSignIn, InputSignIn. |
|
|
685
|
+
| `signInMethod` | `SignInMethod` | ✅ | The sign-in method configuration. Can be QRSignIn, PinSignIn, InputSignIn, GoogleSignIn. |
|
|
686
686
|
| `title` | `string` | ❌ | Header title. |
|
|
687
687
|
| `additionalText` | `string` | ❌ | Additional descriptive text. |
|
|
688
688
|
| `instructions` | `string` | ❌ | Sign-in Instructions text. |
|
|
@@ -696,6 +696,19 @@ Below is a concise overview of the most important props per template. Optional p
|
|
|
696
696
|
| QR | `QrSignIn` | QR Code sign in |
|
|
697
697
|
| PIN | `PinSignIn` | PIN Code sign in (1–12 characters) |
|
|
698
698
|
| Input | `InputSignIn` | Text sign in, for example mail/username and password |
|
|
699
|
+
| Google | `GoogleSignIn` | Sign in with Google. Requires Google Play services 23.08 or newer — check `SignInTemplate.isGoogleSignInAvailable()` first. |
|
|
700
|
+
|
|
701
|
+
`GoogleSignIn` takes a `serverClientId` (your **Web** OAuth client ID), a `signInButtonText` and a `callback(error?, account?)`. On success the returned `GoogleSignInAccount` always carries both `idToken` and `serverAuthCode` (offline access, `openid` `profile` `email` scopes) for your backend. If the user cancels, or either the account picker or the authorization step fails, `callback` is called with an `error` and no account.
|
|
702
|
+
|
|
703
|
+
**Sign in with Google needs a recent Play services.** Constructing a `SignInTemplate` with `GoogleSignIn` throws `playServicesUnavailable` (and `updateTemplate` rejects with it) when Google Play services is missing or older than 23.08 (e.g. Android Automotive builds without GMS). Pick a different method up front instead:
|
|
704
|
+
|
|
705
|
+
```ts
|
|
706
|
+
const signInMethod: SignInMethod = SignInTemplate.isGoogleSignInAvailable()
|
|
707
|
+
? { method: SignInMethods.GOOGLE, serverClientId, signInButtonText: 'Sign in with Google', callback }
|
|
708
|
+
: { method: SignInMethods.QR, url: loginUrl };
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
`isGoogleSignInAvailable()` always returns `false` on iOS.
|
|
699
712
|
|
|
700
713
|
For InputSignIn the keyboard and input fields can be configured with following properties:
|
|
701
714
|
|
package/android/build.gradle
CHANGED
|
@@ -165,7 +165,9 @@ dependencies {
|
|
|
165
165
|
implementation "androidx.car.app:app-projected:1.7.0"
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
implementation 'com.google.android.gms:play-services-
|
|
169
|
-
implementation '
|
|
168
|
+
implementation 'com.google.android.gms:play-services-auth:22.0.0'
|
|
169
|
+
implementation 'androidx.credentials:credentials:1.6.0'
|
|
170
|
+
implementation 'androidx.credentials:credentials-play-services-auth:1.6.0'
|
|
171
|
+
implementation 'com.google.android.libraries.identity.googleid:googleid:1.1.1'
|
|
170
172
|
}
|
|
171
173
|
|
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/AutoPlayError.kt
CHANGED
|
@@ -8,3 +8,7 @@ class TemplateNotFoundException(private val templateId: String) :
|
|
|
8
8
|
class VoiceInputCancelledException : Exception("voiceInputCancelled") {
|
|
9
9
|
override fun toString(): String = "voiceInputCancelled"
|
|
10
10
|
}
|
|
11
|
+
|
|
12
|
+
class PlayServicesUnavailableException : Exception("playServicesUnavailable") {
|
|
13
|
+
override fun toString(): String = "playServicesUnavailable"
|
|
14
|
+
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
package com.margelo.nitro.swe.iternio.reactnativeautoplay
|
|
2
2
|
|
|
3
|
+
import com.google.android.gms.common.ConnectionResult
|
|
4
|
+
import com.google.android.gms.common.GoogleApiAvailability
|
|
5
|
+
import com.margelo.nitro.NitroModules
|
|
3
6
|
import com.margelo.nitro.core.Promise
|
|
4
7
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.template.AndroidAutoTemplate
|
|
5
8
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.template.SignInTemplate
|
|
@@ -9,14 +12,34 @@ class HybridSignInTemplate : HybridSignInTemplateSpec() {
|
|
|
9
12
|
val context = AndroidAutoSession.getRootContext()
|
|
10
13
|
?: throw IllegalArgumentException("createSignInTemplate failed, no carContext found")
|
|
11
14
|
|
|
15
|
+
assertSignInMethodAvailable(config)
|
|
16
|
+
|
|
12
17
|
val template = SignInTemplate(context, config)
|
|
13
18
|
AndroidAutoTemplate.setTemplate(config.id, template)
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
override fun updateTemplate(templateId: String, config: SignInTemplateConfig): Promise<Unit> {
|
|
17
22
|
return Promise.async {
|
|
23
|
+
assertSignInMethodAvailable(config)
|
|
18
24
|
val template = AndroidAutoTemplate.getTemplate<SignInTemplate>(templateId)
|
|
19
25
|
template.updateTemplate(config)
|
|
20
26
|
}
|
|
21
27
|
}
|
|
28
|
+
|
|
29
|
+
override fun isGoogleSignInAvailable(): Boolean {
|
|
30
|
+
val context = NitroModules.applicationContext ?: return false
|
|
31
|
+
|
|
32
|
+
// on older versions sign in with google is no longer supported
|
|
33
|
+
val googleServiceMinVersion = 230815045
|
|
34
|
+
val available = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
|
|
35
|
+
context, googleServiceMinVersion
|
|
36
|
+
)
|
|
37
|
+
return ConnectionResult.SUCCESS == available
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private fun assertSignInMethodAvailable(config: SignInTemplateConfig) {
|
|
41
|
+
if (config.signInMethod?.asFourthOrNull() != null && !isGoogleSignInAvailable()) {
|
|
42
|
+
throw PlayServicesUnavailableException()
|
|
43
|
+
}
|
|
44
|
+
}
|
|
22
45
|
}
|
|
@@ -4,42 +4,90 @@ import android.os.Binder
|
|
|
4
4
|
import android.os.Bundle
|
|
5
5
|
import android.os.IBinder
|
|
6
6
|
import androidx.activity.ComponentActivity
|
|
7
|
-
import androidx.activity.result.
|
|
7
|
+
import androidx.activity.result.IntentSenderRequest
|
|
8
8
|
import androidx.activity.result.contract.ActivityResultContracts
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
9
|
+
import androidx.credentials.CredentialManager
|
|
10
|
+
import androidx.credentials.GetCredentialRequest
|
|
11
|
+
import androidx.lifecycle.lifecycleScope
|
|
12
|
+
import com.google.android.gms.auth.api.identity.AuthorizationRequest
|
|
13
|
+
import com.google.android.gms.auth.api.identity.Identity
|
|
14
|
+
import com.google.android.gms.common.Scopes
|
|
15
|
+
import com.google.android.gms.common.api.Scope
|
|
16
|
+
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption
|
|
17
|
+
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
|
|
18
|
+
import kotlinx.coroutines.launch
|
|
12
19
|
import java.security.InvalidParameterException
|
|
13
|
-
import javax.annotation.Nullable
|
|
14
20
|
|
|
15
21
|
class SignInWithGoogleActivity : ComponentActivity() {
|
|
16
|
-
override fun onCreate(savedInstanceState: Bundle?) {
|
|
17
|
-
super.onCreate(savedInstanceState)
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
private var callback: OnSignInComplete? = null
|
|
24
|
+
private var idCredential: GoogleIdTokenCredential? = null
|
|
25
|
+
|
|
26
|
+
private val authLauncher = registerForActivityResult(
|
|
27
|
+
ActivityResultContracts.StartIntentSenderForResult()
|
|
28
|
+
) { result ->
|
|
29
|
+
val auth = runCatching {
|
|
30
|
+
Identity.getAuthorizationClient(this)
|
|
31
|
+
.getAuthorizationResultFromIntent(result.data)
|
|
32
|
+
}.getOrNull()
|
|
33
|
+
finishWith(auth?.serverAuthCode)
|
|
34
|
+
}
|
|
20
35
|
|
|
36
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
37
|
+
super.onCreate(savedInstanceState)
|
|
38
|
+
callback = intent.extras?.getBinder(BINDER_KEY) as OnSignInComplete?
|
|
21
39
|
val serverClientId = intent.extras?.getString("serverClientId")
|
|
22
40
|
?: throw InvalidParameterException("missing serverClientId parameter")
|
|
23
41
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
42
|
+
lifecycleScope.launch {
|
|
43
|
+
// 1. Authentication: ID token
|
|
44
|
+
val request = GetCredentialRequest.Builder()
|
|
45
|
+
.addCredentialOption(GetSignInWithGoogleOption.Builder(serverClientId).build())
|
|
46
|
+
.build()
|
|
47
|
+
try {
|
|
48
|
+
val result = CredentialManager.create(this@SignInWithGoogleActivity)
|
|
49
|
+
.getCredential(this@SignInWithGoogleActivity, request)
|
|
50
|
+
idCredential = GoogleIdTokenCredential.createFrom(result.credential.data)
|
|
51
|
+
} catch (_: Exception) {
|
|
52
|
+
callback?.onSignInComplete(null, null)
|
|
53
|
+
finish()
|
|
54
|
+
return@launch
|
|
55
|
+
}
|
|
33
56
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
.
|
|
39
|
-
|
|
57
|
+
// 2. Authorization: server auth code
|
|
58
|
+
val authRequest = AuthorizationRequest.builder()
|
|
59
|
+
// matches the legacy DEFAULT_SIGN_IN + requestEmail() scopes, so the exchanged
|
|
60
|
+
// server auth code grants the same access as before the Credential Manager migration
|
|
61
|
+
.setRequestedScopes(
|
|
62
|
+
listOf(Scope(Scopes.OPEN_ID), Scope(Scopes.PROFILE), Scope(Scopes.EMAIL))
|
|
63
|
+
)
|
|
64
|
+
.requestOfflineAccess(serverClientId)
|
|
40
65
|
.build()
|
|
41
|
-
|
|
42
|
-
|
|
66
|
+
Identity.getAuthorizationClient(this@SignInWithGoogleActivity)
|
|
67
|
+
.authorize(authRequest)
|
|
68
|
+
.addOnSuccessListener { res ->
|
|
69
|
+
if (res.hasResolution()) {
|
|
70
|
+
authLauncher.launch(
|
|
71
|
+
IntentSenderRequest.Builder(res.pendingIntent!!.intentSender).build()
|
|
72
|
+
)
|
|
73
|
+
} else {
|
|
74
|
+
finishWith(res.serverAuthCode)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
.addOnFailureListener { finishWith(null) }
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private fun finishWith(serverAuthCode: String?) {
|
|
82
|
+
// a cancelled or failed authorization step yields no server auth code; report it as a
|
|
83
|
+
// failed sign in so callers get either an error or a complete account, as with the
|
|
84
|
+
// legacy GoogleSignIn flow, never an account without a server auth code
|
|
85
|
+
if (serverAuthCode == null) {
|
|
86
|
+
callback?.onSignInComplete(null, null)
|
|
87
|
+
} else {
|
|
88
|
+
callback?.onSignInComplete(idCredential, serverAuthCode)
|
|
89
|
+
}
|
|
90
|
+
finish()
|
|
43
91
|
}
|
|
44
92
|
|
|
45
93
|
/**
|
|
@@ -49,9 +97,13 @@ class SignInWithGoogleActivity : ComponentActivity() {
|
|
|
49
97
|
/**
|
|
50
98
|
* Notifies that sign in flow completed.
|
|
51
99
|
*
|
|
52
|
-
* @param
|
|
100
|
+
* @param credential the account signed in or `null` if there were issues signing in.
|
|
101
|
+
* @param serverAuthCode the server auth code, always non-null when [credential] is non-null.
|
|
53
102
|
*/
|
|
54
|
-
abstract fun onSignInComplete(
|
|
103
|
+
abstract fun onSignInComplete(
|
|
104
|
+
credential: GoogleIdTokenCredential?,
|
|
105
|
+
serverAuthCode: String?
|
|
106
|
+
)
|
|
55
107
|
}
|
|
56
108
|
|
|
57
109
|
companion object {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
package com.margelo.nitro.swe.iternio.reactnativeautoplay.template
|
|
2
2
|
|
|
3
3
|
import android.content.Intent
|
|
4
|
-
import android.net.Uri
|
|
5
4
|
import android.os.Bundle
|
|
5
|
+
import android.util.Base64
|
|
6
6
|
import androidx.car.app.CarContext
|
|
7
7
|
import androidx.car.app.model.Action
|
|
8
8
|
import androidx.car.app.model.ActionStrip
|
|
@@ -18,7 +18,9 @@ import androidx.car.app.model.signin.ProviderSignInMethod
|
|
|
18
18
|
import androidx.car.app.model.signin.QRCodeSignInMethod
|
|
19
19
|
import androidx.car.app.model.signin.SignInTemplate
|
|
20
20
|
import androidx.core.graphics.drawable.IconCompat
|
|
21
|
-
import
|
|
21
|
+
import androidx.core.net.toUri
|
|
22
|
+
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
|
|
23
|
+
import com.margelo.nitro.NitroModules
|
|
22
24
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.KeyboardType
|
|
23
25
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.NitroAction
|
|
24
26
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.NitroActionType
|
|
@@ -26,8 +28,8 @@ import com.margelo.nitro.swe.iternio.reactnativeautoplay.R
|
|
|
26
28
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.SignInTemplateConfig
|
|
27
29
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.SignInWithGoogleActivity
|
|
28
30
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.TextInputType
|
|
31
|
+
import org.json.JSONObject
|
|
29
32
|
import java.security.InvalidParameterException
|
|
30
|
-
import androidx.core.net.toUri
|
|
31
33
|
|
|
32
34
|
class SignInTemplate(
|
|
33
35
|
context: CarContext, config: SignInTemplateConfig
|
|
@@ -115,32 +117,35 @@ class SignInTemplate(
|
|
|
115
117
|
).build()
|
|
116
118
|
)
|
|
117
119
|
setOnClickListener(ParkedOnlyOnClickListener.create {
|
|
118
|
-
val extras = Bundle(
|
|
120
|
+
val extras = Bundle(2)
|
|
119
121
|
extras.putBinder(
|
|
120
122
|
SignInWithGoogleActivity.BINDER_KEY,
|
|
121
123
|
object : SignInWithGoogleActivity.OnSignInComplete() {
|
|
122
|
-
override fun onSignInComplete(
|
|
123
|
-
|
|
124
|
+
override fun onSignInComplete(
|
|
125
|
+
credential: GoogleIdTokenCredential?,
|
|
126
|
+
serverAuthCode: String?
|
|
127
|
+
) {
|
|
128
|
+
if (credential == null) {
|
|
124
129
|
googleSignIn.callback("Error signing in", null)
|
|
125
|
-
|
|
126
|
-
googleSignIn.callback(
|
|
127
|
-
null,
|
|
128
|
-
com.margelo.nitro.swe.iternio.reactnativeautoplay.GoogleSignInAccount(
|
|
129
|
-
serverAuthCode = account.serverAuthCode,
|
|
130
|
-
email = account.email,
|
|
131
|
-
id = account.id,
|
|
132
|
-
displayName = account.displayName,
|
|
133
|
-
photoUrl = account.photoUrl?.toString(),
|
|
134
|
-
idToken = account.idToken,
|
|
135
|
-
givenName = account.givenName,
|
|
136
|
-
familyName = account.familyName
|
|
137
|
-
)
|
|
138
|
-
)
|
|
130
|
+
return
|
|
139
131
|
}
|
|
132
|
+
googleSignIn.callback(
|
|
133
|
+
null,
|
|
134
|
+
com.margelo.nitro.swe.iternio.reactnativeautoplay.GoogleSignInAccount(
|
|
135
|
+
serverAuthCode = serverAuthCode,
|
|
136
|
+
email = credential.id,
|
|
137
|
+
id = subFromIdToken(credential.idToken),
|
|
138
|
+
displayName = credential.displayName,
|
|
139
|
+
photoUrl = credential.profilePictureUri?.toString(),
|
|
140
|
+
idToken = credential.idToken,
|
|
141
|
+
givenName = credential.givenName,
|
|
142
|
+
familyName = credential.familyName
|
|
143
|
+
)
|
|
144
|
+
)
|
|
140
145
|
}
|
|
141
146
|
})
|
|
142
147
|
extras.putString("serverClientId", googleSignIn.serverClientId)
|
|
143
|
-
|
|
148
|
+
NitroModules.applicationContext?.startActivity(
|
|
144
149
|
Intent().setClass(context, SignInWithGoogleActivity::class.java)
|
|
145
150
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).putExtras(extras)
|
|
146
151
|
)
|
|
@@ -211,4 +216,13 @@ class SignInTemplate(
|
|
|
211
216
|
config.onPopped?.let { it() }
|
|
212
217
|
templates.remove(templateId)
|
|
213
218
|
}
|
|
219
|
+
|
|
220
|
+
private fun subFromIdToken(idToken: String): String? = runCatching {
|
|
221
|
+
val payload = idToken.split(".")[1]
|
|
222
|
+
val json = String(
|
|
223
|
+
Base64.decode(payload, Base64.URL_SAFE or Base64.NO_PADDING or Base64.NO_WRAP),
|
|
224
|
+
Charsets.UTF_8
|
|
225
|
+
)
|
|
226
|
+
JSONObject(json).getString("sub")
|
|
227
|
+
}.getOrNull()
|
|
214
228
|
}
|
|
@@ -46,4 +46,9 @@ export declare class SignInTemplate extends Template<SignInTemplateConfig, SignI
|
|
|
46
46
|
* @returns A promise that resolves when the template is updated.
|
|
47
47
|
*/
|
|
48
48
|
updateTemplate(updatedConfig: SignInTemplateUpdateConfig): Promise<void> | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Whether "Sign in with Google" is usable, i.e. Google Play services 23.08+ is installed.
|
|
51
|
+
* Check this before creating a `SignInTemplate` with `GoogleSignIn` — creation throws otherwise.
|
|
52
|
+
*/
|
|
53
|
+
static isGoogleSignInAvailable(): boolean;
|
|
49
54
|
}
|
|
@@ -48,4 +48,11 @@ export class SignInTemplate extends Template {
|
|
|
48
48
|
}
|
|
49
49
|
return HybridSignInTemplate?.updateTemplate(this.id, nitroConfig);
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Whether "Sign in with Google" is usable, i.e. Google Play services 23.08+ is installed.
|
|
53
|
+
* Check this before creating a `SignInTemplate` with `GoogleSignIn` — creation throws otherwise.
|
|
54
|
+
*/
|
|
55
|
+
static isGoogleSignInAvailable() {
|
|
56
|
+
return HybridSignInTemplate?.isGoogleSignInAvailable() ?? false;
|
|
57
|
+
}
|
|
51
58
|
}
|
|
@@ -51,5 +51,12 @@ class SignInTemplate extends Template_1.Template {
|
|
|
51
51
|
}
|
|
52
52
|
return exports.HybridSignInTemplate?.updateTemplate(this.id, nitroConfig);
|
|
53
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Whether "Sign in with Google" is usable, i.e. Google Play services 23.08+ is installed.
|
|
56
|
+
* Check this before creating a `SignInTemplate` with `GoogleSignIn` — creation throws otherwise.
|
|
57
|
+
*/
|
|
58
|
+
static isGoogleSignInAvailable() {
|
|
59
|
+
return exports.HybridSignInTemplate?.isGoogleSignInAvailable() ?? false;
|
|
60
|
+
}
|
|
54
61
|
}
|
|
55
62
|
exports.SignInTemplate = SignInTemplate;
|
|
@@ -144,5 +144,10 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
144
144
|
return __promise;
|
|
145
145
|
}();
|
|
146
146
|
}
|
|
147
|
+
bool JHybridSignInTemplateSpec::isGoogleSignInAvailable() {
|
|
148
|
+
static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("isGoogleSignInAvailable");
|
|
149
|
+
auto __result = method(_javaPart);
|
|
150
|
+
return static_cast<bool>(__result);
|
|
151
|
+
}
|
|
147
152
|
|
|
148
153
|
} // namespace margelo::nitro::swe::iternio::reactnativeautoplay
|
|
@@ -56,6 +56,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
56
56
|
// Methods
|
|
57
57
|
void createSignInTemplate(const SignInTemplateConfig& config) override;
|
|
58
58
|
std::shared_ptr<Promise<void>> updateTemplate(const std::string& templateId, const SignInTemplateConfig& config) override;
|
|
59
|
+
bool isGoogleSignInAvailable() override;
|
|
59
60
|
|
|
60
61
|
private:
|
|
61
62
|
jni::global_ref<JHybridSignInTemplateSpec::JavaPart> _javaPart;
|
|
@@ -37,6 +37,10 @@ abstract class HybridSignInTemplateSpec: HybridObject() {
|
|
|
37
37
|
@DoNotStrip
|
|
38
38
|
@Keep
|
|
39
39
|
abstract fun updateTemplate(templateId: String, config: SignInTemplateConfig): Promise<Unit>
|
|
40
|
+
|
|
41
|
+
@DoNotStrip
|
|
42
|
+
@Keep
|
|
43
|
+
abstract fun isGoogleSignInAvailable(): Boolean
|
|
40
44
|
|
|
41
45
|
// Default implementation of `HybridObject.toString()`
|
|
42
46
|
override fun toString(): String {
|
|
@@ -16,6 +16,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
16
16
|
registerHybrids(this, [](Prototype& prototype) {
|
|
17
17
|
prototype.registerHybridMethod("createSignInTemplate", &HybridSignInTemplateSpec::createSignInTemplate);
|
|
18
18
|
prototype.registerHybridMethod("updateTemplate", &HybridSignInTemplateSpec::updateTemplate);
|
|
19
|
+
prototype.registerHybridMethod("isGoogleSignInAvailable", &HybridSignInTemplateSpec::isGoogleSignInAvailable);
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -53,6 +53,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
53
53
|
// Methods
|
|
54
54
|
virtual void createSignInTemplate(const SignInTemplateConfig& config) = 0;
|
|
55
55
|
virtual std::shared_ptr<Promise<void>> updateTemplate(const std::string& templateId, const SignInTemplateConfig& config) = 0;
|
|
56
|
+
virtual bool isGoogleSignInAvailable() = 0;
|
|
56
57
|
|
|
57
58
|
protected:
|
|
58
59
|
// Hybrid Setup
|
package/package.json
CHANGED
|
@@ -7,4 +7,5 @@ interface SignInTemplateConfig extends NitroTemplateConfig, NitroSignInTemplateC
|
|
|
7
7
|
export interface SignInTemplate extends HybridObject<{ android: 'kotlin' }> {
|
|
8
8
|
createSignInTemplate(config: SignInTemplateConfig): void;
|
|
9
9
|
updateTemplate(templateId: string, config: SignInTemplateConfig): Promise<void>;
|
|
10
|
+
isGoogleSignInAvailable(): boolean;
|
|
10
11
|
}
|
|
@@ -114,4 +114,12 @@ export class SignInTemplate extends Template<
|
|
|
114
114
|
|
|
115
115
|
return HybridSignInTemplate?.updateTemplate(this.id, nitroConfig);
|
|
116
116
|
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Whether "Sign in with Google" is usable, i.e. Google Play services 23.08+ is installed.
|
|
120
|
+
* Check this before creating a `SignInTemplate` with `GoogleSignIn` — creation throws otherwise.
|
|
121
|
+
*/
|
|
122
|
+
static isGoogleSignInAvailable(): boolean {
|
|
123
|
+
return HybridSignInTemplate?.isGoogleSignInAvailable() ?? false;
|
|
124
|
+
}
|
|
117
125
|
}
|