small SPA gleam experiment to fetch and render a single bsky post
at main 60 lines 1.5 kB view raw
1import gleam/dynamic/decode.{at, field, map, optional, string, success} 2import gleam/option.{type Option} 3 4pub type BlobRef { 5 BlobRef(link: String) 6} 7 8pub fn decode_blob_ref() -> decode.Decoder(BlobRef) { 9 at(["ref", "$link"], string) 10 |> map(BlobRef) 11} 12 13pub fn blob_ref_to_url(pds_host: String, did: String, blob: BlobRef) -> String { 14 pds_host 15 <> "/xrpc/com.atproto.sync.getBlob?did=" 16 <> did 17 <> "&cid=" 18 <> blob.link 19} 20 21pub type StrongRef { 22 StrongRef(uri: String, cid: String) 23} 24 25pub fn decode_strong_ref() -> decode.Decoder(StrongRef) { 26 use uri <- field("uri", string) 27 use cid <- field("cid", string) 28 success(StrongRef(uri:, cid:)) 29} 30 31pub type Label { 32 Label(val: String) 33} 34 35pub fn decode_label() -> decode.Decoder(Label) { 36 use val <- field("val", string) 37 success(Label(val:)) 38} 39 40pub type Profile { 41 Profile(display_name: Option(String), avatar: Option(BlobRef)) 42} 43 44pub type MiniDoc { 45 MiniDoc(did: String, handle: String, pds: String, signing_key: String) 46} 47 48pub fn decode_mini_doc() -> decode.Decoder(MiniDoc) { 49 use did <- field("did", string) 50 use handle <- field("handle", string) 51 use pds <- field("pds", string) 52 use signing_key <- field("signing_key", string) 53 success(MiniDoc(did:, handle:, pds:, signing_key:)) 54} 55 56pub fn decode_profile() -> decode.Decoder(Profile) { 57 use display_name <- field("displayName", optional(string)) 58 use avatar <- field("avatar", optional(decode_blob_ref())) 59 success(Profile(display_name:, avatar:)) 60}