1
0
mirror of https://github.com/algora-io/tv.git synced 2025-10-30 23:07:56 +02:00

intersperse shorts and videos on homepage

This commit is contained in:
zafer
2024-03-07 02:43:11 +03:00
parent 874526b090
commit 2934e1f2fd
3 changed files with 88 additions and 15 deletions

View File

@@ -191,6 +191,7 @@ defmodule Algora.Library do
limit: ^limit,
where:
v.visibility == :public and
is_nil(v.vertical_thumbnail_url) and
(v.is_live == true or v.duration >= 120 or v.type == :vod),
select_merge: %{channel_name: u.name}
)
@@ -198,6 +199,18 @@ defmodule Algora.Library do
|> Repo.replica().all()
end
def list_shorts(limit \\ 100) do
from(v in Video,
join: u in User,
on: v.user_id == u.id,
limit: ^limit,
where: v.visibility == :public and not is_nil(v.vertical_thumbnail_url),
select_merge: %{channel_name: u.name}
)
|> order_by_inserted(:desc)
|> Repo.replica().all()
end
def list_channel_videos(%Channel{} = channel, limit \\ 100) do
from(v in Video,
limit: ^limit,

View File

@@ -6,7 +6,6 @@ defmodule AlgoraWeb.ChannelLive do
alias AlgoraWeb.{LayoutComponent, Presence}
alias AlgoraWeb.ChannelLive.{StreamFormComponent}
@impl true
def render(assigns) do
~H"""
<%!-- <:actions>
@@ -205,7 +204,6 @@ defmodule AlgoraWeb.ChannelLive do
"""
end
@impl true
def mount(%{"channel_handle" => channel_handle}, _session, socket) do
%{current_user: current_user} = socket.assigns
@@ -239,13 +237,11 @@ defmodule AlgoraWeb.ChannelLive do
{:ok, socket}
end
@impl true
def handle_params(params, _url, socket) do
LayoutComponent.hide_modal()
{:noreply, socket |> apply_action(socket.assigns.live_action, params)}
end
@impl true
def handle_info({Presence, {:join, presence}}, socket) do
{:noreply, stream_insert(socket, :presences, presence)}
end

View File

@@ -6,29 +6,93 @@ defmodule AlgoraWeb.HomeLive do
def render(assigns) do
~H"""
<.playlist id="playlist" videos={@streams.videos} />
<div class="-mt-16 px-4">
<div :for={{shorts, videos} <- @sections}>
<div class="pt-16">
<h2 class="text-white text-xl font-semibold px-8 sr-only">
Videos
</h2>
<div class="pt-8 gap-8 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3">
<.video_entry :for={video <- videos} id={"video-#{video.id}"} video={video} />
</div>
</div>
<div class="pt-16">
<h2 class="text-white text-xl font-bold flex items-center gap-1">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-8 w-8"
width="24"
height="24"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M13 3l0 7l6 0l-8 11l0 -7l-6 0l8 -11" /></svg>Shorts
</h2>
<div class="pt-4 gap-8 grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6">
<.short_entry :for={video <- shorts} id={"short-#{video.id}"} video={video} />
</div>
</div>
</div>
<div :if={length(@leftover_videos) > 0} class="pt-16">
<h2 class="text-white text-xl font-semibold px-8 sr-only">
Videos
</h2>
<div class="pt-8 gap-8 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3">
<.video_entry :for={video <- @leftover_videos} id={"video-#{video.id}"} video={video} />
</div>
</div>
<div :if={length(@leftover_shorts) > 0} class="pt-16">
<h2 class="text-white text-xl font-bold flex items-center gap-1">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-8 w-8"
width="24"
height="24"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M13 3l0 7l6 0l-8 11l0 -7l-6 0l8 -11" /></svg>Shorts
</h2>
<div class="pt-4 gap-8 grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6">
<.short_entry :for={video <- @leftover_shorts} id={"short-#{video.id}"} video={video} />
</div>
</div>
</div>
"""
end
def mount(_map, _session, socket) do
if connected?(socket) do
Library.subscribe_to_livestreams()
end
short_sections = Library.list_shorts(150) |> Enum.chunk_every(6)
video_sections = Library.list_videos(150) |> Enum.chunk_every(6)
videos = Library.list_videos(150)
num_sections = max(min(length(short_sections), length(video_sections)) - 1, 0)
{:ok, socket |> stream(:videos, videos)}
{shorts, leftover_shorts} = short_sections |> Enum.split(num_sections)
{videos, leftover_videos} = video_sections |> Enum.split(num_sections)
sections = Enum.zip(shorts, videos)
{:ok,
socket
|> assign(sections: sections)
|> assign(leftover_videos: Enum.concat(leftover_videos))
|> assign(leftover_shorts: Enum.concat(leftover_shorts))}
end
def handle_params(params, _url, socket) do
{:noreply, socket |> apply_action(socket.assigns.live_action, params)}
end
def handle_info({Library, _}, socket), do: {:noreply, socket}
defp apply_action(socket, :show, _params) do
socket
|> assign(:page_title, nil)
|> assign(:video, nil)
socket |> assign(:page_title, nil)
end
end