diff --git a/lib/changelog/files/cover.ex b/lib/changelog/files/cover.ex index a5ffbe0b72..742d70d9bc 100644 --- a/lib/changelog/files/cover.ex +++ b/lib/changelog/files/cover.ex @@ -1,14 +1,18 @@ defmodule Changelog.Files.Cover do use Changelog.File, [:jpg, :png] - alias Changelog.Podcast + alias Changelog.{Episode, Podcast} alias ChangelogWeb.PodcastView @versions [:original, :medium, :small] def storage_dir(_, _), do: "uploads/covers" - def filename(version, {_, %{name: _} = scope}) do + def filename(version, {_file, %Episode{} = scope}) do + "episode-#{scope.id}-#{version}" + end + + def filename(version, {_file, %Podcast{} = scope}) do name = if Podcast.is_interviews(scope) do "changelog-interviews" else diff --git a/lib/changelog/kits/mp3_kit.ex b/lib/changelog/kits/mp3_kit.ex index 0e9dca51e3..b18ae106ee 100644 --- a/lib/changelog/kits/mp3_kit.ex +++ b/lib/changelog/kits/mp3_kit.ex @@ -1,6 +1,6 @@ defmodule Changelog.Mp3Kit do alias Changelog.{FileKit, UrlKit} - alias ChangelogWeb.{PodcastView} + alias ChangelogWeb.{EpisodeView} alias Id3vx.Tag @text_frames %{ @@ -16,8 +16,8 @@ defmodule Changelog.Mp3Kit do } def tag(file_path, episode, chapters) do - cover_path = PodcastView.cover_path(episode.podcast, :original) - cover_file = UrlKit.get_tempfile(cover_path) + cover_url = EpisodeView.cover_url(episode.podcast, :original) + cover_file = UrlKit.get_tempfile(cover_url) tagged_file_path = file_path <> "-tagged" new_tag = diff --git a/lib/changelog/schema/episode/episode.ex b/lib/changelog/schema/episode/episode.ex index 8f64d2195d..4c6e75a13f 100644 --- a/lib/changelog/schema/episode/episode.ex +++ b/lib/changelog/schema/episode/episode.ex @@ -46,6 +46,8 @@ defmodule Changelog.Episode do field :recorded_live, :boolean, default: false field :youtube_id, :string + field :cover, Files.Cover.Type + field :audio_file, Files.Audio.Type field :audio_bytes, :integer field :audio_duration, :integer @@ -209,7 +211,7 @@ defmodule Changelog.Episode do email_subject email_teaser email_content recorded_live youtube_id guid type)a) |> prep_audio_file(attrs) |> prep_plusplus_file(attrs) - |> cast_attachments(attrs, [:audio_file, :plusplus_file]) + |> cast_attachments(attrs, [:audio_file, :plusplus_file, :cover]) |> cast_embed(:audio_chapters) |> cast_embed(:plusplus_chapters) |> validate_required([:slug, :title, :published, :featured]) diff --git a/lib/changelog_web/templates/admin/episode/_form.html.eex b/lib/changelog_web/templates/admin/episode/_form.html.eex index d201ab3e43..3e65a82423 100644 --- a/lib/changelog_web/templates/admin/episode/_form.html.eex +++ b/lib/changelog_web/templates/admin/episode/_form.html.eex @@ -46,20 +46,46 @@ <% end %>
-
- +
+
<%= checkbox(f, :featured, class: "hidden") %> <%= AdminHelpers.error_message(f, :featured) %>
-
+
<%= checkbox(f, :requested, class: "hidden", value: !!f.data.request_id) %>
+ +
+ + <%= file_input(f, :cover) %> + <%= AdminHelpers.error_message(f, :cover) %> +
+ +
+ <%= if AdminHelpers.is_persisted(f.data) do %> + + data-content="Using the podcast cover" + <% else %> + data-content="Using the uploaded file" + <% end %> + > + <% end %> +
diff --git a/lib/changelog_web/templates/episode/_item.html.eex b/lib/changelog_web/templates/episode/_item.html.eex index db9caee061..366ff64cde 100644 --- a/lib/changelog_web/templates/episode/_item.html.eex +++ b/lib/changelog_web/templates/episode/_item.html.eex @@ -5,7 +5,7 @@ <%= link to: ~p"/#{slug}", title: @episode.podcast.name, class: "news_item-source-image news_item-source-image--episode" do %> - <%= SharedHelpers.lazy_image(PodcastView.cover_url(@episode.podcast, :small), @episode.podcast.name, width: 70, height: 70, style: "background-color: #121921") %> + <%= SharedHelpers.lazy_image(cover_url(@episode, :small), @episode.podcast.name, width: 70, height: 70, style: "background-color: #121921") %> <% end %> <%= link(podcast_name_and_number(@episode), diff --git a/lib/changelog_web/templates/episode/embed.html.eex b/lib/changelog_web/templates/episode/embed.html.eex index 50e32eb06d..a6ae5b0f22 100644 --- a/lib/changelog_web/templates/episode/embed.html.eex +++ b/lib/changelog_web/templates/episode/embed.html.eex @@ -67,7 +67,7 @@
  • <%= link to: Routes.podcast_url(@conn, :show, @podcast.slug), title: "#{@podcast.name} on Changelog.com", alt: "#{@podcast.name} Podcast" do %> - <%= @podcast.name %> + <%= @podcast.name %> <% end %>
  • diff --git a/lib/changelog_web/templates/feed/plusplus.xml.eex b/lib/changelog_web/templates/feed/plusplus.xml.eex index c700e6632b..0866c64b56 100644 --- a/lib/changelog_web/templates/feed/plusplus.xml.eex +++ b/lib/changelog_web/templates/feed/plusplus.xml.eex @@ -38,7 +38,7 @@ <%= if episode.type == :full do %> <%= EpisodeView.number(episode) %> <% end %> - + <%= TimeView.duration(duration) %> no <%= escaped(episode.subtitle) %> diff --git a/lib/changelog_web/templates/feed/podcast.xml.eex b/lib/changelog_web/templates/feed/podcast.xml.eex index 7dcd7b3853..6b524a0e75 100644 --- a/lib/changelog_web/templates/feed/podcast.xml.eex +++ b/lib/changelog_web/templates/feed/podcast.xml.eex @@ -55,7 +55,7 @@ <%= render("_show_notes.xml", episode: episode, plusplus: false) %> <%= episode.type %> - + <%= TimeView.duration(episode.audio_duration) %> no <%= episode.podcast.keywords %> diff --git a/lib/changelog_web/views/episode_view.ex b/lib/changelog_web/views/episode_view.ex index 51c6464861..2cc0e8d54b 100644 --- a/lib/changelog_web/views/episode_view.ex +++ b/lib/changelog_web/views/episode_view.ex @@ -12,6 +12,8 @@ defmodule ChangelogWeb.EpisodeView do UrlKit } + alias Changelog.Files.Cover + alias ChangelogWeb.{ Endpoint, LayoutView, @@ -70,6 +72,14 @@ defmodule ChangelogWeb.EpisodeView do defp get_down_with_op3(url, _mode), do: String.replace_prefix(url, "", "https://op3.dev/e/") + def cover_url(episode, version \\ :original) do + if episode.cover do + Cover.url({episode.cover, episode}, version) + else + PodcastView.cover_url(episode.podcast, version) + end + end + # simplest case, no ++ def plusplus_cta(%{plusplus_file: pp}) when is_nil(pp), do: fallback_cta() diff --git a/lib/changelog_web/views/podcast_view.ex b/lib/changelog_web/views/podcast_view.ex index e4c4437f2c..61d752eefe 100644 --- a/lib/changelog_web/views/podcast_view.ex +++ b/lib/changelog_web/views/podcast_view.ex @@ -27,28 +27,28 @@ defmodule ChangelogWeb.PodcastView do end end - def cover_path(%{slug: "master"}, version) do + def cover_url(podcast, version \\ :original) + + # Special cases for Master, The Changelog & ++ + def cover_url(%{slug: "master"}, version) do image = "master-#{version}.png" url(~p"/images/podcasts/#{image}") end - def cover_path(%{slug: "podcast", is_meta: true}, version) do + def cover_url(%{slug: "podcast", is_meta: true}, version) do image = "podcast-#{version}.png" url(~p"/images/podcasts/#{image}") end - def cover_path(%{slug: "plusplus"}, version) do + def cover_url(%{slug: "plusplus"}, version) do image = "plusplus-#{version}.png" url(~p"/images/podcasts/#{image}") end - def cover_path(podcast, version), do: Cover.url({podcast.cover, podcast}, version) - - def cover_url(podcast), do: cover_url(podcast, :original) - + # Standard case def cover_url(podcast, version) do if podcast.cover do - cover_path(podcast, version) + Cover.url({podcast.cover, podcast}, version) else url(~p"/images/defaults/black.png") end diff --git a/priv/repo/migrations/20240109164004_add_cover_to_episodes.exs b/priv/repo/migrations/20240109164004_add_cover_to_episodes.exs new file mode 100644 index 0000000000..9d2a642481 --- /dev/null +++ b/priv/repo/migrations/20240109164004_add_cover_to_episodes.exs @@ -0,0 +1,9 @@ +defmodule Changelog.Repo.Migrations.AddCoverFieldsToEpisodes do + use Ecto.Migration + + def change do + alter table(:episodes) do + add :cover, :string + end + end +end