Skip to content

Commit

Permalink
chore: use static per-screen-type audio config
Browse files Browse the repository at this point in the history
The central/motivating change here is a change to `screens-config-lib`
that removes most audio-related parameters from the per-screen configs,
since we'd like them to be the same for all screens of a given type.

This creates a `Static` struct to encode/organize "static" parameters
for each screen type — including candidate generators, refresh rate,
periodic audio readout interval, and now various other audio settings.
  • Loading branch information
digitalcora committed Oct 22, 2024
1 parent a924faa commit 0701a99
Show file tree
Hide file tree
Showing 12 changed files with 375 additions and 322 deletions.
24 changes: 12 additions & 12 deletions assets/src/components/admin/admin_tables.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -242,15 +242,6 @@ const alertsColumn = {
FormCell: FormTextarea,
};

const audioColumn = {
Header: "Audio",
accessor: buildAppParamAccessor("audio"),
mutator: buildAppParamMutator("audio"),
Cell: EditableTextarea,
disableFilters: true,
FormCell: FormTextarea,
};

const DupV2ScreensTable = (): JSX.Element => {
const columns = [
...v2Columns,
Expand Down Expand Up @@ -311,7 +302,6 @@ const GLEinkV2ScreensTable = (): JSX.Element => {
departuresColumn,
footerColumn,
alertsColumn,
audioColumn,
];

const dataFilter = ({ app_id }) => {
Expand All @@ -328,10 +318,21 @@ const BusShelterV2ScreensTable = (): JSX.Element => {

const columns = [
...v2Columns,
{
Header: "Audio Offset",
accessor: (row) => row.app_params.audio.interval_offset_seconds,
mutator: (row, value) => {
const newRow = structuredClone(row);
newRow.app_params.audio.interval_offset_seconds = value;
return newRow;
},
Cell: EditableCell,
disableFilters: true,
FormCell: FormTextCell,
},
departuresColumn,
footerColumn,
alertsColumn,
audioColumn,
{
Header: "Survey",
accessor: buildAppParamAccessor("survey"),
Expand Down Expand Up @@ -408,7 +409,6 @@ const PreFareV2ScreensTable = (): JSX.Element => {
disableFilters: true,
FormCell: FormTextarea,
},
audioColumn,
];

return <AdminTable columns={columns} dataFilter={dataFilter} />;
Expand Down
90 changes: 23 additions & 67 deletions lib/screens/v2/screen_audio_data.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@ defmodule Screens.V2.ScreenAudioData do
@moduledoc false

alias Screens.Config.Cache
alias Screens.Util
alias Screens.V2.ScreenData
alias Screens.V2.ScreenData.Parameters
alias Screens.V2.WidgetInstance
alias ScreensConfig.Screen
alias ScreensConfig.V2.{Audio, BusShelter, Busway, GlEink, PreFare}

@type screen_id :: String.t()

@spec by_screen_id(screen_id()) :: list({module(), map()}) | :error
@spec by_screen_id(screen_id()) :: list({module(), map()})
def by_screen_id(
screen_id,
get_config_fn \\ &Cache.screen/1,
Expand All @@ -20,32 +17,25 @@ defmodule Screens.V2.ScreenAudioData do
now \\ DateTime.utc_now()
) do
config = get_config_fn.(screen_id)
{:ok, now} = DateTime.shift_zone(now, "America/New_York")

case config do
%Screen{app_params: %app{}} when app not in [BusShelter, PreFare, GlEink, Busway] ->
:error

%Screen{app_params: %_app{audio: audio}} ->
if date_in_range?(audio, now) do
visual_widgets_with_audio_equivalence =
config
|> generate_layout_fn.()
|> elem(1)
|> Map.values()
|> Enum.filter(&WidgetInstance.audio_valid_candidate?/1)

audio_only_widgets =
visual_widgets_with_audio_equivalence
|> get_audio_only_instances_fn.(config)
|> Enum.filter(&WidgetInstance.audio_valid_candidate?/1)

(visual_widgets_with_audio_equivalence ++ audio_only_widgets)
|> Enum.sort_by(&WidgetInstance.audio_sort_key/1)
|> Enum.map(&{WidgetInstance.audio_view(&1), WidgetInstance.audio_serialize(&1)})
else
[]
end
if Parameters.audio_enabled?(config, now) do
visual_widgets_with_audio_equivalence =
config
|> generate_layout_fn.()
|> elem(1)
|> Map.values()
|> Enum.filter(&WidgetInstance.audio_valid_candidate?/1)

audio_only_widgets =
visual_widgets_with_audio_equivalence
|> get_audio_only_instances_fn.(config)
|> Enum.filter(&WidgetInstance.audio_valid_candidate?/1)

(visual_widgets_with_audio_equivalence ++ audio_only_widgets)
|> Enum.sort_by(&WidgetInstance.audio_sort_key/1)
|> Enum.map(&{WidgetInstance.audio_view(&1), WidgetInstance.audio_serialize(&1)})
else
[]
end
end

Expand All @@ -55,50 +45,16 @@ defmodule Screens.V2.ScreenAudioData do
get_config_fn \\ &Cache.screen/1,
now \\ DateTime.utc_now()
) do
config = get_config_fn.(screen_id)
{:ok, now} = DateTime.shift_zone(now, "America/New_York")

case config do
%Screen{app_params: %app{}} when app not in [BusShelter] ->
:error

%Screen{app_params: %_app{audio: audio}} ->
{:ok, get_volume(audio, now)}
case screen_id |> get_config_fn.() |> Parameters.audio_volume(now) do
nil -> :error
volume -> {:ok, volume}
end
end

defp get_audio_only_instances(visual_widgets_with_audio_equivalence, config) do
candidate_generator = Parameters.get_candidate_generator(config)

candidate_generator.audio_only_instances(
Parameters.candidate_generator(config).audio_only_instances(
visual_widgets_with_audio_equivalence,
config
)
end

defp get_volume(
%Audio{
daytime_start_time: daytime_start_time,
daytime_stop_time: daytime_stop_time,
daytime_volume: daytime_volume,
nighttime_volume: nighttime_volume
},
now
) do
if Util.time_in_range?(now, daytime_start_time, daytime_stop_time),
do: daytime_volume,
else: nighttime_volume
end

defp date_in_range?(
%Audio{
start_time: start_time,
stop_time: stop_time,
days_active: days_active
},
dt
) do
Date.day_of_week(dt) in days_active and
Util.time_in_range?(DateTime.to_time(dt), start_time, stop_time)
end
end
6 changes: 3 additions & 3 deletions lib/screens/v2/screen_data.ex
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ defmodule Screens.V2.ScreenData do
selected_variant = Keyword.get(opts, :generator_variant)

if Keyword.get(opts, :run_all_variants?, false) do
other_variants = List.delete([nil | @parameters.get_variants(config)], selected_variant)
other_variants = List.delete([nil | @parameters.variants(config)], selected_variant)

Enum.each(other_variants, fn variant ->
{:ok, _pid} =
Expand All @@ -87,7 +87,7 @@ defmodule Screens.V2.ScreenData do

ParallelRunSupervisor
|> Task.Supervisor.async_stream(
[nil | @parameters.get_variants(config)],
[nil | @parameters.variants(config)],
fn variant ->
{variant, config |> Layout.generate(variant) |> then_fn.(config)}
end
Expand All @@ -114,7 +114,7 @@ defmodule Screens.V2.ScreenData do
end

defp resolve_paging(layout, config),
do: Layout.resolve_paging(layout, @parameters.get_refresh_rate(config))
do: Layout.resolve_paging(layout, @parameters.refresh_rate(config))

@spec serialize(Layout.non_paged()) :: map() | nil
def serialize({layout, instance_map, paging_metadata}) do
Expand Down
2 changes: 1 addition & 1 deletion lib/screens/v2/screen_data/layout.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ defmodule Screens.V2.ScreenData.Layout do
@spec generate(Screen.t()) :: t()
@spec generate(Screen.t(), String.t() | nil) :: t()
def generate(config, variant \\ nil) do
candidate_generator = @parameters.get_candidate_generator(config, variant)
candidate_generator = @parameters.candidate_generator(config, variant)
screen_template = candidate_generator.screen_template()

config
Expand Down
Loading

0 comments on commit 0701a99

Please sign in to comment.