Skip to content

Commit

Permalink
Add account-level font family setting
Browse files Browse the repository at this point in the history
Closes #425
  • Loading branch information
ku1ik committed Feb 17, 2024
1 parent 4eb73c1 commit da9ea29
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 34 deletions.
10 changes: 9 additions & 1 deletion lib/asciinema/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,19 @@ defmodule Asciinema.Accounts do
import Ecto.Changeset

user
|> cast(params, [:email, :name, :username, :theme_name, :asciicasts_private_by_default])
|> cast(params, [
:email,
:name,
:username,
:theme_name,
:terminal_font_family,
:asciicasts_private_by_default
])
|> validate_format(:email, @valid_email_re)
|> validate_format(:username, @valid_username_re)
|> validate_length(:username, min: 2, max: 16)
|> validate_inclusion(:theme_name, Media.themes())
|> validate_inclusion(:terminal_font_family, Media.custom_terminal_font_families())
|> add_contraints()
end

Expand Down
1 change: 1 addition & 0 deletions lib/asciinema/accounts/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ defmodule Asciinema.Accounts.User do
field :name, :string
field :auth_token, :string
field :theme_name, :string
field :terminal_font_family, :string
field :asciicasts_private_by_default, :boolean, default: true
field :last_login_at, :utc_datetime_usec
field :is_admin, :boolean
Expand Down
8 changes: 4 additions & 4 deletions lib/asciinema_web/templates/recording/edit.html.eex
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
<div class="form-group row">
<%= label f, :theme_name, "Terminal theme", class: "col-sm-4 col-md-3 col-lg-3 col-form-label" %>
<div class="col-sm-8 col-md-9 col-lg-9">
<%= select f, :theme_name, theme_options(), class: "form-control", prompt: "Default (#{default_theme_name(@changeset.data)})" %>
<%= select f, :theme_name, theme_options(), class: "form-control", prompt: "Account default (#{default_theme_display_name(@changeset.data)})" %>
</div>
</div>

Expand All @@ -69,15 +69,15 @@
<div class="col-sm-8 col-md-9 col-lg-9">
<%= text_input f, :terminal_line_height, class: "form-control", type: "number", min: 1, max: 2, step: "any", placeholder: "1.33333" %>
<%= error_tag f, :terminal_line_height %>
<small class="form-text text-muted">Relative to font size. Lowering it to ~1.1 helps with alignment of block characters like ▀ ▄ █</small>
<small class="form-text text-muted">Relative to the font size. Lowering it to ~1.1 helps with alignment of block characters such as ▀ ▄ █</small>
</div>
</div>

<div class="form-group row">
<%= label f, :terminal_font_family, "Terminal font family", class: "col-sm-4 col-md-3 col-lg-3 col-form-label" %>
<div class="col-sm-8 col-md-9 col-lg-9">
<%= select f, :terminal_font_family, terminal_font_family_options(), class: "form-control", prompt: "Default (web safe, platform specific)" %>
<small class="form-text text-muted">Choose one of Nerd Font variants if icons or other symbols in your recording are not visible.</small>
<%= select f, :terminal_font_family, terminal_font_family_options(), class: "form-control", prompt: "Account default (#{default_font_display_name(@changeset.data)})" %>
<small class="form-text text-muted">Choose one of the Nerd Font variants if icons or other symbols in your recording are not visible.</small>
</div>
</div>

Expand Down
34 changes: 21 additions & 13 deletions lib/asciinema_web/templates/user/edit.html.eex
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,48 @@
<legend>Account settings</legend>

<div class="form-group row string optional user_username <%= error_class(f, :username) %>">
<%= label f, :username, class: "string optional col-form-label col-sm-3 col-md-3 col-lg-2" %>
<div class="col-sm-9 col-md-9 col-lg-10">
<%= label f, :username, class: "string optional col-form-label col-3" %>
<div class="col-9">
<%= text_input f, :username, class: "string optional form-control" %>
<%= error_tag f, :username %>
</div>
</div>

