Implement new URL Preview component (#15607)
Fix https://github.com/status-im/status-mobile/issues/15592 Notes: - The red border around the icon has been reported in issue https://github.com/status-im/status-mobile/issues/15606 - The loading state doesn't have a spinning icon on purpose. This will be done separately.
This commit is contained in:
parent
ccb20d7994
commit
bfc7a2d88b
|
@ -0,0 +1,29 @@
|
|||
(ns quo2.components.links.url-preview.component-spec
|
||||
(:require
|
||||
[quo2.components.links.url-preview.view :as view]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Links - URL Preview"
|
||||
(h/test "default render"
|
||||
(h/render [view/view])
|
||||
(h/is-truthy (h/query-by-label-text :title))
|
||||
(h/is-truthy (h/query-by-label-text :logo))
|
||||
(h/is-truthy (h/query-by-label-text :button-clear-preview))
|
||||
(h/is-null (h/query-by-label-text :url-preview-loading)))
|
||||
|
||||
(h/test "on-clear event"
|
||||
(let [on-clear (h/mock-fn)]
|
||||
(h/render [view/view {:on-clear on-clear}])
|
||||
(h/fire-event :press (h/get-by-label-text :button-clear-preview))
|
||||
(h/was-called on-clear)))
|
||||
|
||||
(h/describe "loading state"
|
||||
(h/test "shows a loading container"
|
||||
(h/render [view/view {:loading? true :loading-message "Hello"}])
|
||||
(h/is-null (h/query-by-label-text :title))
|
||||
(h/is-truthy (h/query-by-label-text :url-preview-loading)))
|
||||
|
||||
(h/test "renders if `loading-message` is not passed"
|
||||
(h/render [view/view {:loading? true}])
|
||||
(h/is-null (h/query-by-label-text :title))
|
||||
(h/is-truthy (h/query-by-label-text :url-preview-loading)))))
|
|
@ -0,0 +1,58 @@
|
|||
(ns quo2.components.links.url-preview.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def horizontal-padding 12)
|
||||
|
||||
(defn container
|
||||
[]
|
||||
{:height 56
|
||||
:background-color (colors/theme-colors colors/neutral-5 colors/neutral-90)
|
||||
:padding-vertical 10
|
||||
:padding-horizontal horizontal-padding
|
||||
:border-radius 12
|
||||
:align-self :stretch
|
||||
:flex-direction :row})
|
||||
|
||||
(defn loading-container
|
||||
[]
|
||||
{:height 56
|
||||
:border-width 1
|
||||
:border-radius 12
|
||||
:border-style :dashed
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:align-self :stretch
|
||||
:padding horizontal-padding
|
||||
:border-color (colors/theme-colors colors/neutral-30 colors/neutral-80)})
|
||||
|
||||
(defn loading-message
|
||||
[]
|
||||
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40)})
|
||||
|
||||
(def logo
|
||||
{:width 16
|
||||
:height 16
|
||||
:top 1
|
||||
:border-radius 8})
|
||||
|
||||
(def content-container
|
||||
{:margin-left 6
|
||||
:flex 1})
|
||||
|
||||
(defn title
|
||||
[]
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white)})
|
||||
|
||||
(defn body
|
||||
[]
|
||||
{:text-transform :lowercase
|
||||
:color (colors/theme-colors colors/neutral-50 colors/neutral-40)})
|
||||
|
||||
(def clear-button
|
||||
{:border-color colors/danger-50
|
||||
:border-width 1})
|
||||
|
||||
(def clear-button-container
|
||||
{:width 20
|
||||
:height 20
|
||||
:margin-left 6})
|
|
@ -0,0 +1,63 @@
|
|||
(ns quo2.components.links.url-preview.view
|
||||
(:require
|
||||
[quo2.components.icon :as icon]
|
||||
[quo2.components.links.url-preview.style :as style]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- logo-component
|
||||
[{:keys [logo]}]
|
||||
[rn/image
|
||||
{:accessibility-label :logo
|
||||
:source logo
|
||||
:style style/logo}])
|
||||
|
||||
(defn- content
|
||||
[{:keys [title body]}]
|
||||
[rn/view {:style style/content-container}
|
||||
[text/text
|
||||
{:accessibility-label :title
|
||||
:size :paragraph-2
|
||||
:weight :semi-bold
|
||||
:number-of-lines 1
|
||||
:style (style/title)}
|
||||
title]
|
||||
[text/text
|
||||
{:accessibility-label :body
|
||||
:size :paragraph-2
|
||||
:weight :medium
|
||||
:number-of-lines 1
|
||||
:style (style/body)}
|
||||
body]])
|
||||
|
||||
(defn- clear-button
|
||||
[{:keys [on-press]}]
|
||||
[rn/touchable-opacity
|
||||
{:on-press on-press
|
||||
:style style/clear-button-container
|
||||
:hit-slop {:top 3 :right 3 :bottom 3 :left 3}
|
||||
:accessibility-label :button-clear-preview}
|
||||
[icon/icon :i/clear
|
||||
{:size 20
|
||||
:container-style style/clear-button
|
||||
:color (colors/theme-colors colors/neutral-50 colors/neutral-60)}]])
|
||||
|
||||
(defn view
|
||||
[{:keys [title body logo on-clear loading? loading-message container-style]}]
|
||||
(if loading?
|
||||
[rn/view
|
||||
{:accessibility-label :url-preview-loading
|
||||
:style (merge (style/loading-container) container-style)}
|
||||
[rn/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:number-of-lines 1
|
||||
:style (style/loading-message)}
|
||||
loading-message]]
|
||||
[rn/view
|
||||
{:accessibility-label :url-preview
|
||||
:style (merge (style/container) container-style)}
|
||||
[logo-component {:logo logo}]
|
||||
[content {:title title :body body}]
|
||||
[clear-button {:on-press on-clear}]]))
|
|
@ -33,6 +33,7 @@
|
|||
quo2.components.inputs.input.view
|
||||
quo2.components.inputs.title-input.view
|
||||
quo2.components.inputs.profile-input.view
|
||||
quo2.components.links.url-preview.view
|
||||
quo2.components.list-items.channel
|
||||
quo2.components.list-items.menu-item
|
||||
quo2.components.list-items.preview-list
|
||||
|
@ -182,3 +183,6 @@
|
|||
(def permission-tag quo2.components.tags.permission-tag/tag)
|
||||
(def status-tag quo2.components.tags.status-tags/status-tag)
|
||||
(def token-tag quo2.components.tags.token-tag/tag)
|
||||
|
||||
;;;; LINKS
|
||||
(def url-preview quo2.components.links.url-preview.view/view)
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
(ns quo2.core-spec
|
||||
(:require [quo2.components.avatars.user-avatar.component-spec]
|
||||
[quo2.components.banners.banner.component-spec]
|
||||
[quo2.components.buttons.--tests--.buttons-component-spec]
|
||||
[quo2.components.colors.color-picker.component-spec]
|
||||
[quo2.components.counter.--tests--.counter-component-spec]
|
||||
[quo2.components.dividers.--tests--.divider-label-component-spec]
|
||||
[quo2.components.dividers.strength-divider.component-spec]
|
||||
[quo2.components.drawers.action-drawers.component-spec]
|
||||
[quo2.components.drawers.drawer-buttons.component-spec]
|
||||
[quo2.components.drawers.permission-context.component-spec]
|
||||
[quo2.components.inputs.input.component-spec]
|
||||
[quo2.components.inputs.profile-input.component-spec]
|
||||
[quo2.components.inputs.title-input.component-spec]
|
||||
[quo2.components.markdown.--tests--.text-component-spec]
|
||||
[quo2.components.onboarding.small-option-card.component-spec]
|
||||
[quo2.components.password.tips.component-spec]
|
||||
[quo2.components.profile.select-profile.component-spec]
|
||||
[quo2.components.record-audio.record-audio.--tests--.record-audio-component-spec]
|
||||
[quo2.components.record-audio.soundtrack.--tests--.soundtrack-component-spec]
|
||||
[quo2.components.selectors.--tests--.selectors-component-spec]
|
||||
[quo2.components.selectors.disclaimer.component-spec]
|
||||
[quo2.components.selectors.filter.component-spec]
|
||||
[quo2.components.tags.--tests--.status-tags-component-spec]))
|
||||
(:require
|
||||
[quo2.components.avatars.user-avatar.component-spec]
|
||||
[quo2.components.banners.banner.component-spec]
|
||||
[quo2.components.buttons.--tests--.buttons-component-spec]
|
||||
[quo2.components.colors.color-picker.component-spec]
|
||||
[quo2.components.counter.--tests--.counter-component-spec]
|
||||
[quo2.components.dividers.--tests--.divider-label-component-spec]
|
||||
[quo2.components.dividers.strength-divider.component-spec]
|
||||
[quo2.components.drawers.action-drawers.component-spec]
|
||||
[quo2.components.drawers.drawer-buttons.component-spec]
|
||||
[quo2.components.drawers.permission-context.component-spec]
|
||||
[quo2.components.inputs.input.component-spec]
|
||||
[quo2.components.inputs.profile-input.component-spec]
|
||||
[quo2.components.inputs.title-input.component-spec]
|
||||
[quo2.components.links.url-preview.component-spec]
|
||||
[quo2.components.markdown.--tests--.text-component-spec]
|
||||
[quo2.components.onboarding.small-option-card.component-spec]
|
||||
[quo2.components.password.tips.component-spec]
|
||||
[quo2.components.profile.select-profile.component-spec]
|
||||
[quo2.components.record-audio.record-audio.--tests--.record-audio-component-spec]
|
||||
[quo2.components.record-audio.soundtrack.--tests--.soundtrack-component-spec]
|
||||
[quo2.components.selectors.--tests--.selectors-component-spec]
|
||||
[quo2.components.selectors.disclaimer.component-spec]
|
||||
[quo2.components.selectors.filter.component-spec]
|
||||
[quo2.components.tags.--tests--.status-tags-component-spec]))
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
(ns status-im2.contexts.quo-preview.links.url-preview
|
||||
(:require
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
|
||||
(def descriptor
|
||||
[{:label "Title"
|
||||
:key :title
|
||||
:type :text}
|
||||
{:label "Body"
|
||||
:key :body
|
||||
:type :text}
|
||||
{:label "Loading?"
|
||||
:key :loading?
|
||||
:type :boolean}
|
||||
{:label "Loading message"
|
||||
:key :loading-message
|
||||
:type :text}])
|
||||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(let [state (reagent/atom
|
||||
{:title "Status - Private, Secure Communication"
|
||||
:body "Status.im"
|
||||
:loading? false
|
||||
:loading-message "Generating preview"})]
|
||||
(fn []
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
[rn/view {:style {:padding-bottom 150}}
|
||||
[preview/customizer state descriptor]
|
||||
[rn/view
|
||||
{:style {:align-items :center
|
||||
:padding-horizontal 16
|
||||
:margin-top 50}}
|
||||
[quo/url-preview
|
||||
{:title (:title @state)
|
||||
:body (:body @state)
|
||||
:logo (resources/get-mock-image :status-logo)
|
||||
:loading? (:loading? @state)
|
||||
:loading-message (:loading-message @state)
|
||||
:on-clear #(js/alert "Clear button pressed")}]]]])))
|
||||
|
||||
(defn preview
|
||||
[]
|
||||
[rn/view
|
||||
{:style {: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}]])
|
|
@ -39,6 +39,7 @@
|
|||
[status-im2.contexts.quo-preview.info.information-box :as information-box]
|
||||
[status-im2.contexts.quo-preview.inputs.profile-input :as profile-input]
|
||||
[status-im2.contexts.quo-preview.inputs.title-input :as title-input]
|
||||
[status-im2.contexts.quo-preview.links.url-preview :as url-preview]
|
||||
[status-im2.contexts.quo-preview.list-items.channel :as channel]
|
||||
[status-im2.contexts.quo-preview.list-items.preview-lists :as preview-lists]
|
||||
[status-im2.contexts.quo-preview.markdown.text :as text]
|
||||
|
@ -177,6 +178,9 @@
|
|||
{:name :title-input
|
||||
:insets {:top false}
|
||||
:component title-input/preview-title-input}]
|
||||
:links [{:name :url-preview
|
||||
:options {:insets {:top? true}}
|
||||
:component url-preview/preview}]
|
||||
:list-items [{:name :channel
|
||||
:insets {:top false}
|
||||
:component channel/preview-channel}
|
||||
|
|
|
@ -186,5 +186,5 @@
|
|||
(.toBeNull (js/expect element)))
|
||||
|
||||
(defn was-called
|
||||
[element]
|
||||
(.toHaveBeenCalled (js/expect element)))
|
||||
[mock]
|
||||
(.toHaveBeenCalled (js/expect mock)))
|
||||
|
|
Loading…
Reference in New Issue