Skip to content

Commit

Permalink
Merge pull request #78 from felipelincoln/refactor/homepage
Browse files Browse the repository at this point in the history
Implement general feed on homepage
  • Loading branch information
felipelincoln committed Jul 10, 2021
2 parents 1b003e5 + d9ff933 commit ccd0096
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 8 deletions.
27 changes: 27 additions & 0 deletions apps/publishing/lib/publishing/manage.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,33 @@ defmodule Publishing.Manage do

import Ecto.Query

def list_articles(opts \\ []) do
start_cursor = opts[:cursor] || DateTime.utc_now()
limit = opts[:limit] || 10

articles =
Article
|> from()
|> order_by([a], desc: a.inserted_at)
|> limit(^limit)
|> where([a], a.inserted_at < ^start_cursor)
|> preload(:blog)
|> Repo.all()

case articles do
[] ->
{nil, []}

articles ->
end_cursor =
articles
|> List.last()
|> Map.get(:inserted_at)

{end_cursor, articles}
end
end

def load_blog!(username) do
db_blog =
Blog
Expand Down
28 changes: 28 additions & 0 deletions apps/publishing/test/publishing/manage_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,34 @@ defmodule Publishing.ManageTest do
assert [_, _] = blog.articles
end

test "list_articles/0 returns nil cursor and empty list" do
assert {nil, []} = Manage.list_articles()
end

test "list_articles/1 returns by default 10 latest articles" do
inserted_at = DateTime.utc_now() |> DateTime.add(-60)
_articles = Factory.insert_list(19, :article, inserted_at: inserted_at)

assert {_cursor, articles} = Manage.list_articles()
assert length(articles) == 10
end

test "list_articles/1 can set limit and cursor" do
inserted_at = DateTime.utc_now() |> DateTime.add(-60)
_articles = Factory.insert(:article, inserted_at: inserted_at)

inserted_at = DateTime.utc_now() |> DateTime.add(-30)
_articles = Factory.insert_list(2, :article, inserted_at: inserted_at)

inserted_at = DateTime.utc_now() |> DateTime.add(-5)
_articles = Factory.insert_list(2, :article, inserted_at: inserted_at)

assert {cursor, [_, _]} = Manage.list_articles(limit: 2)
assert {cursor, [_, _]} = Manage.list_articles(limit: 2, cursor: cursor)
assert {_cursor, [_]} = Manage.list_articles(limit: 2, cursor: cursor)
assert {nil, []}
end

defp raw_deleted(%{url: @valid_raw_url}, _), do: {:ok, %{status: 404}}
defp raw(%{url: @valid_raw_url}, _), do: {:ok, %{status: 200, body: @valid_body}}
defp raw(%{url: @invalid_404_raw_url}, _), do: {:ok, %{status: 404}}
Expand Down
20 changes: 20 additions & 0 deletions apps/web/assets/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@ import {Socket} from "phoenix"
import LiveSocket from "phoenix_live_view"
import Prism from "prismjs"

let scrollAt = () => {
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
let scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight
let clientHeight = document.documentElement.clientHeight

return scrollTop / (scrollHeight - clientHeight) * 100
}

let Hooks = {}

Hooks.CodeHighlight = {
mounted(){
this.handleEvent("highlightAll", () => Prism.highlightAll());
Expand All @@ -17,6 +26,17 @@ Hooks.PublishButton = {
}
}

Hooks.InfiniteScroll = {
page(){ return this.el.dataset.page },
mounted(){
window.addEventListener("scroll", e => {
if(this.page() != "last" && scrollAt() > 80){
this.pushEvent("load-more", {})
}
})
}
}

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks, params: {_csrf_token: csrfToken}})

Expand Down
1 change: 0 additions & 1 deletion apps/web/lib/web/live/blog_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ defmodule Web.BlogLive do
|> assign(:meta, meta)
|> assign(:blog, blog)
|> assign(:articles, articles)
|> push_event("highlightAll", %{})

{:ok, socket}
end
Expand Down
2 changes: 1 addition & 1 deletion apps/web/lib/web/live/blog_live.html.leex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</div>
</section>

<section phx-hook="CodeHighlight" id="content">
<section>
<%= for a <- @articles do %>
<% link = "/#{@blog.username}/#{a.id}" %>
<article>
Expand Down
34 changes: 32 additions & 2 deletions apps/web/lib/web/live/home_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ defmodule Web.HomeLive do

use Phoenix.LiveView

alias Publishing.Manage
alias Web.NewLive
alias Web.Router.Helpers, as: Routes

import Publishing.Helper, only: [format_date: 1]

@meta %{
title: "Branchpage",
description:
Expand All @@ -15,17 +18,44 @@ defmodule Web.HomeLive do

@impl true
def mount(_params, _session, socket) do
{cursor, articles} = Manage.list_articles(limit: 3)

socket =
socket
|> assign(:meta, @meta)
|> assign(:articles, articles)
|> assign(:cursor, cursor)
|> assign(:page, nil)

{:ok, socket}
{:ok, socket, temporary_assigns: [articles: []]}
end

@impl true
def handle_event("go-preview", %{"url" => url}, socket) do
path = Routes.live_path(socket, NewLive, url: url)

{:noreply, push_redirect(socket, to: path)}
{:noreply, redirect(socket, to: path)}
end

@impl true
def handle_event("load-more", _params, %{assigns: %{cursor: nil}} = socket) do
socket =
socket
|> assign(:page, "last")

{:noreply, socket}
end

def handle_event("load-more", _params, socket) do
%{assigns: %{cursor: start_cursor}} = socket

{end_cursor, articles} = Manage.list_articles(limit: 3, cursor: start_cursor)

socket =
socket
|> assign(:cursor, end_cursor)
|> assign(:articles, articles)

{:noreply, socket}
end
end
27 changes: 23 additions & 4 deletions apps/web/lib/web/live/home_live.html.leex
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,26 @@
</div>
</div>

<footer class="p-5 sm:p-8 mt-5 sm:mt-8 text-gray-400">
<a class="hover:underline" href="/">Branchpage</a>
<a class="px-8 hover:underline" href="https://github.com/felipelincoln/branchpage">GitHub</a>
</footer>
<div class="container">
<div class="nav bg-gray-100 flex items-center justify-between rounded-xl my-12">
<div>newest articles</div>
</div>

<section id="feed" phx-update="append" phx-hook="InfiniteScroll" data-page="<%= @page %>">
<%= for a <- @articles do %>
<% link = "/#{a.blog.username}/#{a.id}" %>
<article id="<%= a.id %>" class="flex mb-6">
<div class="flex-grow pr-3">
<h2 class="text-xl sm:text-xl text-black font-black"><a href="<%= link %>"><%= a.title %></a></h2>
<p class="text-gray-500"><%= a.description %></p>
<div class="text-sm text-gray-500 mt-1">
<a href="<%= "/#{a.blog.username}" %>" class="hover:underline font-bold"><%= a.blog.username %></a>
<span class="px-1">·</span>
<a href="<%= link %>"><%= format_date(a.inserted_at) %></a>
</div>
</div>
<a href="<%= link %>" class="flex-shrink-0 bg-cover bg-center" style="width: 170px; height: 170px; background-image: url(<%= a.cover %>)"> </a>
</article>
<% end %>
</section>
</div>

0 comments on commit ccd0096

Please sign in to comment.