<div class="form-group row email required user_email <%= error_class(f, :email) %>">
<%= label f, :email, class: "email required col-form-label col-sm-3 col-md-3 col-lg-2" %>
<div class="col-sm-9 col-md-9 col-lg-10">
<%= label f, :email, class: "email required col-form-label col-3" %>
<div class="col-9">
<%= email_input f, :email, class: "string email required form-control" %>
<%= error_tag f, :email %>
</div>
</div>

<div class="form-group row string optional user_name <%= error_class(f, :name) %>">
<%= label f, :name, "Full name", class: "string optional col-form-label col-sm-3 col-md-3 col-lg-2" %>
<div class="col-sm-9 col-md-9 col-lg-10">
<%= label f, :name, "Full name", class: "string optional col-form-label col-3" %>
<div class="col-9">
<%= text_input f, :name, class: "string optional form-control" %>
<%= error_tag f, :name %>
</div>
</div>

<div class="form-group row select optional user_theme_name">
<%= label f, :theme_name, "Terminal theme", class: "select optional col-form-label col-sm-3 col-md-3 col-lg-2" %>
<div class="col-sm-9 col-md-9 col-lg-10">
<%= label f, :theme_name, "Default terminal theme", class: "col-3 select optional col-form-label" %>
<div class="col-9">
<%= select f, :theme_name, theme_options(), class: "select optional form-control", prompt: "Default (asciinema)" %>
<small class="form-text text-muted">Applies to all your recordings unless a custom theme is chosen for a recording</small>
<small class="form-text text-muted">Applies to all your recordings that don't explicitly override this.</small>
</div>
</div>

<div class="form-group row">
<%= label f, :terminal_font_family, "Default terminal font", class: "col-sm-4 col-md-3 col-form-label" %>
<div class="col-sm-8 col-md-9">
<%= select f, :terminal_font_family, terminal_font_family_options(), class: "form-control", prompt: "Default (#{default_font_display_name()})" %>
<small class="form-text text-muted">Applies to all your recordings that don't explicitly override this.</small>
</div>
</div>

<div class="form-group row radio_buttons optional user_asciicasts_private_by_default">
<%= label f, :asciicasts_private_by_default, "Recording visibility", class: "radio_buttons optional col-form-label col-sm-3 col-md-3 col-lg-2" %>
<div class="col-sm-9 col-md-9 col-lg-10">
<%= label f, :asciicasts_private_by_default, "New recording visibility", class: "col-3 radio_buttons optional col-form-label" %>
<div class="col-9">
<div class="form-check">
<%= radio_button f, :asciicasts_private_by_default, false, class: "radio_buttons optional form-check-input" %>
<%= label f, :asciicasts_private_by_default, "public", for: "user_asciicasts_private_by_default_false", class: "form-check-label" %>
Expand All @@ -52,8 +60,8 @@
</div>

<div class="form-group row">
<label class="col-form-label col-sm-3 col-md-3 col-lg-2"></label>
<div class="col-sm-offset-3 col-sm-9 col-md-offset-3 col-md-9 col-lg-offset-2 col-lg-10">
<label class="col-form-label col-3"></label>
<div class="col-offset-3 col-9">
<br>
<%= submit "Save", class: "btn btn-primary" %>
<%= link "Cancel", to: profile_path(@conn), class: "btn" %>
Expand Down
45 changes: 32 additions & 13 deletions lib/asciinema_web/views/player_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,50 @@ defmodule AsciinemaWeb.PlayerView do
end

def theme_options do
[
{"asciinema", "asciinema"},
{"Dracula", "dracula"},
{"Monokai", "monokai"},
{"Nord", "nord"},
{"Tango", "tango"},
{"Solarized Dark", "solarized-dark"},
{"Solarized Light", "solarized-light"}
]
for theme <- Media.themes() do
{theme_display_name(theme), theme}
end
end

def theme_name(medium) do
medium.theme_name || default_theme_name(medium)
end

def theme_display_name(theme) do
case theme do
"asciinema" -> "asciinema"
"dracula" -> "Dracula"
"monokai" -> "Monokai"
"nord" -> "Nord"
"tango" -> "Tango"
"solarized-dark" -> "Solarized Dark"
"solarized-light" -> "Solarized Light"
end
end

def default_theme_name(%{user: user}) do
UserView.theme_name(user) || "asciinema"
end

