;; Social navigation, header, post cards, timeline, compose ;; --- Navigation --- (defcomp ~federation-nav-choose-username (&key url) (nav :class "flex gap-3 text-sm items-center" (a :href url :class "px-2 py-1 rounded hover:bg-stone-200 font-bold" "Choose username"))) (defcomp ~federation-nav-link (&key href cls label) (a :href href :class cls label)) (defcomp ~federation-nav-notification-link (&key href cls count-url) (a :href href :class cls "Notifications" (span :sx-get count-url :sx-trigger "load, every 30s" :sx-swap "innerHTML" :class "absolute -top-2 -right-3 text-xs bg-red-500 text-white rounded-full px-1 empty:hidden"))) (defcomp ~federation-nav-bar (&key items) (nav :class "flex gap-3 text-sm items-center flex-wrap" items)) (defcomp ~federation-social-header (&key nav) (div :id "social-row" :class "flex flex-col items-center md:flex-row justify-center md:justify-between w-full p-1 bg-sky-400" (div :class "w-full flex flex-row items-center gap-2 flex-wrap" nav))) (defcomp ~federation-header-child (&key inner) (div :id "root-header-child" :class "flex flex-col w-full items-center" inner)) ;; --- Post card --- (defcomp ~federation-boost-label (&key name) (div :class "text-sm text-stone-500 mb-2" "Boosted by " name)) (defcomp ~federation-avatar-img (&key src cls) (img :src src :alt "" :class cls)) (defcomp ~federation-avatar-placeholder (&key cls initial) (div :class cls initial)) (defcomp ~federation-content-cw (&key summary content) (details :class "mt-2" (summary :class "text-stone-500 cursor-pointer" "CW: " (~rich-text :html summary)) (div :class "mt-2 prose prose-sm prose-stone max-w-none" (~rich-text :html content)))) (defcomp ~federation-content-plain (&key content) (div :class "mt-2 prose prose-sm prose-stone max-w-none" (~rich-text :html content))) (defcomp ~federation-original-link (&key url) (a :href url :target "_blank" :rel "noopener" :class "text-sm text-stone-400 hover:underline mt-1 inline-block" "original")) (defcomp ~federation-interactions-wrap (&key id buttons) (div :id id buttons)) (defcomp ~federation-post-card (&key boost avatar actor-name actor-username domain time content original interactions) (article :class "bg-white rounded-lg shadow-sm border border-stone-200 p-4 mb-4" boost (div :class "flex items-start gap-3" avatar (div :class "flex-1 min-w-0" (div :class "flex items-baseline gap-2" (span :class "font-semibold text-stone-900" actor-name) (span :class "text-sm text-stone-500" "@" actor-username domain) (span :class "text-sm text-stone-400 ml-auto" time)) content original interactions)))) ;; --- Interaction buttons --- (defcomp ~federation-reply-link (&key url) (a :href url :class "hover:text-stone-700" "Reply")) (defcomp ~federation-like-form (&key action target oid ainbox csrf cls icon count) (form :sx-post action :sx-target target :sx-swap "innerHTML" (input :type "hidden" :name "object_id" :value oid) (input :type "hidden" :name "author_inbox" :value ainbox) (input :type "hidden" :name "csrf_token" :value csrf) (button :type "submit" :class cls (span icon) " " count))) (defcomp ~federation-boost-form (&key action target oid ainbox csrf cls count) (form :sx-post action :sx-target target :sx-swap "innerHTML" (input :type "hidden" :name "object_id" :value oid) (input :type "hidden" :name "author_inbox" :value ainbox) (input :type "hidden" :name "csrf_token" :value csrf) (button :type "submit" :class cls (span "\u21bb") " " count))) (defcomp ~federation-interaction-buttons (&key like boost reply) (div :class "flex items-center gap-4 mt-3 text-sm text-stone-500" like boost reply)) ;; --- Timeline --- (defcomp ~federation-scroll-sentinel (&key url) (div :sx-get url :sx-trigger "revealed" :sx-swap "outerHTML")) (defcomp ~federation-compose-button (&key url) (a :href url :class "bg-stone-800 text-white px-4 py-2 rounded hover:bg-stone-700" "Compose")) (defcomp ~federation-timeline-page (&key label compose timeline) (div :class "flex items-center justify-between mb-6" (h1 :class "text-2xl font-bold" label " Timeline") compose) (div :id "timeline" timeline)) ;; --- Compose --- (defcomp ~federation-compose-reply (&key reply-to) (input :type "hidden" :name "in_reply_to" :value reply-to) (div :class "text-sm text-stone-500" "Replying to " (span :class "font-mono" reply-to))) (defcomp ~federation-compose-form (&key action csrf reply) (h1 :class "text-2xl font-bold mb-6" "Compose") (form :method "post" :action action :class "space-y-4" (input :type "hidden" :name "csrf_token" :value csrf) reply (textarea :name "content" :rows "6" :maxlength "5000" :required true :class "w-full border border-stone-300 rounded-lg p-3 focus:outline-none focus:ring-2 focus:ring-stone-500" :placeholder "What's on your mind?") (div :class "flex items-center justify-between" (select :name "visibility" :class "border border-stone-300 rounded px-3 py-1.5 text-sm" (option :value "public" "Public") (option :value "unlisted" "Unlisted") (option :value "followers" "Followers only")) (button :type "submit" :class "bg-stone-800 text-white px-6 py-2 rounded hover:bg-stone-700" "Publish"))))