startup user selection

This commit is contained in:
Aidan 2020-12-03 21:19:26 -08:00
parent 170c4cb559
commit 23dd2ee3b3
No known key found for this signature in database
GPG key ID: 327711E983899316
4 changed files with 110 additions and 73 deletions

View file

@ -17,15 +17,19 @@
(def dbpath "/tmp/temp_db")
(def sockpath "/var/run/signald/signald.sock")
(def user (atom {}))
(def link-status (atom false))
;; TODO: handle multi users (with list ui)
(defn handle-users
[data]
(let [users (get-in data ["data" "accounts"])]
(if (> (count users) 1)
(log/info "Alert, multi account not supported yet. picking first on list"))
(reset! user (first users)))
(disassoc-callback-type "account_list"))
[sigd data]
(paint-user-select
(get-in data ["data" "accounts"])
true
(fn [x _]
;; TODO: dont magic string this
(if (= (get x "username") "Link New User")
(make-req sigd {"type" "link"})
(reset! user x)))))
(defn digest-group-or-contact-list
[list db]
@ -55,10 +59,12 @@
;; register callbacks between the UI and signald
(assoc-callback-type "version" (fn [x] (add-str-flag (get-version-from-version-message x))))
(assoc-callback-type "linking_uri" (fn [x] (paint-linking x)))
(assoc-callback-type "linking_successful" (fn [_] (paint-linking nil)))
(assoc-callback-type "linking_error" (fn [_]
(paint-linking nil)
(add-str-flag "Linking returned Error")))
(assoc-callback-type "linking_successful" (fn [_] (paint-linking nil)
(reset! link-status true)))
(assoc-callback-type "linking_error" (fn [_] (paint-linking nil)
(log/error "Linking failed")
(add-str-flag "Linking failed")
(reset! link-status true)))
(assoc-callback-type "unexpected_error" (fn [x] (add-str-flag (str "Unexpected error: "
(get-in x ["data" "message"])))))
(assoc-callback-type "contacts_list" (fn [x] (digest-group-or-contact-list
@ -72,43 +78,60 @@
sigd-loop (thread (callback-loop sigd-output))]
;; handle login basically
(assoc-callback-type "account_list"
(fn [x]
(if (< (count (get-in x ["data" "accounts"])) 1)
(do (make-link-data-req sigd-input)
;; recur via callback
(make-list-accounts-req sigd-input))
(handle-users x))))
(assoc-callback-type "account_list" (fn [x] (handle-users sigd-input x)))
;; log in every time user state changes
;; another way we could do this is to have a callback triggered on a
;; signald message type of "subscribed"
;; but I thought it would be more efficient to just watch for results
;; from the call to handle-users
;; ALSO: close account picker
(add-watch user :login-manager
(fn [key atom old-state new-state]
(let [old-user (get old-state "username")
new-user (get new-state "username")]
(log/info key " changed state from "
(if (not= old-user new-user)
(do (log/info key " changed state from "
old-user " to " new-user)
;; unsub from old acc
(if (some? old-user)
;; TODO: make this a do statement
;; TODO: make this a, do statement
;; add a call to reset the UI
(make-unsubscribe-req sigd-input old-user))
(make-req sigd-input ("type" "unsubscribe"
"username" old-user)))
;; sub to new account
(if (some? new-user)
(do
(make-subscribe-req sigd-input new-user)
(make-contact-sync-req sigd-input new-user)
(make-contact-list-req sigd-input new-user)
(make-group-list-req sigd-input new-user))))))
(make-req sigd-input {"type" "subscribe"
"username" new-user})
(make-req sigd-input {"type" "sync_contacts"
"username" new-user})
(make-req sigd-input {"type" "list_contacts"
"username" new-user})
(make-req sigd-input {"type" "list_groups"
"username" new-user})
;; TODO: load messages or something
;; maybe wait till here to paint main UI
(add-str-flag (str "Now logged in as " new-user))
))
;; close account picker
(paint-user-select [] false (fn [_ _] (log/error "this cannot be called"))))))))
;; whenever a link account operation finishes, retrigger handle-users
(add-watch link-status :linking-manager
(fn [key atom old-state new-state]
(if (and (not= old-state new-state) new-state)
(do
(log/info key " has detected a link account operation finished.")
(reset! link-status false)
(make-req sigd-input {"type" "list_accounts"})))))
;; find avail accounts
(make-list-accounts-req sigd-input)
(make-req sigd-input {"type" "list_accounts"})
;; finally, block on signald loop till return
(<!! sigd-loop))))