def terminal_font_family_options do
for family <- Media.custom_terminal_font_families() do
case family do
"FiraCode Nerd Font" -> {"Nerd Font - Fira Code", family}
"JetBrainsMono Nerd Font" -> {"Nerd Font - JetBrains Mono", family}
end
{terminal_font_family_display_name(family), family}
end
end

def terminal_font_family(medium) do
medium.terminal_font_family || default_terminal_font_family(medium)
end

def terminal_font_family_display_name(family) do
case family do
nil -> "web safe, platform specific"
"FiraCode Nerd Font" -> "Nerd Font - Fira Code"
"JetBrainsMono Nerd Font" -> "Nerd Font - JetBrains Mono"
end
end

def default_terminal_font_family(%{user: user}) do
UserView.terminal_font_family(user)
end
end
16 changes: 14 additions & 2 deletions lib/asciinema_web/views/recording_view.ex
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
defmodule AsciinemaWeb.RecordingView do
alias AsciinemaWeb.PlayerView
use AsciinemaWeb, :view
import Scrivener.HTML
alias Asciinema.Recordings.Asciicast
alias AsciinemaWeb.Endpoint
alias AsciinemaWeb.PlayerView
alias AsciinemaWeb.Router.Helpers.Extra, as: RoutesX
alias AsciinemaWeb.{PlayerView, UserView}

Expand All @@ -12,8 +12,12 @@ defmodule AsciinemaWeb.RecordingView do
defdelegate author_profile_path(stream), to: PlayerView
defdelegate theme_name(stream), to: PlayerView
defdelegate theme_options, to: PlayerView
defdelegate theme_display_name(asciicast), to: PlayerView
defdelegate default_theme_name(stream), to: PlayerView
defdelegate terminal_font_family(asciicast), to: PlayerView
defdelegate terminal_font_family_options, to: PlayerView
defdelegate terminal_font_family_display_name(asciicast), to: PlayerView
defdelegate default_terminal_font_family(asciicast), to: PlayerView
defdelegate username(user), to: UserView

def player_src(asciicast), do: file_url(asciicast)
Expand All @@ -24,7 +28,7 @@ defmodule AsciinemaWeb.RecordingView do
rows: rows(asciicast),
theme: theme_name(asciicast),
terminalLineHeight: asciicast.terminal_line_height,
customTerminalFontFamily: asciicast.terminal_font_family,
customTerminalFontFamily: terminal_font_family(asciicast),
poster: poster(asciicast.snapshot),
markers: markers(asciicast.markers),
idleTimeLimit: asciicast.idle_time_limit,
Expand Down Expand Up @@ -58,6 +62,14 @@ defmodule AsciinemaWeb.RecordingView do
)
end

def default_theme_display_name(%{user: user}) do
theme_display_name(UserView.theme_name(user) || "asciinema")
end

def default_font_display_name(%{user: user}) do
terminal_font_family_display_name(UserView.terminal_font_family(user))
end

defp short_text_description(asciicast) do
if asciicast.description do
asciicast.description
Expand Down
13 changes: 12 additions & 1 deletion lib/asciinema_web/views/user_view.ex
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
defmodule AsciinemaWeb.UserView do
use AsciinemaWeb, :view
import Scrivener.HTML
alias AsciinemaWeb.PlayerView
alias Asciinema.Gravatar

defdelegate theme_options, to: AsciinemaWeb.PlayerView
defdelegate theme_options, to: PlayerView
defdelegate terminal_font_family_options, to: PlayerView
defdelegate terminal_font_family_display_name(asciicast), to: PlayerView

def avatar_url(user) do
username = username(user)
Expand All @@ -29,6 +32,14 @@ defmodule AsciinemaWeb.UserView do
user.theme_name
end

def terminal_font_family(user) do
user.terminal_font_family
end

def default_font_display_name do
terminal_font_family_display_name(nil)
end

def active_tokens(api_tokens) do
api_tokens
|> Enum.reject(& &1.revoked_at)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule Asciinema.Repo.Migrations.AddTerminalFontFamilyToUsers do
use Ecto.Migration

def change do
alter table(:users) do
add :terminal_font_family, :string
end
end
end

0 comments on commit da9ea29

Please sign in to comment.