From 803f2dd712f70ff40aadf84a4d74b0d9e177ffbf Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Thu, 20 Jul 2023 12:10:19 +0200 Subject: [PATCH] Fix theme name validation, add Nord to theme options --- lib/asciinema/accounts.ex | 5 ++--- lib/asciinema/recordings.ex | 7 +++++- lib/asciinema/recordings/asciicast.ex | 3 ++- .../controllers/live_stream_html.ex | 4 ++-- .../templates/doc/embedding.html.md | 5 +++-- .../recording/_svg_theme_nord.css.eex | 22 +++++++++++++++++++ lib/asciinema_web/views/player_view.ex | 11 ++++++++++ lib/asciinema_web/views/recording_view.ex | 2 +- lib/asciinema_web/views/user_view.ex | 12 ++-------- lib/media.ex | 11 ++++++++++ 10 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 lib/asciinema_web/templates/recording/_svg_theme_nord.css.eex diff --git a/lib/asciinema/accounts.ex b/lib/asciinema/accounts.ex index a9c82ad24..27dabe53c 100644 --- a/lib/asciinema/accounts.ex +++ b/lib/asciinema/accounts.ex @@ -3,12 +3,11 @@ defmodule Asciinema.Accounts do import Ecto.Query, warn: false import Ecto, only: [assoc: 2, build_assoc: 2] alias Asciinema.Accounts.{User, ApiToken} - alias Asciinema.Repo + alias Asciinema.{Media, Repo} alias Ecto.Changeset @valid_email_re ~r/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i @valid_username_re ~r/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$/ - @valid_theme_names ["asciinema", "tango", "solarized-dark", "solarized-light", "monokai"] def fetch_user(id) do case get_user(id) do @@ -67,7 +66,7 @@ defmodule Asciinema.Accounts do |> validate_format(:email, @valid_email_re) |> validate_format(:username, @valid_username_re) |> validate_length(:username, min: 2, max: 16) - |> validate_inclusion(:theme_name, @valid_theme_names) + |> validate_inclusion(:theme_name, Media.themes()) |> add_contraints() end diff --git a/lib/asciinema/recordings.ex b/lib/asciinema/recordings.ex index df2bb3a09..396bc8992 100644 --- a/lib/asciinema/recordings.ex +++ b/lib/asciinema/recordings.ex @@ -453,7 +453,12 @@ defmodule Asciinema.Recordings do def update_asciicast(asciicast, attrs \\ %{}) do changeset = - Asciicast.update_changeset(asciicast, attrs, Media.custom_terminal_font_families()) + Asciicast.update_changeset( + asciicast, + attrs, + Media.custom_terminal_font_families(), + Media.themes() + ) with {:ok, asciicast} <- Repo.update(changeset) do if stale_snapshot?(changeset) do diff --git a/lib/asciinema/recordings/asciicast.ex b/lib/asciinema/recordings/asciicast.ex index dd15437ee..a7dde3879 100644 --- a/lib/asciinema/recordings/asciicast.ex +++ b/lib/asciinema/recordings/asciicast.ex @@ -91,7 +91,7 @@ defmodule Asciinema.Recordings.Asciicast do |> generate_secret_token end - def update_changeset(struct, attrs, custom_terminal_font_families \\ []) do + def update_changeset(struct, attrs, custom_terminal_font_families \\ [], themes \\ []) do struct |> changeset(attrs) |> cast(attrs, [ @@ -107,6 +107,7 @@ defmodule Asciinema.Recordings.Asciicast do |> validate_number(:cols_override, greater_than: 0, less_than: 1024) |> validate_number(:rows_override, greater_than: 0, less_than: 512) |> validate_number(:idle_time_limit, greater_than_or_equal_to: 0.5) + |> validate_inclusion(:theme_name, themes) |> validate_number(:terminal_line_height, greater_than_or_equal_to: 1.0, less_than_or_equal_to: 2.0 diff --git a/lib/asciinema_web/controllers/live_stream_html.ex b/lib/asciinema_web/controllers/live_stream_html.ex index 52d74f624..c231e6a68 100644 --- a/lib/asciinema_web/controllers/live_stream_html.ex +++ b/lib/asciinema_web/controllers/live_stream_html.ex @@ -1,6 +1,6 @@ defmodule AsciinemaWeb.LiveStreamHTML do use AsciinemaWeb, :html - alias AsciinemaWeb.{PlayerView, RecordingView, UserView} + alias AsciinemaWeb.{PlayerView, RecordingView} embed_templates "live_stream/*" @@ -8,9 +8,9 @@ defmodule AsciinemaWeb.LiveStreamHTML do defdelegate author_avatar_url(stream), to: PlayerView defdelegate author_profile_path(stream), to: PlayerView defdelegate theme_name(stream), to: PlayerView + defdelegate theme_options, to: PlayerView defdelegate default_theme_name(stream), to: PlayerView defdelegate terminal_font_family_options, to: PlayerView - defdelegate theme_options, to: UserView def player_src(stream) do %{ diff --git a/lib/asciinema_web/templates/doc/embedding.html.md b/lib/asciinema_web/templates/doc/embedding.html.md index a8172ce45..aea9e2bf4 100644 --- a/lib/asciinema_web/templates/doc/embedding.html.md +++ b/lib/asciinema_web/templates/doc/embedding.html.md @@ -148,10 +148,11 @@ to a theme set by the asciicast author (or to "asciinema" if not set by the author). The available themes are: * asciinema -* tango +* monokai +* nord * solarized-dark * solarized-light -* monokai +* tango ### **cols** diff --git a/lib/asciinema_web/templates/recording/_svg_theme_nord.css.eex b/lib/asciinema_web/templates/recording/_svg_theme_nord.css.eex new file mode 100644 index 000000000..b311ca654 --- /dev/null +++ b/lib/asciinema_web/templates/recording/_svg_theme_nord.css.eex @@ -0,0 +1,22 @@ + + +.default-text-fill {fill: #eceff4} +.default-bg-fill {fill: #2e3440} + +.c-0 {fill: #3b4252} +.c-1 {fill: #bf616a} +.c-2 {fill: #a3be8c} +.c-3 {fill: #ebcb8b} +.c-4 {fill: #81a1c1} +.c-5 {fill: #b48ead} +.c-6 {fill: #88c0d0} +.c-7 {fill: #eceff4} +.c-8 {fill: #3b4252} +.c-9 {fill: #bf616a} +.c-10 {fill: #a3be8c} +.c-11 {fill: #ebcb8b} +.c-12 {fill: #81a1c1} +.c-13 {fill: #b48ead} +.c-14 {fill: #88c0d0} +.c-15 {fill: #eceff4} +.c-8, .c-9, .c-10, .c-11, .c-12, .c-13, .c-14, .c-15 {font-weight: bold} diff --git a/lib/asciinema_web/views/player_view.ex b/lib/asciinema_web/views/player_view.ex index 00afc21be..58749c3f7 100644 --- a/lib/asciinema_web/views/player_view.ex +++ b/lib/asciinema_web/views/player_view.ex @@ -28,6 +28,17 @@ defmodule AsciinemaWeb.PlayerView do profile_url(user) end + def theme_options do + [ + {"asciinema", "asciinema"}, + {"Monokai", "monokai"}, + {"Nord", "nord"}, + {"Tango", "tango"}, + {"Solarized Dark", "solarized-dark"}, + {"Solarized Light", "solarized-light"} + ] + end + def theme_name(medium) do medium.theme_name || default_theme_name(medium) end diff --git a/lib/asciinema_web/views/recording_view.ex b/lib/asciinema_web/views/recording_view.ex index 542096f0d..2c9b06a39 100644 --- a/lib/asciinema_web/views/recording_view.ex +++ b/lib/asciinema_web/views/recording_view.ex @@ -6,12 +6,12 @@ defmodule AsciinemaWeb.RecordingView do alias AsciinemaWeb.Endpoint alias AsciinemaWeb.Router.Helpers.Extra, as: RoutesX alias AsciinemaWeb.{PlayerView, UserView} - import UserView, only: [theme_options: 0] defdelegate author_username(asciicast), to: PlayerView defdelegate author_avatar_url(stream), to: PlayerView defdelegate author_profile_path(stream), to: PlayerView defdelegate theme_name(stream), to: PlayerView + defdelegate theme_options, to: PlayerView defdelegate default_theme_name(stream), to: PlayerView defdelegate terminal_font_family_options, to: PlayerView defdelegate username(user), to: UserView diff --git a/lib/asciinema_web/views/user_view.ex b/lib/asciinema_web/views/user_view.ex index d4cdfca37..d45ff555d 100644 --- a/lib/asciinema_web/views/user_view.ex +++ b/lib/asciinema_web/views/user_view.ex @@ -3,6 +3,8 @@ defmodule AsciinemaWeb.UserView do import Scrivener.HTML alias Asciinema.Gravatar + defdelegate theme_options, to: AsciinemaWeb.PlayerView + def avatar_url(user) do username = username(user) email = user.email || "#{username}+#{user.id}@asciinema.org" @@ -27,16 +29,6 @@ defmodule AsciinemaWeb.UserView do user.theme_name end - def theme_options do - [ - {"asciinema", "asciinema"}, - {"Tango", "tango"}, - {"Solarized Dark", "solarized-dark"}, - {"Solarized Light", "solarized-light"}, - {"Monokai", "monokai"} - ] - end - def active_tokens(api_tokens) do api_tokens |> Enum.reject(& &1.revoked_at) diff --git a/lib/media.ex b/lib/media.ex index c114c4118..6888e1ff0 100644 --- a/lib/media.ex +++ b/lib/media.ex @@ -4,5 +4,16 @@ defmodule Asciinema.Media do "JetBrainsMono Nerd Font" ] + @themes [ + "asciinema", + "monokai", + "nord", + "solarized-dark", + "solarized-light", + "tango" + ] + def custom_terminal_font_families, do: @custom_terminal_font_families + + def themes, do: @themes end