diff --git a/src/status_im/ui/components/list/views.cljs b/src/status_im/ui/components/list/views.cljs index a5c825d394..c232cc3464 100644 --- a/src/status_im/ui/components/list/views.cljs +++ b/src/status_im/ui/components/list/views.cljs @@ -82,10 +82,9 @@ [react/view {:style (merge style styles/item-checkbox)} [radio/radio (:checked? props)]])]) -;;TODO DEPRECATED, use status-im.ui.components.list-item.views (defn- wrap-render-fn [f] (fn [^js data] - (reagent/as-element (f (.-item data) (.-index data) (.-separators data))))) + (reagent/as-element [f (.-item data) (.-index data) (.-separators data)]))) (defn- wrap-key-fn [f] (fn [data index] @@ -135,8 +134,8 @@ (defn- wrap-render-section-header-fn [f] (fn [^js data] (let [^js section (.-section data)] - (reagent/as-element (f {:title (.-title section) - :data (.-data section)}))))) + (reagent/as-element [f {:title (.-title section) + :data (.-data section)}])))) (defn- default-render-section-header [{:keys [title data]}] (when (seq data) @@ -150,7 +149,7 @@ (assoc (dissoc props :render-fn) :renderItem (wrap-render-fn f)) props) :data to-array)) -;;TODO DEPRECATED, use status-im.ui.components.list-item.views + (defn section-list "A wrapper for SectionList. To render something on empty sections, use renderSectionFooter and conditionaly diff --git a/src/status_im/ui/components/react.cljs b/src/status_im/ui/components/react.cljs index 58ce370ab1..5ddd584f30 100644 --- a/src/status_im/ui/components/react.cljs +++ b/src/status_im/ui/components/react.cljs @@ -5,6 +5,7 @@ [status-im.ui.components.typography :as typography] [status-im.utils.platform :as platform] [status-im.utils.utils :as utils] + ["react" :as reactjs] ["react-native" :as react-native :refer (Keyboard)] ["react-native-image-crop-picker" :default image-picker] ["react-native-safe-area-context" :as safe-area-context @@ -29,7 +30,8 @@ (def text-class (reagent/adapt-react-class (.-Text react-native))) (def text-input-class (reagent/adapt-react-class (.-TextInput react-native))) -(def image-class (reagent/adapt-react-class (.-Image react-native))) + +(def image-class (reagent/adapt-react-class (reactjs/memo (.-Image react-native)))) (defn image-get-size [uri callback] (.getSize (.-Image react-native) uri callback)) (defn resolve-asset-source [uri] (js->clj (.resolveAssetSource (.-Image react-native) uri) :keywordize-keys true)) diff --git a/src/status_im/ui/components/tabbar/core.cljs b/src/status_im/ui/components/tabbar/core.cljs index b4e8bd8915..879215a6a2 100644 --- a/src/status_im/ui/components/tabbar/core.cljs +++ b/src/status_im/ui/components/tabbar/core.cljs @@ -36,15 +36,15 @@ :content {:title (i18n/label :t/wallet) :icon :main-icons/wallet} :accessibility-label :wallet-tab-button} + {:nav-stack :status-stack + :content {:title (i18n/label :t/status) + :icon :main-icons/status} + :accessibility-label :status-tab-button} {:nav-stack :profile-stack :content {:title (i18n/label :t/profile) :icon :main-icons/user-profile} :count-subscription :get-profile-unread-messages-number - :accessibility-label :profile-tab-button} - {:nav-stack :status-stack - :content {:title (i18n/label :t/status) - :icon :main-icons/status} - :accessibility-label :status-tab-button}] + :accessibility-label :profile-tab-button}] (remove nil?) (map-indexed vector))) diff --git a/src/status_im/ui/screens/chat/message/gap.cljs b/src/status_im/ui/screens/chat/message/gap.cljs index 3cea2a7b44..5c1b44a078 100644 --- a/src/status_im/ui/screens/chat/message/gap.cljs +++ b/src/status_im/ui/screens/chat/message/gap.cljs @@ -19,7 +19,7 @@ (re-frame/dispatch [:chat.ui/fill-gaps ids])))) (views/defview gap - [{:keys [gaps first-gap?]} idx list-ref] + [{:keys [gaps first-gap?]} idx list-ref timeline] (views/letsubs [range [:chats/range] {:keys [might-have-join-time-messages?]} [:chats/current-raw-chat] in-progress? [:chats/fetching-gap-in-progress? @@ -40,8 +40,8 @@ [react/nested-text {:style (style/gap-text connected?)} (i18n/label (if first-gap? - :t/load-more-messages - :t/fetch-messages)) + (if timeline :t/load-more-timeline :t/load-more-messages) + (if timeline :t/fetch-timeline :t/fetch-messages))) (when first-gap? [{:style style/date} (let [date (datetime/timestamp->long-date diff --git a/src/status_im/ui/screens/chat/message/link_preview.cljs b/src/status_im/ui/screens/chat/message/link_preview.cljs index dfacd13cef..ec1f30f79f 100644 --- a/src/status_im/ui/screens/chat/message/link_preview.cljs +++ b/src/status_im/ui/screens/chat/message/link_preview.cljs @@ -57,7 +57,7 @@ :type :secondary} (i18n/label :t/dont-ask)]]) -(defview link-preview-loader [link outgoing] +(defview link-preview-loader [link outgoing timeline] (letsubs [cache [:link-preview/cache]] (let [{:keys [site title thumbnailUrl error] :as preview-data} (get cache link)] (if (not preview-data) @@ -71,7 +71,7 @@ (re-frame/dispatch [:browser.ui/message-link-pressed link]))} - [react/view (styles/link-preview-wrapper outgoing) + [react/view (styles/link-preview-wrapper outgoing timeline) [react/image {:source {:uri thumbnailUrl} :style (styles/link-preview-image outgoing) :accessibility-label :member-photo}] @@ -83,7 +83,7 @@ :style styles/link-preview-site} site]]]))))) -(defview link-preview-wrapper [links outgoing] +(defview link-preview-wrapper [links outgoing timeline] (letsubs [ask-user? [:link-preview/link-preview-request-enabled] whitelist [:link-preview/whitelist] @@ -93,6 +93,6 @@ {:keys [link whitelisted enabled]} link-info] (when (and link whitelisted) (if enabled - [link-preview-loader link outgoing] + [link-preview-loader link outgoing timeline] (when ask-user? [link-preview-enable-request]))))))) \ No newline at end of file diff --git a/src/status_im/ui/screens/chat/message/message.cljs b/src/status_im/ui/screens/chat/message/message.cljs index 9c4793d3c2..65c71d2b5b 100644 --- a/src/status_im/ui/screens/chat/message/message.cljs +++ b/src/status_im/ui/screens/chat/message/message.cljs @@ -234,24 +234,31 @@ ;;MESSAGE CONTENT [react/view content] - [link-preview/link-preview-wrapper (:links (:content message)) outgoing]]] + [link-preview/link-preview-wrapper (:links (:content message)) outgoing false]]] ; delivery status [react/view (style/delivery-status outgoing) [message-delivery-status message]]]) +(def image-max-width 260) +(def image-max-height 192) + +(defn image-set-size [dimensions] + (fn [width height] + (when (< width height) + ;; if width less than the height we reduce width proportionally to height + (let [k (/ height image-max-height)] + (when (not= (/ width k) (first @dimensions)) + (reset! dimensions [(/ width k) image-max-height])))))) + (defn message-content-image [{:keys [content outgoing] :as message} {:keys [on-long-press]}] - (let [dimensions (reagent/atom [260 260]) - visible (reagent/atom false) - uri (:image content)] - (react/image-get-size - uri - (fn [width height] - (reset! dimensions [width height]))) + (let [dimensions (reagent/atom [image-max-width image-max-height]) + visible (reagent/atom false) + uri (:image content)] + (react/image-get-size uri (image-set-size dimensions)) (fn [] - (let [k (/ (max (first @dimensions) (second @dimensions)) 260) - style-opts {:outgoing outgoing - :width (/ (first @dimensions) k) - :height (/ (second @dimensions) k)}] + (let [style-opts {:outgoing outgoing + :width (first @dimensions) + :height (second @dimensions)}] [:<> [preview/preview-image {:message message :visible @visible @@ -261,13 +268,12 @@ (reset! visible true) (react/dismiss-keyboard!)) :on-long-press on-long-press} - [react/view {:style (style/image-message style-opts) + [react/view {:style (style/image-message style-opts) :accessibility-label :message-image} - [react/image {:style {:width (/ (first @dimensions) k) - :height (/ (second @dimensions) k)} - :resize-mode :contain - :source {:uri uri}}] - [react/view {:style (style/image-message-border style-opts)}]]]])))) + [react/image {:style (dissoc style-opts :outgoing) + :resize-mode :cover + :source {:uri uri}} + [react/view {:style (style/image-message-border style-opts)}]]]]])))) (defmulti ->message :content-type) diff --git a/src/status_im/ui/screens/chat/message/reactions_row.cljs b/src/status_im/ui/screens/chat/message/reactions_row.cljs index 27f9297320..10fda68b95 100644 --- a/src/status_im/ui/screens/chat/message/reactions_row.cljs +++ b/src/status_im/ui/screens/chat/message/reactions_row.cljs @@ -4,8 +4,8 @@ [quo.react-native :as rn] [quo.core :as quo])) -(defn reaction [{:keys [outgoing]} {:keys [own emoji-id quantity]}] - [rn/view {:style (styles/reaction-style {:outgoing outgoing +(defn reaction [{:keys [outgoing]} {:keys [own emoji-id quantity]} timeline] + [rn/view {:style (styles/reaction-style {:outgoing (and outgoing (not timeline)) :own own})} [rn/image {:source (get constants/reactions emoji-id) :style {:width 16 @@ -20,4 +20,4 @@ [rn/view {:style (styles/reactions-row message timeline)} (for [emoji-reaction reactions] ^{:key (str emoji-reaction)} - [reaction message emoji-reaction])])) + [reaction message emoji-reaction timeline])])) diff --git a/src/status_im/ui/screens/chat/message/styles.cljs b/src/status_im/ui/screens/chat/message/styles.cljs index 48d7f70034..5f5651b193 100644 --- a/src/status_im/ui/screens/chat/message/styles.cljs +++ b/src/status_im/ui/screens/chat/message/styles.cljs @@ -73,7 +73,7 @@ {:justify-content :flex-end} {:justify-content :flex-start}) (if (or display-photo? timeline) - {:padding-left (+ 16 photos/default-size)} + {:padding-left (+ 16 photos/default-size (when timeline 8))} {:padding-left 8}))) (defn reaction-button [active] @@ -102,12 +102,12 @@ :height 94 :align-self :center}) -(defn link-preview-wrapper [outgoing] +(defn link-preview-wrapper [outgoing timeline] {:overflow :hidden :border-top-left-radius 16 :border-top-right-radius 16 - :border-bottom-left-radius (if outgoing 16 4) - :border-bottom-right-radius (if outgoing 4 16) + :border-bottom-left-radius (if timeline 16 (if outgoing 16 4)) + :border-bottom-right-radius (if timeline 16 (if outgoing 4 16)) :border-width 1 :border-color components.colors/gray-lighter :margin-vertical 4 diff --git a/src/status_im/ui/screens/chat/styles/message/message.cljs b/src/status_im/ui/screens/chat/styles/message/message.cljs index 74249f1c31..148cccff2c 100644 --- a/src/status_im/ui/screens/chat/styles/message/message.cljs +++ b/src/status_im/ui/screens/chat/styles/message/message.cljs @@ -299,7 +299,7 @@ (defn image-message [{:keys [outgoing width height]}] - {:overflow "hidden" + {:overflow :hidden :border-top-left-radius 16 :border-top-right-radius 16 :border-bottom-left-radius (if outgoing 16 4) @@ -309,9 +309,9 @@ (defn image-message-border [opts] (merge (image-message opts) - {:position :absolute + {:border-width 1 :top 0 :left 0 - :background-color "transparent" - :border-width 1 - :border-color colors/black-transparent})) + :position :absolute + :background-color :transparent + :border-color colors/black-transparent})) \ No newline at end of file diff --git a/src/status_im/ui/screens/chat/views.cljs b/src/status_im/ui/screens/chat/views.cljs index 1e42a48ae7..df183e2cac 100644 --- a/src/status_im/ui/screens/chat/views.cljs +++ b/src/status_im/ui/screens/chat/views.cljs @@ -178,7 +178,7 @@ (if (= type :datemark) [message-datemark/chat-datemark (:value message)] (if (= type :gap) - [gap/gap message idx messages-list-ref] + [gap/gap message idx messages-list-ref false] ; message content [message/chat-message (assoc message diff --git a/src/status_im/ui/screens/routing/main.cljs b/src/status_im/ui/screens/routing/main.cljs index a6fc721d22..004f6fd4c2 100644 --- a/src/status_im/ui/screens/routing/main.cljs +++ b/src/status_im/ui/screens/routing/main.cljs @@ -46,12 +46,12 @@ {:name :wallet-stack :insets {:top false} :component wallet-stack/wallet-stack} - {:name :profile-stack - :insets {:top false} - :component profile-stack/profile-stack} {:name :status-stack :insets {:top false} - :component status-stack/status-stack}]]) + :component status-stack/status-stack} + {:name :profile-stack + :insets {:top false} + :component profile-stack/profile-stack}]]) (views/defview get-main-component [_] (views/letsubs [logged-in? [:multiaccount/logged-in?]] diff --git a/src/status_im/ui/screens/status/views.cljs b/src/status_im/ui/screens/status/views.cljs index d20367b2c5..1e1879cee4 100644 --- a/src/status_im/ui/screens/status/views.cljs +++ b/src/status_im/ui/screens/status/views.cljs @@ -25,32 +25,50 @@ [status-im.chat.models :as chat])) (defonce messages-list-ref (atom nil)) -(def image-max-dimension 260) +(def image-max-dimension 192) +(def image-sizes (atom {})) + +(defn image-set-size [dimensions uri] + (fn [width height] + (swap! image-sizes assoc uri {:initialized? true}) + (when (< width height) + ;; if width less than the height we reduce width proportionally to height + (let [k (/ height image-max-dimension)] + (when (not= (/ width k) (first @dimensions)) + (swap! image-sizes assoc uri {:width (/ width k)}) + (reset! dimensions [(/ width k) image-max-dimension])))))) (defn message-content-image [uri _] - (let [dimensions (reagent/atom [image-max-dimension image-max-dimension])] - (react/image-get-size - uri - (fn [width height] - (let [k (/ (max width height) image-max-dimension)] - (reset! dimensions [(/ width k) (/ height k)])))) + (let [stored-image (get @image-sizes uri) + dimensions (reagent/atom [nil image-max-dimension])] + (if stored-image + (reset! dimensions [(:width stored-image) image-max-dimension]) + (js/setTimeout #(react/image-get-size uri (image-set-size dimensions uri)) 20)) (fn [uri show-close?] - [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} - :accessibility-label :message-image} - [react/image {:style {:width (first @dimensions) :height (last @dimensions)} - :resize-mode :contain - :source {:uri uri}}]] + [react/view {:style {:width (first @dimensions) + :height image-max-dimension + :overflow :hidden + :border-radius 16 + :margin-top 8} + :accessibility-label :message-image} + [react/image {:style {:width (first @dimensions) + :height image-max-dimension} + :cache :force-cache + :resize-mode :cover + :source {:uri uri}}] + [react/view {:border-width 1 + :top 0 + :left 0 + :width (first @dimensions) + :height image-max-dimension + :border-radius 16 + :position :absolute + :background-color :transparent + :border-color colors/black-transparent}] (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}} + :style {:right 4 :top 12 :position :absolute}} [react/view {:width 24 :height 24 :background-color colors/black-persist @@ -82,12 +100,12 @@ :on-long-press #(on-long-press-fn on-long-press content true)} [message-content-image (:image content) false]]]))) -(defn message-item [timeline? account] +(defn message-item [account] (fn [{:keys [content-type content from timestamp identicon outgoing] :as message} {:keys [modal on-long-press close-modal]}] [react/view (merge {:padding-vertical 8 :flex-direction :row - :background-color (if (and timeline? outgoing) colors/blue-light colors/white) + :background-color (when modal colors/white) :padding-horizontal 16} (when modal {:border-radius 16})) @@ -115,7 +133,7 @@ [react/touchable-highlight (when-not modal {:on-long-press #(on-long-press-fn on-long-press content false)}) [message/render-parsed-text (assoc message :outgoing false) (:parsed-text content)]]) - [link-preview/link-preview-wrapper (:links content) outgoing]]]])) + [link-preview/link-preview-wrapper (:links content) outgoing true]]]])) (defn render-message [timeline? account] (fn [{:keys [type] :as message} idx] @@ -125,7 +143,7 @@ (if (= type :gap) (if timeline? nil - [gap/gap message idx messages-list-ref]) + [gap/gap message idx messages-list-ref true]) ; message content (let [chat-id (chat/profile-chat-topic (:from message))] [react/view (merge {:accessibility-label :chat-item} @@ -151,7 +169,7 @@ :chat-id chat-id :emoji-id emoji-id :emoji-reaction-id emoji-reaction-id}])) - :render (message-item timeline? account)}]]))))])) + :render (message-item account)}]]))))])) (def state (reagent/atom {:tab :timeline})) diff --git a/translations/en.json b/translations/en.json index 22a2bd1aa2..50b305aa66 100644 --- a/translations/en.json +++ b/translations/en.json @@ -469,6 +469,7 @@ "failed": "Failed", "faq": "Frequently asked questions", "fetch-messages": "↓ Fetch messages", + "fetch-timeline": "↓ Fetch", "find": "Find", "finish": "Finish", "finishing-card-setup": "Finishing card setup", @@ -677,6 +678,7 @@ "linked-on": "Linked on {{date}}", "load-messages-before": "before {{date}}", "load-more-messages": "↓ Fetch more messages", + "load-more-timeline": "↓ Fetch more", "loading": "Loading...", "log-level": "Log level", "log-level-settings": "Log level settings",