This commit is contained in:
arne 2025-11-18 14:08:24 +01:00
commit eb2b10571d
4 changed files with 44 additions and 44 deletions

View file

@ -4,7 +4,8 @@
[applied-science.js-interop :as j]
[clojure.string :as str]
[clojure.pprint :as pprint]
[computersandblues.lodestone.database :as db]))
[computersandblues.lodestone.database :as db]
[computersandblues.lodestone.match :refer [query->matching-fn]]))
(defonce state (r/atom {:root nil
@ -22,6 +23,14 @@
:total 0
:displayed-posts []}}))
; TODO Ensure that user's handles are up to date
; TODO Manually fetch older / newer favorites
; TODO Handle 429
; TODO Search for tags (`#foo`) and handles (`@bar`)
; TODO Explain which kind of search currently is possible
;; Mastodon API helpers
(defn- link-header
@ -133,13 +142,6 @@
(declare fetch-posts!)
(declare refresh-displayed-posts!)
(comment
(-> (db/open-cursor! ::db/application db/all)
(db/transduce-cursor (comp (take 1)
(map )))
(.then db/cursor-value))
)
(defn setup-application!
"Handles Mastodon application setup on the client side"
[]
@ -233,6 +235,7 @@
(seq (:body response)))
on-response on-response
on-error on-error}}]
(js/console.log 'fetch-favorites! instance-url max-id bearer-token)
((fn fetch-favorites' [url]
(let [req-id (js/Date.now)]
(println :calling url)
@ -243,12 +246,12 @@
(if (continue? response)
(js/setTimeout #(fetch-favorites' (link-header "next" (:raw response))) 500)
(when (= req-id (-> @state :section/posts :loading))
(swap! state update :section/posts dissoc :loading))))
(.catch (fn [response]
(when (= req-id (-> @state :section/posts :loading))
(swap! state update :section/posts dissoc :loading))
(on-error response))))))
(favorites-url {:instance-url instance-url :max-id max-id}))))
(swap! state update :section/posts dissoc :loading)))))
(.catch (fn [response]
(when (= req-id (-> @state :section/posts :loading))
(swap! state update :section/posts dissoc :loading))
(on-error response))))))
(favorites-url {:instance-url instance-url :max-id max-id})))
;;; views
@ -321,29 +324,17 @@
[:div.content {:dangerouslySetInnerHTML (r/unsafe-html (:content post))}
(when (seq (:media_attachments post))
[:div.attachments (map-indexed (fn [idx item]
^{:key idx} [attachment {:attachment item}]
(:media_attachments post)))])]
^{:key idx} [attachment {:attachment item}])
(:media_attachments post))])]
#_[debug post]])
(defn ->regex [s]
(try
(js/RegExp. s "i")
(catch js/Error _
(js/RegExp. (js/RegExp.escape s) "i"))))
(defn- refresh-displayed-posts!
[posts-section]
(let [{:keys [per-page query]} posts-section
matches? (if query
(partial re-find (->regex query))
(constantly true))
; this `xform` is responsible for filtering and building the final list
; of results by iterating through the posts in the database.
xform (comp
(filter (fn [post]
(or (matches? (j/get post :content))
(matches? (j/get-in post [:account :acct])) ; search for url + username of poster
(some #(matches? (j/get % :username)) (j/get post :mentions))))) ; search only for username of mentions
(filter (query->matching-fn query))
(take per-page)
(map #(js->clj % :keywordize-keys true)))
refresh-id (js/Date.now)]
@ -352,11 +343,9 @@
(-> (db/open-cursor! ::db/posts db/all "prev")
(db/transduce-cursor xform))])
(.then (fn [[total displayed-posts]]
(swap! state update :section/posts #(let [v (-> (assoc % :total total)
(assoc :displayed-posts displayed-posts))]
(if (= refresh-id (:loading %))
(dissoc v :loading)
v))))))))
(swap! state update :section/posts #(-> (assoc % :total total)
(assoc :displayed-posts displayed-posts)
(cond-> (= refresh-id (:loading %)) (dissoc :loading)))))))))
(def debounced-refresh! (debounce 20 (partial refresh-displayed-posts!)))
@ -382,8 +371,8 @@
(when loading " …")
#_(cond (= api-state :loading) " …"
(= api-state :error) " API Error!")]]
[:ul.results (map-indexed (fn [idx favorite]
^{:key idx} [:li [post {:post favorite}]]) displayed-posts)]
[:ul.results (map-indexed (fn [idx p]
^{:key idx} [:li [post {:post p}]]) displayed-posts)]
#_[:div.load-buttons
[:button
{:on-click (fn [_]

View file

@ -1,5 +1,4 @@
(ns computersandblues.lodestone.database
(:require [clojure.string :as str]))
(ns computersandblues.lodestone.database)
(defonce +db+ (atom nil))
@ -73,9 +72,6 @@
(let [store (open-store @+db+ store-id)]
(.openCursor store key-range direction))))
(defn cursor-value [cursor]
(js->clj (some-> cursor .-value) :keywordize-keys true))
#_(defn logging [f]
(let [n (volatile! 0)]
(fn [& args]

View file

@ -0,0 +1,17 @@
(ns computersandblues.lodestone.match
(:require [applied-science.js-interop :as j]))
(defn ->regex [s]
(try
(js/RegExp. s "i")
(catch js/Error _
(js/RegExp. (js/RegExp.escape s) "i"))))
(defn query->matching-fn [query]
(let [match? (if query
(partial re-find (->regex query))
(constantly true))]
(fn [post]
(or (match? (j/get post :content))
(match? (j/get-in post [:account :acct])) ; search for url + username of poster
(some #(match? (j/get % :username)) (j/get post :mentions))))))