home-assistant / home-assistant/android

New widget type: double-button with visible state

Open
#1,013 6 comments 8 reactions 0 assignees Claimed by @mrdanielps View on GitHub
enhancement widget
Dominant language
Kotlin
Stars
3.9k
Forks
1.1k
Avg merge
1d 12h
Merged PRs (30d)
81

Description

**Is your feature request related to a problem? Please describe.**

I want to be able to do some actions very quickly:

* Turn a light on or off.
* Make a light dimmer or brighter.
* Change the volume of a media player
* etc.

The current way to do those actions is:

1. Open the Home Assistant app.
2. Wait for the splash screen to go away (the one with the white background; which kind hurts my eyes as everything else is dark on my device, but that's a different issue).
3. Wait for the Lovelace webview to load.
4. Navigate to the input I need (either a different sidebar item, and/or a different tab, and/or scroll down to the card).
5. Finally, interact with the input.

**Describe the solution you'd like**

If you notice, most actions have a duality: turn on/off, change the volume up/down, dim the light darker/lighter, make the white balance colder/warmer, roll the blinds up/down...

Thus, I propose a new widget type that contains two buttons, and an optional visible state. Look at this ASCII Art mockup with a few examples (slightly broken because unicode/emoji characters are not the same width as other characters):

```
.-------. .-------. .-------. .-----.
| ⇧ | | ⏽ | | 🔆 | | 🔊 |
| Blind | | Swtch | | Lamp | | 42% |
| ⇩ | | ⭘ | | 🔅 | | 🔉 |
'-------' '-------' '-------' '-----'
```

The widget can have either two or three interactive areas:

* The top half (or top third) will call a service (e.g. `light.turn_on`).
* The bottom half (or bottom third) will call another service (bonus points for automatically suggesting the complementary service in the UI).
* The middle third can update the visible state upon touch. That way, the user can refresh the visible state manually (similar to the current *template* widget).
* This state should be automatically updated a couple of seconds after the service was called if the other thirds were tapped.
* If this state is static (i.e. a literal string), then the middle third could be ignored, and thus the interactive area could be changed to halves instead of thirds. This can be helpful if the user prefers a very compact-size widget.

Bonus idea: I know some widgets have scrolling support (e.g. the calendar widget from your phone calendar). Thus, it's possible to detect up/down swipes in a widget. Then, instead of just tapping (which is a binary action), we could have some analog-ish interaction. The user could swipe up/down and then the amount of brightness/volume changed would be proportional to the length of the swipe. This could be implemented by repeatedly calling the up/down services for each "Y" amount of finger movement. In other words, it would behave similarly as an [incremental encoder](https://en.wikipedia.org/wiki/Incremental_encoder).

**Describe alternatives you've considered, if any**

My alternative, so far, is to have many widgets. Look at this screenshot:

![image](https://user-images.githubusercontent.com/121676/95246549-f3f1a480-0814-11eb-806e-043b56a6cdc6.png)

And the same widgets, after I rotate my device to landscape orientation:

![image](https://user-images.githubusercontent.com/121676/95247046-a6c20280-0815-11eb-9e31-5e80c37fec18.png)

There are four button widgets, plus one template widget in the middle. Five widgets in total. Their paddings were removed (a feature of the [Nova Launcher](https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher)), and they were resized to the minimum "usable" size. There are many issues with my current solution:

* Too many widgets (4+1).
* Button widgets can't have dynamic (template-based) label, forcing me to use a template widget.
* Template widgets can't have any interaction, forcing me to use button widgets.
* Tapping on buttons doesn't update the template; I have to remember to tap the template as well.
* Button widgets can't have an empty label (i.e., if the label is an empty string, there is a wasted "empty" space reserved for the label).
* The label for up/down actions is duplicated (because button widgets must have a label).

**Additional context**

Somewhat related issues:

* [#402 Feature Request: Show entity state in a widget, like a toggle switch](https://github.com/home-assistant/android/issues/402)
* [#755 Add option to set attribute value as label for entity state widget](https://github.com/home-assistant/android/issues/755)
* [#987 Editable widgets](https://github.com/home-assistant/android/issues/987) - as widgets get more complicated, we must be able to edit them.

**Further refactoring idea**

If we take a step back, this widget that I'm suggesting is a superset of the current widgets. Thus, we could imagine a future where we have only one very flexible widget type, and that type contains multiple pieces:

* If it contains only one "button" piece, then it emulates the current button widget.
* If it contains only one "template" piece, then it emulates the current template widget.
* If it contains a button piece, followed by a template piece, followed by another button piece; then it emulates the ASCII-Art mockup I described above.
* This also means we could have a 3-button widget: [volume up, mute, volume down] or [previous, play/pause, next] or [brighter, toggle, darker]
* This also means the user could have some arbitrary presets: set brightness to [100%, 75%, 50%, 25%, 1%]

So, this new flexible widget idea would be one widget to rule them all. Or almost. And I understand it takes quite some work to make it usable (specially building the UI, I know UIs are surprisingly time-consuming to build).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.