home-assistant / home-assistant/android
New widget type: double-button with visible state
- 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:

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

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
Assessment
This issue has not been assessed yet.