Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75c68bcc60 | ||
|
|
8375eebe71 | ||
|
|
a4717ae5d0 | ||
|
|
a47998a7a0 | ||
|
|
141bf5a333 | ||
|
|
231272603d | ||
|
|
255a3b9172 | ||
|
|
6156bfc472 | ||
|
|
6870000490 | ||
|
|
0ef7dc34e4 | ||
|
|
0f7e98cbe2 | ||
|
|
f4d6f64a66 | ||
|
|
a416267094 | ||
|
|
2358eb195b | ||
|
|
21be0ed16c | ||
|
|
89d1bd3f6a | ||
|
|
5148a3c748 | ||
|
|
8701f3545d | ||
|
|
26eeb43569 | ||
|
|
4d7b1baace | ||
|
|
89c2b1c818 | ||
|
|
17df7a0d35 | ||
|
|
0552713143 | ||
|
|
3223c71526 | ||
|
|
914604bbe4 |
@@ -4,6 +4,8 @@ apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.grad
|
||||
|
||||
import com.android.build.OutputFile
|
||||
import com.sun.org.apache.xalan.internal.xsltc.compiler.Copy
|
||||
import groovy.json.JsonBuilder
|
||||
import groovy.json.JsonSlurper
|
||||
|
||||
/**
|
||||
* The react.gradle file registers a task for each build variant:
|
||||
@@ -463,6 +465,32 @@ task hemroidBuild(type: Exec) {
|
||||
executable execPath
|
||||
}
|
||||
|
||||
// Add this task definition at the bottom of your build.gradle file
|
||||
task printAllDependencies {
|
||||
doLast {
|
||||
println "Listing all dependencies for project..."
|
||||
|
||||
// Iterate through all configurations
|
||||
configurations.all { config ->
|
||||
int dependencyCount = 0
|
||||
|
||||
// Count the dependencies for this configuration
|
||||
config.allDependencies.each { dependency ->
|
||||
dependencyCount++
|
||||
}
|
||||
|
||||
// Print the configuration name and dependency count
|
||||
println "Configuration: ${config.name} (Total Dependencies: ${dependencyCount})"
|
||||
|
||||
// Iterate through all dependencies in the current configuration
|
||||
config.allDependencies.each { dependency ->
|
||||
println " - ${dependency.group}:${dependency.name}:${dependency.version}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
preBuild.dependsOn hemroidBuild
|
||||
|
||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
||||
|
||||
@@ -27,3 +27,4 @@ The team members for the initial wallet team are:
|
||||
- @ulisesmac
|
||||
- @erikseppanen
|
||||
- @mmilad75
|
||||
- @tumanov-alex
|
||||
|
||||
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 923 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 721 B |
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,6 +1,6 @@
|
||||
(ns quo2.components.avatars.group-avatar.view
|
||||
(:require [quo2.components.icon :as icon]
|
||||
[quo2.theme :as theme]
|
||||
[quo2.theme :as quo.theme]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
@@ -20,9 +20,11 @@
|
||||
|
||||
(defn- view-internal
|
||||
[_]
|
||||
(fn [{:keys [size theme customization-color picture]
|
||||
(fn [{:keys [size theme customization-color picture icon-name]
|
||||
:or {size :size/s-20
|
||||
customization-color :blue}}]
|
||||
customization-color :blue
|
||||
picture nil
|
||||
icon-name :i/group}}]
|
||||
(let [container-size (get-in sizes [size :container])
|
||||
icon-size (get-in sizes [size :icon])]
|
||||
[rn/view
|
||||
@@ -34,8 +36,8 @@
|
||||
{:source picture
|
||||
:style {:width container-size
|
||||
:height container-size}}]
|
||||
[icon/icon :i/members
|
||||
[icon/icon icon-name
|
||||
{:size icon-size
|
||||
:color colors/white-opa-70}])])))
|
||||
|
||||
(def view (theme/with-theme view-internal))
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
:status-indicator 12
|
||||
:status-indicator-border 2
|
||||
:font-size :paragraph-2}
|
||||
28 {:dimensions 28
|
||||
:status-indicator 0
|
||||
:status-indicator-border 0
|
||||
:font-size :paragraph-2}
|
||||
:xs {:dimensions 24
|
||||
:status-indicator 0
|
||||
:status-indicator-border 0
|
||||
|
||||
@@ -99,6 +99,10 @@
|
||||
:ring? ring?})}
|
||||
(:uri profile-picture)
|
||||
profile-picture
|
||||
|
||||
(number? profile-picture)
|
||||
profile-picture
|
||||
|
||||
:else {:uri profile-picture})}])]))
|
||||
|
||||
(def user-avatar (quo2.theme/with-theme user-avatar-internal))
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
:icon-top :icon-keyword
|
||||
:icon-left :icon-keyword
|
||||
:icon-right :icon-keyword}
|
||||
:customization-color keyword or hexstring
|
||||
:customization-color keyword or hexstring
|
||||
:theme :light/:dark
|
||||
only icon
|
||||
[button {:icon-only? true} :i/close-circle]"
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
track-icon
|
||||
disabled?
|
||||
customization-color
|
||||
size]}]
|
||||
size
|
||||
container-style]}]
|
||||
(let [x-pos (reanimated/use-shared-value 0)
|
||||
dimensions (partial utils/get-dimensions
|
||||
(or @track-width constants/default-width)
|
||||
@@ -49,7 +50,8 @@
|
||||
sliding-complete?)}
|
||||
[reanimated/view
|
||||
{:test-ID :slide-button-track
|
||||
:style (style/track disabled? customization-color (dimensions :track-height))
|
||||
:style (merge (style/track disabled? customization-color (dimensions :track-height))
|
||||
container-style)
|
||||
:on-layout (when-not (some? @track-width)
|
||||
on-track-layout)}
|
||||
[reanimated/view {:style (style/track-cover interpolate-track)}
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
{:padding-top 24
|
||||
:padding-bottom 12
|
||||
:padding-horizontal 20
|
||||
:flex-direction :row})
|
||||
:flex-direction :row
|
||||
:justify-content :center
|
||||
:flex 1
|
||||
:max-height 106})
|
||||
|
||||
(def button-container
|
||||
{:padding-vertical 8
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def color-picker-container
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
{:flex-direction :row
|
||||
:flex-wrap :wrap
|
||||
:justify-content :space-between})
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
(ns quo2.components.common.not-implemented.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn text
|
||||
[blur? theme]
|
||||
{:border-color :red
|
||||
:border-width 1
|
||||
:color (if blur?
|
||||
colors/white
|
||||
(colors/theme-colors colors/neutral-100
|
||||
colors/white
|
||||
theme))})
|
||||
@@ -0,0 +1,11 @@
|
||||
(ns quo2.components.common.not-implemented.view
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.theme :as quo.theme]
|
||||
[quo2.components.common.not-implemented.style :as style]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [blur? theme]}]
|
||||
[rn/text {:style (style/text blur? theme)}
|
||||
"not implemented"])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -1,13 +1,11 @@
|
||||
(ns quo2.components.community.banner.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[quo2.foundations.shadows :as shadows]))
|
||||
|
||||
(defn community-card
|
||||
[theme]
|
||||
{:shadow-offset {:width 0 :height 2}
|
||||
:shadow-radius 16
|
||||
:shadow-opacity 1
|
||||
:shadow-color colors/shadow
|
||||
:elevation 1
|
||||
(assoc
|
||||
(shadows/get 2 theme)
|
||||
:border-radius 16
|
||||
:justify-content :space-between
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-90 theme)
|
||||
@@ -16,7 +14,7 @@
|
||||
:margin-top 8
|
||||
:margin-bottom 8
|
||||
:height 56
|
||||
:padding-right 12})
|
||||
:padding-right 12))
|
||||
|
||||
(def banner-content
|
||||
{:flex 1
|
||||
|
||||
@@ -16,25 +16,26 @@
|
||||
unread-messages?
|
||||
unread-mentions-count
|
||||
customization-color]}]
|
||||
(cond
|
||||
muted?
|
||||
[icons/icon :i/muted
|
||||
{:container-style {:align-items :center
|
||||
:justify-content :center}
|
||||
:resize-mode :center
|
||||
:size 20
|
||||
:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
colors/neutral-40
|
||||
theme)}]
|
||||
(pos? unread-mentions-count)
|
||||
[counter/view
|
||||
{:customization-color customization-color
|
||||
:type :default}
|
||||
unread-mentions-count]
|
||||
[rn/view {:style style/notification-container}
|
||||
(cond
|
||||
muted?
|
||||
[icons/icon :i/muted
|
||||
{:container-style {:align-items :center
|
||||
:justify-content :center}
|
||||
:resize-mode :center
|
||||
:size 20
|
||||
:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
colors/neutral-40
|
||||
theme)}]
|
||||
(pos? unread-mentions-count)
|
||||
[counter/view
|
||||
{:customization-color customization-color
|
||||
:type :default}
|
||||
unread-mentions-count]
|
||||
|
||||
unread-messages?
|
||||
[unread-grey-dot :unviewed-messages-public]))
|
||||
unread-messages?
|
||||
[unread-grey-dot :unviewed-messages-public])])
|
||||
|
||||
(defn- communities-list-view-item-internal
|
||||
[{:keys [theme customization-color] :as props}
|
||||
|
||||
@@ -4,18 +4,14 @@
|
||||
|
||||
(defn community-card
|
||||
[radius theme]
|
||||
{:shadow-offset {:width 0
|
||||
:height 2}
|
||||
:shadow-radius radius
|
||||
:shadow-opacity 1
|
||||
:shadow-color colors/shadow
|
||||
:elevation 1
|
||||
(assoc
|
||||
(shadows/get 2 theme)
|
||||
:border-radius radius
|
||||
:justify-content :space-between
|
||||
:background-color (colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-90
|
||||
theme)})
|
||||
theme)))
|
||||
|
||||
(def detail-container
|
||||
{:flex 1})
|
||||
@@ -252,3 +248,8 @@
|
||||
:margin-top margin-top})
|
||||
|
||||
(def loading-card-content-container {:margin-top 36})
|
||||
|
||||
(def notification-container
|
||||
{:width 20
|
||||
:display :flex
|
||||
:align-items :center})
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
(ns quo2.components.dividers.divider-label
|
||||
(:require [quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as markdown.text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def chevron-icon-container-width 20)
|
||||
|
||||
(def chevron-icon-container-height 20)
|
||||
|
||||
(defn themed-view
|
||||
"label -> string
|
||||
chevron-position -> :left, :right
|
||||
chevron-icon -> keyword
|
||||
on-press -> function
|
||||
padding-bottom -> number
|
||||
counter-value -> number
|
||||
increase-padding-top? -> boolean
|
||||
blur? -> boolean
|
||||
theme -> theme value passed from with-theme HOC"
|
||||
[{:keys [label
|
||||
chevron-position
|
||||
chevron-icon
|
||||
counter-value
|
||||
increase-padding-top?
|
||||
padding-bottom
|
||||
blur?
|
||||
container-style
|
||||
on-press
|
||||
theme]}]
|
||||
(let [dark? (= :dark theme)
|
||||
border-and-counter-bg-color (if dark?
|
||||
(if blur? colors/white-opa-5 colors/neutral-70)
|
||||
colors/neutral-10)
|
||||
padding-top (if increase-padding-top? 16 8)
|
||||
text-and-icon-color (if dark? colors/neutral-40 colors/neutral-50)
|
||||
counter-text-color (if dark? colors/white colors/neutral-100)]
|
||||
[rn/touchable-without-feedback {:on-press on-press}
|
||||
[rn/view
|
||||
{:accessible true
|
||||
:accessibility-label :divider-label
|
||||
:style (merge {:border-top-width 1
|
||||
:border-top-color border-and-counter-bg-color
|
||||
:padding-top padding-top
|
||||
:padding-bottom padding-bottom
|
||||
:padding-left 16
|
||||
:padding-right 16
|
||||
:align-items :center
|
||||
:flex-direction :row}
|
||||
container-style)}
|
||||
(when (= chevron-position :left)
|
||||
[rn/view
|
||||
{:test-ID :divider-label-icon-left
|
||||
:style {:margin-right 4}}
|
||||
[icons/icon
|
||||
(or chevron-icon :i/chevron-down)
|
||||
{:color text-and-icon-color
|
||||
:width chevron-icon-container-width
|
||||
:height chevron-icon-container-height}]])
|
||||
[markdown.text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style {:color text-and-icon-color
|
||||
:flex 1}}
|
||||
label]
|
||||
(when (= chevron-position :right)
|
||||
[rn/view {:test-ID :divider-label-icon-right}
|
||||
[icons/icon
|
||||
(or chevron-icon :i/chevron-down)
|
||||
{:color text-and-icon-color
|
||||
:size chevron-icon-container-width}]])
|
||||
(when (pos? counter-value)
|
||||
[rn/view
|
||||
{:style {:border-radius 6
|
||||
:height 16
|
||||
:width (case (count counter-value)
|
||||
1 16
|
||||
2 20
|
||||
28)
|
||||
:background-color border-and-counter-bg-color
|
||||
:align-items :center
|
||||
:justify-content :center}}
|
||||
[markdown.text/text
|
||||
{:size :label
|
||||
:weight :medium
|
||||
:style {:color counter-text-color}}
|
||||
counter-value]])]]))
|
||||
|
||||
(def divider-label (theme/with-theme themed-view))
|
||||
@@ -0,0 +1,20 @@
|
||||
(ns quo2.components.dividers.divider-label.component-spec
|
||||
(:require [quo2.components.dividers.divider-label.view :as divider-label]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Divider Label"
|
||||
(h/test "default render"
|
||||
(h/render [divider-label/view "Welcome"])
|
||||
(h/is-truthy (h/query-by-label-text :divider-label)))
|
||||
(h/test "with label"
|
||||
(h/render [divider-label/view {:tight? true} "Welcome"])
|
||||
(h/is-truthy (h/query-by-text "Welcome")))
|
||||
(h/test "with label & counter value"
|
||||
(h/render [divider-label/view {:tight? true :counter? true :counter-value 5} "Public"])
|
||||
(h/is-truthy (h/query-by-text "Public"))
|
||||
(h/is-truthy (h/query-by-text "5")))
|
||||
(h/test "on-press event"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render [divider-label/view {:tight? false :on-press on-press} "General"])
|
||||
(h/fire-event :press (h/query-by-label-text :divider-label))
|
||||
(h/was-called on-press))))
|
||||
@@ -0,0 +1,39 @@
|
||||
(ns quo2.components.dividers.divider-label.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn- get-border-color
|
||||
[blur? theme]
|
||||
(colors/theme-colors (if blur? colors/neutral-80-opa-5 colors/neutral-10)
|
||||
(if blur? colors/white-opa-5 colors/neutral-90)
|
||||
theme))
|
||||
|
||||
(defn get-content-color
|
||||
[blur? theme]
|
||||
(colors/theme-colors (if blur? colors/neutral-80-opa-70 colors/neutral-50)
|
||||
(if blur? colors/white-opa-70 colors/neutral-40)
|
||||
theme))
|
||||
|
||||
(defn container
|
||||
[blur? tight? chevron theme]
|
||||
{:border-top-width 1
|
||||
:border-top-color (get-border-color blur? theme)
|
||||
:padding-top (if tight? 6 14)
|
||||
:padding-bottom 7
|
||||
:padding-left (if (= :left chevron) 16 20)
|
||||
:padding-right 20
|
||||
:align-items :center
|
||||
:flex-direction :row})
|
||||
|
||||
(defn content
|
||||
[chevron]
|
||||
{:flex-direction (if (= chevron :right)
|
||||
:row-reverse
|
||||
:row)
|
||||
:align-items :center
|
||||
:height 20
|
||||
:flex 1})
|
||||
|
||||
(defn text
|
||||
[blur? theme]
|
||||
{:color (get-content-color blur? theme)
|
||||
:flex 1})
|
||||
@@ -0,0 +1,60 @@
|
||||
(ns quo2.components.dividers.divider-label.view
|
||||
(:require [quo2.components.markdown.text :as text]
|
||||
[quo2.components.dividers.divider-label.style :as style]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[quo2.components.counter.counter.view :as counter]
|
||||
[quo2.components.icon :as icons]))
|
||||
|
||||
(defn- view-internal
|
||||
"Options:
|
||||
- `counter?` (default: nil) - Display a counter on the right side of the divider.
|
||||
- `counter-value` (default: nil) - Number to display if counter? is true.
|
||||
- `chevron` nil/:right/:left (default: nil) - Display a chevron on the left or right side of the divider.
|
||||
- `chevron-icon` (default: :i/chevron-right) - Icon to display when chevron is :left/:right.
|
||||
- `tight?` (default: true) - Use a tighter padding.
|
||||
- `blur?` (default: nil) - Use a blur background.
|
||||
- `theme` - Theme value from with-theme HOC.
|
||||
- `on-press` - Function called when the divider is pressed.
|
||||
- `container-style` - Style applied to the container view.
|
||||
|
||||
label - String or markdown text component to display in the divider label."
|
||||
[{:keys [counter?
|
||||
counter-value
|
||||
chevron
|
||||
chevron-icon
|
||||
tight?
|
||||
blur?
|
||||
theme
|
||||
on-press
|
||||
container-style]
|
||||
:or {tight? true}}
|
||||
label]
|
||||
[rn/pressable
|
||||
{:on-press on-press
|
||||
:accessibility-label :divider-label
|
||||
:style (merge (style/container blur? tight? chevron theme)
|
||||
container-style)}
|
||||
[rn/view
|
||||
{:style (style/content chevron)}
|
||||
(when chevron
|
||||
[icons/icon (or chevron-icon :i/chevron-right)
|
||||
{:color (style/get-content-color blur? theme)
|
||||
:container-style {(if (= chevron :right)
|
||||
:margin-left
|
||||
:margin-right)
|
||||
2}}])
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/text blur? theme)}
|
||||
label]]
|
||||
(when counter?
|
||||
[counter/view
|
||||
{:type (if blur? :secondary :grey)
|
||||
:container-style {:margin-left 2}}
|
||||
counter-value])])
|
||||
|
||||
(defn view
|
||||
([_ _] (quo.theme/with-theme view-internal))
|
||||
([label] [view {} label]))
|
||||
@@ -1,45 +0,0 @@
|
||||
(ns quo2.components.dividers.divider-label-component-spec
|
||||
(:require ["@testing-library/react-native" :as rtl]
|
||||
[quo2.components.dividers.divider-label :as divider-label]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn render-divider-label
|
||||
([]
|
||||
(render-divider-label {}))
|
||||
([opts]
|
||||
(rtl/render (reagent/as-element [divider-label/divider-label opts]))))
|
||||
|
||||
(js/global.test "default render of divider-label component"
|
||||
(fn []
|
||||
(render-divider-label)
|
||||
(-> (js/expect (rtl/screen.getByLabelText "divider-label"))
|
||||
(.toBeTruthy))))
|
||||
|
||||
(js/global.test "render divider-label component with a label"
|
||||
(fn []
|
||||
(render-divider-label {:label :hello})
|
||||
(-> (js/expect (rtl/screen.getByText "hello"))
|
||||
(.toBeTruthy))))
|
||||
|
||||
(js/global.test "render divider-label component with a counter-value"
|
||||
(fn []
|
||||
(render-divider-label {:label :hello
|
||||
:counter-value "1"})
|
||||
(-> (js/expect (rtl/screen.getByText "1"))
|
||||
(.toBeTruthy))))
|
||||
|
||||
(js/global.test "divider-label chevron icon renders to the left when set"
|
||||
(fn []
|
||||
(render-divider-label {:label :hello
|
||||
:counter-value "1"
|
||||
:chevron-position :left})
|
||||
(-> (js/expect (rtl/screen.getByTestId "divider-label-icon-left"))
|
||||
(.toBeTruthy))))
|
||||
|
||||
(js/global.test "divider-label chevron icon renders to the right when set"
|
||||
(fn []
|
||||
(render-divider-label {:label :hello
|
||||
:counter-value "1"
|
||||
:chevron-position :right})
|
||||
(-> (js/expect (rtl/screen.getByTestId "divider-label-icon-right"))
|
||||
(.toBeTruthy))))
|
||||
@@ -2,7 +2,7 @@
|
||||
(:require [quo2.theme :as quo.theme]
|
||||
[quo2.components.dropdowns.network-dropdown.style :as style]
|
||||
[react-native.core :as rn]
|
||||
[quo2.components.list-items.preview-list :as preview-list]
|
||||
[quo2.components.list-items.preview-list.view :as preview-list]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- internal-view
|
||||
@@ -17,10 +17,10 @@
|
||||
:on-press on-press
|
||||
:on-press-in (fn [] (reset! pressed? true))
|
||||
:on-press-out (fn [] (reset! pressed? false))}
|
||||
[preview-list/preview-list
|
||||
[preview-list/view
|
||||
{:type :network
|
||||
:list-size (count networks)
|
||||
:size 20}
|
||||
:size :size/s-20}
|
||||
networks]])))
|
||||
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
|
||||
@@ -24,3 +24,8 @@
|
||||
{:color colors/white}))
|
||||
|
||||
(def button-container {:margin-top 20})
|
||||
|
||||
(def image-placeholder
|
||||
{:width 80
|
||||
:height 80
|
||||
:background-color colors/danger})
|
||||
|
||||
@@ -7,14 +7,16 @@
|
||||
[quo2.theme :as theme]))
|
||||
|
||||
(defn- empty-state-internal
|
||||
[{:keys [customization-color image title description blur?]
|
||||
[{:keys [customization-color image title description blur? placeholder? container-style]
|
||||
upper-button :upper-button
|
||||
lower-button :lower-button
|
||||
:or {customization-color :blue}}]
|
||||
[rn/view {:style styles/container}
|
||||
[fast-image/fast-image
|
||||
{:style styles/image
|
||||
:source image}]
|
||||
[rn/view {:style (merge styles/container container-style)}
|
||||
(if placeholder?
|
||||
[rn/view {:style styles/image-placeholder}]
|
||||
[fast-image/fast-image
|
||||
{:style styles/image
|
||||
:source image}])
|
||||
[rn/view {:style styles/text-container}
|
||||
[text/text
|
||||
{:style (styles/title blur?)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
[react-native.linear-gradient :as linear-gradient]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [customization-color] :or {customization-color :blue}}]
|
||||
[{:keys [customization-color container-style] :or {customization-color :blue}}]
|
||||
(let [color-top (colors/custom-color customization-color 50 20)
|
||||
color-bottom (colors/custom-color customization-color 50 0)]
|
||||
[linear-gradient/linear-gradient
|
||||
@@ -13,6 +13,6 @@
|
||||
:colors [color-top color-bottom]
|
||||
:start {:x 0 :y 0}
|
||||
:end {:x 0 :y 1}
|
||||
:style style/root-container}]))
|
||||
:style (merge style/root-container container-style)}]))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -2,8 +2,11 @@
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def gradient-background
|
||||
{:height 294
|
||||
:justify-content :flex-end})
|
||||
{:height 294
|
||||
:position :absolute
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0})
|
||||
|
||||
(def x-axis-label-text-style ; We need this to remove unnecessary bottom spacing from graph
|
||||
{:margin-bottom -3
|
||||
|
||||
@@ -37,11 +37,12 @@
|
||||
:style style/illustration}
|
||||
[text/text {:style {:color colors/white}}
|
||||
"Illustration here"]]
|
||||
[linear-gradient/linear-gradient
|
||||
{:colors gradient-colors
|
||||
:start {:x 0 :y 1}
|
||||
:end {:x 0 :y 0}
|
||||
:style style/gradient-background}
|
||||
[rn/view
|
||||
[linear-gradient/linear-gradient
|
||||
{:colors gradient-colors
|
||||
:start {:x 0 :y 1}
|
||||
:end {:x 0 :y 0}
|
||||
:style style/gradient-background}]
|
||||
[rn/view {:accessibility-label :line-chart}
|
||||
[charts/line-chart
|
||||
{:height 96
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
(defn title-text
|
||||
[disabled? blur? theme]
|
||||
{:text-align-vertical :bottom
|
||||
:padding 0
|
||||
:color (if disabled?
|
||||
(get-disabled-color blur? theme)
|
||||
(colors/theme-colors colors/neutral-100 colors/white theme))})
|
||||
@@ -50,7 +51,6 @@
|
||||
|
||||
(def container
|
||||
{:flex-direction :row
|
||||
:flex 1
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
placeholder
|
||||
max-length
|
||||
default-value
|
||||
theme]
|
||||
theme
|
||||
container-style]
|
||||
:or {max-length 0
|
||||
auto-focus false
|
||||
default-value ""}}]
|
||||
@@ -31,7 +32,7 @@
|
||||
(on-change-text v)))]
|
||||
(fn [{:keys [customization-color disabled?]}]
|
||||
[rn/view
|
||||
{:style style/container}
|
||||
{:style (merge style/container container-style)}
|
||||
[rn/view {:style style/text-input-container}
|
||||
[rn/text-input
|
||||
{:style
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
(ns quo2.components.list-items.dapp.component-spec
|
||||
(:require [quo2.components.list-items.dapp.view :as dapp]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(def props
|
||||
{:dapp {:avatar nil
|
||||
:name "Coingecko"
|
||||
:value "coingecko.com"}
|
||||
:state :default
|
||||
:action :icon
|
||||
:blur? false
|
||||
:customization-color :blue})
|
||||
|
||||
(h/describe
|
||||
"dApp component test"
|
||||
(h/test "default render"
|
||||
(h/render [dapp/view props])
|
||||
(h/is-truthy (h/get-by-text (:name (:dapp props))))
|
||||
(h/is-truthy (h/get-by-text (:value (:dapp props)))))
|
||||
(h/test "on-press event"
|
||||
(let [mock-fn (h/mock-fn)]
|
||||
(h/render [dapp/view (assoc props :on-press-icon mock-fn)])
|
||||
(h/fire-event :press (h/get-by-test-id "dapp-component-icon"))
|
||||
(h/was-called mock-fn))))
|
||||
@@ -0,0 +1,47 @@
|
||||
(ns quo2.components.list-items.dapp.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn get-background-color
|
||||
[{:keys [pressed? state blur? customization-color theme]}]
|
||||
(cond
|
||||
(and pressed? (= theme :dark) blur?) colors/white-opa-5
|
||||
|
||||
pressed? (colors/theme-colors
|
||||
(colors/custom-color customization-color 50 5)
|
||||
(colors/custom-color customization-color 60 5)
|
||||
theme)
|
||||
|
||||
(and (= state :active) (= theme :dark) blur?) colors/white-opa-10
|
||||
|
||||
(= state :active) (colors/theme-colors
|
||||
(colors/custom-color customization-color 50 10)
|
||||
(colors/custom-color customization-color 60 10)
|
||||
theme)
|
||||
|
||||
:else :transparent))
|
||||
|
||||
(defn container
|
||||
[props]
|
||||
{:flex 1
|
||||
:padding-horizontal 12
|
||||
:padding-vertical 8
|
||||
:border-radius 12
|
||||
:background-color (get-background-color props)
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center})
|
||||
|
||||
(def container-info
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(def user-info
|
||||
{:margin-left 8})
|
||||
|
||||
(defn style-text-name
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white theme)})
|
||||
|
||||
(defn style-text-value
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/neutral-50 colors/white theme)})
|
||||
@@ -0,0 +1,47 @@
|
||||
(ns quo2.components.list-items.dapp.view
|
||||
(:require [quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[quo2.components.list-items.dapp.style :as style]
|
||||
[quo2.theme :as quo.theme]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- view-internal
|
||||
[]
|
||||
(let [pressed? (reagent/atom false)]
|
||||
(fn [{:keys [dapp action on-press on-press-icon theme] :as props}]
|
||||
[rn/pressable
|
||||
{:style (style/container (assoc props :pressed? @pressed?))
|
||||
:on-press on-press
|
||||
:on-press-in #(reset! pressed? true)
|
||||
:on-press-out #(reset! pressed? false)}
|
||||
[rn/view {:style style/container-info}
|
||||
[fast-image/fast-image
|
||||
{:source (:avatar dapp)
|
||||
:style {:width 32 :height 32}}]
|
||||
[rn/view {:style style/user-info}
|
||||
[text/text
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-1
|
||||
:style (style/style-text-name theme)}
|
||||
(:name dapp)]
|
||||
[text/text
|
||||
{:weight :regular
|
||||
:size :paragraph-2
|
||||
:style (style/style-text-value theme)}
|
||||
(:value dapp)]]]
|
||||
(when (= action :icon)
|
||||
[rn/pressable
|
||||
{:on-press on-press-icon
|
||||
:testID "dapp-component-icon"}
|
||||
[icons/icon :i/options
|
||||
{:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
colors/neutral-40
|
||||
theme)
|
||||
:accessibility-label :icon}]])])))
|
||||
|
||||
(def view
|
||||
(quo.theme/with-theme view-internal))
|
||||
@@ -1,154 +0,0 @@
|
||||
(ns quo2.components.list-items.preview-list
|
||||
(:require [quo2.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo2.components.icon :as quo2.icons]
|
||||
[quo2.components.markdown.text :as quo2.text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[react-native.hole-view :as hole-view]
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(def params
|
||||
{32 {:border-radius {:circular 16 :rounded 10}
|
||||
:hole-radius {:circular 18 :rounded 12}
|
||||
:margin-left -8
|
||||
:hole-size 36
|
||||
:hole-x 22
|
||||
:hole-y -2}
|
||||
24 {:border-radius {:circular 12 :rounded 8}
|
||||
:hole-radius {:circular 13 :rounded 9}
|
||||
:margin-left -4
|
||||
:hole-size 26
|
||||
:hole-x 19
|
||||
:hole-y -1}
|
||||
20 {:border-radius {:circular 10 :rounded 8}
|
||||
:hole-radius {:circular 11 :rounded 9}
|
||||
:margin-left -4
|
||||
:hole-size 22
|
||||
:hole-x 15
|
||||
:hole-y -1}
|
||||
16 {:border-radius {:circular 8 :rounded 8}
|
||||
:hole-radius {:circular 9 :rounded 9}
|
||||
:margin-left -4
|
||||
:hole-size 18
|
||||
:hole-x 11
|
||||
:hole-y -1}})
|
||||
|
||||
;; TODO - Add avatar components for other types once implemented
|
||||
(defn avatar
|
||||
[item type size border-radius]
|
||||
(case type
|
||||
:user [user-avatar/user-avatar
|
||||
(merge {:ring? false
|
||||
:status-indicator? false
|
||||
:size (case size
|
||||
32 :small
|
||||
24 :xs
|
||||
16 :xxxs)}
|
||||
item)]
|
||||
(:photo :collectible :network) [fast-image/fast-image
|
||||
{:source (:source item)
|
||||
:style {:width size
|
||||
:height size
|
||||
:border-radius border-radius}}]))
|
||||
|
||||
(defn list-item
|
||||
[index type size item list-size margin-left
|
||||
hole-size hole-radius hole-x hole-y border-radius]
|
||||
(let [last-item? (= index (- list-size 1))]
|
||||
[hole-view/hole-view
|
||||
{:style {:margin-left (if (= index 0) 0 margin-left)}
|
||||
:holes (if last-item?
|
||||
[]
|
||||
[{:x hole-x
|
||||
:y hole-y
|
||||
:width hole-size
|
||||
:height hole-size
|
||||
:borderRadius hole-radius}])}
|
||||
[avatar item type size border-radius]]))
|
||||
|
||||
(defn get-overflow-color
|
||||
[transparent? transparent-color light-color dark-color theme]
|
||||
(if transparent?
|
||||
transparent-color
|
||||
(colors/theme-colors light-color dark-color theme)))
|
||||
|
||||
(defn overflow-label
|
||||
[{:keys [label size transparent? border-radius margin-left theme more-than-99-label]}]
|
||||
[rn/view
|
||||
{:style {:width size
|
||||
:height size
|
||||
:margin-left margin-left
|
||||
:border-radius border-radius
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color (get-overflow-color
|
||||
transparent?
|
||||
colors/white-opa-10
|
||||
colors/neutral-20
|
||||
colors/neutral-70
|
||||
theme)}}
|
||||
(if (= size 16)
|
||||
[quo2.icons/icon :i/more
|
||||
{:size 12
|
||||
:color (get-overflow-color
|
||||
transparent?
|
||||
colors/white-opa-70
|
||||
colors/neutral-50
|
||||
colors/neutral-40
|
||||
theme)}]
|
||||
[quo2.text/text
|
||||
{:size (if (= size 32) :paragraph-2 :label)
|
||||
:weight :medium
|
||||
:style {:color (get-overflow-color
|
||||
transparent?
|
||||
colors/white-opa-70
|
||||
colors/neutral-60
|
||||
colors/neutral-40
|
||||
theme)
|
||||
:margin-left -2}}
|
||||
;; If overflow label is below 100, show label as +label (ex. +30), else just show 99+
|
||||
(if (< label 100)
|
||||
(str "+" label)
|
||||
more-than-99-label)])])
|
||||
|
||||
(defn border-type
|
||||
[type]
|
||||
(case type
|
||||
(:account :collectible :photo) :rounded
|
||||
:circular))
|
||||
|
||||
(defn- preview-list-internal
|
||||
"[preview-list opts items]
|
||||
opts
|
||||
{:type :user/:community/:account/:token/:collectible/:dapp/:network
|
||||
:size 32/24/16
|
||||
:list-size override items count in overflow label (optional)
|
||||
:transparent? overflow-label transparent?}
|
||||
items preview list items (only 4 items is required for preview)
|
||||
"
|
||||
[{:keys [type size list-size transparent? theme more-than-99-label]} items]
|
||||
(let [items-arr (into [] items)
|
||||
list-size (or list-size (count items))
|
||||
margin-left (get-in params [size :margin-left])
|
||||
hole-size (get-in params [size :hole-size])
|
||||
border-radius (get-in params [size :border-radius (border-type type)])
|
||||
hole-radius (get-in params [size :hole-radius (border-type type)])
|
||||
hole-x (get-in params [size :hole-x])
|
||||
hole-y (get-in params [size :hole-y])]
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
(for [index (range (if (> list-size 4) 3 list-size))]
|
||||
^{:key (str index list-size)}
|
||||
[list-item index type size (get items-arr index) list-size
|
||||
margin-left hole-size hole-radius hole-x hole-y border-radius])
|
||||
(when (> list-size 4)
|
||||
[overflow-label
|
||||
{:label (- list-size 3)
|
||||
:size size
|
||||
:transparent? transparent?
|
||||
:border-radius border-radius
|
||||
:margin-left margin-left
|
||||
:theme theme
|
||||
:more-than-99-label more-than-99-label}])]))
|
||||
|
||||
(def preview-list (quo.theme/with-theme preview-list-internal))
|
||||
@@ -0,0 +1,49 @@
|
||||
(ns quo2.components.list-items.preview-list.properties)
|
||||
|
||||
(def ^:private types-for-squared-border #{:accounts :collectibles})
|
||||
|
||||
(defn border-type
|
||||
[type]
|
||||
(if (types-for-squared-border type) :squared :rounded))
|
||||
|
||||
(def sizes
|
||||
{:size/s-32 {:size 32
|
||||
:user-avatar-size :small
|
||||
:border-radius {:rounded 16 :squared 10}
|
||||
:hole-radius {:rounded 18 :squared 12}
|
||||
:margin-left -8
|
||||
:hole-size 36
|
||||
:hole-x 22
|
||||
:hole-y -2}
|
||||
:size/s-24 {:size 24
|
||||
:user-avatar-size :xs
|
||||
:border-radius {:rounded 12 :squared 8}
|
||||
:hole-radius {:rounded 13 :squared 9}
|
||||
:margin-left -4
|
||||
:hole-size 26
|
||||
:hole-x 19
|
||||
:hole-y -1}
|
||||
:size/s-20 {:size 20
|
||||
:user-avatar-size :xxs
|
||||
:border-radius {:rounded 10 :squared 8}
|
||||
:hole-radius {:rounded 11 :squared 9}
|
||||
:margin-left -4
|
||||
:hole-size 22
|
||||
:hole-x 15
|
||||
:hole-y -1}
|
||||
:size/s-16 {:size 16
|
||||
:user-avatar-size :xxxs
|
||||
:border-radius {:rounded 8 :squared 8}
|
||||
:hole-radius {:rounded 9 :squared 9}
|
||||
:margin-left -4
|
||||
:hole-size 18
|
||||
:hole-x 11
|
||||
:hole-y -1}
|
||||
:size/s-14 {:size 14
|
||||
:user-avatar-size :xxxs
|
||||
:border-radius {:rounded 7 :squared 7}
|
||||
:hole-radius {:rounded 8 :squared 8}
|
||||
:margin-left -2
|
||||
:hole-size 16
|
||||
:hole-x 11
|
||||
:hole-y -1}})
|
||||
@@ -0,0 +1,150 @@
|
||||
(ns quo2.components.list-items.preview-list.view
|
||||
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo2.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo2.components.icon :as quo2.icons]
|
||||
[quo2.components.markdown.text :as quo2.text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as quo.theme]
|
||||
[quo2.components.list-items.preview-list.properties :as properties]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[react-native.hole-view :as hole-view]))
|
||||
|
||||
;; This overflow item needs to be cleaned up once the "number tag" component is implemented
|
||||
;; https://github.com/status-im/status-mobile/issues/17045
|
||||
(defn get-overflow-color
|
||||
[blur? blur-light-color blur-dark-color light-color dark-color theme]
|
||||
(if blur?
|
||||
(colors/theme-colors blur-light-color blur-dark-color theme)
|
||||
(colors/theme-colors light-color dark-color theme)))
|
||||
|
||||
(def more-icon-for-sizes #{16 14})
|
||||
|
||||
(defn overflow-label
|
||||
[{:keys [label size blur? border-radius margin-left theme more-than-99-label]}]
|
||||
[rn/view
|
||||
{:style {:width size
|
||||
:height size
|
||||
:margin-left margin-left
|
||||
:border-radius border-radius
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color (get-overflow-color
|
||||
blur?
|
||||
colors/neutral-80-opa-5
|
||||
colors/white-opa-5
|
||||
colors/neutral-20
|
||||
colors/neutral-90
|
||||
theme)}}
|
||||
(if (more-icon-for-sizes size)
|
||||
[quo2.icons/icon :i/more
|
||||
{:size 12
|
||||
:color (get-overflow-color
|
||||
blur?
|
||||
colors/neutral-80-opa-70
|
||||
colors/white-opa-70
|
||||
colors/neutral-50
|
||||
colors/neutral-40
|
||||
theme)}]
|
||||
[quo2.text/text
|
||||
{:size (if (= size 32) :paragraph-2 :label)
|
||||
:weight :medium
|
||||
:style {:color (get-overflow-color
|
||||
blur?
|
||||
colors/neutral-80-opa-70
|
||||
colors/white-opa-70
|
||||
colors/neutral-50
|
||||
colors/neutral-40
|
||||
theme)
|
||||
:margin-left -2}}
|
||||
;; If overflow label is below 100, show label as +label (ex. +30), else just show 99+
|
||||
(if (< label 100)
|
||||
(str "+" label)
|
||||
more-than-99-label)])])
|
||||
|
||||
(defn- preview-item
|
||||
[{:keys [item type size-key]}]
|
||||
(let [size (get-in properties/sizes [size-key :size])
|
||||
user-avatar-size (get-in properties/sizes [size-key :user-avatar-size])
|
||||
border-radius (get-in properties/sizes
|
||||
[size-key :border-radius (properties/border-type type)])]
|
||||
(case type
|
||||
:user [user-avatar/user-avatar
|
||||
(merge {:ring? false
|
||||
:status-indicator? false
|
||||
:size user-avatar-size}
|
||||
item)]
|
||||
|
||||
:accounts [account-avatar/view
|
||||
(merge item {:size size})]
|
||||
|
||||
(:communities :collectibles) [fast-image/fast-image
|
||||
{:source (:source item)
|
||||
:style {:width size
|
||||
:height size
|
||||
:border-radius border-radius}}]
|
||||
|
||||
(:tokens :network :dapps) [fast-image/fast-image
|
||||
{:source (:source item)
|
||||
:style {:width size
|
||||
:height size
|
||||
:border-radius border-radius}}]
|
||||
nil)))
|
||||
|
||||
(defn- list-item
|
||||
[{:keys [index type size-key item number]}]
|
||||
(let [last-item? (= index (dec number))
|
||||
border-type (properties/border-type type)
|
||||
{margin-left :margin-left
|
||||
hole-size :hole-size
|
||||
hole-x :hole-x
|
||||
hole-y :hole-y
|
||||
{hole-radius border-type} :hole-radius} (properties/sizes size-key)]
|
||||
[hole-view/hole-view
|
||||
{:style {:margin-left (if (= index 0) 0 margin-left)}
|
||||
:holes (if last-item?
|
||||
[]
|
||||
[{:x hole-x
|
||||
:y hole-y
|
||||
:width hole-size
|
||||
:height hole-size
|
||||
:borderRadius hole-radius}])}
|
||||
[preview-item
|
||||
{:item item
|
||||
:type type
|
||||
:size-key size-key}]]))
|
||||
|
||||
(defn- view-internal
|
||||
"[preview-list opts items]
|
||||
opts
|
||||
{:type :user/:communities/:accounts/:tokens/:collectibles/:dapps/:network
|
||||
:size :size/s-32 | :size/s-24 | :size/s-20 | :size/s-16 | :size/s-14
|
||||
:number number of items in the list (optional)
|
||||
:blur? overflow-label blur?}
|
||||
items preview list items (only 4 items is required for preview)
|
||||
"
|
||||
[{:keys [type size number blur? theme more-than-99-label]} items]
|
||||
(let [size-key (if (contains? properties/sizes size) size :size/s-24)
|
||||
number (or number (count items))
|
||||
margin-left (get-in properties/sizes [size-key :margin-left])
|
||||
border-radius (get-in properties/sizes [size-key :border-radius (properties/border-type type)])]
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
(for [index (range (if (> number 4) 3 number))]
|
||||
^{:key (str index number)}
|
||||
[list-item
|
||||
{:index index
|
||||
:type type
|
||||
:size-key size-key
|
||||
:item (get (vec items) index)
|
||||
:number number}])
|
||||
(when (> number 4)
|
||||
[overflow-label
|
||||
{:label (- number 3)
|
||||
:size (get-in properties/sizes [size-key :size])
|
||||
:blur? blur?
|
||||
:border-radius border-radius
|
||||
:margin-left margin-left
|
||||
:theme theme
|
||||
:more-than-99-label more-than-99-label}])]))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -34,7 +34,7 @@
|
||||
:align-items :center
|
||||
:flex 1}}
|
||||
[rn/image
|
||||
{:source (resources/tokens token)
|
||||
{:source (resources/get-token token)
|
||||
:style {:width 32
|
||||
:height 32}}]
|
||||
[rn/view {:style {:margin-left 8}}
|
||||
|
||||
@@ -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))
|
||||
@@ -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?)))))
|
||||
@@ -1,4 +1,4 @@
|
||||
(ns quo2.components.loaders.skeleton.constants)
|
||||
(ns quo2.components.loaders.skeleton-list.constants)
|
||||
|
||||
(def ^:const layout-dimensions
|
||||
{:messages {:height 56
|
||||
@@ -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]
|
||||
@@ -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))
|
||||
@@ -1,12 +1,12 @@
|
||||
(ns quo2.components.markdown.list.view
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.counter.step.view :as step]
|
||||
[quo2.components.markdown.list.style :as style]
|
||||
(:require [quo2.components.counter.step.view :as step]
|
||||
[quo2.components.icon :as icon]
|
||||
[quo2.components.markdown.list.style :as style]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.tags.context-tag.view :as context-tag]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[quo2.components.tags.context-tag.view :as context-tag]))
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn get-colors
|
||||
[theme blur?]
|
||||
@@ -27,7 +27,11 @@
|
||||
:size :paragraph-2}
|
||||
description]
|
||||
[rn/view {:style {:margin-left 4}}
|
||||
[context-tag/context-tag {:blur? blur?} tag-picture tag-name]]
|
||||
[context-tag/view
|
||||
{:blur? blur?
|
||||
:size 24
|
||||
:profile-picture tag-picture
|
||||
:full-name tag-name}]]
|
||||
[text/text
|
||||
{:style {:margin-left 4}
|
||||
:accessibility-label :list-item-description-after-tag
|
||||
|
||||
@@ -6,22 +6,26 @@
|
||||
:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(def middle-dot-nickname
|
||||
{:color colors/neutral-50
|
||||
(defn middle-dot-nickname
|
||||
[]
|
||||
{:color (colors/theme-colors colors/neutral-40 colors/neutral-50)
|
||||
:margin-horizontal 4})
|
||||
|
||||
(def chat-key-text
|
||||
{:color colors/neutral-50
|
||||
(defn chat-key-text
|
||||
[]
|
||||
{:color (colors/theme-colors colors/neutral-40 colors/neutral-50)
|
||||
:margin-left 8})
|
||||
|
||||
(def middle-dot-chat-key
|
||||
{:color colors/neutral-50
|
||||
(defn middle-dot-chat-key
|
||||
[]
|
||||
{:color (colors/theme-colors colors/neutral-40 colors/neutral-50)
|
||||
:margin-left 4})
|
||||
|
||||
(def icon-container
|
||||
{:margin-left 4})
|
||||
|
||||
(defn time-text
|
||||
[ens?]
|
||||
{:color colors/neutral-50
|
||||
:margin-left (if ens? 8 4)})
|
||||
[verified?]
|
||||
{:color (colors/theme-colors colors/neutral-40 colors/neutral-50)
|
||||
:padding-top 1
|
||||
:margin-left (if verified? 8 4)})
|
||||
|
||||
@@ -9,26 +9,33 @@
|
||||
(def middle-dot "·")
|
||||
|
||||
(defn author
|
||||
[{:keys [primary-name secondary-name style short-chat-key time-str contact? verified? untrustworthy?]}]
|
||||
[{:keys [primary-name secondary-name style short-chat-key time-str contact? verified? untrustworthy?
|
||||
muted? size]
|
||||
:or {size 13}}]
|
||||
[rn/view {:style (merge style/container style)}
|
||||
[text/text
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:number-of-lines 1
|
||||
:style {:color (colors/theme-colors colors/neutral-100 colors/white)}}
|
||||
{:weight :semi-bold
|
||||
:size (if (= size 15) :paragraph-1 :paragraph-2)
|
||||
:number-of-lines 1
|
||||
:accessibility-label :author-primary-name
|
||||
:style {:color (if muted?
|
||||
colors/neutral-50
|
||||
(colors/theme-colors colors/neutral-100 colors/white))}}
|
||||
primary-name]
|
||||
(when (not (string/blank? secondary-name))
|
||||
[:<>
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
{:size :label
|
||||
:number-of-lines 1
|
||||
:style style/middle-dot-nickname}
|
||||
:style (style/middle-dot-nickname)}
|
||||
middle-dot]
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:number-of-lines 1
|
||||
:style {:color (colors/theme-colors colors/neutral-60 colors/neutral-40)}}
|
||||
{:weight :medium
|
||||
:size :label
|
||||
:number-of-lines 1
|
||||
:accessibility-label :author-secondary-name
|
||||
:style {:padding-top 1
|
||||
:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}}
|
||||
secondary-name]])
|
||||
(when contact?
|
||||
[icons/icon :main-icons2/contact
|
||||
@@ -51,14 +58,14 @@
|
||||
{:monospace true
|
||||
:size :label
|
||||
:number-of-lines 1
|
||||
:style style/chat-key-text}
|
||||
:style (style/chat-key-text)}
|
||||
short-chat-key])
|
||||
(when (and (not verified?) time-str)
|
||||
(when (and (not verified?) time-str short-chat-key)
|
||||
[text/text
|
||||
{:monospace true
|
||||
:size :label
|
||||
:number-of-lines 1
|
||||
:style style/middle-dot-chat-key}
|
||||
:style (style/middle-dot-chat-key)}
|
||||
middle-dot])
|
||||
(when time-str
|
||||
[text/text
|
||||
|
||||
@@ -1,262 +0,0 @@
|
||||
(ns quo2.components.navigation.page-nav
|
||||
(:require [clojure.string :as string]
|
||||
[quo2.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo2.components.buttons.button.view :as button]
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[quo2.theme :as theme]))
|
||||
|
||||
(def ^:private centrify-style
|
||||
{:display :flex
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
|
||||
(def ^:private align-left (assoc centrify-style :align-items :flex-start))
|
||||
|
||||
(defn- big? [size] (= size :big))
|
||||
|
||||
(defn- icon-props
|
||||
[color size]
|
||||
(merge {:size 20
|
||||
:container-style {:width (if (big? size)
|
||||
20
|
||||
16)
|
||||
:height (if (big? size)
|
||||
20
|
||||
16)}}
|
||||
(if-not (string/blank? color)
|
||||
{:color color}
|
||||
{:no-color true})))
|
||||
|
||||
(defn left-section-view
|
||||
[{:keys [on-press icon accessibility-label type icon-background]
|
||||
:or {type :grey}}
|
||||
put-middle-section-on-left?]
|
||||
[rn/view {:style (when put-middle-section-on-left? {:margin-right 5})}
|
||||
[button/button
|
||||
{:on-press on-press
|
||||
:icon-only? true
|
||||
:type type
|
||||
:size 32
|
||||
:accessibility-label accessibility-label
|
||||
:background icon-background}
|
||||
icon]])
|
||||
|
||||
(defn- mid-section-comp
|
||||
[{:keys [description-img description-user-icon horizontal-description?
|
||||
text-secondary-color align-mid? text-color icon main-text type description]}]
|
||||
[rn/view
|
||||
{:style (assoc centrify-style
|
||||
:flex-direction :row
|
||||
:margin-horizontal 2)}
|
||||
(when (or (and (not horizontal-description?)
|
||||
align-mid?
|
||||
(not= :text-with-description type))
|
||||
(and (or description-img description-user-icon)
|
||||
(not icon)))
|
||||
(if description-img
|
||||
[rn/view {:margin-right 8}
|
||||
[description-img]]
|
||||
[rn/image
|
||||
{:source {:uri description-user-icon}
|
||||
:style {:width 32
|
||||
:height 32
|
||||
:border-radius 32
|
||||
:margin-right 8}}]))
|
||||
[rn/view
|
||||
{:style {:flex-direction (if horizontal-description?
|
||||
:row
|
||||
:column)}}
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:style {:color text-color
|
||||
:line-height 21}}
|
||||
main-text]
|
||||
(when description
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (cond-> {:padding-right 4
|
||||
:color text-secondary-color
|
||||
:line-height 18}
|
||||
horizontal-description? (assoc :margin-left 4 :margin-top 2))}
|
||||
description])]])
|
||||
|
||||
(defn- mid-section-view
|
||||
[{:keys [horizontal-description? one-icon-align-left? type left-align?
|
||||
main-text right-icon main-text-icon-color left-icon on-press avatar theme]
|
||||
:as props}]
|
||||
(let [text-color (colors/theme-colors colors/neutral-95 colors/neutral-5 theme)
|
||||
text-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
component-instance [mid-section-comp (assoc props :text-secondary-color text-secondary-color)]]
|
||||
[rn/touchable-opacity {:on-press on-press}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(if left-align?
|
||||
align-left
|
||||
centrify-style)
|
||||
{:flex 1
|
||||
:margin-left 4
|
||||
:text-align-vertical :center})}
|
||||
(case type
|
||||
:text-only [text/text
|
||||
{:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:style {:color text-color}}
|
||||
main-text]
|
||||
:user-avatar [rn/view {:style (assoc centrify-style :flex-direction :row)}
|
||||
[user-avatar/user-avatar avatar]
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:style {:padding-horizontal 4
|
||||
:color text-color}}
|
||||
main-text]]
|
||||
:text-with-two-icons [rn/view {:style (assoc centrify-style :flex-direction :row)}
|
||||
[icons/icon left-icon
|
||||
(icon-props main-text-icon-color :big)]
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:style {:padding-horizontal 4
|
||||
:color text-color}}
|
||||
main-text]
|
||||
[icons/icon right-icon
|
||||
(icon-props main-text-icon-color :big)]]
|
||||
:text-with-one-icon [rn/view {:style {:flex-direction :row}}
|
||||
(if one-icon-align-left?
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:align-items :center}}
|
||||
(when horizontal-description?
|
||||
[icons/icon left-icon
|
||||
(icon-props main-text-icon-color :big)])
|
||||
component-instance]
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:align-items :center}}
|
||||
component-instance
|
||||
(when horizontal-description?
|
||||
[icons/icon left-icon
|
||||
(icon-props main-text-icon-color :big)])])]
|
||||
:text-with-description component-instance)]]))
|
||||
|
||||
(defn- right-section-view
|
||||
[right-section-buttons]
|
||||
[rn/view
|
||||
{:style (assoc centrify-style
|
||||
:flex-direction :row
|
||||
:justify-content :flex-end)}
|
||||
(let [last-icon-index (-> right-section-buttons count dec)]
|
||||
(map-indexed (fn [index
|
||||
{:keys [icon on-press type style icon-background
|
||||
accessibility-label label]
|
||||
:or {type :grey}}]
|
||||
^{:key index}
|
||||
[rn/view
|
||||
(cond-> {:style (assoc style
|
||||
:margin-right
|
||||
(if (= index last-icon-index) 0 8))}
|
||||
accessibility-label (assoc :accessibility-label accessibility-label
|
||||
:accessible true))
|
||||
[button/button
|
||||
{:on-press on-press
|
||||
:icon-only? (not label)
|
||||
:type type
|
||||
:icon-left (when label icon)
|
||||
:size 32
|
||||
:background icon-background}
|
||||
(if label label icon)]])
|
||||
right-section-buttons))])
|
||||
|
||||
(defn- page-nav-internal
|
||||
"[page-nav opts]
|
||||
opts
|
||||
{ :one-icon-align-left? true/false
|
||||
:horizontal-description? true/false
|
||||
:align-mid? true/false
|
||||
:page-nav-color color
|
||||
:page-nav-background-uri image-uri
|
||||
:mid-section
|
||||
{:type one-of :text-only :text-with-two-icons :text-with-one-icon :text-with-description :user-avatar
|
||||
:icon icon
|
||||
:main-text string
|
||||
:left-icon icon
|
||||
:right-icon icon
|
||||
:description string
|
||||
:description-color color
|
||||
:description-icon icon
|
||||
:description-user-icon icon
|
||||
:description-img a render prop which will be used in place of :description-user-icon
|
||||
:main-text-icon-color color
|
||||
}
|
||||
:left-section
|
||||
{:type button-type
|
||||
:on-press event
|
||||
:icon icon
|
||||
}
|
||||
:right-section-buttons vector of
|
||||
{:type button-type
|
||||
:on-press event
|
||||
:icon icon
|
||||
}
|
||||
:theme :light or :dark
|
||||
}
|
||||
"
|
||||
[{:keys [container-style one-icon-align-left? horizontal-description?
|
||||
align-mid? page-nav-color page-nav-background-uri
|
||||
mid-section
|
||||
left-section
|
||||
right-section-buttons
|
||||
theme]}]
|
||||
(let [put-middle-section-on-left? (or align-mid?
|
||||
(> (count right-section-buttons) 1))
|
||||
mid-section-props
|
||||
{:type (:type mid-section)
|
||||
:theme theme
|
||||
:horizontal-description? horizontal-description?
|
||||
:description-img (:description-img mid-section)
|
||||
:main-text (:main-text mid-section)
|
||||
:main-text-icon-color (:main-text-icon-color mid-section)
|
||||
:one-icon-align-left? one-icon-align-left?
|
||||
:right-icon (:right-icon mid-section)
|
||||
:icon (:icon mid-section)
|
||||
:left-icon (:left-icon mid-section)
|
||||
:avatar (:avatar mid-section)}]
|
||||
[rn/view
|
||||
{:style (cond-> (merge {:display :flex
|
||||
:flex-direction :row
|
||||
;; iPhone 11 Pro's height in Figma divided by Component height 56/1125
|
||||
:align-items :center
|
||||
:padding-horizontal 20
|
||||
:height 56
|
||||
:justify-content :space-between}
|
||||
container-style)
|
||||
page-nav-background-uri (assoc :background-color page-nav-color)
|
||||
page-nav-color (assoc :background page-nav-background-uri))}
|
||||
[rn/view
|
||||
{:style {:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center}}
|
||||
(when left-section
|
||||
[left-section-view left-section put-middle-section-on-left?])
|
||||
(when mid-section
|
||||
(cond
|
||||
put-middle-section-on-left?
|
||||
[mid-section-view
|
||||
(assoc mid-section-props
|
||||
:left-align? true
|
||||
:description (:description mid-section)
|
||||
:description-color (:description-color mid-section)
|
||||
:description-icon (:description-icon mid-section)
|
||||
:align-mid? align-mid?
|
||||
:description-user-icon (:description-user-icon mid-section))]
|
||||
|
||||
(not put-middle-section-on-left?)
|
||||
[mid-section-view mid-section-props]))]
|
||||
[right-section-view right-section-buttons]]))
|
||||
|
||||
(def page-nav (theme/with-theme page-nav-internal))
|
||||
@@ -0,0 +1,90 @@
|
||||
(ns quo2.components.navigation.page-nav.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn container
|
||||
[margin-top]
|
||||
{:margin-top margin-top
|
||||
:padding-horizontal 20
|
||||
:padding-vertical 12
|
||||
:height 56
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center})
|
||||
|
||||
(defn center-content-container
|
||||
[centered?]
|
||||
{:flex 1
|
||||
:margin-horizontal 12
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content (if centered? :center :flex-start)})
|
||||
|
||||
(def account-switcher-placeholder
|
||||
{:width 32
|
||||
:height 32
|
||||
:border-radius 10
|
||||
:background-color (colors/custom-color :purple 50)})
|
||||
|
||||
(def right-actions-container
|
||||
{:flex-direction :row})
|
||||
|
||||
(def right-actions-spacing
|
||||
{:width 12})
|
||||
|
||||
(def right-content-min-size
|
||||
{:min-width 32 :min-height 32})
|
||||
|
||||
(def token-logo
|
||||
{:width 16 :height 16})
|
||||
|
||||
(def token-name
|
||||
{:margin-left 4
|
||||
:text-align-vertical :center})
|
||||
|
||||
(defn token-abbreviation
|
||||
[theme background]
|
||||
(let [color (case background
|
||||
:photo nil
|
||||
:blur (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-40 theme)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))]
|
||||
{:margin-left 4
|
||||
:color color
|
||||
:text-align-vertical :center}))
|
||||
|
||||
(def channel-emoji
|
||||
{:width 20 :height 20})
|
||||
|
||||
(defn channel-icon-color
|
||||
[theme background]
|
||||
(case background
|
||||
:photo nil
|
||||
:blur (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
|
||||
|
||||
(def channel-name
|
||||
{:margin-horizontal 4
|
||||
:text-align-vertical :center})
|
||||
|
||||
(def group-avatar-picture
|
||||
{:margin-right 8})
|
||||
|
||||
(def title-description-container
|
||||
{:height 32
|
||||
:justify-content :center})
|
||||
|
||||
(def title-description-title
|
||||
{:text-align-vertical :center})
|
||||
|
||||
(defn title-description-description
|
||||
[theme background]
|
||||
(let [color (case background
|
||||
:photo (colors/theme-colors colors/neutral-80-opa-80-blur colors/white-opa-70 theme)
|
||||
:blur (colors/theme-colors colors/neutral-80-opa-50 colors/white-opa-40 theme)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))]
|
||||
{:color color
|
||||
:text-align-vertical :center}))
|
||||
|
||||
(def community-network-logo
|
||||
{:width 24
|
||||
:height 24
|
||||
:margin-right 6})
|
||||
@@ -0,0 +1,284 @@
|
||||
(ns quo2.components.navigation.page-nav.view
|
||||
(:require [quo2.components.avatars.group-avatar.view :as group-avatar]
|
||||
[quo2.components.buttons.button.view :as button]
|
||||
[quo2.components.dropdowns.dropdown :as dropdown]
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.navigation.page-nav.style :as style]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def ^:private button-type
|
||||
{:white :grey
|
||||
:neutral-5 :dark-grey
|
||||
:neutral-90 :grey
|
||||
:neutral-95 :dark-grey
|
||||
:neutral-100 :black
|
||||
:photo :grey
|
||||
:blur :grey})
|
||||
|
||||
(defn- page-nav-base
|
||||
[{:keys [margin-top background on-press accessibility-label icon-name]
|
||||
:or {background :white}}
|
||||
& children]
|
||||
(into [rn/view {:style (style/container margin-top)}
|
||||
(when icon-name
|
||||
[button/button
|
||||
{:type (button-type background)
|
||||
:icon-only? true
|
||||
:size 32
|
||||
:on-press on-press
|
||||
:accessibility-label accessibility-label}
|
||||
icon-name])]
|
||||
children))
|
||||
|
||||
(defn- right-section-spacing [] [rn/view {:style style/right-actions-spacing}])
|
||||
|
||||
(defn- add-right-buttons-xf
|
||||
[max-actions background]
|
||||
(comp (filter map?)
|
||||
(take max-actions)
|
||||
(map (fn [{:keys [icon-name label] :as button-props}]
|
||||
[button/button
|
||||
(assoc button-props
|
||||
:type (button-type background)
|
||||
:icon-only? icon-name
|
||||
:size 32
|
||||
:accessible true
|
||||
:background (when (#{:photo :blur} background) background))
|
||||
(or label icon-name)]))
|
||||
(interpose [right-section-spacing])))
|
||||
|
||||
(defn- right-content
|
||||
[{:keys [background content max-actions min-size? support-account-switcher?]
|
||||
:or {support-account-switcher? true}}]
|
||||
[rn/view (when min-size? {:style style/right-content-min-size})
|
||||
(cond
|
||||
;; TODO: use account-switcher when available (issue #16456)
|
||||
(and support-account-switcher? (= content :account-switcher))
|
||||
[rn/view {:style style/account-switcher-placeholder}]
|
||||
|
||||
(coll? content)
|
||||
(into [rn/view {:style style/right-actions-container}]
|
||||
(add-right-buttons-xf max-actions background)
|
||||
content)
|
||||
|
||||
:else
|
||||
nil)])
|
||||
|
||||
(defn- title-center
|
||||
[{:keys [centered? title]}]
|
||||
[rn/view {:style (style/center-content-container centered?)}
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-1
|
||||
:number-of-lines 1}
|
||||
title]])
|
||||
|
||||
(defn- dropdown-center
|
||||
[{:keys [theme background dropdown-on-change dropdown-selected? dropdown-text]}]
|
||||
(let [dropdown-type (cond
|
||||
(= background :photo) :grey
|
||||
(and (= theme :dark) (= background :blur)) :grey
|
||||
:else :ghost)]
|
||||
[rn/view {:style (style/center-content-container true)}
|
||||
[dropdown/dropdown
|
||||
{:type dropdown-type
|
||||
:size 32
|
||||
:on-change dropdown-on-change
|
||||
:selected dropdown-selected?}
|
||||
dropdown-text]]))
|
||||
|
||||
(defn- token-center
|
||||
[{:keys [theme background token-logo token-name token-abbreviation]}]
|
||||
[rn/view {:style (style/center-content-container false)}
|
||||
[rn/image {:style style/token-logo :source token-logo}]
|
||||
[text/text
|
||||
{:style style/token-name
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1
|
||||
:number-of-lines 1}
|
||||
token-name]
|
||||
[text/text
|
||||
{:style (style/token-abbreviation theme background)
|
||||
:weight :medium
|
||||
:size :paragraph-2
|
||||
:number-of-lines 1}
|
||||
token-abbreviation]])
|
||||
|
||||
(defn- channel-center
|
||||
[{:keys [theme background channel-emoji channel-name channel-icon]}]
|
||||
[rn/view {:style (style/center-content-container false)}
|
||||
[rn/text {:style style/channel-emoji}
|
||||
channel-emoji]
|
||||
[text/text
|
||||
{:style style/channel-name
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1
|
||||
:number-of-lines 1}
|
||||
(str "# " channel-name)]
|
||||
[icons/icon channel-icon {:size 16 :color (style/channel-icon-color theme background)}]])
|
||||
|
||||
(defn- title-description-center
|
||||
[{:keys [background theme picture title description]}]
|
||||
[rn/view {:style (style/center-content-container false)}
|
||||
(when picture
|
||||
[rn/view {:style style/group-avatar-picture}
|
||||
[group-avatar/view {:picture picture :size 28}]])
|
||||
[rn/view {:style style/title-description-container}
|
||||
[text/text
|
||||
{:style style/title-description-title
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1
|
||||
:number-of-lines 1}
|
||||
title]
|
||||
[text/text
|
||||
{:style (style/title-description-description theme background)
|
||||
:weight :medium
|
||||
:size :paragraph-2
|
||||
:number-of-lines 1}
|
||||
description]]])
|
||||
|
||||
(defn- community-network-center
|
||||
[{:keys [type community-logo network-logo community-name network-name]}]
|
||||
(let [community? (= type :community)
|
||||
shown-logo (if community? community-logo network-logo)
|
||||
shown-name (if community? community-name network-name)]
|
||||
[rn/view {:style (style/center-content-container false)}
|
||||
[rn/image
|
||||
{:style style/community-network-logo
|
||||
:source shown-logo}]
|
||||
[text/text
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-1
|
||||
:number-of-lines 1}
|
||||
shown-name]]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [type right-side background text-align]
|
||||
:or {type :no-title
|
||||
text-align :center
|
||||
right-side :none
|
||||
background :white}
|
||||
:as props}]
|
||||
(case type
|
||||
:no-title
|
||||
[page-nav-base props
|
||||
[right-content {:background background :content right-side :max-actions 3}]]
|
||||
|
||||
:title
|
||||
(let [centered? (= text-align :center)]
|
||||
[page-nav-base props
|
||||
[title-center (assoc props :centered? centered?)]
|
||||
[right-content
|
||||
{:background background
|
||||
:content right-side
|
||||
:max-actions (if centered? 1 3)
|
||||
:min-size? centered?}]])
|
||||
|
||||
:dropdown
|
||||
[page-nav-base props
|
||||
[dropdown-center props]
|
||||
[rn/view {:style style/right-actions-container}
|
||||
(let [{button-icon :icon-name :as button-props} (first right-side)]
|
||||
[button/button
|
||||
(assoc button-props
|
||||
:type (button-type background)
|
||||
:icon-only? true
|
||||
:size 32
|
||||
:accessible true)
|
||||
button-icon])]]
|
||||
|
||||
:token
|
||||
[page-nav-base props
|
||||
[token-center props]
|
||||
[right-content {:background background :content right-side :max-actions 3}]]
|
||||
|
||||
:channel
|
||||
[page-nav-base props
|
||||
[channel-center props]
|
||||
[right-content
|
||||
{:background background
|
||||
:content right-side
|
||||
:max-actions 3
|
||||
:support-account-switcher? false}]]
|
||||
|
||||
:title-description
|
||||
[page-nav-base props
|
||||
[title-description-center props]
|
||||
[right-content
|
||||
{:background background
|
||||
:content right-side
|
||||
:max-actions 2
|
||||
:support-account-switcher? false}]]
|
||||
|
||||
:wallet-networks
|
||||
[page-nav-base props
|
||||
;; TODO: use wallet-networks when available (issue #16946)
|
||||
[rn/view {:style (style/center-content-container true)}
|
||||
[text/text
|
||||
{:weight :regular
|
||||
:size :paragraph-1
|
||||
:number-of-lines 1}
|
||||
"NETWORK DROPDOWN"]]
|
||||
[right-content
|
||||
{:background background
|
||||
:content right-side
|
||||
:max-actions 1
|
||||
:min-size? true}]]
|
||||
|
||||
(:community :network)
|
||||
[page-nav-base props
|
||||
[community-network-center props]
|
||||
[right-content
|
||||
{:background background
|
||||
:content right-side
|
||||
:max-actions 3
|
||||
:support-account-switcher? false}]]
|
||||
|
||||
nil))
|
||||
|
||||
(def page-nav
|
||||
"Props:
|
||||
- type: defaults to `:no-title`.
|
||||
- background:
|
||||
`:white`, `:neutral-5`, `:neutral-90`, `:neutral-95`, `:neutral-100`, `:photo` or `:blur`
|
||||
- accessibility-label
|
||||
- on-press: callback for left button
|
||||
- icon-name: icon for left button
|
||||
- right-side (optional):
|
||||
- The `:account-switcher` keyword
|
||||
- vector of maps to render buttons, e.g.:
|
||||
{:icon-name :i/my-icon
|
||||
:on-press (fn callback [] nil)
|
||||
:accessibility-label \"an optional label\"}
|
||||
|
||||
Depending on the `type` selected, different properties are accepted:
|
||||
`:title`
|
||||
- title
|
||||
- text-align: `:center` or `:left`
|
||||
`:dropdown`
|
||||
- dropdown-on-change: a callback
|
||||
- dropdown-selected?: a boolean
|
||||
- dropdown-text
|
||||
`:token`
|
||||
- token-logo: a valid rn/image `:source` value
|
||||
- token-name: string
|
||||
- token-abbreviation: string
|
||||
`:channel`
|
||||
- channel-emoji: an emoji in a string
|
||||
- channel-name
|
||||
- channel-icon: an icon keyword (:i/members, :i/lock, etc.)
|
||||
`:title-description`
|
||||
- title
|
||||
- description
|
||||
- picture: a valid rn/image `:source` value
|
||||
`:wallet-network`
|
||||
(Not implemented yet)
|
||||
`:community`
|
||||
- community-name
|
||||
- community-logo: a valid rn/image `:source` value
|
||||
`:network`
|
||||
- network-name
|
||||
- network-logo a valid rn/image `:source` value"
|
||||
(theme/with-theme view-internal))
|
||||
@@ -28,7 +28,7 @@
|
||||
(defn message-container
|
||||
[attachment]
|
||||
{:border-radius 12
|
||||
:margin-top 12
|
||||
:margin-top 10
|
||||
:padding-horizontal 12
|
||||
:padding-vertical (if (#{:photo :gif} attachment) 12 8)
|
||||
:background-color colors/white-opa-5})
|
||||
@@ -39,11 +39,14 @@
|
||||
|
||||
(defn title
|
||||
[]
|
||||
{:color colors/white})
|
||||
{:flex-shrink 1
|
||||
:color colors/white})
|
||||
|
||||
(def timestamp
|
||||
{:text-transform :none
|
||||
:margin-left 8
|
||||
:margin-top 4
|
||||
:flex-shrink 0
|
||||
:color colors/neutral-40})
|
||||
|
||||
(defn unread-dot
|
||||
@@ -65,10 +68,8 @@
|
||||
:flex-wrap :wrap})
|
||||
|
||||
(def top-section-container
|
||||
{:align-items :center
|
||||
:flex-direction :row})
|
||||
{:flex-direction :row})
|
||||
|
||||
(def title-container
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center})
|
||||
:flex-direction :row})
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
(defn- activity-context
|
||||
[context replying?]
|
||||
(let [first-line-offset (if replying? 4 0)
|
||||
gap-between-lines 4]
|
||||
gap-between-lines 5]
|
||||
(into [rn/view {:style (assoc style/context-container :margin-top first-line-offset)}]
|
||||
(mapcat
|
||||
(fn [detail]
|
||||
@@ -130,6 +130,10 @@
|
||||
(assoc :size size)
|
||||
(assoc :type subtype)
|
||||
(assoc :disabled? (and replying? disable-when (disable-when @reply-input)))
|
||||
(assoc :inner-style
|
||||
{:justify-content :center
|
||||
:padding-bottom 0
|
||||
:padding-top 0})
|
||||
(update :container-style merge common-style {:margin-right 8}))
|
||||
label]))
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
(ns quo2.components.profile.showcase-nav.component-spec
|
||||
(:require [quo2.components.profile.showcase-nav.view :as view]
|
||||
[reagent.core :as reagent]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(def nav-data
|
||||
[{:icon :i/recent
|
||||
:id :recent}
|
||||
{:icon :i/profile
|
||||
:id :profile}
|
||||
{:icon :i/communities
|
||||
:id :communities}
|
||||
{:icon :i/wallet
|
||||
:id :wallet}
|
||||
{:icon :i/nft
|
||||
:id :nft}
|
||||
{:icon :i/token
|
||||
:id :token}])
|
||||
|
||||
(h/describe "Profile - Showcase nav"
|
||||
(h/test "default render"
|
||||
(h/render [view/view {:data nav-data}])
|
||||
(-> (count (h/query-all-by-label-text :showcase-nav-item))
|
||||
(h/expect)
|
||||
(.toEqual (count nav-data))))
|
||||
|
||||
(h/test "on press button"
|
||||
(let [event (h/mock-fn)]
|
||||
(h/render [view/view
|
||||
{:data nav-data
|
||||
:on-press #(event)}])
|
||||
(h/fire-event :press (get (h/get-all-by-label-text :showcase-nav-item) 0))
|
||||
(-> (h/expect event)
|
||||
(.toHaveBeenCalled))))
|
||||
|
||||
(h/test "active id updated"
|
||||
(let [active-id (reagent/atom :recent)]
|
||||
(h/render [view/view
|
||||
{:data nav-data
|
||||
:on-press #(reset! active-id %)}])
|
||||
(h/fire-event :press (get (h/get-all-by-label-text :showcase-nav-item) 3))
|
||||
(-> (h/expect @active-id)
|
||||
(.toStrictEqual :wallet)))))
|
||||
@@ -0,0 +1,17 @@
|
||||
(ns quo2.components.profile.showcase-nav.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def root-container
|
||||
{:height 56})
|
||||
|
||||
(defn container
|
||||
[state theme]
|
||||
{:padding-top 12
|
||||
:padding-left 20
|
||||
:padding-bottom 12
|
||||
:background-color (case state
|
||||
:default (colors/theme-colors colors/white colors/neutral-95 theme)
|
||||
:transparent)})
|
||||
|
||||
(def button-container
|
||||
{:margin-right 8})
|
||||
@@ -0,0 +1,40 @@
|
||||
(ns quo2.components.profile.showcase-nav.view
|
||||
(:require [quo2.components.buttons.button.view :as button]
|
||||
[quo2.components.profile.showcase-nav.style :as style]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- render-button
|
||||
[{:keys [icon id]} _ _ {:keys [state on-press active-id]}]
|
||||
(let [active? (= id active-id)
|
||||
button-type (if active? :grey :ghost)
|
||||
scroll-state? (= state :scroll)]
|
||||
[button/button
|
||||
{:accessibility-label :showcase-nav-item
|
||||
:size 32
|
||||
:type button-type
|
||||
:background (when scroll-state? :blur)
|
||||
:icon-only? true
|
||||
:on-press (fn []
|
||||
(when on-press
|
||||
(on-press id)))
|
||||
:container-style style/button-container}
|
||||
icon]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [theme container-style default-active state data on-press active-id]}]
|
||||
[rn/view
|
||||
{:style style/root-container
|
||||
:accessibility-label :showcase-nav}
|
||||
[rn/flat-list
|
||||
{:data data
|
||||
:key-fn str
|
||||
:horizontal true
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:content-container-style (merge (style/container state theme) container-style)
|
||||
:render-fn render-button
|
||||
:render-data {:state state
|
||||
:on-press on-press
|
||||
:active-id (or active-id default-active)}}]])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -38,7 +38,7 @@
|
||||
[customization-color pressed? theme]
|
||||
(when pressed?
|
||||
(if customization-color
|
||||
(colors/custom-color-by-theme customization-color 50 60)
|
||||
(colors/custom-color (or customization-color :blue) 60)
|
||||
(colors/theme-colors colors/primary-50 colors/primary-60 theme))))
|
||||
|
||||
(defn container-outer
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
(ns quo2.components.settings.data-item.component-spec
|
||||
(:require [test-helpers.component :as h]
|
||||
[quo2.core :as quo]))
|
||||
|
||||
(h/describe
|
||||
"date item tests"
|
||||
(h/test "title is visible"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? false
|
||||
:card? true
|
||||
:label :none
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/is-truthy (h/get-by-text "Label")))
|
||||
|
||||
(h/test "data item renders correctly if card? is false"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? false
|
||||
:card? false
|
||||
:label :none
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/has-style (h/query-by-label-text :data-item)
|
||||
{:borderWidth nil}))
|
||||
|
||||
(h/test "data item renders correctly if card? is true and size is small"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? false
|
||||
:card? true
|
||||
:label :none
|
||||
:status :default
|
||||
:size :small
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/has-style (h/query-by-label-text :data-item)
|
||||
{:borderWidth nil}))
|
||||
|
||||
(h/test "data item renders correctly if card? is true"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? false
|
||||
:card? true
|
||||
:label :none
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/has-style (h/query-by-label-text :data-item)
|
||||
{:borderWidth 1}))
|
||||
|
||||
(h/test "subtitle is visible when status is not loading"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? false
|
||||
:card? true
|
||||
:label :none
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/is-truthy (h/get-by-text "Description")))
|
||||
|
||||
(h/test "right icon is not visible when icon-right? is false"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? false
|
||||
:card? true
|
||||
:label :none
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/is-falsy (h/query-by-label-text :icon-right)))
|
||||
|
||||
(h/test "right icon is visible when icon-right? is true"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? true
|
||||
:card? true
|
||||
:label :none
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/is-truthy (h/query-by-label-text :icon-right)))
|
||||
|
||||
(h/test "description icon is visible when description is icon"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :icon
|
||||
:icon-right? true
|
||||
:card? true
|
||||
:label :preview
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/is-truthy (h/query-by-label-text :description-icon)))
|
||||
|
||||
(h/test "description image is visible when description is network"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :network
|
||||
:icon-right? true
|
||||
:card? true
|
||||
:label :preview
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/is-truthy (h/query-by-label-text :description-image)))
|
||||
|
||||
(h/test "description emoji is visible when description is account"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? true
|
||||
:card? true
|
||||
:label :preview
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))))
|
||||
@@ -0,0 +1,71 @@
|
||||
(ns quo2.components.settings.data-item.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn container
|
||||
[size card? blur? theme]
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-vertical (when (= size :default) 8)
|
||||
:padding-horizontal (when (= size :default) 12)
|
||||
:border-radius 16
|
||||
:border-width (when (and card? (not= size :small)) 1)
|
||||
:border-color (if blur?
|
||||
colors/white-opa-10
|
||||
(colors/theme-colors colors/neutral-10
|
||||
colors/neutral-80
|
||||
theme))})
|
||||
|
||||
(defn loading-container
|
||||
[size blur? theme]
|
||||
{:width (if (= size :default) 132 72)
|
||||
:height (if (= size :default) 16 10)
|
||||
:background-color (if blur?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/neutral-5
|
||||
colors/neutral-90
|
||||
theme))
|
||||
:border-radius (if (= size :default) 6 3)
|
||||
:margin-vertical (if (= size :default) 4 3)})
|
||||
|
||||
(def subtitle-container
|
||||
{:flex-direction :row
|
||||
:margin-bottom 1})
|
||||
|
||||
(def right-container
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(defn subtitle-icon-container
|
||||
[description]
|
||||
{:margin-right (when (not= :default description) 4)
|
||||
:justify-content :center})
|
||||
|
||||
(defn title
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/neutral-50
|
||||
colors/neutral-40
|
||||
theme)
|
||||
:margin-right 4})
|
||||
|
||||
(def title-container
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(def image
|
||||
{:width 16
|
||||
:height 16})
|
||||
|
||||
(defn description
|
||||
[blur? theme]
|
||||
{:color (if blur?
|
||||
colors/white
|
||||
(colors/theme-colors colors/neutral-100
|
||||
colors/white
|
||||
theme))})
|
||||
(defn right-icon
|
||||
[label]
|
||||
{:margin-left (if (or (= label :graph) (= label :none)) 12 8)})
|
||||
|
||||
(def left-side
|
||||
{:flex 1})
|
||||
@@ -0,0 +1,126 @@
|
||||
(ns quo2.components.settings.data-item.view
|
||||
(:require [quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[quo2.components.settings.data-item.style :as style]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.common.not-implemented.view :as not-implemented]
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.list-items.preview-list.view :as preview-list]
|
||||
[quo2.foundations.resources :as quo.resources]
|
||||
[quo2.components.avatars.account-avatar.view :as account-avatar]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn- left-loading
|
||||
[{:keys [size blur? theme]}]
|
||||
[rn/view {:style (style/loading-container size blur? theme)}])
|
||||
|
||||
(defn- left-subtitle
|
||||
[{:keys [theme size description icon icon-color blur? subtitle customization-color emoji]}]
|
||||
[rn/view {:style style/subtitle-container}
|
||||
(when (not= :small size)
|
||||
[rn/view {:style (style/subtitle-icon-container description)}
|
||||
(case description
|
||||
:icon [icons/icon icon
|
||||
{:accessibility-label :description-icon
|
||||
:size 16
|
||||
:color icon-color}]
|
||||
:account [account-avatar/view
|
||||
{:customization-color customization-color
|
||||
:size 16
|
||||
:emoji emoji
|
||||
:type :default}]
|
||||
:network [rn/image
|
||||
{:accessibility-label :description-image
|
||||
:source (quo.resources/tokens :eth)
|
||||
:style style/image}]
|
||||
nil)])
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (style/description blur? theme)}
|
||||
subtitle]])
|
||||
|
||||
(defn- left-title
|
||||
[{:keys [title label size theme]}]
|
||||
[rn/view {:style style/title-container}
|
||||
[text/text
|
||||
{:weight :regular
|
||||
:size :paragraph-2
|
||||
:style (style/title theme)}
|
||||
title]
|
||||
(when (and (= :graph label) (not= :small size))
|
||||
[text/text
|
||||
{:weight :regular
|
||||
:size :label
|
||||
:style (style/title theme)}
|
||||
(i18n/label :t/days)])])
|
||||
|
||||
(defn- left-side
|
||||
[{:keys [theme title status size blur? description icon subtitle label icon-color customization-color
|
||||
emoji]}]
|
||||
[rn/view {:style style/left-side}
|
||||
[left-title
|
||||
{:title title
|
||||
:label label
|
||||
:size size
|
||||
:theme theme}]
|
||||
(if (= status :loading)
|
||||
[left-loading
|
||||
{:size size
|
||||
:blur? blur?
|
||||
:theme theme}]
|
||||
[left-subtitle
|
||||
{:theme theme
|
||||
:size size
|
||||
:description description
|
||||
:icon icon
|
||||
:icon-color icon-color
|
||||
:blur? blur?
|
||||
:subtitle subtitle
|
||||
:customization-color customization-color
|
||||
:emoji emoji}])])
|
||||
|
||||
(defn- right-side
|
||||
[{:keys [label icon-right? icon-color communities-list]}]
|
||||
[rn/view {:style style/right-container}
|
||||
(case label
|
||||
:preview [preview-list/view
|
||||
{:type :communities
|
||||
:number 3
|
||||
:size :size/s-24}
|
||||
communities-list]
|
||||
:graph [text/text "graph"]
|
||||
:none nil
|
||||
nil)
|
||||
(when icon-right?
|
||||
[rn/view {:style (style/right-icon label)}
|
||||
[icons/icon
|
||||
(if (= :none label)
|
||||
:i/copy
|
||||
:i/chevron-right)
|
||||
{:accessibility-label :icon-right
|
||||
:color icon-color
|
||||
:size 20}]])])
|
||||
|
||||
(def view-internal
|
||||
(fn [{:keys [blur? card? icon-right? label status size theme on-press communities-list] :as props}]
|
||||
(let [icon-color (if (or blur? (= :dark theme))
|
||||
colors/neutral-40
|
||||
colors/neutral-50)]
|
||||
(if (= :graph label)
|
||||
[not-implemented/view {:blur? blur?}]
|
||||
[rn/pressable
|
||||
{:accessibility-label :data-item
|
||||
:disabled (not icon-right?)
|
||||
:on-press on-press
|
||||
:style (style/container size card? blur? theme)}
|
||||
[left-side props]
|
||||
(when (and (= :default status) (not= :small size))
|
||||
[right-side
|
||||
{:label label
|
||||
:icon-right? icon-right?
|
||||
:icon-color icon-color
|
||||
:communities-list communities-list}])]))))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -1,31 +1,11 @@
|
||||
(ns quo2.components.tags.context-tag.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn base-tag
|
||||
[override-theme blur?]
|
||||
{:border-radius 100
|
||||
:padding-vertical 3
|
||||
:flex-direction :row
|
||||
:padding-right 8
|
||||
:padding-left 8
|
||||
:background-color (if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 override-theme)
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-90 override-theme))})
|
||||
|
||||
(defn context-tag-icon-color
|
||||
[blur?]
|
||||
[theme blur?]
|
||||
(if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40)))
|
||||
|
||||
(def context-tag-text-container
|
||||
{:align-items :center
|
||||
:margin-left 4
|
||||
:flex-direction :row})
|
||||
|
||||
(def audio-tag-container
|
||||
{:padding-left 2
|
||||
:padding-vertical 2})
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
|
||||
|
||||
(def audio-tag-icon-container
|
||||
{:width 20
|
||||
@@ -37,21 +17,91 @@
|
||||
|
||||
(def audio-tag-icon-color colors/white)
|
||||
|
||||
(defn audio-tag-text-color
|
||||
[override-theme]
|
||||
(colors/theme-colors colors/neutral-100 colors/white override-theme))
|
||||
(defn container
|
||||
[{:keys [theme type size state blur? customization-color]}]
|
||||
(let [background-color (if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme)
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-90 theme))
|
||||
border-radius (cond
|
||||
(not (#{:account :collectible} type)) 16
|
||||
(= size 24) 8
|
||||
:else 10)
|
||||
border-color (colors/theme-colors
|
||||
(colors/custom-color customization-color 50)
|
||||
(colors/custom-color customization-color 60)
|
||||
theme)]
|
||||
(cond-> {:padding 2
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:height size
|
||||
:background-color background-color
|
||||
:border-radius border-radius}
|
||||
(= state :selected) (assoc :height (+ size 2)
|
||||
:border-color border-color
|
||||
:border-width 1))))
|
||||
|
||||
(def community-tag
|
||||
{:padding-vertical 2
|
||||
:padding-left 2})
|
||||
|
||||
(def community-tag-text-container
|
||||
{:margin-left 4
|
||||
:flex 1
|
||||
(defn tag-container
|
||||
[size]
|
||||
{:margin-right (if (= size 24) 6 10)
|
||||
:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(defn community-tag-text
|
||||
[override-theme]
|
||||
{:margin-left 2
|
||||
:color (colors/theme-colors colors/neutral-100 colors/white override-theme)})
|
||||
(defn tag-spacing
|
||||
[size]
|
||||
{:margin-left (if (= size 24) 4 8)})
|
||||
|
||||
(defn text
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white theme)})
|
||||
|
||||
(defn circle-logo
|
||||
[size]
|
||||
(if (= size 24)
|
||||
{:width 20 :height 20 :border-radius 10}
|
||||
{:width 28 :height 28 :border-radius 14}))
|
||||
|
||||
(defn rounded-logo
|
||||
[size]
|
||||
(if (= size 24)
|
||||
{:width 20
|
||||
:height 20
|
||||
:border-radius 6}
|
||||
{:width 28
|
||||
:height 28
|
||||
:border-radius 8}))
|
||||
|
||||
(defn address
|
||||
[size]
|
||||
(if (= size 24)
|
||||
{:margin-horizontal 6
|
||||
:margin-vertical 1
|
||||
:flex-direction :row
|
||||
:align-items :center}
|
||||
{:margin-horizontal 10
|
||||
:margin-vertical 3
|
||||
:flex-direction :row
|
||||
:align-items :center}))
|
||||
|
||||
(defn icon
|
||||
[size]
|
||||
(if (= size 24)
|
||||
{:margin-horizontal 6
|
||||
:margin-vertical 1
|
||||
:flex-direction :row
|
||||
:align-items :center}
|
||||
{:margin-left 8
|
||||
:margin-right 10
|
||||
:margin-vertical 3
|
||||
:flex-direction :row
|
||||
:align-items :center}))
|
||||
|
||||
(defn icon-spacing
|
||||
[size]
|
||||
(if (= size 24)
|
||||
{:margin-left 4}
|
||||
{:margin-left 2}))
|
||||
|
||||
(def audio
|
||||
{:margin-right 6
|
||||
:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
@@ -1,106 +1,215 @@
|
||||
(ns quo2.components.tags.context-tag.view
|
||||
(:require [quo2.components.avatars.group-avatar.view :as group-avatar]
|
||||
[quo2.components.avatars.user-avatar.style :as user-avatar.style]
|
||||
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo2.components.avatars.group-avatar.view :as group-avatar]
|
||||
[quo2.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.components.list-items.preview-list.view :as preview-list]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.tags.context-tag.style :as style]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn trim-public-key
|
||||
(defn- tag-skeleton
|
||||
[{:keys [theme size text] :or {size 24}} logo-component]
|
||||
[rn/view {:style (style/tag-container size)}
|
||||
logo-component
|
||||
[rn/view {:style (style/tag-spacing size)}
|
||||
[text/text
|
||||
{:style (style/text theme)
|
||||
:weight :medium
|
||||
:size (if (= size 24) :paragraph-2 :paragraph-1)}
|
||||
text]]])
|
||||
|
||||
(defn- communities-tag
|
||||
[{:keys [theme size community-logo community-name blur? channel? channel-name]}]
|
||||
(let [text-size (if (= size 24) :paragraph-2 :paragraph-1)
|
||||
icon-size (if (= size 24) 16 20)]
|
||||
[rn/view {:style (style/tag-container size)}
|
||||
[rn/image {:style (style/circle-logo size) :source community-logo}]
|
||||
[rn/view {:style (style/tag-spacing size)}
|
||||
[text/text
|
||||
{:style (style/text theme)
|
||||
:weight :medium
|
||||
:size text-size}
|
||||
community-name]]
|
||||
(when channel?
|
||||
[:<>
|
||||
[icons/icon :i/chevron-right
|
||||
{:color (style/context-tag-icon-color theme blur?)
|
||||
:size icon-size}]
|
||||
[text/text
|
||||
{:style (style/text theme)
|
||||
:weight :medium
|
||||
:size text-size}
|
||||
(str "# " channel-name)]])]))
|
||||
|
||||
(defn- trim-public-key
|
||||
[pk]
|
||||
(str (subs pk 0 6) "..." (subs pk (- (count pk) 3))))
|
||||
(str (subs pk 0 5) "..." (subs pk (- (count pk) 3))))
|
||||
|
||||
(defn base-tag
|
||||
[{:keys [override-theme style blur?]} & children]
|
||||
(into
|
||||
[rn/view {:style (merge (style/base-tag override-theme blur?) style)}]
|
||||
children))
|
||||
|
||||
(defn group-avatar-tag
|
||||
[label opts]
|
||||
[base-tag
|
||||
(-> opts
|
||||
(select-keys [:override-theme :style :blur?])
|
||||
(assoc-in [:style :padding-left] 3)
|
||||
(assoc-in [:style :padding-vertical] 2))
|
||||
[group-avatar/view opts]
|
||||
(defn- address-tag
|
||||
[{:keys [theme size address]}]
|
||||
[rn/view {:style (style/address size)}
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (:text-style opts)}
|
||||
(str " " label)]])
|
||||
{:style (style/text theme)
|
||||
:weight :monospace ;; TODO: fix this style (issue #17009)
|
||||
:size (if (= size 24) :paragraph-2 :paragraph-1)}
|
||||
(trim-public-key address)]])
|
||||
|
||||
(defn public-key-tag
|
||||
[params public-key]
|
||||
[base-tag params
|
||||
[text/text
|
||||
{:weight :monospace
|
||||
:size :paragraph-2}
|
||||
(trim-public-key public-key)]])
|
||||
(defn- icon-tag
|
||||
[{:keys [theme size icon blur? context]}]
|
||||
[rn/view {:style (style/icon size)}
|
||||
[icons/icon icon
|
||||
{:color (style/context-tag-icon-color theme blur?)
|
||||
:size (if (= size 24) 12 20)}]
|
||||
[rn/view {:style (style/icon-spacing size)}
|
||||
[text/text
|
||||
{:style (style/text theme)
|
||||
:weight :medium
|
||||
:size (if (= size 24) :paragraph-2 :paragraph-1)}
|
||||
context]]])
|
||||
|
||||
(defn context-tag
|
||||
[{:keys [text-style blur? no-avatar-placeholder? text-container-style ellipsize-text? ring?]
|
||||
:as props}
|
||||
photo
|
||||
name
|
||||
channel-name]
|
||||
(let [text-props {:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (assoc text-style :justify-content :center)
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :tail}
|
||||
empty-photo? (nil? photo)
|
||||
avatar-size :xxs
|
||||
avatar-outer-size (get-in user-avatar.style/sizes [avatar-size :outer])]
|
||||
[base-tag (update-in props [:style :padding-left] #(or % 3))
|
||||
(if (and empty-photo? no-avatar-placeholder?)
|
||||
[rn/view {:style {:width avatar-outer-size}}]
|
||||
[user-avatar/user-avatar
|
||||
{:full-name name
|
||||
:profile-picture photo
|
||||
:size avatar-size
|
||||
:ring? ring?
|
||||
:status-indicator? false}])
|
||||
[rn/view {:style (or text-container-style style/context-tag-text-container)}
|
||||
(if ellipsize-text?
|
||||
[rn/view {:style {:flex 1}}
|
||||
[text/text text-props name]]
|
||||
[text/text text-props (str " " name)])
|
||||
(when channel-name
|
||||
[:<>
|
||||
[icons/icon
|
||||
:i/chevron-right
|
||||
{:color (style/context-tag-icon-color blur?)
|
||||
:size 16}]
|
||||
[text/text text-props (str "# " channel-name)]])]]))
|
||||
(defn- view-internal
|
||||
[{:keys [theme type size state blur? customization-color profile-picture full-name users
|
||||
group-name token-logo amount token-name network-logo network-name networks
|
||||
account-name emoji collectible collectible-name collectible-number duration]
|
||||
:or {customization-color :blue
|
||||
type :default
|
||||
state :default}
|
||||
:as props}]
|
||||
[rn/view
|
||||
{:style (style/container {:theme theme
|
||||
:type type
|
||||
:size size
|
||||
:state state
|
||||
:blur? blur?
|
||||
:customization-color customization-color})}
|
||||
(case type
|
||||
:default
|
||||
[tag-skeleton {:theme theme :size size :text full-name}
|
||||
[user-avatar/user-avatar
|
||||
{:full-name full-name
|
||||
:profile-picture profile-picture
|
||||
:size (if (= size 24) :xxs 28)
|
||||
:status-indicator? false}]]
|
||||
|
||||
(defn user-avatar-tag
|
||||
[params username photo]
|
||||
[context-tag params photo username])
|
||||
:multiuser
|
||||
[preview-list/view {:type :user :size 20}
|
||||
users]
|
||||
|
||||
(defn audio-tag
|
||||
[duration params]
|
||||
[base-tag (merge {:style style/audio-tag-container} params)
|
||||
[rn/view {:style style/audio-tag-icon-container}
|
||||
[icons/icon
|
||||
:i/play
|
||||
{:color style/audio-tag-icon-color
|
||||
:size 12}]]
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style {:margin-left 4
|
||||
:color (style/audio-tag-text-color (:override-theme params))}}
|
||||
duration]])
|
||||
:multinetwork
|
||||
[preview-list/view {:type :network :size 20}
|
||||
(map #(hash-map :profile-picture %) networks)]
|
||||
|
||||
(defn community-tag
|
||||
[avatar community-name {:keys [override-theme] :as params}]
|
||||
[context-tag
|
||||
(merge {:style style/community-tag
|
||||
:text-style (style/community-tag-text override-theme)
|
||||
:text-container-style style/community-tag-text-container
|
||||
:ellipsize-text? true}
|
||||
params)
|
||||
avatar
|
||||
community-name])
|
||||
:audio
|
||||
[tag-skeleton {:theme theme :text (str duration)}
|
||||
[rn/view {:style style/audio-tag-icon-container}
|
||||
[icons/icon :i/play {:color style/audio-tag-icon-color :size 12}]]]
|
||||
|
||||
:group
|
||||
[tag-skeleton {:theme theme :size size :text group-name}
|
||||
[group-avatar/view
|
||||
{:icon-name :i/members
|
||||
:size (if (= size 24) :size/s-20 :size/s-28)
|
||||
:customization-color (colors/custom-color customization-color 50)}]]
|
||||
|
||||
(:channel :community)
|
||||
[communities-tag (assoc props :channel? (= type :channel))]
|
||||
|
||||
:token
|
||||
[tag-skeleton {:theme theme :size size :text (str amount " " token-name)}
|
||||
[rn/image {:style (style/circle-logo size) :source token-logo}]]
|
||||
|
||||
:network
|
||||
[tag-skeleton {:theme theme :size size :text network-name}
|
||||
[rn/image {:style (style/circle-logo size) :source network-logo}]]
|
||||
|
||||
:collectible
|
||||
[tag-skeleton
|
||||
{:theme theme
|
||||
:size size
|
||||
:text (str collectible-name " #" collectible-number)}
|
||||
[rn/image {:style (style/rounded-logo size) :source collectible}]]
|
||||
|
||||
:account
|
||||
[tag-skeleton {:theme theme :size size :text account-name}
|
||||
[account-avatar/view
|
||||
{:customization-color customization-color
|
||||
:emoji emoji
|
||||
:size (if (= size 24) 20 28)}]]
|
||||
|
||||
:address
|
||||
[address-tag props]
|
||||
|
||||
:icon
|
||||
[icon-tag props]
|
||||
|
||||
nil)])
|
||||
|
||||
(def view
|
||||
"Properties:
|
||||
type, state, blur? & customization-color
|
||||
|
||||
Depending on the `type` selected, different properties are accepted:
|
||||
- `:default` or `nil`:
|
||||
- size
|
||||
- profile-picture
|
||||
- full-name
|
||||
|
||||
- `:multiuser`:
|
||||
- users (vector of {:profile-picture pic, :full-name \"a name\"})
|
||||
|
||||
- `:group`
|
||||
- size
|
||||
- group-name
|
||||
|
||||
- `:community`
|
||||
- size
|
||||
- community-logo (valid rn/image :source value)
|
||||
- community-name
|
||||
|
||||
- `:channel`
|
||||
- size
|
||||
- community-logo (valid rn/image :source value)
|
||||
- community-name
|
||||
- channel-name
|
||||
|
||||
- `:token`
|
||||
- size
|
||||
- token-logo (valid rn/image :source value)
|
||||
- amount
|
||||
- token-name
|
||||
|
||||
- `:network`
|
||||
- size
|
||||
- network-logo (valid rn/image :source value)
|
||||
- network-name
|
||||
|
||||
- `:multinetworks`
|
||||
- networks (vector of {:network-logo pic, :network-name \"a name\"})
|
||||
|
||||
- `:account`
|
||||
- size
|
||||
- account-name
|
||||
- emoji (string containing an emoji)
|
||||
|
||||
- `:collectible`
|
||||
- size
|
||||
- collectible (valid rn/image :source value)
|
||||
- collectible-name
|
||||
- collectible-number
|
||||
|
||||
- `:address`
|
||||
- size
|
||||
- address (string)
|
||||
|
||||
- `:icon`
|
||||
- size
|
||||
- icon
|
||||
- context (string)
|
||||
|
||||
- `:audio`
|
||||
- duration (string)
|
||||
"
|
||||
(quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
(merge default-container-style
|
||||
{:min-height 24
|
||||
:padding-horizontal 8
|
||||
:padding-vertical 1}))
|
||||
:padding-vertical 3}))
|
||||
|
||||
(def large-container-style
|
||||
(merge default-container-style
|
||||
|
||||