neiam
/apollos_crib
It's Apollo's Crib
public · Issues · Pulls 1 · Labels · Forks · Compare · Actions failure · Badges · Packages
Log in to mark this repository.
Follow a tint, and show what a Plani is actually asking
951c85d · Gabriel Morell · 2026-09-03 17:38
Message
{commit_body(@commit)}
Files changed
modified
?
+0
−0
Binary file — not rendered.
modified
?
+0
−0
Binary file — not rendered.
modified
apps/room_sanctum/lib/room_sanctum/configuration/plani.ex
+39
−0
| 28 | 28 | |
| 29 | 29 | # What to look for around the anchor. |
| 30 | 30 | field :sources, {:array, :integer}, default: [] |
| 31 | + | |
| 32 | + # Instead of, or as well as, naming them: every source carrying this tint. | |
| 33 | + # A source tinted later joins without the Plani being edited, which is | |
| 34 | + # what makes this a shortcut rather than a bulk select. | |
| 35 | + field :follow_tint, :string | |
| 31 | 36 | field :radius, :integer, default: 800 |
| 32 | 37 | field :limit, :integer, default: 5 |
| 33 | 38 |
| 44 | 49 | :ankyra_id, |
| 45 | 50 | :client_id, |
| 46 | 51 | :sources, |
| 52 | + :follow_tint, | |
| 47 | 53 | :radius, |
| 48 | 54 | :limit |
| 49 | 55 | ]) |
| 52 | 58 | # couple of kilometres this stops meaning "near me". |
| 53 | 59 | |> validate_number(:radius, greater_than_or_equal_to: 50, less_than_or_equal_to: 3000) |
| 54 | 60 | |> validate_number(:limit, greater_than_or_equal_to: 1, less_than_or_equal_to: 20) |
| 61 | + |> validate_tint() | |
| 55 | 62 | |> foreign_key_constraint(:user_id) |
| 56 | 63 | |> foreign_key_constraint(:home_foci_id) |
| 57 | 64 | end |
| 65 | + | |
| 66 | + # A tint that is not one of the offered colours renders as an unstyled dot | |
| 67 | + # rather than failing, which is the kind of wrong that goes unnoticed. | |
| 68 | + defp validate_tint(changeset) do | |
| 69 | + validate_change(changeset, :follow_tint, fn :follow_tint, tint -> | |
| 70 | + if tint in [nil, ""] or RoomSanctum.Tints.valid?(tint) do | |
| 71 | + [] | |
| 72 | + else | |
| 73 | + [follow_tint: "is not a tint"] | |
| 74 | + end | |
| 75 | + end) | |
| 76 | + end | |
| 77 | + | |
| 78 | + @doc """ | |
| 79 | + Every source this Plani asks: the ones it names, and the ones wearing its | |
| 80 | + tint. | |
| 81 | + | |
| 82 | + A union rather than a choice, so following a tint can be a shortcut to most | |
| 83 | + of a list with one or two named on top of it. | |
| 84 | + """ | |
| 85 | + def sources_for(%__MODULE__{} = plani, all_sources) do | |
| 86 | + tinted = | |
| 87 | + case plani.follow_tint do | |
| 88 | + nil -> [] | |
| 89 | + "" -> [] | |
| 90 | + tint -> all_sources |> Enum.filter(&(tint_of(&1) == tint)) |> Enum.map(& &1.id) | |
| 91 | + end | |
| 92 | + | |
| 93 | + (plani.sources ++ tinted) |> Enum.uniq() | |
| 94 | + end | |
| 95 | + | |
| 96 | + defp tint_of(source), do: source.meta && Map.get(source.meta, :tint) | |
| 58 | 97 | end |
modified
apps/room_sanctum/lib/room_sanctum/workers/plani_worker.ex
+10
−1
| 103 | 103 | def handle_cast(:query, state) do |
| 104 | 104 | {anchor, anchored_to} = anchor(state.plani) |
| 105 | 105 | |
| 106 | + # Resolved on every tick rather than held: a source tinted since the last | |
| 107 | + # one should join without the Plani being edited, which is the whole point | |
| 108 | + # of following a tint. | |
| 109 | + sources = | |
| 110 | + RoomSanctum.Configuration.Plani.sources_for( | |
| 111 | + state.plani, | |
| 112 | + Configuration.list_cfg_sources({:user, state.plani.user_id}) | |
| 113 | + ) | |
| 114 | + | |
| 106 | 115 | {data, queries} = |
| 107 | − state.plani.sources | |
| 116 | + sources | |
| 108 | 117 | |> Enum.reduce({%{}, []}, fn source_id, {data, queries} -> |
| 109 | 118 | case ask(source_id, anchor, state.plani) do |
| 110 | 119 | nil -> |
modified
apps/room_sanctum/lib/room_sanctum/workers/pythiae_worker.ex
+16
−10
| 122 | 122 | handle_cast(:refresh_db_cfg, state) |
| 123 | 123 | end |
| 124 | 124 | |
| 125 | − # What this Pythiae is showing: a Plani, or a vision. | |
| 126 | − # | |
| 127 | − # Exclusive, and the Plani wins. A Pythiae pointed at a Plani is asking what | |
| 128 | − # is near its client; reading its vision as well would answer the same | |
| 129 | − # question from a fixed place and publish both. | |
| 130 | − # | |
| 131 | − # Both workers hand back the same shape, so nothing past this point -- the | |
| 132 | − # condensers, Ankyra, any client -- can tell which it was. | |
| 133 | − defp showing(%{curr_plani: plani_id}) when not is_nil(plani_id) do | |
| 125 | + @doc """ | |
| 126 | + What this Pythiae is showing: a Plani, or a vision. | |
| 127 | + | |
| 128 | + Exclusive, and the Plani wins. A Pythiae pointed at a Plani is asking what | |
| 129 | + is near its client; reading its vision as well would answer the same | |
| 130 | + question from a fixed place and publish both. | |
| 131 | + | |
| 132 | + Both workers hand back the same shape, so nothing past this point -- the | |
| 133 | + condensers, Ankyra, any client -- can tell which it was. | |
| 134 | + | |
| 135 | + Public because the rule has two readers: this worker, which publishes, and | |
| 136 | + the config page's preview, which should show what is about to be published | |
| 137 | + rather than what would have been. | |
| 138 | + """ | |
| 139 | + def showing(%{curr_plani: plani_id}) when not is_nil(plani_id) do | |
| 134 | 140 | RoomSanctum.Worker.Plani.get_state(plani_id) |
| 135 | 141 | end |
| 136 | 142 | |
| 137 | − defp showing(pythiae) do | |
| 143 | + def showing(pythiae) do | |
| 138 | 144 | RoomSanctum.Worker.Vision.get_state(pythiae.curr_vision) |
| 139 | 145 | end |
| 140 | 146 |
modified
apps/room_sanctum/lib/room_sanctum_web/components/layouts/_action_menu.html.heex
+1
−0
Click to load diff…
modified
apps/room_sanctum/lib/room_sanctum_web/live/cfg_plani_live/form_component.ex
+74
−10
Click to load diff…
modified
apps/room_sanctum/lib/room_sanctum_web/live/cfg_plani_live/show.ex
+12
−1
Click to load diff…
modified
apps/room_sanctum/lib/room_sanctum_web/live/cfg_plani_live/show.html.heex
+24
−10
Click to load diff…
modified
apps/room_sanctum/lib/room_sanctum_web/live/cfg_pythiae_live/show.ex
+3
−1
Click to load diff…
added
apps/room_sanctum/priv/repo/migrations/20260903150000_add_follow_tint_to_plani.exs
+18
−0
Click to load diff…
modified
apps/room_sanctum/test/room_sanctum_web/live/plani_live_test.exs
+41
−3
Click to load diff…
Parents: cf1bcf1