Improved Start New Private Chat interface

Signed-off-by: Brian Sztamfater <brian@status.im>
This commit is contained in:
Brian Sztamfater 2021-03-29 19:46:50 -03:00 committed by Brian Sztamfater
parent eea5b4eb0f
commit 31ba933917
No known key found for this signature in database
GPG Key ID: 59EB921E0706B48F
4 changed files with 134 additions and 60 deletions

View File

@ -83,7 +83,7 @@
[icons/icon icon {:color icon-color}]])])))
(defn title-column
[{:keys [title text-color subtitle subtitle-max-lines
[{:keys [title text-color subtitle subtitle-max-lines subtitle-secondary
title-accessibility-label size text-size title-text-weight
right-side-present?]}]
[rn/view {:style (merge (:tiny spacing/padding-horizontal)
@ -105,14 +105,37 @@
:size text-size}
title]
title)
(if (string? subtitle)
[text/text {:weight :regular
:color :secondary
:ellipsize-mode :tail
:number-of-lines subtitle-max-lines
:size text-size}
subtitle]
subtitle)]
(if (string? subtitle-secondary)
[rn/view {:flex-direction :row}
[text/text {:style {:max-width "56.5%"}
:weight :regular
:color :secondary
:ellipsize-mode :tail
:number-of-lines subtitle-max-lines
:size text-size}
subtitle]
[text/text {:style {:width "7%" :text-align :center}
:weight :regular
:color :secondary
:ellipsize-mode :middle
:number-of-lines subtitle-max-lines
:size text-size}
"•"]
[text/text {:style {:max-width "36.5%"}
:weight :regular
:color :secondary
:ellipsize-mode :middle
:number-of-lines subtitle-max-lines
:size text-size}
subtitle-secondary]]
(if (string? subtitle)
[text/text {:weight :regular
:color :secondary
:ellipsize-mode :tail
:number-of-lines subtitle-max-lines
:size text-size}
subtitle]
subtitle))]
title
(if (string? title)
@ -170,7 +193,7 @@
(defn list-item
[{:keys [theme accessory disabled subtitle-max-lines icon icon-container-style
left-side-alignment
title subtitle active on-press on-long-press chevron size text-size
title subtitle subtitle-secondary active on-press on-long-press chevron size text-size
accessory-text accessibility-label title-accessibility-label
haptic-feedback haptic-type error animated animated-accessory? title-text-weight]
:or {subtitle-max-lines 1
@ -223,6 +246,7 @@
:text-size text-size
:subtitle subtitle
:subtitle-max-lines subtitle-max-lines
:subtitle-secondary subtitle-secondary
:right-side-present? (or accessory chevron)}]
[right-side {:chevron chevron
:active active

View File

@ -13,17 +13,22 @@
[status-im.ui.components.topbar :as topbar]
[status-im.utils.debounce :as debounce]
[status-im.utils.utils :as utils]
[reagent.core :as reagent])
[reagent.core :as reagent]
[quo.react-native :as rn]
[clojure.string :as string]
[status-im.ui.components.invite.views :as invite]
[status-im.ethereum.ens :as ens]
[quo.platform :as platform]
[status-im.transport.filters.core :as filters]
[status-im.utils.identicon :as identicon])
(:require-macros [status-im.utils.views :as views]))
(defn- render-row [row]
(let [[first-name second-name] (multiaccounts/contact-two-names row false)]
(let [first-name (first (multiaccounts/contact-two-names row false))]
[quo/list-item
{:title first-name
:subtitle second-name
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo row)]
:chevron true
:on-press #(re-frame/dispatch [:chat.ui/start-chat
(:public-key row)])}]))
@ -57,13 +62,33 @@
(defn get-validation-label [value]
(case value
:invalid
(i18n/label :t/user-not-found)
(i18n/label :t/profile-not-found)
:yourself
(i18n/label :t/can-not-add-yourself)))
(defn search-contacts [filter-text {:keys [name alias nickname]}]
(or
(string/includes? (string/lower-case (str name)) filter-text)
(string/includes? (string/lower-case (str alias)) filter-text)
(when nickname
(string/includes? (string/lower-case (str nickname)) filter-text))))
(defn filter-contacts [filter-text contacts]
(let [lower-filter-text (string/lower-case filter-text)]
(if filter-text
(filter (partial search-contacts lower-filter-text) contacts)
contacts)))
(defn is-valid-username? [username]
(let [is-chat-key? (and (filters/is-public-key? username)
(= (count username) 132))
is-ens? (ens/valid-eth-name-prefix? username)]
(or is-chat-key? is-ens?)))
(views/defview new-chat []
(views/letsubs [contacts [:contacts/active]
{:keys [state ens-name public-key error]} [:contacts/new-identity]]
{:keys [state ens-name public-key error]} [:contacts/new-identity]
search-value (reagent/atom "")]
[react/view {:style {:flex 1}}
[topbar/topbar
{:title (i18n/label :t/new-chat)
@ -76,11 +101,11 @@
:handler :contact/qr-code-scanned}])}]}]
[react/view {:flex-direction :row
:padding 16}
[react/view {:flex 1
:padding-right 16}
[react/view {:flex 1}
[quo/text-input
{:on-change-text
#(do
(reset! search-value %)
(re-frame/dispatch [:set-in [:contacts/new-identity :state] :searching])
(debounce/debounce-and-dispatch [:new-chat/set-new-identity %] 600))
:on-submit-editing
@ -90,35 +115,59 @@
:show-cancel false
:accessibility-label :enter-contact-code-input
:auto-capitalize :none
:return-key-type :go}]]
[react/view {:justify-content :center
:align-items :center}
[input-icon state false nil]]]
[react/view {:min-height 30 :justify-content :flex-end}
[quo/text {:style {:margin-horizontal 16}
:size :small
:align :center
:color :secondary}
(cond (= state :error)
(get-validation-label error)
(= state :valid)
(str (if ens-name
ens-name
(gfycat/generate-gfy public-key))
" • ")
:else "")
(when (= state :valid)
[quo/text {:monospace true
:size :inherit
:color :inherit}
(utils/get-shortened-address public-key)])]]
[list/flat-list {:data contacts
:key-fn :address
:render-fn render-row
:enableEmptySections true
:keyboardShouldPersistTaps :always}]]))
:return-key-type :go
:monospace true}]]]
[react/view (if (and
(= (count contacts) 0)
(= @search-value ""))
{:flex 1}
{:justify-content :flex-end})
(if (and
(= (count contacts) 0)
(= @search-value ""))
[react/view {:flex 1
:align-items :center
:padding-horizontal 58
:padding-top 160}
[quo/text {:size :base
:align :center
:color :secondary}
(i18n/label :t/you-dont-have-contacts-invite-friends)]
[invite/button]]
[list/flat-list {:data (filter-contacts @search-value contacts)
:key-fn :address
:render-fn render-row
:enableEmptySections true
:keyboardShouldPersistTaps :always}])]
(when-not (= @search-value "")
[react/view
[quo/text {:style {:margin-horizontal 16
:margin-vertical 14}
:size :base
:align :left
:color :secondary}
(i18n/label :t/non-contacts)]
(when (and (= state :searching)
(is-valid-username? @search-value))
[rn/activity-indicator {:color colors/gray
:size (if platform/android? :large :small)}])
(if (= state :valid)
[quo/list-item
(merge
{:title (or ens-name (gfycat/generate-gfy public-key))
:subtitle (if ens-name (gfycat/generate-gfy public-key) (utils/get-shortened-address public-key))
:icon [chat-icon/contact-icon-contacts-tab
(identicon/identicon public-key)]
:on-press #(re-frame/dispatch [:chat.ui/start-chat public-key])}
(when ens-name {:subtitle-secondary public-key}))]
[quo/text {:style {:margin-horizontal 16}
:size :base
:align :center
:color :secondary}
(if (is-valid-username? @search-value)
(when (= state :error)
(get-validation-label error))
(i18n/label :t/invalid-username-or-key))])])]))
(defn- nickname-input [entered-nickname]
[quo/text-input

View File

@ -95,13 +95,13 @@ class TestChatManagement(SingleDeviceTestCase):
chat.public_key_edit_box.clear()
chat.public_key_edit_box.set_value(invalid_chat_key)
chat.confirm()
if not home.element_by_translation_id("user-not-found").is_element_displayed():
if not home.element_by_translation_id("profile-not-found").is_element_displayed():
self.errors.append('Error is not shown for invalid public key')
home.just_fyi("Check that valid ENS is resolved")
chat.public_key_edit_box.clear()
chat.public_key_edit_box.set_value(ens_user_ropsten['ens'])
resolved_ens = chat.get_resolved_chat_key('%s.stateofus.eth' % ens_user_ropsten['ens'], ens_user_ropsten['public_key'])
resolved_ens = '%s.stateofus.eth' % ens_user_ropsten['ens']
if not chat.element_by_text(resolved_ens).is_element_displayed(10):
self.errors.append('ENS name is not resolved after pasting chat key')
home.back_button.click()
@ -116,8 +116,7 @@ class TestChatManagement(SingleDeviceTestCase):
chat.public_key_edit_box.paste_text_from_clipboard()
if chat.public_key_edit_box.text != public_key:
self.errors.append('Public key is not pasted from clipboard')
expected_resolved_name = chat.get_resolved_chat_key(basic_user['username'], public_key)
if not chat.element_by_text(expected_resolved_name).is_element_displayed():
if not chat.element_by_text(basic_user['username']).is_element_displayed():
self.errors.append('3 random-name is not resolved after pasting chat key')
chat.public_key_edit_box.click()
chat.confirm_until_presence_of_element(chat.chat_message_input)
@ -585,10 +584,9 @@ class TestChatManagementMultipleDevice(MultipleDeviceTestCase):
'Check that user is added to contacts below "Start new chat" and you redirected to 1-1 on tap')
home_1.plus_button.click()
home_1.start_new_chat_button.click()
for name in (nickname, username_2):
if not home_1.element_by_text(name).is_element_displayed():
home_1.driver.fail('List of contacts below "Start new chat" does not contain added user')
home_1.element_by_text(username_2).click()
if not home_1.element_by_text(nickname).is_element_displayed():
home_1.driver.fail('List of contacts below "Start new chat" does not contain added user')
home_1.element_by_text(nickname).click()
if not chat_1.chat_message_input.is_element_displayed():
home_1.driver.fail('No redirect to 1-1 chat if tap on Contact below "Start new chat"')
for element in (chat_1.chat_message_input, chat_1.element_by_text(nickname)):
@ -599,7 +597,7 @@ class TestChatManagementMultipleDevice(MultipleDeviceTestCase):
device_1.just_fyi('Remove user from contacts')
chat_1.profile_button.click()
userprofile = profile_1.open_contact_from_profile(username_2)
userprofile = profile_1.open_contact_from_profile(nickname)
userprofile.remove_from_contacts.click()
if userprofile.remove_from_contacts.is_element_displayed():
self.errors.append("'Remove from contacts' is not changed to 'Add to contacts'")
@ -608,7 +606,7 @@ class TestChatManagementMultipleDevice(MultipleDeviceTestCase):
device_1.just_fyi('Check that user is removed from contact list in profile')
userprofile.back_button.click()
if profile_1.element_by_text(username_2).is_element_displayed():
if profile_1.element_by_text(nickname).is_element_displayed():
self.errors.append('List of contacts in profile contains removed user')
profile_1.home_button.click(desired_view='chat')
if not chat_1.add_to_contacts.is_element_displayed():

View File

@ -503,7 +503,7 @@
"enter-a-private-key": "Enter a private key",
"enter-a-seed-phrase": "Enter a seed phrase",
"enter-address": "Enter address",
"enter-contact-code": "Enter ENS username or chat key",
"enter-contact-code": "ENS (vitalik94) or chat key (0x04…)",
"enter-pair-code": "Enter your pairing code",
"pair-code-placeholder": "Pair code...",
"enter-pair-code-description": "Pairing code was displayed to you during the Keycard setup",
@ -640,6 +640,7 @@
"invalid-number": "Invalid number",
"invalid-pairing-password": "Invalid pairing password",
"invalid-range": "Invalid format, must be between {{min}} and {{max}}",
"invalid-username-or-key": "Invalid username or chat key",
"join-me": "Hey join me on Status: {{url}}",
"join-a-community": "or join a community",
"http-gateway-error": "Oops, request failed!",
@ -1304,6 +1305,7 @@
"you-are-all-set-description": "If you lose your phone, you can now access your funds and chat key using your seed phrase",
"you-can-change-account": "You can change the account name and color to what you wish",
"you-dont-have-stickers": "You dont have any stickers yet",
"you-dont-have-contacts-invite-friends": "You dont have any contacts yet.\nInvite your friends to start chatting.",
"your-contact-code": "Granting access authorizes this DApp to retrieve your chat key",
"your-data-belongs-to-you": "If you lose your seed phrase you lose your data and funds",
"your-data-belongs-to-you-description": "If you lose access, for example by losing your phone, you can only access your keys with your seed phrase. No one, but you has your seed phrase. Write it down. Keep it safe",
@ -1338,7 +1340,7 @@
"add-seed-account": "Add account with a seed phrase",
"account-exists-title": "Account already exists",
"add-private-key-account": "Add account from private key",
"user-not-found": "User not found",
"profile-not-found": "Profile not found",
"waku-bloom-filter-mode": "Waku bloom filter mode",
"appearance": "Appearance",
"preference": "Preference",
@ -1496,5 +1498,6 @@
"rpc-usage-reset": "Reset",
"rpc-usage-filter": "Filter methods",
"rpc-usage-copy": "Copy",
"community-message-preview": "Invitation to join {{community-name}}"
"community-message-preview": "Invitation to join {{community-name}}",
"non-contacts": "Non contacts"
}