diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 676f896..ddba471 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + diff --git a/app/src/main/java/dev/souravdas/hush/activities/MainActivity.kt b/app/src/main/java/dev/souravdas/hush/activities/MainActivity.kt index d6afa56..a10a12e 100644 --- a/app/src/main/java/dev/souravdas/hush/activities/MainActivity.kt +++ b/app/src/main/java/dev/souravdas/hush/activities/MainActivity.kt @@ -1,32 +1,33 @@ package dev.souravdas.hush import android.app.Activity -import android.content.ComponentName import android.content.Context import android.content.Intent -import android.content.ServiceConnection -import android.content.pm.ApplicationInfo -import android.content.pm.PackageManager -import android.os.* +import android.os.Build +import android.os.Bundle +import android.os.Handler +import android.os.Looper import android.provider.Settings import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels -import androidx.compose.material.* -import androidx.compose.runtime.* import androidx.core.app.NotificationManagerCompat import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import dev.sourav.emptycompose.ui.theme.HushTheme -import dev.souravdas.hush.services.KeepAliveService import dev.souravdas.hush.activities.UIKit import dev.souravdas.hush.arch.MainActivityVM -import dev.souravdas.hush.models.InstalledPackageInfo +import dev.souravdas.hush.others.Utils +import dev.souravdas.hush.services.KeepAliveService import kotlinx.coroutines.launch +import javax.inject.Inject @AndroidEntryPoint class MainActivity : ComponentActivity() { + + @Inject + lateinit var utils: Utils private val viewModel: MainActivityVM by viewModels() private var doubleBackToExitPressedOnce = false @@ -35,13 +36,16 @@ class MainActivity : ComponentActivity() { setContent { viewModel.getSelectedApp() - HushTheme { - UIKit().MainActivityScreen() + HushTheme() { + UIKit().MainActivityScreen(onNotificationPermissionGet = { + openNotificationAccessSettingsIfNeeded(this) + }, checkNotificationPermission = { + isNotificationListenerEnabled(this) + }) } } checkService(); - openNotificationAccessSettingsIfNeeded(this) } private fun checkService() { @@ -61,11 +65,6 @@ class MainActivity : ComponentActivity() { } private fun openNotificationAccessSettingsIfNeeded(activity: Activity) { - if (isNotificationListenerEnabled(activity)) { - // Permission is already granted, no need to prompt the user - return - } - // Permission is not granted, prompt the user to grant it val intent = Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS) activity.startActivity(intent) diff --git a/app/src/main/java/dev/souravdas/hush/activities/UIKit.kt b/app/src/main/java/dev/souravdas/hush/activities/UIKit.kt index 235162b..fde7b70 100644 --- a/app/src/main/java/dev/souravdas/hush/activities/UIKit.kt +++ b/app/src/main/java/dev/souravdas/hush/activities/UIKit.kt @@ -16,10 +16,10 @@ import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.* -import androidx.compose.material.FabPosition -import androidx.compose.material.MaterialTheme +import androidx.compose.material.SwitchDefaults import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Done +import androidx.compose.material.icons.filled.Warning import androidx.compose.material.icons.outlined.Edit import androidx.compose.material3.* import androidx.compose.material3.Button @@ -33,6 +33,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource @@ -46,11 +47,6 @@ import androidx.compose.ui.window.DialogProperties import androidx.core.content.ContextCompat import androidx.lifecycle.viewmodel.compose.viewModel import com.google.accompanist.drawablepainter.rememberDrawablePainter -import com.maxkeppeker.sheets.core.models.base.Header -import com.maxkeppeker.sheets.core.models.base.rememberSheetState -import com.maxkeppeler.sheets.clock.ClockDialog -import com.maxkeppeler.sheets.clock.models.ClockConfig -import com.maxkeppeler.sheets.clock.models.ClockSelection import dev.souravdas.hush.HushApp import dev.souravdas.hush.R import dev.souravdas.hush.arch.MainActivityVM @@ -60,10 +56,10 @@ import dev.souravdas.hush.models.SelectedAppForList import dev.souravdas.hush.others.Constants import dev.souravdas.hush.others.HushType import kotlinx.coroutines.launch -import org.threeten.bp.LocalTime import timber.log.Timber import java.text.SimpleDateFormat import java.util.* +import androidx.compose.material3.MaterialTheme as MD3 /** * Created by Sourav @@ -88,16 +84,19 @@ class UIKit() { modifier = Modifier .height(56.dp) .fillMaxWidth() - .background(color = colorResource(id = R.color.color_pale_green)) + .background(color = MD3.colorScheme.primary) ) { Text( text = "Swipe up to select an app", modifier = Modifier.align(alignment = Alignment.Center), - color = Color.White + color = MD3.colorScheme.onPrimary ) } val lazyListState = rememberLazyListState() - LazyColumn(state = lazyListState) { + LazyColumn( + state = lazyListState, + modifier = Modifier.background(color = MD3.colorScheme.background) + ) { itemsIndexed(items = items) { index, item -> ListItem( @@ -128,6 +127,7 @@ class UIKit() { Text( text = item.appName, textAlign = TextAlign.Center, + color = MD3.colorScheme.onBackground, modifier = Modifier.padding(start = 4.dp) ) } @@ -139,14 +139,49 @@ class UIKit() { } } + @Composable + fun ShowAlertDialog( + onConfirmClick: () -> Unit + ) { + AlertDialog( + onDismissRequest = {}, + icon = { + Icon( + Icons.Default.Warning, + contentDescription = null, + modifier = Modifier.size(56.dp) + ) + }, + title = { + Text(text = "Notification Permission Necessary") + }, + text = { + Text(text = stringResource(id = R.string.notification_alert_dialog_body)) + }, + confirmButton = { + Button(onClick = { + onConfirmClick.invoke() + Toast.makeText( + HushApp.context, + "Please Select Hush! from the list", + Toast.LENGTH_LONG + ).show() + }) { + Text(text = stringResource(id = android.R.string.ok)) + } + } + ) + } + @OptIn( ExperimentalMaterial3Api::class, - ExperimentalLayoutApi::class, - ExperimentalMaterialApi::class + ExperimentalMaterialApi::class, ExperimentalLayoutApi::class ) @Composable fun MainActivityScreen( viewModel: MainActivityVM = viewModel(), + checkNotificationPermission: () -> Boolean, + onNotificationPermissionGet: () -> Unit ) { val scope = rememberCoroutineScope() val scaffoldState = rememberBottomSheetScaffoldState() @@ -154,11 +189,19 @@ class UIKit() { viewModel.getInstalledApps() BottomSheetScaffold( + backgroundColor = MD3.colorScheme.background, scaffoldState = scaffoldState, sheetPeekHeight = 56.dp, topBar = { TopAppBar( - title = { Text(stringResource(id = R.string.app_name)) } + title = { + Text( + stringResource(id = R.string.app_name), + fontSize = 32.sp, + fontWeight = FontWeight.Medium, + color = MD3.colorScheme.onBackground + ) + } ) }, sheetContent = { @@ -183,32 +226,45 @@ class UIKit() { } } }, - contentColor = Color.White, + backgroundColor = MD3.colorScheme.secondary, + contentColor = MD3.colorScheme.onSecondary, ) { Icon( painter = painterResource(id = R.drawable.twotone_add_24), + tint = MD3.colorScheme.onSecondary, contentDescription = "Add Icon" ) } }, - ) { it -> - val modifier = Modifier.consumeWindowInsets(it) + modifier = Modifier.background(MD3.colorScheme.background) + ) { mo ->//HERE + val modifier = Modifier.consumeWindowInsets(mo) val hushStatus = viewModel.getHushStatusAsFlow().collectAsState(initial = false) + var showNotificationPermissionAlertDialog by remember { + mutableStateOf(!checkNotificationPermission.invoke()) + } + + if (showNotificationPermissionAlertDialog) + ShowAlertDialog { + showNotificationPermissionAlertDialog = false + onNotificationPermissionGet.invoke() + } // <--- Hush Service Toggle ----> Row( horizontalArrangement = Arrangement.SpaceBetween, - modifier = modifier + modifier = Modifier .fillMaxWidth() .padding(8.dp) .background( - color = if (hushStatus.value) colorResource(id = R.color.color_pale_green) else colorResource( - R.color.grayBG - ), + color = if (hushStatus.value) MD3.colorScheme.primary else MD3.colorScheme.surfaceVariant, shape = RoundedCornerShape(12.dp) ) .clickable { - viewModel.setHushStatus(!hushStatus.value) + if (checkNotificationPermission.invoke()) + viewModel.setHushStatus(!hushStatus.value) + else + showNotificationPermissionAlertDialog = true } ) { @@ -216,7 +272,7 @@ class UIKit() { text = "Start Hush Service", fontSize = 16.sp, fontWeight = FontWeight.Bold, - color = Color.White, + color = if (hushStatus.value) MD3.colorScheme.onPrimary else MD3.colorScheme.onSurfaceVariant, modifier = Modifier .padding(start = 8.dp) .align(alignment = Alignment.CenterVertically) @@ -224,15 +280,21 @@ class UIKit() { Switch( checked = hushStatus.value, + colors = SwitchDefaults.colors( + checkedThumbColor = MD3.colorScheme.primaryContainer + ), onCheckedChange = { status -> - viewModel.setHushStatus(status) + if (checkNotificationPermission.invoke()) + viewModel.setHushStatus(status) + else + showNotificationPermissionAlertDialog = true }, modifier = Modifier.padding(end = 8.dp) ) } ShowSelectedApps( - modifier, + modifier = modifier, viewModel, onRemoveClick = { viewModel.removeApp(it) @@ -243,7 +305,7 @@ class UIKit() { @Composable fun ShowSelectedApps( - modifier: Modifier = Modifier, + modifier: Modifier, viewModel: MainActivityVM, onRemoveClick: (SelectedApp) -> Unit ) { @@ -256,7 +318,11 @@ class UIKit() { ) { item { Box(Modifier.padding(10.dp)) { - Text(text = "Ongoing Hush!", fontSize = 16.sp) + Text( + text = "Ongoing Hush!", + fontSize = 16.sp, + color = MD3.colorScheme.onBackground + ) } } items(itemList.value, key = { @@ -308,14 +374,14 @@ class UIKit() { } .padding(bottom = 10.dp) .background( - colorResource(id = R.color.whiteBG), RoundedCornerShape(12.dp) - ) - .padding(top = 8.dp, bottom = 8.dp)) { + Color(androidx.compose.material3.MaterialTheme.colorScheme.primaryContainer.toArgb()), + RoundedCornerShape(12.dp) + )) { Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier .fillMaxWidth() - .padding(8.dp) + .padding(10.dp) ) { Image( painter = rememberDrawablePainter( @@ -323,7 +389,7 @@ class UIKit() { ), contentDescription = "appIcon", modifier = Modifier - .size(56.dp) + .size(50.dp) .clip(CircleShape) ) Row( @@ -336,17 +402,21 @@ class UIKit() { Text( text = selectedApp.selectedApp.appName, fontSize = 24.sp, + color = MD3.colorScheme.onPrimaryContainer ) if (selectedApp.selectedApp.hushType != null) { if (selectedApp.selectedApp.hushType == HushType.DURATION && System.currentTimeMillis() >= selectedApp.selectedApp.timeUpdated + selectedApp.selectedApp.durationInMinutes!! * 60000 ) { - CustomChip(title = "Expired", color = Color.Red) + CustomChip( + title = "Expired", + color = Color.Red, + fontColor = Color.White + ) } else { CustomChip( - title = selectedApp.selectedApp.hushType.toString(), - color = colorResource(id = R.color.color_lavender) + title = selectedApp.selectedApp.hushType.label, ) } } @@ -421,66 +491,72 @@ class UIKit() { FilledTonalIconToggleButton( checked = !selectedDays[0].isNullOrEmpty(), colors = IconButtonDefaults.filledIconToggleButtonColors( - containerColor = colorResource(id = R.color.switch_container_gray), - checkedContainerColor = colorResource(id = R.color.color_lavender) + containerColor = MD3.colorScheme.surfaceVariant, + checkedContainerColor = MD3.colorScheme.tertiary ), onCheckedChange = { - selectedDays = selectedDays.toMutableList().apply { set(1, if (it) "SAT" else null) } + selectedDays = selectedDays.toMutableList() + .apply { set(0, if (it) "SAT" else null) } }) { ShowDaysText(!selectedDays[0].isNullOrEmpty(), "SAT") } FilledTonalIconToggleButton( checked = !selectedDays[1].isNullOrEmpty(), colors = IconButtonDefaults.filledIconToggleButtonColors( - containerColor = colorResource(id = R.color.switch_container_gray), - checkedContainerColor = colorResource(id = R.color.color_lavender) + containerColor = MD3.colorScheme.surfaceVariant, + checkedContainerColor = MD3.colorScheme.tertiary ), onCheckedChange = { - selectedDays = selectedDays.toMutableList().apply { set(1, if (it) "SUN" else null) } + selectedDays = selectedDays.toMutableList() + .apply { set(1, if (it) "SUN" else null) } }) { ShowDaysText(!selectedDays[1].isNullOrEmpty(), "SUN") } FilledTonalIconToggleButton( checked = !selectedDays[2].isNullOrEmpty(), colors = IconButtonDefaults.filledIconToggleButtonColors( - containerColor = colorResource(id = R.color.switch_container_gray), - checkedContainerColor = colorResource(id = R.color.color_lavender) + containerColor = MD3.colorScheme.surfaceVariant, + checkedContainerColor = MD3.colorScheme.tertiary ), onCheckedChange = { - selectedDays = selectedDays.toMutableList().apply { set(2, if (it) "MON" else null) } + selectedDays = selectedDays.toMutableList() + .apply { set(2, if (it) "MON" else null) } }) { ShowDaysText(!selectedDays[2].isNullOrEmpty(), "MON") } FilledTonalIconToggleButton( checked = !selectedDays[3].isNullOrEmpty(), colors = IconButtonDefaults.filledIconToggleButtonColors( - containerColor = colorResource(id = R.color.switch_container_gray), - checkedContainerColor = colorResource(id = R.color.color_lavender) + containerColor = MD3.colorScheme.surfaceVariant, + checkedContainerColor = MD3.colorScheme.tertiary ), onCheckedChange = { - selectedDays = selectedDays.toMutableList().apply { set(3, if (it) "TUE" else null) } + selectedDays = selectedDays.toMutableList() + .apply { set(3, if (it) "TUE" else null) } }) { ShowDaysText(!selectedDays[3].isNullOrEmpty(), "TUE") } FilledTonalIconToggleButton( checked = !selectedDays[4].isNullOrEmpty(), colors = IconButtonDefaults.filledIconToggleButtonColors( - containerColor = colorResource(id = R.color.switch_container_gray), - checkedContainerColor = colorResource(id = R.color.color_lavender) + containerColor = MD3.colorScheme.surfaceVariant, + checkedContainerColor = MD3.colorScheme.tertiary ), onCheckedChange = { - selectedDays = selectedDays.toMutableList().apply { set(4, if (it) "WED" else null) } + selectedDays = selectedDays.toMutableList() + .apply { set(4, if (it) "WED" else null) } }) { ShowDaysText(!selectedDays[4].isNullOrEmpty(), "WED") } FilledTonalIconToggleButton( checked = !selectedDays[5].isNullOrEmpty(), colors = IconButtonDefaults.filledIconToggleButtonColors( - containerColor = colorResource(id = R.color.switch_container_gray), - checkedContainerColor = colorResource(id = R.color.color_lavender) + containerColor = MD3.colorScheme.surfaceVariant, + checkedContainerColor = MD3.colorScheme.tertiary ), onCheckedChange = { - selectedDays = selectedDays.toMutableList().apply { set(5, if (it) "THU" else null) } + selectedDays = selectedDays.toMutableList() + .apply { set(5, if (it) "THU" else null) } } ) { ShowDaysText(!selectedDays[5].isNullOrEmpty(), "THU") @@ -488,11 +564,12 @@ class UIKit() { FilledTonalIconToggleButton( checked = !selectedDays[6].isNullOrEmpty(), onCheckedChange = { - selectedDays = selectedDays.toMutableList().apply { set(6, if (it) "FRI" else null) } + selectedDays = selectedDays.toMutableList() + .apply { set(6, if (it) "FRI" else null) } }, colors = IconButtonDefaults.filledIconToggleButtonColors( - containerColor = colorResource(id = R.color.switch_container_gray), - checkedContainerColor = colorResource(id = R.color.color_lavender) + containerColor = MD3.colorScheme.surfaceVariant, + checkedContainerColor = MD3.colorScheme.tertiary ) ) { ShowDaysText(!selectedDays[6].isNullOrEmpty(), "FRI") @@ -502,7 +579,8 @@ class UIKit() { Column(Modifier.padding(start = 8.dp, end = 8.dp)) { Text( modifier = Modifier.padding(top = 8.dp, bottom = 4.dp), - text = "Start Time" + text = "Start Time", + color = MD3.colorScheme.onPrimaryContainer ) Row( verticalAlignment = Alignment.CenterVertically, @@ -522,12 +600,14 @@ class UIKit() { text = get12HrsFrom24Hrs(startEndTimePair.startTime), fontSize = 24.sp, fontWeight = FontWeight.Medium, + color = MD3.colorScheme.onPrimaryContainer, modifier = Modifier.padding(start = 24.dp) ) } Text( modifier = Modifier.padding(top = 8.dp, bottom = 4.dp), - text = "End Time" + text = "End Time", + color = MD3.colorScheme.onPrimaryContainer ) Row( verticalAlignment = Alignment.CenterVertically, @@ -546,6 +626,7 @@ class UIKit() { text = get12HrsFrom24Hrs(startEndTimePair.endTime), fontSize = 24.sp, fontWeight = FontWeight.Medium, + color = MD3.colorScheme.onPrimaryContainer, modifier = Modifier.padding(start = 24.dp) ) } @@ -572,6 +653,8 @@ class UIKit() { } Text( text = "Log Notifications", + color = Color(androidx.compose.material3.MaterialTheme.colorScheme.onPrimaryContainer.toArgb()), + modifier = Modifier .align(Alignment.CenterVertically) .padding(start = 8.dp) @@ -630,12 +713,17 @@ class UIKit() { Modifier.padding(start = 16.dp, end = 8.dp, top = 8.dp, bottom = 8.dp) Spacer(modifier = Modifier.weight(1f)) - Text(text = "Cancel", modifier = modifier - .clickable { - onCancelClick.invoke() - }) + Text( + text = "Cancel", + color = MD3.colorScheme.onPrimaryContainer, + modifier = modifier + .clickable { + onCancelClick.invoke() + }) - Text(text = "Add", fontWeight = FontWeight.Medium, + Text(text = "Add", + fontWeight = FontWeight.Medium, + color = MD3.colorScheme.onPrimaryContainer, modifier = modifier .clickable { onAddClick.invoke() @@ -662,10 +750,11 @@ class UIKit() { Surface( modifier = Modifier .clip(RoundedCornerShape(12.dp)) - .background(MaterialTheme.colors.background) + .background(MD3.colorScheme.background) .padding(16.dp) ) { Column( + Modifier.background(MD3.colorScheme.background), horizontalAlignment = Alignment.CenterHorizontally, ) { Row( @@ -675,10 +764,11 @@ class UIKit() { Text( text = title, fontSize = 24.sp, + color = MD3.colorScheme.onBackground, modifier = Modifier.padding(bottom = 16.dp) ) } - TimeInput(state = state) + TimePicker(state = state) AddCancelButtonBar(onAddClick = { onTimeSelected.invoke(state.hour.toString() + ":" + state.minute) }, onCancelClick = { @@ -698,7 +788,7 @@ class UIKit() { Row( modifier = Modifier .background( - colorResource(R.color.color_light_yellow), + color = MD3.colorScheme.secondaryContainer, RoundedCornerShape(bottomStart = 12.dp, bottomEnd = 12.dp) ) .fillMaxWidth() @@ -706,19 +796,19 @@ class UIKit() { TextButton( modifier = buttonModifier, onClick = { Constants.showNIY() }) { - Text("Notification History") + Text("Notification History", color = MD3.colorScheme.onSecondaryContainer) } TextButton( modifier = buttonModifier, onClick = { Constants.showNIY() }) { - Text("Edit") + Text("Edit", color = MD3.colorScheme.onSecondaryContainer) } TextButton( modifier = buttonModifier, onClick = { onRemoveClick.invoke(selectedApp.selectedApp) }) { - Text("Remove") + Text("Remove", color = MD3.colorScheme.onSecondaryContainer) } } } @@ -788,7 +878,11 @@ class UIKit() { @Composable - fun CustomChip(title: String, color: Color, fontColor: Color = Color.White) { + fun CustomChip( + title: String, + color: Color = MD3.colorScheme.tertiary, + fontColor: Color = MD3.colorScheme.onTertiary + ) { Box( modifier = Modifier .padding(top = 4.dp, bottom = 4.dp) @@ -800,7 +894,7 @@ class UIKit() { Text( text = title, modifier = Modifier.padding( - top = 2.dp, bottom = 2.dp, start = 6.dp, end = 6.dp + top = 4.dp, bottom = 4.dp, start = 6.dp, end = 6.dp ), color = fontColor, fontSize = 12.sp, @@ -812,9 +906,18 @@ class UIKit() { @Composable fun ShowDaysText(selected: Boolean, title: String) { if (selected) { - Text(text = title, fontSize = 12.sp, fontWeight = FontWeight.Bold) + Text( + text = title, + fontSize = 12.sp, + fontWeight = FontWeight.Bold, + color = MD3.colorScheme.onTertiary + ) } else { - Text(text = title, color = colorResource(id = R.color.switch_text_unselected), fontSize = 12.sp) + Text( + text = title, + color = MD3.colorScheme.onSurfaceVariant, + fontSize = 12.sp + ) } } @@ -822,124 +925,72 @@ class UIKit() { @Composable fun ShowChipRow(onHushTypeSelected: (HushType) -> Unit = {}) { - var selectedChipIndex by remember { mutableStateOf(HushType.ALWAYS) } + val selectedChipIndex = remember { mutableStateOf(HushType.ALWAYS) } Row(modifier = Modifier.fillMaxWidth()) { - val chipModifier = Modifier.padding(start = 4.dp) - - FilterChip(selected = selectedChipIndex == HushType.ALWAYS, onClick = { - selectedChipIndex = HushType.ALWAYS - onHushTypeSelected.invoke(HushType.ALWAYS) - }, label = { Text("Mute Always") }, modifier = chipModifier, leadingIcon = { - Box( - Modifier.animateContentSize(keyframes { - durationMillis = 100 - }) - ) { - if (selectedChipIndex == HushType.ALWAYS) { - Icon( - imageVector = Icons.Default.Done, - contentDescription = null, - modifier = Modifier.size(FilterChipDefaults.IconSize) - ) - } - } + ShowTypeSelectorChip( + type = HushType.ALWAYS, + selectedChipIndex = selectedChipIndex, + onHushTypeSelected = onHushTypeSelected + ) + ShowTypeSelectorChip( + type = HushType.DURATION, + selectedChipIndex = selectedChipIndex, + onHushTypeSelected = onHushTypeSelected + ) + ShowTypeSelectorChip( + type = HushType.DAYS, + selectedChipIndex = selectedChipIndex, + onHushTypeSelected = onHushTypeSelected + ) - }) + } + } - FilterChip(selected = selectedChipIndex == HushType.DURATION, onClick = { - selectedChipIndex = HushType.DURATION - onHushTypeSelected.invoke(HushType.DURATION) - }, label = { Text("Duration") }, modifier = chipModifier, leadingIcon = { - Box( - Modifier.animateContentSize(keyframes { - durationMillis = 100 - }) - ) { - if (selectedChipIndex == HushType.DURATION) { - Icon( - imageVector = Icons.Default.Done, - contentDescription = null, - modifier = Modifier.size(FilterChipDefaults.IconSize) - ) - } - } + @OptIn(ExperimentalMaterial3Api::class) + @Composable + fun ShowTypeSelectorChip( + type: HushType, + selectedChipIndex: MutableState, + onHushTypeSelected: (HushType) -> Unit + ) { - }) + FilterChip( + selected = selectedChipIndex.value == type, + onClick = { + selectedChipIndex.value = type + onHushTypeSelected.invoke(type) + }, + colors = FilterChipDefaults.filterChipColors( + selectedContainerColor = MD3.colorScheme.tertiary, + containerColor = MD3.colorScheme.surfaceVariant, - FilterChip(selected = selectedChipIndex == HushType.DAYS, onClick = { - selectedChipIndex = HushType.DAYS - onHushTypeSelected.invoke(HushType.DAYS) - }, label = { Text("Days") }, modifier = chipModifier, leadingIcon = { + ), + label = { + Text( + text = type.label, + color = if (selectedChipIndex.value == type) MD3.colorScheme.onTertiary else MD3.colorScheme.onSurfaceVariant + ) + }, + modifier = Modifier.padding(start = 4.dp), leadingIcon = { Box( Modifier.animateContentSize(keyframes { durationMillis = 100 }) ) { - if (selectedChipIndex == HushType.DAYS) { + if (selectedChipIndex.value == type) { Icon( imageVector = Icons.Default.Done, contentDescription = null, + tint = MD3.colorScheme.onTertiary, modifier = Modifier.size(FilterChipDefaults.IconSize) ) } } }) - } - } - - @OptIn(ExperimentalMaterial3Api::class) - @Composable - fun TwoLineButton( - txt1: String, txt2: String, selectedTime: MutableState = remember { - mutableStateOf(null) - } - ) { - - val sheetState = rememberSheetState() - val title = remember { - mutableStateOf(txt1) - } - - OpenClock(sheetState, title, selectedTime) - - - Button(onClick = { - sheetState.show() - }) { - Column { - Text( - text = txt1, textAlign = TextAlign.Center, modifier = Modifier.width(80.dp) - ) - Text( - text = if (selectedTime.value == null) txt2 else selectedTime.value.toString(), - textAlign = TextAlign.Center, - modifier = Modifier.width(80.dp) - ) - } - } } - @OptIn(ExperimentalMaterial3Api::class) - @Composable - fun OpenClock( - sheetState: com.maxkeppeker.sheets.core.models.base.SheetState, - title: MutableState, - selectedTime: MutableState - ) { - ClockDialog( - header = Header.Default(title.value), - state = sheetState, - selection = ClockSelection.HoursMinutes { hours, minutes -> - Timber.d("Time Selected") - selectedTime.value = LocalTime.of(hours, minutes) - }, - config = ClockConfig( - is24HourFormat = false, - ), - ) - } fun get12HrsFrom24Hrs(inputTime: String): String { val timeFormat = SimpleDateFormat("hh:mm", Locale.getDefault()) @@ -948,50 +999,7 @@ class UIKit() { return outputFormat.format(time) } -// -// @Preview -// @Composable -// fun PreviewInitConfig() { -// ShowInitConfig(selectedApp = SelectedAppForList( -// SelectedApp( -// 1, -// "Test APP", -// "com.hush.hush", -// HushType.DAYS, -// 0, -// "FRI,SAT", -// null, -// null, -// 13212312313, -// 3123123123, -// true -// ), icon = null -// -// ), chooseSelectedDays = { "" }) -// } -// -// // @Preview -// @Composable -// fun PreviewSelectedAppItem() { -// SelectedAppItem( -// selectedApp = SelectedAppForList( -// SelectedApp( -// 1, -// "Test APP", -// "com.hush.hush", -// HushType.DAYS, -// 0, -// "FRI,SAT", -// null, -// null, -// 13212312313, -// 3123123123, -// true -// ), icon = null -// -// ) -// ) -// } + data class StartEndTime(var startTime: String, var endTime: String) } \ No newline at end of file diff --git a/app/src/main/java/dev/souravdas/hush/arch/MainActivityVM.kt b/app/src/main/java/dev/souravdas/hush/arch/MainActivityVM.kt index cd94bd3..7569e1c 100644 --- a/app/src/main/java/dev/souravdas/hush/arch/MainActivityVM.kt +++ b/app/src/main/java/dev/souravdas/hush/arch/MainActivityVM.kt @@ -88,7 +88,9 @@ class MainActivityVM @Inject constructor( ) ) } - return packageNames + return packageNames.sortedBy { + it.appName + } } diff --git a/app/src/main/java/dev/souravdas/hush/others/HushType.kt b/app/src/main/java/dev/souravdas/hush/others/HushType.kt index 64bb354..c7c7818 100644 --- a/app/src/main/java/dev/souravdas/hush/others/HushType.kt +++ b/app/src/main/java/dev/souravdas/hush/others/HushType.kt @@ -5,8 +5,8 @@ package dev.souravdas.hush.others * On 3/1/2023 11:51 AM * For Hush! */ -enum class HushType(val id: Int) { - ALWAYS(0), - DURATION(1), - DAYS(2) +enum class HushType(val label: String) { + ALWAYS("Always"), + DURATION("Temporary"), + DAYS("Schedule") } \ No newline at end of file diff --git a/app/src/main/java/dev/souravdas/hush/others/Utils.kt b/app/src/main/java/dev/souravdas/hush/others/Utils.kt index 131d3be..2426bac 100644 --- a/app/src/main/java/dev/souravdas/hush/others/Utils.kt +++ b/app/src/main/java/dev/souravdas/hush/others/Utils.kt @@ -14,7 +14,7 @@ import java.util.* class Utils { - fun checkIfAppExpired(selectedApp: SelectedApp):Boolean{ + fun isHushActive(selectedApp: SelectedApp):Boolean{ return (System.currentTimeMillis() <= selectedApp.timeUpdated + selectedApp.durationInMinutes!!* 60000) } diff --git a/app/src/main/java/dev/souravdas/hush/services/KeepAliveService.kt b/app/src/main/java/dev/souravdas/hush/services/KeepAliveService.kt index 6ceceb6..8ecaf0b 100644 --- a/app/src/main/java/dev/souravdas/hush/services/KeepAliveService.kt +++ b/app/src/main/java/dev/souravdas/hush/services/KeepAliveService.kt @@ -62,6 +62,8 @@ class KeepAliveService : Service() { startForeground(FOREGROUND_SERVICE_ID, notification) + + return START_STICKY } diff --git a/app/src/main/java/dev/souravdas/hush/ui/theme/Color.kt b/app/src/main/java/dev/souravdas/hush/ui/theme/Color.kt index 45d059a..f41b70c 100644 --- a/app/src/main/java/dev/souravdas/hush/ui/theme/Color.kt +++ b/app/src/main/java/dev/souravdas/hush/ui/theme/Color.kt @@ -1,19 +1,67 @@ package dev.souravdas.hush.ui.theme - import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.colorResource -import dev.souravdas.hush.R -val Purple80 = Color(0xFFD0BCFF) -val PurpleGrey80 = Color(0xFFCCC2DC) -val Pink80 = Color(0xFFEFB8C8) +val md_theme_light_primary = Color(0xFF00658F) +val md_theme_light_onPrimary = Color(0xFFFFFFFF) +val md_theme_light_primaryContainer = Color(0xFFC7E7FF) +val md_theme_light_onPrimaryContainer = Color(0xFF001E2E) +val md_theme_light_secondary = Color(0xFF006E2A) +val md_theme_light_onSecondary = Color(0xFFFFFFFF) +val md_theme_light_secondaryContainer = Color(0xFF92F99E) +val md_theme_light_onSecondaryContainer = Color(0xFF002108) +val md_theme_light_tertiary = Color(0xFF84468D) +val md_theme_light_onTertiary = Color(0xFFFFFFFF) +val md_theme_light_tertiaryContainer = Color(0xFFFFD5FF) +val md_theme_light_onTertiaryContainer = Color(0xFF350040) +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(0xFF41484D) +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(0xFF85CFFF) +val md_theme_light_shadow = Color(0xFF000000) +val md_theme_light_surfaceTint = Color(0xFF00658F) +val md_theme_light_outlineVariant = Color(0xFFC1C7CE) +val md_theme_light_scrim = Color(0xFF000000) + +val md_theme_dark_primary = Color(0xFF85CFFF) +val md_theme_dark_onPrimary = Color(0xFF00344C) +val md_theme_dark_primaryContainer = Color(0xFF004C6C) +val md_theme_dark_onPrimaryContainer = Color(0xFFC7E7FF) +val md_theme_dark_secondary = Color(0xFF76DC84) +val md_theme_dark_onSecondary = Color(0xFF003912) +val md_theme_dark_secondaryContainer = Color(0xFF00531E) +val md_theme_dark_onSecondaryContainer = Color(0xFF92F99E) +val md_theme_dark_tertiary = Color(0xFFF6ADFD) +val md_theme_dark_onTertiary = Color(0xFF50155B) +val md_theme_dark_tertiaryContainer = Color(0xFF6A2E74) +val md_theme_dark_onTertiaryContainer = Color(0xFFFFD5FF) +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(0xFF41484D) +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(0xFF00658F) +val md_theme_dark_shadow = Color(0xFF000000) +val md_theme_dark_surfaceTint = Color(0xFF85CFFF) +val md_theme_dark_outlineVariant = Color(0xFF41484D) +val md_theme_dark_scrim = Color(0xFF000000) + -val Purple40 = Color(0xFF6650a4) -val PurpleGrey40 = Color(0xFF625b71) -val Pink40 = Color(0xFF7D5260) -val Taupa = Color(0xFF885053) -val RedBittersweet = Color(0xFFfe5f55) -val Glacious = Color(0xFF777da7) -val CambridgeBlue = Color(0xFF94c9a9) -val TeaGreen = Color(0xFFc6ecae) -val whiteBG = Color(R.color.whiteBG) \ No newline at end of file +val seed = Color(0xFF457B9D) diff --git a/app/src/main/java/dev/souravdas/hush/ui/theme/Theme.kt b/app/src/main/java/dev/souravdas/hush/ui/theme/Theme.kt index 854af72..a2db2d2 100644 --- a/app/src/main/java/dev/souravdas/hush/ui/theme/Theme.kt +++ b/app/src/main/java/dev/souravdas/hush/ui/theme/Theme.kt @@ -15,28 +15,70 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalView import androidx.core.view.ViewCompat import dev.souravdas.hush.ui.theme.* -import kotlin.text.Typography -private val DarkColorScheme = darkColorScheme( - primary = Purple80, - secondary = PurpleGrey80, - tertiary = Pink80 +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 LightColorScheme = lightColorScheme( - primary = Purple40, - secondary = PurpleGrey40, - tertiary = Pink40 - /* Other default colors to override - background = Color(0xFFFFFBFE), - surface = Color(0xFFFFFBFE), - onPrimary = Color.White, - onSecondary = Color.White, - onTertiary = Color.White, - onBackground = Color(0xFF1C1B1F), - onSurface = Color(0xFF1C1B1F), - */ +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 @@ -51,8 +93,8 @@ fun HushTheme( val context = LocalContext.current if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) } - darkTheme -> DarkColorScheme - else -> LightColorScheme + darkTheme -> DarkColors + else -> LightColors } val view = LocalView.current if (!view.isInEditMode) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 58c14e4..92ddc85 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4,5 +4,6 @@ Hush Service Hush Service is running… Keep Alive Service + "Hey! I mute notifications from other apps according to your preference. To perform this, I need notification access permission. No worries. I am a completely opensource app and I do not collect any userdata 😊 " \ No newline at end of file