Current section
Files
Jump to
Current section
Files
src/inlay@detect.erl
-module(inlay@detect).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/inlay/detect.gleam").
-export([detect_with/2, render_with/2, render_inline_with/2, bluesky_height/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Provider dispatch shared by the public `inlay` API and the Lustre component.\n"
"\n"
" `detect_with` walks the enabled providers to turn a URL into an `Embed`, and\n"
" `render_with` turns a detected `Embed` back into HTML. Both honour the\n"
" supplied `Config`.\n"
).
-file("src/inlay/detect.gleam", 153).
-spec try_one(
gleam@option:option(any()),
gleam@uri:uri(),
fun((gleam@uri:uri()) -> gleam@option:option(inlay@embed:embed())),
fun(() -> gleam@option:option(inlay@embed:embed()))
) -> gleam@option:option(inlay@embed:embed()).
try_one(Enabled, Url, Detector, Next) ->
case Enabled of
{some, _} ->
case Detector(Url) of
{some, Found} ->
{some, Found};
none ->
Next()
end;
none ->
Next()
end.
-file("src/inlay/detect.gleam", 169).
-spec try_one_with(
gleam@option:option(SLE),
gleam@uri:uri(),
fun((gleam@uri:uri(), SLE) -> gleam@option:option(inlay@embed:embed())),
fun(() -> gleam@option:option(inlay@embed:embed()))
) -> gleam@option:option(inlay@embed:embed()).
try_one_with(Enabled, Url, Detector, Next) ->
case Enabled of
{some, Cfg} ->
case Detector(Url, Cfg) of
{some, Found} ->
{some, Found};
none ->
Next()
end;
none ->
Next()
end.
-file("src/inlay/detect.gleam", 135).
-spec do_detect(gleam@uri:uri(), inlay@embed:config()) -> gleam@option:option(inlay@embed:embed()).
do_detect(Url, Config) ->
try_one_with(
erlang:element(13, Config),
Url,
fun inlay@mastodon:detect/2,
fun() ->
try_one_with(
erlang:element(14, Config),
Url,
fun inlay@pixelfed:detect/2,
fun() ->
try_one(
erlang:element(2, Config),
Url,
fun inlay@youtube:detect/1,
fun() ->
try_one(
erlang:element(11, Config),
Url,
fun inlay@ted:detect/1,
fun() ->
try_one(
erlang:element(3, Config),
Url,
fun inlay@vimeo:detect/1,
fun() ->
try_one(
erlang:element(4, Config),
Url,
fun inlay@spotify:detect/1,
fun() ->
try_one(
erlang:element(
7,
Config
),
Url,
fun inlay@bluesky:detect/1,
fun() ->
try_one(
erlang:element(
9,
Config
),
Url,
fun inlay@twitch:detect/1,
fun() ->
try_one(
erlang:element(
12,
Config
),
Url,
fun inlay@soundcloud:detect/1,
fun() ->
try_one(
erlang:element(
5,
Config
),
Url,
fun inlay@twitter:detect/1,
fun(
) ->
try_one(
erlang:element(
6,
Config
),
Url,
fun inlay@tiktok:detect/1,
fun(
) ->
try_one(
erlang:element(
8,
Config
),
Url,
fun inlay@instagram:detect/1,
fun(
) ->
try_one(
erlang:element(
10,
Config
),
Url,
fun inlay@openstreetmap:detect/1,
fun(
) ->
try_one(
erlang:element(
15,
Config
),
Url,
fun inlay@apple_music:detect/1,
fun(
) ->
none
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/inlay/detect.gleam", 33).
?DOC(" Detect an embeddable link from a URL using the given configuration.\n").
-spec detect_with(binary(), inlay@embed:config()) -> gleam@option:option(inlay@embed:embed()).
detect_with(Url, Config) ->
case gleam_stdlib:uri_parse(Url) of
{ok, Parsed} ->
do_detect(Parsed, Config);
{error, _} ->
none
end.
-file("src/inlay/detect.gleam", 41).
?DOC(" Render a detected embed as HTML using the given configuration.\n").
-spec render_with(inlay@embed:embed(), inlay@embed:config()) -> lustre@vdom@vnode:element(any()).
render_with(Embed, Config) ->
El@1 = case case Embed of
{youtube_video, _, _, _} ->
inlay@youtube:render(Embed, Config);
{youtube_playlist, _} ->
inlay@youtube:render(Embed, Config);
{vimeo_video, _, _} ->
inlay@vimeo:render(Embed, Config);
{spotify_media, _, _} ->
inlay@spotify:render(Embed, Config);
{tweet, _, _} ->
inlay@twitter:render(Embed, Config);
{tik_tok_video, _, _} ->
inlay@tiktok:render(Embed, Config);
{bluesky_post, _, _} ->
inlay@bluesky:render(Embed, Config);
{instagram_post, _, _} ->
inlay@instagram:render(Embed, Config);
{twitch_channel, _} ->
inlay@twitch:render(Embed, Config);
{twitch_video, _} ->
inlay@twitch:render(Embed, Config);
{map_location, _, _, _} ->
inlay@openstreetmap:render(Embed, Config);
{ted_talk, _} ->
inlay@ted:render(Embed, Config);
{sound_cloud_track, _} ->
inlay@soundcloud:render(Embed, Config);
{mastodon_post, _, _, _} ->
inlay@mastodon:render(Embed, Config);
{pixelfed_post, _, _, _} ->
inlay@pixelfed:render(Embed, Config);
{apple_music_media, _, _, _, _} ->
inlay@apple_music:render(Embed, Config)
end of
{ok, El} -> El;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"inlay/detect"/utf8>>,
function => <<"render_with"/utf8>>,
line => 42,
value => _assert_fail,
start => 1349,
'end' => 2181,
pattern_start => 1360,
pattern_end => 1366})
end,
El@1.
-file("src/inlay/detect.gleam", 128).
-spec pixelfed_height(inlay@embed:config()) -> integer().
pixelfed_height(Config) ->
case erlang:element(14, Config) of
{some, {pixelfed_config, _, _, _, Height}} ->
gleam@option:unwrap(Height, 600);
none ->
600
end.
-file("src/inlay/detect.gleam", 121).
-spec mastodon_height(inlay@embed:config()) -> integer().
mastodon_height(Config) ->
case erlang:element(13, Config) of
{some, {mastodon_config, _, _, Height}} ->
gleam@option:unwrap(Height, 400);
none ->
400
end.
-file("src/inlay/detect.gleam", 114).
-spec tiktok_height(inlay@embed:config()) -> integer().
tiktok_height(Config) ->
case erlang:element(6, Config) of
{some, {tik_tok_config, Height}} ->
gleam@option:unwrap(Height, 750);
none ->
750
end.
-file("src/inlay/detect.gleam", 107).
-spec instagram_height(inlay@embed:config()) -> integer().
instagram_height(Config) ->
case erlang:element(8, Config) of
{some, {instagram_config, Height}} ->
gleam@option:unwrap(Height, 700);
none ->
700
end.
-file("src/inlay/detect.gleam", 100).
-spec tweet_height(inlay@embed:config()) -> integer().
tweet_height(Config) ->
case erlang:element(5, Config) of
{some, {twitter_config, Height}} ->
gleam@option:unwrap(Height, 550);
none ->
550
end.
-file("src/inlay/detect.gleam", 66).
?DOC(
" Render a detected embed for the Lustre component path. Providers that scan\n"
" the host page with a script render nothing or clip inside a component's\n"
" shadow root, so this renders them as self-contained iframes; every other\n"
" provider falls back to [`render_with`](#render_with). Bluesky is handled by\n"
" the component itself because it depends on the resolved DID.\n"
).
-spec render_inline_with(inlay@embed:embed(), inlay@embed:config()) -> lustre@vdom@vnode:element(any()).
render_inline_with(Embed, Config) ->
case Embed of
{tweet, _, Id} ->
inlay@inline:tweet_iframe(Id, tweet_height(Config));
{instagram_post, Post_type, Id@1} ->
inlay@inline:instagram_iframe(
Post_type,
Id@1,
instagram_height(Config)
);
{tik_tok_video, _, Id@2} ->
inlay@inline:tiktok_iframe(Id@2, tiktok_height(Config));
{mastodon_post, Server, User, Id@3} ->
inlay@inline:mastodon_iframe(
Server,
User,
Id@3,
mastodon_height(Config)
);
{pixelfed_post, Server@1, User@1, Id@4} ->
inlay@inline:pixelfed_iframe(
Server@1,
User@1,
Id@4,
pixelfed_height(Config)
);
{youtube_video, _, _, _} ->
render_with(Embed, Config);
{youtube_playlist, _} ->
render_with(Embed, Config);
{vimeo_video, _, _} ->
render_with(Embed, Config);
{spotify_media, _, _} ->
render_with(Embed, Config);
{bluesky_post, _, _} ->
render_with(Embed, Config);
{twitch_channel, _} ->
render_with(Embed, Config);
{twitch_video, _} ->
render_with(Embed, Config);
{map_location, _, _, _} ->
render_with(Embed, Config);
{ted_talk, _} ->
render_with(Embed, Config);
{sound_cloud_track, _} ->
render_with(Embed, Config);
{apple_music_media, _, _, _, _} ->
render_with(Embed, Config)
end.
-file("src/inlay/detect.gleam", 93).
?DOC(
" The initial component-path height for a Bluesky embed, from `config` with a\n"
" default of `600`.\n"
).
-spec bluesky_height(inlay@embed:config()) -> integer().
bluesky_height(Config) ->
case erlang:element(7, Config) of
{some, {bluesky_config, _, Height}} ->
gleam@option:unwrap(Height, 600);
none ->
600
end.