50 lines
1.3 KiB
Elixir
50 lines
1.3 KiB
Elixir
|
|
defmodule SimpleshopThemeWeb.ImageController do
|
||
|
|
use SimpleshopThemeWeb, :controller
|
||
|
|
|
||
|
|
alias SimpleshopTheme.Media
|
||
|
|
alias SimpleshopTheme.Media.SVGRecolorer
|
||
|
|
|
||
|
|
@doc """
|
||
|
|
Serves an SVG image recolored with the specified color.
|
||
|
|
|
||
|
|
The color should be a hex color code (with or without the leading #).
|
||
|
|
Only works with SVG images.
|
||
|
|
"""
|
||
|
|
def recolored_svg(conn, %{"id" => id, "color" => color}) do
|
||
|
|
clean_color = normalize_color(color)
|
||
|
|
|
||
|
|
with true <- SVGRecolorer.valid_hex_color?(clean_color),
|
||
|
|
%{is_svg: true, svg_content: svg} when not is_nil(svg) <- Media.get_image(id) do
|
||
|
|
recolored = SVGRecolorer.recolor(svg, clean_color)
|
||
|
|
|
||
|
|
conn
|
||
|
|
|> put_resp_content_type("image/svg+xml")
|
||
|
|
|> put_resp_header("cache-control", "public, max-age=3600")
|
||
|
|
|> put_resp_header("etag", ~s("#{id}-#{clean_color}"))
|
||
|
|
|> send_resp(200, recolored)
|
||
|
|
else
|
||
|
|
false ->
|
||
|
|
send_resp(conn, 400, "Invalid color format")
|
||
|
|
|
||
|
|
nil ->
|
||
|
|
send_resp(conn, 404, "Image not found")
|
||
|
|
|
||
|
|
%{is_svg: false} ->
|
||
|
|
send_resp(conn, 400, "Image is not an SVG")
|
||
|
|
|
||
|
|
%{svg_content: nil} ->
|
||
|
|
send_resp(conn, 400, "SVG content not available")
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
defp normalize_color(color) do
|
||
|
|
color = String.trim(color)
|
||
|
|
|
||
|
|
if String.starts_with?(color, "#") do
|
||
|
|
color
|
||
|
|
else
|
||
|
|
"#" <> color
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|