Skip to content

Commit

Permalink
Add option to update camera & template tile when 'in view' (#4185)
Browse files Browse the repository at this point in the history
* Add option to update camera & template tile 'on view'

 - Use the tile enter callback to request an update to the tile once it enters the view. Considering that this callback exists it's probably safe to assume an update that is requested in this callback won't be throttled (at least it appears to work during testing).
 - Minor edit to the refresh interval picker to ensure strings that are more than one line look a bit nicer.

* on view -> in view
  • Loading branch information
jpelgrom authored Feb 2, 2024
1 parent 222a938 commit 98f3d7a
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ fun SettingsWearTemplateTile(
expanded = dropdownExpanded,
onDismissRequest = { dropdownExpanded = false }
) {
val options = listOf(0, 60, 2 * 60, 5 * 60, 10 * 60, 15 * 60, 30 * 60, 60 * 60, 2 * 60 * 60, 5 * 60 * 60, 10 * 60 * 60, 24 * 60 * 60)
val options = listOf(0, 1, 60, 2 * 60, 5 * 60, 10 * 60, 15 * 60, 30 * 60, 60 * 60, 2 * 60 * 60, 5 * 60 * 60, 10 * 60 * 60, 24 * 60 * 60)
for (option in options) {
DropdownMenuItem(onClick = {
onRefreshIntervalChanged(option)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import io.homeassistant.companion.android.common.R
fun intervalToString(context: Context, interval: Int): String {
return when {
interval == 0 -> context.getString(R.string.interval_manual)
interval == 1 -> context.getString(R.string.interval_in_view)
interval >= 60 * 60 -> context.resources.getQuantityString(R.plurals.interval_hours, interval / 60 / 60, interval / 60 / 60)
interval >= 60 -> context.resources.getQuantityString(R.plurals.interval_minutes, interval / 60, interval / 60)
else -> context.resources.getQuantityString(R.plurals.interval_seconds, interval, interval)
Expand Down
1 change: 1 addition & 0 deletions common/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@
<item quantity="one">%d second</item>
<item quantity="other">%d seconds</item>
</plurals>
<string name="interval_in_view">In view</string>
<string name="keep_screen_on_def">Do not lock screen when dashboard is active</string>
<string name="keep_screen_on">Keep screen on</string>
<string name="pinch_to_zoom_def">Allow pinch-to-zoom gesture to zoom app window</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.wear.compose.material.ListHeader
Expand Down Expand Up @@ -43,7 +45,8 @@ fun RefreshIntervalPickerView(
currentInterval: Int,
onSelectInterval: (Int) -> Unit
) {
val options = listOf(0, 60, 2 * 60, 5 * 60, 10 * 60, 15 * 60, 30 * 60, 60 * 60, 2 * 60 * 60, 5 * 60 * 60, 10 * 60 * 60, 24 * 60 * 60)
// Refresh interval options: never, when viewed, every x time
val options = listOf(0, 1, 60, 2 * 60, 5 * 60, 10 * 60, 15 * 60, 30 * 60, 60 * 60, 2 * 60 * 60, 5 * 60 * 60, 10 * 60 * 60, 24 * 60 * 60)
val initialIndex = options.indexOf(currentInterval)
val state = rememberPickerState(
initialNumberOfOptions = options.size,
Expand Down Expand Up @@ -76,7 +79,10 @@ fun RefreshIntervalPickerView(
fontSize = MaterialTheme.typography.displayMedium.fontSize.value.dp.toSp() // Ignore text scaling
)
},
color = wearColorScheme.primary
color = wearColorScheme.primary,
textAlign = TextAlign.Center, // In case of overflow, minimize weird layout behavior
overflow = TextOverflow.Ellipsis,
maxLines = 2
)
}
FilledIconButton(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.guava.future
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
Expand Down Expand Up @@ -70,12 +71,15 @@ class CameraTile : TileService() {
if (requestParams.currentState.lastClickableId == MODIFIER_CLICK_REFRESH) {
if (wearPrefsRepository.getWearHapticFeedback()) hapticClick(applicationContext)
}
val freshness = when {
(tileConfig?.refreshInterval != null && tileConfig.refreshInterval!! <= 1) -> 0
tileConfig?.refreshInterval != null -> tileConfig.refreshInterval!!
else -> DEFAULT_REFRESH_INTERVAL
}

Tile.Builder()
.setResourcesVersion("$TAG$tileId.${System.currentTimeMillis()}")
.setFreshnessIntervalMillis(
TimeUnit.SECONDS.toMillis(tileConfig?.refreshInterval ?: DEFAULT_REFRESH_INTERVAL)
)
.setFreshnessIntervalMillis(TimeUnit.SECONDS.toMillis(freshness))
.setTileTimeline(
if (serverManager.isRegistered()) {
timeline(
Expand Down Expand Up @@ -202,6 +206,25 @@ class CameraTile : TileService() {
}
}

override fun onTileEnterEvent(requestParams: EventBuilders.TileEnterEvent) {
serviceScope.launch {
val tileId = requestParams.tileId
val tileConfig = AppDatabase.getInstance(this@CameraTile)
.cameraTileDao()
.get(tileId)
tileConfig?.refreshInterval?.let {
if (it >= 1) {
try {
getUpdater(this@CameraTile)
.requestUpdate(io.homeassistant.companion.android.tiles.CameraTile::class.java)
} catch (e: Exception) {
Log.w(TAG, "Unable to request tile update on enter", e)
}
}
}
}
}

override fun onDestroy() {
super.onDestroy()
serviceScope.cancel()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,19 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.guava.future
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import javax.inject.Inject
import io.homeassistant.companion.android.common.R as commonR

@AndroidEntryPoint
class TemplateTile : TileService() {

companion object {
private const val TAG = "TemplateTile"
}

private val serviceJob = Job()
private val serviceScope = CoroutineScope(Dispatchers.IO + serviceJob)

Expand All @@ -59,12 +65,14 @@ class TemplateTile : TileService() {

val tileId = requestParams.tileId
val templateTileConfig = getTemplateTileConfig(tileId)
val freshness = when {
templateTileConfig.refreshInterval <= 1 -> 0
else -> templateTileConfig.refreshInterval
}

Tile.Builder()
.setResourcesVersion("1")
.setFreshnessIntervalMillis(
templateTileConfig.refreshInterval.toLong() * 1_000
)
.setFreshnessIntervalMillis(freshness.toLong() * 1_000)
.setTileTimeline(
if (serverManager.isRegistered()) {
timeline(templateTileConfig)
Expand Down Expand Up @@ -122,6 +130,20 @@ class TemplateTile : TileService() {
}
}

override fun onTileEnterEvent(requestParams: EventBuilders.TileEnterEvent) {
serviceScope.launch {
val tileId = requestParams.tileId
val templateTileConfig = getTemplateTileConfig(tileId)
if (templateTileConfig.refreshInterval >= 1) {
try {
getUpdater(this@TemplateTile).requestUpdate(TemplateTile::class.java)
} catch (e: Exception) {
Log.w(TAG, "Unable to request tile update on enter", e)
}
}
}
}

override fun onDestroy() {
super.onDestroy()
// Cleans up the coroutine
Expand Down

0 comments on commit 98f3d7a

Please sign in to comment.