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