Compare commits
36
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50759346c4 | ||
|
|
98811e3511 | ||
|
|
818b9e2bdf | ||
|
|
a79c3ad0bf | ||
|
|
ed7463132a | ||
|
|
d20f10cf8b | ||
|
|
ebbae051bd | ||
|
|
521f39b6fb | ||
|
|
ee1f93defb | ||
|
|
3665fe26da | ||
|
|
3ec7209fcc | ||
|
|
195826a7f4 | ||
|
|
5bb4f3632a | ||
|
|
4fe62553ca | ||
|
|
cb586c8676 | ||
|
|
fd50e4281c | ||
|
|
dcbb080217 | ||
|
|
97d1b3faa1 | ||
|
|
9c322397a2 | ||
|
|
ca2b1d5c8e | ||
|
|
9a4bc7e250 | ||
|
|
c6dbfb6244 | ||
|
|
826ab6625e | ||
|
|
a9ec2ca7ba | ||
|
|
1e11edc442 | ||
|
|
bf8461f007 | ||
|
|
5926426672 | ||
|
|
e871357b67 | ||
|
|
9f5e53cc63 | ||
|
|
61c0650cec | ||
|
|
7cc570b6d0 | ||
|
|
e609e2ff6a | ||
|
|
f8cdb3bd7b | ||
|
|
fe9a4eac59 | ||
|
|
d934dc26ef | ||
|
|
ed3cb42572 |
@@ -282,11 +282,12 @@ SIMULATOR=iPhone 13
|
|||||||
# TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded
|
# TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded
|
||||||
run-ios: export TARGET := ios
|
run-ios: export TARGET := ios
|
||||||
run-ios: export IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64
|
run-ios: export IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64
|
||||||
|
run-ios: export XCBeautify=$(shell which xcbeautify) # for react-native-cli to pick this up and to auto format output
|
||||||
run-ios: ##@run Build iOS app and start it in a simulator/device
|
run-ios: ##@run Build iOS app and start it in a simulator/device
|
||||||
ifneq ("$(SIMULATOR)", "")
|
ifneq ("$(SIMULATOR)", "")
|
||||||
npx react-native run-ios --simulator="$(SIMULATOR)" | xcbeautify
|
npx react-native run-ios --simulator="$(SIMULATOR)"
|
||||||
else
|
else
|
||||||
npx react-native run-ios | xcbeautify
|
npx react-native run-ios
|
||||||
endif
|
endif
|
||||||
|
|
||||||
show-ios-devices: ##@other shows connected ios device and its name
|
show-ios-devices: ##@other shows connected ios device and its name
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 9.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -51,3 +51,9 @@
|
|||||||
(visibility-status-updates/<-rpc-settings)
|
(visibility-status-updates/<-rpc-settings)
|
||||||
(set/rename-keys {:compressedKey :compressed-key
|
(set/rename-keys {:compressedKey :compressed-key
|
||||||
:emojiHash :emoji-hash})))
|
:emojiHash :emoji-hash})))
|
||||||
|
|
||||||
|
(defn rpc->setting-value
|
||||||
|
[{:keys [name] :as setting}]
|
||||||
|
(condp = name
|
||||||
|
:currency (update setting :value keyword)
|
||||||
|
setting))
|
||||||
|
|||||||
@@ -231,7 +231,7 @@
|
|||||||
[db]
|
[db]
|
||||||
(into #{}
|
(into #{}
|
||||||
(remove #(= (:type %) :watch)
|
(remove #(= (:type %) :watch)
|
||||||
(map #(eip55/address->checksum (:address %)) (get db :profile/wallet-accounts)))))
|
(map #(eip55/address->checksum (:address %)) (vals (get-in db [:wallet :accounts]))))))
|
||||||
|
|
||||||
;;NOTE we want to handle only last resolve
|
;;NOTE we want to handle only last resolve
|
||||||
(def resolve-last-id (atom nil))
|
(def resolve-last-id (atom nil))
|
||||||
|
|||||||
@@ -79,10 +79,15 @@
|
|||||||
"recent-history-ready" (recent-history-fetching-ended cofx event)
|
"recent-history-ready" (recent-history-fetching-ended cofx event)
|
||||||
"fetching-history-error" (fetching-error cofx event)
|
"fetching-history-error" (fetching-error cofx event)
|
||||||
"non-archival-node-detected" (non-archival-node-detected cofx event)
|
"non-archival-node-detected" (non-archival-node-detected cofx event)
|
||||||
|
"pending-transaction-status-changed" {:fx
|
||||||
|
[[:dispatch
|
||||||
|
[:wallet/pending-transaction-status-changed-received
|
||||||
|
event]]]}
|
||||||
"wallet-owned-collectibles-filtering-done" {:fx [[:dispatch
|
"wallet-owned-collectibles-filtering-done" {:fx [[:dispatch
|
||||||
[:wallet/owned-collectibles-filtering-done
|
[:wallet/owned-collectibles-filtering-done
|
||||||
event]]]}
|
event]]]}
|
||||||
"wallet-get-collectibles-details-done" {:fx [[:dispatch
|
"wallet-get-collectibles-details-done" {:fx [[:dispatch
|
||||||
[:wallet/get-collectible-details-done
|
[:wallet/get-collectible-details-done
|
||||||
event]]]}
|
event]]]}
|
||||||
|
"wallet-tick-reload" {:fx [[:dispatch [:wallet/reload]]]}
|
||||||
(log/debug ::unknown-wallet-event :type type :event event)))
|
(log/debug ::unknown-wallet-event :type type :event event)))
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
[react-native.permissions :as permissions]
|
[react-native.permissions :as permissions]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]
|
||||||
[status-im.common.biometric.events :as biometric]
|
[status-im.common.biometric.events :as biometric]
|
||||||
|
status-im.common.serialization
|
||||||
status-im.common.standard-authentication.events
|
status-im.common.standard-authentication.events
|
||||||
[status-im.common.theme.core :as theme]
|
[status-im.common.theme.core :as theme]
|
||||||
[status-im.common.universal-links :as universal-links]
|
[status-im.common.universal-links :as universal-links]
|
||||||
|
|||||||
@@ -246,7 +246,7 @@
|
|||||||
[rn/touchable-opacity
|
[rn/touchable-opacity
|
||||||
{:on-press #(do
|
{:on-press #(do
|
||||||
(rf/dispatch [:pop-to-root :shell-stack])
|
(rf/dispatch [:pop-to-root :shell-stack])
|
||||||
(rf/dispatch [:navigate-to :community-overview (:id community)])
|
(rf/dispatch [:communities/navigate-to-community-overview (:id community)])
|
||||||
(rf/dispatch [:chat/close]))}
|
(rf/dispatch [:chat/close]))}
|
||||||
[rn/text
|
[rn/text
|
||||||
{:style {:text-align :center
|
{:style {:text-align :center
|
||||||
|
|||||||
@@ -11,17 +11,17 @@
|
|||||||
(defn token-requirement-list-row
|
(defn token-requirement-list-row
|
||||||
[tokens padding?]
|
[tokens padding?]
|
||||||
[rn/view {:style (style/token-row padding?)}
|
[rn/view {:style (style/token-row padding?)}
|
||||||
(map-indexed (fn [token-index token]
|
(map-indexed (fn [token-index {:keys [img-src amount sufficient? purchasable?] :as token}]
|
||||||
(let [{:keys [amount sufficient? purchasable?]} token]
|
^{:key token-index}
|
||||||
^{:key token-index}
|
[rn/view {:style style/token-tag-spacing}
|
||||||
[rn/view {:style style/token-tag-spacing}
|
[token-tag/view
|
||||||
[token-tag/view
|
{:token-symbol (:symbol token)
|
||||||
{:token-symbol (:symbol token)
|
:token-img-src img-src
|
||||||
:token-value amount
|
:token-value amount
|
||||||
:size :size-24
|
:size :size-24
|
||||||
:options (cond
|
:options (cond
|
||||||
sufficient? :hold
|
sufficient? :hold
|
||||||
purchasable? :add)}]]))
|
purchasable? :add)}]])
|
||||||
tokens)])
|
tokens)])
|
||||||
|
|
||||||
(defn- internal-view
|
(defn- internal-view
|
||||||
|
|||||||
@@ -76,15 +76,19 @@
|
|||||||
(str description " · " (i18n/label :t/on-device))])
|
(str description " · " (i18n/label :t/on-device))])
|
||||||
|
|
||||||
(defn- context-tag-subtitle
|
(defn- context-tag-subtitle
|
||||||
[{:keys [community-logo community-name]}]
|
[{:keys [context-tag-type community-logo community-name account-name emoji customization-color]}]
|
||||||
[rn/view
|
(let [tag-type (or context-tag-type :account)]
|
||||||
{:accessibility-label :context-tag-wrapper
|
[rn/view
|
||||||
:style {:flex-wrap :wrap}}
|
{:accessibility-label :context-tag-wrapper
|
||||||
[context-tag/view
|
:style {:flex-wrap :wrap}}
|
||||||
{:type :community
|
[context-tag/view
|
||||||
:community-name community-name
|
{:type tag-type
|
||||||
:community-logo community-logo
|
:account-name account-name
|
||||||
:size 24}]])
|
:emoji emoji
|
||||||
|
:community-name community-name
|
||||||
|
:community-logo community-logo
|
||||||
|
:size 24
|
||||||
|
:customization-color customization-color}]]))
|
||||||
|
|
||||||
(defn- description-subtitle
|
(defn- description-subtitle
|
||||||
[{:keys [theme blur? description]}]
|
[{:keys [theme blur? description]}]
|
||||||
@@ -95,7 +99,8 @@
|
|||||||
description])
|
description])
|
||||||
|
|
||||||
(defn- subtitle
|
(defn- subtitle
|
||||||
[{:keys [type theme blur? keycard? networks description community-name community-logo]}]
|
[{:keys [type theme blur? keycard? networks description community-name community-logo
|
||||||
|
context-tag-type account-name emoji customization-color]}]
|
||||||
(cond
|
(cond
|
||||||
(= :keypair type)
|
(= :keypair type)
|
||||||
[keypair-subtitle
|
[keypair-subtitle
|
||||||
@@ -118,8 +123,12 @@
|
|||||||
|
|
||||||
(= :context-tag type)
|
(= :context-tag type)
|
||||||
[context-tag-subtitle
|
[context-tag-subtitle
|
||||||
{:community-logo community-logo
|
{:context-tag-type context-tag-type
|
||||||
:community-name community-name}]
|
:community-logo community-logo
|
||||||
|
:community-name community-name
|
||||||
|
:account-name account-name
|
||||||
|
:emoji emoji
|
||||||
|
:customization-color customization-color}]
|
||||||
|
|
||||||
(and (not= :label type) description)
|
(and (not= :label type) description)
|
||||||
[description-subtitle
|
[description-subtitle
|
||||||
@@ -173,6 +182,7 @@
|
|||||||
|
|
||||||
(defn- view-internal
|
(defn- view-internal
|
||||||
[{:keys [title title-icon type theme description blur? community-name community-logo button-icon
|
[{:keys [title title-icon type theme description blur? community-name community-logo button-icon
|
||||||
|
account-name emoji
|
||||||
on-button-press
|
on-button-press
|
||||||
on-button-long-press
|
on-button-long-press
|
||||||
button-disabled? account-avatar-emoji account-avatar-type customization-color icon-avatar
|
button-disabled? account-avatar-emoji account-avatar-type customization-color icon-avatar
|
||||||
@@ -196,14 +206,17 @@
|
|||||||
:theme theme
|
:theme theme
|
||||||
:blur? blur?}]
|
:blur? blur?}]
|
||||||
[subtitle
|
[subtitle
|
||||||
{:type type
|
{:type type
|
||||||
:theme theme
|
:theme theme
|
||||||
:blur? blur?
|
:blur? blur?
|
||||||
:keycard? keycard?
|
:keycard? keycard?
|
||||||
:networks networks
|
:networks networks
|
||||||
:description description
|
:description description
|
||||||
:community-name community-name
|
:community-name community-name
|
||||||
:community-logo community-logo}]]
|
:community-logo community-logo
|
||||||
|
:customization-color customization-color
|
||||||
|
:account-name account-name
|
||||||
|
:emoji emoji}]]
|
||||||
[right-icon
|
[right-icon
|
||||||
{:theme theme
|
{:theme theme
|
||||||
:type type
|
:type type
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
(ns quo.components.gradient.gradient-cover.style)
|
(ns quo.components.gradient.gradient-cover.style)
|
||||||
|
|
||||||
(defn root-container
|
(defn root-container
|
||||||
[opacity]
|
[opacity height]
|
||||||
{:height 252
|
{:height (or height 252)
|
||||||
:opacity opacity})
|
:opacity opacity})
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[react-native.linear-gradient :as linear-gradient]))
|
[react-native.linear-gradient :as linear-gradient]))
|
||||||
|
|
||||||
(defn- view-internal
|
(defn- view-internal
|
||||||
[{:keys [customization-color opacity container-style] :or {customization-color :blue}}]
|
[{:keys [customization-color opacity container-style height] :or {customization-color :blue}}]
|
||||||
(let [color-top (colors/custom-color customization-color 50 20)
|
(let [color-top (colors/custom-color customization-color 50 20)
|
||||||
color-bottom (colors/custom-color customization-color 50 0)]
|
color-bottom (colors/custom-color customization-color 50 0)]
|
||||||
[linear-gradient/linear-gradient
|
[linear-gradient/linear-gradient
|
||||||
@@ -14,6 +14,6 @@
|
|||||||
:colors [color-top color-bottom]
|
:colors [color-top color-bottom]
|
||||||
:start {:x 0 :y 0}
|
:start {:x 0 :y 0}
|
||||||
:end {:x 0 :y 1}
|
:end {:x 0 :y 1}
|
||||||
:style (merge (style/root-container opacity) container-style)}]))
|
:style (merge (style/root-container opacity height) container-style)}]))
|
||||||
|
|
||||||
(def view (quo.theme/with-theme view-internal))
|
(def view (quo.theme/with-theme view-internal))
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
(ns quo.components.list-items.network-list.component-spec
|
||||||
|
(:require [quo.components.list-items.network-list.view :as network-list]
|
||||||
|
[quo.foundations.colors :as colors]
|
||||||
|
[test-helpers.component :as h]))
|
||||||
|
|
||||||
|
(defn- render
|
||||||
|
[component]
|
||||||
|
(h/render-with-theme-provider component :light))
|
||||||
|
|
||||||
|
(def props
|
||||||
|
{:theme :light
|
||||||
|
:state :default
|
||||||
|
:label "Mainnet"
|
||||||
|
:network-image 873
|
||||||
|
:customization-color :blue
|
||||||
|
:token-value "100.00 ETH"
|
||||||
|
:fiat-value "€100.00"})
|
||||||
|
|
||||||
|
|
||||||
|
(h/describe "List items: Network List"
|
||||||
|
(h/test "default state explicit"
|
||||||
|
(render [network-list/view props])
|
||||||
|
(h/is-truthy (h/get-by-text "Mainnet")))
|
||||||
|
|
||||||
|
(h/test "Pressed state"
|
||||||
|
(render [network-list/view props])
|
||||||
|
(h/fire-event :on-press-in (h/get-by-label-text ::network-list))
|
||||||
|
(h/wait-for #(h/has-style (h/query-by-label-text ::network-list)
|
||||||
|
{:backgroundColor (colors/resolve-color :blue :light 5)})))
|
||||||
|
|
||||||
|
(h/test "Active state"
|
||||||
|
(render [network-list/view (assoc props :state :active)])
|
||||||
|
(h/has-style (h/query-by-label-text ::network-list)
|
||||||
|
{:backgroundColor (colors/resolve-color :blue :light 10)}))
|
||||||
|
|
||||||
|
(h/test "Call on-press"
|
||||||
|
(let [on-press (h/mock-fn)]
|
||||||
|
(render [network-list/view (assoc props :on-press on-press)])
|
||||||
|
(h/fire-event :on-press (h/get-by-label-text ::network-list))
|
||||||
|
(h/was-called on-press))))
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
(ns quo.components.list-items.network-list.style
|
||||||
|
(:require [quo.foundations.colors :as colors]))
|
||||||
|
|
||||||
|
(defn- background-color
|
||||||
|
[state customization-color theme]
|
||||||
|
(case state
|
||||||
|
:pressed (colors/resolve-color customization-color theme 5)
|
||||||
|
:active (colors/resolve-color customization-color theme 10)
|
||||||
|
:transparent))
|
||||||
|
|
||||||
|
(defn container
|
||||||
|
[state customization-color theme]
|
||||||
|
{:flex-direction :row
|
||||||
|
:justify-content :space-between
|
||||||
|
:align-items :center
|
||||||
|
:padding-horizontal 12
|
||||||
|
:padding-vertical 8
|
||||||
|
:border-radius 12
|
||||||
|
:height 56
|
||||||
|
:background-color (background-color state customization-color theme)})
|
||||||
|
|
||||||
|
(def info
|
||||||
|
{:flex-direction :row
|
||||||
|
:align-items :center
|
||||||
|
:gap 2})
|
||||||
|
|
||||||
|
(def network-image
|
||||||
|
{:border-width 1
|
||||||
|
:border-radius 16
|
||||||
|
:border-color colors/neutral-80-opa-5
|
||||||
|
:margin-right 8
|
||||||
|
:background-color colors/neutral-80-opa-5
|
||||||
|
:height 32
|
||||||
|
:width 32})
|
||||||
|
|
||||||
|
(def values-container
|
||||||
|
{:align-items :flex-end})
|
||||||
|
|
||||||
|
(defn fiat-value
|
||||||
|
[theme]
|
||||||
|
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
(ns quo.components.list-items.network-list.view
|
||||||
|
(:require
|
||||||
|
[clojure.string :as string]
|
||||||
|
[quo.components.list-items.network-list.style :as style]
|
||||||
|
[quo.components.markdown.text :as text]
|
||||||
|
[quo.theme :as quo.theme]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[schema.core :as schema]))
|
||||||
|
|
||||||
|
(defn- info
|
||||||
|
[{:keys [network-image label]}]
|
||||||
|
[rn/view {:style style/info}
|
||||||
|
[rn/image
|
||||||
|
{:source network-image
|
||||||
|
:style style/network-image}]
|
||||||
|
[rn/view
|
||||||
|
[text/text
|
||||||
|
{:weight :semi-bold
|
||||||
|
:style {:text-transform :capitalize}
|
||||||
|
:number-of-lines 1}
|
||||||
|
(if (string/blank? label) "-" label)]]])
|
||||||
|
|
||||||
|
(defn- values
|
||||||
|
[{:keys [token-value fiat-value theme]}]
|
||||||
|
[rn/view {:style style/values-container}
|
||||||
|
[text/text
|
||||||
|
{:weight :medium
|
||||||
|
:size :paragraph-2
|
||||||
|
:number-of-lines 1}
|
||||||
|
token-value]
|
||||||
|
[text/text
|
||||||
|
{:style (style/fiat-value theme)
|
||||||
|
:size :paragraph-2
|
||||||
|
:number-of-lines 1}
|
||||||
|
fiat-value]])
|
||||||
|
|
||||||
|
(def ?schema
|
||||||
|
[:=>
|
||||||
|
[:catn
|
||||||
|
[:props
|
||||||
|
[:map {:closed true}
|
||||||
|
[:network-image :int]
|
||||||
|
[:label :string]
|
||||||
|
[:fiat-value :string]
|
||||||
|
[:token-value :string]
|
||||||
|
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||||
|
[:state [:enum :pressed :active :default]]
|
||||||
|
[:on-press {:optional true} [:maybe fn?]]
|
||||||
|
[:theme :schema.common/theme]]]]
|
||||||
|
:any])
|
||||||
|
|
||||||
|
(defn- view-internal
|
||||||
|
[]
|
||||||
|
(let [pressed? (reagent/atom false)
|
||||||
|
on-press-in #(reset! pressed? true)
|
||||||
|
on-press-out #(reset! pressed? false)]
|
||||||
|
(fn [{:keys [on-press state customization-color theme]
|
||||||
|
:as props
|
||||||
|
:or {customization-color :blue}}]
|
||||||
|
(let [internal-state (if @pressed?
|
||||||
|
:pressed
|
||||||
|
state)]
|
||||||
|
|
||||||
|
[rn/pressable
|
||||||
|
{:style (style/container internal-state customization-color theme)
|
||||||
|
:on-press-in on-press-in
|
||||||
|
:on-press-out on-press-out
|
||||||
|
:on-press on-press
|
||||||
|
:accessibility-label :network-list}
|
||||||
|
[info props]
|
||||||
|
[values props]]))))
|
||||||
|
|
||||||
|
(def view
|
||||||
|
(quo.theme/with-theme
|
||||||
|
(schema/instrument #'view-internal ?schema)))
|
||||||
+28
-25
@@ -1,4 +1,4 @@
|
|||||||
(ns quo.components.list-items.user-list
|
(ns quo.components.list-items.user
|
||||||
(:require
|
(:require
|
||||||
[quo.components.avatars.user-avatar.view :as user-avatar]
|
[quo.components.avatars.user-avatar.view :as user-avatar]
|
||||||
[quo.components.icon :as icons]
|
[quo.components.icon :as icons]
|
||||||
@@ -18,14 +18,14 @@
|
|||||||
:align-items :center})
|
:align-items :center})
|
||||||
|
|
||||||
(defn action-icon
|
(defn action-icon
|
||||||
[{:keys [type on-press on-check disabled? checked?]}]
|
[{:keys [type on-press on-check disabled? checked?]} theme]
|
||||||
[rn/touchable-opacity
|
[rn/touchable-opacity
|
||||||
{:on-press (when on-press on-press)}
|
{:on-press (when on-press on-press)}
|
||||||
(case type
|
(case type
|
||||||
:options
|
:options
|
||||||
[icons/icon :i/options
|
[icons/icon :i/options
|
||||||
{:size 20
|
{:size 20
|
||||||
:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]
|
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}]
|
||||||
:checkbox
|
:checkbox
|
||||||
[selectors/view
|
[selectors/view
|
||||||
{:type :checkbox
|
{:type :checkbox
|
||||||
@@ -37,30 +37,33 @@
|
|||||||
[text/text "not implemented"]
|
[text/text "not implemented"]
|
||||||
[rn/view])])
|
[rn/view])])
|
||||||
|
|
||||||
(defn user-list
|
(defn user
|
||||||
[{:keys [short-chat-key primary-name secondary-name photo-path online? contact? verified?
|
[{:keys [short-chat-key primary-name secondary-name photo-path online? contact? verified?
|
||||||
untrustworthy? on-press on-long-press accessory]}]
|
untrustworthy? on-press on-long-press accessory customization-color theme]}]
|
||||||
[rn/touchable-opacity
|
[rn/touchable-highlight
|
||||||
{:style container-style
|
{:style container-style
|
||||||
|
:underlay-color (colors/resolve-color customization-color theme 5)
|
||||||
:accessibility-label :user-list
|
:accessibility-label :user-list
|
||||||
:on-press (when on-press on-press)
|
:on-press (when on-press on-press)
|
||||||
:on-long-press (when on-long-press on-long-press)}
|
:on-long-press (when on-long-press on-long-press)}
|
||||||
[user-avatar/user-avatar
|
[:<>
|
||||||
{:full-name primary-name
|
[user-avatar/user-avatar
|
||||||
:profile-picture photo-path
|
{:full-name primary-name
|
||||||
:online? online?
|
:profile-picture photo-path
|
||||||
:size :small}]
|
:online? online?
|
||||||
[rn/view {:style {:margin-horizontal 8 :flex 1}}
|
:size :small}]
|
||||||
[author/view
|
[rn/view {:style {:margin-horizontal 8 :flex 1}}
|
||||||
{:primary-name primary-name
|
[author/view
|
||||||
:secondary-name secondary-name
|
{:primary-name primary-name
|
||||||
:contact? contact?
|
:secondary-name secondary-name
|
||||||
:verified? verified?
|
:contact? contact?
|
||||||
:untrustworthy? untrustworthy?}]
|
:verified? verified?
|
||||||
(when short-chat-key
|
:untrustworthy? untrustworthy?
|
||||||
[text/text
|
:size 15}]
|
||||||
{:size :paragraph-1
|
(when short-chat-key
|
||||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}}
|
[text/text
|
||||||
short-chat-key])]
|
{:size :paragraph-2
|
||||||
(when accessory
|
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}}
|
||||||
[action-icon accessory])])
|
short-chat-key])]
|
||||||
|
(when accessory
|
||||||
|
[action-icon accessory theme])]])
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
(defn icon-container
|
(defn icon-container
|
||||||
[is-first?]
|
[is-first?]
|
||||||
{:margin-left (if is-first? 4 2)
|
{:margin-left (if is-first? 4 2)
|
||||||
:margin-bottom 2})
|
:margin-bottom 4})
|
||||||
|
|
||||||
(defn time-text
|
(defn time-text
|
||||||
[theme]
|
[theme]
|
||||||
|
|||||||
@@ -51,8 +51,7 @@
|
|||||||
[icons/icon :main-icons2/untrustworthy
|
[icons/icon :main-icons2/untrustworthy
|
||||||
{:size 12
|
{:size 12
|
||||||
:no-color true
|
:no-color true
|
||||||
:container-style (style/icon-container contact?)}])
|
:container-style (style/icon-container contact?)}])]
|
||||||
]
|
|
||||||
(when (and (not verified?) short-chat-key)
|
(when (and (not verified?) short-chat-key)
|
||||||
[text/text
|
[text/text
|
||||||
{:weight :monospace
|
{:weight :monospace
|
||||||
|
|||||||
@@ -34,10 +34,9 @@
|
|||||||
(= :pinned use-case)
|
(= :pinned use-case)
|
||||||
theme)
|
theme)
|
||||||
container-style)}
|
container-style)}
|
||||||
[rn/image
|
[rn/text
|
||||||
{:style {:width 15 :height 15}
|
{:accessibility-label :emoji}
|
||||||
:accessibility-label :emoji
|
(reaction.resource/system-emojis emoji)]
|
||||||
:source (reaction.resource/get-reaction emoji)}]
|
|
||||||
[text/text
|
[text/text
|
||||||
{:size :paragraph-2
|
{:size :paragraph-2
|
||||||
:weight :semi-bold
|
:weight :semi-bold
|
||||||
|
|||||||
@@ -4,6 +4,14 @@
|
|||||||
(def ^:private reactions
|
(def ^:private reactions
|
||||||
(resolve-all-reactions))
|
(resolve-all-reactions))
|
||||||
|
|
||||||
|
(def system-emojis
|
||||||
|
{:reaction/thumbs-up "👍"
|
||||||
|
:reaction/thumbs-down "👎"
|
||||||
|
:reaction/love "❤"
|
||||||
|
:reaction/laugh "😂"
|
||||||
|
:reaction/sad "😢"
|
||||||
|
:reaction/angry "😡"})
|
||||||
|
|
||||||
(defn get-reaction
|
(defn get-reaction
|
||||||
[reaction]
|
[reaction]
|
||||||
(assert (keyword? reaction) "Reaction should be a keyword")
|
(assert (keyword? reaction) "Reaction should be a keyword")
|
||||||
|
|||||||
@@ -19,6 +19,5 @@
|
|||||||
(swap! pressed? not)
|
(swap! pressed? not)
|
||||||
(when on-press
|
(when on-press
|
||||||
(on-press e)))}
|
(on-press e)))}
|
||||||
[rn/image
|
[rn/text
|
||||||
{:source (reactions.resource/get-reaction emoji)
|
(reactions.resource/system-emojis emoji)]])))
|
||||||
:style {:width 20 :height 20}}]])))
|
|
||||||
|
|||||||
@@ -8,19 +8,20 @@
|
|||||||
|
|
||||||
(defn- category-internal
|
(defn- category-internal
|
||||||
[{:keys [label data container-style] :as props}]
|
[{:keys [label data container-style] :as props}]
|
||||||
[rn/view {:style (merge (style/container label) container-style)}
|
(let [settings-item (filter identity data)]
|
||||||
(when label
|
[rn/view {:style (merge (style/container label) container-style)}
|
||||||
[text/text
|
(when label
|
||||||
{:weight :medium
|
[text/text
|
||||||
:size :paragraph-2
|
{:weight :medium
|
||||||
:style (style/label props)}
|
:size :paragraph-2
|
||||||
label])
|
:style (style/label props)}
|
||||||
[rn/view {:style (style/settings-items props)}
|
label])
|
||||||
(for [item data]
|
[rn/view {:style (style/settings-items props)}
|
||||||
^{:key item}
|
(for [item settings-item]
|
||||||
[:<>
|
^{:key item}
|
||||||
[settings-item/view item]
|
[:<>
|
||||||
(when-not (= item (last data))
|
[settings-item/view item]
|
||||||
[rn/view {:style (style/settings-separator props)}])])]])
|
(when-not (= item (last settings-item))
|
||||||
|
[rn/view {:style (style/settings-separator props)}])])]]))
|
||||||
|
|
||||||
(def settings-category (quo.theme/with-theme category-internal))
|
(def settings-category (quo.theme/with-theme category-internal))
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
network-image]
|
network-image]
|
||||||
:or {subtitle-type :default}}]
|
:or {subtitle-type :default}}]
|
||||||
[rn/view {:style style/subtitle-container}
|
[rn/view {:style style/subtitle-container}
|
||||||
(when (not= :small size)
|
(when (and subtitle-type (not= :small size))
|
||||||
[rn/view {:style (style/subtitle-icon-container subtitle-type)}
|
[rn/view {:style (style/subtitle-icon-container subtitle-type)}
|
||||||
(case subtitle-type
|
(case subtitle-type
|
||||||
:icon [icons/icon icon
|
:icon [icons/icon icon
|
||||||
|
|||||||
@@ -16,6 +16,12 @@
|
|||||||
:padding-top 12
|
:padding-top 12
|
||||||
:padding-bottom 8})
|
:padding-bottom 8})
|
||||||
|
|
||||||
|
(def gradient-bg
|
||||||
|
{:position :absolute
|
||||||
|
:top 0
|
||||||
|
:left 0
|
||||||
|
:right 0})
|
||||||
|
|
||||||
;;; Header
|
;;; Header
|
||||||
(def header-container
|
(def header-container
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
|
|||||||
@@ -4,14 +4,13 @@
|
|||||||
[oops.core :as oops]
|
[oops.core :as oops]
|
||||||
[quo.components.avatars.account-avatar.view :as account-avatar]
|
[quo.components.avatars.account-avatar.view :as account-avatar]
|
||||||
[quo.components.buttons.button.view :as button]
|
[quo.components.buttons.button.view :as button]
|
||||||
|
[quo.components.gradient.gradient-cover.view :as gradient-cover]
|
||||||
[quo.components.markdown.text :as text]
|
[quo.components.markdown.text :as text]
|
||||||
[quo.components.share.qr-code.view :as qr-code]
|
[quo.components.share.qr-code.view :as qr-code]
|
||||||
[quo.components.share.share-qr-code.style :as style]
|
[quo.components.share.share-qr-code.style :as style]
|
||||||
[quo.components.tabs.tab.view :as tab]
|
[quo.components.tabs.tab.view :as tab]
|
||||||
[quo.theme]
|
[quo.theme]
|
||||||
[react-native.blur :as blur]
|
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.platform :as platform]
|
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[utils.i18n :as i18n]))
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
@@ -126,41 +125,44 @@
|
|||||||
[{:keys [share-qr-type qr-image-uri component-width customization-color full-name
|
[{:keys [share-qr-type qr-image-uri component-width customization-color full-name
|
||||||
profile-picture emoji on-share-press]
|
profile-picture emoji on-share-press]
|
||||||
:as props}]
|
:as props}]
|
||||||
[rn/view {:style style/content-container}
|
[:<>
|
||||||
[rn/view
|
[rn/view {:style style/gradient-bg}
|
||||||
{:style style/share-qr-container}
|
[gradient-cover/view {:customization-color customization-color :height 463}]]
|
||||||
|
[rn/view {:style style/content-container}
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/share-qr-inner-container}
|
{:style style/share-qr-container}
|
||||||
[account-avatar/view
|
[rn/view
|
||||||
{:customization-color customization-color
|
{:style style/share-qr-inner-container}
|
||||||
:emoji emoji
|
[account-avatar/view
|
||||||
:size 32}]
|
{:customization-color customization-color
|
||||||
[text/text
|
:emoji emoji
|
||||||
{:size :heading-2
|
:size 32}]
|
||||||
:weight :semi-bold
|
[text/text
|
||||||
:style {:margin-left 8}} full-name]]
|
{:size :heading-2
|
||||||
[share-button {:on-press on-share-press}]]
|
:weight :semi-bold
|
||||||
(when (#{:wallet-legacy :wallet-multichain} share-qr-type)
|
:style {:margin-left 8}} full-name]]
|
||||||
[header props])
|
[share-button {:on-press on-share-press}]]
|
||||||
[quo.theme/provider {:theme :light}
|
(when (#{:wallet-legacy :wallet-multichain} share-qr-type)
|
||||||
[qr-code/view
|
[header props])
|
||||||
{:qr-image-uri qr-image-uri
|
[quo.theme/provider {:theme :light}
|
||||||
:size (style/qr-code-size component-width)
|
[qr-code/view
|
||||||
:avatar (if (= share-qr-type :profile)
|
{:qr-image-uri qr-image-uri
|
||||||
:profile
|
:size (style/qr-code-size component-width)
|
||||||
:wallet-account)
|
:avatar (if (= share-qr-type :profile)
|
||||||
:customization-color customization-color
|
:profile
|
||||||
:full-name full-name
|
:wallet-account)
|
||||||
:profile-picture profile-picture
|
:customization-color customization-color
|
||||||
:emoji emoji}]]
|
:full-name full-name
|
||||||
[rn/view {:style style/bottom-container}
|
:profile-picture profile-picture
|
||||||
(case share-qr-type
|
:emoji emoji}]]
|
||||||
:profile [profile-bottom props]
|
[rn/view {:style style/bottom-container}
|
||||||
:wallet-legacy [wallet-legacy-bottom props]
|
(case share-qr-type
|
||||||
:wallet-multichain [wallet-multichain-bottom props]
|
:profile [profile-bottom props]
|
||||||
nil)]])
|
:wallet-legacy [wallet-legacy-bottom props]
|
||||||
|
:wallet-multichain [wallet-multichain-bottom props]
|
||||||
|
nil)]]])
|
||||||
|
|
||||||
(defn view
|
(defn- view-internal
|
||||||
"Receives the following properties:
|
"Receives the following properties:
|
||||||
- type: :profile | :wallet-legacy | :wallet-multichain
|
- type: :profile | :wallet-legacy | :wallet-multichain
|
||||||
- qr-image-uri: Image source value.
|
- qr-image-uri: Image source value.
|
||||||
@@ -190,16 +192,9 @@
|
|||||||
Sometimes while using a blur layer on top of another on Android, this component looks
|
Sometimes while using a blur layer on top of another on Android, this component looks
|
||||||
bad because of the `blur/view`, so we can set `unblur-on-android? true` to fix it.
|
bad because of the `blur/view`, so we can set `unblur-on-android? true` to fix it.
|
||||||
"
|
"
|
||||||
[{:keys [unblur-on-android?] :as props}]
|
[props]
|
||||||
(reagent/with-let [component-width (reagent/atom nil)
|
(reagent/with-let [component-width (reagent/atom nil)
|
||||||
container-component (if (and platform/android? unblur-on-android?)
|
container-component [rn/view {:background-color style/overlay-color}]]
|
||||||
[rn/view {:background-color style/overlay-color}]
|
|
||||||
[blur/view
|
|
||||||
{:blur-radius 20
|
|
||||||
:blur-amount 20
|
|
||||||
:blur-type :transparent
|
|
||||||
:overlay-color style/overlay-color
|
|
||||||
:background-color style/overlay-color}])]
|
|
||||||
[quo.theme/provider {:theme :dark}
|
[quo.theme/provider {:theme :dark}
|
||||||
[rn/view
|
[rn/view
|
||||||
{:accessibility-label :share-qr-code
|
{:accessibility-label :share-qr-code
|
||||||
@@ -211,3 +206,6 @@
|
|||||||
(-> props
|
(-> props
|
||||||
(assoc :component-width @component-width)
|
(assoc :component-width @component-width)
|
||||||
(clojure.set/rename-keys {:type :share-qr-type}))]))]]))
|
(clojure.set/rename-keys {:type :share-qr-type}))]))]]))
|
||||||
|
|
||||||
|
|
||||||
|
(def view (quo.theme/with-theme view-internal))
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
- :token-symbol - string"
|
- :token-symbol - string"
|
||||||
[]
|
[]
|
||||||
(let [container-width (reagent/atom 0)]
|
(let [container-width (reagent/atom 0)]
|
||||||
(fn [{:keys [options size blur? theme token-value token-symbol]
|
(fn [{:keys [options size blur? theme token-value token-img-src token-symbol]
|
||||||
:or {size :size-24}}]
|
:or {size :size-24}}]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:on-layout #(reset! container-width
|
{:on-layout #(reset! container-width
|
||||||
@@ -42,11 +42,12 @@
|
|||||||
[])}
|
[])}
|
||||||
[rn/view {:style (style/container size options blur? theme)}
|
[rn/view {:style (style/container size options blur? theme)}
|
||||||
[token/view
|
[token/view
|
||||||
{:style (style/token-img size)
|
{:style (style/token-img size)
|
||||||
:token token-symbol
|
:token token-symbol
|
||||||
:size (case size
|
:size (case size
|
||||||
:size-24 :size-20
|
:size-24 :size-20
|
||||||
:size-32 :size-28)}]
|
:size-32 :size-28)
|
||||||
|
:image-source token-img-src}]
|
||||||
[text/text
|
[text/text
|
||||||
{:size :paragraph-2
|
{:size :paragraph-2
|
||||||
:weight :medium
|
:weight :medium
|
||||||
|
|||||||
@@ -15,9 +15,7 @@
|
|||||||
[:token {:optional true} [:or keyword? string?]]
|
[:token {:optional true} [:or keyword? string?]]
|
||||||
[:style {:optional true} map?]
|
[:style {:optional true} map?]
|
||||||
;; Ignores `token` and uses this as parameter to `rn/image`'s source.
|
;; Ignores `token` and uses this as parameter to `rn/image`'s source.
|
||||||
[:image-source {:optional true} [:or :schema.common/image-source :string]]
|
[:image-source {:optional true} [:or :schema.common/image-source :string]]]]
|
||||||
;; If true, adds `data:image/png;base64,` as prefix to the string passed as `image-source`
|
|
||||||
[:add-b64-prefix? {:optional true} boolean?]]]
|
|
||||||
:any])
|
:any])
|
||||||
|
|
||||||
(defn- size->number
|
(defn- size->number
|
||||||
@@ -52,28 +50,32 @@
|
|||||||
first
|
first
|
||||||
string/capitalize)]])
|
string/capitalize)]])
|
||||||
|
|
||||||
|
(defn- normalize-b64-string
|
||||||
|
[b64-image]
|
||||||
|
(if (string/starts-with? b64-image "data:image/")
|
||||||
|
b64-image
|
||||||
|
(str b64-png-image-prefix b64-image)))
|
||||||
|
|
||||||
(defn view-internal
|
(defn view-internal
|
||||||
"Render a token image.
|
"Render a token image.
|
||||||
Props:
|
Props:
|
||||||
- style: extra styles to apply to the `rn/image` component.
|
- style: extra styles to apply to the `rn/image` component.
|
||||||
- size: `:size-nn` or just `nn`, being `nn` any number. Defaults to 32.
|
- size: `:size-nn` or just `nn`, being `nn` any number. Defaults to 32.
|
||||||
- token: string or keyword, it can contain upper case letters or not.
|
- token: string or keyword, it can contain upper case letters or not.
|
||||||
E.g. all of these are valid and resolve to the same:
|
E.g. all of these are valid and resolve to the same:
|
||||||
:token/snt | :snt | :SNT | \"SNT\" | \"snt\".
|
:token/snt | :snt | :SNT | \"SNT\" | \"snt\".
|
||||||
- image-source: Ignores `token` and uses this as parameter to `rn/image`'s source.
|
- image-source: Ignores `token` and uses this as parameter to `rn/image`'s source, it
|
||||||
- add-b64-prefix?: If true, adds `data:image/png;base64,` as prefix to the string
|
can be a b64 string representing an image.
|
||||||
passed as `image-source`.
|
|
||||||
"
|
"
|
||||||
[{:keys [token size style image-source add-b64-prefix?]
|
[{:keys [token size style image-source]
|
||||||
:or {size 32}}]
|
:or {size 32}}]
|
||||||
(let [b64-string (if (and image-source add-b64-prefix?)
|
(let [img-src (if (string? image-source)
|
||||||
(str b64-png-image-prefix image-source)
|
(normalize-b64-string image-source)
|
||||||
image-source)
|
image-source)]
|
||||||
source (or b64-string (token-loader/get-token-image token))]
|
(if-let [existing-source (or img-src (token-loader/get-token-image token))]
|
||||||
(if source
|
|
||||||
[rn/image
|
[rn/image
|
||||||
{:style (token-style style size)
|
{:style (token-style style size)
|
||||||
:source source}]
|
:source existing-source}]
|
||||||
[temp-empty-symbol token size style])))
|
[temp-empty-symbol token size style])))
|
||||||
|
|
||||||
(def view (schema/instrument #'view-internal ?schema))
|
(def view (schema/instrument #'view-internal ?schema))
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
(ns quo.components.wallet.token-input.style
|
(ns quo.components.wallet.token-input.style
|
||||||
(:require
|
(:require
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[quo.foundations.typography :as typography]
|
[quo.foundations.typography :as typography]))
|
||||||
[react-native.platform :as platform]))
|
|
||||||
|
|
||||||
(defn main-container
|
(defn main-container
|
||||||
[width]
|
[width]
|
||||||
@@ -16,23 +15,55 @@
|
|||||||
:flex-direction :row
|
:flex-direction :row
|
||||||
:justify-content :space-between})
|
:justify-content :space-between})
|
||||||
|
|
||||||
(defn text-input
|
(defn token-name
|
||||||
[theme]
|
[theme]
|
||||||
(merge typography/heading-1
|
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||||
{:font-weight "600"
|
:margin-right 8
|
||||||
:margin-left 8
|
:padding-bottom 2})
|
||||||
:margin-right (if platform/ios? 6 4)
|
|
||||||
:color (colors/theme-colors colors/neutral-100 colors/white theme)
|
(def token-label-container
|
||||||
:padding 0
|
{:position :absolute
|
||||||
:text-align :center
|
:left 40 ; token image size + margin
|
||||||
:height "100%"}))
|
:right 0
|
||||||
|
:bottom 0
|
||||||
|
:top 0
|
||||||
|
:flex-direction :row
|
||||||
|
:align-items :flex-end})
|
||||||
|
|
||||||
|
(def text-input-container
|
||||||
|
{:position :absolute
|
||||||
|
:top 0
|
||||||
|
:bottom 0
|
||||||
|
:left 40 ; token image size + margin
|
||||||
|
:right 0})
|
||||||
|
|
||||||
|
(def text-input-dimensions
|
||||||
|
(-> typography/heading-1
|
||||||
|
(dissoc :letter-spacing)
|
||||||
|
(assoc :font-weight "600"
|
||||||
|
:margin-right 5
|
||||||
|
:padding-left 0
|
||||||
|
:padding-right 0
|
||||||
|
:padding-top 0
|
||||||
|
:padding-bottom 0
|
||||||
|
:height "100%")))
|
||||||
|
|
||||||
|
(defn text-input
|
||||||
|
[theme error?]
|
||||||
|
(assoc text-input-dimensions
|
||||||
|
:color
|
||||||
|
(if error?
|
||||||
|
(colors/resolve-color :danger theme)
|
||||||
|
(colors/theme-colors colors/neutral-100 colors/white theme))))
|
||||||
|
|
||||||
|
(defn placeholder-text
|
||||||
|
[theme]
|
||||||
|
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme))
|
||||||
|
|
||||||
(defn divider
|
(defn divider
|
||||||
[width theme]
|
[theme]
|
||||||
{:height 1
|
{:margin-vertical 8
|
||||||
:width width
|
:background-color (colors/theme-colors colors/neutral-10 colors/neutral-90 theme)})
|
||||||
:background-color (colors/theme-colors colors/neutral-10 colors/neutral-90 theme)
|
|
||||||
:margin-vertical 8})
|
|
||||||
|
|
||||||
(def data-container
|
(def data-container
|
||||||
{:padding-top 4
|
{:padding-top 4
|
||||||
@@ -40,3 +71,7 @@
|
|||||||
:flex-direction :row
|
:flex-direction :row
|
||||||
:justify-content :space-between
|
:justify-content :space-between
|
||||||
:align-items :center})
|
:align-items :center})
|
||||||
|
|
||||||
|
(defn fiat-amount
|
||||||
|
[theme]
|
||||||
|
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
|
||||||
|
|||||||
@@ -7,85 +7,137 @@
|
|||||||
[quo.components.tags.network-tags.view :as network-tag]
|
[quo.components.tags.network-tags.view :as network-tag]
|
||||||
[quo.components.utilities.token.view :as token]
|
[quo.components.utilities.token.view :as token]
|
||||||
[quo.components.wallet.token-input.style :as style]
|
[quo.components.wallet.token-input.style :as style]
|
||||||
[quo.foundations.colors :as colors]
|
|
||||||
[quo.foundations.common :as common]
|
[quo.foundations.common :as common]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]))
|
[reagent.core :as reagent]))
|
||||||
|
|
||||||
|
(defn fiat-format
|
||||||
|
[currency num-value conversion]
|
||||||
|
(str (get common/currency-label currency) (.toFixed (* num-value conversion) 2)))
|
||||||
|
|
||||||
|
(defn crypto-format
|
||||||
|
[num-value conversion crypto-decimals token]
|
||||||
|
(str (.toFixed (/ num-value conversion) (or crypto-decimals 2))
|
||||||
|
" "
|
||||||
|
(string/upper-case (or (clj->js token) ""))))
|
||||||
|
|
||||||
(defn calc-value
|
(defn calc-value
|
||||||
[crypto? currency token value conversion]
|
[{:keys [crypto? currency token value conversion crypto-decimals]}]
|
||||||
(let [num-value (if (string? value) (parse-double (or value "0")) value)]
|
(let [num-value (if (string? value)
|
||||||
|
(or (parse-double value) 0)
|
||||||
|
value)]
|
||||||
(if crypto?
|
(if crypto?
|
||||||
(str (get common/currency-label currency) (.toFixed (* num-value conversion) 2))
|
(fiat-format currency num-value conversion)
|
||||||
(str (.toFixed (/ num-value conversion) 2) " " (string/upper-case (or (clj->js token) ""))))))
|
(crypto-format num-value conversion crypto-decimals token))))
|
||||||
|
|
||||||
|
(defn- data-info
|
||||||
|
[{:keys [theme token crypto-decimals conversion networks title crypto? currency amount error?]}]
|
||||||
|
[rn/view {:style style/data-container}
|
||||||
|
[network-tag/view
|
||||||
|
{:networks networks
|
||||||
|
:title title
|
||||||
|
:status (when error? :error)}]
|
||||||
|
[text/text
|
||||||
|
{:size :paragraph-2
|
||||||
|
:weight :medium
|
||||||
|
:style (style/fiat-amount theme)}
|
||||||
|
(calc-value {:crypto? crypto?
|
||||||
|
:currency currency
|
||||||
|
:token token
|
||||||
|
:value amount
|
||||||
|
:conversion conversion
|
||||||
|
:crypto-decimals crypto-decimals})]])
|
||||||
|
|
||||||
|
(defn- token-name-text
|
||||||
|
[theme text]
|
||||||
|
[text/text
|
||||||
|
{:style (style/token-name theme)
|
||||||
|
:size :paragraph-2
|
||||||
|
:weight :semi-bold}
|
||||||
|
(string/upper-case (or (clj->js text) ""))])
|
||||||
|
|
||||||
|
(defn- token-label
|
||||||
|
[{:keys [theme value text]}]
|
||||||
|
[rn/view
|
||||||
|
{:style style/token-label-container
|
||||||
|
:pointer-events :none}
|
||||||
|
[rn/text-input
|
||||||
|
{:max-length 12
|
||||||
|
:style style/text-input-dimensions
|
||||||
|
:editable false
|
||||||
|
:placeholder "0"
|
||||||
|
:opacity 0
|
||||||
|
:value value}]
|
||||||
|
[token-name-text theme text]])
|
||||||
|
|
||||||
|
(defn input-section
|
||||||
|
[{:keys [on-change-text value value-atom]}]
|
||||||
|
(let [input-ref (atom nil)
|
||||||
|
set-ref #(reset! input-ref %)
|
||||||
|
focus-input #(when-let [ref ^js @input-ref]
|
||||||
|
(.focus ref))
|
||||||
|
controlled-input? (some? value)
|
||||||
|
handle-on-change-text (fn [v]
|
||||||
|
(when-not controlled-input?
|
||||||
|
(reset! value-atom v))
|
||||||
|
(when on-change-text
|
||||||
|
(on-change-text v)))]
|
||||||
|
(fn [{:keys [theme token customization-color show-keyboard? crypto? currency value error?]
|
||||||
|
:or {show-keyboard? true}}]
|
||||||
|
[rn/pressable
|
||||||
|
{:on-press focus-input
|
||||||
|
:style {:flex 1}}
|
||||||
|
[token/view
|
||||||
|
{:token token
|
||||||
|
:size :size-32}]
|
||||||
|
[rn/view {:style style/text-input-container}
|
||||||
|
[rn/text-input
|
||||||
|
(cond-> {:style (style/text-input theme error?)
|
||||||
|
:placeholder-text-color (style/placeholder-text theme)
|
||||||
|
:auto-focus true
|
||||||
|
:ref set-ref
|
||||||
|
:placeholder "0"
|
||||||
|
:keyboard-type :numeric
|
||||||
|
:max-length 12
|
||||||
|
:on-change-text handle-on-change-text
|
||||||
|
:selection-color customization-color
|
||||||
|
:show-soft-input-on-focus show-keyboard?}
|
||||||
|
controlled-input? (assoc :value value)
|
||||||
|
(not controlled-input?) (assoc :default-value @value-atom))]]
|
||||||
|
[token-label
|
||||||
|
{:theme theme
|
||||||
|
:text (if crypto? token currency)
|
||||||
|
:value (if controlled-input? value @value-atom)}]])))
|
||||||
|
|
||||||
(defn- view-internal
|
(defn- view-internal
|
||||||
[{external-value :value}]
|
[{:keys [on-swap]}]
|
||||||
(let [width (:width (rn/get-window))
|
(let [width (:width (rn/get-window))
|
||||||
value (reagent/atom nil)
|
value-atom (reagent/atom nil)
|
||||||
crypto? (reagent/atom true)
|
crypto? (reagent/atom true)
|
||||||
input-ref (atom nil)
|
handle-on-swap (fn []
|
||||||
controlled-input? (some? external-value)]
|
(swap! crypto? not)
|
||||||
(fn [{:keys [theme token currency conversion networks title customization-color
|
(when on-swap
|
||||||
on-change-text on-swap container-style show-keyboard?]
|
(on-swap @crypto?)))]
|
||||||
:or {show-keyboard? true}
|
(fn [{:keys [theme container-style value] :as props}]
|
||||||
external-value :value}]
|
[rn/view {:style (merge (style/main-container width) container-style)}
|
||||||
[rn/view
|
|
||||||
{:style (merge
|
|
||||||
(style/main-container width)
|
|
||||||
container-style)}
|
|
||||||
[rn/view {:style style/amount-container}
|
[rn/view {:style style/amount-container}
|
||||||
[rn/pressable
|
[input-section
|
||||||
{:on-press #(when @input-ref (.focus ^js @input-ref))
|
(assoc props
|
||||||
:style {:flex-direction :row
|
:value-atom value-atom
|
||||||
:flex-grow 1
|
:crypto? @crypto?)]
|
||||||
:align-items :flex-end}}
|
|
||||||
[token/view {:token token :size :size-32}]
|
|
||||||
[rn/text-input
|
|
||||||
(cond-> {:auto-focus true
|
|
||||||
:ref #(reset! input-ref %)
|
|
||||||
:placeholder "0"
|
|
||||||
:placeholder-text-color (colors/theme-colors colors/neutral-40
|
|
||||||
colors/neutral-50
|
|
||||||
theme)
|
|
||||||
:keyboard-type :numeric
|
|
||||||
:max-length 12
|
|
||||||
:on-change-text (fn [v]
|
|
||||||
(when-not controlled-input?
|
|
||||||
(reset! value v))
|
|
||||||
(when on-change-text
|
|
||||||
(on-change-text v)))
|
|
||||||
:style (style/text-input theme)
|
|
||||||
:selection-color customization-color
|
|
||||||
:show-soft-input-on-focus show-keyboard?}
|
|
||||||
controlled-input? (assoc :value external-value)
|
|
||||||
(not controlled-input?) (assoc :default-value @value))]
|
|
||||||
[text/text
|
|
||||||
{:size :paragraph-2
|
|
||||||
:weight :semi-bold
|
|
||||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
|
||||||
:margin-right 8
|
|
||||||
:padding-bottom 2}}
|
|
||||||
(string/upper-case (or (clj->js (if @crypto? token currency)) ""))]]
|
|
||||||
[button/button
|
[button/button
|
||||||
{:icon true
|
{:icon true
|
||||||
:icon-only? true
|
:icon-only? true
|
||||||
:size 32
|
:size 32
|
||||||
:on-press (fn []
|
:on-press handle-on-swap
|
||||||
(swap! crypto? not)
|
|
||||||
(when on-swap
|
|
||||||
(on-swap @crypto?)))
|
|
||||||
:type :outline
|
:type :outline
|
||||||
:accessibility-label :reorder}
|
:accessibility-label :reorder}
|
||||||
:i/reorder]]
|
:i/reorder]]
|
||||||
[divider-line/view {:container-style {:margin-vertical 8}}]
|
[divider-line/view {:container-style (style/divider theme)}]
|
||||||
[rn/view {:style style/data-container}
|
[data-info
|
||||||
[network-tag/view {:networks networks :title title}]
|
(assoc props
|
||||||
[text/text
|
:crypto? @crypto?
|
||||||
{:size :paragraph-2
|
:amount (or value @value-atom))]])))
|
||||||
:weight :medium
|
|
||||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
|
||||||
(calc-value @crypto? currency token (or external-value @value) conversion)]]])))
|
|
||||||
|
|
||||||
(def view (quo.theme/with-theme view-internal))
|
(def view (quo.theme/with-theme view-internal))
|
||||||
|
|||||||
+5
-3
@@ -80,13 +80,14 @@
|
|||||||
quo.components.list-items.community.view
|
quo.components.list-items.community.view
|
||||||
quo.components.list-items.dapp.view
|
quo.components.list-items.dapp.view
|
||||||
quo.components.list-items.menu-item
|
quo.components.list-items.menu-item
|
||||||
|
quo.components.list-items.network-list.view
|
||||||
quo.components.list-items.preview-list.view
|
quo.components.list-items.preview-list.view
|
||||||
quo.components.list-items.quiz-item.view
|
quo.components.list-items.quiz-item.view
|
||||||
quo.components.list-items.saved-address.view
|
quo.components.list-items.saved-address.view
|
||||||
quo.components.list-items.saved-contact-address.view
|
quo.components.list-items.saved-contact-address.view
|
||||||
quo.components.list-items.token-network.view
|
quo.components.list-items.token-network.view
|
||||||
quo.components.list-items.token-value.view
|
quo.components.list-items.token-value.view
|
||||||
quo.components.list-items.user-list
|
quo.components.list-items.user
|
||||||
quo.components.loaders.skeleton-list.view
|
quo.components.loaders.skeleton-list.view
|
||||||
quo.components.markdown.list.view
|
quo.components.markdown.list.view
|
||||||
quo.components.markdown.text
|
quo.components.markdown.text
|
||||||
@@ -299,16 +300,17 @@
|
|||||||
(def account-list-card quo.components.list-items.account-list-card.view/view)
|
(def account-list-card quo.components.list-items.account-list-card.view/view)
|
||||||
(def address quo.components.list-items.address.view/view)
|
(def address quo.components.list-items.address.view/view)
|
||||||
(def channel quo.components.list-items.channel.view/view)
|
(def channel quo.components.list-items.channel.view/view)
|
||||||
(def community-list-item quo.components.list-items.community.view/view)
|
(def community-list quo.components.list-items.community.view/view)
|
||||||
(def dapp quo.components.list-items.dapp.view/view)
|
(def dapp quo.components.list-items.dapp.view/view)
|
||||||
(def menu-item quo.components.list-items.menu-item/menu-item)
|
(def menu-item quo.components.list-items.menu-item/menu-item)
|
||||||
|
(def network-list quo.components.list-items.network-list.view/view)
|
||||||
(def preview-list quo.components.list-items.preview-list.view/view)
|
(def preview-list quo.components.list-items.preview-list.view/view)
|
||||||
(def quiz-item quo.components.list-items.quiz-item.view/view)
|
(def quiz-item quo.components.list-items.quiz-item.view/view)
|
||||||
(def saved-address quo.components.list-items.saved-address.view/view)
|
(def saved-address quo.components.list-items.saved-address.view/view)
|
||||||
(def saved-contact-address quo.components.list-items.saved-contact-address.view/view)
|
(def saved-contact-address quo.components.list-items.saved-contact-address.view/view)
|
||||||
(def token-network quo.components.list-items.token-network.view/view)
|
(def token-network quo.components.list-items.token-network.view/view)
|
||||||
(def token-value quo.components.list-items.token-value.view/view)
|
(def token-value quo.components.list-items.token-value.view/view)
|
||||||
(def user-list quo.components.list-items.user-list/user-list)
|
(def user quo.components.list-items.user/user)
|
||||||
|
|
||||||
;;;; Loaders
|
;;;; Loaders
|
||||||
(def skeleton-list quo.components.loaders.skeleton-list.view/view)
|
(def skeleton-list quo.components.loaders.skeleton-list.view/view)
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
quo.components.list-items.channel.component-spec
|
quo.components.list-items.channel.component-spec
|
||||||
quo.components.list-items.community.component-spec
|
quo.components.list-items.community.component-spec
|
||||||
quo.components.list-items.dapp.component-spec
|
quo.components.list-items.dapp.component-spec
|
||||||
|
quo.components.list-items.network-list.component-spec
|
||||||
quo.components.list-items.quiz-item.component-spec
|
quo.components.list-items.quiz-item.component-spec
|
||||||
quo.components.list-items.saved-address.component-spec
|
quo.components.list-items.saved-address.component-spec
|
||||||
quo.components.list-items.saved-contact-address.component-spec
|
quo.components.list-items.saved-contact-address.component-spec
|
||||||
|
|||||||
@@ -17,19 +17,19 @@
|
|||||||
(fn [^js data]
|
(fn [^js data]
|
||||||
(let [^js section (.-section data)]
|
(let [^js section (.-section data)]
|
||||||
(reagent/as-element [f
|
(reagent/as-element [f
|
||||||
{:title (.-title section)
|
{:index (.-index section)
|
||||||
|
:title (.-title section)
|
||||||
:data (.-data section)}]))))
|
:data (.-data section)}]))))
|
||||||
|
|
||||||
(defn- wrap-per-section-render-fn
|
(defn- wrap-per-section-render-fn
|
||||||
[props]
|
[index props]
|
||||||
(update
|
(-> (if-let [f (:render-fn props)]
|
||||||
(if-let [f (:render-fn props)]
|
(assoc (dissoc props :render-fn :render-data)
|
||||||
(assoc (dissoc props :render-fn :render-data)
|
:renderItem
|
||||||
:renderItem
|
(memo-wrap-render-fn f (:render-data props)))
|
||||||
(memo-wrap-render-fn f (:render-data props)))
|
props)
|
||||||
props)
|
(update :data to-array)
|
||||||
:data
|
(assoc :index index)))
|
||||||
to-array))
|
|
||||||
|
|
||||||
(defn section-list
|
(defn section-list
|
||||||
"A wrapper for SectionList.
|
"A wrapper for SectionList.
|
||||||
@@ -42,6 +42,8 @@
|
|||||||
props
|
props
|
||||||
(when render-section-footer-fn
|
(when render-section-footer-fn
|
||||||
{:renderSectionFooter (wrap-render-section-header-fn render-section-footer-fn)})
|
{:renderSectionFooter (wrap-render-section-header-fn render-section-footer-fn)})
|
||||||
{:sections (clj->js (map wrap-per-section-render-fn sections))
|
{:sections (->> sections
|
||||||
|
(map-indexed wrap-per-section-render-fn)
|
||||||
|
(clj->js))
|
||||||
:renderSectionHeader (wrap-render-section-header-fn render-section-header-fn)
|
:renderSectionHeader (wrap-render-section-header-fn render-section-header-fn)
|
||||||
:style style})])
|
:style style})])
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
(ns status-im.common.contact-list.style)
|
||||||
|
|
||||||
|
(defn contacts-section-header
|
||||||
|
[first-item?]
|
||||||
|
{:padding-top (if first-item? 0 8)})
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
(ns status-im.common.contact-list.view
|
(ns status-im.common.contact-list.view
|
||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]))
|
[quo.core :as quo]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[status-im.common.contact-list.style :as style]))
|
||||||
|
|
||||||
(defn contacts-section-header
|
(defn contacts-section-header
|
||||||
[{:keys [title]}]
|
[{:keys [title index]}]
|
||||||
[quo/divider-label title])
|
[rn/view (style/contacts-section-header (= index 0))
|
||||||
|
[quo/divider-label title]])
|
||||||
|
|||||||
@@ -6,17 +6,21 @@
|
|||||||
|
|
||||||
(defn contact-list-item
|
(defn contact-list-item
|
||||||
[{:keys [on-press on-long-press accessory]}
|
[{:keys [on-press on-long-press accessory]}
|
||||||
{:keys [primary-name secondary-name public-key compressed-key ens-verified added?]}]
|
{:keys [primary-name secondary-name public-key compressed-key ens-verified added?]}
|
||||||
(let [photo-path (rf/sub [:chats/photo-path public-key])
|
theme]
|
||||||
online? (rf/sub [:visibility-status-updates/online? public-key])]
|
(let [photo-path (rf/sub [:chats/photo-path public-key])
|
||||||
[quo/user-list
|
online? (rf/sub [:visibility-status-updates/online? public-key])
|
||||||
{:short-chat-key (address/get-shortened-compressed-key (or compressed-key public-key))
|
customization-color (rf/sub [:profile/customization-color])]
|
||||||
:primary-name primary-name
|
[quo/user
|
||||||
:secondary-name secondary-name
|
{:customization-color customization-color
|
||||||
:photo-path photo-path
|
:theme theme
|
||||||
:online? online?
|
:short-chat-key (address/get-shortened-compressed-key (or compressed-key public-key))
|
||||||
:verified? ens-verified
|
:primary-name primary-name
|
||||||
:contact? added?
|
:secondary-name secondary-name
|
||||||
:on-press on-press
|
:photo-path photo-path
|
||||||
:on-long-press on-long-press
|
:online? online?
|
||||||
:accessory accessory}]))
|
:verified? ens-verified
|
||||||
|
:contact? added?
|
||||||
|
:on-press on-press
|
||||||
|
:on-long-press on-long-press
|
||||||
|
:accessory accessory}]))
|
||||||
|
|||||||
@@ -52,7 +52,8 @@
|
|||||||
:remove-listeners remove-listeners}))
|
:remove-listeners remove-listeners}))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [header footer customization-color gradient-cover?]} &
|
[{:keys [header footer customization-color footer-container-padding gradient-cover?]
|
||||||
|
:or {footer-container-padding (safe-area/get-top)}} &
|
||||||
children]
|
children]
|
||||||
(reagent/with-let [window-height (:height (rn/get-window))
|
(reagent/with-let [window-height (:height (rn/get-window))
|
||||||
footer-container-height (reagent/atom 0)
|
footer-container-height (reagent/atom 0)
|
||||||
@@ -94,7 +95,7 @@
|
|||||||
children)]
|
children)]
|
||||||
[rn/keyboard-avoiding-view
|
[rn/keyboard-avoiding-view
|
||||||
{:style style/keyboard-avoiding-view
|
{:style style/keyboard-avoiding-view
|
||||||
:keyboard-vertical-offset (if platform/ios? (safe-area/get-top) 0)
|
:keyboard-vertical-offset (if platform/ios? footer-container-padding 0)
|
||||||
:pointer-events :box-none}
|
:pointer-events :box-none}
|
||||||
[floating-container/view
|
[floating-container/view
|
||||||
{:on-layout set-footer-container-height
|
{:on-layout set-footer-container-height
|
||||||
|
|||||||
@@ -38,6 +38,9 @@
|
|||||||
:no-contacts
|
:no-contacts
|
||||||
{:light (js/require "../resources/images/ui2/no-contacts-light.png")
|
{:light (js/require "../resources/images/ui2/no-contacts-light.png")
|
||||||
:dark (js/require "../resources/images/ui2/no-contacts-dark.png")}
|
:dark (js/require "../resources/images/ui2/no-contacts-dark.png")}
|
||||||
|
:no-contacts-to-chat
|
||||||
|
{:light (js/require "../resources/images/ui2/no-contacts-to-chat-light.png")
|
||||||
|
:dark (js/require "../resources/images/ui2/no-contacts-to-chat-dark.png")}
|
||||||
:keycard-chip
|
:keycard-chip
|
||||||
{:light (js/require "../resources/images/ui2/keycard-chip-light.png")
|
{:light (js/require "../resources/images/ui2/keycard-chip-light.png")
|
||||||
:dark (js/require "../resources/images/ui2/keycard-chip-dark.png")}
|
:dark (js/require "../resources/images/ui2/keycard-chip-dark.png")}
|
||||||
|
|||||||
@@ -259,12 +259,6 @@
|
|||||||
{:type :wallet-account
|
{:type :wallet-account
|
||||||
:account (when account (string/lower-case account))})
|
:account (when account (string/lower-case account))})
|
||||||
|
|
||||||
(defn community-route-type
|
|
||||||
[route-params]
|
|
||||||
(if (string/starts-with? (:community-id route-params) "z")
|
|
||||||
:desktop-community
|
|
||||||
:community))
|
|
||||||
|
|
||||||
(defn handle-uri
|
(defn handle-uri
|
||||||
[chain chats uri cb]
|
[chain chats uri cb]
|
||||||
(let [{:keys [handler route-params query-params]} (match-uri uri)]
|
(let [{:keys [handler route-params query-params]} (match-uri uri)]
|
||||||
@@ -297,14 +291,14 @@
|
|||||||
(cb {:type handler :community-id (:community-id route-params)})
|
(cb {:type handler :community-id (:community-id route-params)})
|
||||||
|
|
||||||
(and (= handler :community) (:community-id route-params))
|
(and (= handler :community) (:community-id route-params))
|
||||||
(cb {:type (community-route-type route-params)
|
(cb {:type :community
|
||||||
:community-id (:community-id route-params)})
|
:community-id (:community-id route-params)})
|
||||||
|
|
||||||
(and (= handler :community-chat) (:community-channel-id route-params) (:community-id route-params))
|
(and (= handler :community-chat) (:community-channel-id route-params) (:community-id route-params))
|
||||||
(match-community-channel-async route-params cb)
|
(match-community-channel-async route-params cb)
|
||||||
|
|
||||||
(and (= handler :community-chat) (:community-id route-params))
|
(and (= handler :community-chat) (:community-id route-params))
|
||||||
(cb {:type (community-route-type route-params)
|
(cb {:type :community
|
||||||
:community-id (:community-id route-params)})
|
:community-id (:community-id route-params)})
|
||||||
|
|
||||||
;; NOTE: removed in `match-uri`, might need this in the future
|
;; NOTE: removed in `match-uri`, might need this in the future
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
(ns status-im.common.serialization
|
||||||
|
(:require
|
||||||
|
[native-module.core :as native-module]
|
||||||
|
[status-im.constants :as constants]
|
||||||
|
[utils.re-frame :as rf]
|
||||||
|
[utils.transforms :as transforms]))
|
||||||
|
|
||||||
|
(rf/reg-fx :serialization/deserialize-and-compress-key
|
||||||
|
(fn [{:keys [serialized-key on-success on-error]}]
|
||||||
|
(native-module/deserialize-and-compress-key
|
||||||
|
serialized-key
|
||||||
|
(fn [resp]
|
||||||
|
(let [{:keys [error]} (transforms/json->clj resp)]
|
||||||
|
(if error
|
||||||
|
(on-error error)
|
||||||
|
(on-success resp)))))))
|
||||||
|
|
||||||
|
(rf/reg-fx :serialization/decompress-public-key
|
||||||
|
(fn [{:keys [compressed-key on-success on-error]}]
|
||||||
|
(native-module/compressed-key->public-key
|
||||||
|
compressed-key
|
||||||
|
constants/deserialization-key
|
||||||
|
(fn [resp]
|
||||||
|
(let [{:keys [error]} (transforms/json->clj resp)]
|
||||||
|
(if error
|
||||||
|
(on-error error)
|
||||||
|
(on-success (str "0x" (subs resp 5)))))))))
|
||||||
@@ -2,12 +2,12 @@
|
|||||||
(:require
|
(:require
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[goog.string :as gstring]
|
[goog.string :as gstring]
|
||||||
[native-module.core :as native-module]
|
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[react-native.async-storage :as async-storage]
|
[react-native.async-storage :as async-storage]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[schema.core :as schema]
|
[schema.core :as schema]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
|
[status-im.contexts.communities.events :as communities.events]
|
||||||
[status-im.navigation.events :as navigation]
|
[status-im.navigation.events :as navigation]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[utils.ethereum.chain :as chain]
|
[utils.ethereum.chain :as chain]
|
||||||
@@ -68,32 +68,6 @@
|
|||||||
(log/info "universal-links: handling community request " community-id)
|
(log/info "universal-links: handling community request " community-id)
|
||||||
(navigation/navigate-to cofx :community-requests-to-join {:community-id community-id}))
|
(navigation/navigate-to cofx :community-requests-to-join {:community-id community-id}))
|
||||||
|
|
||||||
(rf/defn handle-community
|
|
||||||
[cofx {:keys [community-id]}]
|
|
||||||
(log/info "universal-links: handling community" community-id)
|
|
||||||
(navigation/navigate-to cofx :community {:community-id community-id}))
|
|
||||||
|
|
||||||
(rf/defn handle-navigation-to-desktop-community-from-mobile
|
|
||||||
{:events [:handle-navigation-to-desktop-community-from-mobile]}
|
|
||||||
[cofx deserialized-key]
|
|
||||||
(rf/merge
|
|
||||||
cofx
|
|
||||||
{:dispatch [:navigate-to :community-overview deserialized-key]}
|
|
||||||
(navigation/pop-to-root :shell-stack)))
|
|
||||||
|
|
||||||
(rf/defn handle-desktop-community
|
|
||||||
[_ {:keys [community-id]}]
|
|
||||||
(native-module/deserialize-and-compress-key
|
|
||||||
community-id
|
|
||||||
(fn [deserialized-key]
|
|
||||||
(rf/dispatch [:chat.ui/fetch-community (str deserialized-key)])
|
|
||||||
(rf/dispatch [:handle-navigation-to-desktop-community-from-mobile (str deserialized-key)]))))
|
|
||||||
|
|
||||||
(rf/defn handle-community-chat
|
|
||||||
[cofx {:keys [chat-id]}]
|
|
||||||
(log/info "universal-links: handling community chat" chat-id)
|
|
||||||
{:dispatch [:chat/pop-to-root-and-navigate-to-chat chat-id]})
|
|
||||||
|
|
||||||
(rf/defn handle-view-profile
|
(rf/defn handle-view-profile
|
||||||
[{:keys [db] :as cofx} {:keys [public-key ens-name]}]
|
[{:keys [db] :as cofx} {:keys [public-key ens-name]}]
|
||||||
(log/info "universal-links: handling view profile" public-key)
|
(log/info "universal-links: handling view profile" public-key)
|
||||||
@@ -143,14 +117,13 @@
|
|||||||
|
|
||||||
(rf/defn on-handle
|
(rf/defn on-handle
|
||||||
{:events [::match-value]}
|
{:events [::match-value]}
|
||||||
[cofx url {:keys [type] :as data}]
|
[cofx url {:keys [type chat-id] :as data}]
|
||||||
(case type
|
(case type
|
||||||
:group-chat (handle-group-chat cofx data)
|
:group-chat (handle-group-chat cofx data)
|
||||||
:private-chat (handle-private-chat cofx data)
|
:private-chat (handle-private-chat cofx data)
|
||||||
:community-requests (handle-community-requests cofx data)
|
:community-requests (handle-community-requests cofx data)
|
||||||
:community (handle-community cofx data)
|
:community (communities.events/navigate-to-serialized-community cofx data)
|
||||||
:desktop-community (handle-desktop-community cofx data)
|
:community-chat {:dispatch [:communities/navigate-to-community-chat chat-id :pop-to-root]}
|
||||||
:community-chat (handle-community-chat cofx data)
|
|
||||||
:contact (handle-view-profile cofx data)
|
:contact (handle-view-profile cofx data)
|
||||||
:browser (handle-browse cofx data)
|
:browser (handle-browse cofx data)
|
||||||
:eip681 (handle-eip681 cofx data)
|
:eip681 (handle-eip681 cofx data)
|
||||||
|
|||||||
@@ -338,6 +338,13 @@
|
|||||||
(def ^:const local-pairing-action-sync-device 3)
|
(def ^:const local-pairing-action-sync-device 3)
|
||||||
(def ^:const local-pairing-action-pairing-installation 4)
|
(def ^:const local-pairing-action-pairing-installation 4)
|
||||||
|
|
||||||
|
(def ^:const serialization-key
|
||||||
|
"We pass this serialization key as a parameter to MultiformatSerializePublicKey
|
||||||
|
function at status-go, This key determines the output base of the serialization.
|
||||||
|
according to https://specs.status.im/spec/2#public-key-serialization we serialize
|
||||||
|
keys with base58btc encoding"
|
||||||
|
"z")
|
||||||
|
|
||||||
(def ^:const deserialization-key
|
(def ^:const deserialization-key
|
||||||
"We pass this deserialization key as a parameter to MultiformatDeserializePublicKey
|
"We pass this deserialization key as a parameter to MultiformatDeserializePublicKey
|
||||||
function at status-go, This key determines the output base of the deserialization.
|
function at status-go, This key determines the output base of the deserialization.
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
{:icon :i/add-user
|
{:icon :i/add-user
|
||||||
:accessibility-label :add-a-contact
|
:accessibility-label :add-a-contact
|
||||||
:label (i18n/label :t/add-a-contact)
|
:label (i18n/label :t/add-a-contact)
|
||||||
:sub-label (i18n/label :t/enter-a-chat-key)
|
:sub-label (i18n/label :t/enter-chat-key)
|
||||||
:add-divider? true
|
:add-divider? true
|
||||||
:on-press #(debounce/dispatch-and-chill
|
:on-press #(debounce/dispatch-and-chill
|
||||||
[:open-modal :new-contact]
|
[:open-modal :new-contact]
|
||||||
|
|||||||
@@ -1,21 +1,7 @@
|
|||||||
(ns status-im.contexts.chat.home.add-new-contact.effects
|
(ns status-im.contexts.chat.home.add-new-contact.effects
|
||||||
(:require
|
(:require
|
||||||
[legacy.status-im.ethereum.ens :as ens]
|
[legacy.status-im.ethereum.ens :as ens]
|
||||||
[native-module.core :as native-module]
|
[utils.re-frame :as rf]))
|
||||||
[status-im.constants :as constants]
|
|
||||||
[utils.re-frame :as rf]
|
|
||||||
[utils.transforms :as transforms]))
|
|
||||||
|
|
||||||
(rf/reg-fx :effects.contacts/decompress-public-key
|
|
||||||
(fn [{:keys [compressed-key on-success on-error]}]
|
|
||||||
(native-module/compressed-key->public-key
|
|
||||||
compressed-key
|
|
||||||
constants/deserialization-key
|
|
||||||
(fn [resp]
|
|
||||||
(let [{:keys [error]} (transforms/json->clj resp)]
|
|
||||||
(if error
|
|
||||||
(on-error error)
|
|
||||||
(on-success (str "0x" (subs resp 5)))))))))
|
|
||||||
|
|
||||||
(rf/reg-fx :effects.contacts/resolve-public-key-from-ens
|
(rf/reg-fx :effects.contacts/resolve-public-key-from-ens
|
||||||
(fn [{:keys [chain-id ens on-success on-error]}]
|
(fn [{:keys [chain-id ens on-success on-error]}]
|
||||||
|
|||||||
@@ -104,7 +104,7 @@
|
|||||||
:empty {:db (dissoc db :contacts/new-identity)}
|
:empty {:db (dissoc db :contacts/new-identity)}
|
||||||
(:valid :invalid) {:db (assoc db :contacts/new-identity contact)}
|
(:valid :invalid) {:db (assoc db :contacts/new-identity contact)}
|
||||||
:decompress-key {:db (assoc db :contacts/new-identity contact)
|
:decompress-key {:db (assoc db :contacts/new-identity contact)
|
||||||
:effects.contacts/decompress-public-key
|
:serialization/decompress-public-key
|
||||||
{:compressed-key id
|
{:compressed-key id
|
||||||
:on-success
|
:on-success
|
||||||
(dispatcher :contacts/set-new-identity-success input)
|
(dispatcher :contacts/set-new-identity-success input)
|
||||||
|
|||||||
@@ -132,7 +132,7 @@
|
|||||||
:type :compressed-key
|
:type :compressed-key
|
||||||
:public-key nil ; not yet...
|
:public-key nil ; not yet...
|
||||||
:state :decompress-key}))
|
:state :decompress-key}))
|
||||||
:effects.contacts/decompress-public-key
|
:serialization/decompress-public-key
|
||||||
{:compressed-key user-ckey
|
{:compressed-key user-ckey
|
||||||
:on-success [:contacts/set-new-identity-success user-ckey]
|
:on-success [:contacts/set-new-identity-success user-ckey]
|
||||||
:on-error [:contacts/set-new-identity-error user-ckey]}})))
|
:on-error [:contacts/set-new-identity-error user-ckey]}})))
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
[]
|
[]
|
||||||
{:size :heading-1
|
{:size :heading-1
|
||||||
:weight :semi-bold
|
:weight :semi-bold
|
||||||
:style {:margin-top 32
|
:style {:margin-top 28
|
||||||
:margin-bottom 6
|
:margin-bottom 6
|
||||||
:color (colors/theme-colors colors/neutral-100 colors/white)}})
|
:color (colors/theme-colors colors/neutral-100 colors/white)}})
|
||||||
|
|
||||||
|
|||||||
@@ -16,33 +16,38 @@
|
|||||||
|
|
||||||
(defn- no-contacts-view
|
(defn- no-contacts-view
|
||||||
[{:keys [theme]}]
|
[{:keys [theme]}]
|
||||||
[rn/view
|
(let [customization-color (rf/sub [:profile/customization-color])]
|
||||||
{:style (style/no-contacts)}
|
[rn/view
|
||||||
[rn/image {:source (resources/get-themed-image :no-contacts theme)}]
|
{:style (style/no-contacts)}
|
||||||
[quo/text
|
[rn/image {:source (resources/get-themed-image :no-contacts-to-chat theme)}]
|
||||||
{:weight :semi-bold
|
[quo/text
|
||||||
:size :paragraph-1
|
{:weight :semi-bold
|
||||||
:style {:margin-bottom 2
|
:size :paragraph-1
|
||||||
:margin-top 12}}
|
:style {:margin-bottom 2
|
||||||
(i18n/label :t/you-have-no-contacts)]
|
:margin-top 12}}
|
||||||
[quo/text
|
(i18n/label :t/you-have-no-contacts)]
|
||||||
{:weight :regular
|
[quo/text
|
||||||
:size :label}
|
{:weight :regular
|
||||||
(i18n/label :t/dont-yell-at-me)]
|
:size :paragraph-2}
|
||||||
[quo/button
|
(i18n/label :t/dont-yell-at-me)]
|
||||||
{:type :primary
|
[quo/button
|
||||||
:size 32
|
{:customization-color customization-color
|
||||||
:container-style {:margin-top 20
|
:theme theme
|
||||||
:margin-bottom 12}
|
:type :primary
|
||||||
:on-press #(rf/dispatch [:invite.events/share-link])}
|
:size 32
|
||||||
(i18n/label :t/invite-friends)]
|
:container-style {:margin-top 20
|
||||||
[quo/button
|
:margin-bottom 12}
|
||||||
{:type :grey
|
:on-press #(rf/dispatch [:invite.events/share-link])}
|
||||||
:size 32
|
(i18n/label :t/invite-friends)]
|
||||||
:on-press #(do
|
[quo/button
|
||||||
(rf/dispatch [:navigate-back])
|
{:customization-color customization-color
|
||||||
(rf/dispatch [:open-modal :new-contact]))}
|
:theme theme
|
||||||
(i18n/label :t/add-a-contact)]])
|
:type :grey
|
||||||
|
:size 32
|
||||||
|
:on-press #(do
|
||||||
|
(rf/dispatch [:navigate-back])
|
||||||
|
(rf/dispatch [:open-modal :new-contact]))}
|
||||||
|
(i18n/label :t/add-a-contact)]]))
|
||||||
|
|
||||||
(defn contact-item-render
|
(defn contact-item-render
|
||||||
[_]
|
[_]
|
||||||
|
|||||||
@@ -73,7 +73,7 @@
|
|||||||
:shared-value scroll-shared-value})}])))
|
:shared-value scroll-shared-value})}])))
|
||||||
|
|
||||||
(defn contact-item-render
|
(defn contact-item-render
|
||||||
[{:keys [public-key] :as item}]
|
[{:keys [public-key] :as item} theme]
|
||||||
(let [current-pk (rf/sub [:multiaccount/public-key])
|
(let [current-pk (rf/sub [:multiaccount/public-key])
|
||||||
show-profile-actions #(rf/dispatch [:show-bottom-sheet
|
show-profile-actions #(rf/dispatch [:show-bottom-sheet
|
||||||
{:content (fn [] [actions/contact-actions item])}])]
|
{:content (fn [] [actions/contact-actions item])}])]
|
||||||
@@ -83,7 +83,8 @@
|
|||||||
:on-long-press show-profile-actions
|
:on-long-press show-profile-actions
|
||||||
:accessory {:type :options
|
:accessory {:type :options
|
||||||
:on-press show-profile-actions}})
|
:on-press show-profile-actions}})
|
||||||
item]))
|
item
|
||||||
|
theme]))
|
||||||
|
|
||||||
(defn contacts
|
(defn contacts
|
||||||
[{:keys [theme pending-contact-requests set-scroll-ref scroll-shared-value]}]
|
[{:keys [theme pending-contact-requests set-scroll-ref scroll-shared-value]}]
|
||||||
@@ -105,7 +106,8 @@
|
|||||||
:sections items
|
:sections items
|
||||||
:sticky-section-headers-enabled false
|
:sticky-section-headers-enabled false
|
||||||
:render-section-header-fn contact-list/contacts-section-header
|
:render-section-header-fn contact-list/contacts-section-header
|
||||||
:render-fn contact-item-render
|
:render-fn (fn [data]
|
||||||
|
(contact-item-render data theme))
|
||||||
:scroll-event-throttle 8
|
:scroll-event-throttle 8
|
||||||
:on-scroll #(common.banner/set-scroll-shared-value
|
:on-scroll #(common.banner/set-scroll-shared-value
|
||||||
{:scroll-input (oops/oget % "nativeEvent.contentOffset.y")
|
{:scroll-input (oops/oget % "nativeEvent.contentOffset.y")
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
(js/setTimeout #(reanimated/set-shared-value background-y
|
(js/setTimeout #(reanimated/set-shared-value background-y
|
||||||
(- window-height))
|
(- window-height))
|
||||||
300)
|
300)
|
||||||
(rf/dispatch [:chat.ui/replace-mentions-and-send-current-message])
|
(rf/dispatch [:chat.ui/send-current-message])
|
||||||
(rf/dispatch [:chat.ui/set-input-maximized false])
|
(rf/dispatch [:chat.ui/set-input-maximized false])
|
||||||
(rf/dispatch [:chat.ui/set-input-content-height comp-constants/input-height])
|
(rf/dispatch [:chat.ui/set-input-content-height comp-constants/input-height])
|
||||||
(rf/dispatch [:chat.ui/set-chat-input-text nil])
|
(rf/dispatch [:chat.ui/set-chat-input-text nil])
|
||||||
|
|||||||
@@ -114,9 +114,8 @@
|
|||||||
[{:keys [input-ref]}
|
[{:keys [input-ref]}
|
||||||
{:keys [text-value saved-cursor-position cursor-position]}
|
{:keys [text-value saved-cursor-position cursor-position]}
|
||||||
{:keys [edit input-with-mentions]}
|
{:keys [edit input-with-mentions]}
|
||||||
messages-list-on-layout-finished?]
|
chat-screen-layout-calculations-complete?]
|
||||||
(let [mention? (some #(= :mention (first %)) (seq input-with-mentions))
|
(let [mention? (some #(= :mention (first %)) (seq input-with-mentions))]
|
||||||
composer-just-opened? (not @messages-list-on-layout-finished?)]
|
|
||||||
(rn/use-effect
|
(rn/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
(let [mention-text (reduce (fn [acc item]
|
(let [mention-text (reduce (fn [acc item]
|
||||||
@@ -128,7 +127,9 @@
|
|||||||
;; NOTE: using text-value for cases when the user
|
;; NOTE: using text-value for cases when the user
|
||||||
;; leaves the app with an unfinished edit and re-opens
|
;; leaves the app with an unfinished edit and re-opens
|
||||||
;; the chat.
|
;; the chat.
|
||||||
(and (seq @text-value) composer-just-opened?)
|
(and (seq @text-value)
|
||||||
|
(not (reanimated/get-shared-value
|
||||||
|
chat-screen-layout-calculations-complete?)))
|
||||||
@text-value
|
@text-value
|
||||||
:else (get-in edit [:content :text]))
|
:else (get-in edit [:content :text]))
|
||||||
selection-pos (count edit-text)
|
selection-pos (count edit-text)
|
||||||
@@ -150,7 +151,9 @@
|
|||||||
;; UI. This way, `on-focus` will trigger first without changing the height, after which
|
;; UI. This way, `on-focus` will trigger first without changing the height, after which
|
||||||
;; `on-content-size-change` will animate the height of the input based on the injected
|
;; `on-content-size-change` will animate the height of the input based on the injected
|
||||||
;; text.
|
;; text.
|
||||||
(js/setTimeout #(do (when @messages-list-on-layout-finished? (.focus ^js @input-ref))
|
(js/setTimeout #(do (when (reanimated/get-shared-value
|
||||||
|
chat-screen-layout-calculations-complete?)
|
||||||
|
(.focus ^js @input-ref))
|
||||||
(reagent/next-tick inject-edit-text))
|
(reagent/next-tick inject-edit-text))
|
||||||
600))))
|
600))))
|
||||||
[(:message-id edit)])))
|
[(:message-id edit)])))
|
||||||
@@ -159,12 +162,12 @@
|
|||||||
[{:keys [input-ref]}
|
[{:keys [input-ref]}
|
||||||
{:keys [container-opacity]}
|
{:keys [container-opacity]}
|
||||||
{:keys [reply]}
|
{:keys [reply]}
|
||||||
messages-list-on-layout-finished?]
|
chat-screen-layout-calculations-complete?]
|
||||||
(rn/use-effect
|
(rn/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
(when reply
|
(when reply
|
||||||
(reanimated/animate container-opacity 1))
|
(reanimated/animate container-opacity 1))
|
||||||
(when (and reply @input-ref @messages-list-on-layout-finished?)
|
(when (and reply @input-ref (reanimated/get-shared-value chat-screen-layout-calculations-complete?))
|
||||||
(js/setTimeout #(.focus ^js @input-ref) 600)))
|
(js/setTimeout #(.focus ^js @input-ref) 600)))
|
||||||
[(:message-id reply)]))
|
[(:message-id reply)]))
|
||||||
|
|
||||||
|
|||||||
@@ -207,24 +207,12 @@
|
|||||||
(link-preview/reset-unfurled)
|
(link-preview/reset-unfurled)
|
||||||
(cancel-message-edit)))
|
(cancel-message-edit)))
|
||||||
|
|
||||||
(rf/defn replace-mentions-and-send-current-message
|
(rf/defn send-current-message
|
||||||
"Sends message from current chat input"
|
"Sends message from current chat input"
|
||||||
{:events [:chat.ui/replace-mentions-and-send-current-message]}
|
{:events [:chat.ui/send-current-message]}
|
||||||
[{{:keys [current-chat-id] :as db} :db}]
|
[{{:keys [current-chat-id] :as db} :db :as cofx}]
|
||||||
(let [{:keys [input-text metadata]} (get-in db [:chat/inputs current-chat-id])]
|
(let [{:keys [input-text metadata]} (get-in db [:chat/inputs current-chat-id])
|
||||||
{:json-rpc/call [{:method "wakuext_chatMentionReplaceWithPublicKey"
|
editing-message (:editing-message metadata)]
|
||||||
:params [current-chat-id input-text]
|
(if editing-message
|
||||||
:on-error #(log/error "[wakuext_chatMentionReplaceWithPublicKey] on-error" %)
|
(send-edited-message cofx input-text editing-message)
|
||||||
:on-success #(rf/dispatch [:chat.ui/send-current-message-with-mentions
|
(send-messages cofx input-text current-chat-id))))
|
||||||
current-chat-id
|
|
||||||
(:editing-message metadata)
|
|
||||||
input-text
|
|
||||||
%])}]}))
|
|
||||||
|
|
||||||
(rf/defn send-current-message-with-mentions
|
|
||||||
{:events [:chat.ui/send-current-message-with-mentions]}
|
|
||||||
[{:keys [db] :as cofx} current-chat-id editing-message input-text new-text]
|
|
||||||
(rf/merge cofx
|
|
||||||
(if editing-message
|
|
||||||
(send-edited-message new-text editing-message)
|
|
||||||
(send-messages new-text current-chat-id))))
|
|
||||||
|
|||||||
@@ -127,8 +127,9 @@
|
|||||||
(defn change-text
|
(defn change-text
|
||||||
"Update `text-value`, update cursor selection, find links, find mentions"
|
"Update `text-value`, update cursor selection, find links, find mentions"
|
||||||
[text
|
[text
|
||||||
{:keys [input-ref record-reset-fn]}
|
{:keys [input-ref record-reset-fn] :as props}
|
||||||
{:keys [text-value cursor-position recording?]}]
|
{:keys [text-value cursor-position recording?]}
|
||||||
|
scroll-to-end]
|
||||||
(reset! text-value text)
|
(reset! text-value text)
|
||||||
(reagent/next-tick #(when @input-ref
|
(reagent/next-tick #(when @input-ref
|
||||||
(.setNativeProps ^js @input-ref
|
(.setNativeProps ^js @input-ref
|
||||||
@@ -140,6 +141,8 @@
|
|||||||
(rf/dispatch [:chat.ui/set-chat-input-text text])
|
(rf/dispatch [:chat.ui/set-chat-input-text text])
|
||||||
(debounce/debounce-and-dispatch [:link-preview/unfurl-urls text]
|
(debounce/debounce-and-dispatch [:link-preview/unfurl-urls text]
|
||||||
constants/unfurl-debounce-ms)
|
constants/unfurl-debounce-ms)
|
||||||
|
(when (string/ends-with? text (with-out-str (newline)))
|
||||||
|
(scroll-to-end props))
|
||||||
(if (string/ends-with? text "@")
|
(if (string/ends-with? text "@")
|
||||||
(rf/dispatch [:mention/on-change-text text])
|
(rf/dispatch [:mention/on-change-text text])
|
||||||
(debounce/debounce-and-dispatch [:mention/on-change-text text] 300)))
|
(debounce/debounce-and-dispatch [:mention/on-change-text text] 300)))
|
||||||
|
|||||||
@@ -69,17 +69,11 @@
|
|||||||
:min-height constants/input-height})
|
:min-height constants/input-height})
|
||||||
|
|
||||||
(defn input-text
|
(defn input-text
|
||||||
[{:keys [saved-emoji-kb-extra-height]}
|
[{:keys [maximized?]}
|
||||||
{:keys [focused? maximized?]}
|
{:keys [theme]}]
|
||||||
{:keys [max-height theme]}]
|
|
||||||
(assoc typography/paragraph-1
|
(assoc typography/paragraph-1
|
||||||
:color (colors/theme-colors :black :white theme)
|
:color (colors/theme-colors :black :white theme)
|
||||||
:text-align-vertical :top
|
:text-align-vertical :top
|
||||||
:position (if @saved-emoji-kb-extra-height :relative :absolute)
|
|
||||||
:top 0
|
|
||||||
:left 0
|
|
||||||
:right (when (or focused? platform/ios?) 0)
|
|
||||||
:max-height max-height
|
|
||||||
:padding-bottom (when @maximized? 0)))
|
:padding-bottom (when @maximized? 0)))
|
||||||
|
|
||||||
(defn background
|
(defn background
|
||||||
|
|||||||
@@ -175,7 +175,8 @@
|
|||||||
:record-reset-fn (atom nil)
|
:record-reset-fn (atom nil)
|
||||||
:scroll-y (atom 0)
|
:scroll-y (atom 0)
|
||||||
:selection-event (atom nil)
|
:selection-event (atom nil)
|
||||||
:selection-manager (rn/selectable-text-input-manager)})
|
:selection-manager (rn/selectable-text-input-manager)
|
||||||
|
:composer-scrollview-ref (atom nil)})
|
||||||
|
|
||||||
(defn init-reactive-state
|
(defn init-reactive-state
|
||||||
[]
|
[]
|
||||||
|
|||||||
@@ -31,12 +31,12 @@
|
|||||||
(defn sheet-component
|
(defn sheet-component
|
||||||
[{:keys [insets
|
[{:keys [insets
|
||||||
chat-list-scroll-y
|
chat-list-scroll-y
|
||||||
|
chat-screen-layout-calculations-complete?
|
||||||
window-height
|
window-height
|
||||||
blur-height
|
blur-height
|
||||||
opacity
|
opacity
|
||||||
background-y
|
background-y
|
||||||
theme
|
theme]} props state]
|
||||||
messages-list-on-layout-finished?]} props state]
|
|
||||||
(let [subscriptions (utils/init-subs)
|
(let [subscriptions (utils/init-subs)
|
||||||
content-height (reagent/atom (or (:input-content-height ; Actual text height
|
content-height (reagent/atom (or (:input-content-height ; Actual text height
|
||||||
subscriptions)
|
subscriptions)
|
||||||
@@ -68,15 +68,22 @@
|
|||||||
;; Cursor position, needed to determine where to display the mentions view
|
;; Cursor position, needed to determine where to display the mentions view
|
||||||
cursor-pos (utils/cursor-y-position-relative-to-container
|
cursor-pos (utils/cursor-y-position-relative-to-container
|
||||||
props
|
props
|
||||||
state)]
|
state)
|
||||||
|
scroll-to-end (fn []
|
||||||
|
;; Needs to be queued, Otherwise might not be called on the right
|
||||||
|
;; time.
|
||||||
|
(js/setTimeout #(when @(:composer-scrollview-ref props)
|
||||||
|
(.scrollToEnd @(:composer-scrollview-ref props)))
|
||||||
|
50))
|
||||||
|
chat-screen-loaded? (rf/sub [:shell/chat-screen-loaded?])]
|
||||||
(effects/did-mount props)
|
(effects/did-mount props)
|
||||||
(effects/initialize props
|
(effects/initialize props
|
||||||
state
|
state
|
||||||
animations
|
animations
|
||||||
dimensions
|
dimensions
|
||||||
subscriptions)
|
subscriptions)
|
||||||
(effects/use-edit props state subscriptions messages-list-on-layout-finished?)
|
(effects/use-edit props state subscriptions chat-screen-layout-calculations-complete?)
|
||||||
(effects/use-reply props animations subscriptions messages-list-on-layout-finished?)
|
(effects/use-reply props animations subscriptions chat-screen-layout-calculations-complete?)
|
||||||
(effects/update-input-mention props state subscriptions)
|
(effects/update-input-mention props state subscriptions)
|
||||||
(effects/link-previews props state animations subscriptions)
|
(effects/link-previews props state animations subscriptions)
|
||||||
(effects/use-images props state animations subscriptions)
|
(effects/use-images props state animations subscriptions)
|
||||||
@@ -90,8 +97,7 @@
|
|||||||
{:style style/composer-sheet-and-jump-to-container}
|
{:style style/composer-sheet-and-jump-to-container}
|
||||||
[sub-view/shell-button state chat-list-scroll-y window-height]
|
[sub-view/shell-button state chat-list-scroll-y window-height]
|
||||||
[gesture/gesture-detector
|
[gesture/gesture-detector
|
||||||
{:gesture
|
{:gesture (drag-gesture/drag-gesture props state animations dimensions keyboard-shown)}
|
||||||
(drag-gesture/drag-gesture props state animations dimensions keyboard-shown)}
|
|
||||||
[reanimated/view
|
[reanimated/view
|
||||||
{:style (style/sheet-container insets state animations theme)
|
{:style (style/sheet-container insets state animations theme)
|
||||||
:on-layout #(handler/layout % state blur-height)}
|
:on-layout #(handler/layout % state blur-height)}
|
||||||
@@ -112,55 +118,60 @@
|
|||||||
{:ref #(reset! (:selectable-input-ref props) %)
|
{:ref #(reset! (:selectable-input-ref props) %)
|
||||||
:menu-items @(:menu-items state)
|
:menu-items @(:menu-items state)
|
||||||
:style (style/input-view state)}
|
:style (style/input-view state)}
|
||||||
[rn/text-input
|
;; https://github.com/facebook/react-native/issues/39660
|
||||||
{:ref #(reset! (:input-ref props) %)
|
[rn/scroll-view
|
||||||
:default-value @(:text-value state)
|
{:on-scroll #(handler/scroll % props state animations dimensions)
|
||||||
:on-focus #(handler/focus props state animations dimensions)
|
:keyboard-should-persist-taps :handled
|
||||||
:on-blur #(handler/blur state animations dimensions subscriptions)
|
:scroll-event-throttle 64
|
||||||
:on-content-size-change #(handler/content-size-change %
|
:ref #(reset! (:composer-scrollview-ref props) %)
|
||||||
state
|
:shows-vertical-scroll-indicator false}
|
||||||
animations
|
[rn/text-input
|
||||||
dimensions
|
{:ref #(reset! (:input-ref props) %)
|
||||||
(or keyboard-shown
|
:default-value @(:text-value state)
|
||||||
(:edit subscriptions)))
|
:on-focus #(handler/focus props state animations dimensions)
|
||||||
:on-scroll #(handler/scroll % props state animations dimensions)
|
:on-blur #(handler/blur state animations dimensions subscriptions)
|
||||||
:on-change-text #(handler/change-text % props state)
|
:on-change-text #(handler/change-text % props state scroll-to-end)
|
||||||
:on-selection-change #(handler/selection-change % props state)
|
:on-selection-change #(handler/selection-change % props state)
|
||||||
:on-selection #(selection/on-selection % props state)
|
:on-content-size-change #(handler/content-size-change %1
|
||||||
:keyboard-appearance (quo.theme/theme-value :light :dark)
|
state
|
||||||
:max-font-size-multiplier 1
|
animations
|
||||||
:multiline true
|
dimensions
|
||||||
:placeholder (i18n/label :t/type-something)
|
(or keyboard-shown
|
||||||
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50)
|
(:edit subscriptions)))
|
||||||
:style (style/input-text props
|
:on-selection #(selection/on-selection % props state)
|
||||||
state
|
:keyboard-appearance (quo.theme/theme-value :light :dark)
|
||||||
{:max-height max-height
|
:max-font-size-multiplier 1
|
||||||
:theme theme})
|
:multiline true
|
||||||
:max-length constants/max-text-size
|
:scroll-enabled false
|
||||||
:accessibility-label :chat-message-input}]]]
|
:placeholder (i18n/label :t/type-something)
|
||||||
[:<>
|
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50)
|
||||||
[gradients/view props state animations show-bottom-gradient?]
|
:style (style/input-text state
|
||||||
[link-preview/view]
|
{:max-height max-height
|
||||||
[images/images-list]]
|
:theme theme})
|
||||||
|
:max-length constants/max-text-size
|
||||||
|
:accessibility-label :chat-message-input}]]]]
|
||||||
|
(when chat-screen-loaded?
|
||||||
|
[:<>
|
||||||
|
[gradients/view props state animations show-bottom-gradient?]
|
||||||
|
[link-preview/view]
|
||||||
|
[images/images-list]])
|
||||||
[:f> actions/view props state animations window-height insets subscriptions]]]]]))
|
[:f> actions/view props state animations window-height insets subscriptions]]]]]))
|
||||||
|
|
||||||
(defn f-composer
|
(defn f-composer
|
||||||
[{:keys [insets chat-list-scroll-y messages-list-on-layout-finished?]}]
|
[props]
|
||||||
(let [window-height (:height (rn/get-window))
|
(let [window-height (:height (rn/get-window))
|
||||||
theme (quo.theme/use-theme-value)
|
theme (quo.theme/use-theme-value)
|
||||||
opacity (reanimated/use-shared-value 0)
|
opacity (reanimated/use-shared-value 0)
|
||||||
background-y (reanimated/use-shared-value (- window-height)) ; Y position of background
|
background-y (reanimated/use-shared-value (- window-height)) ; Y position of background
|
||||||
; overlay
|
; overlay
|
||||||
blur-height (reanimated/use-shared-value (+ constants/composer-default-height
|
blur-height (reanimated/use-shared-value (+ constants/composer-default-height
|
||||||
(:bottom insets)))
|
(:bottom (:insets props))))
|
||||||
extra-params {:insets insets
|
extra-params (assoc props
|
||||||
:window-height window-height
|
:window-height window-height
|
||||||
:chat-list-scroll-y chat-list-scroll-y
|
:blur-height blur-height
|
||||||
:blur-height blur-height
|
:opacity opacity
|
||||||
:opacity opacity
|
:background-y background-y
|
||||||
:background-y background-y
|
:theme theme)
|
||||||
:theme theme
|
|
||||||
:messages-list-on-layout-finished? messages-list-on-layout-finished?}
|
|
||||||
props (utils/init-non-reactive-state)
|
props (utils/init-non-reactive-state)
|
||||||
state (utils/init-reactive-state)]
|
state (utils/init-reactive-state)]
|
||||||
[rn/view (when platform/ios? {:style {:z-index 1}})
|
[rn/view (when platform/ios? {:style {:z-index 1}})
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
(get constants/reactions (:emoji-id reaction))))
|
(get constants/reactions (:emoji-id reaction))))
|
||||||
|
|
||||||
(defn- view-internal
|
(defn- view-internal
|
||||||
[{:keys [message-id chat-id pinned-by theme]} user-message-content]
|
[{:keys [message-id chat-id pinned-by preview? theme]} user-message-content]
|
||||||
(let [reactions (rf/sub [:chats/message-reactions message-id chat-id])]
|
(let [reactions (rf/sub [:chats/message-reactions message-id chat-id])]
|
||||||
[:<>
|
[:<>
|
||||||
(when (seq reactions)
|
(when (seq reactions)
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
{:container-style {:margin-left 44
|
{:container-style {:margin-left 44
|
||||||
:margin-top 8}
|
:margin-top 8}
|
||||||
:reactions (map add-emoji-key reactions)
|
:reactions (map add-emoji-key reactions)
|
||||||
:add-reaction? true
|
:add-reaction? (not preview?)
|
||||||
:use-case (when pinned-by :pinned)
|
:use-case (when pinned-by :pinned)
|
||||||
:on-press #(on-press (assoc % :message-id message-id))
|
:on-press #(on-press (assoc % :message-id message-id))
|
||||||
:on-long-press #(on-long-press (assoc %
|
:on-long-press #(on-long-press (assoc %
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
(:require
|
(:require
|
||||||
[quo.foundations.colors :as colors]))
|
[quo.foundations.colors :as colors]))
|
||||||
|
|
||||||
|
(def ^:private message-padding-scaling-ratio 4.5)
|
||||||
|
|
||||||
(defn message-container
|
(defn message-container
|
||||||
([]
|
([]
|
||||||
(message-container false nil nil false))
|
(message-container false nil nil false))
|
||||||
@@ -16,10 +18,16 @@
|
|||||||
(assoc :margin-top 4))))
|
(assoc :margin-top 4))))
|
||||||
|
|
||||||
(defn user-message-content
|
(defn user-message-content
|
||||||
[{:keys [outgoing outgoing-status]}]
|
[{:keys [outgoing outgoing-status six-reactions? window-scale small-screen?]}]
|
||||||
{:border-radius 16
|
{:border-radius 16
|
||||||
:padding-horizontal 8
|
:padding-horizontal 8
|
||||||
:padding-vertical 4
|
:padding-top 4
|
||||||
|
:padding-bottom (if (or small-screen?
|
||||||
|
(and
|
||||||
|
(> 3 window-scale)
|
||||||
|
six-reactions?))
|
||||||
|
(* message-padding-scaling-ratio window-scale)
|
||||||
|
4)
|
||||||
:opacity (if (and outgoing (= outgoing-status :sending))
|
:opacity (if (and outgoing (= outgoing-status :sending))
|
||||||
0.5
|
0.5
|
||||||
1)})
|
1)})
|
||||||
|
|||||||
@@ -119,31 +119,38 @@
|
|||||||
[]
|
[]
|
||||||
(let [show-delivery-state? (reagent/atom false)]
|
(let [show-delivery-state? (reagent/atom false)]
|
||||||
(fn [{:keys [message-data context keyboard-shown? show-reactions? in-reaction-and-action-menu?
|
(fn [{:keys [message-data context keyboard-shown? show-reactions? in-reaction-and-action-menu?
|
||||||
show-user-info? theme]}]
|
show-user-info? preview? theme]}]
|
||||||
(let [{:keys [content-type quoted-message content
|
(let [{:keys [content-type quoted-message content
|
||||||
outgoing outgoing-status pinned-by]} message-data
|
outgoing outgoing-status pinned-by
|
||||||
first-image (first (:album message-data))
|
message-id chat-id]} message-data
|
||||||
outgoing-status (if (= content-type
|
first-image (first (:album message-data))
|
||||||
constants/content-type-album)
|
outgoing-status (if (= content-type
|
||||||
(:outgoing-status first-image)
|
constants/content-type-album)
|
||||||
outgoing-status)
|
(:outgoing-status first-image)
|
||||||
outgoing (if (= content-type
|
outgoing-status)
|
||||||
constants/content-type-album)
|
outgoing (if (= content-type
|
||||||
(:outgoing first-image)
|
constants/content-type-album)
|
||||||
outgoing)
|
(:outgoing first-image)
|
||||||
context (assoc context
|
outgoing)
|
||||||
:on-long-press
|
context (assoc context
|
||||||
#(on-long-press message-data
|
:on-long-press
|
||||||
context
|
#(on-long-press message-data
|
||||||
keyboard-shown?))
|
context
|
||||||
response-to (:response-to content)
|
keyboard-shown?))
|
||||||
height (rf/sub [:dimensions/window-height])
|
response-to (:response-to content)
|
||||||
{window-width :width} (rn/get-window)
|
height (rf/sub [:dimensions/window-height])
|
||||||
message-container-data {:window-width window-width
|
{window-width :width
|
||||||
:padding-right 20
|
window-scale :scale} (rn/get-window)
|
||||||
:padding-left 20
|
message-container-data {:window-width window-width
|
||||||
:avatar-container-width 32
|
:padding-right 20
|
||||||
:message-margin-left 8}]
|
:padding-left 20
|
||||||
|
:avatar-container-width 32
|
||||||
|
:message-margin-left 8}
|
||||||
|
reactions (rf/sub [:chats/message-reactions message-id
|
||||||
|
chat-id])
|
||||||
|
six-reactions? (-> reactions
|
||||||
|
count
|
||||||
|
(= 6))]
|
||||||
[rn/touchable-highlight
|
[rn/touchable-highlight
|
||||||
{:accessibility-label (if (and outgoing (= outgoing-status :sending))
|
{:accessibility-label (if (and outgoing (= outgoing-status :sending))
|
||||||
:message-sending
|
:message-sending
|
||||||
@@ -152,7 +159,10 @@
|
|||||||
:style (style/user-message-content
|
:style (style/user-message-content
|
||||||
{:first-in-group? (:first-in-group? message-data)
|
{:first-in-group? (:first-in-group? message-data)
|
||||||
:outgoing outgoing
|
:outgoing outgoing
|
||||||
:outgoing-status outgoing-status})
|
:outgoing-status outgoing-status
|
||||||
|
:small-screen? rn/small-screen?
|
||||||
|
:window-scale window-scale
|
||||||
|
:six-reactions? six-reactions?})
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(if (and platform/ios? keyboard-shown?)
|
(if (and platform/ios? keyboard-shown?)
|
||||||
(do
|
(do
|
||||||
@@ -212,7 +222,7 @@
|
|||||||
(when @show-delivery-state?
|
(when @show-delivery-state?
|
||||||
[status/status outgoing-status])])]
|
[status/status outgoing-status])])]
|
||||||
(when show-reactions?
|
(when show-reactions?
|
||||||
[reactions/message-reactions-row message-data
|
[reactions/message-reactions-row (assoc message-data :preview? preview?)
|
||||||
[rn/view {:pointer-events :none}
|
[rn/view {:pointer-events :none}
|
||||||
[user-message-content-internal
|
[user-message-content-internal
|
||||||
{:theme theme
|
{:theme theme
|
||||||
@@ -226,22 +236,24 @@
|
|||||||
(defn on-long-press
|
(defn on-long-press
|
||||||
[{:keys [deleted? deleted-for-me?] :as message-data} context keyboard-shown?]
|
[{:keys [deleted? deleted-for-me?] :as message-data} context keyboard-shown?]
|
||||||
(rf/dispatch [:dismiss-keyboard])
|
(rf/dispatch [:dismiss-keyboard])
|
||||||
(rf/dispatch [:show-bottom-sheet
|
(rf/dispatch
|
||||||
{:content (drawers/reactions-and-actions message-data context)
|
[:show-bottom-sheet
|
||||||
:border-radius 16
|
{:content (drawers/reactions-and-actions message-data context)
|
||||||
:selected-item
|
:border-radius 16
|
||||||
(if (or deleted? deleted-for-me?)
|
:selected-item
|
||||||
(fn [] [content.deleted/deleted-message message-data])
|
(if (or deleted? deleted-for-me?)
|
||||||
(fn []
|
(fn [] [content.deleted/deleted-message message-data])
|
||||||
[rn/view
|
(fn []
|
||||||
{:pointer-events :none
|
[rn/view
|
||||||
:padding-top 4}
|
{:pointer-events :none
|
||||||
[user-message-content
|
:padding-top 4}
|
||||||
{:message-data message-data
|
[user-message-content
|
||||||
:context context
|
{:message-data message-data
|
||||||
:keyboard-shown? keyboard-shown?
|
:context context
|
||||||
:show-reactions? true
|
:keyboard-shown? keyboard-shown?
|
||||||
:show-user-info? true}]]))}]))
|
:show-reactions? true
|
||||||
|
:show-user-info? true
|
||||||
|
:preview? true}]]))}]))
|
||||||
|
|
||||||
(defn system-message?
|
(defn system-message?
|
||||||
[content-type]
|
[content-type]
|
||||||
|
|||||||
@@ -8,9 +8,7 @@
|
|||||||
:justify-content :center})
|
:justify-content :center})
|
||||||
|
|
||||||
(def tab-icon
|
(def tab-icon
|
||||||
{:margin-right 4
|
{:margin-right 4})
|
||||||
:width 20
|
|
||||||
:height 20})
|
|
||||||
|
|
||||||
(defn tab-count
|
(defn tab-count
|
||||||
[active? theme]
|
[active? theme]
|
||||||
|
|||||||
@@ -34,10 +34,10 @@
|
|||||||
{:id reaction-type-int
|
{:id reaction-type-int
|
||||||
:accessibility-label (keyword (str "authors-for-reaction-" reaction-type-int))
|
:accessibility-label (keyword (str "authors-for-reaction-" reaction-type-int))
|
||||||
:label [rn/view {:style style/tab}
|
:label [rn/view {:style style/tab}
|
||||||
[rn/image
|
[rn/text
|
||||||
{:source (reactions.resource/get-reaction
|
{:style style/tab-icon}
|
||||||
(get constants/reactions reaction-type-int))
|
(reactions.resource/system-emojis
|
||||||
:style style/tab-icon}]
|
(get constants/reactions reaction-type-int))]
|
||||||
[quo/text
|
[quo/text
|
||||||
{:weight :medium
|
{:weight :medium
|
||||||
:size :paragraph-1
|
:size :paragraph-1
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
(ns status-im.contexts.chat.messenger.messages.link-preview.events
|
(ns status-im.contexts.chat.messenger.messages.link-preview.events
|
||||||
(:require
|
(:require
|
||||||
[camel-snake-kebab.core :as csk]
|
[camel-snake-kebab.core :as csk]
|
||||||
[legacy.status-im.mailserver.core :as mailserver]
|
|
||||||
[schema.core :as schema]
|
|
||||||
[status-im.contexts.profile.settings.events :as profile.settings.events]
|
[status-im.contexts.profile.settings.events :as profile.settings.events]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[utils.collection]
|
[utils.collection]
|
||||||
@@ -42,96 +40,6 @@
|
|||||||
(boolean enabled?)
|
(boolean enabled?)
|
||||||
{}))
|
{}))
|
||||||
|
|
||||||
(defn community-resolved
|
|
||||||
[{:keys [db]} [community-id community]]
|
|
||||||
(when community
|
|
||||||
{:db (update db :communities/resolve-community-info dissoc community-id)
|
|
||||||
:fx [[:dispatch [:communities/handle-community community]]
|
|
||||||
[:dispatch
|
|
||||||
[:chat.ui/cache-link-preview-data (community-link community-id) community]]]}))
|
|
||||||
|
|
||||||
(rf/reg-event-fx :chat.ui/community-resolved community-resolved)
|
|
||||||
|
|
||||||
(defn community-failed-to-resolve
|
|
||||||
[{:keys [db]} [community-id]]
|
|
||||||
{:db (update db :communities/resolve-community-info dissoc community-id)})
|
|
||||||
|
|
||||||
(rf/reg-event-fx :chat.ui/community-failed-to-resolve community-failed-to-resolve)
|
|
||||||
|
|
||||||
(defn fetch-community
|
|
||||||
[{:keys [db]} [community-id]]
|
|
||||||
(when community-id
|
|
||||||
{:db (assoc-in db [:communities/resolve-community-info community-id] true)
|
|
||||||
:json-rpc/call [{:method "wakuext_fetchCommunity"
|
|
||||||
:params [{:CommunityKey community-id
|
|
||||||
:TryDatabase true
|
|
||||||
:WaitForResponse true}]
|
|
||||||
:on-success (fn [community]
|
|
||||||
(rf/dispatch [:chat.ui/community-resolved community-id community]))
|
|
||||||
:on-error (fn [err]
|
|
||||||
(rf/dispatch [:chat.ui/community-failed-to-resolve community-id])
|
|
||||||
(log/error {:message
|
|
||||||
"Failed to request community info from mailserver"
|
|
||||||
:error err}))}]}))
|
|
||||||
|
|
||||||
(schema/=> fetch-community
|
|
||||||
[:=>
|
|
||||||
[:catn
|
|
||||||
[:cofx :schema.re-frame/cofx]
|
|
||||||
[:args
|
|
||||||
[:schema [:catn [:community-id [:? :string]]]]]]
|
|
||||||
[:maybe
|
|
||||||
[:map
|
|
||||||
[:db map?]
|
|
||||||
[:json-rpc/call :schema.common/rpc-call]]]])
|
|
||||||
|
|
||||||
(rf/reg-event-fx :chat.ui/fetch-community fetch-community)
|
|
||||||
|
|
||||||
(defn spectate-community-success
|
|
||||||
[{:keys [db]} [{:keys [communities]}]]
|
|
||||||
(when-let [community (first communities)]
|
|
||||||
{:db (-> db
|
|
||||||
(assoc-in [:communities (:id community) :spectated] true)
|
|
||||||
(assoc-in [:communities (:id community) :spectating] false))
|
|
||||||
:fx [[:dispatch [:communities/handle-community community]]
|
|
||||||
[:dispatch [::mailserver/request-messages]]]}))
|
|
||||||
|
|
||||||
(rf/reg-event-fx :chat.ui/spectate-community-success spectate-community-success)
|
|
||||||
|
|
||||||
(defn spectate-community-failed
|
|
||||||
[{:keys [db]} [community-id]]
|
|
||||||
{:db (assoc-in db [:communities community-id :spectating] false)})
|
|
||||||
|
|
||||||
(rf/reg-event-fx :chat.ui/spectate-community-failed spectate-community-failed)
|
|
||||||
|
|
||||||
(defn spectate-community
|
|
||||||
[{:keys [db]} [community-id]]
|
|
||||||
(let [{:keys [spectated spectating joined]} (get-in db [:communities community-id])]
|
|
||||||
(when (and (not joined) (not spectated) (not spectating))
|
|
||||||
{:db (assoc-in db [:communities community-id :spectating] true)
|
|
||||||
:json-rpc/call [{:method "wakuext_spectateCommunity"
|
|
||||||
:params [community-id]
|
|
||||||
:on-success [:chat.ui/spectate-community-success]
|
|
||||||
:on-error (fn [err]
|
|
||||||
(log/error {:message
|
|
||||||
"Failed to spectate community"
|
|
||||||
:error err})
|
|
||||||
(rf/dispatch [:chat.ui/spectate-community-failed
|
|
||||||
community-id]))}]})))
|
|
||||||
|
|
||||||
(schema/=> spectate-community
|
|
||||||
[:=>
|
|
||||||
[:catn
|
|
||||||
[:cofx :schema.re-frame/cofx]
|
|
||||||
[:args
|
|
||||||
[:schema [:catn [:community-id [:? :string]]]]]]
|
|
||||||
[:maybe
|
|
||||||
[:map
|
|
||||||
[:db map?]
|
|
||||||
[:json-rpc/call :schema.common/rpc-call]]]])
|
|
||||||
|
|
||||||
(rf/reg-event-fx :chat.ui/spectate-community spectate-community)
|
|
||||||
|
|
||||||
(rf/defn save-link-preview-whitelist
|
(rf/defn save-link-preview-whitelist
|
||||||
{:events [:chat.ui/link-preview-whitelist-received]}
|
{:events [:chat.ui/link-preview-whitelist-received]}
|
||||||
[{:keys [db]} whitelist]
|
[{:keys [db]} whitelist]
|
||||||
|
|||||||
@@ -1,139 +0,0 @@
|
|||||||
(ns status-im.contexts.chat.messenger.messages.link-preview.events-test
|
|
||||||
(:require [cljs.test :as t]
|
|
||||||
[legacy.status-im.mailserver.core :as mailserver]
|
|
||||||
matcher-combinators.test
|
|
||||||
[status-im.contexts.chat.messenger.messages.link-preview.events :as sut]))
|
|
||||||
|
|
||||||
(t/deftest fetch-community
|
|
||||||
(t/testing "with community id"
|
|
||||||
(t/testing "update resolving indicator in db"
|
|
||||||
(t/is (match?
|
|
||||||
{:db {:communities/resolve-community-info {"community-id" true}}}
|
|
||||||
(sut/fetch-community {} ["community-id"]))))
|
|
||||||
(t/testing "call the fetch community rpc method with correct community id"
|
|
||||||
(t/is (match?
|
|
||||||
{:json-rpc/call [{:method "wakuext_fetchCommunity"
|
|
||||||
:params [{:CommunityKey "community-id"
|
|
||||||
:TryDatabase true
|
|
||||||
:WaitForResponse true}]}]}
|
|
||||||
(sut/fetch-community {} ["community-id"])))))
|
|
||||||
(t/testing "with no community id"
|
|
||||||
(t/testing "do nothing"
|
|
||||||
(t/is (match?
|
|
||||||
nil
|
|
||||||
(sut/fetch-community {} []))))))
|
|
||||||
|
|
||||||
(t/deftest community-failed-to-resolve
|
|
||||||
(t/testing "given a community id"
|
|
||||||
(t/testing "remove community id from resolving indicator in db"
|
|
||||||
(t/is (match?
|
|
||||||
nil
|
|
||||||
(get-in (sut/community-failed-to-resolve {:db {:communities/resolve-community-info
|
|
||||||
{"community-id" true}}}
|
|
||||||
["community-id"])
|
|
||||||
[:db :communities/resolve-community-info "community-id"]))))))
|
|
||||||
|
|
||||||
(t/deftest community-resolved
|
|
||||||
(with-redefs [sut/community-link (fn [id] (str "community-link+" id))]
|
|
||||||
(t/testing "given a community"
|
|
||||||
(let [cofx {:db {:communities/resolve-community-info {"community-id" true}}}
|
|
||||||
arg ["community-id" {:id "community-id"}]]
|
|
||||||
(t/testing "remove community id from resolving indicator in db"
|
|
||||||
(t/is (match?
|
|
||||||
nil
|
|
||||||
(get-in (sut/community-resolved cofx arg)
|
|
||||||
[:db :communities/resolve-community-info "community-id"]))))
|
|
||||||
(t/testing "dispatch fxs"
|
|
||||||
(t/is (match?
|
|
||||||
{:fx [[:dispatch [:communities/handle-community {:id "community-id"}]]
|
|
||||||
[:dispatch
|
|
||||||
[:chat.ui/cache-link-preview-data "community-link+community-id"
|
|
||||||
{:id "community-id"}]]]}
|
|
||||||
(sut/community-resolved cofx arg))))))
|
|
||||||
(t/testing "given a joined community"
|
|
||||||
(let [cofx {:db {:communities/resolve-community-info {"community-id" true}}}
|
|
||||||
arg ["community-id" {:id "community-id" :joined true}]]
|
|
||||||
(t/testing "dispatch fxs, do not spectate community"
|
|
||||||
(t/is (match?
|
|
||||||
{:fx [[:dispatch [:communities/handle-community {:id "community-id"}]]
|
|
||||||
[:dispatch
|
|
||||||
[:chat.ui/cache-link-preview-data "community-link+community-id"
|
|
||||||
{:id "community-id"}]]]}
|
|
||||||
(sut/community-resolved cofx arg))))))
|
|
||||||
(t/testing "given a token-gated community"
|
|
||||||
(let [cofx {:db {:communities/resolve-community-info {"community-id" true}}}
|
|
||||||
arg ["community-id" {:id "community-id" :tokenPermissions [1]}]]
|
|
||||||
(t/testing "dispatch fxs, do not spectate community"
|
|
||||||
(t/is (match?
|
|
||||||
{:fx [[:dispatch [:communities/handle-community {:id "community-id"}]]
|
|
||||||
[:dispatch
|
|
||||||
[:chat.ui/cache-link-preview-data "community-link+community-id"
|
|
||||||
{:id "community-id"}]]]}
|
|
||||||
(sut/community-resolved cofx arg))))))
|
|
||||||
(t/testing "given nil community"
|
|
||||||
(t/testing "do nothing"
|
|
||||||
(t/is (match?
|
|
||||||
nil
|
|
||||||
(sut/community-resolved {} ["community-id" nil])))))))
|
|
||||||
|
|
||||||
(t/deftest spectate-community
|
|
||||||
(t/testing "given a joined community"
|
|
||||||
(t/testing "do nothing"
|
|
||||||
(t/is (match?
|
|
||||||
nil
|
|
||||||
(sut/spectate-community {:db {:communities {"community-id" {:joined true}}}}
|
|
||||||
["community-id"])))))
|
|
||||||
(t/testing "given a spectated community"
|
|
||||||
(t/testing "do nothing"
|
|
||||||
(t/is (match?
|
|
||||||
nil
|
|
||||||
(sut/spectate-community {:db {:communities {"community-id" {:spectated true}}}}
|
|
||||||
["community-id"])))))
|
|
||||||
(t/testing "given a spectating community"
|
|
||||||
(t/testing "do nothing"
|
|
||||||
(t/is (match?
|
|
||||||
nil
|
|
||||||
(sut/spectate-community {:db {:communities {"community-id" {:spectating true}}}}
|
|
||||||
["community-id"])))))
|
|
||||||
(t/testing "given a community"
|
|
||||||
(t/testing "mark community spectating"
|
|
||||||
(t/is (match?
|
|
||||||
{:db {:communities {"community-id" {:spectating true}}}}
|
|
||||||
(sut/spectate-community {:db {:communities {"community-id" {}}}} ["community-id"]))))
|
|
||||||
(t/testing "call spectate community rpc with correct community id"
|
|
||||||
(t/is (match?
|
|
||||||
{:json-rpc/call [{:method "wakuext_spectateCommunity"
|
|
||||||
:params ["community-id"]}]}
|
|
||||||
(sut/spectate-community {:db {:communities {"community-id" {}}}} ["community-id"]))))))
|
|
||||||
|
|
||||||
(t/deftest spectate-community-failed
|
|
||||||
(t/testing "mark community spectating false"
|
|
||||||
(t/is (match?
|
|
||||||
{:db {:communities {"community-id" {:spectating false}}}}
|
|
||||||
(sut/spectate-community-failed {} ["community-id"])))))
|
|
||||||
|
|
||||||
(t/deftest spectate-community-success
|
|
||||||
(t/testing "given communities"
|
|
||||||
(t/testing "mark first community spectating false"
|
|
||||||
(t/is (match?
|
|
||||||
{:db {:communities {"community-id" {:spectating false}}}}
|
|
||||||
(sut/spectate-community-success {} [{:communities [{:id "community-id"}]}]))))
|
|
||||||
(t/testing "mark first community spectated true"
|
|
||||||
(t/is (match?
|
|
||||||
{:db {:communities {"community-id" {:spectated true}}}}
|
|
||||||
(sut/spectate-community-success {} [{:communities [{:id "community-id"}]}]))))
|
|
||||||
(t/testing "dispatch fxs for first community"
|
|
||||||
(t/is (match?
|
|
||||||
{:fx [[:dispatch [:communities/handle-community {:id "community-id"}]]
|
|
||||||
[:dispatch [::mailserver/request-messages]]]}
|
|
||||||
(sut/spectate-community-success {} [{:communities [{:id "community-id"}]}])))))
|
|
||||||
(t/testing "given empty community"
|
|
||||||
(t/testing "do nothing"
|
|
||||||
(t/is (match?
|
|
||||||
nil
|
|
||||||
(sut/spectate-community-success {} [{:communities []}])))))
|
|
||||||
(t/testing "given nil community"
|
|
||||||
(t/testing "do nothing"
|
|
||||||
(t/is (match?
|
|
||||||
nil
|
|
||||||
(sut/spectate-community-success {} []))))))
|
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
(fn []
|
(fn []
|
||||||
(when-not cached-preview-data
|
(when-not cached-preview-data
|
||||||
(let [community-id (community-id-from-link community-link)]
|
(let [community-id (community-id-from-link community-link)]
|
||||||
(rf/dispatch [:chat.ui/fetch-community community-id]))))
|
(rf/dispatch [:communities/fetch-community community-id]))))
|
||||||
:reagent-render
|
:reagent-render
|
||||||
(fn []
|
(fn []
|
||||||
(when cached-preview-data
|
(when cached-preview-data
|
||||||
|
|||||||
@@ -159,7 +159,7 @@
|
|||||||
unmute-chat-label
|
unmute-chat-label
|
||||||
mute-chat-label))
|
mute-chat-label))
|
||||||
:color cover-bg-color
|
:color cover-bg-color
|
||||||
:icon (if muted? :i/muted :i/activity-center)
|
:icon (if muted? :i/activity-center :i/muted)
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(if muted?
|
(if muted?
|
||||||
(home.actions/unmute-chat-action chat-id)
|
(home.actions/unmute-chat-action chat-id)
|
||||||
@@ -267,7 +267,7 @@
|
|||||||
|
|
||||||
(defn on-layout
|
(defn on-layout
|
||||||
[{:keys [event layout-height distance-atom distance-from-list-top
|
[{:keys [event layout-height distance-atom distance-from-list-top
|
||||||
calculations-complete? messages-list-on-layout-finished?]}]
|
chat-screen-layout-calculations-complete?]}]
|
||||||
(let [layout-height-new (oops/oget event "nativeEvent.layout.height")
|
(let [layout-height-new (oops/oget event "nativeEvent.layout.height")
|
||||||
change (- layout-height-new @layout-height)
|
change (- layout-height-new @layout-height)
|
||||||
new-distance (- @distance-atom change)]
|
new-distance (- @distance-atom change)]
|
||||||
@@ -275,9 +275,8 @@
|
|||||||
(reanimated/set-shared-value distance-from-list-top new-distance)
|
(reanimated/set-shared-value distance-from-list-top new-distance)
|
||||||
(reset! distance-atom new-distance)
|
(reset! distance-atom new-distance)
|
||||||
(reset! layout-height layout-height-new))
|
(reset! layout-height layout-height-new))
|
||||||
(when-not (reanimated/get-shared-value calculations-complete?)
|
(when-not (reanimated/get-shared-value chat-screen-layout-calculations-complete?)
|
||||||
(reanimated/set-shared-value calculations-complete? true))
|
(reanimated/set-shared-value chat-screen-layout-calculations-complete? true))))
|
||||||
(js/setTimeout #(reset! messages-list-on-layout-finished? true) 1000)))
|
|
||||||
|
|
||||||
(defn on-scroll-fn
|
(defn on-scroll-fn
|
||||||
[distance-atom layout-height-atom]
|
[distance-atom layout-height-atom]
|
||||||
@@ -288,7 +287,7 @@
|
|||||||
|
|
||||||
(defn f-messages-list-content
|
(defn f-messages-list-content
|
||||||
[{:keys [insets distance-from-list-top content-height layout-height cover-bg-color distance-atom
|
[{:keys [insets distance-from-list-top content-height layout-height cover-bg-color distance-atom
|
||||||
calculations-complete? messages-list-on-layout-finished? chat-list-scroll-y]}]
|
chat-screen-layout-calculations-complete? chat-list-scroll-y]}]
|
||||||
(let [theme (quo.theme/use-theme-value)
|
(let [theme (quo.theme/use-theme-value)
|
||||||
chat (rf/sub [:chats/current-chat-chat-view])
|
chat (rf/sub [:chats/current-chat-chat-view])
|
||||||
{:keys [keyboard-shown]} (hooks/use-keyboard)
|
{:keys [keyboard-shown]} (hooks/use-keyboard)
|
||||||
@@ -351,8 +350,7 @@
|
|||||||
:layout-height layout-height
|
:layout-height layout-height
|
||||||
:distance-atom distance-atom
|
:distance-atom distance-atom
|
||||||
:distance-from-list-top distance-from-list-top
|
:distance-from-list-top distance-from-list-top
|
||||||
:calculations-complete? calculations-complete?
|
:chat-screen-layout-calculations-complete?
|
||||||
:messages-list-on-layout-finished?
|
chat-screen-layout-calculations-complete?})
|
||||||
messages-list-on-layout-finished?})
|
|
||||||
:scroll-enabled (not recording?)
|
:scroll-enabled (not recording?)
|
||||||
:content-inset-adjustment-behavior :never}]]]))
|
:content-inset-adjustment-behavior :never}]]]))
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
[utils.worklets.chat.messenger.navigation :as worklets]))
|
[utils.worklets.chat.messenger.navigation :as worklets]))
|
||||||
|
|
||||||
(defn f-header-content-container
|
(defn f-header-content-container
|
||||||
[{:keys [chat distance-from-list-top all-loaded? calculations-complete?]}]
|
[{:keys [chat distance-from-list-top all-loaded? chat-screen-layout-calculations-complete?]}]
|
||||||
(let [{:keys [chat-id group-chat chat-type chat-name
|
(let [{:keys [chat-id group-chat chat-type chat-name
|
||||||
emoji]} chat
|
emoji]} chat
|
||||||
display-name (cond
|
display-name (cond
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
header-opacity (worklets/navigation-header-opacity
|
header-opacity (worklets/navigation-header-opacity
|
||||||
distance-from-list-top
|
distance-from-list-top
|
||||||
all-loaded?
|
all-loaded?
|
||||||
calculations-complete?
|
chat-screen-layout-calculations-complete?
|
||||||
(if platform/ios?
|
(if platform/ios?
|
||||||
messages.constants/content-animation-start-position-ios
|
messages.constants/content-animation-start-position-ios
|
||||||
messages.constants/content-animation-start-position-android))
|
messages.constants/content-animation-start-position-android))
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
:top-offset navigation-view-height}]]))
|
:top-offset navigation-view-height}]]))
|
||||||
|
|
||||||
(defn f-view
|
(defn f-view
|
||||||
[{:keys [distance-from-list-top calculations-complete?]}]
|
[{:keys [distance-from-list-top chat-screen-layout-calculations-complete?]}]
|
||||||
(let [{:keys [chat-id chat-type] :as chat} (rf/sub [:chats/current-chat-chat-view])
|
(let [{:keys [chat-id chat-type] :as chat} (rf/sub [:chats/current-chat-chat-view])
|
||||||
all-loaded? (reanimated/use-shared-value false)
|
all-loaded? (reanimated/use-shared-value false)
|
||||||
all-loaded-sub (rf/sub [:chats/all-loaded? chat-id])
|
all-loaded-sub (rf/sub [:chats/all-loaded? chat-id])
|
||||||
@@ -129,10 +129,10 @@
|
|||||||
:on-press #(rf/dispatch [:navigate-back])}
|
:on-press #(rf/dispatch [:navigate-back])}
|
||||||
(if (= chat-type constants/community-chat-type) :i/arrow-left :i/close)]
|
(if (= chat-type constants/community-chat-type) :i/arrow-left :i/close)]
|
||||||
[:f> f-header-content-container
|
[:f> f-header-content-container
|
||||||
{:chat chat
|
{:chat chat
|
||||||
:distance-from-list-top distance-from-list-top
|
:distance-from-list-top distance-from-list-top
|
||||||
:all-loaded? all-loaded?
|
:all-loaded? all-loaded?
|
||||||
:calculations-complete? calculations-complete?}]
|
:chat-screen-layout-calculations-complete? chat-screen-layout-calculations-complete?}]
|
||||||
[quo/button
|
[quo/button
|
||||||
{:icon-only? true
|
{:icon-only? true
|
||||||
:type :grey
|
:type :grey
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.reanimated :as reanimated]
|
[react-native.reanimated :as reanimated]
|
||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[status-im.contexts.chat.messenger.composer.view :as composer.view]
|
[status-im.contexts.chat.messenger.composer.view :as composer.view]
|
||||||
[status-im.contexts.chat.messenger.messages.list.style :as style]
|
[status-im.contexts.chat.messenger.messages.list.style :as style]
|
||||||
[status-im.contexts.chat.messenger.messages.list.view :as list.view]
|
[status-im.contexts.chat.messenger.messages.list.view :as list.view]
|
||||||
@@ -15,49 +14,47 @@
|
|||||||
;; improvement. Please avoid refactoring these files. Also if you are not already working on bug
|
;; improvement. Please avoid refactoring these files. Also if you are not already working on bug
|
||||||
;; fixes related to the composer, please skip them. And ping me, so I can address them while refactoring
|
;; fixes related to the composer, please skip them. And ping me, so I can address them while refactoring
|
||||||
(defn- f-chat-screen
|
(defn- f-chat-screen
|
||||||
[calculations-complete?]
|
[chat-screen-layout-calculations-complete?]
|
||||||
(let [insets (safe-area/get-insets)
|
(let [insets (safe-area/get-insets)
|
||||||
content-height (atom 0)
|
content-height (atom 0)
|
||||||
layout-height (atom 0)
|
layout-height (atom 0)
|
||||||
distance-atom (atom 0)
|
distance-atom (atom 0)
|
||||||
messages-list-on-layout-finished? (reagent/atom false)
|
distance-from-list-top (reanimated/use-shared-value 0)
|
||||||
distance-from-list-top (reanimated/use-shared-value 0)
|
chat-list-scroll-y (reanimated/use-shared-value 0)]
|
||||||
chat-list-scroll-y (reanimated/use-shared-value 0)]
|
|
||||||
[rn/keyboard-avoiding-view
|
[rn/keyboard-avoiding-view
|
||||||
{:style style/keyboard-avoiding-container
|
{:style style/keyboard-avoiding-container
|
||||||
:keyboard-vertical-offset (- (:bottom insets))}
|
:keyboard-vertical-offset (- (:bottom insets))}
|
||||||
[:f> messages.navigation/f-view
|
[:f> messages.navigation/f-view
|
||||||
{:distance-from-list-top distance-from-list-top
|
{:distance-from-list-top distance-from-list-top
|
||||||
:calculations-complete? calculations-complete?}]
|
:chat-screen-layout-calculations-complete? chat-screen-layout-calculations-complete?}]
|
||||||
[:f> list.view/f-messages-list-content
|
[:f> list.view/f-messages-list-content
|
||||||
{:insets insets
|
{:insets insets
|
||||||
:layout-height layout-height
|
:layout-height layout-height
|
||||||
:content-height content-height
|
:content-height content-height
|
||||||
:distance-atom distance-atom
|
:distance-atom distance-atom
|
||||||
:calculations-complete? calculations-complete?
|
:chat-screen-layout-calculations-complete? chat-screen-layout-calculations-complete?
|
||||||
:distance-from-list-top distance-from-list-top
|
:distance-from-list-top distance-from-list-top
|
||||||
:chat-list-scroll-y chat-list-scroll-y
|
:chat-list-scroll-y chat-list-scroll-y
|
||||||
:messages-list-on-layout-finished? messages-list-on-layout-finished?
|
:cover-bg-color :turquoise}]
|
||||||
:cover-bg-color :turquoise}]
|
|
||||||
[composer.view/composer
|
[composer.view/composer
|
||||||
{:insets insets
|
{:insets insets
|
||||||
:chat-list-scroll-y chat-list-scroll-y
|
:chat-screen-layout-calculations-complete? chat-screen-layout-calculations-complete?
|
||||||
:messages-list-on-layout-finished? messages-list-on-layout-finished?}]]))
|
:chat-list-scroll-y chat-list-scroll-y}]]))
|
||||||
|
|
||||||
(defn lazy-chat-screen
|
(defn lazy-chat-screen
|
||||||
[calculations-complete?]
|
[chat-screen-layout-calculations-complete?]
|
||||||
(let [screen-loaded? (rf/sub [:shell/chat-screen-loaded?])]
|
(let [screen-loaded? (rf/sub [:shell/chat-screen-loaded?])]
|
||||||
(when-not screen-loaded?
|
(when-not screen-loaded?
|
||||||
(reanimated/set-shared-value calculations-complete? false))
|
(reanimated/set-shared-value chat-screen-layout-calculations-complete? false))
|
||||||
(when screen-loaded?
|
(when screen-loaded?
|
||||||
[:f> f-chat-screen calculations-complete?])))
|
[:f> f-chat-screen chat-screen-layout-calculations-complete?])))
|
||||||
|
|
||||||
(defn- f-chat
|
(defn- f-chat
|
||||||
[]
|
[]
|
||||||
(let [calculations-complete? (reanimated/use-shared-value false)]
|
(let [chat-screen-layout-calculations-complete? (reanimated/use-shared-value false)]
|
||||||
[:<>
|
[:<>
|
||||||
[lazy-chat-screen calculations-complete?]
|
[lazy-chat-screen chat-screen-layout-calculations-complete?]
|
||||||
[:f> placeholder.view/f-view calculations-complete?]]))
|
[:f> placeholder.view/f-view chat-screen-layout-calculations-complete?]]))
|
||||||
|
|
||||||
(defn chat
|
(defn chat
|
||||||
[]
|
[]
|
||||||
|
|||||||
@@ -15,9 +15,9 @@
|
|||||||
:animated? false}])
|
:animated? false}])
|
||||||
|
|
||||||
(defn f-view
|
(defn f-view
|
||||||
[calculations-complete?]
|
[chat-screen-layout-calculations-complete?]
|
||||||
(let [top (safe-area/get-top)
|
(let [top (safe-area/get-top)
|
||||||
opacity (worklets/placeholder-opacity calculations-complete?)
|
opacity (worklets/placeholder-opacity chat-screen-layout-calculations-complete?)
|
||||||
z-index (worklets/placeholder-z-index calculations-complete?)]
|
z-index (worklets/placeholder-z-index chat-screen-layout-calculations-complete?)]
|
||||||
[reanimated/view {:style (style/container top opacity z-index)}
|
[reanimated/view {:style (style/container top opacity z-index)}
|
||||||
[loading-skeleton]]))
|
[loading-skeleton]]))
|
||||||
|
|||||||
@@ -23,11 +23,8 @@
|
|||||||
[]
|
[]
|
||||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||||
{:keys [name color images]} (rf/sub [:communities/community id])
|
{:keys [name color images]} (rf/sub [:communities/community id])
|
||||||
airdrop-account (rf/sub [:communities/airdrop-account])
|
airdrop-account (rf/sub [:communities/airdrop-account id])
|
||||||
selected-accounts (rf/sub [:communities/selected-permission-accounts])]
|
selected-accounts (rf/sub [:communities/selected-permission-accounts id])]
|
||||||
(rn/use-effect (fn []
|
|
||||||
(rf/dispatch [:communities/initialize-permission-addresses]))
|
|
||||||
[])
|
|
||||||
[rn/view {:style style/container}
|
[rn/view {:style style/container}
|
||||||
[quo/page-nav
|
[quo/page-nav
|
||||||
{:text-align :left
|
{:text-align :left
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn- account-item
|
(defn- account-item
|
||||||
[item _ _ selected-addresses]
|
[item _ _ [selected-addresses community-id]]
|
||||||
[quo/account-permissions
|
[quo/account-permissions
|
||||||
{:account {:name (:name item)
|
{:account {:name (:name item)
|
||||||
:address (:address item)
|
:address (:address item)
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
:token-details []
|
:token-details []
|
||||||
:checked? (contains? selected-addresses (:address item))
|
:checked? (contains? selected-addresses (:address item))
|
||||||
:on-change #(rf/dispatch [:communities/toggle-selected-permission-address
|
:on-change #(rf/dispatch [:communities/toggle-selected-permission-address
|
||||||
(:address item)])
|
(:address item) community-id])
|
||||||
:container-style {:margin-bottom 8}}])
|
:container-style {:margin-bottom 8}}])
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||||
{:keys [name color images]} (rf/sub [:communities/community id])
|
{:keys [name color images]} (rf/sub [:communities/community id])
|
||||||
accounts (rf/sub [:wallet/accounts-with-customization-color])
|
accounts (rf/sub [:wallet/accounts-with-customization-color])
|
||||||
selected-addresses (rf/sub [:communities/selected-permission-addresses])]
|
selected-addresses (rf/sub [:communities/selected-permission-addresses id])]
|
||||||
[rn/safe-area-view {:style style/container}
|
[rn/safe-area-view {:style style/container}
|
||||||
[quo/drawer-top
|
[quo/drawer-top
|
||||||
{:type :context-tag
|
{:type :context-tag
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
[rn/flat-list
|
[rn/flat-list
|
||||||
{:render-fn account-item
|
{:render-fn account-item
|
||||||
:render-data selected-addresses
|
:render-data [selected-addresses id]
|
||||||
:content-container-style {:padding 20}
|
:content-container-style {:padding 20}
|
||||||
:key-fn :address
|
:key-fn :address
|
||||||
:data accounts}]
|
:data accounts}]
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
{:type :grey
|
{:type :grey
|
||||||
:container-style {:flex 1}
|
:container-style {:flex 1}
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(rf/dispatch [:communities/reset-selected-permission-addresses])
|
(rf/dispatch [:communities/reset-selected-permission-addresses id])
|
||||||
(rf/dispatch [:navigate-back]))}
|
(rf/dispatch [:navigate-back]))}
|
||||||
(i18n/label :t/cancel)]
|
(i18n/label :t/cancel)]
|
||||||
[quo/button
|
[quo/button
|
||||||
@@ -68,6 +68,6 @@
|
|||||||
:customization-color color
|
:customization-color color
|
||||||
:disabled? (empty? selected-addresses)
|
:disabled? (empty? selected-addresses)
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(rf/dispatch [:communities/update-previous-permission-addresses])
|
(rf/dispatch [:communities/update-previous-permission-addresses id])
|
||||||
(rf/dispatch [:navigate-back]))}
|
(rf/dispatch [:navigate-back]))}
|
||||||
(i18n/label :t/confirm-changes)]]]))
|
(i18n/label :t/confirm-changes)]]]))
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn- render-item
|
(defn- render-item
|
||||||
[item _ _ airdrop-address]
|
[item _ _ [airdrop-address community-id]]
|
||||||
[quo/account-item
|
[quo/account-item
|
||||||
{:account-props item
|
{:account-props item
|
||||||
:state (when (= airdrop-address (:address item)) :selected)
|
:state (when (= airdrop-address (:address item)) :selected)
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(rf/dispatch [:communities/set-airdrop-address (:address item)])
|
(rf/dispatch [:communities/set-airdrop-address (:address item) community-id])
|
||||||
(rf/dispatch [:navigate-back]))
|
(rf/dispatch [:navigate-back]))
|
||||||
:emoji (:emoji item)}])
|
:emoji (:emoji item)}])
|
||||||
|
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
[]
|
[]
|
||||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||||
{:keys [name images color]} (rf/sub [:communities/community id])
|
{:keys [name images color]} (rf/sub [:communities/community id])
|
||||||
selected-accounts (rf/sub [:communities/selected-permission-accounts])
|
selected-accounts (rf/sub [:communities/selected-permission-accounts id])
|
||||||
airdrop-address (rf/sub [:communities/airdrop-address])]
|
airdrop-address (rf/sub [:communities/airdrop-address id])]
|
||||||
[:<>
|
[:<>
|
||||||
[quo/drawer-top
|
[quo/drawer-top
|
||||||
{:type :context-tag
|
{:type :context-tag
|
||||||
@@ -35,6 +35,6 @@
|
|||||||
[rn/flat-list
|
[rn/flat-list
|
||||||
{:data selected-accounts
|
{:data selected-accounts
|
||||||
:render-fn render-item
|
:render-fn render-item
|
||||||
:render-data airdrop-address
|
:render-data [airdrop-address id]
|
||||||
:content-container-style style/account-list-container
|
:content-container-style style/account-list-container
|
||||||
:key-fn :address}]]))
|
:key-fn :address}]]))
|
||||||
|
|||||||
@@ -6,9 +6,8 @@
|
|||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn token-requirements
|
(defn token-requirements
|
||||||
[id]
|
[]
|
||||||
(rf/dispatch [:communities/check-permissions-to-join-community id])
|
(fn [id]
|
||||||
(fn []
|
|
||||||
(let [{:keys [can-request-access?
|
(let [{:keys [can-request-access?
|
||||||
number-of-hold-tokens tokens]} (rf/sub [:community/token-gated-overview id])]
|
number-of-hold-tokens tokens]} (rf/sub [:community/token-gated-overview id])]
|
||||||
[rn/view {:style {:padding-horizontal 12}}
|
[rn/view {:style {:padding-horizontal 12}}
|
||||||
|
|||||||
@@ -20,11 +20,11 @@
|
|||||||
[quo/community-card-view-item
|
[quo/community-card-view-item
|
||||||
{:community (assoc item :cover cover)
|
{:community (assoc item :cover cover)
|
||||||
:width width
|
:width width
|
||||||
:on-press #(rf/dispatch [:navigate-to :community-overview (:id item)])}]
|
:on-press #(rf/dispatch [:communities/navigate-to-community-overview (:id item)])}]
|
||||||
[quo/community-list-item
|
[quo/community-list
|
||||||
{:on-press (fn []
|
{:on-press (fn []
|
||||||
(rf/dispatch [:dismiss-keyboard])
|
(rf/dispatch [:dismiss-keyboard])
|
||||||
(rf/dispatch [:navigate-to :community-overview (:id item)]))
|
(rf/dispatch [:communities/navigate-to-community-overview (:id item)]))
|
||||||
:on-long-press #(rf/dispatch
|
:on-long-press #(rf/dispatch
|
||||||
[:show-bottom-sheet
|
[:show-bottom-sheet
|
||||||
{:content (fn []
|
{:content (fn []
|
||||||
@@ -142,12 +142,13 @@
|
|||||||
(if (= view-type :card-view)
|
(if (= view-type :card-view)
|
||||||
[quo/community-card-view-item
|
[quo/community-card-view-item
|
||||||
{:community (assoc community :cover cover)
|
{:community (assoc community :cover cover)
|
||||||
:on-press #(rf/dispatch [:navigate-to :community-overview (:id community)])}]
|
:on-press #(rf/dispatch [:communities/navigate-to-community-overview (:id community)])}]
|
||||||
|
|
||||||
[quo/community-list-item
|
[quo/community-list
|
||||||
{:on-press (fn []
|
{:on-press (fn []
|
||||||
(rf/dispatch [:dismiss-keyboard])
|
(rf/dispatch [:dismiss-keyboard])
|
||||||
(rf/dispatch [:navigate-to :community-overview (:id community)]))
|
(rf/dispatch [:communities/navigate-to-community-overview
|
||||||
|
(:id community)]))
|
||||||
:on-long-press #(js/alert "TODO: to be implemented")}
|
:on-long-press #(js/alert "TODO: to be implemented")}
|
||||||
community])]))
|
community])]))
|
||||||
(if communities communities communities-ids))
|
(if communities communities communities-ids))
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
(ns status-im.contexts.communities.events
|
(ns status-im.contexts.communities.events
|
||||||
(:require [clojure.set :as set]
|
(:require [clojure.set :as set]
|
||||||
|
[clojure.string :as string]
|
||||||
[clojure.walk :as walk]
|
[clojure.walk :as walk]
|
||||||
[legacy.status-im.data-store.chats :as data-store.chats]
|
[legacy.status-im.data-store.chats :as data-store.chats]
|
||||||
|
[legacy.status-im.mailserver.core :as mailserver]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]
|
||||||
[react-native.share :as share]
|
[react-native.share :as share]
|
||||||
|
[schema.core :as schema]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
|
[status-im.contexts.chat.messenger.messages.link-preview.events :as link-preview.events]
|
||||||
status-im.contexts.communities.actions.community-options.events
|
status-im.contexts.communities.actions.community-options.events
|
||||||
status-im.contexts.communities.actions.leave.events
|
status-im.contexts.communities.actions.leave.events
|
||||||
|
[status-im.navigation.events :as navigation]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
@@ -71,14 +76,20 @@
|
|||||||
(when community-js
|
(when community-js
|
||||||
(let [{:keys [token-permissions
|
(let [{:keys [token-permissions
|
||||||
token-permissions-check joined id]
|
token-permissions-check joined id]
|
||||||
:as community} (<-rpc community-js)
|
:as community} (<-rpc community-js)
|
||||||
has-token-permissions? (not (seq token-permissions))]
|
has-channel-perm? (fn [id-perm-tuple]
|
||||||
|
(let [{:keys [type]} (second id-perm-tuple)]
|
||||||
|
(or (= type constants/community-token-permission-can-view-channel)
|
||||||
|
(=
|
||||||
|
type
|
||||||
|
constants/community-token-permission-can-view-and-post-channel))))]
|
||||||
{:db (assoc-in db [:communities id] community)
|
{:db (assoc-in db [:communities id] community)
|
||||||
:fx [(when (and has-token-permissions? (not joined))
|
:fx [[:dispatch [:communities/initialize-permission-addresses id]]
|
||||||
|
(when (not joined)
|
||||||
[:dispatch [:chat.ui/spectate-community id]])
|
[:dispatch [:chat.ui/spectate-community id]])
|
||||||
(when (and has-token-permissions? (nil? token-permissions-check))
|
(when (nil? token-permissions-check)
|
||||||
[:dispatch [:communities/check-permissions-to-join-community id]])
|
[:dispatch [:communities/check-permissions-to-join-community id]])
|
||||||
(when (and has-token-permissions? (not (get-in db [:community-channels-permissions id])))
|
(when (some has-channel-perm? token-permissions)
|
||||||
[:dispatch [:communities/check-all-community-channels-permissions id]])]}))))
|
[:dispatch [:communities/check-all-community-channels-permissions id]])]}))))
|
||||||
|
|
||||||
(rf/defn handle-removed-chats
|
(rf/defn handle-removed-chats
|
||||||
@@ -189,54 +200,62 @@
|
|||||||
:on-error #(log/error "failed to fetch collapsed community categories" %)}]}))
|
:on-error #(log/error "failed to fetch collapsed community categories" %)}]}))
|
||||||
|
|
||||||
(defn initialize-permission-addresses
|
(defn initialize-permission-addresses
|
||||||
[{:keys [db]}]
|
[{:keys [db]} [community-id]]
|
||||||
(let [accounts (get-in db [:wallet :accounts])
|
(when community-id
|
||||||
sorted-accounts (sort-by :position (vals accounts))
|
(let [accounts (get-in db [:wallet :accounts])
|
||||||
addresses (set (map :address sorted-accounts))]
|
sorted-accounts (sort-by :position (vals accounts))
|
||||||
{:db (assoc db
|
addresses (set (map :address sorted-accounts))]
|
||||||
:communities/previous-permission-addresses addresses
|
{:db (update-in db
|
||||||
:communities/selected-permission-addresses addresses
|
[:communities community-id]
|
||||||
:communities/airdrop-address (:address (first sorted-accounts)))}))
|
assoc
|
||||||
|
:previous-permission-addresses addresses
|
||||||
|
:selected-permission-addresses addresses
|
||||||
|
:airdrop-address (:address (first sorted-accounts)))})))
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/initialize-permission-addresses
|
(rf/reg-event-fx :communities/initialize-permission-addresses
|
||||||
initialize-permission-addresses)
|
initialize-permission-addresses)
|
||||||
|
|
||||||
(defn update-previous-permission-addresses
|
(defn update-previous-permission-addresses
|
||||||
[{:keys [db]}]
|
[{:keys [db]} [community-id]]
|
||||||
(let [accounts (get-in db [:wallet :accounts])
|
(when community-id
|
||||||
sorted-accounts (sort-by :position (vals accounts))
|
(let [accounts (get-in db [:wallet :accounts])
|
||||||
selected-permission-addresses (get-in db [:communities/selected-permission-addresses])
|
sorted-accounts (sort-by :position (vals accounts))
|
||||||
selected-accounts (filter #(contains? selected-permission-addresses
|
selected-permission-addresses (get-in db
|
||||||
(:address %))
|
[:communities community-id
|
||||||
sorted-accounts)
|
:selected-permission-addresses])
|
||||||
current-airdrop-address (get-in db [:communities/airdrop-address])]
|
selected-accounts (filter #(contains? selected-permission-addresses (:address %))
|
||||||
{:db (assoc db
|
sorted-accounts)
|
||||||
:communities/previous-permission-addresses selected-permission-addresses
|
current-airdrop-address (get-in db [:communities community-id :airdrop-address])]
|
||||||
:communities/airdrop-address (if (contains? selected-permission-addresses
|
{:db (update-in db
|
||||||
current-airdrop-address)
|
[:communities community-id]
|
||||||
current-airdrop-address
|
assoc
|
||||||
(:address (first selected-accounts))))}))
|
:previous-permission-addresses selected-permission-addresses
|
||||||
|
:airdrop-address (if (contains? selected-permission-addresses
|
||||||
|
current-airdrop-address)
|
||||||
|
current-airdrop-address
|
||||||
|
(:address (first selected-accounts))))})))
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/update-previous-permission-addresses
|
(rf/reg-event-fx :communities/update-previous-permission-addresses
|
||||||
update-previous-permission-addresses)
|
update-previous-permission-addresses)
|
||||||
|
|
||||||
(defn toggle-selected-permission-address
|
(defn toggle-selected-permission-address
|
||||||
[{:keys [db]} [address]]
|
[{:keys [db]} [address community-id]]
|
||||||
{:db (update db
|
{:db (update-in db
|
||||||
:communities/selected-permission-addresses
|
[:communities community-id :selected-permission-addresses]
|
||||||
(fn [selected-addresses]
|
(fn [selected-addresses]
|
||||||
(if (contains? selected-addresses address)
|
(if (contains? selected-addresses address)
|
||||||
(disj selected-addresses address)
|
(disj selected-addresses address)
|
||||||
(conj selected-addresses address))))})
|
(conj selected-addresses address))))})
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/toggle-selected-permission-address
|
(rf/reg-event-fx :communities/toggle-selected-permission-address
|
||||||
toggle-selected-permission-address)
|
toggle-selected-permission-address)
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/reset-selected-permission-addresses
|
(rf/reg-event-fx :communities/reset-selected-permission-addresses
|
||||||
(fn [{:keys [db]}]
|
(fn [{:keys [db]} [community-id]]
|
||||||
{:db (assoc db
|
(when community-id
|
||||||
:communities/selected-permission-addresses
|
{:db (assoc-in db
|
||||||
(get-in db [:communities/previous-permission-addresses]))}))
|
[:communities community-id :selected-permission-addresses]
|
||||||
|
(get-in db [:communities community-id :previous-permission-addresses]))})))
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/share-community-channel-url-with-data
|
(rf/reg-event-fx :communities/share-community-channel-url-with-data
|
||||||
(fn [_ [chat-id]]
|
(fn [_ [chat-id]]
|
||||||
@@ -265,5 +284,124 @@
|
|||||||
:event "share-community-channel-url-with-data"}))}]})))
|
:event "share-community-channel-url-with-data"}))}]})))
|
||||||
|
|
||||||
(rf/reg-event-fx :communities/set-airdrop-address
|
(rf/reg-event-fx :communities/set-airdrop-address
|
||||||
(fn [{:keys [db]} [address]]
|
(fn [{:keys [db]} [address community-id]]
|
||||||
{:db (assoc db :communities/airdrop-address address)}))
|
{:db (assoc-in db [:communities community-id :airdrop-address] address)}))
|
||||||
|
|
||||||
|
(defn community-fetched
|
||||||
|
[{:keys [db]} [community-id community]]
|
||||||
|
(when community
|
||||||
|
{:db (update db :communities/fetching-community dissoc community-id)
|
||||||
|
:fx [[:dispatch [:communities/handle-community community]]
|
||||||
|
[:dispatch
|
||||||
|
[:chat.ui/cache-link-preview-data (link-preview.events/community-link community-id)
|
||||||
|
community]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :chat.ui/community-fetched community-fetched)
|
||||||
|
|
||||||
|
(defn community-failed-to-fetch
|
||||||
|
[{:keys [db]} [community-id]]
|
||||||
|
{:db (update db :communities/fetching-community dissoc community-id)})
|
||||||
|
|
||||||
|
(rf/reg-event-fx :chat.ui/community-failed-to-fetch community-failed-to-fetch)
|
||||||
|
|
||||||
|
(defn fetch-community
|
||||||
|
[{:keys [db]} [community-id]]
|
||||||
|
(when (and community-id (not (get-in db [:communities/fetching-community community-id])))
|
||||||
|
{:db (assoc-in db [:communities/fetching-community community-id] true)
|
||||||
|
:json-rpc/call [{:method "wakuext_fetchCommunity"
|
||||||
|
:params [{:CommunityKey community-id
|
||||||
|
:TryDatabase true
|
||||||
|
:WaitForResponse true}]
|
||||||
|
:on-success (fn [community]
|
||||||
|
(rf/dispatch [:chat.ui/community-fetched community-id community]))
|
||||||
|
:on-error (fn [err]
|
||||||
|
(rf/dispatch [:chat.ui/community-failed-to-fetch community-id])
|
||||||
|
(log/error {:message
|
||||||
|
"Failed to request community info from mailserver"
|
||||||
|
:error err}))}]}))
|
||||||
|
|
||||||
|
(schema/=> fetch-community
|
||||||
|
[:=>
|
||||||
|
[:catn
|
||||||
|
[:cofx :schema.re-frame/cofx]
|
||||||
|
[:args
|
||||||
|
[:schema [:catn [:community-id [:? :string]]]]]]
|
||||||
|
[:maybe
|
||||||
|
[:map
|
||||||
|
[:db map?]
|
||||||
|
[:json-rpc/call :schema.common/rpc-call]]]])
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/fetch-community fetch-community)
|
||||||
|
|
||||||
|
(defn spectate-community-success
|
||||||
|
[{:keys [db]} [{:keys [communities]}]]
|
||||||
|
(when-let [community (first communities)]
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [:communities (:id community) :spectated] true)
|
||||||
|
(assoc-in [:communities (:id community) :spectating] false))
|
||||||
|
:fx [[:dispatch [:communities/handle-community community]]
|
||||||
|
[:dispatch [::mailserver/request-messages]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :chat.ui/spectate-community-success spectate-community-success)
|
||||||
|
|
||||||
|
(defn spectate-community-failed
|
||||||
|
[{:keys [db]} [community-id]]
|
||||||
|
{:db (assoc-in db [:communities community-id :spectating] false)})
|
||||||
|
|
||||||
|
(rf/reg-event-fx :chat.ui/spectate-community-failed spectate-community-failed)
|
||||||
|
|
||||||
|
(defn spectate-community
|
||||||
|
[{:keys [db]} [community-id]]
|
||||||
|
(let [{:keys [spectated spectating joined]} (get-in db [:communities community-id])]
|
||||||
|
(when (and (not joined) (not spectated) (not spectating))
|
||||||
|
{:db (assoc-in db [:communities community-id :spectating] true)
|
||||||
|
:json-rpc/call [{:method "wakuext_spectateCommunity"
|
||||||
|
:params [community-id]
|
||||||
|
:on-success [:chat.ui/spectate-community-success]
|
||||||
|
:on-error (fn [err]
|
||||||
|
(log/error {:message
|
||||||
|
"Failed to spectate community"
|
||||||
|
:error err})
|
||||||
|
(rf/dispatch [:chat.ui/spectate-community-failed
|
||||||
|
community-id]))}]})))
|
||||||
|
|
||||||
|
(schema/=> spectate-community
|
||||||
|
[:=>
|
||||||
|
[:catn
|
||||||
|
[:cofx :schema.re-frame/cofx]
|
||||||
|
[:args
|
||||||
|
[:schema [:catn [:community-id [:? :string]]]]]]
|
||||||
|
[:maybe
|
||||||
|
[:map
|
||||||
|
[:db map?]
|
||||||
|
[:json-rpc/call :schema.common/rpc-call]]]])
|
||||||
|
|
||||||
|
(rf/reg-event-fx :chat.ui/spectate-community spectate-community)
|
||||||
|
|
||||||
|
(rf/defn navigate-to-serialized-community
|
||||||
|
[_ {:keys [community-id]}]
|
||||||
|
{:serialization/deserialize-and-compress-key
|
||||||
|
{:serialized-key community-id
|
||||||
|
:on-success #(rf/dispatch [:communities/navigate-to-community-overview %])
|
||||||
|
:on-error #(log/error {:message "Failed to decompress community-id"
|
||||||
|
:error %
|
||||||
|
:community-id community-id})}})
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/navigate-to-community-overview
|
||||||
|
(fn [cofx [deserialized-key]]
|
||||||
|
(if (string/starts-with? deserialized-key constants/serialization-key)
|
||||||
|
(navigate-to-serialized-community cofx deserialized-key)
|
||||||
|
(rf/merge
|
||||||
|
cofx
|
||||||
|
{:fx [[:dispatch [:communities/fetch-community deserialized-key]]
|
||||||
|
[:dispatch [:navigate-to :community-overview deserialized-key]]]}
|
||||||
|
(navigation/pop-to-root :shell-stack)))))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :communities/navigate-to-community-chat
|
||||||
|
(fn [{:keys [db]} [chat-id pop-to-root?]]
|
||||||
|
(let [{:keys [community-id]} (get-in db [:chats chat-id])]
|
||||||
|
{:fx [(when community-id
|
||||||
|
[:dispatch [:communities/fetch-community community-id]])
|
||||||
|
(if pop-to-root?
|
||||||
|
[:dispatch [:chat/pop-to-root-and-navigate-to-chat chat-id]]
|
||||||
|
[:dispatch [:chat/navigate-to-chat chat-id]])]})))
|
||||||
|
|||||||
@@ -1,25 +1,31 @@
|
|||||||
(ns status-im.contexts.communities.events-test
|
(ns status-im.contexts.communities.events-test
|
||||||
(:require [cljs.test :refer [deftest is]]
|
(:require [cljs.test :refer [deftest is testing]]
|
||||||
|
[legacy.status-im.mailserver.core :as mailserver]
|
||||||
matcher-combinators.test
|
matcher-combinators.test
|
||||||
|
[status-im.contexts.chat.messenger.messages.link-preview.events :as link-preview.events]
|
||||||
[status-im.contexts.communities.events :as events]))
|
[status-im.contexts.communities.events :as events]))
|
||||||
|
|
||||||
|
(def community-id "community-id")
|
||||||
|
|
||||||
(deftest initialize-permission-addresses-test
|
(deftest initialize-permission-addresses-test
|
||||||
(let [initial-db {:db {:wallet {:accounts {"0x1" {:address "0x1"
|
(let [initial-db {:db {:wallet {:accounts {"0x1" {:address "0x1"
|
||||||
:position 0}
|
:position 0}
|
||||||
"0x2" {:address "0x2"
|
"0x2" {:address "0x2"
|
||||||
:position 1}}}}}
|
:position 1}}}}}
|
||||||
expected-db {:db (assoc (:db initial-db)
|
expected-db {:db (update-in (:db initial-db)
|
||||||
:communities/previous-permission-addresses #{"0x1" "0x2"}
|
[:communities community-id]
|
||||||
:communities/selected-permission-addresses #{"0x1" "0x2"}
|
assoc
|
||||||
:communities/airdrop-address "0x1")}]
|
:previous-permission-addresses #{"0x1" "0x2"}
|
||||||
(is (match? expected-db (events/initialize-permission-addresses initial-db)))))
|
:selected-permission-addresses #{"0x1" "0x2"}
|
||||||
|
:airdrop-address "0x1")}]
|
||||||
|
(is (match? expected-db (events/initialize-permission-addresses initial-db [community-id])))))
|
||||||
|
|
||||||
(deftest toggle-selected-permission-address-test
|
(deftest toggle-selected-permission-address-test
|
||||||
(let [initial-db {:db {:communities/selected-permission-addresses #{"0x1" "0x2"}}}]
|
(let [initial-db {:db {:communities {community-id {:selected-permission-addresses #{"0x1" "0x2"}}}}}]
|
||||||
(is (match? {:db {:communities/selected-permission-addresses #{"0x1"}}}
|
(is (match? {:db {:communities {community-id {:selected-permission-addresses #{"0x1"}}}}}
|
||||||
(events/toggle-selected-permission-address initial-db ["0x2"])))
|
(events/toggle-selected-permission-address initial-db ["0x2" community-id])))
|
||||||
(is (match? {:db {:communities/selected-permission-addresses #{"0x1" "0x2" "0x3"}}}
|
(is (match? {:db {:communities {community-id {:selected-permission-addresses #{"0x1" "0x2" "0x3"}}}}}
|
||||||
(events/toggle-selected-permission-address initial-db ["0x3"])))))
|
(events/toggle-selected-permission-address initial-db ["0x3" community-id])))))
|
||||||
|
|
||||||
(deftest update-previous-permission-addresses-test
|
(deftest update-previous-permission-addresses-test
|
||||||
(let [wallet {:accounts {"0x1" {:address "0x1"
|
(let [wallet {:accounts {"0x1" {:address "0x1"
|
||||||
@@ -28,25 +34,162 @@
|
|||||||
:position 1}
|
:position 1}
|
||||||
"0x3" {:address "0x3"
|
"0x3" {:address "0x3"
|
||||||
:position 2}}}]
|
:position 2}}}]
|
||||||
(let [initial-db {:db {:wallet wallet
|
(let [initial-db {:db {:wallet wallet
|
||||||
:communities/previous-permission-addresses #{"0x1" "0x2"}
|
:communities {community-id {:previous-permission-addresses #{"0x1" "0x2"}
|
||||||
:communities/selected-permission-addresses #{"0x1" "0x2" "0x3"}
|
:selected-permission-addresses #{"0x1" "0x2"
|
||||||
:communities/airdrop-address "0x1"}}
|
"0x3"}
|
||||||
expected-db {:db {:wallet wallet
|
:airdrop-address "0x1"}}}}
|
||||||
:communities/previous-permission-addresses #{"0x1" "0x2" "0x3"}
|
expected-db {:db {:wallet wallet
|
||||||
:communities/selected-permission-addresses #{"0x1" "0x2" "0x3"}
|
:communities {community-id {:previous-permission-addresses #{"0x1" "0x2"
|
||||||
:communities/airdrop-address "0x1"}}]
|
"0x3"}
|
||||||
|
:selected-permission-addresses #{"0x1" "0x2"
|
||||||
|
"0x3"}
|
||||||
|
:airdrop-address "0x1"}}}}]
|
||||||
(is
|
(is
|
||||||
(match? expected-db
|
(match? expected-db
|
||||||
(events/update-previous-permission-addresses initial-db))))
|
(events/update-previous-permission-addresses initial-db [community-id]))))
|
||||||
(let [initial-db {:db {:wallet wallet
|
(let [initial-db {:db {:wallet wallet
|
||||||
:communities/previous-permission-addresses #{"0x1" "0x2"}
|
:communities {community-id {:previous-permission-addresses #{"0x1" "0x2"}
|
||||||
:communities/selected-permission-addresses #{"0x2" "0x3"}
|
:selected-permission-addresses #{"0x2" "0x3"}
|
||||||
:communities/airdrop-address "0x1"}}
|
:airdrop-address "0x1"}}}}
|
||||||
expected-db {:db {:wallet wallet
|
expected-db {:db {:wallet wallet
|
||||||
:communities/previous-permission-addresses #{"0x2" "0x3"}
|
:communities {community-id {:previous-permission-addresses #{"0x2" "0x3"}
|
||||||
:communities/selected-permission-addresses #{"0x2" "0x3"}
|
:selected-permission-addresses #{"0x2" "0x3"}
|
||||||
:communities/airdrop-address "0x2"}}]
|
:airdrop-address "0x2"}}}}]
|
||||||
(is
|
(is
|
||||||
(match? expected-db
|
(match? expected-db
|
||||||
(events/update-previous-permission-addresses initial-db))))))
|
(events/update-previous-permission-addresses initial-db [community-id]))))))
|
||||||
|
|
||||||
|
(deftest fetch-community
|
||||||
|
(testing "with community id"
|
||||||
|
(testing "update fetching indicator in db"
|
||||||
|
(is (match?
|
||||||
|
{:db {:communities/fetching-community {community-id true}}}
|
||||||
|
(events/fetch-community {} [community-id]))))
|
||||||
|
(testing "call the fetch community rpc method with correct community id"
|
||||||
|
(is (match?
|
||||||
|
{:json-rpc/call [{:method "wakuext_fetchCommunity"
|
||||||
|
:params [{:CommunityKey community-id
|
||||||
|
:TryDatabase true
|
||||||
|
:WaitForResponse true}]}]}
|
||||||
|
(events/fetch-community {} [community-id])))))
|
||||||
|
(testing "with no community id"
|
||||||
|
(testing "do nothing"
|
||||||
|
(is (match?
|
||||||
|
nil
|
||||||
|
(events/fetch-community {} []))))))
|
||||||
|
|
||||||
|
(deftest community-failed-to-fetch
|
||||||
|
(testing "given a community id"
|
||||||
|
(testing "remove community id from fetching indicator in db"
|
||||||
|
(is (match?
|
||||||
|
nil
|
||||||
|
(get-in (events/community-failed-to-fetch {:db {:communities/fetching-community
|
||||||
|
{community-id true}}}
|
||||||
|
[community-id])
|
||||||
|
[:db :communities/fetching-community community-id]))))))
|
||||||
|
|
||||||
|
(deftest community-fetched
|
||||||
|
(with-redefs [link-preview.events/community-link (fn [id] (str "community-link+" id))]
|
||||||
|
(testing "given a community"
|
||||||
|
(let [cofx {:db {:communities/fetching-community {community-id true}}}
|
||||||
|
arg [community-id {:id community-id}]]
|
||||||
|
(testing "remove community id from fetching indicator in db"
|
||||||
|
(is (match?
|
||||||
|
nil
|
||||||
|
(get-in (events/community-fetched cofx arg)
|
||||||
|
[:db :communities/fetching-community community-id]))))
|
||||||
|
(testing "dispatch fxs"
|
||||||
|
(is (match?
|
||||||
|
{:fx [[:dispatch [:communities/handle-community {:id community-id}]]
|
||||||
|
[:dispatch
|
||||||
|
[:chat.ui/cache-link-preview-data "community-link+community-id"
|
||||||
|
{:id community-id}]]]}
|
||||||
|
(events/community-fetched cofx arg))))))
|
||||||
|
(testing "given a joined community"
|
||||||
|
(let [cofx {:db {:communities/fetching-community {community-id true}}}
|
||||||
|
arg [community-id {:id community-id :joined true}]]
|
||||||
|
(testing "dispatch fxs, do not spectate community"
|
||||||
|
(is (match?
|
||||||
|
{:fx [[:dispatch [:communities/handle-community {:id community-id}]]
|
||||||
|
[:dispatch
|
||||||
|
[:chat.ui/cache-link-preview-data "community-link+community-id"
|
||||||
|
{:id community-id}]]]}
|
||||||
|
(events/community-fetched cofx arg))))))
|
||||||
|
(testing "given a token-gated community"
|
||||||
|
(let [cofx {:db {:communities/fetching-community {community-id true}}}
|
||||||
|
arg [community-id {:id community-id :tokenPermissions [1]}]]
|
||||||
|
(testing "dispatch fxs, do not spectate community"
|
||||||
|
(is (match?
|
||||||
|
{:fx [[:dispatch [:communities/handle-community {:id community-id}]]
|
||||||
|
[:dispatch
|
||||||
|
[:chat.ui/cache-link-preview-data "community-link+community-id"
|
||||||
|
{:id community-id}]]]}
|
||||||
|
(events/community-fetched cofx arg))))))
|
||||||
|
(testing "given nil community"
|
||||||
|
(testing "do nothing"
|
||||||
|
(is (match?
|
||||||
|
nil
|
||||||
|
(events/community-fetched {} [community-id nil])))))))
|
||||||
|
|
||||||
|
(deftest spectate-community
|
||||||
|
(testing "given a joined community"
|
||||||
|
(testing "do nothing"
|
||||||
|
(is (match?
|
||||||
|
nil
|
||||||
|
(events/spectate-community {:db {:communities {community-id {:joined true}}}}
|
||||||
|
[community-id])))))
|
||||||
|
(testing "given a spectated community"
|
||||||
|
(testing "do nothing"
|
||||||
|
(is (match?
|
||||||
|
nil
|
||||||
|
(events/spectate-community {:db {:communities {community-id {:spectated true}}}}
|
||||||
|
[community-id])))))
|
||||||
|
(testing "given a spectating community"
|
||||||
|
(testing "do nothing"
|
||||||
|
(is (match?
|
||||||
|
nil
|
||||||
|
(events/spectate-community {:db {:communities {community-id {:spectating true}}}}
|
||||||
|
[community-id])))))
|
||||||
|
(testing "given a community"
|
||||||
|
(testing "mark community spectating"
|
||||||
|
(is (match?
|
||||||
|
{:db {:communities {community-id {:spectating true}}}}
|
||||||
|
(events/spectate-community {:db {:communities {community-id {}}}} [community-id]))))
|
||||||
|
(testing "call spectate community rpc with correct community id"
|
||||||
|
(is (match?
|
||||||
|
{:json-rpc/call [{:method "wakuext_spectateCommunity"
|
||||||
|
:params [community-id]}]}
|
||||||
|
(events/spectate-community {:db {:communities {community-id {}}}} [community-id]))))))
|
||||||
|
|
||||||
|
(deftest spectate-community-failed
|
||||||
|
(testing "mark community spectating false"
|
||||||
|
(is (match?
|
||||||
|
{:db {:communities {community-id {:spectating false}}}}
|
||||||
|
(events/spectate-community-failed {} [community-id])))))
|
||||||
|
|
||||||
|
(deftest spectate-community-success
|
||||||
|
(testing "given communities"
|
||||||
|
(testing "mark first community spectating false"
|
||||||
|
(is (match?
|
||||||
|
{:db {:communities {community-id {:spectating false}}}}
|
||||||
|
(events/spectate-community-success {} [{:communities [{:id community-id}]}]))))
|
||||||
|
(testing "mark first community spectated true"
|
||||||
|
(is (match?
|
||||||
|
{:db {:communities {community-id {:spectated true}}}}
|
||||||
|
(events/spectate-community-success {} [{:communities [{:id community-id}]}]))))
|
||||||
|
(testing "dispatch fxs for first community"
|
||||||
|
(is (match?
|
||||||
|
{:fx [[:dispatch [:communities/handle-community {:id community-id}]]
|
||||||
|
[:dispatch [::mailserver/request-messages]]]}
|
||||||
|
(events/spectate-community-success {} [{:communities [{:id community-id}]}])))))
|
||||||
|
(testing "given empty community"
|
||||||
|
(testing "do nothing"
|
||||||
|
(is (match?
|
||||||
|
nil
|
||||||
|
(events/spectate-community-success {} [{:communities []}])))))
|
||||||
|
(testing "given nil community"
|
||||||
|
(testing "do nothing"
|
||||||
|
(is (match?
|
||||||
|
nil
|
||||||
|
(events/spectate-community-success {} []))))))
|
||||||
|
|||||||
@@ -26,7 +26,8 @@
|
|||||||
[quo/communities-membership-list-item
|
[quo/communities-membership-list-item
|
||||||
{:customization-color customization-color
|
{:customization-color customization-color
|
||||||
:style {:padding-horizontal 20}
|
:style {:padding-horizontal 20}
|
||||||
:on-press #(debounce/dispatch-and-chill [:navigate-to :community-overview id] 500)
|
:on-press #(debounce/dispatch-and-chill [:communities/navigate-to-community-overview id]
|
||||||
|
500)
|
||||||
:on-long-press #(rf/dispatch
|
:on-long-press #(rf/dispatch
|
||||||
[:show-bottom-sheet
|
[:show-bottom-sheet
|
||||||
{:content (fn []
|
{:content (fn []
|
||||||
|
|||||||
@@ -144,13 +144,12 @@
|
|||||||
|
|
||||||
(defn request-to-join-with-signatures-and-addresses
|
(defn request-to-join-with-signatures-and-addresses
|
||||||
[{:keys [db]} [community-id signatures]]
|
[{:keys [db]} [community-id signatures]]
|
||||||
(let [airdrop-address (get-in db [:communities/airdrop-address])
|
(let [{:keys [airdrop-address selected-permission-addresses]} (get-in db [:communities community-id])]
|
||||||
addresses-to-reveal (get-in db [:communities/selected-permission-addresses])]
|
|
||||||
{:fx [[:json-rpc/call
|
{:fx [[:json-rpc/call
|
||||||
[{:method "wakuext_requestToJoinCommunity"
|
[{:method "wakuext_requestToJoinCommunity"
|
||||||
:params [{:communityId community-id
|
:params [{:communityId community-id
|
||||||
:signatures signatures
|
:signatures signatures
|
||||||
:addressesToReveal addresses-to-reveal
|
:addressesToReveal selected-permission-addresses
|
||||||
:airdropAddress airdrop-address}]
|
:airdropAddress airdrop-address}]
|
||||||
:js-response true
|
:js-response true
|
||||||
:on-success [:communities/requested-to-join]
|
:on-success [:communities/requested-to-join]
|
||||||
@@ -173,7 +172,7 @@
|
|||||||
[{:keys [db]}
|
[{:keys [db]}
|
||||||
[{:keys [community-id password]}]]
|
[{:keys [community-id password]}]]
|
||||||
(let [pub-key (get-in db [:profile/profile :public-key])
|
(let [pub-key (get-in db [:profile/profile :public-key])
|
||||||
addresses-to-reveal (get-in db [:communities/selected-permission-addresses])]
|
addresses-to-reveal (get-in db [:communities community-id :selected-permission-addresses])]
|
||||||
{:fx [[:json-rpc/call
|
{:fx [[:json-rpc/call
|
||||||
[{:method "wakuext_generateJoiningCommunityRequestsForSigning"
|
[{:method "wakuext_generateJoiningCommunityRequestsForSigning"
|
||||||
:params [pub-key community-id addresses-to-reveal]
|
:params [pub-key community-id addresses-to-reveal]
|
||||||
|
|||||||
@@ -137,8 +137,7 @@
|
|||||||
[quo/icon :i/info {:no-color true}]]])
|
[quo/icon :i/info {:no-color true}]]])
|
||||||
|
|
||||||
(defn token-gates
|
(defn token-gates
|
||||||
[{:keys [id]}]
|
[]
|
||||||
(rf/dispatch [:communities/check-permissions-to-join-community id])
|
|
||||||
(fn [{:keys [id color]}]
|
(fn [{:keys [id color]}]
|
||||||
(let [{:keys [can-request-access?
|
(let [{:keys [can-request-access?
|
||||||
number-of-hold-tokens tokens]} (rf/sub [:community/token-gated-overview id])]
|
number-of-hold-tokens tokens]} (rf/sub [:community/token-gated-overview id])]
|
||||||
@@ -222,8 +221,9 @@
|
|||||||
{:on-press (when joined-or-spectated
|
{:on-press (when joined-or-spectated
|
||||||
(fn []
|
(fn []
|
||||||
(rf/dispatch [:dismiss-keyboard])
|
(rf/dispatch [:dismiss-keyboard])
|
||||||
(debounce/dispatch-and-chill [:chat/navigate-to-chat (str community-id id)]
|
(debounce/dispatch-and-chill
|
||||||
1000)))
|
[:communities/navigate-to-community-chat (str community-id id)]
|
||||||
|
1000)))
|
||||||
:on-long-press #(rf/dispatch
|
:on-long-press #(rf/dispatch
|
||||||
[:show-bottom-sheet
|
[:show-bottom-sheet
|
||||||
{:content (fn []
|
{:content (fn []
|
||||||
@@ -370,9 +370,10 @@
|
|||||||
(let [{:keys [id joined]
|
(let [{:keys [id joined]
|
||||||
:as community} (rf/sub [:communities/community id])
|
:as community} (rf/sub [:communities/community id])
|
||||||
pending? (rf/sub [:communities/my-pending-request-to-join id])]
|
pending? (rf/sub [:communities/my-pending-request-to-join id])]
|
||||||
(when joined
|
(when community
|
||||||
(rf/dispatch [:activity-center.notifications/dismiss-community-overview id]))
|
(when joined
|
||||||
[community-scroll-page community pending?]))
|
(rf/dispatch [:activity-center.notifications/dismiss-community-overview id]))
|
||||||
|
[community-scroll-page community pending?])))
|
||||||
|
|
||||||
(defn overview
|
(defn overview
|
||||||
[id]
|
[id]
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
:status-indicator? false
|
:status-indicator? false
|
||||||
:customization-color customization-color}]]
|
:customization-color customization-color}]]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/card-view}
|
{:pointer-events :none :style style/card-view}
|
||||||
[reanimated/view
|
[reanimated/view
|
||||||
{:style (style/card-container container-background)}
|
{:style (style/card-container container-background)}
|
||||||
[rn/view {:style style/card-header}
|
[rn/view {:style style/card-header}
|
||||||
|
|||||||
@@ -15,3 +15,8 @@
|
|||||||
{:justify-self :flex-end
|
{:justify-self :flex-end
|
||||||
:margin-bottom 46
|
:margin-bottom 46
|
||||||
:margin-horizontal 20})
|
:margin-horizontal 20})
|
||||||
|
|
||||||
|
(defn carousel-background
|
||||||
|
[height width]
|
||||||
|
{:height height
|
||||||
|
:width width})
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
paused? (atom nil)
|
paused? (atom nil)
|
||||||
is-dragging? (atom nil)
|
is-dragging? (atom nil)
|
||||||
drag-amount (atom nil)
|
drag-amount (atom nil)
|
||||||
|
window-width (rf/sub [:dimensions/window-width])
|
||||||
|
window-height (rf/sub [:dimensions/window-height])
|
||||||
{:keys [emoji-hash display-name compressed-key
|
{:keys [emoji-hash display-name compressed-key
|
||||||
public-key]} (rf/sub [:profile/profile])
|
public-key]} (rf/sub [:profile/profile])
|
||||||
{:keys [color]} (rf/sub [:onboarding/profile])
|
{:keys [color]} (rf/sub [:onboarding/profile])
|
||||||
@@ -42,11 +44,16 @@
|
|||||||
{:animate? true
|
{:animate? true
|
||||||
:progress progress
|
:progress progress
|
||||||
:paused? paused?
|
:paused? paused?
|
||||||
:gesture :tappable
|
:gesture :swipeable
|
||||||
:is-dragging? is-dragging?
|
:is-dragging? is-dragging?
|
||||||
:drag-amount drag-amount
|
:drag-amount drag-amount
|
||||||
:header-text header-text}]
|
:header-text header-text
|
||||||
[rn/view {:style style/content-container}
|
:background [rn/view
|
||||||
|
{:style (style/carousel-background window-height
|
||||||
|
(* (count header-text) window-width))}]}]
|
||||||
|
[rn/view
|
||||||
|
{:style style/content-container
|
||||||
|
:pointer-events :box-none}
|
||||||
[profile-card/profile-card
|
[profile-card/profile-card
|
||||||
{:profile-picture photo-path
|
{:profile-picture photo-path
|
||||||
:name display-name
|
:name display-name
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
(ns status-im.contexts.preview.quo.list-items.community-list
|
(ns status-im.contexts.preview.quo.community.list-item
|
||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
:unread-count 5})]
|
:unread-count 5})]
|
||||||
(fn []
|
(fn []
|
||||||
[preview/preview-container {:state state :descriptor (descriptors @state)}
|
[preview/preview-container {:state state :descriptor (descriptors @state)}
|
||||||
[quo/community-list-item
|
[quo/community-list
|
||||||
(merge @state
|
(merge @state
|
||||||
{:container-style {:width 335}
|
{:container-style {:width 335}
|
||||||
:logo (resources/get-mock-image :status-logo)
|
:logo (resources/get-mock-image :status-logo)
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
(ns status-im.contexts.preview.quo.list-items.network-list
|
||||||
|
(:require
|
||||||
|
[quo.core :as quo]
|
||||||
|
[quo.foundations.resources :as quo.resources]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[status-im.contexts.preview.quo.preview :as preview]))
|
||||||
|
|
||||||
|
(def descriptor
|
||||||
|
[{:key :state
|
||||||
|
:type :select
|
||||||
|
:options [{:key :default}
|
||||||
|
{:key :active}
|
||||||
|
{:key :pressed}]}
|
||||||
|
{:key :network-image
|
||||||
|
:type :select
|
||||||
|
:options [{:key (quo.resources/get-network :ethereum)
|
||||||
|
:value :ethereum}
|
||||||
|
{:key (quo.resources/get-network :arbitrum)
|
||||||
|
:value :arbitrum}
|
||||||
|
{:key (quo.resources/get-network :optimism)
|
||||||
|
:value :optimism}]}
|
||||||
|
{:key :label
|
||||||
|
:type :text}
|
||||||
|
{:key :token-value
|
||||||
|
:type :text}
|
||||||
|
{:key :fiat-value
|
||||||
|
:type :text}
|
||||||
|
{:key :show-alert-on-press?
|
||||||
|
:type :boolean}])
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
(let [state (reagent/atom {:network-image (quo.resources/get-network :ethereum)
|
||||||
|
:label "Mainnet"
|
||||||
|
:token-value "0.00 ETH"
|
||||||
|
:fiat-value "€0.00"
|
||||||
|
:state :default
|
||||||
|
:customization-color :blue})]
|
||||||
|
(fn []
|
||||||
|
[preview/preview-container
|
||||||
|
{:state state
|
||||||
|
:descriptor descriptor}
|
||||||
|
[quo/network-list
|
||||||
|
(merge @state
|
||||||
|
(when (:show-alert-on-press? @state)
|
||||||
|
{:on-press #(js/alert "Pressed!")}))]])))
|
||||||
@@ -41,4 +41,4 @@
|
|||||||
:descriptor descriptor
|
:descriptor descriptor
|
||||||
:component-container-style {:padding-vertical 30
|
:component-container-style {:padding-vertical 30
|
||||||
:padding-horizontal 15}}
|
:padding-horizontal 15}}
|
||||||
[quo/user-list @state]])))
|
[quo/user @state]])))
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
:as community-membership-list-view]
|
:as community-membership-list-view]
|
||||||
[status-im.contexts.preview.quo.community.community-stat :as community-stat]
|
[status-im.contexts.preview.quo.community.community-stat :as community-stat]
|
||||||
[status-im.contexts.preview.quo.community.discover-card :as discover-card]
|
[status-im.contexts.preview.quo.community.discover-card :as discover-card]
|
||||||
|
[status-im.contexts.preview.quo.community.list-item :as community-list-item]
|
||||||
[status-im.contexts.preview.quo.community.token-gating :as token-gating]
|
[status-im.contexts.preview.quo.community.token-gating :as token-gating]
|
||||||
[status-im.contexts.preview.quo.counter.counter :as counter]
|
[status-im.contexts.preview.quo.counter.counter :as counter]
|
||||||
[status-im.contexts.preview.quo.counter.step :as step]
|
[status-im.contexts.preview.quo.counter.step :as step]
|
||||||
@@ -92,9 +93,8 @@
|
|||||||
account-list-card]
|
account-list-card]
|
||||||
[status-im.contexts.preview.quo.list-items.address :as address]
|
[status-im.contexts.preview.quo.list-items.address :as address]
|
||||||
[status-im.contexts.preview.quo.list-items.channel :as channel]
|
[status-im.contexts.preview.quo.list-items.channel :as channel]
|
||||||
[status-im.contexts.preview.quo.list-items.community-list :as
|
|
||||||
community-list]
|
|
||||||
[status-im.contexts.preview.quo.list-items.dapp :as dapp]
|
[status-im.contexts.preview.quo.list-items.dapp :as dapp]
|
||||||
|
[status-im.contexts.preview.quo.list-items.network-list :as network-list]
|
||||||
[status-im.contexts.preview.quo.list-items.preview-lists :as preview-lists]
|
[status-im.contexts.preview.quo.list-items.preview-lists :as preview-lists]
|
||||||
[status-im.contexts.preview.quo.list-items.quiz-item :as quiz-item]
|
[status-im.contexts.preview.quo.list-items.quiz-item :as quiz-item]
|
||||||
[status-im.contexts.preview.quo.list-items.saved-address :as saved-address]
|
[status-im.contexts.preview.quo.list-items.saved-address :as saved-address]
|
||||||
@@ -349,9 +349,11 @@
|
|||||||
:component channel/view}
|
:component channel/view}
|
||||||
{:name :community-list
|
{:name :community-list
|
||||||
:options {:insets {:top? true}}
|
:options {:insets {:top? true}}
|
||||||
:component community-list/view}
|
:component community-list-item/view}
|
||||||
{:name :dapp
|
{:name :dapp
|
||||||
:component dapp/preview}
|
:component dapp/preview}
|
||||||
|
{:name :network-list
|
||||||
|
:component network-list/view}
|
||||||
{:name :preview-lists
|
{:name :preview-lists
|
||||||
:component preview-lists/view}
|
:component preview-lists/view}
|
||||||
{:name :quiz-item
|
{:name :quiz-item
|
||||||
|
|||||||
@@ -320,7 +320,7 @@
|
|||||||
(defn- f-preview-container
|
(defn- f-preview-container
|
||||||
[{:keys [title state descriptor blur? blur-dark-only?
|
[{:keys [title state descriptor blur? blur-dark-only?
|
||||||
component-container-style
|
component-container-style
|
||||||
blur-container-style blur-view-props blur-height show-blur-background?]
|
blur-container-style blur-view-props blur-height show-blur-background? full-screen?]
|
||||||
:or {blur-height 200}}
|
:or {blur-height 200}}
|
||||||
& children]
|
& children]
|
||||||
(let [theme (quo.theme/use-theme-value)
|
(let [theme (quo.theme/use-theme-value)
|
||||||
@@ -337,8 +337,11 @@
|
|||||||
[common/navigation-bar {:title title}]
|
[common/navigation-bar {:title title}]
|
||||||
[rn/scroll-view
|
[rn/scroll-view
|
||||||
{:style (style/panel-basic)
|
{:style (style/panel-basic)
|
||||||
:shows-vertical-scroll-indicator false}
|
:shows-vertical-scroll-indicator false
|
||||||
[rn/pressable {:on-press rn/dismiss-keyboard!}
|
:content-container-style (when full-screen? {:flex 1})}
|
||||||
|
[rn/pressable
|
||||||
|
{:style (when full-screen? {:flex 1})
|
||||||
|
:on-press rn/dismiss-keyboard!}
|
||||||
(when descriptor
|
(when descriptor
|
||||||
[rn/view {:style style/customizer-container}
|
[rn/view {:style style/customizer-container}
|
||||||
[customizer state descriptor]])
|
[customizer state descriptor]])
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[quo.foundations.resources :as resources]
|
[quo.foundations.resources :as resources]
|
||||||
|
[react-native.safe-area :as safe-area]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.contexts.preview.quo.preview :as preview]))
|
[status-im.contexts.preview.quo.preview :as preview]))
|
||||||
|
|
||||||
@@ -20,21 +21,35 @@
|
|||||||
{:key :currency
|
{:key :currency
|
||||||
:type :select
|
:type :select
|
||||||
:options [{:key :usd}
|
:options [{:key :usd}
|
||||||
{:key :eur}]}])
|
{:key :eur}]}
|
||||||
|
{:key :error?
|
||||||
|
:type :boolean}])
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [state (reagent/atom {:token :eth
|
(let [state (reagent/atom {:token :eth
|
||||||
:currency :usd
|
:currency :usd
|
||||||
:conversion 0.02
|
:conversion 0.02
|
||||||
:networks networks
|
:networks networks
|
||||||
:title title
|
:title title
|
||||||
:customization-color :blue})]
|
:customization-color :blue
|
||||||
|
:show-keyboard? false})
|
||||||
|
value (reagent/atom "")
|
||||||
|
set-value (fn [v]
|
||||||
|
(swap! value str v))
|
||||||
|
delete (fn [_]
|
||||||
|
(swap! value #(subs % 0 (dec (count %)))))]
|
||||||
(fn []
|
(fn []
|
||||||
[preview/preview-container
|
[preview/preview-container
|
||||||
{:state state
|
{:state state
|
||||||
:descriptor descriptor
|
:descriptor descriptor
|
||||||
:component-container-style {:padding-horizontal 20
|
:full-screen? true
|
||||||
:margin-top 50
|
:component-container-style {:flex 1
|
||||||
:align-items :center}}
|
:justify-content :space-between}}
|
||||||
[quo/token-input @state]])))
|
[quo/token-input (assoc @state :value @value)]
|
||||||
|
[quo/numbered-keyboard
|
||||||
|
{:container-style {:padding-bottom (safe-area/get-top)}
|
||||||
|
:left-action :dot
|
||||||
|
:delete-key? true
|
||||||
|
:on-press set-value
|
||||||
|
:on-delete delete}]])))
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
(ns status-im.contexts.profile.events
|
(ns status-im.contexts.profile.events
|
||||||
(:require
|
(:require
|
||||||
|
[legacy.status-im.data-store.settings :as data-store.settings]
|
||||||
[native-module.core :as native-module]
|
[native-module.core :as native-module]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.contexts.profile.edit.name.events]
|
[status-im.contexts.profile.edit.name.events]
|
||||||
@@ -52,8 +53,10 @@
|
|||||||
|
|
||||||
(rf/defn update-setting-from-backup
|
(rf/defn update-setting-from-backup
|
||||||
{:events [:profile/update-setting-from-backup]}
|
{:events [:profile/update-setting-from-backup]}
|
||||||
[{:keys [db]} {{:keys [name value]} :backedUpSettings}]
|
[{:keys [db]} {:keys [backedUpSettings]}]
|
||||||
{:db (assoc-in db [:profile/profile (keyword name)] value)})
|
(let [setting (update backedUpSettings :name keyword)
|
||||||
|
{:keys [name value]} (data-store.settings/rpc->setting-value setting)]
|
||||||
|
{:db (assoc-in db [:profile/profile name] value)}))
|
||||||
|
|
||||||
(rf/defn update-profile-from-backup
|
(rf/defn update-profile-from-backup
|
||||||
{:events [:profile/update-profile-from-backup]}
|
{:events [:profile/update-profile-from-backup]}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
(ns status-im.contexts.profile.settings.list-items
|
(ns status-im.contexts.profile.settings.list-items
|
||||||
(:require [status-im.common.not-implemented :as not-implemented]
|
(:require [status-im.common.not-implemented :as not-implemented]
|
||||||
|
[status-im.config :as config]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
@@ -89,12 +90,13 @@
|
|||||||
:image :icon
|
:image :icon
|
||||||
:blur? true
|
:blur? true
|
||||||
:image-props :i/toggle}
|
:image-props :i/toggle}
|
||||||
{:title "Quo preview"
|
(when config/quo-preview-enabled?
|
||||||
:on-press #(rf/dispatch [:navigate-to :quo-preview])
|
{:title "Quo preview"
|
||||||
:action :arrow
|
:on-press #(rf/dispatch [:navigate-to :quo-preview])
|
||||||
:image :icon
|
:action :arrow
|
||||||
:blur? true
|
:image :icon
|
||||||
:image-props :i/light}]
|
:blur? true
|
||||||
|
:image-props :i/light})]
|
||||||
[{:title (i18n/label :t/about)
|
[{:title (i18n/label :t/about)
|
||||||
:on-press not-implemented/alert
|
:on-press not-implemented/alert
|
||||||
:action :arrow}
|
:action :arrow}
|
||||||
|
|||||||
+1
-1
@@ -71,7 +71,7 @@
|
|||||||
[gesture/touchable-without-feedback
|
[gesture/touchable-without-feedback
|
||||||
{:on-press (fn []
|
{:on-press (fn []
|
||||||
(rf/dispatch [:navigate-back])
|
(rf/dispatch [:navigate-back])
|
||||||
(rf/dispatch [:navigate-to :community-overview community-id]))}
|
(rf/dispatch [:communities/navigate-to-community-overview community-id]))}
|
||||||
[quo/activity-log
|
[quo/activity-log
|
||||||
{:title header-text
|
{:title header-text
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
|
|||||||
@@ -197,10 +197,10 @@
|
|||||||
(rf/dispatch [:chat/navigate-to-chat id])
|
(rf/dispatch [:chat/navigate-to-chat id])
|
||||||
|
|
||||||
(= card-type shell.constants/community-channel-card)
|
(= card-type shell.constants/community-channel-card)
|
||||||
(rf/dispatch [:chat/navigate-to-chat channel-id])
|
(rf/dispatch [:communities/navigate-to-community-chat channel-id])
|
||||||
|
|
||||||
(= card-type shell.constants/community-card)
|
(= card-type shell.constants/community-card)
|
||||||
(rf/dispatch [:navigate-to :community-overview id])))
|
(rf/dispatch [:communities/navigate-to-community-overview id])))
|
||||||
|
|
||||||
(defn calculate-card-position-and-open-screen
|
(defn calculate-card-position-and-open-screen
|
||||||
[card-ref card-type id channel-id]
|
[card-ref card-type id channel-id]
|
||||||
|
|||||||
@@ -21,11 +21,11 @@
|
|||||||
abbreviated-url (address/get-abbreviated-profile-url
|
abbreviated-url (address/get-abbreviated-profile-url
|
||||||
universal-profile-url)
|
universal-profile-url)
|
||||||
emoji-hash-string (string/join emoji-hash)]
|
emoji-hash-string (string/join emoji-hash)]
|
||||||
[:<>
|
[rn/scroll-view
|
||||||
|
{:content-container-style {:padding-bottom 16}}
|
||||||
[rn/view {:style style/qr-code-container}
|
[rn/view {:style style/qr-code-container}
|
||||||
[qr-codes/share-qr-code
|
[qr-codes/share-qr-code
|
||||||
{:type :profile
|
{:type :profile
|
||||||
:unblur-on-android? true
|
|
||||||
:qr-data universal-profile-url
|
:qr-data universal-profile-url
|
||||||
:qr-data-label-shown abbreviated-url
|
:qr-data-label-shown abbreviated-url
|
||||||
:on-share-press #(list-selection/open-share {:message universal-profile-url})
|
:on-share-press #(list-selection/open-share {:message universal-profile-url})
|
||||||
|
|||||||
@@ -5,13 +5,6 @@
|
|||||||
|
|
||||||
(def screen-padding 20)
|
(def screen-padding 20)
|
||||||
|
|
||||||
(def blur
|
|
||||||
{:position :absolute
|
|
||||||
:top 0
|
|
||||||
:left 0
|
|
||||||
:right 0
|
|
||||||
:bottom 0
|
|
||||||
:overlay-color colors/neutral-80-opa-80-blur})
|
|
||||||
|
|
||||||
(def header-row
|
(def header-row
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
(ns status-im.contexts.shell.share.view
|
(ns status-im.contexts.shell.share.view
|
||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[react-native.blur :as blur]
|
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.platform :as platform]
|
|
||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.contexts.shell.share.profile.view :as profile-view]
|
[status-im.contexts.shell.share.profile.view :as profile-view]
|
||||||
@@ -43,7 +41,7 @@
|
|||||||
[]
|
[]
|
||||||
(let [selected-tab (reagent/atom :profile)]
|
(let [selected-tab (reagent/atom :profile)]
|
||||||
(fn []
|
(fn []
|
||||||
[:<>
|
[rn/view {:style {:padding-top (safe-area/get-top)}}
|
||||||
[header]
|
[header]
|
||||||
[rn/view {:style style/tabs-container}
|
[rn/view {:style style/tabs-container}
|
||||||
[quo/segmented-control
|
[quo/segmented-control
|
||||||
@@ -61,9 +59,7 @@
|
|||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
[rn/view {:flex 1 :padding-top (safe-area/get-top)}
|
[quo/overlay {:type :shell}
|
||||||
[blur/view
|
[rn/view
|
||||||
{:style style/blur
|
{:key :share}
|
||||||
:blur-amount 20
|
[tab-content]]])
|
||||||
:blur-radius (if platform/android? 25 10)}]
|
|
||||||
[tab-content]])
|
|
||||||
|
|||||||
@@ -66,7 +66,6 @@
|
|||||||
:networks @selected-networks
|
:networks @selected-networks
|
||||||
:on-share-press #(share-action qr-url share-title)
|
:on-share-press #(share-action qr-url share-title)
|
||||||
:profile-picture nil
|
:profile-picture nil
|
||||||
:unblur-on-android? true
|
|
||||||
:full-name (:name account)
|
:full-name (:name account)
|
||||||
:customization-color (:color account)
|
:customization-color (:color account)
|
||||||
:emoji (:emoji account)
|
:emoji (:emoji account)
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
[]
|
[]
|
||||||
(let [{:keys [customization-color] :as profile} (rf/sub [:profile/profile-with-image])
|
(let [{:keys [customization-color] :as profile} (rf/sub [:profile/profile-with-image])
|
||||||
{:keys [address path watch-only?]} (rf/sub [:wallet/current-viewing-account])
|
{:keys [address path watch-only?]} (rf/sub [:wallet/current-viewing-account])
|
||||||
networks (rf/sub [:wallet/network-details])]
|
networks (rf/sub [:wallet/network-preference-details])]
|
||||||
[rn/scroll-view
|
[rn/scroll-view
|
||||||
{:style style/about-tab
|
{:style style/about-tab
|
||||||
:content-container-style {:padding-bottom 20}}
|
:content-container-style {:padding-bottom 20}}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
:assets [assets/view]
|
:assets [assets/view]
|
||||||
:collectibles [collectibles/view
|
:collectibles [collectibles/view
|
||||||
{:collectibles collectible-list
|
{:collectibles collectible-list
|
||||||
:on-collectible-press (fn [id]
|
:on-collectible-press (fn [{:keys [id]}]
|
||||||
(rf/dispatch [:wallet/get-collectible-details id])
|
(rf/dispatch [:wallet/get-collectible-details id])
|
||||||
(rf/dispatch [:navigate-to :wallet-collectible]))}]
|
(rf/dispatch [:navigate-to :wallet-collectible]))}]
|
||||||
:activity [activity/view]
|
:activity [activity/view]
|
||||||
|
|||||||
@@ -46,7 +46,9 @@
|
|||||||
[quo/wallet-graph {:time-frame :empty}]
|
[quo/wallet-graph {:time-frame :empty}]
|
||||||
(when (not watch-only?)
|
(when (not watch-only?)
|
||||||
[quo/wallet-ctas
|
[quo/wallet-ctas
|
||||||
{:send-action #(rf/dispatch [:open-modal :wallet-select-address])
|
{:send-action (fn []
|
||||||
|
(rf/dispatch [:wallet/clean-send-data])
|
||||||
|
(rf/dispatch [:open-modal :wallet-select-address]))
|
||||||
:receive-action #(rf/dispatch [:open-modal :wallet-share-address {:status :receive}])
|
:receive-action #(rf/dispatch [:open-modal :wallet-share-address {:status :receive}])
|
||||||
:buy-action #(rf/dispatch [:show-bottom-sheet
|
:buy-action #(rf/dispatch [:show-bottom-sheet
|
||||||
{:content buy-drawer}])
|
{:content buy-drawer}])
|
||||||
|
|||||||
@@ -122,17 +122,17 @@
|
|||||||
(rf/dispatch [:wallet/clean-scanned-address])
|
(rf/dispatch [:wallet/clean-scanned-address])
|
||||||
(rf/dispatch [:wallet/clear-address-activity-check])
|
(rf/dispatch [:wallet/clear-address-activity-check])
|
||||||
(rf/dispatch [:navigate-back]))}]
|
(rf/dispatch [:navigate-back]))}]
|
||||||
:footer
|
:footer [quo/button
|
||||||
[quo/button
|
{:customization-color customization-color
|
||||||
{:customization-color customization-color
|
:disabled? (or (string/blank? @input-value)
|
||||||
:disabled? (or (string/blank? @input-value) (some? (validate @input-value)))
|
(some? (validate @input-value)))
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(rf/dispatch [:navigate-to
|
(rf/dispatch [:navigate-to
|
||||||
:confirm-address-to-watch
|
:confirm-address-to-watch
|
||||||
{:address @input-value}])
|
{:address @input-value}])
|
||||||
(clear-input))
|
(clear-input))
|
||||||
:container-style {:z-index 2}}
|
:container-style {:z-index 2}}
|
||||||
(i18n/label :t/continue)]}
|
(i18n/label :t/continue)]}
|
||||||
[quo/text-combinations
|
[quo/text-combinations
|
||||||
{:container-style style/header-container
|
{:container-style style/header-container
|
||||||
:title (i18n/label :t/add-address)
|
:title (i18n/label :t/add-address)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user