From eae66c967e3f931ec924f3442ae9776b144999b0 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 2 Oct 2020 11:53:02 +0200 Subject: [PATCH] my status Signed-off-by: andrey --- src/quo/components/list/item.cljs | 2 +- src/status_im/chat/models.cljs | 15 +- src/status_im/chat/models/input.cljs | 9 + src/status_im/chat/models/message_list.cljs | 2 +- src/status_im/chat/models_test.cljs | 2 +- src/status_im/contact/block.cljs | 10 +- src/status_im/data_store/chats.cljs | 11 +- src/status_im/events.cljs | 42 ++- src/status_im/qr_scanner/core.cljs | 8 +- src/status_im/subs.cljs | 12 +- src/status_im/transport/filters/core.cljs | 4 +- src/status_im/ui/components/plus_button.cljs | 41 +++ .../ui/components/profile_header/view.cljs | 10 +- src/status_im/ui/components/tabbar/core.cljs | 8 +- src/status_im/ui/components/tabs.cljs | 15 + .../ui/screens/add_new/new_chat/events.cljs | 2 +- .../ui/screens/chat/message/message.cljs | 1 - src/status_im/ui/screens/chat/sheets.cljs | 19 +- .../ui/screens/chat/styles/input/gap.cljs | 2 +- src/status_im/ui/screens/chat/views.cljs | 65 ++-- .../ui/screens/contacts_list/views.cljs | 77 ++--- src/status_im/ui/screens/home/styles.cljs | 24 -- src/status_im/ui/screens/home/views.cljs | 18 +- .../ui/screens/profile/contact/styles.cljs | 10 + .../ui/screens/profile/contact/views.cljs | 194 +++++------ .../ui/screens/profile/my_status/views.cljs | 108 +++++++ src/status_im/ui/screens/profile/status.cljs | 72 +++++ .../ui/screens/profile/user/styles.cljs | 17 +- .../ui/screens/profile/user/views.cljs | 300 ++++++++++-------- .../ui/screens/routing/chat_stack.cljs | 6 - src/status_im/ui/screens/routing/core.cljs | 6 + src/status_im/ui/screens/routing/main.cljs | 13 +- .../ui/screens/routing/profile_stack.cljs | 4 - .../ui/screens/wallet/account/views.cljs | 9 +- .../ui/screens/wallet/accounts/views.cljs | 11 - src/status_im/utils/datetime.cljs | 34 +- src/status_im/utils/universal_links/core.cljs | 5 +- status-go-version.json | 6 +- translations/en.json | 28 +- 39 files changed, 783 insertions(+), 439 deletions(-) create mode 100644 src/status_im/ui/components/plus_button.cljs create mode 100644 src/status_im/ui/components/tabs.cljs create mode 100644 src/status_im/ui/screens/profile/my_status/views.cljs create mode 100644 src/status_im/ui/screens/profile/status.cljs diff --git a/src/quo/components/list/item.cljs b/src/quo/components/list/item.cljs index ee10712610..2056ef81fd 100644 --- a/src/quo/components/list/item.cljs +++ b/src/quo/components/list/item.cljs @@ -64,7 +64,7 @@ :justify-content :space-between})}] children)) -(defn- icon-column +(defn icon-column [{:keys [icon icon-bg-color icon-color size icon-container-style]}] (when icon (let [icon-size (size->icon-size size)] diff --git a/src/status_im/chat/models.cljs b/src/status_im/chat/models.cljs index de496ebe21..b74fa7705d 100644 --- a/src/status_im/chat/models.cljs +++ b/src/status_im/chat/models.cljs @@ -162,9 +162,10 @@ (fx/defn add-public-chat "Adds new public group chat to db" - [cofx topic] + [cofx topic profile-public-key] (upsert-chat cofx {:chat-id topic + :profile-public-key profile-public-key :is-active true :name topic :chat-name (str "#" topic) @@ -243,8 +244,9 @@ (fx/defn navigate-to-chat "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 + {:db (assoc db :inactive-chat-id chat-id)} (preload-chat-data chat-id) (navigation/navigate-to-cofx :chat-stack {:screen :chat}))) @@ -260,15 +262,18 @@ (transport.filters/load-chat chat-id) (navigate-to-chat chat-id)))) +(defn profile-chat-topic [public-key] + (str "@" public-key)) + (fx/defn start-public-chat "Starts a new public chat" - [cofx topic {:keys [dont-navigate?]}] - (if (new-public-chat.db/valid-topic? topic) + [cofx topic {:keys [dont-navigate? profile-public-key]}] + (if (or (new-public-chat.db/valid-topic? topic) profile-public-key) (if (active-chat? cofx topic) (when-not dont-navigate? (navigate-to-chat cofx topic)) (fx/merge cofx - (add-public-chat topic) + (add-public-chat topic profile-public-key) (transport.filters/load-chat topic) #(when-not dont-navigate? (navigate-to-chat % topic)))) diff --git a/src/status_im/chat/models/input.cljs b/src/status_im/chat/models/input.cljs index f5c81c856f..abbe833c8b 100644 --- a/src/status_im/chat/models/input.cljs +++ b/src/status_im/chat/models/input.cljs @@ -142,6 +142,15 @@ :image-path (utils/safe-replace image-path #"file://" "") :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 [cofx audio-path duration current-chat-id] (when-not (string/blank? audio-path) diff --git a/src/status_im/chat/models/message_list.cljs b/src/status_im/chat/models/message_list.cljs index 836f6e08d3..0eada64827 100644 --- a/src/status_im/chat/models/message_list.cljs +++ b/src/status_im/chat/models/message_list.cljs @@ -28,7 +28,7 @@ add-timestamp)) ;; 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? "Whether a message is in the same group as the one after it. diff --git a/src/status_im/chat/models_test.cljs b/src/status_im/chat/models_test.cljs index 23f7b186d8..02967b8b63 100644 --- a/src/status_im/chat/models_test.cljs +++ b/src/status_im/chat/models_test.cljs @@ -49,7 +49,7 @@ (with-redefs [gfycat/generate-gfy (constantly "generated") identicon/identicon (constantly "generated")] (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])] (testing "it sets the name" (is (= topic (:name chat)))) diff --git a/src/status_im/contact/block.cljs b/src/status_im/contact/block.cljs index e82ead53e6..849f972611 100644 --- a/src/status_im/contact/block.cljs +++ b/src/status_im/contact/block.cljs @@ -7,12 +7,6 @@ [status-im.navigation :as navigation] [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 [{:keys [db] :as cofx} public-key @@ -48,7 +42,7 @@ public-key) (assoc :last-updated now) (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 {:db (-> db ;; add the contact to blocked contacts @@ -61,7 +55,7 @@ (re-frame/dispatch [:hide-popover]))) ;; reset navigation to avoid going back to non existing one to one chat (if from-one-to-one-chat? - remove-current-chat-id + (navigation/navigate-to-cofx :home {}) (navigation/navigate-back))))) (fx/defn unblock-contact diff --git a/src/status_im/data_store/chats.cljs b/src/status_im/data_store/chats.cljs index 4eeafb4538..8a5022bac8 100644 --- a/src/status_im/data_store/chats.cljs +++ b/src/status_im/data_store/chats.cljs @@ -8,10 +8,12 @@ (def one-to-one-chat-type 1) (def public-chat-type 2) (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 public? public-chat-type + profile-public-key profile-chat-type group-chat private-group-chat-type :else one-to-one-chat-type))) @@ -21,6 +23,7 @@ :chat-name (str "#" name) :public? true :group-chat true) + (= profile-chat-type chatType) (assoc chat :public? true) (= private-group-chat-type chatType) (assoc chat :chat-name name :public? false @@ -72,7 +75,8 @@ :last-message :lastMessage :deleted-at-clock-value :deletedAtClockValue :is-active :active - :last-clock-value :lastClockValue}) + :last-clock-value :lastClockValue + :profile-public-key :profile}) (dissoc :public? :group-chat :messages :might-have-join-time-messages? :loaded-unviewed-messages-ids @@ -89,7 +93,8 @@ :lastMessage :last-message :active :is-active :lastClockValue :last-clock-value - :invitationAdmin :invitation-admin}) + :invitationAdmin :invitation-admin + :profile :profile-public-key}) (update :last-message #(when % (messages/<-rpc %))) (dissoc :chatType :members))) diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index f9d0d85b42..c3f8615d46 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -1245,10 +1245,24 @@ (fn [{:keys [db]} [_ 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 (handlers/register-handler-fx :screens/on-will-focus - (fn [cofx [_ view-id]] + (fn [{:keys [db] :as cofx} [_ view-id]] (fx/merge cofx #(case view-id :keycard-settings (keycard/settings-screen-did-load %) @@ -1257,10 +1271,28 @@ :keycard-login-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 %) - ;; We need this as if you click on universal-links you transition - ;; from chat to chat, and therefore we won't be loading new - ;; messages - :chat (chat.loading/load-messages %) + (:chat :group-chat-profile) (reset-current-chat % (get db :inactive-chat-id)) :multiaccounts (keycard/multiaccounts-screen-did-load %) (: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)))) + +(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)))) \ No newline at end of file diff --git a/src/status_im/qr_scanner/core.cljs b/src/status_im/qr_scanner/core.cljs index bf5e02b4a9..49f982ec38 100644 --- a/src/status_im/qr_scanner/core.cljs +++ b/src/status_im/qr_scanner/core.cljs @@ -63,10 +63,10 @@ :params {:screen :my-profile}}) (and public-key (not own)) - (navigation/navigate-to-cofx (assoc-in cofx [:db :contacts/identity] public-key) - :tabs - {:screen :chat-stack - :params {:screen :profile}}) + (fx/merge cofx + {:db (assoc db :contacts/identity public-key) + :dispatch [:navigate-to :profile]} + (navigation/navigate-back)) :else {:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) diff --git a/src/status_im/subs.cljs b/src/status_im/subs.cljs index 7e6aa2bb61..87ddd2299e 100644 --- a/src/status_im/subs.cljs +++ b/src/status_im/subs.cljs @@ -123,6 +123,7 @@ (reg-root-key-sub :chats/mention-suggestions :chats/mention-suggestions) (reg-root-key-sub :chats/cursor :chats/cursor) (reg-root-key-sub :chats/input-with-mentions :chats/input-with-mentions) +(reg-root-key-sub :inactive-chat-id :inactive-chat-id) ;;browser (reg-root-key-sub :browsers :browser/browsers) (reg-root-key-sub :browser/options :browser/options) @@ -612,8 +613,8 @@ :chats/active-chats :<- [::chats] (fn [chats] - (reduce-kv (fn [acc id {:keys [is-active] :as chat}] - (if is-active + (reduce-kv (fn [acc id {:keys [is-active profile-public-key] :as chat}] + (if (and is-active (not profile-public-key)) (assoc acc id chat) acc)) {} @@ -650,9 +651,10 @@ :chats/current-chat :<- [:chats/current-raw-chat] :<- [:multiaccount/public-key] + :<- [:inactive-chat-id] (fn [[{:keys [group-chat] :as current-chat} - my-public-key]] - (when current-chat + my-public-key inactive-chat-id]] + (when (and current-chat (= (:chat-id current-chat) inactive-chat-id)) (cond-> current-chat (chat.models/public-chat? current-chat) (assoc :show-input? true) @@ -812,7 +814,7 @@ (re-frame/reg-sub :chats/sending-image - :<- [:chats/current-chat] + :<- [:chats/current-raw-chat] (fn [{:keys [metadata]}] (get-in metadata [:sending-image]))) diff --git a/src/status_im/transport/filters/core.cljs b/src/status_im/transport/filters/core.cljs index 3fa0b6a0e4..bc44e95bd0 100644 --- a/src/status_im/transport/filters/core.cljs +++ b/src/status_im/transport/filters/core.cljs @@ -12,7 +12,9 @@ [taoensso.timbre :as log])) (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] (json-rpc/call {:method (json-rpc/call-ext-method "loadFilters") diff --git a/src/status_im/ui/components/plus_button.cljs b/src/status_im/ui/components/plus_button.cljs new file mode 100644 index 0000000000..b83f692b3a --- /dev/null +++ b/src/status_im/ui/components/plus_button.cljs @@ -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}])]]]) \ No newline at end of file diff --git a/src/status_im/ui/components/profile_header/view.cljs b/src/status_im/ui/components/profile_header/view.cljs index 688a3dfe83..3d68f92c1d 100644 --- a/src/status_im/ui/components/profile_header/view.cljs +++ b/src/status_im/ui/components/profile_header/view.cljs @@ -12,8 +12,9 @@ (def subtitle-margin 4) (defn container-style [{:keys [animation minimized]}] - (merge {:flex-direction :row - :align-items :center} + (merge {:flex-direction :row + :padding-vertical 4 + :align-items :center} (if-not minimized (:base spacing/padding-horizontal) {:opacity animation}))) @@ -36,7 +37,8 @@ (when-not minimized {: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]}] (let [wrapper (if on-press [rn/touchable-opacity {:on-press on-press}] @@ -78,5 +80,5 @@ subtitle]])]] (when-not minimized [animated/view {:pointer-events :none - :style (header-bottom-separator)}])]])))) + :style (when bottom-separator (header-bottom-separator))}])]])))) diff --git a/src/status_im/ui/components/tabbar/core.cljs b/src/status_im/ui/components/tabbar/core.cljs index 3ce68aac92..65b1a52493 100644 --- a/src/status_im/ui/components/tabbar/core.cljs +++ b/src/status_im/ui/components/tabbar/core.cljs @@ -75,7 +75,7 @@ (def tabs (reagent/adapt-react-class (fn [props] - (let [{:keys [navigate index route]} (bean props) + (let [{:keys [navigate index route state]} (bean props) {:keys [keyboard-shown] :or {keyboard-shown false}} (when platform/android? (rn/use-keyboard)) {:keys [bottom]} (safe-area/use-safe-area) @@ -99,7 +99,10 @@ [tab {:icon icon :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 :count-subscription count-subscription :active? (= (str index) (str route-index)) @@ -113,5 +116,6 @@ index (get state :index)] (reagent/as-element [tabs {:navigate navigate + :state (oget props "state") :route (navigation/get-active-route-name state) :index index}]))) diff --git a/src/status_im/ui/components/tabs.cljs b/src/status_im/ui/components/tabs.cljs new file mode 100644 index 0000000000..73ceedd1a2 --- /dev/null +++ b/src/status_im/ui/components/tabs.cljs @@ -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}])]) \ No newline at end of file diff --git a/src/status_im/ui/screens/add_new/new_chat/events.cljs b/src/status_im/ui/screens/add_new/new_chat/events.cljs index 059b9a5ff9..db341618ff 100644 --- a/src/status_im/ui/screens/add_new/new_chat/events.cljs +++ b/src/status_im/ui/screens/add_new/new_chat/events.cljs @@ -95,7 +95,7 @@ (if new-contact? (fx/merge cofx (contact/add-contact chat-key nil) - (navigation/navigate-to-cofx :contacts-list {})) + (navigation/navigate-to-cofx :my-profile {})) (chat/start-chat cofx chat-key)) {:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) :content (get-validation-label validation-result) diff --git a/src/status_im/ui/screens/chat/message/message.cljs b/src/status_im/ui/screens/chat/message/message.cljs index b1628aeebe..834a2374eb 100644 --- a/src/status_im/ui/screens/chat/message/message.cljs +++ b/src/status_im/ui/screens/chat/message/message.cljs @@ -271,7 +271,6 @@ (js/setTimeout #(on-long-press-fn on-long-press message content) 200)) (on-long-press-fn on-long-press message content)))}) [react/view (assoc (style/message-view message) - :remove-clipped-subviews (not outgoing) :max-height (when-not (or outgoing modal) (if @collapsible? (if @collapsed? message-height-px nil) diff --git a/src/status_im/ui/screens/chat/sheets.cljs b/src/status_im/ui/screens/chat/sheets.cljs index 867dc393f6..17122d5cec 100644 --- a/src/status_im/ui/screens/chat/sheets.cljs +++ b/src/status_im/ui/screens/chat/sheets.cljs @@ -159,7 +159,7 @@ :accessibility-label :delete-transaccent-button :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 [] (let [contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])] [react/view @@ -177,14 +177,15 @@ (when from-preview? (re-frame/dispatch [:navigate-back])) (hide-sheet-and-dispatch [:chat.ui/show-profile from]))}]) - [quo/list-item - {:theme :accent - :title (i18n/label :t/message-reply) - :icon :main-icons/reply - :on-press #(do - (when from-preview? - (re-frame/dispatch [:navigate-back])) - (hide-sheet-and-dispatch [:chat.ui/reply-to-message message]))}] + (when-not cant-be-replied + [quo/list-item + {:theme :accent + :title (i18n/label :t/message-reply) + :icon :main-icons/reply + :on-press #(do + (when from-preview? + (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 #_[quo/list-item {:theme :accent diff --git a/src/status_im/ui/screens/chat/styles/input/gap.cljs b/src/status_im/ui/screens/chat/styles/input/gap.cljs index 80a2e80c05..95587ae499 100644 --- a/src/status_im/ui/screens/chat/styles/input/gap.cljs +++ b/src/status_im/ui/screens/chat/styles/input/gap.cljs @@ -8,7 +8,7 @@ :height 48 :align-items :center :justify-content :center - :border-color colors/black-transparent + :border-color colors/gray-lighter :border-top-width 1 :border-bottom-width 1}) diff --git a/src/status_im/ui/screens/chat/views.cljs b/src/status_im/ui/screens/chat/views.cljs index 695e32d0bc..1e42a48ae7 100644 --- a/src/status_im/ui/screens/chat/views.cljs +++ b/src/status_im/ui/screens/chat/views.cljs @@ -281,36 +281,37 @@ (fn [] (let [{:keys [chat-id show-input? group-chat admins invitation-admin] :as current-chat} @(re-frame/subscribe [:chats/current-chat])] - [react/view {:style {:flex 1}} - [connectivity/connectivity - [topbar] + (when current-chat [react/view {:style {:flex 1}} - (if group-chat - [invitation-requests chat-id admins] - [add-contact-bar chat-id]) - [messages-view {:chat current-chat - :bottom-space (max @bottom-space @panel-space) - :pan-responder pan-responder - :space-keeper space-keeper}]]] - (when (and group-chat invitation-admin) - [accessory/view {:y position-y - :on-update-inset on-update} - [invitation-bar chat-id]]) - ;; NOTE(rasom): on android we have to place `autocomplete-mentions` - ;; outside `accessory/view` because otherwise :keyboardShouldPersistTaps - ;; :always doesn't work and keyboard is hidden on pressing suggestion. - ;; Scrolling of suggestions doesn't work neither in this case. - (when platform/android? - [components/autocomplete-mentions text-input-ref]) - (when show-input? - [accessory/view {:y position-y - :pan-state pan-state - :has-panel (boolean @active-panel) - :on-close #(set-active-panel nil) - :on-update-inset on-update} - [components/chat-toolbar - {:active-panel @active-panel - :set-active-panel set-active-panel - :text-input-ref text-input-ref - :on-text-change on-text-change}] - [bottom-sheet @active-panel]])])))) + [connectivity/connectivity + [topbar] + [react/view {:style {:flex 1}} + (if group-chat + [invitation-requests chat-id admins] + [add-contact-bar chat-id]) + [messages-view {:chat current-chat + :bottom-space (max @bottom-space @panel-space) + :pan-responder pan-responder + :space-keeper space-keeper}]]] + (when (and group-chat invitation-admin) + [accessory/view {:y position-y + :on-update-inset on-update} + [invitation-bar chat-id]]) + ;; NOTE(rasom): on android we have to place `autocomplete-mentions` + ;; outside `accessory/view` because otherwise :keyboardShouldPersistTaps + ;; :always doesn't work and keyboard is hidden on pressing suggestion. + ;; Scrolling of suggestions doesn't work neither in this case. + (when platform/android? + [components/autocomplete-mentions text-input-ref]) + (when show-input? + [accessory/view {:y position-y + :pan-state pan-state + :has-panel (boolean @active-panel) + :on-close #(set-active-panel nil) + :on-update-inset on-update} + [components/chat-toolbar + {:active-panel @active-panel + :set-active-panel set-active-panel + :text-input-ref text-input-ref + :on-text-change on-text-change}] + [bottom-sheet @active-panel]])]))))) diff --git a/src/status_im/ui/screens/contacts_list/views.cljs b/src/status_im/ui/screens/contacts_list/views.cljs index 8a76d22c57..0259ba7148 100644 --- a/src/status_im/ui/screens/contacts_list/views.cljs +++ b/src/status_im/ui/screens/contacts_list/views.cljs @@ -6,9 +6,9 @@ [status-im.ui.components.react :as react] [status-im.ui.components.chat-icon.screen :as chat-icon.screen] [status-im.i18n :as i18n] - [status-im.ui.components.invite.views :as invite] [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]])) (defn contacts-list-item [{:keys [public-key] :as contact}] @@ -21,45 +21,50 @@ :chevron true :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 [] (letsubs [blocked-contacts-count [:contacts/blocked-count] - contacts [:contacts/active]] - [react/view {:flex 1} - [topbar/topbar {:title (i18n/label :t/contacts)}] - [react/scroll-view {:flex 1} - [add-new-contact] - (when (pos? blocked-contacts-count) - [react/view {:margin-vertical 16} - [quo/list-item - {:title (i18n/label :t/blocked-users) - :icon :main-icons/cancel - :theme :negative - :accessibility-label :blocked-users-list-button - :chevron true - :accessory :text - :accessory-text blocked-contacts-count - :on-press #(re-frame/dispatch [:navigate-to :blocked-users-list])}]]) - (if (seq contacts) - [list.views/flat-list - {:data contacts - :key-fn :address - :render-fn contacts-list-item}] - [react/view {:align-items :center :flex 1 :justify-content :center} - [react/text {:style {:color colors/gray :margin-vertical 24}} - (i18n/label :t/you-dont-have-contacts)] - [invite/button]])]])) + contacts [:contacts/active]] + [:<> + (when (pos? blocked-contacts-count) + [react/view {:margin-vertical 16} + [quo/list-item + {:title (i18n/label :t/blocked-users) + :icon :main-icons/cancel + :theme :negative + :accessibility-label :blocked-users-list-button + :chevron true + :accessory :text + :accessory-text blocked-contacts-count + :on-press #(re-frame/dispatch [:navigate-to :blocked-users-list])}]]) + (if (seq contacts) + [list.views/flat-list + {:data contacts + :key-fn :address + :render-fn contacts-list-item + :footer [react/view {:height 68}]}] + [react/view {:padding-horizontal 32 :margin-top 32} + [react/view {: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} + [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 [] (letsubs [blocked-contacts [:contacts/blocked]] - [react/view {:flex 1 + [react/view {:flex 1 :background-color colors/white} [topbar/topbar {:title (i18n/label :t/blocked-users)}] [react/scroll-view {:style {:background-color colors/white diff --git a/src/status_im/ui/screens/home/styles.cljs b/src/status_im/ui/screens/home/styles.cljs index 59e16757df..e32e80c6e2 100644 --- a/src/status_im/ui/screens/home/styles.cljs +++ b/src/status_im/ui/screens/home/styles.cljs @@ -59,30 +59,6 @@ :margin-horizontal 40 :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 {:align-items :center :justify-content :center}) diff --git a/src/status_im/ui/screens/home/views.cljs b/src/status_im/ui/screens/home/views.cljs index 74858542da..2a24397c55 100644 --- a/src/status_im/ui/screens/home/views.cljs +++ b/src/status_im/ui/screens/home/views.cljs @@ -19,7 +19,8 @@ [status-im.utils.utils :as utils] [cljs-bean.core :as bean] [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])) (defn welcome-image-wrapper [] @@ -158,16 +159,11 @@ (views/defview plus-button [] (views/letsubs [logging-in? [:multiaccounts/login]] - [react/view styles/action-button-container - [quo/button {:type :scale - :accessibility-label :new-chat-button - :on-press (when-not logging-in? - #(re-frame/dispatch [:bottom-sheet/show-sheet :add-new {}]))} - [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}])]]])) + [components.plus-button/plus-button + {:on-press (when-not logging-in? + #(re-frame/dispatch [:bottom-sheet/show-sheet :add-new {}])) + :loading logging-in? + :accessibility-label :new-chat-button}])) (defn home [] [react/keyboard-avoiding-view {:style styles/home-container} diff --git a/src/status_im/ui/screens/profile/contact/styles.cljs b/src/status_im/ui/screens/profile/contact/styles.cljs index 923b8e6559..a6446de72f 100644 --- a/src/status_im/ui/screens/profile/contact/styles.cljs +++ b/src/status_im/ui/screens/profile/contact/styles.cljs @@ -12,3 +12,13 @@ (def contact-profile-detail-share-icon {: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}) diff --git a/src/status_im/ui/screens/profile/contact/views.cljs b/src/status_im/ui/screens/profile/contact/views.cljs index f83181cf8c..00f6bf06fb 100644 --- a/src/status_im/ui/screens/profile/contact/views.cljs +++ b/src/status_im/ui/screens/profile/contact/views.cljs @@ -17,42 +17,48 @@ [status-im.ui.components.keyboard-avoid-presentation :as kb-presentation] [status-im.utils.platform :as platform] [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])) (defn actions - [{:keys [public-key added? tribute-to-talk] :as contact}] - (let [{:keys [tribute-status tribute-label]} tribute-to-talk] - (concat [(cond-> {:label (i18n/label :t/send-message) - :icon :main-icons/message - :action #(re-frame/dispatch [:contact.ui/send-message-pressed {:public-key public-key}]) - :accessibility-label :start-conversation-button} - (not (#{:none :paid} tribute-status)) - (assoc :subtext tribute-label))] - ;;TODO hide temporary for v1 - #_{:label (i18n/label :t/send-transaction) - :icon :main-icons/send - :action #(re-frame/dispatch [:profile/send-transaction public-key]) - :accessibility-label :send-transaction-button} - (if added? - [{:label (i18n/label :t/remove-from-contacts) - :icon :main-icons/remove-contact - :accessibility-label :in-contacts-button - :action #(re-frame/dispatch [:contact.ui/remove-contact-pressed contact])}] - ;; TODO sheets temporary disabled - ;:action #(re-frame/dispatch [:bottom-sheet/show-sheet - ; {:content sheets/remove-contact - ; :content-height 150} - ; contact]) - [{:label (i18n/label :t/add-to-contacts) - :icon :main-icons/add-contact - :accessibility-label :add-to-contacts-button - :action #(re-frame/dispatch [:contact.ui/add-to-contact-pressed public-key])}])))) - ;; TODO sheets temporary disabled - ;:action #(re-frame/dispatch [:bottom-sheet/show-sheet - ; {:content sheets/add-contact - ; :content-height 150} - ; contact]) + [{:keys [public-key added? blocked?] :as contact} muted?] + (concat [{:label (i18n/label :t/chat) + :icon :main-icons/message + :action #(re-frame/dispatch [:contact.ui/send-message-pressed {:public-key public-key}]) + :accessibility-label :start-conversation-button}] + (if added? + [{:label (i18n/label :t/remove-from-contacts) + :icon :main-icons/remove-contact + :selected true + :accessibility-label :in-contacts-button + :action #(re-frame/dispatch [:contact.ui/remove-contact-pressed contact])}] + [{:label (i18n/label :t/add-to-contacts) + :icon :main-icons/add-contact + :accessibility-label :add-to-contacts-button + :action #(re-frame/dispatch [:contact.ui/add-to-contact-pressed public-key])}]) + (when platform/ios? + [{:label (i18n/label (if muted? :t/unmute :t/mute)) + :icon :main-icons/notification + :accessibility-label :mute-chat + :selected muted? + :action #(re-frame/dispatch [::chat.models/mute-chat-toggled public-key (not muted?)])}]) + [{:label (i18n/label (if blocked? :t/unblock :t/block)) + :negative true + :selected blocked? + :icon :main-icons/cancel + :action (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}])) + :accessibility-label (if blocked? + :unblock-contact + :block-contact)}])) (defn render-detail [{:keys [public-key names name] :as detail}] [quo/list-item @@ -78,49 +84,15 @@ (i18n/label :t/profile-details)]] [render-detail contact]])) -(defn render-chat-settings [{:keys [public-key names]}] - (let [muted? (:muted @(re-frame/subscribe [:chats/chat public-key]))] - [react/view - [quo/list-item - {:title (i18n/label :t/nickname) - :size :small - :accessibility-label :profile-nickname-item - :accessory :text - :accessory-text (or (:nickname names) (i18n/label :t/none)) - :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 nickname-settings [{:keys [names]}] + [quo/list-item + {:title (i18n/label :t/nickname) + :size :small + :accessibility-label :profile-nickname-item + :accessory :text + :accessory-text (or (:nickname names) (i18n/label :t/none)) + :on-press #(re-frame/dispatch [:navigate-to :nickname]) + :chevron true}]) (defn save-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]] [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/letsubs [{:keys [public-key name ens-verified] :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 {:view :share-chat-key :address public-key} (when (and ens-verified name) {:ens-name name}))])] (when contact - [react/view - {:style - (merge {:flex 1})} + [react/view {:flex 1} [quo/animated-header - {:use-insets true + {:use-insets false :right-accessories [{:icon :main-icons/share + :accessibility-label :share-button :on-press on-share}] - :left-accessories [{:icon :main-icons/arrow-left + :left-accessories [{:icon :main-icons/close :accessibility-label :back-button :on-press #(re-frame/dispatch [:navigate-back])}] :extended-header (profile-header/extended-header {:on-press on-share + :bottom-separator false :title first-name :photo (multiaccounts/displayed-photo contact) :monospace (not ens-verified) :subtitle second-name})} - - [react/view {:padding-top 12} - (for [{:keys [label subtext accessibility-label icon action disabled?]} (actions contact) + [react/view {:height 1 :background-color colors/gray-lighter :margin-top 8}] + [nickname-settings 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] ^{:key label} - [quo/list-item {:theme :accent - :title label - :subtitle subtext - :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]]])))) + [button-item action])] + [react/view {:height 1 :background-color colors/gray-lighter :margin-top 16}] + [status]]])))) + diff --git a/src/status_im/ui/screens/profile/my_status/views.cljs b/src/status_im/ui/screens/profile/my_status/views.cljs new file mode 100644 index 0000000000..776450691e --- /dev/null +++ b/src/status_im/ui/screens/profile/my_status/views.cljs @@ -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")]]]]]]))) diff --git a/src/status_im/ui/screens/profile/status.cljs b/src/status_im/ui/screens/profile/status.cljs new file mode 100644 index 0000000000..111e136f2a --- /dev/null +++ b/src/status_im/ui/screens/profile/status.cljs @@ -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]))) \ No newline at end of file diff --git a/src/status_im/ui/screens/profile/user/styles.cljs b/src/status_im/ui/screens/profile/user/styles.cljs index 90955456e7..5531661986 100644 --- a/src/status_im/ui/screens/profile/user/styles.cljs +++ b/src/status_im/ui/screens/profile/user/styles.cljs @@ -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 - {:margin-top 12 + {:margin-top 12 :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}) \ No newline at end of file diff --git a/src/status_im/ui/screens/profile/user/views.cljs b/src/status_im/ui/screens/profile/user/views.cljs index f2db27abb8..52dcc65300 100644 --- a/src/status_im/ui/screens/profile/user/views.cljs +++ b/src/status_im/ui/screens/profile/user/views.cljs @@ -17,7 +17,15 @@ [status-im.utils.gfycat.core :as gfy] [status-im.utils.universal-links.utils :as universal-links] [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])) (views/defview share-chat-key [] @@ -55,14 +63,37 @@ :accessibility-label :share-my-contact-code-button} (i18n/label :t/share-link)]]]))) -(defn tribute-to-talk-item - [opts] - [quo/list-item - (merge {:title (i18n/label :t/tribute-to-talk) - :accessibility-label :notifications-button - :on-press #(re-frame/dispatch - [:tribute-to-talk.ui/menu-item-pressed])} - opts)]) +(def state (reagent/atom {:tab :status})) + +(defn tabs [] + (let [{:keys [tab]} @state] + [react/view {:flex-direction :row :padding-horizontal 4 :margin-top 16} + [tabs/tab-title state :status (i18n/label :t/my-status) (= tab :status)] + [tabs/tab-title state :contacts (i18n/label :t/contacts) (= tab :contacts)] + [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 [] (let [{:keys [preferred-name @@ -70,123 +101,116 @@ notifications-enabled? keycard-pairing]} @(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]) - registrar (stateofus/get-cached-registrar chain)] + registrar (stateofus/get-cached-registrar chain) + {:keys [tab]} @state] [:<> - [quo/list-item - (cond-> {:title (or (when registrar preferred-name) - (i18n/label :t/ens-usernames)) - :subtitle (if registrar - (if preferred-name - (i18n/label :t/ens-your-your-name) - (i18n/label :t/ens-usernames-details)) - (i18n/label :t/ens-network-restriction)) - :subtitle-max-lines (if registrar - (if preferred-name 1 2) - 1) - :accessibility-label :ens-button - :container-margin-top 8 - :disabled (not registrar) - :chevron true - :icon :main-icons/username} - registrar - (assoc :on-press #(re-frame/dispatch [:navigate-to :ens-main registrar])))] - ;; TODO replace this with list-item config map - ;; left it as it is because not sure how to enable it for testing - (when tribute-to-talk [tribute-to-talk-item tribute-to-talk]) - [quo/list-item - {:title (i18n/label :t/contacts) - :icon :main-icons/in-contacts - :accessibility-label :contacts-button - :accessory :text - :accessory-text (if (pos? active-contacts-count) - (str active-contacts-count) - (i18n/label :t/none)) - :chevron true - :on-press #(re-frame/dispatch [:navigate-to :contacts-list])}] - [react/view {:padding-top 16} - [quo/list-header (i18n/label :t/settings)]] - [quo/list-item - {:icon :main-icons/security - :title (i18n/label :t/privacy-and-security) - :accessibility-label :privacy-and-security-settings-button - :chevron true - :accessory (when mnemonic - [components.common/counter {:size 22} 1]) - :on-press #(re-frame/dispatch [:navigate-to :privacy-and-security])}] - (when config/quo-preview-enabled? - [quo/list-item - {:icon :main-icons/appearance - :title "Quo Preview" - :accessibility-label :appearance-settings-button - :chevron true - :on-press #(re-frame/dispatch [:navigate-to :quo-preview])}]) - [quo/list-item - {:icon :main-icons/appearance - :title (i18n/label :t/appearance) - :accessibility-label :appearance-settings-button - :chevron true - :on-press #(re-frame/dispatch [:navigate-to :appearance])}] - (if platform/ios? - [quo/list-item - {:icon :main-icons/notification - :title (i18n/label :t/notifications) - :accessibility-label :notifications-settings-button - :chevron true - :on-press #(re-frame/dispatch [:navigate-to :notifications])}] - (when (and platform/android? - config/local-notifications?) + [tabs] + [react/view {:height 1 :background-color colors/gray-lighter}] + (cond + (= tab :status) + [my-status] + (= tab :contacts) + [contacts-list/contacts-list] + (= tab :settings) + [:<> + [quo/list-item + (cond-> {:title (or (when registrar preferred-name) + (i18n/label :t/ens-usernames)) + :subtitle (if registrar + (if preferred-name + (i18n/label :t/ens-your-your-name) + (i18n/label :t/ens-usernames-details)) + (i18n/label :t/ens-network-restriction)) + :subtitle-max-lines (if registrar + (if preferred-name 1 2) + 1) + :accessibility-label :ens-button + :container-margin-top 8 + :disabled (not registrar) + :chevron true + :icon :main-icons/username} + registrar + (assoc :on-press #(re-frame/dispatch [:navigate-to :ens-main registrar])))] + [quo/list-item + {:icon :main-icons/security + :title (i18n/label :t/privacy-and-security) + :accessibility-label :privacy-and-security-settings-button + :chevron true + :accessory (when mnemonic + [components.common/counter {:size 22} 1]) + :on-press #(re-frame/dispatch [:navigate-to :privacy-and-security])}] + (when config/quo-preview-enabled? + [quo/list-item + {:icon :main-icons/appearance + :title "Quo Preview" + :accessibility-label :appearance-settings-button + :chevron true + :on-press #(re-frame/dispatch [:navigate-to :quo-preview])}]) + [quo/list-item + {:icon :main-icons/appearance + :title (i18n/label :t/appearance) + :accessibility-label :appearance-settings-button + :chevron true + :on-press #(re-frame/dispatch [:navigate-to :appearance])}] + (if platform/ios? + [quo/list-item + {:icon :main-icons/notification + :title (i18n/label :t/notifications) + :accessibility-label :notifications-settings-button + :chevron true + :on-press #(re-frame/dispatch [:navigate-to :notifications])}] + (when (and platform/android? + config/local-notifications?) + [quo/list-item + {:icon :main-icons/notification + :title (i18n/label :t/notifications) + :accessibility-label :notifications-settings-button + :active notifications-enabled? + :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 - {:icon :main-icons/notification - :title (i18n/label :t/notifications) - :accessibility-label :notifications-settings-button - :active notifications-enabled? - :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 - {: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])}]]])) + {: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 [] (fn [] @@ -195,18 +219,26 @@ on-share #(re-frame/dispatch [:show-popover {:view :share-chat-key :address public-key - :ens-name preferred-name}])] - [react/view {:style {:flex 1}} + :ens-name preferred-name}]) + {:keys [tab]} @state] + [react/view {:flex 1} [quo/animated-header - {:right-accessories [{:icon :main-icons/share + {:right-accessories [{:accessibility-label :share-header-button + :icon :main-icons/share :on-press on-share}] :use-insets true :extended-header (profile-header/extended-header - {:on-press on-share - :title (multiaccounts/displayed-name account) - :photo (multiaccounts/displayed-photo account) - :monospace (not ens-verified) - :subtitle (if (and ens-verified public-key) - (gfy/generate-gfy public-key) - public-key)})} - [content]]]))) + {:on-press on-share + :title (multiaccounts/displayed-name account) + :photo (multiaccounts/displayed-photo account) + :monospace (not ens-verified) + :subtitle (if (and ens-verified public-key) + (gfy/generate-gfy public-key) + (utils/get-shortened-address public-key)) + :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]))}])]))) diff --git a/src/status_im/ui/screens/routing/chat_stack.cljs b/src/status_im/ui/screens/routing/chat_stack.cljs index 1245fbbd5d..973f4bce8b 100644 --- a/src/status_im/ui/screens/routing/chat_stack.cljs +++ b/src/status_im/ui/screens/routing/chat_stack.cljs @@ -2,10 +2,8 @@ (:require [status-im.ui.screens.routing.core :as navigation] [status-im.ui.screens.home.views :as home] [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.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.screens.stickers.views :as stickers])) @@ -16,14 +14,10 @@ [stack {:initial-route-name :home :header-mode :none} [{:name :home - :on-focus [::chat.models/offload-all-messages] :style {:padding-bottom tabbar.styles/tabs-diff} :component home/home} {:name :chat :component chat/chat} - {:name :profile - :insets {:top false} - :component profile.contact/profile} {:name :group-chat-profile :insets {:top false} :component profile.group-chat/group-chat-profile} diff --git a/src/status_im/ui/screens/routing/core.cljs b/src/status_im/ui/screens/routing/core.cljs index 412dd86999..8f7181ad4b 100644 --- a/src/status_im/ui/screens/routing/core.cljs +++ b/src/status_im/ui/screens/routing/core.cljs @@ -35,6 +35,12 @@ (get-active-route-name (bean inner-state)) (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 modal-presentation-ios (merge (js->clj (.-ModalPresentationIOS ^js transition-presets)) diff --git a/src/status_im/ui/screens/routing/main.cljs b/src/status_im/ui/screens/routing/main.cljs index 92c2866fa0..9c4cb3b4d9 100644 --- a/src/status_im/ui/screens/routing/main.cljs +++ b/src/status_im/ui/screens/routing/main.cljs @@ -24,7 +24,8 @@ [status-im.ui.screens.chat.image.preview.views :as image-preview] [status-im.ui.screens.profile.contact.views :as contact] [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 bottom-tabs (navigation/create-bottom-tabs)) @@ -135,7 +136,15 @@ {:name :request-transaction :transition :presentation-ios :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? [{:name :quo-preview diff --git a/src/status_im/ui/screens/routing/profile_stack.cljs b/src/status_im/ui/screens/routing/profile_stack.cljs index 5a4a38e851..41c2efe15e 100644 --- a/src/status_im/ui/screens/routing/profile_stack.cljs +++ b/src/status_im/ui/screens/routing/profile_stack.cljs @@ -2,7 +2,6 @@ (:require [status-im.ui.screens.profile.user.views :as profile.user] [status-im.ui.screens.ens.views :as ens] [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 :as edit-bootnode] @@ -65,9 +64,6 @@ :component ens/name-details} {:name :blocked-users-list :component contacts-list/blocked-users-list} - {:name :profile - :insets {:top false} - :component profile.contact/profile} {:name :bootnodes-settings :component bootnodes-settings/bootnodes-settings} {:name :installations diff --git a/src/status_im/ui/screens/wallet/account/views.cljs b/src/status_im/ui/screens/wallet/account/views.cljs index 0c1ea522cd..144718ca0d 100644 --- a/src/status_im/ui/screens/wallet/account/views.cljs +++ b/src/status_im/ui/screens/wallet/account/views.cljs @@ -15,7 +15,8 @@ [status-im.ui.screens.wallet.accounts.views :as accounts] [status-im.ui.screens.wallet.transactions.views :as history] [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])) (def state (reagent/atom {:tab :assets})) @@ -118,9 +119,9 @@ (let [{:keys [tab]} @state] [react/view {:flex 1} [react/view {:flex-direction :row :margin-bottom 8 :padding-horizontal 4} - [accounts/tab-title state :assets (i18n/label :t/wallet-assets) (= tab :assets)] - [accounts/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 :assets (i18n/label :t/wallet-assets) (= tab :assets)] + [tabs/tab-title state :nft (i18n/label :t/wallet-collectibles) (= tab :nft)] + [tabs/tab-title state :history (i18n/label :t/history) (= tab :history)]] (cond (= tab :assets) [list/flat-list {:data tokens diff --git a/src/status_im/ui/screens/wallet/accounts/views.cljs b/src/status_im/ui/screens/wallet/accounts/views.cljs index 962b7b46c3..1d0eb07651 100644 --- a/src/status_im/ui/screens/wallet/accounts/views.cljs +++ b/src/status_im/ui/screens/wallet/accounts/views.cljs @@ -58,17 +58,6 @@ [icons/icon :main-icons/add {:color colors/blue}]] [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]] (fn [{:keys [icon decimals amount color value] :as token}] [quo/list-item diff --git a/src/status_im/utils/datetime.cljs b/src/status_im/utils/datetime.cljs index c72341ba5e..e85fb057e8 100644 --- a/src/status_im/utils/datetime.cljs +++ b/src/status_im/utils/datetime.cljs @@ -16,10 +16,10 @@ (def hour (* 1000 60 60)) (def day (* hour 24)) (def week (* 7 day)) -(def units [{:name :t/datetime-second :limit 60 :in-second 1} - {:name :t/datetime-minute :limit 3600 :in-second 60} - {:name :t/datetime-hour :limit 86400 :in-second 3600} - {:name :t/datetime-day :limit nil :in-second 86400}]) +(def units [{:name :t/datetime-second-short :limit 60 :in-second 1} + {:name :t/datetime-minute-short :limit 3600 :in-second 60} + {:name :t/datetime-hour-short :limit 86400 :in-second 3600} + {:name :t/datetime-day-short :limit nil :in-second 86400}]) (def time-zone-offset (hours (- (/ (.getTimezoneOffset ^js (js/Date.)) 60)))) @@ -113,23 +113,23 @@ (defn format-time-ago [diff unit] (let [name (label-pluralize diff (:name unit))] - (label :t/datetime-ago-format {:ago (label :t/datetime-ago) - :number diff - :time-intervals name}))) + (if (= :t/datetime-second-short (:name unit)) + (label :t/now) + (label :t/datetime-ago-format-short {:ago (label :t/datetime-ago) + :number diff + :time-intervals name})))) (defn seconds-ago [time] (t/in-seconds (t/interval time (t/now)))) (defn time-ago [time] - (let [diff (seconds-ago time)] - (if (< diff 60) - (label :t/active-online) - (let [unit (first (drop-while #(and (>= diff (:limit %)) - (:limit %)) - units))] - (-> (/ diff (:in-second unit)) - Math/floor - int - (format-time-ago unit)))))) + (let [diff (seconds-ago time) + unit (first (drop-while #(and (>= diff (:limit %)) + (:limit %)) + units))] + (-> (/ diff (:in-second unit)) + Math/floor + int + (format-time-ago unit)))) (defn to-date [ms] (from-long ms)) diff --git a/src/status_im/utils/universal_links/core.cljs b/src/status_im/utils/universal_links/core.cljs index 7854b08a6e..0d556cbc84 100644 --- a/src/status_im/utils/universal_links/core.cljs +++ b/src/status_im/utils/universal_links/core.cljs @@ -72,9 +72,8 @@ public-key (navigation/navigate-to-cofx (assoc-in cofx [:db :contacts/identity] public-key) - :tabs - {:screen :chat-stack - :params {:screen :profile}}))) + :profile + {}))) (fx/defn handle-eip681 [cofx data] (fx/merge cofx diff --git a/status-go-version.json b/status-go-version.json index 326f80e563..5e667444d9 100644 --- a/status-go-version.json +++ b/status-go-version.json @@ -2,7 +2,7 @@ "_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh ' instead", "owner": "status-im", "repo": "status-go", - "version": "v0.62.13", - "commit-sha1": "7467ca7b103f685dd64d73485555f90c181a4484", - "src-sha256": "0gv9jxn5c5arnxdr33rfw2zkly9c2nyss59vbdyf444140bd6y6y" + "version": "v0.62.14", + "commit-sha1": "b3880027710ee7a28bbdeacbe099412627485d62", + "src-sha256": "0g3c1rb0hnqr6wk09n4zk9985qs9m7v44f03vfdsrbzvzx93wgkd" } diff --git a/translations/en.json b/translations/en.json index 3467155e1b..ed8a1019e3 100644 --- a/translations/en.json +++ b/translations/en.json @@ -81,6 +81,7 @@ "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", "block": "Block", + "unblock": "Unblock", "block-contact": "Block this user", "block-contact-details": "Blocking will delete this user's previous messages and stop new ones from reaching you", "blocked-users": "Blocked users", @@ -276,6 +277,7 @@ "data": "Data", "datetime-ago": "ago", "datetime-ago-format": "{{number}} {{time-intervals}} {{ago}}", + "datetime-ago-format-short": "{{number}}{{time-intervals}}", "datetime-day": { "one": "day", "other": "days" @@ -292,6 +294,22 @@ "one": "second", "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-yesterday": "yesterday", "decimals": "Decimals", @@ -1279,8 +1297,16 @@ "address-or-ens-name": "Address or ENS name", "name-optional": "Name (optional)", "mute": "Mute", + "unmute": "Unmute", "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.", + "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", - "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" }