Skip to content

Commit

Permalink
Add settings for wear haptic feedback and toast on entity selection
Browse files Browse the repository at this point in the history
  • Loading branch information
dshokouhi committed Nov 10, 2021
1 parent 4fdbe72 commit fe7760d
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 50 deletions.
Expand Up @@ -34,6 +34,10 @@ interface IntegrationRepository {

suspend fun setWearHomeFavorites(favorites: Set<String>)
suspend fun getWearHomeFavorites(): Set<String>
suspend fun setWearHapticFeedback(enabled: Boolean)
suspend fun getWearHapticFeedback(): Boolean
suspend fun setWearToastConfirmation(enabled: Boolean)
suspend fun getWearToastConfirmation(): Boolean

suspend fun getHomeAssistantVersion(): String

Expand Down
Expand Up @@ -57,6 +57,8 @@ class IntegrationRepositoryImpl @Inject constructor(

private const val PREF_CHECK_SENSOR_REGISTRATION_NEXT = "sensor_reg_last"
private const val PREF_WEAR_HOME_FAVORITES = "wear_home_favorites"
private const val PREF_WEAR_HAPTIC_FEEDBACK = "wear_haptic_feedback"
private const val PREF_WEAR_TOAST_CONFIRMATION = "wear_toast_confirmation"
private const val PREF_HA_VERSION = "ha_version"
private const val PREF_AUTOPLAY_VIDEO = "autoplay_video"
private const val PREF_FULLSCREEN_ENABLED = "fullscreen_enabled"
Expand Down Expand Up @@ -352,6 +354,22 @@ class IntegrationRepositoryImpl @Inject constructor(
return localStorage.getStringSet(PREF_WEAR_HOME_FAVORITES) ?: setOf()
}

override suspend fun setWearHapticFeedback(enabled: Boolean) {
localStorage.putBoolean(PREF_WEAR_HAPTIC_FEEDBACK, enabled)
}

override suspend fun getWearHapticFeedback(): Boolean {
return localStorage.getBoolean(PREF_WEAR_HAPTIC_FEEDBACK)
}

override suspend fun setWearToastConfirmation(enabled: Boolean) {
localStorage.putBoolean(PREF_WEAR_TOAST_CONFIRMATION, enabled)
}

override suspend fun getWearToastConfirmation(): Boolean {
return localStorage.getBoolean(PREF_WEAR_TOAST_CONFIRMATION)
}

override suspend fun getNotificationRateLimits(): RateLimitResponse {
val pushToken = localStorage.getString(PREF_PUSH_TOKEN) ?: ""
val requestBody = RateLimitRequest(pushToken)
Expand Down
Expand Up @@ -11,4 +11,9 @@ interface HomePresenter {
suspend fun getEntities(): List<Entity<*>>
suspend fun getWearHomeFavorites(): List<String>
suspend fun setWearHomeFavorites(favorites: List<String>)

suspend fun getWearHapticFeedback(): Boolean
suspend fun setWearHapticFeedback(enabled: Boolean)
suspend fun getWearToastConfirmation(): Boolean
suspend fun setWearToastConfirmation(enabled: Boolean)
}
Expand Up @@ -106,4 +106,20 @@ class HomePresenterImpl @Inject constructor(
override suspend fun setWearHomeFavorites(favorites: List<String>) {
integrationUseCase.setWearHomeFavorites(favorites.toSet())
}

override suspend fun getWearHapticFeedback(): Boolean {
return integrationUseCase.getWearHapticFeedback()
}

override suspend fun setWearHapticFeedback(enabled: Boolean) {
integrationUseCase.setWearHapticFeedback(enabled)
}

override suspend fun getWearToastConfirmation(): Boolean {
return integrationUseCase.getWearToastConfirmation()
}

override suspend fun setWearToastConfirmation(enabled: Boolean) {
integrationUseCase.setWearToastConfirmation(enabled)
}
}
@@ -1,10 +1,16 @@
package io.homeassistant.companion.android.home

import android.content.Context
import android.widget.Toast
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.ui.hapticfeedback.HapticFeedback
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import io.homeassistant.companion.android.R
import io.homeassistant.companion.android.common.data.integration.Entity
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

class MainViewModel : ViewModel() {

Expand All @@ -28,7 +34,7 @@ class MainViewModel : ViewModel() {
}
}

fun toggleEntity(entityId: String) {
fun toggleEntity(entityId: String, entityFriendlyName: String, haptic: HapticFeedback, context: Context) {
viewModelScope.launch {
homePresenter.onEntityClicked(entityId)
val updatedEntities = homePresenter.getEntities()
Expand All @@ -37,6 +43,10 @@ class MainViewModel : ViewModel() {
entities[i] = updatedEntities[i]
}
}
if (isToastEnabled())
Toast.makeText(context, context.getString(R.string.toast_message, entityFriendlyName), Toast.LENGTH_SHORT).show()
if (isHapticEnabled())
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
}

fun addFavorite(entityId: String) {
Expand All @@ -61,6 +71,21 @@ class MainViewModel : ViewModel() {
homePresenter.setWearHomeFavorites(favoriteEntityIds)
}
}
fun isHapticEnabled(): Boolean {
return runBlocking { homePresenter.getWearHapticFeedback() }
}

fun isToastEnabled(): Boolean {
return runBlocking { homePresenter.getWearToastConfirmation() }
}

fun setHapticEnabled(enabled: Boolean) {
runBlocking { homePresenter.setWearHapticFeedback(enabled) }
}

fun setToastEnabled(enabled: Boolean) {
runBlocking { homePresenter.setWearToastConfirmation(enabled) }
}

fun logout() {
homePresenter.onLogoutClicked()
Expand Down
@@ -1,11 +1,14 @@
package io.homeassistant.companion.android.home.views

import android.content.Context
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.hapticfeedback.HapticFeedback
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
Expand All @@ -24,15 +27,17 @@ import io.homeassistant.companion.android.util.setChipDefaults
@Composable
fun EntityUi(
entity: Entity<*>,
onEntityClicked: (String) -> Unit
onEntityClicked: (String, String, HapticFeedback, Context) -> Unit
) {
val haptic = LocalHapticFeedback.current
val context = LocalContext.current
val attributes = entity.attributes as Map<*, *>
val iconBitmap = getIcon(attributes["icon"] as String?, entity.entityId.split(".")[0], LocalContext.current)

if (entity.entityId.split(".")[0] in HomePresenterImpl.toggleDomains) {
ToggleChip(
checked = entity.state == "on",
onCheckedChange = { onEntityClicked(entity.entityId) },
onCheckedChange = { onEntityClicked(entity.entityId, attributes["friendly_name"].toString(), haptic, context) },
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 10.dp),
Expand Down Expand Up @@ -71,7 +76,7 @@ fun EntityUi(
)
},
enabled = entity.state != "unavailable",
onClick = { onEntityClicked(entity.entityId) },
onClick = { onEntityClicked(entity.entityId, attributes["friendly_name"].toString(), haptic, context) },
colors = setChipDefaults()
)
}
Expand Down
Expand Up @@ -7,6 +7,8 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -60,6 +62,8 @@ fun LoadHomePage(
}
} else {
val swipeDismissableNavController = rememberSwipeDismissableNavController()
val haptic = LocalHapticFeedback.current
val context = LocalContext.current
MaterialTheme {
CompositionLocalProvider(
LocalRotaryEventDispatcher provides rotaryEventDispatcher
Expand All @@ -73,7 +77,7 @@ fun LoadHomePage(
MainView(
mainViewModel.entities,
mainViewModel.favoriteEntityIds,
{ mainViewModel.toggleEntity(it) },
{ s: String, s1: String, _, _ -> mainViewModel.toggleEntity(s, s1, haptic, context) },
{ swipeDismissableNavController.navigate(SCREEN_SETTINGS) },
{ mainViewModel.logout() }
)
Expand All @@ -82,7 +86,11 @@ fun LoadHomePage(
SettingsView(
mainViewModel.favoriteEntityIds,
{ swipeDismissableNavController.navigate(SCREEN_SET_FAVORITES) },
{ mainViewModel.clearFavorites() }
{ mainViewModel.clearFavorites() },
mainViewModel.isHapticEnabled(),
mainViewModel.isToastEnabled(),
{ mainViewModel.setHapticEnabled(it) },
{ mainViewModel.setToastEnabled(it) }
)
}
composable(SCREEN_SET_FAVORITES) {
Expand Down
@@ -1,5 +1,6 @@
package io.homeassistant.companion.android.home.views

import android.content.Context
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
Expand All @@ -11,6 +12,7 @@ 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.hapticfeedback.HapticFeedback
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
Expand All @@ -32,7 +34,7 @@ import io.homeassistant.companion.android.util.setChipDefaults
fun MainView(
entities: List<Entity<*>>,
favoriteEntityIds: List<String>,
onEntityClicked: (String) -> Unit,
onEntityClicked: (String, String, HapticFeedback, Context) -> Unit,
onSettingsClicked: () -> Unit,
onLogoutClicked: () -> Unit
) {
Expand Down

0 comments on commit fe7760d

Please sign in to comment.