Skip to content

Commit e923269

Browse files
authored
don't shutdown sticky LiveViews on push_navigate (#3748)
* don't shutdown sticky LiveViews on push_navigate Fixes #3612. Actually fixes #3424. * adjust test
1 parent 5d55733 commit e923269

File tree

8 files changed

+102
-8
lines changed

8 files changed

+102
-8
lines changed

assets/js/phoenix_live_view/view.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
PHX_ROOT_ID,
2525
PHX_SESSION,
2626
PHX_STATIC,
27+
PHX_STICKY,
2728
PHX_TRACK_STATIC,
2829
PHX_TRACK_UPLOADS,
2930
PHX_UPDATE,
@@ -181,6 +182,7 @@ export default class View {
181182
session: this.getSession(),
182183
static: this.getStatic(),
183184
flash: this.flash,
185+
sticky: this.el.hasAttribute(PHX_STICKY)
184186
}
185187
})
186188
}

assets/test/view_test.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -841,8 +841,8 @@ describe("View", function(){
841841
stubChannel(view)
842842

843843
expect(view.channel.params()).toEqual({
844-
"flash": undefined, "params": {"_mounts": 0, "_mount_attempts": 0, "_live_referrer": undefined},
845-
"session": "abc123", "static": null, "url": undefined, "redirect": undefined}
844+
"flash": undefined, "params": {"_mounts": 0, "_mount_attempts": 0, "_live_referer": undefined},
845+
"session": "abc123", "static": null, "url": undefined, "redirect": undefined, "sticky": false}
846846
)
847847

848848
el.innerHTML += "<link rel=\"stylesheet\" href=\"/css/app-123.css?vsn=d\" phx-track-static=\"\">"
@@ -856,12 +856,13 @@ describe("View", function(){
856856
"params": {
857857
"_mounts": 0,
858858
"_mount_attempts": 1,
859-
"_live_referrer": undefined,
859+
"_live_referer": undefined,
860860
"_track_static": [
861861
"http://localhost/css/app-123.css?vsn=d",
862862
"http://localhost/img/tracked.png",
863863
]
864-
}
864+
},
865+
"sticky": false
865866
})
866867
})
867868
})

lib/phoenix_live_view/channel.ex

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,13 @@ defmodule Phoenix.LiveView.Channel do
877877
new_state
878878
|> push_pending_events_on_redirect(new_socket)
879879
|> push_live_redirect(opts, ref)
880-
|> stop_shutdown_redirect(:live_redirect, opts)
880+
|> then(fn state ->
881+
if new_socket.sticky? do
882+
{:noreply, drop_redirect(state)}
883+
else
884+
stop_shutdown_redirect(state, :live_redirect, opts)
885+
end
886+
end)
881887

882888
{:live, :patch, %{to: _to, kind: _kind} = opts} when root_pid == self() ->
883889
{params, action} = patch_params_and_action!(new_socket, opts)
@@ -1178,7 +1184,8 @@ defmodule Phoenix.LiveView.Channel do
11781184
parent_pid: parent,
11791185
root_pid: root_pid || self(),
11801186
id: id,
1181-
router: router
1187+
router: router,
1188+
sticky?: params["sticky"]
11821189
}
11831190

11841191
{params, host_uri, action} =

lib/phoenix_live_view/socket.ex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ defmodule Phoenix.LiveView.Socket do
5656
:parent_pid,
5757
:root_pid,
5858
:assigns,
59-
:transport_pid
59+
:transport_pid,
60+
:sticky?
6061
]}
6162

6263
defstruct id: nil,
@@ -69,7 +70,8 @@ defmodule Phoenix.LiveView.Socket do
6970
private: %{live_temp: %{}},
7071
redirected: nil,
7172
host_uri: nil,
72-
transport_pid: nil
73+
transport_pid: nil,
74+
sticky?: false
7375

7476
@typedoc "Struct returned when `assigns` is not in the socket."
7577
@opaque assigns_not_in_socket :: Phoenix.LiveView.Socket.AssignsNotInSocket.t()

lib/phoenix_live_view/static.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ defmodule Phoenix.LiveView.Static do
210210
endpoint: endpoint,
211211
root_pid: if(sticky?, do: nil, else: parent.root_pid),
212212
parent_pid: if(sticky?, do: nil, else: self()),
213+
sticky?: sticky?,
213214
router: parent.router
214215
},
215216
%{
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
defmodule Phoenix.LiveViewTest.E2E.Issue3612.ALive do
2+
# https://github.com/phoenixframework/phoenix_live_view/issues/3612
3+
4+
use Phoenix.LiveView
5+
6+
def mount(_params, _session, socket) do
7+
{:ok, socket}
8+
end
9+
10+
def render(assigns) do
11+
~H"""
12+
{live_render(@socket, Phoenix.LiveViewTest.E2E.Issue3612.StickyLive,
13+
id: "sticky",
14+
sticky: true
15+
)}
16+
17+
<h1>Page A</h1>
18+
"""
19+
end
20+
end
21+
22+
defmodule Phoenix.LiveViewTest.E2E.Issue3612.BLive do
23+
use Phoenix.LiveView
24+
25+
def mount(_params, _session, socket) do
26+
{:ok, socket}
27+
end
28+
29+
def render(assigns) do
30+
~H"""
31+
{live_render(@socket, Phoenix.LiveViewTest.E2E.Issue3612.StickyLive,
32+
id: "sticky",
33+
sticky: true
34+
)}
35+
36+
<h1>Page B</h1>
37+
"""
38+
end
39+
end
40+
41+
defmodule Phoenix.LiveViewTest.E2E.Issue3612.StickyLive do
42+
use Phoenix.LiveView
43+
44+
def mount(:not_mounted_at_router, _session, socket) do
45+
{:ok, socket, layout: false}
46+
end
47+
48+
def render(assigns) do
49+
~H"""
50+
<div>
51+
<.link phx-click="navigate_to_a">Go to page A</.link>
52+
<.link phx-click="navigate_to_b">Go to page B</.link>
53+
</div>
54+
"""
55+
end
56+
57+
def handle_event("navigate_to_a", _params, socket) do
58+
{:noreply, push_navigate(socket, to: "/issues/3612/a")}
59+
end
60+
61+
def handle_event("navigate_to_b", _params, socket) do
62+
{:noreply, push_navigate(socket, to: "/issues/3612/b")}
63+
end
64+
end

test/e2e/test_helper.exs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ defmodule Phoenix.LiveViewTest.E2E.Router do
160160
live "/3496/a", Issue3496.ALive
161161
live "/3496/b", Issue3496.BLive
162162
live "/3529", Issue3529Live
163+
live "/3612/a", Issue3612.ALive
164+
live "/3612/b", Issue3612.BLive
163165
live "/3651", Issue3651Live
164166
live "/3656", Issue3656Live
165167
live "/3658", Issue3658Live

test/e2e/tests/issues/3612.spec.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const {test, expect} = require("../../test-fixtures")
2+
const {syncLV} = require("../../utils")
3+
4+
// https://github.com/phoenixframework/phoenix_live_view/issues/3612
5+
test("sticky LiveView stays connected when using push_navigate", async ({page}) => {
6+
await page.goto("/issues/3612/a")
7+
await syncLV(page)
8+
await expect(page.locator("h1")).toHaveText("Page A")
9+
await page.getByRole("link", {name: "Go to page B"}).click()
10+
await syncLV(page)
11+
await expect(page.locator("h1")).toHaveText("Page B")
12+
await page.getByRole("link", {name: "Go to page A"}).click()
13+
await syncLV(page)
14+
await expect(page.locator("h1")).toHaveText("Page A")
15+
})

0 commit comments

Comments
 (0)