From 957ff2f1673140f17801f3cd04cf89cc40c2c3ce Mon Sep 17 00:00:00 2001
From: yanmess1ge-dot <257031600+yanmess1ge-dot@users.noreply.github.com>
Date: Mon, 17 Aug 2026 11:25:22 +0000
Subject: [PATCH 1/9] Community translations by @yanmess1ge-dot
---
app/src/main/res/values-de/strings.xml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 4c77d0cec..c5d11a0fe 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -1626,10 +1626,10 @@ Zudem muss die Einstellung unter Umständen mehrfach angewendet werden, damit si
Kein automatisches Einfrieren
Apps mit diesem Tag werden vor dem automatischen Einfrieren geschützt
Tag-Farben im App-Raster anzeigen
- Benachrichtigungen synchronisieren
- Zum Essentials-Launcher
+ Benachrichtigungssynchronisierung
+ Zum Essentials Launcher
Anrufe synchronisieren
- Anrufe mit deiner Smartwatch synchronisieren und steuern
+ Anrufe von Ihrer Uhr synchronisieren und steuern
Apps auswählen
Nur ausgewählte Apps werden mit der Smartwatch synchronisiert
From 8ef8baa80ac52af5bd54ce4a834eeb788ce167b6 Mon Sep 17 00:00:00 2001
From: qxmO5 <277465300+qxmO5@users.noreply.github.com>
Date: Mon, 17 Aug 2026 15:38:55 +0000
Subject: [PATCH 2/9] Community translations by @qxmO5
---
app/src/main/res/values-ar/strings.xml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index ed7b3c2ef..c5a5fe755 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -1582,4 +1582,9 @@
الى مشغل Essentials
استبدال شريط البحث
استبدال مشغل Pixel الافتراضيsearchbar
+ وقت الغفوة الافتراضي
+ الخيار الاول
+ الخيار الثاني
+ الخيار الثالث
+ الخيار الرابع
From 30e18dab6a4382bed6ad1af09dfa15eb8f5516e8 Mon Sep 17 00:00:00 2001
From: qxmO5 <277465300+qxmO5@users.noreply.github.com>
Date: Mon, 17 Aug 2026 16:07:15 +0000
Subject: [PATCH 3/9] Community translations by @qxmO5
---
app/src/main/res/values-ar/strings.xml | 65 +++++++++++++++-----------
1 file changed, 38 insertions(+), 27 deletions(-)
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index c5a5fe755..4a38e1a66 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -68,15 +68,15 @@
نظرة على الوسائط والمعلومات في AOD
وضع التوصيل
حافظ على التراكب المرئي دائماً أثناء تشغيل الموسيقى على AOD
- Respect new notifications
- Briefly disable for new notifications
+ احترام الاشعارات الجديدة
+ تعطيل مؤقت للإشعارات الجديدة
أشكال عشوائية
استخدم أشكال مختلفة من Material 3 لغلاف الألبوم
Album art
Clock
- Always use while charging
- Force Fill mode when the device is plugged in regardless of the selected mode
- Size
+ استعمال دائمًا أثناء الشحن
+ وضع التعبئة الإجبارية عند توصيل الجهاز بغض النظر عن الوضع المحدد
+ الحجم
لمحة الإشعارات
احتفظ بـ AOD قيد التشغيل أثناء انتظار الإشعارات
نفس التطبيقات التي تعمل مع إضاءة الإشعارات
@@ -1307,8 +1307,10 @@
تطبيقات
الحجم والرسوم المتحركة
ضبط حجم النظام والرسوم المتحركة
- Screen Refresh Rate
- Set a fixed or ranged screen refresh rate
+ معدل تحديث الشاشة
+ تعيين معدل تحديث ثابت أو متغير للشاشة
+
+معدل التحديث
نص
مقياس الخط
وزن الخط
@@ -1325,14 +1327,14 @@
Set a custom screen refresh rate using Shizuku. Fixed mode locks both the minimum and peak refresh rate to one value, while range mode lets you define separate minimum and peak values. Reset clears the custom override and returns the device to its system-managed refresh behavior.
Mode
Refresh Rate
- Fixed
- Range
- Fixed refresh rate
- Set both minimum and peak refresh rate to the same value
- Minimum refresh rate
- Choose the lowest refresh rate the display may use
- Peak refresh rate
- Choose the highest refresh rate the display may use
+ ثابت
+ مدى
+ معدل تحديث ثابت
+ حدد كل من معدل التحديث الأدنى والذروة إلى نفس القيمة
+ الحد الأدنى لمعدل التحديث
+ اختر أدنى معدل تحديث قد تستخدمه الشاشة
+ ذروة معدل التحديث
+ اختر أعلى معدل تحديث قد تستخدمه الشاشة.
System
Remove the custom override and return to the system default refresh behavior
Shizuku permission required to adjust refresh rate
@@ -1401,8 +1403,8 @@
اخرس
انا اعرف ماذا افعل
Shut-Up! bypasses app restrictions and checks for developer options, accessibility and debugging by dynamically hiding them when you launch sensitive apps. \n\nUse the custom shortcuts to ensure settings are hidden before the app launches.
- Select Apps
- Choose apps to apply Shut-Up! logic
+ حدد التطبيقات
+ اختر التطبيقات لتطبيق منطق اخرس!
Shut-Up! Settings
Shut-Up! Features
Disable Developer Options
@@ -1420,7 +1422,7 @@
Abort
ساعة شاشة القفل
- تخصيص ساعة شاشة القفل على أجهزة بيكسل
+ تخصيص ساعة شاشة القفل على أجهزة بكسل
Change the lock screen clock style on Pixels. Select from the available clock faces provided by the System UI. Some old styles might not be available.
Big Number
Calligraphy
@@ -1437,10 +1439,10 @@
Clock style applied
WRITE_SECURE_SETTINGS permission required
Default
- Weight
- Width
+ الثقل
+ العرض
Grade
- Roundness
+ الاستدارة
Lightness
Variation
Color
@@ -1578,13 +1580,22 @@
المتَرجم
مزامنة المكالمات والتحكم بها من ساعتك
مزامنة المكالمات
- مزامنة الاشعارات
- الى مشغل Essentials
- استبدال شريط البحث
- استبدال مشغل Pixel الافتراضيsearchbar
- وقت الغفوة الافتراضي
- الخيار الاول
+ مزامنة الأشعار
+ لي Essentials launcher
+ استبدال Searchbar
+ استبدل شريط البحث الافتراضي Pixel Launcher.
+ وقت غفوة الافتراضي
+ الخيار الأول
الخيار الثاني
الخيار الثالث
الخيار الرابع
+ فارغ
+ التاريخ
+ حشوة أفقية
+ حشوة عمودية
+ الخلفية
+ اختر التطبيقات
+ سيتم مزامنة التطبيقات المحددة فقط للساعه
+ تأخر الاستعادة
+ وقت الانتظار قبل استعادة الإعدادات بعد الخروج من تطبيق أخرس!
From 7bdbf2cce343cd44d4608bf43aaad5b25b790466 Mon Sep 17 00:00:00 2001
From: fishqaq123 <145851012+fishqaq123@users.noreply.github.com>
Date: Tue, 18 Aug 2026 09:47:46 +0000
Subject: [PATCH 4/9] Community translations by @fishqaq123
---
app/src/main/res/values-zh/strings.xml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml
index d0d692436..02fd4542c 100644
--- a/app/src/main/res/values-zh/strings.xml
+++ b/app/src/main/res/values-zh/strings.xml
@@ -1538,4 +1538,6 @@
显示无线显示认证选项
移动数据始终开启
即使已连接 Wi-Fi,也要保持移动数据开启状态
+ 网络
+ 控制频率和网络
From a81e8e2e86cd84557fc19a94d546b8e4e6193a12 Mon Sep 17 00:00:00 2001
From: dimzhen <23508487+dimzhen@users.noreply.github.com>
Date: Tue, 18 Aug 2026 11:07:30 +0000
Subject: [PATCH 5/9] Community translations by @dimzhen
---
app/src/main/res/values-in-rID/strings.xml | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/app/src/main/res/values-in-rID/strings.xml b/app/src/main/res/values-in-rID/strings.xml
index 2fcbc3a9e..37cd25237 100644
--- a/app/src/main/res/values-in-rID/strings.xml
+++ b/app/src/main/res/values-in-rID/strings.xml
@@ -182,10 +182,10 @@
Lewati notifikasi bisu
Skip persistent notifications
Flashlight Pulse
- Flashlight pulse
- Only while facing down
+ Lampu kilat berdetak
+ Hanya saat menghadapi ke bawah
Same apps as notification lighting
- Max brightness
+ Kecerahan Maks
Do not trigger on DND
Preview pulse
Style
@@ -207,7 +207,7 @@
Kiri
Tengah
Kanan
- Select Shapes
+ Pilih Bentuk
Choose which shapes are used in the sweep animation
Animasi
Pulse count
@@ -426,7 +426,7 @@
Untuk semua perangkat Android
Cahaya pemberitahuan
Nyalakan untuk pemberitahuan
- Pulse the flashlight for notifications
+ Detakkan lampu kilat untuk pemberitahuan
Sound mode tile
Call vibrations
Vibrate for call actions
@@ -1296,7 +1296,7 @@
README
Refresh
- Sound mode tile
+ Mode ubin suara
QS tile to toggle sound mode
Show slider
Show volume slider in tile
@@ -1684,10 +1684,10 @@
a few minutes
Translations
- Translation Mode
- Long press any text to translate and contribute to the community
- Translated
- %d edit(s) pending — tap to submit or discard
+ Mode Terjemahan
+ Tekan lama tulisan apapun untuk menerjemahkan dan kontribusi ke komunitas
+ Diterjemahkan
+ %d perubahan dijeda — ketuk untuk mengirim atau membatalkan
Submit
Discard
Translate
From b2c8794b6177fb4e6ab6fd02cb8f3cbaf01fe325 Mon Sep 17 00:00:00 2001
From: sameerasw
Date: Wed, 19 Aug 2026 11:18:38 +0530
Subject: [PATCH 6/9] feat: custm settings in DIY
---
.../sameerasw/essentials/domain/diy/Action.kt | 41 ++
.../domain/registry/PermissionRegistry.kt | 7 +-
.../executors/CombinedActionExecutor.kt | 25 +
.../ui/activities/AutomationEditorActivity.kt | 26 +
.../ui/core/sheets/CustomSettingsSheet.kt | 583 ++++++++++++++++++
.../essentials/utils/SettingsRecorder.kt | 94 +++
app/src/main/res/values/strings.xml | 17 +
7 files changed, 790 insertions(+), 3 deletions(-)
create mode 100644 app/src/main/java/com/sameerasw/essentials/ui/core/sheets/CustomSettingsSheet.kt
create mode 100644 app/src/main/java/com/sameerasw/essentials/utils/SettingsRecorder.kt
diff --git a/app/src/main/java/com/sameerasw/essentials/domain/diy/Action.kt b/app/src/main/java/com/sameerasw/essentials/domain/diy/Action.kt
index 3efa21ed4..1c54598ae 100644
--- a/app/src/main/java/com/sameerasw/essentials/domain/diy/Action.kt
+++ b/app/src/main/java/com/sameerasw/essentials/domain/diy/Action.kt
@@ -336,5 +336,46 @@ sealed interface Action {
override val permissions: List = listOf("SHIZUKU", "ROOT")
override val isConfigurable: Boolean = true
}
+
+ @Keep
+ enum class SettingsTable {
+ @SerializedName("SYSTEM")
+ SYSTEM,
+
+ @SerializedName("SECURE")
+ SECURE,
+
+ @SerializedName("GLOBAL")
+ GLOBAL
+ }
+
+ @Keep
+ data class SettingsEntry(
+ @SerializedName("table") val table: SettingsTable = SettingsTable.SYSTEM,
+ @SerializedName("key") val key: String = "",
+ @SerializedName("value") val value: String = ""
+ )
+
+ @Keep
+ data class CustomSettings(
+ @SerializedName("entries") val entries: List = emptyList()
+ ) : Action {
+ override val title: Int get() = R.string.diy_action_custom_settings
+ override val icon: Int get() = R.drawable.rounded_settings_24
+ override val isConfigurable: Boolean = true
+ override val permissions: List
+ get() {
+ val perms = mutableSetOf()
+ for (entry in entries) {
+ when (entry.table) {
+ SettingsTable.SYSTEM -> perms.add("WRITE_SETTINGS")
+ SettingsTable.SECURE -> perms.add("WRITE_SECURE_SETTINGS")
+ SettingsTable.GLOBAL -> perms.add("WRITE_SECURE_SETTINGS")
+ }
+ }
+ return perms.toList()
+ }
+ }
}
+
diff --git a/app/src/main/java/com/sameerasw/essentials/domain/registry/PermissionRegistry.kt b/app/src/main/java/com/sameerasw/essentials/domain/registry/PermissionRegistry.kt
index f063f7f42..e53287207 100644
--- a/app/src/main/java/com/sameerasw/essentials/domain/registry/PermissionRegistry.kt
+++ b/app/src/main/java/com/sameerasw/essentials/domain/registry/PermissionRegistry.kt
@@ -135,9 +135,6 @@ fun initPermissionRegistry() {
// Safe Volume Warning feature
PermissionRegistry.register("WRITE_SECURE_SETTINGS", R.string.feat_safe_volume_title)
- // Notification Snoozing feature
- PermissionRegistry.register("WRITE_SECURE_SETTINGS", R.string.feat_notification_snoozing_title)
-
// Install unknown packages feature
// Watch Call Sync & Notification Sync
PermissionRegistry.register("READ_PHONE_STATE", R.string.watch_call_sync_title)
@@ -145,4 +142,8 @@ fun initPermissionRegistry() {
PermissionRegistry.register("READ_CONTACTS", R.string.watch_call_sync_title)
PermissionRegistry.register("READ_CALL_LOG", R.string.watch_call_sync_title)
PermissionRegistry.register("NOTIFICATION_LISTENER", R.string.watch_notif_sync_title)
+
+ // DIY Automations feature
+ PermissionRegistry.register("WRITE_SECURE_SETTINGS", R.string.tab_diy)
+ PermissionRegistry.register("WRITE_SETTINGS", R.string.tab_diy)
}
diff --git a/app/src/main/java/com/sameerasw/essentials/services/automation/executors/CombinedActionExecutor.kt b/app/src/main/java/com/sameerasw/essentials/services/automation/executors/CombinedActionExecutor.kt
index 43ea619f6..fc937c867 100644
--- a/app/src/main/java/com/sameerasw/essentials/services/automation/executors/CombinedActionExecutor.kt
+++ b/app/src/main/java/com/sameerasw/essentials/services/automation/executors/CombinedActionExecutor.kt
@@ -16,12 +16,14 @@ import android.hardware.camera2.CameraManager
import android.media.AudioManager
import android.net.wifi.WifiManager
import android.os.Build
+import android.provider.Settings
import android.view.KeyEvent
import android.widget.Toast
import com.sameerasw.essentials.domain.HapticFeedbackType
import com.sameerasw.essentials.domain.diy.Action
import com.sameerasw.essentials.services.tiles.ScreenOffAccessibilityService
import com.sameerasw.essentials.utils.DeviceLockUtils
+import com.sameerasw.essentials.utils.ShellUtils
import com.sameerasw.essentials.utils.performHapticFeedback
import rikka.shizuku.ShizukuBinderWrapper
import rikka.shizuku.SystemServiceHelper
@@ -650,6 +652,29 @@ object CombinedActionExecutor {
com.sameerasw.essentials.utils.FreezeManager.unfreezeApp(context, pkg)
}
}
+ is Action.CustomSettings -> {
+ val resolver = context.contentResolver
+ for (entry in action.entries) {
+ val success = try {
+ when (entry.table) {
+ Action.SettingsTable.SYSTEM -> Settings.System.putString(resolver, entry.key, entry.value)
+ Action.SettingsTable.SECURE -> Settings.Secure.putString(resolver, entry.key, entry.value)
+ Action.SettingsTable.GLOBAL -> Settings.Global.putString(resolver, entry.key, entry.value)
+ }
+ } catch (e: Exception) {
+ false
+ }
+ if (!success) {
+ val tableArg = when (entry.table) {
+ Action.SettingsTable.SYSTEM -> "system"
+ Action.SettingsTable.SECURE -> "secure"
+ Action.SettingsTable.GLOBAL -> "global"
+ }
+ val safeValue = if (entry.value.contains(" ")) "\"${entry.value}\"" else entry.value
+ ShellUtils.runCommand(context, "settings put $tableArg ${entry.key} $safeValue")
+ }
+ }
+ }
}
}
diff --git a/app/src/main/java/com/sameerasw/essentials/ui/activities/AutomationEditorActivity.kt b/app/src/main/java/com/sameerasw/essentials/ui/activities/AutomationEditorActivity.kt
index 4469dd4f8..50ec80554 100644
--- a/app/src/main/java/com/sameerasw/essentials/ui/activities/AutomationEditorActivity.kt
+++ b/app/src/main/java/com/sameerasw/essentials/ui/activities/AutomationEditorActivity.kt
@@ -96,6 +96,7 @@ import com.sameerasw.essentials.ui.core.containers.RoundedCardContainer
import com.sameerasw.essentials.ui.core.pickers.SegmentedPicker
import com.sameerasw.essentials.ui.core.sheets.AppSelectionSheet
import com.sameerasw.essentials.ui.core.sheets.BluetoothDeviceSelectionSheet
+import com.sameerasw.essentials.ui.core.sheets.CustomSettingsSheet
import com.sameerasw.essentials.ui.core.sheets.DimWallpaperSettingsSheet
import com.sameerasw.essentials.ui.core.sheets.ScreenOffSettingsSheet
import com.sameerasw.essentials.ui.core.sheets.SingleAppSelectionSheet
@@ -265,6 +266,7 @@ class AutomationEditorActivity : ComponentActivity() {
var showTimeSettings by remember { mutableStateOf(false) }
var showBluetoothSettings by remember { mutableStateOf(false) }
var showWifiSettings by remember { mutableStateOf(false) }
+ var showCustomSettingsSettings by remember { mutableStateOf(false) }
var configAction by remember { mutableStateOf(null) } // Generic config action
val isTriggerConfigured = when (val trigger = selectedTrigger) {
@@ -295,6 +297,7 @@ class AutomationEditorActivity : ComponentActivity() {
fun isActionConfigured(action: Action?): Boolean = when (action) {
is Action.OpenApp -> action.packageName.isNotBlank()
+ is Action.CustomSettings -> action.entries.isNotEmpty()
else -> true
}
@@ -910,6 +913,7 @@ class AutomationEditorActivity : ComponentActivity() {
Action.ToggleFlashlight,
Action.TurnOnLowPower,
Action.TurnOffLowPower,
+ Action.CustomSettings(),
Action.CircleToSearch,
Action.TakeScreenshot,
Action.ShowNotification,
@@ -996,6 +1000,7 @@ class AutomationEditorActivity : ComponentActivity() {
temporarySelectedAppsForAction = resolvedAction.packageNames
showFreezeAppsSettings = true
}
+ is Action.CustomSettings -> showCustomSettingsSettings = true
else -> {}
}
}
@@ -1279,6 +1284,27 @@ class AutomationEditorActivity : ComponentActivity() {
excludePackages = if (automationType == Automation.Type.APP) selectedApps else emptyList()
)
}
+
+ if (showCustomSettingsSettings && configAction is Action.CustomSettings) {
+ CustomSettingsSheet(
+ initialAction = configAction as Action.CustomSettings,
+ onDismiss = { showCustomSettingsSettings = false },
+ onSave = { newAction ->
+ showCustomSettingsSettings = false
+ when (automationType) {
+ Automation.Type.TRIGGER -> selectedAction = newAction
+ Automation.Type.ACTION_SHORTCUT, Automation.Type.PIXEL_SEARCHBAR -> selectedAction =
+ newAction
+
+ Automation.Type.STATE, Automation.Type.APP -> {
+ if (selectedActionTab == 0) selectedInAction = newAction
+ else selectedOutAction = newAction
+ }
+ }
+ configAction = null
+ }
+ )
+ }
}
if (showPermissionSheet) {
diff --git a/app/src/main/java/com/sameerasw/essentials/ui/core/sheets/CustomSettingsSheet.kt b/app/src/main/java/com/sameerasw/essentials/ui/core/sheets/CustomSettingsSheet.kt
new file mode 100644
index 000000000..65af6880a
--- /dev/null
+++ b/app/src/main/java/com/sameerasw/essentials/ui/core/sheets/CustomSettingsSheet.kt
@@ -0,0 +1,583 @@
+/*
+ * Copyright (c) 2026 sameerasw.com
+ * License: MIT License
+ *
+ * Feature Module: UI Feature - System
+ * File: CustomSettingsSheet.kt
+ * Description: Bottom sheet allowing recording, editing, and saving of custom Android settings entries.
+ */
+
+package com.sameerasw.essentials.ui.core.sheets
+
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.core.RepeatMode
+import androidx.compose.animation.core.animateFloat
+import androidx.compose.animation.core.infiniteRepeatable
+import androidx.compose.animation.core.rememberInfiniteTransition
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.expandVertically
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.animation.shrinkVertically
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+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.imePadding
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.ButtonGroupDefaults
+import androidx.compose.material3.Card
+import androidx.compose.material3.CardDefaults
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.OutlinedTextField
+import androidx.compose.material3.SuggestionChip
+import androidx.compose.material3.SuggestionChipDefaults
+import androidx.compose.material3.Text
+import androidx.compose.material3.rememberModalBottomSheetState
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.draw.clip
+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.font.FontWeight
+import androidx.compose.ui.unit.dp
+import com.sameerasw.essentials.R
+import com.sameerasw.essentials.domain.diy.Action
+import com.sameerasw.essentials.ui.core.containers.RoundedCardContainer
+import com.sameerasw.essentials.utils.ColorUtil
+import com.sameerasw.essentials.utils.HapticUtil
+import com.sameerasw.essentials.utils.SettingsRecorder
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+private enum class RecordingState {
+ IDLE,
+ RECORDING
+}
+
+private const val MAX_ENTRIES_LIMIT = 20
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun CustomSettingsSheet(
+ initialAction: Action.CustomSettings,
+ onDismiss: () -> Unit,
+ onSave: (Action.CustomSettings) -> Unit
+) {
+ val context = LocalContext.current
+ val view = LocalView.current
+ val scope = rememberCoroutineScope()
+ val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
+ val scrollState = rememberScrollState()
+
+ var recordingState by remember { mutableStateOf(RecordingState.IDLE) }
+ var beforeSnapshot by remember { mutableStateOf