Skip to content

Commit

Permalink
Support light mode (based on system theme)
Browse files Browse the repository at this point in the history
Add search icon to left of app filter text field.
Minor UI tweaks.
  • Loading branch information
pilot51 committed Jan 9, 2024
1 parent cae60e0 commit 38579fd
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 162 deletions.
65 changes: 34 additions & 31 deletions app/src/main/java/com/pilot51/voicenotify/AppListScreen.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2023 Mark Injerd
* Copyright 2011-2024 Mark Injerd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,26 +15,28 @@
*/
package com.pilot51.voicenotify

import androidx.compose.foundation.clickable
import android.content.res.Configuration
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.selection.toggleable
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CheckBox
import androidx.compose.material.icons.filled.CheckBoxOutlineBlank
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
Expand Down Expand Up @@ -62,9 +64,16 @@ fun AppListActions() {
},
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 4.dp)
.focusRequester(focusRequester),
maxLines = 1,
singleLine = true,
leadingIcon = {
Icon(
imageVector = Icons.Filled.Search,
contentDescription = null
)
},
trailingIcon = {
IconButton(onClick = {
showSearchBar = false
Expand Down Expand Up @@ -136,46 +145,40 @@ private fun AppList(

@Composable
private fun AppListItem(app: App, toggleIgnore: (app: App) -> Unit) {
Row(modifier = Modifier
.fillMaxWidth()
.clickable { toggleIgnore(app) }
.padding(
horizontal = 20.dp,
vertical = 10.dp
)
) {
Column(modifier = Modifier.weight(1f)) {
ListItem(
modifier = Modifier.toggleable(
value = app.enabled,
role = Role.Checkbox,
onValueChange = { toggleIgnore(app) }
),
headlineContent = {
Text(
text = app.label,
modifier = Modifier.fillMaxWidth(),
color = Color.White,
fontSize = 24.sp
)
Text(
text = app.packageName,
modifier = Modifier.fillMaxWidth(),
color = Color.White
},
supportingContent = {
Text(app.packageName)
},
trailingContent = {
Checkbox(
checked = app.enabled,
modifier = Modifier.focusable(false),
onCheckedChange = { toggleIgnore(app) }
)
}
Checkbox(
checked = app.enabled,
modifier = Modifier
.size(40.dp)
.align(Alignment.CenterVertically)
.focusable(false),
onCheckedChange = null
)
}
)
}

@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Composable
private fun AppListPreview() {
val apps = listOf(
App(1, "package.name.one", "App Name 1", true),
App(2, "package.name.two", "App Name 2", false)
)
MaterialTheme(colorScheme = darkColorScheme()) {
AppTheme {
AppList(apps, true) {}
}
}
6 changes: 2 additions & 4 deletions app/src/main/java/com/pilot51/voicenotify/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2023 Mark Injerd
* Copyright 2011-2024 Mark Injerd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,8 +19,6 @@ import android.content.SharedPreferences
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import com.pilot51.voicenotify.PreferenceHelper.KEY_TTS_STREAM
import com.pilot51.voicenotify.PreferenceHelper.prefs

Expand All @@ -29,7 +27,7 @@ class MainActivity : ComponentActivity(), SharedPreferences.OnSharedPreferenceCh
super.onCreate(savedInstanceState)
Common.setVolumeStream(this)
setContent {
MaterialTheme(colorScheme = darkColorScheme()) {
AppTheme {
AppMain()
}
}
Expand Down
38 changes: 24 additions & 14 deletions app/src/main/java/com/pilot51/voicenotify/MainScreen.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2023 Mark Injerd
* Copyright 2011-2024 Mark Injerd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,9 +21,11 @@ import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.os.Build
import android.widget.Toast
import androidx.annotation.StringRes
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
Expand All @@ -32,13 +34,7 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
Expand All @@ -64,14 +60,27 @@ import com.pilot51.voicenotify.PreferenceHelper.KEY_IGNORE_EMPTY
import com.pilot51.voicenotify.PreferenceHelper.KEY_IGNORE_GROUPS
import com.pilot51.voicenotify.PreferenceHelper.KEY_QUIET_END
import com.pilot51.voicenotify.PreferenceHelper.KEY_QUIET_START
import kotlinx.coroutines.flow.MutableStateFlow
import java.util.*

enum class Screen(@StringRes val title: Int) {
private enum class Screen(@StringRes val title: Int) {
MAIN(R.string.app_name),
APP_LIST(R.string.app_list),
TTS(R.string.tts)
}

@Composable
fun AppTheme(content: @Composable () -> Unit) {
MaterialTheme(
colorScheme = if (isSystemInDarkTheme()) {
darkColorScheme(primary = Color(0xFF1CB7D5), primaryContainer = Color(0xFF1E4696))
} else {
lightColorScheme(primary = Color(0xFF2A54A5), primaryContainer = Color(0xFF64F0FF))
},
content = content
)
}

@Composable
fun AppMain() {
val navController = rememberNavController()
Expand Down Expand Up @@ -136,7 +145,7 @@ private fun AppBar(
}
},
colors = TopAppBarDefaults.mediumTopAppBarColors(
containerColor = Color(0xFF333333)
containerColor = MaterialTheme.colorScheme.primaryContainer
)
)
}
Expand Down Expand Up @@ -164,8 +173,8 @@ private fun MainScreen(
statusTitle = context.getString(R.string.service_running)
statusSummary = context.getString(R.string.status_summary_notification_access_enabled)
}
val isRunning by Service.isRunning.collectAsState()
val isSuspended by Service.isSuspended.collectAsState()
val isRunning by (if (isPreview) MutableStateFlow(false) else Service.isRunning).collectAsState()
val isSuspended by (if (isPreview) MutableStateFlow(false) else Service.isSuspended).collectAsState()
if (isSuspended && isRunning) {
statusTitle = stringResource(R.string.service_suspended)
statusSummary = stringResource(R.string.status_summary_suspended)
Expand Down Expand Up @@ -392,10 +401,11 @@ private fun runTestNotification(context: Context) {
}, 5000)
}

@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Composable
private fun AppPreview() {
MaterialTheme(colorScheme = darkColorScheme()) {
AppTheme {
AppMain()
}
}
14 changes: 10 additions & 4 deletions app/src/main/java/com/pilot51/voicenotify/NotifyList.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2023 Mark Injerd
* Copyright 2011-2024 Mark Injerd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,8 +16,10 @@
package com.pilot51.voicenotify

import android.app.Notification
import android.content.res.Configuration
import android.widget.Toast
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
Expand All @@ -30,6 +32,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -130,10 +133,12 @@ private fun Item(item: NotificationInfo) {
)
}
if (item.ignoreReasons.isNotEmpty()) {
val interruptedColor = if (isSystemInDarkTheme()) Color.Yellow else Color(0xFFBBBB00)
Text(
text = item.getIgnoreReasonsAsText(),
modifier = Modifier.fillMaxWidth(),
color = if (item.isInterrupted) Color.Yellow else Color.Red,
color = if (item.isInterrupted) interruptedColor else Color.Red,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center
)
}
Expand Down Expand Up @@ -182,7 +187,8 @@ private fun Item(item: NotificationInfo) {
}
}

@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Composable
private fun NotificationLogDialogPreview() {
val previewNotification = Notification().apply {
Expand All @@ -198,7 +204,7 @@ private fun NotificationLogDialogPreview() {
NotificationInfo(app = App(1, "package.name.one", "App Name 1", true), previewNotification),
NotificationInfo(app = App(2, "package.name.two", "App Name 2", false), previewNotification)
)
MaterialTheme(colorScheme = darkColorScheme()) {
AppTheme {
NotificationLogDialog(list) {}
}
}
12 changes: 8 additions & 4 deletions app/src/main/java/com/pilot51/voicenotify/PermissionHelper.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2023 Mark Injerd
* Copyright 2011-2024 Mark Injerd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,8 +18,11 @@ package com.pilot51.voicenotify
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.content.res.Configuration
import androidx.annotation.StringRes
import androidx.compose.material3.*
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
Expand Down Expand Up @@ -89,15 +92,16 @@ object PermissionHelper {
}

@OptIn(ExperimentalPermissionsApi::class)
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Composable
private fun RationaleDialogPreview() {
val permissionState = object : PermissionState {
override val permission = Manifest.permission.READ_PHONE_STATE
override val status = PermissionStatus.Granted
override fun launchPermissionRequest() {}
}
MaterialTheme(colorScheme = darkColorScheme()) {
AppTheme {
RationaleDialog(
permissionState = permissionState,
rationaleMsgId = R.string.permission_rationale_read_phone_state
Expand Down
Loading

0 comments on commit 38579fd

Please sign in to comment.