feat: add custom Pivoine Rose theme to asciinema

- Mount custom CSS, favicon, and JS into static directories
- Create custom.js to inject theme CSS and favicon via JavaScript
- Add CustomThemeInjector Plug in custom.exs to inject script tag
- Custom theme features:
  - Pivoine rose primary color (#CE275B)
  - Gray tone backgrounds
  - Custom SVG favicon with rose gradient
  - Bootstrap 4 component overrides

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-09 09:50:07 +01:00
parent 95b01afafa
commit 63b96bb8e7
3 changed files with 60 additions and 2 deletions

View File

@@ -8,8 +8,9 @@ services:
volumes:
- asciinema_data:/var/opt/asciinema
- ./custom.exs:/opt/app/etc/custom.exs:ro
- ./theme:/opt/app/priv/static/theme:ro
- ./app.html.heex:/opt/app/lib/asciinema_web-*/eex/layout/app.html.heex:ro
- ./theme/custom.css:/opt/app/priv/static/css/custom.css:ro
- ./theme/favicon.svg:/opt/app/priv/static/images/favicon-custom.svg:ro
- ./theme/custom.js:/opt/app/priv/static/js/custom.js:ro
environment:
SECRET_KEY_BASE: ${ASCIINEMA_SECRET_KEY}
URL_HOST: ${ASCIINEMA_TRAEFIK_HOST}

View File

@@ -15,3 +15,43 @@ config :asciinema, Asciinema.Emails.Mailer,
verify: :verify_none,
versions: [:"tlsv1.2", :"tlsv1.3"]
]
# Custom Plug to inject theme JavaScript into HTML responses
defmodule CustomThemeInjector do
@behaviour Plug
def init(opts), do: opts
def call(conn, _opts) do
Plug.Conn.register_before_send(conn, fn conn ->
if html_response?(conn) do
inject_custom_script(conn)
else
conn
end
end)
end
defp html_response?(conn) do
case Plug.Conn.get_resp_header(conn, "content-type") do
[content_type | _] -> String.contains?(content_type, "text/html")
[] -> false
end
end
defp inject_custom_script(conn) do
{status, headers, body} = Plug.Conn.sent_resp(conn)
if is_binary(body) and String.contains?(body, "</head>") do
script_tag = ~s(<script src="/js/custom.js"></script>\n)
modified_body = String.replace(body, "</head>", "#{script_tag}</head>", global: false)
%{conn | status: status, resp_headers: headers, resp_body: modified_body}
else
conn
end
end
end
# Add the custom plug to the endpoint
config :asciinema, AsciinemaWeb.Endpoint,
http: [plug: CustomThemeInjector]

17
asciinema/theme/custom.js Normal file
View File

@@ -0,0 +1,17 @@
// Pivoine Rose Custom Theme Injector
(function() {
// Inject custom CSS
var customCSS = document.createElement('link');
customCSS.rel = 'stylesheet';
customCSS.href = '/css/custom.css';
document.head.appendChild(customCSS);
// Inject custom favicon
var customFavicon = document.createElement('link');
customFavicon.rel = 'icon';
customFavicon.type = 'image/svg+xml';
customFavicon.href = '/images/favicon-custom.svg';
document.head.appendChild(customFavicon);
console.log('Pivoine Rose theme loaded');
})();