Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e50d73829 | ||
|
|
9dff93bbe8 |
@@ -15,7 +15,6 @@
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.common.universal-links :as links]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.chat.events :as chat.events]
|
||||
@@ -655,11 +654,12 @@
|
||||
stored-bookmarks)]
|
||||
{:db (assoc db :bookmarks/bookmarks bookmarks)}))
|
||||
|
||||
(re-frame/reg-fx :browser/initialize-browser
|
||||
(fn []
|
||||
(json-rpc/call {:method "wakuext_getBrowsers"
|
||||
:on-success [::initialize-browsers]})
|
||||
(json-rpc/call {:method "browsers_getBookmarks"
|
||||
:on-success [::initialize-bookmarks]})
|
||||
(json-rpc/call {:method "permissions_getDappPermissions"
|
||||
:on-success [::initialize-dapp-permissions]})))
|
||||
(rf/defn initialize-browser
|
||||
[_]
|
||||
{:json-rpc/call
|
||||
[{:method "wakuext_getBrowsers"
|
||||
:on-success #(re-frame/dispatch [::initialize-browsers %])}
|
||||
{:method "browsers_getBookmarks"
|
||||
:on-success #(re-frame/dispatch [::initialize-bookmarks %])}
|
||||
{:method "permissions_getDappPermissions"
|
||||
:on-success #(re-frame/dispatch [::initialize-dapp-permissions %])}]})
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
|
||||
legacy.status-im.communities.e2e
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.contexts.shell.activity-center.events :as activity-center]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -83,12 +84,13 @@
|
||||
(navigation/navigate-back)
|
||||
(handle-response response-js)))
|
||||
|
||||
(re-frame/reg-event-fx ::member-banned
|
||||
(fn [{:keys [db]} [response-js]]
|
||||
{:db (assoc db :bottom-sheet/show? false)
|
||||
:fx [[:dismiss-bottom-sheet-overlay-old]
|
||||
[:sanitize-messages-and-process-response response-js]
|
||||
[:activity-center.notifications/fetch-unread-count]]}))
|
||||
(rf/defn member-banned
|
||||
{:events [::member-banned]}
|
||||
[cofx response-js]
|
||||
(rf/merge cofx
|
||||
(bottom-sheet/hide-bottom-sheet-old)
|
||||
(handle-response response-js)
|
||||
(activity-center/notifications-fetch-unread-count)))
|
||||
|
||||
(rf/defn member-ban
|
||||
{:events [::member-ban]}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.contexts.chat.contacts.events :as contacts-store]
|
||||
[status-im.contexts.chat.messenger.messages.list.events :as message-list]
|
||||
[status-im.contexts.shell.activity-center.events :as activity-center]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -44,16 +45,16 @@
|
||||
(apply
|
||||
rf/merge
|
||||
cofx
|
||||
{:db (->
|
||||
db
|
||||
(update :chats dissoc public-key)
|
||||
(update :chats-home-list disj public-key)
|
||||
(assoc-in [:contacts/contacts public-key
|
||||
:added?]
|
||||
false))
|
||||
:fx [[:activity-center.notifications/fetch-unread-count]
|
||||
[:effects/push-notifications-clear-message-notifications [public-key]]
|
||||
[:dispatch [:shell/close-switcher-card public-key]]]}
|
||||
{:db (->
|
||||
db
|
||||
(update :chats dissoc public-key)
|
||||
(update :chats-home-list disj public-key)
|
||||
(assoc-in [:contacts/contacts public-key
|
||||
:added?]
|
||||
false))
|
||||
:dispatch [:shell/close-switcher-card public-key]
|
||||
:effects/push-notifications-clear-message-notifications [public-key]}
|
||||
(activity-center/notifications-fetch-unread-count)
|
||||
fxs)))
|
||||
|
||||
(rf/defn block-contact
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
:line-count nil
|
||||
:links nil
|
||||
:text nil}
|
||||
:bridge-message nil
|
||||
:outgoing false}
|
||||
:message nil
|
||||
:reply-message {:quoted-message nil
|
||||
@@ -62,7 +61,6 @@
|
||||
:line-count nil
|
||||
:links nil
|
||||
:text nil}
|
||||
:bridge-message nil
|
||||
:outgoing false}}
|
||||
(-> raw-notification
|
||||
store/<-rpc
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
[clojure.set :as set]
|
||||
[legacy.status-im.data-store.messages :as messages]
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.constants :as constants]
|
||||
[taoensso.timbre :as log]))
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn rpc->type
|
||||
[{:keys [chat-type name] :as chat}]
|
||||
@@ -118,10 +117,10 @@
|
||||
rpc->type
|
||||
unmarshal-members))
|
||||
|
||||
(re-frame/reg-fx :fetch-chats-preview
|
||||
(fn [{:keys [on-success]}]
|
||||
(json-rpc/call {:method "wakuext_chatsPreview"
|
||||
:params []
|
||||
:js-response true
|
||||
:on-success #(on-success ^js %)
|
||||
:on-error #(log/error "failed to fetch chats" 0 -1 %)})))
|
||||
(rf/defn fetch-chats-preview
|
||||
[_ {:keys [on-success]}]
|
||||
{:json-rpc/call [{:method "wakuext_chatsPreview"
|
||||
:params []
|
||||
:js-response true
|
||||
:on-success #(on-success ^js %)
|
||||
:on-error #(log/error "failed to fetch chats" 0 -1 %)}]})
|
||||
|
||||
@@ -82,13 +82,7 @@
|
||||
:albumImagesCount :album-images-count
|
||||
:displayName :display-name
|
||||
:linkPreviews :link-previews
|
||||
:statusLinkPreviews :status-link-previews
|
||||
:bridgeMessage :bridge-message})
|
||||
(update :bridge-message
|
||||
set/rename-keys
|
||||
{:bridgeName :bridge-name
|
||||
:userName :user-name
|
||||
:userAvatar :user-avatar})
|
||||
:statusLinkPreviews :status-link-previews})
|
||||
(update :link-previews #(map <-link-preview-rpc %))
|
||||
(update :status-link-previews #(map <-status-link-previews-rpc %))
|
||||
(update :quoted-message
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
:image nil
|
||||
:response-to "a"
|
||||
:links nil}
|
||||
:bridge-message nil
|
||||
:whisper-timestamp 1
|
||||
:contact-verification-state 1
|
||||
:contact-request-state 2
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
(:require
|
||||
[clojure.set :as set]
|
||||
[clojure.walk :as walk]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -34,11 +32,11 @@
|
||||
:on-success #()
|
||||
:on-error #()}]})
|
||||
|
||||
(re-frame/reg-fx :switcher-cards/fetch
|
||||
(fn []
|
||||
(json-rpc/call {:method "wakuext_switcherCards"
|
||||
:params []
|
||||
:on-success #(rf/dispatch
|
||||
[:shell/switcher-cards-loaded
|
||||
(:switcherCards ^js %)])
|
||||
:on-error #(log/error "Failed to fetch switcher cards" %)})))
|
||||
(rf/defn fetch-switcher-cards-rpc
|
||||
[_]
|
||||
{:json-rpc/call [{:method "wakuext_switcherCards"
|
||||
:params []
|
||||
:on-success #(rf/dispatch
|
||||
[:shell/switcher-cards-loaded
|
||||
(:switcherCards ^js %)])
|
||||
:on-error #(log/error "Failed to fetch switcher cards" %)}]})
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
(:require
|
||||
[clojure.set :as set]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[taoensso.timbre :as log]))
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn <-rpc
|
||||
[visibility-status-update]
|
||||
@@ -18,13 +18,13 @@
|
||||
{:current-user-status :current-user-visibility-status})
|
||||
(update :current-user-visibility-status <-rpc)))
|
||||
|
||||
(re-frame/reg-fx :visibility-status-updates/fetch
|
||||
(fn []
|
||||
(json-rpc/call {:method "wakuext_statusUpdates"
|
||||
:params []
|
||||
:on-success #(re-frame/dispatch
|
||||
[:visibility-status-updates/visibility-status-updates-loaded
|
||||
(:statusUpdates ^js %)])
|
||||
:on-error #(log/error
|
||||
"failed to fetch visibility-status-updates"
|
||||
%)})))
|
||||
(rf/defn fetch-visibility-status-updates-rpc
|
||||
[_]
|
||||
{:json-rpc/call [{:method "wakuext_statusUpdates"
|
||||
:params []
|
||||
:on-success #(re-frame/dispatch
|
||||
[:visibility-status-updates/visibility-status-updates-loaded
|
||||
(:statusUpdates ^js %)])
|
||||
:on-error #(log/error
|
||||
"failed to fetch visibility-status-updates"
|
||||
%)}]})
|
||||
|
||||
@@ -239,7 +239,7 @@
|
||||
|
||||
(rf/defn tx-history-end-reached
|
||||
[{:keys [db] :as cofx} address]
|
||||
(let [syncing-allowed? (utils.mobile-sync/syncing-allowed? db)]
|
||||
(let [syncing-allowed? (utils.mobile-sync/syncing-allowed? cofx)]
|
||||
{:db (assoc-in db
|
||||
[:wallet-legacy :fetching address :all-fetched?]
|
||||
(if syncing-allowed?
|
||||
@@ -327,7 +327,7 @@
|
||||
{:chain-tokens (:wallet-legacy/all-tokens db)
|
||||
:addresses [address]
|
||||
:before-block min-known-block
|
||||
:fetch-more? (utils.mobile-sync/syncing-allowed? db)
|
||||
:fetch-more? (utils.mobile-sync/syncing-allowed? cofx)
|
||||
;; Transfers are requested before and including `min-known-block` because there is no
|
||||
;; guarantee that all transfers from that block are shown already. To make sure that we fetch
|
||||
;; the whole `default-transfers-limit` of transfers the number of transfers already received
|
||||
|
||||
@@ -8,16 +8,11 @@
|
||||
legacy.status-im.chat.models.loading
|
||||
legacy.status-im.contact.block
|
||||
legacy.status-im.currency.core
|
||||
legacy.status-im.data-store.chats
|
||||
legacy.status-im.data-store.switcher-cards
|
||||
legacy.status-im.data-store.visibility-status-updates
|
||||
legacy.status-im.fleet.core
|
||||
legacy.status-im.group-chats.core
|
||||
[legacy.status-im.keycard.core :as keycard]
|
||||
legacy.status-im.log-level.core
|
||||
legacy.status-im.mailserver.constants
|
||||
[legacy.status-im.mailserver.core :as mailserver]
|
||||
legacy.status-im.mobile-sync-settings.core
|
||||
legacy.status-im.multiaccounts.login.core
|
||||
legacy.status-im.multiaccounts.logout.core
|
||||
[legacy.status-im.multiaccounts.model :as multiaccounts.model]
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
[legacy.status-im.data-store.invitations :as data-store.invitations]
|
||||
[oops.core :as oops]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.chat.events :as chat.events]
|
||||
[status-im.contexts.shell.activity-center.events :as activity-center]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -19,13 +19,15 @@
|
||||
(when (get-in cofx [:db :chats chat-id])
|
||||
(chat.events/pop-to-root-and-navigate-to-chat cofx chat-id nil)))
|
||||
|
||||
(re-frame/reg-event-fx :chat-removed
|
||||
(fn [{:keys [db]} [response chat-id]]
|
||||
{:db (dissoc db :current-chat-id)
|
||||
:fx [[:dispatch [:shell/close-switcher-card chat-id]]
|
||||
[:dispatch [:sanitize-messages-and-process-response response]]
|
||||
[:dispatch [:pop-to-root :shell-stack]]
|
||||
[:activity-center.notifications/fetch-unread-count]]}))
|
||||
(rf/defn handle-chat-removed
|
||||
{:events [:chat-removed]}
|
||||
[cofx response chat-id]
|
||||
(rf/merge cofx
|
||||
{:db (dissoc (:db cofx) :current-chat-id)
|
||||
:dispatch-n [[:shell/close-switcher-card chat-id]
|
||||
[:sanitize-messages-and-process-response response]
|
||||
[:pop-to-root :shell-stack]]}
|
||||
(activity-center/notifications-fetch-unread-count)))
|
||||
|
||||
(rf/defn handle-chat-update
|
||||
{:events [:chat-updated]}
|
||||
@@ -262,7 +264,8 @@
|
||||
{}
|
||||
invitations))})
|
||||
|
||||
(re-frame/reg-fx :group-chats/get-group-chat-invitations
|
||||
(fn []
|
||||
(json-rpc/call {:method "wakuext_getGroupChatInvitations"
|
||||
:on-success [::initialize-invitations]})))
|
||||
(rf/defn get-group-chat-invitations
|
||||
[_]
|
||||
{:json-rpc/call
|
||||
[{:method "wakuext_getGroupChatInvitations"
|
||||
:on-success #(re-frame/dispatch [::initialize-invitations %])}]})
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
[legacy.status-im.node.core :as node]
|
||||
[legacy.status-im.utils.mobile-sync :as mobile-network-utils]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
@@ -62,7 +61,7 @@
|
||||
(dissoc :mailserver/current-request :mailserver/fetching-gaps-in-progress))})
|
||||
|
||||
(defn fetch-use-mailservers?
|
||||
[db]
|
||||
[{:keys [db]}]
|
||||
(get-in db [:profile/profile :use-mailservers?]))
|
||||
|
||||
(defonce showing-connection-error-popup? (atom false))
|
||||
@@ -118,32 +117,24 @@
|
||||
[{:keys [db] :as cofx}]
|
||||
{:db (dissoc db :mailserver/current-request)})
|
||||
|
||||
(defn needs-to-fetch-historic-messages?
|
||||
[db]
|
||||
(and
|
||||
(:messenger/started? db)
|
||||
(mobile-network-utils/syncing-allowed? db)
|
||||
(fetch-use-mailservers? db)
|
||||
(not (:mailserver/current-request db))))
|
||||
|
||||
(rf/defn process-next-messages-request
|
||||
{:events [::request-messages]}
|
||||
[{:keys [db]}]
|
||||
(when (needs-to-fetch-historic-messages? db)
|
||||
{:db (assoc db :mailserver/current-request true)
|
||||
:mailserver/request-all-historic-messages nil}))
|
||||
|
||||
(re-frame/reg-fx :mailserver/request-all-historic-messages
|
||||
(fn []
|
||||
(json-rpc/call {:method "wakuext_requestAllHistoricMessagesWithRetries"
|
||||
:params [false]
|
||||
:js-response true
|
||||
:on-success #(do
|
||||
(log/info "fetched historical messages")
|
||||
(re-frame/dispatch [::request-success %]))
|
||||
:on-error #(do
|
||||
(log/error "failed retrieve historical messages" %)
|
||||
(re-frame/dispatch [::request-error]))})))
|
||||
[{:keys [db now] :as cofx}]
|
||||
(when (and
|
||||
(:messenger/started? db)
|
||||
(mobile-network-utils/syncing-allowed? cofx)
|
||||
(fetch-use-mailservers? cofx)
|
||||
(not (:mailserver/current-request db)))
|
||||
{:db (assoc db :mailserver/current-request true)
|
||||
:json-rpc/call [{:method "wakuext_requestAllHistoricMessagesWithRetries"
|
||||
:params [false]
|
||||
:js-response true
|
||||
:on-success #(do
|
||||
(log/info "fetched historical messages")
|
||||
(re-frame/dispatch [::request-success %]))
|
||||
:on-error #(do
|
||||
(log/error "failed retrieve historical messages" %)
|
||||
(re-frame/dispatch [::request-error]))}]}))
|
||||
|
||||
(rf/defn handle-mailserver-changed
|
||||
[{:keys [db] :as cofx} ms]
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
[legacy.status-im.multiaccounts.model :as multiaccounts.model]
|
||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[legacy.status-im.utils.mobile-sync :as utils]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.contexts.chat.home.add-new-contact.events :as add-new-contact]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -18,24 +18,27 @@
|
||||
(or (nil? remember-choice?)
|
||||
remember-choice?))}))
|
||||
|
||||
(re-frame/reg-event-fx :mobile-network/on-network-status-change
|
||||
(fn [{:keys [db]}]
|
||||
(let [previously-initialized? (get db :network-status/initialized?)
|
||||
logged-in? (multiaccounts.model/logged-in? db)
|
||||
fetch-historic-messages? (mailserver/needs-to-fetch-historic-messages? db)]
|
||||
(if logged-in?
|
||||
{:db (cond-> (-> db
|
||||
(assoc :network-status/initialized? true)
|
||||
(assoc :bottom-sheet/show? false))
|
||||
fetch-historic-messages?
|
||||
(assoc :mailserver/current-request true))
|
||||
:fx [(when fetch-historic-messages?
|
||||
[:mailserver/request-all-historic-messages])
|
||||
[:dismiss-bottom-sheet-overlay-old]
|
||||
(when previously-initialized?
|
||||
(let [new-identity-input (get-in db [:contacts/new-identity :input])]
|
||||
[:dispatch [:contacts/set-new-identity {:input new-identity-input}]]))]}
|
||||
{:db (assoc db :network-status/initialized? true)}))))
|
||||
(rf/defn on-network-status-change
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [initialized? (get db :network-status/initialized?)
|
||||
logged-in? (multiaccounts.model/logged-in? db)
|
||||
{:keys [remember-syncing-choice?]} (:profile/profile db)]
|
||||
(apply
|
||||
rf/merge
|
||||
cofx
|
||||
{:db (assoc db :network-status/initialized? true)}
|
||||
(cond
|
||||
;; NOTE(rasom): When we log into account on-network-status-change is
|
||||
;; dispatched, but that doesn't mean there was a status change, thus
|
||||
;; no reason to restart wallet.
|
||||
(and logged-in? initialized?)
|
||||
[(mailserver/process-next-messages-request)
|
||||
(bottom-sheet/hide-bottom-sheet-old)
|
||||
#(add-new-contact/set-new-identity-reconnected %)]
|
||||
|
||||
logged-in?
|
||||
[(mailserver/process-next-messages-request)
|
||||
(bottom-sheet/hide-bottom-sheet-old)]))))
|
||||
|
||||
(defn apply-settings
|
||||
([sync?] (apply-settings sync? :default))
|
||||
|
||||
@@ -28,8 +28,7 @@
|
||||
[{:keys [db] :as cofx} {:keys [auth-method logout?]}]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
(rf/merge cofx
|
||||
{:set-root :progress
|
||||
:effects.shell/reset-state nil
|
||||
{:effects.shell/reset-state nil
|
||||
:hide-popover nil
|
||||
::logout nil
|
||||
:profile.settings/webview-debug-changed false
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns legacy.status-im.network.net-info
|
||||
(:require
|
||||
["@react-native-community/netinfo" :default net-info]
|
||||
[legacy.status-im.mobile-sync-settings.core :as mobile-network]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[taoensso.timbre :as log]
|
||||
@@ -12,11 +13,11 @@
|
||||
{:db (assoc db :network-status (if is-connected? :online :offline))}))
|
||||
|
||||
(rf/defn change-network-type
|
||||
[{:keys [db] :as cofx} network-type expensive?]
|
||||
[{:keys [db] :as cofx} old-network-type network-type expensive?]
|
||||
(rf/merge cofx
|
||||
{:db (assoc db :network/type network-type)
|
||||
:network/notify-status-go [network-type expensive?]
|
||||
:dispatch [:mobile-network/on-network-status-change]}))
|
||||
:network/notify-status-go [network-type expensive?]}
|
||||
(mobile-network/on-network-status-change)))
|
||||
|
||||
(rf/defn handle-network-info-change
|
||||
{:events [::network-info-changed]}
|
||||
@@ -36,7 +37,7 @@
|
||||
(when-not status-changed?
|
||||
(change-network-status isConnected))
|
||||
(when-not type-changed?
|
||||
(change-network-type type (:is-connection-expensive details))))))
|
||||
(change-network-type old-network-type type (:is-connection-expensive details))))))
|
||||
|
||||
(defn add-net-info-listener
|
||||
[]
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
(:require
|
||||
[legacy.status-im.utils.utils :as utils]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.constants :as constants]
|
||||
[utils.ethereum.chain :as chain]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -23,21 +22,6 @@
|
||||
:params [(chain/chain-id db) id]
|
||||
:on-success #()}]}))
|
||||
|
||||
(re-frame/reg-fx :stickers/load-packs
|
||||
(fn [chain-id]
|
||||
(json-rpc/call {:method "stickers_market"
|
||||
:params [chain-id]
|
||||
:on-success [:stickers/stickers-market-success]})
|
||||
(json-rpc/call {:method "stickers_installed"
|
||||
:params []
|
||||
:on-success [:stickers/stickers-installed-success]})
|
||||
(json-rpc/call {:method "stickers_pending"
|
||||
:params []
|
||||
:on-success [:stickers/stickers-pending-success]})
|
||||
(json-rpc/call {:method "stickers_recent"
|
||||
:params []
|
||||
:on-success [:stickers/stickers-recent-success]})))
|
||||
|
||||
(rf/defn load-packs
|
||||
{:events [:stickers/load-packs]}
|
||||
[{:keys [db]}]
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
(re-frame/reg-sub
|
||||
:mailserver/use-status-nodes?
|
||||
(fn [db _]
|
||||
(boolean (mailserver/fetch-use-mailservers? db))))
|
||||
(boolean (mailserver/fetch-use-mailservers? {:db db}))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:mailserver.edit/validation-errors
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
{:active (= value id)
|
||||
:accessory :radio
|
||||
:title (get titles id)
|
||||
:on-press #(re-frame/dispatch [:profile.settings/profile-update :default-sync-period id])}])
|
||||
:on-press #(re-frame/dispatch [:profile.settings/update-value :default-sync-period id])}])
|
||||
|
||||
(views/defview default-sync-period-settings
|
||||
[]
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
:subtitle (i18n/label :t/webview-camera-permission-requests-subtitle)
|
||||
:subtitle-max-lines 2
|
||||
:on-press #(re-frame/dispatch
|
||||
[:profile.settings/profile-update
|
||||
[:profile.settings/update-value
|
||||
:webview-allow-permission-requests?
|
||||
((complement boolean) webview-allow-permission-requests?)])}])
|
||||
[separator]
|
||||
@@ -169,7 +169,8 @@
|
||||
{:active (= value id)
|
||||
:accessory :radio
|
||||
:title (get titles id)
|
||||
:on-press #(re-frame/dispatch [:profile.settings/profile-update :profile-pictures-visibility id])}])
|
||||
:on-press #(re-frame/dispatch [:profile.settings/update-value :profile-pictures-visibility
|
||||
id])}])
|
||||
|
||||
(views/defview profile-pic
|
||||
[]
|
||||
|
||||
@@ -51,4 +51,4 @@
|
||||
:icon :main-icons/delete
|
||||
:theme :accent
|
||||
:title (i18n/label :t/profile-pic-remove)
|
||||
:on-press #(re-frame/dispatch [:profile.settings/delete-profile-picture])}])]))
|
||||
:on-press #(re-frame/dispatch [:profile.settings/delete-profile-picture nil])}])]))
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.mail :as react-native-mail]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.common.log :as log]
|
||||
[status-im.config :as config]
|
||||
[utils.datetime :as datetime]
|
||||
@@ -32,10 +31,11 @@
|
||||
[{:keys [db]} node-version]
|
||||
{:db (assoc db :web3-node-version node-version)})
|
||||
|
||||
(re-frame/reg-fx :logging/initialize-web3-client-version
|
||||
(fn []
|
||||
(json-rpc/call {:method "web3_clientVersion"
|
||||
:on-success [:logging/store-web3-client-version]})))
|
||||
(rf/defn initialize-web3-client-version
|
||||
{:events [:logging/initialize-web3-client-version]}
|
||||
[_]
|
||||
{:json-rpc/call [{:method "web3_clientVersion"
|
||||
:on-success #(re-frame/dispatch [:logging/store-web3-client-version %])}]})
|
||||
|
||||
(defn extract-url-components
|
||||
[address]
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
(= network-type "cellular"))
|
||||
|
||||
(defn syncing-allowed?
|
||||
[db]
|
||||
[{:keys [db]}]
|
||||
(let [network (:network/type db)
|
||||
{:keys [syncing-on-mobile-network?]} (:profile/profile db)]
|
||||
(or (= network "wifi")
|
||||
|
||||
@@ -2,17 +2,10 @@
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(defn- get-dimensions
|
||||
[size]
|
||||
(case size
|
||||
:size-24 24
|
||||
:size-20 20
|
||||
nil))
|
||||
|
||||
(defn collection-avatar
|
||||
[theme size]
|
||||
{:width (get-dimensions size)
|
||||
:height (get-dimensions size)
|
||||
[theme]
|
||||
{:width 24
|
||||
:height 24
|
||||
:border-width 1
|
||||
:border-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
|
||||
:border-radius 6})
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
|
||||
:image - collection image
|
||||
:theme - keyword -> :light/:dark"
|
||||
[{:keys [image theme size] :or {size :size-24}}]
|
||||
[{:keys [image theme]}]
|
||||
[fast-image/fast-image
|
||||
{:accessibility-label :collection-avatar
|
||||
:source image
|
||||
:style (style/collection-avatar theme size)}])
|
||||
:style (style/collection-avatar theme)}])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns quo.components.colors.color-picker.component-spec
|
||||
(:require
|
||||
[quo.components.colors.color-picker.view :as color-picker]
|
||||
[reagent.core :as reagent]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "color-picker"
|
||||
@@ -11,7 +12,7 @@
|
||||
(-> (h/expect event)
|
||||
(.toHaveBeenCalled))))
|
||||
(h/test "color picker color changed"
|
||||
(let [selected (atom nil)]
|
||||
(let [selected (reagent/atom nil)]
|
||||
(h/render [color-picker/view {:on-change #(reset! selected %)}])
|
||||
(h/fire-event :press (get (h/get-all-by-label-text :color-picker-item) 0))
|
||||
(-> (h/expect @selected)
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
(ns quo.components.community.channel-action.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(defn channel-action-container
|
||||
[{:keys [big? disabled?]}]
|
||||
(cond-> {}
|
||||
disabled? (assoc :opacity 0.3)
|
||||
big? (assoc :flex-grow 1)
|
||||
(not big?) (assoc :width 104)))
|
||||
|
||||
(defn channel-action
|
||||
[{:keys [color pressed? theme]}]
|
||||
{:height 102
|
||||
:padding 12
|
||||
:border-radius 16
|
||||
:background-color (colors/resolve-color color theme (if pressed? 20 10))
|
||||
:justify-content :space-between})
|
||||
|
||||
(def channel-action-row
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center})
|
||||
@@ -1,39 +0,0 @@
|
||||
(ns quo.components.community.channel-action.view
|
||||
(:require
|
||||
[quo.components.community.channel-action.style :as style]
|
||||
[quo.components.counter.counter.view :as counter]
|
||||
[quo.components.icon :as icons]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn view
|
||||
[{:keys [big? customization-color label counter-value icon on-press accessibility-label disabled?]}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[pressed? set-pressed] (rn/use-state false)
|
||||
on-press-in (rn/use-callback #(set-pressed true))
|
||||
on-press-out (rn/use-callback #(set-pressed false))]
|
||||
[rn/view
|
||||
{:style (style/channel-action-container
|
||||
{:big? big?
|
||||
:disabled? disabled?})}
|
||||
[rn/pressable
|
||||
(cond-> {:style (style/channel-action
|
||||
{:big? big?
|
||||
:color customization-color
|
||||
:pressed? pressed?
|
||||
:theme theme
|
||||
:disabled? disabled?})
|
||||
:accessibility-label accessibility-label}
|
||||
(not disabled?) (assoc :on-press on-press
|
||||
:on-press-in on-press-in
|
||||
:on-press-out on-press-out))
|
||||
[rn/view {:style style/channel-action-row}
|
||||
[icons/icon icon]
|
||||
(when counter-value
|
||||
[counter/view {:type :secondary} counter-value])]
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight :medium
|
||||
:number-of-lines 2}
|
||||
label]]]))
|
||||
@@ -0,0 +1,32 @@
|
||||
(ns quo.components.community.channel-actions
|
||||
(:require
|
||||
[quo.components.community.style :as style]
|
||||
[quo.components.counter.counter.view :as counter]
|
||||
[quo.components.icon :as icons]
|
||||
[quo.components.markdown.text :as text]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn channel-action
|
||||
[{:keys [big? color label counter-value icon on-press accessibility-label]}]
|
||||
[rn/touchable-opacity
|
||||
{:on-press on-press
|
||||
:style (style/channel-action-touch big?)
|
||||
:accessibility-label accessibility-label}
|
||||
[rn/view {:style (style/channel-action color)}
|
||||
[rn/view {:style style/channel-action-row}
|
||||
[icons/icon icon]
|
||||
(when counter-value
|
||||
[counter/view {:type :secondary} counter-value])]
|
||||
[text/text {:size :paragraph-1 :weight :medium :number-of-lines 2} label]]])
|
||||
|
||||
(defn channel-actions
|
||||
[{:keys [container-style actions]}]
|
||||
[rn/view {:style (assoc container-style :flex-direction :row)}
|
||||
(map-indexed
|
||||
(fn [index action]
|
||||
^{:key index}
|
||||
[:<>
|
||||
[channel-action action]
|
||||
(when (not= action (last actions))
|
||||
[rn/view {:width 16}])])
|
||||
actions)])
|
||||
@@ -1,16 +0,0 @@
|
||||
(ns quo.components.community.channel-actions.view
|
||||
(:require
|
||||
[quo.components.community.channel-action.view :as channel-action]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn view
|
||||
[{:keys [container-style actions]}]
|
||||
[rn/view {:style (assoc container-style :flex-direction :row)}
|
||||
(map-indexed
|
||||
(fn [index action]
|
||||
^{:key index}
|
||||
[:<>
|
||||
[channel-action/view action]
|
||||
(when (not= action (last actions))
|
||||
[rn/view {:width 16}])])
|
||||
actions)])
|
||||
@@ -133,6 +133,24 @@
|
||||
colors/neutral-80
|
||||
theme)})
|
||||
|
||||
(defn channel-action-touch
|
||||
[big?]
|
||||
{:flex 1
|
||||
:max-width (if big? 216 104)})
|
||||
|
||||
(defn channel-action
|
||||
[color]
|
||||
{:padding 12
|
||||
:height 102
|
||||
:border-radius 16
|
||||
:background-color (colors/custom-color color 50 10)
|
||||
:justify-content :space-between})
|
||||
|
||||
(def channel-action-row
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center})
|
||||
|
||||
(defn loading-card
|
||||
[width theme]
|
||||
(merge
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
[:catn
|
||||
[:props
|
||||
[:map {:closed true}
|
||||
[:container-style {:optional true} [:maybe :map]]
|
||||
[:value {:optional true} [:maybe [:or :string :int]]]
|
||||
[:status {:optional true} [:maybe :keyword]]
|
||||
[:size {:optional true} [:maybe [:enum :size-32 :size-24]]]
|
||||
@@ -20,7 +19,7 @@
|
||||
:any])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [value accessibility-label container-style]
|
||||
[{:keys [value accessibility-label]
|
||||
:as props}]
|
||||
(let [default-props {:status :default
|
||||
:size :size-32}
|
||||
@@ -28,7 +27,7 @@
|
||||
[rn/view
|
||||
{:accessible true
|
||||
:accessibility-label (or accessibility-label :collectible-counter)
|
||||
:style (merge (style/container props) container-style)}
|
||||
:style (style/container props)}
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size (style/get-text-size props)
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
[react-native.reanimated :as reanimated]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(def header-height 56)
|
||||
|
||||
@@ -56,7 +57,7 @@
|
||||
:justify-content :center
|
||||
:align-items :flex-end})
|
||||
|
||||
(defn get-title-style
|
||||
(defn title-style
|
||||
[{:keys [left right]} title-align]
|
||||
(merge
|
||||
absolute-fill
|
||||
@@ -132,77 +133,76 @@
|
||||
:size :large}
|
||||
title])])
|
||||
|
||||
(defn header
|
||||
[{:keys [left-accessories left-component border-bottom left-width right-width
|
||||
right-accessories right-component insets get-layout
|
||||
title subtitle title-component style title-align
|
||||
background]
|
||||
:or {title-align :center
|
||||
border-bottom false}}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[layout set-layout] (rn/use-state {:left {:width (or left-width 8)
|
||||
:height header-height}
|
||||
:right {:width (or right-width 8)
|
||||
:height header-height}
|
||||
:title {:width 0
|
||||
:height header-height}})
|
||||
handle-layout (rn/use-callback
|
||||
(fn [el get-layout]
|
||||
(fn [evt]
|
||||
(let [width (oget evt "nativeEvent" "layout" "width")
|
||||
height (oget evt "nativeEvent" "layout" "height")]
|
||||
(when get-layout
|
||||
(get-layout el
|
||||
{:width width
|
||||
:height height}))
|
||||
(set-layout
|
||||
(assoc layout
|
||||
el
|
||||
{:width width
|
||||
:height height})))))
|
||||
[layout])
|
||||
status-bar-height (get insets :top 0)
|
||||
height (+ header-height status-bar-height)
|
||||
title-style (rn/use-memo (fn [] (get-title-style layout title-align))
|
||||
[layout title-align])]
|
||||
[reanimated/view
|
||||
{:style (header-wrapper-style {:height height
|
||||
:background background
|
||||
:border-bottom border-bottom
|
||||
:theme theme})}
|
||||
[rn/view
|
||||
{:pointer-events :box-none
|
||||
:height status-bar-height}]
|
||||
[rn/view
|
||||
{:style (merge {:height header-height}
|
||||
style)
|
||||
:pointer-events :box-none}
|
||||
[rn/view
|
||||
{:style absolute-fill
|
||||
:pointer-events :box-none}
|
||||
[rn/view
|
||||
{:style content
|
||||
:pointer-events :box-none}
|
||||
[rn/view
|
||||
{:style left-style
|
||||
:on-layout (handle-layout :left get-layout)
|
||||
:pointer-events :box-none}
|
||||
[header-actions
|
||||
{:accessories left-accessories
|
||||
:component left-component}]]
|
||||
[rn/view
|
||||
{:style title-style
|
||||
:on-layout (handle-layout :title get-layout)
|
||||
:pointer-events :box-none}
|
||||
[header-title
|
||||
{:title title
|
||||
:subtitle subtitle
|
||||
:title-align title-align
|
||||
:component title-component}]]
|
||||
[rn/view
|
||||
{:style right-style
|
||||
:on-layout (handle-layout :right get-layout)
|
||||
:pointer-events :box-none}
|
||||
[header-actions
|
||||
{:accessories right-accessories
|
||||
:component right-component}]]]]]]))
|
||||
(defn- header-internal
|
||||
[{:keys [left-width right-width]}]
|
||||
(let [layout (reagent/atom {:left {:width (or left-width 8)
|
||||
:height header-height}
|
||||
:right {:width (or right-width 8)
|
||||
:height header-height}
|
||||
:title {:width 0
|
||||
:height header-height}})
|
||||
handle-layout (fn [el get-layout]
|
||||
(fn [evt]
|
||||
(let [width (oget evt "nativeEvent" "layout" "width")
|
||||
height (oget evt "nativeEvent" "layout" "height")]
|
||||
(when get-layout
|
||||
(get-layout el
|
||||
{:width width
|
||||
:height height}))
|
||||
(swap! layout assoc
|
||||
el
|
||||
{:width width
|
||||
:height height}))))]
|
||||
(fn
|
||||
[{:keys [left-accessories left-component border-bottom
|
||||
right-accessories right-component insets get-layout
|
||||
title subtitle title-component style title-align
|
||||
background theme]
|
||||
:or {title-align :center
|
||||
border-bottom false}}]
|
||||
(let [status-bar-height (get insets :top 0)
|
||||
height (+ header-height status-bar-height)]
|
||||
[reanimated/view
|
||||
{:style (header-wrapper-style {:height height
|
||||
:background background
|
||||
:border-bottom border-bottom
|
||||
:theme theme})}
|
||||
[rn/view
|
||||
{:pointer-events :box-none
|
||||
:height status-bar-height}]
|
||||
[rn/view
|
||||
{:style (merge {:height header-height}
|
||||
style)
|
||||
:pointer-events :box-none}
|
||||
[rn/view
|
||||
{:style absolute-fill
|
||||
:pointer-events :box-none}
|
||||
[rn/view
|
||||
{:style content
|
||||
:pointer-events :box-none}
|
||||
[rn/view
|
||||
{:style left-style
|
||||
:on-layout (handle-layout :left get-layout)
|
||||
:pointer-events :box-none}
|
||||
[header-actions
|
||||
{:accessories left-accessories
|
||||
:component left-component}]]
|
||||
|
||||
[rn/view
|
||||
{:style (title-style @layout title-align)
|
||||
:on-layout (handle-layout :title get-layout)
|
||||
:pointer-events :box-none}
|
||||
[header-title
|
||||
{:title title
|
||||
:subtitle subtitle
|
||||
:title-align title-align
|
||||
:component title-component}]]
|
||||
[rn/view
|
||||
{:style right-style
|
||||
:on-layout (handle-layout :right get-layout)
|
||||
:pointer-events :box-none}
|
||||
[header-actions
|
||||
{:accessories right-accessories
|
||||
:component right-component}]]]]]]))))
|
||||
|
||||
(def header (quo.theme/with-theme header-internal))
|
||||
|
||||
@@ -76,12 +76,12 @@
|
||||
:blur? overflow-label blur?}
|
||||
items preview list items (only 4 items is required for preview)
|
||||
"
|
||||
[{:keys [type size number blur? container-style]} items]
|
||||
[{:keys [type size number blur?]} items]
|
||||
(let [size-key (if (contains? properties/sizes size) size :size-24)
|
||||
number (or number (count items))
|
||||
border-type (properties/border-type type)
|
||||
margin-left (get-in properties/sizes [size-key :margin-left])]
|
||||
[rn/view {:style (assoc container-style :flex-direction :row)}
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
(for [index (range (if (> number 4) 3 number))]
|
||||
^{:key (str index number)}
|
||||
[list-item
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
:align-items :center})
|
||||
|
||||
(defn action-icon
|
||||
[{:keys [type on-press on-check disabled? checked?]} customization-color theme]
|
||||
[{:keys [type on-press on-check disabled? checked?]} theme]
|
||||
[rn/touchable-opacity
|
||||
{:on-press on-press}
|
||||
{:on-press (when on-press on-press)}
|
||||
(case type
|
||||
:options
|
||||
[icons/icon :i/options
|
||||
@@ -30,7 +30,6 @@
|
||||
[selectors/view
|
||||
{:type :checkbox
|
||||
:checked? checked?
|
||||
:customization-color customization-color
|
||||
:accessibility-label :user-list-toggle-check
|
||||
:disabled? disabled?
|
||||
:on-change (when on-check on-check)}]
|
||||
@@ -69,4 +68,4 @@
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}}
|
||||
short-chat-key])]
|
||||
(when accessory
|
||||
[action-icon accessory customization-color theme])]])
|
||||
[action-icon accessory theme])]])
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as theme]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
;;; helpers
|
||||
(def themes
|
||||
@@ -136,25 +137,24 @@
|
||||
style
|
||||
on-press
|
||||
warning-label]}]
|
||||
(let [[body-height set-body-height] (rn/use-state nil)
|
||||
on-layout (rn/use-callback #(set-body-height
|
||||
(oget % "nativeEvent.layout.height")))]
|
||||
[rn/view
|
||||
{:on-layout on-layout
|
||||
:overflow :hidden
|
||||
:flex 1}
|
||||
[hborder {:type :top}]
|
||||
[hborder {:type :bottom}]
|
||||
[rn/view
|
||||
(merge {:width "100%"
|
||||
:background-color (get-color :background)
|
||||
:flex-direction :row
|
||||
:padding 20
|
||||
:padding-left 31
|
||||
:margin-vertical 4}
|
||||
style)
|
||||
(let [body-height (reagent/atom nil)]
|
||||
(fn []
|
||||
[rn/view
|
||||
{:on-layout #(reset! body-height (oget % "nativeEvent.layout.height"))
|
||||
:overflow :hidden
|
||||
:flex 1}
|
||||
[hborder {:type :top}]
|
||||
[hborder {:type :bottom}]
|
||||
[rn/view
|
||||
(merge {:width "100%"
|
||||
:background-color (get-color :background)
|
||||
:flex-direction :row
|
||||
:padding 20
|
||||
:padding-left 31
|
||||
:margin-vertical 4}
|
||||
style)
|
||||
|
||||
[timeline]
|
||||
[body timestamp-far timestamp-near on-info-button-pressed on-press warning-label]]
|
||||
[vborder :left body-height]
|
||||
[vborder :right body-height]]))
|
||||
[timeline]
|
||||
[body timestamp-far timestamp-near on-info-button-pressed on-press warning-label]]
|
||||
[vborder :left body-height]
|
||||
[vborder :right body-height]])))
|
||||
|
||||
@@ -4,48 +4,50 @@
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.numbered-keyboard.keyboard-key.style :as style]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- label->accessibility-label
|
||||
[label]
|
||||
(let [label-name (if (keyword? label) (name label) label)]
|
||||
(keyword (str "keyboard-key-" label-name))))
|
||||
|
||||
(defn view
|
||||
[{:keys [disabled? blur? on-press on-long-press type]} label]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[pressed? set-pressed?] (rn/use-state false)
|
||||
on-press (rn/use-callback #(when on-press (on-press label)) [label])
|
||||
on-long-press (rn/use-callback #(when (fn? on-long-press) (on-long-press label))
|
||||
[label])
|
||||
on-press-in (rn/use-callback #(set-pressed? true))
|
||||
on-press-out (rn/use-callback #(set-pressed? false))
|
||||
label-color (style/get-label-color disabled? theme blur?)
|
||||
background-color (style/toggle-background-color pressed? blur? theme)]
|
||||
[rn/pressable
|
||||
{:accessibility-label (label->accessibility-label label)
|
||||
:disabled (or disabled? (not label))
|
||||
:on-press on-press
|
||||
:on-long-press on-long-press
|
||||
:allow-multiple-presses? true
|
||||
:on-press-in on-press-in
|
||||
:on-press-out on-press-out
|
||||
:hit-slop {:top 8 :bottom 8 :left 25 :right 25}
|
||||
:style (style/container background-color)}
|
||||
(case type
|
||||
:key [icons/icon
|
||||
label
|
||||
{:color label-color
|
||||
:accessibility-label :icon-label}]
|
||||
:digit [text/text
|
||||
{:accessibility-label :text-label
|
||||
:weight :regular
|
||||
:size :heading-1
|
||||
:style {:color label-color}}
|
||||
label]
|
||||
:derivation-path [icons/icon
|
||||
:i/derivation-path
|
||||
{:color label-color
|
||||
:size 32
|
||||
:accessibility-label :derivation-path-label}]
|
||||
nil)]))
|
||||
(defn- view-internal
|
||||
[]
|
||||
(let [pressed? (reagent/atom false)]
|
||||
(fn [{:keys [disabled? theme blur? on-press on-long-press type]} label]
|
||||
(let [label-color (style/get-label-color disabled? theme blur?)
|
||||
background-color (style/toggle-background-color @pressed? blur? theme)]
|
||||
[rn/pressable
|
||||
{:accessibility-label (label->accessibility-label label)
|
||||
:disabled (or disabled? (not label))
|
||||
:on-press (fn []
|
||||
(when on-press
|
||||
(on-press label)))
|
||||
:on-long-press (fn []
|
||||
(when (fn? on-long-press)
|
||||
(on-long-press label)))
|
||||
:allow-multiple-presses? true
|
||||
:on-press-in #(reset! pressed? true)
|
||||
:on-press-out #(reset! pressed? false)
|
||||
:hit-slop {:top 8 :bottom 8 :left 25 :right 25}
|
||||
:style (style/container background-color)}
|
||||
(case type
|
||||
:key [icons/icon
|
||||
label
|
||||
{:color label-color
|
||||
:accessibility-label :icon-label}]
|
||||
:digit [text/text
|
||||
{:accessibility-label :text-label
|
||||
:weight :regular
|
||||
:size :heading-1
|
||||
:style {:color label-color}}
|
||||
label]
|
||||
:derivation-path [icons/icon
|
||||
:i/derivation-path
|
||||
{:color label-color
|
||||
:size 32
|
||||
:accessibility-label :derivation-path-label}]
|
||||
nil)]))))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
(ns quo.components.profile.collectible-list-item.component-spec
|
||||
(:require
|
||||
[quo.components.profile.collectible-list-item.view :as collectible-list-item]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Profile/ collectible list item tests"
|
||||
(h/describe "type card"
|
||||
(h/test "Renders default and on press fires"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider
|
||||
[collectible-list-item/view
|
||||
{:type :card
|
||||
:on-press on-press}])
|
||||
(h/fire-event :press (h/get-by-label-text :collectible-list-item))
|
||||
(h/was-called on-press)))
|
||||
|
||||
(h/test "Renders loading and on press fires"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider
|
||||
[collectible-list-item/view
|
||||
{:type :card
|
||||
:status :loading
|
||||
:on-press on-press}])
|
||||
(h/fire-event :press (h/get-by-label-text :collectible-list-item))
|
||||
(h/was-not-called on-press)
|
||||
(h/is-truthy (h/get-by-label-text :gradient-overlay))))
|
||||
|
||||
(h/test "Renders counter"
|
||||
(h/render-with-theme-provider
|
||||
[collectible-list-item/view
|
||||
{:type :card
|
||||
:counter "x500"}])
|
||||
(h/is-truthy (h/get-by-text "x500")))
|
||||
|
||||
(h/test "Renders counter and collectible name"
|
||||
(h/render-with-theme-provider
|
||||
[collectible-list-item/view
|
||||
{:type :card
|
||||
:collectible-name "Doodle #6822"
|
||||
:counter "x500"}])
|
||||
(h/is-truthy (h/get-by-text "x500"))
|
||||
(h/is-truthy (h/get-by-text "Doodle #6822")))
|
||||
|
||||
(h/test "Renders status cant-fetch"
|
||||
(h/render-with-theme-provider
|
||||
[collectible-list-item/view
|
||||
{:type :card
|
||||
:status :cant-fetch}])
|
||||
(h/is-truthy (h/get-by-translation-text :t/cant-fetch-info)))
|
||||
|
||||
(h/test "Renders status unsupported"
|
||||
(h/render-with-theme-provider
|
||||
[collectible-list-item/view
|
||||
{:type :card
|
||||
:status :unsupported}])
|
||||
(h/is-truthy (h/get-by-translation-text :t/unsupported-file)))
|
||||
|
||||
(h/test "Renders status unsupported and counter"
|
||||
(h/render-with-theme-provider
|
||||
[collectible-list-item/view
|
||||
{:type :card
|
||||
:status :unsupported
|
||||
:counter "x500"}])
|
||||
(h/is-truthy (h/get-by-text "x500"))
|
||||
(h/is-truthy (h/get-by-translation-text :t/unsupported-file))))
|
||||
|
||||
(h/describe "type image"
|
||||
(h/test "Renders default and on press fires"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider
|
||||
[collectible-list-item/view
|
||||
{:type :image
|
||||
:on-press on-press}])
|
||||
(h/fire-event :press (h/get-by-label-text :collectible-list-item))
|
||||
(h/was-called on-press)))
|
||||
|
||||
(h/test "Renders loading and on press fires"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider
|
||||
[collectible-list-item/view
|
||||
{:type :image
|
||||
:status :loading
|
||||
:on-press on-press}])
|
||||
(h/fire-event :press (h/get-by-label-text :collectible-list-item))
|
||||
(h/was-not-called on-press)
|
||||
(h/is-truthy (h/get-by-label-text :gradient-overlay))))
|
||||
|
||||
(h/test "Renders counter"
|
||||
(h/render-with-theme-provider
|
||||
[collectible-list-item/view
|
||||
{:type :image
|
||||
:counter "x500"}])
|
||||
(h/is-truthy (h/get-by-text "x500")))
|
||||
|
||||
(h/test "Renders status cant-fetch"
|
||||
(h/render-with-theme-provider
|
||||
[collectible-list-item/view
|
||||
{:type :image
|
||||
:status :cant-fetch}])
|
||||
(h/is-truthy (h/get-by-translation-text :t/cant-fetch-info)))
|
||||
|
||||
(h/test "Renders status unsupported"
|
||||
(h/render-with-theme-provider
|
||||
[collectible-list-item/view
|
||||
{:type :image
|
||||
:status :unsupported}])
|
||||
(h/is-truthy (h/get-by-translation-text :t/unsupported-file)))
|
||||
|
||||
(h/test "Renders status unsupported and counter"
|
||||
(h/render-with-theme-provider
|
||||
[collectible-list-item/view
|
||||
{:type :image
|
||||
:status :unsupported
|
||||
:counter "x500"}])
|
||||
(h/get-by-text "x500")
|
||||
(h/is-truthy (h/get-by-translation-text :t/unsupported-file)))))
|
||||
@@ -1,90 +0,0 @@
|
||||
(ns quo.components.profile.collectible-list-item.style
|
||||
(:require [quo.foundations.colors :as colors]
|
||||
[quo.foundations.shadows :as shadows]))
|
||||
|
||||
(def container-border-radius 12)
|
||||
(def card-image-padding-vertical 3)
|
||||
(def card-image-padding-horizontal 3)
|
||||
|
||||
(defn fallback
|
||||
[{:keys [theme]}]
|
||||
{:background-color (colors/theme-colors colors/neutral-2_5 colors/neutral-90 theme)
|
||||
:border-style :dashed
|
||||
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
|
||||
:border-width 1
|
||||
:border-radius container-border-radius
|
||||
:width "100%"
|
||||
:aspect-ratio 1
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(def collectible-counter
|
||||
{:position :absolute
|
||||
:top 12
|
||||
:right 12})
|
||||
|
||||
(def avatar
|
||||
{:position :absolute
|
||||
:bottom 12
|
||||
:left 12})
|
||||
|
||||
(def container
|
||||
{:flex 1})
|
||||
|
||||
(defn card-view-container
|
||||
[theme]
|
||||
(merge
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
|
||||
:padding-top card-image-padding-vertical
|
||||
:padding-left card-image-padding-horizontal
|
||||
:padding-right card-image-padding-horizontal
|
||||
:padding-bottom card-image-padding-vertical
|
||||
:border-radius 14
|
||||
:border-width 1
|
||||
:border-color (colors/theme-colors colors/neutral-10 colors/neutral-80 theme)}
|
||||
(shadows/get 2)))
|
||||
|
||||
(def image
|
||||
{:width "100%"
|
||||
:flex 1
|
||||
:border-radius container-border-radius})
|
||||
|
||||
(def card-details-container
|
||||
{:flex-direction :row
|
||||
:height 27
|
||||
:margin-top 3
|
||||
:margin-bottom 2
|
||||
:align-items :center
|
||||
:padding-left 8
|
||||
:padding-right 0
|
||||
:padding-top 4})
|
||||
|
||||
(def card-detail-text
|
||||
{:flex 1})
|
||||
|
||||
(def image-view-container
|
||||
{:aspect-ratio 1
|
||||
:border-radius container-border-radius})
|
||||
|
||||
(defn loading-square
|
||||
[theme]
|
||||
{:height 20
|
||||
:width 20
|
||||
:border-radius 6
|
||||
:align-self :center
|
||||
:background-color (colors/theme-colors colors/neutral-5 colors/neutral-90 theme)})
|
||||
|
||||
(defn loading-message
|
||||
[theme]
|
||||
{:height 14
|
||||
:width 72
|
||||
:margin-left 8
|
||||
:border-radius 6
|
||||
:align-self :center
|
||||
:background-color (colors/theme-colors colors/neutral-5 colors/neutral-90 theme)})
|
||||
|
||||
(defn loading-image
|
||||
[theme]
|
||||
{:flex 1
|
||||
:border-radius container-border-radius
|
||||
:background-color (colors/theme-colors colors/white-70-blur colors/neutral-95-opa-70-blur theme)})
|
||||
@@ -1,195 +0,0 @@
|
||||
(ns quo.components.profile.collectible-list-item.view
|
||||
(:require
|
||||
[quo.components.avatars.collection-avatar.view :as collection-avatar]
|
||||
[quo.components.counter.collectible-counter.view :as collectible-counter]
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.list-items.preview-list.view :as preview-list]
|
||||
[quo.components.markdown.text :as quo]
|
||||
[quo.components.profile.collectible-list-item.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.gradients :as gradients]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[schema.core :as schema]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn- fallback-view
|
||||
[{:keys [label theme type]}]
|
||||
[rn/view
|
||||
{:style (style/fallback {:type type
|
||||
:theme theme})}
|
||||
[rn/view
|
||||
[icon/icon :i/sad {:color (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)}]]
|
||||
[rn/view {:style {:height 4}}]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style {:color (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)}}
|
||||
label]])
|
||||
|
||||
(defn- loading-square
|
||||
[theme]
|
||||
[rn/view {:style (style/loading-square theme)}])
|
||||
|
||||
(defn- loading-message
|
||||
[theme]
|
||||
[rn/view {:style (style/loading-message theme)}])
|
||||
|
||||
(defn- loading-image
|
||||
[{:keys [theme gradient-color-index]}]
|
||||
[gradients/view
|
||||
{:theme theme
|
||||
:container-style (style/loading-image theme)
|
||||
:color-index gradient-color-index}])
|
||||
|
||||
(defn- card-details
|
||||
[{:keys [status community? avatar-image-src collectible-name theme]}]
|
||||
[rn/view {:style style/card-details-container}
|
||||
|
||||
(cond (= :cant-fetch status)
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
:weight :medium
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||
(i18n/label :t/unknown)]
|
||||
|
||||
(= :loading status)
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
[loading-square theme]
|
||||
[loading-message theme]]
|
||||
|
||||
community?
|
||||
[:<>
|
||||
[preview-list/view
|
||||
{:type :communities
|
||||
:size :size-20}
|
||||
[avatar-image-src]]
|
||||
[rn/view {:style {:width 8}}]
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:style style/card-detail-text}
|
||||
collectible-name]]
|
||||
|
||||
:else
|
||||
[:<>
|
||||
[collection-avatar/view
|
||||
{:size :size-20
|
||||
:image avatar-image-src}]
|
||||
[rn/view {:style {:width 8}}]
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:ellipsize-mode :tail
|
||||
:number-of-lines 1
|
||||
:style style/card-detail-text}
|
||||
collectible-name]])])
|
||||
|
||||
(defn- card-view
|
||||
[{:keys [avatar-image-src collectible-name community? counter
|
||||
gradient-color-index image-src status type]}]
|
||||
(let [theme (quo.theme/use-theme-value)]
|
||||
[rn/view {:style (style/card-view-container theme)}
|
||||
[rn/view {:style {:aspect-ratio 1}}
|
||||
(cond
|
||||
(= :loading status)
|
||||
[loading-image
|
||||
{:theme theme
|
||||
:gradient-color-index gradient-color-index}]
|
||||
|
||||
(= status :unsupported)
|
||||
[fallback-view
|
||||
{:theme theme
|
||||
:type type
|
||||
:label (i18n/label :t/unsupported-file)}]
|
||||
|
||||
(= status :cant-fetch)
|
||||
[fallback-view
|
||||
{:theme theme
|
||||
:type type
|
||||
:label (i18n/label :t/cant-fetch-info)}]
|
||||
|
||||
:else
|
||||
[rn/view {:style {:aspect-ratio 1}}
|
||||
[rn/image
|
||||
{:style style/image
|
||||
:source image-src}]])]
|
||||
(when (and (not= status :loading) (not= status :cant-fetch) counter)
|
||||
[collectible-counter/view
|
||||
{:container-style style/collectible-counter
|
||||
:size :size-24
|
||||
:value counter}])
|
||||
[card-details
|
||||
{:status status
|
||||
:community? community?
|
||||
:avatar-image-src avatar-image-src
|
||||
:collectible-name collectible-name
|
||||
:theme theme}]]))
|
||||
|
||||
(defn- image-view
|
||||
[{:keys [avatar-image-src community? counter
|
||||
gradient-color-index image-src status]}]
|
||||
(let [theme (quo.theme/use-theme-value)]
|
||||
[rn/view {:style style/image-view-container}
|
||||
(cond
|
||||
(= :loading status)
|
||||
[loading-image
|
||||
{:theme theme
|
||||
:gradient-color-index gradient-color-index}]
|
||||
|
||||
(= status :unsupported)
|
||||
[fallback-view
|
||||
{:theme theme
|
||||
:type type
|
||||
:label (i18n/label :t/unsupported-file)}]
|
||||
|
||||
(= status :cant-fetch)
|
||||
[fallback-view
|
||||
{:theme theme
|
||||
:type type
|
||||
:label (i18n/label :t/cant-fetch-info)}]
|
||||
|
||||
:else [rn/view {:style {:aspect-ratio 1}}
|
||||
[rn/image
|
||||
{:style style/image
|
||||
:source image-src}]])
|
||||
(when (and (not= status :loading) (not= status :cant-fetch) counter)
|
||||
[collectible-counter/view
|
||||
{:container-style style/collectible-counter
|
||||
:size :size-24
|
||||
:value counter}])
|
||||
(when (and (not= status :loading) (not= status :cant-fetch) community?)
|
||||
[preview-list/view
|
||||
{:container-style style/avatar
|
||||
:type :communities
|
||||
:size :size-24}
|
||||
[avatar-image-src]])]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [container-style type on-press status]
|
||||
:as props}]
|
||||
[rn/pressable
|
||||
{:on-press (when-not (= status :loading) on-press)
|
||||
:accessibility-label :collectible-list-item
|
||||
:style (merge container-style style/container)}
|
||||
(if (= type :card)
|
||||
[card-view props]
|
||||
[image-view props])])
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:catn
|
||||
[:props
|
||||
[:map {:closed true}
|
||||
[:avatar-image-src {:optional true} [:maybe :schema.common/image-source]]
|
||||
[:collectible-name {:optional true} [:maybe string?]]
|
||||
[:community? {:optional true} [:maybe boolean?]]
|
||||
[:counter {:optional true} [:maybe string?]]
|
||||
[:gradient-color-index {:optional true}
|
||||
[:maybe [:enum :gradient-1 :gradient-2 :gradient-3 :gradient-4 :gradient-5]]]
|
||||
[:image-src {:optional true} [:maybe :schema.common/image-source]]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:status {:optional true} [:maybe [:enum :default :loading :cant-fetch :unsupported]]]
|
||||
[:type [:enum :card :image]]]]]
|
||||
:any])
|
||||
|
||||
(def view (schema/instrument #'view-internal ?schema))
|
||||
@@ -3,33 +3,48 @@
|
||||
[quo.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.profile.select-profile.style :as style]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- on-change-handler
|
||||
[selected? on-change]
|
||||
(swap! selected? not)
|
||||
(when on-change (on-change @selected?)))
|
||||
|
||||
(defn view
|
||||
"Options
|
||||
- `default-selected?` The default selected state. Use when the component is not controlled.
|
||||
- `selected?` Selected state. Use when the component is controlled.
|
||||
- `name` Full name
|
||||
- `profile-picture` Profile picture
|
||||
- `customization-color` Customization color
|
||||
- `(on-change selected?)` On change event handler
|
||||
"
|
||||
[{:keys [selected? profile-picture name customization-color on-change]
|
||||
:or {customization-color :turquoise}}]
|
||||
[rn/touchable-opacity
|
||||
{:style (style/container customization-color selected?)
|
||||
:on-press #(when on-change (on-change (not selected?)))
|
||||
:accessibility-label :select-profile}
|
||||
[rn/view {:style style/header}
|
||||
[user-avatar/user-avatar
|
||||
{:full-name name
|
||||
:status-indicator? false
|
||||
:size :medium
|
||||
:profile-picture profile-picture}]
|
||||
[rn/view {:style (style/select-radio selected?)}
|
||||
(when selected?
|
||||
[rn/view {:style style/select-radio-inner}])]]
|
||||
[text/text
|
||||
{:size :heading-2
|
||||
:weight :semi-bold
|
||||
:style style/profile-name}
|
||||
name]])
|
||||
[{:keys [default-selected?]}]
|
||||
(let [internal-selected? (reagent/atom (or default-selected? false))]
|
||||
(fn [{:keys [selected?
|
||||
profile-picture
|
||||
name
|
||||
customization-color
|
||||
on-change]
|
||||
:or {customization-color :turquoise}}]
|
||||
(when (and (not (nil? selected?)) (not= @internal-selected? selected?))
|
||||
(reset! internal-selected? selected?))
|
||||
[rn/touchable-opacity
|
||||
{:style (style/container customization-color @internal-selected?)
|
||||
:on-press #(on-change-handler internal-selected? on-change)
|
||||
:active-opacity 1
|
||||
:accessibility-label :select-profile}
|
||||
[rn/view {:style style/header}
|
||||
[user-avatar/user-avatar
|
||||
{:full-name name
|
||||
:status-indicator? false
|
||||
:size :medium
|
||||
:profile-picture profile-picture}]
|
||||
[rn/view {:style (style/select-radio @internal-selected?)}
|
||||
(when @internal-selected? [rn/view {:style style/select-radio-inner}])]]
|
||||
[text/text
|
||||
{:size :heading-2
|
||||
:weight :semi-bold
|
||||
:style style/profile-name}
|
||||
name]])))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns quo.components.profile.showcase-nav.component-spec
|
||||
(:require
|
||||
[quo.components.profile.showcase-nav.view :as view]
|
||||
[reagent.core :as reagent]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(def nav-data
|
||||
@@ -34,7 +35,7 @@
|
||||
(.toHaveBeenCalled))))
|
||||
|
||||
(h/test "active id updated"
|
||||
(let [active-id (atom :recent)]
|
||||
(let [active-id (reagent/atom :recent)]
|
||||
(h/render [view/view
|
||||
{:data nav-data
|
||||
:on-press #(reset! active-id %)}])
|
||||
|
||||
@@ -7,23 +7,17 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.draggable-flatlist :as draggable-flatlist]))
|
||||
[react-native.draggable-flatlist :as draggable-flatlist]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn key-fn [item index] (str (:title item) index))
|
||||
(defn on-drag-end-fn
|
||||
[data atom-data]
|
||||
(reset! atom-data data)
|
||||
(reagent/flush))
|
||||
|
||||
(defn reorder-category
|
||||
[{:keys [label data blur? container-style]}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[atom-data set-atom-data] (rn/use-state data)
|
||||
render-fn (rn/use-callback
|
||||
(fn [item _ _ _ _ drag]
|
||||
[reorder-item/reorder-item item types/item
|
||||
{:blur? blur? :drag drag}])
|
||||
[blur?])
|
||||
on-drag-end-fn (rn/use-callback (fn [_ _ data] (set-atom-data data)))
|
||||
separator (rn/use-memo (fn [] [rn/view
|
||||
{:style (style/reorder-separator blur? theme)}])
|
||||
[blur? theme])]
|
||||
(defn- reorder-category-internal
|
||||
[{:keys [label data blur? theme container-style]}]
|
||||
(reagent/with-let [atom-data (reagent/atom data)]
|
||||
[rn/view {:style (merge (style/container label) container-style)}
|
||||
[text/text
|
||||
{:weight :medium
|
||||
@@ -31,9 +25,14 @@
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||
label]
|
||||
[draggable-flatlist/draggable-flatlist
|
||||
{:data atom-data
|
||||
:key-fn key-fn
|
||||
{:data @atom-data
|
||||
:key-fn (fn [item index] (str (:title item) index))
|
||||
:style style/reorder-items
|
||||
:render-fn render-fn
|
||||
:on-drag-end-fn on-drag-end-fn
|
||||
:separator separator}]]))
|
||||
:render-fn (fn [item _ _ _ _ drag] [reorder-item/reorder-item item types/item
|
||||
{:blur? blur? :drag drag}])
|
||||
:on-drag-end-fn (fn [_ _ data]
|
||||
(on-drag-end-fn data atom-data))
|
||||
:separator [rn/view
|
||||
{:style (style/reorder-separator blur? theme)}]}]]))
|
||||
|
||||
(def reorder-category (quo.theme/with-theme reorder-category-internal))
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[schema.core :as schema]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
@@ -189,20 +190,20 @@
|
||||
|
||||
(defn- view-internal
|
||||
[props]
|
||||
(let [[component-width
|
||||
set-component-width] (rn/use-state nil)
|
||||
on-layout (rn/use-callback #(set-component-width
|
||||
(oops/oget % "nativeEvent.layout.width")))
|
||||
props (-> props
|
||||
(assoc :component-width component-width)
|
||||
(clojure.set/rename-keys {:type :share-qr-type}))]
|
||||
(reagent/with-let [component-width (reagent/atom nil)
|
||||
container-component [rn/view {:background-color style/overlay-color}]]
|
||||
[quo.theme/provider {:theme :dark}
|
||||
[rn/view
|
||||
{:accessibility-label :share-qr-code
|
||||
:style style/outer-container
|
||||
:on-layout on-layout}
|
||||
[rn/view {:style {:background-color style/overlay-color}}
|
||||
(when component-width
|
||||
[share-qr-code props])]]]))
|
||||
:on-layout #(reset! component-width (oops/oget % "nativeEvent.layout.width"))}
|
||||
(conj container-component
|
||||
(when @component-width
|
||||
[share-qr-code
|
||||
(-> props
|
||||
(assoc :component-width @component-width)
|
||||
(clojure.set/rename-keys {:type :share-qr-type}))]))]]))
|
||||
|
||||
(def view (schema/instrument #'view-internal component-schema/?schema))
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'view-internal component-schema/?schema)))
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
[quo.components.tabs.tab.view :as tab]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(def themes-for-blur
|
||||
{:light {:background-color colors/neutral-80-opa-5}
|
||||
@@ -13,41 +14,41 @@
|
||||
{:light {:background-color colors/neutral-10}
|
||||
:dark {:background-color colors/neutral-90}})
|
||||
|
||||
(defn segmented-control
|
||||
[{:keys [data size blur? container-style item-container-style
|
||||
active-item-container-style default-active on-change]}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[active-tab-id
|
||||
set-active-tab-id] (rn/use-state default-active)
|
||||
on-press (rn/use-callback
|
||||
(fn [tab-id]
|
||||
(set-active-tab-id tab-id)
|
||||
(when on-change (on-change tab-id)))
|
||||
[on-change])]
|
||||
[rn/view
|
||||
(merge
|
||||
{:flex-direction :row
|
||||
:background-color (get-in (if blur? themes-for-blur themes)
|
||||
[theme :background-color])
|
||||
:border-radius (case size
|
||||
32 10
|
||||
28 10
|
||||
24 8
|
||||
20 6)
|
||||
:padding 2}
|
||||
container-style)
|
||||
(for [[indx {:keys [label id]}] (map-indexed vector data)]
|
||||
^{:key id}
|
||||
[rn/view
|
||||
{:margin-left (if (= 0 indx) 0 2)
|
||||
:flex 1}
|
||||
[tab/view
|
||||
{:id id
|
||||
:active-item-container-style active-item-container-style
|
||||
:item-container-style item-container-style
|
||||
:segmented? true
|
||||
:size size
|
||||
:blur? blur?
|
||||
:active (= id active-tab-id)
|
||||
:on-press on-press}
|
||||
label]])]))
|
||||
(defn- segmented-control-internal
|
||||
[{:keys [default-active on-change]}]
|
||||
(let [active-tab-id (reagent/atom default-active)]
|
||||
(fn [{:keys [data size theme blur? container-style item-container-style
|
||||
active-item-container-style]}]
|
||||
(let [active-id @active-tab-id]
|
||||
[rn/view
|
||||
(merge
|
||||
{:flex-direction :row
|
||||
:background-color (get-in (if blur? themes-for-blur themes)
|
||||
[theme :background-color])
|
||||
:border-radius (case size
|
||||
32 10
|
||||
28 10
|
||||
24 8
|
||||
20 6)
|
||||
:padding 2}
|
||||
container-style)
|
||||
(for [[indx {:keys [label id]}] (map-indexed vector data)]
|
||||
^{:key id}
|
||||
[rn/view
|
||||
{:margin-left (if (= 0 indx) 0 2)
|
||||
:flex 1}
|
||||
[tab/view
|
||||
{:id id
|
||||
:active-item-container-style active-item-container-style
|
||||
:item-container-style item-container-style
|
||||
:segmented? true
|
||||
:size size
|
||||
:blur? blur?
|
||||
:active (= id active-id)
|
||||
:on-press (fn [tab-id]
|
||||
(reset! active-tab-id tab-id)
|
||||
(when on-change
|
||||
(on-change tab-id)))}
|
||||
label]])]))))
|
||||
|
||||
(def segmented-control (quo.theme/with-theme segmented-control-internal))
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
(into [:<>] children)))
|
||||
|
||||
(defn- on-scroll-handler
|
||||
[{:keys [on-scroll fading set-fading fade-end-percentage fade-end?]} ^js e]
|
||||
[{:keys [on-scroll fading fade-end-percentage fade-end?]} ^js e]
|
||||
(when fade-end?
|
||||
(let [offset-x (oget e "nativeEvent.contentOffset.x")
|
||||
content-width (oget e "nativeEvent.contentSize.width")
|
||||
@@ -52,8 +52,11 @@
|
||||
:layout-width layout-width
|
||||
:max-fade-percentage fade-end-percentage})]
|
||||
;; Avoid unnecessary re-rendering.
|
||||
(when (not= new-percentage (get fading :fade-end-percentage))
|
||||
(set-fading (assoc fading :fade-end-percentage new-percentage)))))
|
||||
(when (not= new-percentage
|
||||
(get @fading :fade-end-percentage))
|
||||
(swap! fading assoc
|
||||
:fade-end-percentage
|
||||
new-percentage))))
|
||||
(when on-scroll
|
||||
(on-scroll e)))
|
||||
|
||||
@@ -61,7 +64,6 @@
|
||||
[{:keys [id label notification-dot? accessibility-label]}
|
||||
index _
|
||||
{:keys [active-tab-id
|
||||
set-active-tab-id
|
||||
blur?
|
||||
customization-color
|
||||
flat-list-ref
|
||||
@@ -83,9 +85,9 @@
|
||||
:accessibility-label accessibility-label
|
||||
:size size
|
||||
:blur? blur?
|
||||
:active (= id active-tab-id)
|
||||
:active (= id @active-tab-id)
|
||||
:on-press (fn [id]
|
||||
(set-active-tab-id id)
|
||||
(reset! active-tab-id id)
|
||||
(when (and scroll-on-press? @flat-list-ref)
|
||||
(.scrollToIndex ^js @flat-list-ref
|
||||
#js
|
||||
@@ -116,81 +118,87 @@
|
||||
- `scroll-on-press?` When non-nil, clicking on a tag centers it the middle
|
||||
(with animation enabled).
|
||||
"
|
||||
[{:keys [default-active data fade-end-percentage fade-end? on-change on-scroll scroll-on-press?
|
||||
scrollable? style container-style size blur? in-scroll-view? customization-color]
|
||||
:or {fade-end-percentage 0.8
|
||||
fade-end? false
|
||||
scrollable? false
|
||||
scroll-on-press? false
|
||||
size default-tab-size}
|
||||
:as props}]
|
||||
(let [[active-tab-id
|
||||
set-active-tab-id] (rn/use-state default-active)
|
||||
[fading set-fading] (rn/use-state {:fade-end-percentage fade-end-percentage})
|
||||
flat-list-ref (rn/use-ref-atom nil)
|
||||
clean-props (dissoc props
|
||||
:default-active
|
||||
:fade-end-percentage
|
||||
:fade-end?
|
||||
:on-change
|
||||
:scroll-on-press?
|
||||
:size)
|
||||
on-scroll (rn/use-callback
|
||||
(partial on-scroll-handler
|
||||
{:fade-end-percentage fade-end-percentage
|
||||
:fade-end? fade-end?
|
||||
:fading fading
|
||||
:set-fading set-fading
|
||||
:on-scroll on-scroll})
|
||||
[fade-end? fading])]
|
||||
(if scrollable?
|
||||
[rn/view {:style {:margin-top (- (dec unread-count-offset))}}
|
||||
[masked-view-wrapper
|
||||
{:fade-end-percentage (get fading :fade-end-percentage) :fade-end? fade-end?}
|
||||
[(if in-scroll-view?
|
||||
gesture/flat-list
|
||||
rn/flat-list)
|
||||
(merge
|
||||
clean-props
|
||||
(when scroll-on-press?
|
||||
{:initial-scroll-index (utils.collection/first-index #(= active-tab-id (:id %)) data)})
|
||||
{:ref #(reset! flat-list-ref %)
|
||||
:style style
|
||||
;; The padding-top workaround is needed because on Android
|
||||
;; {:overflow :visible} doesn't work on components inheriting
|
||||
;; from ScrollView (e.g. FlatList). There are open issues, here's
|
||||
;; just one about this topic:
|
||||
;; https://github.com/facebook/react-native/issues/31218
|
||||
:content-container-style
|
||||
(assoc container-style :padding-top (dec unread-count-offset))
|
||||
:horizontal true
|
||||
:scroll-event-throttle 64
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:data data
|
||||
:key-fn (comp str :id)
|
||||
:on-scroll-to-index-failed identity
|
||||
:on-scroll on-scroll
|
||||
:render-fn tab-view
|
||||
:render-data {:active-tab-id active-tab-id
|
||||
:set-active-tab-id set-active-tab-id
|
||||
:blur? blur?
|
||||
:customization-color customization-color
|
||||
:flat-list-ref flat-list-ref
|
||||
:number-of-items (count data)
|
||||
:on-change on-change
|
||||
:scroll-on-press? scroll-on-press?
|
||||
:size size
|
||||
:style style}})]]]
|
||||
[rn/view (merge style {:flex-direction :row})
|
||||
(map-indexed (fn [index item]
|
||||
^{:key (:id item)}
|
||||
[tab-view item index nil
|
||||
{:active-tab-id active-tab-id
|
||||
:set-active-tab-id set-active-tab-id
|
||||
:blur? blur?
|
||||
:customization-color customization-color
|
||||
:number-of-items (count data)
|
||||
:on-change on-change
|
||||
:size size
|
||||
:style style}])
|
||||
data)])))
|
||||
[{:keys [default-active fade-end-percentage]
|
||||
:or {fade-end-percentage 0.8}}]
|
||||
(let [active-tab-id (reagent/atom default-active)
|
||||
fading (reagent/atom {:fade-end-percentage fade-end-percentage})
|
||||
flat-list-ref (atom nil)]
|
||||
(fn
|
||||
[{:keys [data
|
||||
fade-end-percentage
|
||||
fade-end?
|
||||
on-change
|
||||
on-scroll
|
||||
scroll-on-press?
|
||||
scrollable?
|
||||
style
|
||||
container-style
|
||||
size
|
||||
blur?
|
||||
in-scroll-view?
|
||||
customization-color]
|
||||
:or {fade-end-percentage fade-end-percentage
|
||||
fade-end? false
|
||||
scrollable? false
|
||||
scroll-on-press? false
|
||||
size default-tab-size}
|
||||
:as props}]
|
||||
(if scrollable?
|
||||
[rn/view {:style {:margin-top (- (dec unread-count-offset))}}
|
||||
[masked-view-wrapper
|
||||
{:fade-end-percentage (get @fading :fade-end-percentage) :fade-end? fade-end?}
|
||||
[(if in-scroll-view?
|
||||
gesture/flat-list
|
||||
rn/flat-list)
|
||||
(merge
|
||||
(dissoc props
|
||||
:default-active
|
||||
:fade-end-percentage
|
||||
:fade-end?
|
||||
:on-change
|
||||
:scroll-on-press?
|
||||
:size)
|
||||
(when scroll-on-press?
|
||||
{:initial-scroll-index (utils.collection/first-index #(= @active-tab-id (:id %)) data)})
|
||||
{:ref #(reset! flat-list-ref %)
|
||||
:style style
|
||||
;; The padding-top workaround is needed because on Android
|
||||
;; {:overflow :visible} doesn't work on components inheriting
|
||||
;; from ScrollView (e.g. FlatList). There are open issues, here's
|
||||
;; just one about this topic:
|
||||
;; https://github.com/facebook/react-native/issues/31218
|
||||
:content-container-style
|
||||
(assoc container-style :padding-top (dec unread-count-offset))
|
||||
:horizontal true
|
||||
:scroll-event-throttle 64
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:data data
|
||||
:key-fn (comp str :id)
|
||||
:on-scroll-to-index-failed identity
|
||||
:on-scroll (partial on-scroll-handler
|
||||
{:fade-end-percentage fade-end-percentage
|
||||
:fade-end? fade-end?
|
||||
:fading fading
|
||||
:on-scroll on-scroll})
|
||||
:render-fn tab-view
|
||||
:render-data {:active-tab-id active-tab-id
|
||||
:blur? blur?
|
||||
:customization-color customization-color
|
||||
:flat-list-ref flat-list-ref
|
||||
:number-of-items (count data)
|
||||
:on-change on-change
|
||||
:scroll-on-press? scroll-on-press?
|
||||
:size size
|
||||
:style style}})]]]
|
||||
[rn/view (merge style {:flex-direction :row})
|
||||
(map-indexed (fn [index item]
|
||||
^{:key (:id item)}
|
||||
[tab-view item index nil
|
||||
{:active-tab-id active-tab-id
|
||||
:blur? blur?
|
||||
:customization-color customization-color
|
||||
:number-of-items (count data)
|
||||
:on-change on-change
|
||||
:size size
|
||||
:style style}])
|
||||
data)]))))
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
[:size {:optional true} [:maybe [:enum :size-24 :size-32]]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:theme :schema.common/theme]
|
||||
[:collectible-img-src [:maybe :schema.common/image-source :string]]
|
||||
[:collectible-img-src :schema.common/image-source]
|
||||
[:collectible-name :string]
|
||||
[:collectible-id {:optional true} [:maybe :string]]]]]
|
||||
[:collectible-id :string]]]]
|
||||
:any])
|
||||
|
||||
+3
-7
@@ -29,8 +29,7 @@
|
||||
quo.components.common.notification-dot.view
|
||||
quo.components.common.separator.view
|
||||
quo.components.community.banner.view
|
||||
quo.components.community.channel-action.view
|
||||
quo.components.community.channel-actions.view
|
||||
quo.components.community.channel-actions
|
||||
quo.components.community.community-card-view
|
||||
quo.components.community.community-list-view
|
||||
quo.components.community.community-stat.view
|
||||
@@ -56,7 +55,7 @@
|
||||
quo.components.dropdowns.network-dropdown.view
|
||||
quo.components.empty-state.empty-state.view
|
||||
quo.components.gradient.gradient-cover.view
|
||||
quo.components.graph.interactive-graph.view
|
||||
[quo.components.graph.interactive-graph.view :as interactive-graph]
|
||||
quo.components.graph.wallet-graph.view
|
||||
quo.components.header
|
||||
quo.components.icon
|
||||
@@ -110,7 +109,6 @@
|
||||
quo.components.onboarding.small-option-card.view
|
||||
quo.components.overlay.view
|
||||
quo.components.password.tips.view
|
||||
quo.components.profile.collectible-list-item.view
|
||||
quo.components.profile.collectible.view
|
||||
quo.components.profile.link-card.view
|
||||
quo.components.profile.profile-card.view
|
||||
@@ -231,8 +229,7 @@
|
||||
(def discover-card quo.components.community.banner.view/view)
|
||||
(def community-icon quo.components.community.icon/community-icon)
|
||||
(def token-requirement-list quo.components.community.token-gating/token-requirement-list)
|
||||
(def channel-action quo.components.community.channel-action.view/view)
|
||||
(def channel-actions quo.components.community.channel-actions.view/view)
|
||||
(def channel-actions quo.components.community.channel-actions/channel-actions)
|
||||
|
||||
;;;; Counter
|
||||
(def collectible-counter quo.components.counter.collectible-counter.view/view)
|
||||
@@ -353,7 +350,6 @@
|
||||
|
||||
;;;; Profile
|
||||
(def collectible quo.components.profile.collectible.view/collectible)
|
||||
(def collectible-list-item quo.components.profile.collectible-list-item.view/view)
|
||||
(def link-card quo.components.profile.link-card.view/view)
|
||||
(def profile-card quo.components.profile.profile-card.view/profile-card)
|
||||
(def select-profile quo.components.profile.select-profile.view/view)
|
||||
|
||||
@@ -63,7 +63,6 @@
|
||||
quo.components.numbered-keyboard.keyboard-key.component-spec
|
||||
quo.components.onboarding.small-option-card.component-spec
|
||||
quo.components.password.tips.component-spec
|
||||
quo.components.profile.collectible-list-item.component-spec
|
||||
quo.components.profile.link-card.component-spec
|
||||
quo.components.profile.select-profile.component-spec
|
||||
quo.components.profile.showcase-nav.component-spec
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
(ns quo.foundations.gradients
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.linear-gradient :as linear-gradient]))
|
||||
|
||||
(defn- gradient-colors
|
||||
[index theme]
|
||||
(case index
|
||||
:gradient-1 [(colors/resolve-color :yellow theme)
|
||||
(colors/resolve-color :sky theme)
|
||||
(colors/resolve-color :purple theme)]
|
||||
:gradient-2 [(colors/resolve-color :orange theme)
|
||||
(colors/resolve-color :purple theme)
|
||||
(colors/resolve-color :blue theme)]
|
||||
:gradient-3 [(colors/resolve-color :blue theme)
|
||||
(colors/resolve-color :magenta theme)
|
||||
(colors/resolve-color :yellow theme)]
|
||||
:gradient-4 [(colors/resolve-color :army theme)
|
||||
(colors/resolve-color :orange theme)
|
||||
(colors/resolve-color :blue theme)]
|
||||
[(colors/resolve-color :purple theme)
|
||||
(colors/resolve-color :army theme)
|
||||
(colors/resolve-color :yellow theme)]))
|
||||
|
||||
(defn view
|
||||
[{:keys [color-index container-style] :or {color-index 1}}]
|
||||
(let [theme (quo.theme/use-theme-value)]
|
||||
[linear-gradient/linear-gradient
|
||||
{:style (merge {:border-radius 16} container-style)
|
||||
:accessibility-label :gradient-overlay
|
||||
:colors (gradient-colors color-index theme)
|
||||
:start {:x 0 :y 0}
|
||||
:end {:x 0 :y 1}}]))
|
||||
@@ -95,34 +95,13 @@
|
||||
(into [{:title title :header? true}] data))
|
||||
sections))
|
||||
|
||||
(defn- find-sticky-indices
|
||||
[data]
|
||||
(->> data
|
||||
(map-indexed (fn [index item] (when (:header? item) index)))
|
||||
(remove nil?)
|
||||
(vec)))
|
||||
|
||||
(defn- is-last-item-in-section
|
||||
[data index]
|
||||
(let [next-item (nth data (inc index) nil)]
|
||||
(or (nil? next-item) (:header? next-item))))
|
||||
|
||||
(defn section-list
|
||||
[{:keys [sections sticky-section-headers-enabled render-section-header-fn render-section-footer-fn
|
||||
render-fn]
|
||||
:or {sticky-section-headers-enabled true}
|
||||
:as props}]
|
||||
[{:keys [sections render-section-header-fn render-fn] :as props}]
|
||||
(let [data (flatten-sections sections)]
|
||||
[flat-list
|
||||
(merge props
|
||||
{:data data
|
||||
:render-fn (fn [p1 p2 p3 p4]
|
||||
[:<>
|
||||
(if (:header? p1)
|
||||
[render-section-header-fn p1 p2 p3 p4]
|
||||
[render-fn p1 p2 p3 p4])
|
||||
(when (and render-section-footer-fn
|
||||
(is-last-item-in-section data p2))
|
||||
[render-section-footer-fn p1 p2 p3 p4])])
|
||||
:sticky-header-indices (when sticky-section-headers-enabled
|
||||
(find-sticky-indices data))})]))
|
||||
{:data data
|
||||
:render-fn (fn [p1 p2 p3 p4]
|
||||
(if (:header? p1)
|
||||
[render-section-header-fn p1 p2 p3 p4]
|
||||
[render-fn p1 p2 p3 p4]))})]))
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
(ns status-im.common.contact-list.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def contacts-section-footer
|
||||
{:height 8})
|
||||
(ns status-im.common.contact-list.style)
|
||||
|
||||
(defn contacts-section-header
|
||||
[theme]
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-95 theme)})
|
||||
[first-item?]
|
||||
{:padding-top (if first-item? 0 8)})
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
(ns status-im.common.contact-list.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.contact-list.style :as style]))
|
||||
|
||||
(defn contacts-section-footer
|
||||
[]
|
||||
[rn/view style/contacts-section-footer])
|
||||
|
||||
(defn contacts-section-header
|
||||
[{:keys [title]}]
|
||||
(let [theme (quo.theme/use-theme-value)]
|
||||
[rn/view (style/contacts-section-header theme)
|
||||
[quo/divider-label title]]))
|
||||
[{:keys [title index]}]
|
||||
[rn/view (style/contacts-section-header (= index 0))
|
||||
[quo/divider-label title]])
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
[clojure.string :as string]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.config :as config]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(def logs-queue (atom #queue []))
|
||||
@@ -50,3 +52,9 @@
|
||||
:logs/set-level
|
||||
(fn [level]
|
||||
(setup level)))
|
||||
|
||||
(rf/defn set-log-level
|
||||
[{:keys [db]} log-level]
|
||||
(let [log-level (or log-level config/log-level)]
|
||||
{:db (assoc-in db [:profile/profile :log-level] log-level)
|
||||
:logs/set-level log-level}))
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
[status-im.contexts.chat.messenger.messages.link-preview.events :as link-preview]
|
||||
[status-im.contexts.chat.messenger.messages.transport.events :as messages.transport]
|
||||
[status-im.contexts.communities.discover.events]
|
||||
[status-im.contexts.profile.login.events :as profile.login]
|
||||
[status-im.contexts.profile.push-notifications.local.events :as local-notifications]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]
|
||||
@@ -36,9 +37,7 @@
|
||||
^js event-js (.-event data)
|
||||
type (.-type data)]
|
||||
(case type
|
||||
"node.login" {:fx [[:dispatch
|
||||
[:profile.login/login-node-signal
|
||||
(transforms/js->clj event-js)]]]}
|
||||
"node.login" (profile.login/login-node-signal cofx (transforms/js->clj event-js))
|
||||
"backup.performed" {:db (assoc-in db
|
||||
[:profile/profile :last-backup]
|
||||
(.-lastBackup event-js))}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
(def ^:const content-type-system-message-mutual-event-sent 15)
|
||||
(def ^:const content-type-system-message-mutual-event-accepted 16)
|
||||
(def ^:const content-type-system-message-mutual-event-removed 17)
|
||||
(def ^:const content-type-bridge-message 18)
|
||||
|
||||
;; Not implemented in status-go, only used for testing/ui work
|
||||
(def ^:const content-type-gif 100)
|
||||
@@ -429,12 +428,6 @@
|
||||
(def ^:const mainnet-chain-ids
|
||||
#{ethereum-mainnet-chain-id arbitrum-mainnet-chain-id optimism-mainnet-chain-id})
|
||||
|
||||
(def ^:const goerli-chain-ids
|
||||
#{ethereum-goerli-chain-id arbitrum-goerli-chain-id optimism-goerli-chain-id})
|
||||
|
||||
(def ^:const sepolia-chain-ids
|
||||
#{ethereum-sepolia-chain-id arbitrum-sepolia-chain-id optimism-sepolia-chain-id})
|
||||
|
||||
(def ^:const mainnet-short-name "eth")
|
||||
(def ^:const optimism-short-name "opt")
|
||||
(def ^:const arbitrum-short-name "arb1")
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
(ns status-im.contexts.chat.contacts.events
|
||||
(:require
|
||||
[oops.core :as oops]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.constants :as constants]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
@@ -66,21 +64,18 @@
|
||||
(when (> (count events) 1)
|
||||
{:dispatch-n events}))))
|
||||
|
||||
(re-frame/reg-event-fx :contacts/contacts-loaded
|
||||
(fn [{:keys [db]} [loaded-contacts]]
|
||||
(let [contacts (->> loaded-contacts
|
||||
(map <-rpc-js)
|
||||
(mapv (fn [{:keys [public-key] :as contact}] [public-key contact]))
|
||||
(into {}))]
|
||||
{:db (assoc db :contacts/contacts contacts)})))
|
||||
(rf/defn initialize-contacts
|
||||
[_]
|
||||
{:json-rpc/call [{:method "wakuext_contacts"
|
||||
:params []
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:contacts/contacts-loaded (map <-rpc-js %)])
|
||||
:on-error #(log/error "failed to fetch contacts" %)}]})
|
||||
|
||||
(re-frame/reg-fx :contacts/initialize-contacts
|
||||
(fn []
|
||||
(json-rpc/call {:method "wakuext_contacts"
|
||||
:params []
|
||||
:js-response true
|
||||
:on-success [:contacts/contacts-loaded]
|
||||
:on-error #(log/error "failed to fetch contacts" %)})))
|
||||
(rf/defn contacts-loaded
|
||||
{:events [:contacts/contacts-loaded]}
|
||||
[{:keys [db]} contacts]
|
||||
{:db (assoc db :contacts/contacts (into {} (map #(vector (:public-key %) %) contacts)))})
|
||||
|
||||
(defn send-contact-request
|
||||
[{:keys [db]} [id message]]
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
:sticky-section-headers-enabled false
|
||||
:sections (rf/sub [:contacts/grouped-by-first-letter])
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:render-section-footer-fn contact-list/contacts-section-footer
|
||||
:content-container-style {:padding-bottom 20}
|
||||
:render-data {:group group}
|
||||
:render-fn add-member-contact-item-render}]
|
||||
|
||||
@@ -186,3 +186,9 @@
|
||||
{:db (dissoc db :contacts/new-identity)})
|
||||
|
||||
(re-frame/reg-event-fx :contacts/clear-new-identity clear-new-identity)
|
||||
|
||||
(defn set-new-identity-reconnected
|
||||
[{:keys [db]}]
|
||||
(let [input (get-in db [:contacts/new-identity :input])]
|
||||
(re-frame/dispatch [:contacts/set-new-identity {:input input}])))
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
(ns status-im.contexts.chat.home.new-chat.styles
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.safe-area :as safe-area]))
|
||||
|
||||
(def contact-selection-heading
|
||||
@@ -10,16 +9,11 @@
|
||||
:margin-top 24
|
||||
:margin-bottom 16})
|
||||
|
||||
(defn chat-button-container
|
||||
[theme]
|
||||
{:position :absolute
|
||||
:bottom 0
|
||||
:padding-bottom 33
|
||||
:background-color (colors/theme-colors colors/white-opa-70 colors/neutral-95-opa-70 theme)
|
||||
:padding-top 12
|
||||
:padding-horizontal 20
|
||||
:left 0
|
||||
:right 0})
|
||||
(def chat-button
|
||||
{:position :absolute
|
||||
:bottom (+ 12 (safe-area/get-bottom))
|
||||
:left 20
|
||||
:right 20})
|
||||
|
||||
(defn no-contacts
|
||||
[]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[quo.theme :as quo.theme]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
@@ -49,54 +49,27 @@
|
||||
(rf/dispatch [:open-modal :new-contact]))}
|
||||
(i18n/label :t/add-a-contact)]]))
|
||||
|
||||
(def ^:private contacts-selection-limit (dec constants/max-group-chat-participants))
|
||||
|
||||
(defn- toggle-selection
|
||||
[public-key user-selected?]
|
||||
(let [selected-contacts-count (rf/sub [:selected-contacts-count])]
|
||||
(if user-selected?
|
||||
(re-frame/dispatch [:deselect-contact public-key])
|
||||
(if (= contacts-selection-limit
|
||||
selected-contacts-count)
|
||||
(do
|
||||
(rf/dispatch
|
||||
[:toasts/upsert
|
||||
{:id :remove-nickname
|
||||
:type :negative
|
||||
:text (i18n/label :t/new-group-limit
|
||||
{:max-contacts
|
||||
contacts-selection-limit})}])
|
||||
true)
|
||||
(re-frame/dispatch [:select-contact public-key])))))
|
||||
|
||||
(defn contact-item-render
|
||||
[{:keys [public-key] :as item} set-has-error]
|
||||
(let [user-selected? (rf/sub [:is-contact-selected? public-key])
|
||||
on-toggle (fn []
|
||||
(-> public-key
|
||||
(toggle-selection user-selected?)
|
||||
boolean
|
||||
set-has-error))]
|
||||
[contact-list-item/contact-list-item
|
||||
{:on-press on-toggle
|
||||
:allow-multiple-presses? true
|
||||
:accessory {:type :checkbox
|
||||
:checked? user-selected?
|
||||
:on-check on-toggle}}
|
||||
item]))
|
||||
[_]
|
||||
(fn [{:keys [public-key] :as item}]
|
||||
(let [user-selected? (rf/sub [:is-contact-selected? public-key])
|
||||
on-toggle #(if user-selected?
|
||||
(re-frame/dispatch [:deselect-contact public-key])
|
||||
(re-frame/dispatch [:select-contact public-key]))]
|
||||
[contact-list-item/contact-list-item
|
||||
{:on-press on-toggle
|
||||
:allow-multiple-presses? true
|
||||
:accessory {:type :checkbox
|
||||
:checked? user-selected?
|
||||
:on-check on-toggle}}
|
||||
item])))
|
||||
|
||||
(defn view
|
||||
[{:keys [scroll-enabled? on-scroll close]}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
contacts (rf/sub [:contacts/sorted-and-grouped-by-first-letter])
|
||||
(defn- view-internal
|
||||
[{:keys [scroll-enabled? on-scroll close theme]}]
|
||||
(let [contacts (rf/sub [:contacts/sorted-and-grouped-by-first-letter])
|
||||
selected-contacts-count (rf/sub [:selected-contacts-count])
|
||||
selected-contacts (rf/sub [:group/selected-contacts])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
one-contact-selected? (= selected-contacts-count 1)
|
||||
[has-error? set-has-error] (rn/use-state false)
|
||||
render-fn (rn/use-callback (fn [item]
|
||||
(contact-item-render item set-has-error))
|
||||
[set-has-error])
|
||||
contacts-selected? (pos? selected-contacts-count)
|
||||
{:keys [primary-name public-key]} (when one-contact-selected?
|
||||
(rf/sub [:contacts/contact-by-identity
|
||||
@@ -113,42 +86,38 @@
|
||||
{:weight :semi-bold
|
||||
:size :heading-1
|
||||
:style {:color (colors/theme-colors colors/neutral-100 colors/white theme)}}
|
||||
(if (or (not contacts-selected?) one-contact-selected?)
|
||||
(i18n/label :t/new-chat)
|
||||
(i18n/label :t/new-group-chat))]
|
||||
(i18n/label :t/new-chat)]
|
||||
(when (seq contacts)
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :regular
|
||||
:style {:margin-bottom 2
|
||||
:color (if has-error?
|
||||
(colors/theme-colors colors/danger-50 colors/danger-60 theme)
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme))}}
|
||||
:color (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)}}
|
||||
(i18n/label :t/selected-count-from-max
|
||||
{:selected selected-contacts-count
|
||||
:max contacts-selection-limit})])]]
|
||||
:max constants/max-group-chat-participants})])]]
|
||||
(if (empty? contacts)
|
||||
[no-contacts-view {:theme theme}]
|
||||
[gesture/section-list
|
||||
{:key-fn :title
|
||||
:sections (rf/sub [:contacts/filtered-active-sections])
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:render-section-footer-fn contact-list/contacts-section-footer
|
||||
:content-container-style {:padding-bottom 70}
|
||||
:render-fn render-fn
|
||||
:scroll-enabled @scroll-enabled?
|
||||
:on-scroll on-scroll}])
|
||||
{:key-fn :title
|
||||
:sticky-section-headers-enabled false
|
||||
:sections (rf/sub [:contacts/filtered-active-sections])
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:content-container-style {:padding-bottom 70}
|
||||
:render-fn contact-item-render
|
||||
:scroll-enabled @scroll-enabled?
|
||||
:on-scroll on-scroll}])
|
||||
(when contacts-selected?
|
||||
[rn/view
|
||||
{:style (style/chat-button-container theme)}
|
||||
[quo/button
|
||||
{:type :primary
|
||||
:customization-color customization-color
|
||||
:accessibility-label :next-button
|
||||
:on-press (fn []
|
||||
(if one-contact-selected?
|
||||
(rf/dispatch [:chat.ui/start-chat public-key])
|
||||
(rf/dispatch [:navigate-to :new-group])))}
|
||||
(if one-contact-selected?
|
||||
(i18n/label :t/chat-with {:selected-user primary-name})
|
||||
(i18n/label :t/setup-group-chat))]])]))
|
||||
[quo/button
|
||||
{:type :primary
|
||||
:accessibility-label :next-button
|
||||
:container-style style/chat-button
|
||||
:on-press (fn []
|
||||
(if one-contact-selected?
|
||||
(rf/dispatch [:chat.ui/start-chat public-key])
|
||||
(rf/dispatch [:navigate-to :new-group])))}
|
||||
(if one-contact-selected?
|
||||
(i18n/label :t/chat-with {:selected-user primary-name})
|
||||
(i18n/label :t/setup-group-chat))])]))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -106,7 +106,6 @@
|
||||
:sections items
|
||||
:sticky-section-headers-enabled false
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:render-section-footer-fn contact-list/contacts-section-footer
|
||||
:render-fn (fn [data]
|
||||
(contact-item-render data theme))
|
||||
:scroll-event-throttle 8
|
||||
@@ -127,42 +126,48 @@
|
||||
:title (i18n/label :t/invite-friends-to-status)
|
||||
:description (i18n/label :t/share-invite-link)}})
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
scroll-ref (rn/use-ref-atom nil)
|
||||
set-scroll-ref (rn/use-callback #(reset! scroll-ref %))
|
||||
{:keys [universal-profile-url]} (rf/sub [:profile/profile])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
pending-contact-requests (rf/sub [:activity-center/pending-contact-requests])
|
||||
selected-tab (or (rf/sub [:messages-home/selected-tab]) :tab/recent)
|
||||
scroll-shared-value (reanimated/use-shared-value 0)]
|
||||
[:<>
|
||||
(if (= selected-tab :tab/contacts)
|
||||
[contacts
|
||||
{:pending-contact-requests pending-contact-requests
|
||||
:set-scroll-ref set-scroll-ref
|
||||
:scroll-shared-value scroll-shared-value
|
||||
:theme theme}]
|
||||
[chats
|
||||
{:selected-tab selected-tab
|
||||
:set-scroll-ref set-scroll-ref
|
||||
:scroll-shared-value scroll-shared-value
|
||||
:theme theme}])
|
||||
[common.banner/animated-banner
|
||||
{:content (banner-data universal-profile-url)
|
||||
:customization-color customization-color
|
||||
:scroll-ref scroll-ref
|
||||
:tabs [{:id :tab/recent
|
||||
:label (i18n/label :t/recent)
|
||||
:accessibility-label :tab-recent}
|
||||
{:id :tab/groups
|
||||
:label (i18n/label :t/groups)
|
||||
:accessibility-label :tab-groups}
|
||||
{:id :tab/contacts
|
||||
:label (i18n/label :t/contacts)
|
||||
:accessibility-label :tab-contacts
|
||||
:notification-dot? (pos? (count pending-contact-requests))}]
|
||||
:selected-tab selected-tab
|
||||
:on-tab-change (fn [tab] (rf/dispatch [:messages-home/select-tab tab]))
|
||||
:scroll-shared-value scroll-shared-value}]]))
|
||||
(defn- f-view-internal
|
||||
[{:keys [theme]}]
|
||||
(let [scroll-ref (atom nil)
|
||||
set-scroll-ref #(reset! scroll-ref %)]
|
||||
(fn []
|
||||
(let [{:keys [universal-profile-url]} (rf/sub [:profile/profile])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
pending-contact-requests (rf/sub [:activity-center/pending-contact-requests])
|
||||
selected-tab (or (rf/sub [:messages-home/selected-tab]) :tab/recent)
|
||||
scroll-shared-value (reanimated/use-shared-value 0)]
|
||||
[:<>
|
||||
(if (= selected-tab :tab/contacts)
|
||||
[contacts
|
||||
{:pending-contact-requests pending-contact-requests
|
||||
:set-scroll-ref set-scroll-ref
|
||||
:scroll-shared-value scroll-shared-value
|
||||
:theme theme}]
|
||||
[chats
|
||||
{:selected-tab selected-tab
|
||||
:set-scroll-ref set-scroll-ref
|
||||
:scroll-shared-value scroll-shared-value
|
||||
:theme theme}])
|
||||
[:f> common.banner/animated-banner
|
||||
{:content (banner-data universal-profile-url)
|
||||
:customization-color customization-color
|
||||
:scroll-ref scroll-ref
|
||||
:tabs [{:id :tab/recent
|
||||
:label (i18n/label :t/recent)
|
||||
:accessibility-label :tab-recent}
|
||||
{:id :tab/groups
|
||||
:label (i18n/label :t/groups)
|
||||
:accessibility-label :tab-groups}
|
||||
{:id :tab/contacts
|
||||
:label (i18n/label :t/contacts)
|
||||
:accessibility-label :tab-contacts
|
||||
:notification-dot? (pos? (count pending-contact-requests))}]
|
||||
:selected-tab selected-tab
|
||||
:on-tab-change (fn [tab] (rf/dispatch [:messages-home/select-tab tab]))
|
||||
:scroll-shared-value scroll-shared-value}]]))))
|
||||
|
||||
(defn- internal-chats-home-view
|
||||
[params]
|
||||
[:f> f-view-internal params])
|
||||
|
||||
(def view (quo.theme/with-theme internal-chats-home-view))
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
(ns status-im.contexts.chat.messenger.messages.content.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.ui.screens.chat.message.legacy-view :as old-message]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.platform :as platform]
|
||||
[reagent.core :as reagent]
|
||||
@@ -115,34 +113,6 @@
|
||||
constants/content-type-system-message-mutual-event-sent
|
||||
[system-message-contact-request message-data :contact-request])))
|
||||
|
||||
(defn bridge-message-content
|
||||
[{:keys [bridge-message timestamp]}]
|
||||
(let [{:keys [user-avatar user-name
|
||||
bridge-name content]} bridge-message
|
||||
user-name (when (string? user-name)
|
||||
(-> user-name
|
||||
(string/replace "<b>" "")
|
||||
(string/replace "</b>" "")))]
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:padding-horizontal 12
|
||||
:padding-top 4}}
|
||||
[fast-image/fast-image
|
||||
{:source {:uri user-avatar}
|
||||
:style {:width 32
|
||||
:margin-top 4
|
||||
:border-radius 16
|
||||
:height 32}}]
|
||||
[rn/view {:margin-left 8 :flex 1}
|
||||
[quo/author
|
||||
{:primary-name (str user-name)
|
||||
:short-chat-key (str "Bridged from " bridge-name)
|
||||
:time-str (datetime/timestamp->time timestamp)}]
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
:style {:line-height 22.75}}
|
||||
content]]]))
|
||||
|
||||
(declare on-long-press)
|
||||
|
||||
(defn- user-message-content-internal
|
||||
@@ -314,9 +284,6 @@
|
||||
keyboard-shown?))
|
||||
context]
|
||||
|
||||
(= content-type constants/content-type-bridge-message)
|
||||
[bridge-message-content message-data]
|
||||
|
||||
:else
|
||||
[user-message-content
|
||||
{:message-data message-data
|
||||
|
||||
@@ -1,65 +1,79 @@
|
||||
(ns status-im.contexts.chat.messenger.messages.link-preview.events
|
||||
(:require [camel-snake-kebab.core :as csk]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.collection]
|
||||
[utils.re-frame :as rf]))
|
||||
(:require
|
||||
[camel-snake-kebab.core :as csk]
|
||||
[status-im.contexts.profile.settings.events :as profile.settings.events]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.collection]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn community-link
|
||||
[id]
|
||||
(str "https://status.app/c#" id))
|
||||
|
||||
(rf/reg-event-fx :chat.ui/cache-link-preview-data
|
||||
(fn [{:keys [db]} [site data]]
|
||||
(let [{:profile/keys [profile]} db
|
||||
link-previews-cache (-> profile
|
||||
(get :link-previews-cache {})
|
||||
(assoc site
|
||||
(utils.collection/map-keys csk/->kebab-case-keyword
|
||||
data)))]
|
||||
{:db (assoc-in db [:profile/profile :link-previews-cache] link-previews-cache)})))
|
||||
(rf/defn cache-link-preview-data
|
||||
{:events [:chat.ui/cache-link-preview-data]}
|
||||
[{{:profile/keys [profile]} :db :as cofx} site data]
|
||||
(let [link-previews-cache (get profile :link-previews-cache {})]
|
||||
(profile.settings.events/optimistic-profile-update
|
||||
cofx
|
||||
:link-previews-cache
|
||||
(assoc link-previews-cache site (utils.collection/map-keys csk/->kebab-case-keyword data)))))
|
||||
|
||||
(rf/reg-event-fx :chat.ui/load-link-preview-data
|
||||
(fn [{{:profile/keys [profile]} :db} [link]]
|
||||
(let [{:keys [error] :as cache-data} (get-in profile [:link-previews-cache link])]
|
||||
(when (or (not cache-data) error)
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_getLinkPreviewData"
|
||||
:params [link]
|
||||
:on-success [:chat.ui/cache-link-preview-data link]
|
||||
:on-error [:chat.ui/cache-link-preview-data link
|
||||
{:error (str "Can't get preview data for " link)}]}]]]}))))
|
||||
(rf/defn load-link-preview-data
|
||||
{:events [:chat.ui/load-link-preview-data]}
|
||||
[{{:profile/keys [profile] :as db} :db} link]
|
||||
(let [{:keys [error] :as cache-data} (get-in profile [:link-previews-cache link])]
|
||||
(if (or (not cache-data) error)
|
||||
{:json-rpc/call [{:method "wakuext_getLinkPreviewData"
|
||||
:params [link]
|
||||
:on-success #(rf/dispatch [:chat.ui/cache-link-preview-data link %])
|
||||
:on-error #(rf/dispatch [:chat.ui/cache-link-preview-data link
|
||||
{:error (str "Can't get preview data for " link)}])}]}
|
||||
{:db db})))
|
||||
|
||||
(rf/reg-event-fx :chat.ui/should-suggest-link-preview
|
||||
(fn [_ [enabled?]]
|
||||
{:fx [[:dispatch
|
||||
[:profile.settings/profile-update :link-preview-request-enabled (boolean enabled?)]]]}))
|
||||
(rf/defn should-suggest-link-preview
|
||||
{:events [:chat.ui/should-suggest-link-preview]}
|
||||
[{:keys [db] :as cofx} enabled?]
|
||||
(profile.settings.events/profile-update
|
||||
cofx
|
||||
:link-preview-request-enabled
|
||||
(boolean enabled?)
|
||||
{}))
|
||||
|
||||
(rf/reg-event-fx :chat.ui/link-preview-whitelist-received
|
||||
(fn [{:keys [db]} [whitelist]]
|
||||
{:db (assoc db :link-previews-whitelist whitelist)}))
|
||||
(rf/defn save-link-preview-whitelist
|
||||
{:events [:chat.ui/link-preview-whitelist-received]}
|
||||
[{:keys [db]} whitelist]
|
||||
{:db (assoc db :link-previews-whitelist whitelist)})
|
||||
|
||||
(rf/reg-fx :chat.ui/request-link-preview-whitelist
|
||||
(fn []
|
||||
(json-rpc/call {:method "wakuext_getLinkPreviewWhitelist"
|
||||
:params []
|
||||
:on-success [:chat.ui/link-preview-whitelist-received]
|
||||
:on-error #(log/error "Failed to get link preview whitelist")})))
|
||||
(rf/defn request-link-preview-whitelist
|
||||
[_]
|
||||
{:json-rpc/call [{:method "wakuext_getLinkPreviewWhitelist"
|
||||
:params []
|
||||
:on-success #(rf/dispatch [:chat.ui/link-preview-whitelist-received %])
|
||||
:on-error #(log/error "Failed to get link preview whitelist")}]})
|
||||
|
||||
(defn cache-community-preview-data
|
||||
[{:keys [id] :as community}]
|
||||
(rf/dispatch [:chat.ui/cache-link-preview-data (community-link id) community]))
|
||||
|
||||
(rf/reg-event-fx :chat.ui/enable-link-previews
|
||||
(fn [{{:profile/keys [profile]} :db} [site enabled?]]
|
||||
(let [enabled-sites (if enabled?
|
||||
(conj (get profile :link-previews-enabled-sites #{}) site)
|
||||
(disj (get profile :link-previews-enabled-sites #{}) site))]
|
||||
{:fx [[:dispatch [:profile.settings/profile-update :link-previews-enabled-sites enabled-sites]]]})))
|
||||
(rf/defn enable
|
||||
{:events [:chat.ui/enable-link-previews]}
|
||||
[{{:profile/keys [profile]} :db :as cofx} site enabled?]
|
||||
(profile.settings.events/profile-update
|
||||
cofx
|
||||
:link-previews-enabled-sites
|
||||
(if enabled?
|
||||
(conj (get profile :link-previews-enabled-sites #{}) site)
|
||||
(disj (get profile :link-previews-enabled-sites #{}) site))
|
||||
{}))
|
||||
|
||||
(rf/reg-event-fx :chat.ui/enable-all-link-previews
|
||||
(fn [_ [link-previews-whitelist enabled?]]
|
||||
(let [enabled-sites (if enabled?
|
||||
(into #{} (map :title link-previews-whitelist))
|
||||
#{})]
|
||||
{:fx [[:dispatch [:profile.settings/profile-update :link-previews-enabled-sites enabled-sites]]]})))
|
||||
(rf/defn enable-all
|
||||
{:events [:chat.ui/enable-all-link-previews]}
|
||||
[cofx link-previews-whitelist enabled?]
|
||||
(profile.settings.events/profile-update
|
||||
cofx
|
||||
:link-previews-enabled-sites
|
||||
(if enabled?
|
||||
(into #{} (map :title link-previews-whitelist))
|
||||
#{})
|
||||
{}))
|
||||
|
||||
@@ -47,8 +47,8 @@
|
||||
|
||||
(defn list-on-end-reached
|
||||
[distance-from-list-top]
|
||||
;; FIXME: that's a bit of a hack but we need to update `distance-from-list-top` once the new
|
||||
;; messages are fetched in order for the header to work properly
|
||||
;; FIXME: that's a bit of a hack but we need to update `distance-from-list-top` once the new messages
|
||||
;; are fetched in order for the header to work properly
|
||||
(let [on-loaded (fn [n]
|
||||
(reanimated/set-shared-value distance-from-list-top
|
||||
(+ (reanimated/get-shared-value distance-from-list-top)
|
||||
@@ -147,7 +147,7 @@
|
||||
:actions [{:accessibility-label :action-button-pinned
|
||||
:big? true
|
||||
:label (or latest-pin-text (i18n/label :t/no-pinned-messages))
|
||||
:customization-color cover-bg-color
|
||||
:color cover-bg-color
|
||||
:icon :i/pin
|
||||
:counter-value pins-count
|
||||
:on-press (fn []
|
||||
@@ -157,7 +157,7 @@
|
||||
:label (i18n/label (if muted
|
||||
unmute-chat-label
|
||||
mute-chat-label))
|
||||
:customization-color cover-bg-color
|
||||
:color cover-bg-color
|
||||
:icon (if muted? :i/activity-center :i/muted)
|
||||
:on-press (fn []
|
||||
(if muted?
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
[status-im.contexts.communities.actions.addresses-for-permissions.view :as addresses-for-permissions]
|
||||
[status-im.contexts.communities.actions.airdrop-addresses.view :as airdrop-addresses]
|
||||
[status-im.contexts.communities.actions.community-rules.view :as community-rules]
|
||||
[status-im.contexts.communities.actions.detail-token-gating.view :as detail-token-gating]
|
||||
[status-im.contexts.communities.utils :as communities.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -35,29 +34,19 @@
|
||||
{:community-id id :password %}])}])
|
||||
(navigate-back))]
|
||||
(fn []
|
||||
(let [{:keys [name color images
|
||||
membership-permissions?]} (rf/sub [:communities/community id])
|
||||
(let [{:keys [name color images]} (rf/sub [:communities/community id])
|
||||
airdrop-account (rf/sub [:communities/airdrop-account id])
|
||||
selected-accounts (rf/sub [:communities/selected-permission-accounts id])
|
||||
{:keys [highest-permission-role
|
||||
no-member-permission?]} (rf/sub [:community/token-gated-overview id])
|
||||
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
||||
highest-role-text (i18n/label (communities.utils/role->translation-key
|
||||
highest-permission-role
|
||||
:t/member))]
|
||||
[rn/safe-area-view {:style style/container}
|
||||
[quo/page-nav
|
||||
(cond-> {:text-align :left
|
||||
:icon-name :i/close
|
||||
:on-press navigate-back
|
||||
:accessibility-label :back-button}
|
||||
(or membership-permissions? (and highest-permission-role (not no-member-permission?)))
|
||||
(assoc :right-side
|
||||
[{:icon-left :i/unlocked
|
||||
:on-press #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [detail-token-gating/view
|
||||
id])}])
|
||||
:label (i18n/label :t/permissions)}]))]
|
||||
{:text-align :left
|
||||
:icon-name :i/close
|
||||
:on-press navigate-back
|
||||
:accessibility-label :back-button}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/request-to-join)
|
||||
:description :context-tag
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(ns status-im.contexts.communities.actions.addresses-for-permissions.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.gesture :as gesture]
|
||||
[status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.communities.actions.detail-token-gating.view :as detail-token-gating]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -66,28 +66,24 @@
|
||||
(rf/dispatch [:hide-bottom-sheet]))]
|
||||
(rf/dispatch [:communities/get-permissioned-balances id])
|
||||
(fn []
|
||||
(let [{:keys [name color images
|
||||
membership-permissions?]} (rf/sub [:communities/community id])
|
||||
(let [{:keys [name color images]} (rf/sub [:communities/community id])
|
||||
{:keys [checking?
|
||||
highest-permission-role
|
||||
no-member-permission?]} (rf/sub [:community/token-gated-overview id])
|
||||
highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
||||
accounts (rf/sub [:wallet/accounts-without-watched-accounts])
|
||||
selected-addresses (rf/sub [:communities/selected-permission-addresses id])
|
||||
share-all-addresses? (rf/sub [:communities/share-all-addresses? id])
|
||||
unsaved-address-changes? (rf/sub [:communities/unsaved-address-changes? id])]
|
||||
[:<>
|
||||
[quo/drawer-top
|
||||
(cond-> {:type :context-tag
|
||||
:title (i18n/label :t/addresses-for-permissions)
|
||||
:context-tag-type :community
|
||||
:community-name name
|
||||
:community-logo (get-in images [:thumbnail :uri])
|
||||
:customization-color color}
|
||||
(or membership-permissions? (and highest-permission-role (not no-member-permission?)))
|
||||
(assoc
|
||||
:button-icon :i/info
|
||||
:on-button-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [detail-token-gating/view id])}])))]
|
||||
{:type :context-tag
|
||||
:title (i18n/label :t/addresses-for-permissions)
|
||||
:context-tag-type :community
|
||||
:community-name name
|
||||
:button-icon :i/info
|
||||
:button-type :grey
|
||||
:on-button-press not-implemented/alert
|
||||
:community-logo (get-in images [:thumbnail :uri])
|
||||
:customization-color color}]
|
||||
|
||||
[gesture/flat-list
|
||||
{:render-fn account-item
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
(ns status-im.contexts.communities.actions.detail-token-gating.style)
|
||||
|
||||
(def container
|
||||
{:flex 1
|
||||
:padding-horizontal 20})
|
||||
|
||||
(def role-container
|
||||
{:flex-direction :row
|
||||
:padding-horizontal 22
|
||||
:margin-bottom 8})
|
||||
|
||||
(def permission-text
|
||||
{:flex-direction :column
|
||||
:margin-top 12})
|
||||
@@ -1,32 +0,0 @@
|
||||
(ns status-im.contexts.communities.actions.detail-token-gating.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.contexts.communities.actions.detail-token-gating.style :as style]
|
||||
[status-im.contexts.communities.utils :as communities.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[id]
|
||||
(let [permissions (rf/sub [:community/token-permissions id])
|
||||
role-text (fn [role]
|
||||
(i18n/label
|
||||
(communities.utils/role->translation-key role
|
||||
:t/token-master)))]
|
||||
[rn/view {:style style/container}
|
||||
(map (fn [{:keys [tokens role satisfied?]}]
|
||||
^{:key role}
|
||||
[rn/view {:style {:margin-bottom 20}}
|
||||
[quo/text {:weight :medium}
|
||||
(if satisfied?
|
||||
(i18n/label :t/you-eligible-to-join-as {:role (role-text role)})
|
||||
(i18n/label :t/you-not-eligible-to-join))]
|
||||
[quo/text {:size :paragraph-2 :style {:padding-bottom 8}}
|
||||
(if satisfied?
|
||||
(i18n/label :t/you-hodl)
|
||||
(i18n/label :t/you-must-hold))]
|
||||
[quo/token-requirement-list
|
||||
{:tokens tokens
|
||||
:container-style {:padding-horizontal 20}}]])
|
||||
permissions)]))
|
||||
@@ -293,7 +293,7 @@
|
||||
(defn community-fetched
|
||||
[{:keys [db]} [community-id community]]
|
||||
(when community
|
||||
{:db (update db :communities/fetching-communities dissoc community-id)
|
||||
{:db (update db :communities/fetching-community dissoc community-id)
|
||||
:fx [[:dispatch [:communities/handle-community community]]
|
||||
[:dispatch [:communities/update-last-opened-at community-id]]
|
||||
[:dispatch
|
||||
@@ -304,14 +304,14 @@
|
||||
|
||||
(defn community-failed-to-fetch
|
||||
[{:keys [db]} [community-id]]
|
||||
{:db (update db :communities/fetching-communities dissoc 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]} [{:keys [community-id update-last-opened-at?]}]]
|
||||
(when (and community-id (not (get-in db [:communities/fetching-communities community-id])))
|
||||
{:db (assoc-in db [:communities/fetching-communities community-id] true)
|
||||
(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
|
||||
@@ -398,7 +398,7 @@
|
||||
:community-id community-id})}})
|
||||
|
||||
(rf/reg-event-fx :communities/navigate-to-community-overview
|
||||
(fn [{:keys [db] :as cofx} [deserialized-key]]
|
||||
(fn [cofx [deserialized-key]]
|
||||
(if (string/starts-with? deserialized-key constants/serialization-key)
|
||||
(navigate-to-serialized-community cofx deserialized-key)
|
||||
(rf/merge
|
||||
@@ -407,9 +407,7 @@
|
||||
[:communities/fetch-community
|
||||
{:community-id deserialized-key
|
||||
:update-last-opened-at? true}]]
|
||||
[:dispatch [:navigate-to :community-overview deserialized-key]]
|
||||
(when (get-in db [:communities deserialized-key :joined])
|
||||
[:dispatch [:activity-center.notifications/dismiss-community-overview deserialized-key]])]}
|
||||
[:dispatch [:navigate-to :community-overview deserialized-key]]]}
|
||||
(navigation/pop-to-root :shell-stack)))))
|
||||
|
||||
(rf/reg-event-fx :communities/navigate-to-community-chat
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
(testing "with community id"
|
||||
(testing "update fetching indicator in db"
|
||||
(is (match?
|
||||
{:db {:communities/fetching-communities {community-id true}}}
|
||||
{:db {:communities/fetching-community {community-id true}}}
|
||||
(events/fetch-community {} [{:community-id community-id}]))))
|
||||
(testing "call the fetch community rpc method with correct community id"
|
||||
(is (match?
|
||||
@@ -124,21 +124,21 @@
|
||||
(testing "remove community id from fetching indicator in db"
|
||||
(is (match?
|
||||
nil
|
||||
(get-in (events/community-failed-to-fetch {:db {:communities/fetching-communities
|
||||
(get-in (events/community-failed-to-fetch {:db {:communities/fetching-community
|
||||
{community-id true}}}
|
||||
[community-id])
|
||||
[:db :communities/fetching-communities 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-communities {community-id true}}}
|
||||
(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-communities community-id]))))
|
||||
[:db :communities/fetching-community community-id]))))
|
||||
(testing "dispatch fxs"
|
||||
(is (match?
|
||||
{:fx [[:dispatch [:communities/handle-community {:id community-id}]]
|
||||
@@ -148,7 +148,7 @@
|
||||
{:id community-id}]]]}
|
||||
(events/community-fetched cofx arg))))))
|
||||
(testing "given a joined community"
|
||||
(let [cofx {:db {:communities/fetching-communities {community-id true}}}
|
||||
(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?
|
||||
@@ -159,7 +159,7 @@
|
||||
{:id community-id}]]]}
|
||||
(events/community-fetched cofx arg))))))
|
||||
(testing "given a token-gated community"
|
||||
(let [cofx {:db {:communities/fetching-communities {community-id true}}}
|
||||
(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?
|
||||
|
||||
@@ -21,13 +21,6 @@
|
||||
:align-items :center
|
||||
:margin-top 20})
|
||||
|
||||
(def fetching-placeholder
|
||||
{:align-items :center
|
||||
:justify-content :center
|
||||
:flex 1})
|
||||
|
||||
(def fetching-text {:color :red})
|
||||
|
||||
(def blur-channel-header
|
||||
{:position :absolute
|
||||
:top 100
|
||||
|
||||
@@ -3,19 +3,16 @@
|
||||
[oops.core :as oops]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as theme]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.home.actions.view :as actions]
|
||||
[status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.common.scroll-page.style :as scroll-page.style]
|
||||
[status-im.common.scroll-page.view :as scroll-page]
|
||||
[status-im.config :as config]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.communities.actions.chat.view :as chat-actions]
|
||||
[status-im.contexts.communities.actions.community-options.view :as options]
|
||||
[status-im.contexts.communities.actions.detail-token-gating.view :as detail-token-gating]
|
||||
[status-im.contexts.communities.overview.style :as style]
|
||||
[status-im.contexts.communities.utils :as communities.utils]
|
||||
[utils.debounce :as debounce]
|
||||
@@ -98,12 +95,21 @@
|
||||
:unknown-access))
|
||||
|
||||
(defn- info-button
|
||||
[on-press]
|
||||
(let [theme (theme/use-theme)]
|
||||
[rn/pressable
|
||||
{:on-press on-press}
|
||||
[rn/view
|
||||
[quo/icon :i/info {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}]]]))
|
||||
[]
|
||||
[rn/pressable
|
||||
{:on-press
|
||||
#(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[quo/documentation-drawers
|
||||
{:title (i18n/label :t/token-gated-communities)
|
||||
:show-button? true
|
||||
:button-label (i18n/label :t/read-more)
|
||||
:button-icon :info}
|
||||
[quo/text (i18n/label :t/token-gated-communities-info)]])}])}
|
||||
[rn/view
|
||||
[quo/icon :i/info {:no-color true}]]])
|
||||
|
||||
(defn- network-not-supported
|
||||
[]
|
||||
@@ -151,9 +157,7 @@
|
||||
(if (and can-request-access? highest-permission-role)
|
||||
(i18n/label :t/you-eligible-to-join-as {:role highest-role-text})
|
||||
(i18n/label :t/you-not-eligible-to-join))]
|
||||
[info-button
|
||||
#(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [detail-token-gating/view id])}])]]
|
||||
[info-button]]
|
||||
[quo/text {:style {:padding-horizontal 12 :padding-bottom 18} :size :paragraph-2}
|
||||
(if can-request-access?
|
||||
(i18n/label :t/you-hodl)
|
||||
@@ -173,6 +177,7 @@
|
||||
:icon-left (if can-request-access? :i/unlocked :i/locked)}
|
||||
(i18n/label :t/join-open-community)]])))
|
||||
|
||||
|
||||
(defn- join-community
|
||||
[{:keys [id joined permissions role-permissions? can-join?] :as community}]
|
||||
(let [pending? (rf/sub [:communities/my-pending-request-to-join id])
|
||||
@@ -361,28 +366,14 @@
|
||||
;; might have been removed.
|
||||
on-first-channel-height-changed}]]))))
|
||||
|
||||
(defn- community-fetching-placeholder
|
||||
[id]
|
||||
(let [fetching? (rf/sub [:communities/fetching-community id])]
|
||||
[rn/view
|
||||
{:style style/fetching-placeholder
|
||||
:accessibility-label (if fetching?
|
||||
:fetching-community-overview
|
||||
:failed-to-fetch-community-overview)}
|
||||
[not-implemented/not-implemented
|
||||
[rn/text
|
||||
{:style style/fetching-text}
|
||||
(if fetching?
|
||||
"Fetching community..."
|
||||
"Failed to fetch community")]]]))
|
||||
|
||||
(defn- community-card-page-view
|
||||
[id]
|
||||
(let [{:keys [joined name images]
|
||||
(let [{:keys [id joined name images]
|
||||
:as community} (rf/sub [:communities/community id])]
|
||||
(if community
|
||||
[community-scroll-page id joined name images]
|
||||
[community-fetching-placeholder id])))
|
||||
(when community
|
||||
(when joined
|
||||
(rf/dispatch [:activity-center.notifications/dismiss-community-overview id]))
|
||||
[community-scroll-page id joined name images])))
|
||||
|
||||
(defn view
|
||||
[id]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns status-im.contexts.onboarding.new-to-status.view
|
||||
(:require
|
||||
[legacy.status-im.keycard.recovery :as keycard]
|
||||
[quo.core :as quo]
|
||||
re-frame.db
|
||||
[react-native.core :as rn]
|
||||
@@ -52,7 +53,7 @@
|
||||
:title (i18n/label :t/use-keycard)
|
||||
:subtitle (i18n/label :t/use-keycard-subtitle)
|
||||
:image (resources/get-image :use-keycard)
|
||||
:on-press #(js/alert "TODO: to be implemented")}]]]))
|
||||
:on-press #(rf/dispatch [::keycard/recover-with-keycard-pressed])}]]]))
|
||||
|
||||
(defn getting-started-doc
|
||||
[]
|
||||
|
||||
@@ -7,11 +7,7 @@
|
||||
[status-im.contexts.preview.quo.preview :as preview]))
|
||||
|
||||
(def descriptor
|
||||
[{:key :size
|
||||
:type :select
|
||||
:options [{:key :size-24}
|
||||
{:key :size-20}]}
|
||||
{:key :image
|
||||
[{:key :image
|
||||
:type :select
|
||||
:options [{:key (resources/get-mock-image :bored-ape)
|
||||
:value "Bored ape"}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
(ns status-im.contexts.preview.quo.community.channel-action
|
||||
(:require [quo.core :as quo]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.contexts.preview.quo.preview :as preview]))
|
||||
|
||||
(def descriptor
|
||||
[{:key :label
|
||||
:type :text}
|
||||
{:key :big?
|
||||
:type :boolean}
|
||||
{:key :counter-value
|
||||
:type :number}
|
||||
{:key :icon
|
||||
:type :select
|
||||
:options [{:key :i/muted}
|
||||
{:key :i/pin}]}
|
||||
(preview/customization-color-option)
|
||||
{:key :disabled?
|
||||
:type :boolean}])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom {:label "Action"
|
||||
:icon :i/muted
|
||||
:customization-color :blue
|
||||
:counter-value nil
|
||||
:disabled? false
|
||||
:big? true})]
|
||||
(fn []
|
||||
[preview/preview-container {:state state :descriptor descriptor}
|
||||
[quo/channel-action @state]])))
|
||||
@@ -8,40 +8,21 @@
|
||||
[]
|
||||
[preview/preview-container
|
||||
[quo/channel-actions
|
||||
{:actions [{:big? true
|
||||
:label "Pinned Messages"
|
||||
:customization-color :blue
|
||||
:icon :i/pin
|
||||
:counter-value 0}]}]
|
||||
{:actions [{:big? true
|
||||
:label "Pinned Messages"
|
||||
:color :blue
|
||||
:icon :i/pin
|
||||
:counter-value 0}]}]
|
||||
[rn/view {:height 50}]
|
||||
[quo/channel-actions
|
||||
{:actions [{:label "Pinned Messages"
|
||||
:customization-color :blue
|
||||
:icon :i/pin
|
||||
:counter-value 5}
|
||||
{:label "Mute chat"
|
||||
:customization-color :blue
|
||||
:icon :i/muted}]}]
|
||||
{:actions [{:label "Pinned Messages" :color :blue :icon :i/pin :counter-value 5}
|
||||
{:label "Mute chat" :color :blue :icon :i/muted}]}]
|
||||
[rn/view {:height 50}]
|
||||
[quo/channel-actions
|
||||
{:actions
|
||||
[{:big? true
|
||||
:label "Pinned Messages"
|
||||
:customization-color :blue
|
||||
:icon :i/pin
|
||||
:counter-value 5}
|
||||
{:label "Mute chat"
|
||||
:customization-color :blue
|
||||
:icon :i/muted}]}]
|
||||
{:actions [{:big? true :label "Pinned Messages" :color :blue :icon :i/pin :counter-value 5}
|
||||
{:label "Mute chat" :color :blue :icon :i/muted}]}]
|
||||
[rn/view {:height 50}]
|
||||
[quo/channel-actions
|
||||
{:actions [{:label "Pinned Messages"
|
||||
:customization-color :blue
|
||||
:icon :i/pin
|
||||
:counter-value 5}
|
||||
{:label "Mute chat"
|
||||
:customization-color :blue
|
||||
:icon :i/muted}
|
||||
{:label "Something else"
|
||||
:customization-color :blue
|
||||
:icon :i/placeholder}]}]])
|
||||
{:actions [{:label "Pinned Messages" :color :blue :icon :i/pin :counter-value 5}
|
||||
{:label "Mute chat" :color :blue :icon :i/muted}
|
||||
{:label "Something else" :color :blue :icon :i/placeholder}]}]])
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
(ns status-im.contexts.preview.quo.foundations.gradients
|
||||
(:require [quo.foundations.gradients :as quo.gradients]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.contexts.preview.quo.preview :as preview]))
|
||||
|
||||
(def ^:private descriptor
|
||||
[{:key :color-index
|
||||
:type :select
|
||||
:options [{:key :gradient-1}
|
||||
{:key :gradient-2}
|
||||
{:key :gradient-3}
|
||||
{:key :gradient-4}
|
||||
{:key :gradient-5}]}])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom {:color-index 1})]
|
||||
(fn []
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:descriptor descriptor
|
||||
:blur? (:blur? @state)
|
||||
:show-blur-background? (:blur? @state)}
|
||||
[quo.gradients/view
|
||||
{:container-style {:align-self :center
|
||||
:height 200
|
||||
:width 200}
|
||||
:color-index (:color-index @state)}]])))
|
||||
@@ -33,8 +33,6 @@
|
||||
[status-im.contexts.preview.quo.colors.color :as color]
|
||||
[status-im.contexts.preview.quo.colors.color-picker :as color-picker]
|
||||
[status-im.contexts.preview.quo.common :as common]
|
||||
[status-im.contexts.preview.quo.community.channel-action :as
|
||||
channel-action]
|
||||
[status-im.contexts.preview.quo.community.channel-actions :as
|
||||
channel-actions]
|
||||
[status-im.contexts.preview.quo.community.community-card-view :as
|
||||
@@ -68,7 +66,6 @@
|
||||
[status-im.contexts.preview.quo.dropdowns.network-dropdown :as
|
||||
network-dropdown]
|
||||
[status-im.contexts.preview.quo.empty-state.empty-state :as empty-state]
|
||||
[status-im.contexts.preview.quo.foundations.gradients :as gradients]
|
||||
[status-im.contexts.preview.quo.foundations.shadows :as shadows]
|
||||
[status-im.contexts.preview.quo.gradient.gradient-cover :as gradient-cover]
|
||||
[status-im.contexts.preview.quo.graph.interactive-graph :as
|
||||
@@ -134,7 +131,6 @@
|
||||
small-option-card]
|
||||
[status-im.contexts.preview.quo.password.tips :as tips]
|
||||
[status-im.contexts.preview.quo.profile.collectible :as collectible]
|
||||
[status-im.contexts.preview.quo.profile.collectible-list-item :as collectible-list-item]
|
||||
[status-im.contexts.preview.quo.profile.link-card :as link-card]
|
||||
[status-im.contexts.preview.quo.profile.profile-card :as profile-card]
|
||||
[status-im.contexts.preview.quo.profile.select-profile :as select-profile]
|
||||
@@ -203,9 +199,7 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def screens-categories
|
||||
{:foundations [{:name :gradients
|
||||
:component gradients/view}
|
||||
{:name :shadows
|
||||
{:foundations [{:name :shadows
|
||||
:component shadows/view}]
|
||||
:animated-list [{:name :animated-header-list
|
||||
:component animated-header-list/mock-screen}]
|
||||
@@ -266,9 +260,6 @@
|
||||
{:name :token-gating
|
||||
:options {:insets {:bottom? true}}
|
||||
:component token-gating/view}
|
||||
{:name :channel-action
|
||||
:options {:insets {:bottom? true}}
|
||||
:component channel-action/view}
|
||||
{:name :channel-actions
|
||||
:options {:insets {:bottom? true}}
|
||||
:component channel-actions/view}]
|
||||
@@ -418,8 +409,6 @@
|
||||
:component tips/view}]
|
||||
:profile [{:name :collectible
|
||||
:component collectible/view}
|
||||
{:name :collectible-list-item
|
||||
:component collectible-list-item/view}
|
||||
{:name :link-card
|
||||
:component link-card/view}
|
||||
{:name :profile-card
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
(ns status-im.contexts.preview.quo.profile.collectible-list-item
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.contexts.preview.quo.preview :as preview]))
|
||||
|
||||
(defonce test-image (resources/get-mock-image :collectible))
|
||||
(defonce test-avatar (resources/get-mock-image :monkey))
|
||||
|
||||
(def descriptor
|
||||
[{:key :type
|
||||
:type :select
|
||||
:options [{:key :card}
|
||||
{:key :image}]}
|
||||
{:key :community?
|
||||
:type :boolean}
|
||||
{:key :status
|
||||
:type :select
|
||||
:options [{:key :loading}
|
||||
{:key :default}
|
||||
{:key :unsupported}
|
||||
{:key :cant-fetch}]}
|
||||
{:key :gradient-color-index
|
||||
:type :select
|
||||
:options [{:key :gradient-1}
|
||||
{:key :gradient-2}
|
||||
{:key :gradient-3}
|
||||
{:key :gradient-4}
|
||||
{:key :gradient-5}]}
|
||||
{:key :counter
|
||||
:type :text}
|
||||
{:key :collectible-name
|
||||
:type :text}])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom {:type :card
|
||||
:collectible-name "Doodle #6822"
|
||||
:gradient-color-index :gradient-1
|
||||
:community? false
|
||||
:status :loading
|
||||
:counter ""})]
|
||||
(fn []
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:descriptor descriptor
|
||||
:component-container-style {:padding-vertical 20
|
||||
:margin-horizontal 95}}
|
||||
[quo/collectible-list-item
|
||||
(assoc @state
|
||||
:counter (when (seq (:counter @state)) (:counter @state))
|
||||
:gradient-color-index (:gradient-color-index @state)
|
||||
:image-src test-image
|
||||
:avatar-image-src test-avatar
|
||||
:on-press #(js/alert "Pressed"))]])))
|
||||
@@ -2,8 +2,8 @@
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.config :as config]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defn login
|
||||
@@ -51,14 +51,14 @@
|
||||
(when path
|
||||
(string/replace-first path "file://" "")))
|
||||
|
||||
(re-frame/reg-event-fx :profile.config/get-node-config-callback
|
||||
(fn [{:keys [db]} [node-config-json]]
|
||||
(let [node-config (transforms/json->clj node-config-json)]
|
||||
{:db (assoc-in db
|
||||
[:profile/profile :wakuv2-config]
|
||||
(get node-config :WakuV2Config))})))
|
||||
(rf/defn get-node-config-callback
|
||||
{:events [:profile.config/get-node-config-callback]}
|
||||
[{:keys [db]} node-config-json]
|
||||
(let [node-config (transforms/json->clj node-config-json)]
|
||||
{:db (assoc-in db
|
||||
[:profile/profile :wakuv2-config]
|
||||
(get node-config :WakuV2Config))}))
|
||||
|
||||
(re-frame/reg-fx :profile.config/get-node-config
|
||||
(fn []
|
||||
(native-module/get-node-config
|
||||
#(re-frame/dispatch [:profile.config/get-node-config-callback %]))))
|
||||
(rf/defn get-node-config
|
||||
[_]
|
||||
(native-module/get-node-config #(rf/dispatch [:profile.config/get-node-config-callback %])))
|
||||
|
||||
@@ -2,21 +2,37 @@
|
||||
(:require
|
||||
[legacy.status-im.data-store.settings :as data-store.settings]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.contexts.profile.edit.accent-colour.events]
|
||||
[status-im.contexts.profile.edit.bio.events]
|
||||
[status-im.contexts.profile.edit.header.events]
|
||||
[status-im.contexts.profile.edit.name.events]
|
||||
status-im.contexts.profile.login.events
|
||||
[status-im.contexts.profile.login.events :as profile.login]
|
||||
[status-im.contexts.profile.rpc :as profile.rpc]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- select-profile
|
||||
[profile key-uid]
|
||||
(-> profile
|
||||
(assoc :key-uid key-uid)
|
||||
(dissoc :error :password)))
|
||||
(re-frame/reg-fx
|
||||
:profile/get-profiles-overview
|
||||
(fn [callback]
|
||||
(native-module/open-accounts callback)))
|
||||
|
||||
(defn- reduce-profiles
|
||||
(rf/defn profile-selected
|
||||
{:events [:profile/profile-selected]}
|
||||
[{:keys [db]} key-uid]
|
||||
{:db (update db
|
||||
:profile/login
|
||||
#(-> %
|
||||
(assoc :key-uid key-uid)
|
||||
(dissoc :error :password)))})
|
||||
|
||||
(rf/defn init-profiles-overview
|
||||
[{:keys [db] :as cofx} profiles key-uid]
|
||||
(rf/merge cofx
|
||||
{:db (assoc db :profile/profiles-overview profiles)}
|
||||
(profile-selected key-uid)))
|
||||
|
||||
(defn reduce-profiles
|
||||
[profiles]
|
||||
(reduce
|
||||
(fn [acc {:keys [key-uid] :as profile}]
|
||||
@@ -24,44 +40,28 @@
|
||||
{}
|
||||
profiles))
|
||||
|
||||
(rf/reg-fx
|
||||
:profile/get-profiles-overview
|
||||
(fn [callback]
|
||||
(native-module/open-accounts callback)))
|
||||
(rf/defn get-profiles-overview-success
|
||||
{:events [:profile/get-profiles-overview-success]}
|
||||
[cofx profiles-overview]
|
||||
(if (seq profiles-overview)
|
||||
(let [profiles (reduce-profiles profiles-overview)
|
||||
{:keys [key-uid]} (first (sort-by :timestamp > (vals profiles)))]
|
||||
(rf/merge cofx
|
||||
(navigation/init-root :profiles)
|
||||
(when key-uid (init-profiles-overview profiles key-uid))
|
||||
;;we check if biometric is available, and try to login with it,
|
||||
;;if succeed "node.login" signal will be triggered
|
||||
(when key-uid (profile.login/login-with-biometric-if-available key-uid))))
|
||||
(navigation/init-root cofx :intro)))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile/profile-selected
|
||||
(fn [{:keys [db]} [key-uid]]
|
||||
{:db (update db :profile/login #(select-profile % key-uid))}))
|
||||
(rf/defn update-setting-from-backup
|
||||
{:events [:profile/update-setting-from-backup]}
|
||||
[{:keys [db]} {:keys [backedUpSettings]}]
|
||||
(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/reg-event-fx
|
||||
:profile/get-profiles-overview-success
|
||||
(fn [{:keys [db]} [profiles-overview]]
|
||||
(if (seq profiles-overview)
|
||||
(let [profiles (reduce-profiles profiles-overview)
|
||||
{:keys [key-uid]} (first (sort-by :timestamp > (vals profiles)))]
|
||||
{:db (if key-uid
|
||||
(-> db
|
||||
(assoc :profile/profiles-overview profiles)
|
||||
(update :profile/login #(select-profile % key-uid)))
|
||||
db)
|
||||
:fx [[:set-root :profiles]
|
||||
(when key-uid
|
||||
[:effects.biometric/check-if-available
|
||||
{:key-uid key-uid
|
||||
:on-success (fn [auth-method]
|
||||
(rf/dispatch [:profile.login/check-biometric-success key-uid
|
||||
auth-method]))}])]})
|
||||
{:fx [[:set-root :intro]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile/update-setting-from-backup
|
||||
(fn [{:keys [db]} [{:keys [backedUpSettings]}]]
|
||||
(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/reg-event-fx
|
||||
:profile/update-profile-from-backup
|
||||
(fn [_ [{{:keys [ensUsernameDetails]} :backedUpProfile}]]
|
||||
{:fx [[:dispatch [:ens/update-usernames ensUsernameDetails]]]}))
|
||||
(rf/defn update-profile-from-backup
|
||||
{:events [:profile/update-profile-from-backup]}
|
||||
[_ {{:keys [ensUsernameDetails]} :backedUpProfile}]
|
||||
{:dispatch [:ens/update-usernames ensUsernameDetails]})
|
||||
|
||||
@@ -1,188 +1,210 @@
|
||||
(ns status-im.contexts.profile.login.events
|
||||
(:require
|
||||
[legacy.status-im.browser.core :as browser]
|
||||
[legacy.status-im.data-store.chats :as data-store.chats]
|
||||
[legacy.status-im.data-store.settings :as data-store.settings]
|
||||
[legacy.status-im.data-store.switcher-cards :as switcher-cards-store]
|
||||
[legacy.status-im.data-store.visibility-status-updates :as visibility-status-updates-store]
|
||||
[legacy.status-im.group-chats.core :as group-chats]
|
||||
[legacy.status-im.mailserver.core :as mailserver]
|
||||
[legacy.status-im.mobile-sync-settings.core :as mobile-network]
|
||||
[legacy.status-im.pairing.core :as pairing]
|
||||
[legacy.status-im.stickers.core :as stickers]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.common.keychain.events :as keychain]
|
||||
[status-im.common.log :as logging]
|
||||
[status-im.common.universal-links :as universal-links]
|
||||
[status-im.config :as config]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.chat.contacts.events :as contacts]
|
||||
[status-im.contexts.chat.messenger.messages.link-preview.events :as link-preview]
|
||||
[status-im.contexts.profile.config :as profile.config]
|
||||
status-im.contexts.profile.login.effects
|
||||
[status-im.contexts.profile.push-notifications.events :as notifications]
|
||||
[status-im.contexts.profile.rpc :as profile.rpc]
|
||||
[status-im.contexts.profile.settings.events :as profile.settings.events]
|
||||
[status-im.contexts.shell.activity-center.events :as activity-center]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.ethereum.chain :as chain]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-event-fx :profile.login/login
|
||||
(fn [{:keys [db]}]
|
||||
(let [{:keys [key-uid password]} (:profile/login db)
|
||||
login-sha3-password (native-module/sha3 (security/safe-unmask-data password))]
|
||||
{:db (-> db
|
||||
(assoc-in [:profile/login :processing] true)
|
||||
(assoc-in [:syncing :login-sha3-password] login-sha3-password))
|
||||
:fx [[:effects.profile/login [key-uid login-sha3-password]]]})))
|
||||
(rf/defn login
|
||||
{:events [:profile.login/login]}
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [key-uid password]} (:profile/login db)
|
||||
login-sha3-password (native-module/sha3 (security/safe-unmask-data password))]
|
||||
{:db (-> db
|
||||
(assoc-in [:profile/login :processing] true)
|
||||
(assoc-in [:syncing :login-sha3-password] login-sha3-password))
|
||||
:effects.profile/login [key-uid login-sha3-password]}))
|
||||
|
||||
(rf/reg-event-fx :profile.login/local-paired-user
|
||||
(fn [{:keys [db]}]
|
||||
(let [{:keys [key-uid password]} (get-in db [:syncing :profile])
|
||||
login-sha3-password (get-in db [:syncing :login-sha3-password])
|
||||
password (if-not (nil? login-sha3-password) ;; already logged in
|
||||
login-sha3-password
|
||||
password)
|
||||
masked-password (security/mask-data password)]
|
||||
{:db (-> db
|
||||
(assoc-in [:onboarding/profile :password] masked-password)
|
||||
(assoc-in [:onboarding/profile :syncing?] true))
|
||||
:effects.profile/login [key-uid password]})))
|
||||
(rf/defn biometrics-login
|
||||
{:events [:profile.login/biometrics-login]}
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [key-uid password]} (:profile/login db)]
|
||||
{:db (assoc-in db [:profile/login :processing] true)
|
||||
:effects.profile/login [key-uid (security/safe-unmask-data password)]}))
|
||||
|
||||
;; login phase 1: we want to load and show chats faster, so we split login into 2 phases
|
||||
(rf/reg-event-fx :profile.login/login-existing-profile
|
||||
(fn [{:keys [db]} [settings account]]
|
||||
(let [{:networks/keys [current-network networks]
|
||||
:as settings}
|
||||
(data-store.settings/rpc->settings settings)
|
||||
profile-overview (profile.rpc/rpc->profiles-overview account)
|
||||
log-level (or (:log-level settings) config/log-level)
|
||||
pairing-completed? (= (get-in db [:syncing :pairing-status]) :completed)]
|
||||
{:db (cond-> (-> db
|
||||
(assoc :chats/loading? true
|
||||
:networks/current-network current-network
|
||||
:networks/networks (merge networks config/default-networks-by-id)
|
||||
:profile/profile (merge profile-overview
|
||||
settings
|
||||
{:log-level log-level}))
|
||||
(assoc-in [:activity-center :loading?] true))
|
||||
pairing-completed?
|
||||
(dissoc :syncing))
|
||||
:fx (into [[:dispatch [:universal-links/generate-profile-url]]
|
||||
[:dispatch [:community/fetch]]
|
||||
[:dispatch [:wallet/initialize]]
|
||||
[:push-notifications/load-preferences]
|
||||
[:fetch-chats-preview
|
||||
{:on-success (fn [result]
|
||||
(rf/dispatch [:chats-list/load-success result])
|
||||
(rf/dispatch [:communities/get-user-requests-to-join])
|
||||
(rf/dispatch [:profile.login/get-chats-callback]))}]
|
||||
[:profile.config/get-node-config]
|
||||
[:logs/set-level log-level]
|
||||
[:activity-center.notifications/fetch-pending-contact-requests-fx]
|
||||
[:activity-center/update-seen-state]
|
||||
[:activity-center.notifications/fetch-unread-count]]
|
||||
(rf/defn login-local-paired-user
|
||||
{:events [:profile.login/local-paired-user]}
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [key-uid password]} (get-in db [:syncing :profile])
|
||||
login-sha3-password (get-in db [:syncing :login-sha3-password])
|
||||
password (if-not (nil? login-sha3-password) ;; already logged in
|
||||
login-sha3-password
|
||||
password)
|
||||
masked-password (security/mask-data password)]
|
||||
{:db (-> db
|
||||
(assoc-in [:onboarding/profile :password] masked-password)
|
||||
(assoc-in [:onboarding/profile :syncing?] true))
|
||||
:effects.profile/login [key-uid password]}))
|
||||
|
||||
(cond
|
||||
pairing-completed?
|
||||
[[:set-root :syncing-results]]
|
||||
(rf/defn redirect-to-root
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pairing-completed? (= (get-in db [:syncing :pairing-status]) :completed)]
|
||||
(cond
|
||||
pairing-completed?
|
||||
{:db (dissoc db :syncing)
|
||||
:dispatch [:init-root :syncing-results]}
|
||||
|
||||
(get db :onboarding/new-account?)
|
||||
[[:dispatch [:onboarding/finalize-setup]]]
|
||||
(get db :onboarding/new-account?)
|
||||
{:dispatch [:onboarding/finalize-setup]}
|
||||
|
||||
:else
|
||||
[[:profile.settings/switch-theme-fx
|
||||
[(or (get-in db [:profile/profile :appearance])
|
||||
constants/theme-type-dark)
|
||||
:shell-stack
|
||||
false]]
|
||||
[:set-root :shell-stack]]))})))
|
||||
:else
|
||||
(rf/merge
|
||||
cofx
|
||||
(profile.settings.events/switch-theme nil :shell-stack)
|
||||
(navigation/init-root :shell-stack)))))
|
||||
|
||||
;; login phase 2: we want to load and show chats faster, so we split login into 2 phases
|
||||
(rf/reg-event-fx :profile.login/get-chats-callback
|
||||
(fn [{:keys [db]}]
|
||||
(let [{:networks/keys [current-network networks]} db
|
||||
{:keys [notifications-enabled? key-uid
|
||||
preview-privacy?]} (:profile/profile db)
|
||||
network-id (str (get-in networks
|
||||
[current-network :config :NetworkId]))]
|
||||
{:db db
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "wakuext_startMessenger"
|
||||
:on-success [:profile.login/messenger-started]
|
||||
:on-error #(log/error
|
||||
"failed to start messenger")}]]
|
||||
[:check-eip1559-activation {:network-id network-id}]
|
||||
[:effects.profile/enable-local-notifications]
|
||||
[:contacts/initialize-contacts]
|
||||
[:browser/initialize-browser]
|
||||
[:dispatch [:mobile-network/on-network-status-change]]
|
||||
[:group-chats/get-group-chat-invitations]
|
||||
[:profile.settings/get-profile-picture key-uid]
|
||||
[:profile.settings/blank-preview-flag-changed preview-privacy?]
|
||||
[:chat.ui/request-link-preview-whitelist]
|
||||
[:visibility-status-updates/fetch]
|
||||
[:switcher-cards/fetch]
|
||||
(when-not (:universal-links/handling db)
|
||||
[:effects.chat/open-last-chat key-uid])
|
||||
(when notifications-enabled?
|
||||
[:effects/push-notifications-enable])]})))
|
||||
;; login phase 1, we want to load and show chats faster so we split login into 2 phases
|
||||
(rf/defn login-existing-profile
|
||||
[{:keys [db] :as cofx} settings account]
|
||||
(let [{:networks/keys [current-network networks]
|
||||
:as settings}
|
||||
(data-store.settings/rpc->settings settings)
|
||||
profile-overview (profile.rpc/rpc->profiles-overview account)]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc :chats/loading? true
|
||||
:networks/current-network current-network
|
||||
:networks/networks (merge networks config/default-networks-by-id)
|
||||
:profile/profile (merge profile-overview settings)))
|
||||
:fx [[:dispatch [:universal-links/generate-profile-url]]
|
||||
[:dispatch [:community/fetch]]
|
||||
[:dispatch [:wallet/initialize]]]}
|
||||
(notifications/load-preferences)
|
||||
(data-store.chats/fetch-chats-preview
|
||||
{:on-success
|
||||
#(do (re-frame/dispatch [:chats-list/load-success %])
|
||||
(rf/dispatch [:communities/get-user-requests-to-join])
|
||||
(re-frame/dispatch [:profile.login/get-chats-callback]))})
|
||||
(profile.config/get-node-config)
|
||||
(logging/set-log-level (:log-level settings))
|
||||
(activity-center/notifications-fetch-pending-contact-requests)
|
||||
(activity-center/update-seen-state)
|
||||
(activity-center/notifications-fetch-unread-count)
|
||||
(redirect-to-root))))
|
||||
|
||||
(rf/reg-event-fx :profile.login/messenger-started
|
||||
(fn [{:keys [db]} [{:keys [mailservers]}]]
|
||||
(let [chain-id (chain/chain-id db)
|
||||
new-account? (get db :onboarding/new-account?)]
|
||||
{:db (-> db
|
||||
(assoc :messenger/started? true)
|
||||
(mailserver/add-mailservers mailservers))
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "admin_nodeInfo"
|
||||
:on-success [:profile.login/node-info-fetched]
|
||||
:on-error #(log/error "node-info: failed error" %)}]]
|
||||
[:pairing/get-our-installations]
|
||||
[:stickers/load-packs chain-id]
|
||||
(when-not new-account?
|
||||
[:dispatch [:universal-links/process-stored-event]])]})))
|
||||
;; login phase 2, we want to load and show chats faster so we split login into 2 phases
|
||||
(rf/defn get-chats-callback
|
||||
{:events [:profile.login/get-chats-callback]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:networks/keys [current-network networks]} db
|
||||
{:keys [notifications-enabled?]} (:profile/profile db)
|
||||
current-network-config (get networks current-network)
|
||||
network-id (str (get-in networks
|
||||
[current-network :config :NetworkId]))]
|
||||
(rf/merge
|
||||
cofx
|
||||
(cond-> {:json-rpc/call [{:method "wakuext_startMessenger"
|
||||
:on-success #(re-frame/dispatch
|
||||
[:messenger-started %])
|
||||
:on-error #(log/error
|
||||
"failed to start messenger")}]
|
||||
:check-eip1559-activation {:network-id network-id}
|
||||
:effects.profile/enable-local-notifications nil}
|
||||
(not (:universal-links/handling db))
|
||||
(assoc :effects.chat/open-last-chat (get-in db [:profile/profile :key-uid]))
|
||||
notifications-enabled?
|
||||
(assoc :effects/push-notifications-enable nil))
|
||||
(contacts/initialize-contacts)
|
||||
(browser/initialize-browser)
|
||||
(mobile-network/on-network-status-change)
|
||||
(group-chats/get-group-chat-invitations)
|
||||
(profile.settings.events/get-profile-picture)
|
||||
(profile.settings.events/change-preview-privacy)
|
||||
(link-preview/request-link-preview-whitelist)
|
||||
(visibility-status-updates-store/fetch-visibility-status-updates-rpc)
|
||||
(switcher-cards-store/fetch-switcher-cards-rpc))))
|
||||
|
||||
(rf/reg-event-fx :profile.login/node-info-fetched
|
||||
(fn [{:keys [db]} [node-info]]
|
||||
{:db (assoc db :node-info node-info)}))
|
||||
(rf/defn messenger-started
|
||||
{:events [:messenger-started]}
|
||||
[{:keys [db] :as cofx} {:keys [mailservers] :as response}]
|
||||
(log/info "Messenger started")
|
||||
(let [new-account? (get db :onboarding/new-account?)]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc :messenger/started? true)
|
||||
(mailserver/add-mailservers mailservers))
|
||||
:json-rpc/call [{:method "admin_nodeInfo"
|
||||
:on-success #(re-frame/dispatch [:node-info-fetched %])
|
||||
:on-error #(log/error "node-info: failed error" %)}]}
|
||||
(pairing/init)
|
||||
(stickers/load-packs)
|
||||
(when-not new-account?
|
||||
(universal-links/process-stored-event)))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile.login/login-node-signal
|
||||
(fn [{{:onboarding/keys [recovered-account? new-account?] :as db} :db}
|
||||
[{:keys [settings account ensUsernames error]}]]
|
||||
(log/debug "[signals] node.login" "error" error)
|
||||
(if error
|
||||
{:db (update db :profile/login #(-> % (dissoc :processing) (assoc :error error)))}
|
||||
{:db (dissoc db :profile/login)
|
||||
:fx [[:logging/initialize-web3-client-version]
|
||||
(when (and new-account? (not recovered-account?))
|
||||
[:dispatch [:wallet-legacy/set-initial-blocks-range]])
|
||||
[:dispatch [:ens/update-usernames ensUsernames]]
|
||||
[:dispatch [:profile.login/login-existing-profile settings account]]]})))
|
||||
(rf/defn set-node-info
|
||||
{:events [:node-info-fetched]}
|
||||
[{:keys [db]} node-info]
|
||||
{:db (assoc db :node-info node-info)})
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile.login/login-with-biometric-if-available
|
||||
(fn [_ [key-uid]]
|
||||
{:fx [[:effects.biometric/check-if-available
|
||||
{:key-uid key-uid
|
||||
:on-success (fn [auth-method]
|
||||
(rf/dispatch
|
||||
[:profile.login/check-biometric-success
|
||||
key-uid auth-method]))}]]}))
|
||||
(rf/defn login-node-signal
|
||||
[{{:onboarding/keys [recovered-account? new-account?] :as db} :db :as cofx}
|
||||
{:keys [settings account ensUsernames error]}]
|
||||
(log/debug "[signals] node.login" "error" error)
|
||||
(if error
|
||||
{:db (update db :profile/login #(-> % (dissoc :processing) (assoc :error error)))}
|
||||
(rf/merge cofx
|
||||
{:db (dissoc db :profile/login)
|
||||
:dispatch-n [[:logging/initialize-web3-client-version]
|
||||
(when (and new-account? (not recovered-account?))
|
||||
[:wallet-legacy/set-initial-blocks-range])
|
||||
[:ens/update-usernames ensUsernames]]}
|
||||
(login-existing-profile settings account))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile.login/check-biometric-success
|
||||
(fn [{:keys [db]} [key-uid auth-method]]
|
||||
{:db (assoc db :auth-method auth-method)
|
||||
:fx [(when (= auth-method keychain/auth-method-biometric)
|
||||
[:keychain/password-hash-migration
|
||||
(rf/defn login-with-biometric-if-available
|
||||
{:events [:profile.login/login-with-biometric-if-available]}
|
||||
[_ key-uid]
|
||||
{:effects.biometric/check-if-available {:key-uid key-uid
|
||||
:on-success (fn [auth-method]
|
||||
(rf/dispatch
|
||||
[:profile.login/check-biometric-success
|
||||
key-uid auth-method]))}})
|
||||
|
||||
(rf/defn check-biometric-success
|
||||
{:events [:profile.login/check-biometric-success]}
|
||||
[{:keys [db]} key-uid auth-method]
|
||||
(merge {:db (assoc db :auth-method auth-method)}
|
||||
(when (= auth-method keychain/auth-method-biometric)
|
||||
{:keychain/password-hash-migration
|
||||
{:key-uid key-uid
|
||||
:callback (fn []
|
||||
(rf/dispatch
|
||||
[:biometric/authenticate
|
||||
{:on-success #(rf/dispatch
|
||||
[:profile.login/biometric-success])
|
||||
:on-fail #(rf/dispatch
|
||||
[:profile.login/biometric-auth-fail %])}]))}])]}))
|
||||
(rf/dispatch [:biometric/authenticate
|
||||
{:on-success #(rf/dispatch [:profile.login/biometric-success])
|
||||
:on-fail #(rf/dispatch
|
||||
[:profile.login/biometric-auth-fail %])}]))}})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile.login/get-user-password-success
|
||||
(fn [{:keys [db]} [password]]
|
||||
(when password
|
||||
(let [{:keys [key-uid password]} (:profile/login db)]
|
||||
{:db (-> db
|
||||
(assoc-in [:profile/login :password] password)
|
||||
(assoc-in [:profile/login :processing] true))
|
||||
:fx [[:set-root :progress]
|
||||
[:effects.profile/login [key-uid (security/safe-unmask-data password)]]]}))))
|
||||
(rf/defn get-user-password-success
|
||||
{:events [:profile.login/get-user-password-success]}
|
||||
[{:keys [db] :as cofx} password]
|
||||
(when password
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc-in db [:profile/login :password] password)}
|
||||
(navigation/init-root :progress)
|
||||
(biometrics-login))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile.login/biometric-success
|
||||
@@ -201,35 +223,35 @@
|
||||
:event :profile.login/biometric-auth-fail)))
|
||||
{:dispatch [:biometric/show-message (ex-cause error)]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile.login/verify-database-password
|
||||
(fn [_ [entered-password cb]]
|
||||
(let [hashed-password (-> entered-password
|
||||
security/safe-unmask-data
|
||||
native-module/sha3)]
|
||||
{:json-rpc/call [{:method "accounts_verifyPassword"
|
||||
:params [hashed-password]
|
||||
:on-success #(rf/dispatch [:profile.login/verified-database-password % cb])
|
||||
:on-error #(log/error "accounts_verifyPassword error" %)}]})))
|
||||
(rf/defn verify-database-password
|
||||
{:events [:profile.login/verify-database-password]}
|
||||
[_ entered-password cb]
|
||||
(let [hashed-password (-> entered-password
|
||||
security/safe-unmask-data
|
||||
native-module/sha3)]
|
||||
{:json-rpc/call [{:method "accounts_verifyPassword"
|
||||
:params [hashed-password]
|
||||
:on-success #(rf/dispatch [:profile.login/verified-database-password % cb])
|
||||
:on-error #(log/error "accounts_verifyPassword error" %)}]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile.login/verified-database-password
|
||||
(fn [{:keys [db]} [valid? callback]]
|
||||
(if valid?
|
||||
(do
|
||||
(when (fn? callback)
|
||||
(callback))
|
||||
{:db (update db
|
||||
:profile/login
|
||||
dissoc
|
||||
:processing :error)})
|
||||
{:db (update db
|
||||
:profile/login
|
||||
#(-> %
|
||||
(dissoc :processing)
|
||||
(assoc :error "Invalid password")))})))
|
||||
(rf/defn verify-database-password-success
|
||||
{:events [:profile.login/verified-database-password]}
|
||||
[{:keys [db]} valid? callback]
|
||||
(if valid?
|
||||
(do
|
||||
(when (fn? callback)
|
||||
(callback))
|
||||
{:db (update db
|
||||
:profile/login
|
||||
dissoc
|
||||
:processing :error)})
|
||||
{:db (update db
|
||||
:profile/login
|
||||
#(-> %
|
||||
(dissoc :processing)
|
||||
(assoc :error "Invalid password")))}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
(re-frame/reg-event-fx
|
||||
:profile/on-password-input-changed
|
||||
(fn [{:keys [db]} [{:keys [password error]}]]
|
||||
{:db (update db :profile/login assoc :password password :error error)}))
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
(:require
|
||||
[cljs-bean.core :as bean]
|
||||
[native-module.push-notifications :as native-module.pn]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.async-storage :as async-storage]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.push-notification-ios :as pn-ios]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.config :as config]
|
||||
status-im.contexts.profile.push-notifications.effects
|
||||
[taoensso.timbre :as log]
|
||||
@@ -57,8 +55,8 @@
|
||||
[{:keys [db]} preferences]
|
||||
{:db (assoc db :push-notifications/preferences preferences)})
|
||||
|
||||
(re-frame/reg-fx :push-notifications/load-preferences
|
||||
(fn []
|
||||
(json-rpc/call {:method "localnotifications_notificationPreferences"
|
||||
:params []
|
||||
:on-success [:push-notifications/preferences-loaded]})))
|
||||
(rf/defn load-preferences
|
||||
[_]
|
||||
{:json-rpc/call [{:method "localnotifications_notificationPreferences"
|
||||
:params []
|
||||
:on-success #(rf/dispatch [:push-notifications/preferences-loaded %])}]})
|
||||
|
||||
@@ -1,47 +1,63 @@
|
||||
(ns status-im.contexts.profile.settings.events
|
||||
(:require [clojure.string :as string]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[legacy.status-im.bottom-sheet.events :as bottom-sheet.events]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
status-im.contexts.profile.settings.effects
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- set-setting-value
|
||||
[db setting setting-value]
|
||||
(if setting-value
|
||||
(assoc-in db [:profile/profile setting] setting-value)
|
||||
(update db :profile/profile dissoc setting)))
|
||||
(rf/defn send-contact-update
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [name preferred-name display-name]} (:profile/profile db)]
|
||||
{:json-rpc/call [{:method "wakuext_sendContactUpdates"
|
||||
:params [(or preferred-name display-name name) ""]
|
||||
:on-success #(log/debug "sent contact update")}]}))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/profile-update
|
||||
(fn [{:keys [db]} [setting setting-value {:keys [dont-sync? on-success]}]]
|
||||
{:db (-> db
|
||||
(set-setting-value setting setting-value))
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "settings_saveSetting"
|
||||
:params [setting setting-value]
|
||||
:on-success on-success}]]
|
||||
(rf/defn profile-update
|
||||
{:events [:profile.settings/profile-update]}
|
||||
[{:keys [db] :as cofx}
|
||||
setting setting-value
|
||||
{:keys [dont-sync? on-success] :or {on-success #()}}]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (if setting-value
|
||||
(assoc-in db [:profile/profile setting] setting-value)
|
||||
(update db :profile/profile dissoc setting))
|
||||
:json-rpc/call
|
||||
[{:method "settings_saveSetting"
|
||||
:params [setting setting-value]
|
||||
:on-success on-success}]}
|
||||
|
||||
(when (#{:name :preferred-name} setting)
|
||||
[:profile/get-profiles-overview #(rf/dispatch [:multiaccounts.ui/update-name %])])
|
||||
(when (#{:name :preferred-name} setting)
|
||||
(constantly {:profile/get-profiles-overview #(rf/dispatch [:multiaccounts.ui/update-name %])}))
|
||||
|
||||
(when (and (not dont-sync?) (#{:name :preferred-name} setting))
|
||||
(let [{:keys [name preferred-name display-name]} (:profile/profile db)]
|
||||
[:json-rpc/call
|
||||
[{:method "wakuext_sendContactUpdates"
|
||||
:params [(or preferred-name display-name name) ""]
|
||||
:on-success #(log/debug "sent contact update")}]]))]}))
|
||||
(when (and (not dont-sync?) (#{:name :preferred-name} setting))
|
||||
(send-contact-update))))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/change-preview-privacy
|
||||
(fn [{:keys [db]}]
|
||||
(let [private? (get-in db [:profile/profile :preview-privacy?])]
|
||||
{:fx [[:profile.settings/blank-preview-flag-changed private?]]})))
|
||||
(rf/defn optimistic-profile-update
|
||||
[{:keys [db]} setting setting-value]
|
||||
{:db (if setting-value
|
||||
(assoc-in db [:profile/profile setting] setting-value)
|
||||
(update db :profile/profile dissoc setting))})
|
||||
|
||||
(rf/reg-event-fx :profile.settings/change-webview-debug
|
||||
(fn [_ [value]]
|
||||
(let [value' (boolean value)]
|
||||
{:fx [[:dispatch [:profile.settings/profile-update :webview-debug value']]
|
||||
[:profile.settings/webview-debug-changed value']]})))
|
||||
(rf/defn change-preview-privacy
|
||||
[{:keys [db]}]
|
||||
(let [private? (get-in db [:profile/profile :preview-privacy?])]
|
||||
{:profile.settings/blank-preview-flag-changed private?}))
|
||||
|
||||
(rf/defn update-value
|
||||
{:events [:profile.settings/update-value]}
|
||||
[cofx key value]
|
||||
(profile-update cofx key value {}))
|
||||
|
||||
(rf/defn change-webview-debug
|
||||
{:events [:profile.settings/change-webview-debug]}
|
||||
[{:keys [db] :as cofx} value]
|
||||
(rf/merge cofx
|
||||
{:profile.settings/webview-debug-changed value}
|
||||
(profile-update :webview-debug (boolean value) {})))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/toggle-test-networks
|
||||
(fn [{:keys [db]}]
|
||||
@@ -66,22 +82,17 @@
|
||||
{:on-success on-success}])
|
||||
:on-cancel nil}]]})))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/change-preview-privacy
|
||||
(fn [_ [private?]]
|
||||
(let [private?' (boolean private?)]
|
||||
{:fx [[:dispatch [:profile.settings/profile-update :preview-privacy? private?']]
|
||||
[:profile.settings/blank-preview-flag-changed private?']]})))
|
||||
(rf/defn change-preview-privacy-flag
|
||||
{:events [:profile.settings/change-preview-privacy]}
|
||||
[{:keys [db] :as cofx} private?]
|
||||
(rf/merge cofx
|
||||
{:profile.settings/blank-preview-flag-changed private?}
|
||||
(profile-update
|
||||
:preview-privacy?
|
||||
(boolean private?)
|
||||
{})))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/change-profile-pictures-show-to
|
||||
(fn [{:keys [db]} [id]]
|
||||
{:db (-> db
|
||||
(assoc-in [:profile/profile :profile-pictures-show-to] id))
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "wakuext_changeIdentityImageShowTo"
|
||||
:params [id]
|
||||
:on-success #(log/debug "picture settings changed successfully")}]]]}))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/toggle-peer-syncing
|
||||
(re-frame/reg-event-fx :profile.settings/toggle-peer-syncing
|
||||
(fn [{:keys [db]}]
|
||||
(let [value (get-in db [:profile/profile :peer-syncing-enabled?])
|
||||
new-value (not value)]
|
||||
@@ -91,69 +102,81 @@
|
||||
:params [{:enabled new-value}]
|
||||
:on-error #(log/error "failed to toggle peer syncing" new-value %)}]]]})))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/change-appearance
|
||||
(fn [_ [theme]]
|
||||
{:fx [[:dispatch [:profile.settings/profile-update :appearance theme]]
|
||||
[:profile.settings/switch-theme-fx [theme :appearance true]]]}))
|
||||
(rf/defn change-profile-pictures-show-to
|
||||
{:events [:profile.settings/change-profile-pictures-show-to]}
|
||||
[cofx id]
|
||||
(rf/merge cofx
|
||||
{:json-rpc/call [{:method "wakuext_changeIdentityImageShowTo"
|
||||
:params [id]
|
||||
:on-success #(log/debug "picture settings changed successfully")}]}
|
||||
(optimistic-profile-update :profile-pictures-show-to id)))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/switch-theme
|
||||
(fn [{:keys [db]} [theme view-id]]
|
||||
(let [theme (or theme
|
||||
(get-in db [:profile/profile :appearance])
|
||||
constants/theme-type-dark)]
|
||||
{:fx [[:profile.settings/switch-theme-fx [theme view-id false]]]})))
|
||||
(rf/defn change-appearance
|
||||
{:events [:profile.settings/change-appearance]}
|
||||
[cofx theme]
|
||||
(rf/merge cofx
|
||||
{:profile.settings/switch-theme-fx [theme :appearance true]}
|
||||
(profile-update :appearance theme {})))
|
||||
|
||||
(rf/reg-fx :profile.settings/get-profile-picture
|
||||
(fn [key-uid]
|
||||
(json-rpc/call {:method "multiaccounts_getIdentityImages"
|
||||
:params [key-uid]
|
||||
:on-success [:profile.settings/update-local-picture]})))
|
||||
(rf/defn switch-theme
|
||||
{:events [:profile.settings/switch-theme]}
|
||||
[cofx theme view-id]
|
||||
(let [theme (or theme
|
||||
(get-in cofx [:db :profile/profile :appearance])
|
||||
constants/theme-type-dark)]
|
||||
{:profile.settings/switch-theme-fx [theme view-id false]}))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/save-profile-picture
|
||||
(fn [{:keys [db]} [path ax ay bx by]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:db (-> db
|
||||
(assoc :bottom-sheet/show? false))
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "multiaccounts_storeIdentityImage"
|
||||
:params [key-uid (string/replace-first path #"file://" "") ax ay bx
|
||||
by]
|
||||
:on-success [:profile.settings/update-local-picture]}]]
|
||||
[:dismiss-bottom-sheet-overlay-old]]})))
|
||||
(rf/defn get-profile-picture
|
||||
{:events [:profile.settings/get-profile-picture]}
|
||||
[cofx]
|
||||
(let [key-uid (get-in cofx [:db :profile/profile :key-uid])]
|
||||
{:json-rpc/call [{:method "multiaccounts_getIdentityImages"
|
||||
:params [key-uid]
|
||||
:on-success [:profile.settings/update-local-picture]}]}))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/save-profile-picture-from-url
|
||||
(fn [{:keys [db]} [url]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:db (-> db
|
||||
(assoc :bottom-sheet/show? false))
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "multiaccounts_storeIdentityImageFromURL"
|
||||
:params [key-uid url]
|
||||
:on-error #(log/error "::save-profile-picture-from-url error" %)
|
||||
:on-success [:profile.settings/update-local-picture]}]]
|
||||
[:dismiss-bottom-sheet-overlay-old]]})))
|
||||
(rf/defn save-profile-picture
|
||||
{:events [:profile.settings/save-profile-picture]}
|
||||
[cofx path ax ay bx by]
|
||||
(let [key-uid (get-in cofx [:db :profile/profile :key-uid])]
|
||||
(rf/merge cofx
|
||||
{:json-rpc/call [{:method "multiaccounts_storeIdentityImage"
|
||||
:params [key-uid (string/replace-first path #"file://" "") ax ay bx
|
||||
by]
|
||||
:on-success [:profile.settings/update-local-picture]}]}
|
||||
(bottom-sheet.events/hide-bottom-sheet-old))))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/delete-profile-picture
|
||||
(fn [{:keys [db]}]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:db (-> db
|
||||
(update :profile/profile dissoc :images)
|
||||
(assoc :bottom-sheet/show? false))
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "multiaccounts_deleteIdentityImage"
|
||||
:params [key-uid]
|
||||
;; NOTE: In case of an error we could fallback to previous image in
|
||||
;; UI with a toast error
|
||||
:on-success #(log/info "[profile] Delete profile image" %)}]]
|
||||
[:dismiss-bottom-sheet-overlay-old]]})))
|
||||
(rf/defn save-profile-picture-from-url
|
||||
{:events [:profile.settings/save-profile-picture-from-url]}
|
||||
[cofx url]
|
||||
(let [key-uid (get-in cofx [:db :profile/profile :key-uid])]
|
||||
(rf/merge cofx
|
||||
{:json-rpc/call [{:method "multiaccounts_storeIdentityImageFromURL"
|
||||
:params [key-uid url]
|
||||
:on-error #(log/error "::save-profile-picture-from-url error" %)
|
||||
:on-success [:profile.settings/update-local-picture]}]}
|
||||
(bottom-sheet.events/hide-bottom-sheet-old))))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/update-local-picture
|
||||
(fn [{:keys [db]} [images]]
|
||||
{:db (assoc-in db [:profile/profile :images] images)}))
|
||||
(rf/defn delete-profile-picture
|
||||
{:events [:profile.settings/delete-profile-picture]}
|
||||
[cofx name]
|
||||
(let [key-uid (get-in cofx [:db :profile/profile :key-uid])]
|
||||
(rf/merge cofx
|
||||
{:json-rpc/call [{:method "multiaccounts_deleteIdentityImage"
|
||||
:params [key-uid]
|
||||
;; NOTE: In case of an error we could fallback to previous image in
|
||||
;; UI with a toast error
|
||||
:on-success #(log/info "[profile] Delete profile image" %)}]}
|
||||
(optimistic-profile-update :images nil)
|
||||
(bottom-sheet.events/hide-bottom-sheet-old))))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/mnemonic-was-shown
|
||||
(fn [_]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "settings_mnemonicWasShown"
|
||||
:on-success #(log/debug "mnemonic was marked as shown")
|
||||
:on-error #(log/error "mnemonic was not marked as shown" %)}]]]}))
|
||||
(rf/defn store-profile-picture
|
||||
{:events [:profile.settings/update-local-picture]}
|
||||
[cofx pics]
|
||||
(optimistic-profile-update cofx :images pics))
|
||||
|
||||
(rf/defn mark-mnemonic-as-shown
|
||||
{:events [:profile.settings/mnemonic-was-shown]}
|
||||
[cofx]
|
||||
{:json-rpc/call [{:method "settings_mnemonicWasShown"
|
||||
:on-success #(log/debug "mnemonic was marked as shown")
|
||||
:on-error #(log/error "mnemonic was not marked as shown" %)}]})
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
[legacy.status-im.data-store.chats :as data-store.chats]
|
||||
[quo.foundations.colors :as colors]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.common.toasts.events :as toasts]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.shell.activity-center.notification-types :as types]
|
||||
@@ -409,17 +408,6 @@
|
||||
(constantly processed)
|
||||
#(concat % processed))))}))
|
||||
|
||||
(re-frame/reg-fx :activity-center.notifications/fetch-pending-contact-requests-fx
|
||||
(fn []
|
||||
(json-rpc/call {:method "wakuext_activityCenterNotifications"
|
||||
:params [{:cursor start-or-end-cursor
|
||||
:limit 20
|
||||
:activityTypes [types/contact-request]
|
||||
:readType (->rpc-read-type :unread)}]
|
||||
:on-success [:activity-center.notifications/fetch-pending-contact-requests-success]
|
||||
:on-error [:activity-center.notifications/fetch-error types/contact-request
|
||||
:unread]})))
|
||||
|
||||
(rf/defn notifications-fetch-pending-contact-requests
|
||||
"Unread contact requests are, in practical terms, the same as pending contact
|
||||
requests in the Activity Center, because pending contact requests are always
|
||||
@@ -431,7 +419,14 @@
|
||||
{:events [:activity-center.notifications/fetch-pending-contact-requests]}
|
||||
[{:keys [db]}]
|
||||
{:db (assoc-in db [:activity-center :loading?] true)
|
||||
:fx [[:activity-center.notifications/fetch-pending-contact-requests-fx]]})
|
||||
:json-rpc/call
|
||||
[{:method "wakuext_activityCenterNotifications"
|
||||
:params [{:cursor start-or-end-cursor
|
||||
:limit 20
|
||||
:activityTypes [types/contact-request]
|
||||
:readType (->rpc-read-type :unread)}]
|
||||
:on-success [:activity-center.notifications/fetch-pending-contact-requests-success]
|
||||
:on-error [:activity-center.notifications/fetch-error types/contact-request :unread]}]})
|
||||
|
||||
(rf/defn notifications-fetch-pending-contact-requests-success
|
||||
{:events [:activity-center.notifications/fetch-pending-contact-requests-success]}
|
||||
@@ -453,12 +448,14 @@
|
||||
|
||||
;;;; Unread counters
|
||||
|
||||
(re-frame/reg-fx :activity-center/update-seen-state
|
||||
(fn []
|
||||
(json-rpc/call [{:method "wakuext_hasUnseenActivityCenterNotifications"
|
||||
:params []
|
||||
:on-success [:activity-center/update-seen-state-success]
|
||||
:on-error [:activity-center/update-seen-state-error]}])))
|
||||
(rf/defn update-seen-state
|
||||
{:events [:activity-center/update-seen-state]}
|
||||
[_]
|
||||
{:json-rpc/call
|
||||
[{:method "wakuext_hasUnseenActivityCenterNotifications"
|
||||
:params []
|
||||
:on-success [:activity-center/update-seen-state-success]
|
||||
:on-error [:activity-center/update-seen-state-error]}]})
|
||||
|
||||
(rf/defn update-seen-state-success
|
||||
{:events [:activity-center/update-seen-state-success]}
|
||||
@@ -495,14 +492,6 @@
|
||||
{:error error
|
||||
:event :activity-center/mark-as-seen}))
|
||||
|
||||
(re-frame/reg-fx :activity-center.notifications/fetch-unread-count
|
||||
(fn []
|
||||
(json-rpc/call {:method "wakuext_activityCenterNotificationsCount"
|
||||
:params [{:activityTypes types/all-supported
|
||||
:readType (->rpc-read-type :unread)}]
|
||||
:on-success [:activity-center.notifications/fetch-unread-count-success]
|
||||
:on-error [:activity-center.notifications/fetch-unread-count-error]})))
|
||||
|
||||
(rf/defn notifications-fetch-unread-count
|
||||
{:events [:activity-center.notifications/fetch-unread-count]}
|
||||
[_]
|
||||
|
||||
@@ -303,15 +303,3 @@
|
||||
label-props
|
||||
(assoc :label :text
|
||||
:label-props label-props)))
|
||||
|
||||
(defn get-default-chain-ids-by-mode
|
||||
[{:keys [test-networks-enabled? is-goerli-enabled?]}]
|
||||
(cond
|
||||
(and test-networks-enabled? is-goerli-enabled?)
|
||||
constants/goerli-chain-ids
|
||||
|
||||
test-networks-enabled?
|
||||
constants/sepolia-chain-ids
|
||||
|
||||
:else
|
||||
constants/mainnet-chain-ids))
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view
|
||||
:as network-preferences]
|
||||
[status-im.contexts.wallet.sheets.remove-account.view :as remove-account]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -66,10 +67,13 @@
|
||||
[create-or-edit-account/view
|
||||
{:page-nav-right-side [(when-not default-account?
|
||||
{:icon-name :i/delete
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[remove-account/view])}])})]
|
||||
:on-press
|
||||
#(ff/alert ::ff/wallet.remove-account
|
||||
(fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[remove-account/view])}])))})]
|
||||
:account-name account-name
|
||||
:account-emoji emoji
|
||||
:account-color color
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[clojure.string :as string]
|
||||
[react-native.background-timer :as background-timer]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.accounts.add-account.address-to-watch.events]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.data-store :as data-store]
|
||||
@@ -94,16 +95,10 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet/remove-account-success
|
||||
(fn [_ [toast-message _]]
|
||||
{:fx [[:dispatch [:wallet/get-accounts]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:hide-bottom-sheet]}]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:pop-to-root :shell-stack]}]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:wallet/show-account-deleted-toast toast-message]}]]}))
|
||||
{:fx [[:dispatch [:hide-bottom-sheet]]
|
||||
[:dispatch [:pop-to-root :shell-stack]]
|
||||
[:dispatch [:wallet/get-accounts]]
|
||||
[:dispatch [:wallet/show-account-deleted-toast toast-message]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/remove-account
|
||||
@@ -446,15 +441,16 @@
|
||||
(fn [{:keys [db]} [{:keys [message]}]]
|
||||
(let [chains (-> (transforms/json->clj message)
|
||||
(update-keys (comp utils.number/parse-int name)))
|
||||
down-chain-ids (-> (select-keys chains
|
||||
down-chains (-> (select-keys chains
|
||||
(for [[k v] chains :when (= v "down")] k))
|
||||
keys)
|
||||
test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
is-goerli-enabled? (get-in db [:profile/profile :is-goerli-enabled?])
|
||||
chain-ids-by-mode (utils/get-default-chain-ids-by-mode
|
||||
{:test-networks-enabled? test-networks-enabled?
|
||||
:is-goerli-enabled? is-goerli-enabled?})
|
||||
chains-filtered-by-mode (remove #(not (contains? chain-ids-by-mode %)) down-chain-ids)
|
||||
disabled-chain-id? (fn [chain-id]
|
||||
(let [mainnet-chain? (contains? constants/mainnet-chain-ids chain-id)]
|
||||
(if test-networks-enabled?
|
||||
mainnet-chain?
|
||||
(not mainnet-chain?))))
|
||||
chains-filtered-by-mode (remove disabled-chain-id? down-chains)
|
||||
chains-down? (seq chains-filtered-by-mode)
|
||||
chain-names (when chains-down?
|
||||
(->> (map #(-> (utils/id->network %)
|
||||
@@ -463,10 +459,9 @@
|
||||
chains-filtered-by-mode)
|
||||
distinct
|
||||
(string/join ", ")))]
|
||||
(when (seq down-chain-ids)
|
||||
(log/info "[wallet] Chain(s) down: " down-chain-ids)
|
||||
(log/info "[wallet] Test network enabled: " (boolean test-networks-enabled?))
|
||||
(log/info "[wallet] Goerli network enabled: " (boolean is-goerli-enabled?)))
|
||||
(when (seq down-chains)
|
||||
(log/info "[wallet] Chain(s) down: " down-chains)
|
||||
(log/info "[wallet] Test network enabled: " (boolean test-networks-enabled?)))
|
||||
{:db (assoc-in db [:wallet :statuses :blockchains] chains)
|
||||
:fx (when chains-down?
|
||||
[[:dispatch
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.home.top-nav.view :as common.top-nav]
|
||||
[status-im.contexts.wallet.home.style :as style]
|
||||
[status-im.contexts.wallet.home.tabs.view :as tabs]
|
||||
@@ -38,49 +39,39 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [[selected-tab set-selected-tab] (rn/use-state (:id (first tabs-data)))
|
||||
account-list-ref (rn/use-ref-atom nil)
|
||||
tokens-loading? (rf/sub [:wallet/tokens-loading?])
|
||||
networks (rf/sub [:wallet/network-details])
|
||||
account-cards-data (rf/sub [:wallet/account-cards-data])
|
||||
cards (conj account-cards-data (new-account-card-data))
|
||||
|
||||
{:keys [formatted-balance]} (rf/sub [:wallet/aggregated-tokens-and-balance])]
|
||||
(rn/use-effect (fn []
|
||||
(when (and @account-list-ref (pos? (count cards)))
|
||||
(.scrollToOffset ^js @account-list-ref
|
||||
#js
|
||||
{:animated true
|
||||
:offset 0}
|
||||
)))
|
||||
[(count cards)])
|
||||
[rn/view {:style (style/home-container)}
|
||||
[common.top-nav/view]
|
||||
[rn/view {:style style/overview-container}
|
||||
[quo/wallet-overview
|
||||
{:state (if tokens-loading? :loading :default)
|
||||
:time-frame :none
|
||||
:metrics :none
|
||||
:balance formatted-balance
|
||||
:networks networks
|
||||
:dropdown-on-press #(ff/alert ::ff/wallet.network-filter
|
||||
(fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content network-filter/view}])))}]]
|
||||
[quo/wallet-graph {:time-frame :empty}]
|
||||
[rn/flat-list
|
||||
{:ref #(reset! account-list-ref %)
|
||||
:style style/accounts-list
|
||||
:content-container-style style/accounts-list-container
|
||||
:data cards
|
||||
:horizontal true
|
||||
:separator [rn/view {:style style/separator}]
|
||||
:render-fn (fn [item] [quo/account-card item])
|
||||
:shows-horizontal-scroll-indicator false}]
|
||||
[quo/tabs
|
||||
{:style style/tabs
|
||||
:size 32
|
||||
:default-active selected-tab
|
||||
:data tabs-data
|
||||
:on-change #(set-selected-tab %)}]
|
||||
[tabs/view {:selected-tab selected-tab}]]))
|
||||
(let [selected-tab (reagent/atom (:id (first tabs-data)))]
|
||||
(fn []
|
||||
(let [tokens-loading? (rf/sub [:wallet/tokens-loading?])
|
||||
networks (rf/sub [:wallet/network-details])
|
||||
account-cards-data (rf/sub [:wallet/account-cards-data])
|
||||
cards (conj account-cards-data (new-account-card-data))
|
||||
{:keys [formatted-balance]} (rf/sub [:wallet/aggregated-tokens-and-balance])]
|
||||
[rn/view {:style (style/home-container)}
|
||||
[common.top-nav/view]
|
||||
[rn/view {:style style/overview-container}
|
||||
[quo/wallet-overview
|
||||
{:state (if tokens-loading? :loading :default)
|
||||
:time-frame :none
|
||||
:metrics :none
|
||||
:balance formatted-balance
|
||||
:networks networks
|
||||
:dropdown-on-press #(ff/alert ::ff/wallet.network-filter
|
||||
(fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content network-filter/view}])))}]]
|
||||
[quo/wallet-graph {:time-frame :empty}]
|
||||
[rn/flat-list
|
||||
{:style style/accounts-list
|
||||
:content-container-style style/accounts-list-container
|
||||
:data cards
|
||||
:horizontal true
|
||||
:separator [rn/view {:style style/separator}]
|
||||
:render-fn (fn [item] [quo/account-card item])
|
||||
:shows-horizontal-scroll-indicator false}]
|
||||
[quo/tabs
|
||||
{:style style/tabs
|
||||
:size 32
|
||||
:default-active @selected-tab
|
||||
:data tabs-data
|
||||
:on-change #(reset! selected-tab %)}]
|
||||
[tabs/view {:selected-tab @selected-tab}]]))))
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
(ns status-im.contexts.wallet.send.save-address.style)
|
||||
|
||||
(def title-input-container
|
||||
{:padding-horizontal 20
|
||||
:padding-top 12
|
||||
:padding-bottom 16})
|
||||
|
||||
(def account-avatar-container
|
||||
{:padding-horizontal 20
|
||||
:padding-top 12})
|
||||
|
||||
(def color-picker-top-divider
|
||||
{:margin-bottom 12})
|
||||
|
||||
(def color-picker-container
|
||||
{:padding-vertical 12})
|
||||
|
||||
(def section-container
|
||||
{:padding-horizontal 20
|
||||
:padding-bottom 4})
|
||||
|
||||
(def color-picker
|
||||
{:padding-horizontal 20
|
||||
:padding-top 12})
|
||||
|
||||
(def color-picker-bottom-divider
|
||||
{:padding-top 8
|
||||
:padding-bottom 12})
|
||||
|
||||
(def save-address-button
|
||||
{:padding-horizontal 20})
|
||||
|
||||
(def data-item
|
||||
{:margin-horizontal 20
|
||||
:padding-vertical 8})
|
||||
|
||||
(def address-container
|
||||
{:padding-top 8
|
||||
:padding-bottom 12})
|
||||
@@ -1,89 +0,0 @@
|
||||
(ns status-im.contexts.wallet.send.save-address.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.contexts.wallet.send.save-address.style :as style]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view
|
||||
:as network-preferences]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- address-view
|
||||
[address]
|
||||
(let [network-details (rf/sub [:wallet/network-preference-details])]
|
||||
[rn/view {:style style/address-container}
|
||||
[quo/data-item
|
||||
{:status :default
|
||||
:size :default
|
||||
:subtitle-type :default
|
||||
:label :none
|
||||
:blur? false
|
||||
:icon-right? true
|
||||
:right-icon :i/advanced
|
||||
:card? true
|
||||
:title (i18n/label :t/address)
|
||||
:custom-subtitle (rn/use-callback
|
||||
(fn [] [quo/address-text
|
||||
{:networks network-details
|
||||
:address address
|
||||
:format :long}]))
|
||||
:on-press (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[network-preferences/view
|
||||
{:on-save (fn [])}])}])))
|
||||
:container-style style/data-item}]]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [[address-label set-address-label] (rn/use-state "")
|
||||
[address-color set-address-color] (rn/use-state :blue)
|
||||
placeholder (i18n/label :t/address-name)]
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding 0
|
||||
:header [quo/page-nav
|
||||
{:type :no-title
|
||||
:background :blur
|
||||
:icon-name :i/close
|
||||
:on-press (rn/use-callback #(rf/dispatch [:navigate-back]))
|
||||
:accessibility-label :save-address-top-bar}]
|
||||
:footer [quo/button
|
||||
{:accessibility-label :save-address-button
|
||||
:type :primary
|
||||
:container-style style/save-address-button}
|
||||
(i18n/label :t/save-address)]
|
||||
:customization-color address-color
|
||||
:gradient-cover? true}
|
||||
[rn/view
|
||||
{:style style/account-avatar-container}
|
||||
[quo/user-avatar
|
||||
{:full-name (if (string/blank? address-label)
|
||||
placeholder
|
||||
address-label)
|
||||
:customization-color address-color
|
||||
:size :big}]]
|
||||
[quo/title-input
|
||||
{:blur? true
|
||||
:auto-focus true
|
||||
:max-length 24
|
||||
:size :heading-1
|
||||
:placeholder placeholder
|
||||
:default-value address-label
|
||||
:on-change-text set-address-label
|
||||
:customization-color address-color
|
||||
:container-style style/title-input-container}]
|
||||
[quo/divider-line {:container-style style/color-picker-top-divider}]
|
||||
[quo/section-label
|
||||
{:section (i18n/label :t/colour)
|
||||
:container-style style/section-container}]
|
||||
[quo/color-picker
|
||||
{:default-selected address-color
|
||||
:on-change set-address-color
|
||||
:container-style style/color-picker}]
|
||||
[quo/divider-line {:container-style style/color-picker-bottom-divider}]
|
||||
[address-view "0xshivek"]]))
|
||||
@@ -25,23 +25,6 @@
|
||||
(some (fn [[_k v]] (= (:status v) :confirmed)) transaction-details) :confirmed
|
||||
:else nil))
|
||||
|
||||
(defn- footer
|
||||
[{:keys [color leave-page]}]
|
||||
(let [save-address-visible? false]
|
||||
[quo/bottom-actions
|
||||
{:actions (if save-address-visible? :two-actions :one-action)
|
||||
:button-two-label (i18n/label :t/save-address)
|
||||
:button-two-props {:type :grey
|
||||
:icon-left :i/contact-book
|
||||
:accessibility-label :save-address
|
||||
:on-press (rn/use-callback
|
||||
#(rf/dispatch [:open-modal :screen/wallet.save-address]))}
|
||||
:button-one-label (i18n/label :t/done)
|
||||
:button-one-props {:customization-color color
|
||||
:type :primary
|
||||
:accessibility-label :done
|
||||
:on-press leave-page}}]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [leave-page #(rf/dispatch [:wallet/close-transaction-progress-page])
|
||||
@@ -57,9 +40,10 @@
|
||||
:margin-top (safe-area/get-top)
|
||||
:on-press leave-page
|
||||
:accessibility-label :top-bar}]
|
||||
:footer [footer
|
||||
{:color color
|
||||
:leave-page leave-page}]
|
||||
:footer [quo/button
|
||||
{:customization-color color
|
||||
:on-press leave-page}
|
||||
(i18n/label :t/done)]
|
||||
:customization-color color
|
||||
:gradient-cover? true}
|
||||
[rn/view {:style style/content-container}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.sheets.account-options.style :as style]
|
||||
[status-im.contexts.wallet.sheets.remove-account.view :as remove-account]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -98,8 +99,12 @@
|
||||
:accessibility-label :remove-account
|
||||
:label (i18n/label :t/remove-account)
|
||||
:danger? true
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content remove-account/view}])})]]]
|
||||
:on-press #(ff/alert ::ff/wallet.remove-account
|
||||
(fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[remove-account/view])}])))})]]]
|
||||
(when show-account-selector?
|
||||
[:<>
|
||||
[quo/divider-line {:container-style style/divider-label}]
|
||||
|
||||
@@ -13,18 +13,19 @@
|
||||
(defn- footer
|
||||
[{:keys [address submit-disabled? toast-message]}]
|
||||
[quo/bottom-actions
|
||||
{:actions :two-actions
|
||||
:button-one-label (i18n/label :t/remove)
|
||||
:button-one-props {:on-press
|
||||
(fn []
|
||||
(rf/dispatch [:wallet/remove-account
|
||||
{:address address
|
||||
:toast-message toast-message}]))
|
||||
:type :danger
|
||||
:disabled? submit-disabled?}
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:on-press #(rf/dispatch [:hide-bottom-sheet])
|
||||
:type :grey}}])
|
||||
{:actions :2-actions
|
||||
:customization-color :danger
|
||||
:button-one-label (i18n/label :t/remove)
|
||||
:button-one-props {:on-press
|
||||
(fn []
|
||||
(rf/dispatch [:wallet/remove-account
|
||||
{:address address
|
||||
:toast-message toast-message}]))
|
||||
:type :danger
|
||||
:disabled? submit-disabled?}
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:on-press #(rf/dispatch [:hide-bottom-sheet])
|
||||
:type :grey}}])
|
||||
|
||||
(defn- recovery-phase-flow
|
||||
[]
|
||||
|
||||
@@ -8,17 +8,13 @@
|
||||
status-im.common.emoji-picker.events
|
||||
status-im.common.font.events
|
||||
[status-im.common.json-rpc.events]
|
||||
status-im.common.log
|
||||
status-im.common.password-authentication.events
|
||||
status-im.common.signals.events
|
||||
status-im.common.theme.events
|
||||
[status-im.common.toasts.events]
|
||||
status-im.common.universal-links
|
||||
status-im.contexts.chat.contacts.events
|
||||
status-im.contexts.chat.events
|
||||
[status-im.contexts.chat.home.add-new-contact.events]
|
||||
status-im.contexts.chat.messenger.composer.events
|
||||
status-im.contexts.chat.messenger.messages.link-preview.events
|
||||
status-im.contexts.chat.messenger.photo-selector.events
|
||||
status-im.contexts.communities.events
|
||||
status-im.contexts.communities.overview.events
|
||||
@@ -33,7 +29,6 @@
|
||||
status-im.contexts.wallet.send.events
|
||||
status-im.contexts.wallet.signals
|
||||
[status-im.db :as db]
|
||||
status-im.navigation.events
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn start-app
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
(reagent/atom
|
||||
{::wallet.edit-default-keypair true
|
||||
::wallet.bridge-token (enabled-in-env? :FLAG_BRIDGE_TOKEN_ENABLED)
|
||||
::wallet.remove-account (enabled-in-env? :FLAG_REMOVE_ACCOUNT_ENABLED)
|
||||
::wallet.network-filter (enabled-in-env? :FLAG_NETWORK_FILTER_ENABLED)
|
||||
::profile.new-contact-ui (enabled-in-env? :FLAG_NEW_CONTACT_UI_ENABLED)}))
|
||||
|
||||
|
||||
@@ -37,14 +37,14 @@
|
||||
|
||||
(navigation/reg-component-did-appear-listener
|
||||
(fn [view-id]
|
||||
(let [view-id-with-prefix (keyword (str "screen/" (name view-id)))
|
||||
view (or (get views/screens view-id)
|
||||
(get views/screens view-id-with-prefix))
|
||||
view-id (:name view)]
|
||||
(when view
|
||||
(when (get views/screens view-id)
|
||||
;;NOTE when back from the background on Android, this event happens for all screens, but we
|
||||
;;need only for active one
|
||||
(when (and @state/curr-modal (= @state/curr-modal view-id))
|
||||
(effects/set-view-id view-id))
|
||||
(when-not @state/curr-modal
|
||||
(effects/set-view-id view-id)
|
||||
(when-not @state/curr-modal
|
||||
(reset! state/pushed-screen-id view-id))))))
|
||||
(reset! state/pushed-screen-id view-id)))))
|
||||
|
||||
;;;; Modal
|
||||
|
||||
@@ -106,9 +106,4 @@
|
||||
(navigation/register-component
|
||||
"bottom-sheet-old"
|
||||
(fn [] (gesture/gesture-handler-root-hoc views/sheet-comp-old))
|
||||
(fn [] views/sheet-comp-old))
|
||||
|
||||
(navigation/register-component
|
||||
"popover"
|
||||
(fn [] (gesture/gesture-handler-root-hoc views/popover-comp))
|
||||
(fn [] views/popover-comp)))
|
||||
(fn [] views/sheet-comp-old)))
|
||||
|
||||
@@ -33,9 +33,7 @@
|
||||
(rf/defn navigate-to-within-stack
|
||||
{:events [:navigate-to-within-stack]}
|
||||
[{:keys [db]} comp-id]
|
||||
{:db (-> db
|
||||
(update :modal-view-ids add-view-to-modals (first comp-id))
|
||||
(assoc :view-id (first comp-id)))
|
||||
{:db (update db :modal-view-ids add-view-to-modals (first comp-id))
|
||||
:fx [[:navigate-to-within-stack comp-id]]})
|
||||
|
||||
(re-frame/reg-event-fx :open-modal
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user