Resolve ENS name in chats and profiles

Signed-off-by: Julien Eluard <julien.eluard@gmail.com>
This commit is contained in:
Julien Eluard 2019-06-25 10:05:25 +02:00
parent 73531b255b
commit e1bcaebd2c
No known key found for this signature in database
GPG Key ID: 6FD7DB5437FCBEF6
15 changed files with 69 additions and 52 deletions

View File

@ -1,6 +1,7 @@
(ns status-im.accounts.core (ns status-im.accounts.core
(:require [re-frame.core :as re-frame] (:require [re-frame.core :as re-frame]
[status-im.accounts.update.core :as accounts.update] [status-im.accounts.update.core :as accounts.update]
[status-im.ethereum.ens :as ens]
[status-im.ethereum.stateofus :as stateofus] [status-im.ethereum.stateofus :as stateofus]
[status-im.i18n :as i18n] [status-im.i18n :as i18n]
[status-im.native-module.core :as native-module] [status-im.native-module.core :as native-module]
@ -12,12 +13,12 @@
[status-im.utils.platform :as platform] [status-im.utils.platform :as platform]
[status-im.utils.utils :as utils])) [status-im.utils.utils :as utils]))
(defn displayed-name [{:keys [ens-name nickname public-key]}] (defn displayed-name [account]
(or nickname (let [name (or (:preferred-name account) (:name account))]
(when ens-name (if (ens/is-valid-eth-name? name)
(let [username (stateofus/username ens-name)] (let [username (stateofus/username name)]
(str "@" (or username ens-name)))) (str "@" (or username name)))
(gfycat/generate-gfy public-key))) (or name (gfycat/generate-gfy (:public-key account))))))
(re-frame/reg-fx (re-frame/reg-fx
::chaos-mode-changed ::chaos-mode-changed

View File

@ -11,8 +11,8 @@
(fx/defn account-update-message [{:keys [db] :as cofx}] (fx/defn account-update-message [{:keys [db] :as cofx}]
(let [account (:account/account db) (let [account (:account/account db)
fcm-token (get-in db [:notifications :fcm-token]) fcm-token (get-in db [:notifications :fcm-token])
{:keys [name photo-path address]} account] {:keys [name preferred-name photo-path address]} account]
(message.contact/ContactUpdate. name photo-path address fcm-token (device-info/all cofx)))) (message.contact/ContactUpdate. (or preferred-name name) photo-path address fcm-token (device-info/all cofx))))
(fx/defn send-account-update [cofx] (fx/defn send-account-update [cofx]
(protocol/send (protocol/send

View File

@ -124,7 +124,9 @@
[input-text current-chat-id {:keys [db] :as cofx}] [input-text current-chat-id {:keys [db] :as cofx}]
(when-not (string/blank? input-text) (when-not (string/blank? input-text)
(let [{:keys [message-id old-message-id]} (let [{:keys [message-id old-message-id]}
(get-in db [:chats current-chat-id :metadata :responding-to-message])] (get-in db [:chats current-chat-id :metadata :responding-to-message])
show-name? (get-in db [:account/account :show-name?])
preferred-name (when show-name? (get-in db [:account/account :preferred-name]))]
(fx/merge cofx (fx/merge cofx
{:db (assoc-in db [:chats current-chat-id :metadata :responding-to-message] nil)} {:db (assoc-in db [:chats current-chat-id :metadata :responding-to-message] nil)}
(chat.message/send-message {:chat-id current-chat-id (chat.message/send-message {:chat-id current-chat-id
@ -133,7 +135,9 @@
:text input-text} :text input-text}
message-id message-id
(assoc :response-to old-message-id (assoc :response-to old-message-id
:response-to-v2 message-id))}) :response-to-v2 message-id)
preferred-name
(assoc :name preferred-name))})
(commands.input/set-command-reference nil) (commands.input/set-command-reference nil)
(set-chat-input-text nil) (set-chat-input-text nil)
(process-cooldown))))) (process-cooldown)))))

View File

