Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore scroll position on reconnects #2326

Closed
josevalim opened this issue Nov 12, 2022 · 3 comments
Closed

Restore scroll position on reconnects #2326

josevalim opened this issue Nov 12, 2022 · 3 comments

Comments

@josevalim
Copy link
Member

Environment

  • Elixir version (elixir -v): v1.4.0
  • Phoenix version (mix deps): v1.6.15
  • Phoenix LiveView version (mix deps): v0.18.3
  • Operating system: macos
  • Browsers you attempted to reproduce this bug on (the more the merrier): all
  • Does the problem persist after removing "assets/node_modules" and trying again? Yes/no: Yes

Actual behavior

If the user loses connection (common when switching tabs on mobile), then it scrolls to the top of the page.

Expected behavior

We should store the scroll position before patching and restore it after patching.

If the page contents changed, then we may point to the wrong location, but I think the rare cases where the contents change, they already break the user experience anyway.

@janwillemvd
Copy link

This might be related to #2080 ?

@tcoopman
Copy link
Contributor

This would be so useful during live_reloads in development as well - not sure if this is the same or needs a new issue

@enewbury
Copy link
Contributor

enewbury commented Aug 4, 2023

Is this issue already fixed? scroll position doesn't change when I connect and reconnect using script.

Application.put_env(:sample, Example.Endpoint,
  http: [ip: {127, 0, 0, 1}, port: 5001],
  server: true,
  live_view: [signing_salt: "aaaaaaaa"],
  secret_key_base: String.duplicate("a", 64)
)

Mix.install([
  {:plug_cowboy, "~> 2.5"},
  {:jason, "~> 1.0"},
  {:phoenix, "~> 1.7.0"},
  {:phoenix_live_view, "~> 0.19.0"}
])

defmodule Example.ErrorView do
  def render(template, _), do: Phoenix.Controller.status_message_from_template(template)
end

defmodule Example.HomeLive do
  use Phoenix.LiveView, layout: {__MODULE__, :live}

  def mount(_params, _session, socket) do
    {:ok, assign(socket, :count, 0)}
  end

  defp phx_vsn, do: Application.spec(:phoenix, :vsn)
  defp lv_vsn, do: Application.spec(:phoenix_live_view, :vsn)

  def render("live.html", assigns) do
    ~H"""
    <script src={"https://cdn.jsdelivr.net/npm/phoenix@#{phx_vsn()}/priv/static/phoenix.min.js"}></script>
    <!-- <script src="http://127.0.0.1:8080/phoenix_live_view.js"></script> -->
    <script src={"https://cdn.jsdelivr.net/npm/phoenix_live_view@#{lv_vsn()}/priv/static/phoenix_live_view.min.js"}></script>
    <script>
      let liveSocket = new window.LiveView.LiveSocket("/live", window.Phoenix.Socket)
      liveSocket.connect()
    </script>
    <style>
      * { font-size: 1.1em; }
    </style>
    <%= @inner_content %>
    """
  end

  def render(assigns) do
    ~H"""
    <%= @count %>
    <button phx-click="inc">+</button>
    <button phx-click="dec">-</button>
    <%= for i <- 1..100 do %>
      <div>Item <%= i%></div>
    <% end %>
    """
  end

  def handle_event("inc", _params, socket) do
    {:noreply, assign(socket, :count, socket.assigns.count + 1)}
  end

  def handle_event("dec", _params, socket) do
    {:noreply, assign(socket, :count, socket.assigns.count - 1)}
  end
end

defmodule Example.Router do
  use Phoenix.Router
  import Phoenix.LiveView.Router

  pipeline :browser do
    plug(:accepts, ["html"])
  end

  scope "/", Example do
    pipe_through(:browser)

    live("/", HomeLive, :index)
  end
end

defmodule Example.Endpoint do
  use Phoenix.Endpoint, otp_app: :sample
  socket("/live", Phoenix.LiveView.Socket)
  plug(Example.Router)
end

{:ok, _} = Supervisor.start_link([Example.Endpoint], strategy: :one_for_one)
Process.sleep(:infinity)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants