Skip to content

Commit

Permalink
feat: add fields for V2 Busway screens
Browse files Browse the repository at this point in the history
  • Loading branch information
digitalcora committed Apr 5, 2024
1 parent e92136e commit 0961f61
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 49 deletions.
23 changes: 20 additions & 3 deletions lib/config/v2/busway.ex
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
defmodule ScreensConfig.V2.Busway do
@moduledoc false
@moduledoc """
Configures "busway"-type screens.
alias ScreensConfig.V2.Departures
The representative use case is a large color screen with audio readout capability, at or near
ground level, a short distance from multiple distinct stopping locations (such as a busway and
a subway platform) which may be served by many different routes.
Can be thought of as a variant of `BusShelter` screens which drops the "flex zone" that would
normally display alerts and evergreen content, and instead uses the space for extra departures,
typically split into multiple sections.
"""

alias ScreensConfig.V2.{Departures, EvergreenContentItem}
alias ScreensConfig.V2.Header.CurrentStopName

@type t :: %__MODULE__{
departures: Departures.t(),
evergreen_content: list(EvergreenContentItem.t()),
header: CurrentStopName.t()
}

@enforce_keys [:departures, :header]
defstruct departures: nil,
evergreen_content: [],
header: nil

use ScreensConfig.Struct, children: [departures: Departures, header: CurrentStopName]
use ScreensConfig.Struct,
children: [
departures: Departures,
evergreen_content: {:list, EvergreenContentItem},
header: CurrentStopName
]
end
5 changes: 4 additions & 1 deletion lib/config/v2/departures.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
defmodule ScreensConfig.V2.Departures do
@moduledoc false
@moduledoc """
Configures the "departures" widget shared across several screen types, which displays upcoming
departures.
"""

alias ScreensConfig.V2.Departures.Section

Expand Down
21 changes: 0 additions & 21 deletions lib/config/v2/departures/filter.ex

This file was deleted.

18 changes: 0 additions & 18 deletions lib/config/v2/departures/filter/route_direction.ex

This file was deleted.

22 changes: 22 additions & 0 deletions lib/config/v2/departures/filters.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule ScreensConfig.V2.Departures.Filters do
@moduledoc """
Configures filtering for the departures displayed in a `Section`.
- `max_minutes` limits how far in the future departures are allowed to be.
- `route_directions` limits departures based on specific combinations of route and direction.
"""

alias ScreensConfig.V2.Departures.Filters.RouteDirections

@type t :: %__MODULE__{
max_minutes: non_neg_integer() | nil,
route_directions: RouteDirections.t() | nil
}

defstruct max_minutes: nil, route_directions: nil

use ScreensConfig.Struct, children: [route_directions: RouteDirections], with_default: true

defp value_from_json(_, value), do: value
defp value_to_json(_, value), do: value
end
27 changes: 27 additions & 0 deletions lib/config/v2/departures/filters/route_directions.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
defmodule ScreensConfig.V2.Departures.Filters.RouteDirections do
@moduledoc false

defmodule RouteDirection do
@moduledoc false

@type t :: %__MODULE__{direction_id: 0 | 1 | nil, route_id: String.t()}

@enforce_keys [:route_id]
defstruct direction_id: nil, route_id: nil

use ScreensConfig.Struct

defp value_from_json(_, value), do: value
defp value_to_json(_, value), do: value
end

@type t :: %__MODULE__{action: :include | :exclude, targets: list(RouteDirection.t())}

@enforce_keys [:action, :targets]
defstruct action: nil, targets: []

use ScreensConfig.Struct, children: [targets: {:list, RouteDirection}]

defp value_from_json("action", "include"), do: :include
defp value_from_json("action", "exclude"), do: :exclude
end
29 changes: 29 additions & 0 deletions lib/config/v2/departures/header.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
defmodule ScreensConfig.V2.Departures.Header do
@moduledoc """
Configures the header of a `Section`.
- `title` is the displayed title of the section.
- `arrow` is the direction of an arrow displayed in the header, for wayfinding. This uses 8-way
compass directions where "n" is towards the top of the display.
- `read_as` is how the section should be announced in audio readouts. If `nil`, defaults to the
configured `title`.
If `title` is not set, there is no visual header, but `read_as` is still read out, if set.
"""

@type t :: %__MODULE__{
arrow: nil | :n | :ne | :e | :se | :s | :sw | :w | :nw,
read_as: String.t() | nil,
title: String.t() | nil
}

defstruct [:arrow, :read_as, :title]

use ScreensConfig.Struct, with_default: true

defp value_from_json("arrow", value) when value in ~w(n ne e se s sw w nw),
do: String.to_existing_atom(value)

defp value_from_json(_, value), do: value
defp value_to_json(_, value), do: value
end
35 changes: 35 additions & 0 deletions lib/config/v2/departures/layout.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
defmodule ScreensConfig.V2.Departures.Layout do
@moduledoc """
Configures the visual layout of a `Section`.
Conceptually, sections have a `base` size, which is how many departures they should ideally
display; a `max` size, which is the most they should display if extra space allows them to
grow; and a `min` size, which is the fewest they should display if space constraints require
them to shrink. The layout algorithm will try to respect the `base` of all sections, treating
`max` and `min` as hard limits.
If `max` is not set, the section may grow to fill all available space. If `base` is not set, it
defaults to the value of `max`.
If `include_later` is set, the section includes a paging "Later Departures" component, which
shows departures that would have otherwise been dropped due to space constraints (plus as many
further-out departures as it has space for). The other fields do not "count" departures shown
here; in other words, a section with `%{base: 4, max: 6, include_later: true}` is treated as
desiring 4-6 departures that are visible at all times, and if more are available, however many
will fit in "Later Departures" in addition to that.
"""

@type t :: %__MODULE__{
base: pos_integer() | nil,
include_later: boolean(),
max: pos_integer() | nil,
min: pos_integer()
}

defstruct base: nil, include_later: false, max: nil, min: 1

use ScreensConfig.Struct, with_default: true

defp value_from_json(_, value), do: value
defp value_to_json(_, value), do: value
end
24 changes: 18 additions & 6 deletions lib/config/v2/departures/section.ex
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
defmodule ScreensConfig.V2.Departures.Section do
@moduledoc false
@moduledoc """
Configures a section within the Departures widget. Sections are a means of grouping departures
by mode, stopping location, etc. Each section can fetch and display its departures differently.
alias ScreensConfig.V2.Departures.{Filter, Headway, Query}
- `bidirectional` enables a special mode that displays exactly two departures: the first one
that would normally be displayed, and the next departure on the same route in the opposite
direction.
"""

alias ScreensConfig.V2.Departures.{Filters, Header, Headway, Layout, Query}

@type t :: %__MODULE__{
query: Query.t(),
filter: Filter.t() | nil,
filters: Filters.t(),
header: Header.t(),
headway: Headway.t(),
bidirectional: boolean() | nil
layout: Layout.t(),
bidirectional: boolean()
}

@enforce_keys [:query]
defstruct query: nil,
filter: nil,
filters: Filters.from_json(:default),
header: Header.from_json(:default),
headway: Headway.from_json(:default),
layout: Layout.from_json(:default),
bidirectional: false

use ScreensConfig.Struct, children: [query: Query, filter: Filter, headway: Headway]
use ScreensConfig.Struct,
children: [query: Query, header: Header, filters: Filters, headway: Headway]

defp value_from_json(_, value), do: value

Expand Down

0 comments on commit 0961f61

Please sign in to comment.