Module userland.scripts.messages.filter_modal

Filter messages screen

Classes

class FilterModal (*args, tags: list[str] | None = None, **kwargs)
Expand source code
class FilterModal(ModalScreen[list[str]]):
    """Filter messages screen"""

    BINDINGS = [("escape", "app.pop_screen", "")]

    CSS = """
        FilterModal {
            align: center middle;
            background: rgba(0, 0, 0, 0.5);
        }

        Button {
            margin: 1;
            width: 33.3333%;
        }

        SelectionList {
            height: 10;
        }

        #filter {
            margin-left: 0;
            margin-top: 1;
        }

        #wrapper {
            background: $primary-background;
            height: 16;
            padding: 1;
            width: 60;
        }
    """

    _tags: list[str]

    def __init__(self, *args, tags: list[str] | None = None, **kwargs):
        super(FilterModal, self).__init__(*args, **kwargs)
        self._tags = tags or []

    def compose(self):
        with Vertical(id="wrapper"):
            yield SelectionList(id="tags")

            with Horizontal():
                yield Button("Filter", variant="success", id="filter")
                yield Button("Reset", id="reset")
                yield Button("Cancel", variant="error", id="cancel")

    def _submit(self) -> None:
        tags = self.query_one(SelectionList)
        assert tags
        self.dismiss(tags.selected)

    async def on_mount(self) -> None:
        tags = self.query_one(SelectionList)
        assert tags
        tags.add_options([Selection(t, t, True) for t in self._tags])

        async with db_session() as db:
            all_tags: Sequence[str] = (  # type: ignore
                await db.exec(
                    select(MessageTag.name).where(
                        and_(
                            col(MessageTag.name).is_not(None),
                            col(MessageTag.name).not_in(self._tags),
                        )
                    )
                )
            ).all()

        tags.add_options([Selection(t, t, False) for t in all_tags])

    def on_button_pressed(self, event: Button.Pressed) -> None:
        if event.button.id == "cancel":
            self.app.pop_screen()  # pop this modal
            return

        if event.button.id == "reset":
            self.dismiss([])
            return

        self._submit()

Filter messages screen

Initialize the screen.

Args

name
The name of the screen.
id
The ID of the screen in the DOM.
classes
The CSS classes for the screen.

Ancestors

  • textual.screen.ModalScreen
  • textual.screen.Screen
  • typing.Generic
  • textual.widget.Widget
  • textual.dom.DOMNode
  • textual.message_pump.MessagePump

Class variables

var BINDINGS
var CSS
var can_focus
var can_focus_children

Methods

def compose(self)
Expand source code
def compose(self):
    with Vertical(id="wrapper"):
        yield SelectionList(id="tags")

        with Horizontal():
            yield Button("Filter", variant="success", id="filter")
            yield Button("Reset", id="reset")
            yield Button("Cancel", variant="error", id="cancel")

Called by Textual to create child widgets.

This method is called when a widget is mounted or by setting recompose=True when calling [refresh()][textual.widget.Widget.refresh].

Note that you don't typically need to explicitly call this method.

Example

def compose(self) -> ComposeResult:
    yield Header()
    yield Label("Press the button below:")
    yield Button()
    yield Footer()
def on_button_pressed(self, event: textual.widgets._button.Button.Pressed) ‑> None
Expand source code
def on_button_pressed(self, event: Button.Pressed) -> None:
    if event.button.id == "cancel":
        self.app.pop_screen()  # pop this modal
        return

    if event.button.id == "reset":
        self.dismiss([])
        return

    self._submit()
async def on_mount(self) ‑> None
Expand source code
async def on_mount(self) -> None:
    tags = self.query_one(SelectionList)
    assert tags
    tags.add_options([Selection(t, t, True) for t in self._tags])

    async with db_session() as db:
        all_tags: Sequence[str] = (  # type: ignore
            await db.exec(
                select(MessageTag.name).where(
                    and_(
                        col(MessageTag.name).is_not(None),
                        col(MessageTag.name).not_in(self._tags),
                    )
                )
            )
        ).all()

    tags.add_options([Selection(t, t, False) for t in all_tags])