]> code.bitgloo.com Git - clyne/lemmold.git/commitdiff
code documentation and refactoring
authorClyne Sullivan <clyne@bitgloo.com>
Sat, 15 Jul 2023 12:35:10 +0000 (08:35 -0400)
committerClyne Sullivan <clyne@bitgloo.com>
Sat, 15 Jul 2023 12:35:10 +0000 (08:35 -0400)
src/lemmold/core.clj

index c08d30f77dc43bcfa0f7751d1352d2c03238b03c..ab366d4061b506c2504b891b091e763037b87354 100644 (file)
@@ -2,19 +2,42 @@
   (:require [clj-http.client :as client])
   (:require [clojure.data.json :as json]))
 
-(def POST-LIST "/post/list")
-(def COMMENTS "/comment/list")
-
-(defn make-api-url [inst endpoint]
-    (str "https://" inst "/api/v3" endpoint))
-
-(defn api-call [api-url query-params]
+(def DEFAULT-INSTANCE
+  "The default instance to access."
+  "lemmy.ml")
+(def POST-PAGESIZE
+  "Number of posts to show per 'page'. Set by the API."
+   5)
+(def COMMENT-PAGESIZE
+  "Number of comments to show per 'page'. Kept low for smaller screens."
+  1)
+(def COMMENT-LIMIT
+  "Maximum number of comments to retrieve for a post."
+  50)
+
+(def POST-LIST
+  "API endpoint for post list."
+  "/post/list")
+(def COMMENTS
+  "API endpoint for comment list (of a given post)."
+  "/comment/list")
+
+(defn make-api-url
+  "Builds URL for API request given the instance and endpoint."
+  [inst endpoint]
+  (str "https://" inst "/api/v3" endpoint))
+
+(defn api-call
+  "Completes an API request, returning the processed JSON."
+  [api-url query-params]
   (-> api-url
       (client/get {:accept :json :query-params query-params})
       (get :body)
       (json/read-str)))
 
-(defn post-list [instance community page]
+(defn post-list
+  "Fetches a post list from the given instance and endpoint."
+  [instance community page]
   (let [query-params (cond-> {:sort "Hot" :page (str page)}
                              (not (empty? community))
                              (assoc :community_name community))]
         (api-call query-params)
         (get "posts"))))
 
-(defn comments-list [instance post]
+(defn comments-list
+  "Fetches the comment list for a given post."
+  [instance post]
   (-> (make-api-url instance COMMENTS)
-      (api-call {:limit "50" :post_id (str (get-in post ["post" "id"]))})
+      (api-call {:limit (str COMMENT-LIMIT)
+                 :post_id (str (get-in post ["post" "id"]))})
       (get "comments")))
 
-(defn show-post-item [index post]
+(defn show-post-item
+  "Renders a listing of the given post. Index is for user selection."
+  [index post]
   (let [items [["creator" "name"]
                ["community" "name"]
                ["post" "name"]
         data (cons (inc index) (mapv (partial get-in post) items))]
     (apply (partial printf "%d. %s on %s\n   %s\n   at %s (%d comments)\n\n") data)))
 
-(defn show-comment-item [commnt]
+(defn show-comment-item
+  "Renders the given comment (from a post)."
+  [commnt]
   (println (get-in commnt ["creator" "name"]) "says:")
   (println (get-in commnt ["comment" "content"]))
-  (println)
-  )
+  (println))
 
-(defn show-posts [posts]
-  (doseq [index (range 0 5)]
+(defn show-posts
+  "Displays a page's worth of post listings."
+  [posts]
+  (doseq [index (range 0 POST-PAGESIZE)]
     (show-post-item index (nth posts index))))
 
-(defn show-comments [comments]
-  (doseq [commnt (take 1 comments)]
+(defn show-comments
+  "Displays a page's worth of comments."
+  [comments]
+  (doseq [commnt (take COMMENT-PAGESIZE comments)]
     (show-comment-item commnt)))
 
-(defn show-posts-prompt []
-  (print "#NPQ> ")
+(defn show-posts-prompt
+  "Collects user input at post listing menu."
+  []
+  (print "#NPCIQ> ")
   (flush)
   (first (read-line)))
 
-(defn show-comments-prompt []
+(defn show-comments-prompt
+  "Collects user input at comment listing menu."
+  []
   (print "BNP> ")
   (flush)
   (first (read-line)))
   (read-line))
 
 (defn show-instance-prompt []
-  (print "Enter instance name [lemmy.ml]: ")
+  (printf "Enter instance name [%s]: " DEFAULT-INSTANCE)
   (flush)
-  (let [inst (read-line)] (if (empty? inst) "lemmy.ml" inst)))
+  (let [inst (read-line)] (if (empty? inst) DEFAULT-INSTANCE inst)))
 
-(defn view-post [instance post]
+(defn view-post
+  "Main loop for viewing a post and its comments."
+  [instance post]
   (loop [offset 0 comments (comments-list instance post)]
     (println)
-    (show-comments (if (pos? offset) (drop (* 1 offset) comments) comments))
+    (show-comments (drop (* COMMENT-PAGESIZE offset) comments))
     (case (show-comments-prompt)
       \B (println)
       \N (recur (inc offset) comments)
       \P (recur (dec offset) comments)
       (do (println "Unknown command.") (recur offset comments)))))
 
-(defn view-page [instance init-community]
-  (loop [top true community init-community page 1 posts (post-list instance community page)]
+(defn view-nth-post
+  "Views the index-th post from the current post list."
+  [state posts index]
+  (view-post
+    (:instance state)
+    (nth posts (cond-> (+ 5 index) (:top state) (- 5))))
+  state)
+
+(defn get-post-list
+  "Fetches a new list of posts given the current (view-page) state."
+  [state]
+  (post-list (:instance state) (:community state) (:page state)))
+
+(defn next-page
+  "Updates state for viewing the next page of posts."
+  [state]
+  (if (:top state)
+    (assoc state :top false)
+    (-> state (assoc :top true) (update :page inc))))
+
+(defn prev-page
+  "Updates state for viewing the previous page of posts."
+  [state]
+  (if-not (:top state)
+    (assoc state :top true)
+    (-> state (assoc :top false) (update :page dec))))
+
+(defn change-community
+  "Updates state for viewing a different community."
+  [state]
+  (-> state
+      (assoc :top true)
+      (assoc :page 1)
+      (assoc :community (show-community-prompt))))
+
+(defn change-instance
+  "Updates state for viewing a different instance."
+  [state]
+  (-> state
+      (assoc :instance (show-instance-prompt))
+      (change-community)))
+
+(defn view-page
+  "Main loop for viewing posts listings."
+  [init-instance init-community]
+  (loop [state {:top true
+                :instance init-instance
+                :community init-community
+                :page 1}
+         posts (get-post-list state)]
     (println)
-    (show-posts (if top posts (drop 5 posts)))
+    (show-posts (if (:top state) posts (drop POST-PAGESIZE posts)))
     (case (show-posts-prompt)
-      \N (if top (recur false community page posts)
-                 (recur true community (inc page) (post-list instance community (inc page))))
-      \P (if top (recur false community (dec page) (post-list instance community (dec page)))
-                 (recur true community page posts))
+      \N (let [new-state (next-page state)]
+           (recur new-state (if (:top new-state) (get-post-list new-state) posts)))
+      \P (let [new-state (prev-page state)]
+           (recur new-state (if (:top new-state) posts (get-post-list new-state))))
       \Q (println)
-      \1 (do (view-post instance (nth posts (cond-> 5 top (- 5)))) (recur top community page posts))
-      \2 (do (view-post instance (nth posts (cond-> 6 top (- 5)))) (recur top community page posts))
-      \3 (do (view-post instance (nth posts (cond-> 7 top (- 5)))) (recur top community page posts))
-      \4 (do (view-post instance (nth posts (cond-> 8 top (- 5)))) (recur top community page posts))
-      \5 (do (view-post instance (nth posts (cond-> 9 top (- 5)))) (recur top community page posts))
-      \C (let [comm (show-community-prompt)] (recur true comm 1 (post-list instance comm page)))
-      (do (println "Unknown command.") (recur top community page posts)))))
+      \1 (recur (view-nth-post state posts 0) posts)
+      \2 (recur (view-nth-post state posts 1) posts)
+      \3 (recur (view-nth-post state posts 2) posts)
+      \4 (recur (view-nth-post state posts 3) posts)
+      \5 (recur (view-nth-post state posts 4) posts)
+      \C (let [new-state (change-community state)]
+           (recur new-state (get-post-list new-state)))
+      \I (let [new-state (change-instance state)]
+           (recur new-state (get-post-list new-state)))
+      (do (println "Unknown command.") (recur state posts)))))
 
 (defn -main [& args]
   (println "Welcome to lemmold, your old-school Lemmy browser!")