parent
973bdb61b3
commit
eae66c967e
|
@ -64,7 +64,7 @@
|
||||||
:justify-content :space-between})}]
|
:justify-content :space-between})}]
|
||||||
children))
|
children))
|
||||||
|
|
||||||
(defn- icon-column
|
(defn icon-column
|
||||||
[{:keys [icon icon-bg-color icon-color size icon-container-style]}]
|
[{:keys [icon icon-bg-color icon-color size icon-container-style]}]
|
||||||
(when icon
|
(when icon
|
||||||
(let [icon-size (size->icon-size size)]
|
(let [icon-size (size->icon-size size)]
|
||||||
|
|
|
@ -162,9 +162,10 @@
|
||||||
|
|
||||||
(fx/defn add-public-chat
|
(fx/defn add-public-chat
|
||||||
"Adds new public group chat to db"
|
"Adds new public group chat to db"
|
||||||
[cofx topic]
|
[cofx topic profile-public-key]
|
||||||
(upsert-chat cofx
|
(upsert-chat cofx
|
||||||
{:chat-id topic
|
{:chat-id topic
|
||||||
|
:profile-public-key profile-public-key
|
||||||
:is-active true
|
:is-active true
|
||||||
:name topic
|
:name topic
|
||||||
:chat-name (str "#" topic)
|
:chat-name (str "#" topic)
|
||||||
|
@ -243,8 +244,9 @@
|
||||||
|
|
||||||
(fx/defn navigate-to-chat
|
(fx/defn navigate-to-chat
|
||||||
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
|
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
|
||||||
[cofx chat-id]
|
[{db :db :as cofx} chat-id]
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
|
{:db (assoc db :inactive-chat-id chat-id)}
|
||||||
(preload-chat-data chat-id)
|
(preload-chat-data chat-id)
|
||||||
(navigation/navigate-to-cofx :chat-stack {:screen :chat})))
|
(navigation/navigate-to-cofx :chat-stack {:screen :chat})))
|
||||||
|
|
||||||
|
@ -260,15 +262,18 @@
|
||||||
(transport.filters/load-chat chat-id)
|
(transport.filters/load-chat chat-id)
|
||||||
(navigate-to-chat chat-id))))
|
(navigate-to-chat chat-id))))
|
||||||
|
|
||||||
|
(defn profile-chat-topic [public-key]
|
||||||
|
(str "@" public-key))
|
||||||
|
|
||||||
(fx/defn start-public-chat
|
(fx/defn start-public-chat
|
||||||
"Starts a new public chat"
|
"Starts a new public chat"
|
||||||
[cofx topic {:keys [dont-navigate?]}]
|
[cofx topic {:keys [dont-navigate? profile-public-key]}]
|
||||||
(if (new-public-chat.db/valid-topic? topic)
|
(if (or (new-public-chat.db/valid-topic? topic) profile-public-key)
|
||||||
(if (active-chat? cofx topic)
|
(if (active-chat? cofx topic)
|
||||||
(when-not dont-navigate?
|
(when-not dont-navigate?
|
||||||
(navigate-to-chat cofx topic))
|
(navigate-to-chat cofx topic))
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
(add-public-chat topic)
|
(add-public-chat topic profile-public-key)
|
||||||
(transport.filters/load-chat topic)
|
(transport.filters/load-chat topic)
|
||||||
#(when-not dont-navigate?
|
#(when-not dont-navigate?
|
||||||
(navigate-to-chat % topic))))
|
(navigate-to-chat % topic))))
|
||||||
|
|
|
@ -142,6 +142,15 @@
|
||||||
:image-path (utils/safe-replace image-path #"file://" "")
|
:image-path (utils/safe-replace image-path #"file://" "")
|
||||||
:text (i18n/label :t/update-to-see-image)})))))
|
:text (i18n/label :t/update-to-see-image)})))))
|
||||||
|
|
||||||
|
(fx/defn send-my-status-message
|
||||||
|
"when not empty, proceed by sending text message with public key topic"
|
||||||
|
{:events [:profile.ui/send-my-status-message]}
|
||||||
|
[{{:keys [current-chat-id] :as db} :db :as cofx}]
|
||||||
|
(let [{:keys [input-text]} (get-in db [:chat/inputs current-chat-id])]
|
||||||
|
(fx/merge cofx
|
||||||
|
(send-image)
|
||||||
|
(send-plain-text-message input-text current-chat-id))))
|
||||||
|
|
||||||
(fx/defn send-audio-message
|
(fx/defn send-audio-message
|
||||||
[cofx audio-path duration current-chat-id]
|
[cofx audio-path duration current-chat-id]
|
||||||
(when-not (string/blank? audio-path)
|
(when-not (string/blank? audio-path)
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
add-timestamp))
|
add-timestamp))
|
||||||
|
|
||||||
;; any message that comes after this amount of ms will be grouped separately
|
;; any message that comes after this amount of ms will be grouped separately
|
||||||
(def ^:private group-ms 60000)
|
(def ^:private group-ms 300000)
|
||||||
|
|
||||||
(defn same-group?
|
(defn same-group?
|
||||||
"Whether a message is in the same group as the one after it.
|
"Whether a message is in the same group as the one after it.
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
(with-redefs [gfycat/generate-gfy (constantly "generated")
|
(with-redefs [gfycat/generate-gfy (constantly "generated")
|
||||||
identicon/identicon (constantly "generated")]
|
identicon/identicon (constantly "generated")]
|
||||||
(let [topic "topic"
|
(let [topic "topic"
|
||||||
fx (chat/add-public-chat {:db {}} topic)
|
fx (chat/add-public-chat {:db {}} topic nil)
|
||||||
chat (get-in fx [:db :chats topic])]
|
chat (get-in fx [:db :chats topic])]
|
||||||
(testing "it sets the name"
|
(testing "it sets the name"
|
||||||
(is (= topic (:name chat))))
|
(is (= topic (:name chat))))
|
||||||
|
|
|
@ -7,12 +7,6 @@
|
||||||
[status-im.navigation :as navigation]
|
[status-im.navigation :as navigation]
|
||||||
[status-im.utils.fx :as fx]))
|
[status-im.utils.fx :as fx]))
|
||||||
|
|
||||||
(fx/defn remove-current-chat-id
|
|
||||||
[{:keys [db] :as cofx}]
|
|
||||||
(fx/merge cofx
|
|
||||||
{:db (dissoc db :current-chat-id)}
|
|
||||||
(navigation/navigate-to-cofx :home {})))
|
|
||||||
|
|
||||||
(fx/defn clean-up-chat
|
(fx/defn clean-up-chat
|
||||||
[{:keys [db] :as cofx}
|
[{:keys [db] :as cofx}
|
||||||
public-key
|
public-key
|
||||||
|
@ -48,7 +42,7 @@
|
||||||
public-key)
|
public-key)
|
||||||
(assoc :last-updated now)
|
(assoc :last-updated now)
|
||||||
(update :system-tags (fnil conj #{}) :contact/blocked))
|
(update :system-tags (fnil conj #{}) :contact/blocked))
|
||||||
from-one-to-one-chat? (not (get-in db [:chats (:current-chat-id db) :group-chat]))]
|
from-one-to-one-chat? (not (get-in db [:chats (:inactive-chat-id db) :group-chat]))]
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
{:db (-> db
|
{:db (-> db
|
||||||
;; add the contact to blocked contacts
|
;; add the contact to blocked contacts
|
||||||
|
@ -61,7 +55,7 @@
|
||||||
(re-frame/dispatch [:hide-popover])))
|
(re-frame/dispatch [:hide-popover])))
|
||||||
;; reset navigation to avoid going back to non existing one to one chat
|
;; reset navigation to avoid going back to non existing one to one chat
|
||||||
(if from-one-to-one-chat?
|
(if from-one-to-one-chat?
|
||||||
remove-current-chat-id
|
(navigation/navigate-to-cofx :home {})
|
||||||
(navigation/navigate-back)))))
|
(navigation/navigate-back)))))
|
||||||
|
|
||||||
(fx/defn unblock-contact
|
(fx/defn unblock-contact
|
||||||
|
|
|
@ -8,10 +8,12 @@
|
||||||
(def one-to-one-chat-type 1)
|
(def one-to-one-chat-type 1)
|
||||||
(def public-chat-type 2)
|
(def public-chat-type 2)
|
||||||
(def private-group-chat-type 3)
|
(def private-group-chat-type 3)
|
||||||
|
(def profile-chat-type 4)
|
||||||
|
|
||||||
(defn type->rpc [{:keys [public? group-chat] :as chat}]
|
(defn type->rpc [{:keys [public? group-chat profile-public-key] :as chat}]
|
||||||
(assoc chat :chatType (cond
|
(assoc chat :chatType (cond
|
||||||
public? public-chat-type
|
public? public-chat-type
|
||||||
|
profile-public-key profile-chat-type
|
||||||
group-chat private-group-chat-type
|
group-chat private-group-chat-type
|
||||||
:else one-to-one-chat-type)))
|
:else one-to-one-chat-type)))
|
||||||
|
|
||||||
|
@ -21,6 +23,7 @@
|
||||||
:chat-name (str "#" name)
|
:chat-name (str "#" name)
|
||||||
:public? true
|
:public? true
|
||||||
:group-chat true)
|
:group-chat true)
|
||||||
|
(= profile-chat-type chatType) (assoc chat :public? true)
|
||||||
(= private-group-chat-type chatType) (assoc chat
|
(= private-group-chat-type chatType) (assoc chat
|
||||||
:chat-name name
|
:chat-name name
|
||||||
:public? false
|
:public? false
|
||||||
|
@ -72,7 +75,8 @@
|
||||||
:last-message :lastMessage
|
:last-message :lastMessage
|
||||||
: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})
|
||||||
(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
|
||||||
|
@ -89,7 +93,8 @@
|
||||||
:lastMessage :last-message
|
:lastMessage :last-message
|
||||||
:active :is-active
|
:active :is-active
|
||||||
:lastClockValue :last-clock-value
|
:lastClockValue :last-clock-value
|
||||||
:invitationAdmin :invitation-admin})
|
:invitationAdmin :invitation-admin
|
||||||
|
:profile :profile-public-key})
|
||||||
(update :last-message #(when % (messages/<-rpc %)))
|
(update :last-message #(when % (messages/<-rpc %)))
|
||||||
(dissoc :chatType :members)))
|
(dissoc :chatType :members)))
|
||||||
|
|
||||||
|
|
|
@ -1245,10 +1245,24 @@
|
||||||
(fn [{:keys [db]} [_ dimensions]]
|
(fn [{:keys [db]} [_ dimensions]]
|
||||||
{:db (assoc db :dimensions/window (dimensions/window dimensions))}))
|
{:db (assoc db :dimensions/window (dimensions/window dimensions))}))
|
||||||
|
|
||||||
|
(fx/defn reset-current-profile-chat [{:keys [db] :as cofx} public-key]
|
||||||
|
(let [chat-id (chat/profile-chat-topic public-key)]
|
||||||
|
(when-not (= (:current-chat-id db) chat-id)
|
||||||
|
(fx/merge cofx
|
||||||
|
(chat/start-public-chat chat-id {:dont-navigate? true :profile-public-key public-key})
|
||||||
|
(chat/offload-all-messages)
|
||||||
|
(chat/preload-chat-data chat-id)))))
|
||||||
|
|
||||||
|
(fx/defn reset-current-chat [{:keys [db] :as cofx} chat-id]
|
||||||
|
(when-not (= (:current-chat-id db) chat-id)
|
||||||
|
(fx/merge cofx
|
||||||
|
(chat/offload-all-messages)
|
||||||
|
(chat/preload-chat-data chat-id))))
|
||||||
|
|
||||||
;; NOTE: Will be removed with the keycard PR
|
;; NOTE: Will be removed with the keycard PR
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:screens/on-will-focus
|
:screens/on-will-focus
|
||||||
(fn [cofx [_ view-id]]
|
(fn [{:keys [db] :as cofx} [_ view-id]]
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
#(case view-id
|
#(case view-id
|
||||||
:keycard-settings (keycard/settings-screen-did-load %)
|
:keycard-settings (keycard/settings-screen-did-load %)
|
||||||
|
@ -1257,10 +1271,28 @@
|
||||||
:keycard-login-pin (keycard/enter-pin-screen-did-load %)
|
:keycard-login-pin (keycard/enter-pin-screen-did-load %)
|
||||||
:add-new-account-pin (keycard/enter-pin-screen-did-load %)
|
:add-new-account-pin (keycard/enter-pin-screen-did-load %)
|
||||||
:keycard-authentication-method (keycard/authentication-method-screen-did-load %)
|
:keycard-authentication-method (keycard/authentication-method-screen-did-load %)
|
||||||
;; We need this as if you click on universal-links you transition
|
(:chat :group-chat-profile) (reset-current-chat % (get db :inactive-chat-id))
|
||||||
;; from chat to chat, and therefore we won't be loading new
|
|
||||||
;; messages
|
|
||||||
:chat (chat.loading/load-messages %)
|
|
||||||
:multiaccounts (keycard/multiaccounts-screen-did-load %)
|
:multiaccounts (keycard/multiaccounts-screen-did-load %)
|
||||||
(:wallet-stack :wallet) (wallet.events/wallet-will-focus %)
|
(:wallet-stack :wallet) (wallet.events/wallet-will-focus %)
|
||||||
|
(:my-profile :profile-stack)
|
||||||
|
(reset-current-profile-chat % (get-in % [:db :multiaccount :public-key]))
|
||||||
|
:profile
|
||||||
|
(reset-current-profile-chat % (get-in % [:db :contacts/identity]))
|
||||||
nil))))
|
nil))))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:screens/tab-will-change
|
||||||
|
(fn [{:keys [db] :as cofx} [_ view-id]]
|
||||||
|
(fx/merge cofx
|
||||||
|
#(case view-id
|
||||||
|
;;when we back to chat we want to show inactive chat
|
||||||
|
:chat
|
||||||
|
(reset-current-chat % (get db :inactive-chat-id))
|
||||||
|
|
||||||
|
(:my-profile :profile-stack)
|
||||||
|
(reset-current-profile-chat % (get-in % [:db :multiaccount :public-key]))
|
||||||
|
|
||||||
|
:profile
|
||||||
|
(reset-current-profile-chat % (get-in % [:db :contacts/identity]))
|
||||||
|
|
||||||
|
nil))))
|
|
@ -63,10 +63,10 @@
|
||||||
:params {:screen :my-profile}})
|
:params {:screen :my-profile}})
|
||||||
|
|
||||||
(and public-key (not own))
|
(and public-key (not own))
|
||||||
(navigation/navigate-to-cofx (assoc-in cofx [:db :contacts/identity] public-key)
|
(fx/merge cofx
|
||||||
:tabs
|
{:db (assoc db :contacts/identity public-key)
|
||||||
{:screen :chat-stack
|
:dispatch [:navigate-to :profile]}
|
||||||
:params {:screen :profile}})
|
(navigation/navigate-back))
|
||||||
|
|
||||||
:else
|
:else
|
||||||
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
|
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
|
||||||
|
|
|
@ -123,6 +123,7 @@
|
||||||
(reg-root-key-sub :chats/mention-suggestions :chats/mention-suggestions)
|
(reg-root-key-sub :chats/mention-suggestions :chats/mention-suggestions)
|
||||||
(reg-root-key-sub :chats/cursor :chats/cursor)
|
(reg-root-key-sub :chats/cursor :chats/cursor)
|
||||||
(reg-root-key-sub :chats/input-with-mentions :chats/input-with-mentions)
|
(reg-root-key-sub :chats/input-with-mentions :chats/input-with-mentions)
|
||||||
|
(reg-root-key-sub :inactive-chat-id :inactive-chat-id)
|
||||||
;;browser
|
;;browser
|
||||||
(reg-root-key-sub :browsers :browser/browsers)
|
(reg-root-key-sub :browsers :browser/browsers)
|
||||||
(reg-root-key-sub :browser/options :browser/options)
|
(reg-root-key-sub :browser/options :browser/options)
|
||||||
|
@ -612,8 +613,8 @@
|
||||||
:chats/active-chats
|
:chats/active-chats
|
||||||
:<- [::chats]
|
:<- [::chats]
|
||||||
(fn [chats]
|
(fn [chats]
|
||||||
(reduce-kv (fn [acc id {:keys [is-active] :as chat}]
|
(reduce-kv (fn [acc id {:keys [is-active profile-public-key] :as chat}]
|
||||||
(if is-active
|
(if (and is-active (not profile-public-key))
|
||||||
(assoc acc id chat)
|
(assoc acc id chat)
|
||||||
acc))
|
acc))
|
||||||
{}
|
{}
|
||||||
|
@ -650,9 +651,10 @@
|
||||||
:chats/current-chat
|
:chats/current-chat
|
||||||
:<- [:chats/current-raw-chat]
|
:<- [:chats/current-raw-chat]
|
||||||
:<- [:multiaccount/public-key]
|
:<- [:multiaccount/public-key]
|
||||||
|
:<- [:inactive-chat-id]
|
||||||
(fn [[{:keys [group-chat] :as current-chat}
|
(fn [[{:keys [group-chat] :as current-chat}
|
||||||
my-public-key]]
|
my-public-key inactive-chat-id]]
|
||||||
(when current-chat
|
(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)
|
||||||
(assoc :show-input? true)
|
(assoc :show-input? true)
|
||||||
|
@ -812,7 +814,7 @@
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:chats/sending-image
|
:chats/sending-image
|
||||||
:<- [:chats/current-chat]
|
:<- [:chats/current-raw-chat]
|
||||||
(fn [{:keys [metadata]}]
|
(fn [{:keys [metadata]}]
|
||||||
(get-in metadata [:sending-image])))
|
(get-in metadata [:sending-image])))
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
(defn is-public-key? [k]
|
(defn is-public-key? [k]
|
||||||
(string/starts-with? k "0x"))
|
(and
|
||||||
|
(string? k)
|
||||||
|
(string/starts-with? k "0x")))
|
||||||
|
|
||||||
(defn load-filters-rpc [chats on-success on-failure]
|
(defn load-filters-rpc [chats on-success on-failure]
|
||||||
(json-rpc/call {:method (json-rpc/call-ext-method "loadFilters")
|
(json-rpc/call {:method (json-rpc/call-ext-method "loadFilters")
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
(ns status-im.ui.components.plus-button
|
||||||
|
(:require [status-im.ui.components.colors :as colors]
|
||||||
|
[quo.core :as quo]
|
||||||
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.ui.components.icons.vector-icons :as icons]))
|
||||||
|
|
||||||
|
(def action-button-container
|
||||||
|
{:position :absolute
|
||||||
|
:z-index 2
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :center
|
||||||
|
:left 0
|
||||||
|
:right 0
|
||||||
|
:bottom 16
|
||||||
|
:height 40})
|
||||||
|
|
||||||
|
(defn action-button []
|
||||||
|
{:width 40
|
||||||
|
:height 40
|
||||||
|
:background-color colors/blue
|
||||||
|
:border-radius 20
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :center
|
||||||
|
:shadow-offset {:width 0 :height 1}
|
||||||
|
:shadow-radius 6
|
||||||
|
:shadow-opacity 1
|
||||||
|
:shadow-color (if (colors/dark?)
|
||||||
|
"rgba(0, 0, 0, 0.75)"
|
||||||
|
"rgba(0, 12, 63, 0.2)")
|
||||||
|
:elevation 2})
|
||||||
|
|
||||||
|
(defn plus-button [{:keys [on-press loading accessibility-label]}]
|
||||||
|
[react/view action-button-container
|
||||||
|
[quo/button {:type :scale
|
||||||
|
:accessibility-label (or accessibility-label :plus-button)
|
||||||
|
:on-press on-press}
|
||||||
|
[react/view (action-button)
|
||||||
|
(if loading
|
||||||
|
[react/activity-indicator {:color colors/white-persist
|
||||||
|
:animating true}]
|
||||||
|
[icons/icon :main-icons/add {:color colors/white-persist}])]]])
|
|
@ -12,8 +12,9 @@
|
||||||
(def subtitle-margin 4)
|
(def subtitle-margin 4)
|
||||||
|
|
||||||
(defn container-style [{:keys [animation minimized]}]
|
(defn container-style [{:keys [animation minimized]}]
|
||||||
(merge {:flex-direction :row
|
(merge {:flex-direction :row
|
||||||
:align-items :center}
|
:padding-vertical 4
|
||||||
|
:align-items :center}
|
||||||
(if-not minimized
|
(if-not minimized
|
||||||
(:base spacing/padding-horizontal)
|
(:base spacing/padding-horizontal)
|
||||||
{:opacity animation})))
|
{:opacity animation})))
|
||||||
|
@ -36,7 +37,8 @@
|
||||||
(when-not minimized
|
(when-not minimized
|
||||||
{:padding-top subtitle-margin})))
|
{:padding-top subtitle-margin})))
|
||||||
|
|
||||||
(defn extended-header [{:keys [title photo color subtitle subtitle-icon on-press monospace]}]
|
(defn extended-header [{:keys [title photo color subtitle subtitle-icon on-press monospace bottom-separator]
|
||||||
|
:or {bottom-separator true}}]
|
||||||
(fn [{:keys [animation minimized]}]
|
(fn [{:keys [animation minimized]}]
|
||||||
(let [wrapper (if on-press
|
(let [wrapper (if on-press
|
||||||
[rn/touchable-opacity {:on-press on-press}]
|
[rn/touchable-opacity {:on-press on-press}]
|
||||||
|
@ -78,5 +80,5 @@
|
||||||
subtitle]])]]
|
subtitle]])]]
|
||||||
(when-not minimized
|
(when-not minimized
|
||||||
[animated/view {:pointer-events :none
|
[animated/view {:pointer-events :none
|
||||||
:style (header-bottom-separator)}])]]))))
|
:style (when bottom-separator (header-bottom-separator))}])]]))))
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
(def tabs
|
(def tabs
|
||||||
(reagent/adapt-react-class
|
(reagent/adapt-react-class
|
||||||
(fn [props]
|
(fn [props]
|
||||||
(let [{:keys [navigate index route]} (bean props)
|
(let [{:keys [navigate index route state]} (bean props)
|
||||||
{:keys [keyboard-shown]
|
{:keys [keyboard-shown]
|
||||||
:or {keyboard-shown false}} (when platform/android? (rn/use-keyboard))
|
:or {keyboard-shown false}} (when platform/android? (rn/use-keyboard))
|
||||||
{:keys [bottom]} (safe-area/use-safe-area)
|
{:keys [bottom]} (safe-area/use-safe-area)
|
||||||
|
@ -99,7 +99,10 @@
|
||||||
[tab
|
[tab
|
||||||
{:icon icon
|
{:icon icon
|
||||||
:label title
|
:label title
|
||||||
:on-press #(navigate (name nav-stack))
|
:on-press #(let [view-id (navigation/get-index-route-name route-index (bean state))]
|
||||||
|
(re-frame/dispatch-sync [:screens/tab-will-change view-id])
|
||||||
|
(reagent/flush)
|
||||||
|
(navigate (name nav-stack)))
|
||||||
:accessibility-label accessibility-label
|
:accessibility-label accessibility-label
|
||||||
:count-subscription count-subscription
|
:count-subscription count-subscription
|
||||||
:active? (= (str index) (str route-index))
|
:active? (= (str index) (str route-index))
|
||||||
|
@ -113,5 +116,6 @@
|
||||||
index (get state :index)]
|
index (get state :index)]
|
||||||
(reagent/as-element
|
(reagent/as-element
|
||||||
[tabs {:navigate navigate
|
[tabs {:navigate navigate
|
||||||
|
:state (oget props "state")
|
||||||
:route (navigation/get-active-route-name state)
|
:route (navigation/get-active-route-name state)
|
||||||
:index index}])))
|
:index index}])))
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
(ns status-im.ui.components.tabs
|
||||||
|
(:require [status-im.ui.components.react :as react]
|
||||||
|
[status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
|
(defn tab-title [state key label active?]
|
||||||
|
[react/view {:align-items :center}
|
||||||
|
[react/touchable-highlight {:on-press #(swap! state assoc :tab key)
|
||||||
|
:underlay-color colors/gray-lighter
|
||||||
|
:accessibility-label (str label "-item-button")
|
||||||
|
:style {:border-radius 8}}
|
||||||
|
[react/view {:padding-horizontal 12 :padding-vertical 8}
|
||||||
|
[react/text {:style {:font-weight "500" :color (if active? colors/blue colors/gray) :line-height 22}}
|
||||||
|
label]]]
|
||||||
|
(when active?
|
||||||
|
[react/view {:width 24 :height 3 :border-radius 4 :background-color colors/blue}])])
|
|
@ -95,7 +95,7 @@
|
||||||
(if new-contact?
|
(if new-contact?
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
(contact/add-contact chat-key nil)
|
(contact/add-contact chat-key nil)
|
||||||
(navigation/navigate-to-cofx :contacts-list {}))
|
(navigation/navigate-to-cofx :my-profile {}))
|
||||||
(chat/start-chat cofx chat-key))
|
(chat/start-chat cofx chat-key))
|
||||||
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
|
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
|
||||||
:content (get-validation-label validation-result)
|
:content (get-validation-label validation-result)
|
||||||
|
|
|
@ -271,7 +271,6 @@
|
||||||
(js/setTimeout #(on-long-press-fn on-long-press message content) 200))
|
(js/setTimeout #(on-long-press-fn on-long-press message content) 200))
|
||||||
(on-long-press-fn on-long-press message content)))})
|
(on-long-press-fn on-long-press message content)))})
|
||||||
[react/view (assoc (style/message-view message)
|
[react/view (assoc (style/message-view message)
|
||||||
:remove-clipped-subviews (not outgoing)
|
|
||||||
:max-height (when-not (or outgoing modal)
|
:max-height (when-not (or outgoing modal)
|
||||||
(if @collapsible?
|
(if @collapsible?
|
||||||
(if @collapsed? message-height-px nil)
|
(if @collapsed? message-height-px nil)
|
||||||
|
|
|
@ -159,7 +159,7 @@
|
||||||
:accessibility-label :delete-transaccent-button
|
:accessibility-label :delete-transaccent-button
|
||||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/delete-message chat-id message-id])}]]))
|
:on-press #(hide-sheet-and-dispatch [:chat.ui/delete-message chat-id message-id])}]]))
|
||||||
|
|
||||||
(defn image-long-press [{:keys [content identicon from outgoing] :as message} from-preview?]
|
(defn image-long-press [{:keys [content identicon from outgoing cant-be-replied] :as message} from-preview?]
|
||||||
(fn []
|
(fn []
|
||||||
(let [contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])]
|
(let [contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])]
|
||||||
[react/view
|
[react/view
|
||||||
|
@ -177,14 +177,15 @@
|
||||||
(when from-preview?
|
(when from-preview?
|
||||||
(re-frame/dispatch [:navigate-back]))
|
(re-frame/dispatch [:navigate-back]))
|
||||||
(hide-sheet-and-dispatch [:chat.ui/show-profile from]))}])
|
(hide-sheet-and-dispatch [:chat.ui/show-profile from]))}])
|
||||||
[quo/list-item
|
(when-not cant-be-replied
|
||||||
{:theme :accent
|
[quo/list-item
|
||||||
:title (i18n/label :t/message-reply)
|
{:theme :accent
|
||||||
:icon :main-icons/reply
|
:title (i18n/label :t/message-reply)
|
||||||
:on-press #(do
|
:icon :main-icons/reply
|
||||||
(when from-preview?
|
:on-press #(do
|
||||||
(re-frame/dispatch [:navigate-back]))
|
(when from-preview?
|
||||||
(hide-sheet-and-dispatch [:chat.ui/reply-to-message message]))}]
|
(re-frame/dispatch [:navigate-back]))
|
||||||
|
(hide-sheet-and-dispatch [:chat.ui/reply-to-message message]))}])
|
||||||
;; we have only base64 string for image, so we need to find a way how to copy it
|
;; we have only base64 string for image, so we need to find a way how to copy it
|
||||||
#_[quo/list-item
|
#_[quo/list-item
|
||||||
{:theme :accent
|
{:theme :accent
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
:height 48
|
:height 48
|
||||||
:align-items :center
|
:align-items :center
|
||||||
:justify-content :center
|
:justify-content :center
|
||||||
:border-color colors/black-transparent
|
:border-color colors/gray-lighter
|
||||||
:border-top-width 1
|
:border-top-width 1
|
||||||
:border-bottom-width 1})
|
:border-bottom-width 1})
|
||||||
|
|
||||||
|
|
|
@ -281,36 +281,37 @@
|
||||||
(fn []
|
(fn []
|
||||||
(let [{:keys [chat-id show-input? group-chat admins invitation-admin] :as current-chat}
|
(let [{:keys [chat-id show-input? group-chat admins invitation-admin] :as current-chat}
|
||||||
@(re-frame/subscribe [:chats/current-chat])]
|
@(re-frame/subscribe [:chats/current-chat])]
|
||||||
[react/view {:style {:flex 1}}
|
(when current-chat
|
||||||
[connectivity/connectivity
|
|
||||||
[topbar]
|
|
||||||
[react/view {:style {:flex 1}}
|
[react/view {:style {:flex 1}}
|
||||||
(if group-chat
|
[connectivity/connectivity
|
||||||
[invitation-requests chat-id admins]
|
[topbar]
|
||||||
[add-contact-bar chat-id])
|
[react/view {:style {:flex 1}}
|
||||||
[messages-view {:chat current-chat
|
(if group-chat
|
||||||
:bottom-space (max @bottom-space @panel-space)
|
[invitation-requests chat-id admins]
|
||||||
:pan-responder pan-responder
|
[add-contact-bar chat-id])
|
||||||
:space-keeper space-keeper}]]]
|
[messages-view {:chat current-chat
|
||||||
(when (and group-chat invitation-admin)
|
:bottom-space (max @bottom-space @panel-space)
|
||||||
[accessory/view {:y position-y
|
:pan-responder pan-responder
|
||||||
:on-update-inset on-update}
|
:space-keeper space-keeper}]]]
|
||||||
[invitation-bar chat-id]])
|
(when (and group-chat invitation-admin)
|
||||||
;; NOTE(rasom): on android we have to place `autocomplete-mentions`
|
[accessory/view {:y position-y
|
||||||
;; outside `accessory/view` because otherwise :keyboardShouldPersistTaps
|
:on-update-inset on-update}
|
||||||
;; :always doesn't work and keyboard is hidden on pressing suggestion.
|
[invitation-bar chat-id]])
|
||||||
;; Scrolling of suggestions doesn't work neither in this case.
|
;; NOTE(rasom): on android we have to place `autocomplete-mentions`
|
||||||
(when platform/android?
|
;; outside `accessory/view` because otherwise :keyboardShouldPersistTaps
|
||||||
[components/autocomplete-mentions text-input-ref])
|
;; :always doesn't work and keyboard is hidden on pressing suggestion.
|
||||||
(when show-input?
|
;; Scrolling of suggestions doesn't work neither in this case.
|
||||||
[accessory/view {:y position-y
|
(when platform/android?
|
||||||
:pan-state pan-state
|
[components/autocomplete-mentions text-input-ref])
|
||||||
:has-panel (boolean @active-panel)
|
(when show-input?
|
||||||
:on-close #(set-active-panel nil)
|
[accessory/view {:y position-y
|
||||||
:on-update-inset on-update}
|
:pan-state pan-state
|
||||||
[components/chat-toolbar
|
:has-panel (boolean @active-panel)
|
||||||
{:active-panel @active-panel
|
:on-close #(set-active-panel nil)
|
||||||
:set-active-panel set-active-panel
|
:on-update-inset on-update}
|
||||||
:text-input-ref text-input-ref
|
[components/chat-toolbar
|
||||||
:on-text-change on-text-change}]
|
{:active-panel @active-panel
|
||||||
[bottom-sheet @active-panel]])]))))
|
:set-active-panel set-active-panel
|
||||||
|
:text-input-ref text-input-ref
|
||||||
|
:on-text-change on-text-change}]
|
||||||
|
[bottom-sheet @active-panel]])])))))
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.ui.components.invite.views :as invite]
|
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[status-im.ui.components.topbar :as topbar])
|
[status-im.ui.components.topbar :as topbar]
|
||||||
|
[status-im.ui.components.icons.vector-icons :as icons])
|
||||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||||
|
|
||||||
(defn contacts-list-item [{:keys [public-key] :as contact}]
|
(defn contacts-list-item [{:keys [public-key] :as contact}]
|
||||||
|
@ -21,45 +21,50 @@
|
||||||
:chevron true
|
:chevron true
|
||||||
:on-press #(re-frame/dispatch [:chat.ui/show-profile public-key])}]))
|
:on-press #(re-frame/dispatch [:chat.ui/show-profile public-key])}]))
|
||||||
|
|
||||||
(defn add-new-contact []
|
|
||||||
[quo/list-item
|
|
||||||
{:icon :main-icons/add
|
|
||||||
:theme :accent
|
|
||||||
:title (i18n/label :t/add-new-contact)
|
|
||||||
:accessibility-label :add-new-contact-button
|
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :new-contact])}])
|
|
||||||
|
|
||||||
(defview contacts-list []
|
(defview contacts-list []
|
||||||
(letsubs [blocked-contacts-count [:contacts/blocked-count]
|
(letsubs [blocked-contacts-count [:contacts/blocked-count]
|
||||||
contacts [:contacts/active]]
|
contacts [:contacts/active]]
|
||||||
[react/view {:flex 1}
|
[:<>
|
||||||
[topbar/topbar {:title (i18n/label :t/contacts)}]
|
(when (pos? blocked-contacts-count)
|
||||||
[react/scroll-view {:flex 1}
|
[react/view {:margin-vertical 16}
|
||||||
[add-new-contact]
|
[quo/list-item
|
||||||
(when (pos? blocked-contacts-count)
|
{:title (i18n/label :t/blocked-users)
|
||||||
[react/view {:margin-vertical 16}
|
:icon :main-icons/cancel
|
||||||
[quo/list-item
|
:theme :negative
|
||||||
{:title (i18n/label :t/blocked-users)
|
:accessibility-label :blocked-users-list-button
|
||||||
:icon :main-icons/cancel
|
:chevron true
|
||||||
:theme :negative
|
:accessory :text
|
||||||
:accessibility-label :blocked-users-list-button
|
:accessory-text blocked-contacts-count
|
||||||
:chevron true
|
:on-press #(re-frame/dispatch [:navigate-to :blocked-users-list])}]])
|
||||||
:accessory :text
|
(if (seq contacts)
|
||||||
:accessory-text blocked-contacts-count
|
[list.views/flat-list
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :blocked-users-list])}]])
|
{:data contacts
|
||||||
(if (seq contacts)
|
:key-fn :address
|
||||||
[list.views/flat-list
|
:render-fn contacts-list-item
|
||||||
{:data contacts
|
:footer [react/view {:height 68}]}]
|
||||||
:key-fn :address
|
[react/view {:padding-horizontal 32 :margin-top 32}
|
||||||
:render-fn contacts-list-item}]
|
[react/view {:border-width 1
|
||||||
[react/view {:align-items :center :flex 1 :justify-content :center}
|
:border-color colors/gray-lighter
|
||||||
[react/text {:style {:color colors/gray :margin-vertical 24}}
|
:border-top-right-radius 16
|
||||||
(i18n/label :t/you-dont-have-contacts)]
|
:border-bottom-left-radius 16
|
||||||
[invite/button]])]]))
|
:border-top-left-radius 16
|
||||||
|
:border-bottom-right-radius 4
|
||||||
|
:padding-horizontal 12
|
||||||
|
:padding-vertical 6}
|
||||||
|
[react/text {:style {:color colors/gray :line-height 22}}
|
||||||
|
(i18n/label :t/contacts-descr)]]
|
||||||
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :new-contact])}
|
||||||
|
[react/view {:flex-direction :row
|
||||||
|
:align-items :center
|
||||||
|
:align-self :center
|
||||||
|
:padding 12}
|
||||||
|
[react/text {:style {:color colors/blue :margin-right 8}}
|
||||||
|
(i18n/label :t/add-contact)]
|
||||||
|
[icons/icon :main-icons/add-contact {:color colors/blue}]]]])]))
|
||||||
|
|
||||||
(defview blocked-users-list []
|
(defview blocked-users-list []
|
||||||
(letsubs [blocked-contacts [:contacts/blocked]]
|
(letsubs [blocked-contacts [:contacts/blocked]]
|
||||||
[react/view {:flex 1
|
[react/view {:flex 1
|
||||||
:background-color colors/white}
|
:background-color colors/white}
|
||||||
[topbar/topbar {:title (i18n/label :t/blocked-users)}]
|
[topbar/topbar {:title (i18n/label :t/blocked-users)}]
|
||||||
[react/scroll-view {:style {:background-color colors/white
|
[react/scroll-view {:style {:background-color colors/white
|
||||||
|
|
|
@ -59,30 +59,6 @@
|
||||||
:margin-horizontal 40
|
:margin-horizontal 40
|
||||||
:color colors/gray})
|
:color colors/gray})
|
||||||
|
|
||||||
(def action-button-container
|
|
||||||
{:position :absolute
|
|
||||||
:z-index 2
|
|
||||||
:align-items :center
|
|
||||||
:align-self :center
|
|
||||||
:bottom 16
|
|
||||||
:width 40
|
|
||||||
:height 40})
|
|
||||||
|
|
||||||
(defn action-button []
|
|
||||||
{:width 40
|
|
||||||
:height 40
|
|
||||||
:background-color colors/blue
|
|
||||||
:border-radius 20
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center
|
|
||||||
:shadow-offset {:width 0 :height 1}
|
|
||||||
:shadow-radius 6
|
|
||||||
:shadow-opacity 1
|
|
||||||
:shadow-color (if (colors/dark?)
|
|
||||||
"rgba(0, 0, 0, 0.75)"
|
|
||||||
"rgba(0, 12, 63, 0.2)")
|
|
||||||
:elevation 2})
|
|
||||||
|
|
||||||
(def empty-chats-header-container
|
(def empty-chats-header-container
|
||||||
{:align-items :center
|
{:align-items :center
|
||||||
:justify-content :center})
|
:justify-content :center})
|
||||||
|
|
|
@ -19,7 +19,8 @@
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
[cljs-bean.core :as bean]
|
[cljs-bean.core :as bean]
|
||||||
[status-im.ui.components.invite.views :as invite]
|
[status-im.ui.components.invite.views :as invite]
|
||||||
[status-im.ui.components.topbar :as topbar])
|
[status-im.ui.components.topbar :as topbar]
|
||||||
|
[status-im.ui.components.plus-button :as components.plus-button])
|
||||||
(:require-macros [status-im.utils.views :as views]))
|
(:require-macros [status-im.utils.views :as views]))
|
||||||
|
|
||||||
(defn welcome-image-wrapper []
|
(defn welcome-image-wrapper []
|
||||||
|
@ -158,16 +159,11 @@
|
||||||
|
|
||||||
(views/defview plus-button []
|
(views/defview plus-button []
|
||||||
(views/letsubs [logging-in? [:multiaccounts/login]]
|
(views/letsubs [logging-in? [:multiaccounts/login]]
|
||||||
[react/view styles/action-button-container
|
[components.plus-button/plus-button
|
||||||
[quo/button {:type :scale
|
{:on-press (when-not logging-in?
|
||||||
:accessibility-label :new-chat-button
|
#(re-frame/dispatch [:bottom-sheet/show-sheet :add-new {}]))
|
||||||
:on-press (when-not logging-in?
|
:loading logging-in?
|
||||||
#(re-frame/dispatch [:bottom-sheet/show-sheet :add-new {}]))}
|
:accessibility-label :new-chat-button}]))
|
||||||
[react/view (styles/action-button)
|
|
||||||
(if logging-in?
|
|
||||||
[react/activity-indicator {:color colors/white-persist
|
|
||||||
:animating true}]
|
|
||||||
[icons/icon :main-icons/add {:color colors/white-persist}])]]]))
|
|
||||||
|
|
||||||
(defn home []
|
(defn home []
|
||||||
[react/keyboard-avoiding-view {:style styles/home-container}
|
[react/keyboard-avoiding-view {:style styles/home-container}
|
||||||
|
|
|
@ -12,3 +12,13 @@
|
||||||
|
|
||||||
(def contact-profile-detail-share-icon
|
(def contact-profile-detail-share-icon
|
||||||
{:color colors/gray-transparent-40})
|
{:color colors/gray-transparent-40})
|
||||||
|
|
||||||
|
(defn updates-descr-cont []
|
||||||
|
{:border-width 1
|
||||||
|
:border-color colors/gray-lighter
|
||||||
|
:border-top-right-radius 16
|
||||||
|
:border-bottom-left-radius 16
|
||||||
|
:border-top-left-radius 16
|
||||||
|
:border-bottom-right-radius 4
|
||||||
|
:padding-horizontal 12
|
||||||
|
:padding-vertical 6})
|
||||||
|
|
|
@ -17,42 +17,48 @@
|
||||||
[status-im.ui.components.keyboard-avoid-presentation :as kb-presentation]
|
[status-im.ui.components.keyboard-avoid-presentation :as kb-presentation]
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[clojure.string :as string])
|
[clojure.string :as string]
|
||||||
|
[quo.components.list.item :as list-item]
|
||||||
|
[status-im.ui.components.list.views :as list]
|
||||||
|
[status-im.ui.screens.profile.status :as my-status]
|
||||||
|
[status-im.ui.screens.chat.views :as chat.views])
|
||||||
(:require-macros [status-im.utils.views :as views]))
|
(:require-macros [status-im.utils.views :as views]))
|
||||||
|
|
||||||
(defn actions
|
(defn actions
|
||||||
[{:keys [public-key added? tribute-to-talk] :as contact}]
|
[{:keys [public-key added? blocked?] :as contact} muted?]
|
||||||
(let [{:keys [tribute-status tribute-label]} tribute-to-talk]
|
(concat [{:label (i18n/label :t/chat)
|
||||||
(concat [(cond-> {:label (i18n/label :t/send-message)
|
:icon :main-icons/message
|
||||||
:icon :main-icons/message
|
:action #(re-frame/dispatch [:contact.ui/send-message-pressed {:public-key public-key}])
|
||||||
:action #(re-frame/dispatch [:contact.ui/send-message-pressed {:public-key public-key}])
|
:accessibility-label :start-conversation-button}]
|
||||||
:accessibility-label :start-conversation-button}
|
(if added?
|
||||||
(not (#{:none :paid} tribute-status))
|
[{:label (i18n/label :t/remove-from-contacts)
|
||||||
(assoc :subtext tribute-label))]
|
:icon :main-icons/remove-contact
|
||||||
;;TODO hide temporary for v1
|
:selected true
|
||||||
#_{:label (i18n/label :t/send-transaction)
|
:accessibility-label :in-contacts-button
|
||||||
:icon :main-icons/send
|
:action #(re-frame/dispatch [:contact.ui/remove-contact-pressed contact])}]
|
||||||
:action #(re-frame/dispatch [:profile/send-transaction public-key])
|
[{:label (i18n/label :t/add-to-contacts)
|
||||||
:accessibility-label :send-transaction-button}
|
:icon :main-icons/add-contact
|
||||||
(if added?
|
:accessibility-label :add-to-contacts-button
|
||||||
[{:label (i18n/label :t/remove-from-contacts)
|
:action #(re-frame/dispatch [:contact.ui/add-to-contact-pressed public-key])}])
|
||||||
:icon :main-icons/remove-contact
|
(when platform/ios?
|
||||||
:accessibility-label :in-contacts-button
|
[{:label (i18n/label (if muted? :t/unmute :t/mute))
|
||||||
:action #(re-frame/dispatch [:contact.ui/remove-contact-pressed contact])}]
|
:icon :main-icons/notification
|
||||||
;; TODO sheets temporary disabled
|
:accessibility-label :mute-chat
|
||||||
;:action #(re-frame/dispatch [:bottom-sheet/show-sheet
|
:selected muted?
|
||||||
; {:content sheets/remove-contact
|
:action #(re-frame/dispatch [::chat.models/mute-chat-toggled public-key (not muted?)])}])
|
||||||
; :content-height 150}
|
[{:label (i18n/label (if blocked? :t/unblock :t/block))
|
||||||
; contact])
|
:negative true
|
||||||
[{:label (i18n/label :t/add-to-contacts)
|
:selected blocked?
|
||||||
:icon :main-icons/add-contact
|
:icon :main-icons/cancel
|
||||||
:accessibility-label :add-to-contacts-button
|
:action (if blocked?
|
||||||
:action #(re-frame/dispatch [:contact.ui/add-to-contact-pressed public-key])}]))))
|
#(re-frame/dispatch [:contact.ui/unblock-contact-pressed public-key])
|
||||||
;; TODO sheets temporary disabled
|
#(re-frame/dispatch [:show-popover
|
||||||
;:action #(re-frame/dispatch [:bottom-sheet/show-sheet
|
{:view sheets/block-contact
|
||||||
; {:content sheets/add-contact
|
:prevent-closing? true
|
||||||
; :content-height 150}
|
:public-key public-key}]))
|
||||||
; contact])
|
:accessibility-label (if blocked?
|
||||||
|
:unblock-contact
|
||||||
|
:block-contact)}]))
|
||||||
|
|
||||||
(defn render-detail [{:keys [public-key names name] :as detail}]
|
(defn render-detail [{:keys [public-key names name] :as detail}]
|
||||||
[quo/list-item
|
[quo/list-item
|
||||||
|
@ -78,49 +84,15 @@
|
||||||
(i18n/label :t/profile-details)]]
|
(i18n/label :t/profile-details)]]
|
||||||
[render-detail contact]]))
|
[render-detail contact]]))
|
||||||
|
|
||||||
(defn render-chat-settings [{:keys [public-key names]}]
|
(defn nickname-settings [{:keys [names]}]
|
||||||
(let [muted? (:muted @(re-frame/subscribe [:chats/chat public-key]))]
|
[quo/list-item
|
||||||
[react/view
|
{:title (i18n/label :t/nickname)
|
||||||
[quo/list-item
|
:size :small
|
||||||
{:title (i18n/label :t/nickname)
|
:accessibility-label :profile-nickname-item
|
||||||
:size :small
|
:accessory :text
|
||||||
:accessibility-label :profile-nickname-item
|
:accessory-text (or (:nickname names) (i18n/label :t/none))
|
||||||
:accessory :text
|
:on-press #(re-frame/dispatch [:navigate-to :nickname])
|
||||||
:accessory-text (or (:nickname names) (i18n/label :t/none))
|
:chevron true}])
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :nickname])
|
|
||||||
:chevron true}]
|
|
||||||
;; Mute chat is only supported on ios for now
|
|
||||||
(when platform/ios?
|
|
||||||
[quo/list-item
|
|
||||||
{:title (i18n/label :t/mute)
|
|
||||||
:active muted?
|
|
||||||
:accessibility-label :mute-chat
|
|
||||||
:on-press #(re-frame/dispatch [::chat.models/mute-chat-toggled public-key (not muted?)])
|
|
||||||
:accessory :switch}])]))
|
|
||||||
|
|
||||||
(defn chat-settings [contact]
|
|
||||||
[react/view
|
|
||||||
[quo/list-header
|
|
||||||
[quo/text {:accessibility-label :chat-settings
|
|
||||||
:color :inherit}
|
|
||||||
(i18n/label :t/chat-settings)]]
|
|
||||||
[render-chat-settings contact]])
|
|
||||||
|
|
||||||
;; TODO: List item
|
|
||||||
(defn block-contact-action [{:keys [blocked? public-key]}]
|
|
||||||
[react/touchable-highlight {:on-press (if blocked?
|
|
||||||
#(re-frame/dispatch [:contact.ui/unblock-contact-pressed public-key])
|
|
||||||
#(re-frame/dispatch [:show-popover
|
|
||||||
{:view sheets/block-contact
|
|
||||||
:prevent-closing? true
|
|
||||||
:public-key public-key}]))}
|
|
||||||
[react/text {:style styles/block-action-label
|
|
||||||
:accessibility-label (if blocked?
|
|
||||||
:unblock-contact
|
|
||||||
:block-contact)}
|
|
||||||
(if blocked?
|
|
||||||
(i18n/label :t/unblock-contact)
|
|
||||||
(i18n/label :t/block-contact))]])
|
|
||||||
|
|
||||||
(defn save-nickname [public-key nickname]
|
(defn save-nickname [public-key nickname]
|
||||||
(re-frame/dispatch [:contacts/update-nickname public-key nickname]))
|
(re-frame/dispatch [:contacts/update-nickname public-key nickname]))
|
||||||
|
@ -167,45 +139,75 @@
|
||||||
(views/letsubs [{:keys [public-key names]} [:contacts/current-contact]]
|
(views/letsubs [{:keys [public-key names]} [:contacts/current-contact]]
|
||||||
[nickname-view public-key names]))
|
[nickname-view public-key names]))
|
||||||
|
|
||||||
|
(defn button-item [{:keys [icon label action selected negative]}]
|
||||||
|
[react/touchable-highlight {:on-press action :style {:flex 1}
|
||||||
|
:accessibility-label (str label "-item-button")}
|
||||||
|
[react/view {:flex 1 :align-items :center}
|
||||||
|
[list-item/icon-column {:icon icon
|
||||||
|
:size :small
|
||||||
|
:icon-bg-color (if negative
|
||||||
|
(if selected colors/red colors/red-light)
|
||||||
|
(if selected colors/blue colors/blue-light))
|
||||||
|
:icon-color (if negative
|
||||||
|
(if selected colors/white colors/red)
|
||||||
|
(if selected colors/white colors/blue))}]
|
||||||
|
[react/text {:style {:text-align :center :color (if negative colors/red colors/blue)
|
||||||
|
:font-size 12 :line-height 16 :margin-top 6}
|
||||||
|
:number-of-lines 2}
|
||||||
|
label]]])
|
||||||
|
|
||||||
|
(defn status []
|
||||||
|
(let [messages @(re-frame/subscribe [:chats/current-chat-messages-stream])
|
||||||
|
no-messages? @(re-frame/subscribe [:chats/current-chat-no-messages?])]
|
||||||
|
(if no-messages?
|
||||||
|
[react/view {:padding-horizontal 32 :margin-top 32}
|
||||||
|
[react/view (styles/updates-descr-cont)
|
||||||
|
[react/text {:style {:color colors/gray :line-height 22}}
|
||||||
|
(i18n/label :t/status-updates-descr)]]]
|
||||||
|
[list/flat-list
|
||||||
|
{:key-fn #(or (:message-id %) (:value %))
|
||||||
|
:ref #(reset! my-status/messages-list-ref %)
|
||||||
|
:on-viewable-items-changed chat.views/on-viewable-items-changed
|
||||||
|
:on-end-reached #(re-frame/dispatch [:chat.ui/load-more-messages])
|
||||||
|
:on-scroll-to-index-failed #() ;;don't remove this
|
||||||
|
:render-fn my-status/render-message
|
||||||
|
:data messages}])))
|
||||||
|
|
||||||
(views/defview profile []
|
(views/defview profile []
|
||||||
(views/letsubs [{:keys [public-key name ens-verified]
|
(views/letsubs [{:keys [public-key name ens-verified]
|
||||||
:as contact} [:contacts/current-contact]]
|
:as contact} [:contacts/current-contact]]
|
||||||
(let [[first-name second-name] (multiaccounts/contact-two-names contact true)
|
(let [muted? (:muted @(re-frame/subscribe [:chats/chat public-key]))
|
||||||
|
[first-name second-name] (multiaccounts/contact-two-names contact true)
|
||||||
on-share #(re-frame/dispatch [:show-popover (merge
|
on-share #(re-frame/dispatch [:show-popover (merge
|
||||||
{:view :share-chat-key
|
{:view :share-chat-key
|
||||||
:address public-key}
|
:address public-key}
|
||||||
(when (and ens-verified name)
|
(when (and ens-verified name)
|
||||||
{:ens-name name}))])]
|
{:ens-name name}))])]
|
||||||
(when contact
|
(when contact
|
||||||
[react/view
|
[react/view {:flex 1}
|
||||||
{:style
|
|
||||||
(merge {:flex 1})}
|
|
||||||
[quo/animated-header
|
[quo/animated-header
|
||||||
{:use-insets true
|
{:use-insets false
|
||||||
:right-accessories [{:icon :main-icons/share
|
:right-accessories [{:icon :main-icons/share
|
||||||
|
:accessibility-label :share-button
|
||||||
:on-press on-share}]
|
:on-press on-share}]
|
||||||
:left-accessories [{:icon :main-icons/arrow-left
|
:left-accessories [{:icon :main-icons/close
|
||||||
:accessibility-label :back-button
|
:accessibility-label :back-button
|
||||||
:on-press #(re-frame/dispatch [:navigate-back])}]
|
:on-press #(re-frame/dispatch [:navigate-back])}]
|
||||||
:extended-header (profile-header/extended-header
|
:extended-header (profile-header/extended-header
|
||||||
{:on-press on-share
|
{:on-press on-share
|
||||||
|
:bottom-separator false
|
||||||
:title first-name
|
:title first-name
|
||||||
:photo (multiaccounts/displayed-photo contact)
|
:photo (multiaccounts/displayed-photo contact)
|
||||||
:monospace (not ens-verified)
|
:monospace (not ens-verified)
|
||||||
:subtitle second-name})}
|
:subtitle second-name})}
|
||||||
|
[react/view {:height 1 :background-color colors/gray-lighter :margin-top 8}]
|
||||||
[react/view {:padding-top 12}
|
[nickname-settings contact]
|
||||||
(for [{:keys [label subtext accessibility-label icon action disabled?]} (actions contact)
|
[react/view {:height 1 :background-color colors/gray-lighter}]
|
||||||
|
[react/view {:padding-top 17 :flex-direction :row :align-items :stretch :flex 1}
|
||||||
|
(for [{:keys [label] :as action} (actions contact muted?)
|
||||||
:when label]
|
:when label]
|
||||||
^{:key label}
|
^{:key label}
|
||||||
[quo/list-item {:theme :accent
|
[button-item action])]
|
||||||
:title label
|
[react/view {:height 1 :background-color colors/gray-lighter :margin-top 16}]
|
||||||
:subtitle subtext
|
[status]]]))))
|
||||||
:icon icon
|
|
||||||
:accessibility-label accessibility-label
|
|
||||||
:disabled disabled?
|
|
||||||
:on-press action}])]
|
|
||||||
[react/view styles/contact-profile-details-container
|
|
||||||
[profile-details contact]
|
|
||||||
[chat-settings contact]]
|
|
||||||
[block-contact-action contact]]]))))
|
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
(ns status-im.ui.screens.profile.my-status.views
|
||||||
|
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||||
|
(:require [status-im.ui.components.keyboard-avoid-presentation :as kb-presentation]
|
||||||
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.ui.components.topbar :as topbar]
|
||||||
|
[status-im.i18n :as i18n]
|
||||||
|
[re-frame.core :as re-frame]
|
||||||
|
[status-im.ui.components.toolbar :as toolbar]
|
||||||
|
[quo.core :as quo]
|
||||||
|
[status-im.ui.components.colors :as colors]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[clojure.string :as string]
|
||||||
|
[status-im.ui.components.icons.vector-icons :as icons]
|
||||||
|
[quo.components.animated.pressable :as pressable]
|
||||||
|
[status-im.ui.screens.profile.status :as my-status.messages]))
|
||||||
|
|
||||||
|
(defn take-picture []
|
||||||
|
(react/show-image-picker-camera #(re-frame/dispatch [:chat.ui/image-captured (.-path %)]) {}))
|
||||||
|
|
||||||
|
(defn buttons []
|
||||||
|
[react/view {:padding-horizontal 14 :padding-vertical 10 :justify-content :space-between :height 88}
|
||||||
|
[pressable/pressable {:type :scale
|
||||||
|
:accessibility-label :take-picture
|
||||||
|
:on-press take-picture}
|
||||||
|
[icons/icon :main-icons/camera]]
|
||||||
|
[react/view {:style {:padding-top 8}}
|
||||||
|
[pressable/pressable {:on-press #(re-frame/dispatch [:chat.ui/open-image-picker])
|
||||||
|
:accessibility-label :open-gallery
|
||||||
|
:type :scale}
|
||||||
|
[icons/icon :main-icons/gallery]]]])
|
||||||
|
|
||||||
|
(defn image-preview [uri]
|
||||||
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:chat.ui/camera-roll-pick uri])}
|
||||||
|
[react/image {:style (merge {:width 72
|
||||||
|
:height 72
|
||||||
|
:background-color :black
|
||||||
|
:resize-mode :cover
|
||||||
|
:margin-right 4
|
||||||
|
:border-radius 4})
|
||||||
|
:source {:uri uri}}]])
|
||||||
|
|
||||||
|
(defview photos []
|
||||||
|
(letsubs [camera-roll-photos [:camera-roll-photos]]
|
||||||
|
{:component-did-mount #(re-frame/dispatch [:chat.ui/camera-roll-get-photos 20])}
|
||||||
|
[react/scroll-view {:horizontal true :style {:max-height 88}
|
||||||
|
:keyboard-should-persist-taps :handled}
|
||||||
|
[react/view {:height 88 :border-top-width 1 :border-top-color colors/gray-lighter
|
||||||
|
:flex-direction :row :align-items :center}
|
||||||
|
[buttons]
|
||||||
|
(for [img camera-roll-photos]
|
||||||
|
^{:key (str "image" img)}
|
||||||
|
(when img
|
||||||
|
[image-preview img]))]]))
|
||||||
|
|
||||||
|
(defview sending-image []
|
||||||
|
(letsubs [{:keys [uri]} [:chats/sending-image]]
|
||||||
|
(when uri
|
||||||
|
[react/view {:margin-horizontal 16 :margin-bottom 16}
|
||||||
|
[my-status.messages/message-content-image uri true]])))
|
||||||
|
|
||||||
|
(defn my-status []
|
||||||
|
(let [images-opened (reagent/atom false)
|
||||||
|
input-text (re-frame/subscribe [:chats/current-chat-input-text])]
|
||||||
|
(fn []
|
||||||
|
[kb-presentation/keyboard-avoiding-view {:style {:flex 1}}
|
||||||
|
[react/view {:flex 1}
|
||||||
|
[topbar/topbar
|
||||||
|
{:modal? true
|
||||||
|
:border-bottom true
|
||||||
|
:title (i18n/label :t/my-status)}]
|
||||||
|
[react/scroll-view {:style {:flex 1}
|
||||||
|
:keyboard-should-persist-taps :handled}
|
||||||
|
[react/text-input
|
||||||
|
{:style {:margin 16}
|
||||||
|
:accessibility-label :my-status-input
|
||||||
|
:max-length 300
|
||||||
|
:auto-focus true
|
||||||
|
:multiline true
|
||||||
|
:on-change-text #(re-frame/dispatch [:chat.ui/set-chat-input-text %])
|
||||||
|
:default-value @input-text
|
||||||
|
:placeholder (i18n/label :t/whats-on-your-mind)}]
|
||||||
|
[sending-image]]
|
||||||
|
[react/view
|
||||||
|
(when @images-opened
|
||||||
|
[photos])
|
||||||
|
[react/view
|
||||||
|
[toolbar/toolbar
|
||||||
|
{:show-border? true
|
||||||
|
:left
|
||||||
|
[quo/button
|
||||||
|
{:accessibility-label :open-images-panel-button
|
||||||
|
:type :secondary
|
||||||
|
:on-press #(swap! images-opened not)}
|
||||||
|
[icons/icon :main-icons/photo {:color (if @images-opened colors/blue colors/gray)}]]
|
||||||
|
:right
|
||||||
|
[quo/button
|
||||||
|
{:accessibility-label :send-my-status-button
|
||||||
|
:type :secondary
|
||||||
|
:after :main-icon/send
|
||||||
|
:disabled (string/blank? @input-text)
|
||||||
|
:on-press #(do
|
||||||
|
(re-frame/dispatch [:profile.ui/send-my-status-message])
|
||||||
|
(re-frame/dispatch [:navigate-back]))}
|
||||||
|
(i18n/label :t/wallet-send)]}]
|
||||||
|
[react/view {:top 0 :bottom 0 :left 0 :right 0 :align-items :center :justify-content :center
|
||||||
|
:position :absolute :pointerEvents :none}
|
||||||
|
[react/text {:style {:color colors/gray}}
|
||||||
|
(str (count @input-text) " / 300")]]]]]])))
|
|
@ -0,0 +1,72 @@
|
||||||
|
(ns status-im.ui.screens.profile.status
|
||||||
|
(:require [status-im.ui.screens.chat.message.message :as message]
|
||||||
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.ui.components.colors :as colors]
|
||||||
|
[status-im.utils.datetime :as datetime]
|
||||||
|
[status-im.ui.screens.chat.message.gap :as gap]
|
||||||
|
[status-im.constants :as constants]
|
||||||
|
[re-frame.core :as re-frame]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[status-im.ui.components.icons.vector-icons :as icons]))
|
||||||
|
|
||||||
|
(defonce messages-list-ref (atom nil))
|
||||||
|
|
||||||
|
(defn message-content-image [_ _]
|
||||||
|
(let [dimensions (reagent/atom [260 260])]
|
||||||
|
(fn [uri show-close?]
|
||||||
|
(react/image-get-size
|
||||||
|
uri
|
||||||
|
(fn [width height]
|
||||||
|
(let [k (/ (max width height) 260)]
|
||||||
|
(reset! dimensions [(/ width k) (/ height k)]))))
|
||||||
|
[react/view
|
||||||
|
[react/view {:style {:width (first @dimensions)
|
||||||
|
:height (last @dimensions)
|
||||||
|
:border-width 1
|
||||||
|
:border-color colors/black-transparent
|
||||||
|
:overflow :hidden
|
||||||
|
:border-radius 16
|
||||||
|
:margin-top 8}}
|
||||||
|
[react/image {:style {:width (first @dimensions) :height (last @dimensions)}
|
||||||
|
:resize-mode :contain
|
||||||
|
:source {:uri uri}}]]
|
||||||
|
(when show-close?
|
||||||
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:chat.ui/cancel-sending-image])
|
||||||
|
:accessibility-label :cancel-send-image
|
||||||
|
:style {:left (- (first @dimensions) 28) :top 12 :position :absolute}}
|
||||||
|
[react/view {:width 24
|
||||||
|
:height 24
|
||||||
|
:background-color colors/black-persist
|
||||||
|
:border-radius 12
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :center}
|
||||||
|
[icons/icon :main-icons/close-circle {:color colors/white-persist}]]])])))
|
||||||
|
|
||||||
|
(defn image-message [{:keys [content] :as message}]
|
||||||
|
[react/touchable-highlight {:on-press (fn [_]
|
||||||
|
(when (:image content)
|
||||||
|
(re-frame/dispatch [:navigate-to :image-preview
|
||||||
|
(assoc message :cant-be-replied true)]))
|
||||||
|
(react/dismiss-keyboard!))}
|
||||||
|
[message-content-image (:image content) false]])
|
||||||
|
|
||||||
|
(defn message-item [{:keys [content-type content from last-in-group? timestamp] :as message}]
|
||||||
|
[react/view (merge {:padding-top 16 :padding-horizontal 16}
|
||||||
|
(when last-in-group?
|
||||||
|
{:padding-bottom 16
|
||||||
|
:border-bottom-width 1
|
||||||
|
:border-bottom-color colors/gray-lighter}))
|
||||||
|
[react/view {:flex-direction :row :justify-content :space-between}
|
||||||
|
[message/message-author-name from]
|
||||||
|
[react/text {:style {:font-size 10 :color colors/gray}} (datetime/time-ago (datetime/to-date timestamp))]]
|
||||||
|
(if (= content-type constants/content-type-image)
|
||||||
|
[image-message message]
|
||||||
|
[message/render-parsed-text (assoc message :outgoing false) (:parsed-text content)])])
|
||||||
|
|
||||||
|
(defn render-message [{:keys [type] :as message} idx]
|
||||||
|
(if (= type :datemark)
|
||||||
|
[react/view]
|
||||||
|
(if (= type :gap)
|
||||||
|
[gap/gap message idx messages-list-ref]
|
||||||
|
; message content
|
||||||
|
[message-item message])))
|
|
@ -1,6 +1,17 @@
|
||||||
(ns status-im.ui.screens.profile.user.styles)
|
(ns status-im.ui.screens.profile.user.styles
|
||||||
|
(:require [status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
(def share-link-button
|
(def share-link-button
|
||||||
{:margin-top 12
|
{:margin-top 12
|
||||||
:margin-horizontal 16
|
:margin-horizontal 16
|
||||||
:margin-bottom 16})
|
:margin-bottom 16})
|
||||||
|
|
||||||
|
(defn descr-container []
|
||||||
|
{:border-width 1
|
||||||
|
:border-color colors/gray-lighter
|
||||||
|
:border-top-right-radius 16
|
||||||
|
:border-bottom-left-radius 16
|
||||||
|
:border-top-left-radius 16
|
||||||
|
:border-bottom-right-radius 4
|
||||||
|
:padding-horizontal 12
|
||||||
|
:padding-vertical 6})
|
|
@ -17,7 +17,15 @@
|
||||||
[status-im.utils.gfycat.core :as gfy]
|
[status-im.utils.gfycat.core :as gfy]
|
||||||
[status-im.utils.universal-links.utils :as universal-links]
|
[status-im.utils.universal-links.utils :as universal-links]
|
||||||
[status-im.ui.components.profile-header.view :as profile-header]
|
[status-im.ui.components.profile-header.view :as profile-header]
|
||||||
[status-im.ethereum.stateofus :as stateofus])
|
[status-im.ui.components.tabs :as tabs]
|
||||||
|
[status-im.utils.utils :as utils]
|
||||||
|
[status-im.ui.screens.contacts-list.views :as contacts-list]
|
||||||
|
[status-im.ui.components.plus-button :as components.plus-button]
|
||||||
|
[status-im.ui.components.icons.vector-icons :as icons]
|
||||||
|
[status-im.ui.components.list.views :as list]
|
||||||
|
[status-im.ui.screens.profile.status :as my-status]
|
||||||
|
[status-im.ethereum.stateofus :as stateofus]
|
||||||
|
[status-im.ui.screens.chat.views :as chat.views])
|
||||||
(:require-macros [status-im.utils.views :as views]))
|
(:require-macros [status-im.utils.views :as views]))
|
||||||
|
|
||||||
(views/defview share-chat-key []
|
(views/defview share-chat-key []
|
||||||
|
@ -55,14 +63,37 @@
|
||||||
:accessibility-label :share-my-contact-code-button}
|
:accessibility-label :share-my-contact-code-button}
|
||||||
(i18n/label :t/share-link)]]])))
|
(i18n/label :t/share-link)]]])))
|
||||||
|
|
||||||
(defn tribute-to-talk-item
|
(def state (reagent/atom {:tab :status}))
|
||||||
[opts]
|
|
||||||
[quo/list-item
|
(defn tabs []
|
||||||
(merge {:title (i18n/label :t/tribute-to-talk)
|
(let [{:keys [tab]} @state]
|
||||||
:accessibility-label :notifications-button
|
[react/view {:flex-direction :row :padding-horizontal 4 :margin-top 16}
|
||||||
:on-press #(re-frame/dispatch
|
[tabs/tab-title state :status (i18n/label :t/my-status) (= tab :status)]
|
||||||
[:tribute-to-talk.ui/menu-item-pressed])}
|
[tabs/tab-title state :contacts (i18n/label :t/contacts) (= tab :contacts)]
|
||||||
opts)])
|
[tabs/tab-title state :settings (i18n/label :t/settings) (= tab :settings)]]))
|
||||||
|
|
||||||
|
(defn my-status []
|
||||||
|
(let [messages @(re-frame/subscribe [:chats/current-chat-messages-stream])
|
||||||
|
no-messages? @(re-frame/subscribe [:chats/current-chat-no-messages?])]
|
||||||
|
(if no-messages?
|
||||||
|
[react/view {:padding-horizontal 32 :margin-top 32}
|
||||||
|
[react/view (styles/descr-container)
|
||||||
|
[react/text {:style {:color colors/gray :line-height 22}}
|
||||||
|
(i18n/label :t/statuses-my-profile-descr)]]
|
||||||
|
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :my-status])}
|
||||||
|
[react/view {:flex-direction :row :align-items :center :align-self :center
|
||||||
|
:padding 12}
|
||||||
|
[react/text {:style {:color colors/blue :margin-right 8}}
|
||||||
|
(i18n/label :t/new-status)]
|
||||||
|
[icons/icon :main-icons/add-circle {:color colors/blue}]]]]
|
||||||
|
[list/flat-list
|
||||||
|
{:key-fn #(or (:message-id %) (:value %))
|
||||||
|
:render-fn my-status/render-message
|
||||||
|
:data messages
|
||||||
|
:on-viewable-items-changed chat.views/on-viewable-items-changed
|
||||||
|
:on-end-reached #(re-frame/dispatch [:chat.ui/load-more-messages])
|
||||||
|
:on-scroll-to-index-failed #() ;;don't remove this
|
||||||
|
:footer [react/view {:height 68}]}])))
|
||||||
|
|
||||||
(defn content []
|
(defn content []
|
||||||
(let [{:keys [preferred-name
|
(let [{:keys [preferred-name
|
||||||
|
@ -70,123 +101,116 @@
|
||||||
notifications-enabled?
|
notifications-enabled?
|
||||||
keycard-pairing]}
|
keycard-pairing]}
|
||||||
@(re-frame/subscribe [:multiaccount])
|
@(re-frame/subscribe [:multiaccount])
|
||||||
active-contacts-count @(re-frame/subscribe [:contacts/active-count])
|
|
||||||
tribute-to-talk @(re-frame/subscribe [:tribute-to-talk/profile])
|
|
||||||
chain @(re-frame/subscribe [:chain-keyword])
|
chain @(re-frame/subscribe [:chain-keyword])
|
||||||
registrar (stateofus/get-cached-registrar chain)]
|
registrar (stateofus/get-cached-registrar chain)
|
||||||
|
{:keys [tab]} @state]
|
||||||
[:<>
|
[:<>
|
||||||
[quo/list-item
|
[tabs]
|
||||||
(cond-> {:title (or (when registrar preferred-name)
|
[react/view {:height 1 :background-color colors/gray-lighter}]
|
||||||
(i18n/label :t/ens-usernames))
|
(cond
|
||||||
:subtitle (if registrar
|
(= tab :status)
|
||||||
(if preferred-name
|
[my-status]
|
||||||
(i18n/label :t/ens-your-your-name)
|
(= tab :contacts)
|
||||||
(i18n/label :t/ens-usernames-details))
|
[contacts-list/contacts-list]
|
||||||
(i18n/label :t/ens-network-restriction))
|
(= tab :settings)
|
||||||
:subtitle-max-lines (if registrar
|
[:<>
|
||||||
(if preferred-name 1 2)
|
[quo/list-item
|
||||||
1)
|
(cond-> {:title (or (when registrar preferred-name)
|
||||||
:accessibility-label :ens-button
|
(i18n/label :t/ens-usernames))
|
||||||
:container-margin-top 8
|
:subtitle (if registrar
|
||||||
:disabled (not registrar)
|
(if preferred-name
|
||||||
:chevron true
|
(i18n/label :t/ens-your-your-name)
|
||||||
:icon :main-icons/username}
|
(i18n/label :t/ens-usernames-details))
|
||||||
registrar
|
(i18n/label :t/ens-network-restriction))
|
||||||
(assoc :on-press #(re-frame/dispatch [:navigate-to :ens-main registrar])))]
|
:subtitle-max-lines (if registrar
|
||||||
;; TODO replace this with list-item config map
|
(if preferred-name 1 2)
|
||||||
;; left it as it is because not sure how to enable it for testing
|
1)
|
||||||
(when tribute-to-talk [tribute-to-talk-item tribute-to-talk])
|
:accessibility-label :ens-button
|
||||||
[quo/list-item
|
:container-margin-top 8
|
||||||
{:title (i18n/label :t/contacts)
|
:disabled (not registrar)
|
||||||
:icon :main-icons/in-contacts
|
:chevron true
|
||||||
:accessibility-label :contacts-button
|
:icon :main-icons/username}
|
||||||
:accessory :text
|
registrar
|
||||||
:accessory-text (if (pos? active-contacts-count)
|
(assoc :on-press #(re-frame/dispatch [:navigate-to :ens-main registrar])))]
|
||||||
(str active-contacts-count)
|
[quo/list-item
|
||||||
(i18n/label :t/none))
|
{:icon :main-icons/security
|
||||||
:chevron true
|
:title (i18n/label :t/privacy-and-security)
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :contacts-list])}]
|
:accessibility-label :privacy-and-security-settings-button
|
||||||
[react/view {:padding-top 16}
|
:chevron true
|
||||||
[quo/list-header (i18n/label :t/settings)]]
|
:accessory (when mnemonic
|
||||||
[quo/list-item
|
[components.common/counter {:size 22} 1])
|
||||||
{:icon :main-icons/security
|
:on-press #(re-frame/dispatch [:navigate-to :privacy-and-security])}]
|
||||||
:title (i18n/label :t/privacy-and-security)
|
(when config/quo-preview-enabled?
|
||||||
:accessibility-label :privacy-and-security-settings-button
|
[quo/list-item
|
||||||
:chevron true
|
{:icon :main-icons/appearance
|
||||||
:accessory (when mnemonic
|
:title "Quo Preview"
|
||||||
[components.common/counter {:size 22} 1])
|
:accessibility-label :appearance-settings-button
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :privacy-and-security])}]
|
:chevron true
|
||||||
(when config/quo-preview-enabled?
|
:on-press #(re-frame/dispatch [:navigate-to :quo-preview])}])
|
||||||
[quo/list-item
|
[quo/list-item
|
||||||
{:icon :main-icons/appearance
|
{:icon :main-icons/appearance
|
||||||
:title "Quo Preview"
|
:title (i18n/label :t/appearance)
|
||||||
:accessibility-label :appearance-settings-button
|
:accessibility-label :appearance-settings-button
|
||||||
:chevron true
|
:chevron true
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :quo-preview])}])
|
:on-press #(re-frame/dispatch [:navigate-to :appearance])}]
|
||||||
[quo/list-item
|
(if platform/ios?
|
||||||
{:icon :main-icons/appearance
|
[quo/list-item
|
||||||
:title (i18n/label :t/appearance)
|
{:icon :main-icons/notification
|
||||||
:accessibility-label :appearance-settings-button
|
:title (i18n/label :t/notifications)
|
||||||
:chevron true
|
:accessibility-label :notifications-settings-button
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :appearance])}]
|
:chevron true
|
||||||
(if platform/ios?
|
:on-press #(re-frame/dispatch [:navigate-to :notifications])}]
|
||||||
[quo/list-item
|
(when (and platform/android?
|
||||||
{:icon :main-icons/notification
|
config/local-notifications?)
|
||||||
:title (i18n/label :t/notifications)
|
[quo/list-item
|
||||||
:accessibility-label :notifications-settings-button
|
{:icon :main-icons/notification
|
||||||
:chevron true
|
:title (i18n/label :t/notifications)
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :notifications])}]
|
:accessibility-label :notifications-settings-button
|
||||||
(when (and platform/android?
|
:active notifications-enabled?
|
||||||
config/local-notifications?)
|
:on-press #(re-frame/dispatch
|
||||||
|
[::notifications/switch (not notifications-enabled?)])
|
||||||
|
:accessory :switch}]))
|
||||||
|
[quo/list-item
|
||||||
|
{:icon :main-icons/mobile
|
||||||
|
:title (i18n/label :t/sync-settings)
|
||||||
|
:accessibility-label :sync-settings-button
|
||||||
|
:chevron true
|
||||||
|
:on-press #(re-frame/dispatch [:navigate-to :sync-settings])}]
|
||||||
|
(when (and (or platform/android?
|
||||||
|
config/keycard-test-menu-enabled?)
|
||||||
|
keycard-pairing)
|
||||||
|
[quo/list-item
|
||||||
|
{:icon :main-icons/keycard
|
||||||
|
:title (i18n/label :t/keycard)
|
||||||
|
:accessibility-label :keycard-button
|
||||||
|
:chevron true
|
||||||
|
:on-press #(re-frame/dispatch [:navigate-to :keycard-settings])}])
|
||||||
|
[quo/list-item
|
||||||
|
{:icon :main-icons/settings-advanced
|
||||||
|
:title (i18n/label :t/advanced)
|
||||||
|
:accessibility-label :advanced-button
|
||||||
|
:chevron true
|
||||||
|
:on-press #(re-frame/dispatch [:navigate-to :advanced-settings])}]
|
||||||
|
[quo/list-item
|
||||||
|
{:icon :main-icons/help
|
||||||
|
:title (i18n/label :t/need-help)
|
||||||
|
:accessibility-label :help-button
|
||||||
|
:chevron true
|
||||||
|
:on-press #(re-frame/dispatch [:navigate-to :help-center])}]
|
||||||
|
[quo/list-item
|
||||||
|
{:icon :main-icons/info
|
||||||
|
:title (i18n/label :t/about-app)
|
||||||
|
:accessibility-label :about-button
|
||||||
|
:chevron true
|
||||||
|
:on-press #(re-frame/dispatch [:navigate-to :about-app])}]
|
||||||
|
[react/view {:padding-vertical 24}
|
||||||
[quo/list-item
|
[quo/list-item
|
||||||
{:icon :main-icons/notification
|
{:icon :main-icons/log-out
|
||||||
:title (i18n/label :t/notifications)
|
:title (i18n/label :t/sign-out)
|
||||||
:accessibility-label :notifications-settings-button
|
:accessibility-label :log-out-button
|
||||||
:active notifications-enabled?
|
:theme :negative
|
||||||
:on-press #(re-frame/dispatch
|
:on-press
|
||||||
[::notifications/switch (not notifications-enabled?)])
|
#(re-frame/dispatch [:multiaccounts.logout.ui/logout-pressed])}]]])]))
|
||||||
:accessory :switch}]))
|
|
||||||
[quo/list-item
|
|
||||||
{:icon :main-icons/mobile
|
|
||||||
:title (i18n/label :t/sync-settings)
|
|
||||||
:accessibility-label :sync-settings-button
|
|
||||||
:chevron true
|
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :sync-settings])}]
|
|
||||||
(when (and (or platform/android?
|
|
||||||
config/keycard-test-menu-enabled?)
|
|
||||||
keycard-pairing)
|
|
||||||
[quo/list-item
|
|
||||||
{:icon :main-icons/keycard
|
|
||||||
:title (i18n/label :t/keycard)
|
|
||||||
:accessibility-label :keycard-button
|
|
||||||
:chevron true
|
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :keycard-settings])}])
|
|
||||||
[quo/list-item
|
|
||||||
{:icon :main-icons/settings-advanced
|
|
||||||
:title (i18n/label :t/advanced)
|
|
||||||
:accessibility-label :advanced-button
|
|
||||||
:chevron true
|
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :advanced-settings])}]
|
|
||||||
[quo/list-item
|
|
||||||
{:icon :main-icons/help
|
|
||||||
:title (i18n/label :t/need-help)
|
|
||||||
:accessibility-label :help-button
|
|
||||||
:chevron true
|
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :help-center])}]
|
|
||||||
[quo/list-item
|
|
||||||
{:icon :main-icons/info
|
|
||||||
:title (i18n/label :t/about-app)
|
|
||||||
:accessibility-label :about-button
|
|
||||||
:chevron true
|
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :about-app])}]
|
|
||||||
[react/view {:padding-vertical 24}
|
|
||||||
[quo/list-item
|
|
||||||
{:icon :main-icons/log-out
|
|
||||||
:title (i18n/label :t/sign-out)
|
|
||||||
:accessibility-label :log-out-button
|
|
||||||
:theme :negative
|
|
||||||
:on-press
|
|
||||||
#(re-frame/dispatch [:multiaccounts.logout.ui/logout-pressed])}]]]))
|
|
||||||
|
|
||||||
(defn my-profile []
|
(defn my-profile []
|
||||||
(fn []
|
(fn []
|
||||||
|
@ -195,18 +219,26 @@
|
||||||
on-share #(re-frame/dispatch [:show-popover
|
on-share #(re-frame/dispatch [:show-popover
|
||||||
{:view :share-chat-key
|
{:view :share-chat-key
|
||||||
:address public-key
|
:address public-key
|
||||||
:ens-name preferred-name}])]
|
:ens-name preferred-name}])
|
||||||
[react/view {:style {:flex 1}}
|
{:keys [tab]} @state]
|
||||||
|
[react/view {:flex 1}
|
||||||
[quo/animated-header
|
[quo/animated-header
|
||||||
{:right-accessories [{:icon :main-icons/share
|
{:right-accessories [{:accessibility-label :share-header-button
|
||||||
|
:icon :main-icons/share
|
||||||
:on-press on-share}]
|
:on-press on-share}]
|
||||||
:use-insets true
|
:use-insets true
|
||||||
:extended-header (profile-header/extended-header
|
:extended-header (profile-header/extended-header
|
||||||
{:on-press on-share
|
{:on-press on-share
|
||||||
:title (multiaccounts/displayed-name account)
|
:title (multiaccounts/displayed-name account)
|
||||||
:photo (multiaccounts/displayed-photo account)
|
:photo (multiaccounts/displayed-photo account)
|
||||||
:monospace (not ens-verified)
|
:monospace (not ens-verified)
|
||||||
:subtitle (if (and ens-verified public-key)
|
:subtitle (if (and ens-verified public-key)
|
||||||
(gfy/generate-gfy public-key)
|
(gfy/generate-gfy public-key)
|
||||||
public-key)})}
|
(utils/get-shortened-address public-key))
|
||||||
[content]]])))
|
:bottom-separator false})}
|
||||||
|
[content]]
|
||||||
|
(when-not (= :settings tab)
|
||||||
|
[components.plus-button/plus-button
|
||||||
|
{:on-press #(if (= :contacts tab)
|
||||||
|
(re-frame/dispatch [:navigate-to :new-contact])
|
||||||
|
(re-frame/dispatch [:navigate-to :my-status]))}])])))
|
||||||
|
|
|
@ -2,10 +2,8 @@
|
||||||
(:require [status-im.ui.screens.routing.core :as navigation]
|
(:require [status-im.ui.screens.routing.core :as navigation]
|
||||||
[status-im.ui.screens.home.views :as home]
|
[status-im.ui.screens.home.views :as home]
|
||||||
[status-im.ui.screens.chat.views :as chat]
|
[status-im.ui.screens.chat.views :as chat]
|
||||||
[status-im.ui.screens.profile.contact.views :as profile.contact]
|
|
||||||
[status-im.ui.screens.group.views :as group]
|
[status-im.ui.screens.group.views :as group]
|
||||||
[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.chat.models :as chat.models]
|
|
||||||
[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]))
|
||||||
|
|
||||||
|
@ -16,14 +14,10 @@
|
||||||
[stack {:initial-route-name :home
|
[stack {:initial-route-name :home
|
||||||
:header-mode :none}
|
:header-mode :none}
|
||||||
[{:name :home
|
[{:name :home
|
||||||
:on-focus [::chat.models/offload-all-messages]
|
|
||||||
:style {:padding-bottom tabbar.styles/tabs-diff}
|
:style {:padding-bottom tabbar.styles/tabs-diff}
|
||||||
:component home/home}
|
:component home/home}
|
||||||
{:name :chat
|
{:name :chat
|
||||||
:component chat/chat}
|
:component chat/chat}
|
||||||
{:name :profile
|
|
||||||
:insets {:top false}
|
|
||||||
:component profile.contact/profile}
|
|
||||||
{:name :group-chat-profile
|
{:name :group-chat-profile
|
||||||
:insets {:top false}
|
:insets {:top false}
|
||||||
:component profile.group-chat/group-chat-profile}
|
:component profile.group-chat/group-chat-profile}
|
||||||
|
|
|
@ -35,6 +35,12 @@
|
||||||
(get-active-route-name (bean inner-state))
|
(get-active-route-name (bean inner-state))
|
||||||
(some-> (get route :name) keyword))))
|
(some-> (get route :name) keyword))))
|
||||||
|
|
||||||
|
(defn get-index-route-name [index {:keys [routes]}]
|
||||||
|
(let [route (bean (get routes index))]
|
||||||
|
(if-let [inner-state (get route :state)]
|
||||||
|
(get-active-route-name (bean inner-state))
|
||||||
|
(some-> (get route :name) keyword))))
|
||||||
|
|
||||||
(def transition-presets TransitionPresets)
|
(def transition-presets TransitionPresets)
|
||||||
|
|
||||||
(def modal-presentation-ios (merge (js->clj (.-ModalPresentationIOS ^js transition-presets))
|
(def modal-presentation-ios (merge (js->clj (.-ModalPresentationIOS ^js transition-presets))
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
[status-im.ui.screens.chat.image.preview.views :as image-preview]
|
[status-im.ui.screens.chat.image.preview.views :as image-preview]
|
||||||
[status-im.ui.screens.profile.contact.views :as contact]
|
[status-im.ui.screens.profile.contact.views :as contact]
|
||||||
[status-im.ui.screens.notifications-settings.views :as notifications-settings]
|
[status-im.ui.screens.notifications-settings.views :as notifications-settings]
|
||||||
[status-im.ui.screens.wallet.send.views :as wallet]))
|
[status-im.ui.screens.wallet.send.views :as wallet]
|
||||||
|
[status-im.ui.screens.profile.my-status.views :as my-status]))
|
||||||
|
|
||||||
(defonce main-stack (navigation/create-stack))
|
(defonce main-stack (navigation/create-stack))
|
||||||
(defonce bottom-tabs (navigation/create-bottom-tabs))
|
(defonce bottom-tabs (navigation/create-bottom-tabs))
|
||||||
|
@ -135,7 +136,15 @@
|
||||||
{:name :request-transaction
|
{:name :request-transaction
|
||||||
:transition :presentation-ios
|
:transition :presentation-ios
|
||||||
:insets {:bottom true}
|
:insets {:bottom true}
|
||||||
:component wallet/request-transaction}]
|
:component wallet/request-transaction}
|
||||||
|
{:name :my-status
|
||||||
|
:transition :presentation-ios
|
||||||
|
:insets {:bottom true}
|
||||||
|
:component my-status/my-status}
|
||||||
|
{:name :profile
|
||||||
|
:transition :presentation-ios
|
||||||
|
:insets {:bottom true}
|
||||||
|
:component contact/profile}]
|
||||||
|
|
||||||
(when config/quo-preview-enabled?
|
(when config/quo-preview-enabled?
|
||||||
[{:name :quo-preview
|
[{:name :quo-preview
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
(:require [status-im.ui.screens.profile.user.views :as profile.user]
|
(:require [status-im.ui.screens.profile.user.views :as profile.user]
|
||||||
[status-im.ui.screens.ens.views :as ens]
|
[status-im.ui.screens.ens.views :as ens]
|
||||||
[status-im.ui.screens.contacts-list.views :as contacts-list]
|
[status-im.ui.screens.contacts-list.views :as contacts-list]
|
||||||
[status-im.ui.screens.profile.contact.views :as profile.contact]
|
|
||||||
[status-im.ui.screens.bootnodes-settings.edit-bootnode.views
|
[status-im.ui.screens.bootnodes-settings.edit-bootnode.views
|
||||||
:as
|
:as
|
||||||
edit-bootnode]
|
edit-bootnode]
|
||||||
|
@ -65,9 +64,6 @@
|
||||||
:component ens/name-details}
|
:component ens/name-details}
|
||||||
{:name :blocked-users-list
|
{:name :blocked-users-list
|
||||||
:component contacts-list/blocked-users-list}
|
:component contacts-list/blocked-users-list}
|
||||||
{:name :profile
|
|
||||||
:insets {:top false}
|
|
||||||
:component profile.contact/profile}
|
|
||||||
{:name :bootnodes-settings
|
{:name :bootnodes-settings
|
||||||
:component bootnodes-settings/bootnodes-settings}
|
:component bootnodes-settings/bootnodes-settings}
|
||||||
{:name :installations
|
{:name :installations
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
[status-im.ui.screens.wallet.accounts.views :as accounts]
|
[status-im.ui.screens.wallet.accounts.views :as accounts]
|
||||||
[status-im.ui.screens.wallet.transactions.views :as history]
|
[status-im.ui.screens.wallet.transactions.views :as history]
|
||||||
[status-im.utils.money :as money]
|
[status-im.utils.money :as money]
|
||||||
[status-im.wallet.utils :as wallet.utils])
|
[status-im.wallet.utils :as wallet.utils]
|
||||||
|
[status-im.ui.components.tabs :as tabs])
|
||||||
(:require-macros [status-im.utils.views :as views]))
|
(:require-macros [status-im.utils.views :as views]))
|
||||||
|
|
||||||
(def state (reagent/atom {:tab :assets}))
|
(def state (reagent/atom {:tab :assets}))
|
||||||
|
@ -118,9 +119,9 @@
|
||||||
(let [{:keys [tab]} @state]
|
(let [{:keys [tab]} @state]
|
||||||
[react/view {:flex 1}
|
[react/view {:flex 1}
|
||||||
[react/view {:flex-direction :row :margin-bottom 8 :padding-horizontal 4}
|
[react/view {:flex-direction :row :margin-bottom 8 :padding-horizontal 4}
|
||||||
[accounts/tab-title state :assets (i18n/label :t/wallet-assets) (= tab :assets)]
|
[tabs/tab-title state :assets (i18n/label :t/wallet-assets) (= tab :assets)]
|
||||||
[accounts/tab-title state :nft (i18n/label :t/wallet-collectibles) (= tab :nft)]
|
[tabs/tab-title state :nft (i18n/label :t/wallet-collectibles) (= tab :nft)]
|
||||||
[accounts/tab-title state :history (i18n/label :t/history) (= tab :history)]]
|
[tabs/tab-title state :history (i18n/label :t/history) (= tab :history)]]
|
||||||
(cond
|
(cond
|
||||||
(= tab :assets)
|
(= tab :assets)
|
||||||
[list/flat-list {:data tokens
|
[list/flat-list {:data tokens
|
||||||
|
|
|
@ -58,17 +58,6 @@
|
||||||
[icons/icon :main-icons/add {:color colors/blue}]]
|
[icons/icon :main-icons/add {:color colors/blue}]]
|
||||||
[react/text {:style {:color colors/blue}} (i18n/label :t/add-account)]]])
|
[react/text {:style {:color colors/blue}} (i18n/label :t/add-account)]]])
|
||||||
|
|
||||||
(defn tab-title [state key label active?]
|
|
||||||
[react/view {:align-items :center}
|
|
||||||
[react/touchable-highlight {:on-press #(swap! state assoc :tab key)
|
|
||||||
:underlay-color colors/gray-lighter
|
|
||||||
:style {:border-radius 8}}
|
|
||||||
[react/view {:padding-horizontal 12 :padding-vertical 9}
|
|
||||||
[react/text {:style {:font-weight "500" :color (if active? colors/black colors/gray) :line-height 22}}
|
|
||||||
label]]]
|
|
||||||
(when active?
|
|
||||||
[react/view {:width 24 :height 3 :border-radius 4 :background-color colors/blue}])])
|
|
||||||
|
|
||||||
(defn render-asset [currency & [on-press]]
|
(defn render-asset [currency & [on-press]]
|
||||||
(fn [{:keys [icon decimals amount color value] :as token}]
|
(fn [{:keys [icon decimals amount color value] :as token}]
|
||||||
[quo/list-item
|
[quo/list-item
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
(def hour (* 1000 60 60))
|
(def hour (* 1000 60 60))
|
||||||
(def day (* hour 24))
|
(def day (* hour 24))
|
||||||
(def week (* 7 day))
|
(def week (* 7 day))
|
||||||
(def units [{:name :t/datetime-second :limit 60 :in-second 1}
|
(def units [{:name :t/datetime-second-short :limit 60 :in-second 1}
|
||||||
{:name :t/datetime-minute :limit 3600 :in-second 60}
|
{:name :t/datetime-minute-short :limit 3600 :in-second 60}
|
||||||
{:name :t/datetime-hour :limit 86400 :in-second 3600}
|
{:name :t/datetime-hour-short :limit 86400 :in-second 3600}
|
||||||
{:name :t/datetime-day :limit nil :in-second 86400}])
|
{:name :t/datetime-day-short :limit nil :in-second 86400}])
|
||||||
|
|
||||||
(def time-zone-offset (hours (- (/ (.getTimezoneOffset ^js (js/Date.)) 60))))
|
(def time-zone-offset (hours (- (/ (.getTimezoneOffset ^js (js/Date.)) 60))))
|
||||||
|
|
||||||
|
@ -113,23 +113,23 @@
|
||||||
|
|
||||||
(defn format-time-ago [diff unit]
|
(defn format-time-ago [diff unit]
|
||||||
(let [name (label-pluralize diff (:name unit))]
|
(let [name (label-pluralize diff (:name unit))]
|
||||||
(label :t/datetime-ago-format {:ago (label :t/datetime-ago)
|
(if (= :t/datetime-second-short (:name unit))
|
||||||
:number diff
|
(label :t/now)
|
||||||
:time-intervals name})))
|
(label :t/datetime-ago-format-short {:ago (label :t/datetime-ago)
|
||||||
|
:number diff
|
||||||
|
:time-intervals name}))))
|
||||||
(defn seconds-ago [time]
|
(defn seconds-ago [time]
|
||||||
(t/in-seconds (t/interval time (t/now))))
|
(t/in-seconds (t/interval time (t/now))))
|
||||||
|
|
||||||
(defn time-ago [time]
|
(defn time-ago [time]
|
||||||
(let [diff (seconds-ago time)]
|
(let [diff (seconds-ago time)
|
||||||
(if (< diff 60)
|
unit (first (drop-while #(and (>= diff (:limit %))
|
||||||
(label :t/active-online)
|
(:limit %))
|
||||||
(let [unit (first (drop-while #(and (>= diff (:limit %))
|
units))]
|
||||||
(:limit %))
|
(-> (/ diff (:in-second unit))
|
||||||
units))]
|
Math/floor
|
||||||
(-> (/ diff (:in-second unit))
|
int
|
||||||
Math/floor
|
(format-time-ago unit))))
|
||||||
int
|
|
||||||
(format-time-ago unit))))))
|
|
||||||
|
|
||||||
(defn to-date [ms]
|
(defn to-date [ms]
|
||||||
(from-long ms))
|
(from-long ms))
|
||||||
|
|
|
@ -72,9 +72,8 @@
|
||||||
|
|
||||||
public-key
|
public-key
|
||||||
(navigation/navigate-to-cofx (assoc-in cofx [:db :contacts/identity] public-key)
|
(navigation/navigate-to-cofx (assoc-in cofx [:db :contacts/identity] public-key)
|
||||||
:tabs
|
:profile
|
||||||
{:screen :chat-stack
|
{})))
|
||||||
:params {:screen :profile}})))
|
|
||||||
|
|
||||||
(fx/defn handle-eip681 [cofx data]
|
(fx/defn handle-eip681 [cofx data]
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
|
|
|
@ -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.62.13",
|
"version": "v0.62.14",
|
||||||
"commit-sha1": "7467ca7b103f685dd64d73485555f90c181a4484",
|
"commit-sha1": "b3880027710ee7a28bbdeacbe099412627485d62",
|
||||||
"src-sha256": "0gv9jxn5c5arnxdr33rfw2zkly9c2nyss59vbdyf444140bd6y6y"
|
"src-sha256": "0g3c1rb0hnqr6wk09n4zk9985qs9m7v44f03vfdsrbzvzx93wgkd"
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
"blank-keycard-text": "You can proceed with your keycard once you've generated your keys and name",
|
"blank-keycard-text": "You can proceed with your keycard once you've generated your keys and name",
|
||||||
"blank-keycard-title": "Looks like you’ve tapped \na blank keycard",
|
"blank-keycard-title": "Looks like you’ve tapped \na blank keycard",
|
||||||
"block": "Block",
|
"block": "Block",
|
||||||
|
"unblock": "Unblock",
|
||||||
"block-contact": "Block this user",
|
"block-contact": "Block this user",
|
||||||
"block-contact-details": "Blocking will delete this user's previous messages and stop new ones from reaching you",
|
"block-contact-details": "Blocking will delete this user's previous messages and stop new ones from reaching you",
|
||||||
"blocked-users": "Blocked users",
|
"blocked-users": "Blocked users",
|
||||||
|
@ -276,6 +277,7 @@
|
||||||
"data": "Data",
|
"data": "Data",
|
||||||
"datetime-ago": "ago",
|
"datetime-ago": "ago",
|
||||||
"datetime-ago-format": "{{number}} {{time-intervals}} {{ago}}",
|
"datetime-ago-format": "{{number}} {{time-intervals}} {{ago}}",
|
||||||
|
"datetime-ago-format-short": "{{number}}{{time-intervals}}",
|
||||||
"datetime-day": {
|
"datetime-day": {
|
||||||
"one": "day",
|
"one": "day",
|
||||||
"other": "days"
|
"other": "days"
|
||||||
|
@ -292,6 +294,22 @@
|
||||||
"one": "second",
|
"one": "second",
|
||||||
"other": "seconds"
|
"other": "seconds"
|
||||||
},
|
},
|
||||||
|
"datetime-day-short": {
|
||||||
|
"one": "D",
|
||||||
|
"other": "D"
|
||||||
|
},
|
||||||
|
"datetime-hour-short": {
|
||||||
|
"one": "H",
|
||||||
|
"other": "H"
|
||||||
|
},
|
||||||
|
"datetime-minute-short": {
|
||||||
|
"one": "M",
|
||||||
|
"other": "M"
|
||||||
|
},
|
||||||
|
"datetime-second-short": {
|
||||||
|
"one": "S",
|
||||||
|
"other": "S"
|
||||||
|
},
|
||||||
"datetime-today": "today",
|
"datetime-today": "today",
|
||||||
"datetime-yesterday": "yesterday",
|
"datetime-yesterday": "yesterday",
|
||||||
"decimals": "Decimals",
|
"decimals": "Decimals",
|
||||||
|
@ -1279,8 +1297,16 @@
|
||||||
"address-or-ens-name": "Address or ENS name",
|
"address-or-ens-name": "Address or ENS name",
|
||||||
"name-optional": "Name (optional)",
|
"name-optional": "Name (optional)",
|
||||||
"mute": "Mute",
|
"mute": "Mute",
|
||||||
|
"unmute": "Unmute",
|
||||||
"scan-tokens": "Scan tokens",
|
"scan-tokens": "Scan tokens",
|
||||||
|
"my-status": "My status",
|
||||||
"warning-sending-to-contract-descr": "The address you entered is a smart contract, sending funds to this address may result in loss of funds. To interact with a DApp, open the DApp in the Status DApp Browser.",
|
"warning-sending-to-contract-descr": "The address you entered is a smart contract, sending funds to this address may result in loss of funds. To interact with a DApp, open the DApp in the Status DApp Browser.",
|
||||||
|
"contacts-descr": "Your contacts will appear here. You will receive status updates from anyone you add as a contact",
|
||||||
|
"status-updates-descr": "Status updates will appear here. Add the profile as a contact to receive updates on your timeline.",
|
||||||
|
"whats-on-your-mind": "What’s on your mind…",
|
||||||
"cant-open-public-chat": "Can't open public chat",
|
"cant-open-public-chat": "Can't open public chat",
|
||||||
"invalid-public-chat-topic": "Invalid public chat topic"
|
"invalid-public-chat-topic": "Invalid public chat topic",
|
||||||
|
"now": "Now",
|
||||||
|
"statuses-my-profile-descr": "Status updates are messages you publish to your profile. They can be viewed by anyone visiting your profile inside Status",
|
||||||
|
"new-status": "New status"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue