Compare commits

..
Author SHA1 Message Date
Vitaliy Vlasov 3449600467 Wakuv2 rendezvous 2021-12-31 15:00:21 +02:00
Churikova Tetiana 3499cdc123 e2e: update ci and made first group 2021-12-29 18:02:58 +01:00
Parvesh Monu 44b8a4c0f4 fix community invite link is not resolved (#12956) 2021-12-28 16:38:42 +05:30
Michele Balistreri e45f959c27 support PUK and seed recovery during onboarding
Signed-off-by: Michele Balistreri <michele@bitgamma.com>
2021-12-27 20:35:33 +03:00
Roman Volosovskyi cd86a1065b [#12936] Add accessibility-id to message timestamp 2021-12-27 13:44:21 +02:00
Parvesh Monu ffba396e4d fix distortion of app theme due to change in system theme (#12934) 2021-12-27 15:24:45 +05:30
Du Cheng 961692251c [#12930] Remove public chat references 2021-12-24 21:10:10 +02:00
Parvesh Monu 94fde74b88 Reorder community chats and categories using drag and drop (#12854) 2021-12-24 21:04:44 +05:30
Roman Volosovskyi 5402c217df [#12913] Properly handle syncing of pubchat delition/installation after offline 2021-12-24 17:03:34 +02:00
Parvesh Monu 4588dafe02 Open user profile from membership requests (#12950) 2021-12-24 20:27:30 +05:30
Parvesh Monu edbb06a7c3 Add community members to mentionable list (#12926) 2021-12-24 20:25:00 +05:30
Roman Volosovskyi 29a7e4dc1c [#12918] Show history gaps only in public chats and communities 2021-12-24 13:40:01 +02:00
Roman Volosovskyi de3c08ba18 Add sync history for 2 mins option for testing purposes 2021-12-21 21:42:42 +02:00
Churikova Tetiana e5ff46fdd5 e2e: fixes
Signed-off-by: Churikova Tetiana <churikova.tm@gmail.com>
2021-12-21 14:58:41 +01:00
73 changed files with 734 additions and 512 deletions
+1
View File
@@ -32,3 +32,4 @@ METRICS_ENABLED=0
DELETE_MESSAGE_ENABLED=1
COLLECTIBLES_ENABLED=1
COMMANDS_ENABLED=1
TWO_MINUTES_SYNCING=1
+1
View File
@@ -33,3 +33,4 @@ COMMUNITIES_ENABLED=1
COMMUNITIES_MANAGEMENT_ENABLED=1
METRICS_ENABLED=0
DELETE_MESSAGE_ENABLED=1
TWO_MINUTES_SYNCING=1
+1
View File
@@ -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>
+7 -7
View File
@@ -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}
"""
}
+9 -9
View File
@@ -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} \
+21 -10
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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",
+14 -2
View File
@@ -99,6 +99,18 @@
"node-01.gc-us-central1-a.eth.test": "enode://f593a27731bc0f8eb088e2d39222c2d59dfb9bf0b3950d7a828d51e8ab9e08fffbd9916a82fd993c1a080c57c2bd70ed6c36f489a969de697aff93088dbee1a9@35.194.31.108:443"
}
},
"go-waku.test": {
"waku": {
"node-01.ac-cn-hongkong-c.go-waku.test": "/ip4/8.218.2.110/tcp/30303/p2p/16Uiu2HAmBDbMWFiG9ki8sDw6fYtraSxo4oHU9HbuN43S2HVyq1FD",
"node-01.do-ams3.go-waku.test": "/ip4/134.209.134.63/tcp/30303/p2p/16Uiu2HAm9vnvCQgCDrynDK1h7GJoEZVGvnuzq84RyDQ3DEdXmcX7",
"node-01.gc-us-central1-a.go-waku.test": "/ip4/35.223.183.91/tcp/30303/p2p/16Uiu2HAmPz63Xc6AuVkDeujz7YeZta18rcdau3Y1BzaxKAfDrBqz"
},
"websocket": {
"node-01.ac-cn-hongkong-c.go-waku.test": "/dns4/node-01.ac-cn-hongkong-c.go-waku.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmBDbMWFiG9ki8sDw6fYtraSxo4oHU9HbuN43S2HVyq1FD",
"node-01.do-ams3.go-waku.test": "/dns4/node-01.do-ams3.go-waku.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAm9vnvCQgCDrynDK1h7GJoEZVGvnuzq84RyDQ3DEdXmcX7",
"node-01.gc-us-central1-a.go-waku.test": "/dns4/node-01.gc-us-central1-a.go-waku.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmPz63Xc6AuVkDeujz7YeZta18rcdau3Y1BzaxKAfDrBqz"
}
},
"wakuv2.prod": {
"waku": {
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/ip4/8.210.222.231/tcp/30303/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD",
@@ -125,7 +137,7 @@
}
},
"meta": {
"hostname": "node-01.do-ams3.proxy.misc",
"timestamp": "2021-06-07T00:00:09.836740"
"hostname": "node-01.do-ams3.sites.misc",
"timestamp": "2021-12-06T00:00:15.242413"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

+4
View File
@@ -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"))
+4 -4
View File
@@ -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,7 +197,7 @@
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]
haptic-feedback haptic-type error animated animated-accessory? title-text-weight container-style]
:or {subtitle-max-lines 1
theme :main
haptic-feedback true
@@ -233,7 +233,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
View File
@@ -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
+5 -4
View File
@@ -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
+54 -19
View File
@@ -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
+26 -3
View File
@@ -288,7 +288,7 @@
(fx/defn edit-channel
{:events [::edit-channel-confirmation-pressed]}
[{:keys [db] :as cofx}]
(let [{:keys [name description color community-id emoji edit-channel-id category-id]}
(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]
+1
View File
@@ -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))
+1
View File
@@ -165,6 +165,7 @@
"wakuext_reorderCommunityChat" {}
"wakuext_editCommunityCategory" {}
"wakuext_deleteCommunityCategory" {}
"wakuext_deleteCommunityChat" {}
"wakuext_ensVerified" {}
"wakuext_dismissActivityCenterNotifications" {}
"wakuext_acceptActivityCenterNotifications" {}
+32 -5
View File
@@ -6,7 +6,7 @@
[status-im.async-storage.core :as async-storage]
status-im.backup.core
status-im.bootnodes.core
status-im.bottom-sheet.core
[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)})
+1 -1
View File
@@ -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)))
+1 -1
View File
@@ -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)
+8 -2
View File
@@ -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]}
+37 -7
View File
@@ -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))}))
+9 -2
View File
@@ -115,7 +115,10 @@
(vals (:static current-fleet))))
:RelayNodes wakuv2-nodes
:StoreNodes wakuv2-nodes
:RendezvousNodes (if wakuv2-enabled [] rendezvous-nodes)})
:FilterNodes wakuv2-nodes
:LightpushNodes wakuv2-nodes
:RendezvousNodes (if wakuv2-enabled [] rendezvous-nodes)
:WakuRendezvousNodes wakuv2-nodes})
:always
(assoc :WalletConfig {:Enabled true}
@@ -129,7 +132,11 @@
:BloomFilterMode waku-bloom-filter-mode
:LightClient true
:MinimumPoW 0.000001}
:WakuV2Config (assoc wakuv2-config :Enabled wakuv2-enabled :Host "0.0.0.0")
:WakuV2Config (assoc wakuv2-config
:Enabled wakuv2-enabled
:Rendezvous true
:PeerExchange true
:Host "0.0.0.0")
:ShhextConfig
{:BackupDisabledDataDir (utils.platform/no-backup-directory)
:InstallationID installation-id
+9 -8
View File
@@ -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]}
+31 -24
View File
@@ -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]
@@ -877,6 +876,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 +918,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 +1417,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 +1431,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 +1444,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]]]))
+21 -20
View File
@@ -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
+5 -3
View File
@@ -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]
+4 -1
View File
@@ -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]
+4 -26
View File
@@ -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]]]))
-5
View File
@@ -288,11 +288,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}}
@@ -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)
+1
View File
@@ -52,6 +52,7 @@
(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")))
;; CONFIG VALUES
(def log-level
+3 -3
View File
@@ -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/wakuv2-rendezvous",
"commit-sha1": "2062cfa40075ab72fb4e7d6d6dd6d4a96093d901",
"src-sha256": "0bpcswrzp8dyp6mniajyjiszbvkzilvqnkh3pp6vjlj4pjj7ba12"
}
+3 -3
View File
@@ -42,11 +42,11 @@ rlp==1.2.0
sauceclient==1.0.0
scrypt==0.8.17
selenium==3.14.1
six==1.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
+2 -2
View File
@@ -12,14 +12,14 @@ RERUN_ERRORS = [
'failed to start the browser or device',
'ERROR The test with session id',
"503 Service Unavailable",
# "object has no attribute",
"object has no attribute",
"[Errno 104] Connection reset by peer",
"Sauce could not start your job",
"HTTP Error 303",
"http.client.RemoteDisconnected: Remote end closed connection without response",
"[Errno 110] Connection timed out",
"replacement transaction underpriced",
# "StaleElementReferenceException",
"StaleElementReferenceException",
"'GetStartedButton' is not found on the screen",
"'AccessKeyButton' is not found on the screen",
"'SignInPhraseText' is not found on the screen"
+4 -3
View File
@@ -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)
+66 -108
View File
@@ -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):
+22 -14
View File
@@ -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()
+1
View File
@@ -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')]")
+18 -2
View File
@@ -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):
+3 -3
View File
@@ -195,7 +195,7 @@ class HomeView(BaseView):
self.notifications_accept_and_add_button = Button(self.driver,
accessibility_id="accept-and-add-activity-center")
self.notifications_select_all = Button(self.driver, xpath="(//android.widget.CheckBox["
"@content-desc='checkbox'])[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()
+1
View File
@@ -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):
+2 -2
View File
@@ -176,7 +176,7 @@ class SignInView(BaseView):
self.driver.info("## Creating new multiaccount (password:'%s', keycard:'%s')" % (password, str(keycard)),
device=False)
if not second_user:
self.accept_tos_checkbox.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()
+3 -5
View File
@@ -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):
+4 -3
View File
@@ -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,6 @@
"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"
}
+5
View File
@@ -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"