This commit is contained in:
parent
69c3a72357
commit
80f063d0dd
|
@ -0,0 +1,67 @@
|
|||
(ns quo2.components.list-items.user-list
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.components.avatars.user-avatar :as user-avatar]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.messages.author.view :as author]
|
||||
[quo2.components.selectors.selectors :as selectors]))
|
||||
|
||||
(def container-style
|
||||
{:margin-horizontal 8
|
||||
:padding-vertical 8
|
||||
:padding-horizontal 12
|
||||
:border-radius 12
|
||||
:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(defn action-icon
|
||||
[{:keys [type on-press on-check disabled? checked?]}]
|
||||
[rn/touchable-opacity
|
||||
{:on-press (when on-press on-press)
|
||||
:style {:position :absolute :right 20}}
|
||||
(case type
|
||||
:options
|
||||
[icons/icon :i/options
|
||||
{:size 20
|
||||
:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]
|
||||
:checkbox
|
||||
[selectors/checkbox
|
||||
{:checked? checked?
|
||||
:accessibility-label :user-list-toggle-check
|
||||
:disabled? disabled?
|
||||
:on-change (when on-check on-check)}]
|
||||
:close
|
||||
[text/text "not implemented"]
|
||||
[rn/view])])
|
||||
|
||||
(defn user-list
|
||||
[{:keys [short-chat-key primary-name secondary-name photo-path online? contact? verified?
|
||||
untrustworthy? on-press on-long-press accessory]}]
|
||||
[rn/touchable-opacity
|
||||
{:style container-style
|
||||
:accessibility-label :user-list
|
||||
:on-press (when on-press on-press)
|
||||
:on-long-press (when on-long-press on-long-press)}
|
||||
[user-avatar/user-avatar
|
||||
{:full-name primary-name
|
||||
:profile-picture photo-path
|
||||
:status-indicator? true
|
||||
:online? online?
|
||||
:size :small
|
||||
:ring? false}]
|
||||
[rn/view {:style {:margin-left 8}}
|
||||
[author/author
|
||||
{:primary-name primary-name
|
||||
:secondary-name secondary-name
|
||||
:contact? contact?
|
||||
:verified? verified?
|
||||
:untrustworthy? untrustworthy?}]
|
||||
(when short-chat-key
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}}
|
||||
short-chat-key])]
|
||||
(when accessory
|
||||
[action-icon accessory])])
|
|
@ -7,14 +7,6 @@
|
|||
:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(defn ens-text
|
||||
[]
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white)})
|
||||
|
||||
(defn nickname-text
|
||||
[]
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white)})
|
||||
|
||||
(def middle-dot-nickname
|
||||
{:color colors/neutral-50
|
||||
:margin-horizontal 4})
|
||||
|
@ -27,12 +19,6 @@
|
|||
{:color colors/neutral-50
|
||||
:margin-left 4})
|
||||
|
||||
(defn profile-name-text
|
||||
[nickname?]
|
||||
{:color (if nickname?
|
||||
(colors/theme-colors colors/neutral-60 colors/neutral-40)
|
||||
(colors/theme-colors colors/neutral-100 colors/white))})
|
||||
|
||||
(def icon-container
|
||||
{:margin-left 4})
|
||||
|
||||
|
|
|
@ -3,66 +3,33 @@
|
|||
[quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.messages.author.style :as style]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[quo2.foundations.colors :as colors]))
|
||||
|
||||
(def middle-dot "·")
|
||||
|
||||
(defn display-name
|
||||
[{:keys [profile-name nickname ens-name text-style]}]
|
||||
(let [ens? (-> ens-name string/blank? not)
|
||||
nickname? (-> nickname string/blank? not)]
|
||||
(if ens?
|
||||
[text/text
|
||||
(merge {:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:style (style/ens-text)}
|
||||
text-style)
|
||||
ens-name]
|
||||
[:<>
|
||||
(if nickname?
|
||||
[text/text
|
||||
(merge {:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:style (style/nickname-text)}
|
||||
text-style)
|
||||
nickname]
|
||||
[text/text
|
||||
(merge {:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:style (style/profile-name-text nickname?)}
|
||||
text-style)
|
||||
profile-name])])))
|
||||
|
||||
(defn author
|
||||
[{:keys [profile-name nickname short-chat-key ens-name time-str contact? verified? untrustworthy?]}]
|
||||
[{:keys [primary-name secondary-name short-chat-key time-str contact? verified? untrustworthy?]}]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [ens? (-> ens-name string/blank? not)
|
||||
nickname? (-> nickname string/blank? not)]
|
||||
[rn/view {:style style/container}
|
||||
(if ens?
|
||||
[text/text
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:style (style/ens-text)}
|
||||
ens-name]
|
||||
[:<>
|
||||
(when nickname?
|
||||
[:<>
|
||||
[text/text
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:style (style/nickname-text)}
|
||||
nickname]
|
||||
:style {:color (colors/theme-colors colors/neutral-100 colors/white)}}
|
||||
primary-name]
|
||||
(when (not (string/blank? secondary-name))
|
||||
[:<>
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style style/middle-dot-nickname}
|
||||
middle-dot]])
|
||||
middle-dot]
|
||||
[text/text
|
||||
{:weight (if nickname? :medium :semi-bold)
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (style/profile-name-text nickname?)}
|
||||
profile-name]])
|
||||
:style {:color (colors/theme-colors colors/neutral-60 colors/neutral-40)}}
|
||||
secondary-name]])]
|
||||
(when contact?
|
||||
[icons/icon :main-icons2/contact
|
||||
{:size 12
|
||||
|
@ -79,13 +46,13 @@
|
|||
{:size 12
|
||||
:no-color true
|
||||
:container-style style/icon-container}])
|
||||
(when-not ens?
|
||||
(when-not verified?
|
||||
[text/text
|
||||
{:monospace true
|
||||
:size :paragraph-2
|
||||
:style style/chat-key-text}
|
||||
short-chat-key])
|
||||
(when-not ens?
|
||||
(when (and (not verified?) time-str)
|
||||
[text/text
|
||||
{:monospace true
|
||||
:size :paragraph-2
|
||||
|
@ -95,5 +62,5 @@
|
|||
{:monospace true
|
||||
:size :paragraph-2
|
||||
:accessibility-label :message-timestamp
|
||||
:style (style/time-text ens?)}
|
||||
time-str]]))])
|
||||
:style (style/time-text verified?)}
|
||||
time-str]])])
|
||||
|
|
|
@ -62,7 +62,8 @@
|
|||
quo2.components.tags.permission-tag
|
||||
quo2.components.tags.tag
|
||||
quo2.components.tags.tags
|
||||
quo2.components.tags.token-tag))
|
||||
quo2.components.tags.token-tag
|
||||
quo2.components.list-items.user-list))
|
||||
|
||||
(def toast quo2.components.notifications.toast/toast)
|
||||
(def button quo2.components.buttons.button/button)
|
||||
|
@ -93,7 +94,6 @@
|
|||
(def filter quo2.components.selectors.filter.view/view)
|
||||
(def skeleton quo2.components.loaders.skeleton/skeleton)
|
||||
(def author quo2.components.messages.author.view/author)
|
||||
(def display-name quo2.components.messages.author.view/display-name)
|
||||
|
||||
;;;; AVATAR
|
||||
(def account-avatar quo2.components.avatars.account-avatar/account-avatar)
|
||||
|
@ -141,6 +141,7 @@
|
|||
(def channel-list-item quo2.components.list-items.channel/list-item)
|
||||
(def menu-item quo2.components.list-items.menu-item/menu-item)
|
||||
(def preview-list quo2.components.list-items.preview-list/preview-list)
|
||||
(def user-list quo2.components.list-items.user-list/user-list)
|
||||
|
||||
;;;; NOTIFICATIONS
|
||||
(def activity-log quo2.components.notifications.activity-log.view/view)
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
(defn- wrap-key-fn
|
||||
[f]
|
||||
(fn [data index]
|
||||
{:post [(some? %)]}
|
||||
(f data index)))
|
||||
(when f
|
||||
(f data index))))
|
||||
|
||||
(defn base-list-props
|
||||
[{:keys [key-fn render-fn empty-component header footer separator data render-data on-drag-end-fn]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
[re-frame.core :as re-frame]
|
||||
[status-im.add-new.db :as db]
|
||||
[status-im2.contexts.chat.events :as chat]
|
||||
[status-im.contact.core :as contact]
|
||||
[status-im2.contexts.contacts.events :as contact]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.ethereum.ens :as ens]
|
||||
[status-im.ethereum.stateofus :as stateofus]
|
||||
|
|
|
@ -41,11 +41,11 @@
|
|||
|
||||
(rf/defn select-mention
|
||||
{:events [:chat.ui/select-mention]}
|
||||
[{:keys [db] :as cofx} text-input-ref {:keys [alias name searched-text match] :as user}]
|
||||
[{:keys [db] :as cofx} text-input-ref {:keys [primary-name searched-text match] :as user}]
|
||||
(let [chat-id (:current-chat-id db)
|
||||
new-text (mentions/new-input-text-with-mention cofx user)
|
||||
at-sign-idx (get-in db [:chats/mentions chat-id :mentions :at-sign-idx])
|
||||
cursor (+ at-sign-idx (count name) 2)]
|
||||
cursor (+ at-sign-idx (count primary-name) 2)]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
|
@ -64,14 +64,13 @@
|
|||
;; programmatically, so we have to call `on-text-input` manually
|
||||
(mentions/on-text-input
|
||||
(let [match-len (count match)
|
||||
searched-text-len (count searched-text)
|
||||
start (inc at-sign-idx)
|
||||
end (+ start match-len)]
|
||||
{:new-text match
|
||||
:previous-text searched-text
|
||||
:start start
|
||||
:end end}))
|
||||
(mentions/recheck-at-idxs {alias user}))))
|
||||
(mentions/recheck-at-idxs {primary-name user}))))
|
||||
|
||||
(rf/defn disable-chat-cooldown
|
||||
"Turns off chat cooldown (protection against message spamming)"
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
(get-in db [:pagination-info chat-id :messages-initialized?])))
|
||||
(let [already-loaded-messages (get-in db [:messages chat-id])
|
||||
;; We remove those messages that are already loaded, as we might get some duplicates
|
||||
{:keys [all-messages new-messages senders contacts]}
|
||||
{:keys [all-messages new-messages contacts]}
|
||||
(reduce (fn [{:keys [all-messages] :as acc}
|
||||
{:keys [message-id from]
|
||||
:as message}]
|
||||
|
@ -143,13 +143,11 @@
|
|||
:cursor-clock-value])
|
||||
clock-value (when cursor (cursor->clock-value cursor))
|
||||
new-messages (map mark-album new-messages)]
|
||||
{:dispatch [:chat/add-senders-to-chat-users (vals senders)]
|
||||
:db (-> db
|
||||
{:db (-> db
|
||||
(update-in [:pagination-info chat-id :cursor-clock-value]
|
||||
#(if (and (seq cursor) (or (not %) (< clock-value %)))
|
||||
clock-value
|
||||
%))
|
||||
|
||||
(update-in [:pagination-info chat-id :cursor]
|
||||
#(if (or (empty? cursor)
|
||||
(not current-clock-value)
|
||||
|
|
|
@ -9,13 +9,10 @@
|
|||
[status-im.native-module.core :as status]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.utils :as utils]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def at-sign "@")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn re-pos
|
||||
[re s]
|
||||
(loop [res []
|
||||
|
@ -177,10 +174,9 @@
|
|||
|
||||
:else (recur data (inc idx)))))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn add-searchable-phrases
|
||||
[{:keys [alias name nickname] :as user}]
|
||||
(defn add-searchable-phrases-to-contact
|
||||
[{:keys [primary-name secondary-name blocked?] :as contact}]
|
||||
(when (not blocked?)
|
||||
(reduce
|
||||
(fn [user s]
|
||||
(if (nil? s)
|
||||
|
@ -189,31 +185,14 @@
|
|||
[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 ens-verified]} community-chat?]
|
||||
(when (and alias
|
||||
(not (string/blank? alias))
|
||||
(or name
|
||||
nickname
|
||||
added?
|
||||
community-chat?)
|
||||
(not blocked?))
|
||||
(add-searchable-phrases
|
||||
{:alias alias
|
||||
:name (or (and ens-verified (utils/safe-replace name ".stateofus.eth" "")) alias)
|
||||
:identicon identicon
|
||||
:nickname nickname
|
||||
:ens-verified ens-verified
|
||||
:public-key public-key})))
|
||||
contact
|
||||
[primary-name secondary-name])))
|
||||
|
||||
(defn mentionable-contacts
|
||||
[contacts]
|
||||
(reduce
|
||||
(fn [acc [key contact]]
|
||||
(let [mentionable-contact (add-searchable-phrases-to-contact contact false)]
|
||||
(let [mentionable-contact (add-searchable-phrases-to-contact contact)]
|
||||
(if (nil? mentionable-contact)
|
||||
acc
|
||||
(assoc acc key mentionable-contact))))
|
||||
|
@ -223,17 +202,8 @@
|
|||
(defn mentionable-contacts-from-identites
|
||||
[contacts my-public-key identities]
|
||||
(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)]
|
||||
(let [contact (multiaccounts/contact-by-identity contacts identity)
|
||||
mentionable-contact (add-searchable-phrases-to-contact contact)]
|
||||
(if (nil? mentionable-contact)
|
||||
acc
|
||||
(assoc acc identity mentionable-contact))))
|
||||
|
@ -247,8 +217,8 @@
|
|||
mentionable-contacts (mentionable-contacts all-contacts)
|
||||
mentionable-users (assoc users
|
||||
public-key
|
||||
{:alias name
|
||||
:name (or preferred-name name)
|
||||
{:secondary-name name
|
||||
:primary-name (or preferred-name name)
|
||||
:public-key public-key})]
|
||||
(cond
|
||||
(= chat-type constants/private-group-chat-type)
|
||||
|
@ -273,30 +243,31 @@
|
|||
(= chat-type constants/public-chat-type)
|
||||
(merge mentionable-users (select-keys mentionable-contacts (keys mentionable-users)))
|
||||
|
||||
:else mentionable-users)))
|
||||
:else
|
||||
mentionable-users)))
|
||||
|
||||
(def ending-chars "[\\s\\.,;:]")
|
||||
(def ending-chars-regex (re-pattern ending-chars))
|
||||
(def word-regex (re-pattern (str "^[\\w\\d]*" ending-chars "|^[\\S]*$")))
|
||||
|
||||
(defn mentioned?
|
||||
[{:keys [alias name]} text]
|
||||
(let [lcase-name (string/lower-case name)
|
||||
lcase-alias (string/lower-case alias)
|
||||
[{:keys [primary-name secondary-name]} text]
|
||||
(let [lcase-fname (string/lower-case primary-name)
|
||||
lcase-sname (when secondary-name (string/lower-case secondary-name))
|
||||
regex (re-pattern
|
||||
(string/join
|
||||
"|"
|
||||
[(str "^" lcase-name ending-chars)
|
||||
(str "^" lcase-name "$")
|
||||
(str "^" lcase-alias ending-chars)
|
||||
(str "^" lcase-alias "$")]))
|
||||
[(str "^" lcase-fname ending-chars)
|
||||
(str "^" lcase-fname "$")
|
||||
(str "^" lcase-sname ending-chars)
|
||||
(str "^" lcase-sname "$")]))
|
||||
lcase-text (string/lower-case text)]
|
||||
(re-find regex lcase-text)))
|
||||
|
||||
(defn get-user-suggestions
|
||||
[users searched-text]
|
||||
(reduce
|
||||
(fn [acc [k {:keys [alias name nickname searchable-phrases] :as user}]]
|
||||
(fn [acc [k {:keys [primary-name secondary-name searchable-phrases] :as user}]]
|
||||
(if-let [match
|
||||
(if (seq searchable-phrases)
|
||||
(when (some
|
||||
|
@ -305,27 +276,23 @@
|
|||
(string/lower-case s)
|
||||
searched-text))
|
||||
searchable-phrases)
|
||||
(or name alias))
|
||||
(or primary-name secondary-name))
|
||||
(cond
|
||||
(and nickname
|
||||
(and primary-name
|
||||
(string/starts-with?
|
||||
(string/lower-case nickname)
|
||||
(string/lower-case primary-name)
|
||||
searched-text))
|
||||
(or name alias)
|
||||
(or primary-name secondary-name)
|
||||
|
||||
(and alias
|
||||
(and secondary-name
|
||||
(string/starts-with?
|
||||
(string/lower-case alias)
|
||||
(string/lower-case secondary-name)
|
||||
searched-text))
|
||||
alias
|
||||
|
||||
(string/starts-with?
|
||||
(string/lower-case name)
|
||||
searched-text)
|
||||
name))]
|
||||
secondary-name))]
|
||||
(assoc acc
|
||||
k
|
||||
(assoc user
|
||||
:key k
|
||||
:match match
|
||||
:searched-text searched-text))
|
||||
acc))
|
||||
|
@ -642,7 +609,7 @@
|
|||
(assoc-in [:chats/mention-suggestions chat-id] mentions))}))))
|
||||
|
||||
(defn new-input-text-with-mention
|
||||
[{:keys [db]} {:keys [name]}]
|
||||
[{:keys [db]} {:keys [primary-name]}]
|
||||
(let [chat-id (:current-chat-id db)
|
||||
text (get-in db [:chat/inputs chat-id :input-text])
|
||||
{:keys [mention-end at-sign-idx]}
|
||||
|
@ -652,7 +619,7 @@
|
|||
new-input-text-with-mention)
|
||||
(string/join
|
||||
[(subs text 0 (inc at-sign-idx))
|
||||
name
|
||||
primary-name
|
||||
(let [next-char (get text mention-end)]
|
||||
(when (or (not next-char)
|
||||
(and next-char
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"@helpinghand.eth"]
|
||||
[:text
|
||||
" "]])
|
||||
|
||||
(def ->info-expected
|
||||
{:at-sign-idx 2
|
||||
:mention-end 19
|
||||
|
@ -75,16 +76,15 @@
|
|||
|
||||
(test/deftest test-replace-mentions
|
||||
(let [users {"User Number One"
|
||||
{:name "User Number One"
|
||||
:alias "User Number One"
|
||||
{:primary-name "User Number One"
|
||||
:public-key "0xpk1"}
|
||||
"User Number Two"
|
||||
{:name "user2"
|
||||
:alias "User Number Two"
|
||||
{:primary-name "user2"
|
||||
:secondary-name "User Number Two"
|
||||
:public-key "0xpk2"}
|
||||
"User Number Three"
|
||||
{:name "user3"
|
||||
:alias "User Number Three"
|
||||
{:primary-name "user3"
|
||||
:secondary-name "User Number Three"
|
||||
:public-key "0xpk3"}}]
|
||||
(test/testing "empty string"
|
||||
(let [text ""
|
||||
|
|
|
@ -2,10 +2,8 @@
|
|||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.chat.models.loading :as chat.loading]
|
||||
[status-im.chat.models.mentions :as mentions]
|
||||
[status-im.data-store.messages :as data-store.messages]
|
||||
[status-im.transport.message.protocol :as protocol]
|
||||
[status-im.utils.gfycat.core :as gfycat]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.types :as types]
|
||||
[status-im2.contexts.chat.messages.delete-message.events :as delete-message]
|
||||
|
@ -34,26 +32,6 @@
|
|||
;; TODO this is too expensive, probably we could mark message somehow and just hide it in the UI
|
||||
(message-list/rebuild-message-list {:db (update-in db [:messages chat-id] dissoc message-id)} chat-id))
|
||||
|
||||
(rf/defn add-senders-to-chat-users
|
||||
{:events [:chat/add-senders-to-chat-users]}
|
||||
[{:keys [db]} messages]
|
||||
(reduce (fn [acc {:keys [chat-id alias name identicon from]}]
|
||||
(let [alias (if (string/blank? alias)
|
||||
(gfycat/generate-gfy from)
|
||||
alias)]
|
||||
(update-in acc
|
||||
[:db :chats chat-id :users]
|
||||
assoc
|
||||
from
|
||||
(mentions/add-searchable-phrases
|
||||
{:alias alias
|
||||
:name (or name alias)
|
||||
:identicon identicon
|
||||
:public-key from
|
||||
:nickname (get-in db [:contacts/contacts from :nickname])}))))
|
||||
{:db db}
|
||||
messages))
|
||||
|
||||
(defn add-message
|
||||
[{:keys [db] :as acc} message-js chat-id message-id cursor-clock-value]
|
||||
(let [{:keys [replace from clock-value] :as message}
|
||||
|
@ -118,7 +96,7 @@
|
|||
(defn receive-many
|
||||
[{:keys [db]} ^js response-js]
|
||||
(let [messages-js ^js (.splice (.-messages response-js) 0 (if platform/low-device? 3 10))
|
||||
{:keys [db senders]}
|
||||
{:keys [db]}
|
||||
(reduce reduce-js-messages
|
||||
{:db db :chats #{} :senders {} :transactions #{}}
|
||||
messages-js)]
|
||||
|
@ -128,9 +106,7 @@
|
|||
:utils/dispatch-later
|
||||
(concat [{:ms 20 :dispatch [:process-response response-js]}]
|
||||
(when (and (:current-chat-id db) (= "active" (:app-state db)))
|
||||
[{:ms 100 :dispatch [:chat/mark-all-as-read (:current-chat-id db)]}])
|
||||
(when (seq senders)
|
||||
[{:ms 100 :dispatch [:chat/add-senders-to-chat-users (vals senders)]}]))}))
|
||||
[{:ms 100 :dispatch [:chat/mark-all-as-read (:current-chat-id db)]}]))}))
|
||||
|
||||
(rf/defn update-db-message-status
|
||||
[{:keys [db] :as cofx} chat-id message-id status]
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
[status-im2.contexts.chat.messages.list.events :as message-list]
|
||||
[status-im.contact.db :as contact.db]
|
||||
[status-im.data-store.chats :as chats-store]
|
||||
[status-im.data-store.contacts :as contacts-store]
|
||||
[status-im2.contexts.contacts.events :as contacts-store]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im.utils.types :as types]
|
||||
[status-im2.contexts.activity-center.events :as activity-center]
|
||||
[status-im2.navigation.events :as navigation]))
|
||||
|
||||
(rf/defn clean-up-chat
|
||||
[{:keys [db] :as cofx}
|
||||
[{:keys [db]}
|
||||
public-key
|
||||
{:keys [chat-id
|
||||
unviewed-messages-count
|
||||
|
@ -35,18 +35,18 @@
|
|||
(message-list/add-many nil (vals (get-in db [:messages chat-id]))))}))
|
||||
|
||||
(rf/defn contact-blocked
|
||||
{:events [::contact-blocked]}
|
||||
[{:keys [db] :as cofx} {:keys [public-key]} chats]
|
||||
(let [fxs (when chats
|
||||
{:events [:contacts/blocked]}
|
||||
[{:keys [db] :as cofx} {:keys [public-key]} chats-js]
|
||||
(let [fxs (when chats-js
|
||||
(map #(->> (chats-store/<-rpc %)
|
||||
(clean-up-chat public-key))
|
||||
(types/js->clj chats)))]
|
||||
(types/js->clj chats-js)))]
|
||||
(apply rf/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
(update :chats dissoc public-key)
|
||||
(update :chats-home-list disj public-key)
|
||||
(assoc-in [:contacts/contacts public-key :added] false))
|
||||
(assoc-in [:contacts/contacts public-key :added?] false))
|
||||
:dispatch [:shell/close-switcher-card public-key]
|
||||
:clear-message-notifications
|
||||
[[public-key] (get-in db [:multiaccount :remote-push-notifications-enabled?])]}
|
||||
|
@ -59,19 +59,15 @@
|
|||
(let [contact (-> (contact.db/public-key->contact
|
||||
(:contacts/contacts db)
|
||||
public-key)
|
||||
(assoc :blocked true
|
||||
:added false))
|
||||
(assoc :blocked? true
|
||||
:added? false))
|
||||
from-one-to-one-chat? (not (get-in db [:chats (:current-chat-id db) :group-chat]))]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
;; add the contact to blocked contacts
|
||||
(update :contacts/blocked (fnil conj #{}) public-key)
|
||||
;; update the contact in contacts list
|
||||
(assoc-in [:contacts/contacts public-key] contact))}
|
||||
{:db (assoc-in db [:contacts/contacts public-key] contact)}
|
||||
(contacts-store/block
|
||||
public-key
|
||||
(fn [^js block-contact]
|
||||
(re-frame/dispatch [::contact-blocked contact (.-chats block-contact)])
|
||||
(re-frame/dispatch [:contacts/blocked contact (.-chats block-contact)])
|
||||
(re-frame/dispatch [:sanitize-messages-and-process-response block-contact])
|
||||
(re-frame/dispatch [:hide-popover])))
|
||||
;; reset navigation to avoid going back to non existing one to one chat
|
||||
|
@ -80,13 +76,11 @@
|
|||
(navigation/navigate-back)))))
|
||||
|
||||
(rf/defn contact-unblocked
|
||||
{:events [::contact-unblocked]}
|
||||
{:events [:contacts/unblocked]}
|
||||
[{:keys [db]} contact-id]
|
||||
(let [contact (-> (get-in db [:contacts/contacts contact-id])
|
||||
(assoc :blocked false))]
|
||||
{:db (-> db
|
||||
(update :contacts/blocked disj contact-id)
|
||||
(assoc-in [:contacts/contacts contact-id] contact))}))
|
||||
(assoc :blocked? false))]
|
||||
{:db (assoc-in db [:contacts/contacts contact-id] contact)}))
|
||||
|
||||
(rf/defn unblock-contact
|
||||
{:events [:contact.ui/unblock-contact-pressed]}
|
||||
|
@ -94,4 +88,4 @@
|
|||
(contacts-store/unblock
|
||||
cofx
|
||||
contact-id
|
||||
#(re-frame/dispatch [::contact-unblocked contact-id])))
|
||||
#(re-frame/dispatch [:contacts/unblocked contact-id])))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(ns status-im.contact.chat
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.contact.core :as contact]
|
||||
[status-im2.contexts.contacts.events :as contact]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.navigation.events :as navigation]))
|
||||
|
||||
|
|
|
@ -1,86 +1,6 @@
|
|||
(ns status-im.contact.core
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im.contact.block :as contact.block]
|
||||
[status-im.contact.db :as contact.db]
|
||||
[status-im.data-store.contacts :as contacts-store]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn build-contact
|
||||
[{{:keys [multiaccount]
|
||||
:contacts/keys [contacts]}
|
||||
:db} public-key]
|
||||
(cond-> (contact.db/public-key->contact contacts public-key)
|
||||
(= public-key (:public-key multiaccount))
|
||||
(assoc :name (:name multiaccount))))
|
||||
|
||||
(rf/defn ensure-contacts
|
||||
[{:keys [db]} contacts chats]
|
||||
(let [events
|
||||
(reduce
|
||||
(fn [acc {:keys [public-key] :as contact}]
|
||||
(let [added (:added contact)
|
||||
was-added (contact.db/added? db public-key)
|
||||
blocked (:blocked contact)
|
||||
was-blocked (contact.db/blocked? db public-key)]
|
||||
(cond-> acc
|
||||
|
||||
(and (not (:has-added-us contact))
|
||||
(= constants/contact-request-state-none (:contact-request-state contact)))
|
||||
(conj [:activity-center/remove-pending-contact-request (:public-key contact)])
|
||||
|
||||
(and was-added (not added))
|
||||
(conj nil)
|
||||
|
||||
(and blocked (not was-blocked))
|
||||
(conj [::contact.block/contact-blocked contact chats]))))
|
||||
[[:chat/offload-messages constants/timeline-chat-id]
|
||||
[:activity-center.notifications/fetch-unread-count]]
|
||||
contacts)]
|
||||
(merge
|
||||
{:db (update db
|
||||
:contacts/contacts
|
||||
#(reduce (fn [acc {:keys [public-key] :as contact}]
|
||||
(-> acc
|
||||
(update public-key merge contact)
|
||||
(assoc-in [public-key :nickname] (:nickname contact))))
|
||||
%
|
||||
contacts))}
|
||||
(when (> (count events) 1)
|
||||
{:dispatch-n events}))))
|
||||
|
||||
(rf/defn add-contact
|
||||
"Add a contact and set pending to false"
|
||||
{:events [:contact.ui/add-contact-pressed]}
|
||||
[{:keys [db] :as cofx} public-key nickname ens-name]
|
||||
(when (not= (get-in db [:multiaccount :public-key]) public-key)
|
||||
(contacts-store/add
|
||||
cofx
|
||||
public-key
|
||||
nickname
|
||||
ens-name
|
||||
#(do
|
||||
(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
(re-frame/dispatch [:chat/offload-messages constants/timeline-chat-id])))))
|
||||
|
||||
(rf/defn remove-contact
|
||||
"Remove a contact from current account's contact list"
|
||||
{:events [:contact.ui/remove-contact-pressed]}
|
||||
[{:keys [db]} {:keys [public-key]}]
|
||||
{:db (-> db
|
||||
(assoc-in [:contacts/contacts public-key :added] false)
|
||||
(assoc-in [:contacts/contacts public-key :contact-request-state]
|
||||
constants/contact-request-state-none))
|
||||
:json-rpc/call [{:method "wakuext_retractContactRequest"
|
||||
:params [{:id public-key}]
|
||||
:on-success #(log/debug "contact removed successfully")}]
|
||||
:dispatch [:chat/offload-messages constants/timeline-chat-id]})
|
||||
|
||||
(rf/defn initialize-contacts
|
||||
[cofx]
|
||||
(contacts-store/fetch-contacts-rpc cofx #(re-frame/dispatch [::contacts-loaded %])))
|
||||
(:require [utils.re-frame :as rf]
|
||||
[status-im2.navigation.events :as navigation]))
|
||||
|
||||
(rf/defn open-contact-toggle-list
|
||||
{:events [:contact.ui/start-group-chat-pressed]}
|
||||
|
@ -90,18 +10,3 @@
|
|||
:group/selected-contacts #{}
|
||||
:new-chat-name "")}
|
||||
(navigation/navigate-to-cofx :contact-toggle-list nil)))
|
||||
|
||||
(rf/defn update-nickname
|
||||
{:events [:contacts/update-nickname]}
|
||||
[{:keys [db] :as cofx} public-key nickname]
|
||||
(rf/merge cofx
|
||||
(contacts-store/set-nickname
|
||||
public-key
|
||||
nickname
|
||||
#(re-frame/dispatch [:sanitize-messages-and-process-response %]))
|
||||
(navigation/navigate-back)))
|
||||
|
||||
(rf/defn set-search-query
|
||||
{:events [:contacts/set-search-query]}
|
||||
[{:keys [db] :as cofx} value]
|
||||
{:db (assoc db :contacts/search-query value)})
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
(ns status-im.contact.core-test)
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
[clojure.string :as string]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.utils.gfycat.core :as gfycat]
|
||||
[status-im.utils.identicon :as identicon]))
|
||||
|
||||
|
@ -12,6 +11,7 @@
|
|||
(let [alias (gfycat/generate-gfy public-key)]
|
||||
{:alias alias
|
||||
:name alias
|
||||
:primary-name alias
|
||||
:identicon (identicon/identicon public-key)
|
||||
:public-key public-key}))
|
||||
|
||||
|
@ -43,84 +43,45 @@
|
|||
(defn sort-contacts
|
||||
[contacts]
|
||||
(sort (fn [c1 c2]
|
||||
(let [name1 (first (:two-names c1))
|
||||
name2 (first (:two-names c2))]
|
||||
(let [name1 (:primary-name c1)
|
||||
name2 (:primary-name c2)]
|
||||
(when (and name1 name2)
|
||||
(compare (string/lower-case name1)
|
||||
(string/lower-case name2))))
|
||||
(string/lower-case name2)))))
|
||||
(vals contacts)))
|
||||
|
||||
(defn filter-dapps
|
||||
[v dev-mode?]
|
||||
(remove #(when-not dev-mode? (true? (:developer? %))) v))
|
||||
|
||||
(defn filter-group-contacts
|
||||
[group-contacts contacts]
|
||||
(let [group-contacts' (into #{} group-contacts)]
|
||||
(filter #(group-contacts' (:public-key %)) contacts)))
|
||||
|
||||
(defn query-chat-contacts
|
||||
[{:keys [contacts]} all-contacts query-fn]
|
||||
(let [participant-set (into #{} (filter identity) contacts)]
|
||||
(query-fn (comp participant-set :public-key) (vals all-contacts))))
|
||||
|
||||
(defn get-all-contacts-in-group-chat
|
||||
[members admins contacts {:keys [public-key] :as current-account}]
|
||||
[members admins contacts {:keys [public-key preferred-name name] :as current-account}]
|
||||
(let [current-contact (some->
|
||||
current-account
|
||||
(select-keys [:name :preferred-name :public-key :identicon :images])
|
||||
(set/rename-keys {:name :alias
|
||||
:preferred-name :name}))
|
||||
(set/rename-keys {:name :alias :preferred-name :name})
|
||||
(assoc :primary-name (or preferred-name name)))
|
||||
all-contacts (cond-> contacts
|
||||
current-contact
|
||||
(assoc public-key current-contact))]
|
||||
(->> members
|
||||
(map #(or (get all-contacts %)
|
||||
(public-key->new-contact %)))
|
||||
(sort-by (comp string/lower-case #(or (:name %) (:alias %))))
|
||||
(sort-by (comp string/lower-case #(or (:primary-name %) (:name %) (:alias %))))
|
||||
(map #(if (get admins (:public-key %))
|
||||
(assoc % :admin? true)
|
||||
%)))))
|
||||
|
||||
(defn contact-exists?
|
||||
[db public-key]
|
||||
(get-in db [:contacts/contacts public-key]))
|
||||
|
||||
(defn added?
|
||||
([{:keys [contact-request-state]}]
|
||||
(or (= constants/contact-request-state-mutual contact-request-state)
|
||||
(= constants/contact-request-state-sent contact-request-state)))
|
||||
([db public-key]
|
||||
(added? (get-in db [:contacts/contacts public-key]))))
|
||||
|
||||
(defn blocked?
|
||||
([contact]
|
||||
(:blocked contact))
|
||||
([db public-key]
|
||||
(blocked? (get-in db [:contacts/contacts public-key]))))
|
||||
|
||||
(defn active?
|
||||
"Checks that we are mutual contacts"
|
||||
([contact]
|
||||
(and (= constants/contact-request-state-mutual
|
||||
(:contact-request-state contact))
|
||||
(not (:blocked contact))))
|
||||
([db public-key]
|
||||
(active? (get-in db [:contacts/contacts public-key]))))
|
||||
|
||||
(defn enrich-contact
|
||||
([contact] (enrich-contact contact nil nil))
|
||||
([{:keys [public-key] :as contact} setting own-public-key]
|
||||
(cond-> (-> contact
|
||||
(dissoc :ens-verified-at :ens-verification-retries)
|
||||
(assoc :blocked? (:blocked contact)
|
||||
:active? (active? contact)
|
||||
:added? (added? contact))
|
||||
(multiaccounts/contact-with-names))
|
||||
(cond-> contact
|
||||
(and setting
|
||||
(not= public-key own-public-key)
|
||||
(or (= setting constants/profile-pictures-visibility-none)
|
||||
(and (= setting constants/profile-pictures-visibility-contacts-only)
|
||||
(not (added? contact)))))
|
||||
(not (:added? contact)))))
|
||||
(dissoc :images))))
|
||||
|
||||
(defn enrich-contacts
|
||||
|
@ -134,15 +95,8 @@
|
|||
(defn get-blocked-contacts
|
||||
[contacts]
|
||||
(reduce (fn [acc {:keys [public-key] :as contact}]
|
||||
(if (:blocked contact)
|
||||
(if (:blocked? contact)
|
||||
(conj acc public-key)
|
||||
acc))
|
||||
#{}
|
||||
contacts))
|
||||
|
||||
(defn get-active-contacts
|
||||
[contacts]
|
||||
(->> contacts
|
||||
(filter (fn [[_ contact]]
|
||||
(active? contact)))
|
||||
sort-contacts))
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
{"0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f"
|
||||
{:last-updated 0
|
||||
:name "User B"
|
||||
:primary-name "User B"
|
||||
:identicon "photo1"
|
||||
:last-online 0
|
||||
:public-key
|
||||
|
@ -28,6 +29,7 @@
|
|||
{:last-updated 0
|
||||
:signed-up? true
|
||||
:sharing-usage-data? false
|
||||
:primary-name "User A"
|
||||
:name "User A"
|
||||
:identicon "photo2"
|
||||
:public-key
|
||||
|
@ -39,17 +41,20 @@
|
|||
contacts
|
||||
current-multiaccount)
|
||||
[{:name "generated"
|
||||
:primary-name "generated"
|
||||
:identicon "generated"
|
||||
:alias "generated"
|
||||
:admin? true
|
||||
:public-key
|
||||
"0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917"}
|
||||
{:alias "User A"
|
||||
:primary-name "User A"
|
||||
:identicon "photo2"
|
||||
:public-key
|
||||
"0x048a2f8b80c60f89a91b4c1316e56f75b087f446e7b8701ceca06a40142d8efe1f5aa36bd0fee9e248060a8d5207b43ae98bef4617c18c71e66f920f324869c09f"}
|
||||
{:last-updated 0
|
||||
:name "User B"
|
||||
:primary-name "User B"
|
||||
:identicon "photo1"
|
||||
:last-online 0
|
||||
:public-key
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
(ns status-im.data-store.contacts
|
||||
(:require [clojure.set :as set]
|
||||
[utils.re-frame :as rf]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn <-rpc
|
||||
[contact]
|
||||
(-> contact
|
||||
(set/rename-keys
|
||||
{:id :public-key
|
||||
:ensVerifiedAt :ens-verified-at
|
||||
:compressedKey :compressed-key
|
||||
:displayName :display-name
|
||||
:ensVerified :ens-verified
|
||||
:ensVerificationRetries :ens-verification-retries
|
||||
:hasAddedUs :has-added-us
|
||||
:contactRequestState :contact-request-state
|
||||
:lastENSClockValue :last-ens-clock-value
|
||||
:lastUpdated :last-updated
|
||||
:localNickname :nickname})
|
||||
(assoc :mutual?
|
||||
(and (:added contact)
|
||||
(:hasAddedUs contact)))))
|
||||
|
||||
(rf/defn fetch-contacts-rpc
|
||||
[_ on-success]
|
||||
{:json-rpc/call [{:method "wakuext_contacts"
|
||||
:params []
|
||||
:on-success #(on-success (map <-rpc %))
|
||||
:on-error #(log/error "failed to fetch contacts" %)}]})
|
||||
|
||||
(rf/defn add
|
||||
[_ public-key nickname ens-name on-success]
|
||||
{:json-rpc/call [{:method "wakuext_addContact"
|
||||
:params [{:id public-key :nickname nickname :ensName ens-name}]
|
||||
:js-response true
|
||||
:on-success #(do
|
||||
(log/info "saved contact" public-key "successfuly")
|
||||
(when on-success
|
||||
(on-success %)))
|
||||
:on-error #(log/error "failed to add contact" public-key %)}]})
|
||||
|
||||
(rf/defn set-nickname
|
||||
[_ public-key nickname on-success]
|
||||
{:json-rpc/call [{:method "wakuext_setContactLocalNickname"
|
||||
:params [{:id public-key :nickname nickname}]
|
||||
:js-response true
|
||||
:on-success #(do
|
||||
(log/debug "set contact nickname" public-key "successfuly" nickname)
|
||||
(when on-success
|
||||
(on-success %)))
|
||||
:on-error #(log/error "failed to set contact nickname "
|
||||
public-key
|
||||
nickname
|
||||
%)}]})
|
||||
|
||||
(rf/defn block
|
||||
[_ contact-id on-success]
|
||||
{:json-rpc/call [{:method "wakuext_blockContact"
|
||||
:params [contact-id]
|
||||
:js-response true
|
||||
:on-success on-success
|
||||
:on-error #(log/error "failed to block contact" % contact-id)}]})
|
||||
|
||||
(rf/defn unblock
|
||||
[_ contact-id on-success]
|
||||
{:json-rpc/call [{:method "wakuext_unblockContact"
|
||||
:params [contact-id]
|
||||
:on-success on-success
|
||||
:js-response true
|
||||
:on-error #(log/error "failed to unblock contact" % contact-id)}]})
|
|
@ -1,22 +0,0 @@
|
|||
(ns status-im.data-store.contacts-test
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.data-store.contacts :as c]))
|
||||
|
||||
(deftest contact<-rpc
|
||||
(let [contact {:id "pk"
|
||||
:address "address"
|
||||
:name "name"
|
||||
:displayName "display-name"
|
||||
:compressedKey "compressed-key"
|
||||
:identicon "identicon"
|
||||
:lastUpdated 1}
|
||||
expected-contact {:public-key "pk"
|
||||
:address "address"
|
||||
:compressed-key "compressed-key"
|
||||
:display-name "display-name"
|
||||
:mutual? nil
|
||||
:name "name"
|
||||
:identicon "identicon"
|
||||
:last-updated 1}]
|
||||
(testing "<-rpc"
|
||||
(is (= expected-contact (c/<-rpc contact))))))
|
|
@ -161,10 +161,10 @@
|
|||
|
||||
(rf/defn on-going-in-background
|
||||
[{:keys [db now]}]
|
||||
{:db (assoc db :app-in-background-since now)
|
||||
{:db (assoc db :app-in-background-since now)})
|
||||
;; event not implemented
|
||||
;; :dispatch-n [[:audio-recorder/on-background] [:audio-message/on-background]]
|
||||
})
|
||||
|
||||
|
||||
(rf/defn app-state-change
|
||||
{:events [:app-state-change]}
|
||||
|
|
|
@ -338,7 +338,7 @@
|
|||
(rf-test/wait-for
|
||||
[:contacts/contact-built]
|
||||
(let [contact @(rf/subscribe [:contacts/current-contact])]
|
||||
(is (= three-words-name (:three-words-name (:names contact)))))
|
||||
(is (= three-words-name (:primary-name contact))))
|
||||
(logout!)
|
||||
(rf-test/wait-for [::logout/logout-method]
|
||||
(assert-logout))))))))))
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
[quo.platform :as platform]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im2.common.bottom-sheet.events :as bottom-sheet]
|
||||
[status-im.ethereum.stateofus :as stateofus]
|
||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[status-im.native-module.core :as native-module]
|
||||
[status-im.theme.core :as theme]
|
||||
|
@ -12,11 +11,11 @@
|
|||
[status-im2.constants :as constants]
|
||||
[status-im.utils.gfycat.core :as gfycat]
|
||||
[status-im.utils.identicon :as identicon]
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im2.setup.hot-reload :as hot-reload]
|
||||
[status-im2.common.theme.core :as utils.theme]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im2.contexts.shell.animation :as shell.animation]))
|
||||
[status-im2.contexts.shell.animation :as shell.animation]
|
||||
[status-im.contact.db :as contact.db]))
|
||||
|
||||
;; validate that the given mnemonic was generated from Status Dictionary
|
||||
(re-frame/reg-fx
|
||||
|
@ -24,47 +23,6 @@
|
|||
(fn [[passphrase callback]]
|
||||
(native-module/validate-mnemonic passphrase callback)))
|
||||
|
||||
(defn contact-names
|
||||
"Returns map of all existing names for contact"
|
||||
[{:keys [name
|
||||
display-name
|
||||
preferred-name
|
||||
alias
|
||||
public-key
|
||||
ens-verified
|
||||
nickname]}]
|
||||
(let [ens-name (or preferred-name
|
||||
name)]
|
||||
(cond-> {:nickname nickname
|
||||
:display-name display-name
|
||||
:three-words-name (or alias (gfycat/generate-gfy public-key))}
|
||||
;; Preferred name is our own otherwise we make sure it's verified
|
||||
(or preferred-name (and ens-verified name))
|
||||
(assoc :ens-name (or (stateofus/username ens-name) ens-name)))))
|
||||
|
||||
(defn contact-two-names
|
||||
"Returns vector of two names in next order nickname, ens name, display-name, three word name, public key"
|
||||
[{:keys [names
|
||||
compressed-key
|
||||
public-key]
|
||||
:as contact} public-key?]
|
||||
(let [{:keys [nickname
|
||||
ens-name
|
||||
display-name
|
||||
three-words-name]}
|
||||
(or names (contact-names contact))
|
||||
non-empty-names (remove string/blank? [nickname ens-name display-name three-words-name])]
|
||||
(if (> (count non-empty-names) 1)
|
||||
(vec (take 2 non-empty-names))
|
||||
[(first non-empty-names)
|
||||
(when public-key? (utils/get-shortened-address (or compressed-key public-key)))])))
|
||||
|
||||
(defn contact-with-names
|
||||
"Returns contact with :names map "
|
||||
[contact]
|
||||
(let [contact' (assoc contact :names (contact-names contact))]
|
||||
(assoc contact' :two-names (contact-two-names contact' true))))
|
||||
|
||||
(defn displayed-name
|
||||
"Use preferred name, display-name, name or alias in that order"
|
||||
[{:keys [name display-name preferred-name alias public-key ens-verified]}]
|
||||
|
@ -74,14 +32,13 @@
|
|||
name)]
|
||||
;; Preferred name is our own otherwise we make sure it's verified
|
||||
(if (or preferred-name (and ens-verified name))
|
||||
(let [username (stateofus/username ens-name)]
|
||||
(or username ens-name))
|
||||
ens-name
|
||||
(or display-name alias (gfycat/generate-gfy public-key)))))
|
||||
|
||||
(defn contact-by-identity
|
||||
[contacts identity]
|
||||
(or (get contacts identity)
|
||||
(contact-with-names {:public-key identity})))
|
||||
(contact.db/public-key->new-contact identity)))
|
||||
|
||||
(defn contact-two-names-by-identity
|
||||
[contact current-multiaccount identity]
|
||||
|
@ -89,7 +46,7 @@
|
|||
(if me?
|
||||
[(or (:preferred-name current-multiaccount)
|
||||
(gfycat/generate-gfy identity))]
|
||||
(contact-two-names contact false))))
|
||||
[(:primary-name contact) (:secondary-name contact)])))
|
||||
|
||||
(def photo-quality-thumbnail :thumbnail)
|
||||
(def photo-quality-large :large)
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
(ns status-im.multiaccounts.core-test
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.multiaccounts.core :as ma]))
|
||||
|
||||
(def compressed-key "zQsomething")
|
||||
(def short-compressed-key "zQsome…ing")
|
||||
(def public-key
|
||||
"0x0461f576da67dc0bca9888cdb4cb28c80285b756b324109da94a081585ed6f007cf00afede6b3ee5638593674fee100b590318fc7bdb0054b8dd9445acea216ad2")
|
||||
(def short-public-key "0x0461…ad2")
|
||||
(def random-name "Studious Gold Mustang")
|
||||
(def override-random-name (str "override" random-name))
|
||||
(def nickname "nickname")
|
||||
(def override-nickname (str nickname "override"))
|
||||
(def display-name "display-name")
|
||||
(def override-display-name (str display-name "override"))
|
||||
(def ens-name "jakubgs.eth")
|
||||
(def formatted-ens (str "@" ens-name))
|
||||
(def override-ens-name (str "override" ens-name))
|
||||
|
||||
(def contact
|
||||
{:nickname nickname
|
||||
:name ens-name
|
||||
:ens-verified true
|
||||
:compressed-key compressed-key
|
||||
:public-key public-key
|
||||
:display-name display-name})
|
||||
|
||||
(deftest contact-two-names-test
|
||||
(testing "names is nil"
|
||||
(testing "nickname has precedence"
|
||||
(is
|
||||
(= [nickname ens-name]
|
||||
(ma/contact-two-names contact public-key))))
|
||||
(testing "ens name is second option"
|
||||
(is
|
||||
(= [ens-name display-name]
|
||||
(ma/contact-two-names
|
||||
(dissoc contact :nickname)
|
||||
public-key))))
|
||||
(testing "ens name is second option but not verified"
|
||||
(is
|
||||
(= [display-name random-name]
|
||||
(ma/contact-two-names
|
||||
(dissoc contact :nickname :ens-verified)
|
||||
public-key))))
|
||||
(testing "display name is third option"
|
||||
(is
|
||||
(= [display-name random-name]
|
||||
(ma/contact-two-names
|
||||
(dissoc contact :nickname :name)
|
||||
public-key))))
|
||||
(testing "3 random words is fallback"
|
||||
(is
|
||||
(= [random-name short-compressed-key]
|
||||
(ma/contact-two-names
|
||||
(dissoc contact
|
||||
:nickname
|
||||
:name
|
||||
:display-name)
|
||||
public-key)))))
|
||||
(testing "public-key is the least favorite"
|
||||
(is
|
||||
(= [random-name short-public-key]
|
||||
(ma/contact-two-names
|
||||
(dissoc contact
|
||||
:nickname
|
||||
:name
|
||||
:compressed-key
|
||||
:display-name)
|
||||
public-key))))
|
||||
(testing "names is provided"
|
||||
(let [names {:nickname override-nickname
|
||||
:display-name override-display-name
|
||||
:three-words-name override-random-name
|
||||
:ens-name override-ens-name}
|
||||
contact-with-names (assoc contact :names names)]
|
||||
|
||||
(testing "nickname has precedence"
|
||||
(is
|
||||
(= [override-nickname override-ens-name]
|
||||
(ma/contact-two-names contact-with-names public-key))))
|
||||
(testing "ens name is second option"
|
||||
(is
|
||||
(= [override-ens-name override-display-name]
|
||||
(ma/contact-two-names
|
||||
(update contact-with-names :names dissoc :nickname)
|
||||
public-key))))
|
||||
(testing "display name is third option"
|
||||
(is
|
||||
(= [override-display-name override-random-name]
|
||||
(ma/contact-two-names
|
||||
(update contact-with-names :names dissoc :nickname :ens-name)
|
||||
public-key))))
|
||||
(testing "3 random words is fallback"
|
||||
(is
|
||||
(= [override-random-name short-compressed-key]
|
||||
(ma/contact-two-names
|
||||
(update contact-with-names :names dissoc :nickname :ens-name :display-name)
|
||||
public-key)))))))
|
|
@ -7,7 +7,7 @@
|
|||
:name "Darkviolet Lightgreen Halcyon"
|
||||
:identicon
|
||||
"data:image/png;base64iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEX///+M2KwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdPOdBAAABAHRSTlP//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmfXxgAABnNJREFUeNoBaAaX+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5UBARL8TK8AAAAASUVORK5CYII="
|
||||
:added true
|
||||
:added? true
|
||||
:last-online 0
|
||||
:public-key
|
||||
"0x04d6e56a475cd35f512d6ce0bf76c2c2af435c85ff48c2b9bdefd129f620e051a436f50961eae5717b2a750e59c3f5b60647d927da46d0b8b11621640b5678fc24"}
|
||||
|
@ -16,7 +16,7 @@
|
|||
:name "rv"
|
||||
:identicon
|
||||
"data:image/png;base64iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEX////VjNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwYzy6AAABAHRSTlP//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmfXxgAABnNJREFUeNoBaAaX+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAAAAAAEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEAAAAAAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQAAAAABAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAAAAAAEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6IYA4bRtf+EAAAAASUVORK5CYII="
|
||||
:added true
|
||||
:added? true
|
||||
:last-online 0
|
||||
:public-key
|
||||
"0x043ae31038ff45a31b096a91d3f8290e079366fbbae76a00fbbd349cd0e5b8d7598965d206772ec4504f68908649a08383cdc51a52cdae5e9ccc744ace4d37020f"}])
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[status-im.data-store.contacts :as data-store.contacts]
|
||||
[status-im2.contexts.contacts.events :as data-store.contacts]
|
||||
[status-im.ui.components.list-selection :as list-selection]
|
||||
[status-im.ui.components.react :as react]
|
||||
[utils.re-frame :as rf]
|
||||
|
@ -103,6 +103,7 @@
|
|||
(assoc :contacts/ens-name ens-name))
|
||||
:json-rpc/call [{:method "wakuext_buildContact"
|
||||
:params [identity]
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:contacts/contact-built
|
||||
identity
|
||||
(data-store.contacts/<-rpc %)])}]})))
|
||||
(data-store.contacts/<-rpc-js %)])}]})))
|
||||
|
|
|
@ -7,10 +7,9 @@
|
|||
[status-im.chat.models.reactions :as models.reactions]
|
||||
[status-im.communities.core :as models.communities]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im.contact.core :as models.contact]
|
||||
[status-im2.contexts.contacts.events :as models.contact]
|
||||
[status-im.data-store.activities :as data-store.activities]
|
||||
[status-im.data-store.chats :as data-store.chats]
|
||||
[status-im.data-store.contacts :as data-store.contacts]
|
||||
[status-im.data-store.invitations :as data-store.invitations]
|
||||
[status-im.data-store.messages :as data-store.messages]
|
||||
[status-im.data-store.reactions :as data-store.reactions]
|
||||
|
@ -84,15 +83,7 @@
|
|||
(models.pairing/handle-installations installations-clj)))
|
||||
|
||||
(seq contacts)
|
||||
(let [contacts-clj (types/js->clj contacts)
|
||||
^js chats (.-chatsForContacts response-js)]
|
||||
(js-delete response-js "contacts")
|
||||
(js-delete response-js "chatsForContacts")
|
||||
(rf/merge cofx
|
||||
(process-next response-js sync-handler)
|
||||
(models.contact/ensure-contacts
|
||||
(map data-store.contacts/<-rpc contacts-clj)
|
||||
chats)))
|
||||
(models.contact/process-js-contacts cofx response-js)
|
||||
|
||||
(seq communities)
|
||||
(let [communities-clj (types/js->clj communities)]
|
||||
|
|
|
@ -29,13 +29,12 @@
|
|||
|
||||
(defn- render-row
|
||||
[row]
|
||||
(let [first-name (first (multiaccounts/contact-two-names row false))]
|
||||
[quo/list-item
|
||||
{:title first-name
|
||||
{:title (:primary-name row)
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo row)]
|
||||
:on-press #(re-frame/dispatch [:chat.ui/start-chat
|
||||
(:public-key row)])}]))
|
||||
(:public-key row)])}])
|
||||
|
||||
(defn- icon-wrapper
|
||||
[color icon]
|
||||
|
|
|
@ -1,41 +1,38 @@
|
|||
(ns status-im.ui.screens.chat.utils
|
||||
(:require [quo.design-system.colors :as colors]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.ui.components.react :as react]))
|
||||
[status-im.ui.components.react :as react]
|
||||
[clojure.string :as string]))
|
||||
|
||||
(defn format-author-old
|
||||
([contact] (format-author-old contact nil))
|
||||
([{:keys [names] :as contact} {:keys [modal profile? you?]}]
|
||||
(let [{:keys [nickname ens-name]} names
|
||||
[first-name second-name] (multiaccounts/contact-two-names contact false)]
|
||||
(if (or nickname ens-name)
|
||||
([{:keys [primary-name secondary-name nickname]} {:keys [modal profile? you?]}]
|
||||
(if (not (string/blank? secondary-name))
|
||||
[react/nested-text
|
||||
{:number-of-lines 2
|
||||
:style {:color (if modal colors/white-persist colors/blue)
|
||||
:font-size (if profile? 15 13)
|
||||
:line-height (if profile? 22 18)
|
||||
:font-weight "500"}}
|
||||
(subs first-name 0 81)
|
||||
(subs primary-name 0 81)
|
||||
(when you?
|
||||
[{:style {:color colors/gray :font-weight "400" :font-size 13}}
|
||||
(str " " (i18n/label :t/You))])
|
||||
(when nickname
|
||||
[{:style {:color colors/gray :font-weight "400"}}
|
||||
(str " " (subs second-name 0 81))])]
|
||||
(str " " (subs secondary-name 0 81))])]
|
||||
[react/text
|
||||
{:style {:color (if modal colors/white-persist colors/gray)
|
||||
:font-size (if profile? 15 12)
|
||||
:line-height (if profile? 22 18)
|
||||
:font-weight "400"}}
|
||||
first-name]))))
|
||||
primary-name])))
|
||||
|
||||
(defn format-author
|
||||
([contact] (format-author contact nil nil))
|
||||
([{:keys [names] :as contact} {:keys [modal profile? you?]} max-length]
|
||||
(let [{:keys [nickname ens-name]} names
|
||||
[first-name second-name] (multiaccounts/contact-two-names contact false)]
|
||||
(if (or nickname ens-name)
|
||||
([contact {:keys [modal profile? you?]} max-length]
|
||||
(let [{:keys [primary-name secondary-name]} contact]
|
||||
(if secondary-name
|
||||
[react/nested-text
|
||||
{:number-of-lines 2
|
||||
:style {:color (if modal colors/white-persist colors/black)
|
||||
|
@ -43,13 +40,12 @@
|
|||
:line-height (if profile? 22 18)
|
||||
:letter-spacing -0.2
|
||||
:font-weight "600"}}
|
||||
(subs first-name 0 81)
|
||||
(subs primary-name 0 81)
|
||||
(when you?
|
||||
[{:style {:color colors/black-light :font-weight "500" :font-size 13}}
|
||||
(str " " (i18n/label :t/You))])
|
||||
(when nickname
|
||||
[{:style {:color colors/black-light :font-weight "500"}}
|
||||
(str " " (subs second-name 0 81))])]
|
||||
(str " " (subs secondary-name 0 81))]]
|
||||
[react/text
|
||||
{:style {:color (if modal colors/white-persist colors/black)
|
||||
:font-size (if profile? 15 13)
|
||||
|
@ -57,6 +53,6 @@
|
|||
:font-weight "600"
|
||||
:letter-spacing -0.2}
|
||||
:number-of-lines 1}
|
||||
(if (and max-length (> (count first-name) max-length))
|
||||
(str (subs first-name 0 max-length) "...")
|
||||
first-name)]))))
|
||||
(if (and max-length (> (count primary-name) max-length))
|
||||
(str (subs primary-name 0 max-length) "...")
|
||||
primary-name)]))))
|
||||
|
|
|
@ -30,10 +30,10 @@
|
|||
|
||||
(defn contacts-list-item
|
||||
[{:keys [public-key active] :as contact} _ _ {:keys [selected]}]
|
||||
(let [[first-name second-name] (multiaccounts/contact-two-names contact true)]
|
||||
(let [{:keys [primary-name secondary-name]} contact]
|
||||
[quo/list-item
|
||||
{:title first-name
|
||||
:subtitle second-name
|
||||
{:title primary-name
|
||||
:subtitle secondary-name
|
||||
:icon [chat-icon.screen/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo contact)]
|
||||
:accessory :checkbox
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
(rf/dispatch event))
|
||||
|
||||
(defn member-sheet
|
||||
[first-name {:keys [public-key] :as member} community-id can-kick-users? can-manage-users? admin?]
|
||||
[primary-name {:keys [public-key] :as member} community-id can-kick-users? can-manage-users? admin?]
|
||||
[:<>
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo member)]
|
||||
:title first-name
|
||||
:title primary-name
|
||||
:subtitle (i18n/label :t/view-profile)
|
||||
:accessibility-label :view-chat-details-button
|
||||
:chevron true
|
||||
|
@ -61,10 +61,10 @@
|
|||
can-kick-users?
|
||||
admin?]}]
|
||||
(let [member (rf/sub [:contacts/contact-by-identity public-key])
|
||||
[first-name second-name] (rf/sub [:contacts/contact-two-names-by-identity public-key])]
|
||||
[primary-name secondary-name] (rf/sub [:contacts/contact-two-names-by-identity public-key])]
|
||||
[quo/list-item
|
||||
{:title first-name
|
||||
:subtitle second-name
|
||||
{:title primary-name
|
||||
:subtitle secondary-name
|
||||
:accessibility-label :member-item
|
||||
:icon [chat-icon/profile-photo-plus-dot-view
|
||||
{:public-key public-key
|
||||
|
@ -74,7 +74,7 @@
|
|||
{:on-press
|
||||
#(rf/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
[member-sheet first-name member community-id
|
||||
[member-sheet primary-name member community-id
|
||||
can-kick-users? can-manage-users? admin?])}])
|
||||
:type :icon
|
||||
:theme :icon
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
|
||||
(defn contacts-list-item
|
||||
[{:keys [public-key] :as contact}]
|
||||
(let [[first-name second-name] (multiaccounts/contact-two-names contact true)]
|
||||
(let [{:keys [primary-name secondary-name]} contact]
|
||||
[quo/list-item
|
||||
{:title first-name
|
||||
:subtitle second-name
|
||||
{:title primary-name
|
||||
:subtitle secondary-name
|
||||
:icon [chat-icon.screen/profile-photo-plus-dot-view
|
||||
{:public-key public-key
|
||||
:photo-path (multiaccounts/displayed-photo contact)}]
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
[status-im.ethereum.stateofus :as stateofus]
|
||||
[status-im.ethereum.tokens :as tokens]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.ui.components.checkbox.view :as checkbox]
|
||||
|
@ -20,7 +19,6 @@
|
|||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.ui.screens.chat.photos :as photos]
|
||||
[status-im.ui.screens.chat.utils :as chat.utils]
|
||||
[status-im.ui.screens.profile.components.views :as profile.components]
|
||||
[status-im.ui.screens.wallet.send.sheets :as sheets]
|
||||
|
@ -717,13 +715,13 @@
|
|||
[]
|
||||
(views/letsubs [contact-name [:multiaccount/preferred-name]]
|
||||
(when-not (string/blank? contact-name)
|
||||
(chat.utils/format-author-old {:names {:ens-name
|
||||
(chat.utils/format-author-old {:primary-name
|
||||
(str "@"
|
||||
(or (stateofus/username contact-name)
|
||||
contact-name))}}))))
|
||||
contact-name))}))))
|
||||
|
||||
(views/defview registered
|
||||
[names {:keys [preferred-name] :as account} _ registrations]
|
||||
[names {:keys [preferred-name]} _ registrations]
|
||||
[react/view {:style {:flex 1}}
|
||||
[react/scroll-view
|
||||
[react/view {:style {:margin-top 8}}
|
||||
|
@ -759,13 +757,7 @@
|
|||
:value preferred-name
|
||||
:action-fn #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content
|
||||
(fn [] (name-list names preferred-name))}])}]])]
|
||||
[react/view
|
||||
[react/view {:padding-left 72}
|
||||
[my-name]]
|
||||
[react/view {:flex-direction :row}
|
||||
[react/view {:padding-left 16 :padding-top 4}
|
||||
[photos/photo (multiaccounts/displayed-photo account) {:size 36}]]]]]])
|
||||
(fn [] (name-list names preferred-name))}])}]])]]])
|
||||
|
||||
(views/defview main
|
||||
[]
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
|
||||
(defn- render-contact
|
||||
[row]
|
||||
(let [[first-name second-name] (multiaccounts/contact-two-names row false)]
|
||||
(let [{:keys [primary-name secondary-name]} row]
|
||||
[quo/list-item
|
||||
{:title first-name
|
||||
:subtitle second-name
|
||||
{:title primary-name
|
||||
:subtitle secondary-name
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo row)]}]))
|
||||
|
||||
|
@ -55,10 +55,10 @@
|
|||
[]
|
||||
(fn [allow-new-users? subs-name {:keys [public-key] :as contact} on-toggle]
|
||||
(let [contact-selected? @(re-frame/subscribe [subs-name public-key])
|
||||
[first-name second-name] (multiaccounts/contact-two-names contact true)]
|
||||
{:keys [primary-name secondary-name]} contact]
|
||||
[quo/list-item
|
||||
{:title first-name
|
||||
:subtitle second-name
|
||||
{:title primary-name
|
||||
:subtitle secondary-name
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo contact)]
|
||||
:on-press #(on-toggle allow-new-users? contact-selected? public-key)
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.ui.screens.profile.components.sheets :as sheets])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
[status-im.ui.screens.profile.components.sheets :as sheets]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn actions
|
||||
[{:keys [public-key added? blocked? ens-name mutual?] :as contact} muted?]
|
||||
|
@ -71,19 +71,21 @@
|
|||
:chevron true}])
|
||||
|
||||
(defn nickname-settings
|
||||
[{:keys [names]}]
|
||||
[{:keys [nickname]}]
|
||||
(println "NUCKNAME" nickname)
|
||||
[quo/list-item
|
||||
{:title (i18n/label :t/nickname)
|
||||
:size :small
|
||||
:accessibility-label :profile-nickname-item
|
||||
:accessory :text
|
||||
:accessory-text (or (:nickname names) (i18n/label :t/none))
|
||||
:accessory-text (or nickname (i18n/label :t/none))
|
||||
:on-press #(re-frame/dispatch [:open-modal :nickname])
|
||||
:chevron true}])
|
||||
|
||||
(defn save-nickname
|
||||
[public-key nickname]
|
||||
(re-frame/dispatch [:contacts/update-nickname public-key nickname]))
|
||||
(re-frame/dispatch [:contacts/update-nickname public-key nickname])
|
||||
(re-frame/dispatch [:navigate-back]))
|
||||
|
||||
(defn valid-nickname?
|
||||
[nickname]
|
||||
|
@ -105,15 +107,16 @@
|
|||
:auto-correct false}])
|
||||
|
||||
(defn nickname-view
|
||||
[public-key {:keys [nickname ens-name three-words-name]}]
|
||||
(let [entered-nickname (reagent/atom nickname)]
|
||||
[]
|
||||
(let [{:keys [public-key primary-name nickname]} (rf/sub [:contacts/current-contact])
|
||||
entered-nickname (reagent/atom nickname)]
|
||||
(fn []
|
||||
[kb-presentation/keyboard-avoiding-view
|
||||
{:style {:flex 1}
|
||||
:ignore-offset true}
|
||||
[topbar/topbar
|
||||
{:title (i18n/label :t/nickname)
|
||||
:subtitle (or ens-name three-words-name)
|
||||
:subtitle primary-name
|
||||
:modal? true}]
|
||||
[react/view {:flex 1 :padding 16}
|
||||
[react/text {:style {:color colors/gray :margin-bottom 16}}
|
||||
|
@ -132,11 +135,6 @@
|
|||
:on-press #(save-nickname public-key @entered-nickname)}
|
||||
(i18n/label :t/done)]}]])))
|
||||
|
||||
(views/defview nickname
|
||||
[]
|
||||
(views/letsubs [{:keys [public-key names]} [:contacts/current-contact]]
|
||||
[nickname-view public-key names]))
|
||||
|
||||
(defn button-item
|
||||
[{:keys [icon label action selected disabled negative]}]
|
||||
[react/touchable-highlight
|
||||
|
@ -180,7 +178,7 @@
|
|||
[:contacts/current-contact])
|
||||
muted? @(re-frame/subscribe [:chats/muted
|
||||
public-key])
|
||||
[first-name second-name] (multiaccounts/contact-two-names contact true)
|
||||
{:keys [primary-name secondary-name]} contact
|
||||
on-share #(re-frame/dispatch
|
||||
[:show-popover
|
||||
(merge
|
||||
|
@ -202,10 +200,10 @@
|
|||
[(profile-header/extended-header
|
||||
{:on-press on-share
|
||||
:bottom-separator false
|
||||
:title first-name
|
||||
:title primary-name
|
||||
:photo (multiaccounts/displayed-photo contact)
|
||||
:monospace (not ens-verified)
|
||||
:subtitle second-name
|
||||
:subtitle secondary-name
|
||||
:compressed-key compressed-key
|
||||
:public-key public-key})]
|
||||
[react/view
|
||||
|
|
|
@ -20,13 +20,12 @@
|
|||
|
||||
(defn member-sheet
|
||||
[chat-id member us-admin?]
|
||||
(let [[first-name _] (multiaccounts/contact-two-names member false)]
|
||||
[react/view
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo member)]
|
||||
:title first-name
|
||||
:title (:primary-name member)
|
||||
:subtitle (i18n/label :t/view-profile)
|
||||
:accessibility-label :view-chat-details-button
|
||||
:chevron true
|
||||
|
@ -50,15 +49,15 @@
|
|||
:icon :main-icons/remove-contact
|
||||
:on-press #(chat.sheets/hide-sheet-and-dispatch
|
||||
[:group-chats.ui/remove-member-pressed chat-id
|
||||
(:public-key member)])}])]))
|
||||
(:public-key member)])}])])
|
||||
|
||||
(defn render-member
|
||||
[{:keys [public-key] :as member} _ _ {:keys [chat-id admin? current-user-identity]}]
|
||||
(let [[first-name second-name] (multiaccounts/contact-two-names member false)]
|
||||
(let [{:keys [primary-name secondary-name]} member]
|
||||
[quo/list-item
|
||||
(merge
|
||||
{:title first-name
|
||||
:subtitle second-name
|
||||
{:title primary-name
|
||||
:subtitle secondary-name
|
||||
:accessibility-label :member-item
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo member)]
|
||||
|
|
|
@ -565,7 +565,7 @@
|
|||
:insets {:bottom true}
|
||||
;;TODO dyn subtitle
|
||||
:options {:topBar {:visible false}}
|
||||
:component contact/nickname}
|
||||
:component contact/nickname-view}
|
||||
|
||||
{:name :new-chat-aio
|
||||
:on-focus [:contacts/new-chat-focus]
|
||||
|
|
|
@ -91,16 +91,15 @@
|
|||
|
||||
(defn contacts-list-item
|
||||
[{:keys [name] :as contact}]
|
||||
(let [[first-name second-name] (multiaccounts/contact-two-names contact true)]
|
||||
[quo/list-item
|
||||
{:title first-name
|
||||
:subtitle second-name
|
||||
{:title (:primary-name contact)
|
||||
:subtitle (:secondary-name contact)
|
||||
:on-press #(do
|
||||
(some-> ^js @scroll-view-ref
|
||||
(.scrollTo #js {:x 0 :animated true}))
|
||||
(re-frame/dispatch [:wallet.recipient/address-changed name]))
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo contact)]}]))
|
||||
(multiaccounts/displayed-photo contact)]}])
|
||||
|
||||
(defn empty-items
|
||||
[icon title]
|
||||
|
|
|
@ -3,33 +3,22 @@
|
|||
[quo2.core :as quo2]
|
||||
[quo2.foundations.colors :as quo2.colors]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[react-native.core :as rn]
|
||||
[utils.re-frame :as rf]
|
||||
[clojure.string :as string]
|
||||
[status-im2.common.contact-list.view :as contact-list]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[status-im.ui.components.invite.events :as invite.events]
|
||||
[status-im.ui2.screens.chat.components.new-chat.styles :as style]
|
||||
[status-im.react-native.resources :as resources]))
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im2.common.contact-list-item.view :as contact-list-item]))
|
||||
|
||||
(defn- hide-sheet-and-dispatch
|
||||
[event]
|
||||
(rf/dispatch [:bottom-sheet/hide])
|
||||
(rf/dispatch event))
|
||||
|
||||
(defn- on-toggle
|
||||
[allow-new-users? checked? public-key]
|
||||
(cond
|
||||
checked?
|
||||
(re-frame/dispatch [:deselect-contact public-key allow-new-users?])
|
||||
;; Only allow new users if not reached the maximum
|
||||
(and (not checked?)
|
||||
allow-new-users?)
|
||||
(re-frame/dispatch [:select-contact public-key allow-new-users?])))
|
||||
|
||||
(defn- no-contacts-view
|
||||
[]
|
||||
[rn/view
|
||||
|
@ -59,27 +48,33 @@
|
|||
:on-press #(hide-sheet-and-dispatch [:open-modal :new-contact])}
|
||||
(i18n/label :t/add-a-contact)]])
|
||||
|
||||
(defn contact-item-render
|
||||
[_]
|
||||
(fn [{:keys [public-key] :as item}]
|
||||
(let [user-selected? (rf/sub [:is-contact-selected? public-key])
|
||||
on-toggle #(if user-selected?
|
||||
(re-frame/dispatch [:deselect-contact public-key])
|
||||
(re-frame/dispatch [:select-contact public-key]))]
|
||||
[contact-list-item/contact-list-item
|
||||
{:on-press on-toggle
|
||||
:accessory {:type :checkbox
|
||||
:checked? user-selected?
|
||||
:on-check on-toggle}}
|
||||
item])))
|
||||
|
||||
(defn contact-selection-list
|
||||
[]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [contacts (rf/sub
|
||||
[:contacts/sorted-and-grouped-by-first-letter])
|
||||
(let [contacts (rf/sub [:contacts/sorted-and-grouped-by-first-letter])
|
||||
selected-contacts-count (rf/sub [:selected-contacts-count])
|
||||
selected-contacts (rf/sub [:group/selected-contacts])
|
||||
window-height (rf/sub [:dimensions/window-height])
|
||||
one-contact-selected? (= selected-contacts-count 1)
|
||||
contacts-selected? (pos? selected-contacts-count)
|
||||
{:keys [names public-key]} (when one-contact-selected?
|
||||
{:keys [primary-name public-key]} (when one-contact-selected?
|
||||
(rf/sub [:contacts/contact-by-identity
|
||||
(first selected-contacts)]))
|
||||
added? (reagent/atom '())
|
||||
{:keys [nickname ens-name display-name
|
||||
three-words-name]} names
|
||||
first-username (or nickname
|
||||
ens-name
|
||||
(when-not (string/blank? display-name) display-name)
|
||||
three-words-name)
|
||||
no-contacts? (empty? contacts)]
|
||||
[rn/view {:style {:height (* window-height 0.9)}}
|
||||
[quo2/button
|
||||
|
@ -102,20 +97,19 @@
|
|||
:weight :regular
|
||||
:style {:color (quo2.colors/theme-colors quo2.colors/neutral-40 quo2.colors/neutral-50)}}
|
||||
(i18n/label :t/selected-count-from-max
|
||||
{:selected (inc selected-contacts-count)
|
||||
{:selected selected-contacts-count
|
||||
:max constants/max-group-chat-participants})])]
|
||||
[rn/view
|
||||
{:style {:flex 1}}
|
||||
(if no-contacts?
|
||||
[no-contacts-view]
|
||||
[contact-list/contact-list
|
||||
{:icon :check
|
||||
:group nil
|
||||
:added? added?
|
||||
:search? false
|
||||
:start-a-new-chat? true
|
||||
:on-toggle on-toggle}
|
||||
70])]
|
||||
[rn/section-list
|
||||
{:key-fn :title
|
||||
:sticky-section-headers-enabled false
|
||||
:sections (rf/sub [:contacts/filtered-active-sections])
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:content-container-style {:padding-bottom 70}
|
||||
:render-fn contact-item-render}])]
|
||||
(when contacts-selected?
|
||||
[button/button
|
||||
{:type :primary
|
||||
|
@ -128,5 +122,5 @@
|
|||
(hide-sheet-and-dispatch [:navigate-to
|
||||
:new-group])))}
|
||||
(if one-contact-selected?
|
||||
(i18n/label :t/chat-with {:selected-user first-username})
|
||||
(i18n/label :t/chat-with {:selected-user primary-name})
|
||||
(i18n/label :t/setup-group-chat))])]))])
|
||||
|
|
|
@ -76,7 +76,6 @@
|
|||
|
||||
(defn on-text-change
|
||||
[val chat-id]
|
||||
(println "on=text-change" val)
|
||||
(swap! input-texts assoc chat-id val)
|
||||
;;we still store it in app-db for mentions, we don't have reactions in views
|
||||
(rf/dispatch [:chat.ui/set-chat-input-text val]))
|
||||
|
|
|
@ -1,51 +1,2 @@
|
|||
(ns status-im.ui2.screens.chat.composer.mentions
|
||||
(:require [quo.components.list.item :as list-item]
|
||||
[quo.components.text :as text]
|
||||
[quo.react]
|
||||
[quo.react-native :as rn]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.screens.chat.photos :as photos]
|
||||
[utils.re-frame :as rf]))
|
||||
(ns status-im.ui2.screens.chat.composer.mentions)
|
||||
|
||||
(defn mention-item
|
||||
[[public-key {:keys [alias name nickname] :as user}] _ _ text-input-ref]
|
||||
(let [ens-name? (not= alias name)]
|
||||
[rn/touchable-opacity
|
||||
{:on-press #(rf/dispatch [:chat.ui/select-mention text-input-ref user])
|
||||
:accessibility-label :mention-item}
|
||||
;;TODO quo2 item should be used
|
||||
[list-item/list-item
|
||||
(cond->
|
||||
{:icon [photos/member-photo public-key]
|
||||
:size :small
|
||||
:text-size :small
|
||||
:title [text/text
|
||||
{:weight :medium
|
||||
:ellipsize-mode :tail
|
||||
:number-of-lines 1
|
||||
:size :small}
|
||||
(or nickname name)
|
||||
(when nickname
|
||||
[text/text
|
||||
{:weight :regular
|
||||
:color :secondary
|
||||
:ellipsize-mode :tail
|
||||
:size :small}
|
||||
" "
|
||||
(when ens-name?
|
||||
"@")
|
||||
name])]
|
||||
:title-text-weight :medium}
|
||||
ens-name?
|
||||
(assoc :subtitle alias))]]))
|
||||
|
||||
(defn autocomplete-mentions
|
||||
[suggestions text-input-ref]
|
||||
[list/flat-list
|
||||
{:keyboardShouldPersistTaps :always
|
||||
:data suggestions
|
||||
:key-fn first
|
||||
:render-fn mention-item
|
||||
:render-data text-input-ref
|
||||
:content-container-style {:padding-bottom 12}
|
||||
:accessibility-label :mentions-list}])
|
||||
|
|
|
@ -154,23 +154,12 @@
|
|||
[rn/view style/not-sent-icon
|
||||
[icons/icon :i/warning {:color quo.colors/red}]]]])
|
||||
|
||||
(defn message-delivery-status
|
||||
[{:keys [chat-id message-id outgoing-status message-type]}]
|
||||
(when (and (not= constants/message-type-private-group-system-message message-type)
|
||||
(= outgoing-status :not-sent))
|
||||
[message-not-sent-text chat-id message-id]))
|
||||
|
||||
;; TODO (Omar): a reminder to clean these defviews
|
||||
(defview message-author-name
|
||||
[from opts max-length]
|
||||
(letsubs [contact-with-names [:contacts/contact-by-identity from]]
|
||||
(chat.utils/format-author contact-with-names opts max-length)))
|
||||
|
||||
(defview message-my-name
|
||||
[opts]
|
||||
(letsubs [contact-with-names [:multiaccount/contact]]
|
||||
(chat.utils/format-author contact-with-names opts nil)))
|
||||
|
||||
(defn display-name-view
|
||||
[display-name contact timestamp show-key?]
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
|
|
|
@ -1,23 +1,6 @@
|
|||
(ns status-im2.common.contact-list.view
|
||||
(:require [quo2.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.contact-list-item.view :as contact-list-item]
|
||||
[utils.re-frame :as rf]))
|
||||
(:require [quo2.core :as quo]))
|
||||
|
||||
(defn contacts-section-header
|
||||
[{:keys [title]}]
|
||||
[quo/divider-label {:label title}])
|
||||
|
||||
(defn contact-list
|
||||
[data padding-bottom]
|
||||
(let [contacts (if (:group data)
|
||||
(rf/sub [:contacts/grouped-by-first-letter])
|
||||
(rf/sub [:contacts/filtered-active-sections]))]
|
||||
[rn/section-list
|
||||
{:key-fn :title
|
||||
:sticky-section-headers-enabled false
|
||||
:sections contacts
|
||||
:render-section-header-fn contacts-section-header
|
||||
:content-container-style {:padding-bottom (or padding-bottom 20)}
|
||||
:render-data data
|
||||
:render-fn contact-list-item/contact-list-item}]))
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
(ns status-im2.common.contact-list-item.style)
|
||||
|
||||
(def container
|
||||
{:margin-top 8
|
||||
:margin-horizontal 8
|
||||
:padding-vertical 8
|
||||
:padding-horizontal 12
|
||||
:border-radius 12
|
||||
:flex-direction :row
|
||||
:align-items :center})
|
|
@ -1,119 +1,21 @@
|
|||
(ns status-im2.common.contact-list-item.view
|
||||
(:require [quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.home.actions.view :as actions]
|
||||
[status-im2.contexts.chat.home.chat-list-item.style :as style]
|
||||
[utils.address :as utils.address]
|
||||
[utils.re-frame :as rf]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn group-chat-member-toggle
|
||||
[member? selected? public-key]
|
||||
(if-not member?
|
||||
(if selected?
|
||||
(rf/dispatch [:select-participant public-key true])
|
||||
(rf/dispatch [:deselect-participant public-key true]))
|
||||
(if selected?
|
||||
(rf/dispatch [:undo-deselect-member public-key true])
|
||||
(rf/dispatch [:deselect-member public-key true]))))
|
||||
|
||||
(defn open-chat
|
||||
[public-key member? selected? current-pk]
|
||||
(let [view-id (rf/sub [:view-id])]
|
||||
(when (not= current-pk public-key)
|
||||
(case view-id
|
||||
:shell-stack (do (rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:chat.ui/show-profile public-key])
|
||||
(rf/dispatch [:search/home-filter-changed nil]))
|
||||
:group-chat-profile (group-chat-member-toggle member? selected? public-key)))))
|
||||
|
||||
(defn action-icon
|
||||
[{:keys [public-key]
|
||||
:as item}
|
||||
{:keys [icon start-a-new-chat?]
|
||||
:as extra-data} on-toggle admin? member?
|
||||
checked?]
|
||||
(let [on-check (fn []
|
||||
(if start-a-new-chat?
|
||||
(on-toggle true @checked? public-key)
|
||||
(group-chat-member-toggle member? (swap! checked? not) public-key)))]
|
||||
[:f>
|
||||
(fn []
|
||||
[rn/touchable-opacity
|
||||
{:on-press #(rf/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [actions/actions item extra-data])}])
|
||||
:style {:position :absolute
|
||||
:right 20}}
|
||||
(if (= icon :options)
|
||||
[quo/icon :i/options
|
||||
{:size 20
|
||||
:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]
|
||||
[quo/checkbox
|
||||
{:checked? @checked?
|
||||
:accessibility-label :contact-toggle-check
|
||||
:disabled? (and member? (not admin?))
|
||||
:on-change on-check}])])]))
|
||||
[utils.address :as address]))
|
||||
|
||||
(defn contact-list-item
|
||||
[item _ _ {:keys [start-a-new-chat? on-toggle group] :as extra-data}]
|
||||
(let [{:keys [public-key compressed-key ens-verified
|
||||
added? images]} item
|
||||
display-name (first
|
||||
(rf/sub
|
||||
[:contacts/contact-two-names-by-identity
|
||||
public-key]))
|
||||
photo-path (when (seq images)
|
||||
(rf/sub [:chats/photo-path public-key]))
|
||||
online? (rf/sub [:visibility-status-updates/online?
|
||||
public-key])
|
||||
user-selected? (rf/sub [:is-contact-selected? public-key])
|
||||
{:keys [contacts admins]} group
|
||||
member? (contains? contacts public-key)
|
||||
current-pk (rf/sub [:multiaccount/public-key])
|
||||
admin? (get admins current-pk)
|
||||
checked? (reagent/atom (if start-a-new-chat?
|
||||
user-selected?
|
||||
member?))]
|
||||
[rn/touchable-opacity
|
||||
(merge
|
||||
{:style (style/container)
|
||||
:accessibility-label :contact
|
||||
:active-opacity 1
|
||||
:on-press #(if start-a-new-chat?
|
||||
(on-toggle true user-selected? public-key)
|
||||
(open-chat public-key member? (swap! checked? not) current-pk))
|
||||
:on-long-press #(rf/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [actions/actions item extra-data])}])})
|
||||
[quo/user-avatar
|
||||
{:full-name display-name
|
||||
:profile-picture photo-path
|
||||
:status-indicator? true
|
||||
[{:keys [on-press on-long-press accessory]}
|
||||
{:keys [primary-name secondary-name public-key compressed-key ens-verified added?]}]
|
||||
(let [photo-path (rf/sub [:chats/photo-path public-key])
|
||||
online? (rf/sub [:visibility-status-updates/online? public-key])]
|
||||
[quo/user-list
|
||||
{:short-chat-key (address/get-shortened-key (or compressed-key public-key))
|
||||
:primary-name primary-name
|
||||
:secondary-name secondary-name
|
||||
:photo-path photo-path
|
||||
:online? online?
|
||||
:size :small
|
||||
:ring? false}]
|
||||
[rn/view {:style {:margin-left 8}}
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
[quo/text {:weight :semi-bold} display-name]
|
||||
(if ens-verified
|
||||
[rn/view
|
||||
{:style {:margin-left 5
|
||||
:margin-top 4}}
|
||||
[quo/icon :i/verified
|
||||
{:no-color true
|
||||
:size 12
|
||||
:color (colors/theme-colors colors/success-50 colors/success-60)}]]
|
||||
(when added?
|
||||
[rn/view
|
||||
{:style {:margin-left 5
|
||||
:margin-top 4}}
|
||||
[quo/icon :i/contact
|
||||
{:no-color true
|
||||
:size 12
|
||||
:color (colors/theme-colors colors/primary-50 colors/primary-60)}]]))]
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}}
|
||||
(utils.address/get-shortened-address (or compressed-key public-key))]]
|
||||
(when-not (= current-pk public-key)
|
||||
[action-icon item extra-data on-toggle admin? member? checked?])]))
|
||||
:verified? ens-verified
|
||||
:contact? added?
|
||||
:on-press on-press
|
||||
:on-long-press on-long-press
|
||||
:accessory accessory}]))
|
||||
|
|
|
@ -433,16 +433,15 @@
|
|||
(leave-group-entry contact extra-data)
|
||||
(remove-from-group-entry contact chat-id))])]]))
|
||||
|
||||
(defn actions
|
||||
[{:keys [chat-type] :as item} {:keys [inside-chat?] :as extra-data}]
|
||||
(defn chat-actions
|
||||
[{:keys [chat-type] :as item} inside-chat?]
|
||||
(case chat-type
|
||||
constants/one-to-one-chat-type
|
||||
[one-to-one-actions item inside-chat?]
|
||||
constants/public-chat-type
|
||||
[public-chat-actions item inside-chat?]
|
||||
constants/private-group-chat-type
|
||||
[private-group-chat-actions item inside-chat?]
|
||||
[contact-actions item extra-data]))
|
||||
[private-group-chat-actions item inside-chat?]))
|
||||
|
||||
(defn group-details-actions
|
||||
[{:keys [admins] :as group}]
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
[quo2.foundations.colors :as colors]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im2.contexts.activity-center.notification.common.style :as style]
|
||||
[status-im2.contexts.activity-center.utils :as activity-center.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
|
@ -18,7 +17,7 @@
|
|||
:size :small
|
||||
:style style/user-avatar-tag
|
||||
:text-style style/user-avatar-tag-text}
|
||||
(activity-center.utils/contact-name contact)
|
||||
(:primary-name contact)
|
||||
(multiaccounts/displayed-photo contact)]))
|
||||
|
||||
(defn- render-swipe-action
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
(ns status-im2.contexts.activity-center.utils)
|
||||
|
||||
(defn contact-name
|
||||
[contact]
|
||||
(->> [(get-in contact [:names :nickname])
|
||||
(get-in contact [:names :ens-name])
|
||||
(get-in contact [:names :display-name])
|
||||
(get-in contact [:names :three-words-name])]
|
||||
|
||||
(filter seq)
|
||||
first))
|
|
@ -10,9 +10,10 @@
|
|||
[status-im2.constants :as constants]
|
||||
[status-im.chat.models.loading :as loading]
|
||||
[status-im.data-store.chats :as chats-store]
|
||||
[status-im.data-store.contacts :as contacts-store]
|
||||
[status-im2.contexts.contacts.events :as contacts-store]
|
||||
[status-im.multiaccounts.model :as multiaccounts.model]
|
||||
[status-im.utils.clocks :as utils.clocks]))
|
||||
[status-im.utils.clocks :as utils.clocks]
|
||||
[status-im.utils.types :as types]))
|
||||
|
||||
(defn- get-chat
|
||||
[cofx chat-id]
|
||||
|
@ -221,10 +222,10 @@
|
|||
|
||||
(rf/defn handle-one-to-one-chat-created
|
||||
{:events [:chat/one-to-one-chat-created]}
|
||||
[{:keys [db]} chat-id response]
|
||||
(let [chat (chats-store/<-rpc (first (:chats response)))
|
||||
contact-rpc (first (:contacts response))
|
||||
contact (when contact-rpc (contacts-store/<-rpc contact-rpc))]
|
||||
[{:keys [db]} chat-id response-js]
|
||||
(let [chat (chats-store/<-rpc (first (types/js->clj (.-chats ^js response-js))))
|
||||
contact-js (first (.-contacts ^js response-js))
|
||||
contact (when contact-js (contacts-store/<-rpc-js contact-js))]
|
||||
{:db (cond-> db
|
||||
contact
|
||||
(assoc-in [:contacts/contacts chat-id] contact)
|
||||
|
@ -255,6 +256,7 @@
|
|||
(when (not= (multiaccounts.model/current-public-key cofx) chat-id)
|
||||
{:json-rpc/call [{:method "wakuext_createOneToOneChat"
|
||||
:params [{:id chat-id :ensName ens-name}]
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:chat/one-to-one-chat-created chat-id %])
|
||||
:on-error #(log/error "failed to create one-to-on chat" chat-id %)}]}))
|
||||
|
||||
|
|
|
@ -1,30 +1,31 @@
|
|||
(ns status-im2.contexts.chat.group-details.view
|
||||
(:require [utils.i18n :as i18n]
|
||||
[quo.components.safe-area :as safe-area]
|
||||
[quo2.core :as quo2]
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.contexts.chat.group-details.style :as style]
|
||||
[status-im2.common.contact-list.view :as contact-list]
|
||||
[status-im2.common.contact-list-item.view :as contact-list-item]
|
||||
[status-im2.common.home.actions.view :as actions]
|
||||
[utils.re-frame :as rf]))
|
||||
[utils.re-frame :as rf]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn back-button
|
||||
[]
|
||||
[quo2/button
|
||||
[quo/button
|
||||
{:type :grey
|
||||
:size 32
|
||||
:width 32
|
||||
:style {:margin-left 20}
|
||||
:accessibility-label :back-button
|
||||
:on-press #(rf/dispatch [:navigate-back])}
|
||||
[quo2/icon :i/arrow-left {:color (colors/theme-colors colors/neutral-100 colors/white)}]])
|
||||
[quo/icon :i/arrow-left {:color (colors/theme-colors colors/neutral-100 colors/white)}]])
|
||||
|
||||
(defn options-button
|
||||
[]
|
||||
(let [group (rf/sub [:chats/current-chat])]
|
||||
[quo2/button
|
||||
[quo/button
|
||||
{:type :grey
|
||||
:size 32
|
||||
:width 32
|
||||
|
@ -32,7 +33,7 @@
|
|||
:accessibility-label :options-button
|
||||
:on-press #(rf/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [actions/group-details-actions group])}])}
|
||||
[quo2/icon :i/options {:color (colors/theme-colors colors/neutral-100 colors/white)}]]))
|
||||
[quo/icon :i/options {:color (colors/theme-colors colors/neutral-100 colors/white)}]]))
|
||||
|
||||
(defn top-buttons
|
||||
[]
|
||||
|
@ -47,7 +48,7 @@
|
|||
[rn/view
|
||||
{:style (style/count-container)
|
||||
:accessibility-label accessibility-label}
|
||||
[quo2/text
|
||||
[quo/text
|
||||
{:size :label
|
||||
:weight :medium
|
||||
:style {:text-align :center}} count]])
|
||||
|
@ -60,11 +61,37 @@
|
|||
:border-top-color colors/neutral-20
|
||||
:padding-vertical 8
|
||||
:margin-top 8}}
|
||||
[quo2/text
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}} title]])
|
||||
|
||||
(defn group-chat-member-toggle
|
||||
[member? selected? public-key]
|
||||
(if-not member?
|
||||
(if selected?
|
||||
(rf/dispatch [:select-participant public-key true])
|
||||
(rf/dispatch [:deselect-participant public-key true]))
|
||||
(if selected?
|
||||
(rf/dispatch [:undo-deselect-member public-key true])
|
||||
(rf/dispatch [:deselect-member public-key true]))))
|
||||
|
||||
(defn add-member-contact-item-render
|
||||
[{:keys [public-key] :as item} _ _ {:keys [group]}]
|
||||
(let [current-pk (rf/sub [:multiaccount/public-key])
|
||||
{:keys [contacts]} group
|
||||
member? (contains? contacts public-key)
|
||||
checked? (reagent/atom member?)]
|
||||
(fn []
|
||||
(let [on-toggle #(group-chat-member-toggle member? (swap! checked? not) public-key)]
|
||||
[contact-list-item/contact-list-item
|
||||
(when (not= current-pk public-key)
|
||||
{:on-press on-toggle
|
||||
:accessory {:type :checkbox
|
||||
:checked? @checked?
|
||||
:on-check on-toggle}})
|
||||
item]))))
|
||||
|
||||
(defn add-members-sheet
|
||||
[group admin?]
|
||||
[:f>
|
||||
|
@ -78,18 +105,22 @@
|
|||
{:on-press #(rf/dispatch [:bottom-sheet/hide])
|
||||
:accessibility-label :close-manage-members
|
||||
:style (style/close-icon)}
|
||||
[quo2/icon :i/close {:color (colors/theme-colors colors/neutral-100 colors/white)}]]
|
||||
[quo2/text
|
||||
[quo/icon :i/close {:color (colors/theme-colors colors/neutral-100 colors/white)}]]
|
||||
[quo/text
|
||||
{:size :heading-1
|
||||
:weight :semi-bold
|
||||
:style {:margin-left 20}}
|
||||
(i18n/label (if admin? :t/manage-members :t/add-members))]
|
||||
[contact-list/contact-list
|
||||
{:icon :check
|
||||
:group group
|
||||
:search? true}]
|
||||
[rn/section-list
|
||||
{:key-fn :title
|
||||
:sticky-section-headers-enabled false
|
||||
:sections (rf/sub [:contacts/grouped-by-first-letter])
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:content-container-style {:padding-bottom 20}
|
||||
:render-data {:group group}
|
||||
:render-fn add-member-contact-item-render}]
|
||||
[rn/view {:style (style/bottom-container safe-area)}
|
||||
[quo2/button
|
||||
[quo/button
|
||||
{:style {:flex 1}
|
||||
:accessibility-label :save
|
||||
:on-press (fn []
|
||||
|
@ -103,6 +134,20 @@
|
|||
(zero? (count deselected-members)))}
|
||||
(i18n/label :t/save)]]]))])
|
||||
|
||||
(defn contact-item-render
|
||||
[{:keys [public-key] :as item} _ _ extra-data]
|
||||
(let [current-pk (rf/sub [:multiaccount/public-key])
|
||||
show-profile-actions #(rf/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [actions/contact-actions item
|
||||
extra-data])}])]
|
||||
[contact-list-item/contact-list-item
|
||||
(when (not= public-key current-pk)
|
||||
{:on-press #(rf/dispatch [:chat.ui/show-profile public-key])
|
||||
:on-long-press show-profile-actions
|
||||
:accessory {:type :options
|
||||
:on-press show-profile-actions}})
|
||||
item]))
|
||||
|
||||
(defn group-details
|
||||
[]
|
||||
(let [{:keys [admins chat-id chat-name color public?
|
||||
|
@ -116,7 +161,7 @@
|
|||
[rn/view
|
||||
{:style {:flex 1
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95)}}
|
||||
[quo2/header
|
||||
[quo/header
|
||||
{:left-component [back-button]
|
||||
:right-component [options-button]
|
||||
:background (colors/theme-colors colors/white colors/neutral-95)}]
|
||||
|
@ -124,15 +169,15 @@
|
|||
{:style {:flex-direction :row
|
||||
:margin-top 24
|
||||
:padding-horizontal 20}}
|
||||
[quo2/group-avatar
|
||||
[quo/group-avatar
|
||||
{:color color
|
||||
:size :medium}]
|
||||
[quo2/text
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-1
|
||||
:style {:margin-horizontal 8}} chat-name]
|
||||
[rn/view {:style {:margin-top 8}}
|
||||
[quo2/icon (if public? :i/world :i/privacy)
|
||||
[quo/icon (if public? :i/world :i/privacy)
|
||||
{:size 20 :color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]]]
|
||||
[rn/view {:style (style/actions-view)}
|
||||
[rn/touchable-opacity
|
||||
|
@ -144,17 +189,17 @@
|
|||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between}}
|
||||
[quo2/icon :i/pin {:size 20 :color (colors/theme-colors colors/neutral-100 colors/white)}]
|
||||
[quo/icon :i/pin {:size 20 :color (colors/theme-colors colors/neutral-100 colors/white)}]
|
||||
[count-container (count pinned-messages) :pinned-count]]
|
||||
[quo2/text {:style {:margin-top 16} :size :paragraph-1 :weight :medium}
|
||||
[quo/text {:style {:margin-top 16} :size :paragraph-1 :weight :medium}
|
||||
(i18n/label :t/pinned-messages)]]
|
||||
[rn/touchable-opacity
|
||||
{:style (style/action-container color)
|
||||
:accessibility-label :toggle-mute
|
||||
:on-press #(rf/dispatch [:chat.ui/mute chat-id (not muted)])}
|
||||
[quo2/icon (if muted :i/muted :i/activity-center)
|
||||
[quo/icon (if muted :i/muted :i/activity-center)
|
||||
{:size 20 :color (colors/theme-colors colors/neutral-100 colors/white)}]
|
||||
[quo2/text {:style {:margin-top 16} :size :paragraph-1 :weight :medium}
|
||||
[quo/text {:style {:margin-top 16} :size :paragraph-1 :weight :medium}
|
||||
(i18n/label (if muted :unmute-group :mute-group))]]
|
||||
[rn/touchable-opacity
|
||||
{:style (style/action-container color)
|
||||
|
@ -168,16 +213,15 @@
|
|||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between}}
|
||||
[quo2/icon :i/add-user {:size 20 :color (colors/theme-colors colors/neutral-100 colors/white)}]
|
||||
[quo/icon :i/add-user {:size 20 :color (colors/theme-colors colors/neutral-100 colors/white)}]
|
||||
[count-container (count contacts) :members-count]]
|
||||
[quo2/text {:style {:margin-top 16} :size :paragraph-1 :weight :medium}
|
||||
[quo/text {:style {:margin-top 16} :size :paragraph-1 :weight :medium}
|
||||
(i18n/label (if admin? :t/manage-members :t/add-members))]]]
|
||||
[rn/section-list
|
||||
{:key-fn :title
|
||||
:sticky-section-headers-enabled false
|
||||
:sections members
|
||||
:render-section-header-fn contacts-section-header
|
||||
:render-fn contact-list-item/contact-list-item
|
||||
:render-data {:chat-id chat-id
|
||||
:admin? admin?
|
||||
:icon :options}}]]))
|
||||
:admin? admin?}
|
||||
:render-fn contact-item-render}]]))
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
(merge {:style (style/container)
|
||||
:on-press (open-chat chat-id)
|
||||
:on-long-press #(rf/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [actions/actions item false])}])})
|
||||
{:content (fn [] [actions/chat-actions item false])}])})
|
||||
[avatar-view group-chat color display-name photo-path chat-id]
|
||||
[rn/view {:style {:margin-left 8}}
|
||||
[name-view display-name contact timestamp]
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
[status-im2.common.home.view :as common.home]
|
||||
[status-im2.contexts.chat.home.chat-list-item.view :as chat-list-item]
|
||||
[status-im2.contexts.chat.home.contact-request.view :as contact-request]
|
||||
[utils.re-frame :as rf]))
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.common.contact-list-item.view :as contact-list-item]
|
||||
[status-im2.common.home.actions.view :as actions]))
|
||||
|
||||
(defn get-item-layout
|
||||
[_ index]
|
||||
|
@ -50,6 +52,29 @@
|
|||
[quo/text {:weight :semi-bold} (i18n/label :t/no-contacts)]
|
||||
[quo/text (i18n/label :t/blank-contacts-text)]])
|
||||
|
||||
(defn contact-item-render
|
||||
[{:keys [public-key] :as item}]
|
||||
(let [current-pk (rf/sub [:multiaccount/public-key])
|
||||
show-profile-actions #(rf/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [actions/contact-actions item])}])]
|
||||
[contact-list-item/contact-list-item
|
||||
(when (not= public-key current-pk)
|
||||
{:on-press #(rf/dispatch [:chat.ui/show-profile public-key])
|
||||
:on-long-press show-profile-actions
|
||||
:accessory {:type :options
|
||||
:on-press show-profile-actions}})
|
||||
item]))
|
||||
|
||||
(defn contacts-section-list
|
||||
[sections]
|
||||
[rn/section-list
|
||||
{:key-fn :title
|
||||
:sticky-section-headers-enabled false
|
||||
:sections sections
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:content-container-style {:padding-bottom 20}
|
||||
:render-fn contact-item-render}])
|
||||
|
||||
(defn contacts
|
||||
[pending-contact-requests]
|
||||
(let [items (rf/sub [:contacts/active-sections])]
|
||||
|
@ -59,7 +84,7 @@
|
|||
(when (seq pending-contact-requests)
|
||||
[contact-request/contact-requests pending-contact-requests])
|
||||
(when (seq items)
|
||||
[contact-list/contact-list {:icon :options}])])))
|
||||
[contacts-section-list items])])))
|
||||
|
||||
(defn tabs
|
||||
[]
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
(ns status-im2.contexts.chat.messages.composer.mentions.view
|
||||
(:require [utils.re-frame :as rf]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im2.common.contact-list-item.view :as contact-list-item]))
|
||||
|
||||
(defn mention-item
|
||||
[user _ _ text-input-ref]
|
||||
[contact-list-item/contact-list-item
|
||||
{:on-press #(rf/dispatch [:chat.ui/select-mention text-input-ref user])} user])
|
||||
|
||||
(defn mentions
|
||||
[{:keys [refs suggestions max-y]} insets]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [translate-y (reanimated/use-shared-value 0)]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(reanimated/set-shared-value translate-y
|
||||
(reanimated/with-timing (if (seq suggestions) 0 200)))))
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}]}
|
||||
{:bottom (or (:bottom insets) 0)
|
||||
:position :absolute
|
||||
:left 0
|
||||
:right 0
|
||||
:z-index 5
|
||||
:elevation 5
|
||||
:max-height (/ max-y 2)})}
|
||||
[rn/flat-list
|
||||
{:keyboardShouldPersistTaps :always
|
||||
:data (vals suggestions)
|
||||
:key-fn :key
|
||||
:render-fn mention-item
|
||||
:render-data (:text-input-ref refs)
|
||||
:accessibility-label :mentions-list}]]))])
|
|
@ -9,9 +9,9 @@
|
|||
[utils.re-frame :as rf]
|
||||
[status-im2.contexts.chat.messages.composer.style :as style]
|
||||
[status-im2.contexts.chat.messages.composer.controls.view :as controls]
|
||||
[status-im2.contexts.chat.messages.composer.mentions.view :as mentions]
|
||||
[status-im.ui2.screens.chat.composer.edit.view :as edit]
|
||||
[status-im.ui2.screens.chat.composer.input :as input]
|
||||
[status-im.ui2.screens.chat.composer.mentions :as mentions]
|
||||
[status-im.ui2.screens.chat.composer.reply :as reply]))
|
||||
|
||||
(def initial-content-height (atom nil))
|
||||
|
@ -98,25 +98,6 @@
|
|||
(update-y params))
|
||||
(reset! initial-content-height new-height)))))
|
||||
|
||||
(defn mentions
|
||||
[{:keys [refs suggestions max-y]} insets]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [translate-y (reanimated/use-shared-value 0)]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(reanimated/set-shared-value translate-y
|
||||
(reanimated/with-timing (if (seq suggestions) 0 200)))))
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}]}
|
||||
{:bottom (or (:bottom insets) 0)
|
||||
:position :absolute
|
||||
:z-index 5
|
||||
:elevation 5
|
||||
:max-height (/ max-y 2)})}
|
||||
[mentions/autocomplete-mentions suggestions (:text-input-ref refs)]]))])
|
||||
|
||||
(defn effect!
|
||||
[{:keys [keyboard-shown reply edit suggestions images] :as params}]
|
||||
(rn/use-effect
|
||||
|
@ -241,7 +222,7 @@
|
|||
:sending-image (seq images)
|
||||
:refs refs}]]]]
|
||||
(if suggestions?
|
||||
[mentions params insets]
|
||||
[mentions/mentions params insets]
|
||||
[controls/view send-ref params insets chat-id images #(clean-and-minimize params)])
|
||||
;;;;black background
|
||||
[reanimated/view
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
(defn user-xxx-deleted-this-message
|
||||
[{:keys [display-name profile-picture]}]
|
||||
[rn/view {:style {:flex-direction :row :align-items :center}}
|
||||
[rn/view {:style {:flex-direction :row :align-items :center :flex 1 :flex-wrap :wrap}}
|
||||
[rn/view {:style {:margin-right 4}}
|
||||
[quo/user-avatar
|
||||
{:full-name display-name
|
||||
|
@ -15,9 +15,7 @@
|
|||
:status-indicator? false
|
||||
:ring? false
|
||||
:size :xxxs}]]
|
||||
[quo/display-name
|
||||
{:profile-name display-name
|
||||
:text-style {}}]
|
||||
[quo/author {:primary-name display-name}]
|
||||
[quo/text {:style {:margin-left 4} :size :paragraph-2}
|
||||
(i18n/label :t/deleted-this-message)]])
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
(ns status-im2.contexts.chat.messages.content.view
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im2.contexts.chat.messages.content.style :as style]
|
||||
[status-im2.contexts.chat.messages.content.pin.view :as pin]
|
||||
[status-im2.constants :as constants]
|
||||
|
@ -18,7 +17,8 @@
|
|||
[status-im.ui2.screens.chat.messages.message :as old-message]
|
||||
[status-im2.common.not-implemented :as not-implemented]
|
||||
[utils.datetime :as datetime]
|
||||
[reagent.core :as reagent]))
|
||||
[reagent.core :as reagent]
|
||||
[utils.address :as address]))
|
||||
|
||||
(def delivery-state-showing-time-ms 3000)
|
||||
|
||||
|
@ -52,12 +52,12 @@
|
|||
from
|
||||
timestamp]}]
|
||||
(when (or (and (seq response-to) quoted-message) last-in-group? pinned)
|
||||
(let [display-name (first (rf/sub [:contacts/contact-two-names-by-identity from]))
|
||||
(let [[primary-name secondary-name] (rf/sub [:contacts/contact-two-names-by-identity from])
|
||||
{:keys [ens-verified added?]} (rf/sub [:contacts/contact-by-address from])]
|
||||
[quo/author
|
||||
{:profile-name display-name
|
||||
:short-chat-key (utils/get-shortened-address (or compressed-key
|
||||
from))
|
||||
{:primary-name primary-name
|
||||
:secondary-name secondary-name
|
||||
:short-chat-key (address/get-shortened-key (or compressed-key from))
|
||||
:time-str (datetime/timestamp->time timestamp)
|
||||
:contact? added?
|
||||
:verified? ens-verified}])))
|
||||
|
|
|
@ -1,22 +1,124 @@
|
|||
(ns status-im2.contexts.contacts.events
|
||||
(:require
|
||||
[utils.re-frame :as rf]
|
||||
[status-im.contact.db :as contact.db]
|
||||
[status-im.data-store.contacts :as contacts-store]))
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.utils.types :as types]
|
||||
[oops.core :as oops]
|
||||
[status-im2.constants :as constants]))
|
||||
|
||||
(rf/defn load-contacts
|
||||
{:events [:contacts/contacts-loaded]}
|
||||
[{:keys [db] :as cofx} all-contacts]
|
||||
(let [contacts-list (map #(vector (:public-key %)
|
||||
(if (empty? (:address %))
|
||||
(dissoc % :address)
|
||||
%))
|
||||
all-contacts)
|
||||
contacts (into {} contacts-list)]
|
||||
{:db (cond-> (-> db
|
||||
(update :contacts/contacts #(merge contacts %))
|
||||
(assoc :contacts/blocked (contact.db/get-blocked-contacts all-contacts))))}))
|
||||
(defn <-rpc-js
|
||||
[^js js-contact]
|
||||
{:public-key (oops/oget js-contact "id")
|
||||
:compressed-key (oops/oget js-contact "compressedKey")
|
||||
:primary-name (oops/oget js-contact "primaryName")
|
||||
:secondary-name (.-secondaryName js-contact)
|
||||
:ens-name (.-ensName js-contact)
|
||||
:nickname (.-localNickname js-contact)
|
||||
:identicon (oops/oget js-contact "identicon")
|
||||
:images (types/js->clj (oops/oget js-contact "images"))
|
||||
:ens-verified (oops/oget js-contact "ensVerified")
|
||||
:contact-request-state (oops/oget js-contact "contactRequestState")
|
||||
:last-updated (oops/oget js-contact "lastUpdated")
|
||||
:active? (oops/oget js-contact "active")
|
||||
:blocked? (oops/oget js-contact "blocked")
|
||||
:added? (oops/oget js-contact "added")
|
||||
:has-added-us? (oops/oget js-contact "hasAddedUs")
|
||||
:mutual? (oops/oget js-contact "mutual")})
|
||||
|
||||
(defn prepare-events-for-contact
|
||||
[db chats-js]
|
||||
(fn [events {:keys [public-key has-added-us? blocked? contact-request-state] :as contact}]
|
||||
(let [was-blocked? (get-in db [:contacts/contacts public-key :blocked?])]
|
||||
(cond-> events
|
||||
(and (not has-added-us?) (= constants/contact-request-state-none contact-request-state))
|
||||
(conj [:activity-center/remove-pending-contact-request public-key])
|
||||
|
||||
(and blocked? (not was-blocked?))
|
||||
(conj [:contacts/blocked contact chats-js])))))
|
||||
|
||||
(defn update-contacts
|
||||
[contacts-cljs]
|
||||
(fn [contacts]
|
||||
(reduce (fn [contacts {:keys [public-key] :as contact}]
|
||||
(update contacts public-key merge contact))
|
||||
contacts
|
||||
contacts-cljs)))
|
||||
|
||||
(rf/defn process-js-contacts
|
||||
[{:keys [db]} response-js]
|
||||
(let [contacts-js (oops/oget response-js "contacts")
|
||||
contacts-cljs (map <-rpc-js contacts-js)
|
||||
chats-js (.-chatsForContacts response-js)
|
||||
events (reduce
|
||||
(prepare-events-for-contact db chats-js)
|
||||
[[:activity-center.notifications/fetch-unread-count]]
|
||||
contacts-cljs)]
|
||||
(js-delete response-js "contacts")
|
||||
(js-delete response-js "chatsForContacts")
|
||||
(merge
|
||||
{:db (update db :contacts/contacts (update-contacts contacts-cljs))
|
||||
:utils/dispatch-later [{:ms 20 :dispatch [:process-response response-js]}]}
|
||||
(when (> (count events) 1)
|
||||
{:dispatch-n events}))))
|
||||
|
||||
(rf/defn initialize-contacts
|
||||
[cofx]
|
||||
(contacts-store/fetch-contacts-rpc cofx #(rf/dispatch [:contacts/contacts-loaded %])))
|
||||
[_]
|
||||
{:json-rpc/call [{:method "wakuext_contacts"
|
||||
:params []
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:contacts/contacts-loaded (map <-rpc-js %)])
|
||||
:on-error #(log/error "failed to fetch contacts" %)}]})
|
||||
|
||||
(rf/defn contacts-loaded
|
||||
{:events [:contacts/contacts-loaded]}
|
||||
[{:keys [db]} contacts]
|
||||
{:db (assoc db :contacts/contacts (into {} (map #(vector (:public-key %) %) contacts)))})
|
||||
|
||||
(rf/defn add-contact
|
||||
"Add a contact and set pending to false"
|
||||
{:events [:contact.ui/add-contact-pressed]}
|
||||
[{:keys [db]} public-key nickname ens-name]
|
||||
(when (not= (get-in db [:multiaccount :public-key]) public-key)
|
||||
{:json-rpc/call [{:method "wakuext_addContact"
|
||||
:params [{:id public-key :nickname nickname :ensName ens-name}]
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to add contact" public-key %)}]}))
|
||||
|
||||
(rf/defn remove-contact
|
||||
"Remove a contact from current account's contact list"
|
||||
{:events [:contact.ui/remove-contact-pressed]}
|
||||
[{:keys [db]} {:keys [public-key]}]
|
||||
{:db (-> db
|
||||
(assoc-in [:contacts/contacts public-key :added?] false)
|
||||
(assoc-in [:contacts/contacts public-key :contact-request-state]
|
||||
constants/contact-request-state-none))
|
||||
:json-rpc/call [{:method "wakuext_retractContactRequest"
|
||||
:params [{:id public-key}]
|
||||
:on-success #(log/debug "contact removed successfully")
|
||||
:on-error #(log/error "failed to remove contact" public-key %)}]})
|
||||
|
||||
(rf/defn update-nickname
|
||||
{:events [:contacts/update-nickname]}
|
||||
[_ public-key nickname]
|
||||
{:json-rpc/call [{:method "wakuext_setContactLocalNickname"
|
||||
:params [{:id public-key :nickname nickname}]
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to set contact nickname " public-key nickname %)}]})
|
||||
|
||||
(rf/defn block
|
||||
[_ contact-id on-success]
|
||||
{:json-rpc/call [{:method "wakuext_blockContact"
|
||||
:params [contact-id]
|
||||
:js-response true
|
||||
:on-success on-success
|
||||
:on-error #(log/error "failed to block contact" % contact-id)}]})
|
||||
|
||||
(rf/defn unblock
|
||||
[_ contact-id on-success]
|
||||
{:json-rpc/call [{:method "wakuext_unblockContact"
|
||||
:params [contact-id]
|
||||
:on-success on-success
|
||||
:js-response true
|
||||
:on-error #(log/error "failed to unblock contact" % contact-id)}]})
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
|
||||
(defn preview-channel
|
||||
[]
|
||||
[rn/keyboard-avoiding-view {:style {:flex 1}}
|
||||
[rn/view
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-90)
|
||||
:flex 1}
|
||||
|
@ -76,4 +77,4 @@
|
|||
{:flex 1
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|
||||
:key-fn str}]]])
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
(ns status-im2.contexts.quo-preview.list-items.user-list
|
||||
(:require [react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]
|
||||
[quo2.components.list-items.user-list :as user-list]
|
||||
[utils.address :as address]))
|
||||
|
||||
(def descriptor
|
||||
[{:label "Primary name"
|
||||
:key :primary-name
|
||||
:type :text
|
||||
:limit 24}
|
||||
{:label "Secondary name"
|
||||
:key :secondary-name
|
||||
:type :text}
|
||||
{:label "Chat key"
|
||||
:key :chat-key
|
||||
:type :text}
|
||||
{:label "Is contact?"
|
||||
:key :contact?
|
||||
:type :boolean}
|
||||
{:label "Is verified?"
|
||||
:key :verified?
|
||||
:type :boolean}
|
||||
{:label "Is untrustworthy?"
|
||||
:key :untrustworthy?
|
||||
:type :boolean}
|
||||
{:label "Online?"
|
||||
:key :online?
|
||||
:type :boolean}
|
||||
{:label "Accessory:"
|
||||
:key :accessory
|
||||
:type :select
|
||||
:options [{:key {:type :options}
|
||||
:value "Options"}
|
||||
{:key {:type :checkbox}
|
||||
:value "Checkbox"}
|
||||
{:key {:type :close}
|
||||
:value "Close"}]}])
|
||||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(let [state (reagent/atom {:primary-name "Alisher Yakupov"
|
||||
:short-chat-key (address/get-shortened-key
|
||||
"zQ3ssgRy5TtB47MMiMKMKaGyaawkCgMqqbrnAUYrZJ1sgt5N")
|
||||
:ens-verified true
|
||||
:contact? false
|
||||
:verified? false
|
||||
:untrustworthy? false
|
||||
:online? false})]
|
||||
(fn []
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
[rn/view {:padding-bottom 150}
|
||||
[rn/view {:flex 1}
|
||||
[preview/customizer state descriptor]]
|
||||
[rn/view
|
||||
{:padding-vertical 60
|
||||
:padding--horizontal 15
|
||||
:justify-content :center}
|
||||
[user-list/user-list @state]]]])))
|
||||
|
||||
(defn preview-user-list
|
||||
[]
|
||||
[rn/keyboard-avoiding-view {:style {:flex 1}}
|
||||
[rn/view
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-90)
|
||||
:flex 1}
|
||||
[rn/flat-list
|
||||
{:flex 1
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]]])
|
|
@ -7,7 +7,6 @@
|
|||
[quo2.theme :as theme]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im2.contexts.quo-preview.animated-header-list.animated-header-list :as animated-header-list]
|
||||
[status-im2.contexts.quo-preview.avatars.account-avatar :as account-avatar]
|
||||
[status-im2.contexts.quo-preview.avatars.channel-avatar :as channel-avatar]
|
||||
|
@ -74,7 +73,8 @@
|
|||
[status-im2.contexts.quo-preview.wallet.lowest-price :as lowest-price]
|
||||
[status-im2.contexts.quo-preview.wallet.network-amount :as network-amount]
|
||||
[status-im2.contexts.quo-preview.wallet.network-breakdown :as network-breakdown]
|
||||
[status-im2.contexts.quo-preview.wallet.token-overview :as token-overview]))
|
||||
[status-im2.contexts.quo-preview.wallet.token-overview :as token-overview]
|
||||
[status-im2.contexts.quo-preview.list-items.user-list :as user-list]))
|
||||
|
||||
(def screens-categories
|
||||
{:foundations [{:name :shadows
|
||||
|
@ -166,7 +166,10 @@
|
|||
:component channel/preview-channel}
|
||||
{:name :preview-lists
|
||||
:insets {:top false}
|
||||
:component preview-lists/preview-preview-lists}]
|
||||
:component preview-lists/preview-preview-lists}
|
||||
{:name :user-list
|
||||
:insets {:top false}
|
||||
:component user-list/preview-user-list}]
|
||||
:markdown [{:name :texts
|
||||
:insets {:top false}
|
||||
:component text/preview-text}]
|
||||
|
@ -289,11 +292,8 @@
|
|||
(defn main-screen
|
||||
[]
|
||||
(fn []
|
||||
[safe-area/consumer
|
||||
(fn [insets]
|
||||
[rn/scroll-view
|
||||
{:flex 1
|
||||
:padding-top (:top insets)
|
||||
:padding-bottom 8
|
||||
:padding-horizontal 16
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-90)}
|
||||
|
@ -314,7 +314,7 @@
|
|||
:style {:margin-vertical 8}
|
||||
:on-press #(re-frame/dispatch [:navigate-to name])}
|
||||
(clojure.core/name name)])])
|
||||
(sort screens-categories))]])]))
|
||||
(sort screens-categories))]]))
|
||||
|
||||
(def main-screens
|
||||
[{:name :quo2-preview
|
||||
|
|
|
@ -5,23 +5,19 @@
|
|||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]
|
||||
[status-im.utils.utils :as utils]))
|
||||
[utils.address :as address]))
|
||||
|
||||
(def descriptor
|
||||
[{:label "Profile name"
|
||||
:key :profile-name
|
||||
[{:label "Primary name"
|
||||
:key :primary-name
|
||||
:type :text
|
||||
:limit 24}
|
||||
{:label "Nickname"
|
||||
:key :nickname
|
||||
{:label "Secondary name"
|
||||
:key :secondary-name
|
||||
:type :text}
|
||||
{:label "Chat key"
|
||||
:key :chat-key
|
||||
:type :text}
|
||||
{:label "ENS name"
|
||||
:key :ens-name
|
||||
:type :text
|
||||
:suffix ".eth"}
|
||||
{:label "Time"
|
||||
:key :time-str
|
||||
:type :text
|
||||
|
@ -38,12 +34,11 @@
|
|||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(let [state (reagent/atom {:profile-name "Alisher Yakupov"
|
||||
:nickname ""
|
||||
:short-chat-key (utils/get-shortened-address
|
||||
(let [state (reagent/atom {:primary-name "Alisher Yakupov"
|
||||
:seconadary-name ""
|
||||
:short-chat-key (address/get-shortened-key
|
||||
"zQ3ssgRy5TtB47MMiMKMKaGyaawkCgMqqbrnAUYrZJ1sgt5N")
|
||||
:time-str "09:30"
|
||||
:ens-name ""
|
||||
:contact? false
|
||||
:verified? false
|
||||
:untrustworthy? false})]
|
||||
|
@ -58,14 +53,11 @@
|
|||
:justify-content :center}
|
||||
[rn/view
|
||||
[text/text "Author:"]
|
||||
[quo2/author @state]]
|
||||
[rn/view {:height 50}]
|
||||
[rn/view
|
||||
[text/text "Display Name:"]
|
||||
[quo2/display-name @state]]]]])))
|
||||
[quo2/author @state]]]]])))
|
||||
|
||||
(defn preview-author
|
||||
[]
|
||||
[rn/keyboard-avoiding-view {:style {:flex 1}}
|
||||
[rn/view
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-90)
|
||||
:flex 1}
|
||||
|
@ -73,4 +65,4 @@
|
|||
{:flex 1
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|
||||
:key-fn str}]]])
|
||||
|
|
|
@ -54,17 +54,14 @@
|
|||
:type :group-avatar})]
|
||||
(fn []
|
||||
(let [contacts {example-pk {:public-key example-pk
|
||||
:names {:three-words-name
|
||||
"Automatic incompatible Coati"}
|
||||
:primary-name "Automatic incompatible Coati"
|
||||
:photo example-photo}
|
||||
example-pk2 {:public-key example-pk2
|
||||
:names {:three-words-name
|
||||
"Clearcut Flickering Rattlesnake"}
|
||||
:primary-name "Clearcut Flickering Rattlesnake"
|
||||
:photo example-photo2}}
|
||||
contacts-public-keys (map (fn [{:keys [public-key]}]
|
||||
{:key public-key
|
||||
:value (multiaccounts/displayed-name
|
||||
(get contacts public-key))})
|
||||
:value (get-in contacts [public-key :primary-name])})
|
||||
(vals contacts))
|
||||
current-username (if (seq (:contact @state))
|
||||
(->> @state
|
||||
|
|
|
@ -338,7 +338,7 @@
|
|||
|
||||
(defn filter-selected-contacts
|
||||
[selected-contacts contacts]
|
||||
(filter #(:added (contacts %)) selected-contacts))
|
||||
(filter #(:added? (contacts %)) selected-contacts))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:selected-contacts-count
|
||||
|
@ -399,10 +399,14 @@
|
|||
:<- [:contacts/blocked-set]
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:multiaccount]
|
||||
(fn [[{:keys [users community-id] :as chat} blocked all-contacts
|
||||
{:keys [public-key] :as current-multiaccount}]]
|
||||
(let [community-members @(re-frame/subscribe [:communities/community-members community-id])
|
||||
mentionable-users (mentions/get-mentionable-users chat
|
||||
:<- [:communities/current-community-members]
|
||||
(fn
|
||||
[[{:keys [users] :as chat}
|
||||
blocked
|
||||
all-contacts
|
||||
{:keys [public-key] :as current-multiaccount}
|
||||
community-members]]
|
||||
(let [mentionable-users (mentions/get-mentionable-users chat
|
||||
all-contacts
|
||||
current-multiaccount
|
||||
community-members)
|
||||
|
|
|
@ -50,6 +50,13 @@
|
|||
(fn [communities [_ id]]
|
||||
(get-in communities [id :members])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/current-community-members
|
||||
:<- [:chats/current-chat]
|
||||
:<- [:communities]
|
||||
(fn [[{:keys [community-id]} communities]]
|
||||
(get-in communities [community-id :members])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/sorted-community-members
|
||||
(fn [[_ community-id]]
|
||||
|
|
|
@ -70,14 +70,16 @@
|
|||
:contacts/active
|
||||
:<- [:contacts/contacts]
|
||||
(fn [contacts]
|
||||
(contact.db/get-active-contacts contacts)))
|
||||
(->> contacts
|
||||
(filter (fn [[_ contact]] (:active? contact)))
|
||||
contact.db/sort-contacts)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/active-sections
|
||||
:<- [:contacts/active]
|
||||
(fn [contacts]
|
||||
(->> contacts
|
||||
(group-by #(string/upper-case (ffirst (:two-names %))))
|
||||
(group-by #(string/upper-case (first (:primary-name %))))
|
||||
sort
|
||||
(mapv (fn [[title items]] {:title title :data items})))))
|
||||
|
||||
|
@ -117,7 +119,7 @@
|
|||
:allow-new-users?
|
||||
(< selected-contacts-count
|
||||
(dec constants/max-group-chat-participants))))
|
||||
(group-by (comp (fnil string/upper-case "") first :alias))
|
||||
(group-by (comp (fnil string/upper-case "") first :primary-name))
|
||||
(sort-by first)
|
||||
(map (fn [[title data]]
|
||||
{:title title
|
||||
|
@ -135,8 +137,14 @@
|
|||
(fn [contacts]
|
||||
(->> contacts
|
||||
(filter (fn [[_ contact]]
|
||||
(:blocked contact)))
|
||||
(contact.db/sort-contacts))))
|
||||
(:blocked? contact)))
|
||||
contact.db/sort-contacts)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/blocked-set
|
||||
:<- [:contacts/blocked]
|
||||
(fn [contacts]
|
||||
(into #{} (map :public-key contacts))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/blocked-count
|
||||
|
@ -145,14 +153,12 @@
|
|||
(count blocked-contacts)))
|
||||
|
||||
(defn filter-recipient-contacts
|
||||
[search-filter {:keys [names]}]
|
||||
(let [{:keys [nickname three-words-name ens-name]} names]
|
||||
[search-filter {:keys [primary-name secondary-name]}]
|
||||
(or
|
||||
(when ens-name
|
||||
(string/includes? (string/lower-case (str ens-name)) search-filter))
|
||||
(string/includes? (string/lower-case three-words-name) search-filter)
|
||||
(when nickname
|
||||
(string/includes? (string/lower-case nickname) search-filter)))))
|
||||
(when primary-name
|
||||
(string/includes? (string/lower-case (str primary-name)) search-filter))
|
||||
(when secondary-name
|
||||
(string/includes? (string/lower-case (str secondary-name)) search-filter))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/active-with-ens-names
|
||||
|
@ -195,7 +201,7 @@
|
|||
(fn [[_ identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-by-identity identity])])
|
||||
(fn [[contact] _]
|
||||
(:added contact)))
|
||||
(:added? contact)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contact-blocked?
|
||||
|
@ -248,7 +254,7 @@
|
|||
:contacts/all-contacts-not-in-current-chat
|
||||
:<- [::query-current-chat-contacts remove]
|
||||
(fn [contacts]
|
||||
(filter :added contacts)))
|
||||
(filter :added? contacts)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/current-chat-contacts
|
||||
|
|
|
@ -11,8 +11,9 @@
|
|||
:mutual? true
|
||||
:contactRequestClock 0
|
||||
:images {}
|
||||
:added true
|
||||
:added? true
|
||||
:name "slim.shady"
|
||||
:primary-name "rslim.shady"
|
||||
:Removed false
|
||||
:trustStatus 0
|
||||
:alias "Real Slim Shady"
|
||||
|
@ -21,18 +22,20 @@
|
|||
:display-name ""
|
||||
:ens-verified true
|
||||
:socialLinks nil
|
||||
:blocked false
|
||||
:blocked? false
|
||||
:active? true
|
||||
:verificationStatus 0
|
||||
:lastUpdatedLocally 1672582563204
|
||||
:public-key "0xtest"
|
||||
:has-added-us true
|
||||
:has-added-us? true
|
||||
:contact-request-state 1}
|
||||
"0xtest2" {:last-updated 1672582629695
|
||||
:mutual? true
|
||||
:contactRequestClock 0
|
||||
:images {}
|
||||
:added true
|
||||
:added? true
|
||||
:name "slim.shady"
|
||||
:primary-name "fslim.shady"
|
||||
:Removed false
|
||||
:trustStatus 0
|
||||
:alias "Fake Slim Shady"
|
||||
|
@ -41,18 +44,20 @@
|
|||
:display-name ""
|
||||
:ens-verified true
|
||||
:socialLinks nil
|
||||
:blocked false
|
||||
:blocked? false
|
||||
:active? true
|
||||
:verificationStatus 0
|
||||
:lastUpdatedLocally 1672582563204
|
||||
:public-key "0xtest"
|
||||
:has-added-us true
|
||||
:has-added-us? true
|
||||
:contact-request-state 1}
|
||||
"0xtest3" {:last-updated 1672582629695
|
||||
:mutual? true
|
||||
:contactRequestClock 0
|
||||
:images {}
|
||||
:added true
|
||||
:added? true
|
||||
:name "slim.shady"
|
||||
:primary-name "islim.shady"
|
||||
:Removed false
|
||||
:trustStatus 0
|
||||
:alias "Instant noodles"
|
||||
|
@ -61,11 +66,12 @@
|
|||
:display-name ""
|
||||
:ens-verified true
|
||||
:socialLinks nil
|
||||
:blocked false
|
||||
:blocked? false
|
||||
:active? true
|
||||
:verificationStatus 0
|
||||
:lastUpdatedLocally 1672582563204
|
||||
:public-key "0xtest"
|
||||
:has-added-us true
|
||||
:has-added-us? true
|
||||
:contact-request-state 1}}})
|
||||
|
||||
(def expected-sorted-contacts
|
||||
|
@ -76,9 +82,9 @@
|
|||
:blocked? false
|
||||
:contactRequestClock 0
|
||||
:images {}
|
||||
:added true
|
||||
:name "slim.shady"
|
||||
:added? true
|
||||
:name "slim.shady"
|
||||
:primary-name "fslim.shady"
|
||||
:Removed false
|
||||
:trustStatus 0
|
||||
:alias "Fake Slim Shady"
|
||||
|
@ -87,17 +93,11 @@
|
|||
:display-name ""
|
||||
:ens-verified true
|
||||
:socialLinks nil
|
||||
:blocked false
|
||||
:allow-new-users? true
|
||||
:verificationStatus 0
|
||||
:lastUpdatedLocally 1672582563204
|
||||
:public-key "0xtest"
|
||||
:names {:nickname nil
|
||||
:display-name ""
|
||||
:three-words-name "Fake Slim Shady"
|
||||
:ens-name "slim.shady"}
|
||||
:two-names ["slim.shady" "Fake Slim Shady"]
|
||||
:has-added-us true
|
||||
:has-added-us? true
|
||||
:contact-request-state 1}]}
|
||||
{:title "I"
|
||||
:data [{:active? true
|
||||
|
@ -106,9 +106,9 @@
|
|||
:blocked? false
|
||||
:contactRequestClock 0
|
||||
:images {}
|
||||
:added true
|
||||
:name "slim.shady"
|
||||
:added? true
|
||||
:name "slim.shady"
|
||||
:primary-name "islim.shady"
|
||||
:Removed false
|
||||
:trustStatus 0
|
||||
:alias "Instant noodles"
|
||||
|
@ -117,17 +117,11 @@
|
|||
:display-name ""
|
||||
:ens-verified true
|
||||
:socialLinks nil
|
||||
:blocked false
|
||||
:allow-new-users? true
|
||||
:verificationStatus 0
|
||||
:lastUpdatedLocally 1672582563204
|
||||
:public-key "0xtest"
|
||||
:names {:nickname nil
|
||||
:display-name ""
|
||||
:three-words-name "Instant noodles"
|
||||
:ens-name "slim.shady"}
|
||||
:two-names ["slim.shady" "Instant noodles"]
|
||||
:has-added-us true
|
||||
:has-added-us? true
|
||||
:contact-request-state 1}]}
|
||||
{:title "R"
|
||||
:data [{:active? true
|
||||
|
@ -136,9 +130,9 @@
|
|||
:blocked? false
|
||||
:contactRequestClock 0
|
||||
:images {}
|
||||
:added true
|
||||
:name "slim.shady"
|
||||
:added? true
|
||||
:name "slim.shady"
|
||||
:primary-name "rslim.shady"
|
||||
:Removed false
|
||||
:trustStatus 0
|
||||
:alias "Real Slim Shady"
|
||||
|
@ -147,17 +141,11 @@
|
|||
:display-name ""
|
||||
:ens-verified true
|
||||
:socialLinks nil
|
||||
:blocked false
|
||||
:allow-new-users? true
|
||||
:verificationStatus 0
|
||||
:lastUpdatedLocally 1672582563204
|
||||
:public-key "0xtest"
|
||||
:names {:nickname nil
|
||||
:display-name ""
|
||||
:three-words-name "Real Slim Shady"
|
||||
:ens-name "slim.shady"}
|
||||
:two-names ["slim.shady" "Real Slim Shady"]
|
||||
:has-added-us true
|
||||
:has-added-us? true
|
||||
:contact-request-state 1}]}])
|
||||
|
||||
(h/deftest-sub :contacts/sorted-and-grouped-by-first-letter
|
||||
|
@ -182,5 +170,4 @@
|
|||
(dissoc contact :identicon))
|
||||
%)))
|
||||
(rf/sub [sub-name]))]
|
||||
|
||||
(is (= expected-sorted-contacts contact-list-without-identicons)))))
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
(ns status-im2.subs.multiaccount
|
||||
(:require [cljs.spec.alpha :as spec]
|
||||
[clojure.set :as set]
|
||||
[clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.fleet.core :as fleet]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.multiaccounts.db :as multiaccounts.db]
|
||||
[status-im.utils.image-server :as image-server]
|
||||
[utils.security.core :as security]))
|
||||
|
@ -20,11 +18,7 @@
|
|||
:multiaccount/contact
|
||||
:<- [:multiaccount]
|
||||
(fn [current-account]
|
||||
(some->
|
||||
current-account
|
||||
(select-keys [:name :preferred-name :public-key :identicon :image :images])
|
||||
(set/rename-keys {:name :alias})
|
||||
(multiaccounts/contact-with-names))))
|
||||
(select-keys current-account [:name :preferred-name :public-key :identicon :image :images])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:multiaccount/preferred-name
|
||||
|
|
|
@ -153,7 +153,6 @@
|
|||
(reg-root-key-sub :contacts/current-contact-ens-name :contacts/ens-name)
|
||||
(reg-root-key-sub :contacts/new-identity :contacts/new-identity)
|
||||
(reg-root-key-sub :group/selected-contacts :group/selected-contacts)
|
||||
(reg-root-key-sub :contacts/blocked-set :contacts/blocked)
|
||||
(reg-root-key-sub :contacts/search-query :contacts/search-query)
|
||||
|
||||
;;wallet
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
(:require [status-im.ethereum.core :as ethereum]
|
||||
[status-im.ethereum.eip55 :as eip55]))
|
||||
|
||||
(defn get-shortened-address
|
||||
(defn get-shortened-key
|
||||
"Takes first and last 4 digits from address including leading 0x
|
||||
and adds unicode ellipsis in between"
|
||||
[address]
|
||||
(when address
|
||||
(str (subs address 0 6) "\u2026" (subs address (- (count address) 3) (count address)))))
|
||||
[value]
|
||||
(when value
|
||||
(str (subs value 0 6) "\u2026" (subs value (- (count value) 3) (count value)))))
|
||||
|
||||
(defn get-shortened-checksum-address
|
||||
[address]
|
||||
(when address
|
||||
(get-shortened-address (eip55/address->checksum (ethereum/normalized-hex address)))))
|
||||
(get-shortened-key (eip55/address->checksum (ethereum/normalized-hex address)))))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.132.3",
|
||||
"commit-sha1": "999d8c0ee0f2274c58b5a2de3beddab7feaabd16",
|
||||
"src-sha256": "0qcpbhkhy8l3cq1055gnxghi7292jnd7xznl6s6h92pcg37y1jzc"
|
||||
"version": "feature/contacts-fields",
|
||||
"commit-sha1": "dde6e6570e3e1035b2d56b2db3695ddbc72909c7",
|
||||
"src-sha256": "1h0wcmi41svyky5w3059nzbyyzzldir1bf01wgzhbykvnn26sjhp"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue