Mix.install([
{:req, "~> 0.3"},
{:jason, "~> 1.4.0"},
{:kino, "~> 0.9.1"}
])
inputs = [
identifier: Kino.Input.text("identifier"),
password: Kino.Input.password("password")
]
form = Kino.Control.form(inputs, submit: "Create a session", reset_on_submit: [:message])
Kino.Control.subscribe(form, :new_session)
form
session =
receive do
{:new_session, %{data: data}} ->
body = Jason.encode!(data)
Req.post!("https://bsky.social/xrpc/com.atproto.server.createSession",
body: body,
headers: [content_type: "application/json", accept: "application/json"]
)
|> Map.fetch!(:body)
end
query =
%{
repo: session["handle"],
collection: "app.bsky.feed.post"
}
|> URI.encode_query()
Req.get!("https://bsky.social/xrpc/app.bsky.feed.getTimeline?#{query}",
headers: [accept: "application/json", authorization: "Bearer #{session["accessJwt"]}"]
)
|> then(& &1.body["feed"])
|> Enum.map(fn e ->
[
created_at: get_in(e, ["post", "record", "createdAt"]),
author: get_in(e, ["post", "author", "displayName"]),
text: get_in(e, ["post", "record", "text"])
]
end)
|> Kino.DataTable.new()
form =
[
text: Kino.Input.textarea("text")
]
|> Kino.Control.form(submit: "submit", reset_on_submit: [:text])
Kino.listen(form, fn %{data: data} ->
body =
%{
repo: session["handle"],
collection: "app.bsky.feed.post",
record: %{
text: data.text,
createdAt: DateTime.utc_now() |> DateTime.to_iso8601()
}
}
|> Jason.encode!()
Req.post!("https://bsky.social/xrpc/com.atproto.repo.createRecord",
body: body,
headers: [
authorization: "Bearer #{session["accessJwt"]}",
content_type: "application/json",
accept: "application/json"
]
)
end)
form