Skip to content

Commit

Permalink
Add vibration off switch (#963)
Browse files Browse the repository at this point in the history
**Background**

Right now we have request for off vibration in app

**Changes**

Add vibration off toggle

**Test plan**

Try toggle it and check vibration state
  • Loading branch information
LionZXY authored Oct 8, 2024
1 parent 18a214e commit 800cd24
Show file tree
Hide file tree
Showing 21 changed files with 129 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Attention: don't forget to add the flag for F-Droid before release
- [Feature] Add new icons for remote-controls
- [Feature] Add experimental option to enable remote controls
- [Feature] Better information during synchronization
- [Feature] Add vibration off switch
- [Feature] New File Manager listing and uploading
- [Refactor] Load RemoteControls from flipper, emulating animation
- [Refactor] Update to Kotlin 2.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator

fun Vibrator.vibrateCompat(milliseconds: Long) {
fun Vibrator.vibrateCompat(milliseconds: Long, ignoreVibration: Boolean) {
if (ignoreVibration) {
return
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrate(
VibrationEffect.createOneShot(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,5 @@ message Settings {
FileManagerOrientation file_manager_orientation = 30;
FileManagerSort file_manager_sort = 31;
bool show_hidden_files_on_flipper = 32;
bool disabled_vibration = 33;
}
1 change: 1 addition & 0 deletions components/infrared/editor/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies {
implementation(projects.components.core.di)
implementation(projects.components.core.ktx)
implementation(projects.components.core.log)
implementation(projects.components.core.preference)
implementation(projects.components.core.ui.decompose)
implementation(projects.components.core.ui.theme)
implementation(projects.components.core.ui.tabswitch)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.flipperdevices.infrared.editor.viewmodel
import android.content.Context
import android.os.Vibrator
import androidx.core.content.ContextCompat
import androidx.datastore.core.DataStore
import com.flipperdevices.bridge.api.utils.FlipperSymbolFilter
import com.flipperdevices.bridge.dao.api.delegates.key.SimpleKeyApi
import com.flipperdevices.bridge.dao.api.delegates.key.UpdateKeyApi
Expand All @@ -13,6 +14,7 @@ import com.flipperdevices.bridge.synchronization.api.SynchronizationApi
import com.flipperdevices.core.ktx.android.vibrateCompat
import com.flipperdevices.core.log.LogTagProvider
import com.flipperdevices.core.log.info
import com.flipperdevices.core.preference.pb.Settings
import com.flipperdevices.core.ui.lifecycle.DecomposeViewModel
import com.flipperdevices.infrared.editor.R
import com.flipperdevices.infrared.editor.core.model.InfraredRemote
Expand All @@ -28,6 +30,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import java.nio.charset.Charset

Expand All @@ -40,7 +43,8 @@ class InfraredEditorViewModel @AssistedInject constructor(
private val simpleKeyApi: SimpleKeyApi,
private val updateKeyApi: UpdateKeyApi,
private val synchronizationApi: SynchronizationApi,
context: Context
context: Context,
private val settings: DataStore<Settings>
) : DecomposeViewModel(), LogTagProvider {
override val TAG: String = "InfraredEditorViewModel"

Expand Down Expand Up @@ -105,7 +109,10 @@ class InfraredEditorViewModel @AssistedInject constructor(
info { "Errors remote: $errorRemotes count ${errorRemotes.size}" }

if (errorRemotes.isNotEmpty()) {
vibrator?.vibrateCompat(VIBRATOR_TIME_MS)
vibrator?.vibrateCompat(
VIBRATOR_TIME_MS,
settings.data.first().disabled_vibration
)
keyStateFlow.emit(
InfraredEditorState.Ready(
remotes = currentState.remotes,
Expand Down Expand Up @@ -199,7 +206,10 @@ class InfraredEditorViewModel @AssistedInject constructor(
var value = FlipperSymbolFilter.filterUnacceptableSymbol(source)
if (value.length > MAX_SIZE_REMOTE_LENGTH) {
value = value.substring(0, MAX_SIZE_REMOTE_LENGTH)
vibrator?.vibrateCompat(VIBRATOR_TIME_MS)
vibrator?.vibrateCompat(
VIBRATOR_TIME_MS,
runBlocking { settings.data.first().disabled_vibration }
)
}
viewModelScope.launch {
val remotes = currentState.remotes.toMutableList()
Expand Down
1 change: 1 addition & 0 deletions components/keyedit/impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ dependencies {
implementation(projects.components.core.ktx)
implementation(projects.components.core.log)
implementation(projects.components.core.storage)
implementation(projects.components.core.preference)
implementation(projects.components.core.ui.res)
implementation(projects.components.core.ui.ktx)
implementation(projects.components.core.ui.theme)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package com.flipperdevices.keyedit.impl.viewmodel
import android.content.Context
import android.os.Vibrator
import androidx.core.content.ContextCompat
import androidx.datastore.core.DataStore
import com.flipperdevices.bridge.api.utils.FlipperSymbolFilter
import com.flipperdevices.bridge.dao.api.model.FlipperKey
import com.flipperdevices.core.ktx.android.vibrateCompat
import com.flipperdevices.core.log.LogTagProvider
import com.flipperdevices.core.log.error
import com.flipperdevices.core.log.wtf
import com.flipperdevices.core.preference.pb.Settings
import com.flipperdevices.core.ui.lifecycle.DecomposeViewModel
import com.flipperdevices.keyedit.impl.model.EditableKey
import com.flipperdevices.keyedit.impl.model.KeyEditState
Expand All @@ -18,22 +20,25 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.flow.updateAndGet
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

private const val VIBRATOR_TIME_MS = 500L

class KeyEditViewModel @AssistedInject constructor(
context: Context,
@Assisted private val editableKey: EditableKey,
private val existedKeyProcessor: EditableKeyProcessor<EditableKey.Existed>,
private val limbKeyProcessor: EditableKeyProcessor<EditableKey.Limb>
private val limbKeyProcessor: EditableKeyProcessor<EditableKey.Limb>,
private val settings: DataStore<Settings>
) : DecomposeViewModel(), LogTagProvider {
override val TAG = "KeyEditViewModel"

private val vibrator = ContextCompat.getSystemService(context, Vibrator::class.java)
private val lengthFilter = LengthFilter(context)
private val lengthFilter = LengthFilter(context, settings)

private val keyEditState = MutableStateFlow<KeyEditState>(KeyEditState.Loading)

Expand All @@ -58,7 +63,10 @@ class KeyEditViewModel @AssistedInject constructor(

if (filteredName.length != newName.length) {
// String contains forbidden characters
vibrator?.vibrateCompat(VIBRATOR_TIME_MS)
vibrator?.vibrateCompat(
VIBRATOR_TIME_MS,
runBlocking { settings.data.first().disabled_vibration }
)
}

lengthFilter.nameLengthFilter(filteredName) { limitedName ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ package com.flipperdevices.keyedit.impl.viewmodel
import android.content.Context
import android.os.Vibrator
import androidx.core.content.ContextCompat
import androidx.datastore.core.DataStore
import com.flipperdevices.core.ktx.android.vibrateCompat
import com.flipperdevices.core.preference.pb.Settings
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking

private const val MAX_NAME_LENGTH = 21
private const val MAX_NOTE_LENGTH = 1024
private const val VIBRATOR_TIME_MS = 500L

class LengthFilter(context: Context) {
class LengthFilter(
context: Context,
private val dataStoreSettings: DataStore<Settings>,
) {
private val vibrator = ContextCompat.getSystemService(context, Vibrator::class.java)

fun nameLengthFilter(name: String, result: (String) -> Unit) {
Expand All @@ -20,11 +27,18 @@ class LengthFilter(context: Context) {
maxLengthFilter(note, MAX_NOTE_LENGTH, result)
}

private fun maxLengthFilter(source: String, maxLength: Int, result: (String) -> Unit) {
private fun maxLengthFilter(
source: String,
maxLength: Int,
result: (String) -> Unit
) {
var newLine = source
if (source.length > maxLength) {
newLine = newLine.substring(0, maxLength)
vibrator?.vibrateCompat(VIBRATOR_TIME_MS)
vibrator?.vibrateCompat(
VIBRATOR_TIME_MS,
runBlocking { dataStoreSettings.data.first().disabled_vibration }
)
}

result(newLine)
Expand Down
1 change: 1 addition & 0 deletions components/keyemulate/impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dependencies {
implementation(projects.components.core.log)
implementation(projects.components.core.ktx)
implementation(projects.components.core.data)
implementation(projects.components.core.preference)
implementation(projects.components.core.ui.res)
implementation(projects.components.core.ui.ktx)
implementation(projects.components.core.ui.theme)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.flipperdevices.keyemulate.viewmodel

import android.os.Vibrator
import androidx.core.content.ContextCompat
import androidx.datastore.core.DataStore
import com.flipperdevices.bridge.api.manager.ktx.state.ConnectionState
import com.flipperdevices.bridge.api.manager.ktx.state.FlipperSupportedState
import com.flipperdevices.bridge.api.utils.Constants.API_SUPPORTED_REMOTE_EMULATE
Expand All @@ -14,6 +15,7 @@ import com.flipperdevices.core.ktx.android.vibrateCompat
import com.flipperdevices.core.log.LogTagProvider
import com.flipperdevices.core.log.error
import com.flipperdevices.core.log.info
import com.flipperdevices.core.preference.pb.Settings
import com.flipperdevices.core.ui.lifecycle.DecomposeViewModel
import com.flipperdevices.keyemulate.api.EmulateHelper
import com.flipperdevices.keyemulate.exception.AlreadyOpenedAppException
Expand All @@ -29,10 +31,12 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import android.app.Application as FlipperApp

const val VIBRATOR_TIME = 100L
Expand All @@ -42,7 +46,8 @@ abstract class EmulateViewModel(
private val emulateHelper: EmulateHelper,
private val synchronizationApi: SynchronizationApi,
private val closeEmulateAppTaskHolder: CloseEmulateAppTaskHolder,
application: FlipperApp
application: FlipperApp,
private val settings: DataStore<Settings>
) : DecomposeViewModel(), LogTagProvider, FlipperBleServiceConsumer {

protected val emulateButtonStateFlow =
Expand All @@ -60,7 +65,10 @@ abstract class EmulateViewModel(
config: EmulateConfig
) {
info { "#onStartEmulate" }
vibrator?.vibrateCompat(VIBRATOR_TIME)
vibrator?.vibrateCompat(
VIBRATOR_TIME,
runBlocking { settings.data.first().disabled_vibration }
)

emulateButtonStateFlow.update {
when (it) {
Expand All @@ -70,6 +78,7 @@ abstract class EmulateViewModel(
progress = EmulateProgress.Infinite,
config = config
)

is EmulateButtonState.Active -> return
}
}
Expand Down Expand Up @@ -126,7 +135,10 @@ abstract class EmulateViewModel(
}
}
}
vibrator?.vibrateCompat(VIBRATOR_TIME)
vibrator?.vibrateCompat(
VIBRATOR_TIME,
runBlocking { settings.data.first().disabled_vibration }
)
}

fun closeDialog() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.flipperdevices.keyemulate.viewmodel

import android.app.Application
import androidx.datastore.core.DataStore
import com.flipperdevices.bridge.dao.api.model.FlipperKeyType
import com.flipperdevices.bridge.service.api.FlipperServiceApi
import com.flipperdevices.bridge.service.api.provider.FlipperServiceProvider
import com.flipperdevices.bridge.synchronization.api.SynchronizationApi
import com.flipperdevices.core.ktx.android.vibrateCompat
import com.flipperdevices.core.log.error
import com.flipperdevices.core.log.info
import com.flipperdevices.core.preference.pb.Settings
import com.flipperdevices.keyemulate.api.EmulateHelper
import com.flipperdevices.keyemulate.exception.AlreadyOpenedAppException
import com.flipperdevices.keyemulate.exception.ForbiddenFrequencyException
Expand All @@ -20,20 +22,23 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import javax.inject.Inject

class InfraredViewModel @Inject constructor(
private val serviceProvider: FlipperServiceProvider,
private val emulateHelper: EmulateHelper,
synchronizationApi: SynchronizationApi,
closeEmulateAppTaskHolder: CloseEmulateAppTaskHolder,
application: Application
application: Application,
private val settings: DataStore<Settings>
) : EmulateViewModel(
serviceProvider,
emulateHelper,
synchronizationApi,
closeEmulateAppTaskHolder,
application
application,
settings
) {
override val TAG = "InfraredViewModel"

Expand All @@ -56,7 +61,10 @@ class InfraredViewModel @Inject constructor(

fun onSinglePress(config: EmulateConfig) {
info { "#onSinglePress $config" }
vibrator?.vibrateCompat(VIBRATOR_TIME)
vibrator?.vibrateCompat(
VIBRATOR_TIME,
runBlocking { settings.data.first().disabled_vibration }
)
if (config.keyType != FlipperKeyType.INFRARED) {
return
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.flipperdevices.keyemulate.viewmodel

import android.app.Application
import androidx.datastore.core.DataStore
import com.flipperdevices.bridge.service.api.provider.FlipperServiceProvider
import com.flipperdevices.bridge.synchronization.api.SynchronizationApi
import com.flipperdevices.core.preference.pb.Settings
import com.flipperdevices.keyemulate.api.EmulateHelper
import com.flipperdevices.keyemulate.tasks.CloseEmulateAppTaskHolder
import javax.inject.Inject
Expand All @@ -13,12 +15,14 @@ class SimpleEmulateViewModel @Inject constructor(
synchronizationApi: SynchronizationApi,
closeEmulateAppTaskHolder: CloseEmulateAppTaskHolder,
application: Application,
settings: DataStore<Settings>
) : EmulateViewModel(
serviceProvider,
emulateHelper,
synchronizationApi,
closeEmulateAppTaskHolder,
application
application,
settings
) {
override val TAG = "SimpleEmulateViewModel"
}
Loading

0 comments on commit 800cd24

Please sign in to comment.