Prepare for placing 'open' buttons on article threads.

This commit is contained in:
Robert C. Martin 2022-02-08 13:38:04 -06:00
parent a6b4fdcdcc
commit 4cdb70033c
6 changed files with 120 additions and 75 deletions

View File

@ -32,9 +32,9 @@
(should (s/valid? ::a/article article)))
(it "is properly formatted"
(should= [
(should= [:open-button
:bold
"* Bob"
"Bob"
:regular
" (15)"
:bold

View File

@ -46,21 +46,26 @@
(abbreviate pubkey 8))
(defn markup-article [article]
[
:bold
(str "* " (abbreviate-author (:author article)))
:regular
(str " (" (:thread-count article) ")")
:bold
:pos 40
(:subject article)
:regular
:pos 80
(format-time (:time article))
:new-line
:multi-line (abbreviate-body (:body article))
:line
:new-line])
(let [
thread-count (:thread-count article)]
[
(if (> thread-count 0)
:open-button
:null-button)
:bold
(abbreviate-author (:author article))
:regular
(str " (" thread-count ")")
:bold
:pos 40
(:subject article)
:regular
:pos 80
(format-time (:time article))
:new-line
:multi-line (abbreviate-body (:body article))
:line
:new-line]))
(defn markup-author [[pubkey name]]
[:bold

View File

@ -1,8 +1,23 @@
(ns more-speech.nostr.events
(:require [more-speech.content.article :as article]
(:require [clojure.spec.alpha :as s]
[more-speech.content.article :as article]
[clojure.data.json :as json]
[more-speech.nostr.util :refer [hex-string->num]]))
(s/def ::id number?)
(s/def ::pubkey number?)
(s/def ::created-at number?)
(s/def ::content string?)
(s/def ::sig number?)
(s/def ::tag (s/tuple keyword? number?))
(s/def ::tags (s/coll-of ::tag))
(s/def ::references (s/coll-of number?))
(s/def ::event (s/keys :req-un [::id
::pubkey
::created-at
::content
::sig
::tags
::references]))
(declare process-text-event)
(defn process-event [{:keys [application] :as state} event]

View File

@ -1,5 +1,6 @@
(ns more-speech.ui.application
(:require [more-speech.ui.widget :refer [widget
(:require [clojure.spec.alpha :as s]
[more-speech.ui.widget :refer [widget
draw-widget
draw-child-widgets
setup-child-widgets]]
@ -7,7 +8,16 @@
draw-article-window]]
[more-speech.ui.author-window :refer [map->author-window
draw-author-window]]
[more-speech.ui.graphics :as g]))
[more-speech.ui.graphics :as g]
[more-speech.nostr.events :as events]))
(s/def ::nicknames (s/map-of number? string?))
(s/def ::chronological-text-events (s/coll-of number?))
(s/def ::text-event-map (s/map-of number? ::events/event))
(s/def ::application (s/keys :req-un [::nicknames
::chronological-text-events
::text-event-map
]))
(declare setup-application)

View File

@ -1,6 +1,6 @@
(ns more-speech.ui.article-window
(:require
[more-speech.ui.cursor :as text]
[more-speech.ui.cursor :as cursor]
[more-speech.content.article :as a]
[more-speech.ui.widget :refer [widget]]
[more-speech.ui.button :refer [map->button
@ -16,59 +16,66 @@
(defrecord article-window [x y w h page-up page-down display-position]
widget
(setup-widget [widget state]
(assoc widget :display-position 0
:page-up (map->button {:x (+ x 20) :y (+ y h -30) :h 20 :w 20
:left-down scroll-up
:left-held scroll-up
:draw up-arrow})
:page-down (map->button {:x (+ x w -20) :y (+ y h -30) :h 20 :w 20
:left-down scroll-down
:left-held scroll-down
:draw down-arrow})
))
(let [scroll-up (partial scroll-up (:path widget))
scroll-down (partial scroll-down (:path widget))]
(assoc widget :display-position 0
:page-up (map->button {:x (+ x 20) :y (+ y h -30) :h 20 :w 20
:left-down scroll-up
:left-held scroll-up
:draw up-arrow})
:page-down (map->button {:x (+ x w -20) :y (+ y h -30) :h 20 :w 20
:left-down scroll-down
:left-held scroll-down
:draw down-arrow})
)))
(update-widget [widget state]
state)
(draw-widget [widget state]
(draw-article-window (:application state) widget))
(draw-article-window state widget))
)
(defn- scroll-up [button state]
(let [button-path (:path button)
parent-path (drop-last button-path)
article-window (get-in state parent-path)
(defn- scroll-up [widget-path button state]
(let [article-window (get-in state widget-path)
articles (get-in state [:application :chronological-text-events])
display-position (:display-position article-window)
display-position (min (count articles) (inc display-position))
article-window (assoc article-window :display-position display-position)
state (assoc-in state parent-path article-window)]
state (assoc-in state widget-path article-window)]
state))
(defn- scroll-down [button state]
(let [button-path (:path button)
parent-path (drop-last button-path)
article-window (get-in state parent-path)
(defn- scroll-down [widget-path button state]
(let [article-window (get-in state widget-path)
display-position (:display-position article-window)
display-position (max 0 (dec display-position))
article-window (assoc article-window :display-position display-position)
state (assoc-in state parent-path article-window)]
state (assoc-in state widget-path article-window)]
state))
(defn- open-button [cursor]
(cursor/draw-text cursor "+"))
(defn- null-button [cursor]
(cursor/draw-text cursor " "))
(defn draw-article [window cursor article]
(let [g (:graphics cursor)]
(g/text-align g [:left])
(g/fill g [0 0 0])
(text/render cursor window (a/markup-article article)))
(cursor/render cursor window (a/markup-article article)
{:open-button open-button
:null-button null-button}))
)
(defn draw-articles [application window]
(let [g (:graphics application)
(defn draw-articles [state window]
(let [application (:application state)
g (:graphics application)
nicknames (:nicknames application)
article-map (:text-event-map application)
articles (:chronological-text-events application)
display-position (:display-position window)
articles (drop display-position articles)
articles (take 19 articles)]
(loop [cursor (text/->cursor g 0 (g/line-height g) 5)
(loop [cursor (cursor/->cursor g 0 (g/line-height g) 5)
articles articles]
(if (empty? articles)
cursor
@ -81,8 +88,9 @@
(recur (draw-article window cursor article)
(rest articles)))))))
(defn draw-article-window [application window]
(let [g (:graphics application)]
(defn draw-article-window [state window]
(let [application (:application state)
g (:graphics application)]
(g/with-translation
g [(:x window) (:y window)]
(fn [g]
@ -90,5 +98,5 @@
(g/stroke-weight g 2)
(g/fill g [255 255 255])
(g/rect g [0 0 (:w window) (:h window)])
(draw-articles application window))
(draw-articles state window))
)))

View File

@ -52,28 +52,35 @@
cursor
(recur (draw-line cursor (first lines)) (rest lines)))))
(defn render [cursor window markup]
(let [g (:graphics cursor)
{:keys [bold regular]} (:fonts g)]
(loop [cursor cursor
markup markup]
(cond
(empty? markup) cursor
(= :bold (first markup)) (do (g/text-font g bold)
(recur cursor (rest markup)))
(= :regular (first markup)) (do (g/text-font g regular)
(recur cursor (rest markup)))
(= :pos (first markup)) (recur (set-pos cursor (second markup))
(drop 2 markup))
(= :new-line (first markup)) (recur (-> cursor (set-x 0) (new-lines 1))
(rest markup))
(= :line (first markup)) (do (g/stroke-weight g 1)
(g/line g [0 (:y cursor) (:w window) (:y cursor)])
(recur cursor (rest markup)))
(= :multi-line (first markup)) (recur (draw-multi-line cursor (second markup))
(drop 2 markup))
(string? (first markup)) (recur (draw-text cursor (first markup))
(rest markup))
:else (recur (draw-text cursor (.toString (first markup)))
(rest markup)))
)))
(defn render
([cursor window markup]
(render cursor window markup {}))
([cursor window markup artifacts]
(let [g (:graphics cursor)
{:keys [bold regular]} (:fonts g)]
(loop [cursor cursor
markup markup]
(cond
(empty? markup) cursor
(= :bold (first markup)) (do (g/text-font g bold)
(recur cursor (rest markup)))
(= :regular (first markup)) (do (g/text-font g regular)
(recur cursor (rest markup)))
(= :pos (first markup)) (recur (set-pos cursor (second markup))
(drop 2 markup))
(= :new-line (first markup)) (recur (-> cursor (set-x 0) (new-lines 1))
(rest markup))
(= :line (first markup)) (do (g/stroke-weight g 1)
(g/line g [0 (:y cursor) (:w window) (:y cursor)])
(recur cursor (rest markup)))
(= :multi-line (first markup)) (recur (draw-multi-line cursor (second markup))
(drop 2 markup))
(keyword? (first markup)) (let [k (first markup)
f (get artifacts k)]
(recur (f cursor) (rest markup)))
(string? (first markup)) (recur (draw-text cursor (first markup))
(rest markup))
:else (recur (draw-text cursor (.toString (first markup)))
(rest markup)))
))))