From a8db802e43a36d359eb46deef41f7edbcda7724c Mon Sep 17 00:00:00 2001 From: "Robert C. Martin" Date: Thu, 23 Feb 2023 16:24:22 -0600 Subject: [PATCH] Manage relays menu is working, sort of. --- src/more_speech/nostr/protocol.clj | 29 +++++---- src/more_speech/nostr/relays.clj | 2 +- src/more_speech/ui/swing/main_window.clj | 75 ++++++++++++++++++++++-- 3 files changed, 91 insertions(+), 15 deletions(-) diff --git a/src/more_speech/nostr/protocol.clj b/src/more_speech/nostr/protocol.clj index 9a867f1..8c07c77 100644 --- a/src/more_speech/nostr/protocol.clj +++ b/src/more_speech/nostr/protocol.clj @@ -51,26 +51,31 @@ (defn unsubscribe [relay id] (relay/send relay ["CLOSE" id])) +(defn close-relay [relay] + (relay/close relay) + (swap! relays assoc-in [(::ws-relay/url relay) :connection] nil)) + (defn close-connection [relay id] (unsubscribe relay id) - (relay/close relay)) + (close-relay relay) + ) (defn handle-relay-message [relay message] (let [url (::ws-relay/url relay)] (swap! config/websocket-backlog inc) (send-off events/event-agent handlers/handle-event message url))) -(defn subscribe-to-relay [url id date now] +(defn subscribe-to-relay [url id since now] (let [relay (get-in @relays [url :connection]) read-type (get-in @relays [url :read])] (when (and (or (not= :false read-type) (not= :no-read read-type)) (some? relay)) (condp = read-type - true (subscribe-all relay id date now) - :read-all (subscribe-all relay id date now) - :read-trusted (subscribe-trusted relay id date now) - :read-web-of-trust (subscribe-web-of-trust relay id date now) + true (subscribe-all relay id since now) + :read-all (subscribe-all relay id since now) + :read-trusted (subscribe-trusted relay id since now) + :read-web-of-trust (subscribe-web-of-trust relay id since now) nil) (swap! relays assoc-in [url :subscribed] true)))) @@ -114,8 +119,10 @@ now (quot (System/currentTimeMillis) 1000) minutes-10 600 date (- now minutes-10) - retrying (get-in @relays [url :retrying])] - (when-not retrying + retrying (get-in @relays [url :retrying]) + active (or (get-in @relays [url :write]) + (not= :read-none (get-in @relays [url :read])))] + (when (and (not retrying) active) (prn 'relay-closed url) (swap! relays assoc-in [url :retrying] true) (swap! relays assoc-in [url :connection] nil) @@ -131,10 +138,12 @@ (connect-to-relay relay) (subscribe-to-relay url (str config/subscription-id-base "-reconnect") date now)))))) +(defn make-relay [url] + (ws-relay/make url {:recv handle-relay-message + :close handle-close})) (defn connect-to-relays [] (doseq [url (keys @relays)] - (let [relay (ws-relay/make url {:recv handle-relay-message - :close handle-close})] + (let [relay (make-relay url)] (connect-to-relay relay))) (prn 'relay-connection-attempts-complete)) diff --git a/src/more_speech/nostr/relays.clj b/src/more_speech/nostr/relays.clj index 687ff11..d3cb9c6 100644 --- a/src/more_speech/nostr/relays.clj +++ b/src/more_speech/nostr/relays.clj @@ -8,7 +8,7 @@ (defn- connection? [c] (= (::relay/type c) ::ws-relay/websocket)) -(s/def ::read #{:read-all :read-trusted :read-web-of-trust}) +(s/def ::read #{:read-all :read-trusted :read-web-of-trust :read-none}) (s/def ::write boolean?) (s/def ::retries integer?) (s/def ::retrying boolean?) diff --git a/src/more_speech/ui/swing/main_window.clj b/src/more_speech/ui/swing/main_window.clj index 7d5fe08..b53d6b9 100644 --- a/src/more_speech/ui/swing/main_window.clj +++ b/src/more_speech/ui/swing/main_window.clj @@ -11,7 +11,9 @@ [more-speech.config :as config :refer [get-db]] [more-speech.ui.formatter-util :as formatter-util] [more-speech.nostr.util :as util] - [clojure.string :as string]) + [clojure.string :as string] + [clojure.set :as set] + [more-speech.nostr.protocol :as protocol]) (:use [seesaw core]) (:import (javax.swing Timer) (javax.swing.event HyperlinkEvent$EventType))) @@ -53,13 +55,78 @@ name (formatter-util/abbreviate (:name profile) 20)] (format "%-20s %s %s" name (util/num32->hex-string id) (:picture profile)))) +(defn reconnect-to-relay [url] + (let [relay (get-in @relays [url :connection]) + relay (if (some? relay) relay (protocol/make-relay url)) + now (util/get-now)] + (-> relay protocol/close-relay protocol/connect-to-relay) + (protocol/subscribe-to-relay url config/subscription-id-base (- now 3600) now) + )) + +(defn set-relay-read [label url read-type _e] + (swap! relays assoc-in [url :read] read-type) + (config! label :text (str read-type)) + (reconnect-to-relay url)) + +(defn set-relay-write [label url write-type _e] + (swap! relays assoc-in [url :write] write-type) + (config! label :text (str write-type)) + (reconnect-to-relay url)) + +(defn read-click [url e] + (when (.isPopupTrigger e) + (let [x (.x (.getPoint e)) + y (.y (.getPoint e)) + label (.getComponent e) + p (popup :items [(action :name "none" :handler (partial set-relay-read label url :read-none)) + (action :name "all" :handler (partial set-relay-read label url :read-all)) + (action :name "trusted" :handler (partial set-relay-read label url :read-trusted)) + (action :name "web of trust" :handler (partial set-relay-read label url :read-web-of-trust))])] + (.show p (to-widget e) x y)))) + +(defn write-click [url e] + (when (.isPopupTrigger e) + (let [x (.x (.getPoint e)) + y (.y (.getPoint e)) + label (.getComponent e) + p (popup :items [(action :name "true" :handler (partial set-relay-write label url true)) + (action :name "false" :handler (partial set-relay-write label url false)) + ])] + (.show p (to-widget e) x y)))) + +(defn is-connected? [url] + (some? (get-in @relays [url :connection]))) + +(defn make-relay-element [url] + (let [relay (get @relays url) + name (label :text (re-find config/relay-pattern url) :size [250 :by 20]) + connection-label (label :text (if (is-connected? url) "✓" "X") :size [10 :by 20]) + read-label (text :text (str (:read relay)) :editable? false :size [100 :by 20]) + write-label (text :text (str (:write relay)) :size [40 :by 20]) + element (horizontal-panel :size [500 :by 20] :items [name connection-label read-label write-label])] + (listen read-label :mouse-pressed (partial read-click url)) + (listen write-label :mouse-pressed (partial write-click url)) + element)) + +(defn show-relays [_e] + (let [relay-frame (frame :title "Relays" :size [500 :by 500]) + all-relay-urls (set (keys @relays)) + connected-relays (set (filter #(or (not= :read-none (:read (get @relays %))) + (:write (get @relays %))) all-relay-urls)) + unconnected-relays (set/difference all-relay-urls connected-relays) + connected-elements (map make-relay-element connected-relays) + unconnected-elements (map make-relay-element unconnected-relays) + relay-box (scrollable (vertical-panel :items (concat connected-elements unconnected-elements))) + ] + (config! relay-frame :content relay-box) + (show! relay-frame))) + (defn make-menubar [] - (let [relays-item (menu-item :text "Relays...") + (let [relays-item (menu-item :action (action :name "Relays..." :handler show-relays)) users-item (menu-item :text "Users...") profile-item (menu-item :text "Profile...") manage-menu (menu :text "Manage" :items [relays-item users-item profile-item]) - menu-bar (menubar :items [manage-menu]) - ] + menu-bar (menubar :items [manage-menu])] menu-bar)) (defn make-main-window []