From d3781720bdc5888bf26657856dd390db5b42e38c Mon Sep 17 00:00:00 2001 From: Jerod Santo Date: Tue, 2 Jan 2024 15:56:32 -0600 Subject: [PATCH] Simplify rendering of posts index --- assets/app/components/news_item.scss | 2 + lib/changelog/schema/factory.ex | 4 +- lib/changelog/schema/news/news_item.ex | 219 ------------------ .../controllers/post_controller.ex | 7 +- .../templates/page/index.html.eex | 2 +- .../templates/post/_item.html.eex | 65 ++++++ .../templates/post/index.html.eex | 7 +- .../controllers/post_controller_test.exs | 8 +- 8 files changed, 82 insertions(+), 232 deletions(-) create mode 100644 lib/changelog_web/templates/post/_item.html.eex diff --git a/assets/app/components/news_item.scss b/assets/app/components/news_item.scss index 2722831801..0f4ff3786a 100644 --- a/assets/app/components/news_item.scss +++ b/assets/app/components/news_item.scss @@ -103,6 +103,8 @@ .news_item--sponsor & { top: 45px; } + .page_news_item & { left: -50px; } + &-icon, img { width: $size; diff --git a/lib/changelog/schema/factory.ex b/lib/changelog/schema/factory.ex index c1498ad017..88b94b308c 100644 --- a/lib/changelog/schema/factory.ex +++ b/lib/changelog/schema/factory.ex @@ -274,11 +274,11 @@ defmodule Changelog.Factory do end def published_post_factory do - %Changelog.Post{post_factory() | published: true, published_at: hours_ago(1)} + %Changelog.Post{publishable_post_factory() | published: true, published_at: hours_ago(1)} end def scheduled_post_factory do - %Changelog.Post{post_factory() | published: true, published_at: hours_from_now(1)} + %Changelog.Post{publishable_post_factory() | published: true, published_at: hours_from_now(1)} end def sponsor_factory do diff --git a/lib/changelog/schema/news/news_item.ex b/lib/changelog/schema/news/news_item.ex index 83ed47006f..bf5c867b31 100644 --- a/lib/changelog/schema/news/news_item.ex +++ b/lib/changelog/schema/news/news_item.ex @@ -194,225 +194,6 @@ defmodule Changelog.NewsItem do |> file_changeset(attrs) end - def get_pinned_non_feed_news_items do - from(news_item in __MODULE__, - left_join: author in assoc(news_item, :author), - left_join: comments in assoc(news_item, :comments), - left_join: submitter in assoc(news_item, :submitter), - left_join: source in assoc(news_item, :source), - left_join: logger in assoc(news_item, :logger), - left_join: news_item_topics in assoc(news_item, :news_item_topics), - left_join: news_item_topics_topic in assoc(news_item_topics, :topic), - where: news_item.status == ^:published, - where: news_item.published_at <= ^Timex.now(), - where: not news_item.feed_only, - where: news_item.pinned, - order_by: [desc: :published_at, asc: news_item_topics.position], - preload: [ - author: author, - comments: comments, - submitter: submitter, - topics: news_item_topics_topic, - source: source, - logger: logger - ] - ) - |> Repo.all() - end - - def get_unpinned_non_feed_news_items(params) do - page = - from(news_item in __MODULE__, - where: news_item.status == ^:published, - where: news_item.published_at <= ^Timex.now(), - where: not news_item.feed_only, - where: not news_item.pinned, - order_by: [desc: :published_at] - ) - |> Repo.paginate(Map.put(params, :page_size, 20)) - - news_item_ids = - page - |> Map.get(:entries) - |> Enum.map(fn news_item -> - news_item.id - end) - - results = - from(news_item in __MODULE__, - left_join: author in assoc(news_item, :author), - left_join: comments in assoc(news_item, :comments), - left_join: submitter in assoc(news_item, :submitter), - left_join: source in assoc(news_item, :source), - left_join: logger in assoc(news_item, :logger), - left_join: news_item_topics in assoc(news_item, :news_item_topics), - left_join: news_item_topics_topic in assoc(news_item_topics, :topic), - where: news_item.id in ^news_item_ids, - order_by: [desc: :published_at, asc: news_item_topics.position], - preload: [ - author: author, - comments: comments, - submitter: submitter, - topics: news_item_topics_topic, - source: source, - logger: logger - ] - ) - |> Repo.all() - - {page, results} - end - - def get_post_news_items(params) do - page = - from(news_item in __MODULE__, - where: like(news_item.object_id, ^"posts:%"), - where: news_item.status == ^:published, - where: news_item.published_at <= ^Timex.now(), - where: not news_item.feed_only, - order_by: [desc: :inserted_at] - ) - |> Repo.paginate(Map.put(params, :page_size, 15)) - - news_item_ids = - page - |> Map.get(:entries) - |> Enum.map(fn news_item -> - news_item.id - end) - - results = - from(news_item in __MODULE__, - left_join: author in assoc(news_item, :author), - left_join: logger in assoc(news_item, :logger), - left_join: submitter in assoc(news_item, :submitter), - left_join: topics in assoc(news_item, :topics), - left_join: source in assoc(news_item, :source), - left_join: comments in assoc(news_item, :comments), - left_join: news_item_topics in assoc(news_item, :news_item_topics), - left_join: news_item_topics_topic in assoc(news_item_topics, :topic), - where: news_item.id in ^news_item_ids, - order_by: [desc: :inserted_at, asc: news_item_topics.position, desc: topics.id], - preload: [ - author: author, - comments: comments, - logger: logger, - submitter: submitter, - source: source, - topics: topics, - news_item_topics: {news_item_topics, topic: news_item_topics_topic} - ] - ) - |> Repo.all() - |> batch_load_objects() - - {page, results} - end - - def batch_load_objects(news_items) do - {episodes, posts} = - Enum.split_with(news_items, fn news_item -> - news_item.type == :audio - end) - - episode_ids = - episodes - |> Enum.map(fn - %{object_id: nil} -> - nil - - %{object_id: object_id} -> - [_podcast_id, episode_id] = String.split(object_id, ":") - episode_id - - _ -> - nil - end) - |> Enum.reject(fn - nil -> true - _ -> false - end) - - # Only hit the DB if there are episodes to resolve - episode_data = - if episode_ids == [] do - [] - else - from(episode in Episode.exclude_transcript(), - left_join: podcast in assoc(episode, :podcast), - left_join: episode_guests in assoc(episode, :episode_guests), - left_join: person in assoc(episode_guests, :person), - left_join: guests in assoc(episode, :guests), - left_join: hosts in assoc(episode, :hosts), - where: episode.id in ^episode_ids, - order_by: [asc: episode_guests.position], - preload: [ - podcast: podcast, - episode_guests: {episode_guests, person: person}, - guests: guests, - hosts: hosts - ] - ) - |> Repo.all() - end - - post_ids = - posts - |> Enum.map(fn - %{object_id: nil} -> - nil - - %{object_id: object_id} -> - [_, slug] = String.split(object_id, ":") - slug - - _ -> - nil - end) - - # Only hit the DB if there are posts to resolve - post_data = - if post_ids == [] do - [] - else - from(post in Post.published(), - left_join: author in assoc(post, :author), - left_join: editor in assoc(post, :editor), - left_join: post_topics in assoc(post, :post_topics), - left_join: post_topics_topic in assoc(post_topics, :topic), - left_join: topics in assoc(post, :topics), - where: post.slug in ^post_ids, - order_by: [asc: post_topics.position, asc: post_topics_topic.id], - preload: [ - author: author, - editor: editor, - post_topics: {post_topics, topic: post_topics_topic}, - topics: topics - ] - ) - |> Repo.all() - end - - news_items - |> Enum.map(fn - %{object_id: nil} = result -> - result - - %{type: :audio, object_id: object_id} = result -> - [_podcast_id, episode_id] = String.split(object_id, ":") - - object = - Enum.find(episode_data, fn episode -> Integer.to_string(episode.id) == episode_id end) - - %{result | object: object} - - result -> - [_, slug] = String.split(result.object_id, ":") - object = Enum.find(post_data, fn post -> post.slug == slug end) - %{result | object: object} - end) - end - def slug(item) do item.headline |> String.downcase() diff --git a/lib/changelog_web/controllers/post_controller.ex b/lib/changelog_web/controllers/post_controller.ex index 7248d66814..d3f924532c 100644 --- a/lib/changelog_web/controllers/post_controller.ex +++ b/lib/changelog_web/controllers/post_controller.ex @@ -4,11 +4,14 @@ defmodule ChangelogWeb.PostController do alias Changelog.{Post, NewsItem, NewsItemComment} def index(conn, params) do - {page, items} = NewsItem.get_post_news_items(params) + page = + Post.published() + |> Post.newest_first(:published_at) + |> Post.preload_all() + |> Repo.paginate(Map.put(params, :page_size, 15)) conn |> assign(:page, page) - |> assign(:items, items) |> render(:index) end diff --git a/lib/changelog_web/templates/page/index.html.eex b/lib/changelog_web/templates/page/index.html.eex index 86c703607b..7e9ea2d341 100644 --- a/lib/changelog_web/templates/page/index.html.eex +++ b/lib/changelog_web/templates/page/index.html.eex @@ -16,7 +16,7 @@ - <%= if Enum.any?(@page) do %> + <%= if Enum.any?(@page.entries) do %> <%= render_many(@page, EpisodeView, "_item.html") %>