Communities
Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
parent
35c2c226df
commit
2ca39daa59
2
.env
2
.env
|
@ -26,3 +26,5 @@ ENABLE_REFERRAL_INVITE=1
|
||||||
ENABLE_QUO_PREVIEW=1
|
ENABLE_QUO_PREVIEW=1
|
||||||
MAX_IMAGES_BATCH=5
|
MAX_IMAGES_BATCH=5
|
||||||
APN_TOPIC=im.status.ethereum.pr
|
APN_TOPIC=im.status.ethereum.pr
|
||||||
|
COMMUNITIES_ENABLED=1
|
||||||
|
COMMUNITIES_MANAGEMENT_ENABLED=1
|
||||||
|
|
2
.env.e2e
2
.env.e2e
|
@ -26,3 +26,5 @@ ENABLE_REFERRAL_INVITE=1
|
||||||
MAX_IMAGES_BATCH=5
|
MAX_IMAGES_BATCH=5
|
||||||
APN_TOPIC=im.status.ethereum.pr
|
APN_TOPIC=im.status.ethereum.pr
|
||||||
VERIFY_TRANSACTION_CHAIN_ID=3
|
VERIFY_TRANSACTION_CHAIN_ID=3
|
||||||
|
COMMUNITIES_ENABLED=1
|
||||||
|
COMMUNITIES_MANAGEMENT_ENABLED=0
|
||||||
|
|
|
@ -26,3 +26,5 @@ APN_TOPIC=im.status.ethereum.pr
|
||||||
BLANK_PREVIEW=0
|
BLANK_PREVIEW=0
|
||||||
MAX_IMAGES_BATCH=5
|
MAX_IMAGES_BATCH=5
|
||||||
GOOGLE_FREE=0
|
GOOGLE_FREE=0
|
||||||
|
COMMUNITIES_ENABLED=1
|
||||||
|
COMMUNITIES_MANAGEMENT_ENABLED=0
|
||||||
|
|
|
@ -20,3 +20,4 @@ ENABLE_ROOT_ALERT=1
|
||||||
ENABLE_REFERRAL_INVITE=0
|
ENABLE_REFERRAL_INVITE=0
|
||||||
MAX_IMAGES_BATCH=5
|
MAX_IMAGES_BATCH=5
|
||||||
BLANK_PREVIEW=0
|
BLANK_PREVIEW=0
|
||||||
|
COMMUNITIES_ENABLED=1
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 841 B |
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
|
@ -10,6 +10,7 @@
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.mailserver.core :as mailserver]
|
[status-im.mailserver.core :as mailserver]
|
||||||
[status-im.ui.components.colors :as colors]
|
[status-im.ui.components.colors :as colors]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[status-im.navigation :as navigation]
|
[status-im.navigation :as navigation]
|
||||||
[status-im.utils.clocks :as utils.clocks]
|
[status-im.utils.clocks :as utils.clocks]
|
||||||
[status-im.utils.fx :as fx]
|
[status-im.utils.fx :as fx]
|
||||||
|
@ -32,6 +33,9 @@
|
||||||
(def one-to-one-chat?
|
(def one-to-one-chat?
|
||||||
(complement multi-user-chat?))
|
(complement multi-user-chat?))
|
||||||
|
|
||||||
|
(defn community-chat? [{:keys [chat-type]}]
|
||||||
|
(= chat-type constants/community-chat-type))
|
||||||
|
|
||||||
(defn public-chat?
|
(defn public-chat?
|
||||||
([chat]
|
([chat]
|
||||||
(:public? chat))
|
(:public? chat))
|
||||||
|
@ -94,6 +98,7 @@
|
||||||
{:chat-id chat-id
|
{:chat-id chat-id
|
||||||
:name (or name "")
|
:name (or name "")
|
||||||
:color (rand-nth colors/chat-colors)
|
:color (rand-nth colors/chat-colors)
|
||||||
|
:chat-type constants/one-to-one-chat-type
|
||||||
:group-chat false
|
:group-chat false
|
||||||
:is-active true
|
:is-active true
|
||||||
:timestamp now
|
:timestamp now
|
||||||
|
@ -176,6 +181,9 @@
|
||||||
:name topic
|
:name topic
|
||||||
:chat-name (str "#" topic)
|
:chat-name (str "#" topic)
|
||||||
:group-chat true
|
:group-chat true
|
||||||
|
:chat-type (if timeline?
|
||||||
|
constants/timeline-chat-type
|
||||||
|
constants/public-chat-type)
|
||||||
:contacts #{}
|
:contacts #{}
|
||||||
:public? true
|
:public? true
|
||||||
:might-have-join-time-messages? (get-in cofx [:db :multiaccount :use-mailservers?])
|
:might-have-join-time-messages? (get-in cofx [:db :multiaccount :use-mailservers?])
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.chat.models.mentions
|
(ns status-im.chat.models.mentions
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[status-im.utils.fx :as fx]
|
[status-im.utils.fx :as fx]
|
||||||
[status-im.contact.db :as contact.db]
|
[status-im.contact.db :as contact.db]
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
|
@ -172,11 +173,11 @@
|
||||||
(defn get-mentionable-users
|
(defn get-mentionable-users
|
||||||
[{{:keys [current-chat-id]
|
[{{:keys [current-chat-id]
|
||||||
:contacts/keys [contacts] :as db} :db}]
|
:contacts/keys [contacts] :as db} :db}]
|
||||||
(let [{:keys [group-chat public? users] :as chat}
|
(let [{:keys [chat-type users] :as chat}
|
||||||
(get-in db [:chats current-chat-id])
|
(get-in db [:chats current-chat-id])
|
||||||
chat-specific-suggestions
|
chat-specific-suggestions
|
||||||
(cond
|
(cond
|
||||||
(and group-chat (not public?))
|
(= chat-type constants/private-group-chat-type)
|
||||||
(let [{:keys [public-key]} (:multiaccount db)
|
(let [{:keys [public-key]} (:multiaccount db)
|
||||||
all-contacts (:contacts/contacts db)
|
all-contacts (:contacts/contacts db)
|
||||||
group-contacts
|
group-contacts
|
||||||
|
|
|
@ -114,20 +114,6 @@
|
||||||
(get-in db [:chats chat-id])]
|
(get-in db [:chats chat-id])]
|
||||||
(>= deleted-at-clock-value clock-value)))
|
(>= deleted-at-clock-value clock-value)))
|
||||||
|
|
||||||
(defn extract-chat-id
|
|
||||||
"Validate and return a valid chat-id"
|
|
||||||
[cofx {:keys [chat-id from message-type]}]
|
|
||||||
(cond
|
|
||||||
(and (= constants/message-type-private-group message-type)
|
|
||||||
(and (get-in cofx [:db :chats chat-id :contacts from])
|
|
||||||
(get-in cofx [:db :chats chat-id :members-joined (multiaccounts.model/current-public-key cofx)]))) chat-id
|
|
||||||
(and (= constants/message-type-public-group message-type)
|
|
||||||
(get-in cofx [:db :chats chat-id :public?])) chat-id
|
|
||||||
(and (= constants/message-type-one-to-one message-type)
|
|
||||||
(= (multiaccounts.model/current-public-key cofx) from)) chat-id
|
|
||||||
(= constants/message-type-private-group-system-message message-type) chat-id
|
|
||||||
(= constants/message-type-one-to-one message-type) from))
|
|
||||||
|
|
||||||
(fx/defn update-unviewed-count
|
(fx/defn update-unviewed-count
|
||||||
[{:keys [db] :as cofx} {:keys [chat-id from message-type message-id new?]}]
|
[{:keys [db] :as cofx} {:keys [chat-id from message-type message-id new?]}]
|
||||||
(when-not (= message-type constants/message-type-private-group-system-message)
|
(when-not (= message-type constants/message-type-private-group-system-message)
|
||||||
|
@ -159,24 +145,22 @@
|
||||||
|
|
||||||
(fx/defn receive-one
|
(fx/defn receive-one
|
||||||
{:events [::receive-one]}
|
{:events [::receive-one]}
|
||||||
[{:keys [db] :as cofx} {:keys [message-id] :as message}]
|
[{:keys [db] :as cofx} {:keys [message-id chat-id] :as message}]
|
||||||
(when-let [chat-id (extract-chat-id cofx message)]
|
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
;;If its a profile updates we want to add this message to the timeline as well
|
;;If its a profile updates we want to add this message to the timeline as well
|
||||||
#(when (get-in cofx [:db :chats chat-id :profile-public-key])
|
#(when (get-in cofx [:db :chats chat-id :profile-public-key])
|
||||||
{:dispatch-n [[::receive-one (assoc message :chat-id chat-model/timeline-chat-id)]]})
|
{:dispatch-n [[::receive-one (assoc message :chat-id chat-model/timeline-chat-id)]]})
|
||||||
#(let [message-with-chat-id (assoc message :chat-id chat-id)]
|
#(when-not (earlier-than-deleted-at? cofx message)
|
||||||
(when-not (earlier-than-deleted-at? cofx message-with-chat-id)
|
(if (message-loaded? cofx message)
|
||||||
(if (message-loaded? cofx message-with-chat-id)
|
|
||||||
;; If the message is already loaded, it means it's an update, that
|
;; If the message is already loaded, it means it's an update, that
|
||||||
;; happens when a message that was missing a reply had the reply
|
;; happens when a message that was missing a reply had the reply
|
||||||
;; coming through, in which case we just insert the new message
|
;; coming through, in which case we just insert the new message
|
||||||
{:db (assoc-in db [:messages chat-id message-id] message-with-chat-id)}
|
{:db (assoc-in db [:messages chat-id message-id] message)}
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
(add-received-message message-with-chat-id)
|
(add-received-message message)
|
||||||
(update-unviewed-count message-with-chat-id)
|
(update-unviewed-count message)
|
||||||
(chat-model/join-time-messages-checked chat-id)
|
(chat-model/join-time-messages-checked chat-id)
|
||||||
(check-for-incoming-tx message-with-chat-id))))))))
|
(check-for-incoming-tx message))))))
|
||||||
|
|
||||||
;;TODO currently we process every message, we need to precess them by batches
|
;;TODO currently we process every message, we need to precess them by batches
|
||||||
;;or better move processing to status-go
|
;;or better move processing to status-go
|
||||||
|
|
|
@ -3,11 +3,8 @@
|
||||||
[status-im.chat.models.loading :as chat-loading]
|
[status-im.chat.models.loading :as chat-loading]
|
||||||
[status-im.chat.models.message :as message]
|
[status-im.chat.models.message :as message]
|
||||||
[status-im.chat.models.message-list :as models.message-list]
|
[status-im.chat.models.message-list :as models.message-list]
|
||||||
[status-im.constants :as constants]
|
|
||||||
[status-im.ui.screens.chat.state :as view.state]
|
[status-im.ui.screens.chat.state :as view.state]
|
||||||
[status-im.utils.datetime :as time]
|
[status-im.utils.datetime :as time]))
|
||||||
[status-im.utils.gfycat.core :as gfycat]
|
|
||||||
[status-im.utils.identicon :as identicon]))
|
|
||||||
|
|
||||||
(deftest add-received-message-test
|
(deftest add-received-message-test
|
||||||
(with-redefs [message/add-message (constantly :added)]
|
(with-redefs [message/add-message (constantly :added)]
|
||||||
|
@ -154,129 +151,6 @@
|
||||||
:clock-value 0
|
:clock-value 0
|
||||||
:chat-id "a"}))))
|
:chat-id "a"}))))
|
||||||
|
|
||||||
(deftest add-own-received-message
|
|
||||||
(let [db {:multiaccount {:public-key "me"}
|
|
||||||
:view-id :chat
|
|
||||||
:loaded-chat-id "chat-id"
|
|
||||||
:current-chat-id "chat-id"
|
|
||||||
:messages {"chat-id" {}}
|
|
||||||
:chats {"chat-id" {}}}]
|
|
||||||
(testing "a message coming from you!"
|
|
||||||
(let [actual (message/receive-one {:db db}
|
|
||||||
{:from "me"
|
|
||||||
:message-type constants/message-type-one-to-one
|
|
||||||
:timestamp 0
|
|
||||||
:whisper-timestamp 0
|
|
||||||
:message-id "id"
|
|
||||||
:chat-id "chat-id"
|
|
||||||
:outgoing true
|
|
||||||
:content "b"
|
|
||||||
:clock-value 1})
|
|
||||||
message (get-in actual [:db :messages "chat-id" "id"])]
|
|
||||||
(testing "it adds the message"
|
|
||||||
(is message))))))
|
|
||||||
|
|
||||||
(deftest receive-group-chats
|
|
||||||
(let [cofx {:db {:chats {"chat-id" {:contacts #{"present"}
|
|
||||||
:members-joined #{"a"}}}
|
|
||||||
:multiaccount {:public-key "a"}
|
|
||||||
:loaded-chat-id "chat-id"
|
|
||||||
:current-chat-id "chat-id"
|
|
||||||
:view-id :chat}}
|
|
||||||
cofx-without-member (update-in cofx [:db :chats "chat-id" :members-joined] disj "a")
|
|
||||||
valid-message {:chat-id "chat-id"
|
|
||||||
:from "present"
|
|
||||||
:message-type constants/message-type-private-group
|
|
||||||
:message-id "1"
|
|
||||||
:clock-value 1
|
|
||||||
:whisper-timestamp 0
|
|
||||||
:timestamp 0}
|
|
||||||
bad-chat-id-message {:chat-id "bad-chat-id"
|
|
||||||
:from "present"
|
|
||||||
:message-type constants/message-type-private-group
|
|
||||||
:message-id "1"
|
|
||||||
:clock-value 1
|
|
||||||
:whisper-timestamp 0
|
|
||||||
:timestamp 0}
|
|
||||||
bad-from-message {:chat-id "chat-id"
|
|
||||||
:from "not-present"
|
|
||||||
:message-type constants/message-type-private-group
|
|
||||||
:message-id "1"
|
|
||||||
:clock-value 1
|
|
||||||
:whisper-timestamp 0
|
|
||||||
:timestamp 0}]
|
|
||||||
(testing "a valid message"
|
|
||||||
(is (get-in (message/receive-one cofx valid-message) [:db :messages "chat-id" "1"])))
|
|
||||||
(testing "a message from someone not in the list of participants"
|
|
||||||
(is (not (message/receive-one cofx bad-from-message))))
|
|
||||||
(testing "a message with non existing chat-id"
|
|
||||||
(is (not (message/receive-one cofx bad-chat-id-message))))
|
|
||||||
(testing "a message from a delete chat"
|
|
||||||
(is (not (message/receive-one cofx-without-member valid-message))))))
|
|
||||||
|
|
||||||
(deftest receive-public-chats
|
|
||||||
(let [cofx {:db {:chats {"chat-id" {:public? true}}
|
|
||||||
:multiaccount {:public-key "a"}
|
|
||||||
:loaded-chat-id "chat-id"
|
|
||||||
:current-chat-id "chat-id"
|
|
||||||
:view-id :chat}}
|
|
||||||
valid-message {:chat-id "chat-id"
|
|
||||||
:from "anyone"
|
|
||||||
:message-type constants/message-type-public-group
|
|
||||||
:message-id "1"
|
|
||||||
:clock-value 1
|
|
||||||
:whisper-timestamp 0
|
|
||||||
:timestamp 0}
|
|
||||||
bad-chat-id-message {:chat-id "bad-chat-id"
|
|
||||||
:from "present"
|
|
||||||
:message-type constants/message-type-public-group
|
|
||||||
:message-id "1"
|
|
||||||
:clock-value 1
|
|
||||||
:whisper-timestamp 0
|
|
||||||
:timestamp 0}]
|
|
||||||
(testing "a valid message"
|
|
||||||
(is (get-in (message/receive-one cofx valid-message) [:db :messages "chat-id" "1"])))
|
|
||||||
(testing "a message with non existing chat-id"
|
|
||||||
(is (not (message/receive-one cofx bad-chat-id-message))))))
|
|
||||||
|
|
||||||
(deftest receive-one-to-one
|
|
||||||
(with-redefs [gfycat/generate-gfy (constantly "generated")
|
|
||||||
identicon/identicon (constantly "generated")]
|
|
||||||
|
|
||||||
(let [cofx {:db {:chats {"matching" {}}
|
|
||||||
:multiaccount {:public-key "me"}
|
|
||||||
:current-chat-id "matching"
|
|
||||||
:loaded-chat-id "matching"
|
|
||||||
:view-id :chat}}
|
|
||||||
valid-message {:chat-id "matching"
|
|
||||||
:from "matching"
|
|
||||||
:message-type constants/message-type-one-to-one
|
|
||||||
:message-id "1"
|
|
||||||
:clock-value 1
|
|
||||||
:whisper-timestamp 0
|
|
||||||
:timestamp 0}
|
|
||||||
own-message {:chat-id "matching"
|
|
||||||
:from "me"
|
|
||||||
:message-type constants/message-type-one-to-one
|
|
||||||
:message-id "1"
|
|
||||||
:clock-value 1
|
|
||||||
:whisper-timestamp 0
|
|
||||||
:timestamp 0}
|
|
||||||
|
|
||||||
bad-chat-id-message {:chat-id "bad-chat-id"
|
|
||||||
:from "not-matching"
|
|
||||||
:message-type constants/message-type-one-to-one
|
|
||||||
:message-id "1"
|
|
||||||
:clock-value 1
|
|
||||||
:whisper-timestamp 0
|
|
||||||
:timestamp 0}]
|
|
||||||
(testing "a valid message"
|
|
||||||
(is (get-in (message/receive-one cofx valid-message) [:db :messages "matching" "1"])))
|
|
||||||
(testing "our own message"
|
|
||||||
(is (get-in (message/receive-one cofx own-message) [:db :messages "matching" "1"])))
|
|
||||||
(testing "a message with non matching chat-id"
|
|
||||||
(is (not (get-in (message/receive-one cofx bad-chat-id-message) [:db :messages "not-matching" "1"])))))))
|
|
||||||
|
|
||||||
(deftest delete-message
|
(deftest delete-message
|
||||||
(with-redefs [time/day-relative (constantly "day-relative")
|
(with-redefs [time/day-relative (constantly "day-relative")
|
||||||
time/timestamp->time (constantly "timestamp")]
|
time/timestamp->time (constantly "timestamp")]
|
||||||
|
|
|
@ -0,0 +1,319 @@
|
||||||
|
(ns status-im.communities.core
|
||||||
|
(:require
|
||||||
|
[re-frame.core :as re-frame]
|
||||||
|
[clojure.walk :as walk]
|
||||||
|
[taoensso.timbre :as log]
|
||||||
|
[status-im.utils.fx :as fx]
|
||||||
|
[status-im.constants :as constants]
|
||||||
|
[status-im.chat.models :as models.chat]
|
||||||
|
[status-im.transport.filters.core :as models.filters]
|
||||||
|
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]
|
||||||
|
[status-im.data-store.chats :as data-store.chats]
|
||||||
|
[status-im.ethereum.json-rpc :as json-rpc]))
|
||||||
|
|
||||||
|
(def featured
|
||||||
|
[{:name "Status"
|
||||||
|
:id constants/status-community-id}])
|
||||||
|
|
||||||
|
(def access-no-membership 1)
|
||||||
|
(def access-invitation-only 2)
|
||||||
|
(def access-on-request 3)
|
||||||
|
|
||||||
|
(defn <-chats-rpc [chats]
|
||||||
|
(reduce-kv (fn [acc k v]
|
||||||
|
(assoc acc
|
||||||
|
(name k)
|
||||||
|
(-> v
|
||||||
|
(update :members walk/stringify-keys)
|
||||||
|
(assoc :identity {:display-name (get-in v [:identity :display_name])
|
||||||
|
:description (get-in v [:identity :description])}
|
||||||
|
:id (name k)))))
|
||||||
|
{}
|
||||||
|
chats))
|
||||||
|
|
||||||
|
(defn <-rpc [{:keys [description] :as c}]
|
||||||
|
(let [identity (:identity description)]
|
||||||
|
(-> c
|
||||||
|
(update-in [:description :members] walk/stringify-keys)
|
||||||
|
(assoc-in [:description :identity] {:display-name (:display_name identity)
|
||||||
|
:description (:description identity)})
|
||||||
|
(update-in [:description :chats] <-chats-rpc))))
|
||||||
|
|
||||||
|
(fx/defn handle-chats [cofx chats]
|
||||||
|
(models.chat/ensure-chats cofx chats))
|
||||||
|
|
||||||
|
(fx/defn handle-filters [cofx filters]
|
||||||
|
(models.filters/handle-filters cofx filters))
|
||||||
|
|
||||||
|
(fx/defn handle-removed-filters [cofx filters]
|
||||||
|
(models.filters/handle-filters-removed cofx (map models.filters/responses->filters filters)))
|
||||||
|
|
||||||
|
(fx/defn handle-removed-chats [{:keys [db]} chat-ids]
|
||||||
|
{:db (reduce (fn [db chat-id]
|
||||||
|
(update db :chats dissoc chat-id))
|
||||||
|
db
|
||||||
|
chat-ids)})
|
||||||
|
|
||||||
|
(fx/defn handle-community
|
||||||
|
[{:keys [db]} {:keys [id] :as community}]
|
||||||
|
{:db (assoc-in db [:communities id] (<-rpc community))})
|
||||||
|
|
||||||
|
(fx/defn handle-fetched
|
||||||
|
{:events [::fetched]}
|
||||||
|
[{:keys [db]} communities]
|
||||||
|
{:db (reduce (fn [db {:keys [id] :as community}]
|
||||||
|
(assoc-in db [:communities id] (<-rpc community)))
|
||||||
|
db
|
||||||
|
communities)})
|
||||||
|
|
||||||
|
(fx/defn handle-response [cofx response]
|
||||||
|
(fx/merge cofx
|
||||||
|
(handle-removed-chats (:removedChats response))
|
||||||
|
(handle-chats (map #(-> %
|
||||||
|
(data-store.chats/<-rpc)
|
||||||
|
(dissoc :unviewed-messages-count))
|
||||||
|
(:chats response)))
|
||||||
|
(handle-fetched (:communities response))
|
||||||
|
(handle-removed-filters (:removedFilters response))
|
||||||
|
(handle-filters (:filters response))))
|
||||||
|
|
||||||
|
(fx/defn left
|
||||||
|
{:events [::left]}
|
||||||
|
[cofx response]
|
||||||
|
(handle-response cofx response))
|
||||||
|
|
||||||
|
(fx/defn joined
|
||||||
|
{:events [::joined]}
|
||||||
|
[cofx response]
|
||||||
|
(handle-response cofx response))
|
||||||
|
|
||||||
|
(fx/defn export
|
||||||
|
[cofx community-id on-success]
|
||||||
|
{::json-rpc/call [{:method "wakuext_exportCommunity"
|
||||||
|
:params [community-id]
|
||||||
|
:on-success on-success
|
||||||
|
:on-error #(do
|
||||||
|
(log/error "failed to export community" community-id %)
|
||||||
|
(re-frame/dispatch [::failed-to-export %]))}]})
|
||||||
|
(fx/defn import-community
|
||||||
|
{:events [::import]}
|
||||||
|
[cofx community-key on-success]
|
||||||
|
{::json-rpc/call [{:method "wakuext_importCommunity"
|
||||||
|
:params [community-key]
|
||||||
|
:on-success on-success
|
||||||
|
:on-error #(do
|
||||||
|
(log/error "failed to import community" %)
|
||||||
|
(re-frame/dispatch [::failed-to-import %]))}]})
|
||||||
|
|
||||||
|
(fx/defn join
|
||||||
|
{:events [::join]}
|
||||||
|
[cofx community-id]
|
||||||
|
{::json-rpc/call [{:method "wakuext_joinCommunity"
|
||||||
|
:params [community-id]
|
||||||
|
:on-success #(re-frame/dispatch [::joined %])
|
||||||
|
:on-error #(do
|
||||||
|
(log/error "failed to join community" community-id %)
|
||||||
|
(re-frame/dispatch [::failed-to-join %]))}]})
|
||||||
|
|
||||||
|
(fx/defn leave
|
||||||
|
{:events [::leave]}
|
||||||
|
[cofx community-id]
|
||||||
|
{::json-rpc/call [{:method "wakuext_leaveCommunity"
|
||||||
|
:params [community-id]
|
||||||
|
:on-success #(re-frame/dispatch [::left %])
|
||||||
|
:on-error #(do
|
||||||
|
(log/error "failed to leave community" community-id %)
|
||||||
|
(re-frame/dispatch [::failed-to-leave %]))}]})
|
||||||
|
|
||||||
|
(fx/defn fetch [_]
|
||||||
|
{::json-rpc/call [{:method "wakuext_communities"
|
||||||
|
:params []
|
||||||
|
:on-success #(re-frame/dispatch [::fetched %])
|
||||||
|
:on-error #(do
|
||||||
|
(log/error "failed to fetch communities" %)
|
||||||
|
(re-frame/dispatch [::failed-to-fetch %]))}]})
|
||||||
|
|
||||||
|
(fx/defn chat-created
|
||||||
|
{:events [::chat-created]}
|
||||||
|
[cofx community-id user-pk]
|
||||||
|
{::json-rpc/call [{:method "wakuext_sendChatMessage"
|
||||||
|
:params [{:chatId user-pk
|
||||||
|
:text "Upgrade here to see an invitation to community"
|
||||||
|
:communityId community-id
|
||||||
|
:contentType constants/content-type-community}]
|
||||||
|
:on-success
|
||||||
|
#(re-frame/dispatch [:transport/message-sent % 1])
|
||||||
|
:on-failure #(log/error "failed to send a message" %)}]})
|
||||||
|
|
||||||
|
(fx/defn invite-user [cofx
|
||||||
|
community-id
|
||||||
|
user-pk
|
||||||
|
on-success-event
|
||||||
|
on-failure-event]
|
||||||
|
|
||||||
|
(fx/merge cofx
|
||||||
|
{::json-rpc/call [{:method "wakuext_inviteUserToCommunity"
|
||||||
|
:params [community-id
|
||||||
|
user-pk]
|
||||||
|
:on-success #(re-frame/dispatch [on-success-event %])
|
||||||
|
:on-error #(do
|
||||||
|
(log/error "failed to invite-user community" %)
|
||||||
|
(re-frame/dispatch [on-failure-event %]))}]}
|
||||||
|
(models.chat/upsert-chat {:chat-id user-pk
|
||||||
|
:active (get-in cofx [:db :chats user-pk :active])}
|
||||||
|
#(re-frame/dispatch [::chat-created community-id user-pk]))))
|
||||||
|
|
||||||
|
(fx/defn create [{:keys [db]}
|
||||||
|
community-name
|
||||||
|
community-description
|
||||||
|
community-membership
|
||||||
|
on-success-event
|
||||||
|
on-failure-event]
|
||||||
|
(let [membership (js/parseInt community-membership)
|
||||||
|
my-public-key (get-in db [:multiaccount :public-key])]
|
||||||
|
{::json-rpc/call [{:method "wakuext_createCommunity"
|
||||||
|
:params [{:identity {:display_name community-name
|
||||||
|
:description community-description}
|
||||||
|
:members {my-public-key {}}
|
||||||
|
:permissions {:access membership}}]
|
||||||
|
:on-success #(re-frame/dispatch [on-success-event %])
|
||||||
|
:on-error #(do
|
||||||
|
(log/error "failed to create community" %)
|
||||||
|
(re-frame/dispatch [on-failure-event %]))}]}))
|
||||||
|
|
||||||
|
(defn create-channel [community-id
|
||||||
|
community-channel-name
|
||||||
|
community-channel-description
|
||||||
|
on-success-event
|
||||||
|
on-failure-event]
|
||||||
|
{::json-rpc/call [{:method "wakuext_createCommunityChat"
|
||||||
|
:params [community-id
|
||||||
|
{:identity {:display_name community-channel-name
|
||||||
|
:description community-channel-description}
|
||||||
|
:permissions {:access access-no-membership}}]
|
||||||
|
:on-success #(re-frame/dispatch [on-success-event %])
|
||||||
|
:on-error #(do
|
||||||
|
(log/error "failed to create community channel" %)
|
||||||
|
(re-frame/dispatch [on-failure-event %]))}]})
|
||||||
|
|
||||||
|
(def no-membership-access 1)
|
||||||
|
(def invitation-only-access 2)
|
||||||
|
(def on-request-access 3)
|
||||||
|
|
||||||
|
(defn require-membership? [permissions]
|
||||||
|
(not= no-membership-access (:access permissions)))
|
||||||
|
|
||||||
|
(def community-id-length 68)
|
||||||
|
;; TODO: test this
|
||||||
|
(defn can-post? [{:keys [admin] :as community} pk local-chat-id]
|
||||||
|
(let [chat-id (subs local-chat-id community-id-length)
|
||||||
|
can-access-community? (or (get-in community [:description :members pk])
|
||||||
|
(not (require-membership? (get-in community [:description :permissions]))))]
|
||||||
|
(or admin
|
||||||
|
(get-in community [:description :chats chat-id :members pk])
|
||||||
|
(and can-access-community?
|
||||||
|
(not (require-membership? (get-in community [:description :chats chat-id :permissions])))))))
|
||||||
|
|
||||||
|
(fx/defn reset-community-id-input [{:keys [db]} id]
|
||||||
|
{:db (assoc db :communities/community-id-input id)})
|
||||||
|
|
||||||
|
(defn fetch-community-id-input [{:keys [db]}]
|
||||||
|
(:communities/community-id-input db))
|
||||||
|
|
||||||
|
(fx/defn import-pressed
|
||||||
|
{:events [::import-pressed]}
|
||||||
|
[cofx]
|
||||||
|
(bottom-sheet/show-bottom-sheet cofx {:view :import-community}))
|
||||||
|
|
||||||
|
(fx/defn create-pressed
|
||||||
|
{:events [::create-pressed]}
|
||||||
|
[cofx]
|
||||||
|
(bottom-sheet/show-bottom-sheet cofx {:view :create-community}))
|
||||||
|
|
||||||
|
(fx/defn invite-people-pressed
|
||||||
|
{:events [::invite-people-pressed]}
|
||||||
|
[cofx id]
|
||||||
|
(fx/merge cofx
|
||||||
|
(reset-community-id-input id)
|
||||||
|
(bottom-sheet/show-bottom-sheet {:view :invite-people-community})))
|
||||||
|
|
||||||
|
(fx/defn create-channel-pressed
|
||||||
|
{:events [::create-channel-pressed]}
|
||||||
|
[cofx id]
|
||||||
|
(fx/merge cofx
|
||||||
|
(reset-community-id-input id)
|
||||||
|
(bottom-sheet/show-bottom-sheet {:view :create-community-channel})))
|
||||||
|
|
||||||
|
(fx/defn community-created
|
||||||
|
{:events [::community-created]}
|
||||||
|
[cofx response]
|
||||||
|
(fx/merge cofx
|
||||||
|
(bottom-sheet/hide-bottom-sheet)
|
||||||
|
(handle-response response)))
|
||||||
|
|
||||||
|
(fx/defn community-imported
|
||||||
|
{:events [::community-imported]}
|
||||||
|
[cofx response]
|
||||||
|
(fx/merge cofx
|
||||||
|
(bottom-sheet/hide-bottom-sheet)
|
||||||
|
(handle-response response)))
|
||||||
|
|
||||||
|
(fx/defn people-invited
|
||||||
|
{:events [::people-invited]}
|
||||||
|
[cofx response]
|
||||||
|
(fx/merge cofx
|
||||||
|
(bottom-sheet/hide-bottom-sheet)
|
||||||
|
(handle-response response)))
|
||||||
|
|
||||||
|
(fx/defn community-channel-created
|
||||||
|
{:events [::community-channel-created]}
|
||||||
|
[cofx response]
|
||||||
|
(fx/merge cofx
|
||||||
|
(bottom-sheet/hide-bottom-sheet)
|
||||||
|
(handle-response response)))
|
||||||
|
|
||||||
|
(fx/defn handle-export-pressed
|
||||||
|
{:events [::export-pressed]}
|
||||||
|
[cofx community-id]
|
||||||
|
(export cofx community-id
|
||||||
|
#(re-frame/dispatch [:show-popover {:view :export-community
|
||||||
|
:community-key %}])))
|
||||||
|
|
||||||
|
(fx/defn import-confirmation-pressed
|
||||||
|
{:events [::import-confirmation-pressed]}
|
||||||
|
[cofx community-key]
|
||||||
|
(import-community
|
||||||
|
cofx
|
||||||
|
community-key
|
||||||
|
#(re-frame/dispatch [::community-imported %])))
|
||||||
|
|
||||||
|
(fx/defn create-confirmation-pressed
|
||||||
|
{:events [::create-confirmation-pressed]}
|
||||||
|
[cofx community-name community-description membership]
|
||||||
|
(create
|
||||||
|
cofx
|
||||||
|
community-name
|
||||||
|
community-description
|
||||||
|
membership
|
||||||
|
::community-created
|
||||||
|
::failed-to-create-community))
|
||||||
|
|
||||||
|
(fx/defn create-channel-confirmation-pressed
|
||||||
|
{:events [::create-channel-confirmation-pressed]}
|
||||||
|
[cofx community-channel-name community-channel-description]
|
||||||
|
(create-channel
|
||||||
|
(fetch-community-id-input cofx)
|
||||||
|
community-channel-name
|
||||||
|
community-channel-description
|
||||||
|
::community-channel-created
|
||||||
|
::failed-to-create-community-channel))
|
||||||
|
|
||||||
|
(fx/defn invite-people-confirmation-pressed
|
||||||
|
{:events [::invite-people-confirmation-pressed]}
|
||||||
|
[cofx user-pk]
|
||||||
|
(invite-user
|
||||||
|
cofx
|
||||||
|
(fetch-community-id-input cofx)
|
||||||
|
user-pk
|
||||||
|
::people-invited
|
||||||
|
::failed-to-invite-people))
|
|
@ -14,6 +14,7 @@
|
||||||
(def content-type-system-text 6)
|
(def content-type-system-text 6)
|
||||||
(def content-type-image 7)
|
(def content-type-image 7)
|
||||||
(def content-type-audio 8)
|
(def content-type-audio 8)
|
||||||
|
(def content-type-community 9)
|
||||||
|
|
||||||
(def emoji-reaction-love 1)
|
(def emoji-reaction-love 1)
|
||||||
(def emoji-reaction-thumbs-up 2)
|
(def emoji-reaction-thumbs-up 2)
|
||||||
|
@ -22,6 +23,13 @@
|
||||||
(def emoji-reaction-sad 5)
|
(def emoji-reaction-sad 5)
|
||||||
(def emoji-reaction-angry 6)
|
(def emoji-reaction-angry 6)
|
||||||
|
|
||||||
|
(def one-to-one-chat-type 1)
|
||||||
|
(def public-chat-type 2)
|
||||||
|
(def private-group-chat-type 3)
|
||||||
|
(def profile-chat-type 4)
|
||||||
|
(def timeline-chat-type 5)
|
||||||
|
(def community-chat-type 6)
|
||||||
|
|
||||||
(def reactions {emoji-reaction-love (:love resources/reactions)
|
(def reactions {emoji-reaction-love (:love resources/reactions)
|
||||||
emoji-reaction-thumbs-up (:thumbs-up resources/reactions)
|
emoji-reaction-thumbs-up (:thumbs-up resources/reactions)
|
||||||
emoji-reaction-thumbs-down (:thumbs-down resources/reactions)
|
emoji-reaction-thumbs-down (:thumbs-down resources/reactions)
|
||||||
|
@ -199,3 +207,5 @@
|
||||||
(def faq "https://status.im/faq/")
|
(def faq "https://status.im/faq/")
|
||||||
(def faq-keycard (str faq "#keycard"))
|
(def faq-keycard (str faq "#keycard"))
|
||||||
(def keycard-integration-link "https://status.im/keycard-integration")
|
(def keycard-integration-link "https://status.im/keycard-integration")
|
||||||
|
|
||||||
|
(def status-community-id "0x039b2da47552aa117a96ea8f1d4d108ba66637c7517a3c94a57b99dbb8a002eda2")
|
||||||
|
|
|
@ -2,41 +2,41 @@
|
||||||
(:require [clojure.set :as clojure.set]
|
(:require [clojure.set :as clojure.set]
|
||||||
[status-im.data-store.messages :as messages]
|
[status-im.data-store.messages :as messages]
|
||||||
[status-im.ethereum.json-rpc :as json-rpc]
|
[status-im.ethereum.json-rpc :as json-rpc]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[status-im.utils.fx :as fx]
|
[status-im.utils.fx :as fx]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
(def one-to-one-chat-type 1)
|
(defn type->rpc [{:keys [chat-type public? group-chat profile-public-key timeline?] :as chat}]
|
||||||
(def public-chat-type 2)
|
(if chat-type
|
||||||
(def private-group-chat-type 3)
|
(assoc chat :chatType chat-type)
|
||||||
(def profile-chat-type 4)
|
|
||||||
(def timeline-chat-type 5)
|
|
||||||
|
|
||||||
(defn type->rpc [{:keys [public? group-chat profile-public-key timeline?] :as chat}]
|
|
||||||
(assoc chat :chatType (cond
|
(assoc chat :chatType (cond
|
||||||
profile-public-key profile-chat-type
|
profile-public-key constants/profile-chat-type
|
||||||
timeline? timeline-chat-type
|
timeline? constants/timeline-chat-type
|
||||||
public? public-chat-type
|
public? constants/public-chat-type
|
||||||
group-chat private-group-chat-type
|
group-chat constants/private-group-chat-type
|
||||||
:else one-to-one-chat-type)))
|
:else constants/one-to-one-chat-type))))
|
||||||
|
|
||||||
(defn rpc->type [{:keys [chatType name] :as chat}]
|
(defn rpc->type [{:keys [chatType name] :as chat}]
|
||||||
(cond
|
(cond
|
||||||
(or (= public-chat-type chatType)
|
(or (= constants/public-chat-type chatType)
|
||||||
(= profile-chat-type chatType)
|
(= constants/profile-chat-type chatType)
|
||||||
(= timeline-chat-type chatType)) (assoc chat
|
(= constants/timeline-chat-type chatType)) (assoc chat
|
||||||
:chat-name (str "#" name)
|
:chat-name (str "#" name)
|
||||||
:public? true
|
:public? true
|
||||||
:group-chat true
|
:group-chat true
|
||||||
:timeline? (= timeline-chat-type chatType))
|
:timeline? (= constants/timeline-chat-type chatType))
|
||||||
(= private-group-chat-type chatType) (assoc chat
|
(= constants/community-chat-type chatType) (assoc chat
|
||||||
|
:chat-name name
|
||||||
|
:group-chat true)
|
||||||
|
(= constants/private-group-chat-type chatType) (assoc chat
|
||||||
:chat-name name
|
:chat-name name
|
||||||
:public? false
|
:public? false
|
||||||
:group-chat true)
|
:group-chat true)
|
||||||
:else (assoc chat :public? false :group-chat false)))
|
:else (assoc chat :public? false :group-chat false)))
|
||||||
|
|
||||||
(defn- marshal-members [{:keys [admins contacts members-joined chatType] :as chat}]
|
(defn- marshal-members [{:keys [admins contacts members-joined chat-type] :as chat}]
|
||||||
(cond-> chat
|
(cond-> chat
|
||||||
(= chatType private-group-chat-type)
|
(= chat-type constants/private-group-chat-type)
|
||||||
(assoc :members (map #(hash-map :id %
|
(assoc :members (map #(hash-map :id %
|
||||||
:admin (boolean (admins %))
|
:admin (boolean (admins %))
|
||||||
:joined (boolean (members-joined %))) contacts))
|
:joined (boolean (members-joined %))) contacts))
|
||||||
|
@ -45,11 +45,11 @@
|
||||||
|
|
||||||
(defn- unmarshal-members [{:keys [members chatType] :as chat}]
|
(defn- unmarshal-members [{:keys [members chatType] :as chat}]
|
||||||
(cond
|
(cond
|
||||||
(= public-chat-type chatType) (assoc chat
|
(= constants/public-chat-type chatType) (assoc chat
|
||||||
:contacts #{}
|
:contacts #{}
|
||||||
:admins #{}
|
:admins #{}
|
||||||
:members-joined #{})
|
:members-joined #{})
|
||||||
(= private-group-chat-type chatType) (merge chat
|
(= constants/private-group-chat-type chatType) (merge chat
|
||||||
(reduce (fn [acc member]
|
(reduce (fn [acc member]
|
||||||
(cond-> acc
|
(cond-> acc
|
||||||
(:admin member)
|
(:admin member)
|
||||||
|
@ -70,20 +70,21 @@
|
||||||
|
|
||||||
(defn- ->rpc [chat]
|
(defn- ->rpc [chat]
|
||||||
(-> chat
|
(-> chat
|
||||||
type->rpc
|
|
||||||
marshal-members
|
marshal-members
|
||||||
(update :last-message messages/->rpc)
|
(update :last-message messages/->rpc)
|
||||||
|
type->rpc
|
||||||
(clojure.set/rename-keys {:chat-id :id
|
(clojure.set/rename-keys {:chat-id :id
|
||||||
:membership-update-events :membershipUpdateEvents
|
:membership-update-events :membershipUpdateEvents
|
||||||
:unviewed-messages-count :unviewedMessagesCount
|
:unviewed-messages-count :unviewedMessagesCount
|
||||||
:last-message :lastMessage
|
:last-message :lastMessage
|
||||||
|
:community-id :communityId
|
||||||
:deleted-at-clock-value :deletedAtClockValue
|
:deleted-at-clock-value :deletedAtClockValue
|
||||||
:is-active :active
|
:is-active :active
|
||||||
:last-clock-value :lastClockValue
|
:last-clock-value :lastClockValue
|
||||||
:profile-public-key :profile})
|
:profile-public-key :profile})
|
||||||
(dissoc :public? :group-chat :messages
|
(dissoc :public? :group-chat :messages
|
||||||
:might-have-join-time-messages?
|
:might-have-join-time-messages?
|
||||||
:loaded-unviewed-messages-ids
|
:loaded-unviewed-messages-ids :chat-type
|
||||||
:contacts :admins :members-joined)))
|
:contacts :admins :members-joined)))
|
||||||
|
|
||||||
(defn <-rpc [chat]
|
(defn <-rpc [chat]
|
||||||
|
@ -91,8 +92,10 @@
|
||||||
rpc->type
|
rpc->type
|
||||||
unmarshal-members
|
unmarshal-members
|
||||||
(clojure.set/rename-keys {:id :chat-id
|
(clojure.set/rename-keys {:id :chat-id
|
||||||
|
:communityId :community-id
|
||||||
:membershipUpdateEvents :membership-update-events
|
:membershipUpdateEvents :membership-update-events
|
||||||
:deletedAtClockValue :deleted-at-clock-value
|
:deletedAtClockValue :deleted-at-clock-value
|
||||||
|
:chatType :chat-type
|
||||||
:unviewedMessagesCount :unviewed-messages-count
|
:unviewedMessagesCount :unviewed-messages-count
|
||||||
:lastMessage :last-message
|
:lastMessage :last-message
|
||||||
:active :is-active
|
:active :is-active
|
||||||
|
@ -100,7 +103,7 @@
|
||||||
:invitationAdmin :invitation-admin
|
:invitationAdmin :invitation-admin
|
||||||
:profile :profile-public-key})
|
:profile :profile-public-key})
|
||||||
(update :last-message #(when % (messages/<-rpc %)))
|
(update :last-message #(when % (messages/<-rpc %)))
|
||||||
(dissoc :chatType :members)))
|
(dissoc :members)))
|
||||||
|
|
||||||
(fx/defn save-chat [cofx {:keys [chat-id] :as chat} on-success]
|
(fx/defn save-chat [cofx {:keys [chat-id] :as chat} on-success]
|
||||||
{::json-rpc/call [{:method (json-rpc/call-ext-method "saveChat")
|
{::json-rpc/call [{:method (json-rpc/call-ext-method "saveChat")
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
:color "color"
|
:color "color"
|
||||||
:contacts #{"a" "b" "c" "d"}
|
:contacts #{"a" "b" "c" "d"}
|
||||||
:last-clock-value 10
|
:last-clock-value 10
|
||||||
|
:chat-type 3
|
||||||
:admins #{"a" "b"}
|
:admins #{"a" "b"}
|
||||||
:members-joined #{"a" "c"}
|
:members-joined #{"a" "c"}
|
||||||
:name "name"
|
:name "name"
|
||||||
|
@ -70,6 +71,7 @@
|
||||||
:color "color"
|
:color "color"
|
||||||
:chat-name "name"
|
:chat-name "name"
|
||||||
:contacts #{"a" "b" "c" "d"}
|
:contacts #{"a" "b" "c" "d"}
|
||||||
|
:chat-type 3
|
||||||
:last-clock-value 10
|
:last-clock-value 10
|
||||||
:last-message nil
|
:last-message nil
|
||||||
:admins #{"a" "b"}
|
:admins #{"a" "b"}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
:sticker (:sticker content))
|
:sticker (:sticker content))
|
||||||
:always
|
:always
|
||||||
(clojure.set/rename-keys {:chat-id :chatId
|
(clojure.set/rename-keys {:chat-id :chatId
|
||||||
|
:community-id :communityId
|
||||||
:clock-value :clock})))
|
:clock-value :clock})))
|
||||||
|
|
||||||
(defn <-rpc [message]
|
(defn <-rpc [message]
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
:commandParameters :command-parameters
|
:commandParameters :command-parameters
|
||||||
:messageType :message-type
|
:messageType :message-type
|
||||||
:localChatId :chat-id
|
:localChatId :chat-id
|
||||||
|
:communityId :community-id
|
||||||
:contentType :content-type
|
:contentType :content-type
|
||||||
:clock :clock-value
|
:clock :clock-value
|
||||||
:quotedMessage :quoted-message
|
:quotedMessage :quoted-message
|
||||||
|
@ -27,7 +29,7 @@
|
||||||
:audioDurationMs :audio-duration-ms
|
:audioDurationMs :audio-duration-ms
|
||||||
:new :new?})
|
:new :new?})
|
||||||
|
|
||||||
(update :quoted-message clojure.set/rename-keys {:parsedText :parsed-text})
|
(update :quoted-message clojure.set/rename-keys {:parsedText :parsed-text :communityId :community-id})
|
||||||
(update :outgoing-status keyword)
|
(update :outgoing-status keyword)
|
||||||
(update :command-parameters clojure.set/rename-keys {:transactionHash :transaction-hash
|
(update :command-parameters clojure.set/rename-keys {:transactionHash :transaction-hash
|
||||||
:commandState :command-state})
|
:commandState :command-state})
|
||||||
|
|
|
@ -115,6 +115,14 @@
|
||||||
"multiaccounts_getIdentityImage" {}
|
"multiaccounts_getIdentityImage" {}
|
||||||
"multiaccounts_storeIdentityImage" {}
|
"multiaccounts_storeIdentityImage" {}
|
||||||
"multiaccounts_deleteIdentityImage" {}
|
"multiaccounts_deleteIdentityImage" {}
|
||||||
|
"wakuext_createCommunity" {}
|
||||||
|
"wakuext_createCommunityChat" {}
|
||||||
|
"wakuext_inviteUserToCommunity" {}
|
||||||
|
"wakuext_joinCommunity" {}
|
||||||
|
"wakuext_leaveCommunity" {}
|
||||||
|
"wakuext_communities" {}
|
||||||
|
"wakuext_importCommunity" {}
|
||||||
|
"wakuext_exportCommunity" {}
|
||||||
"status_chats" {}
|
"status_chats" {}
|
||||||
"localnotifications_switchWalletNotifications" {}
|
"localnotifications_switchWalletNotifications" {}
|
||||||
"localnotifications_notificationPreferences" {}
|
"localnotifications_notificationPreferences" {}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
(defn button [label accessibility-label handler]
|
(defn button [label accessibility-label handler]
|
||||||
[react/view
|
[react/view
|
||||||
{:style {:width 50
|
{:style {:width 50
|
||||||
:height 40
|
:height 30
|
||||||
:justify-content :center
|
:justify-content :center
|
||||||
:align-items :center}}
|
:align-items :center}}
|
||||||
[react/text
|
[react/text
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
(defn test-menu []
|
(defn test-menu []
|
||||||
[react/view
|
[react/view
|
||||||
{:style {:position :absolute
|
{:style {:position :absolute
|
||||||
:top 100
|
:top 70
|
||||||
:right 0
|
:right 0
|
||||||
:width 50
|
:width 50
|
||||||
:justify-content :center
|
:justify-content :center
|
||||||
|
|
|
@ -96,7 +96,7 @@
|
||||||
(fx/defn update-many [cofx mailserver-topics]
|
(fx/defn update-many [cofx mailserver-topics]
|
||||||
(apply fx/merge cofx (map (partial update-topic true) mailserver-topics)))
|
(apply fx/merge cofx (map (partial update-topic true) mailserver-topics)))
|
||||||
|
|
||||||
(fx/defn delete [{:keys [db] :as cofx} {:keys [chat-id filter-id]}]
|
(fx/defn delete [{:keys [db] :as cofx} {:keys [filter-id]}]
|
||||||
(when-let [matching-topics (filter (fn [{:keys [filter-ids] :as topic}]
|
(when-let [matching-topics (filter (fn [{:keys [filter-ids] :as topic}]
|
||||||
(if (not filter-ids)
|
(if (not filter-ids)
|
||||||
(do (log/warn "topic not initialized, removing" topic)
|
(do (log/warn "topic not initialized, removing" topic)
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
[status-im.native-module.core :as status]
|
[status-im.native-module.core :as status]
|
||||||
[status-im.notifications.core :as notifications]
|
[status-im.notifications.core :as notifications]
|
||||||
[status-im.popover.core :as popover]
|
[status-im.popover.core :as popover]
|
||||||
|
[status-im.communities.core :as communities]
|
||||||
[status-im.protocol.core :as protocol]
|
[status-im.protocol.core :as protocol]
|
||||||
[status-im.stickers.core :as stickers]
|
[status-im.stickers.core :as stickers]
|
||||||
[status-im.ui.screens.mobile-network-settings.events :as mobile-network]
|
[status-im.ui.screens.mobile-network-settings.events :as mobile-network]
|
||||||
|
@ -221,6 +222,7 @@
|
||||||
(protocol/initialize-protocol {:default-mailserver true})
|
(protocol/initialize-protocol {:default-mailserver true})
|
||||||
(check-network-version network-id)
|
(check-network-version network-id)
|
||||||
(chat.loading/initialize-chats)
|
(chat.loading/initialize-chats)
|
||||||
|
(communities/fetch)
|
||||||
(contact/initialize-contacts)
|
(contact/initialize-contacts)
|
||||||
(stickers/init-stickers-packs)
|
(stickers/init-stickers-packs)
|
||||||
(mobile-network/on-network-status-change)
|
(mobile-network/on-network-status-change)
|
||||||
|
@ -293,6 +295,8 @@
|
||||||
:mailserver-ranges {}
|
:mailserver-ranges {}
|
||||||
:mailserver-topics {}
|
:mailserver-topics {}
|
||||||
:default-mailserver true})
|
:default-mailserver true})
|
||||||
|
|
||||||
|
(communities/fetch)
|
||||||
(multiaccounts/switch-preview-privacy-mode-flag)
|
(multiaccounts/switch-preview-privacy-mode-flag)
|
||||||
(link-preview/request-link-preview-whitelist)
|
(link-preview/request-link-preview-whitelist)
|
||||||
(logging/set-log-level (:log-level multiaccount)))))
|
(logging/set-log-level (:log-level multiaccount)))))
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
[status-im.ethereum.transactions.core :as transactions]
|
[status-im.ethereum.transactions.core :as transactions]
|
||||||
[status-im.fleet.core :as fleet]
|
[status-im.fleet.core :as fleet]
|
||||||
[status-im.group-chats.db :as group-chats.db]
|
[status-im.group-chats.db :as group-chats.db]
|
||||||
|
[status-im.communities.core :as communities]
|
||||||
[status-im.group-chats.core :as group-chat]
|
[status-im.group-chats.core :as group-chat]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.multiaccounts.core :as multiaccounts]
|
[status-im.multiaccounts.core :as multiaccounts]
|
||||||
|
@ -217,8 +218,58 @@
|
||||||
(reg-root-key-sub :push-notifications/preferences :push-notifications/preferences)
|
(reg-root-key-sub :push-notifications/preferences :push-notifications/preferences)
|
||||||
|
|
||||||
(reg-root-key-sub :acquisition :acquisition)
|
(reg-root-key-sub :acquisition :acquisition)
|
||||||
|
|
||||||
|
;; communities
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:communities
|
||||||
|
(fn [db]
|
||||||
|
(cond
|
||||||
|
config/communities-management-enabled?
|
||||||
|
(:communities db)
|
||||||
|
config/communities-enabled?
|
||||||
|
;; If no management enabled, only return status-community
|
||||||
|
(select-keys (:communities db) [constants/status-community-id])
|
||||||
|
:else
|
||||||
|
[])))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:communities/community
|
||||||
|
:<- [:communities]
|
||||||
|
(fn [communities [_ id]]
|
||||||
|
(get communities id)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:communities/status-community
|
||||||
|
:<- [:search/home-filter]
|
||||||
|
:<- [:communities]
|
||||||
|
(fn [[search-filter communities]]
|
||||||
|
(let [status-community (get communities constants/status-community-id)]
|
||||||
|
(when (and (:joined status-community)
|
||||||
|
(or (string/blank? search-filter)
|
||||||
|
(string/includes? (string/lower-case
|
||||||
|
(get-in status-community [:description :identity :display-name])) search-filter)))
|
||||||
|
status-community))))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:communities/current-community
|
||||||
|
:<- [:communities]
|
||||||
|
:<- [:chats/current-raw-chat]
|
||||||
|
(fn [[communities {:keys [community-id]}]]
|
||||||
|
(get communities community-id)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:communities/unviewed-count
|
||||||
|
(fn [[_ community-id]]
|
||||||
|
[(re-frame/subscribe [:chats/by-community-id community-id])])
|
||||||
|
(fn [[chats]]
|
||||||
|
(reduce (fn [acc {:keys [unviewed-messages-count]}]
|
||||||
|
(+ acc (or unviewed-messages-count 0)))
|
||||||
|
0
|
||||||
|
chats)))
|
||||||
|
|
||||||
;;GENERAL ==============================================================================================================
|
;;GENERAL ==============================================================================================================
|
||||||
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:multiaccount/logged-in?
|
:multiaccount/logged-in?
|
||||||
(fn [db]
|
(fn [db]
|
||||||
|
@ -616,6 +667,16 @@
|
||||||
(fn [chats [_ chat-id]]
|
(fn [chats [_ chat-id]]
|
||||||
(get chats chat-id)))
|
(get chats chat-id)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:chats/by-community-id
|
||||||
|
:<- [:chats/active-chats]
|
||||||
|
(fn [chats [_ community-id]]
|
||||||
|
(->> chats
|
||||||
|
(keep (fn [[_ chat]]
|
||||||
|
(when (= (:community-id chat) community-id)
|
||||||
|
chat)))
|
||||||
|
(sort-by :timestamp >))))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:chats/current-chat-ui-props
|
:chats/current-chat-ui-props
|
||||||
:<- [::chat-ui-props]
|
:<- [::chat-ui-props]
|
||||||
|
@ -678,8 +739,11 @@
|
||||||
:<- [:chats/current-raw-chat]
|
:<- [:chats/current-raw-chat]
|
||||||
:<- [:multiaccount/public-key]
|
:<- [:multiaccount/public-key]
|
||||||
:<- [:inactive-chat-id]
|
:<- [:inactive-chat-id]
|
||||||
|
:<- [:communities/current-community]
|
||||||
(fn [[{:keys [group-chat] :as current-chat}
|
(fn [[{:keys [group-chat] :as current-chat}
|
||||||
my-public-key inactive-chat-id]]
|
my-public-key
|
||||||
|
inactive-chat-id
|
||||||
|
community]]
|
||||||
(when (and current-chat (= (:chat-id current-chat) inactive-chat-id))
|
(when (and current-chat (= (:chat-id current-chat) inactive-chat-id))
|
||||||
(cond-> current-chat
|
(cond-> current-chat
|
||||||
(chat.models/public-chat? current-chat)
|
(chat.models/public-chat? current-chat)
|
||||||
|
@ -690,6 +754,10 @@
|
||||||
(assoc :show-input? true
|
(assoc :show-input? true
|
||||||
:joined? true)
|
:joined? 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)
|
(not group-chat)
|
||||||
(assoc :show-input? true)))))
|
(assoc :show-input? true)))))
|
||||||
|
|
||||||
|
@ -698,7 +766,14 @@
|
||||||
:<- [:chats/current-raw-chat]
|
:<- [:chats/current-raw-chat]
|
||||||
(fn [current-chat]
|
(fn [current-chat]
|
||||||
(select-keys current-chat
|
(select-keys current-chat
|
||||||
[:public? :group-chat :chat-id :chat-name :color :invitation-admin])))
|
[:community-id
|
||||||
|
:public?
|
||||||
|
:group-chat
|
||||||
|
:chat-type
|
||||||
|
:chat-id
|
||||||
|
:chat-name
|
||||||
|
:color
|
||||||
|
:invitation-admin])))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:current-chat/one-to-one-chat?
|
:current-chat/one-to-one-chat?
|
||||||
|
@ -2011,7 +2086,10 @@
|
||||||
(vals chats))
|
(vals chats))
|
||||||
(vals chats))]
|
(vals chats))]
|
||||||
|
|
||||||
(sort-by :timestamp > filtered-chats))))
|
(sort-by :timestamp > (filter (fn [{:keys [community-id]}]
|
||||||
|
;; Ignore communities
|
||||||
|
(not community-id))
|
||||||
|
filtered-chats)))))
|
||||||
|
|
||||||
(defn extract-currency-attributes [currency]
|
(defn extract-currency-attributes [currency]
|
||||||
(let [{:keys [code display-name]} (val currency)]
|
(let [{:keys [code display-name]} (val currency)]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
"This namespace is used to handle filters loading and unloading from statusgo"
|
"This namespace is used to handle filters loading and unloading from statusgo"
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[status-im.contact.db :as contact.db]
|
[status-im.contact.db :as contact.db]
|
||||||
[status-im.ethereum.json-rpc :as json-rpc]
|
[status-im.ethereum.json-rpc :as json-rpc]
|
||||||
[status-im.mailserver.core :as mailserver]
|
[status-im.mailserver.core :as mailserver]
|
||||||
|
@ -65,10 +66,8 @@
|
||||||
(fx/defn upsert-group-chat-topics
|
(fx/defn upsert-group-chat-topics
|
||||||
"Update topics for each member of the group chat"
|
"Update topics for each member of the group chat"
|
||||||
[{:keys [db] :as cofx}]
|
[{:keys [db] :as cofx}]
|
||||||
(let [group-chats (filter (fn [{:keys [group-chat
|
(let [group-chats (filter (fn [{:keys [chat-type]}]
|
||||||
public?]}]
|
(= chat-type constants/private-group-chat-type))
|
||||||
(and group-chat
|
|
||||||
(not public?)))
|
|
||||||
(vals (:chats db)))]
|
(vals (:chats db)))]
|
||||||
(apply fx/merge
|
(apply fx/merge
|
||||||
cofx
|
cofx
|
||||||
|
@ -195,7 +194,7 @@
|
||||||
|
|
||||||
;; shh filters
|
;; shh filters
|
||||||
|
|
||||||
(defn- responses->filters [{:keys [negotiated
|
(defn responses->filters [{:keys [negotiated
|
||||||
discovery
|
discovery
|
||||||
filterId
|
filterId
|
||||||
chatId
|
chatId
|
||||||
|
@ -232,6 +231,9 @@
|
||||||
(mailserver/process-next-messages-request))
|
(mailserver/process-next-messages-request))
|
||||||
(set-filters-initialized)))
|
(set-filters-initialized)))
|
||||||
|
|
||||||
|
(fx/defn handle-filters [cofx filters]
|
||||||
|
(handle-filters-added cofx (map responses->filters filters)))
|
||||||
|
|
||||||
(fx/defn handle-filters-removed
|
(fx/defn handle-filters-removed
|
||||||
"Called when we remove a filter from status-go, it will update the mailserver
|
"Called when we remove a filter from status-go, it will update the mailserver
|
||||||
topics"
|
topics"
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
[status-im.chat.models :as models.chat]
|
[status-im.chat.models :as models.chat]
|
||||||
[status-im.chat.models.reactions :as models.reactions]
|
[status-im.chat.models.reactions :as models.reactions]
|
||||||
[status-im.contact.core :as models.contact]
|
[status-im.contact.core :as models.contact]
|
||||||
|
[status-im.communities.core :as models.communities]
|
||||||
[status-im.pairing.core :as models.pairing]
|
[status-im.pairing.core :as models.pairing]
|
||||||
|
[status-im.transport.filters.core :as models.filters]
|
||||||
[status-im.data-store.messages :as data-store.messages]
|
[status-im.data-store.messages :as data-store.messages]
|
||||||
[status-im.data-store.reactions :as data-store.reactions]
|
[status-im.data-store.reactions :as data-store.reactions]
|
||||||
[status-im.data-store.contacts :as data-store.contacts]
|
[status-im.data-store.contacts :as data-store.contacts]
|
||||||
|
@ -23,20 +25,32 @@
|
||||||
(fx/defn handle-message [cofx message]
|
(fx/defn handle-message [cofx message]
|
||||||
(models.message/receive-one cofx message))
|
(models.message/receive-one cofx message))
|
||||||
|
|
||||||
|
(fx/defn handle-community [cofx community]
|
||||||
|
(models.communities/handle-community cofx community))
|
||||||
|
|
||||||
(fx/defn handle-reactions [cofx reactions]
|
(fx/defn handle-reactions [cofx reactions]
|
||||||
(models.reactions/receive-signal cofx reactions))
|
(models.reactions/receive-signal cofx reactions))
|
||||||
|
|
||||||
(fx/defn handle-invitations [cofx invitations]
|
(fx/defn handle-invitations [cofx invitations]
|
||||||
(models.group/handle-invitations cofx invitations))
|
(models.group/handle-invitations cofx invitations))
|
||||||
|
|
||||||
|
(fx/defn handle-filters [cofx filters]
|
||||||
|
(models.filters/handle-filters cofx filters))
|
||||||
|
|
||||||
|
(fx/defn handle-filters-removed [cofx filters]
|
||||||
|
(models.filters/handle-filters-removed cofx filters))
|
||||||
|
|
||||||
(fx/defn process-response
|
(fx/defn process-response
|
||||||
{:events [::process]}
|
{:events [::process]}
|
||||||
[cofx ^js response-js]
|
[cofx ^js response-js]
|
||||||
(let [^js chats (.-chats response-js)
|
(let [^js communities (.-communities response-js)
|
||||||
|
^js chats (.-chats response-js)
|
||||||
^js contacts (.-contacts response-js)
|
^js contacts (.-contacts response-js)
|
||||||
^js installations (.-installations response-js)
|
^js installations (.-installations response-js)
|
||||||
^js messages (.-messages response-js)
|
^js messages (.-messages response-js)
|
||||||
^js emoji-reactions (.-emojiReactions response-js)
|
^js emoji-reactions (.-emojiReactions response-js)
|
||||||
|
^js filters (.-filters response-js)
|
||||||
|
^js removed-filters (.-removedFilters response-js)
|
||||||
^js invitations (.-invitations response-js)]
|
^js invitations (.-invitations response-js)]
|
||||||
(cond
|
(cond
|
||||||
(seq installations)
|
(seq installations)
|
||||||
|
@ -53,6 +67,11 @@
|
||||||
{:utils/dispatch-later [{:ms 20 :dispatch [::process response-js]}]}
|
{:utils/dispatch-later [{:ms 20 :dispatch [::process response-js]}]}
|
||||||
(handle-contacts (map data-store.contacts/<-rpc contacts-clj))))
|
(handle-contacts (map data-store.contacts/<-rpc contacts-clj))))
|
||||||
|
|
||||||
|
(seq communities)
|
||||||
|
(let [community (.pop communities)]
|
||||||
|
(fx/merge cofx
|
||||||
|
{:utils/dispatch-later [{:ms 20 :dispatch [::process response-js]}]}
|
||||||
|
(handle-community (types/js->clj community))))
|
||||||
(seq chats)
|
(seq chats)
|
||||||
(let [chats-clj (types/js->clj chats)]
|
(let [chats-clj (types/js->clj chats)]
|
||||||
(js-delete response-js "chats")
|
(js-delete response-js "chats")
|
||||||
|
@ -81,7 +100,20 @@
|
||||||
(js-delete response-js "invitations")
|
(js-delete response-js "invitations")
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
{:utils/dispatch-later [{:ms 20 :dispatch [::process response-js]}]}
|
{:utils/dispatch-later [{:ms 20 :dispatch [::process response-js]}]}
|
||||||
(handle-invitations (map data-store.invitations/<-rpc invitations)))))))
|
(handle-invitations (map data-store.invitations/<-rpc invitations))))
|
||||||
|
(seq filters)
|
||||||
|
(let [filters (types/js->clj filters)]
|
||||||
|
(js-delete response-js "filters")
|
||||||
|
(fx/merge cofx
|
||||||
|
{:utils/dispatch-later [{:ms 20 :dispatch [::process response-js]}]}
|
||||||
|
(handle-filters filters)))
|
||||||
|
|
||||||
|
(seq removed-filters)
|
||||||
|
(let [removed-filters (types/js->clj removed-filters)]
|
||||||
|
(js-delete response-js "removedFilters")
|
||||||
|
(fx/merge cofx
|
||||||
|
{:utils/dispatch-later [{:ms 20 :dispatch [::process response-js]}]}
|
||||||
|
(handle-filters-removed filters))))))
|
||||||
|
|
||||||
(fx/defn remove-hash
|
(fx/defn remove-hash
|
||||||
[{:keys [db] :as cofx} envelope-hash]
|
[{:keys [db] :as cofx} envelope-hash]
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
text
|
text
|
||||||
response-to
|
response-to
|
||||||
ens-name
|
ens-name
|
||||||
|
community-id
|
||||||
image-path
|
image-path
|
||||||
audio-path
|
audio-path
|
||||||
audio-duration-ms
|
audio-duration-ms
|
||||||
|
@ -21,6 +22,7 @@
|
||||||
:imagePath image-path
|
:imagePath image-path
|
||||||
:audioPath audio-path
|
:audioPath audio-path
|
||||||
:audioDurationMs audio-duration-ms
|
:audioDurationMs audio-duration-ms
|
||||||
|
:communityId community-id
|
||||||
:sticker sticker
|
:sticker sticker
|
||||||
:contentType content-type})
|
:contentType content-type})
|
||||||
|
|
||||||
|
|
|
@ -24,13 +24,6 @@
|
||||||
(second name)
|
(second name)
|
||||||
(first name)))]]))
|
(first name)))]]))
|
||||||
|
|
||||||
(defn dapp-badge [{:keys [online-view-wrapper online-view online-dot-left online-dot-right]}]
|
|
||||||
[react/view online-view-wrapper
|
|
||||||
[react/view online-view
|
|
||||||
[react/view
|
|
||||||
[react/view online-dot-left]
|
|
||||||
[react/view online-dot-right]]]])
|
|
||||||
|
|
||||||
(defn chat-icon-view
|
(defn chat-icon-view
|
||||||
[chat-id group-chat name styles]
|
[chat-id group-chat name styles]
|
||||||
[react/view (:container styles)
|
[react/view (:container styles)
|
||||||
|
@ -43,10 +36,6 @@
|
||||||
[chat-id group-chat name color]
|
[chat-id group-chat name color]
|
||||||
[chat-icon-view chat-id group-chat name
|
[chat-icon-view chat-id group-chat name
|
||||||
{:container styles/container-chat-toolbar
|
{:container styles/container-chat-toolbar
|
||||||
:online-view-wrapper styles/online-view-wrapper
|
|
||||||
:online-view styles/online-view
|
|
||||||
:online-dot-left styles/online-dot-left
|
|
||||||
:online-dot-right styles/online-dot-right
|
|
||||||
:size 36
|
:size 36
|
||||||
:chat-icon styles/chat-icon-chat-toolbar
|
:chat-icon styles/chat-icon-chat-toolbar
|
||||||
:default-chat-icon (styles/default-chat-icon-chat-toolbar color)
|
:default-chat-icon (styles/default-chat-icon-chat-toolbar color)
|
||||||
|
@ -56,10 +45,6 @@
|
||||||
[chat-id group-chat name color]
|
[chat-id group-chat name color]
|
||||||
[chat-icon-view chat-id group-chat name
|
[chat-icon-view chat-id group-chat name
|
||||||
{:container styles/container-chat-list
|
{:container styles/container-chat-list
|
||||||
:online-view-wrapper styles/online-view-wrapper
|
|
||||||
:online-view styles/online-view
|
|
||||||
:online-dot-left styles/online-dot-left
|
|
||||||
:online-dot-right styles/online-dot-right
|
|
||||||
:size 40
|
:size 40
|
||||||
:chat-icon styles/chat-icon-chat-list
|
:chat-icon styles/chat-icon-chat-list
|
||||||
:default-chat-icon (styles/default-chat-icon-chat-list color)
|
:default-chat-icon (styles/default-chat-icon-chat-list color)
|
||||||
|
@ -69,10 +54,6 @@
|
||||||
[chat-id group-chat name color]
|
[chat-id group-chat name color]
|
||||||
[chat-icon-view chat-id group-chat name
|
[chat-icon-view chat-id group-chat name
|
||||||
{:container styles/container-chat-list
|
{:container styles/container-chat-list
|
||||||
:online-view-wrapper styles/online-view-wrapper
|
|
||||||
:online-view styles/online-view
|
|
||||||
:online-dot-left styles/online-dot-left
|
|
||||||
:online-dot-right styles/online-dot-right
|
|
||||||
:size 40
|
:size 40
|
||||||
:chat-icon styles/chat-icon-chat-list
|
:chat-icon styles/chat-icon-chat-list
|
||||||
:default-chat-icon (styles/default-chat-icon-chat-list color)
|
:default-chat-icon (styles/default-chat-icon-chat-list color)
|
||||||
|
@ -85,13 +66,9 @@
|
||||||
:default-chat-icon-text (styles/default-chat-icon-text (or size 40))}]])
|
:default-chat-icon-text (styles/default-chat-icon-text (or size 40))}]])
|
||||||
|
|
||||||
(defn contact-icon-view
|
(defn contact-icon-view
|
||||||
[{:keys [name dapp?] :as contact} {:keys [container] :as styles}]
|
[contact {:keys [container] :as styles}]
|
||||||
[react/view container
|
[react/view container
|
||||||
(if dapp?
|
[photos/photo (multiaccounts/displayed-photo contact) styles]])
|
||||||
[default-chat-icon name styles]
|
|
||||||
[photos/photo (multiaccounts/displayed-photo contact) styles])
|
|
||||||
(when dapp?
|
|
||||||
[dapp-badge styles])])
|
|
||||||
|
|
||||||
(defn contact-icon-contacts-tab [photo-path]
|
(defn contact-icon-contacts-tab [photo-path]
|
||||||
[react/view styles/container-chat-list
|
[react/view styles/container-chat-list
|
||||||
|
@ -100,10 +77,6 @@
|
||||||
(defn dapp-icon-permission [contact size]
|
(defn dapp-icon-permission [contact size]
|
||||||
[contact-icon-view contact
|
[contact-icon-view contact
|
||||||
{:container {:width size :height size}
|
{:container {:width size :height size}
|
||||||
:online-view-wrapper styles/online-view-wrapper
|
|
||||||
:online-view styles/online-view
|
|
||||||
:online-dot-left styles/online-dot-left
|
|
||||||
:online-dot-right styles/online-dot-right
|
|
||||||
:size size
|
:size size
|
||||||
:chat-icon (styles/custom-size-icon size)
|
:chat-icon (styles/custom-size-icon size)
|
||||||
:default-chat-icon (styles/default-chat-icon-profile colors/default-chat-color size)
|
:default-chat-icon (styles/default-chat-icon-profile colors/default-chat-color size)
|
||||||
|
@ -118,9 +91,6 @@
|
||||||
|
|
||||||
(defn profile-icon-view [photo-path name color edit? size override-styles]
|
(defn profile-icon-view [photo-path name color edit? size override-styles]
|
||||||
(let [styles (merge {:container {:width size :height size}
|
(let [styles (merge {:container {:width size :height size}
|
||||||
:online-view styles/online-view-profile
|
|
||||||
:online-dot-left styles/online-dot-left-profile
|
|
||||||
:online-dot-right styles/online-dot-right-profile
|
|
||||||
:size size
|
:size size
|
||||||
:chat-icon styles/chat-icon-profile
|
:chat-icon styles/chat-icon-profile
|
||||||
:default-chat-icon (styles/default-chat-icon-profile color size)
|
:default-chat-icon (styles/default-chat-icon-profile color size)
|
||||||
|
|
|
@ -94,6 +94,7 @@
|
||||||
(def mention-outgoing "#9EE8FA")
|
(def mention-outgoing "#9EE8FA")
|
||||||
(def text black)
|
(def text black)
|
||||||
(def text-gray gray)
|
(def text-gray gray)
|
||||||
|
(def default-community-color "#773377")
|
||||||
|
|
||||||
(def default-chat-color "#a187d5") ;; legacy
|
(def default-chat-color "#a187d5") ;; legacy
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[status-im.utils.universal-links.utils :as links]
|
[status-im.utils.universal-links.utils :as links]
|
||||||
[status-im.ui.screens.chat.styles.main :as style]
|
[status-im.ui.screens.chat.styles.main :as style]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.ui.components.list-selection :as list-selection]
|
[status-im.ui.components.list-selection :as list-selection]
|
||||||
[status-im.ui.components.colors :as colors]
|
[status-im.ui.components.colors :as colors]
|
||||||
[status-im.constants :as constants]
|
|
||||||
[status-im.utils.debounce :as debounce])
|
[status-im.utils.debounce :as debounce])
|
||||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||||
|
|
||||||
|
@ -83,18 +83,33 @@
|
||||||
:size :small
|
:size :small
|
||||||
:color colors/gray}]])
|
:color colors/gray}]])
|
||||||
|
|
||||||
(defview no-messages-group-chat-description-container [chat-id]
|
(defn calculate-quiet-time [highest-request-to
|
||||||
|
lowest-request-from]
|
||||||
|
(let [quiet-hours (quot (- highest-request-to lowest-request-from)
|
||||||
|
(* 60 60))]
|
||||||
|
(if (<= quiet-hours 24)
|
||||||
|
(i18n/label :t/quiet-hours
|
||||||
|
{:quiet-hours quiet-hours})
|
||||||
|
(i18n/label :t/quiet-days
|
||||||
|
{:quiet-days (quot quiet-hours 24)}))))
|
||||||
|
|
||||||
|
(defview no-messages-community-chat-description-container [chat-id]
|
||||||
|
(letsubs [{:keys [highest-request-to lowest-request-from]}
|
||||||
|
[:mailserver/ranges-by-chat-id chat-id]]
|
||||||
|
[react/text {:style (merge style/intro-header-description
|
||||||
|
{:margin-bottom 36})}
|
||||||
|
(let [quiet-time (calculate-quiet-time highest-request-to
|
||||||
|
lowest-request-from)]
|
||||||
|
(i18n/label :t/empty-chat-description-community
|
||||||
|
{:quiet-hours quiet-time}))]))
|
||||||
|
|
||||||
|
(defview no-messages-private-group-chat-description-container [chat-id]
|
||||||
(letsubs [{:keys [highest-request-to lowest-request-from]}
|
(letsubs [{:keys [highest-request-to lowest-request-from]}
|
||||||
[:mailserver/ranges-by-chat-id chat-id]]
|
[:mailserver/ranges-by-chat-id chat-id]]
|
||||||
[react/nested-text {:style (merge style/intro-header-description
|
[react/nested-text {:style (merge style/intro-header-description
|
||||||
{:margin-bottom 36})}
|
{:margin-bottom 36})}
|
||||||
(let [quiet-hours (quot (- highest-request-to lowest-request-from)
|
(let [quiet-time (calculate-quiet-time highest-request-to
|
||||||
(* 60 60))
|
lowest-request-from)]
|
||||||
quiet-time (if (<= quiet-hours 24)
|
|
||||||
(i18n/label :t/quiet-hours
|
|
||||||
{:quiet-hours quiet-hours})
|
|
||||||
(i18n/label :t/quiet-days
|
|
||||||
{:quiet-days (quot quiet-hours 24)}))]
|
|
||||||
(i18n/label :t/empty-chat-description-public
|
(i18n/label :t/empty-chat-description-public
|
||||||
{:quiet-hours quiet-time}))
|
{:quiet-hours quiet-time}))
|
||||||
[{:style {:color colors/blue}
|
[{:style {:color colors/blue}
|
||||||
|
@ -143,20 +158,23 @@
|
||||||
(i18n/label :t/membership-description)])
|
(i18n/label :t/membership-description)])
|
||||||
|
|
||||||
(defn group-chat-description-container
|
(defn group-chat-description-container
|
||||||
[{:keys [public?
|
[{:keys [invitation-admin
|
||||||
invitation-admin
|
|
||||||
chat-id
|
chat-id
|
||||||
chat-name
|
chat-name
|
||||||
|
chat-type
|
||||||
loading-messages?
|
loading-messages?
|
||||||
no-messages?]}]
|
no-messages?]}]
|
||||||
(cond loading-messages?
|
(cond loading-messages?
|
||||||
group-chat-description-loading
|
group-chat-description-loading
|
||||||
|
|
||||||
(and no-messages? public?)
|
(and no-messages? (= chat-type constants/public-chat-type))
|
||||||
[no-messages-group-chat-description-container chat-id]
|
[no-messages-private-group-chat-description-container chat-id]
|
||||||
|
|
||||||
|
(and no-messages? (= chat-type constants/community-chat-type))
|
||||||
|
[no-messages-community-chat-description-container chat-id]
|
||||||
|
|
||||||
invitation-admin
|
invitation-admin
|
||||||
[group-chat-membership-description]
|
[group-chat-membership-description]
|
||||||
|
|
||||||
(not public?)
|
(= chat-type constants/private-group-chat-type)
|
||||||
[group-chat-inviter-description-container chat-id chat-name]))
|
[group-chat-inviter-description-container chat-id chat-name]))
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
|
[status-im.communities.core :as communities]
|
||||||
|
[status-im.utils.config :as config]
|
||||||
|
[status-im.react-native.resources :as resources]
|
||||||
[status-im.ui.components.colors :as colors]
|
[status-im.ui.components.colors :as colors]
|
||||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
|
@ -10,6 +13,7 @@
|
||||||
[status-im.ui.screens.chat.message.command :as message.command]
|
[status-im.ui.screens.chat.message.command :as message.command]
|
||||||
[status-im.ui.screens.chat.photos :as photos]
|
[status-im.ui.screens.chat.photos :as photos]
|
||||||
[status-im.ui.screens.chat.sheets :as sheets]
|
[status-im.ui.screens.chat.sheets :as sheets]
|
||||||
|
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||||
[status-im.ui.screens.chat.styles.message.message :as style]
|
[status-im.ui.screens.chat.styles.message.message :as style]
|
||||||
[status-im.ui.screens.chat.utils :as chat.utils]
|
[status-im.ui.screens.chat.utils :as chat.utils]
|
||||||
[status-im.utils.contenthash :as contenthash]
|
[status-im.utils.contenthash :as contenthash]
|
||||||
|
@ -209,6 +213,64 @@
|
||||||
(letsubs [contact-with-names [:multiaccount/contact]]
|
(letsubs [contact-with-names [:multiaccount/contact]]
|
||||||
(chat.utils/format-author contact-with-names opts)))
|
(chat.utils/format-author contact-with-names opts)))
|
||||||
|
|
||||||
|
(defview community-content [{:keys [community-id] :as message}]
|
||||||
|
(letsubs [{:keys [joined verified] :as community} [:communities/community community-id]]
|
||||||
|
(when (and
|
||||||
|
config/communities-enabled?
|
||||||
|
community)
|
||||||
|
[react/view {:style (assoc (style/message-wrapper message)
|
||||||
|
:margin-vertical 10
|
||||||
|
:width 271)}
|
||||||
|
(when verified
|
||||||
|
[react/view {:border-right-width 1
|
||||||
|
:border-left-width 1
|
||||||
|
:border-top-width 1
|
||||||
|
:border-left-color colors/gray-lighter
|
||||||
|
:border-right-color colors/gray-lighter
|
||||||
|
:border-top-left-radius 10
|
||||||
|
:border-top-right-radius 10
|
||||||
|
:padding-vertical 8
|
||||||
|
:padding-horizontal 15
|
||||||
|
:border-top-color colors/gray-lighter}
|
||||||
|
[react/text {:style {:font-size 13
|
||||||
|
:color colors/blue}} (i18n/label :t/communities-verified)]])
|
||||||
|
|
||||||
|
[react/view {:flex-direction :row
|
||||||
|
:padding-vertical 12
|
||||||
|
:border-top-left-radius (when-not verified 10)
|
||||||
|
:border-top-right-radius (when-not verified 10)
|
||||||
|
:border-right-width 1
|
||||||
|
:border-left-width 1
|
||||||
|
:border-top-width 1
|
||||||
|
:border-color colors/gray-lighter}
|
||||||
|
|
||||||
|
[react/view {:width 62
|
||||||
|
:padding-left 14}
|
||||||
|
(if (= community-id constants/status-community-id)
|
||||||
|
[react/image {:source (resources/get-image :status-logo)
|
||||||
|
:style {:width 40
|
||||||
|
:height 40}}]
|
||||||
|
|
||||||
|
(let [display-name (get-in community [:description :identity :display-name])]
|
||||||
|
[chat-icon/chat-icon-view-chat-list
|
||||||
|
display-name
|
||||||
|
true
|
||||||
|
display-name
|
||||||
|
colors/default-community-color]))]
|
||||||
|
[react/view {:padding-right 14}
|
||||||
|
[react/text {:style {:font-weight "700"
|
||||||
|
:font-size 17}}
|
||||||
|
(get-in community [:description :identity :display-name])]
|
||||||
|
[react/text (get-in community [:description :identity :description])]]]
|
||||||
|
[react/view {:border-width 1
|
||||||
|
:padding-vertical 8
|
||||||
|
:border-bottom-left-radius 10
|
||||||
|
:border-bottom-right-radius 10
|
||||||
|
:border-color colors/gray-lighter}
|
||||||
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [(if joined ::communities/leave ::communities/join) (:id community)])}
|
||||||
|
[react/text {:style {:text-align :center
|
||||||
|
:color colors/blue}} (if joined (i18n/label :t/leave) (i18n/label :t/join))]]]])))
|
||||||
|
|
||||||
(defn message-content-wrapper
|
(defn message-content-wrapper
|
||||||
"Author, userpic and delivery wrapper"
|
"Author, userpic and delivery wrapper"
|
||||||
[{:keys [first-in-group? display-photo? display-username?
|
[{:keys [first-in-group? display-photo? display-username?
|
||||||
|
@ -356,6 +418,10 @@
|
||||||
[collapsible-text-message message on-long-press modal]
|
[collapsible-text-message message on-long-press modal]
|
||||||
reaction-picker])
|
reaction-picker])
|
||||||
|
|
||||||
|
(defmethod ->message constants/content-type-community
|
||||||
|
[message]
|
||||||
|
[community-content message])
|
||||||
|
|
||||||
(defmethod ->message constants/content-type-status
|
(defmethod ->message constants/content-type-status
|
||||||
[{:keys [content content-type] :as message}]
|
[{:keys [content content-type] :as message}]
|
||||||
[message-content-wrapper message
|
[message-content-wrapper message
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[status-im.ui.components.list-selection :as list-selection]
|
[status-im.ui.components.list-selection :as list-selection]
|
||||||
[status-im.utils.universal-links.utils :as universal-links]
|
[status-im.utils.universal-links.utils :as universal-links]
|
||||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||||
|
@ -78,6 +79,27 @@
|
||||||
:icon :main-icons/delete
|
:icon :main-icons/delete
|
||||||
:on-press #(re-frame/dispatch [:chat.ui/remove-chat-pressed chat-id])}]]))
|
:on-press #(re-frame/dispatch [:chat.ui/remove-chat-pressed chat-id])}]]))
|
||||||
|
|
||||||
|
(defn community-chat-accents []
|
||||||
|
(fn [{:keys [chat-id group-chat chat-name color]}]
|
||||||
|
[react/view
|
||||||
|
[quo/list-item
|
||||||
|
{:theme :accent
|
||||||
|
:title chat-name
|
||||||
|
:icon [chat-icon/chat-icon-view-chat-sheet
|
||||||
|
chat-id group-chat chat-name color]}]
|
||||||
|
[quo/list-item
|
||||||
|
{:theme :accent
|
||||||
|
:title (i18n/label :t/mark-all-read)
|
||||||
|
:accessibility-label :mark-all-read-button
|
||||||
|
:icon :main-icons/check
|
||||||
|
:on-press #(hide-sheet-and-dispatch [:chat.ui/mark-all-read-pressed chat-id])}]
|
||||||
|
[quo/list-item
|
||||||
|
{:theme :accent
|
||||||
|
:title (i18n/label :t/clear-history)
|
||||||
|
:accessibility-label :clear-history-button
|
||||||
|
:icon :main-icons/close
|
||||||
|
:on-press #(re-frame/dispatch [:chat.ui/clear-history-pressed chat-id])}]]))
|
||||||
|
|
||||||
(defn group-chat-accents []
|
(defn group-chat-accents []
|
||||||
(fn [{:keys [chat-id group-chat chat-name color invitation-admin]}]
|
(fn [{:keys [chat-id group-chat chat-name color invitation-admin]}]
|
||||||
(let [{:keys [joined?]} @(re-frame/subscribe [:group-chat/inviter-info chat-id])]
|
(let [{:keys [joined?]} @(re-frame/subscribe [:group-chat/inviter-info chat-id])]
|
||||||
|
@ -117,11 +139,20 @@
|
||||||
:icon :main-icons/arrow-left
|
:icon :main-icons/arrow-left
|
||||||
:on-press #(re-frame/dispatch [:group-chats.ui/leave-chat-pressed chat-id])}])]))))
|
:on-press #(re-frame/dispatch [:group-chats.ui/leave-chat-pressed chat-id])}])]))))
|
||||||
|
|
||||||
(defn actions [{:keys [public? group-chat]
|
(defn actions [{:keys [chat-type]
|
||||||
:as current-chat}]
|
:as current-chat}]
|
||||||
(cond
|
(cond
|
||||||
public? [public-chat-accents current-chat]
|
(#{constants/public-chat-type
|
||||||
group-chat [group-chat-accents current-chat]
|
constants/profile-chat-type
|
||||||
|
constants/timeline-chat-type} chat-type)
|
||||||
|
[public-chat-accents current-chat]
|
||||||
|
|
||||||
|
(= chat-type constants/community-chat-type)
|
||||||
|
[community-chat-accents current-chat]
|
||||||
|
|
||||||
|
(= chat-type constants/private-group-chat-type)
|
||||||
|
[group-chat-accents current-chat]
|
||||||
|
|
||||||
:else [one-to-one-chat-accents current-chat]))
|
:else [one-to-one-chat-accents current-chat]))
|
||||||
|
|
||||||
(defn options [chat-id message-id]
|
(defn options [chat-id message-id]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(ns status-im.ui.screens.chat.toolbar-content
|
(ns status-im.ui.screens.chat.toolbar-content
|
||||||
(:require [status-im.i18n :as i18n]
|
(:require [status-im.i18n :as i18n]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.screens.chat.styles.main :as st]
|
[status-im.ui.screens.chat.styles.main :as st]
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
color
|
color
|
||||||
chat-id
|
chat-id
|
||||||
contacts
|
contacts
|
||||||
|
chat-type
|
||||||
chat-name
|
chat-name
|
||||||
public?]}]
|
public?]}]
|
||||||
[react/view {:style st/toolbar-container}
|
[react/view {:style st/toolbar-container}
|
||||||
|
@ -49,6 +51,6 @@
|
||||||
[one-to-one-name chat-id])
|
[one-to-one-name chat-id])
|
||||||
(when-not group-chat
|
(when-not group-chat
|
||||||
[contact-indicator chat-id])
|
[contact-indicator chat-id])
|
||||||
(when (and group-chat (not invitation-admin))
|
(when (and group-chat (not invitation-admin) (not= chat-type constants/community-chat-type))
|
||||||
[group-last-activity {:contacts contacts
|
[group-last-activity {:contacts contacts
|
||||||
:public? public?}])]])
|
:public? public?}])]])
|
||||||
|
|
|
@ -74,10 +74,10 @@
|
||||||
|
|
||||||
(defn chat-intro [{:keys [chat-id
|
(defn chat-intro [{:keys [chat-id
|
||||||
chat-name
|
chat-name
|
||||||
|
chat-type
|
||||||
group-chat
|
group-chat
|
||||||
invitation-admin
|
invitation-admin
|
||||||
contact-name
|
contact-name
|
||||||
public?
|
|
||||||
color
|
color
|
||||||
loading-messages?
|
loading-messages?
|
||||||
no-messages?]}]
|
no-messages?]}]
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
:invitation-admin invitation-admin
|
:invitation-admin invitation-admin
|
||||||
:loading-messages? loading-messages?
|
:loading-messages? loading-messages?
|
||||||
:chat-name chat-name
|
:chat-name chat-name
|
||||||
:public? public?
|
:chat-type chat-type
|
||||||
:no-messages? no-messages?}]
|
:no-messages? no-messages?}]
|
||||||
[react/text {:style (assoc style/intro-header-description
|
[react/text {:style (assoc style/intro-header-description
|
||||||
:margin-bottom 32)}
|
:margin-bottom 32)}
|
||||||
|
@ -115,6 +115,7 @@
|
||||||
|
|
||||||
(defn chat-intro-header-container
|
(defn chat-intro-header-container
|
||||||
[{:keys [group-chat invitation-admin
|
[{:keys [group-chat invitation-admin
|
||||||
|
chat-type
|
||||||
might-have-join-time-messages?
|
might-have-join-time-messages?
|
||||||
color chat-id chat-name
|
color chat-id chat-name
|
||||||
public?]}
|
public?]}
|
||||||
|
@ -128,6 +129,7 @@
|
||||||
{:chat-id chat-id
|
{:chat-id chat-id
|
||||||
:group-chat group-chat
|
:group-chat group-chat
|
||||||
:invitation-admin invitation-admin
|
:invitation-admin invitation-admin
|
||||||
|
:chat-type chat-type
|
||||||
:chat-name chat-name
|
:chat-name chat-name
|
||||||
:public? public?
|
:public? public?
|
||||||
:color color
|
:color color
|
||||||
|
@ -170,7 +172,7 @@
|
||||||
|
|
||||||
(defn messages-view
|
(defn messages-view
|
||||||
[{:keys [chat bottom-space pan-responder space-keeper]}]
|
[{:keys [chat bottom-space pan-responder space-keeper]}]
|
||||||
(let [{:keys [group-chat chat-id public? invitation-admin]} chat
|
(let [{:keys [group-chat chat-id chat-type public? invitation-admin]} chat
|
||||||
|
|
||||||
messages @(re-frame/subscribe [:chats/current-chat-messages-stream])
|
messages @(re-frame/subscribe [:chats/current-chat-messages-stream])
|
||||||
no-messages? @(re-frame/subscribe [:chats/current-chat-no-messages?])
|
no-messages? @(re-frame/subscribe [:chats/current-chat-no-messages?])
|
||||||
|
@ -180,11 +182,11 @@
|
||||||
pan-responder
|
pan-responder
|
||||||
{:key-fn #(or (:message-id %) (:value %))
|
{:key-fn #(or (:message-id %) (:value %))
|
||||||
:ref #(reset! messages-list-ref %)
|
:ref #(reset! messages-list-ref %)
|
||||||
:header (when (and group-chat (not public?))
|
:header (when (= chat-type constants/private-group-chat-type)
|
||||||
[chat.group/group-chat-footer chat-id invitation-admin])
|
[chat.group/group-chat-footer chat-id invitation-admin])
|
||||||
:footer [:<>
|
:footer [:<>
|
||||||
[chat-intro-header-container chat no-messages?]
|
[chat-intro-header-container chat no-messages?]
|
||||||
(when (and (not group-chat) (not public?))
|
(when (= chat-type constants/one-to-one-chat-type)
|
||||||
[invite.chat/reward-messages])]
|
[invite.chat/reward-messages])]
|
||||||
:data messages
|
:data messages
|
||||||
:inverted true
|
:inverted true
|
||||||
|
|
|
@ -0,0 +1,423 @@
|
||||||
|
(ns status-im.ui.screens.communities.views (:require-macros [status-im.utils.views :as views])
|
||||||
|
(:require
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[re-frame.core :as re-frame]
|
||||||
|
[quo.core :as quo]
|
||||||
|
[status-im.i18n :as i18n]
|
||||||
|
[status-im.utils.core :as utils]
|
||||||
|
[status-im.utils.config :as config]
|
||||||
|
[status-im.constants :as constants]
|
||||||
|
[status-im.communities.core :as communities]
|
||||||
|
[status-im.ui.screens.home.views.inner-item :as inner-item]
|
||||||
|
[status-im.ui.screens.home.styles :as home.styles]
|
||||||
|
[status-im.ui.components.list.views :as list]
|
||||||
|
[status-im.ui.components.copyable-text :as copyable-text]
|
||||||
|
[status-im.react-native.resources :as resources]
|
||||||
|
[status-im.ui.components.topbar :as topbar]
|
||||||
|
[status-im.ui.components.icons.vector-icons :as icons]
|
||||||
|
[status-im.ui.components.colors :as colors]
|
||||||
|
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
||||||
|
[status-im.ui.components.toolbar :as toolbar]
|
||||||
|
[status-im.ui.components.react :as react]))
|
||||||
|
|
||||||
|
(defn hide-sheet-and-dispatch [event]
|
||||||
|
(re-frame/dispatch [:bottom-sheet/hide])
|
||||||
|
(re-frame/dispatch event))
|
||||||
|
|
||||||
|
(defn community-list-item [{:keys [id description]}]
|
||||||
|
(let [identity (:identity description)]
|
||||||
|
[quo/list-item
|
||||||
|
{:icon (if (= id constants/status-community-id)
|
||||||
|
[react/image {:source (resources/get-image :status-logo)
|
||||||
|
:style {:width 40
|
||||||
|
:height 40}}]
|
||||||
|
|
||||||
|
[chat-icon.screen/chat-icon-view-chat-list
|
||||||
|
id
|
||||||
|
true
|
||||||
|
(:display-name identity)
|
||||||
|
;; TODO: should be derived by id
|
||||||
|
(or (:color identity)
|
||||||
|
(rand-nth colors/chat-colors))
|
||||||
|
false
|
||||||
|
false])
|
||||||
|
:title [react/view {:flex-direction :row
|
||||||
|
:flex 1}
|
||||||
|
[react/view {:flex-direction :row
|
||||||
|
:flex 1
|
||||||
|
:padding-right 16
|
||||||
|
:align-items :center}
|
||||||
|
[quo/text {:weight :medium
|
||||||
|
:accessibility-label :community-name-text
|
||||||
|
:ellipsize-mode :tail
|
||||||
|
:number-of-lines 1}
|
||||||
|
(utils/truncate-str (:display-name identity) 30)]]]
|
||||||
|
:title-accessibility-label :community-name-text
|
||||||
|
:subtitle [react/view {:flex-direction :row}
|
||||||
|
[react/view {:flex 1}
|
||||||
|
[quo/text
|
||||||
|
(utils/truncate-str (:description identity) 30)]]]
|
||||||
|
:on-press #(do
|
||||||
|
(re-frame/dispatch [:dismiss-keyboard])
|
||||||
|
(re-frame/dispatch [:navigate-to :community id]))}]))
|
||||||
|
|
||||||
|
(defn communities-actions []
|
||||||
|
[react/view
|
||||||
|
[quo/list-item
|
||||||
|
{:theme :accent
|
||||||
|
:title (i18n/label :t/import-community)
|
||||||
|
:accessibility-label :community-import-community
|
||||||
|
:icon :main-icons/check
|
||||||
|
:on-press #(hide-sheet-and-dispatch [::communities/import-pressed])}]
|
||||||
|
[quo/list-item
|
||||||
|
{:theme :accent
|
||||||
|
:title (i18n/label :t/create-community)
|
||||||
|
:accessibility-label :community-create-community
|
||||||
|
:icon :main-icons/check
|
||||||
|
:on-press #(hide-sheet-and-dispatch [::communities/create-pressed])}]])
|
||||||
|
|
||||||
|
(views/defview communities []
|
||||||
|
(views/letsubs [communities [:communities]]
|
||||||
|
[react/view {:flex 1}
|
||||||
|
[topbar/topbar (cond-> {:title (i18n/label :t/communities)}
|
||||||
|
config/communities-management-enabled?
|
||||||
|
(assoc :right-accessories [{:icon :main-icons/more
|
||||||
|
:accessibility-label :chat-menu-button
|
||||||
|
:on-press
|
||||||
|
#(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||||
|
{:content (fn []
|
||||||
|
[communities-actions])
|
||||||
|
:height 256}])}]))]
|
||||||
|
[react/scroll-view {:style {:flex 1}
|
||||||
|
:content-container-style {:padding-vertical 8}}
|
||||||
|
[list/flat-list
|
||||||
|
{:key-fn :id
|
||||||
|
:keyboard-should-persist-taps :always
|
||||||
|
:data (vals communities)
|
||||||
|
:render-fn (fn [community] [community-list-item community])}]]
|
||||||
|
(when config/communities-management-enabled?
|
||||||
|
[toolbar/toolbar
|
||||||
|
{:show-border? true
|
||||||
|
:center [quo/button {:on-press #(re-frame/dispatch [::communities/create-pressed])}
|
||||||
|
(i18n/label :t/create)]}])]))
|
||||||
|
|
||||||
|
(defn valid? [community-name community-description]
|
||||||
|
(and (not= "" community-name)
|
||||||
|
(not= "" community-description)))
|
||||||
|
|
||||||
|
(defn import-community []
|
||||||
|
(let [community-key (reagent/atom "")]
|
||||||
|
(fn []
|
||||||
|
[react/view {:style {:padding-left 16
|
||||||
|
:padding-right 8}}
|
||||||
|
[react/view {:style {:padding-horizontal 20}}
|
||||||
|
[quo/text-input
|
||||||
|
{:label (i18n/label :t/community-key)
|
||||||
|
:placeholder (i18n/label :t/community-key-placeholder)
|
||||||
|
:on-change-text #(reset! community-key %)
|
||||||
|
:auto-focus true}]]
|
||||||
|
[react/view {:style {:padding-top 20
|
||||||
|
:padding-horizontal 20}}
|
||||||
|
[quo/button {:disabled (= @community-key "")
|
||||||
|
:on-press #(re-frame/dispatch [::communities/import-confirmation-pressed @community-key])}
|
||||||
|
(i18n/label :t/import)]]])))
|
||||||
|
|
||||||
|
(defn create []
|
||||||
|
(let [community-name (reagent/atom "")
|
||||||
|
membership (reagent/atom 1)
|
||||||
|
community-description (reagent/atom "")]
|
||||||
|
(fn []
|
||||||
|
[react/view {:style {:padding-left 16
|
||||||
|
:padding-right 8}}
|
||||||
|
[react/view {:style {:padding-horizontal 20}}
|
||||||
|
[quo/text-input
|
||||||
|
{:label (i18n/label :t/name-your-community)
|
||||||
|
:placeholder (i18n/label :t/name-your-community-placeholder)
|
||||||
|
:on-change-text #(reset! community-name %)
|
||||||
|
:auto-focus true}]]
|
||||||
|
[react/view {:style {:padding-horizontal 20}}
|
||||||
|
[quo/text-input
|
||||||
|
{:label (i18n/label :t/give-a-short-description-community)
|
||||||
|
:placeholder (i18n/label :t/give-a-short-description-community)
|
||||||
|
:multiline true
|
||||||
|
:number-of-lines 4
|
||||||
|
:on-change-text #(reset! community-description %)}]]
|
||||||
|
[react/view {:style {:padding-horizontal 20}}
|
||||||
|
[quo/text-input
|
||||||
|
{:label (i18n/label :t/membership-type)
|
||||||
|
:placeholder (i18n/label :t/membership-type-placeholder)
|
||||||
|
:on-change-text #(reset! membership %)}]]
|
||||||
|
|
||||||
|
[react/view {:style {:padding-top 20
|
||||||
|
:padding-horizontal 20}}
|
||||||
|
[quo/button {:disabled (not (valid? @community-name @community-description))
|
||||||
|
:on-press #(re-frame/dispatch [::communities/create-confirmation-pressed @community-name @community-description @membership])}
|
||||||
|
(i18n/label :t/create)]]])))
|
||||||
|
|
||||||
|
(def create-sheet
|
||||||
|
{:content create})
|
||||||
|
|
||||||
|
(def import-sheet
|
||||||
|
{:content import-community})
|
||||||
|
|
||||||
|
(defn create-channel []
|
||||||
|
(let [channel-name (reagent/atom "")
|
||||||
|
channel-description (reagent/atom "")]
|
||||||
|
(fn []
|
||||||
|
[react/view {:style {:padding-left 16
|
||||||
|
:padding-right 8}}
|
||||||
|
[react/view {:style {:padding-horizontal 20}}
|
||||||
|
[quo/text-input
|
||||||
|
{:label (i18n/label :t/name-your-channel)
|
||||||
|
:placeholder (i18n/label :t/name-your-channel-placeholder)
|
||||||
|
:on-change-text #(reset! channel-name %)
|
||||||
|
:auto-focus true}]]
|
||||||
|
[react/view {:style {:padding-horizontal 20}}
|
||||||
|
[quo/text-input
|
||||||
|
{:label (i18n/label :t/give-a-short-description-channel)
|
||||||
|
:placeholder (i18n/label :t/give-a-short-description-channel)
|
||||||
|
:multiline true
|
||||||
|
:number-of-lines 4
|
||||||
|
:on-change-text #(reset! channel-description %)}]]
|
||||||
|
|
||||||
|
(when config/communities-management-enabled?
|
||||||
|
[react/view {:style {:padding-top 20
|
||||||
|
:padding-horizontal 20}}
|
||||||
|
[quo/button {:disabled (not (valid? @channel-name @channel-description))
|
||||||
|
:on-press #(re-frame/dispatch [::communities/create-channel-confirmation-pressed @channel-name @channel-description])}
|
||||||
|
(i18n/label :t/create)]])])))
|
||||||
|
|
||||||
|
(def create-channel-sheet
|
||||||
|
{:content create-channel})
|
||||||
|
|
||||||
|
(defn invite-people []
|
||||||
|
(let [user-pk (reagent/atom "")]
|
||||||
|
(fn []
|
||||||
|
[react/view {:style {:padding-left 16
|
||||||
|
:padding-right 8}}
|
||||||
|
[react/view {:style {:padding-horizontal 20}}
|
||||||
|
[quo/text-input
|
||||||
|
{:label (i18n/label :t/enter-user-pk)
|
||||||
|
:placeholder (i18n/label :t/enter-user-pk)
|
||||||
|
:on-change-text #(reset! user-pk %)
|
||||||
|
:auto-focus true}]]
|
||||||
|
[react/view {:style {:padding-top 20
|
||||||
|
:padding-horizontal 20}}
|
||||||
|
[quo/button {:disabled (= "" user-pk)
|
||||||
|
:on-press #(re-frame/dispatch [::communities/invite-people-confirmation-pressed @user-pk])}
|
||||||
|
(i18n/label :t/invite)]]])))
|
||||||
|
|
||||||
|
(def invite-people-sheet
|
||||||
|
{:content invite-people})
|
||||||
|
|
||||||
|
(defn community-actions [id admin]
|
||||||
|
[react/view
|
||||||
|
(when (and config/communities-management-enabled? admin)
|
||||||
|
[quo/list-item
|
||||||
|
{:theme :accent
|
||||||
|
:title (i18n/label :t/export-key)
|
||||||
|
:accessibility-label :community-export-key
|
||||||
|
:icon :main-icons/check
|
||||||
|
:on-press #(hide-sheet-and-dispatch [::communities/export-pressed id])}])
|
||||||
|
(when (and config/communities-management-enabled? admin)
|
||||||
|
[quo/list-item
|
||||||
|
{:theme :accent
|
||||||
|
:title (i18n/label :t/create-channel)
|
||||||
|
:accessibility-label :community-create-channel
|
||||||
|
:icon :main-icons/check
|
||||||
|
:on-press #(hide-sheet-and-dispatch [::communities/create-channel-pressed id])}])
|
||||||
|
(when (and config/communities-management-enabled? admin)
|
||||||
|
[quo/list-item
|
||||||
|
{:theme :accent
|
||||||
|
:title (i18n/label :t/invite-people)
|
||||||
|
:accessibility-label :community-invite-people
|
||||||
|
:icon :main-icons/close
|
||||||
|
:on-press #(re-frame/dispatch [::communities/invite-people-pressed id])}])
|
||||||
|
[quo/list-item
|
||||||
|
{:theme :accent
|
||||||
|
:title (i18n/label :t/leave)
|
||||||
|
:accessibility-label :leave
|
||||||
|
:icon :main-icons/close
|
||||||
|
:on-press #(do
|
||||||
|
(re-frame/dispatch [:navigate-to :home])
|
||||||
|
(re-frame/dispatch [:bottom-sheet/hide])
|
||||||
|
(re-frame/dispatch [::communities/leave id]))}]])
|
||||||
|
|
||||||
|
(defn toolbar-content [id display-name color]
|
||||||
|
[react/view {:style {:flex 1
|
||||||
|
:align-items :center
|
||||||
|
:flex-direction :row}}
|
||||||
|
[react/view {:margin-right 10}
|
||||||
|
(if (= id constants/status-community-id)
|
||||||
|
[react/image {:source (resources/get-image :status-logo)
|
||||||
|
:style {:width 40
|
||||||
|
:height 40}}]
|
||||||
|
[chat-icon.screen/chat-icon-view-toolbar
|
||||||
|
id
|
||||||
|
true
|
||||||
|
display-name
|
||||||
|
(or color
|
||||||
|
(rand-nth colors/chat-colors))])]
|
||||||
|
[react/view {:style {:flex 1 :justify-content :center}}
|
||||||
|
[react/text {:style {:typography :main-medium
|
||||||
|
:font-size 15
|
||||||
|
:line-height 22}
|
||||||
|
:number-of-lines 1
|
||||||
|
:accessibility-label :community-name-text}
|
||||||
|
display-name]]])
|
||||||
|
|
||||||
|
(defn topbar [id display-name color admin joined]
|
||||||
|
[topbar/topbar
|
||||||
|
{:content [toolbar-content id display-name color]
|
||||||
|
:navigation {:on-press #(re-frame/dispatch [:navigate-back])}
|
||||||
|
:right-accessories (when (or admin joined)
|
||||||
|
[{:icon :main-icons/more
|
||||||
|
:accessibility-label :community-menu-button
|
||||||
|
:on-press
|
||||||
|
#(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||||
|
{:content (fn []
|
||||||
|
[community-actions id admin])
|
||||||
|
:height 256}])}])}])
|
||||||
|
|
||||||
|
(defn welcome-blank-page []
|
||||||
|
[react/view {:style {:flex 1 :flex-direction :row :align-items :center :justify-content :center}}
|
||||||
|
[react/i18n-text {:style home.styles/welcome-blank-text :key :welcome-blank-message}]])
|
||||||
|
|
||||||
|
(views/defview community-unviewed-count [id]
|
||||||
|
(views/letsubs [unviewed-count [:communities/unviewed-count id]]
|
||||||
|
(when-not (zero? unviewed-count)
|
||||||
|
[react/view {:style {:background-color colors/blue
|
||||||
|
:border-radius 6
|
||||||
|
:margin-right 5
|
||||||
|
:margin-top 2
|
||||||
|
:width 12
|
||||||
|
:height 12}
|
||||||
|
:accessibility-label :unviewed-messages-public}])))
|
||||||
|
|
||||||
|
(defn status-community [{:keys [id description]}]
|
||||||
|
[quo/list-item
|
||||||
|
{:icon [react/image {:source (resources/get-image :status-logo)
|
||||||
|
:style {:width 40
|
||||||
|
:height 40}}]
|
||||||
|
:title [react/view {:flex-direction :row
|
||||||
|
:flex 1}
|
||||||
|
[react/view {:flex-direction :row
|
||||||
|
:flex 1
|
||||||
|
:padding-right 16
|
||||||
|
:align-items :center}
|
||||||
|
[quo/text {:weight :medium
|
||||||
|
:accessibility-label :chat-name-text
|
||||||
|
:font-size 17
|
||||||
|
:ellipsize-mode :tail
|
||||||
|
:number-of-lines 1}
|
||||||
|
(get-in description [:identity :display-name])]]
|
||||||
|
[react/view {:flex-direction :row
|
||||||
|
:flex 1
|
||||||
|
:justify-content :flex-end
|
||||||
|
:align-items :center}
|
||||||
|
[community-unviewed-count id]]]
|
||||||
|
|
||||||
|
:title-accessibility-label :chat-name-text
|
||||||
|
:on-press #(do
|
||||||
|
(re-frame/dispatch [:dismiss-keyboard])
|
||||||
|
(re-frame/dispatch [:navigate-to :community id]))
|
||||||
|
;; TODO: actions
|
||||||
|
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||||
|
nil])}])
|
||||||
|
|
||||||
|
(defn channel-preview-item [{:keys [id identity]}]
|
||||||
|
[quo/list-item
|
||||||
|
{:icon [chat-icon.screen/chat-icon-view-chat-list
|
||||||
|
id true (:display-name identity) colors/blue false false]
|
||||||
|
:title [react/view {:flex-direction :row
|
||||||
|
:flex 1}
|
||||||
|
[react/view {:flex-direction :row
|
||||||
|
:flex 1
|
||||||
|
:padding-right 16
|
||||||
|
:align-items :center}
|
||||||
|
[icons/icon :main-icons/tiny-group
|
||||||
|
{:color colors/black
|
||||||
|
:width 15
|
||||||
|
:height 15
|
||||||
|
:container-style {:width 15
|
||||||
|
:height 15
|
||||||
|
:margin-right 2}}]
|
||||||
|
[quo/text {:weight :medium
|
||||||
|
:accessibility-label :chat-name-text
|
||||||
|
:ellipsize-mode :tail
|
||||||
|
:number-of-lines 1}
|
||||||
|
(utils/truncate-str (:display-name identity) 30)]]]
|
||||||
|
:title-accessibility-label :chat-name-text
|
||||||
|
:subtitle [react/view {:flex-direction :row}
|
||||||
|
[react/text-class {:style home.styles/last-message-text
|
||||||
|
:number-of-lines 1
|
||||||
|
:ellipsize-mode :tail
|
||||||
|
:accessibility-label :chat-message-text} (:description identity)]]}])
|
||||||
|
|
||||||
|
(defn community-channel-preview-list [_ description]
|
||||||
|
(let [chats (reduce-kv
|
||||||
|
(fn [acc k v]
|
||||||
|
(conj acc (assoc v :id (name k))))
|
||||||
|
[]
|
||||||
|
(get-in description [:chats]))]
|
||||||
|
[list/flat-list
|
||||||
|
{:key-fn :id
|
||||||
|
:keyboard-should-persist-taps :always
|
||||||
|
:data chats
|
||||||
|
:render-fn channel-preview-item}]))
|
||||||
|
|
||||||
|
(defn community-chat-list [chats]
|
||||||
|
(if (empty? chats)
|
||||||
|
[welcome-blank-page]
|
||||||
|
[list/flat-list
|
||||||
|
{:key-fn :chat-id
|
||||||
|
:keyboard-should-persist-taps :always
|
||||||
|
:data chats
|
||||||
|
:render-fn (fn [home-item] [inner-item/home-list-item (assoc home-item :color colors/blue)])
|
||||||
|
:footer [react/view {:height 68}]}]))
|
||||||
|
|
||||||
|
(views/defview community-channel-list [id]
|
||||||
|
(views/letsubs [chats [:chats/by-community-id id]]
|
||||||
|
[community-chat-list chats]))
|
||||||
|
|
||||||
|
(views/defview community [route]
|
||||||
|
(views/letsubs [{:keys [id description joined admin]} [:communities/community (get-in route [:route :params])]]
|
||||||
|
[react/view {:style {:flex 1}}
|
||||||
|
[topbar
|
||||||
|
id
|
||||||
|
(get-in description [:identity :display-name])
|
||||||
|
(get-in description [:identity :color])
|
||||||
|
admin
|
||||||
|
joined]
|
||||||
|
(if joined
|
||||||
|
[community-channel-list id]
|
||||||
|
[community-channel-preview-list id description])
|
||||||
|
(when-not joined
|
||||||
|
[react/view {:style {:padding-top 20
|
||||||
|
:margin-bottom 10
|
||||||
|
:padding-horizontal 20}}
|
||||||
|
[quo/button {:on-press #(re-frame/dispatch [::communities/join id])}
|
||||||
|
(i18n/label :t/join)]])]))
|
||||||
|
|
||||||
|
(views/defview export-community []
|
||||||
|
(views/letsubs [{:keys [community-key]} [:popover/popover]]
|
||||||
|
[react/view {}
|
||||||
|
[react/view {:style {:padding-top 16 :padding-horizontal 16}}
|
||||||
|
[copyable-text/copyable-text-view
|
||||||
|
{:label :t/community-key
|
||||||
|
:container-style {:margin-top 12 :margin-bottom 4}
|
||||||
|
:copied-text community-key}
|
||||||
|
[quo/text {:number-of-lines 1
|
||||||
|
:ellipsize-mode :middle
|
||||||
|
:accessibility-label :chat-key
|
||||||
|
:monospace true}
|
||||||
|
community-key]]]]))
|
||||||
|
|
||||||
|
(defn render-featured-community [{:keys [name id]}]
|
||||||
|
^{:key id}
|
||||||
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :community id])
|
||||||
|
:accessibility-label :chat-item}
|
||||||
|
[react/view {:padding-right 8 :padding-vertical 8}
|
||||||
|
[react/view {:border-color colors/gray-lighter :border-radius 36 :border-width 1 :padding-horizontal 8 :padding-vertical 5}
|
||||||
|
[react/text {:style {:color colors/blue :typography :main-medium}} name]]]])
|
||||||
|
|
|
@ -47,6 +47,13 @@
|
||||||
:accessibility-label :join-public-chat-button
|
:accessibility-label :join-public-chat-button
|
||||||
:icon :main-icons/public-chat
|
:icon :main-icons/public-chat
|
||||||
:on-press #(hide-sheet-and-dispatch [:navigate-to :new-public-chat])}]
|
:on-press #(hide-sheet-and-dispatch [:navigate-to :new-public-chat])}]
|
||||||
|
(when config/communities-enabled?
|
||||||
|
[quo/list-item
|
||||||
|
{:theme :accent
|
||||||
|
:title (i18n/label :t/communities-alpha)
|
||||||
|
:accessibility-label :communities-button
|
||||||
|
:icon :main-icons/communities
|
||||||
|
:on-press #(hide-sheet-and-dispatch [:navigate-to :communities])}])
|
||||||
[invite/list-item
|
[invite/list-item
|
||||||
{:accessibility-label :chats-menu-invite-friends-button}]])
|
{:accessibility-label :chats-menu-invite-friends-button}]])
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,13 @@
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.react-native.resources :as resources]
|
[status-im.react-native.resources :as resources]
|
||||||
|
[status-im.communities.core :as communities]
|
||||||
[status-im.ui.components.connectivity.view :as connectivity]
|
[status-im.ui.components.connectivity.view :as connectivity]
|
||||||
[status-im.ui.components.icons.vector-icons :as icons]
|
[status-im.ui.components.icons.vector-icons :as icons]
|
||||||
[status-im.ui.components.list.views :as list]
|
[status-im.ui.components.list.views :as list]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.screens.home.styles :as styles]
|
[status-im.ui.screens.home.styles :as styles]
|
||||||
|
[status-im.ui.screens.communities.views :as communities.views]
|
||||||
[status-im.ui.screens.home.views.inner-item :as inner-item]
|
[status-im.ui.screens.home.views.inner-item :as inner-item]
|
||||||
[status-im.ui.screens.referrals.home-item :as referral-item]
|
[status-im.ui.screens.referrals.home-item :as referral-item]
|
||||||
[status-im.ui.components.colors :as colors]
|
[status-im.ui.components.colors :as colors]
|
||||||
|
@ -79,7 +81,14 @@
|
||||||
[react/view {:style styles/tags-wrapper}
|
[react/view {:style styles/tags-wrapper}
|
||||||
[react/view {:flex-direction :row :flex-wrap :wrap :justify-content :center}
|
[react/view {:flex-direction :row :flex-wrap :wrap :justify-content :center}
|
||||||
(for [chat (new-public-chat/featured-public-chats)]
|
(for [chat (new-public-chat/featured-public-chats)]
|
||||||
(new-public-chat/render-topic chat))]]]])
|
(new-public-chat/render-topic chat))]]
|
||||||
|
[react/i18n-text {:style {:margin-horizontal 16
|
||||||
|
:text-align :center}
|
||||||
|
:key :join-a-community}]
|
||||||
|
[react/view {:style styles/tags-wrapper}
|
||||||
|
[react/view {:flex-direction :row :flex-wrap :wrap :justify-content :center}
|
||||||
|
(for [community communities/featured]
|
||||||
|
(communities.views/render-featured-community community))]]]])
|
||||||
|
|
||||||
(defn welcome-blank-page []
|
(defn welcome-blank-page []
|
||||||
[react/view {:style {:flex 1 :flex-direction :row :align-items :center :justify-content :center}}
|
[react/view {:style {:flex 1 :flex-direction :row :align-items :center :justify-content :center}}
|
||||||
|
@ -136,31 +145,48 @@
|
||||||
(defn render-fn [home-item]
|
(defn render-fn [home-item]
|
||||||
[inner-item/home-list-item home-item])
|
[inner-item/home-list-item home-item])
|
||||||
|
|
||||||
(views/defview chats-list []
|
(defn communities-and-chats [chats status-community loading? search-filter hide-home-tooltip?]
|
||||||
(views/letsubs [loading? [:chats/loading?]
|
|
||||||
{:keys [chats search-filter]} [:home-items]
|
|
||||||
{:keys [hide-home-tooltip?]} [:multiaccount]]
|
|
||||||
(if loading?
|
(if loading?
|
||||||
[react/view {:flex 1 :align-items :center :justify-content :center}
|
[react/view {:flex 1 :align-items :center :justify-content :center}
|
||||||
[react/activity-indicator {:animating true}]]
|
[react/activity-indicator {:animating true}]]
|
||||||
(if (and (empty? chats)
|
(if (and (empty? chats)
|
||||||
|
(not status-community)
|
||||||
(empty? search-filter)
|
(empty? search-filter)
|
||||||
hide-home-tooltip?
|
hide-home-tooltip?
|
||||||
(not @search-active?))
|
(not @search-active?))
|
||||||
[welcome-blank-page]
|
[welcome-blank-page]
|
||||||
|
[react/view
|
||||||
|
[:<>
|
||||||
|
(when (or (seq chats) @search-active? (seq search-filter))
|
||||||
|
[search-input-wrapper search-filter chats])
|
||||||
|
[referral-item/list-item]]
|
||||||
|
(when
|
||||||
|
(and (empty? chats)
|
||||||
|
(not status-community))
|
||||||
|
(or @search-active? (seq search-filter))
|
||||||
|
[start-suggestion search-filter])
|
||||||
|
(when status-community
|
||||||
|
;; We only support one community now, Status
|
||||||
|
[communities.views/status-community status-community])
|
||||||
|
(when (and status-community
|
||||||
|
(seq chats))
|
||||||
|
[quo/separator])
|
||||||
[list/flat-list
|
[list/flat-list
|
||||||
{:key-fn :chat-id
|
{:key-fn :chat-id
|
||||||
:keyboard-should-persist-taps :always
|
:keyboard-should-persist-taps :always
|
||||||
:data chats
|
:data chats
|
||||||
:render-fn render-fn
|
:render-fn render-fn
|
||||||
:header [:<> (when (or (seq chats) @search-active? (seq search-filter))
|
|
||||||
[search-input-wrapper search-filter chats])
|
|
||||||
[referral-item/list-item]]
|
|
||||||
:empty-component (when (or @search-active? (seq search-filter))
|
|
||||||
[start-suggestion search-filter])
|
|
||||||
:footer (if (and (not hide-home-tooltip?) (not @search-active?))
|
:footer (if (and (not hide-home-tooltip?) (not @search-active?))
|
||||||
[home-tooltip-view]
|
[home-tooltip-view]
|
||||||
[react/view {:height 68}])}]))))
|
[react/view {:height 68}])}]])))
|
||||||
|
|
||||||
|
(views/defview chats-list []
|
||||||
|
(views/letsubs [status-community [:communities/status-community]
|
||||||
|
loading? [:chats/loading?]
|
||||||
|
{:keys [chats search-filter]} [:home-items]
|
||||||
|
{:keys [hide-home-tooltip?]} [:multiaccount]]
|
||||||
|
[react/scroll-view
|
||||||
|
[communities-and-chats chats status-community loading? search-filter hide-home-tooltip?]]))
|
||||||
|
|
||||||
(views/defview plus-button []
|
(views/defview plus-button []
|
||||||
(views/letsubs [logging-in? [:multiaccounts/login]]
|
(views/letsubs [logging-in? [:multiaccounts/login]]
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
[status-im.ui.screens.wallet.signing-phrase.views :as signing-phrase]
|
[status-im.ui.screens.wallet.signing-phrase.views :as signing-phrase]
|
||||||
|
[status-im.ui.screens.communities.views :as communities]
|
||||||
[status-im.ui.screens.wallet.request.views :as request]
|
[status-im.ui.screens.wallet.request.views :as request]
|
||||||
[status-im.ui.screens.profile.user.views :as profile.user]
|
[status-im.ui.screens.profile.user.views :as profile.user]
|
||||||
["react-native" :refer (BackHandler)]
|
["react-native" :refer (BackHandler)]
|
||||||
|
@ -147,6 +148,9 @@
|
||||||
(= :advertiser-invite view)
|
(= :advertiser-invite view)
|
||||||
[advertiser.invite/accept-popover]
|
[advertiser.invite/accept-popover]
|
||||||
|
|
||||||
|
(= :export-community view)
|
||||||
|
[communities/export-community]
|
||||||
|
|
||||||
(= :dapp-invite view)
|
(= :dapp-invite view)
|
||||||
[dapp.invite/accept-popover]
|
[dapp.invite/accept-popover]
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
[status-im.ui.screens.chat.views :as chat]
|
[status-im.ui.screens.chat.views :as chat]
|
||||||
[status-im.ui.screens.group.views :as group]
|
[status-im.ui.screens.group.views :as group]
|
||||||
[status-im.ui.screens.referrals.public-chat :as referrals.public-chat]
|
[status-im.ui.screens.referrals.public-chat :as referrals.public-chat]
|
||||||
|
[status-im.ui.screens.communities.views :as communities]
|
||||||
[status-im.ui.screens.profile.group-chat.views :as profile.group-chat]
|
[status-im.ui.screens.profile.group-chat.views :as profile.group-chat]
|
||||||
[status-im.ui.components.tabbar.styles :as tabbar.styles]
|
[status-im.ui.components.tabbar.styles :as tabbar.styles]
|
||||||
[status-im.ui.screens.stickers.views :as stickers]))
|
[status-im.ui.screens.stickers.views :as stickers]))
|
||||||
|
@ -19,6 +20,14 @@
|
||||||
:component home/home}
|
:component home/home}
|
||||||
{:name :referral-enclav
|
{:name :referral-enclav
|
||||||
:component referrals.public-chat/view}
|
:component referrals.public-chat/view}
|
||||||
|
{:name :communities
|
||||||
|
:transition :presentation-ios
|
||||||
|
:insets {:bottom true}
|
||||||
|
:component communities/communities}
|
||||||
|
{:name :community
|
||||||
|
:transition :presentation-ios
|
||||||
|
:insets {:bottom true}
|
||||||
|
:component communities/community}
|
||||||
{:name :chat
|
{:name :chat
|
||||||
:component chat/chat}
|
:component chat/chat}
|
||||||
{:name :group-chat-profile
|
{:name :group-chat-profile
|
||||||
|
|
|
@ -154,7 +154,6 @@
|
||||||
:transition :presentation-ios
|
:transition :presentation-ios
|
||||||
:insets {:bottom true}
|
:insets {:bottom true}
|
||||||
:component contact/profile}]
|
:component contact/profile}]
|
||||||
|
|
||||||
(when config/quo-preview-enabled?
|
(when config/quo-preview-enabled?
|
||||||
[{:name :quo-preview
|
[{:name :quo-preview
|
||||||
:insets {:top false :bottom false}
|
:insets {:top false :bottom false}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
[status-im.ui.screens.routing.main :as routing]
|
[status-im.ui.screens.routing.main :as routing]
|
||||||
[status-im.ui.screens.signing.views :as signing]
|
[status-im.ui.screens.signing.views :as signing]
|
||||||
[status-im.ui.screens.popover.views :as popover]
|
[status-im.ui.screens.popover.views :as popover]
|
||||||
|
[status-im.ui.screens.communities.views :as communities]
|
||||||
[status-im.ui.screens.multiaccounts.recover.views :as recover.views]
|
[status-im.ui.screens.multiaccounts.recover.views :as recover.views]
|
||||||
[status-im.ui.screens.wallet.send.views :as wallet]
|
[status-im.ui.screens.wallet.send.views :as wallet]
|
||||||
[status-im.ui.components.status-bar.view :as statusbar]
|
[status-im.ui.components.status-bar.view :as statusbar]
|
||||||
|
@ -49,6 +50,18 @@
|
||||||
(= view :learn-more)
|
(= view :learn-more)
|
||||||
(merge about-app/learn-more)
|
(merge about-app/learn-more)
|
||||||
|
|
||||||
|
(= view :create-community)
|
||||||
|
(merge communities/create-sheet)
|
||||||
|
|
||||||
|
(= view :import-community)
|
||||||
|
(merge communities/import-sheet)
|
||||||
|
|
||||||
|
(= view :create-community-channel)
|
||||||
|
(merge communities/create-channel-sheet)
|
||||||
|
|
||||||
|
(= view :invite-people-community)
|
||||||
|
(merge communities/invite-people-sheet)
|
||||||
|
|
||||||
(= view :recover-sheet)
|
(= view :recover-sheet)
|
||||||
(merge recover.views/bottom-sheet))]
|
(merge recover.views/bottom-sheet))]
|
||||||
[quo/bottom-sheet opts
|
[quo/bottom-sheet opts
|
||||||
|
|
|
@ -46,6 +46,10 @@
|
||||||
(def referrals-invite-enabled? (enabled? (get-config :ENABLE_REFERRAL_INVITE "0")))
|
(def referrals-invite-enabled? (enabled? (get-config :ENABLE_REFERRAL_INVITE "0")))
|
||||||
(def quo-preview-enabled? (enabled? (get-config :ENABLE_QUO_PREVIEW "0")))
|
(def quo-preview-enabled? (enabled? (get-config :ENABLE_QUO_PREVIEW "0")))
|
||||||
(def google-free (enabled? (get-config :GOOGLE_FREE "0")))
|
(def google-free (enabled? (get-config :GOOGLE_FREE "0")))
|
||||||
|
(def communities-enabled? (enabled? (get-config :COMMUNITIES_ENABLED "0")))
|
||||||
|
(def communities-management-enabled? (and (enabled? (get-config :COMMUNITIES_MANAGEMENT_ENABLED "0"))
|
||||||
|
communities-enabled?))
|
||||||
|
|
||||||
;; CONFIG VALUES
|
;; CONFIG VALUES
|
||||||
(def log-level
|
(def log-level
|
||||||
(string/upper-case (get-config :LOG_LEVEL "")))
|
(string/upper-case (get-config :LOG_LEVEL "")))
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
(when-not (= json "undefined")
|
(when-not (= json "undefined")
|
||||||
(try
|
(try
|
||||||
(js->clj (.parse js/JSON json))
|
(js->clj (.parse js/JSON json))
|
||||||
(catch js/Error _ (when (string? json) json)))))
|
(catch js/Error _
|
||||||
|
(when (string? json) json)))))
|
||||||
|
|
||||||
(def serialize clj->json)
|
(def serialize clj->json)
|
||||||
(defn deserialize [o] (try (json->clj o)
|
(defn deserialize [o] (try (json->clj o)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
|
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
|
||||||
"owner": "status-im",
|
"owner": "status-im",
|
||||||
"repo": "status-go",
|
"repo": "status-go",
|
||||||
"version": "v0.66.2",
|
"version": "v0.67.0",
|
||||||
"commit-sha1": "fee08aafbe0cdad352a4bdccff2ec883a3443b9c",
|
"commit-sha1": "f5482ec187b981dd77d184cc7003dcc0c6ae5d22",
|
||||||
"src-sha256": "0q5x70mdya3561dyigmkickhb8hkz92d14cc9hhwmbkpz41bcrd8"
|
"src-sha256": "18bzsf1nskvsvkxxw9v8v4zpgxfaag7q6a07fbdmz7f0y3a3mxjz"
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,6 +145,17 @@
|
||||||
"close-app-content": "The app will stop and close. When you reopen it, the selected network will be used",
|
"close-app-content": "The app will stop and close. When you reopen it, the selected network will be used",
|
||||||
"close-app-title": "Warning!",
|
"close-app-title": "Warning!",
|
||||||
"command-button-send": "Send",
|
"command-button-send": "Send",
|
||||||
|
"communities": "Communities",
|
||||||
|
"name-your-channel": "Name your channel",
|
||||||
|
"give-a-short-description": "Give a short description",
|
||||||
|
"communities-alpha": "Communities (alpha)",
|
||||||
|
"communities-verified": "✓ Verified Status Community",
|
||||||
|
"create-community": "Create a community",
|
||||||
|
"create-channel": "Create a channel",
|
||||||
|
"import-community": "Import a community",
|
||||||
|
"name-your-community": "Name your community",
|
||||||
|
"name-your-community-placeholder": "A catchy name",
|
||||||
|
"give-a-short-description-community": "Give it a short description",
|
||||||
"complete-hardwallet-setup": "This card is now linked. You need it to sign transactions and unlock your keys",
|
"complete-hardwallet-setup": "This card is now linked. You need it to sign transactions and unlock your keys",
|
||||||
"completed": "Completed",
|
"completed": "Completed",
|
||||||
"confirm": "Confirm",
|
"confirm": "Confirm",
|
||||||
|
@ -355,6 +366,7 @@
|
||||||
"empty-chat-description": "There are no messages \nin this chat yet",
|
"empty-chat-description": "There are no messages \nin this chat yet",
|
||||||
"empty-chat-description-one-to-one": "Any messages you send here are encrypted and can only be read by you and ",
|
"empty-chat-description-one-to-one": "Any messages you send here are encrypted and can only be read by you and ",
|
||||||
"empty-chat-description-public": "It's been quiet here for the last {{quiet-hours}}. Start the conversation or ",
|
"empty-chat-description-public": "It's been quiet here for the last {{quiet-hours}}. Start the conversation or ",
|
||||||
|
"empty-chat-description-community": "It's been quiet here for the last {{quiet-hours}}.",
|
||||||
"empty-chat-description-public-share-this": "share this chat.",
|
"empty-chat-description-public-share-this": "share this chat.",
|
||||||
"enable": "Enable",
|
"enable": "Enable",
|
||||||
"encrypt-with-password": "Encrypt with password",
|
"encrypt-with-password": "Encrypt with password",
|
||||||
|
@ -466,6 +478,7 @@
|
||||||
"ethereum-node-started-incorrectly-title": "Ethereum node started incorrectly",
|
"ethereum-node-started-incorrectly-title": "Ethereum node started incorrectly",
|
||||||
"etherscan-lookup": "Look up on Etherscan",
|
"etherscan-lookup": "Look up on Etherscan",
|
||||||
"export-account": "Export account",
|
"export-account": "Export account",
|
||||||
|
"export-key": "Export key",
|
||||||
"failed": "Failed",
|
"failed": "Failed",
|
||||||
"faq": "Frequently asked questions",
|
"faq": "Frequently asked questions",
|
||||||
"fetch-messages": "↓ Fetch messages",
|
"fetch-messages": "↓ Fetch messages",
|
||||||
|
@ -574,9 +587,11 @@
|
||||||
"invalid-pairing-password": "Invalid pairing password",
|
"invalid-pairing-password": "Invalid pairing password",
|
||||||
"invalid-range": "Invalid format, must be between {{min}} and {{max}}",
|
"invalid-range": "Invalid format, must be between {{min}} and {{max}}",
|
||||||
"join-me": "Hey join me on Status: {{url}}",
|
"join-me": "Hey join me on Status: {{url}}",
|
||||||
|
"join-a-community": "or join a community",
|
||||||
"http-gateway-error": "Oops, request failed!",
|
"http-gateway-error": "Oops, request failed!",
|
||||||
"sign-request-failed": "Could not sign message",
|
"sign-request-failed": "Could not sign message",
|
||||||
"invite-friends": "Invite friends",
|
"invite-friends": "Invite friends",
|
||||||
|
"invite-people": "Invite people",
|
||||||
"invite-reward": "Earn crypto for every friend you invite!",
|
"invite-reward": "Earn crypto for every friend you invite!",
|
||||||
"invite-select-account": "Select an account to receive your referral bonus",
|
"invite-select-account": "Select an account to receive your referral bonus",
|
||||||
"invited": "invited",
|
"invited": "invited",
|
||||||
|
@ -681,6 +696,7 @@
|
||||||
"learn-more": "Learn more",
|
"learn-more": "Learn more",
|
||||||
"learn-more-about-keycard": "Learn more about Keycard",
|
"learn-more-about-keycard": "Learn more about Keycard",
|
||||||
"leave": "Leave",
|
"leave": "Leave",
|
||||||
|
"joined": "Joined",
|
||||||
"leave-group": "Leave group",
|
"leave-group": "Leave group",
|
||||||
"left": "left",
|
"left": "left",
|
||||||
"lets-go": "Let's go",
|
"lets-go": "Let's go",
|
||||||
|
|
Loading…
Reference in New Issue