From 2b78afde3844cb2cd439e2e8623a763716dc39b6 Mon Sep 17 00:00:00 2001 From: arne Date: Thu, 20 Nov 2025 11:25:19 +0100 Subject: [PATCH 1/3] Clean up database interop --- src/computersandblues/lodestone/app.cljs | 20 ++++++++----------- src/computersandblues/lodestone/database.cljs | 17 ++++++++-------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/computersandblues/lodestone/app.cljs b/src/computersandblues/lodestone/app.cljs index 945705c..15ba487 100644 --- a/src/computersandblues/lodestone/app.cljs +++ b/src/computersandblues/lodestone/app.cljs @@ -156,10 +156,8 @@ (declare refresh-displayed-posts!) (defn- fetch-application-settings [] - (-> (db/open-cursor! ::db/application db/all) - (db/transduce-cursor (comp (take 1) - (map #(js->clj % :keywordize-keys true))) - (fn [_ x] x)))) + (->> (db/open-cursor! ::db/application db/all) + (db/first-result (map #(js->clj % :keywordize-keys true))))) (defn setup-application! "Handles Mastodon application setup on the client side" @@ -377,8 +375,8 @@ refresh-id (js/Date.now)] (swap! state update-in [:section/posts :loading] conj refresh-id) (. (promise-all [(db/count! ::db/posts) - (-> (db/open-cursor! ::db/posts ::db/post-created-at db/all "prev") - (db/transduce-cursor xform))]) + (->> (db/open-cursor! ::db/posts ::db/post-created-at db/all "prev") + (db/transduce-cursor xform))]) (then (fn [[total displayed-posts]] (swap! state update :section/posts #(-> (assoc % :total total) (assoc :displayed-posts displayed-posts) @@ -407,12 +405,10 @@ (paginate-posts! (merge defaults opts)))) (defn- internal-post-id [max-or-min] - (-> (db/open-cursor! ::db/posts ::db/post-created-at db/all (if (= max-or-min :min) - "next" - "prev")) - (db/transduce-cursor (comp (keep (j/get :internal_id)) - (take 1)) - (fn [_ x] x)))) + (->> (db/open-cursor! ::db/posts ::db/post-created-at db/all (if (= max-or-min :min) + "next" + "prev")) + (db/first-result (keep (j/get :internal_id))))) (defn fetch-more-posts! [e] (.preventDefault e) diff --git a/src/computersandblues/lodestone/database.cljs b/src/computersandblues/lodestone/database.cljs index 0ec3905..119bc6a 100644 --- a/src/computersandblues/lodestone/database.cljs +++ b/src/computersandblues/lodestone/database.cljs @@ -103,13 +103,13 @@ 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 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 - (-> (transduce-cursor cursor-req xform conj! (transient [])) + (-> (transduce-cursor xform conj! (transient []) cursor-req) (.then persistent!))) - ([cursor-req xform rf] - (transduce-cursor cursor-req xform rf (rf))) - ([cursor-req xform rf init] + ([xform rf cursor-req] + (transduce-cursor xform rf (rf) cursor-req)) + ([xform rf init cursor-req] (let [result (volatile! init) xform (xform rf)] (js/Promise. @@ -121,14 +121,15 @@ ; to avoid unnecessary conversion costs. (let [step (xform @result (.-value cursor))] (if (reduced? step) - (do - (vreset! result @step) - (resolve @result)) + (resolve @step) (do (vreset! result step) (.continue cursor)))) (resolve @result))))))))) +(defn first-result [xform cursor-req] + (transduce-cursor (comp xform (take 1)) (fn [_ x] x) cursor-req)) + (def all (js/IDBKeyRange.lowerBound "")) (comment From c91b1ff2d4a6b013e79b287b870284b10ccb0102 Mon Sep 17 00:00:00 2001 From: arne Date: Thu, 20 Nov 2025 11:25:46 +0100 Subject: [PATCH 2/3] Add support for gifs --- src/computersandblues/lodestone/app.cljs | 27 +++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/computersandblues/lodestone/app.cljs b/src/computersandblues/lodestone/app.cljs index 15ba487..af14545 100644 --- a/src/computersandblues/lodestone/app.cljs +++ b/src/computersandblues/lodestone/app.cljs @@ -315,16 +315,23 @@ (drop 1))]) (defn attachment [{:keys [attachment]}] - (case (:type attachment) - "image" [:img {:src (:preview_url attachment) - :alt (:description attachment) - :lazy "lazy"}] - "video" [:video {:controls true} - [:source {:type (str "video/" (last (str/split (:remote_url attachment) #"\."))) - :src (:remote_url attachment)}] - [:a {:href (:remote_url attachment)} (str "Original video at " (:remote_url attachment))]] - [:div [:strong "Unsupported attachment"] - [debug attachment]])) + (let [preview-url (or (:preview_remote_url attachment) (:preview_url attachment)) + remote-url (or (:remote_url attachment) (:url attachment)) + _ (js/console.log :preview-url preview-url :remote_url remote-url :attachment attachment) + ext (last (str/split remote-url #"\."))] + (case (:type attachment) + "image" [:img {:src preview-url + :srcset (str preview-url ", " remote-url) + :alt (:description attachment) + :lazy "lazy"}] + "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]}] ; TODO: handle (:sensitive post) From 8d7e4dde0ec39440bb924b6ad0d0355af20527a6 Mon Sep 17 00:00:00 2001 From: arne Date: Thu, 20 Nov 2025 12:19:48 +0100 Subject: [PATCH 3/3] Debounce refresh when typing --- src/computersandblues/lodestone/app.cljs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/computersandblues/lodestone/app.cljs b/src/computersandblues/lodestone/app.cljs index af14545..70cd04d 100644 --- a/src/computersandblues/lodestone/app.cljs +++ b/src/computersandblues/lodestone/app.cljs @@ -153,7 +153,7 @@ (obtain-oauth-authorization-code! application)))))) (declare fetch-posts!) -(declare refresh-displayed-posts!) +(declare debounced-refresh!) (defn- fetch-application-settings [] (->> (db/open-cursor! ::db/application db/all) @@ -200,7 +200,7 @@ (if (zero? post-count) (fetch-posts! {:instance-url (:instance_url application) :bearer-token (:bearer_token application)}) - (refresh-displayed-posts! (:section/posts @state)))))))) + (debounced-refresh! (:section/posts @state)))))))) ;;; views @@ -287,7 +287,7 @@ :on-change (fn [e] (let [query (.. e -target -value)] (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 "Implements a lazy pretty-printer for whatever is passed in as `obj`. The