onetwothree

onetwothree

Liveview InfiniteScroll position absolute bottom value

Hey guys,

It’s default example from InfiniteScroll - only difference is that I want to have it on the bottom of the page with absolute positioning, it stops receiving callbacks as soon as I uncomment bottom: 0px; any ideas? I probably can apply proper top value in js but it seems hackish, am I missing something?

Demo

Mix.install([
  {:phoenix_playground, "~> 0.1.3"}
])

Section

defmodule DemoLive do
  use Phoenix.LiveView

  def render(assigns) do
    ~H"""
      <div id="root-container">
        <div id="scroll-root">
          <div id="scroll">
            <ul
              id="posts"
              phx-update="stream"
              phx-viewport-top={@page > 1 && "prev-page"}
              phx-viewport-bottom={!@end_of_timeline? && "next-page"}
              phx-page-loading
            >
              <li :for={{id, post} <- @streams.posts} id={id} class="mb-8">
                <div><%= post.title %></div>
              </li>
            </ul>
            <div :if={@end_of_timeline?} class="mt-5 text-[50px] text-center">
              🎉 You made it to the beginning of time 🎉
            </div>
          </div>
        </div>
      </div>    

    <style type="text/css">
      #root-container {
        position: absolute;
        height: 250px;
        width: 250px;
        # bottom: 0px;
      }
      #scroll-root {
        height: 250px;
        overflow: hidden;
      }
      #scroll {
        overflow: auto;
        height: 250px;
      }
      #posts {
        padding-bottom: 10px;
        padding-top: 10px;
      }
      body { padding: 1em; }
      span { font-family: monospace; }
    </style>
    """
  end

  def mount(_, _, socket) do
  {:ok,
   socket
   |> assign(page: 1, per_page: 20)
   |> paginate_posts(1)}
end

  defp paginate_posts(socket, new_page) when new_page >= 1 do
    %{per_page: per_page, page: cur_page} = socket.assigns
    posts = list_posts(offset: (new_page - 1) * per_page, limit: per_page)

    {posts, at, limit} =
      if new_page >= cur_page do
        {posts, -1, per_page * 3 * -1}
      else
        {Enum.reverse(posts), 0, per_page * 3}
      end

    case posts do
      [] ->
        assign(socket, end_of_timeline?: at == -1)

      [_ | _] = posts ->
        socket
        |> assign(end_of_timeline?: false)
        |> assign(:page, new_page)
        |> stream(:posts, posts, at: at, limit: limit)
    end
  end

  defp list_posts(opts) do
    offset = Keyword.fetch!(opts, :offset)
    limit = Keyword.fetch!(opts, :limit)

    if offset < 200 do
      for i <- offset..(offset + limit - 1) do
        %{id: i, title: "Post #{i}"}
      end
    else
      []
    end
  end

  def handle_event("next-page", _, socket) do
    {:noreply, paginate_posts(socket, socket.assigns.page + 1)}
  end

  def handle_event("prev-page", %{"_overran" => true}, socket) do
    {:noreply, paginate_posts(socket, 1)}
  end

  def handle_event("prev-page", _, socket) do
    if socket.assigns.page > 1 do
      {:noreply, paginate_posts(socket, socket.assigns.page - 1)}
    else
      {:noreply, socket}
    end
  end



end

PhoenixPlayground.start(live: DemoLive)

Where Next?

Popular in Questions Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 130286 1222
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement