Improved Start New Private Chat interface
Signed-off-by: Brian Sztamfater <brian@status.im>
This commit is contained in:
parent
eea5b4eb0f
commit
31ba933917
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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 don’t have any stickers yet",
|
||||
"you-dont-have-contacts-invite-friends": "You don’t 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"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue