small changes
This commit is contained in:
@ -23,7 +23,8 @@ android {
|
|||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
isMinifyEnabled = false
|
isMinifyEnabled = true
|
||||||
|
isShrinkResources = true
|
||||||
proguardFiles(
|
proguardFiles(
|
||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
"proguard-rules.pro"
|
"proguard-rules.pro"
|
||||||
@ -36,6 +37,7 @@ android {
|
|||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
compose = true
|
compose = true
|
||||||
|
buildConfig = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
30
app/proguard-rules.pro
vendored
30
app/proguard-rules.pro
vendored
@ -1,21 +1,15 @@
|
|||||||
# Add project specific ProGuard rules here.
|
# Gson models used for API parsing.
|
||||||
# You can control the set of applied configuration files using the
|
-keep class com.tomhempel.coordinatorapp.data.** { *; }
|
||||||
# proguardFiles setting in build.gradle.
|
-keep class com.tomhempel.coordinatorapp.network.** { *; }
|
||||||
#
|
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
# If your project uses WebView with JS, uncomment the following
|
# AndroidX Security crypto (EncryptedSharedPreferences / MasterKey)
|
||||||
# and specify the fully qualified class name to the JavaScript interface
|
-keep class androidx.security.crypto.** { *; }
|
||||||
# class:
|
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
||||||
# public *;
|
|
||||||
#}
|
|
||||||
|
|
||||||
# Uncomment this to preserve the line number information for
|
# Gson reflective serialization
|
||||||
# debugging stack traces.
|
-keepattributes Signature
|
||||||
#-keepattributes SourceFile,LineNumberTable
|
-keepattributes *Annotation*
|
||||||
|
-dontwarn sun.misc.**
|
||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
# Keep line numbers for crash reports.
|
||||||
# hide the original source file name.
|
-keepattributes SourceFile,LineNumberTable
|
||||||
#-renamesourcefileattribute SourceFile
|
-renamesourcefileattribute SourceFile
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="false"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
|||||||
@ -0,0 +1,11 @@
|
|||||||
|
package com.tomhempel.coordinatorapp.network
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import com.tomhempel.coordinatorapp.BuildConfig
|
||||||
|
|
||||||
|
internal object ApiLog {
|
||||||
|
fun response(label: String, httpCode: Int, body: String?) {
|
||||||
|
if (!BuildConfig.DEBUG) return
|
||||||
|
Log.d("NAT_AS_API", "$label HTTP $httpCode (${body?.length ?: 0} bytes)")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -176,6 +176,7 @@ object NatAsApiClient {
|
|||||||
private inline fun <T> execute(request: Request, parse: (JsonObject) -> T): T {
|
private inline fun <T> execute(request: Request, parse: (JsonObject) -> T): T {
|
||||||
client.newCall(request).execute().use { response ->
|
client.newCall(request).execute().use { response ->
|
||||||
val bodyText = response.body?.string()
|
val bodyText = response.body?.string()
|
||||||
|
ApiLog.response("${request.method} ${request.url.encodedPath}", response.code, bodyText)
|
||||||
val root = parseEnvelope(response.code, bodyText)
|
val root = parseEnvelope(response.code, bodyText)
|
||||||
val data = root.get("data")
|
val data = root.get("data")
|
||||||
return when {
|
return when {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.tomhempel.coordinatorapp.ui.components
|
package com.tomhempel.coordinatorapp.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@ -15,7 +16,6 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Brush
|
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.res.vectorResource
|
import androidx.compose.ui.res.vectorResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
@ -44,25 +44,19 @@ fun CoordinatorBrandBadge(
|
|||||||
iconSize: Dp = 40.dp,
|
iconSize: Dp = 40.dp,
|
||||||
) {
|
) {
|
||||||
val scheme = MaterialTheme.colorScheme
|
val scheme = MaterialTheme.colorScheme
|
||||||
|
val shape = RoundedCornerShape(22.dp)
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.size(size)
|
.size(size)
|
||||||
.clip(RoundedCornerShape(22.dp))
|
.clip(shape)
|
||||||
.background(
|
.border(1.dp, scheme.outline, shape)
|
||||||
Brush.linearGradient(
|
.background(scheme.surface),
|
||||||
colors = listOf(
|
|
||||||
scheme.primary,
|
|
||||||
scheme.primary.copy(alpha = 0.82f),
|
|
||||||
scheme.primaryContainer,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = ImageVector.vectorResource(R.drawable.ic_coordinator_mark),
|
imageVector = ImageVector.vectorResource(R.drawable.ic_coordinator_mark),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = scheme.onPrimary,
|
tint = scheme.primary,
|
||||||
modifier = Modifier.size(iconSize),
|
modifier = Modifier.size(iconSize),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,6 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Brush
|
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
@ -40,15 +39,7 @@ fun CoordinatorBackground(
|
|||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(
|
.background(scheme.background),
|
||||||
Brush.verticalGradient(
|
|
||||||
colors = listOf(
|
|
||||||
scheme.background,
|
|
||||||
scheme.surfaceVariant,
|
|
||||||
scheme.background,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
) {
|
) {
|
||||||
content()
|
content()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ package com.tomhempel.coordinatorapp.ui.theme
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
val BrandPurple = Color(0xFF6E56CF)
|
val BrandPurple = Color(0xFF6E56CF)
|
||||||
val BrandPurpleDark = Color(0xFF9B8AE8)
|
val BrandPurpleDark = Color(0xFF8F84B8)
|
||||||
|
|
||||||
val BrandWindowBg = Color(0xFFF4F8F7)
|
val BrandWindowBg = Color(0xFFF4F8F7)
|
||||||
val BrandSurface = Color(0xFFFFFFFF)
|
val BrandSurface = Color(0xFFFFFFFF)
|
||||||
@ -13,9 +13,9 @@ val BrandStroke = Color(0xFFD5E4E0)
|
|||||||
val BrandDestructive = Color(0xFFC62828)
|
val BrandDestructive = Color(0xFFC62828)
|
||||||
val BrandAccentContainer = Color(0xFFE6F4F0)
|
val BrandAccentContainer = Color(0xFFE6F4F0)
|
||||||
|
|
||||||
val BrandWindowBgDark = Color(0xFF121A19)
|
val BrandWindowBgDark = Color(0xFF0F1413)
|
||||||
val BrandSurfaceDark = Color(0xFF1E2A28)
|
val BrandSurfaceDark = Color(0xFF171D1C)
|
||||||
val BrandTextLight = Color(0xFFE8F2F0)
|
val BrandTextLight = Color(0xFFE4EDEB)
|
||||||
val BrandTextMutedDark = Color(0xFF8AA39E)
|
val BrandTextMutedDark = Color(0xFF7F9490)
|
||||||
val BrandStrokeDark = Color(0xFF2D403C)
|
val BrandStrokeDark = Color(0xFF2B3634)
|
||||||
val BrandAccentContainerDark = Color(0xFF243532)
|
val BrandAccentContainerDark = Color(0xFF222A28)
|
||||||
|
|||||||
@ -30,14 +30,14 @@ private val LightColorScheme = lightColorScheme(
|
|||||||
|
|
||||||
private val DarkColorScheme = darkColorScheme(
|
private val DarkColorScheme = darkColorScheme(
|
||||||
primary = BrandPurpleDark,
|
primary = BrandPurpleDark,
|
||||||
onPrimary = Color(0xFF1F163D),
|
onPrimary = BrandWindowBgDark,
|
||||||
primaryContainer = BrandAccentContainerDark,
|
primaryContainer = BrandAccentContainerDark,
|
||||||
onPrimaryContainer = BrandTextLight,
|
onPrimaryContainer = BrandTextLight,
|
||||||
background = BrandWindowBgDark,
|
background = BrandWindowBgDark,
|
||||||
onBackground = BrandTextLight,
|
onBackground = BrandTextLight,
|
||||||
surface = BrandSurfaceDark,
|
surface = BrandSurfaceDark,
|
||||||
onSurface = BrandTextLight,
|
onSurface = BrandTextLight,
|
||||||
surfaceVariant = BrandAccentContainerDark,
|
surfaceVariant = BrandSurfaceDark,
|
||||||
onSurfaceVariant = BrandTextMutedDark,
|
onSurfaceVariant = BrandTextMutedDark,
|
||||||
outline = BrandStrokeDark,
|
outline = BrandStrokeDark,
|
||||||
error = BrandDestructive,
|
error = BrandDestructive,
|
||||||
|
|||||||
@ -45,12 +45,29 @@ class CoordinatorViewModel(application: Application) : AndroidViewModel(applicat
|
|||||||
counselors = counselors,
|
counselors = counselors,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} catch (_: Exception) {
|
} catch (e: ApiException) {
|
||||||
|
if (e.isAuthError()) {
|
||||||
SessionStore.clear(context)
|
SessionStore.clear(context)
|
||||||
_uiState.update { CoordinatorUiState() }
|
_uiState.update { CoordinatorUiState() }
|
||||||
|
} else {
|
||||||
|
_uiState.update {
|
||||||
|
CoordinatorUiState(
|
||||||
|
errorMessage = e.message ?: "Could not verify session",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
_uiState.update {
|
||||||
|
CoordinatorUiState(
|
||||||
|
errorMessage = e.message ?: "Could not verify session",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ApiException.isAuthError(): Boolean =
|
||||||
|
code == "UNAUTHORIZED" || code == "FORBIDDEN" || code == "PASSWORD_CHANGE_REQUIRED"
|
||||||
|
|
||||||
fun login(username: String, password: String) {
|
fun login(username: String, password: String) {
|
||||||
val trimmedUser = username.trim()
|
val trimmedUser = username.trim()
|
||||||
|
|||||||
@ -1,13 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!--
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
Sample backup rules file; uncomment and customize as necessary.
|
|
||||||
See https://developer.android.com/guide/topics/data/autobackup
|
|
||||||
for details.
|
|
||||||
Note: This file is ignored for devices older than API 31
|
|
||||||
See https://developer.android.com/about/versions/12/backup-restore
|
|
||||||
-->
|
|
||||||
<full-backup-content>
|
<full-backup-content>
|
||||||
<!--
|
<exclude domain="sharedpref" path="." />
|
||||||
<include domain="sharedpref" path="."/>
|
<exclude domain="database" path="." />
|
||||||
<exclude domain="sharedpref" path="device.xml"/>
|
<exclude domain="file" path="." />
|
||||||
-->
|
|
||||||
</full-backup-content>
|
</full-backup-content>
|
||||||
@ -1,19 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!--
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
Sample data extraction rules file; uncomment and customize as necessary.
|
|
||||||
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
|
|
||||||
for details.
|
|
||||||
-->
|
|
||||||
<data-extraction-rules>
|
<data-extraction-rules>
|
||||||
<cloud-backup>
|
<cloud-backup>
|
||||||
<!-- TODO: Use <include> and <exclude> to control what is backed up.
|
<exclude domain="sharedpref" path="." />
|
||||||
<include .../>
|
<exclude domain="database" path="." />
|
||||||
<exclude .../>
|
<exclude domain="file" path="." />
|
||||||
-->
|
|
||||||
</cloud-backup>
|
</cloud-backup>
|
||||||
<!--
|
|
||||||
<device-transfer>
|
<device-transfer>
|
||||||
<include .../>
|
<exclude domain="sharedpref" path="." />
|
||||||
<exclude .../>
|
<exclude domain="database" path="." />
|
||||||
|
<exclude domain="file" path="." />
|
||||||
</device-transfer>
|
</device-transfer>
|
||||||
-->
|
|
||||||
</data-extraction-rules>
|
</data-extraction-rules>
|
||||||
Reference in New Issue
Block a user