Skip to content

Commit

Permalink
Quiltthub example app wip
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-quiltt committed Feb 18, 2024
1 parent 66daaf6 commit eaabf8c
Show file tree
Hide file tree
Showing 14 changed files with 453 additions and 70 deletions.
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data android:scheme="quilttandroidexample"
<data
android:scheme="quilttandroidexample"
android:host="open.kotlin.app" />
</intent-filter>
</activity>
Expand Down
11 changes: 11 additions & 0 deletions app_jetpack_compose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ android {
vectorDrawables {
useSupportLibrary = true
}

buildFeatures {
buildConfig = true
}

val ingressConnectorId = System.getenv("MOBILE_INGRESS_CONNECTOR_ID")
val addConnectorId = System.getenv("MOBILE_ADD_CONNECTOR_ID")
buildConfigField("String", "INGRESS_CONNECTOR_ID", "\"$ingressConnectorId\"")
buildConfigField("String", "ADD_CONNECTOR_ID", "\"$addConnectorId\"")
}

buildTypes {
Expand Down Expand Up @@ -70,6 +79,8 @@ dependencies {
debugImplementation("androidx.compose.ui:ui-test-manifest")

implementation("androidx.core:core-splashscreen:1.0.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9")
implementation("androidx.browser:browser:1.4.0")
implementation(project(":connector"))
// Enable below to use the published version
// implementation("app.quiltt:connector:<VERSION>")
Expand Down
21 changes: 14 additions & 7 deletions app_jetpack_compose/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />

Expand All @@ -10,36 +11,42 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.App.First">
<activity
android:name=".QuilttHubActivity"
android:exported="true"
android:label="@string/title_activity_quiltt_hub"
android:theme="@style/Theme.QuilttConnector"></activity>
<activity
android:name=".QuilttConnectorActivity"
android:launchMode="singleTop"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/Theme.QuilttConnector">
<tools:validation testUrl="https://quiltt.app/mobile/hub/connect" />

<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data android:scheme="quilttandroidexample"
android:host="open.kotlin.app" />
<data android:scheme="https" />
<data android:host="quiltt.app" />
<data android:pathPattern="/mobile/hub/connect" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/Theme.App.First">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />


<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>


</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package app.quiltt.app_jetpack_compose

object AppConfig {
val ingressConnectorId = BuildConfig.INGRESS_CONNECTOR_ID
val addConnectorId = BuildConfig.ADD_CONNECTOR_ID
val oauthRedirectUrl = "https://quiltt.app/mobile/hub/reconnect"
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,22 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import androidx.activity.viewModels
import androidx.compose.material3.Button
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.ViewModelProvider
import app.quiltt.connector.AuthResponse
import app.quiltt.connector.QuilttAuthApi
import app.quiltt.connector.QuilttConnector
import app.quiltt.connector.QuilttConnectorConnectConfiguration
import kotlinx.coroutines.Dispatchers

class MainActivity : ComponentActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val token = SharedPreferencesHelper(context = this).getData("token")
val viewModel: MainViewModel by viewModels { MainViewModelFactory(token) }

installSplashScreen().apply {
setKeepOnScreenCondition {
Expand All @@ -38,49 +40,65 @@ class MainActivity : ComponentActivity() {
}

setContent {
MainContent()
val isValidToken by viewModel.isValidToken.collectAsState()
if (isValidToken) {
val intent = Intent(this@MainActivity, QuilttHubActivity::class.java)
startActivity(intent)
} else {
IngressConnector()
}
}
}
}

class MainViewModel : ViewModel() {
class MainViewModelFactory(private val token: String?) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T = MainViewModel(token) as T
}

class MainViewModel(private val token:String?) : ViewModel() {
private val _loading = MutableStateFlow(true)
private val _isValidToken = MutableStateFlow(false)
val loading = _loading.asStateFlow()
val isValidToken = _isValidToken.asStateFlow()

init {
viewModelScope.launch {// run background task here
delay(2000)
_loading.value = false
viewModelScope.launch(Dispatchers.IO) {// run background task here
if (token != null) {
val result = QuilttAuthApi(clientId = null).ping(token = token)
if (result is AuthResponse.SessionResponse) {
_isValidToken.value = true
_loading.value = false
} else {
_isValidToken.value = false
_loading.value = false
}
} else {
_isValidToken.value = false
_loading.value = false
}
}
}
}

@Composable
fun MainContent() {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
LaunchConnectorButton()
}
}

@Composable
fun LaunchConnectorButton() {
fun IngressConnector() {
val context = LocalContext.current
Button(
onClick = {
val intent = Intent(context, QuilttConnectorActivity::class.java)
val quilttConnector = QuilttConnector(context)
val config = QuilttConnectorConnectConfiguration(connectorId = AppConfig.ingressConnectorId)
val connectorWebView = quilttConnector.connect(config = config, onExitSuccess = { metadata ->
val token: String? = metadata.token
if (token != null) {
SharedPreferencesHelper(context).saveData("token", token)
val intent = Intent(context, QuilttHubActivity::class.java)
context.startActivity(intent)
},
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF800080))
) {
Text("Launch Connector")
}
(context as MainActivity).finish()
}
})
AndroidView(factory = { connectorWebView } )
}

@Preview(showBackground = true)
@Composable
fun QuilttHubPreview() {
MainContent()
IngressConnector()
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package app.quiltt.app_jetpack_compose

import android.app.Activity
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.Composable
Expand All @@ -11,41 +10,78 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.viewinterop.AndroidView
import app.quiltt.connector.QuilttConnector
import app.quiltt.connector.QuilttConnectorConnectConfiguration
import app.quiltt.connector.QuilttConnectorReconnectConfiguration

class QuilttConnectorActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val config = QuilttConnectorConnectConfiguration(
connectorId = "<CONNECTOR_ID>",
oauthRedirectUrl = "<YOUR_HTTP_APP_LINK")
val token = "<ACCESS_TOKEN>"
setContent {
QuilttConnectorContent(config = config, token = token)
val connectionId = intent.getStringExtra("connectionId")
val connectorId = AppConfig.addConnectorId
val oauthRedirectUrl = AppConfig.oauthRedirectUrl
val token = SharedPreferencesHelper(context = this).getData("token")
println("Connection ID: $connectionId")
if (connectionId != null) {
val config = QuilttConnectorReconnectConfiguration(
connectorId = connectorId,
oauthRedirectUrl = oauthRedirectUrl,
connectionId = connectionId
)
setContent {
QuilttReconnectContent(config = config, token = token!!)
}
} else {
val config = QuilttConnectorConnectConfiguration(
connectorId = connectorId,
oauthRedirectUrl = oauthRedirectUrl)
setContent {
QuilttConnectContent(config = config, token = token!!)
}
}

}
}

@Composable
fun QuilttConnectorContent(config: QuilttConnectorConnectConfiguration, token: String? = null) {
fun QuilttConnectContent(config: QuilttConnectorConnectConfiguration, token: String) {
val context = LocalContext.current
val quilttConnector = QuilttConnector(context)
if (token != null) {
quilttConnector.authenticate(token)
}
quilttConnector.authenticate(token)
val connectorWebView = quilttConnector.connect(
config = config,
onEvent = { eventType, metadata ->
println("Event: $eventType")
onExitSuccess = { metadata ->
println("Exit success!")
println("Metadata: $metadata")
if (context is Activity) {
context.finish()
}
},
onExit = { eventType, metadata ->
println("Event: $eventType")
onExitAbort = { metadata ->
println("Exit abort!")
println("Metadata: $metadata")
if (context is Activity) {
context.finish()
}
},
onExitError = { metadata ->
println("Exit error!")
println("Metadata: $metadata")
if (context is Activity) {
context.finish()
}
})
AndroidView(factory = { connectorWebView } )
}

@Composable
fun QuilttReconnectContent(config: QuilttConnectorReconnectConfiguration, token: String) {
val context = LocalContext.current
val quilttConnector = QuilttConnector(context)
quilttConnector.authenticate(token)
val connectorWebView = quilttConnector.reconnect(
config = config,
onExitSuccess = { metadata ->
println("Exit success!")
println("Metadata: $metadata")
Toast.makeText(context, metadata.connectionId, Toast.LENGTH_LONG).show()
if (context is Activity) {
context.finish()
}
Expand All @@ -70,10 +106,11 @@ fun QuilttConnectorContent(config: QuilttConnectorConnectConfiguration, token: S
@Preview(showBackground = true)
@Composable
fun QuilttConnectorPreview() {
QuilttConnectorContent(
QuilttConnectContent(
config = QuilttConnectorConnectConfiguration(
connectorId = "<CONNECTOR_ID>",
oauthRedirectUrl = "<YOUR_HTTP_APP_LINK>"
)
),
token = "<TOKEN>"
)
}
Loading

0 comments on commit eaabf8c

Please sign in to comment.