rharish101 / ReGreet

Clean and customizable greeter for greetd
GNU General Public License v3.0
420 stars 18 forks source link

Refactor the UI to be Elm architecture #85

Open max-ishere opened 2 months ago

max-ishere commented 2 months ago

Here are the changes I propose:

  1. Break up the widgets into separate structs. Right now all the widgets are this one giant widget template. Instead, if you take a look at the current UI there's:
    - background
    - clock widget
    - reboot buttons
    - login form:
     - welcome message
     - either:
       session selection:
         - user field
         - session field
         - goto auth button
       auth:
         - selected user (const)
         - why no selected session? (const)
         - password field
         - auth button

    And some of these components are the same thing, just different labels, So there's not gonna be a separate type for each element.

  2. Encode the state (session/auth screen, selected users) as a data structure and use it to render the ui.
  3. Move the business logic (greetd interface) into a trait and instead of doing if demo { Make a DemoGreeter. Btw this demo greeter can respond with "Demo mode password: pass".

And this way the UI can be tested too by simply setting up the UI state struct, running the update() method and asserting the updated ui state.


I can do the refactoring work and PR it in as small of increments as is managable for review. The steps would probably be as such (not sure about the order):

max-ishere commented 2 months ago

Okie... I have made a widget that replicates (good enough) the behavior of the user/session input widget. It works like this: you give it options and initial state (which can even be the freeform manual input thing) and it sends Output messages with what the user has typed/clicked from list. The widget works by itself, but I anticipate it being a challange to integrate into the current app.

max-ishere commented 2 months ago

These are the images of the most bare bones implementation that I made, you can see there's no styling, gaps, the toggle button is in the wrong state, it will be more polished in the PR.

This window has a box: left: input widget, right: what the root thinks the widget state is (text after the toggle button).

The input widget can be customized: label text, manual input placeholder (gray text) and the list of options, initial state.

It emits events with what is selected, either index of the current option in the list (number) or the string in the text field, whichever the user sees.

initial widget state in text input mode, text: GNU Emacs first item selected: Sway edited input: Cage

max-ishere commented 2 months ago

I think this will make the code a little cleaner and easier to work with