parent
1af6d925d2
commit
e21b8d4396
|
@ -1,6 +1,6 @@
|
|||
(ns quo2.components.avatars.group-avatar
|
||||
(:require [quo2.components.icon :as icon]
|
||||
[quo2.foundations.colors :as colors]
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[quo2.components.icon :as icon]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def sizes
|
||||
|
@ -11,20 +11,17 @@
|
|||
:medium 32
|
||||
:large 48}})
|
||||
|
||||
;; TODO: this implementation does not support group display picture (can only display default group
|
||||
;; icon).
|
||||
(defn group-avatar
|
||||
[_]
|
||||
;; TODO: this implementation does not support group display picture (can only display default group icon).
|
||||
(defn group-avatar [_]
|
||||
(fn [{:keys [color size]}]
|
||||
(let [container-size (get-in sizes [:container size])
|
||||
icon-size (get-in sizes [:icon size])]
|
||||
[rn/view
|
||||
{:width container-size
|
||||
:height container-size
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:border-radius (/ container-size 2)
|
||||
:background-color (colors/custom-color-by-theme color 50 60)}
|
||||
[icon/icon :i/group
|
||||
{:size icon-size
|
||||
:color colors/white-opa-70}]])))
|
||||
[rn/view {:width container-size
|
||||
:height container-size
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:border-radius (/ container-size 2)
|
||||
;:background-color (colors/custom-color-by-theme color 50 60) ; TODO: this is temporary only. Issue: https://github.com/status-im/status-mobile/issues/14566
|
||||
:background-color color}
|
||||
[icon/icon :i/group {:size icon-size
|
||||
:color colors/white-opa-70}]])))
|
||||
|
|
|
@ -37,17 +37,26 @@
|
|||
{:events [:group-chats.ui/remove-member-pressed]}
|
||||
[_ chat-id member do-not-navigate?]
|
||||
{:json-rpc/call [{:method "wakuext_removeMemberFromGroupChat"
|
||||
:params [nil chat-id member]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated % do-not-navigate?])}]})
|
||||
:params [nil chat-id member]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated % true])}]})
|
||||
|
||||
(fx/defn remove-members
|
||||
{:events [:group-chats.ui/remove-members-pressed]}
|
||||
[{{:keys [current-chat-id] :group-chat/keys [deselected-members]} :db :as cofx}]
|
||||
{:json-rpc/call [{:method "wakuext_removeMembersFromGroupChat"
|
||||
:params [nil current-chat-id deselected-members]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated % true])
|
||||
:on-error #()}]})
|
||||
|
||||
(fx/defn join-chat
|
||||
{:events [:group-chats.ui/join-pressed]}
|
||||
[_ chat-id]
|
||||
{:json-rpc/call [{:method "wakuext_confirmJoiningGroup"
|
||||
:params [chat-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]})
|
||||
:params [chat-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]})
|
||||
|
||||
(fx/defn create
|
||||
{:events [:group-chats.ui/create-pressed]
|
||||
|
@ -55,54 +64,54 @@
|
|||
[{:keys [db] :as cofx} group-name]
|
||||
(let [selected-contacts (:group/selected-contacts db)]
|
||||
{:json-rpc/call [{:method "wakuext_createGroupChatWithMembers"
|
||||
:params [nil group-name (into [] selected-contacts)]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]}))
|
||||
:params [nil group-name (into [] selected-contacts)]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]}))
|
||||
|
||||
(fx/defn create-from-link
|
||||
[cofx {:keys [chat-id invitation-admin chat-name]}]
|
||||
(if (get-in cofx [:db :chats chat-id])
|
||||
{:dispatch [:chat.ui/navigate-to-chat chat-id]}
|
||||
{:json-rpc/call [{:method "wakuext_createGroupChatFromInvitation"
|
||||
:params [chat-name chat-id invitation-admin]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]}))
|
||||
:params [chat-name chat-id invitation-admin]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]}))
|
||||
|
||||
(fx/defn make-admin
|
||||
{:events [:group-chats.ui/make-admin-pressed]}
|
||||
[_ chat-id member]
|
||||
{:json-rpc/call [{:method "wakuext_addAdminsToGroupChat"
|
||||
:params [nil chat-id [member]]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]})
|
||||
:params [nil chat-id [member]]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]})
|
||||
|
||||
(fx/defn add-members
|
||||
"Add members to a group chat"
|
||||
{:events [:group-chats.ui/add-members-pressed]}
|
||||
[{{:keys [current-chat-id selected-participants]} :db :as cofx}]
|
||||
[{{:keys [current-chat-id] :group-chat/keys [selected-participants]} :db :as cofx}]
|
||||
{:json-rpc/call [{:method "wakuext_addMembersToGroupChat"
|
||||
:params [nil current-chat-id selected-participants]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]})
|
||||
:params [nil current-chat-id selected-participants]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated % true])}]})
|
||||
|
||||
(fx/defn add-members-from-invitation
|
||||
"Add members to a group chat"
|
||||
{:events [:group-chats.ui/add-members-from-invitation]}
|
||||
[{{:keys [current-chat-id] :as db} :db :as cofx} id participant]
|
||||
{:db (assoc-in db [:group-chat/invitations id :state] constants/invitation-state-approved)
|
||||
{:db (assoc-in db [:group-chat/invitations id :state] constants/invitation-state-approved)
|
||||
:json-rpc/call [{:method "wakuext_addMembersToGroupChat"
|
||||
:params [nil current-chat-id [participant]]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]})
|
||||
:params [nil current-chat-id [participant]]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]})
|
||||
|
||||
(fx/defn leave
|
||||
"Leave chat"
|
||||
{:events [:group-chats.ui/leave-chat-confirmed]}
|
||||
[{:keys [db] :as cofx} chat-id]
|
||||
{:json-rpc/call [{:method "wakuext_leaveGroupChat"
|
||||
:params [nil chat-id true]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-removed %])}]})
|
||||
:params [nil chat-id true]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-removed %])}]})
|
||||
|
||||
(fx/defn remove
|
||||
"Remove chat"
|
||||
|
@ -124,11 +133,11 @@
|
|||
{:events [:group-chats.ui/name-changed]}
|
||||
[{:keys [db] :as cofx} chat-id new-name]
|
||||
(when (valid-name? new-name)
|
||||
{:db (assoc-in db [:chats chat-id :name] new-name)
|
||||
{:db (assoc-in db [:chats chat-id :name] new-name)
|
||||
:json-rpc/call [{:method "wakuext_changeGroupChatName"
|
||||
:params [nil chat-id new-name]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]}))
|
||||
:params [nil chat-id new-name]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]}))
|
||||
|
||||
(fx/defn membership-retry
|
||||
{:events [:group-chats.ui/membership-retry]}
|
||||
|
@ -146,20 +155,20 @@
|
|||
[{{:keys [current-chat-id chats] :as db} :db :as cofx}]
|
||||
(let [{:keys [invitation-admin]} (get chats current-chat-id)
|
||||
message (get-in db [:chat/memberships current-chat-id :message])]
|
||||
{:db (assoc-in db [:chat/memberships current-chat-id] nil)
|
||||
{:db (assoc-in db [:chat/memberships current-chat-id] nil)
|
||||
:json-rpc/call [{:method "wakuext_sendGroupChatInvitationRequest"
|
||||
:params [nil current-chat-id invitation-admin message]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]}))
|
||||
:params [nil current-chat-id invitation-admin message]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]}))
|
||||
|
||||
(fx/defn send-group-chat-membership-rejection
|
||||
"Send group chat membership rejection"
|
||||
{:events [:send-group-chat-membership-rejection]}
|
||||
[cofx invitation-id]
|
||||
{:json-rpc/call [{:method "wakuext_sendGroupChatInvitationRejection"
|
||||
:params [nil invitation-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]})
|
||||
:params [nil invitation-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]})
|
||||
|
||||
(fx/defn handle-invitations
|
||||
[{db :db} invitations]
|
||||
|
@ -179,6 +188,16 @@
|
|||
:type
|
||||
(= constants/invitation-state-removed)))
|
||||
|
||||
(fx/defn deselect-member
|
||||
{:events [:deselect-member]}
|
||||
[{:keys [db]} id]
|
||||
{:db (update db :group-chat/deselected-members conj id)})
|
||||
|
||||
(fx/defn undo-deselect-member
|
||||
{:events [:undo-deselect-member]}
|
||||
[{:keys [db]} id]
|
||||
{:db (update db :group-chat/deselected-members disj id)})
|
||||
|
||||
(fx/defn deselect-contact
|
||||
{:events [:deselect-contact]}
|
||||
[{:keys [db]} id]
|
||||
|
@ -192,17 +211,22 @@
|
|||
(fx/defn deselect-participant
|
||||
{:events [:deselect-participant]}
|
||||
[{:keys [db]} id]
|
||||
{:db (update db :selected-participants disj id)})
|
||||
{:db (update db :group-chat/selected-participants disj id)})
|
||||
|
||||
(fx/defn select-participant
|
||||
{:events [:select-participant]}
|
||||
[{:keys [db]} id]
|
||||
{:db (update db :selected-participants conj id)})
|
||||
{:db (update db :group-chat/selected-participants conj id)})
|
||||
|
||||
(fx/defn add-participants-toggle-list
|
||||
{:events [:group/add-participants-toggle-list]}
|
||||
(fx/defn clear-added-participants
|
||||
{:events [:group/clear-added-participants]}
|
||||
[{db :db}]
|
||||
{:db (assoc db :selected-participants #{})})
|
||||
{:db (assoc db :group-chat/selected-participants #{})})
|
||||
|
||||
(fx/defn clear-removed-members
|
||||
{:events [:group/clear-removed-members]}
|
||||
[{db :db}]
|
||||
{:db (assoc db :group-chat/deselected-members #{})})
|
||||
|
||||
(fx/defn show-group-chat-profile
|
||||
{:events [:show-group-chat-profile]}
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
(ns status-im.ui.screens.group.views
|
||||
(:require [clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.ui.components.keyboard-avoid-presentation
|
||||
:as
|
||||
kb-presentation]
|
||||
[status-im.ui.components.invite.views :as invite]
|
||||
[status-im.ui.components.keyboard-avoid-presentation :as kb-presentation]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.search-input.view :as search]
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.ui.screens.group.styles :as styles]
|
||||
[quo.core :as quo]
|
||||
[utils.debounce :as debounce])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn- render-contact
|
||||
[row]
|
||||
(defn- render-contact [row]
|
||||
(let [[first-name second-name] (multiaccounts/contact-two-names row false)]
|
||||
[quo/list-item
|
||||
{:title first-name
|
||||
|
@ -27,8 +28,7 @@
|
|||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo row)]}]))
|
||||
|
||||
(defn- on-toggle
|
||||
[allow-new-users? checked? public-key]
|
||||
(defn- on-toggle [allow-new-users? checked? public-key]
|
||||
(cond
|
||||
|
||||
checked?
|
||||
|
@ -39,8 +39,7 @@
|
|||
allow-new-users?)
|
||||
(re-frame/dispatch [:select-contact public-key allow-new-users?])))
|
||||
|
||||
(defn- on-toggle-participant
|
||||
[allow-new-users? checked? public-key]
|
||||
(defn- on-toggle-participant [allow-new-users? checked? public-key]
|
||||
(cond
|
||||
|
||||
checked?
|
||||
|
@ -51,229 +50,196 @@
|
|||
allow-new-users?)
|
||||
(re-frame/dispatch [:select-participant public-key allow-new-users?])))
|
||||
|
||||
(defn- toggle-item
|
||||
[]
|
||||
(defn- toggle-item []
|
||||
(fn [allow-new-users? subs-name {:keys [public-key] :as contact} on-toggle]
|
||||
(let [contact-selected? @(re-frame/subscribe [subs-name public-key])
|
||||
(let [contact-selected? @(re-frame/subscribe [subs-name public-key])
|
||||
[first-name second-name] (multiaccounts/contact-two-names contact true)]
|
||||
[quo/list-item
|
||||
{:title first-name
|
||||
:subtitle second-name
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo contact)]
|
||||
(multiaccounts/displayed-photo contact)]
|
||||
:on-press #(on-toggle allow-new-users? contact-selected? public-key)
|
||||
:active contact-selected?
|
||||
:accessory :checkbox}])))
|
||||
|
||||
(defn- group-toggle-contact
|
||||
[contact _ _ allow-new-users?]
|
||||
(defn- group-toggle-contact [contact _ _ allow-new-users?]
|
||||
[toggle-item allow-new-users? :is-contact-selected? contact on-toggle])
|
||||
|
||||
(defn- group-toggle-participant
|
||||
[contact _ _ allow-new-users?]
|
||||
(defn- group-toggle-participant [contact _ _ allow-new-users?]
|
||||
[toggle-item allow-new-users? :is-participant-selected? contact on-toggle-participant])
|
||||
|
||||
(defn toggle-list
|
||||
[{:keys [contacts render-fn render-data]}]
|
||||
[list/flat-list
|
||||
{:data contacts
|
||||
:key-fn :public-key
|
||||
:render-data render-data
|
||||
:render-fn render-fn
|
||||
:keyboardShouldPersistTaps :always}])
|
||||
(defn toggle-list [{:keys [contacts render-fn render-data]}]
|
||||
[list/flat-list {:data contacts
|
||||
:key-fn :public-key
|
||||
:render-data render-data
|
||||
:render-fn render-fn
|
||||
:keyboardShouldPersistTaps :always}])
|
||||
|
||||
(defn no-contacts
|
||||
[{:keys [no-contacts]}]
|
||||
(defn no-contacts [{:keys [no-contacts]}]
|
||||
[react/view {:style styles/no-contacts}
|
||||
[react/text
|
||||
{:style (styles/no-contact-text)}
|
||||
no-contacts]
|
||||
[invite/button]])
|
||||
|
||||
(defn filter-contacts
|
||||
[filter-text contacts]
|
||||
(defn filter-contacts [filter-text contacts]
|
||||
(let [lower-filter-text (string/lower-case (str filter-text))
|
||||
filter-fn (fn [{:keys [name alias nickname]}]
|
||||
(or
|
||||
(string/includes? (string/lower-case (str name)) lower-filter-text)
|
||||
(string/includes? (string/lower-case (str alias)) lower-filter-text)
|
||||
(when nickname
|
||||
(string/includes? (string/lower-case (str nickname))
|
||||
lower-filter-text))))]
|
||||
(string/includes? (string/lower-case (str name)) lower-filter-text)
|
||||
(string/includes? (string/lower-case (str alias)) lower-filter-text)
|
||||
(when nickname
|
||||
(string/includes? (string/lower-case (str nickname)) lower-filter-text))))]
|
||||
(if filter-text
|
||||
(filter filter-fn contacts)
|
||||
contacts)))
|
||||
|
||||
;; Set name of new group-chat
|
||||
(views/defview new-group
|
||||
[]
|
||||
(views/letsubs [contacts [:selected-group-contacts]
|
||||
group-name [:new-chat-name]]
|
||||
(let [group-name-empty? (not (and (string? group-name) (not-empty group-name)))]
|
||||
[react/keyboard-avoiding-view
|
||||
{:style styles/group-container
|
||||
:ignore-offset true}
|
||||
[react/view {:flex 1}
|
||||
[topbar/topbar
|
||||
{:use-insets false
|
||||
:title (i18n/label :t/new-group-chat)
|
||||
:subtitle (i18n/label :t/group-chat-members-count
|
||||
{:selected (inc (count contacts))
|
||||
:max constants/max-group-chat-participants})}]
|
||||
[react/view
|
||||
{:style {:padding-top 16
|
||||
:flex 1}}
|
||||
[react/view {:style {:padding-horizontal 16}}
|
||||
[quo/text-input
|
||||
{:auto-focus true
|
||||
:on-change-text #(re-frame/dispatch [:set :new-chat-name %])
|
||||
:default-value group-name
|
||||
:placeholder (i18n/label :t/set-a-topic)
|
||||
:accessibility-label :chat-name-input}]
|
||||
[react/text {:style (styles/members-title)}
|
||||
(i18n/label :t/members-title)]]
|
||||
[react/view
|
||||
{:style {:margin-top 8
|
||||
:flex 1}}
|
||||
[list/flat-list
|
||||
{:data contacts
|
||||
:key-fn :address
|
||||
:render-fn render-contact
|
||||
:bounces false
|
||||
:keyboard-should-persist-taps :always
|
||||
:enable-empty-sections true}]]]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:left
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:before :main-icon/back
|
||||
:accessibility-label :previous-button
|
||||
:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
(i18n/label :t/back)]
|
||||
:right
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:accessibility-label :create-group-chat-button
|
||||
:disabled group-name-empty?
|
||||
:on-press #(debounce/dispatch-and-chill [:group-chats.ui/create-pressed
|
||||
group-name]
|
||||
300)}
|
||||
(i18n/label :t/create-group-chat)]}]]])))
|
||||
(views/defview new-group []
|
||||
(views/letsubs [contacts [:selected-group-contacts]
|
||||
group-name [:new-chat-name]]
|
||||
(let [group-name-empty? (not (and (string? group-name) (not-empty group-name)))]
|
||||
[react/keyboard-avoiding-view {:style styles/group-container
|
||||
:ignore-offset true}
|
||||
[react/view {:flex 1}
|
||||
[topbar/topbar {:use-insets false
|
||||
:title (i18n/label :t/new-group-chat)
|
||||
:subtitle (i18n/label :t/group-chat-members-count
|
||||
{:selected (inc (count contacts))
|
||||
:max constants/max-group-chat-participants})}]
|
||||
[react/view {:style {:padding-top 16
|
||||
:flex 1}}
|
||||
[react/view {:style {:padding-horizontal 16}}
|
||||
[quo/text-input
|
||||
{:auto-focus true
|
||||
:on-change-text #(re-frame/dispatch [:set :new-chat-name %])
|
||||
:default-value group-name
|
||||
:placeholder (i18n/label :t/set-a-topic)
|
||||
:accessibility-label :chat-name-input}]
|
||||
[react/text {:style (styles/members-title)}
|
||||
(i18n/label :t/members-title)]]
|
||||
[react/view {:style {:margin-top 8
|
||||
:flex 1}}
|
||||
[list/flat-list {:data contacts
|
||||
:key-fn :address
|
||||
:render-fn render-contact
|
||||
:bounces false
|
||||
:keyboard-should-persist-taps :always
|
||||
:enable-empty-sections true}]]]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:left
|
||||
[quo/button {:type :secondary
|
||||
:before :main-icon/back
|
||||
:accessibility-label :previous-button
|
||||
:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
(i18n/label :t/back)]
|
||||
:right
|
||||
[quo/button {:type :secondary
|
||||
:accessibility-label :create-group-chat-button
|
||||
:disabled group-name-empty?
|
||||
:on-press #(debounce/dispatch-and-chill [:group-chats.ui/create-pressed group-name]
|
||||
300)}
|
||||
(i18n/label :t/create-group-chat)]}]]])))
|
||||
|
||||
(defn searchable-contact-list
|
||||
[]
|
||||
(defn searchable-contact-list []
|
||||
(let [search-value (reagent/atom nil)]
|
||||
(fn [{:keys [contacts no-contacts-label toggle-fn allow-new-users?]}]
|
||||
[react/view {:style {:flex 1}}
|
||||
[react/view {:style (styles/search-container)}
|
||||
[search/search-input-old
|
||||
{:on-cancel #(reset! search-value nil)
|
||||
:on-change #(reset! search-value %)}]]
|
||||
[react/view
|
||||
{:style {:flex 1
|
||||
:padding-vertical 8}}
|
||||
[search/search-input-old {:on-cancel #(reset! search-value nil)
|
||||
:on-change #(reset! search-value %)}]]
|
||||
[react/view {:style {:flex 1
|
||||
:padding-vertical 8}}
|
||||
(if (seq contacts)
|
||||
[toggle-list
|
||||
{:contacts (filter-contacts @search-value contacts)
|
||||
:render-data allow-new-users?
|
||||
:render-fn toggle-fn}]
|
||||
[toggle-list {:contacts (filter-contacts @search-value contacts)
|
||||
:render-data allow-new-users?
|
||||
:render-fn toggle-fn}]
|
||||
[no-contacts {:no-contacts no-contacts-label}])]])))
|
||||
|
||||
;; Start group chat
|
||||
(views/defview contact-toggle-list
|
||||
[]
|
||||
(views/letsubs [contacts [:contacts/active]
|
||||
selected-contacts-count [:selected-contacts-count]]
|
||||
[react/keyboard-avoiding-view
|
||||
{:style styles/group-container
|
||||
:ignore-offset true}
|
||||
[topbar/topbar
|
||||
{:use-insets false
|
||||
:border-bottom false
|
||||
:title (i18n/label :t/new-group-chat)
|
||||
:subtitle (i18n/label :t/group-chat-members-count
|
||||
{:selected (inc selected-contacts-count)
|
||||
:max constants/max-group-chat-participants})}]
|
||||
[searchable-contact-list
|
||||
{:contacts contacts
|
||||
:no-contacts-label (i18n/label :t/group-chat-no-contacts)
|
||||
:toggle-fn group-toggle-contact
|
||||
:allow-new-users? (< selected-contacts-count
|
||||
(dec constants/max-group-chat-participants))}]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:right
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:after :main-icon/next
|
||||
:accessibility-label :next-button
|
||||
:on-press #(re-frame/dispatch [:navigate-to :new-group])}
|
||||
(i18n/label :t/next)]}]]))
|
||||
(views/defview contact-toggle-list []
|
||||
(views/letsubs [contacts [:contacts/active]
|
||||
selected-contacts-count [:selected-contacts-count]]
|
||||
[react/keyboard-avoiding-view {:style styles/group-container
|
||||
:ignore-offset true}
|
||||
[topbar/topbar {:use-insets false
|
||||
:border-bottom false
|
||||
:title (i18n/label :t/new-group-chat)
|
||||
:subtitle (i18n/label :t/group-chat-members-count
|
||||
{:selected (inc selected-contacts-count)
|
||||
:max constants/max-group-chat-participants})}]
|
||||
[searchable-contact-list
|
||||
{:contacts contacts
|
||||
:no-contacts-label (i18n/label :t/group-chat-no-contacts)
|
||||
:toggle-fn group-toggle-contact
|
||||
:allow-new-users? (< selected-contacts-count
|
||||
(dec constants/max-group-chat-participants))}]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:right
|
||||
[quo/button {:type :secondary
|
||||
:after :main-icon/next
|
||||
:accessibility-label :next-button
|
||||
:on-press #(re-frame/dispatch [:navigate-to :new-group])}
|
||||
(i18n/label :t/next)]}]]))
|
||||
|
||||
;; Add participants to existing group chat
|
||||
(views/defview add-participants-toggle-list
|
||||
[]
|
||||
(views/letsubs [contacts [:contacts/all-contacts-not-in-current-chat]
|
||||
current-chat [:chats/current-chat]
|
||||
selected-contacts-count [:selected-participants-count]]
|
||||
(let [current-participants-count (count (:contacts current-chat))]
|
||||
[kb-presentation/keyboard-avoiding-view {:style styles/group-container}
|
||||
[topbar/topbar
|
||||
{:use-insets false
|
||||
:border-bottom false
|
||||
:title (i18n/label :t/add-members)
|
||||
:subtitle (i18n/label :t/group-chat-members-count
|
||||
{:selected (+ current-participants-count selected-contacts-count)
|
||||
:max constants/max-group-chat-participants})}]
|
||||
[searchable-contact-list
|
||||
{:contacts contacts
|
||||
:no-contacts-label (i18n/label :t/group-chat-all-contacts-invited)
|
||||
:toggle-fn group-toggle-participant
|
||||
:allow-new-users? (< (+ current-participants-count
|
||||
selected-contacts-count)
|
||||
constants/max-group-chat-participants)}]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:center
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:accessibility-label :next-button
|
||||
:disabled (zero? selected-contacts-count)
|
||||
:on-press #(re-frame/dispatch [:group-chats.ui/add-members-pressed])}
|
||||
(i18n/label :t/add)]}]])))
|
||||
(views/defview add-participants-toggle-list []
|
||||
(views/letsubs [contacts [:contacts/all-contacts-not-in-current-chat]
|
||||
current-chat [:chats/current-chat]
|
||||
selected-contacts-count [:group-chat/selected-participants-count]]
|
||||
(let [current-participants-count (count (:contacts current-chat))]
|
||||
[kb-presentation/keyboard-avoiding-view {:style styles/group-container}
|
||||
[topbar/topbar {:use-insets false
|
||||
:border-bottom false
|
||||
:title (i18n/label :t/add-members)
|
||||
:subtitle (i18n/label :t/group-chat-members-count
|
||||
{:selected (+ current-participants-count selected-contacts-count)
|
||||
:max constants/max-group-chat-participants})}]
|
||||
[searchable-contact-list
|
||||
{:contacts contacts
|
||||
:no-contacts-label (i18n/label :t/group-chat-all-contacts-invited)
|
||||
:toggle-fn group-toggle-participant
|
||||
:allow-new-users? (< (+ current-participants-count
|
||||
selected-contacts-count)
|
||||
constants/max-group-chat-participants)}]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:center
|
||||
[quo/button {:type :secondary
|
||||
:accessibility-label :next-button
|
||||
:disabled (zero? selected-contacts-count)
|
||||
:on-press #(re-frame/dispatch [:group-chats.ui/add-members-pressed])}
|
||||
(i18n/label :t/add)]}]])))
|
||||
|
||||
(views/defview edit-group-chat-name
|
||||
[]
|
||||
(views/letsubs [{:keys [name chat-id]} [:chats/current-chat]
|
||||
new-group-chat-name (reagent/atom nil)]
|
||||
[kb-presentation/keyboard-avoiding-view {:style styles/group-container}
|
||||
[react/scroll-view
|
||||
{:style {:padding 16
|
||||
:flex 1}}
|
||||
[quo/text-input
|
||||
{:on-change-text #(reset! new-group-chat-name %)
|
||||
:default-value name
|
||||
:on-submit-editing #(when (seq @new-group-chat-name)
|
||||
(re-frame/dispatch [:group-chats.ui/name-changed chat-id
|
||||
@new-group-chat-name]))
|
||||
:placeholder (i18n/label :t/enter-contact-code)
|
||||
:accessibility-label :new-chat-name
|
||||
:return-key-type :go}]]
|
||||
[react/view {:style {:flex 1}}]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:center
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:accessibility-label :done
|
||||
:disabled (and (<= (count @new-group-chat-name) 1)
|
||||
(not (nil? @new-group-chat-name)))
|
||||
:on-press #(cond
|
||||
(< 1 (count @new-group-chat-name))
|
||||
(re-frame/dispatch [:group-chats.ui/name-changed chat-id
|
||||
@new-group-chat-name])
|
||||
(views/defview edit-group-chat-name []
|
||||
(views/letsubs [{:keys [name chat-id]} [:chats/current-chat]
|
||||
new-group-chat-name (reagent/atom nil)]
|
||||
[kb-presentation/keyboard-avoiding-view {:style styles/group-container}
|
||||
[react/scroll-view {:style {:padding 16
|
||||
:flex 1}}
|
||||
[quo/text-input
|
||||
{:on-change-text #(reset! new-group-chat-name %)
|
||||
:default-value name
|
||||
:on-submit-editing #(when (seq @new-group-chat-name)
|
||||
(re-frame/dispatch [:group-chats.ui/name-changed chat-id @new-group-chat-name]))
|
||||
:placeholder (i18n/label :t/enter-contact-code)
|
||||
:accessibility-label :new-chat-name
|
||||
:return-key-type :go}]]
|
||||
[react/view {:style {:flex 1}}]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:center
|
||||
[quo/button {:type :secondary
|
||||
:accessibility-label :done
|
||||
:disabled (and (<= (count @new-group-chat-name) 1)
|
||||
(not (nil? @new-group-chat-name)))
|
||||
:on-press #(cond
|
||||
(< 1 (count @new-group-chat-name))
|
||||
(re-frame/dispatch [:group-chats.ui/name-changed chat-id @new-group-chat-name])
|
||||
|
||||
(nil? @new-group-chat-name)
|
||||
(re-frame/dispatch [:navigate-back]))}
|
||||
(i18n/label :t/done)]}]]))
|
||||
(nil? @new-group-chat-name)
|
||||
(re-frame/dispatch [:navigate-back]))}
|
||||
(i18n/label :t/done)]}]]))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(ns status-im.ui2.screens.chat.group-details.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(defn actions-view
|
||||
[]
|
||||
|
@ -33,12 +34,15 @@
|
|||
:align-items :center
|
||||
:margin-bottom 24})
|
||||
|
||||
(def bottom-container
|
||||
{:position :absolute
|
||||
(defn bottom-container [safe-area]
|
||||
{
|
||||
;:position :absolute
|
||||
:padding-horizontal 20
|
||||
:padding-vertical 12
|
||||
:padding-bottom 33
|
||||
:padding-bottom (+ 33 (if platform/ios? (:bottom safe-area) 0))
|
||||
:width "100%"
|
||||
:background-color colors/white
|
||||
:flex-direction :row
|
||||
:bottom 0})
|
||||
;:padding-bottom (if platform/ios? (:bottom safe-area) 0)
|
||||
:margin-bottom (if platform/ios? 0 70)
|
||||
})
|
||||
|
|
|
@ -1,176 +1,139 @@
|
|||
(ns status-im.ui2.screens.chat.group-details.view
|
||||
(:require [i18n.i18n :as i18n]
|
||||
[oops.core :refer [oget]]
|
||||
[quo.components.safe-area :as safe-area]
|
||||
[quo2.core :as quo2]
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.chat.models :as chat.models]
|
||||
[status-im.ui2.screens.chat.group-details.style :as style]
|
||||
[status-im.ui2.screens.common.contact-list.view :as contact-list]
|
||||
[quo2.core :as quo2]
|
||||
[utils.re-frame :as rf]
|
||||
[i18n.i18n :as i18n]
|
||||
[status-im.chat.models :as chat.models]
|
||||
[status-im2.common.contact-list-item.view :as contact-list-item]
|
||||
[quo.components.safe-area :as safe-area]
|
||||
[status-im2.common.home.actions.view :as actions]
|
||||
[utils.re-frame :as rf]))
|
||||
[status-im.ui2.screens.common.contact-list.view :as contact-list]))
|
||||
|
||||
(defn back-button
|
||||
[]
|
||||
[quo2/button
|
||||
{:type :grey
|
||||
:size 32
|
||||
:width 32
|
||||
:style {:margin-left 20}
|
||||
:accessibility-label :back-button
|
||||
:on-press #(rf/dispatch [:navigate-back])}
|
||||
(defn back-button []
|
||||
[quo2/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)}]])
|
||||
|
||||
(defn options-button
|
||||
[]
|
||||
(defn options-button []
|
||||
(let [group (rf/sub [:chats/current-chat])]
|
||||
[quo2/button
|
||||
{:type :grey
|
||||
:size 32
|
||||
:width 32
|
||||
:style {:margin-right 20}
|
||||
:accessibility-label :options-button
|
||||
:on-press #(rf/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [actions/group-details-actions group])}])}
|
||||
[quo2/button {:type :grey
|
||||
:size 32
|
||||
:width 32
|
||||
:style {:margin-right 20}
|
||||
: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)}]]))
|
||||
|
||||
(defn top-buttons
|
||||
[]
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:padding-horizontal 20
|
||||
:justify-content :space-between}}
|
||||
(defn top-buttons []
|
||||
[rn/view {:style {:flex-direction :row
|
||||
:padding-horizontal 20
|
||||
:justify-content :space-between}}
|
||||
[back-button] [options-button]])
|
||||
|
||||
(defn count-container
|
||||
[count]
|
||||
[rn/view {:style (style/count-container)}
|
||||
[quo2/text
|
||||
{:size :label
|
||||
:weight :medium
|
||||
:style {:text-align :center}} count]])
|
||||
(defn count-container [count accessibility-label]
|
||||
[rn/view {:style (style/count-container)
|
||||
:accessibility-label accessibility-label}
|
||||
[quo2/text {:size :label
|
||||
:weight :medium
|
||||
:style {:text-align :center}} count]])
|
||||
|
||||
(defn contacts-section-header
|
||||
[{:keys [title]}]
|
||||
[rn/view
|
||||
{:style {:padding-horizontal 20
|
||||
:border-top-width 1
|
||||
:border-top-color colors/neutral-20
|
||||
:padding-vertical 8
|
||||
:margin-top 8}}
|
||||
[quo2/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}} title]])
|
||||
(defn contacts-section-header [{:keys [title]}]
|
||||
[rn/view {:style {:padding-horizontal 20 :border-top-width 1 :border-top-color colors/neutral-20 :padding-vertical 8 :margin-top 8}}
|
||||
[quo2/text {:size :paragraph-2
|
||||
:weight :medium
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}} title]])
|
||||
|
||||
(def added (reagent/atom ()))
|
||||
(defn add-members-sheet [group admin?]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [{window-height :height} (rn/use-window-dimensions)
|
||||
safe-area (safe-area/use-safe-area)
|
||||
selected-participants (rf/sub [:group-chat/selected-participants])
|
||||
deselected-members (rf/sub [:group-chat/deselected-members])]
|
||||
[rn/view {:style {:height (- window-height (:top safe-area))}}
|
||||
[rn/touchable-opacity
|
||||
{: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 {: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/view {:style (style/bottom-container safe-area)}
|
||||
[quo2/button {:style {:flex 1}
|
||||
:accessibility-label :save
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:group-chats.ui/add-members-pressed])
|
||||
(js/setTimeout #(rf/dispatch [:group-chats.ui/remove-members-pressed]) 500)
|
||||
(rf/dispatch [:bottom-sheet/hide]))
|
||||
:disabled (and (zero? (count selected-participants)) (zero? (count deselected-members)))}
|
||||
(i18n/label :t/save)]]]))])
|
||||
|
||||
(defn contact-requests-sheet
|
||||
[group]
|
||||
(let [added (reagent/atom ())]
|
||||
(fn []
|
||||
[:f>
|
||||
(fn []
|
||||
(let [{window-height :height} (rn/use-window-dimensions)
|
||||
safe-area (safe-area/use-safe-area)]
|
||||
[rn/view {:style {:height (- window-height (:top safe-area))}}
|
||||
[rn/touchable-opacity
|
||||
{:on-press #(rf/dispatch [:bottom-sheet/hide])
|
||||
:style (style/close-icon)}
|
||||
[quo2/icon :i/close {:color (colors/theme-colors colors/neutral-100 colors/white)}]]
|
||||
[quo2/text
|
||||
{:size :heading-1
|
||||
:weight :semi-bold
|
||||
:style {:margin-left 20}}
|
||||
(i18n/label :t/add-members)]
|
||||
[rn/text-input
|
||||
{:placeholder (str (i18n/label :t/search) "...")
|
||||
:style {:height 32
|
||||
:padding-horizontal 20
|
||||
:margin-vertical 12}
|
||||
:on-change (fn [e]
|
||||
(rf/dispatch [:contacts/set-search-query (oget e "nativeEvent.text")]))}]
|
||||
[contact-list/contact-list
|
||||
{:icon :check
|
||||
:group group
|
||||
:added added
|
||||
:search? true}]
|
||||
[rn/view {:style style/bottom-container}
|
||||
[quo2/button
|
||||
{:style {:flex 1}
|
||||
:on-press #(rf/dispatch [:bottom-sheet/hide])
|
||||
:disabled (zero? (count @added))}
|
||||
(i18n/label :t/save)]]]))])))
|
||||
|
||||
(defn group-details
|
||||
[]
|
||||
(let [{:keys [admins chat-id chat-name color public? muted contacts] :as group} (rf/sub
|
||||
[:chats/current-chat])
|
||||
members (rf/sub [:contacts/group-members-sections])
|
||||
(defn group-details []
|
||||
(let [{:keys [admins chat-id chat-name color public? muted contacts] :as group} (rf/sub [:chats/current-chat])
|
||||
members (rf/sub [:contacts/group-members-sections])
|
||||
pinned-messages (rf/sub [:chats/pinned chat-id])
|
||||
current-pk (rf/sub [:multiaccount/public-key])
|
||||
admin? (get admins current-pk)]
|
||||
[rn/view
|
||||
{:style {:flex 1
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95)}}
|
||||
[quo2/header
|
||||
{:left-component [back-button]
|
||||
:right-component [options-button]
|
||||
:background (colors/theme-colors colors/white colors/neutral-95)}]
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:margin-top 24
|
||||
:padding-horizontal 20}}
|
||||
[quo2/group-avatar
|
||||
{:color color
|
||||
:size :medium}]
|
||||
[quo2/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-1
|
||||
:style {:margin-horizontal 8}} chat-name]
|
||||
current-pk (rf/sub [:multiaccount/public-key])
|
||||
admin? (get admins current-pk)]
|
||||
[rn/view {:style {:flex 1
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95)}}
|
||||
[quo2/header {:left-component [back-button]
|
||||
:right-component [options-button]
|
||||
:background (colors/theme-colors colors/white colors/neutral-95)}]
|
||||
[rn/view {:style {:flex-direction :row
|
||||
:margin-top 24
|
||||
:padding-horizontal 20}}
|
||||
[quo2/group-avatar {:color color
|
||||
:size :medium}]
|
||||
[quo2/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)
|
||||
{:size 20 :color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]]]
|
||||
[quo2/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
|
||||
{:style (style/action-container color)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:bottom-sheet/show-sheet :pinned-messages-list chat-id]))}
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between}}
|
||||
[rn/touchable-opacity {:style (style/action-container color)
|
||||
:accessibility-label :pinned-messages
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:bottom-sheet/show-sheet :pinned-messages-list chat-id]))}
|
||||
[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)}]
|
||||
[count-container (count pinned-messages)]]
|
||||
[quo2/text {:style {:margin-top 16} :size :paragraph-1 :weight :medium}
|
||||
(i18n/label :t/pinned-messages)]]
|
||||
[rn/touchable-opacity
|
||||
{:style (style/action-container color)
|
||||
:on-press #(rf/dispatch [::chat.models/mute-chat-toggled chat-id (not muted)])}
|
||||
[quo2/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}
|
||||
(i18n/label (if muted :unmute-group :mute-group))]]
|
||||
[rn/touchable-opacity
|
||||
{:style (style/action-container color)
|
||||
:on-press #(rf/dispatch
|
||||
[:bottom-sheet/show-sheet
|
||||
{:content (fn [] [contact-requests-sheet group])}])}
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between}}
|
||||
[count-container (count pinned-messages) :pinned-count]]
|
||||
[quo2/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.models/mute-chat-toggled chat-id (not muted)])}
|
||||
[quo2/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} (i18n/label (if muted :unmute-group :mute-group))]]
|
||||
[rn/touchable-opacity {:style (style/action-container color)
|
||||
:accessibility-label :manage-members
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:group/clear-added-participants])
|
||||
(rf/dispatch [:group/clear-removed-members])
|
||||
(rf/dispatch
|
||||
[:bottom-sheet/show-sheet
|
||||
{:content (fn [] [add-members-sheet group admin?])}]))}
|
||||
[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)}]
|
||||
[count-container (count contacts)]]
|
||||
[quo2/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}}]]))
|
||||
[count-container (count contacts) :members-count]]
|
||||
[quo2/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}}]]))
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
(ns status-im.ui2.screens.common.contact-list.view
|
||||
(:require [quo2.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
(:require [react-native.core :as rn]
|
||||
[status-im2.common.contact-list-item.view :as contact-list-item]
|
||||
[utils.re-frame :as rf]))
|
||||
[utils.re-frame :as rf]
|
||||
[quo2.core :as quo]))
|
||||
|
||||
(defn contacts-section-header
|
||||
[{:keys [title]}]
|
||||
(defn contacts-section-header [{:keys [title]}]
|
||||
[quo/divider-label {:label title}])
|
||||
|
||||
(defn contact-list
|
||||
[data]
|
||||
(let [contacts (rf/sub [:contacts/filtered-active-sections])]
|
||||
(defn contact-list [data]
|
||||
(let [contacts (if (:group data) (rf/sub [:contacts/add-members-sections]) (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 120}
|
||||
:render-data data
|
||||
:render-fn contact-list-item/contact-list-item}]))
|
||||
:content-container-style {:padding-bottom 20}
|
||||
:render-data data
|
||||
:render-fn contact-list-item/contact-list-item}]))
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
(ns status-im2.common.contact-list-item.view
|
||||
(:require [quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[status-im2.contexts.chat.home.chat-list-item.style :as style]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.common.home.actions.view :as actions]
|
||||
[quo2.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[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]))
|
||||
[utils.address :as utils.address]))
|
||||
|
||||
(defn open-chat
|
||||
[chat-id]
|
||||
(defn open-chat [chat-id]
|
||||
(let [view-id (rf/sub [:view-id])]
|
||||
(when (= view-id :shell-stack)
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
|
@ -18,62 +17,58 @@
|
|||
(rf/dispatch [:chat.ui/navigate-to-chat chat-id]))
|
||||
(rf/dispatch [:search/home-filter-changed nil]))))
|
||||
|
||||
(defn action-icon
|
||||
[{:keys [public-key] :as item} {:keys [icon group added] :as extra-data}]
|
||||
(let [{:keys [contacts]} group
|
||||
member? (contains? contacts public-key)]
|
||||
[rn/touchable-opacity
|
||||
{:on-press #(rf/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [actions/actions item extra-data])}])
|
||||
:style {:position :absolute
|
||||
:right 20}}
|
||||
(defn action-icon [{:keys [public-key] :as item} {:keys [icon group] :as extra-data}]
|
||||
(let [{:keys [contacts admins]} group
|
||||
member? (contains? contacts public-key)
|
||||
current-pk (rf/sub [:multiaccount/public-key])
|
||||
admin? (get admins current-pk)]
|
||||
[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
|
||||
{:default-checked? member?
|
||||
:on-change (fn [selected]
|
||||
(if selected
|
||||
(swap! added conj public-key)
|
||||
(reset! added (remove #(= % public-key) @added))))}])]))
|
||||
[quo/checkbox {:default-checked? member?
|
||||
:accessibility-label :contact-toggle-check
|
||||
:disabled? (and member? (not admin?))
|
||||
:on-change (fn [selected]
|
||||
(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 contact-list-item
|
||||
[item _ _ extra-data]
|
||||
(defn contact-list-item [item _ _ extra-data]
|
||||
(let [{:keys [public-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]))
|
||||
current-pk (rf/sub [:multiaccount/public-key])]
|
||||
[rn/touchable-opacity
|
||||
(merge {:style (style/container)
|
||||
:active-opacity 1
|
||||
:on-press #(open-chat public-key)
|
||||
: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
|
||||
:online? true
|
||||
:size :small
|
||||
:ring? false}]
|
||||
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]))
|
||||
current-pk (rf/sub [:multiaccount/public-key])
|
||||
online? (rf/sub [:visibility-status-updates/online? public-key])]
|
||||
[rn/touchable-opacity (merge {:style (style/container)
|
||||
:accessibility-label :contact
|
||||
:active-opacity 1
|
||||
:on-press #(open-chat public-key)
|
||||
: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
|
||||
: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)}]]
|
||||
[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)}}
|
||||
[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 public-key)]]
|
||||
(when-not (= current-pk public-key)
|
||||
[action-icon item extra-data])]))
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
(ns status-im2.common.home.actions.view
|
||||
(:require [i18n.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[quo2.components.drawers.action-drawers :as drawer]
|
||||
[status-im.chat.models :as chat.models]
|
||||
[status-im2.common.confirmation-drawer.view :as confirmation-drawer] ;;TODO move to
|
||||
;;status-im2
|
||||
[status-im2.common.constants :as constants]
|
||||
[utils.re-frame :as rf]))
|
||||
[status-im2.common.confirmation-drawer.view :as confirmation-drawer]
|
||||
|
||||
(defn- entry
|
||||
[{:keys [icon label on-press danger? sub-label chevron? add-divider?]}]
|
||||
;;TODO move to status-im2
|
||||
[status-im2.common.constants :as constants]
|
||||
[status-im.chat.models :as chat.models]))
|
||||
|
||||
(defn- entry [{:keys [icon label on-press danger? sub-label chevron? add-divider? accessibility-label]}]
|
||||
{:pre [(keyword? icon)
|
||||
(string? label)
|
||||
(fn? on-press)
|
||||
|
@ -20,94 +20,73 @@
|
|||
:danger? danger?
|
||||
:sub-label sub-label
|
||||
:right-icon (when chevron? :i/chevron-right)
|
||||
:add-divider? add-divider?})
|
||||
:add-divider? add-divider?
|
||||
:accessibility-label accessibility-label})
|
||||
|
||||
(defn hide-sheet-and-dispatch
|
||||
[event]
|
||||
(defn hide-sheet-and-dispatch [event]
|
||||
(rf/dispatch [:bottom-sheet/hide])
|
||||
(rf/dispatch event))
|
||||
|
||||
(defn show-profile-action
|
||||
[chat-id]
|
||||
(defn show-profile-action [chat-id]
|
||||
(hide-sheet-and-dispatch [:chat.ui/show-profile chat-id])
|
||||
(rf/dispatch [:pin-message/load-pin-messages chat-id]))
|
||||
|
||||
(defn mark-all-read-action
|
||||
[chat-id]
|
||||
(defn mark-all-read-action [chat-id]
|
||||
(hide-sheet-and-dispatch [:chat/mark-all-as-read chat-id]))
|
||||
|
||||
(defn edit-nickname-action
|
||||
[chat-id]
|
||||
(defn edit-nickname-action [chat-id]
|
||||
(hide-sheet-and-dispatch [:chat.ui/edit-nickname chat-id]))
|
||||
|
||||
(defn mute-chat-action
|
||||
[chat-id]
|
||||
(defn mute-chat-action [chat-id]
|
||||
(hide-sheet-and-dispatch [::chat.models/mute-chat-toggled chat-id true]))
|
||||
|
||||
(defn unmute-chat-action
|
||||
[chat-id]
|
||||
(defn unmute-chat-action [chat-id]
|
||||
(hide-sheet-and-dispatch [::chat.models/mute-chat-toggled chat-id false]))
|
||||
|
||||
(defn clear-history-action
|
||||
[{:keys [chat-id] :as item}]
|
||||
(hide-sheet-and-dispatch
|
||||
[:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
(confirmation-drawer/confirmation-drawer
|
||||
{:title (i18n/label :t/clear-history?)
|
||||
:description (i18n/label :t/clear-history-confirmation-content)
|
||||
:context item
|
||||
:button-text (i18n/label :t/clear-history)
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/clear-history chat-id])}))}]))
|
||||
(defn clear-history-action [{:keys [chat-id] :as item}]
|
||||
(hide-sheet-and-dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
(confirmation-drawer/confirmation-drawer {:title (i18n/label :t/clear-history?)
|
||||
:description (i18n/label :t/clear-history-confirmation-content)
|
||||
:context item
|
||||
:button-text (i18n/label :t/clear-history)
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/clear-history chat-id])}))}]))
|
||||
|
||||
(defn delete-chat-action
|
||||
[{:keys [chat-id] :as item}]
|
||||
(hide-sheet-and-dispatch
|
||||
[:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
(confirmation-drawer/confirmation-drawer
|
||||
{:title (i18n/label :t/delete-chat?)
|
||||
:description (i18n/label :t/delete-chat-confirmation)
|
||||
:context item
|
||||
:button-text (i18n/label :t/delete-chat)
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/remove-chat chat-id])}))}]))
|
||||
(defn delete-chat-action [{:keys [chat-id] :as item}]
|
||||
(hide-sheet-and-dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
(confirmation-drawer/confirmation-drawer {:title (i18n/label :t/delete-chat?)
|
||||
:description (i18n/label :t/delete-chat-confirmation)
|
||||
:context item
|
||||
:button-text (i18n/label :t/delete-chat)
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/remove-chat chat-id])}))}]))
|
||||
|
||||
(defn leave-group-action
|
||||
[item chat-id]
|
||||
(hide-sheet-and-dispatch
|
||||
[:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
(confirmation-drawer/confirmation-drawer
|
||||
{:title (i18n/label :t/leave-group?)
|
||||
:description (i18n/label :t/leave-chat-confirmation)
|
||||
:context item
|
||||
:button-text (i18n/label :t/leave-group)
|
||||
:on-press #(do
|
||||
(rf/dispatch [:navigate-back])
|
||||
(hide-sheet-and-dispatch [:group-chats.ui/leave-chat-confirmed
|
||||
chat-id]))}))}]))
|
||||
(defn leave-group-action [item chat-id]
|
||||
(hide-sheet-and-dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
(confirmation-drawer/confirmation-drawer {:title (i18n/label :t/leave-group?)
|
||||
:description (i18n/label :t/leave-chat-confirmation)
|
||||
:context item
|
||||
:button-text (i18n/label :t/leave-group)
|
||||
:on-press #(do
|
||||
(rf/dispatch [:navigate-back])
|
||||
(hide-sheet-and-dispatch [:group-chats.ui/leave-chat-confirmed chat-id]))}))}]))
|
||||
|
||||
(defn block-user-action
|
||||
[{:keys [public-key] :as item}]
|
||||
(hide-sheet-and-dispatch
|
||||
[:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
(confirmation-drawer/confirmation-drawer
|
||||
{:title (i18n/label :t/block-user?)
|
||||
:description (i18n/label :t/block-contact-details)
|
||||
:context item
|
||||
:button-text (i18n/label :t/block-user)
|
||||
:on-press #(hide-sheet-and-dispatch [:contact.ui/block-contact-confirmed
|
||||
public-key])}))}]))
|
||||
(defn block-user-action [{:keys [public-key] :as item}]
|
||||
(hide-sheet-and-dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] (confirmation-drawer/confirmation-drawer {:title (i18n/label :t/block-user?)
|
||||
:description (i18n/label :t/block-contact-details)
|
||||
:context item
|
||||
:button-text (i18n/label :t/block-user)
|
||||
:on-press #(hide-sheet-and-dispatch [:contact.ui/block-contact-confirmed public-key])}))}]))
|
||||
|
||||
(defn mute-chat-entry
|
||||
[chat-id]
|
||||
(defn mute-chat-entry [chat-id]
|
||||
(let [muted? (rf/sub [:chats/muted chat-id])]
|
||||
(entry {:icon (if muted? :i/muted :i/activity-center)
|
||||
:label (i18n/label
|
||||
(if muted?
|
||||
:unmute-chat
|
||||
:mute-chat))
|
||||
(if muted?
|
||||
:unmute-chat
|
||||
:mute-chat))
|
||||
:on-press (if muted?
|
||||
#(unmute-chat-action chat-id)
|
||||
#(mute-chat-action chat-id))
|
||||
|
@ -115,8 +94,7 @@
|
|||
:sub-label nil
|
||||
:chevron? true})))
|
||||
|
||||
(defn mark-as-read-entry
|
||||
[chat-id]
|
||||
(defn mark-as-read-entry [chat-id]
|
||||
(entry {:icon :i/correct
|
||||
:label (i18n/label :t/mark-as-read)
|
||||
:on-press #(mark-all-read-action chat-id)
|
||||
|
@ -125,8 +103,7 @@
|
|||
:chevron? false
|
||||
:add-divider? true}))
|
||||
|
||||
(defn clear-history-entry
|
||||
[chat-id]
|
||||
(defn clear-history-entry [chat-id]
|
||||
(entry {:icon :i/delete
|
||||
:label (i18n/label :t/clear-history)
|
||||
:on-press #(clear-history-action chat-id)
|
||||
|
@ -135,8 +112,7 @@
|
|||
:chevron? false
|
||||
:add-divider? true}))
|
||||
|
||||
(defn delete-chat-entry
|
||||
[item]
|
||||
(defn delete-chat-entry [item]
|
||||
(entry {:icon :i/delete
|
||||
:label (i18n/label :t/delete-chat)
|
||||
:on-press #(delete-chat-action item)
|
||||
|
@ -144,8 +120,7 @@
|
|||
:sub-label nil
|
||||
:chevron? false}))
|
||||
|
||||
(defn leave-group-entry
|
||||
[item extra-data]
|
||||
(defn leave-group-entry [item extra-data]
|
||||
(entry {:icon :i/log-out
|
||||
:label (i18n/label :t/leave-group)
|
||||
:on-press #(leave-group-action item (if extra-data (:chat-id extra-data) (:chat-id item)))
|
||||
|
@ -154,8 +129,7 @@
|
|||
:chevron? false
|
||||
:add-divider? extra-data}))
|
||||
|
||||
(defn view-profile-entry
|
||||
[chat-id]
|
||||
(defn view-profile-entry [chat-id]
|
||||
(entry {:icon :i/friend
|
||||
:label (i18n/label :t/view-profile)
|
||||
:on-press #(show-profile-action chat-id)
|
||||
|
@ -163,8 +137,7 @@
|
|||
:sub-label nil
|
||||
:chevron? false}))
|
||||
|
||||
(defn edit-nickname-entry
|
||||
[chat-id]
|
||||
(defn edit-nickname-entry [chat-id]
|
||||
(entry {:icon :i/edit
|
||||
:label (i18n/label :t/edit-nickname)
|
||||
:on-press #(edit-nickname-action chat-id)
|
||||
|
@ -173,8 +146,7 @@
|
|||
:chevron? false}))
|
||||
|
||||
;; TODO(OmarBasem): Requires design input.
|
||||
(defn edit-name-image-entry
|
||||
[]
|
||||
(defn edit-name-image-entry []
|
||||
(entry {:icon :i/edit
|
||||
:label (i18n/label :t/edit-name-and-image)
|
||||
:on-press #(js/alert "TODO: to be implemented, requires design input")
|
||||
|
@ -183,8 +155,7 @@
|
|||
:chevron? false}))
|
||||
|
||||
;; TODO(OmarBasem): Requires design input.
|
||||
(defn notifications-entry
|
||||
[add-divider?]
|
||||
(defn notifications-entry [add-divider?]
|
||||
(entry {:icon :i/notifications
|
||||
:label (i18n/label :t/notifications)
|
||||
:on-press #(js/alert "TODO: to be implemented, requires design input")
|
||||
|
@ -194,8 +165,7 @@
|
|||
:add-divider? add-divider?}))
|
||||
|
||||
;; TODO(OmarBasem): Requires design input.
|
||||
(defn fetch-messages-entry
|
||||
[]
|
||||
(defn fetch-messages-entry []
|
||||
(entry {:icon :i/save
|
||||
:label (i18n/label :t/fetch-messages)
|
||||
:on-press #(js/alert "TODO: to be implemented, requires design input")
|
||||
|
@ -204,8 +174,7 @@
|
|||
:chevron? true}))
|
||||
|
||||
;; TODO(OmarBasem): Requires design input.
|
||||
(defn pinned-messages-entry
|
||||
[]
|
||||
(defn pinned-messages-entry []
|
||||
(entry {:icon :i/pin
|
||||
:label (i18n/label :t/pinned-messages)
|
||||
:on-press #(js/alert "TODO: to be implemented, requires design input")
|
||||
|
@ -213,8 +182,7 @@
|
|||
:sub-label nil
|
||||
:chevron? true}))
|
||||
|
||||
(defn remove-from-contacts-entry
|
||||
[contact]
|
||||
(defn remove-from-contacts-entry [contact]
|
||||
(entry {:icon :i/remove-user
|
||||
:label (i18n/label :t/remove-from-contacts)
|
||||
:on-press #(hide-sheet-and-dispatch [:contact.ui/remove-contact-pressed contact])
|
||||
|
@ -223,8 +191,7 @@
|
|||
:chevron? false}))
|
||||
|
||||
;; TODO(OmarBasem): Requires design input.
|
||||
(defn rename-entry
|
||||
[]
|
||||
(defn rename-entry []
|
||||
(entry {:icon :i/edit
|
||||
:label (i18n/label :t/rename)
|
||||
:on-press #(js/alert "TODO: to be implemented, requires design input")
|
||||
|
@ -233,8 +200,7 @@
|
|||
:chevron? false}))
|
||||
|
||||
;; TODO(OmarBasem): Requires design input.
|
||||
(defn show-qr-entry
|
||||
[]
|
||||
(defn show-qr-entry []
|
||||
(entry {:icon :i/qr-code
|
||||
:label (i18n/label :t/show-qr)
|
||||
:on-press #(js/alert "TODO: to be implemented, requires design input")
|
||||
|
@ -243,8 +209,7 @@
|
|||
:chevron? false}))
|
||||
|
||||
;; TODO(OmarBasem): to be implemented.
|
||||
(defn share-profile-entry
|
||||
[]
|
||||
(defn share-profile-entry []
|
||||
(entry {:icon :i/share
|
||||
:label (i18n/label :t/share-profile)
|
||||
:on-press #(js/alert "TODO: to be implemented")
|
||||
|
@ -253,8 +218,7 @@
|
|||
:chevron? false}))
|
||||
|
||||
;; TODO(OmarBasem): to be implemented.
|
||||
(defn share-group-entry
|
||||
[]
|
||||
(defn share-group-entry []
|
||||
(entry {:icon :i/share
|
||||
:label (i18n/label :t/share)
|
||||
:on-press #(js/alert "TODO: to be implemented")
|
||||
|
@ -263,8 +227,7 @@
|
|||
:chevron? false}))
|
||||
|
||||
;; TODO(OmarBasem): Requires status-go impl.
|
||||
(defn mark-untrustworthy-entry
|
||||
[]
|
||||
(defn mark-untrustworthy-entry []
|
||||
(entry {:icon :i/alert
|
||||
:label (i18n/label :t/mark-untrustworthy)
|
||||
:on-press #(js/alert "TODO: to be implemented, requires status-go impl.")
|
||||
|
@ -273,8 +236,7 @@
|
|||
:chevron? false
|
||||
:add-divider? true}))
|
||||
|
||||
(defn block-user-entry
|
||||
[item]
|
||||
(defn block-user-entry [item]
|
||||
(entry {:icon :i/block
|
||||
:label (i18n/label :t/block-user)
|
||||
:on-press #(block-user-action item)
|
||||
|
@ -282,30 +244,27 @@
|
|||
:sub-label nil
|
||||
:chevron? false}))
|
||||
|
||||
(defn remove-from-group-entry
|
||||
[{:keys [public-key]} chat-id]
|
||||
(defn remove-from-group-entry [{:keys [public-key]} chat-id]
|
||||
(let [username (first (rf/sub [:contacts/contact-two-names-by-identity public-key]))]
|
||||
(entry {:icon :i/placeholder
|
||||
:label (i18n/label :t/remove-user-from-group {:username username})
|
||||
:on-press #(hide-sheet-and-dispatch [:group-chats.ui/remove-member-pressed chat-id
|
||||
public-key true])
|
||||
:on-press #(hide-sheet-and-dispatch [:group-chats.ui/remove-member-pressed chat-id public-key true])
|
||||
:danger? true
|
||||
:sub-label nil
|
||||
:chevron? false
|
||||
:add-divider? true})))
|
||||
|
||||
(defn group-details-entry
|
||||
[chat-id]
|
||||
(defn group-details-entry [chat-id]
|
||||
(entry {:icon :i/members
|
||||
:label (i18n/label :t/group-details)
|
||||
:accessibility-label :group-details
|
||||
:on-press #(hide-sheet-and-dispatch [:show-group-chat-profile chat-id])
|
||||
:danger? false
|
||||
:sub-label nil
|
||||
:chevron? false}))
|
||||
|
||||
;; TODO(OmarBasem): to be implemented.
|
||||
(defn add-members-entry
|
||||
[]
|
||||
(defn add-members-entry []
|
||||
(entry {:icon :i/add-user
|
||||
:label (i18n/label :t/add-members)
|
||||
:on-press #(js/alert "TODO: to be implemented")
|
||||
|
@ -314,8 +273,7 @@
|
|||
:chevron? false}))
|
||||
|
||||
;; TODO(OmarBasem): to be implemented.
|
||||
(defn manage-members-entry
|
||||
[]
|
||||
(defn manage-members-entry []
|
||||
(entry {:icon :i/add-user
|
||||
:label (i18n/label :t/manage-members)
|
||||
:on-press #(js/alert "TODO: to be implemented")
|
||||
|
@ -324,8 +282,7 @@
|
|||
:chevron? false}))
|
||||
|
||||
;; TODO(OmarBasem): to be implemented.
|
||||
(defn edit-group-entry
|
||||
[]
|
||||
(defn edit-group-entry []
|
||||
(entry {:icon :i/edit
|
||||
:label (i18n/label :t/edit-name-and-image)
|
||||
:on-press #(js/alert "TODO: to be implemented")
|
||||
|
@ -334,8 +291,7 @@
|
|||
:chevron? false}))
|
||||
|
||||
;; TODO(OmarBasem): to be implemented.
|
||||
(defn group-privacy-entry
|
||||
[]
|
||||
(defn group-privacy-entry []
|
||||
(entry {:icon :i/privacy
|
||||
:label (i18n/label :t/change-group-privacy)
|
||||
:on-press #(js/alert "TODO: to be implemented")
|
||||
|
@ -343,15 +299,13 @@
|
|||
:sub-label nil
|
||||
:chevron? false}))
|
||||
|
||||
(defn destructive-actions
|
||||
[{:keys [group-chat] :as item}]
|
||||
(defn destructive-actions [{:keys [group-chat] :as item}]
|
||||
[(clear-history-entry item)
|
||||
(if group-chat
|
||||
(leave-group-entry item nil)
|
||||
(delete-chat-entry item))])
|
||||
|
||||
(defn notification-actions
|
||||
[{:keys [chat-id group-chat public?]} inside-chat?]
|
||||
(defn notification-actions [{:keys [chat-id group-chat public?]} inside-chat?]
|
||||
[(mark-as-read-entry chat-id)
|
||||
(mute-chat-entry chat-id)
|
||||
(notifications-entry false)
|
||||
|
@ -365,11 +319,12 @@
|
|||
(when public?
|
||||
(share-group-entry))])
|
||||
|
||||
(defn group-actions
|
||||
[{:keys [chat-id admins]} inside-chat?]
|
||||
(defn group-actions [{:keys [chat-id admins]} inside-chat?]
|
||||
(let [current-pub-key (rf/sub [:multiaccount/public-key])
|
||||
admin? (get admins current-pub-key)]
|
||||
[(group-details-entry chat-id)
|
||||
admin? (get admins current-pub-key)
|
||||
removed? (rf/sub [:group-chat/removed-from-current-chat?])]
|
||||
[(when-not removed?
|
||||
(group-details-entry chat-id))
|
||||
(when inside-chat?
|
||||
(if admin?
|
||||
(manage-members-entry)
|
||||
|
@ -377,48 +332,39 @@
|
|||
(when (and admin? inside-chat?) (edit-group-entry))
|
||||
(when (and admin? inside-chat?) (group-privacy-entry))]))
|
||||
|
||||
(defn one-to-one-actions
|
||||
[{:keys [chat-id] :as item} inside-chat?]
|
||||
[drawer/action-drawer
|
||||
[[(view-profile-entry chat-id)
|
||||
(edit-nickname-entry chat-id)]
|
||||
(notification-actions item inside-chat?)
|
||||
(destructive-actions item)]])
|
||||
(defn one-to-one-actions [{:keys [chat-id] :as item} inside-chat?]
|
||||
[drawer/action-drawer [[(view-profile-entry chat-id)
|
||||
(edit-nickname-entry chat-id)]
|
||||
(notification-actions item inside-chat?)
|
||||
(destructive-actions item)]])
|
||||
|
||||
(defn public-chat-actions
|
||||
[{:keys [chat-id] :as item} inside-chat?]
|
||||
[drawer/action-drawer
|
||||
[[(group-details-entry chat-id)
|
||||
(when inside-chat?
|
||||
(add-members-entry))]
|
||||
(notification-actions item inside-chat?)
|
||||
(destructive-actions item)]])
|
||||
(defn public-chat-actions [{:keys [chat-id] :as item} inside-chat?]
|
||||
[drawer/action-drawer [[(group-details-entry chat-id)
|
||||
(when inside-chat?
|
||||
(add-members-entry))]
|
||||
(notification-actions item inside-chat?)
|
||||
(destructive-actions item)]])
|
||||
|
||||
(defn private-group-chat-actions
|
||||
[item inside-chat?]
|
||||
[drawer/action-drawer
|
||||
[(group-actions item inside-chat?)
|
||||
(notification-actions item inside-chat?)
|
||||
(destructive-actions item)]])
|
||||
(defn private-group-chat-actions [item inside-chat?]
|
||||
[drawer/action-drawer [(group-actions item inside-chat?)
|
||||
(notification-actions item inside-chat?)
|
||||
(destructive-actions item)]])
|
||||
|
||||
(defn contact-actions
|
||||
[{:keys [public-key] :as contact} {:keys [chat-id admin?] :as extra-data}]
|
||||
(defn contact-actions [{:keys [public-key] :as contact} {:keys [chat-id admin?] :as extra-data}]
|
||||
(let [current-pub-key (rf/sub [:multiaccount/public-key])]
|
||||
[drawer/action-drawer
|
||||
[[(view-profile-entry public-key)
|
||||
(remove-from-contacts-entry contact)
|
||||
(rename-entry)
|
||||
(show-qr-entry)
|
||||
(share-profile-entry)]
|
||||
[(mark-untrustworthy-entry)
|
||||
(block-user-entry contact)]
|
||||
(when (and admin? chat-id)
|
||||
[(if (= current-pub-key public-key)
|
||||
(leave-group-entry contact extra-data)
|
||||
(remove-from-group-entry contact chat-id))])]]))
|
||||
[drawer/action-drawer [[(view-profile-entry public-key)
|
||||
(remove-from-contacts-entry contact)
|
||||
(rename-entry)
|
||||
(show-qr-entry)
|
||||
(share-profile-entry)]
|
||||
[(mark-untrustworthy-entry)
|
||||
(block-user-entry contact)]
|
||||
(when (and admin? chat-id)
|
||||
[(if (= current-pub-key public-key)
|
||||
(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 actions [{:keys [chat-type] :as item} {:keys [inside-chat?] :as extra-data}]
|
||||
(case chat-type
|
||||
constants/one-to-one-chat-type
|
||||
[one-to-one-actions item inside-chat?]
|
||||
|
@ -428,11 +374,9 @@
|
|||
[private-group-chat-actions item inside-chat?]
|
||||
[contact-actions item extra-data]))
|
||||
|
||||
(defn group-details-actions
|
||||
[{:keys [admins] :as group}]
|
||||
(defn group-details-actions [{:keys [admins] :as group}]
|
||||
(let [current-pub-key (rf/sub [:multiaccount/public-key])
|
||||
admin? (get admins current-pub-key)]
|
||||
[drawer/action-drawer
|
||||
[(when admin? [(edit-name-image-entry)])
|
||||
[(notifications-entry admin?)]
|
||||
(destructive-actions group)]]))
|
||||
admin? (get admins current-pub-key)]
|
||||
[drawer/action-drawer [(when admin? [(edit-name-image-entry)])
|
||||
[(notifications-entry admin?)]
|
||||
(destructive-actions group)]]))
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
{:on-press #(rf/dispatch [:bottom-sheet/hide])
|
||||
:style (style/contact-requests-sheet)}
|
||||
[quo/icon :i/close]]
|
||||
[rn/text {:size :heading-1 :weight :semi-bold}
|
||||
[quo/text {:size :heading-1 :weight :semi-bold}
|
||||
(i18n/label :t/pending-requests)]
|
||||
[quo/tabs
|
||||
{:style {:margin-top 12 :margin-bottom 20}
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
(ns status-im2.contexts.chat.messages.view
|
||||
(:require [quo2.core :as quo]
|
||||
(:require [reagent.core :as reagent]
|
||||
[re-frame.db]
|
||||
[i18n.i18n :as i18n]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.ui2.screens.chat.composer.view :as composer]
|
||||
[status-im.ui2.screens.chat.pin-limit-popover.view :as pin-limit-popover]
|
||||
[status-im2.common.constants :as constants]
|
||||
[status-im2.contexts.chat.messages.list.view :as messages.list]
|
||||
[status-im2.contexts.chat.messages.pin.banner.view :as pin.banner] ;;TODO move to status-im2
|
||||
[status-im2.navigation.state :as navigation.state]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.re-frame :as rf]))
|
||||
[quo2.core :as quo]
|
||||
[status-im2.common.constants :as constants]
|
||||
[status-im2.navigation.state :as navigation.state]
|
||||
[status-im2.contexts.chat.messages.list.view :as messages.list]
|
||||
[status-im2.contexts.chat.messages.pin.banner.view :as pin.banner]
|
||||
|
||||
(defn navigate-back-handler
|
||||
[]
|
||||
;;TODO move to status-im2
|
||||
[status-im.ui2.screens.chat.pin-limit-popover.view :as pin-limit-popover]
|
||||
[status-im.ui2.screens.chat.composer.view :as composer]))
|
||||
|
||||
(defn navigate-back-handler []
|
||||
(when (and (not @navigation.state/curr-modal) (= (get @re-frame.db/app-db :view-id) :chat))
|
||||
(rn/hw-back-remove-listener navigate-back-handler)
|
||||
(rf/dispatch [:close-chat])
|
||||
(rf/dispatch [:navigate-back])))
|
||||
|
||||
(defn page-nav
|
||||
[]
|
||||
(defn page-nav []
|
||||
(let [{:keys [group-chat chat-id chat-name emoji chat-type]} (rf/sub [:chats/current-chat])
|
||||
display-name (if (= chat-type constants/one-to-one-chat-type)
|
||||
(first (rf/sub [:contacts/contact-two-names-by-identity chat-id]))
|
||||
|
@ -29,7 +30,7 @@
|
|||
contact (when-not group-chat (rf/sub [:contacts/contact-by-address chat-id]))
|
||||
photo-path (when-not (empty? (:images contact)) (rf/sub [:chats/photo-path chat-id]))]
|
||||
[quo/page-nav
|
||||
{:align-mid? true
|
||||
{:align-mid? true
|
||||
|
||||
:mid-section
|
||||
(if group-chat
|
||||
|
@ -55,15 +56,14 @@
|
|||
:icon :i/options
|
||||
:accessibility-label :options-button}]}]))
|
||||
|
||||
(defn chat-render
|
||||
[]
|
||||
(defn chat-render []
|
||||
(let [;;we want to react only on these fields, do not use full chat map here
|
||||
{:keys [chat-id show-input?] :as chat} (rf/sub [:chats/current-chat-chat-view])
|
||||
mutual-contact-requests-enabled? (rf/sub [:mutual-contact-requests/enabled?])]
|
||||
show-input? (not (rf/sub [:group-chat/removed-from-current-chat?]))
|
||||
{:keys [chat-id] :as chat} (rf/sub [:chats/current-chat-chat-view])
|
||||
mutual-contact-requests-enabled? (rf/sub [:mutual-contact-requests/enabled?])]
|
||||
[rn/keyboard-avoiding-view {:style {:flex 1}}
|
||||
[page-nav]
|
||||
;; TODO (flexsurfer) this should be in-app notification component in quo2
|
||||
;; https://github.com/status-im/status-mobile/issues/14527
|
||||
;; TODO (flexsurfer) this should be in-app notification component in quo2 https://github.com/status-im/status-mobile/issues/14527
|
||||
[pin-limit-popover/pin-limit-popover chat-id]
|
||||
[pin.banner/banner chat-id]
|
||||
;;MESSAGES LIST
|
||||
|
@ -74,13 +74,17 @@
|
|||
:bottom-space 15}]
|
||||
;;INPUT COMPOSER
|
||||
(when show-input?
|
||||
[composer/composer chat-id])]))
|
||||
[composer/composer chat-id])
|
||||
[quo/floating-shell-button
|
||||
{:jump-to {:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
|
||||
:label (i18n/label :t/jump-to)}}
|
||||
{:position :absolute
|
||||
:bottom 117}]]))
|
||||
|
||||
(defn chat
|
||||
[]
|
||||
(defn chat []
|
||||
(reagent/create-class
|
||||
{:component-did-mount (fn []
|
||||
(rn/hw-back-remove-listener navigate-back-handler)
|
||||
(rn/hw-back-add-listener navigate-back-handler))
|
||||
:component-will-unmount (fn [] (rn/hw-back-remove-listener navigate-back-handler))
|
||||
:reagent-render chat-render}))
|
||||
{:component-did-mount (fn []
|
||||
(rn/hw-back-remove-listener navigate-back-handler)
|
||||
(rn/hw-back-add-listener navigate-back-handler))
|
||||
:component-will-unmount (fn [] (rn/hw-back-remove-listener navigate-back-handler))
|
||||
:reagent-render chat-render}))
|
||||
|
|
|
@ -1,54 +1,48 @@
|
|||
(ns status-im2.contexts.quo-preview.avatars.group-avatar
|
||||
(:require [quo2.components.avatars.group-avatar :as quo2]
|
||||
[quo2.foundations.colors :as colors]
|
||||
(:require [reagent.core :as reagent]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
[status-im2.contexts.quo-preview.preview :as preview]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.avatars.group-avatar :as quo2]))
|
||||
|
||||
(def descriptor
|
||||
[{:label "Size"
|
||||
:key :size
|
||||
:type :select
|
||||
:options [{:key :small
|
||||
:value "Small"}
|
||||
{:key :medium
|
||||
:value "Medium"}
|
||||
{:key :large
|
||||
:value "Large"}]}
|
||||
{:label "Color"
|
||||
:key :color
|
||||
:type :select
|
||||
:options
|
||||
(map
|
||||
(fn [c]
|
||||
{:key c
|
||||
:value c})
|
||||
(keys colors/customization))}])
|
||||
(def descriptor [{:label "Size"
|
||||
:key :size
|
||||
:type :select
|
||||
:options [{:key :small
|
||||
:value "Small"}
|
||||
{:key :medium
|
||||
:value "Medium"}
|
||||
{:key :large
|
||||
:value "Large"}]}
|
||||
{:label "Color"
|
||||
:key :color
|
||||
:type :select
|
||||
:options
|
||||
(map
|
||||
(fn [c]
|
||||
{:key c
|
||||
:value c})
|
||||
["#ff0000" "#0000ff"])}]) ; TODO: this is temporary only. Issue: https://github.com/status-im/status-mobile/issues/14566
|
||||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(defn cool-preview []
|
||||
(let [state (reagent/atom {:theme :light
|
||||
:color :purple
|
||||
:size :small})]
|
||||
:size :small})]
|
||||
(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
|
||||
:flex-direction :row
|
||||
:justify-content :center}
|
||||
[rn/view {:padding-vertical 60
|
||||
:flex-direction :row
|
||||
:justify-content :center}
|
||||
[quo2/group-avatar @state]]]])))
|
||||
|
||||
(defn preview-group-avatar
|
||||
[]
|
||||
[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}]])
|
||||
(defn preview-group-avatar []
|
||||
[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}]])
|
||||
|
|
|
@ -1,43 +1,45 @@
|
|||
(ns status-im2.setup.db
|
||||
(:require [react-native.core :as rn] ;; TODO (14/11/22 flexsurfer move to status-im2 namespace
|
||||
[status-im.fleet.core :as fleet]
|
||||
[status-im.wallet.db :as wallet.db]))
|
||||
(:require
|
||||
[react-native.core :as rn]
|
||||
;; TODO (14/11/22 flexsurfer move to status-im2 namespace
|
||||
[status-im.fleet.core :as fleet]
|
||||
[status-im.wallet.db :as wallet.db]))
|
||||
|
||||
;; initial state of app-db
|
||||
(def app-db
|
||||
{:contacts/contacts {}
|
||||
:pairing/installations {}
|
||||
:group/selected-contacts #{}
|
||||
:chats {}
|
||||
:current-chat-id nil
|
||||
:selected-participants #{}
|
||||
:sync-state :done
|
||||
:link-previews-whitelist []
|
||||
:app-state "active"
|
||||
:wallet wallet.db/default-wallet
|
||||
:wallet/all-tokens {}
|
||||
:peers-count 0
|
||||
:node-info {}
|
||||
:peers-summary []
|
||||
:transport/message-envelopes {}
|
||||
:mailserver/mailservers (fleet/default-mailservers {})
|
||||
:mailserver/topics {}
|
||||
:mailserver/pending-requests 0
|
||||
:chat/cooldowns 0
|
||||
:chat/inputs {}
|
||||
:chat/cooldown-enabled? false
|
||||
:chat/last-outgoing-message-sent-at 0
|
||||
:chat/spam-messages-frequency 0
|
||||
:chats-home-list #{}
|
||||
:home-items-show-number 20
|
||||
:tooltips {}
|
||||
:dimensions/window (rn/get-window)
|
||||
:registry {}
|
||||
:visibility-status-updates {}
|
||||
:stickers/packs-pending #{}
|
||||
:keycard {:nfc-enabled? false
|
||||
:pin {:original []
|
||||
:confirmation []
|
||||
:current []
|
||||
:puk []
|
||||
:enter-step :original}}})
|
||||
(def app-db {:contacts/contacts {}
|
||||
:pairing/installations {}
|
||||
:group/selected-contacts #{}
|
||||
:chats {}
|
||||
:current-chat-id nil
|
||||
:group-chat/selected-participants #{}
|
||||
:group-chat/deselected-members #{}
|
||||
:sync-state :done
|
||||
:link-previews-whitelist []
|
||||
:app-state "active"
|
||||
:wallet wallet.db/default-wallet
|
||||
:wallet/all-tokens {}
|
||||
:peers-count 0
|
||||
:node-info {}
|
||||
:peers-summary []
|
||||
:transport/message-envelopes {}
|
||||
:mailserver/mailservers (fleet/default-mailservers {})
|
||||
:mailserver/topics {}
|
||||
:mailserver/pending-requests 0
|
||||
:chat/cooldowns 0
|
||||
:chat/inputs {}
|
||||
:chat/cooldown-enabled? false
|
||||
:chat/last-outgoing-message-sent-at 0
|
||||
:chat/spam-messages-frequency 0
|
||||
:chats-home-list #{}
|
||||
:home-items-show-number 20
|
||||
:tooltips {}
|
||||
:dimensions/window (rn/get-window)
|
||||
:registry {}
|
||||
:visibility-status-updates {}
|
||||
:stickers/packs-pending #{}
|
||||
:keycard {:nfc-enabled? false
|
||||
:pin {:original []
|
||||
:confirmation []
|
||||
:current []
|
||||
:puk []
|
||||
:enter-step :original}}})
|
||||
|
|
|
@ -1,425 +1,413 @@
|
|||
(ns status-im2.subs.chat.chats
|
||||
(:require [clojure.string :as string]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[clojure.string :as string]
|
||||
[status-im2.common.constants :as constants]
|
||||
[quo.design-system.colors :as colors]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.add-new.db :as db]
|
||||
[status-im.chat.models :as chat.models]
|
||||
[status-im.chat.models.mentions :as mentions]
|
||||
[status-im.communities.core :as communities]
|
||||
[status-im.group-chats.core :as group-chat]
|
||||
[status-im.group-chats.db :as group-chats.db]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.utils.image-server :as image-server]
|
||||
[status-im2.common.constants :as constants]))
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.group-chats.core :as group-chat]
|
||||
[status-im.chat.models.mentions :as mentions]
|
||||
[status-im.group-chats.db :as group-chats.db]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.add-new.db :as db]
|
||||
[status-im.i18n.i18n :as i18n]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/chat
|
||||
:<- [:chats/chats]
|
||||
(fn [chats [_ chat-id]]
|
||||
(get chats chat-id)))
|
||||
:chats/chat
|
||||
:<- [:chats/chats]
|
||||
(fn [chats [_ chat-id]]
|
||||
(get chats chat-id)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/by-community-id
|
||||
:<- [:chats/chats]
|
||||
(fn [chats [_ community-id]]
|
||||
(->> chats
|
||||
(keep (fn [[_ chat]]
|
||||
(when (= (:community-id chat) community-id)
|
||||
chat)))
|
||||
(sort-by :timestamp >))))
|
||||
:chats/by-community-id
|
||||
:<- [:chats/chats]
|
||||
(fn [chats [_ community-id]]
|
||||
(->> chats
|
||||
(keep (fn [[_ chat]]
|
||||
(when (= (:community-id chat) community-id)
|
||||
chat)))
|
||||
(sort-by :timestamp >))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/with-empty-category-by-community-id
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:chats/by-community-id community-id])
|
||||
(re-frame/subscribe [:communities/community-chats community-id])])
|
||||
(fn [[chats comm-chats] [_ community-id]]
|
||||
(filter #(string/blank? (get-in comm-chats
|
||||
[(string/replace (:chat-id %) community-id "") :categoryID]))
|
||||
chats)))
|
||||
:chats/with-empty-category-by-community-id
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:chats/by-community-id community-id])
|
||||
(re-frame/subscribe [:communities/community-chats community-id])])
|
||||
(fn [[chats comm-chats] [_ community-id]]
|
||||
(filter #(string/blank? (get-in comm-chats [(string/replace (:chat-id %) community-id "") :categoryID])) chats)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/sorted-categories-by-community-id
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:chats/by-community-id community-id])
|
||||
(re-frame/subscribe [:communities/community-chats community-id])])
|
||||
(fn [[chats comm-chats] [_ community-id]]
|
||||
(let [chat-cat (into {}
|
||||
(map (fn [{:keys [id categoryID position]}]
|
||||
{(str community-id id) {:categoryID categoryID
|
||||
:position position}})
|
||||
(vals comm-chats)))]
|
||||
(group-by :categoryID
|
||||
(sort-by :position
|
||||
(map #(cond-> (merge % (chat-cat (:chat-id %)))
|
||||
(= community-id constants/status-community-id)
|
||||
(assoc :color colors/blue))
|
||||
chats))))))
|
||||
:chats/sorted-categories-by-community-id
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:chats/by-community-id community-id])
|
||||
(re-frame/subscribe [:communities/community-chats community-id])])
|
||||
(fn [[chats comm-chats] [_ community-id]]
|
||||
(let [chat-cat (into {} (map (fn [{:keys [id categoryID position]}]
|
||||
{(str community-id id) {:categoryID categoryID
|
||||
:position position}})
|
||||
(vals comm-chats)))]
|
||||
(group-by :categoryID (sort-by :position
|
||||
(map #(cond-> (merge % (chat-cat (:chat-id %)))
|
||||
(= community-id constants/status-community-id)
|
||||
(assoc :color colors/blue))
|
||||
chats))))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/category-by-chat-id
|
||||
(fn [[_ community-id _]]
|
||||
[(re-frame/subscribe [:communities/community community-id])])
|
||||
(fn [[{:keys [chats categories]}] [_ community-id chat-id]]
|
||||
(get categories (get-in chats [(string/replace chat-id community-id "") :categoryID]))))
|
||||
:chats/category-by-chat-id
|
||||
(fn [[_ community-id _]]
|
||||
[(re-frame/subscribe [:communities/community community-id])])
|
||||
(fn [[{:keys [chats categories]}] [_ community-id chat-id]]
|
||||
(get categories (get-in chats [(string/replace chat-id community-id "") :categoryID]))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/community-chat-by-id
|
||||
(fn [[_ community-id _]]
|
||||
[(re-frame/subscribe [:communities/community community-id])])
|
||||
(fn [[{:keys [chats]}] [_ community-id chat-id]]
|
||||
(get chats (string/replace chat-id community-id ""))))
|
||||
:chats/community-chat-by-id
|
||||
(fn [[_ community-id _]]
|
||||
[(re-frame/subscribe [:communities/community community-id])])
|
||||
(fn [[{:keys [chats]}] [_ community-id chat-id]]
|
||||
(get chats (string/replace chat-id community-id ""))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/home-list-chats
|
||||
:<- [:chats/chats]
|
||||
:<- [:chats-home-list]
|
||||
(fn [[chats active-chats]]
|
||||
(reduce #(if-let [item (get chats %2)]
|
||||
(conj %1 item)
|
||||
%1)
|
||||
[]
|
||||
active-chats)))
|
||||
:chats/home-list-chats
|
||||
:<- [:chats/chats]
|
||||
:<- [:chats-home-list]
|
||||
(fn [[chats active-chats]]
|
||||
(reduce #(if-let [item (get chats %2)]
|
||||
(conj %1 item)
|
||||
%1)
|
||||
[]
|
||||
active-chats)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chat-by-id
|
||||
:<- [:chats/chats]
|
||||
(fn [chats [_ chat-id]]
|
||||
(get chats chat-id)))
|
||||
:chat-by-id
|
||||
:<- [:chats/chats]
|
||||
(fn [chats [_ chat-id]]
|
||||
(get chats chat-id)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/synced-from
|
||||
(fn [[_ chat-id] _]
|
||||
(re-frame/subscribe [:chat-by-id chat-id]))
|
||||
(fn [{:keys [synced-from]}]
|
||||
synced-from))
|
||||
:chats/synced-from
|
||||
(fn [[_ chat-id] _]
|
||||
(re-frame/subscribe [:chat-by-id chat-id]))
|
||||
(fn [{:keys [synced-from]}]
|
||||
synced-from))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/muted
|
||||
(fn [[_ chat-id] _]
|
||||
(re-frame/subscribe [:chat-by-id chat-id]))
|
||||
(fn [{:keys [muted]}]
|
||||
muted))
|
||||
:chats/muted
|
||||
(fn [[_ chat-id] _]
|
||||
(re-frame/subscribe [:chat-by-id chat-id]))
|
||||
(fn [{:keys [muted]}]
|
||||
muted))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/chat-type
|
||||
(fn [[_ chat-id] _]
|
||||
(re-frame/subscribe [:chat-by-id chat-id]))
|
||||
(fn [{:keys [chat-type]}]
|
||||
chat-type))
|
||||
:chats/chat-type
|
||||
(fn [[_ chat-id] _]
|
||||
(re-frame/subscribe [:chat-by-id chat-id]))
|
||||
(fn [{:keys [chat-type]}]
|
||||
chat-type))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/joined
|
||||
(fn [[_ chat-id] _]
|
||||
(re-frame/subscribe [:chat-by-id chat-id]))
|
||||
(fn [{:keys [joined]}]
|
||||
joined))
|
||||
:chats/joined
|
||||
(fn [[_ chat-id] _]
|
||||
(re-frame/subscribe [:chat-by-id chat-id]))
|
||||
(fn [{:keys [joined]}]
|
||||
joined))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/synced-to-and-from
|
||||
(fn [[_ chat-id] _]
|
||||
(re-frame/subscribe [:chat-by-id chat-id]))
|
||||
(fn [chat]
|
||||
(select-keys chat [:synced-to :synced-from])))
|
||||
:chats/synced-to-and-from
|
||||
(fn [[_ chat-id] _]
|
||||
(re-frame/subscribe [:chat-by-id chat-id]))
|
||||
(fn [chat]
|
||||
(select-keys chat [:synced-to :synced-from])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-raw-chat
|
||||
:<- [:chats/chats]
|
||||
:<- [:chats/current-chat-id]
|
||||
(fn [[chats current-chat-id]]
|
||||
(get chats current-chat-id)))
|
||||
:chats/current-raw-chat
|
||||
:<- [:chats/chats]
|
||||
:<- [:chats/current-chat-id]
|
||||
(fn [[chats current-chat-id]]
|
||||
(get chats current-chat-id)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-inputs
|
||||
:<- [:chats/current-chat-id]
|
||||
:<- [:chat/inputs]
|
||||
(fn [[chat-id inputs]]
|
||||
(get inputs chat-id)))
|
||||
:chats/current-chat-inputs
|
||||
:<- [:chats/current-chat-id]
|
||||
:<- [:chat/inputs]
|
||||
(fn [[chat-id inputs]]
|
||||
(get inputs chat-id)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/timeline-chat-input
|
||||
:<- [:chat/inputs]
|
||||
:<- [:multiaccount/public-key]
|
||||
(fn [[inputs public-key]]
|
||||
(get inputs (chat.models/profile-chat-topic public-key))))
|
||||
:chats/timeline-chat-input
|
||||
:<- [:chat/inputs]
|
||||
:<- [:multiaccount/public-key]
|
||||
(fn [[inputs public-key]]
|
||||
(get inputs (chat.models/profile-chat-topic public-key))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/timeline-chat-input-text
|
||||
:<- [:chats/timeline-chat-input]
|
||||
(fn [input]
|
||||
(:input-text input)))
|
||||
:chats/timeline-chat-input-text
|
||||
:<- [:chats/timeline-chat-input]
|
||||
(fn [input]
|
||||
(:input-text input)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-membership
|
||||
:<- [:chats/current-chat-id]
|
||||
:<- [:chat/memberships]
|
||||
(fn [[chat-id memberships]]
|
||||
(get memberships chat-id)))
|
||||
:chats/current-chat-membership
|
||||
:<- [:chats/current-chat-id]
|
||||
:<- [:chat/memberships]
|
||||
(fn [[chat-id memberships]]
|
||||
(get memberships chat-id)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat
|
||||
:<- [:chats/current-raw-chat]
|
||||
:<- [:multiaccount/public-key]
|
||||
:<- [:communities/current-community]
|
||||
:<- [:contacts/blocked-set]
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:chat/inputs]
|
||||
:<- [:mutual-contact-requests/enabled?]
|
||||
(fn [[{:keys [group-chat chat-id] :as current-chat} my-public-key community blocked-users-set contacts
|
||||
inputs mutual-contact-requests-enabled?]]
|
||||
(when current-chat
|
||||
(cond-> current-chat
|
||||
(chat.models/public-chat? current-chat)
|
||||
(assoc :show-input? true)
|
||||
:chats/current-chat
|
||||
:<- [:chats/current-raw-chat]
|
||||
:<- [:multiaccount/public-key]
|
||||
:<- [:communities/current-community]
|
||||
:<- [:contacts/blocked-set]
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:chat/inputs]
|
||||
:<- [:mutual-contact-requests/enabled?]
|
||||
(fn [[{:keys [group-chat chat-id] :as current-chat} my-public-key community blocked-users-set contacts inputs mutual-contact-requests-enabled?]]
|
||||
(when current-chat
|
||||
(cond-> current-chat
|
||||
(chat.models/public-chat? current-chat)
|
||||
(assoc :show-input? true)
|
||||
|
||||
(and (chat.models/group-chat? current-chat)
|
||||
(group-chats.db/member? my-public-key current-chat))
|
||||
(assoc :show-input? true
|
||||
:member? true)
|
||||
(and (chat.models/group-chat? current-chat)
|
||||
(group-chats.db/member? my-public-key current-chat))
|
||||
(assoc :show-input? true
|
||||
:member? true)
|
||||
|
||||
(and (chat.models/community-chat? current-chat)
|
||||
(communities/can-post? community my-public-key (:chat-id current-chat)))
|
||||
(assoc :show-input? true)
|
||||
(and (chat.models/community-chat? current-chat)
|
||||
(communities/can-post? community my-public-key (:chat-id current-chat)))
|
||||
(assoc :show-input? true)
|
||||
|
||||
(not group-chat)
|
||||
(assoc :show-input?
|
||||
(and
|
||||
(or
|
||||
(not mutual-contact-requests-enabled?)
|
||||
(get-in inputs [chat-id :metadata :sending-contact-request])
|
||||
(and mutual-contact-requests-enabled?
|
||||
(= constants/contact-request-state-mutual
|
||||
(get-in contacts [chat-id :contact-request-state]))))
|
||||
(not (contains? blocked-users-set chat-id))))))))
|
||||
(not group-chat)
|
||||
(assoc :show-input?
|
||||
(and
|
||||
(or
|
||||
(not mutual-contact-requests-enabled?)
|
||||
(get-in inputs [chat-id :metadata :sending-contact-request])
|
||||
(and mutual-contact-requests-enabled?
|
||||
(= constants/contact-request-state-mutual
|
||||
(get-in contacts [chat-id :contact-request-state]))))
|
||||
(not (contains? blocked-users-set chat-id))))))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-chat-view
|
||||
:<- [:chats/current-chat]
|
||||
(fn [current-chat]
|
||||
(select-keys current-chat
|
||||
[:chat-id :show-input? :group-chat :admins :invitation-admin :public? :chat-type :color
|
||||
:chat-name :synced-to :synced-from :community-id :emoji])))
|
||||
:chats/current-chat-chat-view
|
||||
:<- [:chats/current-chat]
|
||||
(fn [current-chat]
|
||||
(select-keys current-chat [:chat-id :show-input? :group-chat :admins :invitation-admin :public? :chat-type :color :chat-name :synced-to :synced-from :community-id :emoji])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:current-chat/metadata
|
||||
:<- [:chats/current-raw-chat]
|
||||
(fn [current-chat]
|
||||
(select-keys current-chat
|
||||
[:community-id
|
||||
:contacts
|
||||
:public?
|
||||
:group-chat
|
||||
:chat-type
|
||||
:chat-id
|
||||
:chat-name
|
||||
:color
|
||||
:invitation-admin])))
|
||||
:current-chat/metadata
|
||||
:<- [:chats/current-raw-chat]
|
||||
(fn [current-chat]
|
||||
(select-keys current-chat
|
||||
[:community-id
|
||||
:contacts
|
||||
:public?
|
||||
:group-chat
|
||||
:chat-type
|
||||
:chat-id
|
||||
:chat-name
|
||||
:color
|
||||
:invitation-admin])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:current-chat/one-to-one-chat?
|
||||
:<- [:chats/current-raw-chat]
|
||||
(fn [current-chat]
|
||||
(not (or (chat.models/group-chat? current-chat)
|
||||
(chat.models/public-chat? current-chat)))))
|
||||
:current-chat/one-to-one-chat?
|
||||
:<- [:chats/current-raw-chat]
|
||||
(fn [current-chat]
|
||||
(not (or (chat.models/group-chat? current-chat)
|
||||
(chat.models/public-chat? current-chat)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-profile-chat
|
||||
:<- [:contacts/current-contact-identity]
|
||||
(fn [identity]
|
||||
(chat.models/profile-chat-topic identity)))
|
||||
:chats/current-profile-chat
|
||||
:<- [:contacts/current-contact-identity]
|
||||
(fn [identity]
|
||||
(chat.models/profile-chat-topic identity)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/photo-path
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:profile/multiaccount]
|
||||
:<- [:mediaserver/port]
|
||||
(fn [[contacts {:keys [public-key] :as multiaccount} port] [_ id]]
|
||||
(let [contact (or (when (= id public-key)
|
||||
multiaccount)
|
||||
(get contacts id))]
|
||||
(if (nil? contact)
|
||||
(image-server/get-identicons-uri port id)
|
||||
(multiaccounts/displayed-photo contact)))))
|
||||
:chats/photo-path
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:profile/multiaccount]
|
||||
:<- [:mediaserver/port]
|
||||
(fn [[contacts {:keys [public-key] :as multiaccount} port] [_ id]]
|
||||
(let [contact (or (when (= id public-key)
|
||||
multiaccount)
|
||||
(get contacts id))]
|
||||
(if (nil? contact)
|
||||
(image-server/get-identicons-uri port id)
|
||||
(multiaccounts/displayed-photo contact)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/unread-messages-number
|
||||
:<- [:chats/home-list-chats]
|
||||
(fn [chats _]
|
||||
(reduce (fn [{:keys [public other]} {:keys [unviewed-messages-count public?] :as chat}]
|
||||
(if (or public? (chat.models/community-chat? chat))
|
||||
{:public (+ public unviewed-messages-count)
|
||||
:other other}
|
||||
{:other (+ other unviewed-messages-count)
|
||||
:public public}))
|
||||
{:public 0
|
||||
:other 0}
|
||||
chats)))
|
||||
:chats/unread-messages-number
|
||||
:<- [:chats/home-list-chats]
|
||||
(fn [chats _]
|
||||
(reduce (fn [{:keys [public other]} {:keys [unviewed-messages-count public?] :as chat}]
|
||||
(if (or public? (chat.models/community-chat? chat))
|
||||
{:public (+ public unviewed-messages-count)
|
||||
:other other}
|
||||
{:other (+ other unviewed-messages-count)
|
||||
:public public}))
|
||||
{:public 0
|
||||
:other 0}
|
||||
chats)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-cooldown-enabled?
|
||||
:<- [:chats/current-chat]
|
||||
:<- [:chats/cooldown-enabled?]
|
||||
(fn [[{:keys [public?]} cooldown-enabled?]]
|
||||
(and public?
|
||||
cooldown-enabled?)))
|
||||
:chats/current-chat-cooldown-enabled?
|
||||
:<- [:chats/current-chat]
|
||||
:<- [:chats/cooldown-enabled?]
|
||||
(fn [[{:keys [public?]} cooldown-enabled?]]
|
||||
(and public?
|
||||
cooldown-enabled?)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/reply-message
|
||||
:<- [:chats/current-chat-inputs]
|
||||
(fn [{:keys [metadata]}]
|
||||
(:responding-to-message metadata)))
|
||||
:chats/reply-message
|
||||
:<- [:chats/current-chat-inputs]
|
||||
(fn [{:keys [metadata]}]
|
||||
(:responding-to-message metadata)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/edit-message
|
||||
:<- [:chats/current-chat-inputs]
|
||||
(fn [{:keys [metadata]}]
|
||||
(:editing-message metadata)))
|
||||
:chats/edit-message
|
||||
:<- [:chats/current-chat-inputs]
|
||||
(fn [{:keys [metadata]}]
|
||||
(:editing-message metadata)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/sending-contact-request
|
||||
:<- [:chats/current-chat-inputs]
|
||||
(fn [{:keys [metadata]}]
|
||||
(:sending-contact-request metadata)))
|
||||
:chats/sending-contact-request
|
||||
:<- [:chats/current-chat-inputs]
|
||||
(fn [{:keys [metadata]}]
|
||||
(:sending-contact-request metadata)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/sending-image
|
||||
:<- [:chats/current-chat-inputs]
|
||||
(fn [{:keys [metadata]}]
|
||||
(:sending-image metadata)))
|
||||
:chats/sending-image
|
||||
:<- [:chats/current-chat-inputs]
|
||||
(fn [{:keys [metadata]}]
|
||||
(:sending-image metadata)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/timeline-sending-image
|
||||
:<- [:chats/timeline-chat-input]
|
||||
(fn [{:keys [metadata]}]
|
||||
(:sending-image metadata)))
|
||||
:chats/timeline-sending-image
|
||||
:<- [:chats/timeline-chat-input]
|
||||
(fn [{:keys [metadata]}]
|
||||
(:sending-image metadata)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/chat-toolbar
|
||||
:<- [:multiaccounts/login]
|
||||
:<- [:chats/sending-image]
|
||||
:<- [:mainnet?]
|
||||
:<- [:current-chat/one-to-one-chat?]
|
||||
:<- [:current-chat/metadata]
|
||||
:<- [:chats/reply-message]
|
||||
:<- [:chats/edit-message]
|
||||
:<- [:chats/sending-contact-request]
|
||||
(fn [[{:keys [processing]} sending-image mainnet? one-to-one-chat? {:keys [public?]} reply edit
|
||||
sending-contact-request]]
|
||||
(let [sending-image (seq sending-image)]
|
||||
{:send (not processing)
|
||||
:stickers (and (or config/stickers-test-enabled? mainnet?)
|
||||
(not sending-image)
|
||||
(not sending-contact-request)
|
||||
(not reply))
|
||||
:image (and (not reply)
|
||||
(not edit)
|
||||
(not sending-contact-request)
|
||||
(not public?))
|
||||
:extensions (and one-to-one-chat?
|
||||
(or config/commands-enabled? mainnet?)
|
||||
(not edit)
|
||||
(not sending-contact-request)
|
||||
(not reply))
|
||||
:audio (and (not sending-image)
|
||||
(not reply)
|
||||
(not edit)
|
||||
(not sending-contact-request)
|
||||
(not public?))
|
||||
:sending-image sending-image})))
|
||||
:chats/chat-toolbar
|
||||
:<- [:multiaccounts/login]
|
||||
:<- [:chats/sending-image]
|
||||
:<- [:mainnet?]
|
||||
:<- [:current-chat/one-to-one-chat?]
|
||||
:<- [:current-chat/metadata]
|
||||
:<- [:chats/reply-message]
|
||||
:<- [:chats/edit-message]
|
||||
:<- [:chats/sending-contact-request]
|
||||
(fn [[{:keys [processing]} sending-image mainnet? one-to-one-chat? {:keys [public?]} reply edit sending-contact-request]]
|
||||
(let [sending-image (seq sending-image)]
|
||||
{:send (not processing)
|
||||
:stickers (and (or config/stickers-test-enabled? mainnet?)
|
||||
(not sending-image)
|
||||
(not sending-contact-request)
|
||||
(not reply))
|
||||
:image (and (not reply)
|
||||
(not edit)
|
||||
(not sending-contact-request)
|
||||
(not public?))
|
||||
:extensions (and one-to-one-chat?
|
||||
(or config/commands-enabled? mainnet?)
|
||||
(not edit)
|
||||
(not sending-contact-request)
|
||||
(not reply))
|
||||
:audio (and (not sending-image)
|
||||
(not reply)
|
||||
(not edit)
|
||||
(not sending-contact-request)
|
||||
(not public?))
|
||||
:sending-image sending-image})))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:public-chat.new/topic-error-message
|
||||
:<- [:public-group-topic]
|
||||
(fn [topic]
|
||||
(when-not (or (empty? topic)
|
||||
(db/valid-topic? topic))
|
||||
(i18n/label :topic-name-error))))
|
||||
:public-chat.new/topic-error-message
|
||||
:<- [:public-group-topic]
|
||||
(fn [topic]
|
||||
(when-not (or (empty? topic)
|
||||
(db/valid-topic? topic))
|
||||
(i18n/label :topic-name-error))))
|
||||
|
||||
(defn filter-selected-contacts
|
||||
[selected-contacts contacts]
|
||||
(filter #(:added (contacts %)) selected-contacts))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:selected-contacts-count
|
||||
:<- [:group/selected-contacts]
|
||||
:<- [:contacts/contacts]
|
||||
(fn [[selected-contacts contacts]]
|
||||
(count (filter-selected-contacts selected-contacts contacts))))
|
||||
:selected-contacts-count
|
||||
:<- [:group/selected-contacts]
|
||||
:<- [:contacts/contacts]
|
||||
(fn [[selected-contacts contacts]]
|
||||
(count (filter-selected-contacts selected-contacts contacts))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:selected-participants-count
|
||||
:<- [:selected-participants]
|
||||
(fn [selected-participants]
|
||||
(count selected-participants)))
|
||||
:group-chat/selected-participants-count
|
||||
:<- [:group-chat/selected-participants]
|
||||
(fn [selected-participants]
|
||||
(count selected-participants)))
|
||||
|
||||
(defn filter-contacts
|
||||
[selected-contacts active-contacts]
|
||||
(defn filter-contacts [selected-contacts active-contacts]
|
||||
(filter #(selected-contacts (:public-key %)) active-contacts))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:selected-group-contacts
|
||||
:<- [:group/selected-contacts]
|
||||
:<- [:contacts/active]
|
||||
(fn [[selected-contacts active-contacts]]
|
||||
(filter-contacts selected-contacts active-contacts)))
|
||||
:selected-group-contacts
|
||||
:<- [:group/selected-contacts]
|
||||
:<- [:contacts/active]
|
||||
(fn [[selected-contacts active-contacts]]
|
||||
(filter-contacts selected-contacts active-contacts)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:group-chat/inviter-info
|
||||
(fn [[_ chat-id] _]
|
||||
[(re-frame/subscribe [:chat-by-id chat-id])
|
||||
(re-frame/subscribe [:multiaccount/public-key])])
|
||||
(fn [[chat my-public-key]]
|
||||
{:member? (group-chats.db/member? my-public-key chat)
|
||||
:inviter-pk (group-chats.db/get-inviter-pk my-public-key chat)}))
|
||||
:group-chat/inviter-info
|
||||
(fn [[_ chat-id] _]
|
||||
[(re-frame/subscribe [:chat-by-id chat-id])
|
||||
(re-frame/subscribe [:multiaccount/public-key])])
|
||||
(fn [[chat my-public-key]]
|
||||
{:member? (group-chats.db/member? my-public-key chat)
|
||||
:inviter-pk (group-chats.db/get-inviter-pk my-public-key chat)}))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:group-chat/invitations-by-chat-id
|
||||
:<- [:group-chat/invitations]
|
||||
(fn [invitations [_ chat-id]]
|
||||
(filter #(= (:chat-id %) chat-id) (vals invitations))))
|
||||
:group-chat/invitations-by-chat-id
|
||||
:<- [:group-chat/invitations]
|
||||
(fn [invitations [_ chat-id]]
|
||||
(filter #(= (:chat-id %) chat-id) (vals invitations))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:group-chat/pending-invitations-by-chat-id
|
||||
(fn [[_ chat-id] _]
|
||||
[(re-frame/subscribe [:group-chat/invitations-by-chat-id chat-id])])
|
||||
(fn [[invitations]]
|
||||
(filter #(= constants/invitation-state-requested (:state %)) invitations)))
|
||||
:group-chat/pending-invitations-by-chat-id
|
||||
(fn [[_ chat-id] _]
|
||||
[(re-frame/subscribe [:group-chat/invitations-by-chat-id chat-id])])
|
||||
(fn [[invitations]]
|
||||
(filter #(= constants/invitation-state-requested (:state %)) invitations)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:group-chat/removed-from-current-chat?
|
||||
:<- [:chats/current-raw-chat]
|
||||
:<- [:multiaccount/public-key]
|
||||
(fn [[current-chat pk]]
|
||||
(group-chat/member-removed? current-chat pk)))
|
||||
:group-chat/removed-from-current-chat?
|
||||
:<- [:chats/current-raw-chat]
|
||||
:<- [:multiaccount/public-key]
|
||||
(fn [[current-chat pk]]
|
||||
(group-chat/member-removed? current-chat pk)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/mentionable-users
|
||||
:<- [:chats/current-chat]
|
||||
:<- [: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
|
||||
all-contacts
|
||||
current-multiaccount
|
||||
community-members)
|
||||
members-left (into #{} (filter #(group-chat/member-removed? chat %) (keys users)))]
|
||||
(apply dissoc mentionable-users (conj (concat blocked members-left) public-key)))))
|
||||
:chats/mentionable-users
|
||||
:<- [:chats/current-chat]
|
||||
:<- [: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 all-contacts current-multiaccount community-members)
|
||||
members-left (into #{} (filter #(group-chat/member-removed? chat %) (keys users)))]
|
||||
(apply dissoc mentionable-users (conj (concat blocked members-left) public-key)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chat/mention-suggestions
|
||||
:<- [:chats/current-chat-id]
|
||||
:<- [:chats/mention-suggestions]
|
||||
(fn [[chat-id mentions]]
|
||||
(take 15 (get mentions chat-id))))
|
||||
:chat/mention-suggestions
|
||||
:<- [:chats/current-chat-id]
|
||||
:<- [:chats/mention-suggestions]
|
||||
(fn [[chat-id mentions]]
|
||||
(take 15 (get mentions chat-id))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chat/input-with-mentions
|
||||
:<- [:chats/current-chat-id]
|
||||
:<- [:chat/inputs-with-mentions]
|
||||
(fn [[chat-id cursor]]
|
||||
(get cursor chat-id)))
|
||||
:chat/input-with-mentions
|
||||
:<- [:chats/current-chat-id]
|
||||
:<- [:chat/inputs-with-mentions]
|
||||
(fn [[chat-id cursor]]
|
||||
(get cursor chat-id)))
|
||||
|
|
|
@ -1,59 +1,54 @@
|
|||
(ns status-im2.subs.contact
|
||||
(:require [clojure.string :as string]
|
||||
[i18n.i18n :as i18n]
|
||||
[re-frame.core :as re-frame]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.contact.db :as contact.db]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.utils.image-server :as image-server]
|
||||
[status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.utils.gfycat.core :as gfycat]
|
||||
[status-im.utils.image-server :as image-server]))
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[clojure.string :as string]
|
||||
[utils.collection]
|
||||
[i18n.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::query-current-chat-contacts
|
||||
:<- [:chats/current-chat]
|
||||
:<- [:contacts/contacts]
|
||||
(fn [[chat contacts] [_ query-fn]]
|
||||
(contact.db/query-chat-contacts chat contacts query-fn)))
|
||||
::query-current-chat-contacts
|
||||
:<- [:chats/current-chat]
|
||||
:<- [:contacts/contacts]
|
||||
(fn [[chat contacts] [_ query-fn]]
|
||||
(contact.db/query-chat-contacts chat contacts query-fn)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:multiaccount/profile-pictures-show-to
|
||||
:<- [:multiaccount]
|
||||
(fn [multiaccount]
|
||||
(get multiaccount :profile-pictures-show-to)))
|
||||
:multiaccount/profile-pictures-show-to
|
||||
:<- [:multiaccount]
|
||||
(fn [multiaccount]
|
||||
(get multiaccount :profile-pictures-show-to)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:mutual-contact-requests/enabled?
|
||||
:<- [:multiaccount]
|
||||
(fn [settings]
|
||||
(boolean (:mutual-contact-enabled? settings))))
|
||||
:mutual-contact-requests/enabled?
|
||||
:<- [:multiaccount]
|
||||
(fn [settings]
|
||||
(boolean (:mutual-contact-enabled? settings))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::profile-pictures-visibility
|
||||
:<- [:multiaccount]
|
||||
(fn [multiaccount]
|
||||
(get multiaccount :profile-pictures-visibility)))
|
||||
::profile-pictures-visibility
|
||||
:<- [:multiaccount]
|
||||
(fn [multiaccount]
|
||||
(get multiaccount :profile-pictures-visibility)))
|
||||
|
||||
(defn- replace-contact-image-uri
|
||||
[contact port identity]
|
||||
(let [identicon (image-server/get-identicons-uri port identity)
|
||||
(defn- replace-contact-image-uri [contact port identity]
|
||||
(let [identicon (image-server/get-identicons-uri port identity)
|
||||
contact-images (:images contact)
|
||||
contact-images (reduce (fn [acc image]
|
||||
(let [image-name (:type image)
|
||||
; We pass the clock so that we reload the image if the image is
|
||||
; updated
|
||||
clock (:clock image)
|
||||
uri (image-server/get-contact-image-uri port
|
||||
identity
|
||||
image-name
|
||||
clock)]
|
||||
(assoc-in acc [(keyword image-name) :uri] uri)))
|
||||
contact-images (reduce (fn [acc image] (let [image-name (:type image)
|
||||
; We pass the clock so that we reload the image if the image is updated
|
||||
clock (:clock image)
|
||||
uri (image-server/get-contact-image-uri port identity image-name clock)]
|
||||
(assoc-in acc [(keyword image-name) :uri] uri)))
|
||||
contact-images
|
||||
(vals contact-images))]
|
||||
(assoc contact :identicon identicon :images contact-images)))
|
||||
|
||||
(defn- reduce-contacts-image-uri
|
||||
[contacts port]
|
||||
(defn- reduce-contacts-image-uri [contacts port]
|
||||
(reduce-kv (fn [acc public-key contact]
|
||||
(let [contact (replace-contact-image-uri contact port public-key)]
|
||||
(assoc acc public-key contact)))
|
||||
|
@ -61,237 +56,250 @@
|
|||
contacts))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contacts
|
||||
:<- [:contacts/contacts-raw]
|
||||
:<- [::profile-pictures-visibility]
|
||||
:<- [:multiaccount/public-key]
|
||||
:<- [:mediaserver/port]
|
||||
(fn [[contacts profile-pictures-visibility public-key port]]
|
||||
(let [contacts (contact.db/enrich-contacts contacts profile-pictures-visibility public-key)]
|
||||
(reduce-contacts-image-uri contacts port))))
|
||||
:contacts/contacts
|
||||
:<- [:contacts/contacts-raw]
|
||||
:<- [::profile-pictures-visibility]
|
||||
:<- [:multiaccount/public-key]
|
||||
:<- [:mediaserver/port]
|
||||
(fn [[contacts profile-pictures-visibility public-key port]]
|
||||
(let [contacts (contact.db/enrich-contacts contacts profile-pictures-visibility public-key)]
|
||||
(reduce-contacts-image-uri contacts port))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/active
|
||||
:<- [:contacts/contacts]
|
||||
(fn [contacts]
|
||||
(contact.db/get-active-contacts contacts)))
|
||||
:contacts/active
|
||||
:<- [:contacts/contacts]
|
||||
(fn [contacts]
|
||||
(contact.db/get-active-contacts contacts)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/active-sections
|
||||
:<- [:contacts/active]
|
||||
(fn [contacts]
|
||||
(-> (reduce
|
||||
(fn [acc contact]
|
||||
(let [first-char (first (:alias contact))]
|
||||
(if (get acc first-char)
|
||||
(update-in acc [first-char :data] #(conj % contact))
|
||||
(assoc acc first-char {:title first-char :data [contact]}))))
|
||||
{}
|
||||
contacts)
|
||||
sort
|
||||
vals)))
|
||||
:contacts/active-sections
|
||||
:<- [:contacts/active]
|
||||
(fn [contacts]
|
||||
(-> (reduce
|
||||
(fn [acc contact]
|
||||
(let [first-char (first (:alias contact))]
|
||||
(if (get acc first-char)
|
||||
(update-in acc [first-char :data] #(conj % contact))
|
||||
(assoc acc first-char {:title first-char :data [contact]}))))
|
||||
{}
|
||||
contacts)
|
||||
sort
|
||||
vals)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/sorted-contacts
|
||||
:<- [:contacts/active]
|
||||
(fn [active-contacts]
|
||||
(->> active-contacts
|
||||
(sort-by :alias)
|
||||
(sort-by
|
||||
#(visibility-status-utils/visibility-status-order (:public-key %))))))
|
||||
:contacts/add-members-sections
|
||||
:<- [:contacts/current-chat-contacts]
|
||||
:<- [:contacts/active]
|
||||
(fn [[members contacts]]
|
||||
(-> (reduce
|
||||
(fn [acc contact]
|
||||
(let [first-char (first (:alias contact))]
|
||||
(if (get acc first-char)
|
||||
(update-in acc [first-char :data] #(conj % contact))
|
||||
(assoc acc first-char {:title first-char :data [contact]}))))
|
||||
{}
|
||||
(utils.collection/distinct-by :public-key (concat members contacts)))
|
||||
sort
|
||||
vals)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/active-count
|
||||
:<- [:contacts/active]
|
||||
(fn [active-contacts]
|
||||
(count active-contacts)))
|
||||
:contacts/sorted-contacts
|
||||
:<- [:contacts/active]
|
||||
(fn [active-contacts]
|
||||
(->> active-contacts
|
||||
(sort-by :alias)
|
||||
(sort-by
|
||||
#(visibility-status-utils/visibility-status-order (:public-key %))))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/blocked
|
||||
:<- [:contacts/contacts]
|
||||
(fn [contacts]
|
||||
(->> contacts
|
||||
(filter (fn [[_ contact]]
|
||||
(:blocked contact)))
|
||||
(contact.db/sort-contacts))))
|
||||
:contacts/active-count
|
||||
:<- [:contacts/active]
|
||||
(fn [active-contacts]
|
||||
(count active-contacts)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/blocked-count
|
||||
:<- [:contacts/blocked]
|
||||
(fn [blocked-contacts]
|
||||
(count blocked-contacts)))
|
||||
:contacts/blocked
|
||||
:<- [:contacts/contacts]
|
||||
(fn [contacts]
|
||||
(->> contacts
|
||||
(filter (fn [[_ contact]]
|
||||
(:blocked contact)))
|
||||
(contact.db/sort-contacts))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/blocked-count
|
||||
:<- [:contacts/blocked]
|
||||
(fn [blocked-contacts]
|
||||
(count blocked-contacts)))
|
||||
|
||||
(defn filter-recipient-contacts
|
||||
[search-filter {:keys [names]}]
|
||||
(let [{:keys [nickname three-words-name ens-name]} names]
|
||||
(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 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)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/active-with-ens-names
|
||||
:<- [:contacts/active]
|
||||
:<- [:search/recipient-filter]
|
||||
(fn [[contacts search-filter]]
|
||||
(let [contacts (filter :ens-verified contacts)]
|
||||
(if (string/blank? search-filter)
|
||||
contacts
|
||||
(filter (partial filter-recipient-contacts
|
||||
(string/lower-case search-filter))
|
||||
contacts)))))
|
||||
:contacts/active-with-ens-names
|
||||
:<- [:contacts/active]
|
||||
:<- [:search/recipient-filter]
|
||||
(fn [[contacts search-filter]]
|
||||
(let [contacts (filter :ens-verified contacts)]
|
||||
(if (string/blank? search-filter)
|
||||
contacts
|
||||
(filter (partial filter-recipient-contacts
|
||||
(string/lower-case search-filter))
|
||||
contacts)))))
|
||||
|
||||
(defn- enrich-contact
|
||||
[_ identity ens-name port]
|
||||
(defn- enrich-contact [_ identity ens-name port]
|
||||
(let [contact (contact.db/enrich-contact
|
||||
(contact.db/public-key-and-ens-name->new-contact identity ens-name))]
|
||||
(contact.db/public-key-and-ens-name->new-contact identity ens-name))]
|
||||
(replace-contact-image-uri contact port identity)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/current-contact
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:contacts/current-contact-identity]
|
||||
:<- [:contacts/current-contact-ens-name]
|
||||
:<- [:mediaserver/port]
|
||||
(fn [[contacts identity ens-name port]]
|
||||
(let [contact (get contacts identity)]
|
||||
(cond-> contact
|
||||
(nil? contact)
|
||||
(enrich-contact identity ens-name port)))))
|
||||
:contacts/current-contact
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:contacts/current-contact-identity]
|
||||
:<- [:contacts/current-contact-ens-name]
|
||||
:<- [:mediaserver/port]
|
||||
(fn [[contacts identity ens-name port]]
|
||||
(let [contact (get contacts identity)]
|
||||
(cond-> contact
|
||||
(nil? contact)
|
||||
(enrich-contact identity ens-name port)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contact-by-identity
|
||||
:<- [:contacts/contacts]
|
||||
(fn [contacts [_ identity]]
|
||||
(multiaccounts/contact-by-identity contacts identity)))
|
||||
:contacts/contact-by-identity
|
||||
:<- [:contacts/contacts]
|
||||
(fn [contacts [_ identity]]
|
||||
(multiaccounts/contact-by-identity contacts identity)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contact-added?
|
||||
(fn [[_ identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-by-identity identity])])
|
||||
(fn [[contact] _]
|
||||
(:added contact)))
|
||||
:contacts/contact-added?
|
||||
(fn [[_ identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-by-identity identity])])
|
||||
(fn [[contact] _]
|
||||
(:added contact)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contact-blocked?
|
||||
(fn [[_ identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-by-identity identity])])
|
||||
(fn [[contact] _]
|
||||
(:blocked contact)))
|
||||
:contacts/contact-blocked?
|
||||
(fn [[_ identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-by-identity identity])])
|
||||
(fn [[contact] _]
|
||||
(:blocked contact)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contact-two-names-by-identity
|
||||
(fn [[_ identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-by-identity identity])
|
||||
(re-frame/subscribe [:multiaccount])])
|
||||
(fn [[contact current-multiaccount] [_ identity]]
|
||||
(multiaccounts/contact-two-names-by-identity contact
|
||||
current-multiaccount
|
||||
identity)))
|
||||
:contacts/contact-two-names-by-identity
|
||||
(fn [[_ identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-by-identity identity])
|
||||
(re-frame/subscribe [:multiaccount])])
|
||||
(fn [[contact current-multiaccount] [_ identity]]
|
||||
(multiaccounts/contact-two-names-by-identity contact current-multiaccount
|
||||
identity)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contact-name-by-identity
|
||||
(fn [[_ identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-two-names-by-identity identity])])
|
||||
(fn [[names] _]
|
||||
(first names)))
|
||||
:contacts/contact-name-by-identity
|
||||
(fn [[_ identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-two-names-by-identity identity])])
|
||||
(fn [[names] _]
|
||||
(first names)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:messages/quote-info
|
||||
:<- [:chats/messages]
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:multiaccount]
|
||||
(fn [[messages contacts current-multiaccount] [_ message-id]]
|
||||
(when-let [message (get messages message-id)]
|
||||
(let [identity (:from message)
|
||||
me? (= (:public-key current-multiaccount) identity)]
|
||||
(if me?
|
||||
{:quote {:from identity
|
||||
:text (get-in message [:content :text])}
|
||||
:ens-name (:preferred-name current-multiaccount)
|
||||
:alias (gfycat/generate-gfy identity)}
|
||||
(let [contact (or (contacts identity)
|
||||
(contact.db/public-key->new-contact identity))]
|
||||
{:quote {:from identity
|
||||
:text (get-in message [:content :text])}
|
||||
:ens-name (when (:ens-verified contact)
|
||||
(:name contact))
|
||||
:alias (or (:alias contact)
|
||||
(gfycat/generate-gfy identity))}))))))
|
||||
:messages/quote-info
|
||||
:<- [:chats/messages]
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:multiaccount]
|
||||
(fn [[messages contacts current-multiaccount] [_ message-id]]
|
||||
(when-let [message (get messages message-id)]
|
||||
(let [identity (:from message)
|
||||
me? (= (:public-key current-multiaccount) identity)]
|
||||
(if me?
|
||||
{:quote {:from identity
|
||||
:text (get-in message [:content :text])}
|
||||
:ens-name (:preferred-name current-multiaccount)
|
||||
:alias (gfycat/generate-gfy identity)}
|
||||
(let [contact (or (contacts identity)
|
||||
(contact.db/public-key->new-contact identity))]
|
||||
{:quote {:from identity
|
||||
:text (get-in message [:content :text])}
|
||||
:ens-name (when (:ens-verified contact)
|
||||
(:name contact))
|
||||
:alias (or (:alias contact)
|
||||
(gfycat/generate-gfy identity))}))))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/all-contacts-not-in-current-chat
|
||||
:<- [::query-current-chat-contacts remove]
|
||||
(fn [contacts]
|
||||
(filter :added contacts)))
|
||||
:contacts/all-contacts-not-in-current-chat
|
||||
:<- [::query-current-chat-contacts remove]
|
||||
(fn [contacts]
|
||||
(filter :added contacts)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/current-chat-contacts
|
||||
:<- [:chats/current-chat]
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:multiaccount]
|
||||
(fn [[{:keys [contacts admins]} all-contacts current-multiaccount]]
|
||||
(contact.db/get-all-contacts-in-group-chat contacts admins all-contacts current-multiaccount)))
|
||||
:contacts/current-chat-contacts
|
||||
:<- [:chats/current-chat]
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:multiaccount]
|
||||
(fn [[{:keys [contacts admins]} all-contacts current-multiaccount]]
|
||||
(contact.db/get-all-contacts-in-group-chat contacts admins all-contacts current-multiaccount)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contacts-by-chat
|
||||
(fn [[_ _ chat-id] _]
|
||||
[(re-frame/subscribe [:chats/chat chat-id])
|
||||
(re-frame/subscribe [:contacts/contacts])])
|
||||
(fn [[chat all-contacts] [_ query-fn]]
|
||||
(contact.db/query-chat-contacts chat all-contacts query-fn)))
|
||||
:contacts/contacts-by-chat
|
||||
(fn [[_ _ chat-id] _]
|
||||
[(re-frame/subscribe [:chats/chat chat-id])
|
||||
(re-frame/subscribe [:contacts/contacts])])
|
||||
(fn [[chat all-contacts] [_ query-fn]]
|
||||
(contact.db/query-chat-contacts chat all-contacts query-fn)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contact-by-address
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:multiaccount/contact]
|
||||
(fn [[contacts multiaccount] [_ address]]
|
||||
(if (ethereum/address= address (:public-key multiaccount))
|
||||
multiaccount
|
||||
(contact.db/find-contact-by-address contacts address))))
|
||||
:contacts/contact-by-address
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:multiaccount/contact]
|
||||
(fn [[contacts multiaccount] [_ address]]
|
||||
(if (ethereum/address= address (:public-key multiaccount))
|
||||
multiaccount
|
||||
(contact.db/find-contact-by-address contacts address))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contacts-by-address
|
||||
:<- [:contacts/contacts]
|
||||
(fn [contacts]
|
||||
(reduce (fn [acc [_ {:keys [address] :as contact}]]
|
||||
(if address
|
||||
(assoc acc address contact)
|
||||
acc))
|
||||
{}
|
||||
contacts)))
|
||||
:contacts/contacts-by-address
|
||||
:<- [:contacts/contacts]
|
||||
(fn [contacts]
|
||||
(reduce (fn [acc [_ {:keys [address] :as contact}]]
|
||||
(if address
|
||||
(assoc acc address contact)
|
||||
acc))
|
||||
{}
|
||||
contacts)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/filtered-active-sections
|
||||
:<- [:contacts/active-sections]
|
||||
:<- [:contacts/search-query]
|
||||
(fn [[contacts query]]
|
||||
(if (empty? query)
|
||||
contacts
|
||||
(->> contacts
|
||||
(map (fn [item]
|
||||
(update item
|
||||
:data
|
||||
(fn [data]
|
||||
(filter #(string/includes?
|
||||
(string/lower-case (:alias %))
|
||||
(string/lower-case query))
|
||||
data)))))
|
||||
(remove #(empty? (:data %)))))))
|
||||
:contacts/filtered-active-sections
|
||||
:<- [:contacts/active-sections]
|
||||
:<- [:contacts/search-query]
|
||||
(fn [[contacts query]]
|
||||
(if (empty? query)
|
||||
contacts
|
||||
(->> contacts
|
||||
(map (fn [item]
|
||||
(update item :data (fn [data]
|
||||
(filter #(string/includes?
|
||||
(string/lower-case (:alias %))
|
||||
(string/lower-case query))
|
||||
data)))))
|
||||
(remove #(empty? (:data %)))))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/group-members-sections
|
||||
:<- [:contacts/current-chat-contacts]
|
||||
(fn [members]
|
||||
(let [admins (filter :admin? members)
|
||||
online (filter #(and (not (:admin? %)) (:online? %)) members)
|
||||
offline (filter #(and (not (:admin? %)) (not (:online? %))) members)]
|
||||
(vals (cond-> {}
|
||||
(seq admins) (assoc :owner {:title (i18n/label :t/owner) :data admins})
|
||||
(seq online) (assoc :online {:title (i18n/label :t/online) :data online})
|
||||
(seq offline) (assoc :offline {:title (i18n/label :t/offline) :data offline}))))))
|
||||
|
||||
:contacts/group-members-sections
|
||||
:<- [:contacts/current-chat-contacts]
|
||||
(fn [members]
|
||||
(let [admins (filter :admin? members)
|
||||
online (filter #(let [online (rf/sub [:visibility-status-updates/online? (:public-key %)])]
|
||||
(and (not (:admin? %)) online)) members)
|
||||
offline (filter #(let [online (rf/sub [:visibility-status-updates/online? (:public-key %)])]
|
||||
(and (not (:admin? %)) (not online))) members)]
|
||||
(vals (cond-> {}
|
||||
(seq admins) (assoc :owner {:title (i18n/label :t/owner) :data admins})
|
||||
(seq online) (assoc :online {:title (i18n/label :t/online) :data online})
|
||||
(seq offline) (assoc :offline {:title (i18n/label :t/offline) :data offline}))))))
|
||||
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@
|
|||
|
||||
(re-frame/reg-sub
|
||||
:is-participant-selected?
|
||||
:<- [:selected-participants]
|
||||
:<- [:group-chat/selected-participants]
|
||||
(fn [selected-participants [_ element]]
|
||||
(-> selected-participants
|
||||
(contains? element))))
|
||||
|
|
|
@ -98,7 +98,8 @@
|
|||
(reg-root-key-sub :new-chat-name :new-chat-name)
|
||||
(reg-root-key-sub :group-chat-profile/editing? :group-chat-profile/editing?)
|
||||
(reg-root-key-sub :group-chat-profile/profile :group-chat-profile/profile)
|
||||
(reg-root-key-sub :selected-participants :selected-participants)
|
||||
(reg-root-key-sub :group-chat/selected-participants :group-chat/selected-participants)
|
||||
(reg-root-key-sub :group-chat/deselected-members :group-chat/deselected-members)
|
||||
(reg-root-key-sub :chat/inputs :chat/inputs)
|
||||
(reg-root-key-sub :chat/memberships :chat/memberships)
|
||||
(reg-root-key-sub :camera-roll/photos :camera-roll/photos)
|
||||
|
|
|
@ -14,3 +14,9 @@
|
|||
Similar to group-by except that the map values are single objects (depends on key uniqueness)."
|
||||
[key coll]
|
||||
(into {} (map #(vector (key %) %) coll)))
|
||||
|
||||
(defn distinct-by
|
||||
"Given a key and a collection returns a unique collection by that key"
|
||||
[key coll]
|
||||
(let [groups (group-by key coll)]
|
||||
(map #(first (groups %)) (distinct (map key coll)))))
|
||||
|
|
|
@ -1912,5 +1912,6 @@
|
|||
"instruction-after-qr-generated": "On your other device, navigate to the Syncing screen and select “Scan sync”",
|
||||
"show-existing-keys": "Show Existing Keys",
|
||||
"scan-sync-code": "Scan Sync Code",
|
||||
"confirm-selection": "Confirm selection"
|
||||
"confirm-selection": "Confirm selection",
|
||||
"online": "Online"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue