diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index db90a3da1..64047bbc1 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -29,7 +29,8 @@ android {
buildTypes {
release {
- isMinifyEnabled = false
+ isMinifyEnabled = true
+ isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
@@ -44,6 +45,11 @@ android {
compose = true
buildConfig = true
}
+ packaging {
+ jniLibs {
+ useLegacyPackaging = true
+ }
+ }
}
dependencies {
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index 481bb4348..ef42cdef8 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -18,4 +18,21 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
-#-renamesourcefileattribute SourceFile
\ No newline at end of file
+#-renamesourcefileattribute SourceFile
+
+# Gson rules
+-keep class com.google.gson.** { *; }
+-keepattributes Signature
+-keepattributes *Annotation*
+
+# Shizuku rules
+-keep class rikka.shizuku.** { *; }
+-keep class dev.rikka.shizuku.** { *; }
+
+# Kotlin Reflect
+-keep class kotlin.reflect.** { *; }
+-keep class com.sameerasw.essentials.domain.model.** { *; }
+
+# Prevent over-minification of settings and registry classes
+-keep class com.sameerasw.essentials.data.repository.** { *; }
+-keep class com.sameerasw.essentials.domain.registry.** { *; }
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index fff3f3096..d0b233fe8 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -98,6 +98,15 @@
android:label="@string/tab_app_updates_title"
android:theme="@style/Theme.Essentials">
+
+
{
+ var showFreezeMenu by remember { mutableStateOf(false) }
+ Box {
+ IconButton(
+ onClick = {
+ HapticUtil.performVirtualKeyHaptic(view)
+ showFreezeMenu = true
+ },
+ colors = IconButtonDefaults.iconButtonColors(
+ containerColor = MaterialTheme.colorScheme.surfaceBright
+ )
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.rounded_mode_cool_24),
+ contentDescription = stringResource(R.string.tab_freeze)
+ )
+ }
+
+ SegmentedDropdownMenu(
+ expanded = showFreezeMenu,
+ onDismissRequest = { showFreezeMenu = false }
+ ) {
+ SegmentedDropdownMenuItem(
+ text = { Text(stringResource(R.string.action_freeze_all)) },
+ onClick = {
+ showFreezeMenu = false
+ viewModel.freezeAllApps(context)
+ },
+ leadingIcon = {
+ Icon(
+ painter = painterResource(id = R.drawable.rounded_mode_cool_24),
+ contentDescription = null
+ )
+ }
+ )
+ SegmentedDropdownMenuItem(
+ text = { Text(stringResource(R.string.action_unfreeze_all)) },
+ onClick = {
+ showFreezeMenu = false
+ viewModel.unfreezeAllApps(context)
+ },
+ leadingIcon = {
+ Icon(
+ painter = painterResource(id = R.drawable.rounded_mode_cool_off_24),
+ contentDescription = null
+ )
+ }
+ )
+ SegmentedDropdownMenuItem(
+ text = { Text("Freeze Automatic") },
+ onClick = {
+ showFreezeMenu = false
+ viewModel.freezeAutomaticApps(context)
+ },
+ leadingIcon = {
+ Icon(
+ painter = painterResource(id = R.drawable.rounded_nest_farsight_cool_24),
+ contentDescription = null
+ )
+ }
+ )
+ }
+ }
+ Spacer(modifier = Modifier.width(8.dp))
+ }
+
+ DIYTabs.DIY -> {
+ IconButton(
+ onClick = {
+ HapticUtil.performVirtualKeyHaptic(view)
+ showNewAutomationSheet = true
+ },
+ colors = IconButtonDefaults.iconButtonColors(
+ containerColor = MaterialTheme.colorScheme.surfaceBright
)
- } else {
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.rounded_add_24),
+ contentDescription = stringResource(R.string.diy_editor_new_title)
+ )
+ }
+ Spacer(modifier = Modifier.width(8.dp))
+ }
+
+ DIYTabs.APPS -> {
+ IconButton(
+ onClick = {
+ HapticUtil.performVirtualKeyHaptic(view)
+ showAddRepoSheet = true
+ },
+ colors = IconButtonDefaults.iconButtonColors(
+ containerColor = MaterialTheme.colorScheme.surfaceBright
+ )
+ ) {
Icon(
- painter = painterResource(id = R.drawable.rounded_refresh_24),
- contentDescription = stringResource(R.string.action_refresh),
- modifier = Modifier.size(24.dp)
+ painter = painterResource(id = R.drawable.rounded_add_24),
+ contentDescription = stringResource(R.string.action_add_repo)
)
}
+ Spacer(modifier = Modifier.width(8.dp))
+
+ IconButton(
+ onClick = {
+ HapticUtil.performVirtualKeyHaptic(view)
+ updatesViewModel.checkForUpdates(context)
+ },
+ enabled = refreshingRepoIds.isEmpty(),
+ colors = IconButtonDefaults.iconButtonColors(
+ containerColor = MaterialTheme.colorScheme.surfaceBright
+ ),
+ modifier = Modifier.size(40.dp)
+ ) {
+ if (refreshingRepoIds.isNotEmpty()) {
+ CircularWavyProgressIndicator(
+ progress = { animatedProgress },
+ modifier = Modifier.size(24.dp)
+ )
+ } else {
+ Icon(
+ painter = painterResource(id = R.drawable.rounded_refresh_24),
+ contentDescription = stringResource(R.string.action_refresh),
+ modifier = Modifier.size(24.dp)
+ )
+ }
+ }
+ Spacer(modifier = Modifier.width(8.dp))
}
- Spacer(modifier = Modifier.width(8.dp))
+
+ else -> {}
}
},
hasUpdateAvailable = isUpdateAvailable,
@@ -545,7 +652,9 @@ class MainActivity : FragmentActivity() {
DIYTabs.DIY -> {
DIYScreen(
- modifier = Modifier.padding(innerPadding)
+ modifier = Modifier.padding(innerPadding),
+ showNewAutomationSheet = showNewAutomationSheet,
+ onDismissNewAutomationSheet = { showNewAutomationSheet = false }
)
}
@@ -816,29 +925,9 @@ class MainActivity : FragmentActivity() {
}
}
- // FAB
- FloatingActionButton(
- onClick = {
- HapticUtil.performMediumHaptic(view)
- showAddRepoSheet = true
- },
- modifier = Modifier
- .align(Alignment.BottomEnd)
- .padding(
- bottom = 150.dp,
- end = 32.dp
- ),
- containerColor = MaterialTheme.colorScheme.primaryContainer,
- contentColor = MaterialTheme.colorScheme.onPrimaryContainer
- ) {
- Icon(
- painter = painterResource(id = R.drawable.rounded_add_24),
- contentDescription = stringResource(R.string.action_add_repo)
- )
}
}
}
- }
}
}
}
diff --git a/app/src/main/java/com/sameerasw/essentials/services/tiles/ColorPickerTileService.kt b/app/src/main/java/com/sameerasw/essentials/services/tiles/ColorPickerTileService.kt
index 468817d66..bdb675c75 100644
--- a/app/src/main/java/com/sameerasw/essentials/services/tiles/ColorPickerTileService.kt
+++ b/app/src/main/java/com/sameerasw/essentials/services/tiles/ColorPickerTileService.kt
@@ -29,8 +29,7 @@ class ColorPickerTileService : BaseTileService() {
override fun getTileState(): Int = Tile.STATE_INACTIVE
override fun onTileClick() {
- val intent = Intent(Intent.ACTION_MAIN).apply {
- component = ComponentName("com.android.eyedropper", "com.android.eyedropper.MainActivity")
+ val intent = Intent(this, com.sameerasw.essentials.ui.activities.ColorPickerActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
}
diff --git a/app/src/main/java/com/sameerasw/essentials/ui/activities/ColorPickerActivity.kt b/app/src/main/java/com/sameerasw/essentials/ui/activities/ColorPickerActivity.kt
new file mode 100644
index 000000000..220564f53
--- /dev/null
+++ b/app/src/main/java/com/sameerasw/essentials/ui/activities/ColorPickerActivity.kt
@@ -0,0 +1,81 @@
+package com.sameerasw.essentials.ui.activities
+
+import android.app.Activity
+import android.content.ClipData
+import android.content.ClipboardManager
+import android.content.Context
+import android.content.Intent
+import android.graphics.Color
+import android.os.Build
+import android.os.Bundle
+import android.widget.Toast
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import com.sameerasw.essentials.R
+import com.sameerasw.essentials.ui.components.sheets.ColorPickerBottomSheet
+import com.sameerasw.essentials.ui.theme.EssentialsTheme
+import com.sameerasw.essentials.utils.HapticUtil
+
+class ColorPickerActivity : ComponentActivity() {
+
+ private var pickedColor by mutableStateOf(null)
+ private var showBottomSheet by mutableStateOf(false)
+
+ private val eyeDropperLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+ if (result.resultCode == Activity.RESULT_OK) {
+ val color = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ result.data?.getIntExtra("android.intent.extra.COLOR", Color.BLACK) ?: Color.BLACK
+ } else {
+ Color.BLACK
+ }
+
+ pickedColor = color
+ showBottomSheet = true
+ HapticUtil.performHapticForService(this)
+ } else {
+ // If they cancelled the eye dropper and no bottom sheet is showing, finish
+ if (!showBottomSheet) {
+ finish()
+ }
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ setContent {
+ EssentialsTheme {
+ if (showBottomSheet && pickedColor != null) {
+ ColorPickerBottomSheet(
+ colorInt = pickedColor!!,
+ onRetake = {
+ showBottomSheet = false
+ launchColorPicker()
+ },
+ onDismissRequest = {
+ finish()
+ }
+ )
+ }
+ }
+ }
+
+ if (savedInstanceState == null) {
+ launchColorPicker()
+ }
+ }
+
+ private fun launchColorPicker() {
+ try {
+ val intent = Intent("android.intent.action.OPEN_EYE_DROPPER")
+ eyeDropperLauncher.launch(intent)
+ } catch (e: Exception) {
+ Toast.makeText(this, getString(R.string.toast_eyedropper_failed), Toast.LENGTH_SHORT).show()
+ finish()
+ }
+ }
+}
diff --git a/app/src/main/java/com/sameerasw/essentials/ui/components/sheets/ColorPickerBottomSheet.kt b/app/src/main/java/com/sameerasw/essentials/ui/components/sheets/ColorPickerBottomSheet.kt
new file mode 100644
index 000000000..564d91e58
--- /dev/null
+++ b/app/src/main/java/com/sameerasw/essentials/ui/components/sheets/ColorPickerBottomSheet.kt
@@ -0,0 +1,195 @@
+package com.sameerasw.essentials.ui.components.sheets
+
+import android.content.Intent
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialShapes
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.ModalBottomSheet
+import androidx.compose.material3.OutlinedButton
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Text
+import androidx.compose.material3.rememberModalBottomSheetState
+import androidx.compose.material3.toShape
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+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.Path
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
+import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
+import androidx.compose.ui.graphics.nativeCanvas
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.platform.LocalClipboardManager
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.dp
+import com.sameerasw.essentials.R
+import com.sameerasw.essentials.ui.components.containers.RoundedCardContainer
+import com.sameerasw.essentials.ui.components.pickers.SegmentedPicker
+import com.sameerasw.essentials.utils.ColorFormatUtils
+import com.sameerasw.essentials.utils.HapticUtil
+import kotlin.math.cos
+import kotlin.math.sin
+
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
+@Composable
+fun ColorPickerBottomSheet(
+ colorInt: Int,
+ onRetake: () -> Unit,
+ onDismissRequest: () -> Unit
+) {
+ val context = LocalContext.current
+ val view = LocalView.current
+ val clipboardManager = LocalClipboardManager.current
+ val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
+
+ var selectedFormat by remember { mutableStateOf(ColorFormatUtils.ColorFormat.HEX) }
+ val formattedColor = remember(colorInt, selectedFormat) {
+ ColorFormatUtils.formatColor(colorInt, selectedFormat)
+ }
+
+ ModalBottomSheet(
+ onDismissRequest = onDismissRequest,
+ sheetState = sheetState,
+ containerColor = MaterialTheme.colorScheme.surfaceContainerHigh
+ ) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 24.dp)
+ .padding(bottom = 32.dp),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.spacedBy(24.dp)
+ ) {
+ // Shape
+ Box(
+ modifier = Modifier
+ .size(160.dp)
+ .clip(MaterialShapes.Cookie6Sided.toShape())
+ .background(Color(colorInt))
+ .border(5.dp, MaterialTheme.colorScheme.outline, MaterialShapes.Cookie6Sided.toShape()),
+ contentAlignment = Alignment.Center
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.rounded_palette_24),
+ contentDescription = null,
+ modifier = Modifier.size(48.dp),
+ tint = MaterialTheme.colorScheme.outline
+ )
+ }
+
+ RoundedCardContainer {
+ // Segmented Picker for Format
+ SegmentedPicker(
+ items = ColorFormatUtils.ColorFormat.values().toList(),
+ selectedItem = selectedFormat,
+ onItemSelected = { selectedFormat = it },
+ labelProvider = { it.name },
+ modifier = Modifier.fillMaxWidth()
+ )
+
+ // Formatted Color Text
+ Surface(
+ color = MaterialTheme.colorScheme.surfaceBright,
+ shape = MaterialTheme.shapes.extraSmall,
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ Text(
+ text = formattedColor,
+ style = MaterialTheme.typography.headlineMedium,
+ fontWeight = FontWeight.Bold,
+ color = MaterialTheme.colorScheme.primary,
+ modifier = Modifier.padding(16.dp),
+ textAlign = androidx.compose.ui.text.style.TextAlign.Center
+ )
+ }
+ }
+
+ // Actions Row
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.spacedBy(12.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ // Retake Button
+ OutlinedButton(
+ onClick = {
+ HapticUtil.performMediumHaptic(view)
+ onRetake()
+ },
+ modifier = Modifier.weight(0.75f).height(56.dp)
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.rounded_colorize_24),
+ contentDescription = null,
+ modifier = Modifier.size(24.dp)
+ )
+ }
+
+ // Share Button
+ OutlinedButton(
+ onClick = {
+ HapticUtil.performUIHaptic(view)
+ val sendIntent: Intent = Intent().apply {
+ action = Intent.ACTION_SEND
+ putExtra(Intent.EXTRA_TEXT, formattedColor)
+ type = "text/plain"
+ }
+ val shareIntent = Intent.createChooser(sendIntent, null)
+ context.startActivity(shareIntent)
+ },
+ modifier = Modifier.weight(1.5f).height(56.dp)
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.rounded_share_24),
+ contentDescription = "Share",
+ modifier = Modifier.size(24.dp)
+ )
+ }
+
+ // Copy Button
+ Button(
+ onClick = {
+ HapticUtil.performHeavyHaptic(view)
+ clipboardManager.setText(AnnotatedString(formattedColor))
+ android.widget.Toast.makeText(context, "Copied to clipboard", android.widget.Toast.LENGTH_SHORT).show()
+ onDismissRequest()
+ },
+ modifier = Modifier.weight(1.5f).height(56.dp)
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.rounded_content_copy_24),
+ contentDescription = null,
+ modifier = Modifier.size(24.dp)
+ )
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/sameerasw/essentials/ui/composables/DIYScreen.kt b/app/src/main/java/com/sameerasw/essentials/ui/composables/DIYScreen.kt
index 3a8ab2cbd..6f8b43cc6 100644
--- a/app/src/main/java/com/sameerasw/essentials/ui/composables/DIYScreen.kt
+++ b/app/src/main/java/com/sameerasw/essentials/ui/composables/DIYScreen.kt
@@ -8,23 +8,17 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.material3.FloatingActionButton
-import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
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.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
-import androidx.compose.ui.platform.LocalView
-import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
@@ -33,20 +27,19 @@ import com.sameerasw.essentials.ui.activities.AutomationEditorActivity
import com.sameerasw.essentials.ui.components.containers.RoundedCardContainer
import com.sameerasw.essentials.ui.components.diy.AutomationItem
import com.sameerasw.essentials.ui.components.sheets.NewAutomationSheet
-import com.sameerasw.essentials.utils.HapticUtil
import com.sameerasw.essentials.viewmodels.DIYViewModel
@Composable
fun DIYScreen(
modifier: Modifier = Modifier,
- viewModel: DIYViewModel = viewModel()
+ viewModel: DIYViewModel = viewModel(),
+ showNewAutomationSheet: Boolean = false,
+ onDismissNewAutomationSheet: () -> Unit = {}
) {
val context = LocalContext.current
val automations by viewModel.automations.collectAsState()
val focusManager = LocalFocusManager.current
- var showNewAutomationSheet by remember { mutableStateOf(false) }
-
Box(modifier = modifier.fillMaxSize()) {
Column(
modifier = Modifier
@@ -147,32 +140,13 @@ fun DIYScreen(
}
}
}
-
- // FAB
- val view = LocalView.current
- FloatingActionButton(
- onClick = {
- HapticUtil.performUIHaptic(view)
- showNewAutomationSheet = true
- },
- modifier = Modifier
- .align(Alignment.BottomEnd)
- .padding(bottom = 32.dp, end = 32.dp),
- containerColor = MaterialTheme.colorScheme.primaryContainer,
- contentColor = MaterialTheme.colorScheme.onPrimaryContainer
- ) {
- Icon(
- painter = painterResource(id = R.drawable.rounded_add_24),
- contentDescription = stringResource(R.string.diy_editor_new_title)
- )
- }
}
if (showNewAutomationSheet) {
NewAutomationSheet(
- onDismiss = { showNewAutomationSheet = false },
+ onDismiss = onDismissNewAutomationSheet,
onOptionSelected = { type ->
- showNewAutomationSheet = false
+ onDismissNewAutomationSheet()
context.startActivity(AutomationEditorActivity.createIntent(context, type))
}
)
diff --git a/app/src/main/java/com/sameerasw/essentials/ui/composables/FreezeGridUI.kt b/app/src/main/java/com/sameerasw/essentials/ui/composables/FreezeGridUI.kt
index d60ff16e9..6dcba1fa5 100644
--- a/app/src/main/java/com/sameerasw/essentials/ui/composables/FreezeGridUI.kt
+++ b/app/src/main/java/com/sameerasw/essentials/ui/composables/FreezeGridUI.kt
@@ -1,7 +1,5 @@
package com.sameerasw.essentials.ui.composables
-import androidx.activity.compose.BackHandler
-import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -25,24 +23,17 @@ import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
-import androidx.compose.material3.FloatingActionButtonMenu
-import androidx.compose.material3.FloatingActionButtonMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.LoadingIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
-import androidx.compose.material3.ToggleFloatingActionButton
-import androidx.compose.material3.ToggleFloatingActionButtonDefaults.animateIcon
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateMapOf
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
-import androidx.compose.runtime.saveable.rememberSaveable
-import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -52,13 +43,9 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.semantics.contentDescription
-import androidx.compose.ui.semantics.semantics
-import androidx.compose.ui.semantics.stateDescription
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner
@@ -179,19 +166,6 @@ fun FreezeGridUI(
}
}
}
-
- // FAB
- Box(
- modifier = Modifier
- .align(Alignment.BottomEnd)
- .padding(bottom = 150.dp, end = 16.dp)
- ) {
- ExpandableFreezeFab(
- onUnfreezeAll = { viewModel.unfreezeAllApps(context) },
- onFreezeAll = { viewModel.freezeAllApps(context) },
- onFreezeAutomatic = { viewModel.freezeAutomaticApps(context) }
- )
- }
}
}
@@ -282,84 +256,3 @@ fun AppGridItem(
}
}
}
-
-@OptIn(ExperimentalMaterial3ExpressiveApi::class)
-@Composable
-fun ExpandableFreezeFab(
- onUnfreezeAll: () -> Unit,
- onFreezeAll: () -> Unit,
- onFreezeAutomatic: () -> Unit
-) {
- var fabMenuExpanded by rememberSaveable { mutableStateOf(false) }
-
- BackHandler(fabMenuExpanded) { fabMenuExpanded = false }
-
- FloatingActionButtonMenu(
- expanded = fabMenuExpanded,
- button = {
- ToggleFloatingActionButton(
- modifier = Modifier
- .semantics {
- stateDescription = if (fabMenuExpanded) "Expanded" else "Collapsed"
- contentDescription = "Toggle menu"
- },
- checked = fabMenuExpanded,
- onCheckedChange = { fabMenuExpanded = !fabMenuExpanded },
- ) {
- // Animate the icon based on the state
- val progress by animateFloatAsState(
- targetValue = if (fabMenuExpanded) 1f else 0f,
- label = "fab_icon_animation"
- )
-
- Icon(
- painter = painterResource(
- id = if (fabMenuExpanded) R.drawable.rounded_close_24 else R.drawable.rounded_mode_cool_24
- ),
- contentDescription = null,
- modifier = Modifier.animateIcon({ progress }),
- )
- }
- },
- ) {
- FloatingActionButtonMenuItem(
- onClick = {
- fabMenuExpanded = false
- onFreezeAll()
- },
- icon = {
- Icon(
- painterResource(id = R.drawable.rounded_mode_cool_24),
- contentDescription = null
- )
- },
- text = { Text(text = "Freeze All") },
- )
- FloatingActionButtonMenuItem(
- onClick = {
- fabMenuExpanded = false
- onUnfreezeAll()
- },
- icon = {
- Icon(
- painterResource(id = R.drawable.rounded_mode_cool_off_24),
- contentDescription = null
- )
- },
- text = { Text(text = "Unfreeze All") },
- )
- FloatingActionButtonMenuItem(
- onClick = {
- fabMenuExpanded = false
- onFreezeAutomatic()
- },
- icon = {
- Icon(
- painterResource(id = R.drawable.rounded_nest_farsight_cool_24),
- contentDescription = null
- )
- },
- text = { Text(text = "Freeze Automatic") },
- )
- }
-}
diff --git a/app/src/main/java/com/sameerasw/essentials/utils/ColorFormatUtils.kt b/app/src/main/java/com/sameerasw/essentials/utils/ColorFormatUtils.kt
new file mode 100644
index 000000000..942b4dad3
--- /dev/null
+++ b/app/src/main/java/com/sameerasw/essentials/utils/ColorFormatUtils.kt
@@ -0,0 +1,33 @@
+package com.sameerasw.essentials.utils
+
+import android.graphics.Color
+import androidx.core.graphics.ColorUtils as AndroidColorUtils
+
+object ColorFormatUtils {
+
+ enum class ColorFormat {
+ HEX, RGB, HSL, HSV
+ }
+
+ fun formatColor(color: Int, format: ColorFormat): String {
+ return when (format) {
+ ColorFormat.HEX -> String.format("#%06X", 0xFFFFFF and color)
+ ColorFormat.RGB -> {
+ val r = Color.red(color)
+ val g = Color.green(color)
+ val b = Color.blue(color)
+ "rgb($r, $g, $b)"
+ }
+ ColorFormat.HSL -> {
+ val hsl = FloatArray(3)
+ AndroidColorUtils.colorToHSL(color, hsl)
+ String.format("hsl(%.0f, %.0f%%, %.0f%%)", hsl[0], hsl[1] * 100, hsl[2] * 100)
+ }
+ ColorFormat.HSV -> {
+ val hsv = FloatArray(3)
+ Color.colorToHSV(color, hsv)
+ String.format("hsv(%.0f, %.0f%%, %.0f%%)", hsv[0], hsv[1] * 100, hsv[2] * 100)
+ }
+ }
+ }
+}
diff --git a/app/src/main/res/drawable/rounded_palette_24.xml b/app/src/main/res/drawable/rounded_palette_24.xml
new file mode 100644
index 000000000..afe0f1329
--- /dev/null
+++ b/app/src/main/res/drawable/rounded_palette_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+