Skip to content

Commit

Permalink
Refactor before adding new functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Sep 20, 2023
1 parent 87dc84f commit d587dc1
Showing 1 changed file with 70 additions and 25 deletions.
95 changes: 70 additions & 25 deletions lib/phoenix_live_view/diff.ex
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ defmodule Phoenix.LiveView.Diff do
render_component(csocket, component, id, cid, false, %{}, cids, %{}, components)

{cdiffs, components} =
render_pending_components(socket, pending, %{}, cids, cdiffs, components)
render_pending_components(socket, pending, cids, cdiffs, components)

{diff, cdiffs} = extract_events({diff, cdiffs})
{Map.put(diff, @components, cdiffs), components, extra}
Expand Down Expand Up @@ -627,40 +627,85 @@ defmodule Phoenix.LiveView.Diff do

{{pending, diffs, components}, seen_ids} =
Enum.reduce(pending, acc, fn {component, entries}, acc ->
{{pending, diffs, components}, seen_ids} = acc
# TODO: Check for update_many? instead
update_many? = false
entries = maybe_preload_components(component, Enum.reverse(entries))

Enum.reduce(entries, acc, fn {cid, id, new?, new_assigns}, {triplet, seen_ids} ->
{pending, diffs, components} = triplet
{assigns_sockets, metadata, components, seen_ids} =
Enum.reduce(entries, {[], [], components, seen_ids}, fn
{cid, id, new?, new_assigns}, {assigns_sockets, metadata, components, seen_ids} ->
if Map.has_key?(seen_ids, [component | id]) do
raise "found duplicate ID #{inspect(id)} " <>
"for component #{inspect(component)} when rendering template"
end

if Map.has_key?(seen_ids, [component | id]) do
raise "found duplicate ID #{inspect(id)} " <>
"for component #{inspect(component)} when rendering template"
end
{socket, components} =
case cids do
%{^cid => {_component, _id, assigns, private, prints}} ->
private = Map.delete(private, @marked_for_deletion)
{configure_socket_for_component(socket, assigns, private, prints), components}

%{} ->
myself_assigns = %{myself: %Phoenix.LiveComponent.CID{cid: cid}}

{mount_component(socket, component, myself_assigns),
put_cid(components, component, id, cid)}
end

assigns_sockets =
if update_many? do
[{new_assigns, socket} | assigns_sockets]
else
[Utils.maybe_call_update!(socket, component, new_assigns) | assigns_sockets]
end

metadata = [{cid, id, new?} | metadata]
seen_ids = Map.put(seen_ids, [component | id], true)
{assigns_sockets, metadata, components, seen_ids}
end)

{socket, components} =
case cids do
%{^cid => {_component, _id, assigns, private, prints}} ->
private = Map.delete(private, @marked_for_deletion)
{configure_socket_for_component(socket, assigns, private, prints), components}
sockets =
if update_many? do
component.update_many(assigns_sockets)
else
assigns_sockets
end

%{} ->
myself_assigns = %{myself: %Phoenix.LiveComponent.CID{cid: cid}}
triplet =
zip_components(
Enum.reverse(sockets),
Enum.reverse(metadata),
component,
cids,
{pending, diffs, components}
)

{mount_component(socket, component, myself_assigns),
put_cid(components, component, id, cid)}
end
{triplet, seen_ids}
end)

socket = Utils.maybe_call_update!(socket, component, new_assigns)
diffs = maybe_put_events(diffs, socket)
render_pending_components(socket, pending, seen_ids, cids, diffs, components)
end

triplet =
render_component(socket, component, id, cid, new?, pending, cids, diffs, components)
defp zip_components(
[%{__struct__: Phoenix.LiveView.Socket} = socket | sockets],
[{cid, id, new?} | metadata],
component,
cids,
{pending, diffs, components}
) do
diffs = maybe_put_events(diffs, socket)
acc = render_component(socket, component, id, cid, new?, pending, cids, diffs, components)
zip_components(sockets, metadata, component, cids, acc)
end

{triplet, Map.put(seen_ids, [component | id], true)}
end)
end)
defp zip_components([], [], _component, _cids, acc) do
acc
end

render_pending_components(socket, pending, seen_ids, cids, diffs, components)
defp zip_components(_sockets, _metadata, component, _cids, _acc) do
raise "#{inspect(component)}.update_many/1 must return a list of Phoenix.LiveView.Socket " <>
"of the same length as the input list, got mismatched return type"
end

defp maybe_preload_components(component, entries) do
Expand Down

0 comments on commit d587dc1

Please sign in to comment.