diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index f735708..d67b1c4 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -54,6 +54,7 @@ dependencies {
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3:1.4.0")
implementation("androidx.compose.material:material-icons-core:1.7.8")
+ implementation("androidx.compose.material:material-icons-extended:1.7.8")
implementation("androidx.core:core-splashscreen:1.2.0")
// Compose navigation
diff --git a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/repository/BootRepository.kt b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/repository/BootRepository.kt
index 844cdf7..47e4149 100644
--- a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/repository/BootRepository.kt
+++ b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/repository/BootRepository.kt
@@ -12,6 +12,7 @@ import ru.hepolise.volumekeytrackcontrol.util.LSPosedLogger
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.LAST_BOOT_COMPLETED_TIME
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.getStatusSharedPreferences
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.isBootCompleted
+import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.isHooked
import ru.hepolise.volumekeytrackcontrol.util.StatusSysPropsHelper
class BootRepository private constructor(private val sharedPreferences: SharedPreferences) {
@@ -31,6 +32,10 @@ class BootRepository private constructor(private val sharedPreferences: SharedPr
return sharedPreferences.isBootCompleted()
}
+ fun isHooked(): Boolean {
+ return StatusSysPropsHelper.isHooked || sharedPreferences.isHooked()
+ }
+
fun setBootCompleted() {
sharedPreferences.edit {
putLong(LAST_BOOT_COMPLETED_TIME, System.currentTimeMillis())
diff --git a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/component/LongPressActionSetting.kt b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/component/LongPressActionSetting.kt
new file mode 100644
index 0000000..cfc5325
--- /dev/null
+++ b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/component/LongPressActionSetting.kt
@@ -0,0 +1,142 @@
+package ru.hepolise.volumekeytrackcontrol.ui.component
+
+import android.content.SharedPreferences
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.expandVertically
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.animation.shrinkVertically
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.defaultMinSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Edit
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.SegmentedButton
+import androidx.compose.material3.SegmentedButtonDefaults
+import androidx.compose.material3.SingleChoiceSegmentedButtonRow
+import androidx.compose.material3.Text
+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.res.stringResource
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
+import androidx.core.content.edit
+import ru.hepolise.volumekeytrackcontrol.util.RewindActionType
+import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.REWIND_ACTION_TYPE
+import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.REWIND_DURATION
+import ru.hepolise.volumekeytrackcontrolmodule.R
+
+data class RewindSettingData(
+ val rewindActionType: RewindActionType,
+ val rewindDuration: Int
+)
+
+@Composable
+fun LongPressActionSetting(
+ data: RewindSettingData,
+ sharedPreferences: SharedPreferences,
+ onValueChange: (RewindSettingData) -> Unit
+) {
+ val rewindActionType = data.rewindActionType
+ val rewindDuration = data.rewindDuration
+
+ var showRewindDurationDialog by remember { mutableStateOf(false) }
+
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ SingleChoiceSegmentedButtonRow {
+ RewindActionType.entries.forEachIndexed { index, actionType ->
+ SegmentedButton(
+ selected = rewindActionType == actionType,
+ onClick = {
+ onValueChange(data.copy(rewindActionType = actionType))
+ sharedPreferences.edit {
+ putString(REWIND_ACTION_TYPE, actionType.name)
+ }
+ },
+ shape = SegmentedButtonDefaults.itemShape(
+ index = index,
+ count = RewindActionType.entries.size
+ ),
+ modifier = Modifier
+ .defaultMinSize(minWidth = 140.dp)
+ .weight(1f)
+ ) {
+ Text(
+ text = when (actionType) {
+ RewindActionType.TRACK_CHANGE -> stringResource(R.string.track_change)
+ RewindActionType.REWIND -> stringResource(R.string.rewind)
+ },
+ maxLines = 1,
+ overflow = TextOverflow.Visible,
+ softWrap = false
+ )
+ }
+ }
+ }
+ }
+
+ Box {
+ AnimatedVisibility(
+ visible = rewindActionType == RewindActionType.REWIND,
+ enter = fadeIn() + expandVertically(expandFrom = Alignment.Top),
+ exit = fadeOut() + shrinkVertically(shrinkTowards = Alignment.Top),
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ PrefsSlider(
+ value = rewindDuration,
+ onValueChange = {
+ onValueChange(data.copy(rewindDuration = it))
+ },
+ valueRange = 1f..60f,
+ prefKey = REWIND_DURATION,
+ sharedPreferences = sharedPreferences
+ )
+
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Text(
+ text = stringResource(R.string.rewind_duration, rewindDuration),
+ modifier = Modifier.clickable { showRewindDurationDialog = true }
+ )
+ IconButton(
+ onClick = {
+ showRewindDurationDialog = true
+ }
+ ) {
+ Icon(
+ imageVector = Icons.Default.Edit,
+ contentDescription = stringResource(R.string.edit_rewind_duration)
+ )
+ }
+ }
+ }
+ }
+ }
+
+ if (showRewindDurationDialog) {
+ NumberAlertDialog(
+ title = stringResource(R.string.rewind_duration_dialog_title),
+ defaultValue = rewindDuration,
+ minValue = 1,
+ maxValue = 60,
+ onDismissRequest = { showRewindDurationDialog = false },
+ onConfirm = {
+ onValueChange(data.copy(rewindDuration = it))
+ sharedPreferences.edit { putInt(REWIND_DURATION, it) }
+ showRewindDurationDialog = false
+ }
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/component/LongPressSetting.kt b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/component/LongPressSetting.kt
index f1ef797..dc96181 100644
--- a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/component/LongPressSetting.kt
+++ b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/component/LongPressSetting.kt
@@ -1,24 +1,12 @@
package ru.hepolise.volumekeytrackcontrol.ui.component
import android.content.SharedPreferences
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.expandVertically
-import androidx.compose.animation.fadeIn
-import androidx.compose.animation.fadeOut
-import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.defaultMinSize
-import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
-import androidx.compose.material3.SegmentedButton
-import androidx.compose.material3.SegmentedButtonDefaults
-import androidx.compose.material3.SingleChoiceSegmentedButtonRow
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@@ -28,37 +16,21 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.text.style.TextOverflow
-import androidx.compose.ui.unit.dp
import androidx.core.content.edit
-import ru.hepolise.volumekeytrackcontrol.util.RewindActionType
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.LONG_PRESS_DURATION
-import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.REWIND_ACTION_TYPE
-import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.REWIND_DURATION
import ru.hepolise.volumekeytrackcontrolmodule.R
-data class LongPressSettingData(
- val longPressDuration: Int,
- val rewindActionType: RewindActionType,
- val rewindDuration: Int
-)
-
@Composable
fun LongPressSetting(
- data: LongPressSettingData,
+ longPressDuration: Int,
sharedPreferences: SharedPreferences,
- onValueChange: (LongPressSettingData) -> Unit
+ onValueChange: (Int) -> Unit
) {
- val longPressDuration = data.longPressDuration
- val rewindActionType = data.rewindActionType
- val rewindDuration = data.rewindDuration
-
var showLongPressTimeoutDialog by remember { mutableStateOf(false) }
- var showRewindDurationDialog by remember { mutableStateOf(false) }
PrefsSlider(
value = longPressDuration,
- onValueChange = { onValueChange(data.copy(longPressDuration = it)) },
+ onValueChange = { onValueChange(it) },
valueRange = 100f..1000f,
prefKey = LONG_PRESS_DURATION,
sharedPreferences = sharedPreferences
@@ -81,85 +53,6 @@ fun LongPressSetting(
}
}
- Row(verticalAlignment = Alignment.CenterVertically) {
- Text(
- text = stringResource(R.string.long_press_action),
- )
- }
-
- Row(verticalAlignment = Alignment.CenterVertically) {
- SingleChoiceSegmentedButtonRow {
- RewindActionType.entries.forEachIndexed { index, actionType ->
- SegmentedButton(
- selected = rewindActionType == actionType,
- onClick = {
- onValueChange(data.copy(rewindActionType = actionType))
- sharedPreferences.edit {
- putString(REWIND_ACTION_TYPE, actionType.name)
- }
- },
- shape = SegmentedButtonDefaults.itemShape(
- index = index,
- count = RewindActionType.entries.size
- ),
- modifier = Modifier
- .defaultMinSize(minWidth = 140.dp)
- .weight(1f)
- ) {
- Text(
- text = when (actionType) {
- RewindActionType.TRACK_CHANGE -> stringResource(R.string.track_change)
- RewindActionType.REWIND -> stringResource(R.string.rewind)
- },
- maxLines = 1,
- overflow = TextOverflow.Visible,
- softWrap = false
- )
- }
- }
- }
- }
-
- Box {
- AnimatedVisibility(
- visible = rewindActionType == RewindActionType.REWIND,
- enter = fadeIn() + expandVertically(expandFrom = Alignment.Top),
- exit = fadeOut() + shrinkVertically(shrinkTowards = Alignment.Top),
- modifier = Modifier.fillMaxWidth()
- ) {
- Column(
- horizontalAlignment = Alignment.CenterHorizontally,
- ) {
- PrefsSlider(
- value = rewindDuration,
- onValueChange = {
- onValueChange(data.copy(rewindDuration = it))
- },
- valueRange = 1f..60f,
- prefKey = REWIND_DURATION,
- sharedPreferences = sharedPreferences
- )
-
- Row(verticalAlignment = Alignment.CenterVertically) {
- Text(
- text = stringResource(R.string.rewind_duration, rewindDuration),
- modifier = Modifier.clickable { showRewindDurationDialog = true }
- )
- IconButton(
- onClick = {
- showRewindDurationDialog = true
- }
- ) {
- Icon(
- imageVector = Icons.Default.Edit,
- contentDescription = stringResource(R.string.edit_rewind_duration)
- )
- }
- }
- }
- }
- }
-
if (showLongPressTimeoutDialog) {
NumberAlertDialog(
title = stringResource(R.string.long_press_duration_dialog_title),
@@ -168,25 +61,10 @@ fun LongPressSetting(
maxValue = 1000,
onDismissRequest = { showLongPressTimeoutDialog = false },
onConfirm = {
- onValueChange(data.copy(longPressDuration = it))
+ onValueChange(it)
sharedPreferences.edit { putInt(LONG_PRESS_DURATION, it) }
showLongPressTimeoutDialog = false
}
)
}
-
- if (showRewindDurationDialog) {
- NumberAlertDialog(
- title = stringResource(R.string.rewind_duration_dialog_title),
- defaultValue = rewindDuration,
- minValue = 1,
- maxValue = 60,
- onDismissRequest = { showRewindDurationDialog = false },
- onConfirm = {
- onValueChange(data.copy(rewindDuration = it))
- sharedPreferences.edit { putInt(REWIND_DURATION, it) }
- showRewindDurationDialog = false
- }
- )
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/screen/SettingsScreen.kt b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/screen/SettingsScreen.kt
index bb4b8cd..328d7af 100644
--- a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/screen/SettingsScreen.kt
+++ b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/screen/SettingsScreen.kt
@@ -34,11 +34,13 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Done
import androidx.compose.material.icons.filled.Edit
+import androidx.compose.material.icons.filled.FastForward
import androidx.compose.material.icons.filled.Info
-import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.filled.Settings
+import androidx.compose.material.icons.filled.SkipNext
import androidx.compose.material.icons.filled.Star
+import androidx.compose.material.icons.filled.Vibration
import androidx.compose.material.icons.filled.Warning
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
@@ -92,14 +94,16 @@ import androidx.core.net.toUri
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import ru.hepolise.volumekeytrackcontrol.ui.component.AppFilterSetting
+import ru.hepolise.volumekeytrackcontrol.ui.component.LongPressActionSetting
import ru.hepolise.volumekeytrackcontrol.ui.component.LongPressSetting
-import ru.hepolise.volumekeytrackcontrol.ui.component.LongPressSettingData
+import ru.hepolise.volumekeytrackcontrol.ui.component.RewindSettingData
import ru.hepolise.volumekeytrackcontrol.ui.component.SwapButtonsSetting
import ru.hepolise.volumekeytrackcontrol.ui.component.VibrationEffectSetting
import ru.hepolise.volumekeytrackcontrol.ui.component.VibrationSettingData
import ru.hepolise.volumekeytrackcontrol.ui.isInstalledAfterReboot
import ru.hepolise.volumekeytrackcontrol.util.AppFilterType
import ru.hepolise.volumekeytrackcontrol.util.Constants
+import ru.hepolise.volumekeytrackcontrol.util.RewindActionType
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.APP_FILTER_TYPE_DEFAULT_VALUE
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.EFFECT_DEFAULT_VALUE
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.IS_SWAP_BUTTONS_DEFAULT_VALUE
@@ -263,15 +267,10 @@ fun SettingsScreen(
title = stringResource(R.string.long_press_settings)
) {
LongPressSetting(
- LongPressSettingData(
- longPressDuration,
- rewindActionType,
- rewindDuration
- ), settingsPrefs
+ longPressDuration,
+ settingsPrefs
) {
- longPressDuration = it.longPressDuration
- rewindActionType = it.rewindActionType
- rewindDuration = it.rewindDuration
+ longPressDuration = it
}
SwapButtonsSetting(
isSwapButtons = isSwapButtons,
@@ -282,7 +281,25 @@ fun SettingsScreen(
}
SettingsCard(
- icon = Icons.Default.Notifications,
+ icon = when (rewindActionType) {
+ RewindActionType.TRACK_CHANGE -> Icons.Default.SkipNext
+ RewindActionType.REWIND -> Icons.Default.FastForward
+ },
+ title = stringResource(R.string.long_press_action)
+ ) {
+ LongPressActionSetting(
+ RewindSettingData(
+ rewindActionType,
+ rewindDuration
+ ), settingsPrefs
+ ) {
+ rewindActionType = it.rewindActionType
+ rewindDuration = it.rewindDuration
+ }
+ }
+
+ SettingsCard(
+ icon = Icons.Default.Vibration,
title = stringResource(R.string.vibration_settings)
) {
VibrationEffectSetting(
diff --git a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/viewmodel/BootViewModel.kt b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/viewmodel/BootViewModel.kt
index 2fa7bf6..5eed922 100644
--- a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/viewmodel/BootViewModel.kt
+++ b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/viewmodel/BootViewModel.kt
@@ -49,7 +49,7 @@ class BootViewModel(
delay(1_000)
StatusSysPropsHelper.refreshIsHooked()
- if (StatusSysPropsHelper.isHooked) {
+ if (bootRepository.isHooked()) {
LSPosedLogger.log("Boot completed - hook detected")
bootRepository.setBootCompleted()
return
diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml
index de2e4de..c6bfebb 100644
--- a/app/src/main/res/values-ru-rRU/strings.xml
+++ b/app/src/main/res/values-ru-rRU/strings.xml
@@ -37,16 +37,16 @@
Можно выбрать не более %1$d приложений.
Очистить
- - Удалить из списка %d приложение
- - Удалить из списка %d приложения
- - Удалить из списка %d приложений
- - Удалить из списка %d приложения
+ - Очистить %d приложение
+ - Очистить %d приложения
+ - Очистить %d приложений
+ - Очистить %d приложения
- - Удалить из списка %d приложение?
- - Удалить из списка %d приложения?
- - Удалить из списка %d приложений?
- - Удалить из списка %d приложения?
+ - Очистить %d приложение?
+ - Очистить %d приложения?
+ - Очистить %d приложений?
+ - Очистить %d приложения?
Длительность: %d мс
@@ -54,7 +54,7 @@
Поменять кнопки Вверх/Вниз для переключения
- Переключение трека
+ Переключение
Действие при долгом нажатии
Перемотка
Длительность перемотки: %d сек