Compare commits

..
78 changed files with 543 additions and 1331 deletions
-2
View File
@@ -32,5 +32,3 @@ METRICS_ENABLED=0
DELETE_MESSAGE_ENABLED=1
COLLECTIBLES_ENABLED=1
COMMANDS_ENABLED=1
TWO_MINUTES_SYNCING=1
SWAP_ENABLED=1
-1
View File
@@ -33,4 +33,3 @@ COMMUNITIES_ENABLED=1
COMMUNITIES_MANAGEMENT_ENABLED=1
METRICS_ENABLED=0
DELETE_MESSAGE_ENABLED=1
TWO_MINUTES_SYNCING=1
-1
View File
@@ -35,4 +35,3 @@ COMMUNITIES_ENABLED=1
COMMUNITIES_MANAGEMENT_ENABLED=1
METRICS_ENABLED=0
DELETE_MESSAGE_ENABLED=1
TWO_MINUTES_SYNCING=1
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="alert_text">#ffffff</color>
</resources>
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="alert_text">#000000</color>
</resources>
@@ -8,7 +8,6 @@
<item name="android:forceDarkAllowed">true</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:statusBarColor">?attr/backgroundColor</item>
<item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
</style>
<style name="LightTheme" parent="AppTheme">
@@ -22,9 +21,4 @@
<item name="backgroundColor">#000000</item>
<item name="android:windowLightStatusBar">false</item>
</style>
<style name="AlertDialogTheme" parent="Base.Theme.AppCompat.Light.Dialog.Alert">
<item name="android:textColor">@color/alert_text</item>
<item name="android:textColorPrimary">@color/alert_text</item>
</style>
</resources>
+7 -7
View File
@@ -4,13 +4,13 @@ pipeline {
parameters {
string(
name: 'APK_NAME',
description: 'Filename of APK uploaded to SauceLabs.',
name: 'NETWORK',
description: 'Name of test network to use.',
defaultValue: 'ropsten',
)
string(
name: 'KEYWORD_EXPRESSION',
description: 'This will run tests which contain names that match the given string expression (Optional)',
defaultValue: '',
name: 'APK_NAME',
description: 'Filename of APK uploaded to SauceLabs.',
)
}
@@ -56,8 +56,8 @@ pipeline {
--rerun_count=2 \
--testrail_report=True \
-m testrail_id \
-m \"not upgrade\" \
-k \"${params.KEYWORD_EXPRESSION}\" \
-m "not upgrade" \
--network=${params.NETWORK} \
--apk=${params.APK_NAME}
"""
}
+9 -9
View File
@@ -8,10 +8,15 @@ pipeline {
description: 'Name of the branch to checkout and build.',
defaultValue: 'develop',
)
string(
name: 'NETWORK',
description: 'Name of test network to use.',
defaultValue: 'ropsten',
)
string(
name: 'TEST_MARKERS',
description: 'Marker expression for matching tests to run.',
defaultValue: '',
defaultValue: 'critical or high',
)
string(
name: 'APK_NAME',
@@ -21,14 +26,9 @@ pipeline {
name: 'PR_ID',
description: 'ID of the Pull Request triggering this build.',
)
string(
name: 'KEYWORD_EXPRESSION',
description: 'This will run tests which contain names that match the given string expression (Optional)',
defaultValue: '',
)
string(
name: 'TR_CASE_IDS',
description: 'IDs of the TestRail case, separated by a comma (Optional)',
description: 'IDs of the TestRail case, separated by a comma. (Optional)',
defaultValue: '',
)
}
@@ -91,8 +91,8 @@ pipeline {
--numprocesses 15 \
--rerun_count=2 \
--testrail_report=True \
-m \"${params.TEST_MARKERS}\" \
-k \"${params.KEYWORD_EXPRESSION}\" \
-m "${params.TEST_MARKERS}" \
--network=${params.NETWORK} \
--apk=${params.APK_NAME} \
--build=PR-${params.PR_ID} \
--pr_number=${params.PR_ID} \
+10 -21
View File
@@ -3,6 +3,11 @@ pipeline {
agent { label 'linux' }
parameters {
string(
name: 'NETWORK',
description: 'Name of test network to use',
defaultValue: 'ropsten',
)
string(
name: 'APK_NAME',
description: 'Filename of APK uploaded to SauceLabs (base for upgrade, usually release build)',
@@ -11,16 +16,6 @@ pipeline {
name: 'APK_NAME_UPGRADE',
description: 'Filename of APK of upgraded application (installed on top of base)',
)
string(
name: 'KEYWORD_EXPRESSION',
description: 'This will run tests which contain names that match the given string expression (Optional)',
defaultValue: '',
)
string(
name: 'TR_CASE_IDS',
description: 'IDs of the TestRail case, separated by a comma (Optional)',
defaultValue: '',
)
}
options {
@@ -37,12 +32,7 @@ pipeline {
} }
}
stage('Test') {
steps { script {
/* for managing optional arguments */
def extraPytestOpts = ''
if (params.TR_CASE_IDS != '') {
extraPytestOpts = "--run_testrail_ids='${params.TR_CASE_IDS}'"
}
steps {
withCredentials([
usernamePassword(
credentialsId: 'test-rail-api',
@@ -66,19 +56,18 @@ pipeline {
dir('test/appium/tests') {
sh """
python3 -m pytest \
-m "upgrade" \
-k \"${params.KEYWORD_EXPRESSION}\" \
-m upgrade \
--numprocesses 15 \
--rerun_count=2 \
--testrail_report=True \
--network=${params.NETWORK} \
--apk=${params.APK_NAME} \
--apk_upgrade=${params.APK_NAME_UPGRADE} \
${extraPytestOpts}
--apk_upgrade=${params.APK_NAME_UPGRADE}
"""
}
}
}
} }
}
}
post {
+1 -5
View File
@@ -163,8 +163,4 @@ used for some abi encoding primitives
## "rn-emoji-keyboard": "https://github.com/status-im/rn-emoji-keyboard"
Used for taking emoji input, for custom emoji thumbnails for community channels
## "react-native-draggable-flatlist": "https://github.com/computerjazz/react-native-draggable-flatlist"
A drag-and-drop-enabled FlatList component for React Native
Used for taking emoji input, for custom emoji thumbnails for community channels
+3 -3
View File
@@ -230,7 +230,7 @@ PODS:
- React
- react-native-status (1.0.0):
- React
- react-native-status-keycard (2.5.37):
- react-native-status-keycard (2.5.36):
- Keycard
- React
- react-native-webview (11.3.0):
@@ -626,7 +626,7 @@ SPEC CHECKSUMS:
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
glog: 61334f8bdb4deea07543d4fbac3fb5948e78a7a5
glog: 5bc68409594b19a3e5c5cbced7b1ecf61053b709
Keycard: dd96182888da0aacf4de821b641103143bbb26cc
libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc
Permission-Camera: afad27bf90337684d4a86f3825112d648c8c4d3b
@@ -653,7 +653,7 @@ SPEC CHECKSUMS:
react-native-slider: 12bd76d3d568c9c5500825db54123d44b48e4ad4
react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
react-native-status: 45dbf1302ce3c258b459dfab137cd1c2c68c295d
react-native-status-keycard: 961d01ca190889ddf220206822fd752f8f4f3f7a
react-native-status-keycard: eb84554a23315510948613a9467e7e3481be340c
react-native-webview: af9990b21a9aeafa8e8347746eb4116c0de086af
React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336
React-RCTAnimation: 1bde3ecc0c104c55df246eda516e0deb03c4e49b
-1
View File
@@ -39,7 +39,6 @@
"react-native-dark-mode": "^0.2.2",
"react-native-device-info": "^7.4.0",
"react-native-dialogs": "^1.0.4",
"react-native-draggable-flatlist": "^3.0.3",
"react-native-fast-image": "8.5.11",
"react-native-fetch-polyfill": "^1.1.2",
"react-native-fs": "^2.14.1",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 899 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 B

-4
View File
@@ -206,9 +206,6 @@
(def rn-emoji-keyboard
#js {:EmojiKeyboard #js {}})
(def react-native-draggable-flatlist
#js {:default #js {}})
;; Update i18n_resources.cljs
(defn mock [module]
(case module
@@ -242,7 +239,6 @@
"@react-native-community/push-notification-ios" push-notification-ios
"react-native-camera-kit" react-native-camera-kit
"rn-emoji-keyboard" rn-emoji-keyboard
"react-native-draggable-flatlist" react-native-draggable-flatlist
"./fleets.js" default-fleets
"./chats.js" default-chats
"../translations/ar.json" (js/JSON.parse (slurp "./translations/ar.json"))
+12 -14
View File
@@ -55,13 +55,13 @@
:small :base
:large))
(defn container [{:keys [size container-style]} & children]
(defn container [{:keys [size]} & children]
(into [rn/view {:style (merge (:tiny spacing/padding-horizontal)
{:min-height (size->container-size size)
:padding-vertical 8
:flex-direction :row
:align-items :center
:justify-content :space-between} container-style)}]
:justify-content :space-between})}]
children))
(defn icon-column
@@ -197,19 +197,17 @@
left-side-alignment icon-color icon-bg-color
title subtitle subtitle-secondary active on-press on-long-press chevron size text-size
accessory-text accessibility-label title-accessibility-label accessory-style
haptic-feedback haptic-type error animated animated-accessory? title-text-weight container-style
active-background-enabled]
:or {subtitle-max-lines 1
theme :main
haptic-feedback true
animated platform/ios?
active-background-enabled true
haptic-type :selection}}]
haptic-feedback haptic-type error animated animated-accessory? title-text-weight]
:or {subtitle-max-lines 1
theme :main
haptic-feedback true
animated platform/ios?
haptic-type :selection}}]
(let [theme (if disabled :disabled theme)
{:keys [text-color active-background passive-background]}
(themes theme)
icon-color (or icon-color (:icon-color (themes theme)))
icon-bg-color (or icon-bg-color (:icon-bg-color (themes theme)))
icon-color (or icon-color (:icon-color (themes theme)))
icon-bg-color (or icon-bg-color (:icon-bg-color (themes theme)))
optional-haptic (fn []
(when haptic-feedback
(haptic/trigger haptic-type)))
@@ -225,7 +223,7 @@
[component
(merge {:type :list-item
:disabled disabled
:bg-color (when active-background-enabled active-background)
:bg-color active-background
:accessibility-label accessibility-label}
(when on-press
{:on-press (fn []
@@ -235,7 +233,7 @@
{:on-long-press (fn []
(optional-haptic)
(on-long-press))}))
[container {:size size :container-style container-style}
[container {:size size}
[left-side {:icon-color icon-color
:text-color (if on-press
text-color
+10 -23
View File
@@ -5,10 +5,7 @@
["react-native" :as rn]
["@react-native-community/hooks" :as hooks]
["react-native-navigation" :refer (Navigation)]
["rn-emoji-keyboard" :refer (EmojiKeyboard)]
["react-native-draggable-flatlist" :default DraggableFlatList]))
(def rn-draggable-flatlist (reagent/adapt-react-class DraggableFlatList))
["rn-emoji-keyboard" :refer (EmojiKeyboard)]))
(def emoji-keyboard (reagent/adapt-react-class EmojiKeyboard))
@@ -110,13 +107,7 @@
(defn- wrap-render-fn [f render-data]
(fn [data]
(reagent/as-element [f (.-item ^js data) (.-index ^js data)
(.-separators ^js data) render-data
(.-isActive ^js data) (.-drag ^js data)])))
(defn- wrap-on-drag-end-fn [f]
(fn [data]
(f (.-from ^js data) (.-to ^js data) (.-data ^js data))))
(reagent/as-element [f (.-item ^js data) (.-index ^js data) (.-separators ^js data) render-data])))
(defn- wrap-key-fn [f]
(fn [data index]
@@ -124,23 +115,19 @@
(f data index)))
(defn base-list-props
[{:keys [key-fn render-fn empty-component header footer separator data render-data on-drag-end-fn] :as props}]
[{:keys [key-fn render-fn empty-component header footer separator data render-data] :as props}]
(merge {:data (to-array data)}
(when key-fn {:keyExtractor (wrap-key-fn key-fn)})
(when render-fn {:renderItem (wrap-render-fn render-fn render-data)})
(when separator {:ItemSeparatorComponent (fn [] (reagent/as-element separator))})
(when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))})
(when header {:ListHeaderComponent (reagent/as-element header)})
(when footer {:ListFooterComponent (reagent/as-element footer)})
(when on-drag-end-fn {:onDragEnd (wrap-on-drag-end-fn on-drag-end-fn)})
(dissoc props :data :header :footer :empty-component :separator :render-fn :key-fn :on-drag-end-fn)))
(when key-fn {:keyExtractor (wrap-key-fn key-fn)})
(when render-fn {:renderItem (wrap-render-fn render-fn render-data)})
(when separator {:ItemSeparatorComponent (fn [] (reagent/as-element separator))})
(when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))})
(when header {:ListHeaderComponent (reagent/as-element header)})
(when footer {:ListFooterComponent (reagent/as-element footer)})
(dissoc props :data :header :footer :empty-component :separator :render-fn :key-fn)))
(defn flat-list [props]
[rn-flat-list (base-list-props props)])
(defn draggable-flat-list [props]
[rn-draggable-flatlist (base-list-props props)])
(defn animated-flat-list [props]
[animated-flat-list-class (base-list-props props)])
;; Hooks
+4 -5
View File
@@ -42,15 +42,11 @@
[{:keys [db]} community-id]
{:db (community-failed-to-resolve db community-id)})
(defn community-link [id]
(str "https://join.status.im/c/" id))
(fx/defn handle-community-resolved
{:events [::community-resolved]}
[{:keys [db] :as cofx} community-id community]
(fx/merge cofx
{:db (community-resolved db community-id)
:dispatch [::cache-link-preview-data (community-link community-id) community]}
{:db (community-resolved db community-id)}
(models.communities/handle-community community)))
(fx/defn resolve-community-info
@@ -82,6 +78,9 @@
:link-previews-cache
(assoc (get multiaccount :link-previews-cache {}) site data)))
(defn community-link [id]
(str "https://join.status.im/c/" id))
(defn cache-community-preview-data
[{:keys [id] :as community}]
(re-frame/dispatch [::cache-link-preview-data
+19 -54
View File
@@ -9,8 +9,7 @@
[status-im.utils.utils :as utils]
[status-im.native-module.core :as status]
[quo.react-native :as rn]
[quo.react :as react]
[status-im.multiaccounts.core :as multiaccounts]))
[quo.react :as react]))
(def at-sign "@")
@@ -171,55 +170,11 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn add-searchable-phrases
[{:keys [alias name nickname] :as user}]
(reduce
(fn [user s]
(if (nil? s)
user
(let [new-words (concat
[s]
(rest (string/split s " ")))]
(update user :searchable-phrases (fnil concat []) new-words))))
user
[alias name nickname]))
(defn add-searchable-phrases-to-contact
[{:keys [alias name added? blocked? identicon public-key nickname]} community-chat?]
(when (and alias
(not (string/blank? alias))
(or name
nickname
added?
community-chat?)
(not blocked?))
(add-searchable-phrases
{:alias alias
:name (or (utils/safe-replace name ".stateofus.eth" "") alias)
:identicon identicon
:nickname nickname
:public-key public-key})))
(defn mentionable-commmunity-members [contacts my-public-key community-members]
(reduce (fn [acc identity]
(let [contact (multiaccounts/contact-by-identity
contacts identity)
contact (if (string/blank? (:alias contact))
(assoc contact :alias
(get-in contact [:names :three-words-name]))
contact)
mentionable-contact (add-searchable-phrases-to-contact
contact true)]
(if (nil? mentionable-contact) acc
(assoc acc identity mentionable-contact))))
{}
(keys (dissoc community-members my-public-key))))
(defn get-mentionable-users
[{{:keys [current-chat-id]
:contacts/keys [contacts] :as db} :db}]
(let [{:keys [chat-type community-id users] :as chat} (get-in db [:chats current-chat-id])
{:keys [name preferred-name public-key]} (:multiaccount db)
(let [{:keys [chat-type users] :as chat}
(get-in db [:chats current-chat-id])
chat-specific-suggestions
(cond
(= chat-type constants/private-group-chat-type)
@@ -245,12 +200,9 @@
current-chat-id
(contact.db/public-key->contact contacts current-chat-id))
(= chat-type constants/community-chat-type)
(merge users (mentionable-commmunity-members
contacts public-key
(get-in db [:communities community-id :members])))
:else users)]
:else users)
{:keys [name preferred-name public-key]}
(:multiaccount db)]
(reduce
(fn [acc [key {:keys [alias name identicon]}]]
(let [name (utils/safe-replace name ".stateofus.eth" "")]
@@ -682,6 +634,19 @@
[_ ref cursor]
{::reset-text-input-cursor [ref cursor]})
(defn add-searchable-phrases
[{:keys [alias name nickname] :as user}]
(reduce
(fn [user s]
(if (nil? s)
user
(let [new-words (concat
[s]
(rest (string/split s " ")))]
(update user :searchable-phrases (fnil concat []) new-words))))
user
[alias name nickname]))
(defn is-valid-terminating-character? [c]
(case c
"\t" true ; tab
+3 -26
View File
@@ -288,7 +288,7 @@
(fx/defn edit-channel
{:events [::edit-channel-confirmation-pressed]}
[{:keys [db] :as cofx}]
(let [{:keys [name description color community-id emoji edit-channel-id category-id position]}
(let [{:keys [name description color community-id emoji edit-channel-id category-id]}
(get db :communities/create-channel)]
{::json-rpc/call [{:method "wakuext_editCommunityChat"
:params [community-id
@@ -298,7 +298,6 @@
:color color
:emoji emoji}
:category_id category-id
:position position
:permissions {:access constants/community-channel-access-no-membership}}]
:js-response true
:on-success #(re-frame/dispatch [::community-channel-edited %])
@@ -346,7 +345,7 @@
(fx/defn edit-channel-pressed
{:events [::edit-channel-pressed]}
[{:keys [db] :as cofx} community-id chat-name description color emoji chat-id category-id position]
[{:keys [db] :as cofx} community-id chat-name description color emoji chat-id category-id]
(let [{:keys [color emoji]} (if (string/blank? emoji)
(rand-nth emoji-thumbnail-styles/emoji-picker-default-thumbnails)
{:color color :emoji emoji})]
@@ -357,8 +356,7 @@
:community-id community-id
:emoji emoji
:edit-channel-id chat-id
:category-id category-id
:position position})}
:category-id category-id})}
(navigation/open-modal :edit-community-channel nil))))
(fx/defn community-created
@@ -566,15 +564,6 @@
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to remove chat from community" %)}]}))
(fx/defn delete-community-chat
{:events [:delete-community-chat]}
[_ community-id chat-id]
{::json-rpc/call [{:method "wakuext_deleteCommunityChat"
:params [community-id chat-id]
:js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to delete community chat" %)}]})
(fx/defn delete-category
{:events [:delete-community-category]}
[_ community-id category-id]
@@ -603,18 +592,6 @@
(navigation/navigate-back)
(remove-chat-from-category community-id id categoryID))))
(fx/defn reorder-category-chat
{:events [::reorder-community-category-chat]}
[_ community-id category-id chat-id new-position]
{::json-rpc/call [{:method "wakuext_reorderCommunityChat"
:params [{:communityId community-id
:categoryId category-id
:chatId chat-id
:position new-position}]
:js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to reorder community category chat" %)}]})
(fx/defn reorder-category
{:events [::reorder-community-category]}
[_ community-id category-id new-position]
-1
View File
@@ -146,7 +146,6 @@
(def ^:const timeline-chat-id "@timeline70bd746ddcc12beb96b2c9d572d0784ab137ffc774f5383e50585a932080b57cca0484b259e61cecbaa33a4c98a300a")
(def ^:const two-mins (* 2 60))
(def ^:const one-day (* 60 60 24))
(def ^:const three-days (* one-day 3))
(def ^:const one-week (* one-day 7))
-1
View File
@@ -165,7 +165,6 @@
"wakuext_reorderCommunityChat" {}
"wakuext_editCommunityCategory" {}
"wakuext_deleteCommunityCategory" {}
"wakuext_deleteCommunityChat" {}
"wakuext_ensVerified" {}
"wakuext_dismissActivityCenterNotifications" {}
"wakuext_acceptActivityCenterNotifications" {}
+5 -32
View File
@@ -6,7 +6,7 @@
[status-im.async-storage.core :as async-storage]
status-im.backup.core
status-im.bootnodes.core
[status-im.bottom-sheet.core :as bottom-sheet]
status-im.bottom-sheet.core
status-im.browser.core
status-im.browser.permissions
[status-im.chat.models :as chat]
@@ -58,9 +58,7 @@
status-im.wallet.accounts.core
status-im.wallet.choose-recipient.core
[status-im.wallet.core :as wallet]
status-im.wallet.custom-tokens.core
[status-im.navigation.core :as navigation.core]
[status-im.multiaccounts.login.core :as login.core]))
status-im.wallet.custom-tokens.core))
(re-frame/reg-fx
:dismiss-keyboard
@@ -114,35 +112,10 @@
(fx/defn system-theme-mode-changed
{:events [:system-theme-mode-changed]}
[{:keys [db] :as cofx} theme]
(let [cur-theme (get-in db [:multiaccount :appearance])
current-tab (get db :current-tab :chat)
view-id (:view-id db)
screen-params (get-in db [:navigation/screen-params view-id])
root-id @navigation.core/root-id]
(navigation.core/dismiss-all-modals)
[{:keys [db]} theme]
(let [cur-theme (get-in db [:multiaccount :appearance])]
(when (or (nil? cur-theme) (zero? cur-theme))
(fx/merge cofx
{::multiaccounts/switch-theme (if (= :dark theme) 2 1)
:utils/dispatch-later
(cond-> [{:ms 2000 :dispatch
(if (= view-id :chat)
[:chat.ui/navigate-to-chat (:current-chat-id db)]
[:navigate-to view-id screen-params])}]
(some #(= view-id %) navigation.core/community-screens)
(conj {:ms 1000 :dispatch
[:navigate-to :community
(get-in db [:navigation/screen-params :community])]})
(= view-id :community-emoji-thumbnail-picker)
(conj {:ms 1500 :dispatch
[:navigate-to :create-community-channel
(get-in db [:navigation/screen-params :create-community-channel])]}))}
(bottom-sheet/hide-bottom-sheet)
(navigation/init-root root-id)
(when (= root-id :chat-stack)
(navigation/change-tab current-tab))))))
{::multiaccounts/switch-theme (if (= :dark theme) 2 1)})))
(def authentication-options
{:reason (i18n/label :t/biometric-auth-reason-login)})
+1 -1
View File
@@ -16,7 +16,7 @@
(fx/merge cofx
{:db (-> db
(assoc-in [:keycard :creating-backup?] backup-type))}
(when (:multiaccount db)
(when-not (:multiaccounts/login db)
(navigation/change-tab :profile))
(navigation/navigate-to-cofx :seed-phrase nil)))
+1 -1
View File
@@ -66,7 +66,7 @@
:error nil
:status nil))
:hide-popover nil})
(when (:multiaccount db)
(when-not (:multiaccounts/login db)
(navigation/change-tab :profile))
(when-not (:multiaccounts/login db)
(if (:popover/popover db)
+2 -8
View File
@@ -217,15 +217,9 @@
:t/keycard-access-reset :t/keycard-backup-success-title))
:content (i18n/label (if (= backup-type :recovery-card)
:t/keycard-can-use-with-new-passcode :t/keycard-backup-success-body))}}
(cond
(multiaccounts.model/logged-in? cofx)
(if (multiaccounts.model/logged-in? cofx)
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])
(:multiaccounts/login db)
(return-to-keycard-login)
:else
(navigation/set-stack-root :onboarding [:get-your-keys]))))
(return-to-keycard-login))))
(re-frame/reg-fx
::finish-migration
@@ -109,15 +109,12 @@
types/json->clj
:error
string/blank?
not)
onboarding? (not (or (:multiaccounts/login db) (:multiaccount db)))]
not)]
(if error?
(popover/show-popover cofx {:view :custom-seed-phrase})
{::validate-seed-against-key-uid {:seed-phrase (-> db :multiaccounts/key-storage :seed-phrase)
;; Unique key-uid of the account for which we are going to move keys
:key-uid (or (-> db :multiaccounts/login :key-uid)
(-> db :multiaccount :key-uid)
(and onboarding? (-> db :keycard :application-info :key-uid)))}})))
:key-uid (or (-> db :multiaccounts/login :key-uid) (-> db :multiaccount :key-uid))}})))
(fx/defn choose-storage-pressed
{:events [::choose-storage-pressed]}
+7 -37
View File
@@ -1,7 +1,6 @@
(ns status-im.navigation.core
(:require
["react-native" :as rn]
[clojure.set :as clojure.set]
["react-native-gesture-handler" :refer (gestureHandlerRootHOC)]
["react-native-navigation" :refer (Navigation)]
[quo.components.text-input :as quo.text-input]
@@ -158,14 +157,12 @@
(.registerComponentDidDisappearListener
(.events Navigation)
(fn [^js evn]
(let [view-id (keyword (.-componentName evn))]
(when-not (#{"popover" "bottom-sheet" "signing-sheet" "visibility-status-popover"}
(.-componentName evn))
(re-frame/dispatch [::view-disappeared view-id])
(doseq [[_ {:keys [ref value]}] @quo.text-input/text-input-refs]
(.setNativeProps ^js ref (clj->js {:text value})))
(doseq [[^js text-input default-value] @react/text-input-refs]
(.setNativeProps text-input (clj->js {:text default-value}))))))))
(when-not (#{"popover" "bottom-sheet" "signing-sheet" "visibility-status-popover"}
(.-componentName evn))
(doseq [[_ {:keys [ref value]}] @quo.text-input/text-input-refs]
(.setNativeProps ^js ref (clj->js {:text value})))
(doseq [[^js text-input default-value] @react/text-input-refs]
(.setNativeProps text-input (clj->js {:text default-value})))))))
;; SET ROOT
(re-frame/reg-fx
@@ -280,10 +277,7 @@
(.registerBottomTabSelectedListener
(.events Navigation)
(fn [^js evn]
(let [selected-tab-index (.-selectedTabIndex evn)
comp (get tab-root-ids selected-tab-index)
tab-key (get (clojure.set/map-invert tab-key-idx) selected-tab-index)]
(re-frame/dispatch [:set :current-tab tab-key])
(let [comp (get tab-root-ids (.-selectedTabIndex evn))]
(when (and platform/android? (= @root-comp-id comp))
(.popToRoot Navigation (name comp)))
(reset! root-comp-id comp)))))
@@ -383,27 +377,3 @@
(log/debug :navigate-replace-fx view-id)
(.pop Navigation (name @root-comp-id))
(navigate view-id)))
(def community-screens '(:community-management
:community-members
:community-requests-to-join
:create-community-channel
:community-emoji-thumbnail-picker
:create-community-category
:community-edit-chats))
;; change view-id if it is still same after component is disappeared
;; https://github.com/wix/react-native-navigation/issues/5744#issuecomment-563226820
(fx/defn view-disappeared
{:events [::view-disappeared]}
[{:keys [db]} view-id]
(when (= view-id (:view-id db))
{:db (assoc db :view-id (cond
(= view-id :community-emoji-thumbnail-picker)
:create-community-channel
(some #(= view-id %) community-screens)
:community
:else
:home))}))
+8 -9
View File
@@ -19,16 +19,15 @@
{:unread-count (get db :activity.center/notifications-count 0)
:notifications (get-in db [:activity.center/notifications :notifications])}
activities)]
(merge
{:db (-> db
(assoc-in [:activity.center/notifications :notifications] notifications)
(assoc :activity.center/notifications-count (max 0 unread-count)))}
(cond
(= (:view-id db) :notifications-center)
{:dispatch [:mark-all-activity-center-notifications-as-read]}
{:db (-> db
(assoc-in [:activity.center/notifications :notifications] notifications)
(assoc :activity.center/notifications-count (max 0 unread-count)))
:dispatch (cond
(= (:view-id db) :notifications-center)
[:mark-all-activity-center-notifications-as-read]
(= (:view-id db) :chat)
{:dispatch [:accept-all-activity-center-notifications-from-chat (:current-chat-id db)]}))))
(= (:view-id db) :chat)
[:accept-all-activity-center-notifications-from-chat (:current-chat-id db)])}))
(fx/defn get-activity-center-notifications-count
{:events [:get-activity-center-notifications-count]}
+24 -37
View File
@@ -34,6 +34,7 @@
[status-im.utils.security :as security]
[status-im.wallet.db :as wallet.db]
[status-im.wallet.utils :as wallet.utils]
[status-im.utils.utils :as utils]
status-im.ui.screens.keycard.subs
[status-im.chat.models.mentions :as mentions]
[status-im.notifications.core :as notifications]
@@ -180,12 +181,6 @@
(reg-root-key-sub :wallet/fetching-collection-assets :wallet/fetching-collection-assets)
(reg-root-key-sub :wallet/collectible-assets :wallet/collectible-assets)
(reg-root-key-sub :wallet/selected-collectible :wallet/selected-collectible)
(reg-root-key-sub :wallet/modal-selecting-source-token? :wallet/modal-selecting-source-token?)
(reg-root-key-sub :wallet/swap-from-token :wallet/swap-from-token)
(reg-root-key-sub :wallet/swap-to-token :wallet/swap-to-token)
(reg-root-key-sub :wallet/swap-from-token-amount :wallet/swap-from-token-amount)
(reg-root-key-sub :wallet/swap-to-token-amount :wallet/swap-to-token-amount)
(reg-root-key-sub :wallet/swap-advanced-mode? :wallet/swap-advanced-mode?)
;;commands
(reg-root-key-sub :commands/select-account :commands/select-account)
@@ -882,22 +877,6 @@
(assoc :color colors/blue))
chats)))))
(re-frame/reg-sub
:chats/sorted-categories-by-community-id
(fn [[_ community-id]]
[(re-frame/subscribe [:chats/by-community-id community-id])
(re-frame/subscribe [:communities/community-chats community-id])])
(fn [[chats comm-chats] [_ community-id]]
(let [chat-cat (into {} (map (fn [{:keys [id categoryID position]}]
{(str community-id id) {:categoryID categoryID
:position position}})
(vals comm-chats)))]
(group-by :categoryID (sort-by :position
(map #(cond-> (merge % (chat-cat (:chat-id %)))
(= community-id constants/status-community-id)
(assoc :color colors/blue))
chats))))))
(re-frame/reg-sub
:chats/category-by-chat-id
(fn [[_ community-id _]]
@@ -924,9 +903,7 @@
:<- [:communities]
(fn [communities [_ id]]
(->> (get-in communities [id :categories])
(map #(assoc (get % 1) :community-id id))
(sort-by :position)
(into []))))
(sort-by #(:position (get % 1))))))
(re-frame/reg-sub
:chats/current-chat-ui-props
@@ -1423,11 +1400,22 @@
:<- [:contacts/contacts]
(fn [contacts]
(reduce
(fn [acc [key contact]]
(let [mentionable-contact (mentions/add-searchable-phrases-to-contact
contact false)]
(if (nil? mentionable-contact) acc
(assoc acc key mentionable-contact))))
(fn [acc [key {:keys [alias name added? blocked? identicon public-key nickname]}]]
(if (and alias
(not= alias "")
(or name
nickname
added?)
(not blocked?))
(let [name (utils/safe-replace name ".stateofus.eth" "")]
(assoc acc public-key
(mentions/add-searchable-phrases
{:alias alias
:name (or name alias)
:identicon identicon
:nickname nickname
:public-key key})))
acc))
{}
contacts)))
@@ -1437,9 +1425,7 @@
:<- [:chats/mentionable-contacts]
:<- [:contacts/blocked-set]
:<- [:multiaccount]
:<- [:contacts/contacts]
(fn [[{:keys [chat-id users contacts community-id chat-type] :as chat}
mentionable-contacts blocked {:keys [public-key]} my-contacts]]
(fn [[{:keys [chat-id users contacts community-id chat-type] :as chat} mentionable-contacts blocked {:keys [name preferred-name public-key]}]]
(let [community-members @(re-frame/subscribe [:communities/community-members
community-id])
contacts-with-one-to-one (if (= chat-type constants/one-to-one-chat-type)
@@ -1450,13 +1436,14 @@
members-left (into #{} (filter #(group-chat/member-removed? chat %) (keys users)))
filtered-contacts (select-keys contacts-with-one-to-one (if (nil? community-id)
(distinct (concat (seq contacts) (keys users) [chat-id]))
(keys community-members)))
mentionable-commmunity-members (mentions/mentionable-commmunity-members
my-contacts public-key community-members)]
(keys community-members)))]
(apply dissoc
(-> users
(merge filtered-contacts)
(merge mentionable-commmunity-members))
(assoc public-key (mentions/add-searchable-phrases
{:alias name
:name (or preferred-name name)
:public-key public-key})))
(conj (concat blocked members-left) public-key)))))
(re-frame/reg-sub
@@ -6,8 +6,7 @@
(defn emoji-thumbnail [emoji color size]
(when-not (string/blank? emoji)
[react/view (styles/emoji-thumbnail-icon color size)
[react/text {:style (styles/emoji-thumbnail-icon-text size)
:accessibility-label :thumbnail-emoji} emoji]]))
[react/text {:style (styles/emoji-thumbnail-icon-text size)} emoji]]))
(defn emoji-thumbnail-touchable [emoji color size func]
(when-not (string/blank? emoji)
@@ -17,6 +17,7 @@
(defn emoji-thumbnail-icon-text [size]
{:font-size (emoji-utils/emoji-font-size size)
:line-height size
:accessibility-label :thumbnail-emoji
:margin-top (emoji-utils/emoji-top-margin-for-vertical-alignment size)}) ;; Required for vertical alignment bug - Check function defination for more info
@@ -86,4 +86,22 @@
: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]]]))
[chat-name-input topic error]]
[react/view {:margin-top 32}
(for [[section chats] (chat.models/chats)]
^{:key section}
[react/view
[react/view {:margin-right 16 :padding-left 16 :padding-vertical 3
:border-bottom-width 1 :border-bottom-color colors/gray-lighter
:border-top-width 1 :border-top-color colors/gray-lighter
:border-right-width 1 :border-right-color colors/gray-lighter
:border-bottom-right-radius 14 :border-top-right-radius 14}
[quo/text {:weight :medium} section]]
[react/view {:flex-direction :row :flex-wrap :wrap :margin-vertical 8 :padding-horizontal 16}
(let [lang-topic (get-language-topic)
chats (if (and (= section-featured section) lang-topic)
(conj chats lang-topic)
chats)]
(for [chat chats]
^{:key chat}
[render-topic chat]))]])]]))
+20 -21
View File
@@ -12,29 +12,28 @@
(re-frame/dispatch [:chat.ui/fill-gaps chat-id gap-ids])))
(views/defview gap
[{:keys [gap-ids chat-id gap-parameters public? community?]}]
[{:keys [gap-ids chat-id gap-parameters]}]
(views/letsubs [in-progress? [:chats/fetching-gap-in-progress?
gap-ids
chat-id]
connected? [:mailserver/connected?]
first-gap? (= gap-ids #{:first-gap})]
(when (or (not first-gap?) public? community?)
[react/view {:style (style/gap-container)}
[react/touchable-highlight
{:on-press (when (and connected? (not in-progress?))
(on-press chat-id gap-ids))
:style style/touchable}
[react/view {:style style/label-container}
(if in-progress?
[react/activity-indicator]
[react/nested-text
{:style (style/gap-text connected?)}
(i18n/label (if first-gap? :t/load-more-messages :t/fetch-messages))
(when first-gap?
[{:style style/date}
(let [date (datetime/timestamp->long-date
(* 1000 (:from gap-parameters)))]
(str
"\n"
(i18n/label :t/load-messages-before
{:date date})))])])]]])))
[react/view {:style (style/gap-container)}
[react/touchable-highlight
{:on-press (when (and connected? (not in-progress?))
(on-press chat-id gap-ids))
:style style/touchable}
[react/view {:style style/label-container}
(if in-progress?
[react/activity-indicator]
[react/nested-text
{:style (style/gap-text connected?)}
(i18n/label (if first-gap? :t/load-more-messages :t/fetch-messages))
(when first-gap?
[{:style style/date}
(let [date (datetime/timestamp->long-date
(* 1000 (:from gap-parameters)))]
(str
"\n"
(i18n/label :t/load-messages-before
{:date date})))])])]]]))
@@ -80,9 +80,7 @@
(let [anim-opacity (animation/create-value 0)]
[react/animated-view {:style (style/message-timestamp-wrapper message) :opacity anim-opacity}
(when @show-timestamp? (message-timestamp-anim anim-opacity show-timestamp?))
[react/text
{:style (style/message-timestamp-text)
:accessibility-label :message-timestamp}
[react/text {:style (style/message-timestamp-text)}
timestamp-str]])))
(defview quoted-message
+3 -5
View File
@@ -4,12 +4,11 @@
[status-im.ui.screens.chat.styles.photos :as style]
[status-im.profile.db :as profile.db]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.utils.image :as utils.image]
[quo.design-system.colors :as colors]))
[status-im.utils.image :as utils.image]))
(def memo-photo-rend
(memoize
(fn [photo-path size accessibility-label _]
(fn [photo-path size accessibility-label]
(let [identicon? (when photo-path (profile.db/base64-png? photo-path))]
[react/view {:style (style/photo-container size)}
[react/image {:source (utils.image/source photo-path)
@@ -19,9 +18,8 @@
(when identicon?
[react/view {:style (style/photo-border size)}])]))))
;; "(colors/dark?)" is passed to memoized function to avoid previous themes cache
(defn photo [photo-path {:keys [size accessibility-label]}]
[memo-photo-rend photo-path size accessibility-label (colors/dark?)])
[memo-photo-rend photo-path size accessibility-label])
;; We optionally pass identicon for perfomance reason, so it does not have to be calculated for each message
(defn member-photo [pub-key identicon]
+1 -4
View File
@@ -243,8 +243,7 @@
(defn render-fn [{:keys [outgoing type] :as message}
idx
_
{:keys [group-chat public? community? current-public-key space-keeper
chat-id show-input? message-pin-enabled edit-enabled in-pinned-view?]}]
{:keys [group-chat public? current-public-key space-keeper chat-id show-input? message-pin-enabled edit-enabled in-pinned-view?]}]
[react/view {:style (when (and platform/android? (not in-pinned-view?)) {:scaleY -1})}
(if (= type :datemark)
[message-datemark/chat-datemark (:value message)]
@@ -256,7 +255,6 @@
:incoming-group (and group-chat (not outgoing))
:group-chat group-chat
:public? public?
:community? community?
:current-public-key current-public-key
:show-input? show-input?
:message-pin-enabled message-pin-enabled
@@ -287,7 +285,6 @@
community-admin?))))]
{:group-chat group-chat
:public? public?
:community? (not (nil? community-id))
:current-public-key current-public-key
:space-keeper space-keeper
:chat-id chat-id
@@ -12,7 +12,6 @@
(fn []
(let [current-chat (<sub [:chat-by-id chat-id])
{:keys [chat-name color description community-id emoji]} current-chat
{:keys [position]} (<sub [:chats/community-chat-by-id community-id chat-id])
category (<sub [:chats/category-by-chat-id community-id chat-id])
{:keys [admin]} (<sub [:communities/community community-id])
pinned-messages (<sub [:chats/pinned chat-id])]
@@ -28,8 +27,7 @@
color
emoji
chat-id
(:id category)
position])}])
(:id category)])}])
:extended-header (profile-header/extended-header
{:title chat-name
:color color
@@ -22,6 +22,7 @@
[re-frame.core :as re-frame]
[status-im.ui.screens.chat.sheets :as sheets]
[status-im.ui.components.accordion :as accordion]
[clojure.string :as string]
[status-im.ui.screens.communities.styles :as styles]))
(def request-cooldown-ms (* 60 1000))
@@ -138,6 +139,12 @@
:title (i18n/label :t/edit-chats)
:accessibility-label :community-edit-chats
:icon :main-icons/edit
:on-press #(hide-sheet-and-dispatch [:open-modal :community-edit-chats {:community-id id}])}]
[quo/list-item
{:theme :accent
:title (i18n/label :t/reorder-categories)
:accessibility-label :community-reorder-categories
:icon :main-icons/channel-category
:on-press #(hide-sheet-and-dispatch
[:open-modal :community-reorder-categories {:community-id id}])}]])]))
@@ -161,28 +168,46 @@
{:content (fn []
[sheets/actions home-item])}])}])
(defn categories-accordion [community-id chats categories data]
(defn categories-accordion [community-id chats categories edit data]
[:<>
(for [{:keys [name id state]} categories]
(for [{:keys [name id state]} (vals categories)]
^{:key (str "cat" name id)}
[:<>
[accordion/section
{:on-open #(>evt [::communities/store-category-state community-id id true])
:on-close #(>evt [::communities/store-category-state community-id id false])
:default state
:opened edit
:disabled edit
:title [rn/view styles/category-item
[icons/icon :main-icons/channel-category {:color colors/gray}]
(if edit
[rn/touchable-opacity {:on-press #(>evt [:delete-community-category community-id id])}
[icons/icon :main-icons/delete-circle {:no-color true}]]
[icons/icon :main-icons/channel-category {:color colors/gray}])
[rn/text {:style {:font-size 17 :margin-left 10 :color colors/black}} name]]
:content [:<>
:content [rn/view
(for [chat (get chats id)]
^{:key (str "chat" chat id)}
[community-chat-item chat nil nil data])]}]
(if edit
^{:key (str "chat" chat id)}
[rn/view styles/category-item
[rn/touchable-opacity {:on-press #(>evt [:remove-chat-from-community-category
community-id
(string/replace (:chat-id chat) community-id "")
(:categoryID chat)])}
[icons/icon :main-icons/delete-circle {:no-color true}]]
[rn/view {:flex 1}
[inner-item/home-list-item
(assoc chat :public? true)]]]
^{:key (str "chat" chat id)}
[community-chat-item chat nil nil data]))]}]
[quo/separator]])])
(defn community-chat-list [community-id categories from-chat]
(let [chats (<sub [:chats/sorted-categories-by-community-id community-id])]
(defn community-chat-list [community-id categories edit from-chat]
(let [chats (<sub [:chats/categories-by-community-id community-id])]
(if (and (empty? categories) (empty? chats))
[blank-page (i18n/label :t/welcome-community-blank-message)]
(if edit
[blank-page (i18n/label :t/welcome-community-blank-message-edit-chats)]
[blank-page (i18n/label :t/welcome-community-blank-message)])
[list/flat-list
{:key-fn :chat-id
:content-container-style {:padding-bottom 8}
@@ -190,7 +215,7 @@
:data (get chats "")
:render-data {:from-chat from-chat}
:render-fn community-chat-item
:header [categories-accordion community-id chats categories {:from-chat from-chat}]
:header [categories-accordion community-id chats categories edit {:from-chat from-chat}]
:footer [rn/view {:height 68}]}])))
(defn channel-preview-item [{:keys [id name]}]
@@ -242,6 +267,23 @@
[components.react/small-loading-indicator]
(i18n/label :t/fetch-community))]]]))
(defn community-edit []
(let [{:keys [community-id]} (<sub [:get-screen-params])]
(fn []
(let [{:keys [id name images members permissions color]} (<sub [:communities/community community-id])
categories (<sub [:communities/sorted-categories community-id])]
[:<>
[topbar/topbar
{:modal? true
:content [toolbar-content
id
name
color
images
(not= (:access permissions) constants/community-no-membership-access)
(count members)]}]
[community-chat-list id categories true false]]))))
(defn community []
(let [{:keys [community-id from-chat]} (<sub [:get-screen-params])]
(fn []
@@ -65,4 +65,4 @@
@category-name
(vec @selected-items)]
3000)}
(i18n/label :t/create)]}]]))))
(i18n/label :t/create)]}]]))))
@@ -1,176 +1,60 @@
(ns status-im.ui.screens.communities.reorder-categories
(:require [quo.core :as quo]
[clojure.walk :as walk]
[quo.react-native :as rn]
[reagent.core :as reagent]
[clojure.string :as string]
[clojure.set :as clojure.set]
[status-im.i18n.i18n :as i18n]
[status-im.utils.utils :as utils]
[status-im.constants :as constants]
[quo.design-system.colors :as colors]
[status-im.utils.platform :as platform]
[status-im.ui.components.react :as react]
[status-im.ui.components.topbar :as topbar]
[status-im.communities.core :as communities]
[status-im.utils.handlers :refer [>evt <sub]]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.screens.communities.styles :as styles]
[status-im.ui.screens.communities.community :as community]
[status-im.ui.screens.home.views.inner-item :as inner-item]))
[status-im.ui.screens.communities.community :as community]))
(def collapse-chats? (reagent/atom false))
(def data (reagent/atom []))
(defn category-change-positon [community-id key up? position]
(let [new-position (if up? (dec position) (inc position))]
(>evt [::communities/reorder-community-category community-id key new-position])))
(defn show-delete-chat-confirmation [community-id chat-id]
(utils/show-confirmation
{:title (i18n/label :t/delete-confirmation)
:content (i18n/label :t/delete-chat-confirmation)
:confirm-button-text (i18n/label :t/delete)
:on-accept #(>evt [:delete-community-chat community-id chat-id])}))
(defn category-item-button [community-id up? disabled? key position]
(let [[margin-right icon] (if up?
[10 :main-icons/dropdown-up]
[25 :main-icons/dropdown])]
[react/touchable-opacity {:disabled disabled?
:on-press #(category-change-positon
community-id key up? position)}
[rn/view {:style (styles/reorder-categories-button margin-right)}
[icons/icon icon {:color colors/black}]]]))
(defn show-delete-catgory-confirmation [community-id category-id]
(utils/show-confirmation
{:title (i18n/label :t/delete-confirmation)
:content (i18n/label :t/delete-category-confirmation)
:confirm-button-text (i18n/label :t/delete)
:on-accept #(>evt [:delete-community-category community-id category-id])}))
(defn chat-item
[{:keys [id community-id] :as home-item} is-active? drag]
(let [chat-id (string/replace id community-id "")
background-color (if is-active? colors/gray-lighter colors/white)
home-item (clojure.set/rename-keys home-item {:id :chat-id})]
[rn/view {:accessibility-label :chat-item
:style (merge styles/category-item
{:background-color background-color})}
[rn/touchable-opacity
{:accessibility-label :delete-community-chat
:on-press #(show-delete-chat-confirmation community-id chat-id)}
[icons/icon :main-icons/delete-circle {:no-color true}]]
[rn/view {:flex 1}
[inner-item/home-list-item (assoc home-item :edit? true) {:active-opacity 1}]]
[rn/touchable-opacity {:on-long-press drag
:delay-long-press 100
:accessibility-label :chat-drag-handle
:style {:padding 20}}
[icons/icon :main-icons/reorder-handle {:no-color true :width 18 :height 12}]]]))
(defn category-item
[{:keys [id name community-id]} is-active? drag]
(let [background-color (if is-active? colors/gray-lighter colors/white)
category-none? (string/blank? id)]
(defn category-item [community-id count {:keys [key name position]}]
(let [up-disabled? (= position 0)
down-disabled? (= position (dec count))]
[:<>
[quo/separator]
[rn/view {:accessibility-label :category-item
:style (merge styles/category-item
{:background-color background-color})}
(if category-none?
[icons/icon :main-icons/channel-category {:color colors/gray}]
[rn/touchable-opacity
{:accessibility-label :delete-category-button
:on-press #(show-delete-catgory-confirmation community-id id)}
[icons/icon :main-icons/delete-circle {:no-color true}]])
[rn/view {:flex 1}
[rn/text {:style {:font-size 17 :margin-left 10 :color colors/black}} name]]
(when (and (not category-none?) @collapse-chats?)
[rn/touchable-opacity {:accessibility-label :category-drag-handle
:on-long-press drag
:delay-long-press 100
:style {:padding 20}}
[icons/icon :main-icons/reorder-handle {:no-color true :width 18 :height 12}]])]]))
[rn/view {:style styles/reorder-categories-item}
[icons/icon :main-icons/channel-category {:color colors/gray}]
[rn/text {:style (styles/reorder-categories-text)} name]
[category-item-button community-id true up-disabled? key position]
[category-item-button community-id false down-disabled? key position]]
[quo/separator]]))
(defn render-fn
[{:keys [chat-type] :as item} _ _ _ is-active? drag]
(if (= chat-type constants/community-chat-type)
[chat-item item is-active? drag]
[category-item item is-active? drag]))
(defn calculate-chat-new-position-and-category
[to second-call? old-category going-up?]
(let [{:keys [id chat-type categoryID position]} (get @data to)
[new-category new-position]
(if going-up?
(if (= chat-type constants/community-chat-type)
[categoryID (if second-call? (inc position) position)]
(if second-call? [id 0]
(calculate-chat-new-position-and-category (dec to) true old-category true)))
(if (= chat-type constants/community-chat-type)
(if (= categoryID old-category)
[categoryID position]
[categoryID (inc position)]) [id 0]))]
[new-category new-position]))
(defn update-local-atom [data-js]
(reset! data data-js)
(reagent/flush))
(defn on-drag-end-chat [from to data-js]
(let [{:keys [id community-id categoryID position]} (get @data from)
[new-category new-position] (calculate-chat-new-position-and-category
to false categoryID (> from to))
chat-id (string/replace id community-id "")]
(when-not (and (= new-position position) (= new-category categoryID))
(update-local-atom data-js)
(>evt [::communities/reorder-community-category-chat
community-id new-category chat-id new-position]))))
(defn on-drag-end-category [from to data-js]
(let [{:keys [id community-id position]} (get @data from)]
(when (and (< to (count @data)) (not= position to) (not= id ""))
(update-local-atom data-js)
(>evt [::communities/reorder-community-category community-id id to]))))
(defn on-drag-end-fn [from to data-js]
(if @collapse-chats?
(on-drag-end-category from to data-js)
(when-not (= to 0) (on-drag-end-chat from to data-js))))
(defn reset-data [categories chats]
(reset! data (if @collapse-chats? categories ;; If chats are collapsed then only show categories
(walk/postwalk-replace ;; else, categories and chats
{:chat-id :id}
(reduce (fn [acc category]
(-> acc
(conj category)
(into (get chats (:id category))))) [] categories)))))
(defn draggable-list []
[rn/draggable-flat-list
{:key-fn :id
:data @data
:render-fn render-fn
:autoscroll-threshold (if platform/android? 150 250)
:autoscroll-speed (if platform/android? 10 150) ;; TODO - Use same speed for both ios and android
:container-style {:margin-bottom 108} ;; after bumping react native version to > 0.64
:on-drag-end-fn on-drag-end-fn}])
(defn categories-view [community-id categories count]
[rn/view {:accessibility-label :reorder-categories-list}
(for [category-vector categories]
(let [category (clojure.set/rename-keys (get category-vector 1) {:id :key})]
[category-item community-id count category]))])
(defn view []
(let [{:keys [community-id]} (<sub [:get-screen-params])
{:keys [id name images members permissions color]}
(<sub [:communities/community community-id])
sorted-categories (<sub [:communities/sorted-categories community-id])
categories (if @collapse-chats? sorted-categories
(conj sorted-categories
{:id ""
:position (count sorted-categories)
:name (i18n/label :t/none)
:community-id community-id}))
chats (<sub [:chats/sorted-categories-by-community-id community-id])]
(reset-data categories chats)
categories (<sub [:communities/sorted-categories community-id])]
[:<>
[topbar/topbar
{:modal? true
:content [community/toolbar-content id name color images
(not= (:access permissions) constants/community-no-membership-access)
(count members)]}]
(if (and (empty? sorted-categories) (empty? chats))
[community/blank-page (i18n/label :t/welcome-community-blank-message-edit-chats)]
[:<>
[quo/list-item {:size :small
:title (i18n/label :t/rearrange-categories)
:active @collapse-chats?
:accessory :switch
:container-style {:padding-left 10}
:on-press #(reset! collapse-chats? (not @collapse-chats?))}]
[quo/separator]
[draggable-list]])]))
(if (empty? categories)
[community/blank-page (i18n/label :t/welcome-community-blank-message-categories)]
[categories-view community-id categories (count categories)])]))
@@ -11,8 +11,7 @@
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.topbar :as topbar]
[status-im.i18n.i18n :as i18n]
[status-im.communities.core :as communities]
[quo.components.animated.pressable :as animation]))
[status-im.communities.core :as communities]))
(defn hide-sheet-and-dispatch [event]
(>evt [:bottom-sheet/hide])
@@ -20,11 +19,11 @@
(defn request-actions [community-id request-id]
[react/view {:flex-direction :row}
[animation/pressable {:on-press #(re-frame/dispatch [:communities.ui/accept-request-to-join-pressed community-id request-id])}
[react/touchable-highlight {:on-press #(re-frame/dispatch [:communities.ui/accept-request-to-join-pressed community-id request-id])}
[icons/icon :main-icons/checkmark-circle {:width 35
:height 35
:color colors/green}]]
[animation/pressable {:on-press #(re-frame/dispatch [:communities.ui/decline-request-to-join-pressed community-id request-id])}
[react/touchable-highlight {:on-press #(re-frame/dispatch [:communities.ui/decline-request-to-join-pressed community-id request-id])}
[icons/icon :main-icons/cancel {:width 35
:height 35
:container-style {:margin-left 16}
@@ -42,8 +41,7 @@
:accessory (when can-manage-users?
[request-actions community-id id])
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo member)]
:on-press #(re-frame/dispatch [:chat.ui/show-profile public-key])}]))
(multiaccounts/displayed-photo member)]}]))
(defn requests-to-join []
(let [{:keys [community-id]} (<sub [:get-screen-params])]
@@ -25,7 +25,6 @@
(let [{:keys [community-id chat]} (<sub [:get-screen-params])]
(fn []
(let [categories (<sub [:communities/sorted-categories community-id])
chats (<sub [:chats/sorted-categories-by-community-id community-id])
comm-chat (<sub [:chats/community-chat-by-id community-id (:chat-id chat)])
_ (reset! selected-item (:categoryID comm-chat))]
[:<>
@@ -45,7 +44,7 @@
:create-community-category
{:community-id community-id}])
:title (i18n/label :t/create-category)}]
:data (conj categories {:name (i18n/label :t/none) :id ""})
:data (conj (vec (vals categories)) {:name (i18n/label :t/none) :id ""})
:render-fn render-fn}]]
[toolbar/toolbar
{:show-border? true
@@ -55,7 +54,6 @@
[::communities/change-category-confirmation-pressed
community-id
@selected-item
(assoc comm-chat :position
(count (get chats @selected-item)))] ;; Add as last item in new category
comm-chat]
3000)}
(i18n/label :t/done)]}]]))))
@@ -1,8 +1,34 @@
(ns status-im.ui.screens.communities.styles)
(ns status-im.ui.screens.communities.styles
(:require [quo.design-system.colors :as colors]))
(def category-item
{:flex 1
:flex-direction :row
:align-items :center
:height 52
:padding-left 18})
:margin-left 18})
(def reorder-categories-item
{:accessibility-label :reorder-categories-item
:flex-direction :row
:height 60
:align-items :center
:margin-left 18})
(defn reorder-categories-text []
{:font-size 17
:margin-left 10
:color (colors/get-color :text-01)
:flex 1})
(defn reorder-categories-button [margin-right]
{:accessibility-label :reorder-categories-button
:width 30
:height 30
:border-radius 15
:margin 10
:margin-right margin-right
:border-width 1
:justify-content :center
:align-items :center
:border-color colors/black})
@@ -3,12 +3,10 @@
(:require [status-im.ui.components.react :as react]
[status-im.i18n.i18n :as i18n]
[status-im.constants :as constants]
[status-im.utils.config :as config]
[quo.core :as quo]
[re-frame.core :as re-frame]))
(def titles {constants/two-mins (i18n/label :t/two-minutes)
constants/one-day (i18n/label :t/one-day)
(def titles {constants/one-day (i18n/label :t/one-day)
constants/three-days (i18n/label :t/three-days)
constants/one-week (i18n/label :t/one-week)
constants/one-month (i18n/label :t/one-month)})
@@ -23,8 +21,6 @@
(views/defview default-sync-period-settings []
(views/letsubs [{:keys [default-sync-period]} [:multiaccount]]
[react/view {:margin-top 8}
(when config/two-minutes-syncing?
[radio-item constants/two-mins default-sync-period])
[radio-item constants/one-day default-sync-period]
[radio-item constants/three-days default-sync-period]
[radio-item constants/one-week default-sync-period]
+26 -4
View File
@@ -3,6 +3,7 @@
[reagent.core :as reagent]
[status-im.i18n.i18n :as i18n]
[status-im.react-native.resources :as resources]
[status-im.communities.core :as communities]
[status-im.ui.components.connectivity.view :as connectivity]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.list.views :as list]
@@ -12,6 +13,7 @@
[status-im.ui.screens.home.views.inner-item :as inner-item]
[status-im.ui.screens.referrals.home-item :as referral-item]
[quo.design-system.colors :as colors]
[status-im.ui.screens.add-new.new-public-chat.view :as new-public-chat]
[quo.core :as quo]
[status-im.add-new.core :as new-chat]
[status-im.ui.components.search-input.view :as search-input]
@@ -39,10 +41,30 @@
: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]]])
[invite/button]
[react/view {:align-items :center :margin-bottom 16}
[react/view {:style (styles/hr-wrapper)}]
[react/i18n-text {:style (styles/or-text) :key :or}]]
[react/i18n-text {:style {:margin-horizontal 16
:text-align :center}
:key :follow-your-interests}]
[react/view {:flex-direction :row :flex-wrap :wrap :justify-content :center
:margin-top 10
:margin-bottom 18}
(for [chat (new-public-chat/featured-public-chats)]
^{:key chat}
[new-public-chat/render-topic chat])]
(when @(re-frame/subscribe [:communities/enabled?])
[:<>
[react/i18n-text {:style {:margin-horizontal 16
:text-align :center}
:key :join-a-community}]
[react/view {:flex-direction :row :flex-wrap :wrap :justify-content :center
:margin-top 10
:margin-bottom 18}
(for [{:keys [id] :as community} communities/featured]
^{:key id}
[communities.views/render-featured-community community])]])])
(defn welcome-blank-page []
[react/view {:style {:flex 1 :flex-direction :row :align-items :center :justify-content :center}}
@@ -149,16 +149,13 @@
:else
[icons/icon :main-icons/tiny-new-contact (icon-style)]))
(defn chat-item-title [chat-id muted group-chat chat-name edit?]
(defn chat-item-title [chat-id muted group-chat chat-name]
[quo/text {:weight :medium
:color (when muted :secondary)
:accessibility-label :chat-name-text
:ellipsize-mode :tail
:number-of-lines 1
:style {:position :absolute
:left 92
:top 10
:right (if edit? 50 90)}}
:style {:position :absolute :left 92 :top 10 :right 90}}
(if group-chat
(utils/truncate-str chat-name 30)
;; This looks a bit odd, but I would like only to subscribe
@@ -167,7 +164,7 @@
(first @(re-frame/subscribe [:contacts/contact-two-names-by-identity chat-id])))])
(defn home-list-item [home-item opts]
(let [{:keys [chat-id chat-name color group-chat public? timestamp last-message muted emoji highlight edit?]} home-item
(let [{:keys [chat-id chat-name color group-chat public? timestamp last-message muted emoji highlight]} home-item
background-color (when highlight (colors/get-color :interactive-02))]
[react/touchable-opacity (merge {:style {:height 64 :background-color background-color}} opts)
[:<>
@@ -181,15 +178,13 @@
:default-chat-icon-text (if (string/blank? emoji)
(chat-icon.styles/default-chat-icon-text 40)
(chat-icon.styles/emoji-chat-icon-text 40))}]
[chat-item-title chat-id muted group-chat chat-name edit?]
(when-not edit?
[:<>
[react/text {:style styles/datetime-text
:number-of-lines 1
:accessibility-label :last-message-time-text}
;;TODO (perf) move to event
(memo-timestamp (if (pos? (:whisper-timestamp last-message))
(:whisper-timestamp last-message)
timestamp))]
[unviewed-indicator home-item]])
[message-content-text (select-keys last-message [:content :content-type :community-id]) true]]]))
[chat-item-title chat-id muted group-chat chat-name]
[react/text {:style styles/datetime-text
:number-of-lines 1
:accessibility-label :last-message-time-text}
;;TODO (perf) move to event
(memo-timestamp (if (pos? (:whisper-timestamp last-message))
(:whisper-timestamp last-message)
timestamp))]
[message-content-text (select-keys last-message [:content :content-type :community-id]) true]
[unviewed-indicator home-item]]]))
+21 -43
View File
@@ -44,17 +44,6 @@
[status-im.ui.screens.currency-settings.views :as currency-settings]
[status-im.ui.screens.dapps-permissions.views :as dapps-permissions]
[status-im.ui.screens.default-sync-period-settings.view :as default-sync-period-settings]
[status-im.ui.screens.wallet.settings.views :as wallet-settings]
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions]
[status-im.ui.screens.wallet.custom-tokens.views :as custom-tokens]
[status-im.ui.screens.wallet.accounts.views :as wallet.accounts]
[status-im.ui.screens.wallet.collectibles.views :as wallet.collectibles]
[status-im.ui.screens.wallet.account.views :as wallet.account]
[status-im.ui.screens.wallet.add-new.views :as add-account]
[status-im.ui.screens.wallet.account-settings.views :as account-settings]
[status-im.ui.screens.wallet.swap.views :as wallet.swap]
[status-im.ui.screens.status.views :as status.views]
[status-im.ui.screens.profile.user.views :as profile.user]
[status-im.ui.screens.ens.views :as ens]
[status-im.ui.screens.fleet-settings.views :as fleet-settings]
[status-im.ui.screens.glossary.view :as glossary]
@@ -102,6 +91,7 @@
[status-im.ui.screens.profile.contact.views :as contact]
[status-im.ui.screens.profile.group-chat.views :as profile.group-chat]
[status-im.ui.screens.profile.seed.views :as profile.seed]
[status-im.ui.screens.profile.user.views :as profile.user]
[status-im.ui.screens.progress.views :as progress]
[status-im.ui.screens.qr-scanner.views :as qr-scanner]
[status-im.ui.screens.referrals.public-chat :as referrals.public-chat]
@@ -109,6 +99,7 @@
[status-im.ui.screens.reset-password.views :as reset-password]
[status-im.ui.screens.rpc-usage-info :as rpc-usage-info]
[status-im.ui.screens.status.new.views :as status.new]
[status-im.ui.screens.status.views :as status.views]
[status-im.ui.screens.stickers.views :as stickers]
[status-im.ui.screens.sync-settings.views :as sync-settings]
[status-im.ui.screens.terms-of-service.views :as terms-of-service]
@@ -116,10 +107,18 @@
:as
edit-wakuv2-node]
[status-im.ui.screens.wakuv2-settings.views :as wakuv2-settings]
[status-im.ui.screens.wallet.account-settings.views :as account-settings]
[status-im.ui.screens.wallet.account.views :as wallet.account]
[status-im.ui.screens.wallet.accounts-manage.views :as accounts-manage]
[status-im.ui.screens.wallet.accounts.views :as wallet.accounts]
[status-im.ui.screens.wallet.add-new.views :as add-account]
[status-im.ui.screens.wallet.buy-crypto.views :as wallet.buy-crypto]
[status-im.ui.screens.wallet.collectibles.views :as wallet.collectibles]
[status-im.ui.screens.wallet.custom-tokens.views :as custom-tokens]
[status-im.ui.screens.wallet.recipient.views :as recipient]
[status-im.ui.screens.wallet.send.views :as wallet.send]))
[status-im.ui.screens.wallet.send.views :as wallet.send]
[status-im.ui.screens.wallet.settings.views :as wallet-settings]
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions]))
(def components
[{:name :chat-toolbar
@@ -221,9 +220,9 @@
;Chat
{:name :chat
:options {:popGesture false
:topBar {:title {:component {:name :chat-toolbar :id :chat-toolbar}
:alignment :fill}
:rightButtons (right-button-options :chat :more)}}
:topBar {:title {:component {:name :chat-toolbar :id :chat-toolbar}
:alignment :fill}
:rightButtons (right-button-options :chat :more)}}
:right-handler chat/topbar-button
:component chat/chat}
@@ -289,6 +288,11 @@
;;TODO custom
:options {:topBar {:visible false}}
:component select-category/view}
{:name :community-edit-chats
;;TODO custom
:insets {:bottom true}
:options {:topBar {:visible false}}
:component community/community-edit}
{:name :community-reorder-categories
:insets {:top false}
:options {:topBar {:visible false}}
@@ -396,32 +400,6 @@
:options {:topBar {:title {:text (i18n/label :t/wallet-manage-accounts)}}}
:component accounts-manage/manage}
{:name :token-swap
;;TODO dynamic title
:options {:topBar {:visible false}}
:component wallet.swap/swap}
{:name :token-swap-advanced-nonce
:options {:topBar {:title {:text (i18n/label :t/nonce)}}}
:component wallet.swap/nonce-modal}
{:name :token-swap-advanced-approve-token
:options {:topBar {:title {:text (i18n/label :t/approve-token)}}}
:component wallet.swap/approve-token-modal}
{:name :token-swap-advanced-transaction-fee
:options {:topBar {:title {:text (i18n/label :t/transaction-fee)}}}
:component wallet.swap/transaction-fee-modal}
{:name :token-swap-advanced-swap-details
:options {:topBar {:title {:text (i18n/label :t/swap-details)}}}
:component wallet.swap/swap-details-modal}
{:name :swap-asset-selector
;;TODO dynamic title
:options {:topBar {:visible false}}
:component wallet.swap/asset-selector}
;;MY STATUS
{:name :status
@@ -730,8 +708,8 @@
:options {:topBar {:visible false}}
:component wallet.buy-crypto/website}
{:name :nft-details
:insets {:bottom true}
{:name :nft-details
:insets {:bottom true}
;;TODO dynamic title
:options {:topBar {:visible false}}
:component wallet.collectibles/nft-details-modal}
@@ -40,8 +40,6 @@
:chevron true
:accessory :text
:accessory-text (cond
(= default-sync-period constants/two-mins)
(i18n/label :t/two-minutes)
(= default-sync-period constants/one-day)
(i18n/label :t/one-day)
(= default-sync-period constants/three-days)
@@ -42,19 +42,3 @@
:duration 200
:easing (.-ease ^js animation/easing)
:useNativeDriver true}))
(def round-action-button
{:background-color colors/blue
:height 44
:flex 1
:justify-content :center
:align-items :center
:width 44
:border-radius 44})
(def top-actions
{:flex 1
:flex-direction :row
:justify-content :space-between
:width "60%"
:align-self :center})
@@ -7,17 +7,16 @@
[quo.design-system.colors :as colors]
[status-im.ui.components.icons.icons :as icons]
[quo.core :as quo]
[quo.design-system.spacing :as spacing]
[status-im.ui.components.react :as react]
[status-im.ui.components.topbar :as topbar]
[status-im.utils.config :as config]
[status-im.ui.screens.wallet.account.styles :as styles]
[status-im.ui.screens.wallet.accounts.sheets :as sheets]
[status-im.ui.screens.wallet.accounts.views :as accounts]
[status-im.ui.screens.wallet.buy-crypto.views :as buy-crypto]
[status-im.ui.screens.wallet.transactions.views :as history]
[status-im.ui.components.tabs :as tabs]
[status-im.ui.screens.wallet.collectibles.views :as collectibles.views]
[status-im.ui.screens.wallet.buy-crypto.views :as buy-crypto])
[status-im.ui.screens.wallet.collectibles.views :as collectibles.views])
(:require-macros [status-im.utils.views :as views]))
(def state (reagent/atom {:tab :assets}))
@@ -103,6 +102,7 @@
currency [:wallet/currency]
opensea-enabled? [:opensea-enabled?]
collectible-collection [:wallet/collectible-collection address]
mainnet? [:mainnet?]
ethereum-network? [:ethereum-network?]]
(let [{:keys [tab]} @state]
[react/view {:flex 1}
@@ -111,10 +111,11 @@
(when ethereum-network?
[tabs/tab-title state :nft (i18n/label :t/wallet-collectibles) (= tab :nft)])
[tabs/tab-title state :history (i18n/label :t/history) (= tab :history)]]
[quo/separator {:style {:margin-top -8}}]
(cond
(= tab :assets)
[:<>
(when mainnet?
[buy-crypto/banner])
(for [item tokens]
^{:key (:name item)}
[accounts/render-asset item nil nil (:code currency)])]
@@ -180,31 +181,10 @@
(styles/bottom-send-recv-buttons-lower anim-y button-group-height)
#(reset! to-show false))))))))
(defn round-action-button [{:keys [icon title on-press]}]
[react/view {:style {:flex 1
:align-items :center
:margin-vertical (:large spacing/spacing)}}
[react/touchable-opacity {:style styles/round-action-button
:on-press on-press}
(icons/icon icon {:color colors/white})]
[quo/text {:color :secondary
:size :small
:style {:margin-top (:tiny spacing/spacing)}}
title]])
(defn top-actions []
[react/view {:style styles/top-actions}
[round-action-button {:icon :main-icons/add
:title (i18n/label :t/buy-crypto)
:on-press #(re-frame/dispatch [:buy-crypto.ui/open-screen])}]
[round-action-button {:icon :main-icons/change
:title (i18n/label :t/swap)
:on-press #(re-frame/dispatch [:open-modal :token-swap])}]])
(views/defview account []
(views/letsubs [{:keys [name address] :as account} [:multiaccount/current-account]
fetching-error [:wallet/fetching-error]]
(let [anim-y (animation/create-value button-group-height)
(let [anim-y (animation/create-value button-group-height)
scroll-y (animation/create-value 0)]
(anim-listener anim-y scroll-y)
[:<>
@@ -226,9 +206,9 @@
@accounts/updates-counter
@(re-frame/subscribe [:wallet/refreshing-history?])))}
(when fetching-error
[react/view {:style {:flex 1
[react/view {:style {:flex 1
:align-items :center
:margin 8}}
:margin 8}}
[icons/icon
:main-icons/warning
{:color :red
@@ -253,8 +233,5 @@
[react/scroll-view {:horizontal true}
[react/view {:flex-direction :row :padding-top 8 :padding-bottom 12}
[account-card account]]]]
(if config/swap-enabled?
[top-actions]
[buy-crypto/banner])
[assets-and-collections address]]
[bottom-send-recv-buttons account anim-y]])))
@@ -1,433 +0,0 @@
(ns status-im.ui.screens.wallet.swap.views
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[re-frame.core :as re-frame]
[status-im.ethereum.tokens :as tokens]
[status-im.i18n.i18n :as i18n]
[status-im.ui.components.chat-icon.screen :as chat-icon]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.keyboard-avoid-presentation
:as
kb-presentation]
[status-im.ui.components.react :as react]
[status-im.ui.components.search-input.view :as search-input]
[status-im.ui.components.slider :as slider]
[status-im.wallet.swap.core :as wallet.swap]
[status-im.ui.components.toolbar :as toolbar]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.wallet.components.views :as wallet.components]
[status-im.utils.handlers :refer [<sub]]
[status-im.wallet.utils :as wallet.utils]
[clojure.string :as str]))
(defn render-asset [{{:keys
[icon decimals amount color value]
:as token} :token
currency :currency
on-press :on-press}]
[quo/list-item
{:title [quo/text {:weight :medium}
[quo/text {:weight :inherit}
(str (if amount
(wallet.utils/format-amount amount decimals)
"...")
" ")]
[quo/text {:color :secondary
:weight :inherit}
(wallet.utils/display-symbol token)]]
:on-press on-press
:subtitle (str (if value value "...") " " currency)
:accessibility-label
(str (:symbol token) "-asset-value")
:icon (if icon
[wallet.components/token-icon icon]
[chat-icon/custom-icon-view-list (:name token) color])}])
(defn asset-selector []
(let [{:keys [address]} (<sub [:multiaccount/current-account])
{:keys [tokens]} (<sub [:wallet/visible-assets-with-values address])
source? (<sub [:wallet/modal-selecting-source-token?])
currency (<sub [:wallet/currency])]
[:<>
[topbar/topbar
{:title (if source?
(i18n/label :t/select-token-to-swap)
(i18n/label :t/select-token-to-receive))
:modal? true}]
[search-input/search-input
{:search-active? true}]
[react/scroll-view
(for [token tokens]
^{:key (:name token)}
[render-asset {:token token
:on-press #(re-frame/dispatch
[(if source?
::wallet.swap/set-from-token
::wallet.swap/set-to-token)
(:symbol token)])
:currency (:code currency)}])]]))
(defn pill-button [{:keys [on-press label margin-left]}]
[react/touchable-opacity {:on-press on-press
:style {:background-color colors/blue-light
:padding-horizontal 12
:padding-vertical 2
:border-radius 24
:margin-left (or margin-left 8)}}
[quo/text {:color :link
:weight :medium} label]])
(defn token-display
"Show token and act as an anchor to open selector."
[{:keys [token source?]}]
(let [token-icon-source (-> token :icon :source)]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [::wallet.swap/open-asset-selector-modal source?])}
[react/view {:style {:flex-direction :row
:align-items :center
:border-width 1
:border-color colors/gray-lighter
:border-radius 8
:margin-left 16
:padding-horizontal 8
:padding-vertical 2}
:accessibility-label
:choose-asset-button}
[quo/text {:style {:margin-right 8}}
(-> token :symbol name)]
[react/image {:source (if (fn? token-icon-source)
(token-icon-source)
token-icon-source)}]]]))
(defn token-input
"Component to get the amount and type of tokens"
[{:keys [amount error label token max-from source?]}]
(let [window-width (<sub [:dimensions/window-width])]
[react/view {:style {:justify-content :space-between
:flex-direction :row
:align-items :center}}
[react/view {:flex 2}
[react/view {:flex-direction :row
:align-items :center}
[quo/text label]
(when max-from [pill-button {:on-press #()
:label "Max 0.043"}])]
[react/text-input
{:style {:font-size 38
:max-width (- (* (/ window-width 4) 3) 106)
:color (if error colors/red colors/black)}
:keyboard-type :decimal-pad
:auto-capitalize :words
:accessibility-label :amount-input
:default-value amount
:editable true
:auto-focus true
:on-change-text #(re-frame/dispatch [(when source?
::wallet.swap/set-from-token-amount)
%])
:placeholder "0.0"}]]
[token-display {:token token
:source? source?}]]))
(defn separator-with-icon []
[react/view
{:margin-vertical 8}
[quo/separator]
[react/touchable-opacity
{:on-press #(re-frame/dispatch [::wallet.swap/switch-from-token-with-to])}
[react/view {:style {:background-color colors/gray-lighter
:width 40
:height 40
:border-radius 40
:border-width 4
:border-color colors/white
:margin-top -20
:margin-bottom -20
:align-self :center
:align-items :center
:justify-content :center}}
[react/image {:source (icons/icon-source :main-icons/change)
:style {:tint-color colors/gray
:transform [{:rotate "90deg"}]}}]]]])
(defn floating-card [{:keys [icon title body on-press]}]
[react/view {:style {:border-width 1
:padding 2 ;; need a padding because border breaks otherwise
:border-radius 12
:margin-top 12
:border-color colors/gray-lighter}}
[quo/list-item {:title title
:subtitle body
:active-background-enabled
false
:on-press on-press
:theme :main
:chevron true
:icon [react/view {:style {:background-color colors/blue-light
:padding 8
:border-radius 4}}
(icons/icon icon {:color :dark})]}]])
(defn card-body-row [key value primary?]
[react/view {:flex-direction :row}
[quo/text {:color (when-not primary? :secondary)} key]
[quo/text {:style {:margin-right 4}
:color (when-not primary? :secondary)} ":"]
[quo/text {:ellipsize-mode :middle
:number-of-lines 1
:style {:width "50%"}
:color (when-not primary? :secondary)
:weight :semi-bold} value]])
(defn transaction-fee-card [{:keys [gas-amount price-limit tip-limit gas-in-eth gas-in-usd]}]
[floating-card {:title (i18n/label :t/transaction-fee)
:icon :main-icons/gas
:on-press #(re-frame/dispatch [:open-modal :token-swap-advanced-transaction-fee])
:body [react/view
[card-body-row (i18n/label :t/gas-amount-limit) gas-amount]
[card-body-row (i18n/label :t/per-gas-price-limit) price-limit]
[card-body-row (i18n/label :t/per-gas-tip-limit) tip-limit]
[card-body-row (i18n/label :t/total-gas)
(str gas-in-eth " • $" gas-in-usd)
true]]}])
(defn swap-details-card [{:keys [slippage price-impact]}]
[floating-card {:title (i18n/label :t/swap-details)
:icon :main-icons/change
:on-press #(re-frame/dispatch [:open-modal :token-swap-advanced-swap-details])
:body [react/view
[card-body-row (i18n/label :t/slippage) (str slippage " %")]
[card-body-row (i18n/label :t/price-impact) (str price-impact " %")]]}])
(defn nonce-card [{:keys [nonce]}]
[floating-card {:title (i18n/label :t/nonce)
:icon :main-icons/channel
:on-press #(re-frame/dispatch [:open-modal :token-swap-advanced-nonce])
:body [react/view
[card-body-row (i18n/label :t/nonce) nonce]]}])
(defn approve-token-card [{:keys [token contract-address approve-limit]}]
[floating-card {:title (i18n/label :t/approve)
:icon :main-icons/check
:on-press #(re-frame/dispatch [:open-modal :token-swap-advanced-approve-token])
:body [react/view
[card-body-row (i18n/label :t/token) token]
[card-body-row (i18n/label :t/contract-address) contract-address]
[card-body-row (i18n/label :t/approve-limit) approve-limit]]}])
(defn advanced-input [{:keys [label label-help value on-change after]}]
[react/view {:style {:padding-horizontal 16
:margin-bottom 16}}
[react/view {:style {:flex-direction :row
:justify-content :space-between}}
[quo/text {} label]
label-help]
[quo/text-input {:default-value (str value)
:show-cancel false
:style {:margin-top 12
:border-radius 8}
:after {:component after}
:on-change-text on-change}]])
(defn help-label-kv [{:keys [key value]}]
[react/view {:style {:flex-direction :row}}
[quo/text {:color :secondary} key]
[quo/text {:color :secondary
:style {:margin-right 4}} ":"]
[quo/text {:color :secondary} value]])
(defn nonce-modal []
(let [last-txn-nonce 22
nonce 23]
[kb-presentation/keyboard-avoiding-view {:style {:flex 1
:margin-top 16}
:ignore-offset true}
[advanced-input {:label (i18n/label :t/nonce)
:label-help [help-label-kv {:key (i18n/label :t/last-transaction)
:value last-txn-nonce}]
:value nonce
:on-change #()
:on-save #()}]
[toolbar/toolbar
{:show-border? true
:left [quo/button {:type :secondary}
(i18n/label :t/cancel)]
:right [quo/button {:theme :accent}
(i18n/label :t/save)]}]]))
(defn approve-token-modal []
[quo/text "modal"])
(defn transaction-fee-modal []
(let [gas-amount-limit 21000
gas-amount 21000
per-gas-price-limit 7.3
current-avg-per-gas-price-limit 7.3
per-gas-tip-limit 150
current-avg-per-gas-tip-limit 150]
[kb-presentation/keyboard-avoiding-view {:style {:flex 1
:margin-top 16}
:ignore-offset true}
[react/view {:flex 1}
[advanced-input {:label (i18n/label :t/gas-amount-limit)
:label-help [help-label-kv {:key (i18n/label :t/limit)
:value gas-amount-limit}]
:value gas-amount
:after [quo/text {:color :secondary} (i18n/label :t/gwei)]
:on-change #()
:on-save #()}]
[advanced-input {:label (i18n/label :t/per-gas-price-limit)
:label-help [help-label-kv {:key (i18n/label :t/current-average)
:value current-avg-per-gas-price-limit}]
:value per-gas-price-limit
:after [quo/text {:color :secondary} (i18n/label :t/gwei)]
:on-change #()
:on-save #()}]
[advanced-input {:label (i18n/label :t/per-gas-price-limit)
:label-help [help-label-kv {:key (i18n/label :t/current-average)
:value current-avg-per-gas-tip-limit}]
:value per-gas-tip-limit
:after [quo/text {:color :secondary} (i18n/label :t/gwei)]
:on-change #()
:on-save #()}]
[quo/list-item {:title (i18n/label :t/maximum-fee)
:text-size :base
:title-text-weight :regular
:accessory :text
:accessory-text [quo/text "0.3 ETH"]
:container-style {:margin-top 16}}]
[quo/text {:color :secondary
:style {:padding-horizontal 16}}
(i18n/label :t/maximum-fee-desc)]]
[toolbar/toolbar
{:show-border? true
:left [quo/button {:type :secondary}
(i18n/label :t/cancel)]
:right [quo/button {:theme :accent}
(i18n/label :t/save)]}]]))
(defn swap-details-modal []
(let [slippage-limit 20
slippage 0.5
price-impact 4]
[kb-presentation/keyboard-avoiding-view {:style {:flex 1
:margin-top 16}
:ignore-offset true}
[react/view {:flex 1}
[advanced-input {:label (str (i18n/label :t/slippage) " %")
:label-help [help-label-kv {:key (i18n/label :t/limit)
:value (str slippage-limit "%")}]
:value slippage
:on-change #()
:on-save #()}]
[quo/list-item {:title (i18n/label :t/price-impact)
:text-size :base
:title-text-weight :regular
:accessory :text
:accessory-text (str price-impact "%")
:container-style {:margin-top 16}}]
[quo/text {:color :secondary
:style {:padding-horizontal 16}}
(i18n/label :t/price-impact-desc)]]
[toolbar/toolbar
{:show-border? true
:left [quo/button {:type :secondary}
(i18n/label :t/cancel)]
:right [quo/button {:theme :accent}
(i18n/label :t/save)]}]]))
(defn advanced-settings []
[react/view {:style {:flex 1
:padding-horizontal 16}}
[react/view {:align-self :flex-start}
[pill-button {:label (i18n/label :t/switch-to-simple-interface)
:margin-left 0
:on-press #(re-frame/dispatch [::wallet.swap/set-advanced-mode false])}]]
[transaction-fee-card {:gas-amount 21000
:price-limit 74
:tip-limit 21
:gas-in-eth 0.0031
:gas-in-usd 34.28}]
[swap-details-card {:slippage 0.5
:price-impact 4}]
[approve-token-card {:token "USDC"
:contract-address "0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2"
:approve-limit "unlimited"}]
[nonce-card {:nonce 22}]])
(defn swap []
(let [{:keys [name]}
(<sub [:multiaccount/current-account])
all-tokens (<sub [:wallet/all-tokens])
from-symbol (<sub [:wallet/swap-from-token])
to-symbol (<sub [:wallet/swap-to-token])
advanced-mode? (<sub [:wallet/swap-advanced-mode?])
amount "0.02"
from-token (tokens/symbol->token all-tokens (or from-symbol :DGX))
to-token (tokens/symbol->token all-tokens (or to-symbol :SNT))]
[kb-presentation/keyboard-avoiding-view {:style (merge
{:flex 1})
:ignore-offset true}
[topbar/topbar
{:title name
:subtitle (str/upper-case (i18n/label :t/powered-by-paraswap))
:modal? true}]
[react/view (merge {:padding-horizontal 16
:margin-vertical 32}
(when-not advanced-mode?
{:flex 1}))
[token-input {:amount amount
:error nil
:label (i18n/label :t/amount)
:token from-token
:source? true
:max-from 67.28}]
[separator-with-icon]
[token-input {:amount "0.01"
:error nil
:label (i18n/label :t/minimum-received)
:source? false
:token to-token}]]
(when-not advanced-mode?
[react/view {:style {:flex-direction :row
:justify-content :space-between
:padding-horizontal 16
:align-items :center}}
[react/view {:style {:flex-direction :row}}
[quo/text {} (i18n/label :t/priority)]
[pill-button {:label (i18n/label :t/advanced)
:on-press #(re-frame/dispatch [::wallet.swap/set-advanced-mode true])}]]
[quo/text {:color :secondary} "0.0034 ETH/ $ 8.09"]])
(comment
(re-frame/dispatch [::wallet.swap/set-advanced-mode false]))
(when-not advanced-mode?
[react/view {:style {:padding-horizontal 16}}
[slider/animated-slider
{:minimum-value 0
:maximum-value 100
:style {:margin-vertical 8}}]])
(when advanced-mode?
[quo/text "here"]
[advanced-settings])
[toolbar/toolbar
{:show-border? true
:right [quo/button {:theme :accent}
(i18n/label :t/swap)]}]]))
-2
View File
@@ -52,8 +52,6 @@
(def delete-message-enabled? (enabled? (get-config :DELETE_MESSAGE_ENABLED "0")))
(def collectibles-enabled? (enabled? (get-config :COLLECTIBLES_ENABLED "1")))
(def test-stateofus? (enabled? (get-config :TEST_STATEOFUS "0")))
(def two-minutes-syncing? (enabled? (get-config :TWO_MINUTES_SYNCING "0")))
(def swap-enabled? (enabled? (get-config :SWAP_ENABLED "0")))
;; CONFIG VALUES
(def log-level
-51
View File
@@ -1,51 +0,0 @@
(ns status-im.wallet.swap.core
(:require [status-im.utils.fx :as fx]
[re-frame.db :as re-frame.db]
[status-im.navigation :as navigation]))
(fx/defn open-asset-selector-modal
"source? true signinfies we are selecting the source asset. false implies selection of sink asset"
{:events [::open-asset-selector-modal]}
[{:keys [db]} source?]
(fx/merge {:db (assoc db :wallet/modal-selecting-source-token? source?)}
(navigation/open-modal :swap-asset-selector {})))
(fx/defn set-from-token
{:events [::set-from-token]}
[{:keys [db]} from-symbol]
(fx/merge {:db (assoc db :wallet/swap-from-token from-symbol)}
(navigation/navigate-back)))
(fx/defn set-to-token
{:events [::set-to-token]}
[{:keys [db]} to-symbol]
(fx/merge {:db (assoc db :wallet/swap-to-token to-symbol)}
(navigation/navigate-back)))
(fx/defn set-from-token-amount
[{:keys [db]} from-amount]
{:db (assoc db :wallet/swap-from-token-amount from-amount)})
(fx/defn set-max-from-token-amount
[{:keys [db]} _]
{:db (assoc db :wallet/swap-from-token-amount 0)})
(fx/defn switch-from-token-with-to
{:events [::switch-from-token-with-to]}
[{:keys [db]}]
{:db (assoc db
:wallet/swap-from-token (:wallet/swap-to-token db)
:wallet/swap-to-token (:wallet/swap-from-token db))})
(fx/defn set-advanced-mode
{:events [::set-advanced-mode]}
[{:keys [db]} mode]
{:db (assoc db :wallet/swap-advanced-mode? mode)})
(comment
(->> re-frame.db/app-db
deref
:wallet/all-tokens
vals
(map #(str (:name %) "-" (:symbol %)))))
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "feat/node-config",
"commit-sha1": "3daf1ea073fe1aa636a9d301a8e2a04acd7adbca",
"src-sha256": "1vc70av6jvsch12hyr32hsnh5yqsaavmhy32d20zx3nfb3kxgv12"
"version": "v0.92.5",
"commit-sha1": "64589fbd1f81022c7f995a7d993f0c026ecc6923",
"src-sha256": "0d4zh9kmgi0vwgn1wsbjfnp7hiv2m0l1472wkjg23snskz2g5g14"
}
+3 -3
View File
@@ -42,11 +42,11 @@ rlp==1.2.0
sauceclient==1.0.0
scrypt==0.8.17
selenium==3.14.1
six==1.11.0
six==1.10.0
urllib3==1.26.3
yarl==1.6.3
zbarlight==3.0
docker==4.4.0
influxdb==5.3.1
web3==5.25.0
imagehash
web3
imagehash
+2 -2
View File
@@ -12,14 +12,14 @@ RERUN_ERRORS = [
'failed to start the browser or device',
'ERROR The test with session id',
"503 Service Unavailable",
"object has no attribute",
# "object has no attribute",
"[Errno 104] Connection reset by peer",
"Sauce could not start your job",
"HTTP Error 303",
"http.client.RemoteDisconnected: Remote end closed connection without response",
"[Errno 110] Connection timed out",
"replacement transaction underpriced",
"StaleElementReferenceException",
# "StaleElementReferenceException",
"'GetStartedButton' is not found on the screen",
"'AccessKeyButton' is not found on the screen",
"'SignInPhraseText' is not found on the screen"
+3 -4
View File
@@ -97,11 +97,10 @@ class TestrailReport(BaseTestReport):
def get_regression_cases(self):
test_cases = dict()
test_cases['critical'] = 730
test_cases['critical'] = 734
test_cases['high'] = 735
test_cases['medium'] = 736
test_cases['upgrade'] = 881
test_cases['public_chat'] = 50654
test_cases['one_to_one_chat'] = 50655
case_ids = list()
for arg in argv:
if "run_testrail_ids" in arg:
@@ -109,7 +108,7 @@ class TestrailReport(BaseTestReport):
case_ids = value.split(',')
if len(case_ids) == 0:
if 'critical or high' in argv:
for case in self.get_cases([test_cases['critical'], test_cases['public_chat'], test_cases['one_to_one_chat']]):
for case in self.get_cases([test_cases['critical'], test_cases['high']]):
case_ids.append(case['id'])
elif 'upgrade' in argv and 'not upgrade' not in argv:
for case in self.get_cases([test_cases['upgrade']]):
@@ -96,7 +96,7 @@ class TestCreateAccount(SingleDeviceTestCase):
sign_in.get_started_button.click()
if sign_in.generate_key_button.is_element_displayed():
self.errors.append("Agree with ToS is not mandatory to proceed onboarding!")
sign_in.accept_tos_checkbox.enable()
sign_in.accept_tos_checkbox.click()
sign_in.get_started_button.click_until_presence_of_element(sign_in.generate_key_button)
sign_in.generate_key_button.click()
from views.sign_in_view import MultiAccountButton
@@ -141,7 +141,7 @@ class TestCreateAccount(SingleDeviceTestCase):
@marks.high
def test_pass_phrase_validation(self):
sign_in = SignInView(self.driver)
sign_in.accept_tos_checkbox.enable()
sign_in.accept_tos_checkbox.click()
sign_in.get_started_button.click_until_presence_of_element(sign_in.access_key_button)
sign_in.access_key_button.click()
validations = [
@@ -219,7 +219,7 @@ class TestCreateAccount(SingleDeviceTestCase):
@marks.medium
def test_create_account_short_and_mismatch_password(self):
sign_in = SignInView(self.driver)
sign_in.accept_tos_checkbox.enable()
sign_in.accept_tos_checkbox.click()
sign_in.get_started_button.click()
sign_in.generate_key_button.click()
sign_in.next_button.click()
@@ -179,7 +179,7 @@ class TestCreateAccount(SingleDeviceTestCase):
sign_in = SignInView(self.driver)
sign_in.just_fyi('Cancel on PIN code setup stage')
sign_in.accept_tos_checkbox.enable()
sign_in.accept_tos_checkbox.click()
sign_in.get_started_button.click()
sign_in.generate_key_button.click()
username = sign_in.first_username_on_choose_chat_name.text
@@ -232,7 +232,7 @@ class TestCreateAccount(SingleDeviceTestCase):
@marks.flaky
def test_keycard_interruption_access_key_onboarding_flow(self):
sign_in = SignInView(self.driver)
sign_in.accept_tos_checkbox.enable()
sign_in.accept_tos_checkbox.click()
sign_in.get_started_button.click()
sign_in.access_key_button.click()
@@ -277,7 +277,7 @@ class TestCreateAccount(SingleDeviceTestCase):
recovered_user = transaction_senders['A']
sign_in.just_fyi('Recover multiaccount')
sign_in.accept_tos_checkbox.enable()
sign_in.accept_tos_checkbox.click()
sign_in.get_started_button.click_until_presence_of_element(sign_in.access_key_button)
sign_in.access_key_button.click()
sign_in.recover_with_keycard_button.click()
@@ -324,7 +324,7 @@ class TestCreateAccount(SingleDeviceTestCase):
sign_in.toggle_airplane_mode()
sign_in.just_fyi('Recover multiaccount offline')
sign_in.accept_tos_checkbox.enable()
sign_in.accept_tos_checkbox.click()
sign_in.get_started_button.click_until_presence_of_element(sign_in.access_key_button)
sign_in.access_key_button.click()
sign_in.recover_with_keycard_button.click()
@@ -673,7 +673,7 @@ class TestKeycardCreateMultiaccountMultipleDevice(MultipleDeviceTestCase):
device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
device_1.just_fyi("Create keycard account and save seed phrase")
device_1.accept_tos_checkbox.enable()
device_1.accept_tos_checkbox.click()
device_1.get_started_button.click()
device_1.generate_key_button.click_until_presence_of_element(device_1.next_button)
device_1.next_button.click_until_absense_of_element(device_1.element_by_translation_id("intro-wizard-title2"))
@@ -1219,7 +1219,7 @@ class TestProfileMultipleDevice(MultipleDeviceTestCase):
@marks.testrail_id(695856)
@marks.medium
#@marks.flaky
@marks.flaky
def test_pair_devices_sync_photo_community_group_chats(self):
self.create_drivers(2)
device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
@@ -1296,12 +1296,12 @@ class TestProfileMultipleDevice(MultipleDeviceTestCase):
[home.home_button.double_click() for home in (home_1, home_2)]
home_1.get_chat(comm_before_sync_name, community=True).click()
comm_before_1.leave_community()
if not home_2.element_by_text_part(comm_before_sync_name).is_element_disappeared(30):
if not home_2.get_chat(comm_before_sync_name).is_element_disappeared(30):
self.errors.append("Leaving community was not synced!")
device_1.just_fyi("Adding new community and check it will be synced")
home_1.create_community(comm_after_sync_name)
if not home_2.element_by_text(comm_after_sync_name).is_element_displayed(30):
if not home_2.get_chat(comm_after_sync_name, community=True).is_element_displayed(30):
self.errors.append('Added community was not appeared after initial sync')
# TODO: skip until #11558 (rechecked 23.11.21, valid)
@@ -168,10 +168,7 @@ class TestWalletManagement(SingleDeviceTestCase):
self.errors.append('%s asset is not shown in wallet after relogin' % asset)
sign_in.just_fyi("Deselecting asset")
wallet.multiaccount_more_options.click()
wallet.manage_assets_button.click()
wallet.asset_checkbox_by_name(asset).click()
wallet.cross_icon.click()
wallet.select_asset(asset)
if wallet.asset_by_name(asset).is_element_displayed():
self.errors.append('%s asset is shown in wallet but was deselected' % asset)
self.errors.verify_no_errors()
@@ -696,6 +696,7 @@ class TestChatManagementMultipleDevice(MultipleDeviceTestCase):
if public_chat_after_block_1.chat_element_by_text(message_after_block_2).is_element_displayed():
self.errors.append("Message from blocked user '%s' is received" % device_2.driver.number)
public_chat_after_block_1.get_back_to_home_view()
if home_1.notifications_unread_badge.is_element_displayed():
device_1.driver.fail("Unread badge is shown after receiving new message from blocked user")
if blocked_chat_user.is_element_displayed():
@@ -717,7 +718,6 @@ class TestChatManagementMultipleDevice(MultipleDeviceTestCase):
device_1.click_system_home_button()
self.drivers[0].launch_app()
device_1.sign_in()
public_chat_after_block_1.home_button.double_click()
if home_1.notifications_unread_badge.is_element_displayed():
device_1.driver.fail("Unread badge is shown after after fetching new messages from offline")
if blocked_chat_user.is_element_displayed():
@@ -45,7 +45,7 @@ class TestCommandsMultipleDevices(MultipleDeviceTestCase):
chat_2 = home_2.get_chat(sender['username']).click()
receiver_message = chat_2.get_incoming_transaction(account_name)
timestamp_sender = sender_message.timestamp_command_message.text
timestamp_sender = sender_message.timestamp_message.text
if not receiver_message.is_element_displayed():
self.drivers[0].fail('No message about incoming transaction in 1-1 chat is shown for receiver')
receiver_message.transaction_status.wait_for_element_text(receiver_message.address_requested)
@@ -68,7 +68,7 @@ class TestCommandsMultipleDevices(MultipleDeviceTestCase):
send_bottom_sheet = sender_message.sign_and_send.click()
send_bottom_sheet.next_button.click()
send_bottom_sheet.sign_transaction()
updated_timestamp_sender = sender_message.timestamp_command_message.text
updated_timestamp_sender = sender_message.timestamp_message.text
if updated_timestamp_sender == timestamp_sender:
self.errors.append("Timestamp of message is not updated after signing transaction")
chat_1.wallet_button.click()
@@ -40,7 +40,7 @@ class TestCommandsMultipleDevices(MultipleDeviceTestCase):
chat_2 = home_2.get_chat(sender['username']).click()
receiver_message = chat_2.get_incoming_transaction()
timestamp_sender = sender_message.timestamp_command_message.text
timestamp_sender = sender_message.timestamp_message.text
if not receiver_message.is_element_displayed():
self.drivers[0].fail('No message about incoming transaction in 1-1 chat is shown for receiver')
receiver_message.transaction_status.wait_for_element_text(receiver_message.address_requested)
@@ -63,7 +63,7 @@ class TestCommandsMultipleDevices(MultipleDeviceTestCase):
send_message = sender_message.sign_and_send.click()
send_message.next_button.click()
send_message.sign_transaction(keycard=True)
updated_timestamp_sender = sender_message.timestamp_command_message.text
updated_timestamp_sender = sender_message.timestamp_message.text
if updated_timestamp_sender == timestamp_sender:
self.errors.append("Timestamp of message is not updated after signing transaction")
@@ -109,7 +109,8 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
home_1.just_fyi('go back online and check that 1-1 chat will be fetched')
home_1.toggle_airplane_mode()
chat_element = home_1.get_chat(username_2, wait_time=60)
chat_element = home_1.get_chat(username_2)
chat_element.wait_for_visibility_of_element(30)
chat_1 = chat_element.click()
chat_1.chat_element_by_text(message_1).wait_for_visibility_of_element(2)
@@ -161,14 +162,13 @@ class TestMessagesOneToOneChatMultiple(MultipleDeviceTestCase):
if device_2_chat.user_name_text.text != default_username_1:
self.errors.append("Default username '%s' is not shown in one-to-one chat" % default_username_1)
# TODO: disabled until https://github.com/status-im/status-react/issues/12936 fix
# profile_1.just_fyi("Check timestamps for sender and receiver")
# for chat in device_1_chat, device_2_chat:
# chat.verify_message_is_under_today_text(timestamp_message, self.errors)
# timestamp = chat.chat_element_by_text(timestamp_message).timestamp_message.text
# if timestamp not in sent_time_variants:
# self.errors.append(
# "Timestamp is not shown, expected '%s', in fact '%s'" % (sent_time_variants.join(","), timestamp))
profile_1.just_fyi("Check timestamps for sender and receiver")
for chat in device_1_chat, device_2_chat:
chat.verify_message_is_under_today_text(timestamp_message, self.errors)
timestamp = chat.chat_element_by_text(timestamp_message).timestamp_message.text
if timestamp not in sent_time_variants:
self.errors.append(
"Timestamp is not shown, expected '%s', in fact '%s'" % (sent_time_variants.join(","), timestamp))
device_2_home.just_fyi("Add user to contact and verify his default username")
device_2_chat.add_to_contacts.click()
@@ -883,7 +883,7 @@ class TestMessagesOneToOneChatSingle(SingleDeviceTestCase):
chat.send_message_button.click()
message_bubble = chat.chat_element_by_text(formatted_message[message])
message_bubble.sent_status_checkmark.long_press_element()
message_bubble.timestamp_message.long_press_element()
chat.element_by_text('Copy').click()
message_input.paste_text_from_clipboard()
@@ -964,10 +964,13 @@ class TestMessagesOneToOneChatSingle(SingleDeviceTestCase):
self.errors.append('"%s" is not show in chat preview on home screen!' % message)
home.get_chat('@%s' % ens).click()
home.just_fyi('Check redirect to user profile on mention by ENS tap')
chat.chat_element_by_text(message).click()
if not chat.profile_block_contact.is_element_displayed():
self.errors.append('No redirect to user profile after tapping on message with mention (ENS) in 1-1 chat')
home.just_fyi('Set nickname and mention user by nickname in 1-1 chat')
russian_nickname = 'МОЙ дорогой ДРУх'
chat.chat_options.click()
chat.view_profile_button.click()
chat.set_nickname(russian_nickname)
chat.select_mention_from_suggestion_list(russian_nickname + ' @' + ens)
+108 -66
View File
@@ -9,6 +9,7 @@ from dateutil import parser
from tests import marks
from tests.base_test_case import MultipleDeviceTestCase, SingleDeviceTestCase, create_shared_drivers, \
MultipleSharedDeviceTestCase
from views.home_view import HomeView
from views.sign_in_view import SignInView
@@ -19,102 +20,104 @@ class TestPublicChatMultipleDeviceMerged(MultipleSharedDeviceTestCase):
def setup_class(cls):
cls.drivers, cls.loop = create_shared_drivers(2)
device_1, device_2 = SignInView(cls.drivers[0]), SignInView(cls.drivers[1])
cls.home_1, cls.home_2 = device_1.create_user(), device_2.create_user()
profile_1 = cls.home_1.profile_button.click()
home_1, home_2 = device_1.create_user(), device_2.create_user()
profile_1 = home_1.profile_button.click()
cls.username_1 = profile_1.default_username_text.text
profile_1.home_button.click()
cls.home_2.home_button.click()
cls.public_chat_name = cls.home_1.get_random_chat_name()
cls.chat_1, cls.chat_2 = cls.home_1.join_public_chat(cls.public_chat_name), cls.home_2.join_public_chat(cls.public_chat_name)
home_2.home_button.click()
@marks.testrail_id(5313)
@marks.critical
def test_public_chat_text_timestamps_while_on_different_tab(self):
message = 'hello'
self.chat_2.dapp_tab_button.click()
self.chat_1.send_message(message)
sent_time_variants = self.chat_1.convert_device_time_to_chat_timestamp()
timestamp = self.chat_1.chat_element_by_text(message).timestamp_on_tap
if timestamp not in sent_time_variants:
self.errors.append("Timestamp is not shown, expected: '%s', in fact: '%s'" % (sent_time_variants.join(','), timestamp))
self.chat_2.home_button.click(desired_view='chat')
for chat in self.chat_1, self.chat_2:
chat.verify_message_is_under_today_text(message, self.errors)
if self.chat_2.chat_element_by_text(message).username.text != self.username_1:
self.errors.append("Default username '%s' is not shown next to the received message" % self.username_1)
self.errors.verify_no_errors()
def test_public_chat_messaging_emojis_timestamps(self):
home_1, home_2 = HomeView(self.drivers[0]), HomeView(self.drivers[1])
home_1.just_fyi("Check preselected chats, redirect to status chat")
home_1.plus_button.click_until_presence_of_element(home_1.join_public_chat_button)
home_1.join_public_chat_button.click()
preselected_chats = ['#status', '#chitchat', '#defi', '#crypto', '#markets', '#dap-ps']
for chat in preselected_chats:
if not home_1.element_by_text(chat).is_element_displayed():
self.errors.append("'%s' text is not in the list of preselected chats" % chat)
home_1.element_by_text(preselected_chats[0]).click()
status_chat = home_1.get_chat_view()
if not status_chat.user_name_text != preselected_chats[0]:
self.errors.append('No redirect to chat if tap on #status chat')
status_chat.home_button.click()
@marks.testrail_id(700719)
@marks.critical
def test_public_emoji(self):
public_chat_name = home_1.get_random_chat_name()
chat_1, chat_2 = home_1.join_public_chat(public_chat_name), home_2.join_public_chat(public_chat_name)
home_1.just_fyi("Check sending text messages, emojis, usernames and timestamps on messages")
emoji_name = random.choice(list(emoji.EMOJI_UNICODE))
emoji_unicode = emoji.EMOJI_UNICODE[emoji_name]
emoji_message = emoji.emojize(emoji_name)
self.chat_1.send_message(emoji_message)
for chat in self.chat_1, self.chat_2:
if not chat.chat_element_by_text(emoji_unicode).is_element_displayed(30):
message, emoji_message = 'hello', emoji.emojize(emoji_name)
chat_1.send_message(message)
sent_time_variants = chat_1.convert_device_time_to_chat_timestamp()
for chat in chat_1, chat_2:
chat.verify_message_is_under_today_text(message, self.errors)
timestamp = chat.chat_element_by_text(message).timestamp_message.text
if timestamp not in sent_time_variants:
self.errors.append(
"Timestamp is not shown, expected '%s', in fact '%s'" % (sent_time_variants.join(','), timestamp))
if chat_2.chat_element_by_text(message).username.text != self.username_1:
self.errors.append("Default username '%s' is not shown next to the received message" % self.username_1)
chat_1.send_message(emoji_message)
for chat in chat_1, chat_2:
if not chat.chat_element_by_text(emoji_unicode).is_element_displayed():
self.errors.append('Message with emoji was not sent or received in public chat')
self.chat_1.just_fyi("Can copy and paste emojis")
self.chat_1.element_by_text_part(emoji_unicode).long_press_element()
self.chat_1.element_by_text('Copy').click()
self.chat_1.chat_message_input.paste_text_from_clipboard()
if self.chat_1.chat_message_input.text != emoji_unicode:
self.errors.append('Emoji message was not copied')
self.chat_1.just_fyi("Can reply to emojis")
self.chat_2.quote_message(emoji_unicode)
message_text = 'test message'
self.chat_2.chat_message_input.send_keys(message_text)
self.chat_2.send_message_button.click()
chat_element_1 = self.chat_1.chat_element_by_text(message_text)
if not chat_element_1.is_element_displayed(sec=10) or chat_element_1.replied_message_text != emoji_unicode:
self.errors.append('Reply message was not received by the sender')
self.errors.verify_no_errors()
@marks.testrail_id(5360)
@marks.critical
def test_public_unread_messages_counter(self):
self.chat_1.send_message('пиу')
home_1 = self.chat_1.home_button.click()
message = 'test message'
self.chat_2.send_message(message)
if not self.chat_1.home_button.public_unread_messages.is_element_displayed():
def test_unread_messages_counter_public_chat(self):
home_1, home_2 = HomeView(self.drivers[0]), HomeView(self.drivers[1])
home_1.get_back_to_home_view()
home_2.get_back_to_home_view()
home_1.home_button.click()
home_2.home_button.click()
chat_name = home_1.get_random_chat_name()
chat_1, chat_2 = home_1.join_public_chat(chat_name), home_2.join_public_chat(chat_name)
chat_1.send_message('пиу')
chat_1.home_button.click()
message, message_2 = 'test message', 'test message2'
chat_2.send_message(message)
home_1.just_fyi(
"Check unread message indicator on home, on chat element and that it is not shown after reading messages")
if not home_1.home_button.public_unread_messages.is_element_displayed():
self.errors.append('New messages public chat badge is not shown on Home button')
chat_element = home_1.get_chat('#' + self.public_chat_name)
chat_element = home_1.get_chat('#' + chat_name)
if not chat_element.new_messages_public_chat.is_element_displayed():
self.errors.append('New messages counter is not shown in public chat')
self.errors.verify_no_errors()
@marks.testrail_id(700718)
@marks.critical
def test_public_unread_messages_counter_for_mentions_relogin(self):
message = 'test message2'
[chat.home_button.double_click() for chat in (self.chat_1, self.chat_2)]
chat_element = self.home_1.get_chat('#' + self.public_chat_name)
self.home_2.get_chat('#' + self.public_chat_name).click()
self.chat_2.select_mention_from_suggestion_list(self.username_1, self.username_1[:2])
self.chat_2.send_message_button.click()
home_1.just_fyi("Check unread message counter when mentioned in public chat")
chat_2 = home_2.get_chat_view()
chat_2.select_mention_from_suggestion_list(self.username_1, self.username_1[:2])
chat_2.send_message_button.click()
chat_element.new_messages_counter.wait_for_element(30)
chat_element.new_messages_counter.wait_for_element_text("1", 60)
chat_element.click()
self.home_1.home_button.double_click()
if self.home_1.home_button.public_unread_messages.is_element_displayed():
home_1.home_button.double_click()
if home_1.home_button.public_unread_messages.is_element_displayed():
self.errors.append('New messages public chat badge is shown on Home button')
if chat_element.new_messages_public_chat.is_element_displayed():
self.errors.append('Unread messages badge is shown in public chat while there are no unread messages')
[home.get_chat('#' + self.public_chat_name).click() for home in (self.home_1, self.home_2)]
self.chat_1.send_message(message)
self.chat_2.chat_element_by_text(message).wait_for_element(20)
[home.get_chat('#' + chat_name).click() for home in (home_1, home_2)]
chat_1.send_message(message_2)
chat_2.chat_element_by_text(message_2).wait_for_element(20)
self.chat_2.just_fyi("Check that unread messages counter doesn't reappear after relogin")
home_2.just_fyi("Check that unread message indicator is not reappeared after relogin")
driver_2 = self.drivers[1]
driver_2.close_app()
driver_2.launch_app()
SignInView(driver_2).sign_in()
chat_element = self.home_2.get_chat('#' + self.public_chat_name)
chat_element = home_2.get_chat('#' + chat_name)
if chat_element.new_messages_public_chat.is_element_displayed():
self.drivers[0].fail('New messages counter is shown after relogin')
self.errors.append('New messages counter is shown after relogin')
self.errors.verify_no_errors()
@@ -149,6 +152,45 @@ class TestPublicChatMultipleDevice(MultipleDeviceTestCase):
self.errors.verify_no_errors()
@marks.testrail_id(6275)
@marks.medium
def test_receive_message_while_in_different_tab_and_emoji_messages_long_press(self):
self.create_drivers(2)
device_1, device_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
home_1, home_2 = device_1.create_user(), device_2.create_user()
public_chat_name = home_1.get_random_chat_name()
chat_1, chat_2 = home_1.join_public_chat(public_chat_name), home_2.join_public_chat(public_chat_name)
device_2.just_fyi("Switch to different tab out from chat")
device_2.dapp_tab_button.click()
emoji_name = random.choice(list(emoji.EMOJI_UNICODE))
emoji_unicode = emoji.EMOJI_UNICODE[emoji_name]
chat_1.chat_message_input.send_keys(emoji.emojize(emoji_name))
chat_1.send_message_button.click()
device_1.just_fyi("Long press emoji message actions")
chat_1.element_by_text_part(emoji_unicode).long_press_element()
chat_1.element_by_text('Copy').click()
chat_1.chat_message_input.paste_text_from_clipboard()
if chat_1.chat_message_input.text != emoji_unicode:
self.errors.append('Emoji message was not copied')
home_2.home_button.click(desired_view='chat')
chat_element_2 = chat_2.element_by_text_part(emoji_unicode)
if not chat_element_2.is_element_displayed(sec=10):
self.errors.append('Message with emoji was not received in public chat by the recipient')
chat_2.quote_message(emoji_unicode)
message_text = 'test message'
chat_2.chat_message_input.send_keys(message_text)
chat_2.send_message_button.click()
chat_element_1 = chat_1.chat_element_by_text(message_text)
if not chat_element_1.is_element_displayed(sec=10) or chat_element_1.replied_message_text != emoji_unicode:
self.errors.append('Reply message was not received by the sender')
self.errors.verify_no_errors()
@marks.testrail_id(6342)
@marks.medium
def test_different_status_in_timeline(self):
+14 -22
View File
@@ -91,20 +91,6 @@ class BaseElement(object):
self.driver.info('Tap on found: %s' % self.name)
return self.navigate()
def click_until_presence_of_element(self, desired_element, attempts=4):
counter = 0
self.driver.info("Click until '%s' by '%s': `%s` will be presented" % (
desired_element.name, desired_element.by, desired_element.locator))
while not desired_element.is_element_present(1) and counter <= attempts:
try:
self.find_element().click()
desired_element.wait_for_element(5)
return self.navigate()
except (NoSuchElementException, TimeoutException):
counter += 1
else:
self.driver.info("%s element not found" % desired_element.name)
def double_click(self):
self.driver.info('Double tap on: %s' % self.name)
[self.find_element().click() for _ in range(2)]
@@ -366,6 +352,19 @@ class Button(BaseElement):
self.wait_for_visibility_of_element(sec)
self.click()
def click_until_presence_of_element(self, desired_element, attempts=4):
counter = 0
self.driver.info("Click until '%s' by '%s': `%s` will be presented" % (
desired_element.name, desired_element.by, desired_element.locator))
while not desired_element.is_element_present(1) and counter <= attempts:
try:
self.find_element().click()
desired_element.wait_for_element(5)
return self.navigate()
except (NoSuchElementException, TimeoutException):
counter += 1
else:
self.driver.info("%s element not found" % desired_element.name)
def click_until_absense_of_element(self, desired_element, attempts=3):
counter = 0
@@ -403,13 +402,6 @@ class SilentButton(Button):
class CheckBox(Button):
def __init__(self, driver, **kwargs):
super(Button, self).__init__(driver, **kwargs)
def enable(self):
def click(self):
super(CheckBox, self).click_until_presence_of_element(Button(self.driver, accessibility_id="checkbox-on"))
return self.navigate()
def disable(self):
super(CheckBox, self).click_until_presence_of_element(Button(self.driver, accessibility_id="checkbox-off"))
return self.navigate()
-1
View File
@@ -84,7 +84,6 @@ class HomeButton(TabButton):
return self.navigate()
class DappTabButton(TabButton):
def __init__(self, driver):
super().__init__(driver, xpath="//*[contains(@content-desc,'tab, 2 out of 5')]")
+2 -18
View File
@@ -143,25 +143,13 @@ class ChatElementByText(Text):
return ''
@property
def timestamp_command_message(self):
class TimeStampText(Button):
def timestamp_message(self):
class TimeStampText(Text):
def __init__(self, driver, parent_locator: str):
super().__init__(driver, xpath="(%s//android.widget.TextView)[last()]" % parent_locator)
return TimeStampText(self.driver, self.locator)
@property
def timestamp_on_tap(self):
timestamp_element = Text(self.driver, xpath="//*[@content-desc='message-timestamp']")
try:
self.sent_status_checkmark.wait_for_element(30)
except NoSuchElementException:
return ''
self.sent_status_checkmark.click_until_presence_of_element(timestamp_element)
return timestamp_element.text
@property
def member_photo(self):
class MemberPhoto(Button):
@@ -203,10 +191,6 @@ class ChatElementByText(Text):
status = 'delivered'
return status
@property
def sent_status_checkmark(self) -> object:
return Text(self.driver, prefix=self.locator, xpath="//*[@content-desc='sent']")
@property
def replied_message_text(self):
class RepliedMessageText(Text):
+3 -3
View File
@@ -195,7 +195,7 @@ class HomeView(BaseView):
self.notifications_accept_and_add_button = Button(self.driver,
accessibility_id="accept-and-add-activity-center")
self.notifications_select_all = Button(self.driver, xpath="(//android.widget.CheckBox["
"@content-desc='checkbox-off'])[1]")
"@content-desc='checkbox'])[1]")
# Options on long tap
self.chats_menu_invite_friends_button = Button(self.driver, accessibility_id="chats-menu-invite-friends-button")
@@ -231,11 +231,11 @@ class HomeView(BaseView):
except TimeoutException:
break
def get_chat(self, username, community=False,wait_time=30):
def get_chat(self, username, community=False):
self.driver.info("Looking for chat: '%s'" % username)
chat_element = ChatElement(self.driver, username[:25], community=community)
if not chat_element.is_element_displayed():
self.notifications_unread_badge.wait_and_click(wait_time)
self.notifications_unread_badge.wait_and_click(30)
chat_in_ac = ActivityCenterChatElement(self.driver, username[:25])
chat_in_ac.wait_for_element(20)
chat_in_ac.click()
-1
View File
@@ -38,7 +38,6 @@ class KeycardView(BaseView):
def get_recovery_word(self, word_id):
word_element = SilentButton(self.driver, accessibility_id="word%s" % word_id)
word_element.wait_for_visibility_of_element()
return word_element.text
def get_required_word_number(self):
+2 -2
View File
@@ -176,7 +176,7 @@ class SignInView(BaseView):
self.driver.info("## Creating new multiaccount (password:'%s', keycard:'%s')" % (password, str(keycard)),
device=False)
if not second_user:
self.accept_tos_checkbox.enable()
self.accept_tos_checkbox.click()
self.get_started_button.click_until_presence_of_element(self.generate_key_button)
self.generate_key_button.click()
@@ -204,7 +204,7 @@ class SignInView(BaseView):
enable_notifications=False, second_user=False):
self.driver.info("## Recover access(password:%s, keycard:%s)" % (password, str(keycard)), device=False)
if not second_user:
self.accept_tos_checkbox.enable()
self.accept_tos_checkbox.click()
self.get_started_button.click_until_presence_of_element(self.access_key_button)
self.access_key_button.click()
self.enter_seed_phrase_button.click()
+5 -3
View File
@@ -18,9 +18,9 @@ class AssetCheckBox(CheckBox):
def __init__(self, driver, asset_name):
super().__init__(driver, xpath="//*[@text='%s']" % asset_name)
def enable(self):
def click(self):
self.scroll_to_element(12)
super().enable()
super().click()
class BackupRecoveryPhrase(Button):
@@ -102,6 +102,8 @@ class WalletView(BaseView):
self.manage_assets_button = Button(self.driver, accessibility_id="wallet-manage-assets")
self.manage_accounts_button = Button(self.driver, accessibility_id="wallet-manage-accounts")
self.scan_tokens_button = Button(self.driver, accessibility_id="wallet-scan-token")
self.stt_check_box = CheckBox(self.driver,
xpath="//*[@text='STT']/../android.view.ViewGroup[@content-desc='checkbox-off']")
self.all_assets_full_names = Text(self.driver,
xpath="//*[@content-desc='checkbox-off']/../android.widget.TextView[1]")
self.all_assets_symbols = Button(self.driver,
@@ -268,7 +270,7 @@ class WalletView(BaseView):
self.multiaccount_more_options.click()
self.manage_assets_button.click()
for asset in args:
self.asset_checkbox_by_name(asset).enable()
self.asset_checkbox_by_name(asset).click()
self.cross_icon.click()
def scan_tokens(self, *args):
+3 -29
View File
@@ -184,7 +184,7 @@
"membership-request-pending": "Membership request pending",
"create-community": "Create a community",
"create-category": "Create category",
"rearrange-categories": "Rearrange Categories",
"reorder-categories": "Reorder categories",
"edited": "Edited",
"edit-community": "Edit community",
"editing-message": "Editing message",
@@ -412,7 +412,6 @@
"delete-bootnode-title": "Delete bootnode",
"delete-chat": "Delete chat",
"delete-chat-confirmation": "Are you sure you want to delete this chat?",
"delete-category-confirmation": "Are you sure you want to delete this category?",
"delete-confirmation": "Delete?",
"delete-mailserver": "Delete Status node",
"delete-mailserver-are-you-sure": "Are you sure you want to delete this Status node?",
@@ -1345,6 +1344,7 @@
"welcome-blank-message": "Your chats will appear here. To start new chats press the ⊕ button",
"welcome-community-blank-message": "Your channels will appear here. To create a new channel, click on the ⊕ button and select \"Create a channel\"",
"welcome-community-blank-message-edit-chats": "Your channels will appear here. To create a new channel, go back to the community screen, click on the ⊕ button and select \"Create a channel\"",
"welcome-community-blank-message-categories": "Your categories will appear here. To create a new category, go back to the community screen, click on the ⊕ button and select \"Create category\"",
"welcome-blank-community-message": "Your communities will appear here.",
"fetch-community": "Fetch community",
"fetching-community": "Fetching community...",
@@ -1703,31 +1703,5 @@
"status-dnd-subtitle": "Mutes all notifications",
"status-always-online": "Always Online",
"status-inactive": "Inactive",
"status-inactive-subtitle": "Hides your online status",
"two-minutes": "two minutes",
"swap": "Swap",
"select-token-to-swap": "Select token to Swap",
"select-token-to-receive": "Select token to receive",
"minimum-received": "Minimum received",
"powered-by-paraswap": "Powered by Paraswap",
"priority": "Priority",
"switch-to-simple-interface":"Switch to simple interface",
"transaction-fee": "Transaction fee",
"swap-details": "Swap details",
"slippage": "Slippage",
"price-impact": "Price impact",
"total-gas": "Total gas",
"token": "Token",
"approve-limit": "Approve limit",
"approve-token": "Approve token",
"approve-token-contract-desc": "Approving a token with a contract allows it to spend your token balance. If you feel that a project is untrustworthy, dont approve the token with them, or approve only the amount you will use with them.",
"unlimited": "Unlimited",
"approve": "Approve",
"limit": "Limit",
"last-transaction": "Last transaction",
"price-impact-desc": "Estimated price impact for this transaction. If the current block base fee exceeds this, your transaction will be included in a following block with a lower base fee.",
"safe-estimate": "Safe estimate",
"current-average": "Current average",
"current-base": "Current base",
"maximum-fee-desc": "Maximum overall price for the transaction. If the current block base fee exceeds this, your transaction will be included in a following block with a lower base fee."
"status-inactive-subtitle": "Hides your online status"
}
-5
View File
@@ -6618,11 +6618,6 @@ react-native-dialogs@^1.0.4:
resolved "https://registry.yarnpkg.com/react-native-dialogs/-/react-native-dialogs-1.1.0.tgz#8f7ee7f9d96574fc878fb7c1be101611fb4af517"
integrity sha512-clnxO0nMyML/6+G5dja3Yt34gPxegLY2OHTwb8BwYTEvQ2UhRKR49Uq91XqU0q6g7Ur9DiYxC0tqV3rcZWUrjQ==
react-native-draggable-flatlist@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/react-native-draggable-flatlist/-/react-native-draggable-flatlist-3.0.3.tgz#e85503585253be01ad251f78d5b341ac22f9d952"
integrity sha512-bDro6aqQMvvTm/CuHre9dAjSBKosAfZRLDx3nmrjOz799kxcn0bq+uCB6yF6m+g1Xd/gVPl7E3Ss4uX+oPUlHg==
react-native-fast-image@8.5.11:
version "8.5.11"
resolved "https://registry.yarnpkg.com/react-native-fast-image/-/react-native-fast-image-8.5.11.tgz#e3dc969d0e4e8df026646bf18194465aa55cbc2b"