@ -34,9 +34,9 @@
(defn- own-info (defn- own-info
[db] [db]
(let [{:keys [name photo-path address]} (:account/account db) (let [{:keys [name preferred-name photo-path address]} (:account/account db)
fcm-token (get-in db [:notifications :fcm-token])] fcm-token (get-in db [:notifications :fcm-token])]
{:name name {:name (or preferred-name name)
:profile-image photo-path :profile-image photo-path
:address address :address address
:device-info (device-info/all {:db db}) :device-info (device-info/all {:db db})

View File

@ -121,7 +121,14 @@
[{:keys [db] :as cofx} name] [{:keys [db] :as cofx} name]
(fx/merge (assoc-in cofx [:db :account/account :preferred-name] name) (fx/merge (assoc-in cofx [:db :account/account :preferred-name] name)
(accounts.update/account-update cofx (accounts.update/account-update cofx
{:preferred-name name}))) {:preferred-name name})
(accounts.update/send-account-update)))
(fx/defn save-preferred-name-when-first
[cofx names name]
(when (= 1 (count names))
;; First name, save it as default
(save-preferred-name cofx name)))
(fx/defn save-username (fx/defn save-username
{:events [:ens/save-username]} {:events [:ens/save-username]}
@ -133,9 +140,7 @@
(accounts.update/account-update cofx (accounts.update/account-update cofx
{:usernames names} {:usernames names}
{:success-event [:ens/set-state username :saved]}) {:success-event [:ens/set-state username :saved]})
(when (= 1 (count names)) (save-preferred-name-when-first names name))))
;; First name, save it as default
(save-preferred-name cofx name)))))
(fx/defn switch-show-username (fx/defn switch-show-username
{:events [:ens/switch-show-username]} {:events [:ens/switch-show-username]}

View File

@ -143,8 +143,7 @@
:on-success :on-success
(fn [[x y]] (fn [[x y]]
(let [public-key (uncompressed-public-key x y)] (let [public-key (uncompressed-public-key x y)]
(when-not (= public-key default-key) (cb public-key)))}))
(cb public-key))))}))
(defn get-addr (defn get-addr
[registry ens-name cb] [registry ens-name cb]

View File

@ -151,7 +151,7 @@
(defn- get-contact-name [{:keys [db] :as cofx} from] (defn- get-contact-name [{:keys [db] :as cofx} from]
(if (accounts.model/logged-in? cofx) (if (accounts.model/logged-in? cofx)
(accounts/displayed-name (hash->contact from (-> db :contacts/contacts vals))) (:name (hash->contact from (-> db :contacts/contacts vals)))
(anonymize-pubkey from))) (anonymize-pubkey from)))
(defn- build-notification [{:keys [title body decoded-payload]}] (defn- build-notification [{:keys [title body decoded-payload]}]

View File

@ -1,8 +1,7 @@
(ns ^{:doc "Contact request and update API"} (ns ^{:doc "Contact request and update API"}
status-im.transport.message.contact status-im.transport.message.contact
(:require [cljs.spec.alpha :as spec] (:require [cljs.spec.alpha :as spec]
[status-im.transport.message.protocol :as protocol] [status-im.transport.message.protocol :as protocol]))
[status-im.utils.fx :as fx]))
(defrecord ContactRequest [name profile-image address fcm-token device-info] (defrecord ContactRequest [name profile-image address fcm-token device-info]
protocol/StatusMessage protocol/StatusMessage

View File

@ -215,9 +215,9 @@
(if outgoing-status (if outgoing-status
[text-status outgoing-status])))))) [text-status outgoing-status]))))))
(defview message-author-name [from message-username name] (defview message-author-name [from name]
(letsubs [username [:contacts/contact-name-by-identity from]] (letsubs [username [:contacts/contact-name-by-identity from]]
(chat.utils/format-author from (or username message-username) style/message-author-name name))) (chat.utils/format-author from style/message-author-name name)))
(defn message-body (defn message-body
[{:keys [last-in-group? [{:keys [last-in-group?
@ -226,8 +226,7 @@
from from
outgoing outgoing
modal? modal?
username content] :as message} child]
name] :as message} content]
[react/view (style/group-message-wrapper message) [react/view (style/group-message-wrapper message)
[react/view (style/message-body message) [react/view (style/message-body message)
(when display-photo? (when display-photo?
@ -239,9 +238,9 @@
[react/view (style/group-message-view outgoing display-photo?) [react/view (style/group-message-view outgoing display-photo?)
(when display-username? (when display-username?
[react/touchable-opacity {:on-press #(re-frame/dispatch [:chat.ui/show-profile from])} [react/touchable-opacity {:on-press #(re-frame/dispatch [:chat.ui/show-profile from])}
[message-author-name from username name]]) [message-author-name from (:name content)]])
[react/view {:style (style/timestamp-content-wrapper outgoing)} [react/view {:style (style/timestamp-content-wrapper outgoing)}
content]]] child]]]
[react/view (style/delivery-status outgoing) [react/view (style/delivery-status outgoing)
[message-delivery-status message]]]) [message-delivery-status message]]])

View File

@ -1,5 +1,6 @@
(ns status-im.ui.screens.chat.utils (ns status-im.ui.screens.chat.utils
(:require [re-frame.core :as re-frame] (:require [re-frame.core :as re-frame]
[status-im.ethereum.ens :as ens]
[status-im.ethereum.stateofus :as stateofus] [status-im.ethereum.stateofus :as stateofus]
[status-im.utils.gfycat.core :as gfycat] [status-im.utils.gfycat.core :as gfycat]
[status-im.utils.platform :as platform] [status-im.utils.platform :as platform]
@ -9,11 +10,14 @@
[status-im.ui.components.colors :as colors] [status-im.ui.components.colors :as colors]
[status-im.utils.http :as http])) [status-im.utils.http :as http]))
(defn format-author [from username style ens-name] (defn format-author [from style name]
(cond (cond
ens-name (ens/is-valid-eth-name? name)
[react/text {:style {:color colors/blue :font-size 13 :font-weight "500"}} [react/text {:style {:color colors/blue :font-size 13 :font-weight "500"}}
(str "@" (or (stateofus/username ens-name) ens-name))] (str "@" (or (stateofus/username name) name))]
name
[react/text {:style {:color colors/blue :font-size 13 :font-weight "500"}}
name]
:else :else
[react/text {:style {:color colors/gray :font-size 12 :font-weight "400"}} [react/text {:style {:color colors/gray :font-size 12 :font-weight "400"}}
(gfycat/generate-gfy from)])) (gfycat/generate-gfy from)]))
@ -22,7 +26,7 @@
(or (and (= from current-public-key) (or (and (= from current-public-key)
[react/text {:style (style true)} [react/text {:style (style true)}
(i18n/label :t/You)]) (i18n/label :t/You)])
(format-author from username style nil))) (format-author from style nil)))
(def ^:private styling->prop (def ^:private styling->prop
{:bold {:style {:font-weight "700"}} {:bold {:style {:font-weight "700"}}

View File

@ -1,6 +1,7 @@
(ns status-im.ui.screens.chat.views (ns status-im.ui.screens.chat.views
(:require [re-frame.core :as re-frame] (:require [re-frame.core :as re-frame]
[reagent.core :as reagent] [reagent.core :as reagent]
[status-im.accounts.core :as accounts]
[status-im.contact.db :as contact.db] [status-im.contact.db :as contact.db]
[status-im.i18n :as i18n] [status-im.i18n :as i18n]
[status-im.tribute-to-talk.core :as tribute-to-talk] [status-im.tribute-to-talk.core :as tribute-to-talk]
@ -123,10 +124,10 @@
(str " " (i18n/label :learn-more))]]) (str " " (i18n/label :learn-more))]])
(defn intro-header (defn intro-header
[name] [contact]
[react/text {:style (assoc style/intro-header-description [react/text {:style (assoc style/intro-header-description
:margin-bottom 32)} :margin-bottom 32)}
(str (i18n/label :t/empty-chat-description-one-to-one) name)]) (str (i18n/label :t/empty-chat-description-one-to-one) (accounts/displayed-name contact))])
(defn join-chat-button [chat-id] (defn join-chat-button [chat-id]
[buttons/secondary-button [buttons/secondary-button
@ -278,7 +279,7 @@
(:paid :none) (:paid :none)
[react/view [react/view
[intro-header name] [intro-header contact]
(when (= tribute-status :paid) (when (= tribute-status :paid)
[pay-to-chat-messages snt-amount chat-id tribute-status tribute-label [pay-to-chat-messages snt-amount chat-id tribute-status tribute-label
fiat-amount fiat-currency token]) fiat-amount fiat-currency token])
@ -297,7 +298,7 @@
(i18n/label (if received? :tribute-to-talk-tribute-received2 (i18n/label (if received? :tribute-to-talk-tribute-received2
:tribute-to-talk-contact-received-your-tribute))]]])] :tribute-to-talk-contact-received-your-tribute))]]])]
[intro-header name])) [intro-header contact]))
(defn chat-intro-header-container (defn chat-intro-header-container
[{:keys [group-chat name pending-invite-inviter-name [{:keys [group-chat name pending-invite-inviter-name
@ -305,7 +306,7 @@
contact universal-link intro-status height input-height] :as chat} contact universal-link intro-status height input-height] :as chat}
no-messages] no-messages]
(let [icon-text (if public? chat-id name) (let [icon-text (if public? chat-id name)
intro-name (if public? chat-name name)] intro-name (if public? chat-name (accounts/displayed-name contact))]
;; TODO This when check ought to be unnecessary but for now it prevents ;; TODO This when check ought to be unnecessary but for now it prevents
;; jerky motion when fresh chat is created, when input-height can be null ;; jerky motion when fresh chat is created, when input-height can be null
;; affecting the calculation of content-layout-height to be briefly adjusted ;; affecting the calculation of content-layout-height to be briefly adjusted

View File

@ -32,19 +32,23 @@
(list-selection/show {:title (i18n/label :t/image-source-title) (list-selection/show {:title (i18n/label :t/image-source-title)
:options options}))) :options options})))
(defn- names [{:keys [name public-key] :as contact}]
(let [generated-name (when public-key (gfy/generate-gfy public-key))]
[react/view styles/profile-header-name-container
[react/text {:style styles/profile-name-text
:number-of-lines 1}
(accounts/displayed-name contact)]
(when generated-name
[react/text {:style styles/profile-three-words
:number-of-lines 1}
generated-name])]))
(defn- profile-header-display [{:keys [name public-key] :as contact}] (defn- profile-header-display [{:keys [name public-key] :as contact}]
(let [generated-name (when public-key (gfy/generate-gfy public-key))] (let [generated-name (when public-key (gfy/generate-gfy public-key))]
[react/view styles/profile-header-display [react/view styles/profile-header-display
[chat-icon.screen/my-profile-icon {:account contact [chat-icon.screen/my-profile-icon {:account contact
:edit? false}] :edit? false}]
[react/view styles/profile-header-name-container [names contact]]))
[react/text {:style styles/profile-name-text
:number-of-lines 1}
(accounts/displayed-name contact)]
(when (and public-key (not= generated-name name))
[react/text {:style styles/profile-three-words
:number-of-lines 1}
generated-name])]]))
(defn- profile-header-edit [{:keys [name group-chat] :as contact} (defn- profile-header-edit [{:keys [name group-chat] :as contact}
icon-options on-change-text-event allow-icon-change?] icon-options on-change-text-event allow-icon-change?]
@ -54,14 +58,12 @@
[react/view styles/modal-menu [react/view styles/modal-menu
[chat-icon.screen/my-profile-icon {:account contact [chat-icon.screen/my-profile-icon {:account contact
:edit? allow-icon-change?}]]] :edit? allow-icon-change?}]]]
[react/view styles/profile-header-name-container [names contact]])
[profile-name-input name on-change-text-event
(when group-chat {:accessibility-label :chat-name-input})]]])
(defn profile-header (defn profile-header
[{:keys [contact edited-contact editing? allow-icon-change? options on-change-text-event]}] [{:keys [contact edited-contact editing? allow-icon-change? options on-change-text-event]}]
(if editing? (if editing?
[profile-header-edit (or edited-contact contact) options on-change-text-event allow-icon-change?] [profile-header-edit (merge edited-contact contact) options on-change-text-event allow-icon-change?]
[profile-header-display contact])) [profile-header-display contact]))
;; settings items elements ;; settings items elements

View File

@ -2,6 +2,7 @@
(:require [clojure.string :as string] (:require [clojure.string :as string]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[reagent.core :as reagent] [reagent.core :as reagent]
[status-im.accounts.core :as accounts]
[status-im.i18n :as i18n] [status-im.i18n :as i18n]
[status-im.ui.components.button.view :as button] [status-im.ui.components.button.view :as button]
[status-im.ui.components.colors :as colors] [status-im.ui.components.colors :as colors]
@ -87,7 +88,7 @@
ttt-enabled? [:tribute-to-talk/enabled?]] ttt-enabled? [:tribute-to-talk/enabled?]]
[react/view styles/qr-code-viewer [react/view styles/qr-code-viewer
[status-bar/status-bar {:type :modal-white}] [status-bar/status-bar {:type :modal-white}]
[qr-viewer-toolbar (:name contact) value] [qr-viewer-toolbar (accounts/displayed-name contact) value]
[qr-code-viewer/qr-code-viewer [qr-code-viewer/qr-code-viewer
(merge (merge
{:style styles/qr-code {:style styles/qr-code

View File

@ -2,6 +2,7 @@
(:require-macros [status-im.utils.views :as views]) (:require-macros [status-im.utils.views :as views])
(:require [status-im.ui.components.react :as react] (:require [status-im.ui.components.react :as react]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[status-im.accounts.core :as accounts]
[status-im.ui.components.colors :as colors] [status-im.ui.components.colors :as colors]
[status-im.ui.components.animation :as anim] [status-im.ui.components.animation :as anim]
[reagent.core :as reagent] [reagent.core :as reagent]
@ -51,7 +52,7 @@
[list-item/list-item {:type :small [list-item/list-item {:type :small
:title (i18n/label :t/to) :title (i18n/label :t/to)
:accessories [[react/text {:ellipsize-mode :middle :number-of-lines 1 :style {:flex-wrap :wrap}} :accessories [[react/text {:ellipsize-mode :middle :number-of-lines 1 :style {:flex-wrap :wrap}}
(or (:name contact) (:address contact))]]}]) (accounts/displayed-name contact)]]}])
(defn token-item [{:keys [icon color] :as token} display-symbol] (defn token-item [{:keys [icon color] :as token} display-symbol]
(when token (when token
@ -82,7 +83,7 @@
[react/nested-text {:style {:color colors/gray} [react/nested-text {:style {:color colors/gray}
:ellipsize-mode :middle :ellipsize-mode :middle
:number-of-lines 1} (i18n/label :t/to) " " :number-of-lines 1} (i18n/label :t/to) " "
[{:style {:color colors/black}} (or (:name contact) (:address contact))]] [{:style {:color colors/black}} (accounts/displayed-name contact)]]
[react/text {:style {:margin-top 6 :color colors/gray}} [react/text {:style {:margin-top 6 :color colors/gray}}
(str fee " " fee-display-symbol " " (string/lower-case (i18n/label :t/network-fee)))])] (str fee " " fee-display-symbol " " (string/lower-case (i18n/label :t/network-fee)))])]
[react/touchable-highlight (when-not in-progress? {:on-press #(re-frame/dispatch [:signing.ui/cancel-is-pressed])}) [react/touchable-highlight (when-not in-progress? {:on-press #(re-frame/dispatch [:signing.ui/cancel-is-pressed])})

View File

@ -2,6 +2,7 @@
(:require [clojure.string :as string] (:require [clojure.string :as string]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[reagent.core :as reagent] [reagent.core :as reagent]
[status-im.accounts.core :as accounts]
[status-im.ethereum.core :as ethereum] [status-im.ethereum.core :as ethereum]
[status-im.ethereum.eip55 :as eip55] [status-im.ethereum.eip55 :as eip55]
[status-im.ethereum.tokens :as tokens] [status-im.ethereum.tokens :as tokens]
@ -196,7 +197,7 @@
[photos/photo (:photo-path contact) {:size list.styles/image-size}] [photos/photo (:photo-path contact) {:size list.styles/image-size}]
[list/item-content [list/item-content
[list/item-primary {:accessibility-label :contact-name-text} [list/item-primary {:accessibility-label :contact-name-text}
(:name contact)] (accounts/displayed-name contact)]
[react/text {:style list.styles/secondary-text [react/text {:style list.styles/secondary-text
:accessibility-label :contact-address-text} :accessibility-label :contact-address-text}
(eip55/address->checksum (ethereum/normalized-address (:address contact)))]]]]) (eip55/address->checksum (ethereum/normalized-address (:address contact)))]]]])