[Feature] Added messages skeleton (#14072)

* [Feature][#14025] Added Messages Skeleton while loading messages

* [Improvements][#14025] Added animation to message skeleton

* [Improvements][#14025] Changed to Reanimated2 for message skeleton animation

* [Chores][#14025] Removed unused code

* [Improvements][#14025] Added preview screen for messages skeleton

* [Improvements][#14025] Style update for messages skeleton

* [Chore][#14025] Indentation for message skeleton

* [Improvements][#14025] On Layout calculation cleanup

* [Fix][#14025] Added Skeleton on New UI only

* [Chore] Moved Message Skeleton to new UI

* [Feature][#14025] Added Message Skeleton on message gap

* [TEMP][#14025] Added delay of preloading messages for testing

* [Lint][#14025] Lint fixes for Message Gap component

* [Chore][#14025] Reanimated namespace update

* [Chore][#14025] React native namespace update

* [Chore][#14025] Rollback preload messages
This commit is contained in:
Mohamed Javid 2022-11-16 22:13:58 +05:30 committed by GitHub
parent e44d4c83c0
commit 509ffc2a01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 116 additions and 8 deletions

View File

@ -2,8 +2,9 @@
(:require ["react-native" :as rn]
[reagent.core :as reagent]
[clojure.string :as string]
["react-native-linear-gradient" :default LinearGradient]
["react-native-reanimated" :default reanimated
:refer (useSharedValue useAnimatedStyle withTiming withDelay withSpring Easing Keyframe)]))
:refer (useSharedValue useAnimatedStyle withTiming withDelay withSpring withRepeat Easing Keyframe)]))
;; Animated Components
(def create-animated-component (comp reagent/adapt-react-class (.-createAnimatedComponent reanimated)))
@ -12,6 +13,8 @@
(def image (reagent/adapt-react-class (.-Image reanimated)))
(def touchable-opacity (create-animated-component (.-TouchableOpacity ^js rn)))
(def linear-gradient (create-animated-component LinearGradient))
;; Hooks
(def use-shared-value useSharedValue)
(def use-animated-style useAnimatedStyle)
@ -21,6 +24,7 @@
(def with-delay withDelay)
(def with-spring withSpring)
(def key-frame Keyframe)
(def with-repeat withRepeat)
;; Easings
(def bezier (.-bezier ^js Easing))
@ -68,3 +72,7 @@
(defn animate-shared-value-with-delay [anim val duration easing delay]
(set-shared-value anim (with-delay delay (with-timing val (js-obj "duration" duration
"easing" (get easings easing))))))
(defn animate-shared-value-with-repeat [anim val duration easing number-of-repetitions reverse?]
(set-shared-value anim (with-repeat (with-timing val (js-obj "duration" duration
"easing" (get easings easing))) number-of-repetitions reverse?)))

View File

@ -0,0 +1,77 @@
(ns status-im.ui.screens.chat.components.messages-skeleton
(:require [status-im.ui.components.react :as react]
[react-native.core :as rn]
[reagent.core :as reagent]
[react-native.reanimated :as reanimated]
[quo2.foundations.colors :as colors]))
(def message-skeleton-height 54)
(def avatar-skeleton-size 32)
(def message-content-width [{:author 80
:message 249}
{:author 124
:message 156}
{:author 96
:message 212}
{:author 112
:message 144}])
;; Standlone message skeleton
(defn message-skeleton []
[:f>
(fn []
(let [color (colors/theme-colors colors/neutral-5 colors/neutral-70)
loading-color (colors/theme-colors colors/neutral-10 colors/neutral-60)
content-width (rand-nth message-content-width)
author-width (content-width :author)
message-width (content-width :message)
{window-width :width} (rn/use-window-dimensions)
translate-x (reanimated/use-shared-value (- window-width))
animated-gradient-style (reanimated/apply-animations-to-style
{:transform [{:translateX translate-x}]}
{:width window-width
:height "100%"})]
(reanimated/animate-shared-value-with-repeat translate-x window-width 1000 :linear (- 1) false)
[react/masked-view
{:style {:height message-skeleton-height}
:maskElement (reagent/as-element
[rn/view {:style {:height message-skeleton-height
:flex-direction :row
:padding-vertical 11
:background-color :transparent
:padding-left 21}}
[rn/view {:style {:height avatar-skeleton-size
:width avatar-skeleton-size
:border-radius (/ avatar-skeleton-size 2)
:background-color color
:overflow :hidden}}]
[rn/view {:style {:padding-left 8
:background-color :transparent}}
[rn/view {:style {:height 8
:width author-width
:border-radius 6
:background-color color
:margin-bottom 8
:overflow :hidden}}]
[rn/view {:style {:height 16
:width message-width
:border-radius 6
:overflow :hidden
:background-color color}}]]])}
[rn/view {:style {:flex 1
:background-color color}}
[reanimated/linear-gradient {:colors [color color loading-color color color]
:start {:x 0 :y 0}
:end {:x 1 :y 0}
:style animated-gradient-style}]]]))])
(defn messages-skeleton [parent-height]
(let [number-of-skeletons (int (Math/floor (/ parent-height message-skeleton-height)))]
[rn/view {:style {:background-color (colors/theme-colors
colors/white
colors/neutral-90)
:flex 1}}
(for [n (range number-of-skeletons)]
[message-skeleton {:key n}])]))

View File

@ -4,6 +4,7 @@
[re-frame.core :as re-frame]
[status-im.i18n.i18n :as i18n]
[status-im.utils.datetime :as datetime]
[status-im.ui.screens.chat.components.messages-skeleton :as messages-skeleton]
[status-im.ui.screens.chat.styles.input.gap :as style]))
(defn on-press
@ -18,16 +19,17 @@
chat-id]
connected? [:mailserver/connected?]
use-status-nodes? [:mailserver/use-status-nodes?]
first-gap? (= gap-ids #{:first-gap})]
first-gap? (= gap-ids #{:first-gap})
window-height [:dimensions/window-height]]
(when (or (not first-gap?) public? community?)
[react/view {:style (style/gap-container)}
[react/view {:style (when-not in-progress? style/gap-container)}
[react/touchable-highlight
{:on-press (when (and (not in-progress?) use-status-nodes? connected?)
(on-press chat-id gap-ids))
:style style/touchable}
:style {:height (if in-progress? window-height 48)}}
[react/view {:style style/label-container}
(if in-progress?
[react/activity-indicator]
[messages-skeleton/messages-skeleton window-height]
[react/nested-text
{:style (style/gap-text (and connected? use-status-nodes?))}
(i18n/label (if first-gap? :t/load-more-messages :t/fetch-messages))

View File

@ -9,6 +9,7 @@
[status-im.ui.screens.chat.group :as chat.group]
[status-im.ui.screens.chat.message.datemark :as message-datemark]
[status-im.ui.screens.chat.message.gap :as gap]
[status-im.ui.screens.chat.components.messages-skeleton :as messages-skeleton]
[status-im.utils.utils :as utils]
[status-im.utils.platform :as platform]
[status-im.ui.screens.chat.state :as state]
@ -19,6 +20,11 @@
(defonce show-floating-scroll-down-button (reagent/atom false))
(defonce messages-list-ref (atom nil))
(def messages-view-height (reagent/atom 0))
(defn on-messages-view-layout [^js ev]
(reset! messages-view-height (-> ev .-nativeEvent .-layout .-height)))
(def list-key-fn #(or (:message-id %) (:value %)))
(def list-ref #(reset! messages-list-ref %))
@ -63,8 +69,7 @@
all-loaded? (<sub [:chats/all-loaded? chat-id])]
[rn/view {:style (when platform/android? {:scaleY -1})}
(if (or loading-messages? (not chat-id) (not all-loaded?))
[rn/view {:height 324 :align-items :center :justify-content :center}
[rn/activity-indicator {:animating true}]]
[messages-skeleton/messages-skeleton @messages-view-height]
[chat-intro-header-container chat no-messages?])]))
(defn list-header [{:keys [chat-id chat-type invitation-admin]}]
@ -186,6 +191,7 @@
:on-scroll on-scroll
;;TODO https://github.com/facebook/react-native/issues/30034
:inverted (when platform/ios? true)
:style (when platform/android? {:scaleY -1})})]
:style (when platform/android? {:scaleY -1})
:on-layout on-messages-view-layout})]
(when @show-floating-scroll-down-button
[floating-scroll-down-button show-input?])]))

View File

@ -31,6 +31,7 @@
[status-im.ui2.screens.quo2-preview.messages.gap :as messages-gap]
[status-im.ui2.screens.quo2-preview.messages.system-message :as system-message]
[status-im.ui2.screens.quo2-preview.notifications.activity-logs :as activity-logs]
[status-im.ui2.screens.quo2-preview.posts-and-attachments.messages-skeleton :as messages-skeleton]
[status-im.ui2.screens.quo2-preview.reactions.react :as react]
[status-im.ui2.screens.quo2-preview.selectors.disclaimer :as disclaimer]
[status-im.ui2.screens.quo2-preview.selectors.selectors :as selectors]
@ -144,6 +145,9 @@
:notifications [{:name :activity-logs
:insets {:top false}
:component activity-logs/preview-activity-logs}]
:posts-and-attachments [{:name :messages-skeleton
:insets {:top false}
:component messages-skeleton/preview-messages-skeleton}]
:reactions [{:name :react
:insets {:top false}
:component react/preview-react}]

View File

@ -0,0 +1,11 @@
(ns status-im.ui2.screens.quo2-preview.posts-and-attachments.messages-skeleton
(:require [quo.react-native :as rn]
[quo2.foundations.colors :as colors]
[status-im.ui.screens.chat.components.messages-skeleton :as messages-skeleton]))
(defn preview-messages-skeleton []
[rn/view {:background-color (colors/theme-colors
colors/white
colors/neutral-90)
:flex 1}
[messages-skeleton/messages-skeleton]])