diff --git a/src/quo2/components/loaders/skeleton/view.cljs b/src/quo2/components/loaders/skeleton/view.cljs deleted file mode 100644 index 01bfaa86d3..0000000000 --- a/src/quo2/components/loaders/skeleton/view.cljs +++ /dev/null @@ -1,46 +0,0 @@ -(ns quo2.components.loaders.skeleton.view - (:require [quo2.theme :as theme] - [react-native.core :as rn] - [quo2.foundations.colors :as colors] - [quo2.components.loaders.skeleton.style :as style] - [quo2.components.loaders.skeleton.constants :as constants])) - -(defn- skeleton-item - [index content color] - [rn/view {:style (style/container content)} - [rn/view {:style (style/avatar color)}] - [rn/view {:style style/content-container} - [rn/view - {:style (style/content-view - {:type (if (= content :list-items) :message :author) - :index index - :content content - :color color})}] - [rn/view - {:style (style/content-view - {:type (if (= content :list-items) :author :message) - :index index - :content content - :color color})}] - (when (= content :notifications) - [rn/view - {:style (style/content-view {:type :message2 - :index index - :content content - :color color})}])]]) - -(defn- internal-view - [{:keys [content theme blur? parent-height]}] - (let [skeleton-height (get-in constants/layout-dimensions [content :height]) - number-of-skeletons (int (Math/ceil (/ parent-height skeleton-height))) - color (cond - blur? colors/white-opa-5 - (= theme :dark) colors/neutral-90 - :else colors/neutral-5)] - [rn/view {:style {:padding 8}} - (doall - (for [index (range number-of-skeletons)] - ^{:key index} - [skeleton-item (mod index 4) content color]))])) - -(def view (theme/with-theme internal-view)) diff --git a/src/quo2/components/loaders/skeleton_list/component_spec.cljs b/src/quo2/components/loaders/skeleton_list/component_spec.cljs new file mode 100644 index 0000000000..7d3aac4fc8 --- /dev/null +++ b/src/quo2/components/loaders/skeleton_list/component_spec.cljs @@ -0,0 +1,26 @@ +(ns quo2.components.loaders.skeleton-list.component-spec + (:require [quo2.components.loaders.skeleton-list.view :as skeleton-list] + [quo2.foundations.colors :as colors] + [test-helpers.component :as h])) + +(defn test-skeleton + [content animated?] + (let [rendered (h/render [skeleton-list/view + {:index 0 + :content content + :color colors/neutral-10 + :parent-height 600 + :animated? animated?}]) + accessibility-text :skeleton-list] + (h/is-truthy (h/get-by-label-text rendered accessibility-text)))) + +(h/describe "Skeleton tests" + (doseq [content [:messages :notifications :list-items] + animated? [true false]] + (let [content-str (name content)] + (h/test (str "Skeleton :" + content-str + " is " + (if animated? "animated" "static") + " based on animated? " animated?) + (test-skeleton content animated?))))) diff --git a/src/quo2/components/loaders/skeleton/constants.cljs b/src/quo2/components/loaders/skeleton_list/constants.cljs similarity index 98% rename from src/quo2/components/loaders/skeleton/constants.cljs rename to src/quo2/components/loaders/skeleton_list/constants.cljs index 0fb3133017..80fce618fe 100644 --- a/src/quo2/components/loaders/skeleton/constants.cljs +++ b/src/quo2/components/loaders/skeleton_list/constants.cljs @@ -1,4 +1,4 @@ -(ns quo2.components.loaders.skeleton.constants) +(ns quo2.components.loaders.skeleton-list.constants) (def ^:const layout-dimensions {:messages {:height 56 diff --git a/src/quo2/components/loaders/skeleton/style.cljs b/src/quo2/components/loaders/skeleton_list/style.cljs similarity index 85% rename from src/quo2/components/loaders/skeleton/style.cljs rename to src/quo2/components/loaders/skeleton_list/style.cljs index b0a17b3064..40da6c13ac 100644 --- a/src/quo2/components/loaders/skeleton/style.cljs +++ b/src/quo2/components/loaders/skeleton_list/style.cljs @@ -1,5 +1,5 @@ -(ns quo2.components.loaders.skeleton.style - (:require [quo2.components.loaders.skeleton.constants :as constants])) +(ns quo2.components.loaders.skeleton-list.style + (:require [quo2.components.loaders.skeleton-list.constants :as constants])) (defn container [content] diff --git a/src/quo2/components/loaders/skeleton_list/view.cljs b/src/quo2/components/loaders/skeleton_list/view.cljs new file mode 100644 index 0000000000..e64f3c77cf --- /dev/null +++ b/src/quo2/components/loaders/skeleton_list/view.cljs @@ -0,0 +1,99 @@ +(ns quo2.components.loaders.skeleton-list.view + (:require [quo2.theme :as theme] + [react-native.core :as rn] + [quo2.foundations.colors :as colors] + [react-native.masked-view :as masked-view] + [react-native.reanimated :as reanimated] + [quo2.components.loaders.skeleton-list.style :as style] + [reagent.core :as reagent] + [quo2.components.loaders.skeleton-list.constants :as constants])) + +(defn static-skeleton-view + [{:keys [index content color]}] + [rn/view + {:style (style/container content)} + [rn/view {:style (style/avatar color)}] + [rn/view {:style style/content-container} + [rn/view + {:style (style/content-view + {:type (if (= content :list-items) :message :author) + :index index + :content content + :color color})}] + [rn/view + {:style (style/content-view + {:type (if (= content :list-items) :author :message) + :index index + :content content + :color color})}] + (when (= content :notifications) + [rn/view + {:style (style/content-view {:type :message2 + :index index + :content content + :color color})}])]]) + +(defn- f-animated-skeleton-view + [{:keys [style color skeleton-height animated? translate-x window-width] :as data}] + (let [loading-color (colors/theme-colors colors/neutral-10 colors/neutral-60)] + + (rn/use-effect + (fn [] + (when-not animated? + (reanimated/cancel-animation translate-x)) + (reanimated/animate-shared-value-with-repeat translate-x window-width 1000 :linear -1 false) + #(when-not animated? + (reanimated/cancel-animation translate-x))) + [animated?]) + + + [masked-view/masked-view + {:style {:height skeleton-height} + :mask-element (reagent/as-element [static-skeleton-view data])} + [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 style}]]])) + +(defn- animated-skeleton-view + [props] + [:f> f-animated-skeleton-view props]) + +(defn- f-internal-view + [{:keys [content theme blur? parent-height animated?] :as props}] + (let [{window-width :width} (rn/get-window) + 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%"}) + skeleton-height (get-in constants/layout-dimensions [content :height]) + number-of-skeletons (int (Math/ceil (/ parent-height skeleton-height))) + color (cond + (and blur? (= theme :dark)) colors/white-opa-5 + (= theme :dark) colors/neutral-90 + :else colors/neutral-5) + component (if animated? animated-skeleton-view static-skeleton-view)] + [rn/view + {:style {:padding 8} + :accessibility-label :skeleton-list} + (for [parent-index (range number-of-skeletons)] + ^{:key parent-index} + [component + (merge props + {:index (mod parent-index 4) + :parent-index parent-index + :color color + :translate-x translate-x + :skeleton-height skeleton-height + :style animated-gradient-style})])])) + +(defn- internal-view + [props] + [:f> f-internal-view props]) + +(def view (theme/with-theme internal-view)) diff --git a/src/quo2/core.cljs b/src/quo2/core.cljs index 207edb821e..5a9cf70b9e 100644 --- a/src/quo2/core.cljs +++ b/src/quo2/core.cljs @@ -68,7 +68,7 @@ quo2.components.list-items.token-value.view quo2.components.list-items.user-list quo2.components.loaders.skeleton - quo2.components.loaders.skeleton.view + quo2.components.loaders.skeleton-list.view quo2.components.markdown.list.view quo2.components.markdown.text quo2.components.messages.author.view @@ -247,7 +247,7 @@ ;;;; Loaders (def skeleton quo2.components.loaders.skeleton/skeleton) -(def static-skeleton quo2.components.loaders.skeleton.view/view) +(def skeleton-list quo2.components.loaders.skeleton-list.view/view) ;;;; Navigation (def floating-shell-button quo2.components.navigation.floating-shell-button.view/view) diff --git a/src/quo2/core_spec.cljs b/src/quo2/core_spec.cljs index 18dc885f66..bab60f49d9 100644 --- a/src/quo2/core_spec.cljs +++ b/src/quo2/core_spec.cljs @@ -38,6 +38,7 @@ [quo2.components.list-items.community.component-spec] [quo2.components.list-items.dapp.component-spec] [quo2.components.list-items.token-value.component-spec] + [quo2.components.loaders.skeleton-list.component-spec] [quo2.components.markdown.text-component-spec] [quo2.components.markdown.list.component-spec] [quo2.components.notifications.notification.component-spec] diff --git a/src/status_im2/contexts/chat/messages/list/view.cljs b/src/status_im2/contexts/chat/messages/list/view.cljs index eec18a3f21..2649ea9210 100644 --- a/src/status_im2/contexts/chat/messages/list/view.cljs +++ b/src/status_im2/contexts/chat/messages/list/view.cljs @@ -355,7 +355,7 @@ (if chat-screen-loaded? [:f> f-messages-list-content props] [rn/view {:style {:flex 1}} - [quo/static-skeleton + [quo/skeleton-list {:content :messages :parent-height content-height}]]))) diff --git a/src/status_im2/contexts/quo_preview/loaders/skeleton.cljs b/src/status_im2/contexts/quo_preview/loaders/skeleton.cljs deleted file mode 100644 index 59e82d8d09..0000000000 --- a/src/status_im2/contexts/quo_preview/loaders/skeleton.cljs +++ /dev/null @@ -1,43 +0,0 @@ -(ns status-im2.contexts.quo-preview.loaders.skeleton - (:require [quo2.core :as quo] - [quo2.foundations.colors :as colors] - [react-native.core :as rn] - [reagent.core :as reagent] - [status-im2.contexts.quo-preview.preview :as preview])) - -(def descriptor - [{:label "Content:" - :key :content - :type :select - :options [{:key :list-items - :value "List items"} - {:key :notifications - :value "Notifications"} - {:key :messages - :value "Messages"}]} - {:label "Blur?" - :key :blur? - :type :boolean}]) - -(defn cool-preview - [] - (let [state (reagent/atom {:content :messages - :blur? false - :parent-height 600})] - (fn [] - [rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!} - [rn/view {:padding-bottom 150} - [preview/customizer state descriptor] - [rn/view - [quo/static-skeleton @state]]]]))) - -(defn preview-skeleton - [] - [rn/view - {:background-color (colors/theme-colors colors/white colors/neutral-95) - :flex 1} - [rn/flat-list - {:flex 1 - :keyboard-should-persist-taps :always - :header [cool-preview] - :key-fn str}]]) diff --git a/src/status_im2/contexts/quo_preview/loaders/skeleton_list.cljs b/src/status_im2/contexts/quo_preview/loaders/skeleton_list.cljs new file mode 100644 index 0000000000..f10d751499 --- /dev/null +++ b/src/status_im2/contexts/quo_preview/loaders/skeleton_list.cljs @@ -0,0 +1,23 @@ +(ns status-im2.contexts.quo-preview.loaders.skeleton-list + (:require [quo2.core :as quo] + [reagent.core :as reagent] + [status-im2.contexts.quo-preview.preview :as preview])) + +(def descriptor + [{:key :content + :type :select + :options [{:key :list-items} + {:key :notifications} + {:key :messages}]} + {:key :blur? :type :boolean} + {:key :animated? :type :boolean}]) + +(defn view + [] + (let [state (reagent/atom {:content :messages + :blur? false + :animated? true + :parent-height 600})] + (fn [] + [preview/preview-container {:state state :descriptor descriptor} + [quo/skeleton-list @state]]))) diff --git a/src/status_im2/contexts/quo_preview/main.cljs b/src/status_im2/contexts/quo_preview/main.cljs index 711bba57ab..91b6f3679e 100644 --- a/src/status_im2/contexts/quo_preview/main.cljs +++ b/src/status_im2/contexts/quo_preview/main.cljs @@ -66,7 +66,6 @@ [status-im2.contexts.quo-preview.list-items.preview-lists :as preview-lists] [status-im2.contexts.quo-preview.list-items.user-list :as user-list] [status-im2.contexts.quo-preview.list-items.community-list :as community-list] - [status-im2.contexts.quo-preview.list-items.token-value :as token-value] [status-im2.contexts.quo-preview.markdown.text :as text] [status-im2.contexts.quo-preview.markdown.list :as markdown-list] [status-im2.contexts.quo-preview.messages.author :as messages-author] @@ -111,7 +110,7 @@ [status-im2.contexts.quo-preview.tags.token-tag :as token-tag] [status-im2.contexts.quo-preview.title.title :as title] [status-im2.contexts.quo-preview.keycard.keycard :as keycard] - [status-im2.contexts.quo-preview.loaders.skeleton :as skeleton] + [status-im2.contexts.quo-preview.loaders.skeleton-list :as skeleton-list] [status-im2.contexts.quo-preview.community.channel-actions :as channel-actions] [status-im2.contexts.quo-preview.gradient.gradient-cover :as gradient-cover] [status-im2.contexts.quo-preview.wallet.account-card :as account-card] @@ -256,11 +255,11 @@ {:name :preview-lists :component preview-lists/view} {:name :user-list - :component user-list/preview-user-list} - {:name :token-value - :component token-value/preview}] - :loaders [{:name :skeleton - :component skeleton/preview-skeleton}] + :options {:topBar {:visible true}} + :component user-list/preview-user-list}] + :loaders [{:name :skeleton-list + :options {:topBar {:visible true}} + :component skeleton-list/view}] :markdown [{:name :texts :component text/preview-text} {:name :markdown-list