Updated packages: - bandit: 1.10.3 → 1.10.4 - phoenix_live_view: 1.1.27 → 1.1.28 - phoenix_pubsub_redis: 3.0.1 → 3.1.0 - oban_met: 1.0.6 → 1.1.0 (vendored) - oban_web: 2.11.8 → 2.12.1 (vendored) All tests passing (8923 tests, 0 failures). Reviewed-on: graham/towerops-web#194
97 lines
2.3 KiB
Elixir
97 lines
2.3 KiB
Elixir
defmodule Oban.Web.Assets do
|
|
@moduledoc false
|
|
|
|
@behaviour Plug
|
|
|
|
import Plug.Conn
|
|
|
|
@static_path Application.app_dir(:oban_web, ["priv", "static"])
|
|
|
|
# Icons
|
|
|
|
icon_files =
|
|
for dir <- ["outline", "solid", "special"],
|
|
base = Path.join([@static_path, "icons", dir]),
|
|
file <- File.ls!(base),
|
|
String.ends_with?(file, ".svg") do
|
|
path = Path.join(base, file)
|
|
Module.put_attribute(__MODULE__, :external_resource, path)
|
|
{Path.join(dir, file), File.read!(path)}
|
|
end
|
|
|
|
@icons Map.new(icon_files)
|
|
|
|
# Font
|
|
|
|
@external_resource font_path = Path.join(@static_path, "fonts/Inter.woff2")
|
|
|
|
@font File.read!(font_path)
|
|
|
|
# CSS
|
|
|
|
@external_resource css_path = Path.join(@static_path, "app.css")
|
|
|
|
@css File.read!(css_path)
|
|
|
|
# JS
|
|
|
|
phoenix_js_paths =
|
|
for app <- ~w(phoenix phoenix_html phoenix_live_view)a do
|
|
path = Application.app_dir(app, ["priv", "static", "#{app}.js"])
|
|
Module.put_attribute(__MODULE__, :external_resource, path)
|
|
path
|
|
end
|
|
|
|
@external_resource js_path = Path.join(@static_path, "app.js")
|
|
|
|
@js """
|
|
#{for path <- phoenix_js_paths, do: path |> File.read!() |> String.replace("//# sourceMappingURL=", "// ")}
|
|
#{File.read!(js_path)}
|
|
"""
|
|
|
|
@impl Plug
|
|
def init(asset), do: asset
|
|
|
|
@impl Plug
|
|
def call(conn, :css) do
|
|
serve_asset(conn, @css, "text/css")
|
|
end
|
|
|
|
def call(conn, :js) do
|
|
serve_asset(conn, @js, "text/javascript")
|
|
end
|
|
|
|
def call(conn, :font) do
|
|
serve_asset(conn, @font, "font/woff2")
|
|
end
|
|
|
|
def call(conn, :icon) do
|
|
icon_path = Enum.join(conn.path_params["path"], "/")
|
|
|
|
case Map.get(@icons, icon_path) do
|
|
nil ->
|
|
conn
|
|
|> put_resp_header("content-type", "text/plain")
|
|
|> send_resp(404, "Icon not found")
|
|
|> halt()
|
|
|
|
contents ->
|
|
serve_asset(conn, contents, "image/svg+xml")
|
|
end
|
|
end
|
|
|
|
defp serve_asset(conn, contents, content_type) do
|
|
conn
|
|
|> put_resp_header("content-type", content_type)
|
|
|> put_resp_header("cache-control", "public, max-age=31536000, immutable")
|
|
|> put_private(:plug_skip_csrf_protection, true)
|
|
|> send_resp(200, contents)
|
|
|> halt()
|
|
end
|
|
|
|
for {key, val} <- [css: @css, js: @js] do
|
|
md5 = Base.encode16(:crypto.hash(:md5, val), case: :lower)
|
|
|
|
def current_hash(unquote(key)), do: unquote(md5)
|
|
end
|
|
end
|