Compare commits
18
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1a868fc0d | ||
|
|
4d3a564312 | ||
|
|
757b8ebcac | ||
|
|
5ff9097410 | ||
|
|
6fdb57a753 | ||
|
|
8d821c27cb | ||
|
|
3be9bd0bbb | ||
|
|
541e51b37b | ||
|
|
c3a62f080b | ||
|
|
5346dfec0f | ||
|
|
83e9f8f0fc | ||
|
|
691768b691 | ||
|
|
797578ae73 | ||
|
|
5f7081c30f | ||
|
|
8efbf7e43d | ||
|
|
97019fffee | ||
|
|
143410871b | ||
|
|
85382bbc28 |
@@ -35,6 +35,7 @@
|
||||
size 40
|
||||
customization-color (if (= type :primary) :blue nil)}}
|
||||
children]
|
||||
(when (string? children) (js/console.log "button - " children))
|
||||
(let [[pressed-state? set-pressed-state] (rn/use-state false)
|
||||
theme (quo.theme/use-theme)
|
||||
{:keys [icon-color background-color label-color border-color blur-type
|
||||
|
||||
@@ -181,6 +181,14 @@
|
||||
#(let [ret (handler)] (if (fn? ret) ret js/undefined))
|
||||
(get-js-deps deps))))
|
||||
|
||||
(defn use-layout-effect
|
||||
([handler]
|
||||
(use-layout-effect handler nil))
|
||||
([handler deps]
|
||||
(react/useLayoutEffect
|
||||
#(let [ret (handler)] (if (fn? ret) ret js/undefined))
|
||||
(get-js-deps deps))))
|
||||
|
||||
(defn use-mount
|
||||
[handler]
|
||||
(use-effect handler []))
|
||||
@@ -195,6 +203,35 @@
|
||||
([handler deps]
|
||||
(react/useCallback handler (get-js-deps deps))))
|
||||
|
||||
(defn use-fn-factory-factory
|
||||
"A dirty code translation from the form-2 solution `make-fn-factory`."
|
||||
[f]
|
||||
(let [*args1 (use-ref-atom nil)
|
||||
cached (use-ref-atom
|
||||
(fn [& args2]
|
||||
(apply f (concat @*args1 args2))))
|
||||
factory (use-ref-atom
|
||||
(fn factory
|
||||
[& args1]
|
||||
(reset! *args1 args1)
|
||||
@cached))]
|
||||
@factory))
|
||||
|
||||
(defn use-fn-factory
|
||||
[f & args]
|
||||
(let [factory (use-fn-factory-factory f)]
|
||||
(apply factory args)))
|
||||
|
||||
(defn make-fn-factory
|
||||
"Should be used in a form-2 component."
|
||||
[f]
|
||||
(let [*args1 (atom nil)
|
||||
cached (fn [& args2]
|
||||
(apply f (concat @*args1 args2)))]
|
||||
(fn [& args1]
|
||||
(reset! *args1 args1)
|
||||
cached)))
|
||||
|
||||
(defn use-memo
|
||||
[handler deps]
|
||||
(react/useMemo handler (get-js-deps deps)))
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
[{:keys [on-press allow-multiple-presses? throttle-duration]} throttle-id]
|
||||
(if allow-multiple-presses?
|
||||
on-press
|
||||
(fn []
|
||||
(fn [event]
|
||||
(let [id @throttle-id]
|
||||
(when (and id (not (get @throttle id)))
|
||||
(swap! throttle assoc id true)
|
||||
(on-press)
|
||||
(on-press event)
|
||||
(js/setTimeout
|
||||
#(swap! throttle dissoc id)
|
||||
(or throttle-duration 500)))))))
|
||||
|
||||
@@ -3,32 +3,173 @@
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[reagent.ratom]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.profile.contact.contact-request.style :as style]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
;; ---
|
||||
|
||||
(def ^:private lookup-sentinel (js-obj))
|
||||
|
||||
(defn memo
|
||||
"Returns a memoized version of a referentially transparent function. The
|
||||
memoized version of the function keeps a cache of the mapping from arguments
|
||||
to results and, when calls with the same arguments are repeated often, has
|
||||
higher performance at the expense of higher memory use."
|
||||
[mem f]
|
||||
(fn [& args]
|
||||
(js/console.log "lookup")
|
||||
(let [v (get @mem args lookup-sentinel)]
|
||||
(if (identical? v lookup-sentinel)
|
||||
(let [ret (apply f args)]
|
||||
(js/console.log "swap")
|
||||
(swap! mem assoc args ret)
|
||||
ret)
|
||||
v))))
|
||||
|
||||
(defn make-snapshot-handler-factory
|
||||
[snapshot]
|
||||
(let [storage (rn/use-memo #(atom {}) [])
|
||||
capture (rn/use-memo #(atom snapshot) [])
|
||||
_update (rn/use-layout-effect
|
||||
(fn []
|
||||
(swap! capture (fn [_] snapshot)))
|
||||
snapshot)
|
||||
factory (rn/use-memo
|
||||
(fn []
|
||||
(fn [handler]
|
||||
((memo storage
|
||||
(fn [callback]
|
||||
(fn [event]
|
||||
(callback @capture event))))
|
||||
handler)))
|
||||
[storage capture])]
|
||||
{:factory factory
|
||||
:storage storage}))
|
||||
|
||||
(defn use-bind-snapshot
|
||||
[snapshot]
|
||||
(let [{:keys [factory storage]}
|
||||
(make-snapshot-handler-factory snapshot)]
|
||||
(rn/use-unmount (fn []
|
||||
(js/console.log "unmount bind-snapshot")
|
||||
(prn "unmount storage" storage)))
|
||||
factory))
|
||||
|
||||
;; ---
|
||||
|
||||
(defn on-message-submit
|
||||
[public-key message _event]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch [:contact.ui/send-contact-request public-key message])
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :send-contact-request
|
||||
:type :positive
|
||||
:text (i18n/label
|
||||
:t/contact-request-was-sent)}]))
|
||||
|
||||
(defn on-message-change
|
||||
[set-message full-name message-text]
|
||||
;; This is just an example tap to check that when full-name is recomputed,
|
||||
;; this function sees the most up-to-date value.
|
||||
(tap> [:on-message-change full-name message-text])
|
||||
(set-message message-text))
|
||||
|
||||
(defn use-event
|
||||
[f scope]
|
||||
(let [bind (use-bind-snapshot scope)]
|
||||
(bind f)))
|
||||
|
||||
(defn use-events
|
||||
[fs scope]
|
||||
(let [bind (use-bind-snapshot scope)]
|
||||
(->> fs
|
||||
(reduce-kv
|
||||
(fn [acc label f]
|
||||
(assoc acc label (bind f)))
|
||||
{}))))
|
||||
|
||||
(defn view--using-factory-with-form-2
|
||||
[]
|
||||
(let [on-change-factory (rn/make-fn-factory on-message-change)
|
||||
on-submit-factory (rn/make-fn-factory on-message-submit)]
|
||||
(fn []
|
||||
(let [{:keys [public-key customization-color]
|
||||
:as profile} (rf/sub [:contacts/current-contact])
|
||||
full-name (profile.utils/displayed-name profile)
|
||||
profile-picture (profile.utils/photo profile)
|
||||
input-ref (rn/use-ref-atom nil)
|
||||
[message set-message] (rn/use-state "")
|
||||
on-change (on-change-factory set-message full-name)
|
||||
on-submit (on-submit-factory public-key message)]
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(let [listener (.addListener rn/keyboard
|
||||
"keyboardDidHide"
|
||||
(fn [_event]
|
||||
(when (and platform/android? @input-ref)
|
||||
(.blur ^js @input-ref))))]
|
||||
#(.remove ^js listener))))
|
||||
[:<>
|
||||
[quo/drawer-top
|
||||
{:type :context-tag
|
||||
:context-tag-type :default
|
||||
:title (i18n/label :t/send-contact-request)
|
||||
:full-name full-name
|
||||
:profile-picture profile-picture
|
||||
:customization-color customization-color}]
|
||||
[quo/text {:style style/message-prompt-wrapper}
|
||||
(i18n/label :t/contact-request-message-prompt)]
|
||||
[rn/view {:style style/message-input-wrapper}
|
||||
[quo/input
|
||||
{:type :text
|
||||
:ref #(reset! input-ref %)
|
||||
:multiline? true
|
||||
:char-limit constants/contact-request-message-max-length
|
||||
:max-length constants/contact-request-message-max-length
|
||||
:placeholder (i18n/label :t/type-something)
|
||||
:auto-focus true
|
||||
:accessibility-label :contact-request-message
|
||||
:label (i18n/label :t/message)
|
||||
:on-change-text on-change
|
||||
:container-style {:flex-shrink 1}
|
||||
:input-container-style {:flex-shrink 1}}]]
|
||||
[quo/bottom-actions
|
||||
{:container-style {:style {:flex 1}}
|
||||
:actions :one-action
|
||||
:button-one-props {:disabled? (string/blank? message)
|
||||
:accessibility-label :send-contact-request
|
||||
:customization-color :purple
|
||||
:on-press on-submit}
|
||||
:button-one-label "Past Present Sub"}]
|
||||
[quo/bottom-actions
|
||||
{:container-style {:style {:flex 1}}
|
||||
:actions :two-actions
|
||||
:button-one-props {:accessibility-label :send-contact-request
|
||||
:customization-color :blue
|
||||
:on-press on-submit}
|
||||
:button-one-label "Snapshot"
|
||||
:button-two-props {:accessibility-label :test-button
|
||||
:customization-color :orange
|
||||
:on-press on-submit}
|
||||
:button-two-label "Sub"}]]))))
|
||||
|
||||
(defn view--using-factory-hook
|
||||
[]
|
||||
(let [{:keys [public-key customization-color]
|
||||
:as profile} (rf/sub [:contacts/current-contact])
|
||||
customization-color customization-color
|
||||
full-name (profile.utils/displayed-name profile)
|
||||
profile-picture (profile.utils/photo profile)
|
||||
input-ref (rn/use-ref-atom nil)
|
||||
[message set-message] (rn/use-state "")
|
||||
on-message-change (rn/use-callback #(set-message %))
|
||||
on-message-submit (rn/use-callback (fn []
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch [:contact.ui/send-contact-request
|
||||
public-key message])
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :send-contact-request
|
||||
:type :positive
|
||||
:text (i18n/label
|
||||
:t/contact-request-was-sent)}]))
|
||||
[public-key message])]
|
||||
on-change (rn/use-fn-factory on-message-change set-message full-name)
|
||||
on-submit (rn/use-fn-factory on-message-submit public-key message)]
|
||||
;; `on-change` is always the same function instance, even if the arguments
|
||||
;; `set-message` and `full-name` change.
|
||||
(tap> {:hashes {:on-change (hash on-change)}})
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(let [listener (.addListener rn/keyboard
|
||||
@@ -58,7 +199,7 @@
|
||||
:auto-focus true
|
||||
:accessibility-label :contact-request-message
|
||||
:label (i18n/label :t/message)
|
||||
:on-change-text on-message-change
|
||||
:on-change-text on-change
|
||||
:container-style {:flex-shrink 1}
|
||||
:input-container-style {:flex-shrink 1}}]]
|
||||
[quo/bottom-actions
|
||||
@@ -66,7 +207,19 @@
|
||||
:actions :one-action
|
||||
:button-one-props {:disabled? (string/blank? message)
|
||||
:accessibility-label :send-contact-request
|
||||
:customization-color customization-color
|
||||
:on-press on-message-submit}
|
||||
:button-one-label (i18n/label :t/send-contact-request)}]]))
|
||||
:customization-color :purple
|
||||
:on-press on-submit}
|
||||
:button-one-label "Past Present Sub"}]
|
||||
[quo/bottom-actions
|
||||
{:container-style {:style {:flex 1}}
|
||||
:actions :two-actions
|
||||
:button-one-props {:accessibility-label :send-contact-request
|
||||
:customization-color :blue
|
||||
:on-press on-submit}
|
||||
:button-one-label "Snapshot"
|
||||
:button-two-props {:accessibility-label :test-button
|
||||
:customization-color :orange
|
||||
:on-press on-submit}
|
||||
:button-two-label "Sub"}]]))
|
||||
|
||||
(def view view--using-factory-hook)
|
||||
|
||||
Reference in New Issue
Block a user