Compare commits

..

3 commits

Author SHA1 Message Date
8d7e4dde0e Debounce refresh when typing 2025-11-20 12:19:48 +01:00
c91b1ff2d4 Add support for gifs 2025-11-20 11:25:46 +01:00
2b78afde38 Clean up database interop 2025-11-20 11:25:41 +01:00
2 changed files with 37 additions and 33 deletions

View file

@ -153,13 +153,11 @@
(obtain-oauth-authorization-code! application)))))) (obtain-oauth-authorization-code! application))))))
(declare fetch-posts!) (declare fetch-posts!)
(declare refresh-displayed-posts!) (declare debounced-refresh!)
(defn- fetch-application-settings [] (defn- fetch-application-settings []
(-> (db/open-cursor! ::db/application db/all) (->> (db/open-cursor! ::db/application db/all)
(db/transduce-cursor (comp (take 1) (db/first-result (map #(js->clj % :keywordize-keys true)))))
(map #(js->clj % :keywordize-keys true)))
(fn [_ x] x))))
(defn setup-application! (defn setup-application!
"Handles Mastodon application setup on the client side" "Handles Mastodon application setup on the client side"
@ -202,7 +200,7 @@
(if (zero? post-count) (if (zero? post-count)
(fetch-posts! {:instance-url (:instance_url application) (fetch-posts! {:instance-url (:instance_url application)
:bearer-token (:bearer_token application)}) :bearer-token (:bearer_token application)})
(refresh-displayed-posts! (:section/posts @state)))))))) (debounced-refresh! (:section/posts @state))))))))
;;; views ;;; views
@ -289,7 +287,7 @@
:on-change (fn [e] :on-change (fn [e]
(let [query (.. e -target -value)] (let [query (.. e -target -value)]
(swap! state assoc-in [:section/posts :query] (if (str/blank? query) nil query)) (swap! state assoc-in [:section/posts :query] (if (str/blank? query) nil query))
(refresh-displayed-posts! (:section/posts @state))))}]) (debounced-refresh! (:section/posts @state))))}])
(defn- debug (defn- debug
"Implements a lazy pretty-printer for whatever is passed in as `obj`. The "Implements a lazy pretty-printer for whatever is passed in as `obj`. The
@ -317,16 +315,23 @@
(drop 1))]) (drop 1))])
(defn attachment [{:keys [attachment]}] (defn attachment [{:keys [attachment]}]
(case (:type attachment) (let [preview-url (or (:preview_remote_url attachment) (:preview_url attachment))
"image" [:img {:src (:preview_url attachment) remote-url (or (:remote_url attachment) (:url attachment))
:alt (:description attachment) _ (js/console.log :preview-url preview-url :remote_url remote-url :attachment attachment)
:lazy "lazy"}] ext (last (str/split remote-url #"\."))]
"video" [:video {:controls true} (case (:type attachment)
[:source {:type (str "video/" (last (str/split (:remote_url attachment) #"\."))) "image" [:img {:src preview-url
:src (:remote_url attachment)}] :srcset (str preview-url ", " remote-url)
[:a {:href (:remote_url attachment)} (str "Original video at " (:remote_url attachment))]] :alt (:description attachment)
[:div [:strong "Unsupported attachment"] :lazy "lazy"}]
[debug attachment]])) "video" [:video {:controls true}
[:source {:type (str "video/" ext) :src remote-url}]
[:a {:href (:remote_url attachment)} (str "Original video at " (:remote_url attachment))]]
"gifv" [:video {:controls true :loop true :autoplay true}
[:source {:type (str "video/" ext) :src remote-url}]
[:a {:href (:remote_url attachment)} (str "Original video at " (:remote_url attachment))]]
[:div [:strong "Unsupported attachment"]
[debug attachment]])))
(defn post [{:keys [post]}] (defn post [{:keys [post]}]
; TODO: handle (:sensitive post) ; TODO: handle (:sensitive post)
@ -377,8 +382,8 @@
refresh-id (js/Date.now)] refresh-id (js/Date.now)]
(swap! state update-in [:section/posts :loading] conj refresh-id) (swap! state update-in [:section/posts :loading] conj refresh-id)
(. (promise-all [(db/count! ::db/posts) (. (promise-all [(db/count! ::db/posts)
(-> (db/open-cursor! ::db/posts ::db/post-created-at db/all "prev") (->> (db/open-cursor! ::db/posts ::db/post-created-at db/all "prev")
(db/transduce-cursor xform))]) (db/transduce-cursor xform))])
(then (fn [[total displayed-posts]] (then (fn [[total displayed-posts]]
(swap! state update :section/posts #(-> (assoc % :total total) (swap! state update :section/posts #(-> (assoc % :total total)
(assoc :displayed-posts displayed-posts) (assoc :displayed-posts displayed-posts)
@ -407,12 +412,10 @@
(paginate-posts! (merge defaults opts)))) (paginate-posts! (merge defaults opts))))
(defn- internal-post-id [max-or-min] (defn- internal-post-id [max-or-min]
(-> (db/open-cursor! ::db/posts ::db/post-created-at db/all (if (= max-or-min :min) (->> (db/open-cursor! ::db/posts ::db/post-created-at db/all (if (= max-or-min :min)
"next" "next"
"prev")) "prev"))
(db/transduce-cursor (comp (keep (j/get :internal_id)) (db/first-result (keep (j/get :internal_id)))))
(take 1))
(fn [_ x] x))))
(defn fetch-more-posts! [e] (defn fetch-more-posts! [e]
(.preventDefault e) (.preventDefault e)

View file

@ -103,13 +103,13 @@
Takes a transducer `xform`, a reducing function `rf` and an initial `init`. Takes a transducer `xform`, a reducing function `rf` and an initial `init`.
If no `init` is given, it will default to `(rf)`. If no `rf` is given, the If no `init` is given, it will default to `(rf)`. If no `rf` is given, the
resulting value will be a persistent vector containing the result of all steps." resulting value will be a persistent vector containing the result of all steps."
([cursor-req xform] ([xform cursor-req]
; optimization: work with a transient vector before returning the final result ; optimization: work with a transient vector before returning the final result
(-> (transduce-cursor cursor-req xform conj! (transient [])) (-> (transduce-cursor xform conj! (transient []) cursor-req)
(.then persistent!))) (.then persistent!)))
([cursor-req xform rf] ([xform rf cursor-req]
(transduce-cursor cursor-req xform rf (rf))) (transduce-cursor xform rf (rf) cursor-req))
([cursor-req xform rf init] ([xform rf init cursor-req]
(let [result (volatile! init) (let [result (volatile! init)
xform (xform rf)] xform (xform rf)]
(js/Promise. (js/Promise.
@ -121,14 +121,15 @@
; to avoid unnecessary conversion costs. ; to avoid unnecessary conversion costs.
(let [step (xform @result (.-value cursor))] (let [step (xform @result (.-value cursor))]
(if (reduced? step) (if (reduced? step)
(do (resolve @step)
(vreset! result @step)
(resolve @result))
(do (do
(vreset! result step) (vreset! result step)
(.continue cursor)))) (.continue cursor))))
(resolve @result))))))))) (resolve @result)))))))))
(defn first-result [xform cursor-req]
(transduce-cursor (comp xform (take 1)) (fn [_ x] x) cursor-req))
(def all (js/IDBKeyRange.lowerBound "")) (def all (js/IDBKeyRange.lowerBound ""))
(comment (comment