View file

@ -55,44 +55,9 @@
c-id)))
;; sends data to signal socket
;; expects data to be a map
;; adds a newline
(defn -make-req
(defn make-req
[output-stream data]
(try (.write output-stream (str data "\n")) (.flush output-stream)
(try (.write output-stream (str (json/write-str data) "\n")) (.flush output-stream)
(catch Exception e (log/error e "Error sending to signald"))))
(defn make-link-data-req
[output-stream]
(-make-req output-stream "{\"type\": \"link\"}"))
(defn make-list-accounts-req
[output-stream]
(-make-req output-stream "{\"type\": \"list_accounts\"}"))
(defn make-subscribe-req
[output-stream username]
(-make-req output-stream
(json/write-str {"type" "subscribe"
"username" username})))
(defn make-unsubscribe-req
[output-stream username]
(-make-req output-stream
(json/write-str {"type" "unsubscribe"
"username" username})))
(defn make-contact-sync-req
[output-stream username]
(-make-req output-stream
(json/write-str {"type" "sync_contacts"
"username" username})))
(defn make-contact-list-req
[output-stream username]
(-make-req output-stream
(json/write-str {"type" "list_contacts"
"username" username})))
(defn make-group-list-req
[output-stream username]
(-make-req output-stream
(json/write-str {"type" "list_groups"
"username" username})))

3
src/whisper/storage.clj~ Normal file
View file

@ -0,0 +1,3 @@
(ns whisper.storage
"Whisper storage module
(:require [codax]))

View file

@ -21,8 +21,10 @@
[contact]
{:fx/type :v-box
:children [{:fx/type :label
:scale-x 1.1
:text (get contact "name")}
{:fx/type :label
:scale-x 0.9
:text (get contact "id")}]})
(defn paint-flag
@ -64,7 +66,15 @@
:height 500
:scene {:fx/type :scene
:root {:fx/type :v-box
:children (fx/sub-val context :flags)}}})
:children (conj (fx/sub-val context :flags)
{:fx/type :h-box
:children [{:fx/type :v-box
:children (fx/sub-val context :contacts)}
;; TODO: scrollable view (list view?)
{:fx/type :v-box
:children (fx/sub-val context :messages)}
;; TODO: compose message view
]})}}})
(defn qrcode-ui
[{:keys [showing image]}]
@ -80,6 +90,31 @@
:fit-width 480
:image image}]}}})
(defn user-select-ui
[{:keys [users callback showing]}]
{:fx/type :stage
:showing showing
:title "select a user"
:width 200
:height 500
:scene {:fx/type :scene
:root {:fx/type :v-box
:children [{:fx/type :label
:v-box/margin 5
:text "Pick a user to continue"}
{:fx/type fx/ext-let-refs
:refs {::toggle-group {:fx/type :toggle-group}}
:desc {:fx/type :v-box
:padding 20
:spacing 10
:children (for [user users]
{:fx/type :radio-button
:toggle-group {:fx/type fx/ext-get-ref
:ref ::toggle-group}
:selected false
:text (get user "username")
:on-action #(callback user %)})}}]}}})
(def main-renderer (fx/create-renderer
:middleware (comp
fx/wrap-context-desc
@ -108,3 +143,14 @@
(aux-renderer {:fx/type qrcode-ui
:showing true
:image (Image. (FileInputStream. image))}))))
;; TODO: modify callback into event handler
(defn paint-user-select
[users showing callback]
(aux-renderer
{:fx/type user-select-ui
:showing showing
;; "Make New User" is a magic token
;; TODO: dont
:users (conj users {"username" "Link New User"})
:callback callback}))