Skip to content

Commit

Permalink
Improve dismiss handling
Browse files Browse the repository at this point in the history
  • Loading branch information
nrobi144 committed Feb 11, 2022
1 parent 15dde2b commit 8aa10c1
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand All @@ -25,29 +26,34 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var message by remember { mutableStateOf<String?>(null) }
if (message == null) {
TeslAuth(
logLevel = LogLevel.DEFAULT,
onAuthorizationCodeReceived = {
Log.i(TAG, "Authorization Code: $it")
},
onBearerTokenReceived = {
Log.i(TAG, "Bearer token: $it")
},
onAccessTokenReceived = {
message = it.toString()
}, onError = {
message = it.toString()
})
} else {
Box(Modifier.padding(16.dp)) {
Text(
message ?: "",
Modifier
.wrapContentSize()
.align(Alignment.Center)
)
MaterialTheme {
var message by remember { mutableStateOf<String?>(null) }
if (message == null) {
TeslAuth(
logLevel = LogLevel.DEFAULT,
onAuthorizationCodeReceived = {
Log.i(TAG, "Authorization Code: $it")
},
onBearerTokenReceived = {
Log.i(TAG, "Bearer token: $it")
},
onAccessTokenReceived = {
message = it.toString()
}, onError = {
message = it.toString()
}, onDismiss = {
message = "Dismissed"
})
} else {
Box(Modifier.padding(16.dp)) {
Text(
text = message ?: "",
modifier = Modifier
.wrapContentSize()
.align(Alignment.Center),
style = MaterialTheme.typography.body2.copy(color = MaterialTheme.colors.onPrimary)
)
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ plugins {
apply from: "${rootDir}/scripts/publish-root.gradle"

group = "energy.octopus"
version = "0.1.2"
version = "0.1.2¡"
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ typealias OnTokenReceivedCallback = (AuthToken) -> Unit
* @param onAccessTokenReceived callback called with the [AuthToken] as parameter if getting the authorization token was successful,
* @see <a href="https://tesla-api.timdorr.com/api-basics/authentication#refreshing-an-access-token">https://tesla-api.timdorr.com/api-basics/authentication#refreshing-an-access-token</a>
* @param onError callback called with the [Throwable] that occurred when trying to get the authorization token
* @param onDismiss called when the underlying [WebView] can't go back and the back press represents a dismiss of the Authentication WebView
* @param loadingIndicator optional composable, default is [CircularProgressIndicator]
*/

Expand All @@ -51,6 +52,7 @@ fun TeslAuth(
onBearerTokenReceived: OnTokenReceivedCallback? = null,
onAccessTokenReceived: OnTokenReceivedCallback? = null,
onError: (Throwable) -> Unit = {},
onDismiss: () -> Unit = {},
loadingIndicator: @Composable BoxScope.() -> Unit = {
CircularProgressIndicator(
Modifier.align(
Expand All @@ -67,15 +69,9 @@ fun TeslAuth(
WebAuth(
url = viewModel.url,
modifier = modifier.fillMaxSize(),
onCodeReceived = {
if (it != null) {
onAuthorizationCodeReceived?.invoke(it)
if (onBearerTokenReceived != null || onAccessTokenReceived != null) {
viewModel.getBearerToken(it)
}
}
},
onCodeReceived = viewModel::onCodeReceived,
onPageLoaded = viewModel::onPageLoaded,
onDismiss = onDismiss,
)
if (isLoading) {
loadingIndicator()
Expand All @@ -93,6 +89,10 @@ fun TeslAuth(
}
is ReceivedAccessToken -> onAccessTokenReceived?.invoke(it.token)
is Error -> onError(it.t)
is AuthorizationCodeReceived -> if (onBearerTokenReceived != null || onAccessTokenReceived != null) {
viewModel.getBearerToken(it.code)
}
Dismiss -> onDismiss()
}
}.launchIn(this)
}
Expand All @@ -104,6 +104,7 @@ private fun WebAuth(
modifier: Modifier = Modifier,
onCodeReceived: (String?) -> Unit = {},
onPageLoaded: () -> Unit = {},
onDismiss: () -> Unit = {},
) {
AndroidView(
modifier = modifier,
Expand All @@ -128,16 +129,16 @@ private fun WebAuth(
Logger.log("User agent: ${settings.userAgentString}")
Logger.log("Opening url for login: $url")
loadUrl(url)
setBackListener()
setBackListener(onDismiss = onDismiss)
}
}
)
}

private fun WebView.setBackListener() {
private fun WebView.setBackListener(onDismiss: () -> Unit = {}) {
setOnKeyListener { _, keyCode, keyEvent ->
if (keyEvent.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK && canGoBack()) {
goBack()
if (keyEvent.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK) {
onDismiss()
true
} else {
false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package energy.octopus.octopusenergy.teslauth
import android.net.Uri
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import energy.octopus.octopusenergy.teslauth.TeslaAuthViewModel.Event.*
import energy.octopus.octopusenergy.teslauth.api.TeslaApi
import energy.octopus.octopusenergy.teslauth.logging.Logger
import energy.octopus.octopusenergy.teslauth.model.AccessTokenRequest
Expand Down Expand Up @@ -54,7 +55,7 @@ internal class TeslaAuthViewModel(private val api: TeslaApi = TeslaApi()) : View
)
Logger.log("Got bearer token $bearerTokenResponse")
_event.emit(
Event.ReceivedBearerToken(
ReceivedBearerToken(
AuthToken(
accessToken = bearerTokenResponse.accessToken,
refreshToken = bearerTokenResponse.refreshToken,
Expand All @@ -64,7 +65,7 @@ internal class TeslaAuthViewModel(private val api: TeslaApi = TeslaApi()) : View
)
)
} catch (t: Throwable) {
_event.emit(Event.Error(t))
_event.emit(Error(t))
} finally {
_isLoading.value = false
}
Expand All @@ -84,7 +85,7 @@ internal class TeslaAuthViewModel(private val api: TeslaApi = TeslaApi()) : View
)
Logger.log("Got auth token $authTokenResponse")
_event.emit(
Event.ReceivedAccessToken(
ReceivedAccessToken(
AuthToken(
accessToken = authTokenResponse.accessToken,
refreshToken = authTokenResponse.refreshToken,
Expand All @@ -94,19 +95,36 @@ internal class TeslaAuthViewModel(private val api: TeslaApi = TeslaApi()) : View
)
)
} catch (t: Throwable) {
_event.emit(Event.Error(t))
_event.emit(Error(t))
} finally {
_isLoading.value = false
}
}
}

fun onCodeReceived(code: String?) {
code ?: return

viewModelScope.launch {
val error = code.substringAfter("error", missingDelimiterValue = "")
_event.emit(
if (error.isNotBlank()) {
if (error.contains("cancelled", ignoreCase = true)) Dismiss
else Error(IllegalStateException("Auth failed with: $error"))
} else AuthorizationCodeReceived(code)
)
}
}


fun onPageLoaded() {
_isLoading.value = false
}

sealed class Event {
object Dismiss : Event()
data class Error(val t: Throwable) : Event()
data class AuthorizationCodeReceived(val code: String) : Event()
data class ReceivedBearerToken(val token: AuthToken) : Event()
data class ReceivedAccessToken(val token: AuthToken) : Event()
}
Expand Down

0 comments on commit 8aa10c1

Please sign in to comment.