Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code link login #96

Merged
merged 8 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ debug.properties
release.properties
prod.properties
earlybird.properties
aussie.properties

_ignore*.kt
core/database/schemas/com.crisiscleanup.core.database.TestCrisisCleanupDatabase
Expand Down
14 changes: 11 additions & 3 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ plugins {

android {
defaultConfig {
val buildVersion = 166
val buildVersion = 170
applicationId = "com.crisiscleanup"
versionCode = buildVersion
versionName = "0.8.${buildVersion - 155}"
versionName = "0.9.${buildVersion - 168}"

// Custom test runner to set up Hilt dependency graph
testInstrumentationRunner = "com.crisiscleanup.core.testing.CrisisCleanupTestRunner"
Expand Down Expand Up @@ -69,6 +69,11 @@ android {
buildConfigField("Boolean", "IS_PROD_BUILD", "true")
buildConfigField("Boolean", "IS_EARLYBIRD_BUILD", "true")
}

val aussie by getting {
buildConfigField("Boolean", "IS_PROD_BUILD", "true")
buildConfigField("Boolean", "IS_EARLYBIRD_BUILD", "false")
}
}

packaging {
Expand All @@ -91,7 +96,10 @@ secrets {
androidComponents {
beforeVariants { variantBuilder ->
// Unnecessary variants
if (variantBuilder.name == "prodDebug" || variantBuilder.name == "earlybirdDebug") {
if (variantBuilder.name == "prodDebug" ||
variantBuilder.name == "earlybirdDebug" ||
variantBuilder.name == "aussieDebug"
) {
variantBuilder.enable = false
}
}
Expand Down
48 changes: 48 additions & 0 deletions app/src/aussie/res/drawable/ic_launcher_foreground.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="256"
android:viewportHeight="256">
<group android:scaleX="0.67"
android:scaleY="0.67"
android:translateX="42.24"
android:translateY="42.24">
<path
android:pathData="M99,59C132.14,59 159,85.86 159,119C159,132.47 154.56,144.91 147.06,154.92L99,232L50.94,154.93C43.44,144.92 39,132.48 39,119C39,85.86 65.86,59 99,59Z"
android:strokeWidth="1"
android:fillColor="#454545"
android:fillAlpha="0.5325612"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M99,59C132.14,59 159,85.86 159,119C159,132.47 154.56,144.91 147.06,154.92L99,232L50.94,154.93C43.44,144.92 39,132.48 39,119C39,85.86 65.86,59 99,59Z"
android:strokeWidth="1"
android:fillColor="#FECE09"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M89,98.5C96.7,98.5 103.38,102.85 106.73,109.23L98.03,114.2C96.42,110.83 92.98,108.5 89,108.5C83.48,108.5 79,112.98 79,118.5C79,124.02 83.48,128.5 89,128.5C92.98,128.5 96.42,126.17 98.03,122.8L106.73,127.77C103.38,134.15 96.7,138.5 89,138.5C77.95,138.5 69,129.55 69,118.5C69,107.45 77.95,98.5 89,98.5Z"
android:strokeWidth="1"
android:fillColor="#F79820"
android:fillType="nonZero"
android:strokeColor="#00000000"/>
<path
android:pathData="M136.5,98.5C144.2,98.5 150.88,102.85 154.23,109.23L145.53,114.2C143.92,110.83 140.48,108.5 136.5,108.5C130.98,108.5 126.5,112.98 126.5,118.5C126.5,124.02 130.98,128.5 136.5,128.5C140.48,128.5 143.92,126.17 145.53,122.8L154.23,127.77C150.88,134.15 144.2,138.5 136.5,138.5C125.45,138.5 116.5,129.55 116.5,118.5C116.5,107.45 125.45,98.5 136.5,98.5Z"
android:strokeWidth="1"
android:fillColor="#F79820"
android:fillType="nonZero"
android:strokeColor="#00000000"/>
<path
android:pathData="M76.62,153.3C86.38,162.13 99.31,167.5 113.5,167.5C125.53,167.5 136.66,163.64 145.72,157.08L135.33,173.74C128.51,176.18 121.16,177.5 113.5,177.5C96.55,177.5 81.11,171.01 69.54,160.38L76.62,153.3Z"
android:strokeWidth="1"
android:fillColor="#F79820"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M136.23,215L141.82,199.53L162.24,199.53L167.48,215L175.14,215L156.41,163.36L148.5,163.36L129.05,215L136.23,215ZM159.99,193.84L143.82,193.84L152.15,171.02L159.99,193.84ZM202.32,216.37C211.04,216.37 216.97,213.25 220.11,207.02C221.82,203.6 222.68,198.71 222.68,192.36L222.68,192.36L222.68,163.36L215.57,163.36L215.57,195.28C215.57,199 215,201.97 213.85,204.17C211.72,208.23 207.69,210.25 201.76,210.25C196.81,210.25 193.3,208.38 191.21,204.63C189.8,202.14 189.1,199.03 189.1,195.28L189.1,195.28L189.1,163.36L182,163.36L182,192.36C182,198.71 182.86,203.6 184.57,207.02C187.68,213.25 193.6,216.37 202.32,216.37Z"
android:strokeWidth="1"
android:fillColor="#000000"
android:fillType="nonZero"
android:strokeColor="#00000000"/>
</group>
</vector>
4 changes: 0 additions & 4 deletions app/src/demo/res/mipmap-anydpi-v26/ic_launcher.xml

This file was deleted.

4 changes: 0 additions & 4 deletions app/src/demoDebug/res/mipmap-anydpi-v26/ic_launcher.xml

This file was deleted.

4 changes: 0 additions & 4 deletions app/src/earlybird/res/mipmap-anydpi-v26/ic_launcher.xml

This file was deleted.

7 changes: 5 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@

<activity
android:name=".MainActivity"
android:exported="true">
android:exported="true"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand All @@ -50,8 +51,10 @@

<data android:host="${APP_LINK_TLD}" />

<data android:pathPrefix="/o/callback" />
<data android:pathPrefix="/l" />
<data android:pathPrefix="/password/reset" />
<data android:pathPrefix="/invitation_token" />
<data android:pathPrefix="/mobile_app_user_invite" />
</intent-filter>
</activity>
</application>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ class ExternalIntentProcessor @Inject constructor(
}

private fun processMainIntent(url: Uri, urlPath: String): Boolean {
if (urlPath.startsWith("/o/callback")) {
url.getQueryParameter("code")?.let { code ->
if (urlPath.startsWith("/l/")) {
val code = urlPath.replace("/l/", "")
if (code.isNotBlank()) {
authEventBus.onEmailLoginLink(code)
}
} else if (urlPath.startsWith("/password/reset/")) {
Expand Down
24 changes: 20 additions & 4 deletions app/src/main/java/com/crisiscleanup/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.crisiscleanup

import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
Expand Down Expand Up @@ -160,14 +161,22 @@ class MainActivity : ComponentActivity() {

intent?.let {
if (!intentProcessor.processMainIntent(it)) {
it.data?.let { dataUri ->
// TODO Open to browser or WebView. Do no loop back here.
logger.logDebug("App link not processed $dataUri")
}
logUnprocessedExternalUri(it)
}
}
}

override fun onNewIntent(intent: Intent?) {
var isConsumed = false
intent?.let {
isConsumed = intentProcessor.processMainIntent(it)
}
if (!isConsumed) {
logUnprocessedExternalUri(intent)
super.onNewIntent(intent)
}
}

override fun onResume() {
super.onResume()
lazyStats.get().isTrackingEnabled = true
Expand Down Expand Up @@ -202,6 +211,13 @@ class MainActivity : ComponentActivity() {
trimMemoryEventManager.onTrimMemory(level)
super.onTrimMemory(level)
}

private fun logUnprocessedExternalUri(intent: Intent?) {
intent?.data?.let { dataUri ->
// TODO Open to browser or WebView. Do no loop back here.
logger.logDebug("App link not processed $dataUri")
}
}
}

/**
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/java/com/crisiscleanup/MainActivityViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import com.crisiscleanup.core.data.IncidentSelector
import com.crisiscleanup.core.data.repository.AccountDataRefresher
import com.crisiscleanup.core.data.repository.AccountDataRepository
import com.crisiscleanup.core.data.repository.AppDataManagementRepository
import com.crisiscleanup.core.data.repository.ClearAppDataStep.*
import com.crisiscleanup.core.data.repository.IncidentsRepository
import com.crisiscleanup.core.data.repository.LocalAppMetricsRepository
import com.crisiscleanup.core.data.repository.LocalAppPreferencesRepository
Expand Down Expand Up @@ -165,8 +164,8 @@ class MainActivityViewModel @Inject constructor(
return null
}

// TODO Build route to auth/forgot-password rather than switches through the hierarchy
val showPasswordReset = authEventBus.showResetPassword
val showMagicLinkLogin = authEventBus.showMagicLinkLogin

val isSwitchingToProduction: StateFlow<Boolean>
val productionSwitchMessage: StateFlow<String>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import com.crisiscleanup.core.appnav.RouteConstant
import com.crisiscleanup.core.appnav.RouteConstant.authGraphRoutePattern
import com.crisiscleanup.feature.authentication.navigation.authGraph
import com.crisiscleanup.feature.authentication.navigation.emailLoginLinkScreen
import com.crisiscleanup.feature.authentication.navigation.forgotPasswordScreen
import com.crisiscleanup.feature.authentication.navigation.loginWithEmailScreen
import com.crisiscleanup.feature.authentication.navigation.loginWithPhoneScreen
import com.crisiscleanup.feature.authentication.navigation.magicLinkLoginScreen
import com.crisiscleanup.feature.authentication.navigation.navigateToEmailLoginLink
import com.crisiscleanup.feature.authentication.navigation.navigateToForgotPassword
import com.crisiscleanup.feature.authentication.navigation.navigateToLoginWithEmail
import com.crisiscleanup.feature.authentication.navigation.navigateToLoginWithPhone
import com.crisiscleanup.feature.authentication.navigation.resetPasswordScreen

@Composable
fun CrisisCleanupAuthNavHost(
Expand All @@ -21,10 +25,12 @@ fun CrisisCleanupAuthNavHost(
closeAuthentication: () -> Unit,
onBack: () -> Unit,
modifier: Modifier = Modifier,
startDestination: String = RouteConstant.authGraphRoutePattern,
startDestination: String = authGraphRoutePattern,
) {
val navToLoginWithEmail =
remember(navController) { { navController.navigateToLoginWithEmail() } }
val navToLoginWithPhone =
remember(navController) { { navController.navigateToLoginWithPhone() } }
val navToForgotPassword =
remember(navController) { { navController.navigateToForgotPassword() } }
val navToEmailMagicLink =
Expand All @@ -51,9 +57,22 @@ fun CrisisCleanupAuthNavHost(
)
},
)
loginWithPhoneScreen(
onBack = onBack,
closeAuthentication = closeAuthentication,
)
resetPasswordScreen(
onBack = onBack,
closeResetPassword = navToLoginWithEmail,
)
magicLinkLoginScreen(
onBack = onBack,
closeAuthentication = closeAuthentication,
)
},
enableBackHandler = enableBackHandler,
openLoginWithEmail = navToLoginWithEmail,
openLoginWithPhone = navToLoginWithPhone,
closeAuthentication = closeAuthentication,
)
}
Expand Down
20 changes: 16 additions & 4 deletions app/src/main/java/com/crisiscleanup/ui/CrisisCleanupApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import androidx.compose.animation.slideIn
import androidx.compose.animation.slideOut
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
Expand Down Expand Up @@ -73,6 +72,8 @@ import com.crisiscleanup.core.designsystem.icon.Icon.ImageVectorIcon
import com.crisiscleanup.core.ui.AppLayoutArea
import com.crisiscleanup.core.ui.LocalAppLayout
import com.crisiscleanup.core.ui.rememberIsKeyboardOpen
import com.crisiscleanup.feature.authentication.navigation.navigateToMagicLinkLogin
import com.crisiscleanup.feature.authentication.navigation.navigateToPasswordReset
import com.crisiscleanup.feature.cases.ui.SelectIncidentDialog
import com.crisiscleanup.navigation.CrisisCleanupAuthNavHost
import com.crisiscleanup.navigation.CrisisCleanupNavHost
Expand Down Expand Up @@ -153,9 +154,22 @@ private fun LoadedContent(
val isAccountExpired by viewModel.isAccountExpired

val showPasswordReset by viewModel.showPasswordReset.collectAsStateWithLifecycle(false)
val showMagicLinkLogin by viewModel.showMagicLinkLogin.collectAsStateWithLifecycle(false)
val isNotAuthenticatedState = authState !is AuthState.Authenticated
var openAuthentication by rememberSaveable { mutableStateOf(isNotAuthenticatedState) }
if (openAuthentication || isNotAuthenticatedState || showPasswordReset) {
if (openAuthentication ||
isNotAuthenticatedState ||
showPasswordReset ||
showMagicLinkLogin
) {
LaunchedEffect(showPasswordReset, showMagicLinkLogin) {
if (showPasswordReset) {
appState.navController.navigateToPasswordReset()
} else if (showMagicLinkLogin) {
appState.navController.navigateToMagicLinkLogin()
}
}

val toggleAuthentication = remember(authState) {
{ open: Boolean -> openAuthentication = open }
}
Expand Down Expand Up @@ -209,7 +223,6 @@ private fun LoadedContent(

@OptIn(
ExperimentalComposeUiApi::class,
ExperimentalLayoutApi::class,
)
@Composable
private fun AuthenticateContent(
Expand Down Expand Up @@ -246,7 +259,6 @@ private fun AuthenticateContent(
}

@OptIn(
ExperimentalLayoutApi::class,
ExperimentalComposeUiApi::class,
)
@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum class NiaFlavor(val dimension: FlavorDimension, val applicationIdSuffix: St
demo(FlavorDimension.contentType, ".demo"),
prod(FlavorDimension.contentType, ".prod"),
earlybird(FlavorDimension.contentType, ".earlybird"),
aussie(FlavorDimension.contentType, ".aussie"),
}

fun configureFlavors(
Expand Down
24 changes: 23 additions & 1 deletion build_sign_prod_release_bundle.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,36 @@ APP_OUT=$DIR/app/build/outputs
if [[ -z "$DIST_DIR" ]]; then
DIST_DIR=$DIR/app/build
fi

DIST_AAB=$DIST_DIR/app-prod-release.aab
MAPPING_FILE_NAME=release-aab-mapping.txt
MAPPING_FILE_NAME=prod-release-aab-mapping.txt
cp $APP_OUT/bundle/prodRelease/app-prod-release.aab $DIST_AAB
cp $APP_OUT/mapping/prodRelease/mapping.txt $DIST_DIR/$MAPPING_FILE_NAME

# Sign app bundle
jarsigner -verbose -storepass $CRISIS_CLEANUP_ANDROID_KEYSTORE_PW -keystore $CRISIS_CLEANUP_ANDROID_KEYSTORE_PATH $DIST_AAB $CRISIS_CLEANUP_ANDROID_KEYSTORE_KEY_ALIAS -keypass $CRISIS_CLEANUP_ANDROID_KEYSTORE_KEY_PW

# Most likely successful
if [[ -f "$DIST_AAB" && -f "$DIST_DIR/$MAPPING_FILE_NAME" ]]; then
GREEN='\033[0;32m'
NC='\033[0m'
dirPathLength=${#DIR}
bundleRelativePath=${DIST_AAB:dirPathLength}
echo -e "\n${GREEN}Signed bundle at${NC} .$bundleRelativePath. Mapping $MAPPING_FILE_NAME is copied to same area.\n"
else
messageExit "Something went wrong during build/signing"
fi

$GRADLEW bundleAussieRelease

DIST_AAB=$DIST_DIR/app-aussie-release.aab
MAPPING_FILE_NAME=aussie-release-aab-mapping.txt
cp $APP_OUT/bundle/aussieRelease/app-aussie-release.aab $DIST_AAB
cp $APP_OUT/mapping/aussieRelease/mapping.txt $DIST_DIR/$MAPPING_FILE_NAME

# Sign app bundle
jarsigner -verbose -storepass $CRISIS_CLEANUP_ANDROID_KEYSTORE_PW -keystore $CRISIS_CLEANUP_ANDROID_KEYSTORE_PATH $DIST_AAB $CRISIS_CLEANUP_ANDROID_KEYSTORE_KEY_ALIAS -keypass $CRISIS_CLEANUP_ANDROID_KEYSTORE_KEY_PW

# Most likely successful
if [[ -f "$DIST_AAB" && -f "$DIST_DIR/$MAPPING_FILE_NAME" ]]; then
GREEN='\033[0;32m'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface AddressSearchRepository {
center: LatLng? = null,
southwest: LatLng? = null,
northeast: LatLng? = null,
maxResults: Int = 8,
maxResults: Int = 10,
): List<KeySearchAddress>

suspend fun getPlaceAddress(placeId: String): LocationAddress?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ object RouteConstant {

const val authRoute = "auth_route"
const val loginWithEmailRoute = "$authRoute/login_with_email"
const val loginWithPhoneRoute = "$authRoute/login_with_phone"
const val forgotPasswordRoute = "forgot_password_route"
const val emailLoginLinkRoute = "email_login_link_route"
// const val resetPasswordRoute = "reset_password_route"
const val resetPasswordRoute = "$authRoute/reset_password_route"
const val magicLinkLoginRoute = "$authRoute/magic_link_login"

// This cannot be used as the navHost startDestination
const val casesRoute = "cases_route"
Expand Down
Loading
Loading