Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98b0c218b4 | ||
|
|
eeb8db00f7 | ||
|
|
3499cdc123 | ||
|
|
44b8a4c0f4 | ||
|
|
e45f959c27 | ||
|
|
cd86a1065b | ||
|
|
ffba396e4d | ||
|
|
961692251c | ||
|
|
94fde74b88 | ||
|
|
5402c217df | ||
|
|
4588dafe02 | ||
|
|
edbb06a7c3 | ||
|
|
29a7e4dc1c | ||
|
|
de3c08ba18 | ||
|
|
e5ff46fdd5 |
@@ -32,3 +32,5 @@ METRICS_ENABLED=0
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
COLLECTIBLES_ENABLED=1
|
||||
COMMANDS_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
SWAP_ENABLED=1
|
||||
|
||||
@@ -33,3 +33,4 @@ COMMUNITIES_ENABLED=1
|
||||
COMMUNITIES_MANAGEMENT_ENABLED=1
|
||||
METRICS_ENABLED=0
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
|
||||
@@ -35,3 +35,4 @@ COMMUNITIES_ENABLED=1
|
||||
COMMUNITIES_MANAGEMENT_ENABLED=1
|
||||
METRICS_ENABLED=0
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="alert_text">#ffffff</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="alert_text">#000000</color>
|
||||
</resources>
|
||||
@@ -8,6 +8,7 @@
|
||||
<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">
|
||||
@@ -21,4 +22,9 @@
|
||||
<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>
|
||||
|
||||
@@ -3,15 +3,15 @@ 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.',
|
||||
)
|
||||
string(
|
||||
name: 'KEYWORD_EXPRESSION',
|
||||
description: 'This will run tests which contain names that match the given string expression (Optional)',
|
||||
defaultValue: '',
|
||||
)
|
||||
}
|
||||
|
||||
options {
|
||||
@@ -56,8 +56,8 @@ pipeline {
|
||||
--rerun_count=2 \
|
||||
--testrail_report=True \
|
||||
-m testrail_id \
|
||||
-m "not upgrade" \
|
||||
--network=${params.NETWORK} \
|
||||
-m \"not upgrade\" \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--apk=${params.APK_NAME}
|
||||
"""
|
||||
}
|
||||
|
||||
@@ -8,15 +8,10 @@ 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: 'critical or high',
|
||||
defaultValue: '',
|
||||
)
|
||||
string(
|
||||
name: 'APK_NAME',
|
||||
@@ -26,9 +21,14 @@ 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}" \
|
||||
--network=${params.NETWORK} \
|
||||
-m \"${params.TEST_MARKERS}\" \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--apk=${params.APK_NAME} \
|
||||
--build=PR-${params.PR_ID} \
|
||||
--pr_number=${params.PR_ID} \
|
||||
|
||||
@@ -3,11 +3,6 @@ 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)',
|
||||
@@ -16,6 +11,16 @@ 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 {
|
||||
@@ -32,7 +37,12 @@ pipeline {
|
||||
} }
|
||||
}
|
||||
stage('Test') {
|
||||
steps {
|
||||
steps { script {
|
||||
/* for managing optional arguments */
|
||||
def extraPytestOpts = ''
|
||||
if (params.TR_CASE_IDS != '') {
|
||||
extraPytestOpts = "--run_testrail_ids='${params.TR_CASE_IDS}'"
|
||||
}
|
||||
withCredentials([
|
||||
usernamePassword(
|
||||
credentialsId: 'test-rail-api',
|
||||
@@ -56,18 +66,19 @@ pipeline {
|
||||
dir('test/appium/tests') {
|
||||
sh """
|
||||
python3 -m pytest \
|
||||
-m upgrade \
|
||||
-m "upgrade" \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--numprocesses 15 \
|
||||
--rerun_count=2 \
|
||||
--testrail_report=True \
|
||||
--network=${params.NETWORK} \
|
||||
--apk=${params.APK_NAME} \
|
||||
--apk_upgrade=${params.APK_NAME_UPGRADE}
|
||||
--apk_upgrade=${params.APK_NAME_UPGRADE} \
|
||||
${extraPytestOpts}
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
post {
|
||||
|
||||
+5
-1
@@ -163,4 +163,8 @@ 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
|
||||
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
|
||||
|
||||
+3
-3
@@ -230,7 +230,7 @@ PODS:
|
||||
- React
|
||||
- react-native-status (1.0.0):
|
||||
- React
|
||||
- react-native-status-keycard (2.5.36):
|
||||
- react-native-status-keycard (2.5.37):
|
||||
- Keycard
|
||||
- React
|
||||
- react-native-webview (11.3.0):
|
||||
@@ -626,7 +626,7 @@ SPEC CHECKSUMS:
|
||||
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
|
||||
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
|
||||
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
|
||||
glog: 5bc68409594b19a3e5c5cbced7b1ecf61053b709
|
||||
glog: 61334f8bdb4deea07543d4fbac3fb5948e78a7a5
|
||||
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: eb84554a23315510948613a9467e7e3481be340c
|
||||
react-native-status-keycard: 961d01ca190889ddf220206822fd752f8f4f3f7a
|
||||
react-native-webview: af9990b21a9aeafa8e8347746eb4116c0de086af
|
||||
React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336
|
||||
React-RCTAnimation: 1bde3ecc0c104c55df246eda516e0deb03c4e49b
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
"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.
|
After Width: | Height: | Size: 527 B |
Binary file not shown.
|
After Width: | Height: | Size: 899 B |
Binary file not shown.
|
After Width: | Height: | Size: 196 B |
Binary file not shown.
|
After Width: | Height: | Size: 250 B |
@@ -206,6 +206,9 @@
|
||||
(def rn-emoji-keyboard
|
||||
#js {:EmojiKeyboard #js {}})
|
||||
|
||||
(def react-native-draggable-flatlist
|
||||
#js {:default #js {}})
|
||||
|
||||
;; Update i18n_resources.cljs
|
||||
(defn mock [module]
|
||||
(case module
|
||||
@@ -239,6 +242,7 @@
|
||||
"@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"))
|
||||
|
||||
@@ -55,13 +55,13 @@
|
||||
:small :base
|
||||
:large))
|
||||
|
||||
(defn container [{:keys [size]} & children]
|
||||
(defn container [{:keys [size container-style]} & 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})}]
|
||||
:justify-content :space-between} container-style)}]
|
||||
children))
|
||||
|
||||
(defn icon-column
|
||||
@@ -197,17 +197,19 @@
|
||||
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]
|
||||
:or {subtitle-max-lines 1
|
||||
theme :main
|
||||
haptic-feedback true
|
||||
animated platform/ios?
|
||||
haptic-type :selection}}]
|
||||
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}}]
|
||||
(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)))
|
||||
@@ -223,7 +225,7 @@
|
||||
[component
|
||||
(merge {:type :list-item
|
||||
:disabled disabled
|
||||
:bg-color active-background
|
||||
:bg-color (when active-background-enabled active-background)
|
||||
:accessibility-label accessibility-label}
|
||||
(when on-press
|
||||
{:on-press (fn []
|
||||
@@ -233,7 +235,7 @@
|
||||
{:on-long-press (fn []
|
||||
(optional-haptic)
|
||||
(on-long-press))}))
|
||||
[container {:size size}
|
||||
[container {:size size :container-style container-style}
|
||||
[left-side {:icon-color icon-color
|
||||
:text-color (if on-press
|
||||
text-color
|
||||
|
||||
+23
-10
@@ -5,7 +5,10 @@
|
||||
["react-native" :as rn]
|
||||
["@react-native-community/hooks" :as hooks]
|
||||
["react-native-navigation" :refer (Navigation)]
|
||||
["rn-emoji-keyboard" :refer (EmojiKeyboard)]))
|
||||
["rn-emoji-keyboard" :refer (EmojiKeyboard)]
|
||||
["react-native-draggable-flatlist" :default DraggableFlatList]))
|
||||
|
||||
(def rn-draggable-flatlist (reagent/adapt-react-class DraggableFlatList))
|
||||
|
||||
(def emoji-keyboard (reagent/adapt-react-class EmojiKeyboard))
|
||||
|
||||
@@ -107,7 +110,13 @@
|
||||
|
||||
(defn- wrap-render-fn [f render-data]
|
||||
(fn [data]
|
||||
(reagent/as-element [f (.-item ^js data) (.-index ^js data) (.-separators ^js data) render-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))))
|
||||
|
||||
(defn- wrap-key-fn [f]
|
||||
(fn [data index]
|
||||
@@ -115,19 +124,23 @@
|
||||
(f data index)))
|
||||
|
||||
(defn base-list-props
|
||||
[{:keys [key-fn render-fn empty-component header footer separator data render-data] :as props}]
|
||||
[{:keys [key-fn render-fn empty-component header footer separator data render-data on-drag-end-fn] :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)})
|
||||
(dissoc props :data :header :footer :empty-component :separator :render-fn :key-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)})
|
||||
(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)))
|
||||
|
||||
(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
|
||||
|
||||
@@ -42,11 +42,15 @@
|
||||
[{: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)}
|
||||
{:db (community-resolved db community-id)
|
||||
:dispatch [::cache-link-preview-data (community-link community-id) community]}
|
||||
(models.communities/handle-community community)))
|
||||
|
||||
(fx/defn resolve-community-info
|
||||
@@ -78,9 +82,6 @@
|
||||
: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
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.native-module.core :as status]
|
||||
[quo.react-native :as rn]
|
||||
[quo.react :as react]))
|
||||
[quo.react :as react]
|
||||
[status-im.multiaccounts.core :as multiaccounts]))
|
||||
|
||||
(def at-sign "@")
|
||||
|
||||
@@ -170,11 +171,55 @@
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(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 users] :as chat}
|
||||
(get-in db [:chats current-chat-id])
|
||||
(let [{:keys [chat-type community-id users] :as chat} (get-in db [:chats current-chat-id])
|
||||
{:keys [name preferred-name public-key]} (:multiaccount db)
|
||||
chat-specific-suggestions
|
||||
(cond
|
||||
(= chat-type constants/private-group-chat-type)
|
||||
@@ -200,9 +245,12 @@
|
||||
current-chat-id
|
||||
(contact.db/public-key->contact contacts current-chat-id))
|
||||
|
||||
:else users)
|
||||
{:keys [name preferred-name public-key]}
|
||||
(:multiaccount db)]
|
||||
(= chat-type constants/community-chat-type)
|
||||
(merge users (mentionable-commmunity-members
|
||||
contacts public-key
|
||||
(get-in db [:communities community-id :members])))
|
||||
|
||||
:else users)]
|
||||
(reduce
|
||||
(fn [acc [key {:keys [alias name identicon]}]]
|
||||
(let [name (utils/safe-replace name ".stateofus.eth" "")]
|
||||
@@ -634,19 +682,6 @@
|
||||
[_ 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
|
||||
|
||||
@@ -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]}
|
||||
(let [{:keys [name description color community-id emoji edit-channel-id category-id position]}
|
||||
(get db :communities/create-channel)]
|
||||
{::json-rpc/call [{:method "wakuext_editCommunityChat"
|
||||
:params [community-id
|
||||
@@ -298,6 +298,7 @@
|
||||
: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 %])
|
||||
@@ -345,7 +346,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]
|
||||
[{:keys [db] :as cofx} community-id chat-name description color emoji chat-id category-id position]
|
||||
(let [{:keys [color emoji]} (if (string/blank? emoji)
|
||||
(rand-nth emoji-thumbnail-styles/emoji-picker-default-thumbnails)
|
||||
{:color color :emoji emoji})]
|
||||
@@ -356,7 +357,8 @@
|
||||
:community-id community-id
|
||||
:emoji emoji
|
||||
:edit-channel-id chat-id
|
||||
:category-id category-id})}
|
||||
:category-id category-id
|
||||
:position position})}
|
||||
(navigation/open-modal :edit-community-channel nil))))
|
||||
|
||||
(fx/defn community-created
|
||||
@@ -564,6 +566,15 @@
|
||||
: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]
|
||||
@@ -592,6 +603,18 @@
|
||||
(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]
|
||||
|
||||
@@ -146,6 +146,7 @@
|
||||
|
||||
(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))
|
||||
|
||||
@@ -165,6 +165,7 @@
|
||||
"wakuext_reorderCommunityChat" {}
|
||||
"wakuext_editCommunityCategory" {}
|
||||
"wakuext_deleteCommunityCategory" {}
|
||||
"wakuext_deleteCommunityChat" {}
|
||||
"wakuext_ensVerified" {}
|
||||
"wakuext_dismissActivityCenterNotifications" {}
|
||||
"wakuext_acceptActivityCenterNotifications" {}
|
||||
|
||||
@@ -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
|
||||
[status-im.bottom-sheet.core :as bottom-sheet]
|
||||
status-im.browser.core
|
||||
status-im.browser.permissions
|
||||
[status-im.chat.models :as chat]
|
||||
@@ -58,7 +58,9 @@
|
||||
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.wallet.custom-tokens.core
|
||||
[status-im.navigation.core :as navigation.core]
|
||||
[status-im.multiaccounts.login.core :as login.core]))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:dismiss-keyboard
|
||||
@@ -112,10 +114,35 @@
|
||||
|
||||
(fx/defn system-theme-mode-changed
|
||||
{:events [:system-theme-mode-changed]}
|
||||
[{:keys [db]} theme]
|
||||
(let [cur-theme (get-in db [:multiaccount :appearance])]
|
||||
[{: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)
|
||||
(when (or (nil? cur-theme) (zero? cur-theme))
|
||||
{::multiaccounts/switch-theme (if (= :dark theme) 2 1)})))
|
||||
(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))))))
|
||||
|
||||
(def authentication-options
|
||||
{:reason (i18n/label :t/biometric-auth-reason-login)})
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :creating-backup?] backup-type))}
|
||||
(when-not (:multiaccounts/login db)
|
||||
(when (:multiaccount db)
|
||||
(navigation/change-tab :profile))
|
||||
(navigation/navigate-to-cofx :seed-phrase nil)))
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
:error nil
|
||||
:status nil))
|
||||
:hide-popover nil})
|
||||
(when-not (:multiaccounts/login db)
|
||||
(when (:multiaccount db)
|
||||
(navigation/change-tab :profile))
|
||||
(when-not (:multiaccounts/login db)
|
||||
(if (:popover/popover db)
|
||||
|
||||
@@ -217,9 +217,15 @@
|
||||
: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))}}
|
||||
(if (multiaccounts.model/logged-in? cofx)
|
||||
(cond
|
||||
(multiaccounts.model/logged-in? cofx)
|
||||
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])
|
||||
(return-to-keycard-login))))
|
||||
|
||||
(:multiaccounts/login db)
|
||||
(return-to-keycard-login)
|
||||
|
||||
:else
|
||||
(navigation/set-stack-root :onboarding [:get-your-keys]))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::finish-migration
|
||||
|
||||
@@ -109,12 +109,15 @@
|
||||
types/json->clj
|
||||
:error
|
||||
string/blank?
|
||||
not)]
|
||||
not)
|
||||
onboarding? (not (or (:multiaccounts/login db) (:multiaccount db)))]
|
||||
(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))}})))
|
||||
:key-uid (or (-> db :multiaccounts/login :key-uid)
|
||||
(-> db :multiaccount :key-uid)
|
||||
(and onboarding? (-> db :keycard :application-info :key-uid)))}})))
|
||||
|
||||
(fx/defn choose-storage-pressed
|
||||
{:events [::choose-storage-pressed]}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(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]
|
||||
@@ -157,12 +158,14 @@
|
||||
(.registerComponentDidDisappearListener
|
||||
(.events Navigation)
|
||||
(fn [^js evn]
|
||||
(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})))))))
|
||||
(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}))))))))
|
||||
|
||||
;; SET ROOT
|
||||
(re-frame/reg-fx
|
||||
@@ -277,7 +280,10 @@
|
||||
(.registerBottomTabSelectedListener
|
||||
(.events Navigation)
|
||||
(fn [^js evn]
|
||||
(let [comp (get tab-root-ids (.-selectedTabIndex 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])
|
||||
(when (and platform/android? (= @root-comp-id comp))
|
||||
(.popToRoot Navigation (name comp)))
|
||||
(reset! root-comp-id comp)))))
|
||||
@@ -377,3 +383,27 @@
|
||||
(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))}))
|
||||
|
||||
@@ -19,15 +19,16 @@
|
||||
{:unread-count (get db :activity.center/notifications-count 0)
|
||||
:notifications (get-in db [:activity.center/notifications :notifications])}
|
||||
activities)]
|
||||
{: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]
|
||||
(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]}
|
||||
|
||||
(= (:view-id db) :chat)
|
||||
[:accept-all-activity-center-notifications-from-chat (:current-chat-id db)])}))
|
||||
(= (:view-id db) :chat)
|
||||
{:dispatch [:accept-all-activity-center-notifications-from-chat (:current-chat-id db)]}))))
|
||||
|
||||
(fx/defn get-activity-center-notifications-count
|
||||
{:events [:get-activity-center-notifications-count]}
|
||||
|
||||
+37
-24
@@ -34,7 +34,6 @@
|
||||
[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]
|
||||
@@ -181,6 +180,12 @@
|
||||
(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)
|
||||
@@ -877,6 +882,22 @@
|
||||
(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 _]]
|
||||
@@ -903,7 +924,9 @@
|
||||
:<- [:communities]
|
||||
(fn [communities [_ id]]
|
||||
(->> (get-in communities [id :categories])
|
||||
(sort-by #(:position (get % 1))))))
|
||||
(map #(assoc (get % 1) :community-id id))
|
||||
(sort-by :position)
|
||||
(into []))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-ui-props
|
||||
@@ -1400,22 +1423,11 @@
|
||||
:<- [:contacts/contacts]
|
||||
(fn [contacts]
|
||||
(reduce
|
||||
(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))
|
||||
(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))))
|
||||
{}
|
||||
contacts)))
|
||||
|
||||
@@ -1425,7 +1437,9 @@
|
||||
:<- [:chats/mentionable-contacts]
|
||||
:<- [:contacts/blocked-set]
|
||||
:<- [:multiaccount]
|
||||
(fn [[{:keys [chat-id users contacts community-id chat-type] :as chat} mentionable-contacts blocked {:keys [name preferred-name public-key]}]]
|
||||
:<- [:contacts/contacts]
|
||||
(fn [[{:keys [chat-id users contacts community-id chat-type] :as chat}
|
||||
mentionable-contacts blocked {:keys [public-key]} my-contacts]]
|
||||
(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)
|
||||
@@ -1436,14 +1450,13 @@
|
||||
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)))]
|
||||
(keys community-members)))
|
||||
mentionable-commmunity-members (mentions/mentionable-commmunity-members
|
||||
my-contacts public-key community-members)]
|
||||
(apply dissoc
|
||||
(-> users
|
||||
(merge filtered-contacts)
|
||||
(assoc public-key (mentions/add-searchable-phrases
|
||||
{:alias name
|
||||
:name (or preferred-name name)
|
||||
:public-key public-key})))
|
||||
(merge mentionable-commmunity-members))
|
||||
(conj (concat blocked members-left) public-key)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
(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)} emoji]]))
|
||||
[react/text {:style (styles/emoji-thumbnail-icon-text size)
|
||||
:accessibility-label :thumbnail-emoji} emoji]]))
|
||||
|
||||
(defn emoji-thumbnail-touchable [emoji color size func]
|
||||
(when-not (string/blank? emoji)
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
(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,22 +86,4 @@
|
||||
: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]]
|
||||
[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]))]])]]))
|
||||
[chat-name-input topic error]]]))
|
||||
|
||||
@@ -12,28 +12,29 @@
|
||||
(re-frame/dispatch [:chat.ui/fill-gaps chat-id gap-ids])))
|
||||
|
||||
(views/defview gap
|
||||
[{:keys [gap-ids chat-id gap-parameters]}]
|
||||
[{:keys [gap-ids chat-id gap-parameters public? community?]}]
|
||||
(views/letsubs [in-progress? [:chats/fetching-gap-in-progress?
|
||||
gap-ids
|
||||
chat-id]
|
||||
connected? [:mailserver/connected?]
|
||||
first-gap? (= gap-ids #{:first-gap})]
|
||||
[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})))])])]]]))
|
||||
(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})))])])]]])))
|
||||
|
||||
@@ -80,7 +80,9 @@
|
||||
(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)}
|
||||
[react/text
|
||||
{:style (style/message-timestamp-text)
|
||||
:accessibility-label :message-timestamp}
|
||||
timestamp-str]])))
|
||||
|
||||
(defview quoted-message
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
[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]))
|
||||
[status-im.utils.image :as utils.image]
|
||||
[quo.design-system.colors :as colors]))
|
||||
|
||||
(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)
|
||||
@@ -18,8 +19,9 @@
|
||||
(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])
|
||||
[memo-photo-rend photo-path size accessibility-label (colors/dark?)])
|
||||
|
||||
;; We optionally pass identicon for perfomance reason, so it does not have to be calculated for each message
|
||||
(defn member-photo [pub-key identicon]
|
||||
|
||||
@@ -243,7 +243,8 @@
|
||||
(defn render-fn [{:keys [outgoing type] :as message}
|
||||
idx
|
||||
_
|
||||
{:keys [group-chat public? current-public-key space-keeper chat-id show-input? message-pin-enabled edit-enabled in-pinned-view?]}]
|
||||
{:keys [group-chat public? community? 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)]
|
||||
@@ -255,6 +256,7 @@
|
||||
: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
|
||||
@@ -285,6 +287,7 @@
|
||||
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,6 +12,7 @@
|
||||
(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])]
|
||||
@@ -27,7 +28,8 @@
|
||||
color
|
||||
emoji
|
||||
chat-id
|
||||
(:id category)])}])
|
||||
(:id category)
|
||||
position])}])
|
||||
:extended-header (profile-header/extended-header
|
||||
{:title chat-name
|
||||
:color color
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
[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))
|
||||
@@ -139,12 +138,6 @@
|
||||
: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}])}]])]))
|
||||
|
||||
@@ -168,46 +161,28 @@
|
||||
{:content (fn []
|
||||
[sheets/actions home-item])}])}])
|
||||
|
||||
(defn categories-accordion [community-id chats categories edit data]
|
||||
(defn categories-accordion [community-id chats categories data]
|
||||
[:<>
|
||||
(for [{:keys [name id state]} (vals categories)]
|
||||
(for [{:keys [name id state]} 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
|
||||
(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}])
|
||||
[icons/icon :main-icons/channel-category {:color colors/gray}]
|
||||
[rn/text {:style {:font-size 17 :margin-left 10 :color colors/black}} name]]
|
||||
:content [rn/view
|
||||
:content [:<>
|
||||
(for [chat (get chats id)]
|
||||
(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]))]}]
|
||||
^{:key (str "chat" chat id)}
|
||||
[community-chat-item chat nil nil data])]}]
|
||||
[quo/separator]])])
|
||||
|
||||
(defn community-chat-list [community-id categories edit from-chat]
|
||||
(let [chats (<sub [:chats/categories-by-community-id community-id])]
|
||||
(defn community-chat-list [community-id categories from-chat]
|
||||
(let [chats (<sub [:chats/sorted-categories-by-community-id community-id])]
|
||||
(if (and (empty? categories) (empty? chats))
|
||||
(if edit
|
||||
[blank-page (i18n/label :t/welcome-community-blank-message-edit-chats)]
|
||||
[blank-page (i18n/label :t/welcome-community-blank-message)])
|
||||
[blank-page (i18n/label :t/welcome-community-blank-message)]
|
||||
[list/flat-list
|
||||
{:key-fn :chat-id
|
||||
:content-container-style {:padding-bottom 8}
|
||||
@@ -215,7 +190,7 @@
|
||||
:data (get chats "")
|
||||
:render-data {:from-chat from-chat}
|
||||
:render-fn community-chat-item
|
||||
:header [categories-accordion community-id chats categories edit {:from-chat from-chat}]
|
||||
:header [categories-accordion community-id chats categories {:from-chat from-chat}]
|
||||
:footer [rn/view {:height 68}]}])))
|
||||
|
||||
(defn channel-preview-item [{:keys [id name]}]
|
||||
@@ -267,23 +242,6 @@
|
||||
[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,60 +1,176 @@
|
||||
(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.ui.components.react :as react]
|
||||
[status-im.utils.platform :as platform]
|
||||
[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.communities.community :as community]
|
||||
[status-im.ui.screens.home.views.inner-item :as inner-item]))
|
||||
|
||||
(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])))
|
||||
(def collapse-chats? (reagent/atom false))
|
||||
(def data (reagent/atom []))
|
||||
|
||||
(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-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 [community-id count {:keys [key name position]}]
|
||||
(let [up-disabled? (= position 0)
|
||||
down-disabled? (= position (dec count))]
|
||||
(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)]
|
||||
[:<>
|
||||
[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]]))
|
||||
[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}]])]]))
|
||||
|
||||
(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 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 view []
|
||||
(let [{:keys [community-id]} (<sub [:get-screen-params])
|
||||
{:keys [id name images members permissions color]}
|
||||
(<sub [:communities/community community-id])
|
||||
categories (<sub [:communities/sorted-categories 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)
|
||||
[:<>
|
||||
[topbar/topbar
|
||||
{:modal? true
|
||||
:content [community/toolbar-content id name color images
|
||||
(not= (:access permissions) constants/community-no-membership-access)
|
||||
(count members)]}]
|
||||
(if (empty? categories)
|
||||
[community/blank-page (i18n/label :t/welcome-community-blank-message-categories)]
|
||||
[categories-view community-id categories (count categories)])]))
|
||||
(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]])]))
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
[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]))
|
||||
[status-im.communities.core :as communities]
|
||||
[quo.components.animated.pressable :as animation]))
|
||||
|
||||
(defn hide-sheet-and-dispatch [event]
|
||||
(>evt [:bottom-sheet/hide])
|
||||
@@ -19,11 +20,11 @@
|
||||
|
||||
(defn request-actions [community-id request-id]
|
||||
[react/view {:flex-direction :row}
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:communities.ui/accept-request-to-join-pressed community-id request-id])}
|
||||
[animation/pressable {: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}]]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:communities.ui/decline-request-to-join-pressed community-id request-id])}
|
||||
[animation/pressable {: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}
|
||||
@@ -41,7 +42,8 @@
|
||||
:accessory (when can-manage-users?
|
||||
[request-actions community-id id])
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo member)]}]))
|
||||
(multiaccounts/displayed-photo member)]
|
||||
:on-press #(re-frame/dispatch [:chat.ui/show-profile public-key])}]))
|
||||
|
||||
(defn requests-to-join []
|
||||
(let [{:keys [community-id]} (<sub [:get-screen-params])]
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
(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))]
|
||||
[:<>
|
||||
@@ -44,7 +45,7 @@
|
||||
:create-community-category
|
||||
{:community-id community-id}])
|
||||
:title (i18n/label :t/create-category)}]
|
||||
:data (conj (vec (vals categories)) {:name (i18n/label :t/none) :id ""})
|
||||
:data (conj categories {:name (i18n/label :t/none) :id ""})
|
||||
:render-fn render-fn}]]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
@@ -54,6 +55,7 @@
|
||||
[::communities/change-category-confirmation-pressed
|
||||
community-id
|
||||
@selected-item
|
||||
comm-chat]
|
||||
(assoc comm-chat :position
|
||||
(count (get chats @selected-item)))] ;; Add as last item in new category
|
||||
3000)}
|
||||
(i18n/label :t/done)]}]]))))
|
||||
|
||||
@@ -1,34 +1,8 @@
|
||||
(ns status-im.ui.screens.communities.styles
|
||||
(:require [quo.design-system.colors :as colors]))
|
||||
(ns status-im.ui.screens.communities.styles)
|
||||
|
||||
(def category-item
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:height 52
|
||||
: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})
|
||||
:padding-left 18})
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
(: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/one-day (i18n/label :t/one-day)
|
||||
(def titles {constants/two-mins (i18n/label :t/two-minutes)
|
||||
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)})
|
||||
@@ -21,6 +23,8 @@
|
||||
(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]
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
[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]
|
||||
@@ -13,7 +12,6 @@
|
||||
[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]
|
||||
@@ -41,30 +39,10 @@
|
||||
: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}]
|
||||
[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])]])])
|
||||
[react/view {:align-items :center
|
||||
:margin-top 8
|
||||
:margin-bottom 12}
|
||||
[invite/button]]])
|
||||
|
||||
(defn welcome-blank-page []
|
||||
[react/view {:style {:flex 1 :flex-direction :row :align-items :center :justify-content :center}}
|
||||
|
||||
@@ -149,13 +149,16 @@
|
||||
:else
|
||||
[icons/icon :main-icons/tiny-new-contact (icon-style)]))
|
||||
|
||||
(defn chat-item-title [chat-id muted group-chat chat-name]
|
||||
(defn chat-item-title [chat-id muted group-chat chat-name edit?]
|
||||
[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 90}}
|
||||
:style {:position :absolute
|
||||
:left 92
|
||||
:top 10
|
||||
:right (if edit? 50 90)}}
|
||||
(if group-chat
|
||||
(utils/truncate-str chat-name 30)
|
||||
;; This looks a bit odd, but I would like only to subscribe
|
||||
@@ -164,7 +167,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]} home-item
|
||||
(let [{:keys [chat-id chat-name color group-chat public? timestamp last-message muted emoji highlight edit?]} home-item
|
||||
background-color (when highlight (colors/get-color :interactive-02))]
|
||||
[react/touchable-opacity (merge {:style {:height 64 :background-color background-color}} opts)
|
||||
[:<>
|
||||
@@ -178,13 +181,15 @@
|
||||
: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]
|
||||
[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]]]))
|
||||
[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]]]))
|
||||
|
||||
@@ -44,6 +44,17 @@
|
||||
[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]
|
||||
@@ -91,7 +102,6 @@
|
||||
[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]
|
||||
@@ -99,7 +109,6 @@
|
||||
[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]
|
||||
@@ -107,18 +116,10 @@
|
||||
: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.settings.views :as wallet-settings]
|
||||
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions]))
|
||||
[status-im.ui.screens.wallet.send.views :as wallet.send]))
|
||||
|
||||
(def components
|
||||
[{:name :chat-toolbar
|
||||
@@ -220,9 +221,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}
|
||||
|
||||
@@ -288,11 +289,6 @@
|
||||
;;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}}
|
||||
@@ -400,6 +396,32 @@
|
||||
: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
|
||||
@@ -708,8 +730,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,6 +40,8 @@
|
||||
: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,3 +42,19 @@
|
||||
: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,16 +7,17 @@
|
||||
[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.collectibles.views :as collectibles.views]
|
||||
[status-im.ui.screens.wallet.buy-crypto.views :as buy-crypto])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(def state (reagent/atom {:tab :assets}))
|
||||
@@ -102,7 +103,6 @@
|
||||
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,11 +111,10 @@
|
||||
(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)])]
|
||||
@@ -181,10 +180,31 @@
|
||||
(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)
|
||||
[:<>
|
||||
@@ -206,9 +226,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
|
||||
@@ -233,5 +253,8 @@
|
||||
[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]])))
|
||||
|
||||
@@ -0,0 +1,433 @@
|
||||
(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)]}]]))
|
||||
|
||||
@@ -52,6 +52,8 @@
|
||||
(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
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
(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,7 +3,7 @@
|
||||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.92.5",
|
||||
"commit-sha1": "64589fbd1f81022c7f995a7d993f0c026ecc6923",
|
||||
"src-sha256": "0d4zh9kmgi0vwgn1wsbjfnp7hiv2m0l1472wkjg23snskz2g5g14"
|
||||
"version": "feat/node-config",
|
||||
"commit-sha1": "3daf1ea073fe1aa636a9d301a8e2a04acd7adbca",
|
||||
"src-sha256": "1vc70av6jvsch12hyr32hsnh5yqsaavmhy32d20zx3nfb3kxgv12"
|
||||
}
|
||||
|
||||
@@ -42,11 +42,11 @@ rlp==1.2.0
|
||||
sauceclient==1.0.0
|
||||
scrypt==0.8.17
|
||||
selenium==3.14.1
|
||||
six==1.10.0
|
||||
six==1.11.0
|
||||
urllib3==1.26.3
|
||||
yarl==1.6.3
|
||||
zbarlight==3.0
|
||||
docker==4.4.0
|
||||
influxdb==5.3.1
|
||||
web3
|
||||
imagehash
|
||||
web3==5.25.0
|
||||
imagehash
|
||||
@@ -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"
|
||||
|
||||
@@ -97,10 +97,11 @@ class TestrailReport(BaseTestReport):
|
||||
|
||||
def get_regression_cases(self):
|
||||
test_cases = dict()
|
||||
test_cases['critical'] = 734
|
||||
test_cases['high'] = 735
|
||||
test_cases['critical'] = 730
|
||||
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:
|
||||
@@ -108,7 +109,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['high']]):
|
||||
for case in self.get_cases([test_cases['critical'], test_cases['public_chat'], test_cases['one_to_one_chat']]):
|
||||
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.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
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.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
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.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
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.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
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.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
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.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
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.click()
|
||||
sign_in.accept_tos_checkbox.enable()
|
||||
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.click()
|
||||
device_1.accept_tos_checkbox.enable()
|
||||
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.get_chat(comm_before_sync_name).is_element_disappeared(30):
|
||||
if not home_2.element_by_text_part(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.get_chat(comm_after_sync_name, community=True).is_element_displayed(30):
|
||||
if not home_2.element_by_text(comm_after_sync_name).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,7 +168,10 @@ class TestWalletManagement(SingleDeviceTestCase):
|
||||
self.errors.append('%s asset is not shown in wallet after relogin' % asset)
|
||||
|
||||
sign_in.just_fyi("Deselecting asset")
|
||||
wallet.select_asset(asset)
|
||||
wallet.multiaccount_more_options.click()
|
||||
wallet.manage_assets_button.click()
|
||||
wallet.asset_checkbox_by_name(asset).click()
|
||||
wallet.cross_icon.click()
|
||||
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,7 +696,6 @@ 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():
|
||||
@@ -718,6 +717,7 @@ 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_message.text
|
||||
timestamp_sender = sender_message.timestamp_command_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_message.text
|
||||
updated_timestamp_sender = sender_message.timestamp_command_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_message.text
|
||||
timestamp_sender = sender_message.timestamp_command_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_message.text
|
||||
updated_timestamp_sender = sender_message.timestamp_command_message.text
|
||||
if updated_timestamp_sender == timestamp_sender:
|
||||
self.errors.append("Timestamp of message is not updated after signing transaction")
|
||||
|
||||
|
||||
@@ -109,8 +109,7 @@ 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)
|
||||
chat_element.wait_for_visibility_of_element(30)
|
||||
chat_element = home_1.get_chat(username_2, wait_time=60)
|
||||
chat_1 = chat_element.click()
|
||||
chat_1.chat_element_by_text(message_1).wait_for_visibility_of_element(2)
|
||||
|
||||
@@ -162,13 +161,14 @@ 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)
|
||||
|
||||
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))
|
||||
# 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))
|
||||
|
||||
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.timestamp_message.long_press_element()
|
||||
message_bubble.sent_status_checkmark.long_press_element()
|
||||
chat.element_by_text('Copy').click()
|
||||
|
||||
message_input.paste_text_from_clipboard()
|
||||
@@ -964,13 +964,10 @@ 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)
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ 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
|
||||
|
||||
|
||||
@@ -20,104 +19,102 @@ 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])
|
||||
home_1, home_2 = device_1.create_user(), device_2.create_user()
|
||||
profile_1 = home_1.profile_button.click()
|
||||
cls.home_1, cls.home_2 = device_1.create_user(), device_2.create_user()
|
||||
profile_1 = cls.home_1.profile_button.click()
|
||||
cls.username_1 = profile_1.default_username_text.text
|
||||
profile_1.home_button.click()
|
||||
home_2.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)
|
||||
|
||||
@marks.testrail_id(5313)
|
||||
@marks.critical
|
||||
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()
|
||||
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()
|
||||
|
||||
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")
|
||||
@marks.testrail_id(700719)
|
||||
@marks.critical
|
||||
def test_public_emoji(self):
|
||||
emoji_name = random.choice(list(emoji.EMOJI_UNICODE))
|
||||
emoji_unicode = emoji.EMOJI_UNICODE[emoji_name]
|
||||
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():
|
||||
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):
|
||||
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_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():
|
||||
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():
|
||||
self.errors.append('New messages public chat badge is not shown on Home button')
|
||||
chat_element = home_1.get_chat('#' + chat_name)
|
||||
chat_element = home_1.get_chat('#' + self.public_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()
|
||||
|
||||
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()
|
||||
@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()
|
||||
chat_element.new_messages_counter.wait_for_element(30)
|
||||
chat_element.new_messages_counter.wait_for_element_text("1", 60)
|
||||
|
||||
chat_element.click()
|
||||
home_1.home_button.double_click()
|
||||
|
||||
if home_1.home_button.public_unread_messages.is_element_displayed():
|
||||
self.home_1.home_button.double_click()
|
||||
if self.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('#' + 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)
|
||||
[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_2.just_fyi("Check that unread message indicator is not reappeared after relogin")
|
||||
self.chat_2.just_fyi("Check that unread messages counter doesn't reappear after relogin")
|
||||
driver_2 = self.drivers[1]
|
||||
driver_2.close_app()
|
||||
driver_2.launch_app()
|
||||
SignInView(driver_2).sign_in()
|
||||
chat_element = home_2.get_chat('#' + chat_name)
|
||||
chat_element = self.home_2.get_chat('#' + self.public_chat_name)
|
||||
if chat_element.new_messages_public_chat.is_element_displayed():
|
||||
self.errors.append('New messages counter is shown after relogin')
|
||||
self.drivers[0].fail('New messages counter is shown after relogin')
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
|
||||
@@ -152,45 +149,6 @@ 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):
|
||||
|
||||
@@ -91,6 +91,20 @@ 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)]
|
||||
@@ -352,19 +366,6 @@ 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
|
||||
@@ -402,6 +403,13 @@ class SilentButton(Button):
|
||||
|
||||
|
||||
class CheckBox(Button):
|
||||
def click(self):
|
||||
def __init__(self, driver, **kwargs):
|
||||
super(Button, self).__init__(driver, **kwargs)
|
||||
|
||||
def enable(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()
|
||||
|
||||
@@ -84,6 +84,7 @@ 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')]")
|
||||
|
||||
@@ -143,13 +143,25 @@ class ChatElementByText(Text):
|
||||
return ''
|
||||
|
||||
@property
|
||||
def timestamp_message(self):
|
||||
class TimeStampText(Text):
|
||||
def timestamp_command_message(self):
|
||||
|
||||
class TimeStampText(Button):
|
||||
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):
|
||||
@@ -191,6 +203,10 @@ 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):
|
||||
|
||||
@@ -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'])[1]")
|
||||
"@content-desc='checkbox-off'])[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):
|
||||
def get_chat(self, username, community=False,wait_time=30):
|
||||
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(30)
|
||||
self.notifications_unread_badge.wait_and_click(wait_time)
|
||||
chat_in_ac = ActivityCenterChatElement(self.driver, username[:25])
|
||||
chat_in_ac.wait_for_element(20)
|
||||
chat_in_ac.click()
|
||||
|
||||
@@ -38,6 +38,7 @@ 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):
|
||||
|
||||
@@ -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.click()
|
||||
self.accept_tos_checkbox.enable()
|
||||
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.click()
|
||||
self.accept_tos_checkbox.enable()
|
||||
self.get_started_button.click_until_presence_of_element(self.access_key_button)
|
||||
self.access_key_button.click()
|
||||
self.enter_seed_phrase_button.click()
|
||||
|
||||
@@ -18,9 +18,9 @@ class AssetCheckBox(CheckBox):
|
||||
def __init__(self, driver, asset_name):
|
||||
super().__init__(driver, xpath="//*[@text='%s']" % asset_name)
|
||||
|
||||
def click(self):
|
||||
def enable(self):
|
||||
self.scroll_to_element(12)
|
||||
super().click()
|
||||
super().enable()
|
||||
|
||||
|
||||
class BackupRecoveryPhrase(Button):
|
||||
@@ -102,8 +102,6 @@ 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,
|
||||
@@ -270,7 +268,7 @@ class WalletView(BaseView):
|
||||
self.multiaccount_more_options.click()
|
||||
self.manage_assets_button.click()
|
||||
for asset in args:
|
||||
self.asset_checkbox_by_name(asset).click()
|
||||
self.asset_checkbox_by_name(asset).enable()
|
||||
self.cross_icon.click()
|
||||
|
||||
def scan_tokens(self, *args):
|
||||
|
||||
+29
-3
@@ -184,7 +184,7 @@
|
||||
"membership-request-pending": "Membership request pending",
|
||||
"create-community": "Create a community",
|
||||
"create-category": "Create category",
|
||||
"reorder-categories": "Reorder categories",
|
||||
"rearrange-categories": "Rearrange Categories",
|
||||
"edited": "Edited",
|
||||
"edit-community": "Edit community",
|
||||
"editing-message": "Editing message",
|
||||
@@ -412,6 +412,7 @@
|
||||
"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?",
|
||||
@@ -1344,7 +1345,6 @@
|
||||
"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,5 +1703,31 @@
|
||||
"status-dnd-subtitle": "Mutes all notifications",
|
||||
"status-always-online": "Always Online",
|
||||
"status-inactive": "Inactive",
|
||||
"status-inactive-subtitle": "Hides your online status"
|
||||
"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, don’t 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."
|
||||
}
|
||||
|
||||
@@ -6618,6 +6618,11 @@ 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"
|
||||
|
||||
Reference in New Issue
Block a user