Compare commits

..
Author SHA1 Message Date
Siddarth Kumar 75c68bcc60 list high level deps 2023-08-30 11:58:37 +05:30
Siddarth Kumar 8375eebe71 first attempt at listing dependencies 2023-08-30 10:46:01 +05:30
Omar Basem a4717ae5d0 Feat: wallet create account screen UI (#17118)
* feat: wallet create account
2023-08-29 21:06:36 +04:00
BalogunofAfrica a47998a7a0 fix: resolve activity centre design feedback (#17105) 2023-08-29 16:55:11 +01:00
Flavio Fraschetti 141bf5a333 FF/animate-loading-skeleton (#16865)
New Animated skeleton loader
2023-08-29 15:15:32 +01:00
Mohsen Ghafouri 231272603d [#16861] fix: resolve discover communities design feedbacks (#17128) 2023-08-28 18:09:42 +03:00
Ulises Manuel 255a3b9172 Add missing context tags variants & fix API (#16962)
Add icon-name to group avatar

Add missing context-tags variants and fix the API to match figma

Updates context-tag previous uses

Update use of group-avatar api
2023-08-28 04:37:43 -07:00
Ulises Manuel 6156bfc472 [#16963] Refactor page nav and fix its API (#17031)
* Refactor page-nav and fix API

* Update and fix page-nav in scroll-page component

* Update page-nav uses in quo-preview

* Update page-nav uses in syncing

* Update page-nav uses in communities

* Update page-nav uses in wallet

* Update page-nav uses in onboarding
2023-08-28 02:44:53 -07:00
mmilad75 6870000490 Implement Data Item component (#16960)
Implement Data Item component #16960
2023-08-26 18:33:10 +03:30
Omar Basem 0ef7dc34e4 fix: composer cursor hidden (#17099)
* fix: iOS cursor in chat
2023-08-25 21:33:40 +04:00
Mohamed Javid 0f7e98cbe2 Update "Preview list" component (#17051)
This commit updates the "Preview list" component to support the following types (according to Figma):
- collectibles
- dapps
- accounts
- network
- tokens

Additionally, imports the images for wallet networks and dApps.
---------

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-08-25 21:41:03 +05:30
Mohamed Javid f4d6f64a66 [Feature] Implement "Showcase nav" component (#17100)
This commit implements the "Showcase nav" component which is needed for emoji picker development.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-08-25 21:16:26 +05:30
Yevheniia Berdnyk a416267094 e2e: appium upgrade 2023-08-25 17:32:54 +03:00
Mohsen Ghafouri 2358eb195b [#16846] fix: resolve communities home design feedbacks (#17089)
* [#16846] fix: resolve communities home design feedbacks

* [#16846] fix: ios card shadow cutoff, re #17098
2023-08-25 17:26:53 +03:00
Yevheniia Berdnyk 21be0ed16c e2e: fixes 25.08 2023-08-25 15:59:51 +03:00
Parvesh Monu 89d1bd3f6a fix Jump to button not responding in chat after app returns from background (#17085) 2023-08-25 15:11:18 +05:30
Ajay Sivan 5148a3c748 Quo divider-label component refactor (#17035) 2023-08-24 12:29:26 -07:00
8701f3545d [#16864] Design review: messages home (#17050)
---------

Co-authored-by: Yevheniia Berdnyk <ie.berdnyk@gmail.com>
Co-authored-by: Churikova Tetiana <tatiana@status.im>
2023-08-24 14:30:47 +02:00
Mohsen Ghafouri 26eeb43569 [#16846] fix: resolve glow issue in communities home (#17097) 2023-08-24 15:05:31 +03:00
Jamie Caprani 4d7b1baace chore: add Alex to wallet team (#17024) 2023-08-24 13:11:22 +02:00
Yevheniia Berdnyk 89c2b1c818 e2e: nightly fixes 23.08 2023-08-24 04:31:27 +03:00
Icaro Motta 17df7a0d35 DRY up preview screens (#17095)
Migrate 47 out of ~90 preview screens to use the new capabilities found in quo-preview.preview.
2023-08-23 20:56:34 +00:00
erikseppanen 0552713143 Add quo2 dApp component (#17074) 2023-08-23 16:31:28 -04:00
Omar Basem 3223c71526 Feat: wallet empty account UI (#17077)
* feat: wallet account empty
2023-08-23 21:10:46 +04:00
Omar Basem 914604bbe4 UI Fix: wallet graph gradient (#17093)
* fix: wallet graph gradient
2023-08-23 20:19:19 +04:00
232 changed files with 4711 additions and 4101 deletions
+28
View File
@@ -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)
+1
View File
@@ -27,3 +27,4 @@ The team members for the initial wallet team are:
- @ulisesmac
- @erikseppanen
- @mmilad75
- @tumanov-alex
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 923 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

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))
+1 -1
View File
@@ -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}
+8 -7
View File
@@ -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))
+10 -6
View File
@@ -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
+13 -9
View File
@@ -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)})
+21 -14
View File
@@ -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))
+87 -37
View File
@@ -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})
+200 -91
View File
@@ -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))
+1 -1
View File
@@ -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

Some files were not shown because too many files have changed in this diff Show More