diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index fb7f4a8..b589d56 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
deleted file mode 100644
index b121649..0000000
--- a/.idea/deploymentTargetDropDown.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 526b4c2..9f47dfb 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -5,15 +5,15 @@
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index df11045..e92c2b3 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -4,12 +4,13 @@ plugins {
}
android {
- compileSdk = 30
+ namespace = "com.wbrawner.skerge"
+ compileSdk = 34
defaultConfig {
applicationId = "com.wbrawner.skerge"
- minSdk = 26
- targetSdk = 30
+ minSdk = 29
+ targetSdk = 34
versionCode = 1
versionName = "1.0"
@@ -43,26 +44,30 @@ android {
compose = true
}
composeOptions {
- kotlinCompilerExtensionVersion = rootProject.extra["compose_version"] as String
+ kotlinCompilerExtensionVersion = "1.5.4"
}
}
dependencies {
-
- implementation("androidx.core:core-ktx:1.5.0")
- implementation("androidx.appcompat:appcompat:1.3.0")
- implementation("com.google.android.material:material:1.3.0")
- implementation("androidx.compose.ui:ui:${rootProject.extra["compose_version"]}")
- implementation("androidx.compose.material:material:${rootProject.extra["compose_version"]}")
- implementation("androidx.compose.ui:ui-tooling:${rootProject.extra["compose_version"]}")
- implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.3.1")
- implementation("androidx.activity:activity-compose:1.3.0-beta02")
- val ktorVersion = "1.6.0"
+ val composeBom = platform("androidx.compose:compose-bom:2023.10.01")
+ implementation(composeBom)
+ implementation("androidx.core:core-ktx:1.12.0")
+ implementation("androidx.appcompat:appcompat:1.6.1")
+ implementation("com.google.android.material:material:1.10.0")
+ implementation("androidx.compose.ui:ui")
+ implementation("androidx.compose.material:material")
+ implementation("androidx.compose.material3:material3")
+ implementation("androidx.compose.ui:ui-tooling")
+ implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
+ implementation("androidx.preference:preference-ktx:1.2.1")
+ implementation("androidx.activity:activity-compose:1.8.0")
+ val ktorVersion = "2.3.6"
implementation("io.ktor:ktor-client-cio:$ktorVersion")
implementation("io.ktor:ktor-client-android:$ktorVersion")
androidTestImplementation("io.ktor:ktor-client-mock:$ktorVersion")
testImplementation("junit:junit:4.13.2")
- androidTestImplementation("androidx.test.ext:junit:1.1.2")
- androidTestImplementation("androidx.test.espresso:espresso-core:3.3.0")
- androidTestImplementation("androidx.compose.ui:ui-test-junit4:${rootProject.extra["compose_version"]}")
+ androidTestImplementation(composeBom)
+ androidTestImplementation("androidx.test.ext:junit:1.1.5")
+ androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
+ androidTestImplementation("androidx.compose.ui:ui-test-junit4")
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 33a92e3..20f5462 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,6 +1,5 @@
-
+
@@ -16,6 +15,7 @@
android:name="com.wbrawner.skerge.MainActivity"
android:exported="true"
android:label="@string/app_name"
+ android:windowSoftInputMode="adjustPan|adjustResize"
android:theme="@style/Theme.Skerge.NoActionBar">
diff --git a/app/src/main/java/com/wbrawner/skerge/MainActivity.kt b/app/src/main/java/com/wbrawner/skerge/MainActivity.kt
index aff727f..bd24a3d 100644
--- a/app/src/main/java/com/wbrawner/skerge/MainActivity.kt
+++ b/app/src/main/java/com/wbrawner/skerge/MainActivity.kt
@@ -5,99 +5,198 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
+import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
+import androidx.compose.foundation.combinedClickable
+import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
-import androidx.compose.material.*
+import androidx.compose.foundation.text.KeyboardActions
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material.ExperimentalMaterialApi
+import androidx.compose.material3.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
+import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.Share
+import androidx.compose.material.rememberSwipeableState
+import androidx.compose.material.swipeable
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.input.KeyboardCapitalization
+import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import androidx.lifecycle.lifecycleScope
+import androidx.core.view.WindowCompat
import com.wbrawner.skerge.ui.theme.SkergeTheme
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File
class MainActivity : ComponentActivity() {
- private val viewModel: MainViewModel by viewModels()
- private val scansDirectory: File by lazy { File(cacheDir, "scans") }
+ private val viewModel: MainViewModel by viewModels {
+ MainViewModel.Factory(applicationContext)
+ }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
+ val darkMode = isSystemInDarkTheme()
+ LaunchedEffect(darkMode) {
+ WindowCompat.getInsetsController(window, window.decorView)
+ .isAppearanceLightNavigationBars = !darkMode
+ }
+ val pages by viewModel.pages.collectAsState(initial = emptyList())
+ val scannerUrl by viewModel.scannerUrl.collectAsState(initial = "")
+ val coroutineScope = rememberCoroutineScope()
+ val context = LocalContext.current
+ val (loading, setLoading) = remember { mutableStateOf(false) }
+ var pdfShareJob: Job? by remember { mutableStateOf(null) }
SkergeTheme {
ScanScreen(
- addButtonClicked = { viewModel.requestScan(scansDirectory) },
- shareButtonClicked = { sharePdf(viewModel.pages.replayCache.first()) },
+ loading = loading,
+ setLoading = { loading ->
+ if (!loading) {
+ pdfShareJob?.cancel()
+ }
+ setLoading(loading)
+ },
+ scannerUrl = scannerUrl,
+ setScannerUrl = viewModel::setScannerUrl,
+ addButtonClicked = viewModel::requestScan,
+ shareButtonClicked = {
+ pdfShareJob = coroutineScope.launch {
+ delay(10_000)
+ val file = if (pages.size == 1) {
+ pages.first().file ?: return@launch
+ } else {
+ pages.merge()
+ }
+ startActivity(file.buildShareIntent(context))
+ }
+ },
removePage = viewModel::removePage,
- pagesFlow = viewModel.pages
+ pages = pages
)
}
}
}
-
- private fun sharePdf(pages: List) {
- // TODO: Show loading dialog for this
- lifecycleScope.launch {
- val file = if (pages.size == 1) {
- pages.first().file ?: return@launch
- } else {
- pages.merge()
- }
- startActivity(file.buildShareIntent(this@MainActivity))
- }
- }
}
+@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ScanScreen(
+ loading: Boolean,
+ setLoading: (Boolean) -> Unit,
+ scannerUrl: String,
+ setScannerUrl: (String) -> Unit,
addButtonClicked: () -> Unit,
shareButtonClicked: () -> Unit,
removePage: (Page) -> Unit,
- pagesFlow: SharedFlow>
+ pages: List
) {
- val pages = pagesFlow.collectAsState(initial = emptyList())
+ var showScannerUrlInput by remember { mutableStateOf(false) }
Scaffold(
modifier = Modifier.fillMaxSize(),
topBar = {
TopAppBar(
+ modifier = Modifier.statusBarsPadding(),
title = { Text("Skerge") },
actions = {
IconButton(onClick = shareButtonClicked) {
Icon(imageVector = Icons.Default.Share, contentDescription = "Share")
}
+ IconButton(onClick = { showScannerUrlInput = true }) {
+ Icon(imageVector = Icons.Default.Settings, contentDescription = "Settings")
+ }
}
)
},
floatingActionButton = {
- if (pages.value.none { it.file == null }) {
+ if (pages.none { it.file == null }) {
FloatingActionButton(onClick = addButtonClicked) {
Icon(imageVector = Icons.Default.Add, contentDescription = "Add")
}
}
}
- ) {
- if (pages.value.isEmpty()) {
- EmptyDocumentView()
+ ) { paddingValues ->
+ if (pages.isEmpty()) {
+ EmptyDocumentView(modifier = Modifier.padding(paddingValues))
} else {
- PageList(pages.value, removePage)
+ PageList(
+ modifier = Modifier.padding(paddingValues),
+ pages = pages,
+ removePage = removePage
+ )
+ }
+ if (loading) {
+ AlertDialog(
+ onDismissRequest = { setLoading(false) },
+ confirmButton = {
+ TextButton(onClick = { setLoading(false) }) {
+ Text("Cancel")
+ }
+ },
+ text = {
+ Column(horizontalAlignment = Alignment.CenterHorizontally) {
+ Text("Merging PDF...")
+ CircularProgressIndicator()
+ }
+ }
+ )
+ } else if (showScannerUrlInput) {
+ val (scannerInput, setScannerInput) = remember { mutableStateOf(scannerUrl) }
+ AlertDialog(
+ onDismissRequest = { showScannerUrlInput = false },
+ dismissButton = {
+ TextButton(onClick = { showScannerUrlInput = false }) {
+ Text("Cancel")
+ }
+ },
+ confirmButton = {
+ TextButton(
+ onClick = {
+ setScannerUrl(scannerInput)
+ showScannerUrlInput = false
+ }
+ ) {
+ Text("Save")
+ }
+ },
+ text = {
+ OutlinedTextField(
+ value = scannerInput,
+ onValueChange = setScannerInput,
+ label = {
+ Text("Scanner URL")
+ },
+ keyboardActions = KeyboardActions {
+ setScannerUrl(scannerInput)
+ showScannerUrlInput = false
+ },
+ keyboardOptions = KeyboardOptions.Default.copy(
+ autoCorrect = false,
+ capitalization = KeyboardCapitalization.None,
+ keyboardType = KeyboardType.Uri
+ )
+ )
+ }
+ )
}
}
}
@Composable
-fun EmptyDocumentView() {
+fun EmptyDocumentView(modifier: Modifier) {
Column(
- modifier = Modifier
+ modifier = modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center,
@@ -113,8 +212,8 @@ fun EmptyDocumentView() {
}
@Composable
-fun PageList(pages: List, removePage: (Page) -> Unit) {
- LazyColumn(modifier = Modifier.fillMaxSize()) {
+fun PageList(pages: List, removePage: (Page) -> Unit, modifier: Modifier) {
+ LazyColumn(modifier = modifier.fillMaxSize()) {
itemsIndexed(items = pages) { index, page ->
val topPadding = if (index == 0) 16.dp else 8.dp
val bottomPadding = if (index == pages.size - 1) 16.dp else 8.dp
@@ -130,6 +229,7 @@ fun PageList(pages: List, removePage: (Page) -> Unit) {
}
}
+@OptIn(ExperimentalMaterialApi::class, ExperimentalFoundationApi::class)
@Composable
fun PagePreview(page: Page, removePage: (Page) -> Unit) {
val (pageBitmap, setPageBitmap) = remember { mutableStateOf(null) }
@@ -137,11 +237,26 @@ fun PagePreview(page: Page, removePage: (Page) -> Unit) {
setPageBitmap(page.loadBitmap().first)
}
pageBitmap?.let {
- Image(
- modifier = Modifier.fillMaxSize(),
- bitmap = it.asImageBitmap(),
- contentDescription = null
- )
+ var showMenu by remember { mutableStateOf(false) }
+ Box(
+ modifier = Modifier.fillMaxSize()
+ ) {
+ Image(
+ modifier = Modifier
+ .fillMaxSize()
+ .combinedClickable(
+ onClick = {},
+ onLongClick = {
+ showMenu = true
+ }
+ ),
+ bitmap = it.asImageBitmap(),
+ contentDescription = null
+ )
+ DropdownMenu(expanded = showMenu, onDismissRequest = { showMenu = false }) {
+ DropdownMenuItem(text = { Text("Remove") }, onClick = { removePage(page) })
+ }
+ }
}
?: page.error?.let {
Column(
@@ -173,7 +288,7 @@ fun LoadingPage() {
@Composable
fun DefaultPreview() {
SkergeTheme {
- ScanScreen({}, {}, {}, MutableSharedFlow())
+ ScanScreen(false, {}, "", {}, {}, {}, {}, emptyList())
}
}
diff --git a/app/src/main/java/com/wbrawner/skerge/MainViewModel.kt b/app/src/main/java/com/wbrawner/skerge/MainViewModel.kt
index 6815351..e5887e3 100644
--- a/app/src/main/java/com/wbrawner/skerge/MainViewModel.kt
+++ b/app/src/main/java/com/wbrawner/skerge/MainViewModel.kt
@@ -1,8 +1,12 @@
package com.wbrawner.skerge
+import android.content.Context
+import androidx.preference.PreferenceManager
import android.util.Log
import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.viewmodel.CreationExtras
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow
@@ -10,11 +14,21 @@ import java.io.File
import java.io.IOException
import java.util.*
-class MainViewModel(private val scannerService: ScannerService = HpScannerService()) : ViewModel() {
+class MainViewModel(
+ private val scannerService: ScannerService,
+ private val fileDirectory: File
+) : ViewModel() {
private val _pages = MutableStateFlow>(emptyList())
val pages = _pages.asSharedFlow()
+ private val _scannerUrl = MutableStateFlow(scannerService.url)
+ val scannerUrl = _scannerUrl.asSharedFlow()
- fun requestScan(fileDirectory: File) {
+ fun setScannerUrl(url: String) {
+ scannerService.url = url
+ _scannerUrl.value = url
+ }
+
+ fun requestScan() {
val page = Page()
_pages.value = _pages.value.toMutableList().apply {
add(page)
@@ -104,6 +118,20 @@ class MainViewModel(private val scannerService: ScannerService = HpScannerServic
}
_pages.value = updatedPages
}
+
+ class Factory(private val context: Context) : ViewModelProvider.Factory {
+ @Suppress("UNCHECKED_CAST")
+ override fun create(
+ modelClass: Class,
+ extras: CreationExtras
+ ): T {
+ val sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(context.applicationContext)
+ val scannerService = HpScannerService(sharedPreferences = sharedPreferences)
+ val fileDirectory = File(context.applicationContext.cacheDir, "scans")
+ return MainViewModel(scannerService, fileDirectory) as T
+ }
+ }
}
data class Page(
diff --git a/app/src/main/java/com/wbrawner/skerge/ScannerService.kt b/app/src/main/java/com/wbrawner/skerge/ScannerService.kt
index 2877d9f..41ad21b 100644
--- a/app/src/main/java/com/wbrawner/skerge/ScannerService.kt
+++ b/app/src/main/java/com/wbrawner/skerge/ScannerService.kt
@@ -1,17 +1,25 @@
package com.wbrawner.skerge
+import android.content.SharedPreferences
+import androidx.core.content.edit
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.engine.cio.*
-import io.ktor.client.features.*
+import io.ktor.client.plugins.HttpTimeout
+import io.ktor.client.plugins.onDownload
+import io.ktor.client.plugins.timeout
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.client.utils.*
import io.ktor.http.*
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
import java.io.File
import java.io.IOException
+import java.util.concurrent.TimeUnit
interface ScannerService {
+ var url: String
suspend fun requestScan(scanSettings: ScanSettings = ScanSettings()): String
suspend fun getScanStatus(scanId: String): ScannerStatus
suspend fun downloadFile(
@@ -21,20 +29,30 @@ interface ScannerService {
)
}
-// TODO: It would be cool to be able to autodiscover the printer(s) or manually enter the details
-const val SCANNER_URL = "http://brawner.print"
+private const val KEY_SCANNER_URL = "scannerUrl"
class HpScannerService(
private val client: HttpClient = HttpClient(CIO) {
+ install(HttpTimeout) {
+ requestTimeoutMillis = TimeUnit.MINUTES.toMillis(2)
+ }
buildHeaders {
append("Content-Type", "text/xml")
}
- }
+ },
+ private val sharedPreferences: SharedPreferences
) : ScannerService {
+ override var url: String
+ get() = sharedPreferences.getString(KEY_SCANNER_URL, null).orEmpty()
+ set(value) = sharedPreferences.edit { putString(KEY_SCANNER_URL, value) }
+
override suspend fun requestScan(scanSettings: ScanSettings): String {
- val url = URLBuilder(SCANNER_URL).path("eSCL", "ScanJobs").build()
+ val url = URLBuilder(url).run {
+ path("eSCL", "ScanJobs")
+ build()
+ }
val response: HttpResponse = client.post(url) {
- body = scanSettings.toXml()
+ setBody(scanSettings.toXml())
}
val location = response.headers["Location"]
?: throw IOException("Scanner didn't return location")
@@ -42,7 +60,13 @@ class HpScannerService(
}
override suspend fun getScanStatus(scanId: String): ScannerStatus = ScannerStatus.fromXml(
- client.get(URLBuilder(SCANNER_URL).path("eSCL", "ScannerStatus").build())
+ client.get(
+ URLBuilder(url)
+ .run {
+ path("eSCL", "ScannerStatus")
+ build()
+ }
+ ).body()
)
override suspend fun downloadFile(
@@ -51,13 +75,16 @@ class HpScannerService(
onProgress: (downloaded: Long, size: Long) -> Unit
) {
val httpResponse: HttpResponse = client.get(
- URLBuilder(SCANNER_URL).path("eSCL", "ScanJobs", uuid, "NextDocument").build()
+ URLBuilder(url).run {
+ path("eSCL", "ScanJobs", uuid, "NextDocument")
+ build()
+ }
) {
onDownload { bytesSentTotal, contentLength ->
onProgress(bytesSentTotal, contentLength)
}
}
- val responseBody: ByteArray = httpResponse.receive()
+ val responseBody: ByteArray = httpResponse.body()
destination.writeBytes(responseBody)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/wbrawner/skerge/ui/theme/Color.kt b/app/src/main/java/com/wbrawner/skerge/ui/theme/Color.kt
index 16dcdd9..17f751f 100644
--- a/app/src/main/java/com/wbrawner/skerge/ui/theme/Color.kt
+++ b/app/src/main/java/com/wbrawner/skerge/ui/theme/Color.kt
@@ -1,5 +1,67 @@
package com.wbrawner.skerge.ui.theme
-
import androidx.compose.ui.graphics.Color
-val SkergeBlue = Color(0xFF0096d6)
+val md_theme_light_primary = Color(0xFF006491)
+val md_theme_light_onPrimary = Color(0xFFFFFFFF)
+val md_theme_light_primaryContainer = Color(0xFFC9E6FF)
+val md_theme_light_onPrimaryContainer = Color(0xFF001E2F)
+val md_theme_light_secondary = Color(0xFF4F606E)
+val md_theme_light_onSecondary = Color(0xFFFFFFFF)
+val md_theme_light_secondaryContainer = Color(0xFFD3E5F5)
+val md_theme_light_onSecondaryContainer = Color(0xFF0C1D29)
+val md_theme_light_tertiary = Color(0xFF64597C)
+val md_theme_light_onTertiary = Color(0xFFFFFFFF)
+val md_theme_light_tertiaryContainer = Color(0xFFEADDFF)
+val md_theme_light_onTertiaryContainer = Color(0xFF201635)
+val md_theme_light_error = Color(0xFFBA1A1A)
+val md_theme_light_errorContainer = Color(0xFFFFDAD6)
+val md_theme_light_onError = Color(0xFFFFFFFF)
+val md_theme_light_onErrorContainer = Color(0xFF410002)
+val md_theme_light_background = Color(0xFFFCFCFF)
+val md_theme_light_onBackground = Color(0xFF191C1E)
+val md_theme_light_surface = Color(0xFFFCFCFF)
+val md_theme_light_onSurface = Color(0xFF191C1E)
+val md_theme_light_surfaceVariant = Color(0xFFDDE3EA)
+val md_theme_light_onSurfaceVariant = Color(0xFF41474D)
+val md_theme_light_outline = Color(0xFF71787E)
+val md_theme_light_inverseOnSurface = Color(0xFFF0F0F3)
+val md_theme_light_inverseSurface = Color(0xFF2E3133)
+val md_theme_light_inversePrimary = Color(0xFF8ACEFF)
+val md_theme_light_shadow = Color(0xFF000000)
+val md_theme_light_surfaceTint = Color(0xFF006491)
+val md_theme_light_outlineVariant = Color(0xFFC1C7CE)
+val md_theme_light_scrim = Color(0xFF000000)
+
+val md_theme_dark_primary = Color(0xFF8ACEFF)
+val md_theme_dark_onPrimary = Color(0xFF00344D)
+val md_theme_dark_primaryContainer = Color(0xFF004C6E)
+val md_theme_dark_onPrimaryContainer = Color(0xFFC9E6FF)
+val md_theme_dark_secondary = Color(0xFFB7C9D9)
+val md_theme_dark_onSecondary = Color(0xFF22323F)
+val md_theme_dark_secondaryContainer = Color(0xFF384956)
+val md_theme_dark_onSecondaryContainer = Color(0xFFD3E5F5)
+val md_theme_dark_tertiary = Color(0xFFCEC0E8)
+val md_theme_dark_onTertiary = Color(0xFF352B4B)
+val md_theme_dark_tertiaryContainer = Color(0xFF4C4163)
+val md_theme_dark_onTertiaryContainer = Color(0xFFEADDFF)
+val md_theme_dark_error = Color(0xFFFFB4AB)
+val md_theme_dark_errorContainer = Color(0xFF93000A)
+val md_theme_dark_onError = Color(0xFF690005)
+val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
+val md_theme_dark_background = Color(0xFF191C1E)
+val md_theme_dark_onBackground = Color(0xFFE2E2E5)
+val md_theme_dark_surface = Color(0xFF191C1E)
+val md_theme_dark_onSurface = Color(0xFFE2E2E5)
+val md_theme_dark_surfaceVariant = Color(0xFF41474D)
+val md_theme_dark_onSurfaceVariant = Color(0xFFC1C7CE)
+val md_theme_dark_outline = Color(0xFF8B9198)
+val md_theme_dark_inverseOnSurface = Color(0xFF191C1E)
+val md_theme_dark_inverseSurface = Color(0xFFE2E2E5)
+val md_theme_dark_inversePrimary = Color(0xFF006491)
+val md_theme_dark_shadow = Color(0xFF000000)
+val md_theme_dark_surfaceTint = Color(0xFF8ACEFF)
+val md_theme_dark_outlineVariant = Color(0xFF41474D)
+val md_theme_dark_scrim = Color(0xFF000000)
+
+
+val seed = Color(0xFF0096D6)
diff --git a/app/src/main/java/com/wbrawner/skerge/ui/theme/Theme.kt b/app/src/main/java/com/wbrawner/skerge/ui/theme/Theme.kt
index 496b032..afa9646 100644
--- a/app/src/main/java/com/wbrawner/skerge/ui/theme/Theme.kt
+++ b/app/src/main/java/com/wbrawner/skerge/ui/theme/Theme.kt
@@ -1,35 +1,90 @@
package com.wbrawner.skerge.ui.theme
import androidx.compose.foundation.isSystemInDarkTheme
-import androidx.compose.material.MaterialTheme
-import androidx.compose.material.darkColors
-import androidx.compose.material.lightColors
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.lightColorScheme
+import androidx.compose.material3.darkColorScheme
import androidx.compose.runtime.Composable
-private val DarkColorPalette = darkColors(
- primary = SkergeBlue,
- primaryVariant = SkergeBlue,
- secondary = SkergeBlue
+
+private val LightColors = lightColorScheme(
+ primary = md_theme_light_primary,
+ onPrimary = md_theme_light_onPrimary,
+ primaryContainer = md_theme_light_primaryContainer,
+ onPrimaryContainer = md_theme_light_onPrimaryContainer,
+ secondary = md_theme_light_secondary,
+ onSecondary = md_theme_light_onSecondary,
+ secondaryContainer = md_theme_light_secondaryContainer,
+ onSecondaryContainer = md_theme_light_onSecondaryContainer,
+ tertiary = md_theme_light_tertiary,
+ onTertiary = md_theme_light_onTertiary,
+ tertiaryContainer = md_theme_light_tertiaryContainer,
+ onTertiaryContainer = md_theme_light_onTertiaryContainer,
+ error = md_theme_light_error,
+ errorContainer = md_theme_light_errorContainer,
+ onError = md_theme_light_onError,
+ onErrorContainer = md_theme_light_onErrorContainer,
+ background = md_theme_light_background,
+ onBackground = md_theme_light_onBackground,
+ surface = md_theme_light_surface,
+ onSurface = md_theme_light_onSurface,
+ surfaceVariant = md_theme_light_surfaceVariant,
+ onSurfaceVariant = md_theme_light_onSurfaceVariant,
+ outline = md_theme_light_outline,
+ inverseOnSurface = md_theme_light_inverseOnSurface,
+ inverseSurface = md_theme_light_inverseSurface,
+ inversePrimary = md_theme_light_inversePrimary,
+ surfaceTint = md_theme_light_surfaceTint,
+ outlineVariant = md_theme_light_outlineVariant,
+ scrim = md_theme_light_scrim,
)
-private val LightColorPalette = lightColors(
- primary = SkergeBlue,
- primaryVariant = SkergeBlue,
- secondary = SkergeBlue
+
+private val DarkColors = darkColorScheme(
+ primary = md_theme_dark_primary,
+ onPrimary = md_theme_dark_onPrimary,
+ primaryContainer = md_theme_dark_primaryContainer,
+ onPrimaryContainer = md_theme_dark_onPrimaryContainer,
+ secondary = md_theme_dark_secondary,
+ onSecondary = md_theme_dark_onSecondary,
+ secondaryContainer = md_theme_dark_secondaryContainer,
+ onSecondaryContainer = md_theme_dark_onSecondaryContainer,
+ tertiary = md_theme_dark_tertiary,
+ onTertiary = md_theme_dark_onTertiary,
+ tertiaryContainer = md_theme_dark_tertiaryContainer,
+ onTertiaryContainer = md_theme_dark_onTertiaryContainer,
+ error = md_theme_dark_error,
+ errorContainer = md_theme_dark_errorContainer,
+ onError = md_theme_dark_onError,
+ onErrorContainer = md_theme_dark_onErrorContainer,
+ background = md_theme_dark_background,
+ onBackground = md_theme_dark_onBackground,
+ surface = md_theme_dark_surface,
+ onSurface = md_theme_dark_onSurface,
+ surfaceVariant = md_theme_dark_surfaceVariant,
+ onSurfaceVariant = md_theme_dark_onSurfaceVariant,
+ outline = md_theme_dark_outline,
+ inverseOnSurface = md_theme_dark_inverseOnSurface,
+ inverseSurface = md_theme_dark_inverseSurface,
+ inversePrimary = md_theme_dark_inversePrimary,
+ surfaceTint = md_theme_dark_surfaceTint,
+ outlineVariant = md_theme_dark_outlineVariant,
+ scrim = md_theme_dark_scrim,
)
@Composable
-fun SkergeTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) {
- val colors = if (darkTheme) {
- DarkColorPalette
- } else {
- LightColorPalette
- }
+fun SkergeTheme(
+ useDarkTheme: Boolean = isSystemInDarkTheme(),
+ content: @Composable() () -> Unit
+) {
+ val colors = if (!useDarkTheme) {
+ LightColors
+ } else {
+ DarkColors
+ }
- MaterialTheme(
- colors = colors,
- typography = Typography,
- shapes = Shapes,
- content = content
- )
+ MaterialTheme(
+ colorScheme = colors,
+ content = content
+ )
}
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 8409e8a..accb1cc 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -5,13 +5,11 @@
- @color/skerge_blue
- @color/skerge_blue
- @color/white
-
- @color/skerge_blue
- @color/skerge_blue
- @color/black
-
- - ?attr/colorPrimaryVariant
-
+ - @android:color/transparent
+ - @android:color/transparent