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