Compare commits

..
Author SHA1 Message Date
Ajay Sivan a0540d2396 show enable biometric screen in sync flow 2023-05-02 16:01:43 +05:30
Siddarth Kumar fac368521b (fix) modify disclaimer component for on tap UX (#15757) 2023-05-02 15:55:49 +05:30
Omar Basem 51b9253734 revert podfile.lock (#15791)
* revert podfile.lock
2023-05-02 09:27:47 +04:00
Omar Basem 08e6b8164e feat: composer - edit message (#15772)
* feat: new composer - edit message
2023-05-01 20:39:07 +04:00
Parvesh Monu 9a8354f783 Improve dissmiss all overlays (#15773) 2023-04-28 20:52:34 +05:30
Churikova Tetiana 6c0c742676 e2e: align with new communities / cleanup 2023-04-28 13:56:31 +02:00
flexsurfer e0ed2a250b clean old code, remove public chat, implement drawers for home screens (#15766) 2023-04-28 13:42:38 +02:00
jakub 2f988fcd47 nix: disable sandboxing for xcodewrapper
Otherwise we see weird errors like this:
```
/nix/store/g0jijpgcb4q54zbvz5p8yvxcnb6lshnk-stdenv-darwin/setup: line 1391: /nix/store/sja8sqq4y5s9ijkb97i3pi2jrhsy40cz-xcode-wrapper-14.3/bin/xcodebuild: Operation not permitted
We require xcodebuild version: 14.3
error: builder for '/nix/store/d1dji0ywl851wgj9vv58ibpm32gq3wsm-xcode-wrapper-14.3.drv' failed with exit code 1;
       last 2 log lines:
       > /nix/store/g0jijpgcb4q54zbvz5p8yvxcnb6lshnk-stdenv-darwin/setup: line 1391: /nix/store/sja8sqq4y5s9ijkb97i3pi2jrhsy40cz-xcode-wrapper-14.3/bin/xcodebuild: Operation not permitted
       > We require xcodebuild version: 14.3
```
Related to: https://github.com/NixOS/nixpkgs/pull/228696

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2023-04-28 11:24:16 +02:00
frank ee71117111 remove unused code relate to old text-input component (#15765)
* remove unused code relate to old text-input component

* removed tow lines
2023-04-28 09:37:13 +08:00
Omar Basem 3e9d5dde54 Reimplement composer: add reply (#15736)
* feat: add composer reply
2023-04-27 20:20:00 +04:00
Siddarth Kumar 2eed30be8f (chore) : Improve QR code quo2 component (#15755)
This PR adds the ability to :

- Generate a QR by passing any url.
- See different error correction levels.
- Shows the media server url for that specific QR code.
- Moved media server URI generation logic to `image_server.cljs`
2023-04-27 19:25:49 +05:30
Parvesh Monu 8e49a06dbe fix UI freeze issue (#15761) 2023-04-27 17:26:33 +05:30
Roman Volosovskyi fb326bbf4e [#15741] Fix error on tapping pinned message 2023-04-27 10:23:16 +02:00
Jamie Caprani 52c6687608 feat: add identifiers screen to onboarding-flow (#15684) 2023-04-26 21:26:32 -07:00
frank cfefef6b75 fix [#15616] Sometimes mentions list does not appear after typing @ in chat input filed (#15622) 2023-04-27 11:37:01 +08:00
flexsurfer e6ba40ac17 fix quo hotreload (#15760) 2023-04-26 18:14:58 +02:00
flexsurfer efbf93f6e2 move status native module (#15749) 2023-04-26 18:14:14 +02:00
Mohamed Javid 6eb2029c51 Show "Kicked from community" notification in Activity Center (#15734)
* [Feature] Implement Community Kicked notification

* Status Go Update
2023-04-26 19:56:33 +05:30
Parvesh Monu 55bab9454a fix status bar font color (#15744) 2023-04-26 19:35:51 +05:30
flexsurferandChurikova Tetiana 0ca6ee3934 Request to join community screen is not scrollable on Android #15748 (#15750)
Co-authored-by: Churikova Tetiana <tatiana@status.im>
2023-04-26 13:33:00 +02:00
Parvesh Monu 0649c66dde fix device theme change listener in ios (#15724) 2023-04-26 16:41:11 +05:30
Roman Volosovskyi 1b0374a156 [#15655] Resolve messages with markdown on Jump To screen 2023-04-26 11:55:45 +02:00
168 changed files with 1276 additions and 3698 deletions
+5 -5
View File
@@ -12,11 +12,11 @@ status-im.chat.models.message-content/actions
status-im.chat.models.message-content/blank-string
status-im.chat.models.message-content/sorted-ranges
status-im.ethereum.mnemonic/words->passphrase
status-im.native-module.core/listener
status-im.native-module.core/multiaccount-reset
status-im.native-module.core/extract-group-membership-signatures
status-im.native-module.core/sign-group-membership
status-im.native-module.core/update-mailservers
native-module.core/listener
native-module.core/multiaccount-reset
native-module.core/extract-group-membership-signatures
native-module.core/sign-group-membership
native-module.core/update-mailservers
status-im.ethereum.abi-spec/bytes-to-hex
status-im.android.core/init
status-im.chat.models.message/transport-keys
@@ -8,6 +8,9 @@ assert stdenv.isDarwin;
stdenv.mkDerivation {
name = "xcode-wrapper-${version}${if allowHigher then "-plus" else ""}";
# Fix 'xcodebuild: Operation not permitted' when 'sandbox=relaxed' is used.
# https://github.com/NixOS/nixpkgs/pull/228696
__noChroot = stdenv.isDarwin;
buildCommand = ''
mkdir -p $out/bin
cd $out/bin
+2 -2
View File
@@ -18,11 +18,11 @@ export function stackOpacity (stackId, selectedStackId) {
);
}
export function stackPointer (stackId, selectedStackId) {
export function stackZIndex (stackId, selectedStackId) {
return useDerivedValue(
function () {
'worklet'
return selectedStackId.value == stackId ? "auto" : "none";
return selectedStackId.value == stackId ? 10 : 9;
}
);
}
@@ -1,19 +1,19 @@
(ns status-im.native-module.core
(ns native-module.core
(:require ["react-native" :as react-native]
[re-frame.core :as re-frame]
[status-im2.utils.validators :as validators]
[status-im.utils.platform :as platform]
[status-im.utils.react-native :as react-native-utils]
[status-im.utils.types :as types]
[utils.validators :as validators]
[taoensso.timbre :as log]
[status-im2.constants :as constants]))
[react-native.platform :as platform]
[react-native.core :as rn]
[utils.transforms :as types]))
(defn status
[]
(when (exists? (.-NativeModules react-native))
(.-Status ^js (.-NativeModules react-native))))
(def adjust-resize 16)
(defn init
[handler]
(.addListener ^js rn/device-event-emitter "gethEvent" #(handler (.-jsonEvent ^js %))))
(defn clear-web-data
[]
@@ -72,15 +72,6 @@
accounts-data
chat-key)))
(defn login
"NOTE: beware, the password has to be sha3 hashed"
[key-uid account-data hashed-password]
(log/debug "[native-module] login")
(clear-web-data)
(init-keystore
key-uid
#(.login ^js (status) account-data hashed-password)))
(defn login-with-config
"NOTE: beware, the password has to be sha3 hashed"
[key-uid account-data hashed-password config]
@@ -123,11 +114,6 @@
(clear-web-data)
(.logout ^js (status)))
(defonce listener
(.addListener ^js react-native-utils/device-event-emitter
"gethEvent"
#(re-frame/dispatch [:signals/signal-received (.-jsonEvent ^js %)])))
(defn multiaccount-load-account
"NOTE: beware, the password has to be sha3 hashed
@@ -141,14 +127,6 @@
:password hashed-password})
callback))
(defn multiaccount-reset
"TODO: this function is not used anywhere
if usage isn't planned, remove"
[callback]
(log/debug "[native-module] multiaccount-reset")
(.multiAccountReset ^js (status)
callback))
(defn multiaccount-derive-addresses
"NOTE: this should be named derive-accounts
this only derive addresses, they still need to be stored
@@ -298,43 +276,13 @@
:key key})
(.deserializeAndCompressKey ^js (status) key callback))
(defn public-key->compressed-key
"Provides public key to status-go and gets back a compressed key via serialization"
[public-key callback]
(let [serialization-key constants/serialization-key
multi-code-prefix constants/multi-code-prefix
multi-code-key (str multi-code-prefix (subs public-key 2))]
(log/info "[native-module] Serializing public key"
{:fn :public-key->compressed-key
:public-key public-key
:multi-code-key multi-code-key})
(.multiformatSerializePublicKey ^js (status) multi-code-key serialization-key callback)))
(defn compressed-key->public-key
"Provides compressed key to status-go and gets back the uncompressed public key via deserialization"
[public-key callback]
(let [deserialization-key constants/deserialization-key]
(log/info "[native-module] Deserializing compressed key"
{:fn :compressed-key->public-key
:public-key public-key})
(.multiformatDeserializePublicKey ^js (status) public-key deserialization-key callback)))
(defn decompress-public-key
"Provides compressed key to status-go and gets back the uncompressed public key"
[public-key callback]
(log/info "[native-module] Decompressing public key"
{:fn :decompress-public-key
[public-key deserialization-key callback]
(log/info "[native-module] Deserializing compressed key"
{:fn :compressed-key->public-key
:public-key public-key})
(.decompressPublicKey ^js (status) public-key callback))
(defn compress-public-key
"Provides a public key to status-go and gets back a 33bit compressed key back"
[public-key callback]
(log/info "[native-module] Compressing public key"
{:fn :compress-public-key
:public-key public-key})
(.compressPublicKey ^js (status) public-key callback))
(.multiformatDeserializePublicKey ^js (status) public-key deserialization-key callback))
(defn hash-typed-data
"used for keycard"
@@ -388,11 +336,6 @@
(log/debug "[native-module] send-logs")
(.sendLogs ^js (status) dbJson js-logs callback))
(defn add-peer
[enode on-result]
(log/debug "[native-module] add-peer")
(.addPeer ^js (status) enode on-result))
(defn close-application
[]
(log/debug "[native-module] close-application")
@@ -408,11 +351,6 @@
(log/debug "[native-module] app-state-change")
(.appStateChange ^js (status) state))
(defn stop-local-notifications
[]
(log/debug "[native-module] stop-local-notifications")
(.stopLocalNotifications ^js (status)))
(defn start-local-notifications
[]
(log/debug "[native-module] start-local-notifications")
@@ -433,26 +371,11 @@
:build-id (.-buildId status)
:device-id (.-deviceId status)}))
(defn extract-group-membership-signatures
[signature-pairs callback]
(log/debug "[native-module] extract-group-membership-signatures")
(.extractGroupMembershipSignatures ^js (status) signature-pairs callback))
(defn sign-group-membership
[content callback]
(log/debug "[native-module] sign-group-membership")
(.signGroupMembership ^js (status) content callback))
(defn get-node-config
[callback]
(log/debug "[native-module] get-node-config")
(.getNodeConfig ^js (status) callback))
(defn update-mailservers
[enodes on-result]
(log/debug "[native-module] update-mailservers")
(.updateMailservers ^js (status) enodes on-result))
(defn toggle-webview-debug
[on]
(log/debug "[native-module] toggle-webview-debug" on)
@@ -483,12 +406,6 @@
(when (validators/valid-public-key? public-key)
(.generateAlias ^js (status) public-key)))
(defn generate-gfycat-async
"Generate a 3 words random name based on the user public-key, asynchronously"
[public-key callback]
(when (validators/valid-public-key? public-key)
(.generateAliasAsync ^js (status) public-key callback)))
(defn identicon
"Generate a icon based on a string, synchronously"
[seed]
@@ -500,11 +417,6 @@
(log/debug "[native-module] encode-transfer")
(.encodeTransfer ^js (status) to-norm amount-hex))
(defn encode-function-call
[method params]
(log/debug "[native-module] encode-function-call")
(.encodeFunctionCall ^js (status) method (types/clj->json params)))
(defn decode-parameters
[bytes-string types]
(log/debug "[native-module] decode-parameters")
@@ -555,11 +467,6 @@
(log/debug "[native-module] to-checksum-address")
(.toChecksumAddress ^js (status) address))
(defn identicon-async
"Generate a icon based on a string, asynchronously"
[seed callback]
(.identiconAsync ^js (status) seed callback))
(defn gfycat-identicon-async
"Generate an icon based on a string and 3 words random name asynchronously"
[seed callback]
@@ -585,16 +492,6 @@
(log/debug "[native-module] delete-imported-key")
(.deleteImportedKey ^js (status) key-uid address hashed-password callback))
(defn activate-keep-awake
[]
(log/debug "[native-module] activateKeepAwake")
(.activateKeepAwake ^js (status)))
(defn deactivate-keep-awake
[]
(log/debug "[native-module] deactivateKeepAwake")
(.deactivateKeepAwake ^js (status)))
(defn reset-keyboard-input
[input selection]
(log/debug "[native-module] resetKeyboardInput")
@@ -1,10 +1,10 @@
(ns status-im.native-module.core-test
(ns native-module.core-test
(:require [cljs.test :refer [deftest is testing]]
[status-im.native-module.core :as status]))
[native-module.core :as native-module]))
(deftest identicon-test
(testing "check if identicon test works"
(is
(=
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAjklEQVR4nOzXsQmAMBQGYRV3cUAdQwd0Gm2sJIWSBI6f+0oR8XjwSKYhhCE0htAYQmMITUzI/PXF49yv0vN12cYWP1L7/ZiJGEJjCE31xvm7bXptv5iJGEJjCE31WasVz1oPQ2gMoWlyuyvpfaN8i5mIITSG0BhCYwiNIeokZiKG0BhCYwiNITR3AAAA//+A3RtWaKqXgQAAAABJRU5ErkJggg=="
(status/identicon "a")))))
(native-module/identicon "a")))))
@@ -30,7 +30,7 @@
[customization-color blur? override-theme]
(if blur?
(colors/theme-colors colors/neutral-100 colors/white override-theme)
(colors/custom-color customization-color (if (or (= :dark override-theme) colors/dark?) 60 50))))
(colors/custom-color customization-color (if (or (= :dark override-theme) (colors/dark?)) 60 50))))
(def text-input-container {:flex 1})
@@ -5,15 +5,17 @@
[react-native.core :as rn]))
(defn view
[{:keys [checked? blur? on-change accessibility-label container-style]} label]
[rn/view
{:style (merge container-style (style/container blur?))}
[selectors/checkbox
{:accessibility-label accessibility-label
:blur? blur?
:checked? checked?
:on-change on-change}]
[text/text
{:size :paragraph-2
:style style/text}
label]])
[{:keys [checked? blur? accessibility-label container-style on-change]} label]
[rn/touchable-opacity
{:on-press on-change
:accessibility-label "disclaimer-touchable-opacity"}
[rn/view {:style (merge container-style (style/container blur?))}
[selectors/checkbox
{:accessibility-label accessibility-label
:blur? blur?
:checked? checked?
:on-change on-change}]
[text/text
{:size :paragraph-2
:style style/text}
label]]])
+2
View File
@@ -37,6 +37,8 @@
(def dismiss-keyboard! #(.dismiss keyboard))
(def device-event-emitter (.-DeviceEventEmitter ^js react-native))
(defn hide-splash-screen
[]
(.hide ^js (-> react-native .-NativeModules .-SplashScreen)))
-102
View File
@@ -1,102 +0,0 @@
(ns status-im.add-new.core
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.add-new.db :as db]
[status-im2.contexts.chat.events :as chat]
[status-im2.contexts.contacts.events :as contact]
[status-im.ethereum.core :as ethereum]
[status-im.ethereum.ens :as ens]
[status-im.ethereum.stateofus :as stateofus]
[utils.i18n :as i18n]
[status-im.router.core :as router]
[status-im.utils.db :as utils.db]
[utils.re-frame :as rf]
[status-im.utils.random :as random]
[status-im.utils.utils :as utils]
[status-im2.navigation.events :as navigation]))
(re-frame/reg-fx
:resolve-public-key
(fn [{:keys [chain-id contact-identity cb]}]
(let [ens-name (stateofus/ens-name-parse contact-identity)]
(ens/pubkey chain-id ens-name cb))))
;;NOTE we want to handle only last resolve
(def resolve-last-id (atom nil))
(rf/defn new-chat-set-new-identity
{:events [:new-chat/set-new-identity]}
[{db :db} new-identity-raw new-ens-name id]
(let [ens-error (and (= new-identity-raw "0x") (not (string/blank? new-ens-name)))]
(when (or (not id) (= id @resolve-last-id))
(if ens-error
{:db (assoc-in db [:contacts/new-identity :state] :error)}
(let [new-identity (utils/safe-trim new-identity-raw)
is-public-key? (and (string? new-identity)
(utils.db/valid-public-key? new-identity))
is-ens? (and (not is-public-key?)
(ens/valid-eth-name-prefix? new-identity))
error (db/validate-pub-key db new-identity)]
(reset! resolve-last-id nil)
(merge {:db (assoc db
:contacts/new-identity
{:public-key new-identity
:state (cond is-ens?
:searching
(and (string/blank? new-identity) (not new-ens-name))
:empty
error
:error
:else
:valid)
:error error
:ens-name (stateofus/ens-name-parse new-ens-name)})}
(when is-ens?
(reset! resolve-last-id (random/id))
{:resolve-public-key
{:chain-id (ethereum/chain-id db)
:contact-identity new-identity
:cb #(re-frame/dispatch [:new-chat/set-new-identity
%
new-identity
@resolve-last-id])}})))))))
(rf/defn clear-new-identity
{:events [::clear-new-identity ::new-chat-focus]}
[{:keys [db]}]
{:db (dissoc db :contacts/new-identity)})
(rf/defn qr-code-handled
{:events [::qr-code-handled]}
[{:keys [db] :as cofx} {:keys [type public-key chat-id data ens-name]}
{:keys [new-contact? nickname] :as opts}]
(let [public-key? (and (string? data)
(string/starts-with? data "0x"))
chat-key (cond
(= type :private-chat) chat-id
(= type :contact) public-key
(and (= type :undefined)
public-key?)
data)
validation-result (db/validate-pub-key db chat-key)]
(if-not validation-result
(if new-contact?
(rf/merge cofx
(contact/send-contact-request chat-key)
(navigation/navigate-to :contacts-list {}))
(chat/start-chat cofx chat-key ens-name))
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:content (case validation-result
:invalid
(i18n/label :t/use-valid-contact-code)
:yourself
(i18n/label :t/can-not-add-yourself))
:on-dismiss #(re-frame/dispatch [:pop-to-root :shell-stack])}})))
(rf/defn qr-code-scanned
{:events [:contact/qr-code-scanned]}
[{:keys [db]} data opts]
{::router/handle-uri {:chain (ethereum/chain-keyword db)
:chats (get db :chats)
:uri data
:cb #(re-frame/dispatch [::qr-code-handled % opts])}})
-30
View File
@@ -1,30 +0,0 @@
(ns status-im.add-new.db
(:require [cljs.spec.alpha :as spec]
[status-im.ethereum.ens :as ens]
[status-im2.utils.validators :as validators]))
(defn own-public-key?
[{:keys [multiaccount]} public-key]
(= (:public-key multiaccount) public-key))
(defn validate-pub-key
[db public-key]
(cond
(or (not (validators/valid-public-key? public-key))
(= public-key ens/default-key))
:invalid
(own-public-key? db public-key)
:yourself))
(spec/def ::name (spec/and string? not-empty))
(spec/def ::topic
(spec/and string?
not-empty
(partial re-matches #"[a-z0-9\-]+")))
(defn valid-topic?
[topic]
(and topic
(spec/valid? ::topic topic)
(not (validators/valid-public-key? topic))))
-4
View File
@@ -1,7 +1,6 @@
(ns status-im.bottom-sheet.sheets
(:require [utils.re-frame :as rf]
[status-im.ui.screens.about-app.views :as about-app]
[status-im.ui.screens.home.sheet.views :as home.sheet]
[status-im.ui.screens.keycard.views :as keycard]
[status-im.ui.screens.mobile-network-settings.view :as mobile-network-settings]
[status-im.ui.screens.multiaccounts.key-storage.views :as key-storage]
@@ -27,9 +26,6 @@
(= view :mobile-network-offline)
(merge mobile-network-settings/offline-sheet)
(= view :add-new)
(merge home.sheet/add-new)
(= view :keycard.login/more)
(merge keycard/more-sheet)
+3 -3
View File
@@ -13,7 +13,7 @@
[status-im.ethereum.ens :as ens]
[utils.i18n :as i18n]
[status-im.multiaccounts.update.core :as multiaccounts.update]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.signing.core :as signing]
[status-im.ui.components.list-selection :as list-selection]
[utils.re-frame :as rf]
@@ -537,7 +537,7 @@
(re-frame/reg-fx
:browser/call-rpc
(fn [[payload callback]]
(status/call-rpc
(native-module/call-rpc
(types/clj->json payload)
(fn [response]
(if (= "" response)
@@ -559,7 +559,7 @@
(re-frame/reg-fx
:browser/clear-web-data
(fn []
(status/clear-web-data)))
(native-module/clear-web-data)))
(defn share-link
[url]
-35
View File
@@ -1,35 +0,0 @@
(ns status-im.chat.models
(:require [utils.i18n :as i18n]
[re-frame.core :as re-frame]
[utils.re-frame :as rf]
[taoensso.timbre :as log]
[status-im.add-new.db :as new-public-chat.db]
[status-im.data-store.chats :as chats-store]))
;; OLD
(rf/defn handle-public-chat-created
{:events [::public-chat-created]}
[{:keys [db]} chat-id response]
{:db (-> db
(assoc-in [:chats chat-id] (chats-store/<-rpc (first (:chats response))))
(update :chats-home-list conj chat-id))
:dispatch [:chat/navigate-to-chat chat-id]})
(rf/defn create-public-chat-go
[_ chat-id]
{:json-rpc/call [{:method "wakuext_createPublicChat"
:params [{:id chat-id}]
:on-success #(re-frame/dispatch [::public-chat-created chat-id %])
:on-error #(log/error "failed to create public chat" chat-id %)}]})
(rf/defn start-public-chat
"Starts a new public chat"
{:events [:chat.ui/start-public-chat]}
[cofx topic]
(if (new-public-chat.db/valid-topic? topic)
(create-public-chat-go
cofx
topic)
{:utils/show-popup {:title (i18n/label :t/cant-open-public-chat)
:content (i18n/label :t/invalid-public-chat-topic)}}))
+22 -19
View File
@@ -11,8 +11,7 @@
[utils.re-frame :as rf]
[utils.i18n :as i18n]
[status-im.utils.utils :as utils]
[taoensso.timbre :as log]
[status-im.ui.screens.chat.components.input :as input]))
[taoensso.timbre :as log]))
(defn text->emoji
"Replaces emojis in a specified `text`"
@@ -52,6 +51,12 @@
(let [current-chat-id (or chat-id (:current-chat-id db))]
{:db (assoc-in db [:chat/inputs current-chat-id :input-maximized?] maximized?)}))
(rf/defn set-input-focused
{:events [:chat.ui/set-input-focused]}
[{db :db} focused? chat-id]
(let [current-chat-id (or chat-id (:current-chat-id db))]
{:db (assoc-in db [:chat/inputs current-chat-id :focused?] focused?)}))
(rf/defn select-mention
{:events [:chat.ui/select-mention]}
[{:keys [db] :as cofx} text-input-ref {:keys [primary-name searched-text match public-key] :as user}]
@@ -93,16 +98,15 @@
[{:keys [db] :as cofx} message]
(let [current-chat-id (:current-chat-id db)
text (get-in message [:content :text])]
(rf/merge cofx
{:db (-> db
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message]
message)
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message] nil)
(update-in [:chat/inputs current-chat-id :metadata]
dissoc
:sending-image))}
(when-not config/new-composer-enabled?
(input/set-input-text text current-chat-id)))))
{:db (-> db
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message]
message)
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message] nil)
(update-in [:chat/inputs current-chat-id :metadata]
dissoc
:sending-image))
:dispatch (when-not config/new-composer-enabled?
[:mention/to-input-field text current-chat-id])}))
(rf/defn show-contact-request-input
"Sets reference to previous chat message and focuses on input"
@@ -272,13 +276,12 @@
{:events [:contacts/send-contact-request]}
[{:keys [db] :as cofx} public-key message]
(rf/merge cofx
{:chat.ui/clear-inputs nil
:chat.ui/clear-inputs-old nil
:json-rpc/call [{:method "wakuext_sendContactRequest"
:js-response true
:params [{:id public-key :message message}]
:on-error #(log/warn "failed to send a contact request" %)
:on-success #(re-frame/dispatch [:transport/message-sent %])}]}
{:chat.ui/clear-inputs nil
:json-rpc/call [{:method "wakuext_sendContactRequest"
:js-response true
:params [{:id public-key :message message}]
:on-error #(log/warn "failed to send a contact request" %)
:on-success #(re-frame/dispatch [:transport/message-sent %])}]}
(mentions/clear-mentions)
(clean-input (:current-chat-id db))))
+41 -70
View File
@@ -4,9 +4,8 @@
[quo.react-native :as rn]
[re-frame.core :as re-frame]
[utils.re-frame :as rf]
[status-im.utils.platform :as platform]
[taoensso.timbre :as log]
[status-im.native-module.core :as status]))
[native-module.core :as native-module]))
(defn- transfer-input-segments
[segments]
@@ -56,8 +55,8 @@
:ensVerified :ens-verified
:added :added?
:displayName :display-name
:searchedText :searched-text
})))
:searchedText :searched-text})))
{}
mentionable-users))
(defn- transfer-mention-result
@@ -81,6 +80,19 @@
(log/error "[mentions] on-error"
{:context context
:error error}))
(rf/defn to-input-field
{:events [:mention/to-input-field]}
[_ text chat-id]
(let [params [chat-id text]
method "wakuext_chatMentionToInputField"]
(log/debug "[mentions] to-input-field" {:params params})
{:json-rpc/call [{:method method
:params params
:on-success #(rf/dispatch [:mention/on-to-input-field-success %])
:on-error #(rf/dispatch [:mention/on-error
{:method method
:params params} %])}]}))
(rf/defn on-to-input-field-success
{:events [:mention/on-to-input-field-success]}
[{:keys [db]} result]
@@ -91,38 +103,29 @@
(assoc-in [:chats/mentions chat-id :mentions] state)
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
(rf/defn on-text-input
{:events [:mention/on-text-input]}
[{:keys [db]} {:keys [previous-text start end] :as args}]
(let [previous-text
;; NOTE(rasom): on iOS `previous-text` contains entire input's text. To
;; get only removed part of text we have cut it.
(if platform/android?
previous-text
(subs previous-text start end))
chat-id (:current-chat-id db)
state (merge args {:previous-text previous-text})
state (set/rename-keys state
{:previous-text :PreviousText
:new-text :NewText
:start :Start
:end :End})
params [chat-id state]
method "wakuext_chatMentionOnTextInput"]
(log/debug "[mentions] on-text-input" {:params params})
(rf/defn on-change-text
{:events [:mention/on-change-text]}
[{:keys [db]} text]
(let [chat-id (:current-chat-id db)
params [chat-id text]
method "wakuext_chatMentionOnChangeText"]
(log/debug "[mentions] on-change-text" {:params params})
{:json-rpc/call [{:method method
:params [chat-id state]
:on-success #(rf/dispatch [:mention/on-text-input-success %])
:params params
:on-success #(rf/dispatch [:mention/on-change-text-success %])
:on-error #(rf/dispatch [:mention/on-error
{:method method
:params params} %])}]}))
(rf/defn on-text-input-success
{:events [:mention/on-text-input-success]}
(rf/defn on-change-text-success
{:events [:mention/on-change-text-success]}
[{:keys [db]} result]
(log/debug "[mentions] on-text-input-success" {:result result})
(let [{:keys [state chat-id]} (transfer-mention-result result)]
{:db (assoc-in db [:chats/mentions chat-id :mentions] state)}))
(let [{:keys [state chat-id mentionable-users input-segments]} (transfer-mention-result result)]
{:db (-> db
(assoc-in [:chats/mention-suggestions chat-id] mentionable-users)
(assoc-in [:chats/mentions chat-id :mentions] state)
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
(rf/defn recheck-at-idxs
[{:keys [db]} public-key]
@@ -175,16 +178,6 @@
;; programmatic change. By calling `reset-text-input-cursor` we force the
;; keyboard's cursor position to be changed before the next input.
(reset-text-input-cursor text-input-ref cursor)
;; NOTE(roman): on-text-input event is not dispatched when we change input
;; programmatically, so we have to call `on-text-input` manually
(on-text-input
(let [match-len (count match)
start (inc at-sign-idx)
end (+ start match-len)]
{:new-text match
:previous-text searched-text
:start start
:end end}))
(recheck-at-idxs public-key))))
(rf/defn clear-suggestions
@@ -220,7 +213,7 @@
(when text
(log/debug "[mentions] check-selection" {:params params})
{:json-rpc/call [{:method method
:params [chat-id text start end]
:params params
:on-success #(rf/dispatch [:mention/on-handle-selection-change-success %])
:on-error #(rf/dispatch [:mention/on-error
{:method method
@@ -230,38 +223,16 @@
{:events [:mention/on-handle-selection-change-success]}
[{:keys [db]} result]
(log/debug "[mentions] on-check-selection-success" {:result result})
(let [{:keys [state chat-id]} (transfer-mention-result result)]
{:db (assoc-in db [:chats/mentions chat-id :mentions] (rename-state state))}))
(re-frame/reg-fx
::reset-text-input-cursor
(fn [[ref cursor]]
(when ref
(status/reset-keyboard-input
(rn/find-node-handle (react/current-ref ref))
cursor))))
(rf/defn calculate-suggestions
{:events [:mention/calculate-suggestions]}
[{:keys [db]}]
(let [chat-id (:current-chat-id db)
text (get-in db [:chat/inputs chat-id :input-text])
params [chat-id text]
method "wakuext_chatMentionCalculateSuggestions"]
(log/debug "[mentions] calculate-suggestions" {:params params})
{:json-rpc/call [{:method method
:params [chat-id text]
:on-success #(rf/dispatch [:mention/on-calculate-suggestions-success %])
:on-error #(rf/dispatch [:mention/on-error
{:method method
:params params} %])}]}))
(rf/defn on-calculate-suggestions-success
{:events [:mention/on-calculate-suggestions-success]}
[{:keys [db]} result]
(log/debug "[mentions] on-calculate-suggestions-success" {:result result})
(let [{:keys [state chat-id mentionable-users input-segments]} (transfer-mention-result result)]
{:db (-> db
(assoc-in [:chats/mention-suggestions chat-id] mentionable-users)
(assoc-in [:chats/mentions chat-id :mentions] state)
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
(re-frame/reg-fx
::reset-text-input-cursor
(fn [[ref cursor]]
(when ref
(native-module/reset-keyboard-input
(rn/find-node-handle (react/current-ref ref))
cursor))))
+1 -1
View File
@@ -505,7 +505,7 @@
(handle-response response-js)))
(rf/defn open-create-community
{:events [::open-create-community]}
{:events [:legacy-only-for-e2e/open-create-community]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc db :communities/create {:membership constants/community-no-membership-access})}
+1 -6
View File
@@ -9,8 +9,7 @@
(defn rpc->type
[{:keys [chat-type name] :as chat}]
(cond
(or (= constants/public-chat-type chat-type)
(= constants/profile-chat-type chat-type)
(or (= constants/profile-chat-type chat-type)
(= constants/timeline-chat-type chat-type))
(assoc chat
:chat-name (str "#" name)
@@ -39,10 +38,6 @@
(defn- unmarshal-members
[{:keys [members chat-type] :as chat}]
(cond
(= constants/public-chat-type chat-type) (assoc chat
:contacts #{}
:admins #{}
:members-joined #{})
(= constants/private-group-chat-type chat-type) (merge chat
(reduce members-reducer
{:admins #{}
+5 -5
View File
@@ -1,23 +1,23 @@
(ns status-im.ethereum.core
(:require [clojure.string :as string]
[status-im.ethereum.eip55 :as eip55]
[status-im.native-module.core :as status]))
[native-module.core :as native-module]))
(defn sha3
[s]
(when s
(status/sha3 (str s))))
(native-module/sha3 (str s))))
(defn utf8-to-hex
[s]
(let [hex (status/utf8-to-hex (str s))]
(let [hex (native-module/utf8-to-hex (str s))]
(if (empty? hex)
nil
hex)))
(defn hex-to-utf8
[s]
(let [utf8 (status/hex-to-utf8 s)]
(let [utf8 (native-module/hex-to-utf8 s)]
(if (empty? utf8)
nil
utf8)))
@@ -118,7 +118,7 @@
(defn address?
[s]
(when s
(status/address? s)))
(native-module/address? s)))
(defn network->chain-id
[network]
+3 -3
View File
@@ -5,7 +5,7 @@
e.g. 0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"
(:require [clojure.string :as string]
[status-im.native-module.core :as status]))
[native-module.core :as native-module]))
(def hex-prefix "0x")
@@ -13,7 +13,7 @@
"Converts an arbitrary case address to one with correct checksum case."
[address]
(when address
(status/to-checksum-address
(native-module/to-checksum-address
(if (string/starts-with? address hex-prefix)
address
(str hex-prefix address)))))
@@ -21,4 +21,4 @@
(defn valid-address-checksum?
"Checks address checksum validity."
[address]
(status/check-address-checksum address))
(native-module/check-address-checksum address))
+2 -2
View File
@@ -1,6 +1,6 @@
(ns status-im.ethereum.encode
(:require [status-im.native-module.core :as status]))
(:require [native-module.core :as native-module]))
(defn uint
[x]
(str "0x" (status/number-to-hex x)))
(str "0x" (native-module/number-to-hex x)))
+2 -2
View File
@@ -1,6 +1,6 @@
(ns status-im.ethereum.ens
(:require [clojure.string :as string]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im2.common.json-rpc.events :as json-rpc]))
;; this is the addresses of ens registries for the different networks
@@ -66,7 +66,7 @@
:params [chain-id ens-name]
:on-success
;;NOTE: returns a timestamp in s and we want ms
#(cb (* (js/Number (status/hex-to-number %)) 1000))}))
#(cb (* (js/Number (native-module/hex-to-number %)) 1000))}))
(defn register-prepare-tx
[chain-id from ens-name pubkey cb]
+10 -4
View File
@@ -7,7 +7,6 @@
status-im.bootnodes.core
status-im.browser.core
status-im.browser.permissions
status-im.chat.models
status-im.chat.models.images
status-im.chat.models.input
status-im.chat.models.loading
@@ -30,7 +29,7 @@
status-im.multiaccounts.logout.core
[status-im.multiaccounts.model :as multiaccounts.model]
status-im.multiaccounts.update.core
[status-im.native-module.core :as status]
[native-module.core :as native-module]
status-im.network.net-info
status-im.pairing.core
status-im.profile.core
@@ -60,6 +59,9 @@
status-im2.contexts.onboarding.events
status-im.chat.models.gaps
[status-im2.navigation.events :as navigation]
[status-im2.common.theme.core :as theme]
[react-native.core :as rn]
[react-native.platform :as platform]
status-im2.contexts.chat.home.events))
(re-frame/reg-fx
@@ -85,12 +87,16 @@
(re-frame/reg-fx
:ui/close-application
(fn [_]
(status/close-application)))
(native-module/close-application)))
(re-frame/reg-fx
::app-state-change-fx
(fn [state]
(status/app-state-change state)))
(when (and platform/ios? (= state "active"))
;; Change the app theme if the ios device theme was updated when the app was in the background
;; https://github.com/status-im/status-mobile/issues/15708
(theme/change-device-theme (rn/get-color-scheme)))
(native-module/app-state-change state)))
(re-frame/reg-fx
:ui/listen-to-window-dimensions-change
-15
View File
@@ -2,21 +2,6 @@
(:require [re-frame.core :as re-frame]
[status-im.utils.http :as http]))
(re-frame/reg-fx
:http-get
(fn [{:keys [url response-validator on-success on-error timeout-ms]}]
(let [opts {:valid-response? response-validator
:timeout-ms timeout-ms}]
(http/get url on-success on-error opts))))
(re-frame/reg-fx
:http-get-n
(fn [calls]
(doseq [{:keys [url response-validator on-success on-error timeout-ms]} calls]
(let [opts {:valid-response? response-validator
:timeout-ms timeout-ms}]
(http/get url on-success on-error opts)))))
(re-frame/reg-fx
:http-post
(fn [{:keys [url data response-validator on-success on-error timeout-ms opts]}]
+1 -1
View File
@@ -125,7 +125,7 @@
(rf-test/wait-for ; wait for login
[::transport/messenger-started]
(assert-messenger-started)
(rf/dispatch-sync [:status-im.communities.core/open-create-community])
(rf/dispatch-sync [:legacy-only-for-e2e/open-create-community])
(doseq [[k v] (dissoc community :membership)]
(rf/dispatch-sync [:status-im.communities.core/create-field k v]))
(rf/dispatch [:status-im.communities.core/create-confirmation-pressed])
+2 -2
View File
@@ -3,7 +3,7 @@
["react-native" :refer (BackHandler)]
[re-frame.core :as re-frame]
[status-im.keycard.card :as card]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.utils.types :as types]
[taoensso.timbre :as log]))
@@ -202,7 +202,7 @@
(re-frame/reg-fx
:keycard/generate-name-and-photo
(fn [{:keys [public-key on-success]}]
(status/gfycat-identicon-async
(native-module/gfycat-identicon-async
public-key
(fn [whisper-name photo-path]
(re-frame/dispatch
+5 -5
View File
@@ -4,7 +4,7 @@
[clojure.string :as string]
[status-im.ethereum.core :as ethereum]
[status-im.keycard.keycard :as keycard]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.utils.platform :as platform]
[status-im.utils.types :as types]
[taoensso.timbre :as log]))
@@ -296,7 +296,7 @@
(defn save-multiaccount-and-login
[{:keys [key-uid multiaccount-data password settings node-config accounts-data chat-key]}]
(status/save-multiaccount-and-login-with-keycard
(native-module/save-multiaccount-and-login-with-keycard
key-uid
(types/clj->json multiaccount-data)
password
@@ -307,15 +307,15 @@
(defn login
[args]
(status/login-with-keycard args))
(native-module/login-with-keycard args))
(defn send-transaction-with-signature
[{:keys [transaction signature on-completed]}]
(status/send-transaction-with-signature transaction signature on-completed))
(native-module/send-transaction-with-signature transaction signature on-completed))
(defn delete-multiaccount-before-migration
[{:keys [key-uid on-success on-error]}]
(status/delete-multiaccount
(native-module/delete-multiaccount
key-uid
(fn [result]
(let [{:keys [error]} (types/json->clj result)]
+3 -3
View File
@@ -10,7 +10,7 @@
status-im.keycard.fx
[status-im.multiaccounts.create.core :as multiaccounts.create]
[status-im.multiaccounts.model :as multiaccounts.model]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.popover.core :as popover]
[utils.re-frame :as rf]
[utils.datetime :as datetime]
@@ -250,14 +250,14 @@
(re-frame/reg-fx
::finish-migration
(fn [[account settings password encryption-pass login-params]]
(status/convert-to-keycard-account
(native-module/convert-to-keycard-account
account
settings
password
encryption-pass
#(let [{:keys [error]} (types/json->clj %)]
(if (string/blank? error)
(status/login-with-keycard login-params)
(native-module/login-with-keycard login-params)
(throw
(js/Error.
"Please shake the phone to report this error and restart the app. Migration failed unexpectedly.")))))))
+15 -15
View File
@@ -7,7 +7,7 @@
[utils.i18n :as i18n]
[status-im.keycard.keycard :as keycard]
[status-im.multiaccounts.create.core :as multiaccounts.create]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.node.core :as node]
[status-im.utils.types :as types]
[status-im.utils.utils :as utils]
@@ -249,14 +249,14 @@
[{:keys [password on-success]}]
(when (and (not @initialization)
(not @derived-acc))
(status/multiaccount-import-mnemonic
(native-module/multiaccount-import-mnemonic
"night fortune spider version version armed amused winner matter tonight cave flag"
nil
(fn [result]
(let [{:keys [id] :as root-data}
(multiaccounts.create/normalize-multiaccount-data-keys
(types/json->clj result))]
(status-im.native-module.core/multiaccount-derive-addresses
(native-module.core/multiaccount-derive-addresses
id
[constants/path-wallet-root
constants/path-eip1581
@@ -266,7 +266,7 @@
(let [derived-data (multiaccounts.create/normalize-derived-data-keys
(types/json->clj result))
public-key (get-in derived-data [constants/path-whisper-keyword :public-key])]
(status/gfycat-identicon-async
(native-module/gfycat-identicon-async
public-key
(fn [name photo-path]
(let [derived-data-extended
@@ -294,7 +294,7 @@
(if delete-multiaccount?
(fn [on-deletion-success]
(js/alert "OH SHEET")
(status/delete-multiaccount
(native-module/delete-multiaccount
key-uid
(fn [result]
(let [{:keys [error]} (types/json->clj result)]
@@ -304,7 +304,7 @@
(fn [cb] (cb)))]
(deletion-wrapper
(fn []
(status/multiaccount-store-derived
(native-module/multiaccount-store-derived
id
(:key-uid response)
[constants/path-wallet-root
@@ -398,14 +398,14 @@
path-num (inc (get-in @re-frame.db/app-db
[:multiaccount :latest-derived-path]))
path (str "m/" path-num)]
(status/multiaccount-load-account
(native-module/multiaccount-load-account
wallet-root-address
hashed-password
(fn [value]
(let [{:keys [id error]} (types/json->clj value)]
(if error
(re-frame/dispatch [::new-account-error :password-error error])
(status/multiaccount-derive-addresses
(native-module/multiaccount-derive-addresses
id
[path]
(fn [derived]
@@ -413,7 +413,7 @@
(if (some (fn [a] (= derived-address (get a :address))) accounts)
(re-frame/dispatch [::new-account-error :account-error
(i18n/label :t/account-exists-title)])
(status/multiaccount-store-derived
(native-module/multiaccount-store-derived
id
key-uid
[path]
@@ -436,7 +436,7 @@
(swap! state assoc-in
[:application-info :key-uid]
(:key-uid keys))
(status/multiaccount-store-derived
(native-module/multiaccount-store-derived
id
(:key-uid keys)
[constants/path-wallet-root
@@ -473,7 +473,7 @@
{:account address
:password password
:data (or data (str "0x" hash))})]
(status/sign-message
(native-module/sign-message
params
(fn [res]
(let [signature (-> res
@@ -481,7 +481,7 @@
:result
ethereum/normalized-hex)]
(on-success signature)))))
(status/sign-typed-data
(native-module/sign-typed-data
data
address
password
@@ -498,7 +498,7 @@
(defn save-multiaccount-and-login
[{:keys [key-uid multiaccount-data password settings node-config accounts-data]}]
(status/save-account-and-login
(native-module/save-account-and-login
key-uid
(types/clj->json multiaccount-data)
password
@@ -508,11 +508,11 @@
(defn login
[{:keys [key-uid multiaccount-data password]}]
(status/login-with-config key-uid multiaccount-data password node/login-node-config))
(native-module/login-with-config key-uid multiaccount-data password node/login-node-config))
(defn send-transaction-with-signature
[{:keys [transaction on-completed]}]
(status/send-transaction transaction account-password on-completed))
(native-module/send-transaction transaction account-password on-completed))
(defn delete-multiaccount-before-migration
[{:keys [on-success]}]
@@ -3,7 +3,7 @@
[quo.design-system.colors :as colors]
[re-frame.core :as re-frame]
[utils.i18n :as i18n]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.popover.core :as popover]
[utils.re-frame :as rf]
[status-im.utils.keychain.core :as keychain]
@@ -17,7 +17,7 @@
;;; android blacklist based on device info:
(def deviceinfo (status/get-device-model-info))
(def deviceinfo (native-module/get-device-model-info))
;; {:model ?
;; :brand "Xiaomi"
+2 -1
View File
@@ -4,7 +4,7 @@
[re-frame.core :as re-frame]
[status-im.bottom-sheet.events :as bottom-sheet]
[status-im.multiaccounts.update.core :as multiaccounts.update]
[status-im.native-module.core :as native-module]
[native-module.core :as native-module]
[utils.re-frame :as rf]
[quo2.foundations.colors :as colors]
[status-im2.constants :as constants]
@@ -150,6 +150,7 @@
(re-frame/dispatch [:change-shell-status-bar-style
(if (shell.animation/home-stack-open?) status-bar-theme :light)])
(when reload-ui?
(rf/dispatch [:dissmiss-all-overlays])
(hot-reload/reload)
(when-not (= view-id :shell-stack)
(re-frame/dispatch [:change-shell-nav-bar-color nav-bar-color]))))))
+5 -5
View File
@@ -6,7 +6,7 @@
[status-im.ethereum.core :as ethereum]
[status-im.ethereum.eip55 :as eip55]
[utils.i18n :as i18n]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.node.core :as node]
[status-im2.config :as config]
[utils.re-frame :as rf]
@@ -44,7 +44,7 @@
(re-frame/reg-fx
::store-multiaccount
(fn [[id key-uid hashed-password callback]]
(status/multiaccount-store-derived
(native-module/multiaccount-store-derived
id
key-uid
[constants/path-wallet-root
@@ -69,7 +69,7 @@
(fn [result]
(let [derived-data (normalize-derived-data-keys (types/json->clj result))
public-key (get-in derived-data [constants/path-whisper-keyword :public-key])]
(status/gfycat-identicon-async
(native-module/gfycat-identicon-async
public-key
(fn [name identicon]
(let [derived-whisper (derived-data constants/path-whisper-keyword)
@@ -81,7 +81,7 @@
(re-frame/reg-fx
:multiaccount-generate-and-derive-addresses
(fn []
(status/multiaccount-generate-and-derive-addresses
(native-module/multiaccount-generate-and-derive-addresses
5
12
[constants/path-whisper
@@ -127,7 +127,7 @@
(re-frame/reg-fx
::save-account-and-login
(fn [[key-uid multiaccount-data hashed-password settings config accounts-data]]
(status/save-account-and-login
(native-module/save-account-and-login
key-uid
multiaccount-data
hashed-password
@@ -11,7 +11,7 @@
[status-im.multiaccounts.logout.core :as multiaccounts.logout]
[status-im.multiaccounts.model :as multiaccounts.model]
[status-im.multiaccounts.recover.core :as multiaccounts.recover]
[status-im.native-module.core :as native-module]
[native-module.core :as native-module]
[status-im.popover.core :as popover]
[utils.re-frame :as rf]
[status-im.utils.types :as types]
+6 -6
View File
@@ -20,7 +20,7 @@
[status-im.mobile-sync-settings.core :as mobile-network]
[status-im.multiaccounts.biometric.core :as biometric]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.node.core :as node]
[status-im.notifications.core :as notifications]
[status-im.popover.core :as popover]
@@ -58,22 +58,22 @@
(re-frame/reg-fx
::login
(fn [[key-uid account-data hashed-password]]
(status/login-with-config key-uid account-data hashed-password node/login-node-config)))
(native-module/login-with-config key-uid account-data hashed-password node/login-node-config)))
(re-frame/reg-fx
::export-db
(fn [[key-uid account-data hashed-password callback]]
(status/export-db key-uid account-data hashed-password callback)))
(native-module/export-db key-uid account-data hashed-password callback)))
(re-frame/reg-fx
::import-db
(fn [[key-uid account-data hashed-password]]
(status/import-db key-uid account-data hashed-password)))
(native-module/import-db key-uid account-data hashed-password)))
(re-frame/reg-fx
::enable-local-notifications
(fn []
(status/start-local-notifications)))
(native-module/start-local-notifications)))
(re-frame/reg-fx
::initialize-wallet-connect
@@ -363,7 +363,7 @@
(rf/defn get-node-config
[_]
(status/get-node-config #(re-frame/dispatch [::get-node-config-callback %])))
(native-module/get-node-config #(re-frame/dispatch [::get-node-config-callback %])))
(rf/defn redirect-to-root
"Decides which root should be initialised depending on user and app state"
+2 -3
View File
@@ -2,7 +2,7 @@
(:require [re-frame.core :as re-frame]
[utils.i18n :as i18n]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.notifications.core :as notifications]
[utils.re-frame :as rf]
[status-im.utils.keychain.core :as keychain]
@@ -16,7 +16,6 @@
(rf/merge cofx
{:set-root :progress
:chat.ui/clear-inputs nil
:chat.ui/clear-inputs-old nil
:shell/reset-bottom-tabs nil
:hide-popover nil
::logout nil
@@ -62,4 +61,4 @@
(re-frame/reg-fx
::logout
(fn []
(status/logout)))
(native-module/logout)))
@@ -9,7 +9,7 @@
[status-im.keycard.nfc :as nfc]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.multiaccounts.create.core :as multiaccounts.create]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.popover.core :as popover]
[utils.re-frame :as rf]
[status-im.utils.types :as types]
@@ -89,14 +89,14 @@
::import-multiaccount
(fn [{:keys [passphrase password success-event]}]
(log/debug "[recover] ::import-multiaccount")
(status/multiaccount-import-mnemonic
(native-module/multiaccount-import-mnemonic
passphrase
password
(fn [result]
(let [{:keys [id] :as root-data}
(multiaccounts.create/normalize-multiaccount-data-keys
(types/json->clj result))]
(status-im.native-module.core/multiaccount-derive-addresses
(native-module.core/multiaccount-derive-addresses
id
[constants/path-wallet-root
constants/path-eip1581
@@ -106,7 +106,7 @@
(let [derived-data (multiaccounts.create/normalize-derived-data-keys
(types/json->clj result))
public-key (get-in derived-data [constants/path-whisper-keyword :public-key])]
(status/gfycat-identicon-async
(native-module/gfycat-identicon-async
public-key
(fn [name identicon]
(let [derived-data-extended
@@ -2,7 +2,7 @@
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.ethereum.core :as ethereum]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.popover.core :as popover]
[utils.re-frame :as rf]
[status-im.utils.keychain.core :as keychain]
@@ -59,7 +59,7 @@
(re-frame/reg-fx
::change-db-password
(fn [[key-uid {:keys [current-password new-password]}]]
(status/reset-password
(native-module/reset-password
key-uid
(ethereum/sha3 (security/safe-unmask-data current-password))
(ethereum/sha3 (security/safe-unmask-data new-password))
@@ -88,9 +88,9 @@
::validate-current-password-and-reset
(fn [{:keys [address current-password] :as form-vals}]
(let [hashed-pass (ethereum/sha3 (security/safe-unmask-data current-password))]
(status/verify address
hashed-pass
(partial handle-verification form-vals)))))
(native-module/verify address
hashed-pass
(partial handle-verification form-vals)))))
(rf/defn reset
{:events [::reset]}
+2 -2
View File
@@ -2,7 +2,7 @@
(:require ["@react-native-community/netinfo" :default net-info]
[re-frame.core :as re-frame]
[status-im.mobile-sync-settings.core :as mobile-network]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[utils.re-frame :as rf]
[status-im.wallet.core :as wallet]
[taoensso.timbre :as log]))
@@ -59,4 +59,4 @@
(re-frame/reg-fx
:network/notify-status-go
(fn [[network-type expensive?]]
(status/connection-change network-type expensive?)))
(native-module/connection-change network-type expensive?)))
+2 -2
View File
@@ -1,6 +1,6 @@
(ns status-im.node.core
(:require [re-frame.core :as re-frame]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im2.config :as config]
[utils.re-frame :as rf]
[status-im.utils.platform :as utils.platform]
@@ -221,4 +221,4 @@ app-db"
(re-frame/reg-fx
::prepare-new-config
(fn [[key-uid config callback]]
(status/prepare-dir-and-update-config key-uid config callback)))
(native-module/prepare-dir-and-update-config key-uid config callback)))
+3 -3
View File
@@ -11,9 +11,9 @@
[status-im.notifications.android :as pn-android]
[utils.re-frame :as rf]
[status-im.utils.money :as money]
[status-im.utils.react-native :as react-native-utils]
[status-im.utils.types :as types]
[status-im.utils.utils :as utils]))
[status-im.utils.utils :as utils]
[react-native.core :as rn]))
(def default-erc20-token
{:symbol :ERC20
@@ -56,7 +56,7 @@
(fn [notification]
(handle-notification-press {:userInfo (bean/bean (.getData ^js
notification))})))
(.addListener ^js react-native-utils/device-event-emitter
(.addListener ^js rn/device-event-emitter
notification-event-android
(fn [^js data]
(when (and data (.-dataJSON data))
+6 -15
View File
@@ -1,7 +1,5 @@
(ns status-im.qr-scanner.core
(:require [re-frame.core :as re-frame]
[status-im.add-new.db :as new-chat.db]
[status-im.chat.models :as chat]
[status-im.ethereum.core :as ethereum]
[status-im.group-chats.core :as group-chats]
[utils.i18n :as i18n]
@@ -43,25 +41,24 @@
{:browser/show-browser-selection url}
(navigation/navigate-back)))
(defn own-public-key?
[{:keys [multiaccount]} public-key]
(= (:public-key multiaccount) public-key))
(rf/defn handle-private-chat
[{:keys [db] :as cofx} {:keys [chat-id]}]
(if-not (new-chat.db/own-public-key? db chat-id)
(if-not (own-public-key? db chat-id)
{:dispatch [:chat.ui/start-chat chat-id]}
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:content (i18n/label :t/can-not-add-yourself)}}))
(rf/defn handle-public-chat
[cofx {:keys [topic]}]
(when (seq topic)
(chat/start-public-chat cofx topic)))
(rf/defn handle-group-chat
[cofx params]
(group-chats/create-from-link cofx params))
(rf/defn handle-view-profile
[{:keys [db] :as cofx} {:keys [public-key ens-name]}]
(let [own (new-chat.db/own-public-key? db public-key)]
(let [own (own-public-key? db public-key)]
(cond
(and public-key own)
(rf/merge cofx
@@ -85,11 +82,6 @@
(navigation/change-tab :wallet-stack)
(navigation/pop-to-root :shell-stack)))
(rf/defn handle-wallet-connect
{:events [::handle-wallet-connect-uri]}
[cofx data]
{:dispatch [:wallet-connect/pair data]})
(rf/defn handle-local-pairing
{:events [::handle-local-pairing-uri]}
[_ data]
@@ -99,7 +91,6 @@
{:events [::match-scanned-value]}
[cofx {:keys [type] :as data}]
(case type
:public-chat (handle-public-chat cofx data)
:group-chat (handle-group-chat cofx data)
:private-chat (handle-private-chat cofx data)
:contact (handle-view-profile cofx data)
@@ -65,11 +65,3 @@
k
(get ui k))
k)))
(def reactions-old
{:love (js/require "../resources/images/reactions/love.png")
:angry (js/require "../resources/images/reactions/angry.png")
:sad (js/require "../resources/images/reactions/sad.png")
:laugh (js/require "../resources/images/reactions/laugh.png")
:thumbs-up (js/require "../resources/images/reactions/thumbs-up.png")
:thumbs-down (js/require "../resources/images/reactions/thumbs-down.png")})
+5 -19
View File
@@ -2,16 +2,15 @@
(:require [bidi.bidi :as bidi]
[clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.add-new.db :as public-chat.db]
[status-im2.contexts.chat.events :as chat.events]
[status-im2.constants :as constants]
[status-im.ethereum.core :as ethereum]
[status-im.ethereum.eip681 :as eip681]
[status-im.ethereum.ens :as ens]
[status-im.utils.types :as types]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.ethereum.stateofus :as stateofus]
[status-im2.utils.validators :as validators]
[utils.validators :as validators]
[status-im.utils.http :as http]
[status-im.utils.wallet-connect :as wallet-connect]
[taoensso.timbre :as log]
@@ -21,8 +20,6 @@
(def uri-schemes ["status-im://" "status-im:"])
(def wallet-connect-scheme "wc:")
(def web-prefixes ["https://" "http://" "https://www." "http://wwww."])
(def web2-domain "join.status.im")
@@ -48,9 +45,7 @@
(def routes
[""
{handled-schemes {["" :chat-id] :public-chat
"chat" {["/public/" :chat-id] :public-chat}
"b/" browser-extractor
{handled-schemes {"b/" browser-extractor
"browser/" browser-extractor
["p/" :chat-id] :private-chat
["cr/" :community-id] :community-requests
@@ -83,8 +78,9 @@
:ens-name ens-name})
valid-compressed-key?
(status/compressed-key->public-key
(native-module/compressed-key->public-key
user-id
constants/deserialization-key
(fn [response]
(let [{:keys [error]} (types/json->clj response)]
(when-not error
@@ -106,14 +102,6 @@
(callback {:type :contact
:error :not-found}))))
(defn match-public-chat
[{:keys [chat-id]}]
(if (public-chat.db/valid-topic? chat-id)
{:type :public-chat
:topic chat-id}
{:type :public-chat
:error :invalid-topic}))
(defn match-group-chat
[chats {:strs [a a1 a2]}]
(let [[admin-pk encoded-chat-name chat-id] [a a1 a2]
@@ -224,8 +212,6 @@
(let [{:keys [handler route-params query-params]} (match-uri uri)]
(log/info "[router] uri " uri " matched " handler " with " route-params)
(cond
(= handler :public-chat)
(cb (match-public-chat route-params))
(= handler :browser)
(cb (match-browser uri route-params))
-6
View File
@@ -18,9 +18,6 @@
:query-params (when (= 3 (count expected)) (last expected))
:uri uri})
"status-im://status"
[:public-chat {:chat-id "status"}]
"status-im://u/statuse2e"
[:user {:user-id "statuse2e"}]
@@ -36,9 +33,6 @@
(str "https://join.status.im/g/args?a=" public-key "&a1=" chat-name-url "&a2=" chat-id)
[:group-chat {:params "arg"} {"a" public-key "a1" chat-name "a2" chat-id}]
"https://join.status.im/status"
[:public-chat {:chat-id "status"}]
"https://join.status.im/u/statuse2e"
[:user {:user-id "statuse2e"}]
+22 -22
View File
@@ -9,7 +9,7 @@
[utils.i18n :as i18n]
[status-im.keycard.card :as keycard.card]
[status-im.keycard.common :as keycard.common]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.signing.eip1559 :as eip1559]
[status-im.signing.keycard :as signing.keycard]
[utils.re-frame :as rf]
@@ -26,9 +26,9 @@
(re-frame/reg-fx
:signing/send-transaction-fx
(fn [{:keys [tx-obj hashed-password cb]}]
(status/send-transaction (types/clj->json tx-obj)
hashed-password
cb)))
(native-module/send-transaction (types/clj->json tx-obj)
hashed-password
cb)))
(re-frame/reg-fx
:signing/show-transaction-error
@@ -43,21 +43,21 @@
(re-frame/reg-fx
:signing.fx/sign-message
(fn [{:keys [params on-completed]}]
(status/sign-message (types/clj->json params)
on-completed)))
(native-module/sign-message (types/clj->json params)
on-completed)))
(re-frame/reg-fx
:signing.fx/recover-message
(fn [{:keys [params on-completed]}]
(status/recover-message (types/clj->json params)
on-completed)))
(native-module/recover-message (types/clj->json params)
on-completed)))
(re-frame/reg-fx
:signing.fx/sign-typed-data
(fn [{:keys [v4 data account on-completed hashed-password]}]
(if v4
(status/sign-typed-data-v4 data account hashed-password on-completed)
(status/sign-typed-data data account hashed-password on-completed))))
(native-module/sign-typed-data-v4 data account hashed-password on-completed)
(native-module/sign-typed-data data account hashed-password on-completed))))
(defn get-contact
[db to]
@@ -109,18 +109,18 @@
(sign-message cofx)
(let [tx-obj-to-send (merge tx-obj
(when gas
{:gas (str "0x" (status/number-to-hex gas))})
{:gas (str "0x" (native-module/number-to-hex gas))})
(when gasPrice
{:gasPrice (str "0x" (status/number-to-hex gasPrice))})
{:gasPrice (str "0x" (native-module/number-to-hex gasPrice))})
(when nonce
{:nonce (str "0x" (status/number-to-hex nonce))})
{:nonce (str "0x" (native-module/number-to-hex nonce))})
(when maxPriorityFeePerGas
{:maxPriorityFeePerGas (str "0x"
(status/number-to-hex
(native-module/number-to-hex
(js/parseInt maxPriorityFeePerGas)))})
(when maxFeePerGas
{:maxFeePerGas (str "0x"
(status/number-to-hex
(native-module/number-to-hex
(js/parseInt maxFeePerGas)))}))]
(when-not in-progress?
{:db (update db :signing/sign assoc :error nil :in-progress? true)
@@ -184,7 +184,7 @@
(let [{:keys [symbol decimals] :as token} (tokens/address->token (:wallet/all-tokens db) to)]
(when (and token data (string? data))
(when-let [type (get-method-type data)]
(let [[address value _] (status/decode-parameters
(let [[address value _] (native-module/decode-parameters
(str "0x" (subs data 10))
(if (= type :approve-and-call)
["address" "uint256" "bytes"]
@@ -476,7 +476,7 @@
{:events [:wallet.ui/sign-transaction-button-clicked-from-chat]}
[{:keys [db] :as cofx} {:keys [to amount from token]}]
(let [{:keys [symbol address]} token
amount-hex (str "0x" (status/number-to-hex amount))
amount-hex (str "0x" (native-module/number-to-hex amount))
to-norm (ethereum/normalized-hex (if (string? to) to (:address to)))
from-address (:address from)
identity (:current-chat-id db)
@@ -495,7 +495,7 @@
:from from-address
:chat-id identity
:command? true
:data (status/encode-transfer to-norm amount-hex)})}))
:data (native-module/encode-transfer to-norm amount-hex)})}))
{:db db
:json-rpc/call
[{:method "wakuext_requestAddressForTransaction"
@@ -512,7 +512,7 @@
[{:keys [db] :as cofx} {:keys [amount from token]}]
(let [{:keys [request-parameters chat-id]} (:wallet/prepare-transaction db)
{:keys [symbol address]} token
amount-hex (str "0x" (status/number-to-hex amount))
amount-hex (str "0x" (native-module/number-to-hex amount))
to-norm (:address request-parameters)
from-address (:address from)]
(rf/merge cofx
@@ -532,13 +532,13 @@
:command? true
:message-id (:id request-parameters)
:chat-id chat-id
:data (status/encode-transfer to-norm amount-hex)})})))))
:data (native-module/encode-transfer to-norm amount-hex)})})))))
(rf/defn sign-transaction-button-clicked
{:events [:wallet.ui/sign-transaction-button-clicked]}
[{:keys [db] :as cofx} {:keys [to amount from token gas gasPrice maxFeePerGas maxPriorityFeePerGas]}]
(let [{:keys [symbol address]} token
amount-hex (str "0x" (status/number-to-hex amount))
amount-hex (str "0x" (native-module/number-to-hex amount))
to-norm (ethereum/normalized-hex (if (string? to) to (:address to)))
from-address (:address from)]
(rf/merge cofx
@@ -558,7 +558,7 @@
{:to to-norm
:value amount-hex}
{:to (ethereum/normalized-hex address)
:data (status/encode-transfer to-norm amount-hex)}))}))))
:data (native-module/encode-transfer to-norm amount-hex)}))}))))
(re-frame/reg-fx
:signing/get-transaction-by-hash-fx
+4 -4
View File
@@ -1,15 +1,15 @@
(ns status-im.signing.core-test
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.signing.core :as signing]))
(deftest signing-test
(testing "showing sheet"
(let [to "0x2f88d65f3cb52605a54a833ae118fb1363acccd2"
contract "0xc55cf4b03948d7ebc8b9e8bad92643703811d162"
amount1-hex (str "0x" (status/number-to-hex "10000000000000000000"))
amount2-hex (str "0x" (status/number-to-hex "100000000000000000000"))
data (status/encode-transfer to amount2-hex)
amount1-hex (str "0x" (native-module/number-to-hex "10000000000000000000"))
amount2-hex (str "0x" (native-module/number-to-hex "100000000000000000000"))
data (native-module/encode-transfer to amount2-hex)
first-tx {:tx-obj {:to to
:from nil
:value amount1-hex}}
+9 -9
View File
@@ -1,7 +1,7 @@
(ns status-im.signing.keycard
(:require [re-frame.core :as re-frame]
[utils.i18n :as i18n]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[utils.re-frame :as rf]
[status-im.utils.types :as types]
[taoensso.timbre :as log]))
@@ -9,19 +9,19 @@
(re-frame/reg-fx
::hash-transaction
(fn [{:keys [transaction on-completed]}]
(status/hash-transaction (types/clj->json transaction) on-completed)))
(native-module/hash-transaction (types/clj->json transaction) on-completed)))
(re-frame/reg-fx
::hash-message
(fn [{:keys [message on-completed]}]
(status/hash-message message on-completed)))
(native-module/hash-message message on-completed)))
(re-frame/reg-fx
::hash-typed-data
(fn [{:keys [v4 data on-completed]}]
(if v4
(status/hash-typed-data-v4 data on-completed)
(status/hash-typed-data data on-completed))))
(native-module/hash-typed-data-v4 data on-completed)
(native-module/hash-typed-data data on-completed))))
(defn prepare-transaction
[{:keys [gas gasPrice data nonce tx-obj] :as params}]
@@ -37,17 +37,17 @@
maxPriorityFeePerGas
(assoc :maxPriorityFeePerGas
(str "0x"
(status/number-to-hex
(native-module/number-to-hex
(js/parseInt maxPriorityFeePerGas))))
maxFeePerGas
(assoc :maxFeePerGas
(str "0x"
(status/number-to-hex
(native-module/number-to-hex
(js/parseInt maxFeePerGas))))
gas
(assoc :gas (str "0x" (status/number-to-hex gas)))
(assoc :gas (str "0x" (native-module/number-to-hex gas)))
gasPrice
(assoc :gasPrice (str "0x" (status/number-to-hex gasPrice)))
(assoc :gasPrice (str "0x" (native-module/number-to-hex gasPrice)))
data
(assoc :data data)
nonce
@@ -1,362 +0,0 @@
(ns status-im.ui.screens.add-new.new-chat.views
(:require
[clojure.string :as string]
[quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.platform :as platform]
[quo.react-native :as rn]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.ethereum.ens :as ens]
[utils.i18n :as i18n]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.qr-scanner.core :as qr-scanner]
[status-im.ui.components.animation :as animation]
[status-im.ui.components.chat-icon.screen :as chat-icon]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.invite.views :as invite]
[status-im.ui.components.keyboard-avoid-presentation :as kb-presentation]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.react :as react]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.chat.photos :as photos]
[status-im2.utils.validators :as validators]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.identicon :as identicon]
[status-im.utils.utils :as utils]
[utils.debounce :as debounce])
(:require-macros [status-im.utils.views :as views]))
(defn- render-row
[row]
[quo/list-item
{:title (:primary-name row)
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo row)]
:on-press #(re-frame/dispatch [:chat.ui/start-chat
(:public-key row)])}])
(defn- icon-wrapper
[color icon]
[react/view
{:style {:width 32
:height 32
:border-radius 25
:align-items :center
:justify-content :center
:background-color color}}
icon])
(defn- input-icon
[state new-contact? entered-nickname blocked?]
(let [icon (if new-contact? :main-icons/add :main-icons/arrow-right)]
(cond
(= state :searching)
[icon-wrapper colors/gray
[react/activity-indicator {:color colors/white-persist}]]
(and (= state :valid) (not blocked?))
[react/touchable-highlight
{:on-press #(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted new-contact?
entered-nickname]
3000)}
[icon-wrapper colors/blue
[icons/icon icon {:color colors/white-persist}]]]
:else
[icon-wrapper colors/gray
[icons/icon icon {:color colors/white-persist}]])))
(defn get-validation-label
[value]
(case value
:invalid
(i18n/label :t/profile-not-found)
:yourself
(i18n/label :t/can-not-add-yourself)))
(defn search-contacts
[filter-text {:keys [name alias nickname]}]
(or
(string/includes? (string/lower-case (str name)) filter-text)
(string/includes? (string/lower-case (str alias)) filter-text)
(when nickname
(string/includes? (string/lower-case (str nickname)) filter-text))))
(defn filter-contacts
[filter-text contacts]
(let [lower-filter-text (string/lower-case filter-text)]
(if filter-text
(filter (partial search-contacts lower-filter-text) contacts)
contacts)))
(defn is-public-key?
[k]
(and
(string? k)
(string/starts-with? k "0x")))
(defn is-valid-username?
[username]
(let [is-chat-key? (and (is-public-key? username)
(= (count username) 132))
is-ens? (ens/valid-eth-name-prefix? username)]
(or is-chat-key? is-ens?)))
(defn translate-anim
[translate-y-value translate-y-anim-value]
(animation/start
(animation/timing translate-y-anim-value
{:toValue translate-y-value
:duration 200
:useNativeDriver true})))
(views/defview new-chat
[]
(views/letsubs [contacts [:contacts/active]
{:keys [state ens-name public-key error]} [:contacts/new-identity]
search-value (reagent/atom "")
account @(re-frame/subscribe [:multiaccount])
on-share #(re-frame/dispatch
[:show-popover
{:view :share-chat-key
:address (account :public-key)
:ens-name (account :preferred-name)}])
my-profile-button-anim-y (animation/create-value 0)
keyboard-show-listener (atom nil)
keyboard-hide-listener (atom nil)
on-keyboard-show (fn []
;; 42 is the bottom position so we
;; translate it by 32 pts to leave 10 as
;; margin
(translate-anim 32
my-profile-button-anim-y))
on-keyboard-hide (fn []
(translate-anim 0
my-profile-button-anim-y))
keyboard-show-event (if platform/android?
"keyboardDidShow"
"keyboardWillShow")
keyboard-hide-event (if platform/android?
"keyboardDidHide"
"keyboardWillHide")]
{:component-did-mount
(fn [_]
(reset! keyboard-show-listener (.addListener react/keyboard keyboard-show-event on-keyboard-show))
(reset! keyboard-hide-listener (.addListener react/keyboard
keyboard-hide-event
on-keyboard-hide)))
:component-will-unmount
(fn []
(some-> ^js @keyboard-show-listener
.remove)
(some-> ^js @keyboard-hide-listener
.remove))}
[kb-presentation/keyboard-avoiding-view {:style {:flex 1}}
[react/view {:style {:flex 1}}
[topbar/topbar
{:title (i18n/label :t/new-chat)
:modal? true
:right-accessories
[{:icon :qr
:accessibility-label :scan-contact-code-button
:on-press #(re-frame/dispatch [::qr-scanner/scan-code
{:title (i18n/label :t/new-chat)
:handler :contact/qr-code-scanned}])}]}]
[react/view
{:flex-direction :row
:padding 16}
[react/view {:flex 1}
[quo/text-input
{:on-change-text
#(do
(reset! search-value %)
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :empty])
(debounce/debounce-and-dispatch [:contacts/set-new-identity %] 600))
:on-submit-editing
#(when (= state :valid)
(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted false nil] 3000))
:placeholder (i18n/label :t/enter-contact-code)
:show-cancel false
:accessibility-label :enter-contact-code-input
:auto-capitalize :none
:return-key-type :go
:monospace true
:auto-correct false}]]]
[react/scroll-view
{:style {:flex 1}
:keyboard-dismiss-mode :on-drag
:keyboard-should-persist-taps :handled}
[react/view
(when (and
(= (count contacts) 0)
(= @search-value ""))
{:flex 1})
(if (and
(= (count contacts) 0)
(= @search-value ""))
[react/view
{:flex 1
:align-items :center
:padding-horizontal 58
:padding-top 160}
[quo/text
{:size :base
:align :center
:color :secondary}
(i18n/label :t/you-dont-have-contacts-invite-friends)]
[invite/button]]
[list/flat-list
{:data (filter-contacts @search-value contacts)
:key-fn :address
:render-fn render-row}])]
(when-not (= @search-value "")
[react/view
[quo/text
{:style {:margin-horizontal 16
:margin-vertical 14}
:size :base
:align :left
:color :secondary}
(i18n/label :t/non-contacts)]
(when (and (= state :searching)
(is-valid-username? @search-value))
[rn/activity-indicator
{:color colors/gray
:size (if platform/android? :large :small)}])
(if (= state :valid)
[quo/list-item
(merge
{:title (or ens-name (gfycat/generate-gfy public-key))
:subtitle (if ens-name
(gfycat/generate-gfy public-key)
(utils/get-shortened-address public-key))
:icon [chat-icon/contact-icon-contacts-tab
(identicon/identicon public-key)]
:on-press #(do
(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted false] 3000)
(re-frame/dispatch [:search/home-filter-changed nil]))}
(when ens-name {:subtitle-secondary public-key}))]
[quo/text
{:style {:margin-horizontal 16}
:size :base
:align :center
:color :secondary}
(if (is-valid-username? @search-value)
(when (= state :error)
(get-validation-label error))
(i18n/label :t/invalid-username-or-key))])])]
(when-not (and
(= (count contacts) 0)
(= @search-value ""))
[react/animated-view
{:style {:height 36
:width 124
:position :absolute
:bottom 42
:transform [{:translateY my-profile-button-anim-y}]
:align-self :center}}
[react/touchable-opacity
{:style {:padding-horizontal 2
:height 36
:width 124
:background-color colors/blue
:border-radius 18
:elevation 4
:shadow-offset {:width 0 :height 4}
:shadow-color "rgba(0, 34, 51, 0.16)"
:shadow-radius 4
:shadow-opacity 1}
:on-press on-share}
[react/view
{:style {:flex 1
:flex-direction :row
:align-items :center}}
[photos/photo
(multiaccounts/displayed-photo account)
{:size 32
:accessibility-label :current-account-photo}]
[quo/text
{:size :base
:weight :medium
:color :inverse
:style {:margin-left 6}}
(i18n/label :t/my-profile)]]]])]]))
(defn- nickname-input
[entered-nickname]
[quo/text-input
{:on-change-text #(reset! entered-nickname %)
:auto-capitalize :none
:max-length 32
:auto-focus false
:accessibility-label :nickname-input
:placeholder (i18n/label :t/add-nickname)
:return-key-type :done
:auto-correct false}])
(defn new-contact
[]
(let [entered-nickname (reagent/atom "")]
(fn []
(let [{:keys [state ens-name public-key error]} @(re-frame/subscribe [:contacts/new-identity])
blocked? (and
(validators/valid-public-key? (or public-key ""))
@(re-frame/subscribe [:contacts/contact-blocked?
public-key]))]
[react/view {:style {:flex 1}}
[topbar/topbar
{:title (i18n/label :t/new-contact)
:modal? true
:right-accessories
[{:icon :qr
:accessibility-label :scan-contact-code-button
:on-press #(re-frame/dispatch [::qr-scanner/scan-code
{:title (i18n/label :t/new-contact)
:handler :contact/qr-code-scanned
:new-contact? true
:nickname @entered-nickname}])}]}]
[react/view
{:flex-direction :row
:padding 16}
[react/view
{:flex 1
:padding-right 16}
[quo/text-input
{:on-change-text
#(do
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
(debounce/debounce-and-dispatch [:contacts/set-new-identity %] 600))
:on-submit-editing
#(when (= state :valid)
(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted true @entered-nickname]
3000))
:placeholder (i18n/label :t/enter-contact-code)
:show-cancel false
:accessibility-label :enter-contact-code-input
:auto-capitalize :none
:return-key-type :go}]]
[react/view
{:justify-content :center
:align-items :center}
[input-icon state true @entered-nickname blocked?]]]
[react/view {:min-height 30 :justify-content :flex-end :margin-bottom 16}
[quo/text
{:style {:margin-horizontal 16}
:size :small
:align :center
:color :secondary}
(cond (= state :error)
(get-validation-label error)
(= state :valid)
(str (when ens-name (str ens-name " • "))
(utils/get-shortened-address public-key))
:else "")]]
[react/text {:style {:margin-horizontal 16 :color colors/gray}}
(i18n/label :t/nickname-description)]
[react/view {:padding 16}
[nickname-input entered-nickname]
[react/text
{:style {:align-self :flex-end
:margin-top 16
:color colors/gray}}
(str (count @entered-nickname) " / 32")]]]))))
@@ -1,50 +0,0 @@
(ns status-im.ui.screens.add-new.new-public-chat.view
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[re-frame.core :as re-frame]
[status-im.add-new.db :as db]
[status-im.react-native.resources :as resources]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.react :as react]
[utils.i18n :as i18n])
(:require-macros [status-im.utils.views :as views]))
(defn- start-chat
[topic]
(re-frame/dispatch [:chat.ui/start-public-chat topic])
(re-frame/dispatch [:set :public-group-topic nil]))
(defn- hash-icon
[]
[icons/icon :main-icons/channel {:color colors/gray}])
(defn- chat-name-input
[topic error]
[quo/text-input
{:on-change-text #(re-frame/dispatch [:set :public-group-topic %])
:on-submit-editing #(when (db/valid-topic? topic) (start-chat topic))
:auto-capitalize :none
:auto-focus false
:accessibility-label :chat-name-input
:before {:component [hash-icon]}
;; Set default-value as otherwise it will
;; be erased in global `onWillBlur` handler
:default-value topic
:placeholder "chat-name"
:return-key-type :go
:auto-correct false
:error error}])
(views/defview new-public-chat
[]
(views/letsubs [topic [:public-group-topic]
error [:public-chat.new/topic-error-message]]
[react/scroll-view {:style {:flex 1}}
[react/view {:padding-horizontal 16}
[react/view {:align-items :center :padding-vertical 8}
[react/image
{:source (:new-chat-header resources/ui)
:style {:width 160 :height 160}}]]
[react/text {:style {:text-align :center :margin-bottom 16 :line-height 22}}
(i18n/label :t/public-chat-description)]
[chat-name-input topic error]]]))
@@ -41,8 +41,7 @@
(defn browser-options
[url account empty-tab name]
(fn []
(let [topic (http/topic-from-url url)
bookmarks @(re-frame/subscribe [:bookmarks/active])
(let [bookmarks @(re-frame/subscribe [:bookmarks/active])
permissions @(re-frame/subscribe [:dapps/permissions])
fav? (get bookmarks url)
connected? (some #{constants/dapp-permission-web3}
@@ -85,15 +84,6 @@
(js/setTimeout
#(browser/share-link url)
200))}]
[quo/list-item
{:icon [chat-icon/custom-icon-view-list
topic
(rand-nth colors/chat-colors)]
:accessibility-label :open-chat
:title (str "#" topic)
:subtitle (i18n/label :t/open-chat)
:on-press #(hide-sheet-and-dispatch [:chat.ui/start-public-chat topic])
:chevron true}]
[components/separator]])
(if connected?
[quo/list-item
@@ -1,157 +0,0 @@
(ns status-im.ui.screens.chat.components.accessory
(:require [cljs-bean.core :as bean]
[quo.animated :as animated]
[quo.design-system.colors :as colors]
[quo.platform :as platform]
[quo.react :as react]
[quo.react-native :as rn]
[reagent.core :as reagent]
[status-im.ui.components.tabbar.core :as tabbar]
[status-im.ui.screens.chat.components.hooks :refer [use-keyboard-dimension]]
[react-native.safe-area :as safe-area]))
(def duration 250)
(defn create-pan-responder
[y pan-active]
(when-not platform/android?
(js->clj
(.-panHandlers
^js
(.create
^js rn/pan-responder
#js
{:onPanResponderGrant (fn []
(animated/set-value pan-active 1))
:onPanResponderMove (fn [_ ^js state]
(animated/set-value y (.-moveY state)))
:onPanResponderRelease (fn []
(animated/set-value pan-active 0)
(js/setTimeout
#(animated/set-value y 0)
100))
:onPanResponderTerminate (fn []
(animated/set-value pan-active 0)
(js/setTimeout
#(animated/set-value y 0)
100))})))))
(def ios-view
(reagent/adapt-react-class
(react/memo
(fn [props]
(let [{on-update-inset :onUpdateInset
y :y
pan-state :panState
on-close :onClose
has-panel :hasPanel
children :children}
(bean/bean props)
{keyboard-height :height
keyboard-max-height :max-height
keyboard-end-position :end-position}
(use-keyboard-dimension)
bottom (safe-area/get-bottom)
{on-layout :on-layout
bar-height :height}
(rn/use-layout)
visible (or has-panel (pos? keyboard-height))
anim-visible (animated/use-value visible)
kb-on-screen (if platform/android? 0 (* -1 (- keyboard-height bottom (tabbar/get-height))))
panel-on-screen (* -1 (- keyboard-max-height bottom (tabbar/get-height)))
max-delta (min 0 (if has-panel panel-on-screen kb-on-screen))
panel-height (* -1 max-delta)
end-position (- keyboard-end-position (when has-panel keyboard-max-height))
delay (+ (/ (- keyboard-max-height panel-height)
(/ keyboard-max-height duration))
16)
drag-diff (animated/clamp (animated/sub y end-position) 0 keyboard-max-height)
animated-y (react/use-memo
(fn []
(animated/mix
(animated/with-timing-transition anim-visible
{:duration (- duration delay)
:easing (:keyboard animated/easings)})
0
panel-on-screen))
[panel-on-screen])
delta-y (animated/clamp (animated/add drag-diff animated-y) max-delta 0)
on-update (fn []
(when on-update-inset
(on-update-inset (+ bar-height panel-height))))
children (react/get-children children)]
(react/effect! on-update [panel-height bar-height])
(animated/code!
(fn []
(when has-panel
;; TODO: Check also velocity
(animated/cond* (animated/and* (animated/greater-or-eq drag-diff (* 0.6 panel-height))
(animated/not* pan-state))
[(animated/call* [] on-close)])))
[delta-y pan-state has-panel on-close])
(animated/code!
(fn []
(animated/delay
(animated/set anim-visible (if visible 1 0))
(if visible delay 0)))
[visible keyboard-max-height delay])
(reagent/as-element
[animated/view
{:style {:position :absolute
:left 0
:right 0
:background-color (:ui-background @colors/theme)
:bottom max-delta
:transform [{:translateY delta-y}]}}
[rn/view {:on-layout on-layout}
(first children)]
[rn/view
{:style {:flex 1
:height (when (pos? panel-height) panel-height)}}
(second children)]]))))))
(def android-view
(reagent/adapt-react-class
(react/memo
(fn [props]
(let [{on-update-inset :onUpdateInset
on-close :onClose
has-panel :hasPanel
children :children}
(bean/bean props)
{keyboard-max-height :max-height} (use-keyboard-dimension)
bottom (safe-area/get-bottom)
{on-layout :on-layout
bar-height :height}
(rn/use-layout)
visible has-panel
panel-on-screen (* -1 (- keyboard-max-height bottom (tabbar/get-height)))
max-delta (min 0 (if has-panel panel-on-screen 0))
panel-height (* -1 max-delta)
on-update (fn []
(when on-update-inset
(on-update-inset (+ bar-height panel-height))))
children (react/get-children children)]
(react/effect! on-update [panel-height bar-height])
(rn/use-back-handler
(fn []
(when visible
(on-close))
visible))
(reagent/as-element
[animated/view
{:style {:position :absolute
:left 0
:right 0
:bottom 0
:background-color (:ui-background @colors/theme)}}
[rn/view {:on-layout on-layout}
(first children)]
[rn/view
{:style {:flex 1
:height (when (pos? panel-height) panel-height)}}
(second children)]]))))))
(def view (if platform/android? android-view ios-view))
@@ -1,98 +0,0 @@
(ns status-im.ui.screens.chat.components.contact-request
(:require [clojure.string :as string]
[quo.core :as quo]
[quo.design-system.colors :as quo.colors]
[quo.react :as quo.react]
[quo.react-native :as rn]
[re-frame.core :as re-frame]
[status-im.ethereum.stateofus :as stateofus]
[utils.i18n :as i18n]
[status-im.ui.screens.chat.components.style :as styles])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(def ^:private contact-request-symbol "↪ ")
(defn input-focus
[text-input-ref]
(some-> ^js (quo.react/current-ref text-input-ref)
.focus))
(defn format-author
[contact-name]
(let [author (if (or (= (aget contact-name 0) "@")
;; in case of replies
(= (aget contact-name 1) "@"))
(or (stateofus/username contact-name)
(subs contact-name 0 81))
contact-name)]
(i18n/label :contact-requesting-to {:author author})))
(defn format-contact-request-author
[from username current-public-key]
(or (and (= from current-public-key)
(str contact-request-symbol (i18n/label :t/You)))
(str contact-request-symbol (format-author username))))
(defn get-quoted-text-with-mentions
[parsed-text]
(string/join
(mapv (fn [{:keys [type literal children]}]
(cond
(= type "paragraph")
(get-quoted-text-with-mentions children)
(= type "mention")
@(re-frame/subscribe [:messages/resolve-mention literal])
(seq children)
(get-quoted-text-with-mentions children)
:else
literal))
parsed-text)))
(defn contact-request-message
[their-public-key]
(let [{:keys [input-text]} @(re-frame/subscribe [:chats/current-chat-input])]
[rn/view {:style {:flex-direction :row}}
[rn/view {:style (styles/contact-request-content)}
[quo/button
{:type :secondary
:weight :medium
:number-of-lines 1
:style {:line-height 18}
:on-press #(re-frame/dispatch [:chat.ui/cancel-contact-request])}
(i18n/label :t/cancel)]
[quo/button
{:type :secondary
:disabled (string/blank? input-text)
:weight :medium
:after :main-icons/send
:on-press #(re-frame/dispatch [:contacts/send-contact-request their-public-key input-text])
:style {:line-height 18}}
(i18n/label :t/send-request)]]]))
(defn focus-input-on-contact-request
[contact-request had-contact-request text-input-ref]
;;when we show contact-request we focus input
(when-not (= contact-request @had-contact-request)
(reset! had-contact-request contact-request)
(when contact-request
(js/setTimeout #(input-focus text-input-ref) 250))))
(defn contact-request-message-wrapper
[contact-request]
[rn/view
{:style {:padding-horizontal 15
:border-top-width 1
:border-top-color (:ui-01 @quo.colors/theme)
:padding-vertical 8}}
[contact-request-message contact-request]])
(defview contact-request-message-auto-focus-wrapper
[text-input-ref]
(letsubs [had-reply (atom nil)
contact-request @(re-frame/subscribe [:chats/sending-contact-request])]
{:component-did-mount #(focus-input-on-contact-request contact-request had-reply text-input-ref)}
(when contact-request
[contact-request-message-wrapper contact-request])))
@@ -1,59 +0,0 @@
(ns status-im.ui.screens.chat.components.edit
(:require [quo.components.animated.pressable :as pressable]
[quo.core :as quo]
[quo.design-system.colors :as quo.colors]
[quo.react :as quo.react]
[quo.react-native :as rn]
[re-frame.core :as re-frame]
[utils.i18n :as i18n]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.screens.chat.components.style :as styles]))
(defn input-focus
[text-input-ref]
(some-> ^js (quo.react/current-ref text-input-ref)
.focus))
(defn edit-message
[]
[rn/view {:style {:flex-direction :row}}
[rn/view {}
[icons/icon :tiny-icons/tiny-edit {:container-style {:margin-top 5}}]]
[rn/view {:style (styles/reply-content)}
[quo/text
{:weight :medium
:number-of-lines 1}
(i18n/label :t/editing-message)]]
[rn/view
[pressable/pressable
{:on-press #(re-frame/dispatch [:chat.ui/cancel-message-edit])
:accessibility-label :cancel-message-reply}
[icons/icon :main-icons/close-circle
{:container-style (styles/close-button)
:color (:icon-02 @quo.colors/theme)}]]]])
(defn focus-input-on-edit
[edit had-edit text-input-ref]
;;when we show edit we focus input
(when-not (= edit @had-edit)
(reset! had-edit edit)
(when edit
(js/setTimeout #(input-focus text-input-ref) 250))))
(defn edit-message-wrapper
[edit]
[rn/view
{:style {:padding-horizontal 15
:border-top-width 1
:border-top-color (:ui-01 @quo.colors/theme)
:padding-vertical 8}}
[edit-message edit]])
(defn edit-message-auto-focus-wrapper
[text-input-ref]
(let [had-edit (atom nil)]
(fn []
(let [edit @(re-frame/subscribe [:chats/edit-message])]
(focus-input-on-edit edit had-edit text-input-ref)
(when edit
[edit-message-wrapper])))))
@@ -1,50 +0,0 @@
(ns status-im.ui.screens.chat.components.hooks
(:require [quo.platform :as platform]
[quo.react :as react]
[quo.react-native :refer [use-window-dimensions] :as rn]
[react-native.safe-area :as safe-area]))
(def ^:private keyboard-change-event (if platform/android? "keyboardDidShow" "keyboardWillChangeFrame"))
(def default-kb-height (if platform/ios? 258 272))
(def min-duration 100)
(defn use-keyboard-dimension
[]
(let [{:keys [height]} (use-window-dimensions)
bottom (safe-area/get-bottom)
keyboard-listener (atom nil)
keyboard (react/state
{:height 0
:duration min-duration
:end-position height
:max-height (+ (if platform/ios? bottom 0) default-kb-height)})]
(react/effect!
(fn []
(letfn
[(dimensions-change [evt]
(swap! keyboard assoc :end-position (-> ^js evt .-window .-height)))
(keyboard-dimensions [evt]
(let [duration (.-duration ^js evt)
easing (.-easing ^js evt)
screen-y (-> ^js evt .-endCoordinates .-screenY)
new-height (- height screen-y)]
(when-not (= new-height (:height @keyboard))
(when (and duration easing platform/ios?)
(rn/configure-next
#js
{:duration (max min-duration duration)
:update #js
{:duration (max min-duration duration)
:type (-> ^js rn/layout-animation .-Types (aget easing))}})))
(reset! keyboard {:height new-height
:end-position screen-y
:duration (max min-duration duration)
:max-height (max new-height (:max-height @keyboard))})))]
(.addEventListener rn/dimensions "change" dimensions-change)
(reset! keyboard-listener (.addListener rn/keyboard keyboard-change-event keyboard-dimensions))
(fn []
(.removeEventListener rn/dimensions "change" dimensions-change)
(some-> ^js @keyboard-listener
.remove)))))
@keyboard))
@@ -1,428 +0,0 @@
(ns status-im.ui.screens.chat.components.input
(:require [clojure.string :as string]
[quo.components.animated.pressable :as pressable]
[quo.components.list.item :as list-item]
[quo.components.text :as text]
[quo.design-system.colors :as colors]
[quo.platform :as platform]
[quo.react :as quo.react]
[quo.react-native :as rn]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im2.constants :as chat.constants]
[utils.i18n :as i18n]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.list.views :as list]
[status-im.ui.screens.chat.components.reply :as reply]
[status-im.ui.screens.chat.components.style :as styles]
[status-im.ui.screens.chat.photos :as photos]
[utils.re-frame :as rf]
[status-im.utils.utils :as utils.utils]))
(defn input-focus
[text-input-ref]
(some-> ^js (quo.react/current-ref text-input-ref)
.focus))
(def panel->icons
{:extensions :main-icons/commands
:images :main-icons/photo})
(defn touchable-icon
[{:keys [panel active set-active accessibility-label]}]
[pressable/pressable
{:type :scale
:accessibility-label accessibility-label
:on-press #(set-active (when-not (= active panel) panel))}
[rn/view {:style (styles/touchable-icon)}
[icons/icon
(panel->icons panel)
(styles/icon (= active panel))]]])
(defn touchable-stickers-icon
[{:keys [panel active set-active accessibility-label input-focus]}]
[pressable/pressable
{:type :scale
:accessibility-label accessibility-label
:on-press #(if (= active panel)
(input-focus)
(set-active panel))}
[rn/view {:style (styles/in-input-touchable-icon)}
(if (= active panel)
[icons/icon :main-icons/keyboard (styles/icon false)]
[icons/icon :main-icons/stickers (styles/icon false)])]])
;; TODO(Ferossgp): Move this into audio panel.
;; Instead of not changing panel we can show a placeholder with no permission
(defn- request-record-audio-permission
[set-active panel]
(re-frame/dispatch
[:request-permissions
{:permissions [:record-audio]
:on-allowed
#(set-active panel)
:on-denied
#(utils.utils/set-timeout
(fn []
(utils.utils/show-popup
(i18n/label :t/audio-recorder-error)
(i18n/label :t/audio-recorder-permissions-error)))
50)}]))
(defn touchable-audio-icon
[{:keys [panel active set-active accessibility-label input-focus]}]
[pressable/pressable
{:type :scale
:accessibility-label accessibility-label
:on-press #(if (= active panel)
(input-focus)
(request-record-audio-permission set-active panel))}
[rn/view {:style (styles/in-input-touchable-icon)}
(if (= active panel)
[icons/icon :main-icons/keyboard (styles/icon false)]
[icons/icon :main-icons/speech (styles/icon false)])]])
(defn send-button
[on-send contact-request]
[rn/touchable-opacity {:on-press-in on-send}
[rn/view {:style (styles/send-message-button)}
(when-not contact-request
[icons/icon :main-icons/arrow-up
{:container-style (styles/send-message-container contact-request)
:accessibility-label :send-message-button
:color (styles/send-icon-color)}])]])
(defn on-selection-change
[timeout-id last-text-change args]
(let [selection (.-selection ^js (.-nativeEvent ^js args))
start (.-start selection)
end (.-end selection)]
;; NOTE(rasom): on iOS we do not dispatch this event immediately
;; because it is needed only in case if selection is changed without
;; typing. Timeout might be canceled on `on-change`.
(when platform/ios?
(reset!
timeout-id
(utils.utils/set-timeout
#(re-frame/dispatch [:mention/on-selection-change
{:start start
:end end}])
50)))
;; NOTE(rasom): on Android we dispatch event only in case if there
;; was no text changes during last 50ms. `on-selection-change` is
;; dispatched after `on-change`, that's why there is no another way
;; to know whether selection was changed without typing.
(when (and platform/android?
(or (not @last-text-change)
(< 50 (- (js/Date.now) @last-text-change))))
(re-frame/dispatch [:mention/on-selection-change
{:start start
:end end}]))))
(defonce input-texts (atom {}))
(defonce mentions-enabled (reagent/atom {}))
(defonce chat-input-key (reagent/atom 1))
(re-frame/reg-fx
:chat.ui/clear-inputs-old
(fn []
(reset! input-texts {})
(reset! mentions-enabled {})
(reset! chat-input-key 1)))
(defn force-text-input-update!
"force-text-input-update! forces the
input to re-render, necessary when we are setting value"
[]
(swap! chat-input-key inc))
(defn show-send
[{:keys [actions-ref send-ref sticker-ref]}]
(when actions-ref
(quo.react/set-native-props actions-ref #js {:width 0 :left -88}))
(quo.react/set-native-props send-ref #js {:width nil :right nil})
(when sticker-ref
(quo.react/set-native-props sticker-ref #js {:width 0 :right -100})))
(defn hide-send
[{:keys [actions-ref send-ref sticker-ref]}]
(when actions-ref
(quo.react/set-native-props actions-ref #js {:width nil :left nil}))
(quo.react/set-native-props send-ref #js {:width 0 :right -100})
(when sticker-ref
(quo.react/set-native-props sticker-ref #js {:width nil :right nil})))
(defn reset-input
[refs chat-id]
(some-> ^js (quo.react/current-ref (:text-input-ref refs))
.clear)
(swap! mentions-enabled update :render not)
(swap! input-texts dissoc chat-id))
(defn clear-input
[chat-id refs]
(hide-send refs)
(if (get @mentions-enabled chat-id)
(do
(swap! mentions-enabled dissoc chat-id)
;;we need this timeout, because if we clear text input and first index was a mention object with
;;blue color,
;;after clearing text will be typed with this blue color, so we render white text first and then
;;clear it
(js/setTimeout #(reset-input refs chat-id) 50))
(reset-input refs chat-id)))
(defn on-text-change
[val chat-id]
(swap! input-texts assoc chat-id val)
;;we still store it in app-db for mentions, we don't have reactions in views
(re-frame/dispatch [:chat.ui/set-chat-input-text val]))
(defn on-change
[last-text-change timeout-id refs chat-id sending-image args]
(let [text (.-text ^js (.-nativeEvent ^js args))
prev-text (get @input-texts chat-id)]
(when (and (seq prev-text) (empty? text) (not sending-image))
(hide-send refs))
(when (and (empty? prev-text) (seq text))
(show-send refs))
(when (and (not (get @mentions-enabled chat-id)) (string/index-of text "@"))
(swap! mentions-enabled assoc chat-id true))
;; NOTE(rasom): on iOS `on-selection-change` is canceled in case if it
;; happens during typing because it is not needed for mention
;; suggestions calculation
(when (and platform/ios? @timeout-id)
(utils.utils/clear-timeout @timeout-id))
(when platform/android?
(reset! last-text-change (js/Date.now)))
(on-text-change text chat-id)
;; NOTE(rasom): on iOS `on-change` is dispatched after `on-text-input`,
;; that's why mention suggestions are calculated on `on-change`
(when platform/ios?
(re-frame/dispatch [:mention/calculate-suggestions]))))
(rf/defn set-input-text
"Set input text for current-chat. Takes db and input text and cofx
as arguments and returns new fx. Always clear all validation messages."
{:events [:chat.ui.input/set-chat-input-text]}
[{:keys [db]} text chat-id]
(let [params [chat-id text]
method "wakuext_chatMentionToInputField"]
{:json-rpc/call [{:method method
:params params
:on-success #(rf/dispatch [:mention/on-to-input-field-success %])
:on-error #(rf/dispatch [:mention/on-error
{:method method
:params params} %])}]}))
(defn on-text-input
[chat-id args]
(let [native-event (.-nativeEvent ^js args)
text (.-text ^js native-event)
previous-text (.-previousText ^js native-event)
range (.-range ^js native-event)
start (.-start ^js range)
end (.-end ^js range)]
(when (and (not (get @mentions-enabled chat-id)) (string/index-of text "@"))
(swap! mentions-enabled assoc chat-id true))
(re-frame/dispatch
[:mention/on-text-input
{:new-text text
:previous-text previous-text
:start start
:end end}])
;; NOTE(rasom): on Android `on-text-input` is dispatched after
;; `on-change`, that's why mention suggestions are calculated
;; on `on-change`
(when platform/android?
(re-frame/dispatch [:mention/calculate-suggestions]))))
(defn text-input
[{:keys [set-active-panel refs chat-id sending-image]}]
(let [cooldown-enabled? @(re-frame/subscribe [:chats/current-chat-cooldown-enabled?])
timeout-id (atom nil)
last-text-change (atom nil)
mentions-enabled (get @mentions-enabled chat-id)
contact-request @(re-frame/subscribe [:chats/sending-contact-request])]
[rn/text-input
{:style (styles/text-input contact-request)
:ref (:text-input-ref refs)
:max-font-size-multiplier 1
:accessibility-label :chat-message-input
:text-align-vertical :center
:multiline true
:editable (not cooldown-enabled?)
:blur-on-submit false
:auto-focus false
:on-focus #(set-active-panel nil)
:max-length chat.constants/max-text-size
:placeholder-text-color (:text-02 @colors/theme)
:placeholder (if cooldown-enabled?
(i18n/label :cooldown/text-input-disabled)
(i18n/label :t/type-a-message))
:underline-color-android :transparent
:auto-capitalize :sentences
:on-selection-change (partial on-selection-change
timeout-id
last-text-change)
:on-change
(partial on-change last-text-change timeout-id refs chat-id sending-image)
:on-text-input (partial on-text-input chat-id)}
(if mentions-enabled
(for [[idx [type text]] (map-indexed
(fn [idx item]
[idx item])
@(re-frame/subscribe [:chat/input-with-mentions]))]
^{:key (str idx "_" type "_" text)}
[rn/text (when (= type :mention) {:style {:color "#0DA4C9"}})
text])
(get @input-texts chat-id))]))
(defn mention-item
[[public-key {:keys [alias name nickname] :as user}] _ _ text-input-ref]
(let [ens-name? (not= alias name)]
[list-item/list-item
(cond->
{:icon [photos/member-photo public-key]
:size :small
:text-size :small
:title
[text/text
{:weight :medium
:ellipsize-mode :tail
:number-of-lines 1
:size :small}
(if nickname
nickname
name)
(when nickname
[text/text
{:weight :regular
:color :secondary
:ellipsize-mode :tail
:size :small}
" "
(when ens-name?
"@")
name])]
:title-text-weight :medium
:on-press
(fn []
(re-frame/dispatch [:chat.ui/select-mention text-input-ref user]))}
ens-name?
(assoc :subtitle alias))]))
(def chat-toolbar-height (reagent/atom nil))
(defn autocomplete-mentions
[text-input-ref bottom]
(let [suggestions @(re-frame/subscribe [:chat/mention-suggestions])]
(when (seq suggestions)
(let [height (+ 16 (* 52 (min 4.5 (count suggestions))))]
[rn/view
{:style (styles/autocomplete-container bottom)
:accessibility-label :suggestions-list}
[rn/view
{:style {:height height}}
[list/flat-list
{:keyboard-should-persist-taps :always
:footer [rn/view {:style {:height 8}}]
:header [rn/view {:style {:height 8}}]
:data suggestions
:key-fn first
:render-data text-input-ref
:render-fn mention-item}]]]))))
(defn on-chat-toolbar-layout
[^js ev]
(reset! chat-toolbar-height (-> ev .-nativeEvent .-layout .-height)))
(defn send-image
[]
(let [sending-image @(re-frame/subscribe [:chats/sending-image])]
(when (seq sending-image)
[reply/send-image sending-image])))
(defn actions
[extensions image show-send actions-ref active-panel set-active-panel contact-request]
[rn/view
{:style (styles/actions-wrapper (and (not contact-request) show-send))
:ref actions-ref}
(when extensions
[touchable-icon
{:panel :extensions
:accessibility-label :show-extensions-icon
:active active-panel
:set-active set-active-panel}])
(when image
[touchable-icon
{:panel :images
:accessibility-label :show-photo-icon
:active active-panel
:set-active set-active-panel}])])
(defn chat-toolbar
[{:keys [chat-id]}]
(let [actions-ref (quo.react/create-ref)
send-ref (quo.react/create-ref)
sticker-ref (quo.react/create-ref)
toolbar-options (re-frame/subscribe [:chats/chat-toolbar])
show-send (seq (get @input-texts chat-id))]
(fn [{:keys [active-panel set-active-panel text-input-ref chat-id]}]
(let [;we want to control components on native level, so instead of RN state we set native props
;via reference
;we don't react on input text in this view, @input-texts below is a regular atom
refs {:actions-ref actions-ref
:send-ref send-ref
:sticker-ref sticker-ref
:text-input-ref text-input-ref}
{:keys [send stickers image extensions audio
sending-image]} @toolbar-options
show-send (or show-send sending-image)
contact-request @(re-frame/subscribe [:chats/sending-contact-request])]
[rn/view
{:style (styles/toolbar)
:on-layout on-chat-toolbar-layout}
;; EXTENSIONS and IMAGE buttons
[actions extensions image show-send actions-ref active-panel set-active-panel contact-request]
[rn/view {:style (styles/input-container contact-request)}
[send-image]
[rn/view {:style styles/input-row}
[text-input
{:chat-id chat-id
:sending-image sending-image
:refs refs
:set-active-panel set-active-panel}]
;; SEND button
[rn/view {:ref send-ref :style (when-not show-send {:width 0 :right -100})}
(when send
[send-button
#(do (clear-input chat-id refs)
(re-frame/dispatch [:chat.ui/send-current-message]))
contact-request])]
;; STICKERS and AUDIO buttons
(when-not @(re-frame/subscribe [:chats/edit-message])
[rn/view
{:style (merge {:flex-direction :row} (when show-send {:width 0 :right -100}))
:ref sticker-ref}
(when stickers
[touchable-stickers-icon
{:panel :stickers
:accessibility-label :show-stickers-icon
:active active-panel
:input-focus #(input-focus text-input-ref)
:set-active set-active-panel}])
(when audio
[touchable-audio-icon
{:panel :audio
:accessibility-label :show-audio-message-icon
:active active-panel
:input-focus #(input-focus text-input-ref)
:set-active set-active-panel}])])]]]))))
@@ -1,121 +0,0 @@
(ns status-im.ui.screens.chat.components.reply
(:require [clojure.string :as string]
[quo.components.animated.pressable :as pressable]
[quo.core :as quo]
[quo.design-system.colors :as quo.colors]
[quo.react :as quo.react]
[quo.react-native :as rn]
[re-frame.core :as re-frame]
[status-im.ethereum.stateofus :as stateofus]
[utils.i18n :as i18n]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.screens.chat.components.style :as styles]))
(def ^:private reply-symbol "↪ ")
(defn input-focus
[text-input-ref]
(some-> ^js (quo.react/current-ref text-input-ref)
.focus))
(defn format-author
[contact-name]
(let [author (if (or (= (aget contact-name 0) "@")
;; in case of replies
(= (aget contact-name 1) "@"))
(or (stateofus/username contact-name)
(subs contact-name 0 81))
contact-name)]
(i18n/label :replying-to {:author author})))
(defn format-reply-author
[from username current-public-key]
(or (and (= from current-public-key)
(str reply-symbol (i18n/label :t/You)))
(str reply-symbol (format-author username))))
(defn get-quoted-text-with-mentions
[parsed-text]
(string/join
(mapv (fn [{:keys [type literal children]}]
(cond
(= type "paragraph")
(get-quoted-text-with-mentions children)
(= type "mention")
@(re-frame/subscribe [:messages/resolve-mention literal])
(seq children)
(get-quoted-text-with-mentions children)
:else
literal))
parsed-text)))
(defn reply-message
[{:keys [from]}]
(let [contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])
current-public-key @(re-frame/subscribe [:multiaccount/public-key])]
[rn/view {:style {:flex-direction :row}}
[rn/view {:style (styles/reply-content)}
[quo/text
{:weight :medium
:number-of-lines 1
:style {:line-height 18}}
(format-reply-author from contact-name current-public-key)]]
[rn/view
[pressable/pressable
{:on-press #(re-frame/dispatch [:chat.ui/cancel-message-reply])
:accessibility-label :cancel-message-reply}
[icons/icon :main-icons/close-circle
{:container-style (styles/close-button)
:color (:icon-02 @quo.colors/theme)}]]]]))
(defn send-image
[images]
[rn/view {:style (styles/reply-container-image)}
[rn/scroll-view
{:horizontal true
:style (styles/reply-content)}
(for [{:keys [uri]} (vals images)]
^{:key uri}
[rn/image
{:source {:uri uri}
:style {:width 56
:height 56
:border-radius 4
:margin-right 4}}])]
[rn/view
[pressable/pressable
{:on-press #(re-frame/dispatch [:chat.ui/cancel-sending-image])
:accessibility-label :cancel-send-image}
[icons/icon :main-icons/close-circle
{:container-style (styles/close-button)
:color quo.colors/white}]]]])
(defn focus-input-on-reply
[reply had-reply text-input-ref]
;;when we show reply we focus input
(when-not (= reply @had-reply)
(reset! had-reply reply)
(when reply
;; A setTimeout of 0 is necessary to ensure the statement is enqueued and will get executed ASAP.
(js/setTimeout #(input-focus text-input-ref) 0))))
(defn reply-message-wrapper
[reply]
[rn/view
{:style {:padding-horizontal 15
:border-top-width 1
:border-top-color (:ui-01 @quo.colors/theme)
:padding-vertical 8}}
[reply-message reply]])
(defn reply-message-auto-focus-wrapper
[text-input-ref]
(let [had-reply (atom nil)]
(fn []
(let [reply @(re-frame/subscribe [:chats/reply-message])]
(focus-input-on-reply reply had-reply text-input-ref)
(when reply
[reply-message-wrapper reply])))))
@@ -1,152 +0,0 @@
(ns status-im.ui.screens.chat.components.style
(:require [quo.design-system.colors :as colors]
[quo.design-system.typography :as typography]
[quo.platform :as platform]))
(defn toolbar
[]
{:min-height 52
:padding-vertical 8
:border-top-width 1
:border-top-color (:ui-01 @colors/theme)
:align-items :flex-end
:flex-direction :row})
(defn input-container
[contact-request]
{:background-color (:ui-01 @colors/theme)
:flex 1
:height (when contact-request 44)
:border-top-left-radius (if contact-request 8 16)
:border-top-right-radius (if contact-request 8 16)
:border-bottom-right-radius (if contact-request 8 4)
:border-bottom-left-radius (if contact-request 8 16)
:margin-horizontal 8})
(def input-row
{:flex-direction :row
:overflow :hidden
:align-items :flex-end})
(defn text-input-wrapper
[]
(merge {:flex-direction :row
:align-items :flex-start
:flex 1
:min-height 34
:max-height 144}
(when platform/ios?
{:padding-top 2})))
(defn text-input
[contact-request]
(merge typography/font-regular
typography/base
{:flex 1
:min-height 34
:max-height 144
:margin 0
:flex-shrink 1
:color (:text-01 @colors/theme)
:padding-horizontal 12}
(if platform/android?
{:padding-vertical 2}
{:padding-top (if contact-request 10 2)
:padding-bottom (if contact-request 5 6)})))
(defn actions-wrapper
[show-send]
(merge (when show-send
{:width 0 :left -88})
{:flex-direction :row
:padding-left 4
:min-height 34}))
(defn touchable-icon
[]
{:padding-horizontal 10
:padding-vertical 5
:justify-content :center
:align-items :center})
(defn in-input-touchable-icon
[]
{:padding-horizontal 6
:padding-vertical 5
:justify-content :center
:align-items :center})
(defn icon
[active]
{:color (if active
(:icon-04 @colors/theme)
(:icon-02 @colors/theme))})
(defn reply-container-image
[]
{:border-top-left-radius 14
:border-top-right-radius 14
:border-bottom-right-radius 4
:border-bottom-left-radius 14
:margin 2
:flex-direction :row
:background-color (:ui-03 @colors/theme)})
(defn reply-container
[]
{:flex-direction :row})
(defn reply-content
[]
{:padding-vertical 6
:padding-horizontal 10
:flex 1})
(defn quoted-message
[pin?]
(merge {:flex-direction :row
:align-items :center
:width "45%"}
(when-not pin?
{:position :absolute
:left 34
:top 3})))
(defn contact-request-content
[]
{:flex 1
:flex-direction :row
:justify-content :space-between})
(defn close-button
[]
{:margin-top 3})
(defn send-message-button
[]
{:margin-vertical 4
:margin-horizontal 5})
(defn send-message-container
[contact-request]
{:background-color (:interactive-01 @colors/theme)
:width 26
:height (if contact-request 44 26)
:border-radius (if contact-request 22 13)
:justify-content :center
:align-items :center})
(defn send-icon-color
[]
colors/white)
(defn autocomplete-container
[bottom]
{:position :absolute
:left 0
:right 0
:bottom bottom
:background-color (colors/get-color :ui-background)
:border-top-width 1
:border-top-color (colors/get-color :ui-01)
:z-index 3})
+1 -43
View File
@@ -4,10 +4,8 @@
[status-im2.constants :as constants]
[utils.i18n :as i18n]
[status-im.ui.components.chat-icon.screen :as chat-icon]
[status-im.ui.components.list-selection :as list-selection]
[status-im.ui.components.react :as react]
[status-im.ui.screens.chat.styles.message.sheets :as sheets.styles]
[status-im.utils.universal-links.utils :as universal-links]))
[status-im.ui.screens.chat.styles.message.sheets :as sheets.styles]))
(defn hide-sheet-and-dispatch
[event]
@@ -42,41 +40,6 @@
:icon :main-icons/delete
:on-press #(re-frame/dispatch [:chat.ui/show-remove-confirmation chat-id])}]]))
(defn public-chat-accents
[chat-id]
(let [link (universal-links/generate-link :public-chat :external chat-id)
message (i18n/label :t/share-public-chat-text {:link link})]
[react/view
[quo/list-item
{:theme :accent
:title (i18n/label :t/share-chat)
:accessibility-label :share-chat-button
:icon :main-icons/share
:on-press (fn []
(re-frame/dispatch [:bottom-sheet/hide-old])
;; https://github.com/facebook/react-native/pull/26839
(js/setTimeout
#(list-selection/open-share {:message message})
250))}]
[quo/list-item
{:theme :accent
:title (i18n/label :t/mark-all-read)
:accessibility-label :mark-all-read-button
:icon :main-icons/check
:on-press #(hide-sheet-and-dispatch [:chat.ui/mark-all-read-pressed chat-id])}]
[quo/list-item
{:theme :accent
:title (i18n/label :t/clear-history)
:accessibility-label :clear-history-button
:icon :main-icons/close
:on-press #(re-frame/dispatch [:chat.ui/show-clear-history-confirmation chat-id])}]
[quo/list-item
{:theme :negative
:title (i18n/label :t/delete-chat)
:accessibility-label :delete-chat-button
:icon :main-icons/delete
:on-press #(re-frame/dispatch [:chat.ui/show-remove-confirmation chat-id])}]]))
(defn community-chat-accents
[]
(fn [{:keys [chat-id group-chat chat-name color emoji]}]
@@ -150,11 +113,6 @@
[{:keys [chat-type chat-id]
:as current-chat}]
(cond
(#{constants/public-chat-type
constants/profile-chat-type
constants/timeline-chat-type}
chat-type)
[public-chat-accents chat-id]
(= chat-type constants/community-chat-type)
[community-chat-accents current-chat]
@@ -19,10 +19,10 @@
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.chat.photos :as photos]
[status-im.ui.screens.chat.sheets :as sheets]
[status-im.ui.screens.home.views.inner-item :as inner-item]
[status-im.utils.core :as utils]
[utils.datetime :as datetime]
[utils.re-frame :as rf]))
[utils.re-frame :as rf]
[status-im.ui.screens.home.views.inner-item :as inner-item]))
(def request-cooldown-ms (* 24 60 60 1000))
@@ -1,183 +0,0 @@
(ns status-im.ui.screens.communities.views
(:require [quo.core :as quo]
[quo.design-system.colors :as quo.colors]
[status-im.communities.core :as communities]
[status-im2.constants :as constants]
[utils.i18n :as i18n]
[status-im.ui.components.badge :as badge]
[status-im.ui.components.copyable-text :as copyable-text]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.react :as react]
[status-im.ui.components.toolbar :as toolbar]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.communities.community :as community]
[status-im.ui.screens.communities.icon :as communities.icon]
[status-im.utils.core :as utils]
[utils.re-frame :as rf]))
(defn hide-sheet-and-dispatch
[event]
(rf/dispatch [:bottom-sheet/hide-old])
(rf/dispatch event))
(defn community-unviewed-count
[id]
(let [{:keys [unviewed-messages-count unviewed-mentions-count]} (rf/sub [:communities/unviewed-counts
id])]
(cond
(pos? unviewed-mentions-count)
[badge/message-counter unviewed-mentions-count]
(pos? unviewed-messages-count)
[react/view
{:style {:background-color quo.colors/blue
:border-radius 6
:margin-right 5
:margin-top 2
:width 12
:height 12}
:accessibility-label :unviewed-messages-public}])))
(defn community-home-list-item
[{:keys [id name last?] :as community}]
[react/touchable-opacity
{:style (merge {:height 64}
(when last?
{:border-bottom-color (quo.colors/get-color :ui-01)
:border-bottom-width 1}))
:on-press (fn []
(rf/dispatch [:communities/load-category-states id])
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:navigate-to :community-overview id]))
:on-long-press #(rf/dispatch [:bottom-sheet/show-sheet-old
{:content (fn []
[community/community-actions community])}])}
[:<>
[react/view {:top 12 :left 16 :position :absolute}
[communities.icon/community-icon community]]
[react/view
{:style {:margin-left 72
:flex-direction :row
:flex 1}
:accessibility-label :chat-name-text}
[react/view
{:flex-direction :row
:flex 1
:padding-right 16
:align-items :center}
[quo/text
{:weight :medium
:accessibility-label :chat-name-text
:font-size 17
:ellipsize-mode :tail
:number-of-lines 1}
name]]
[react/view
{:flex-direction :row
:flex 1
:margin-right 15
:justify-content :flex-end
:align-items :center}
[community-unviewed-count id]]]]])
(defn community-list-item
[{:keys [id permissions members name description] :as community}]
(let [members-count (count members)
show-members-count? (not= (:access permissions) constants/community-no-membership-access)]
[quo/list-item
{:icon [communities.icon/community-icon community]
:title [react/view
{:flex-direction :row
:flex 1
:padding-right 16
:align-items :center}
[quo/text
{:weight :medium
:accessibility-label :community-name-text
:ellipsize-mode :tail
:number-of-lines 1}
(utils/truncate-str name 30)]]
:title-accessibility-label :community-name-text
:subtitle [react/view
[quo/text {:number-of-lines 1}
description]
[quo/text
{:number-of-lines 1
:color :secondary}
(if show-members-count?
(i18n/label-pluralize members-count
:t/community-members
{:count members-count})
(i18n/label :t/open-membership))]]
:on-press #(do
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:navigate-to :community-overview id]))}]))
(defn communities-actions
[]
[:<>
[quo/list-item
{:theme :accent
:title (i18n/label :t/import-community)
:accessibility-label :community-import-community
:icon :main-icons/objects
:on-press #(hide-sheet-and-dispatch [:navigate-to :community-import])}]
[quo/list-item
{:theme :accent
:title (i18n/label :t/create-community)
:accessibility-label :community-create-community
:icon :main-icons/add
:on-press #(hide-sheet-and-dispatch [::communities/open-create-community])}]])
(defn communities-list
[communities]
[list/section-list
{:content-container-style {:padding-vertical 8}
:key-fn :id
:keyboard-should-persist-taps :always
:sticky-section-headers-enabled false
:sections communities
:render-section-header-fn quo/list-index
:render-fn community-list-item}])
(defn communities
[]
(let [communities (rf/sub [:communities/section-list])]
[:<>
[topbar/topbar
{:title (i18n/label :t/communities)
:right-accessories
[{:icon :main-icons/more
:accessibility-label :chat-menu-button
:on-press
#(rf/dispatch [:bottom-sheet/show-sheet-old
{:content (fn []
[communities-actions])
:height 256}])}]}]
[communities-list communities]
[toolbar/toolbar
{:show-border? true
:center [quo/button
{:on-press #(rf/dispatch [::communities/open-create-community])
:type :secondary}
(i18n/label :t/create-community)]}]]))
(defn export-community
[]
(let [{:keys [community-key]} (rf/sub [:popover/popover])]
[react/view
{:style {:padding-top 16
:padding-horizontal 16}}
[quo/text
{:size :x-large
:align :center}
(i18n/label :t/community-private-key)]
[copyable-text/copyable-text-view
{:container-style {:padding-vertical 12}
:copied-text community-key}
[quo/text
{:number-of-lines 1
:ellipsize-mode :middle
:accessibility-label :chat-key
:monospace true}
community-key]]]))
@@ -11,8 +11,7 @@
:title (i18n/label :t/faq)
:accessibility-label :faq-button
:on-press
#(.openURL ^js react/linking
constants/faq)
#(.openURL ^js react/linking constants/faq)
:chevron true}
{:size :small
:title (i18n/label :t/glossary)
@@ -25,13 +24,6 @@
:accessibility-label :submit-bug-button
:on-press
#(re-frame/dispatch [:open-modal :bug-report])
:chevron true}
{:size :small
:title (i18n/label :t/request-feature)
:accessibility-label :request-a-feature-button
:on-press
#(re-frame/dispatch [:chat.ui/start-public-chat
"support"])
:chevron true}])
(defn help-center
@@ -1,7 +0,0 @@
(ns status-im.ui.screens.home.sheet.styles)
(def add-new-view-wrapper
{:style {:flex-direction :row
:padding-left 16
:padding-right 8
:justify-content :space-between
:align-items :center}})
@@ -1,62 +0,0 @@
(ns status-im.ui.screens.home.sheet.views
(:require [quo.core :as quo]
[utils.re-frame :as rf]
[utils.i18n :as i18n]
[status-im.qr-scanner.core :as qr-scanner]
[status-im.ui.components.invite.views :as invite]
[status-im.ui.components.react :as rn]
[status-im2.config :as config]
[status-im.ui.screens.home.sheet.styles :as style]))
(defn- hide-sheet-and-dispatch
[event]
(rf/dispatch [:bottom-sheet/hide-old])
(rf/dispatch event))
(defn add-new-view
[]
[rn/view
[rn/view style/add-new-view-wrapper
[quo/text
{:size :large
:weight :bold}
(i18n/label :t/open-home)]
[quo/button
{:type :icon
:theme :icon
:accessibility-label :universal-qr-scanner
:on-press #(hide-sheet-and-dispatch
[::qr-scanner/scan-code
{:handler ::qr-scanner/on-scan-success}])}
:main-icons/qr]]
[quo/list-item
{:theme :accent
:title (i18n/label :t/start-new-chat)
:accessibility-label :start-1-1-chat-button
:icon :main-icons/one-on-one-chat
:on-press #(hide-sheet-and-dispatch [:open-modal :new-chat])}]
(when config/group-chat-enabled?
[quo/list-item
{:theme :accent
:title (i18n/label :t/start-group-chat)
:accessibility-label :start-group-chat-button
:icon :main-icons/group-chat
:on-press #(hide-sheet-and-dispatch [:contact.ui/start-group-chat-pressed])}])
[quo/list-item
{:theme :accent
:title (i18n/label :t/new-public-group-chat)
:accessibility-label :join-public-chat-button
:icon :main-icons/public-chat
:on-press #(hide-sheet-and-dispatch [:open-modal :new-public-chat])}]
[quo/list-item
{:theme :accent
:title (i18n/label :t/communities-alpha)
:accessibility-label :communities-button
:icon :main-icons/communities
:on-press #(hide-sheet-and-dispatch [:navigate-to :communities])}]
[invite/list-item
{:accessibility-label :chats-menu-invite-friends-button}]])
;; Deprecated
(def add-new
{:content add-new-view})
-375
View File
@@ -1,375 +0,0 @@
(ns status-im.ui.screens.home.views
(:require
[quo.core :as quo]
[quo.design-system.colors :as colors]
[quo2.components.buttons.button :as quo2.button]
[quo2.components.markdown.text :as quo2.text]
[quo2.foundations.colors :as quo2.colors]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.add-new.db :as db]
[utils.i18n :as i18n]
[status-im.qr-scanner.core :as qr-scanner]
[status-im.react-native.resources :as resources]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.ui.components.chat-icon.styles :as chat-icon.styles]
[status-im.ui.components.connectivity.view :as connectivity]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.invite.views :as invite]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.plus-button :as components.plus-button]
[status-im.ui.components.react :as react]
[status-im.ui.components.search-input.view :as search-input]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.chat.sheets :as sheets]
[status-im.ui.screens.communities.views :as communities.views]
[status-im.ui.screens.home.styles :as styles]
[status-im.ui.screens.home.views.inner-item :as inner-item]
[status-im.utils.utils :as utils]
[utils.debounce :as debounce])
(:require-macros [status-im.utils.views :as views]))
(defn home-tooltip-view
[]
[react/view (styles/chat-tooltip)
[react/view
{:style {:width 66
:position :absolute
:top -6
:background-color colors/white
:align-items :center}}
[react/image
{:source (resources/get-image :empty-chats-header)
:style {:width 50 :height 50}}]]
[react/touchable-highlight
{:style {:position :absolute
:right 0
:top 0
:width 44
:height 44
:align-items :center
:justify-content :center}
:on-press #(re-frame/dispatch [:multiaccounts.ui/hide-home-tooltip])
:accessibility-label :hide-home-button}
[icons/icon :main-icons/close-circle {:color colors/gray}]]
[react/i18n-text {:style styles/no-chats-text :key :chat-and-transact}]
[react/view
{:align-items :center
:margin-top 8
:margin-bottom 12}
[invite/button]]])
(defn welcome-blank-page
[]
[react/view {:style {:flex 1 :flex-direction :row :align-items :center :justify-content :center}}
[react/i18n-text {:style styles/welcome-blank-text :key :welcome-blank-message}]])
(defonce search-active? (reagent/atom false))
(defn search-input-wrapper
[search-filter chats-empty]
[react/view
{:padding-horizontal 16
:padding-vertical 10}
[search-input/search-input
{:search-active? search-active?
:placeholder (i18n/label :t/search)
:border-radius 10
:search-filter search-filter
:before true
:on-cancel #(re-frame/dispatch [:search/home-filter-changed nil])
:on-blur (fn []
(when chats-empty
(re-frame/dispatch [:search/home-filter-changed nil]))
(re-frame/dispatch [:contacts/clear-new-identity]))
:on-focus (fn [search-filter]
(when-not search-filter
(re-frame/dispatch [:search/home-filter-changed ""])
(re-frame/dispatch [:contacts/clear-new-identity])))
:on-change (fn [text]
(re-frame/dispatch [:search/home-filter-changed text])
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
(debounce/debounce-and-dispatch [:contacts/set-new-identity text] 300))}]])
(defn search-input-wrapper-old
[search-filter chats-empty]
[react/view
{:padding-horizontal 16
:padding-vertical 10}
[search-input/search-input-old
{:search-active? search-active?
:search-filter search-filter
:on-cancel #(re-frame/dispatch [:search/home-filter-changed nil])
:on-blur (fn []
(when chats-empty
(re-frame/dispatch [:search/home-filter-changed nil]))
(re-frame/dispatch [:contacts/clear-new-identity]))
:on-focus (fn [search-filter]
(when-not search-filter
(re-frame/dispatch [:search/home-filter-changed ""])
(re-frame/dispatch [:contacts/clear-new-identity])))
:on-change (fn [text]
(re-frame/dispatch [:search/home-filter-changed text])
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
(debounce/debounce-and-dispatch [:new-chat/set-new-identity text] 300))}]])
(defn start-suggestion
[search-value]
(let [{:keys [state ens-name public-key compressed-key]}
@(re-frame/subscribe [:contacts/new-identity])
valid-private? (= state :valid)
valid-public? (db/valid-topic? search-value)]
(when (or valid-public? valid-private?)
[react/view
[quo/list-header (i18n/label :t/search-no-chat-found)]
(when valid-private?
[quo/list-item
{:theme :accent
:icon :main-icons/private-chat
:title (or ens-name
(utils/get-shortened-address
(or compressed-key public-key)))
:subtitle (i18n/label :t/join-new-private-chat)
:on-press (fn []
(debounce/dispatch-and-chill [:contact.ui/contact-code-submitted false] 3000)
(re-frame/dispatch [:search/home-filter-changed nil]))}])
(when valid-public?
[quo/list-item
{:theme :accent
:icon :main-icons/public-chat
:title (str "#" search-value)
:subtitle (i18n/label :t/join-new-public-chat)
:on-press (fn []
(re-frame/dispatch [:chat.ui/start-public-chat search-value])
(re-frame/dispatch [:set :public-group-topic nil])
(re-frame/dispatch [:search/home-filter-changed nil]))}])])))
(defn render-fn
[{:keys [chat-id] :as home-item}]
;; We use `chat-id` to distinguish communities from chats
(if chat-id
[inner-item/home-list-item
home-item
{:on-press (fn []
(re-frame/dispatch [:dismiss-keyboard])
(re-frame/dispatch [:chat/navigate-to-chat chat-id])
(re-frame/dispatch [:search/home-filter-changed nil]))
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
{:content (fn []
[sheets/actions home-item])}])}]
[communities.views/community-home-list-item home-item]))
(defn render-fn-old
[{:keys [chat-id] :as home-item}]
;; We use `chat-id` to distinguish communities from chats
(if chat-id
[inner-item/home-list-item-old
home-item
{:on-press (fn []
(re-frame/dispatch [:dismiss-keyboard])
(re-frame/dispatch [:chat/navigate-to-chat chat-id])
(re-frame/dispatch [:search/home-filter-changed nil]))
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
{:content (fn []
[sheets/actions home-item])}])}]
[communities.views/community-home-list-item home-item]))
(defn chat-list-key-fn
[item]
(or (:chat-id item) (:id item)))
(defn get-item-layout
[_ index]
#js {:length 64 :offset (* 64 index) :index index})
(views/defview communities-and-chats
[]
(views/letsubs [{:keys [items search-filter]} [:home-items]
hide-home-tooltip? [:hide-home-tooltip?]]
(if (and (empty? items)
(empty? search-filter)
hide-home-tooltip?
(not @search-active?))
[welcome-blank-page]
[list/flat-list
{:key-fn chat-list-key-fn
:getItemLayout get-item-layout
:on-end-reached #(re-frame/dispatch [:chat/show-more-chats])
:keyboard-should-persist-taps :always
:data items
:render-fn render-fn
:header [:<>
(when (or (seq items) @search-active? (seq search-filter))
[search-input-wrapper search-filter (empty? items)])
(when (and (empty? items)
(or @search-active? (seq search-filter)))
[start-suggestion search-filter])]
:footer (if (and (not hide-home-tooltip?) (not @search-active?))
[home-tooltip-view]
[react/view {:height 68}])}])))
(views/defview communities-and-chats-old
[]
(views/letsubs [{:keys [items search-filter]} [:home-items]
hide-home-tooltip? [:hide-home-tooltip?]]
(if (and (empty? items)
(empty? search-filter)
hide-home-tooltip?
(not @search-active?))
[welcome-blank-page]
[list/flat-list
{:key-fn chat-list-key-fn
:getItemLayout get-item-layout
:on-end-reached #(re-frame/dispatch [:chat/show-more-chats])
:keyboard-should-persist-taps :always
:data items
:render-fn render-fn-old
:header [:<>
(when (or (seq items) @search-active? (seq search-filter))
[search-input-wrapper-old search-filter (empty? items)])
(when (and (empty? items)
(or @search-active? (seq search-filter)))
[start-suggestion search-filter])]
:footer (if (and (not hide-home-tooltip?) (not @search-active?))
[home-tooltip-view]
[react/view {:height 68}])}])))
(views/defview chats-list
[]
(views/letsubs [loading? [:chats/loading?]]
[:<>
[connectivity/loading-indicator]
(if loading?
[react/view {:flex 1 :align-items :center :justify-content :center}
[react/activity-indicator {:animating true}]]
[communities-and-chats])]))
(views/defview chats-list-old
[]
(views/letsubs [loading? [:chats/loading?]]
[:<>
[connectivity/loading-indicator]
(if loading?
[react/view {:flex 1 :align-items :center :justify-content :center}
[react/activity-indicator {:animating true}]]
[communities-and-chats-old])]))
(views/defview plus-button
[]
(views/letsubs [logging-in? [:multiaccounts/login]]
[components.plus-button/plus-button-old
{:on-press (when-not logging-in?
(fn []
(re-frame/dispatch [:group-chat/clear-contacts])
(re-frame/dispatch [:bottom-sheet/show-sheet-old :start-a-new-chat {}])))
:loading logging-in?
:accessibility-label :new-chat-button}]))
(views/defview plus-button-old
[]
(views/letsubs [logging-in? [:multiaccounts/login]]
[components.plus-button/plus-button-old
{:on-press (when-not logging-in?
(fn []
(re-frame/dispatch [:group-chat/clear-contacts])
(re-frame/dispatch [:bottom-sheet/show-sheet-old :start-a-new-chat {}])))
:loading logging-in?
:accessibility-label :new-chat-button}]))
(views/defview notifications-button
[]
(views/letsubs [notif-count [:activity-center/unread-count]]
[react/view
[quo2.button/button
{:type :grey
:size 32
:width 32
:style {:margin-left 12}
:accessibility-label :notifications-button
:on-press #(re-frame/dispatch [:activity-center/open])}
[icons/icon :main-icons/notification2
{:color (quo2.colors/theme-colors quo2.colors/neutral-100 quo2.colors/white)}]]
(when (pos? notif-count)
[react/view
{:style (merge (styles/counter-public-container) {:top 5 :right 5})
:pointer-events :none}
[react/view
{:style styles/counter-public
:accessibility-label :notifications-unread-badge}]])]))
(defn qr-button
[]
[quo2.button/button
{:type :grey
:accessibility-label "qr-button"
:size 32
:width 32
:style {:margin-left 12}
:on-press #(do
(re-frame/dispatch [::qr-scanner/scan-code
{:handler ::qr-scanner/on-scan-success}]))}
[icons/icon :main-icons/qr2
{:color (quo2.colors/theme-colors quo2.colors/neutral-100 quo2.colors/white)}]])
(defn scan-button
[]
[quo2.button/button
{:type :grey
:size 32
:width 32
:accessibility-label "scan-button"
:on-press #(do
(re-frame/dispatch [::qr-scanner/scan-code
{:handler ::qr-scanner/on-scan-success}]))}
[icons/icon :main-icons/scan2
{:color (quo2.colors/theme-colors quo2.colors/neutral-100 quo2.colors/white)}]])
(views/defview profile-button
[]
(views/letsubs [{:keys [public-key preferred-name emoji]} [:multiaccount]]
[react/view
[chat-icon.screen/emoji-chat-icon-view public-key false preferred-name emoji
{:size 28
:chat-icon chat-icon.styles/chat-icon-chat-list}]]))
(defn home
[]
[react/keyboard-avoiding-view
{:style {:flex 1
:background-color (quo2.colors/theme-colors quo2.colors/neutral-5
quo2.colors/neutral-95)}
:ignore-offset true}
[topbar/topbar
{:navigation :none
:use-insets true
:background (quo2.colors/theme-colors quo2.colors/neutral-5 quo2.colors/neutral-95)
:left-component [react/view {:flex-direction :row :margin-left 16}
[profile-button]]
:right-component [react/view {:flex-direction :row :margin-right 16}
[scan-button]
[qr-button]
[notifications-button]]
:border-bottom false}]
[react/view
{:flex-direction :row
:justify-content :space-between
:align-items :center
:margin-horizontal 16
:margin-top 15
:margin-bottom 8}
[quo2.text/text {:size :heading-1 :weight :semi-bold} (i18n/label :t/messages)]
[plus-button]]
[chats-list]])
(defn home-old
[]
[react/keyboard-avoiding-view
{:style {:flex 1}
:ignore-offset true}
[topbar/topbar
{:title (i18n/label :t/chat)
:navigation :none
:right-component [react/view {:flex-direction :row :margin-right 16}
[connectivity/connectivity-button]]}]
[chats-list-old]
[plus-button-old]])
@@ -2,7 +2,7 @@
(:require [re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.ethereum.decode :as decode]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.ui.components.react :as react]
[status-im2.common.json-rpc.events :as json-rpc]
[utils.datetime :as datetime]))
@@ -36,7 +36,7 @@
(reset! latest-block res)
(get-block
(str "0x"
(status/number-to-hex
(native-module/number-to-hex
(last-loaded-block-number)))
(fn [res]
(reset! last-loaded-block res))))))]
@@ -7,7 +7,6 @@
[status-im.ui.components.animation :as anim]
[status-im.ui.components.react :as react]
[status-im.ui.screens.biometric.views :as biometric]
[status-im.ui.screens.communities.views :as communities]
[status-im.ui.screens.keycard.frozen-card.view :as frozen-card]
[status-im.ui.screens.keycard.views :as keycard.views]
[status-im.ui.screens.multiaccounts.key-storage.views :as multiaccounts.key-storage]
@@ -167,9 +166,6 @@
(= :blocked-card view)
[keycard.views/blocked-card-popover]
(= :export-community view)
[communities/export-community]
(= :seed-key-uid-mismatch view)
[multiaccounts.key-storage/seed-key-uid-mismatch-popover]
@@ -3,7 +3,7 @@
[re-frame.core :as re-frame]
[status-im.ethereum.core :as ethereum]
[utils.i18n :as i18n]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[utils.re-frame :as rf]
[status-im.utils.types :as types]
[taoensso.timbre :as log]
@@ -21,7 +21,7 @@
(-> masked-password
security/safe-unmask-data
ethereum/sha3)]
(status/verify
(native-module/verify
address
hashed-password
(fn [result]
@@ -29,7 +29,7 @@
(log/info "[delete-profile] verify-password" result error)
(if-not (safe-blank? error)
(callback :wrong-password nil)
(status/delete-multiaccount
(native-module/delete-multiaccount
key-uid
(fn [result]
(let [{:keys [error]} (types/json->clj result)]
+6 -31
View File
@@ -4,8 +4,6 @@
[utils.i18n :as i18n]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.screens.about-app.views :as about-app]
[status-im.ui.screens.add-new.new-chat.views :as new-chat]
[status-im.ui.screens.add-new.new-public-chat.view :as new-public-chat]
[status-im.ui.screens.advanced-settings.views :as advanced-settings]
[status-im.ui.screens.appearance.views :as appearance]
[status-im.ui.screens.backup-settings.view :as backup-settings]
@@ -30,7 +28,6 @@
[status-im.ui.screens.communities.reorder-categories :as reorder-categories]
[status-im.ui.screens.communities.requests-to-join :as requests-to-join]
[status-im.ui.screens.communities.select-category :as select-category]
[status-im.ui.screens.communities.views :as communities]
[status-im.ui.screens.contacts-list.views :as contacts-list]
[status-im.ui.screens.currency-settings.views :as currency-settings]
[status-im.ui.screens.dapps-permissions.views :as dapps-permissions]
@@ -277,13 +274,10 @@
:options {:insets {:top? true}}
;;TODO custom subtitle
:component group-chat/new-group}
{:name :communities
;;TODO custom
:options {:insets {:top? true}}
:component communities/communities}
{:name :community-import
:options {:topBar {:title {:text (i18n/label :t/import-community-title)}}
:insets {:top? true}}
:insets {:top? true
:bottom? true}}
:component communities.import/view}
{:name :community-edit
:options {:topBar {:title {:text (i18n/label :t/community-edit-title)}}
@@ -291,11 +285,13 @@
:component community.edit/edit}
{:name :community-create
:options {:topBar {:title {:text (i18n/label :t/new-community-title)}}
:insets {:top? true}}
:insets {:top? true
:bottom? true}}
:component communities.create/view}
{:name :community-membership
:options {:topBar {:title {:text (i18n/label :t/membership-title)}}
:insets {:top? true}}
:insets {:top? true
:bottom? true}}
:component membership/membership}
;;WALLET
@@ -576,20 +572,6 @@
;;MODALS
;[Chat] New Chat
{:name :new-chat
:on-focus [:contacts/new-chat-focus]
;;TODO accessories
:options {:insets {:top? true}}
:component new-chat/new-chat}
;[Chat] New Public chat
{:name :new-public-chat
:options {:topBar {:title {:text (i18n/label :t/new-public-group-chat)}}
:insets {:bottom? true
:top? true}}
:component new-public-chat/new-public-chat}
;[Chat] Link preview settings
{:name :link-preview-settings
:options {:topBar {:title {:text (i18n/label :t/chat-link-previews)}}
@@ -610,13 +592,6 @@
:options {:insets {:top? true}}
:component new-chat-aio/contact-selection-list}
;[Chat] New Public chat
{:name :new-public-chat
:options {:topBar {:title {:text (i18n/label :t/new-public-group-chat)}}
:insets {:bottom? true
:top? true}}
:component new-public-chat/new-public-chat}
;[Group chat] Add participants
{:name :add-participants-toggle-list
:on-focus [:group/add-participants-toggle-list]
@@ -141,33 +141,15 @@
(reset! last-text-change (js/Date.now)))
(on-text-change text chat-id)
;; NOTE(rasom): on iOS `on-change` is dispatched after `on-text-input`,
;; that's why mention suggestions are calculated on `on-change`
(when platform/ios?
(rf/dispatch [:mention/calculate-suggestions]))))
(rf/dispatch [:mention/on-change-text text])))
(defn on-text-input
[chat-id args]
(let [native-event (.-nativeEvent ^js args)
text (.-text ^js native-event)
previous-text (.-previousText ^js native-event)
range (.-range ^js native-event)
start (.-start ^js range)
end (.-end ^js range)]
(let [native-event (.-nativeEvent ^js args)
text (.-text ^js native-event)]
(when (and (not (get @mentions-enabled? chat-id)) (string/index-of text "@"))
(swap! mentions-enabled? assoc chat-id true))
(rf/dispatch
[:mention/on-text-input
{:new-text text
:previous-text previous-text
:start start
:end end}])
;; NOTE(rasom): on Android `on-text-input` is dispatched after
;; `on-change`, that's why mention suggestions are calculated
;; on `on-change`
(when platform/android?
(rf/dispatch [:mention/calculate-suggestions]))))
(swap! mentions-enabled? assoc chat-id true))))
(defn text-input-style
[chat-id]
+1 -12
View File
@@ -1,6 +1,5 @@
(ns status-im.utils.gfycat.core
(:require [re-frame.core :as re-frame]
[status-im.native-module.core :as native-module]))
(:require [native-module.core :as native-module]))
(def unknown-gfy "Unknown")
@@ -12,13 +11,3 @@
(native-module/generate-gfycat public-key)))
(def generate-gfy (memoize build-gfy))
(re-frame/reg-fx
:insert-gfycats
(fn [key-path-seq]
(for [key-path key-path-seq]
(let [public-key (first key-path)
path-for-gfycat (second key-path)]
(native-module/generate-gfycat-async public-key
#(re-frame/dispatch [:gfycat-generated path-for-gfycat
%]))))))
+1 -12
View File
@@ -1,15 +1,4 @@
(ns status-im.utils.identicon
(:require [re-frame.core :as re-frame]
[status-im.native-module.core :as native-module]))
(:require [native-module.core :as native-module]))
(def identicon (memoize native-module/identicon))
(def identicon-async native-module/identicon-async)
(re-frame/reg-fx
:insert-identicons
(fn [key-path-seq]
(for [key-path key-path-seq]
(let [public-key (first key-path)
path-for-identicon (second key-path)]
(identicon-async public-key #(re-frame/dispatch [:identicon-generated path-for-identicon %]))))))
+2 -2
View File
@@ -2,7 +2,7 @@
(:require ["react-native-keychain" :as react-native-keychain]
[clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[utils.re-frame :as rf]
[status-im.utils.platform :as platform]
[taoensso.timbre :as log]
@@ -63,7 +63,7 @@
;; Android only
(defn- device-not-rooted?
[callback]
(status/rooted-device? (fn [rooted?] (callback (not rooted?)))))
(native-module/rooted-device? (fn [rooted?] (callback (not rooted?)))))
;; Android only
(defn- secure-hardware-available?
+2 -2
View File
@@ -5,7 +5,7 @@
[react-native.mail :as react-native-mail]
[status-im.bottom-sheet.events :as bottom-sheet]
[utils.i18n :as i18n]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.transport.utils :as transport.utils]
[status-im.ui.components.react :as react]
[status-im.utils.build :as build]
@@ -20,7 +20,7 @@
(re-frame/reg-fx
:logs/archive-logs
(fn [[db-json callback-handler]]
(status/send-logs
(native-module/send-logs
db-json
(string/join "\n" (log/get-logs-queue))
#(re-frame/dispatch [callback-handler %]))))
-8
View File
@@ -1,8 +0,0 @@
(ns status-im.utils.react-native
(:require ["react-native" :as react-native]))
; Moved from status-im.ui.components.react(let's short for R), so status-im.native-module.core(short for
; N) don't need to have a dependency to R.
; We should keep N's dependencies as simple as possible, otherwise we may see issue like:
; Circular dependency detected: N -> R -> status-im.utils.utils -> status-im.ethereum.eip55 -> N
(def device-event-emitter (.-DeviceEventEmitter react-native))
+9 -15
View File
@@ -2,8 +2,6 @@
(:require [clojure.string :as string]
[goog.string :as gstring]
[re-frame.core :as re-frame]
[status-im.add-new.db :as new-chat.db]
[status-im.chat.models :as chat]
[status-im2.constants :as constants]
[status-im.ethereum.core :as ethereum]
[status-im.group-chats.core :as group-chats]
@@ -15,7 +13,7 @@
[status-im.wallet.choose-recipient.core :as choose-recipient]
[status-im2.navigation.events :as navigation]
[taoensso.timbre :as log]
[status-im.native-module.core :as status]))
[native-module.core :as native-module]))
;; TODO(yenda) investigate why `handle-universal-link` event is
;; dispatched 7 times for the same link
@@ -26,8 +24,7 @@
:internal "status-im:/"})
(def links
{:public-chat "%s/%s"
:private-chat "%s/p/%s"
{:private-chat "%s/p/%s"
:community-requests "%s/cr/%s"
:community "%s/c/%s"
:group-chat "%s/g/%s"
@@ -60,11 +57,15 @@
(log/info "universal-links: handling group" params)
(group-chats/create-from-link cofx params))
(defn own-public-key?
[{:keys [multiaccount]} public-key]
(= (:public-key multiaccount) public-key))
(rf/defn handle-private-chat
[{:keys [db] :as cofx} {:keys [chat-id]}]
(log/info "universal-links: handling private chat" chat-id)
(when chat-id
(if-not (new-chat.db/own-public-key? db chat-id)
(if-not (own-public-key? db chat-id)
{:dispatch [:chat.ui/start-chat chat-id]}
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:content (i18n/label :t/can-not-add-yourself)}})))
@@ -88,7 +89,7 @@
(rf/defn handle-desktop-community
[cofx {:keys [community-id]}]
(status/deserialize-and-compress-key
(native-module/deserialize-and-compress-key
community-id
(fn [deserialized-key]
(rf/dispatch [:handle-navigation-to-desktop-community-from-mobile cofx (str deserialized-key)]))))
@@ -98,17 +99,11 @@
(log/info "universal-links: handling community chat" chat-id)
{:dispatch [:chat/navigate-to-chat chat-id]})
(rf/defn handle-public-chat
[cofx {:keys [topic]}]
(log/info "universal-links: handling public chat" topic)
(when (seq topic)
(chat/start-public-chat cofx topic)))
(rf/defn handle-view-profile
[{:keys [db] :as cofx} {:keys [public-key ens-name]}]
(log/info "universal-links: handling view profile" public-key)
(cond
(and public-key (new-chat.db/own-public-key? db public-key))
(and public-key (own-public-key? db public-key))
(rf/merge cofx
{:pop-to-root-fx :shell-stack}
(navigation/navigate-to :my-profile nil))
@@ -153,7 +148,6 @@
[cofx url {:keys [type] :as data}]
(case type
:group-chat (handle-group-chat cofx data)
:public-chat (handle-public-chat cofx data)
:private-chat (handle-private-chat cofx data)
:community-requests (handle-community-requests cofx data)
:community (handle-community cofx data)
@@ -8,8 +8,7 @@
:internal "status-im:/"})
(def links
{:public-chat "%s/%s"
:private-chat "%s/p/%s"
{:private-chat "%s/p/%s"
:user "%s/u/%s"
:browse "%s/b/%s"})
+8 -8
View File
@@ -14,7 +14,7 @@
[status-im.multiaccounts.core :as multiaccounts]
[status-im.multiaccounts.key-storage.core :as key-storage]
[status-im.multiaccounts.update.core :as multiaccounts.update]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im.ui.components.list-selection :as list-selection]
[utils.re-frame :as rf]
[status-im.utils.hex :as hex]
@@ -74,7 +74,7 @@
(let [{:keys [id error]} (types/json->clj value)]
(if error
(re-frame/dispatch [::new-account-error :password-error error])
(status/multiaccount-derive-addresses
(native-module/multiaccount-derive-addresses
id
[path]
(fn [derived]
@@ -82,7 +82,7 @@
(if (some #(= derived-address (get % :address)) accounts)
(re-frame/dispatch [::new-account-error :account-error
(i18n/label :t/account-exists-title)])
(status/multiaccount-store-derived
(native-module/multiaccount-store-derived
id
key-uid
[path]
@@ -110,7 +110,7 @@
(re-frame/dispatch [::new-account-error
(if (= error pass-error) :password-error :account-error)
error])
(status/multiaccount-store-account
(native-module/multiaccount-store-account
id
key-uid
hashed-password
@@ -119,7 +119,7 @@
(re-frame/reg-fx
::verify-password
(fn [{:keys [address hashed-password]}]
(status/verify
(native-module/verify
address
hashed-password
#(re-frame/dispatch [:wallet.accounts/add-new-account-password-verifyied % hashed-password]))))
@@ -128,7 +128,7 @@
::generate-account
(fn [{:keys [derivation-info hashed-password accounts key-uid]}]
(let [{:keys [address path]} derivation-info]
(status/multiaccount-load-account
(native-module/multiaccount-load-account
address
hashed-password
(derive-and-store-account key-uid path hashed-password :generated accounts)))))
@@ -136,7 +136,7 @@
(re-frame/reg-fx
::import-account-seed
(fn [{:keys [passphrase hashed-password accounts key-uid]}]
(status/multiaccount-import-mnemonic
(native-module/multiaccount-import-mnemonic
(mnemonic/sanitize-passphrase (security/unmask passphrase))
""
(derive-and-store-account key-uid constants/path-default-wallet hashed-password :seed accounts))))
@@ -144,7 +144,7 @@
(re-frame/reg-fx
::import-account-private-key
(fn [{:keys [private-key hashed-password key-uid]}]
(status/multiaccount-import-private-key
(native-module/multiaccount-import-private-key
(string/trim (security/unmask private-key))
(store-account key-uid constants/path-default-wallet hashed-password :key))))
@@ -433,15 +433,6 @@
(notification-actions item inside-chat?)
(destructive-actions item)]])
(defn public-chat-actions
[{:keys [chat-id] :as item} inside-chat?]
[quo/action-drawer
[[(group-details-entry chat-id)
(when inside-chat?
(add-members-entry))]
(notification-actions item inside-chat?)
(destructive-actions item)]])
(defn private-group-chat-actions
[item inside-chat?]
[quo/action-drawer
@@ -470,8 +461,6 @@
(case chat-type
constants/one-to-one-chat-type
[one-to-one-actions item inside-chat?]
constants/public-chat-type
[public-chat-actions item inside-chat?]
constants/private-group-chat-type
[private-group-chat-actions item inside-chat?]))
+2 -2
View File
@@ -2,7 +2,7 @@
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[react-native.background-timer :as background-timer]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[taoensso.timbre :as log]
[utils.transforms :as transforms]))
@@ -29,7 +29,7 @@
on-error (or on-error
(on-error-retry call arg)
#(log/warn :json-rpc/error method :error % :params params))]
(status/call-private-rpc
(native-module/call-private-rpc
(transforms/clj->json {:jsonrpc "2.0"
:id 1
:method method
+19 -8
View File
@@ -1,18 +1,29 @@
(ns status-im2.common.theme.core
(:require [quo.theme :as quo]
[quo2.theme :as quo2]
[react-native.core :as rn]))
[utils.re-frame :as rf]
[oops.core :refer [oget]]
[react-native.core :as rn]
[react-native.platform :as platform]))
(def device-theme (atom (rn/get-color-scheme)))
;; Note - don't use value returned by change listener
;; https://github.com/facebook/react-native/issues/28525
(defn change-device-theme
[theme]
(when-not (= theme @device-theme)
(reset! device-theme theme)
(rf/dispatch [:system-theme-mode-changed (keyword theme)])))
;; Appearance change listener fires false events in ios when the app is in the background
;; So, we are ignoring those events and when the device returns form the background,
;; we are manually checking the device theme, in ::app-state-change-fx
;; https://github.com/status-im/status-mobile/issues/15708
(defn add-device-theme-change-listener
[callback]
(rn/appearance-add-change-listener #(let [theme (rn/get-color-scheme)]
(when-not (= theme @device-theme)
(reset! device-theme theme)
(callback (keyword theme))))))
[]
(rn/appearance-add-change-listener
#(when (or platform/android?
(not= (oget rn/app-state "currentState") "background"))
(change-device-theme (oget % "colorScheme")))))
(defn device-theme-dark?
[]
+8
View File
@@ -45,3 +45,11 @@
(update-in [:db :toasts] assoc :hide-toasts-timer-set true)
(assoc :dispatch-later [{:ms 500 :dispatch [:toasts/hide-with-check]}]))
effect))))
(rf/defn close-all-toasts
{:events [:toasts/close-all-toasts]}
[{:keys [db]}]
{:dispatch-n (reduce (fn [acc toast]
(conj acc [:toasts/close (key toast)]))
[]
(get-in db [:toasts :toasts]))})
+1 -1
View File
@@ -159,4 +159,4 @@
(def default-kdf-iterations 3200)
(def ^:const new-composer-enabled? true)
(def ^:const new-composer-enabled? false)
@@ -0,0 +1,37 @@
(ns status-im2.contexts.activity-center.notification.community-kicked.view
(:require [quo2.core :as quo]
[status-im2.contexts.activity-center.notification.common.style :as common-style]
[status-im2.contexts.activity-center.notification.common.view :as common]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- swipeable
[{:keys [active-swipeable extra-fn]} child]
[common/swipeable
{:left-button common/swipe-button-read-or-unread
:left-on-press common/swipe-on-press-toggle-read
:right-button common/swipe-button-delete
:right-on-press common/swipe-on-press-delete
:active-swipeable active-swipeable
:extra-fn extra-fn}
child])
(defn view
[{:keys [notification set-swipeable-height] :as props}]
(let [{:keys [community-id read
timestamp]} notification
community (rf/sub [:communities/community community-id])
community-name (:name community)
community-image (get-in community [:images :thumbnail :uri])]
[swipeable props
[quo/activity-log
{:title (i18n/label :t/community-kicked-heading)
:icon :i/placeholder
:on-layout set-swipeable-height
:timestamp (datetime/timestamp->relative timestamp)
:unread? (not read)
:context [[quo/text {:style common-style/user-avatar-tag-text}
(i18n/label :t/community-kicked-body)]
[quo/context-tag common/tag-params {:uri community-image}
community-name]]}]]))
@@ -8,6 +8,7 @@
(def ^:const contact-request 5)
(def ^:const community-request 7)
(def ^:const admin 8)
(def ^:const community-kicked 9)
(def ^:const contact-verification 10)
(def ^:const all-supported
@@ -18,6 +19,7 @@
contact-request
community-request
admin
community-kicked
contact-verification})
;; TODO: Replace with correct enum values once status-go implements them.
@@ -29,4 +31,5 @@
it doesn't have a corresponding type in the backend. Think of the collection
as a composite key of actual types."
#{private-group-chat
community-request})
community-request
community-kicked})
@@ -14,6 +14,8 @@
[status-im2.contexts.activity-center.notification.reply.view :as reply]
[status-im2.contexts.activity-center.notification.community-request.view :as
community-request]
[status-im2.contexts.activity-center.notification.community-kicked.view :as
community-kicked]
[status-im2.contexts.activity-center.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
@@ -203,6 +205,8 @@
types/community-request [community-request/view props]
types/community-kicked [community-kicked/view props]
nil)
:else
@@ -6,11 +6,12 @@
[status-im.ethereum.core :as ethereum]
[status-im.ethereum.ens :as ens]
[status-im.ethereum.stateofus :as stateofus]
[status-im.native-module.core :as status]
[native-module.core :as native-module]
[status-im2.navigation.events :as navigation]
[status-im2.utils.validators :as validators]
[utils.validators :as validators]
[status-im2.contexts.contacts.events :as data-store.contacts]
[status-im.utils.utils :as utils]))
[status-im.utils.utils :as utils]
[status-im2.constants :as constants]))
(defn init-contact
"Create a new contact (persisted to app-db as [:contacts/new-identity]).
@@ -124,8 +125,9 @@
(re-frame/reg-fx
:contacts/decompress-public-key
(fn [{:keys [compressed-key on-success on-error]}]
(status/compressed-key->public-key
(native-module/compressed-key->public-key
compressed-key
constants/deserialization-key
(fn [resp]
(let [{:keys [error]} (types/json->clj resp)]
(if error
@@ -0,0 +1,20 @@
(ns status-im2.contexts.chat.actions.view
(:require [quo2.core :as quo]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn new-chat
[]
[quo/action-drawer
[[{:icon :i/new-message
:accessibility-label :start-a-new-chat
:label (i18n/label :t/new-chat)
:on-press (fn []
(rf/dispatch [:group-chat/clear-contacts])
(rf/dispatch [:open-modal :start-a-new-chat]))}
{:icon :i/add-user
:accessibility-label :add-a-contact
:label (i18n/label :t/add-a-contact)
:sub-label (i18n/label :t/enter-a-chat-key)
:add-divider? true
:on-press #(rf/dispatch [:open-modal :new-contact])}]]])
@@ -28,10 +28,10 @@
[quo/button
{:width 24
:size 24
:accessibility-label :reply-cancel-button
:on-press #(do
(cancel)
(rf/dispatch [:chat.ui/cancel-message-edit]))
:accessibility-label :edit-cancel-button
:on-press (fn []
(cancel)
(rf/dispatch [:chat.ui/cancel-message-edit]))
:type :outline}
[quo/icon :i/close
{:size 16
@@ -14,6 +14,7 @@
:as animations}
{:keys [max-height] :as dimensions}]
(reset! focused? true)
(rf/dispatch [:chat.ui/set-input-focused true])
(reanimated/animate height (reanimated/get-shared-value last-height))
(reanimated/set-shared-value saved-height (reanimated/get-shared-value last-height))
(reanimated/animate container-opacity 1)
@@ -39,6 +40,7 @@
(let [min-height (utils/get-min-height lines)
reopen-height (utils/calc-reopen-height text-value min-height content-height saved-height)]
(reset! focused? false)
(rf/dispatch [:chat.ui/set-input-focused false])
(reanimated/set-shared-value last-height reopen-height)
(reanimated/animate height min-height)
(reanimated/set-shared-value saved-height min-height)
@@ -59,7 +61,6 @@
{:keys [height saved-height opacity background-y]}
{:keys [content-height window-height max-height]}
keyboard-shown]
(println "qqq" (oops/oget event "nativeEvent.contentSize.height") keyboard-shown)
(when keyboard-shown
(let [content-size (+ (oops/oget event "nativeEvent.contentSize.height")
constants/extra-content-offset)
@@ -126,11 +126,14 @@
(get-quoted-text-with-mentions (or parsed-text (:parsed-text content))))]])]
(when (and in-chat-input? (not recording-audio?))
[quo/button
{:icon true
:type :outline
:size 24
:on-press #(rf/dispatch [:chat.ui/cancel-message-reply])}
:i/close])
{:width 24
:size 24
:accessibility-label :reply-cancel-button
:on-press #(rf/dispatch [:chat.ui/cancel-message-reply])
:type :outline}
[quo/icon :i/close
{:size 16
:color (colors/theme-colors colors/neutral-100 colors/neutral-40)}]])
(when (and in-chat-input? recording-audio?)
[linear-gradient/linear-gradient
{:colors [(colors/theme-colors colors/white-opa-0 colors/neutral-90-opa-0)
@@ -140,12 +143,13 @@
:style style/gradient}])]))
(defn- f-view
[reply]
(let [height (reanimated/use-shared-value (if reply constants/reply-container-height 0))]
[]
(let [reply (rf/sub [:chats/reply-message])
height (reanimated/use-shared-value (if reply constants/reply-container-height 0))]
(rn/use-effect #(reanimated/animate height (if reply constants/reply-container-height 0)) [reply])
[reanimated/view {:style (reanimated/apply-animations-to-style {:height height} {})}
(when reply [reply-message reply true false false])]))
(defn view
[reply]
[:f> f-view reply])
[]
[:f> f-view])
@@ -6,18 +6,18 @@
[status-im2.contexts.chat.bottom-sheet-composer.constants :as constants]))
(defn shadow
[elevation?]
[focused?]
(if platform/ios?
{:shadow-radius 20
:shadow-opacity (colors/theme-colors 0.1 0.7)
:shadow-color colors/neutral-100
:shadow-offset {:width 0 :height (colors/theme-colors -4 -8)}}
{:elevation (if elevation? 10 0)}))
{:elevation (if @focused? 10 0)}))
(defn sheet-container
[insets opacity elevation?]
[insets {:keys [focused?]} {:keys [container-opacity]}]
(reanimated/apply-animations-to-style
{:opacity opacity}
{:opacity container-opacity}
(merge
{:border-top-left-radius 20
:border-top-right-radius 20
@@ -29,7 +29,7 @@
:background-color (colors/theme-colors colors/white colors/neutral-95)
:z-index 3
:padding-bottom (:bottom insets)}
(shadow elevation?))))
(shadow focused?))))
(def bar-container
{:height constants/bar-container-height
@@ -55,7 +55,7 @@
:overflow :hidden}))
(defn input
[maximized? saved-keyboard-height]
[focused? saved-keyboard-height]
(merge typography/paragraph-1
{:min-height constants/input-height
:color (colors/theme-colors :black :white)
@@ -65,7 +65,7 @@
:position (if saved-keyboard-height :relative :absolute)
:top 0
:left 0
:right (when (or maximized? platform/ios?) 0)}))
:right (when (or focused? platform/ios?) 0)}))
(defn background
[opacity background-y window-height]
@@ -82,10 +82,11 @@
(or (> lines 1) (seq images) reply? edit?))
(defn cancel-edit-message
[{:keys [text-value]}
[{:keys [text-value maximized?]}
{:keys [height saved-height last-height]}]
(reanimated/animate height constants/input-height)
(reanimated/set-shared-value saved-height constants/input-height)
(reanimated/set-shared-value last-height constants/input-height)
(when-not @maximized?
(reanimated/animate height constants/input-height)
(reanimated/set-shared-value saved-height constants/input-height)
(reanimated/set-shared-value last-height constants/input-height))
(reset! text-value "")
(rf/dispatch [:chat.ui/set-input-content-height constants/input-height]))
@@ -93,11 +93,7 @@
:window-height window-height
:lines lines
:max-lines max-lines}
show-bottom-gradient? (utils/show-bottom-gradient? state dimensions)
android-elevation? (utils/android-elevation? lines
images
reply
edit)]
show-bottom-gradient? (utils/show-bottom-gradient? state dimensions)]
(effects/initialize props
state
animations
@@ -110,9 +106,7 @@
[gesture/gesture-detector
{:gesture (drag-gesture/drag-gesture props state animations dimensions keyboard-shown)}
[reanimated/view
{:style (style/sheet-container insets
(:container-opacity animations)
android-elevation?)
{:style (style/sheet-container insets state animations)
:on-layout #(handler/layout % state blur-height)}
[sub-view/bar]
[reply/view reply]
@@ -140,23 +134,25 @@
:multiline true
:placeholder (i18n/label :t/type-something)
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50)
:style (style/input @(:maximized? state)
:style (style/input @(:focused? state)
@(:saved-emoji-kb-extra-height props))
:accessibility-label :chat-message-input}]
[gradients/view props state animations show-bottom-gradient?]]
[images/images-list]
[actions/view props state animations window-height insets (seq images)]]]))]))])
(defn f-bottom-sheet-composer
[insets]
(let [window-height (rf/sub [:dimensions/window-height])
opacity (reanimated/use-shared-value 0)
background-y (reanimated/use-shared-value (- window-height))
blur-height (reanimated/use-shared-value (+ constants/composer-default-height
(:bottom insets)))]
[rn/view
[reanimated/view {:style (style/background opacity background-y window-height)}]
[sub-view/blur-view blur-height]
[sheet insets window-height blur-height opacity background-y]]))
(defn bottom-sheet-composer
[insets]
[:f>
(fn []
(let [window-height (rf/sub [:dimensions/window-height])
opacity (reanimated/use-shared-value 0)
background-y (reanimated/use-shared-value (- window-height))
blur-height (reanimated/use-shared-value (+ constants/composer-default-height
(:bottom insets)))]
[rn/view
[reanimated/view {:style (style/background opacity background-y window-height)}]
[sub-view/blur-view blur-height]
[sheet insets window-height blur-height opacity background-y]]))])
[:f> f-bottom-sheet-composer insets])
+2 -3
View File
@@ -15,7 +15,7 @@
[react-native.blur :as blur]
[status-im2.contexts.chat.home.style :as style]
[react-native.platform :as platform]
[status-im2.contexts.chat.sheets.view :as home.sheet]))
[status-im2.contexts.chat.actions.view :as home.sheet]))
(defn get-item-layout
[_ index]
@@ -117,8 +117,7 @@
[common.home/top-nav]
[common.home/title-column
{:label (i18n/label :t/messages)
:handler #(rf/dispatch [:show-bottom-sheet
{:content home.sheet/new-chat-bottom-sheet}])
:handler #(rf/dispatch [:show-bottom-sheet {:content home.sheet/new-chat}])
:accessibility-label :new-chat-button}]
[quo/discover-card
{:title (i18n/label :t/invite-friends-to-status)
@@ -17,7 +17,7 @@
;; TODO (flexsurfer) probably we don't want reactions here
(if (or deleted? deleted-for-me?)
[content.deleted/deleted-message message context]
[message/message-with-reactions message context]))
[message/message-with-reactions message context (atom false)]))
(defn pinned-messages
[chat-id]
@@ -4,11 +4,13 @@
[react-native.background-timer :as background-timer]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]
[status-im.ui.screens.chat.group :as chat.group]
[status-im.ui.screens.chat.message.gap :as message.gap]
[status-im2.common.not-implemented :as not-implemented]
[status-im2.constants :as constants]
[status-im2.contexts.chat.bottom-sheet-composer.utils :as utils]
[status-im2.contexts.chat.messages.content.deleted.view :as content.deleted]
[status-im2.contexts.chat.messages.content.view :as message]
[status-im2.contexts.chat.messages.list.state :as state]
@@ -103,6 +105,47 @@
[content.deleted/deleted-message message-data context]
[message/message-with-reactions message-data context keyboard-shown])]))])
(defn calc-shell-position
[y]
(let [{:keys [input-content-height focused?]} (rf/sub [:chats/current-chat-input])
reply (rf/sub [:chats/reply-message])
edit (rf/sub [:chats/edit-message])
lines (utils/calc-lines input-content-height)
base (if (or reply edit)
(- composer.constants/edit-container-height)
0)]
(if (not focused?)
(if (> lines 1) (+ -18 base) base)
(if (> lines 12)
(reanimated/get-shared-value y)
(if (> lines 1) (- (- input-content-height composer.constants/input-height base)) base)))))
(defn shell-button
[insets]
(let [y (reanimated/use-shared-value 0)
shell-position (calc-shell-position y)]
(rn/use-effect (fn []
(reanimated/animate y shell-position))
[shell-position])
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:transform [{:translate-y y}]}
{:bottom (+ composer.constants/composer-default-height (:bottom insets) 6)
:position :absolute
:left 0
:right 0})}
[quo/floating-shell-button
(merge {:jump-to
{:on-press #(do
(rf/dispatch [:chat/close true])
(rf/dispatch [:shell/navigate-to-jump-to]))
:label (i18n/label :t/jump-to)
:style {:align-self :center}}}
(when @show-floating-scroll-down-button
{:scroll-to-bottom {:on-press scroll-to-bottom}}))
{}]]))
(defn messages-list-content
[{:keys [chat-id] :as chat} insets keyboard-shown]
(fn []
@@ -139,16 +182,8 @@
:inverted (when platform/ios? true)
:style (when platform/android? {:scaleY -1})
:on-layout on-messages-view-layout}]
[quo/floating-shell-button
(merge {:jump-to
{:on-press #(do
(rf/dispatch [:chat/close true])
(rf/dispatch [:shell/navigate-to-jump-to]))
:label (i18n/label :t/jump-to)}}
(when @show-floating-scroll-down-button
{:scroll-to-bottom {:on-press scroll-to-bottom}}))
{:position :absolute
:bottom (+ (:bottom insets) composer.constants/composer-default-height 6)}]])))
[:f> shell-button insets]])))
(defn use-keyboard-visibility
[]
@@ -1,29 +1,8 @@
(ns status-im2.contexts.chat.messages.pin.banner.view
(:require [quo2.core :as quo]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn resolve-message
[parsed-text]
(reduce
(fn [acc {:keys [type literal destination] :as some-text}]
(str acc
(case type
"paragraph"
(resolve-message (:children some-text))
"mention"
(rf/sub [:messages/resolve-mention literal])
"status-tag"
(str "#" literal)
"link"
destination
literal)))
""
parsed-text))
[utils.re-frame :as rf]
[status-im2.contexts.chat.messages.resolver.message-resolver :as resolver]))
(defn banner
[chat-id]
@@ -35,7 +14,7 @@
latest-pin-text
(cond deleted? (i18n/label :t/message-deleted-for-everyone)
deleted-for-me? (i18n/label :t/message-deleted-for-you)
:else (resolve-message latest-pin-text))]
:else (resolver/resolve-message latest-pin-text))]
[quo/banner
{:latest-pin-text latest-pin-text
:pins-count pins-count
@@ -0,0 +1,24 @@
(ns status-im2.contexts.chat.messages.resolver.message-resolver
(:require [utils.re-frame :as rf]))
(defn resolve-message
[parsed-text]
(reduce
(fn [acc {:keys [type literal destination] :as some-text}]
(str acc
(case type
"paragraph"
(resolve-message (:children some-text))
"mention"
(rf/sub [:messages/resolve-mention literal])
"status-tag"
(str "#" literal)
"link"
destination
literal)))
""
parsed-text))
@@ -1,5 +1,5 @@
(ns status-im2.contexts.chat.messages.pin.banner.view-test
(:require [status-im2.contexts.chat.messages.pin.banner.view :as view]
(ns status-im2.contexts.chat.messages.resolver.message-resolver-test
(:require [status-im2.contexts.chat.messages.resolver.message-resolver :as resolver]
[cljs.test :as t]
[utils.re-frame :as rf]))
@@ -29,6 +29,6 @@
(t/deftest test-resolve-message
(with-redefs [rf/sub sub]
(t/testing ""
(let [text (view/resolve-message parsed-text)]
(let [text (resolver/resolve-message parsed-text)]
(t/is (= text
"foobar i just mention you here to debug this issue https://foo.bar , no worries"))))))
@@ -1,40 +0,0 @@
(ns status-im2.contexts.chat.sheets.view
(:require [quo2.core :as quo]
[utils.i18n :as i18n]
[quo2.foundations.colors :as colors]
[utils.re-frame :as rf]))
(defn new-chat-bottom-sheet
[]
[:<>
[quo/menu-item
{:type :transparent
:title (i18n/label :t/new-chat)
:icon-bg-color :transparent
:container-padding-vertical 12
:title-column-style {:margin-left 2}
:style-props {:border-bottom-width 1
:border-bottom-color (colors/theme-colors colors/neutral-10
colors/neutral-90)}
:icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40)
:accessibility-label :start-a-new-chat
:icon :i/new-message
:on-press (fn []
(rf/dispatch [:group-chat/clear-contacts])
(rf/dispatch [:open-modal :start-a-new-chat]))}]
[quo/menu-item
{:type :transparent
:title (i18n/label :t/add-a-contact)
:icon-bg-color :transparent
:icon-container-style {:padding-horizontal 0}
:container-padding-horizontal {:padding-horizontal 4}
:style-props {:margin-top 18
:margin-bottom 9}
:container-padding-vertical 12
:title-column-style {:margin-left 2}
:icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40)
:accessibility-label :add-a-contact
:subtitle (i18n/label :t/enter-a-chat-key)
:subtitle-color colors/neutral-50
:icon :i/add-user
:on-press #(rf/dispatch [:open-modal :new-contact])}]])
@@ -1,8 +1,8 @@
(ns status-im2.contexts.communities.menus.community-options.component-spec
(ns status-im2.contexts.communities.actions.community-options.component-spec
(:require [re-frame.core :as re-frame]
[test-helpers.component :as h]
[status-im2.contexts.communities.menus.community-options.view :as options]))
[status-im2.contexts.communities.actions.community-options.view :as options]))
(defn setup-subs
[subs]

Some files were not shown because too many files have changed in this diff Show More