Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6239ab7b9d | ||
|
|
b84cc6c54e | ||
|
|
bc168cb94e | ||
|
|
294913c05b | ||
|
|
1b42c9d58e | ||
|
|
3c6e6e19c7 | ||
|
|
e7b8f188e1 | ||
|
|
b8d51a404e | ||
|
|
027f35906b | ||
|
|
d513690290 | ||
|
|
7101be0dac | ||
|
|
7d12f75977 | ||
|
|
35b2cc582d | ||
|
|
ca648e7153 | ||
|
|
e12a0d1596 | ||
|
|
7a8c0ab724 | ||
|
|
8f9d78d359 | ||
|
|
87a150cec1 | ||
|
|
98e2d8c6f1 | ||
|
|
43d72e0ba1 | ||
|
|
5bb309ca30 | ||
|
|
eaa089b78c | ||
|
|
9f12b4335c | ||
|
|
7bc98fcc44 | ||
|
|
da22f4a809 | ||
|
|
961150ac30 | ||
|
|
13e9db198f | ||
|
|
9eaee8864c | ||
|
|
bf8b31d22d | ||
|
|
713cf8bf79 | ||
|
|
79994e2dbf | ||
|
|
715fc13d46 | ||
|
|
1536ff8fa5 | ||
|
|
625510d6c9 | ||
|
|
8bab9f8f22 | ||
|
|
1cb16b4945 | ||
|
|
302c54b6c4 | ||
|
|
87574ad78a | ||
|
|
30175f5d8b | ||
|
|
5a3d886055 | ||
|
|
6550bc058d | ||
|
|
528df179d9 | ||
|
|
6b4b9d99f4 | ||
|
|
016b38f15c | ||
|
|
6274bd7cb6 | ||
|
|
2976830497 | ||
|
|
11c798817e | ||
|
|
79bf4bb8d5 | ||
|
|
ff1ae2f4aa | ||
|
|
2869edafdd | ||
|
|
d143b1d0e9 | ||
|
|
bf502175f7 | ||
|
|
d8680ecf29 | ||
|
|
24c4cd1509 | ||
|
|
86e16564fa | ||
|
|
d5c1ecc104 | ||
|
|
bc18e8aac5 | ||
|
|
5b495927ef | ||
|
|
2819c20400 | ||
|
|
18347b44fe | ||
|
|
bad9aa9e20 | ||
|
|
e5b6378e15 | ||
|
|
7ad378e9c8 | ||
|
|
f6ce63734c | ||
|
|
d9b54c47d3 | ||
|
|
109061a112 | ||
|
|
98085cd9c9 | ||
|
|
cccf5ed015 | ||
|
|
b0e45207df | ||
|
|
7b425c1a53 | ||
|
|
049e958992 | ||
|
|
3f433d6f19 | ||
|
|
da8ca36369 | ||
|
|
d26db932e8 | ||
|
|
ba859b163a | ||
|
|
08bca43f0f | ||
|
|
ad17c37dc1 | ||
|
|
07336edef6 | ||
|
|
7c73b7ea12 | ||
|
|
1a97731454 | ||
|
|
21807cb761 | ||
|
|
b8d01c8bb9 | ||
|
|
99c10519c3 | ||
|
|
81b8c7ca65 | ||
|
|
96ff8ab382 | ||
|
|
cf11743f87 | ||
|
|
162f02ea27 | ||
|
|
0ee0137c72 |
@@ -32,3 +32,4 @@ DELETE_MESSAGE_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
STICKERS_TEST_ENABLED=1
|
||||
LOCAL_PAIRING_ENABLED=1
|
||||
FAST_CREATE_COMMUNITY_ENABLED=1
|
||||
|
||||
@@ -34,3 +34,4 @@ TWO_MINUTES_SYNCING=1
|
||||
ENABLE_QUO_PREVIEW=1
|
||||
STICKERS_TEST_ENABLED=1
|
||||
LOCAL_PAIRING_ENABLED=1
|
||||
FAST_CREATE_COMMUNITY_ENABLED=1
|
||||
|
||||
@@ -21,3 +21,4 @@ BLANK_PREVIEW=0
|
||||
COMMUNITIES_ENABLED=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
FAST_CREATE_COMMUNITY_ENABLED=0
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name: MVPBug Report
|
||||
about: MVPBug Report
|
||||
title: ''
|
||||
labels: 'E:Mobile Bugfixes MVP'
|
||||
labels: 'E:Mobile Bug MVP'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
@@ -46,7 +46,10 @@ export NIX_USER_CONF_FILES = $(PWD)/nix/nix.conf
|
||||
# Location of symlinks to derivations that should not be garbage collected
|
||||
export _NIX_GCROOTS = /nix/var/nix/gcroots/per-user/$(USER)/status-mobile
|
||||
# Defines which variables will be kept for Nix pure shell, use semicolon as divider
|
||||
export _NIX_KEEP ?= TMPDIR,BUILD_ENV,STATUS_GO_SRC_OVERRIDE
|
||||
export _NIX_KEEP ?= TMPDIR,BUILD_ENV,\
|
||||
BUILD_TYPE,BUILD_NUMBER,COMMIT_HASH,\
|
||||
ANDROID_GRADLE_OPTS,ANDROID_ABI_SPLIT,ANDROID_ABI_INCLUDE,\
|
||||
STATUS_GO_SRC_OVERRIDE,STATUS_GO_IPFS_GATEWAY_URL
|
||||
|
||||
# Useful for Android release builds
|
||||
TMP_BUILD_NUMBER := $(shell ./scripts/version/gen_build_no.sh | cut -c1-10)
|
||||
|
||||
@@ -168,6 +168,7 @@ def getVersionCode = { ->
|
||||
|
||||
def getVersionName = { ->
|
||||
new ByteArrayOutputStream().withStream { stdOut ->
|
||||
// TODO: probably not used, cleanup
|
||||
if (project.hasProperty("releaseVersion")) {
|
||||
return project.releaseVersion
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.7.12'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.7.12'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
@@ -9,8 +9,6 @@ pipeline {
|
||||
disableConcurrentBuilds()
|
||||
/* Prevent Jenkins jobs from running forever */
|
||||
timeout(time: 40, unit: 'MINUTES')
|
||||
/* Allow copying of artifacts from this job. */
|
||||
copyArtifactPermission('/status-mobile/e2e/*')
|
||||
/* Limit builds retained */
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
@@ -49,9 +47,6 @@ pipeline {
|
||||
stage('Android') { steps { script {
|
||||
apk = jenkins.Build('status-mobile/platforms/android')
|
||||
} } }
|
||||
stage('Android e2e') { steps { script {
|
||||
apke2e = jenkins.Build('status-mobile/platforms/android-e2e')
|
||||
} } }
|
||||
stage('Tests') { steps { script {
|
||||
jenkins.Build('status-mobile/platforms/tests')
|
||||
} } }
|
||||
@@ -61,9 +56,7 @@ pipeline {
|
||||
steps { script {
|
||||
sh('rm -f pkg/*')
|
||||
jenkins.copyArts(ios)
|
||||
//jenkins.copyArts(iose2e)
|
||||
jenkins.copyArts(apk)
|
||||
jenkins.copyArts(apke2e)
|
||||
sha = "pkg/${utils.pkgFilename(ext: 'sha256')}"
|
||||
dir('pkg') {
|
||||
/* generate sha256 checksums for upload */
|
||||
@@ -77,8 +70,8 @@ pipeline {
|
||||
/* object for easier URLs handling */
|
||||
urls = [
|
||||
/* mobile */
|
||||
Apk: utils.pkgUrl(apk), Apke2e: utils.pkgUrl(apke2e),
|
||||
iOS: utils.pkgUrl(ios), /*iOSe2e: utils.pkgUrl(iose2e),*/
|
||||
Apk: utils.pkgUrl(apk),
|
||||
iOS: utils.pkgUrl(ios),
|
||||
Diawi: utils.getEnv(ios, 'DIAWI_URL'),
|
||||
/* upload the sha256 checksums file too */
|
||||
SHA: s3.uploadArtifact(sha),
|
||||
@@ -102,17 +95,6 @@ pipeline {
|
||||
}
|
||||
} }
|
||||
}
|
||||
stage('Run e2e') {
|
||||
when { expression { btype == 'nightly' && params.PUBLISH } }
|
||||
steps { script {
|
||||
e2eApk = utils.getEnv(apke2e, 'SAUCE_URL')
|
||||
build(
|
||||
job: 'status-mobile/e2e/status-app-nightly',
|
||||
parameters: [string(name: 'APK_URL', value: e2eApk)],
|
||||
wait: false
|
||||
)
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.12'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
triggers {
|
||||
// Nightly at 2am
|
||||
cron 'H 2 * * *'
|
||||
}
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'BRANCH',
|
||||
description: 'Name of the branch to checkout and build.',
|
||||
defaultValue: 'develop',
|
||||
)
|
||||
}
|
||||
|
||||
options {
|
||||
timestamps()
|
||||
disableConcurrentBuilds()
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '30',
|
||||
))
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
script {
|
||||
apk_build = jenkins.Build('status-mobile/platforms/android-e2e')
|
||||
apk_build_number = apk_build.getNumber().toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Run e2e') {
|
||||
steps {
|
||||
build(
|
||||
job: 'status-mobile/e2e/status-app-nightly',
|
||||
parameters: [
|
||||
string(name: 'APK_BUILD_NUMBER', value: apk_build_number),
|
||||
string(name: 'BRANCH', value: env.BRANCH),
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.7.12'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.7.12'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.7.12'
|
||||
|
||||
pipeline {
|
||||
|
||||
@@ -7,14 +7,24 @@ pipeline {
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'APK_URL',
|
||||
description: 'URL of APK uploaded to SauceLabs.',
|
||||
name: 'APK_BUILD_NUMBER',
|
||||
description: 'platform/e2e build number for apk artifact',
|
||||
)
|
||||
string(
|
||||
name: 'KEYWORD_EXPRESSION',
|
||||
description: 'This will run tests which contain names that match the given string expression (Optional)',
|
||||
defaultValue: '',
|
||||
)
|
||||
string(
|
||||
name: 'BRANCH',
|
||||
description: 'Name of the branch to checkout and build.',
|
||||
defaultValue: 'develop',
|
||||
)
|
||||
string(
|
||||
name: 'TR_CASE_IDS',
|
||||
description: 'IDs of the TestRail case, separated by a comma (Optional)',
|
||||
defaultValue: '',
|
||||
)
|
||||
}
|
||||
|
||||
options {
|
||||
@@ -23,15 +33,14 @@ pipeline {
|
||||
|
||||
stages {
|
||||
stage('Fetch') {
|
||||
when { expression { !params.APK_URL } }
|
||||
steps { script {
|
||||
copyArtifacts(
|
||||
projectName: "status-mobile/nightly",
|
||||
filter: '*-x86.apk',
|
||||
/* WARNING: This copies the latest available artifact. */
|
||||
selector: lastWithArtifacts(),
|
||||
projectName: "status-mobile/platforms/android-e2e",
|
||||
filter: 'result/*-x86.apk',
|
||||
selector: specific(env.APK_BUILD_NUMBER),
|
||||
)
|
||||
apk_path = "${env.WORKSPACE}/${utils.findFile('*-x86.apk')}"
|
||||
apk_path = "${env.WORKSPACE}/${utils.findFile('result/*-x86.apk')}"
|
||||
|
||||
} }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.7.12'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.7.12'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.7.12'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.7.12'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.7.12'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
library 'status-jenkins-lib@v1.7.12'
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
|
||||
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 64 KiB |
@@ -40,7 +40,9 @@ In practice, this means that sometimes they need to be merged in lockstep.
|
||||
git push origin vx.y.z
|
||||
```
|
||||
5) Update status-mobile with the new status-go version, using the new tag `scripts/update-status-go.sh "vx.y.z"`
|
||||
6) In status-mobile, push, rebase against `develop` and merge it 🚀
|
||||
6) If you had to rebase status-go to include new changes, e2e test MUST be re-run. If there's any issue you will
|
||||
have to fix in status-go with another PR and follow the same process.
|
||||
7) In status-mobile, push, rebase against `develop` and merge it 🚀
|
||||
|
||||
|
||||
important note : make sure your status-go PRs get a tested-ok by QA before merging them in.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Code Style Guidelines
|
||||
|
||||
>The goal of this document is to help all contributors (core and external) to
|
||||
>write code in _unison_ and help establish good practices that serve the Status
|
||||
>Mobile contributors well.
|
||||
> [!IMPORTANT]
|
||||
> The goal of this document is to help all contributors (core and external) to
|
||||
> write code in _unison_ and help establish good practices that serve the Status
|
||||
> Mobile contributors well.
|
||||
|
||||
We don't want to turn this document into an exhaustive list of rules to be
|
||||
followed that nobody will read. As much as possible, we'll try to document only
|
||||
@@ -10,35 +11,28 @@ what we consider important for Status Mobile. In other words, we don't want to
|
||||
maintain a general Clojure convention/style guide, nor do we want to turn this
|
||||
document into a long tutorial.
|
||||
|
||||
This is a **work in progress**, and not all conventions are properly implemented
|
||||
in the codebase yet. The project structure is also going over major changes (as
|
||||
of Nov/2022), and it'll take a considerable amount of time until we migrate the
|
||||
existing code to the new structure.
|
||||
> [!WARNING]
|
||||
> This is a **work in progress**, and not all conventions are properly
|
||||
> implemented in the codebase yet. The project structure is also undergoing
|
||||
> major changes, and it will take a considerable amount of time until we migrate
|
||||
> the existing code to the new structure.
|
||||
|
||||
If you find out anything is outdated or missing, please, share with us or even
|
||||
better, create a pull-request! 🤸
|
||||
|
||||
## Style guide
|
||||
|
||||
We mostly follow the [Clojure Style
|
||||
Guide](https://github.com/bbatsov/clojure-style-guide), so it's recommended to
|
||||
get familiar with it.
|
||||
|
||||
As of Nov/2022, running `make lint` should fix the most basic formatting issues,
|
||||
and we are in the process of integrating a tool to format non-trivial code
|
||||
according to the Clojure Style Guide. This should greatly reduce noise in
|
||||
pull-request reviews and it'll simplify the life of all contributors.
|
||||
|
||||
Pay special attention to:
|
||||
|
||||
- Align let bindings https://github.com/bbatsov/clojure-style-guide#bindings-alignment
|
||||
- Align map keys https://github.com/bbatsov/clojure-style-guide#map-keys-alignment
|
||||
We follow the [Clojure Style
|
||||
Guide](https://github.com/bbatsov/clojure-style-guide) and we use
|
||||
[zprint](https://github.com/kkinnear/zprint) to format Clojure code. Running
|
||||
`make lint-fix` should fix most formatting issues, but not all of them.
|
||||
|
||||
## Dos and don'ts
|
||||
|
||||
### Hiccup
|
||||
|
||||
Never use anonymous inline function in hiccup, this will lead to reinitialization of component on each render of parent component
|
||||
Never use anonymous inline function in hiccup, this will lead to
|
||||
reinitialization of component on each render of parent component.
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
@@ -57,7 +51,7 @@ Never use anonymous inline function in hiccup, this will lead to reinitializatio
|
||||
[comp]])
|
||||
```
|
||||
|
||||
This mistake mostly happens with functional components
|
||||
This mistake mostly happens with functional components.
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
@@ -71,20 +65,24 @@ This mistake mostly happens with functional components
|
||||
;; good
|
||||
(defn f-comp [atom]
|
||||
[rn/text atom])
|
||||
|
||||
|
||||
(fn []
|
||||
(let [atom (rf/sub [:sub])]
|
||||
(fn []
|
||||
[:f> f-comp atom])))
|
||||
[:f> f-comp atom])))
|
||||
```
|
||||
|
||||
it's important to name functional components with `f-` prefix
|
||||
It's important to name functional components with `f-` prefix.
|
||||
|
||||
### Component props and API scheme to match Figma as closely as possible
|
||||
|
||||
Ideally, the prop names for components (particularly in quo2 Design System) should match the Figma properties as best as possible. This makes it easier for the developer using that component to configure it correctly for the screen it is being used on and avoids unnecessary overwrites and adjustments being made.
|
||||
Ideally, the prop names for components (particularly in quo2 Design System)
|
||||
should match the Figma properties as best as possible. This makes it easier for
|
||||
the developer using that component to configure it correctly for the screen it
|
||||
is being used on and avoids unnecessary overwrites and adjustments being made.
|
||||
|
||||
#### Avoid unnecessarily grouping categories to reduce the number of props
|
||||
|
||||
For example in Figma if there is a component and it has the following variants:
|
||||
|
||||
|theme: "light" blur: "False"|theme: "dark" blur: "False"|theme: "light" blur: "True"|theme: "dark" blur: "True"|
|
||||
@@ -107,12 +105,18 @@ type - can be :neutral :active :danger :danger-blur"
|
||||
(defn my-component [{:keys [theme blur? type]} label])
|
||||
```
|
||||
|
||||
Please note this is only for the external API of the component and there should be no restriction of how the component manages its internal API as that will not affect the developer using the component with the issues described above.
|
||||
Please note this is only for the external API of the component and there should
|
||||
be no restriction of how the component manages its internal API as that will not
|
||||
affect the developer using the component with the issues described above.
|
||||
|
||||
In some cases this is not always possible or does not make sense. However the thought process should be how easy will it be for another developer to use this component with the correct configuration given the screen designs for Figma.
|
||||
In some cases this is not always possible or does not make sense. However the
|
||||
thought process should be how easy will it be for another developer to use this
|
||||
component with the correct configuration given the screen designs for Figma.
|
||||
|
||||
#### Avoid unnecessarily renaming props
|
||||
In general it can be helpful to avoid renaming props from their counterpart in Figma.
|
||||
#### Avoid unnecessarily renaming props
|
||||
|
||||
In general it can be helpful to avoid renaming props from their counterpart in
|
||||
Figma.
|
||||
|
||||
For example if Figma has sizes `:small`, `:medium` and `:large`
|
||||
|
||||
@@ -153,7 +157,7 @@ the source file. For a real example, see
|
||||
|
||||
### Always add styles inside the `:style` key
|
||||
|
||||
Although when compiling ReactNative for mobile some components are able work with
|
||||
Although when compiling ReactNative for mobile some components are able work with
|
||||
their styles in the top-level of the properties map, prefer to add them inside the
|
||||
`:style` key in order to separate styles from properties:
|
||||
|
||||
@@ -172,12 +176,11 @@ their styles in the top-level of the properties map, prefer to add them inside t
|
||||
:on-press #(js/alert "Hi!")
|
||||
:title "Button"}]
|
||||
|
||||
;; better
|
||||
;; better
|
||||
;; (define them in a style ns & place them inside `:style` key)
|
||||
[rn/button {:style (style/button)
|
||||
:on-press #(js/alert "Hi!")
|
||||
:title "Button"}
|
||||
]
|
||||
:title "Button"}]
|
||||
```
|
||||
|
||||
Also its fine to keep one liner styles in view
|
||||
@@ -189,7 +192,7 @@ Also its fine to keep one liner styles in view
|
||||
|
||||
### Don't define properties in styles ns
|
||||
|
||||
Properties must be set on view level
|
||||
Properties must be set on view level
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
@@ -209,10 +212,8 @@ Properties must be set on view level
|
||||
:bottom 0}
|
||||
```
|
||||
|
||||
|
||||
### Apply animated styles in the style file
|
||||
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
(defn circle
|
||||
@@ -245,24 +246,37 @@ Joshua Comeau.
|
||||
[rn/view {:style {:padding-horizontal 20}}]
|
||||
```
|
||||
|
||||
### Don't prepend booleans with is-
|
||||
### Use a question mark to convey the value is a boolean
|
||||
|
||||
It is a common practice in JavaScript and other languages to prepend boolean variable names with `is-*`.
|
||||
In ClojureScript it is common practice to suffix boolean variable names with a `?`.
|
||||
There is no need for both of these and so it is preferable to stick with the latter.
|
||||
The Clojure Style Guide suggests using a question mark only in [predicate
|
||||
functions](https://guide.clojure.style/#naming-predicates), but nothing is
|
||||
mentioned about other symbols and keywords. We prefer to extend the convention
|
||||
to all boolean references.
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
(let [is-open? true] ...)
|
||||
(def flag-is-enabled false)
|
||||
|
||||
;; good
|
||||
(let [open? true] ...)
|
||||
(def flag-enabled? false)
|
||||
```
|
||||
|
||||
And for keywords too:
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
[some-component {:logged-in true}]
|
||||
|
||||
;; good
|
||||
[some-component {:logged-in? true}]
|
||||
```
|
||||
|
||||
### Styles def vs defn
|
||||
|
||||
Always use `def` over `defn`, unless the style relies on dynamic values, such as
|
||||
deref'ed atoms.
|
||||
Always use `def` over `defn` if there are no dynamic values. This helps cut the
|
||||
cost of function calls.
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
@@ -286,15 +300,18 @@ deref'ed atoms.
|
||||
|
||||
### Custom Colors
|
||||
|
||||
The Status designs have a lot of customization of user and group colors with components and pages. For consistency it is best to use `customization-color` as the prop key on pages and components. This will help easily identify what pages and components in the application are using customized colors.
|
||||
The Status designs have a lot of customization of user and group colors. For
|
||||
consistency it is best to use `customization-color` as the prop key on pages and
|
||||
components. This will help easily identify what pages and components in the
|
||||
application are using customized colors.
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
(defn community-card [{keys [custom-color]}]
|
||||
(defn community-card [{keys [custom-color]}]
|
||||
...)
|
||||
|
||||
;; good
|
||||
(defn community-card [{keys [customization-color]}]
|
||||
(defn community-card [{keys [customization-color]}]
|
||||
...)
|
||||
```
|
||||
|
||||
@@ -518,9 +535,9 @@ the `quo2/` directory.
|
||||
|
||||
;; good
|
||||
(ns my-namespace
|
||||
(:require [quo2.core :as quo2]))
|
||||
(:require [quo2.core :as quo]))
|
||||
|
||||
(quo2/icon :i/verified)
|
||||
(quo/icon :i/verified)
|
||||
|
||||
;; also good because both namespaces are inside quo2/
|
||||
(ns quo2.components.tabs.account-selector
|
||||
@@ -587,8 +604,7 @@ indices.
|
||||
|
||||
### Icons
|
||||
|
||||
Use the appropriate keyword qualification/namespace and don't directly require
|
||||
namespaces inside `quo2/components/`.
|
||||
Use the appropriate keyword qualification/namespace.
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
PODS:
|
||||
- boost (1.76.0)
|
||||
- BVLinearGradient (2.5.6):
|
||||
- React
|
||||
- BVLinearGradient (2.8.0):
|
||||
- React-Core
|
||||
- CryptoSwift (1.5.1)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.69.10)
|
||||
@@ -425,8 +425,8 @@ PODS:
|
||||
- React-Core
|
||||
- RNStaticSafeAreaInsets (2.2.0):
|
||||
- React-Core
|
||||
- RNSVG (9.13.6):
|
||||
- React
|
||||
- RNSVG (13.10.0):
|
||||
- React-Core
|
||||
- SDWebImage (5.11.1):
|
||||
- SDWebImage/Core (= 5.11.1)
|
||||
- SDWebImage/Core (5.11.1)
|
||||
@@ -701,7 +701,7 @@ CHECKOUT OPTIONS:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
boost: a7c83b31436843459a1961bfd74b96033dc77234
|
||||
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
|
||||
BVLinearGradient: 612a04ff38e8480291f3379ee5b5a2c571f03fe0
|
||||
CryptoSwift: c4f2debceb38bf44c80659afe009f71e23e4a082
|
||||
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
|
||||
FBLazyVector: a8af91c2b5a0029d12ff6b32e428863d63c48991
|
||||
@@ -772,10 +772,10 @@ SPEC CHECKSUMS:
|
||||
RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e
|
||||
RNPermissions: ad71dd4f767ec254f2cd57592fbee02afee75467
|
||||
RNReactNativeHapticFeedback: 2566b468cc8d0e7bb2f84b23adc0f4614594d071
|
||||
RNReanimated: 43adb0307a62c1ce9694f36f124ca3b51a15272a
|
||||
RNReanimated: d0db0ee059c33381bca787a2193c27e52750ccaf
|
||||
RNShare: d82e10f6b7677f4b0048c23709bd04098d5aee6c
|
||||
RNStaticSafeAreaInsets: 055ddbf5e476321720457cdaeec0ff2ba40ec1b8
|
||||
RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f
|
||||
RNSVG: 80584470ff1ffc7994923ea135a3e5ad825546b9
|
||||
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
|
||||
SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d
|
||||
secp256k1: f61d67e6fdcb85fd727acf1bf35ace6036db540c
|
||||
@@ -785,6 +785,6 @@ SPEC CHECKSUMS:
|
||||
TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4
|
||||
Yoga: d24d6184b6b85f742536bd93bd07d69d7b9bb4c1
|
||||
|
||||
PODFILE CHECKSUM: a7c3cb360cf217ab90667d67deeab588677d540a
|
||||
PODFILE CHECKSUM: 1b60eee24bff3a6287f8b33e57657289b2966342
|
||||
|
||||
COCOAPODS: 1.12.1
|
||||
COCOAPODS: 1.12.0
|
||||
|
||||
@@ -23,7 +23,6 @@ There are a few main files that define the whole build environment:
|
||||
* [`nix/shells.nix`](./shells.nix) - Definitions of other Nix shells used in builds
|
||||
* [`nix/targets.nix`](./targets.nix) - Hierarchy of main build targets
|
||||
* [`nix/pkgs.nix`](./pkgs.nix) - Definition of a custom `nixpkgs` repo
|
||||
* [`nix/config.nix`](./config.nix) - Default config values for instantiating `nixpkgs`
|
||||
* [`nix/overlay.nix`](./overlay.nix) - Overrides for `nixpkgs`, custom packages
|
||||
|
||||
The [`default.nix`](../default.nix) and [`shell.nix`](../shell.nix) files at th repo root are just a gateway into the `nix` sub folder.
|
||||
@@ -75,13 +74,6 @@ nix-build \
|
||||
--attr targets.mobile.android.release \
|
||||
--argstr secrets-file '/tmp/tmp-status-mobile-559a3a441/tmp.xAnrPuNtAP' \
|
||||
--option extra-sandbox-paths '/home/joe/.gradle/status-im.keystore /tmp/tmp-status-mobile-559a3a441/tmp.xAnrPuNtAP' \
|
||||
--arg config '{ \
|
||||
status-im.build-type="nightly";
|
||||
status-im.build-number="2020022418";
|
||||
status-im.android.keystore-path="/home/joe/.gradle/status-im.keystore";
|
||||
status-im.android.abi-split="false";
|
||||
status-im.android.abi-include="armeabi-v7a;arm64-v8a;x86";
|
||||
}' \
|
||||
default.nix
|
||||
```
|
||||
Some of those are required which is why just calling:
|
||||
|
||||
@@ -8,27 +8,27 @@ The main config file is [`nix/nix.conf`](/nix/nix.conf) and its main purpose is
|
||||
|
||||
## Build arguments
|
||||
|
||||
We leverage the `config` argument of standard `nixpkgs` for our own parameterization of the builds (e.g. to pass a build number or build type).
|
||||
We leverage the environment variables for parameterization of the builds (e.g. to pass a build number or build type).
|
||||
|
||||
Here is a sample structure of the `config` attribute set:
|
||||
|
||||
```nix
|
||||
{
|
||||
status-im = {
|
||||
build-type = "pr"; # Build type (influences which .env file gets used for feature flags)
|
||||
build-number = 9999; # Used for versionCode and CFBundleVersion in Android and iOS respectively
|
||||
android = {
|
||||
gradle-opts = ""; # Gradle options passed for Android builds
|
||||
abi-split = false; # If APKs should be split based on architectures
|
||||
abi-include = "x86"; # Android architectures to build for
|
||||
};
|
||||
status-go = {
|
||||
src-override = "$HOME/my/source/status-go"; # local source override
|
||||
};
|
||||
};
|
||||
}
|
||||
Here is the list of variables you can use to override defaults:
|
||||
```shell
|
||||
# Build type (influences which .env file gets used for feature flags)
|
||||
export BUILD_TYPE="pr"
|
||||
# Used for versionCode and CFBundleVersion in Android and iOS respectively
|
||||
export BUILD_NUMBER=9999
|
||||
# Gradle options passed for Android builds
|
||||
export ANDROID_GRADLE_OPTS=""
|
||||
# If APKs should be split based on architectures
|
||||
export ANDROID_ABI_SPLIT=false
|
||||
# Android architectures to build for
|
||||
export ANDROID_ABI_INCLUDE="x86"
|
||||
# Local source override, see below
|
||||
export STATUS_GO_SRC_OVERRIDE="$HOME/my/source/status-go"
|
||||
export STATUS_GO_IPFS_GATEWAY_URL="https://ipfs.status.im/"
|
||||
```
|
||||
You can see the defaults in [`nix/config.nix`](./config.nix).
|
||||
You can see the defaults in code:
|
||||
- [`nix/status-go/default.nix`](./status-go/default.nix)
|
||||
- [`nix/mobile/android/release.nix`](./mobile/android/release.nix)
|
||||
|
||||
## Shell
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
# Status defaults for config
|
||||
{
|
||||
status-im = {
|
||||
build-type = "pr"; # Build type (influences which .env file gets used for feature flags)
|
||||
build-number = 9999; # Used for versionCode and CFBundleVersion in Android and iOS respectively
|
||||
commit-hash = "unknown"; # Included in APK Manifest for easier identification.
|
||||
|
||||
android = {
|
||||
gradle-opts = null; # Gradle options passed for Android builds
|
||||
apk-signed = true; # F-Droid builds aren't signed by us
|
||||
abi-split = false; # If APKs should be split based on architectures
|
||||
abi-include = "armeabi-v7a;arm64-v8a;x86"; # Android architectures to build for
|
||||
};
|
||||
|
||||
status-go = {
|
||||
src-override = null;
|
||||
ipfs-gateway-url = "https://ipfs.status.im/";
|
||||
};
|
||||
};
|
||||
|
||||
# Android SDK requires an accepted license
|
||||
android_sdk.accept_license = true;
|
||||
allowUnfree = true;
|
||||
}
|
||||
@@ -9492,16 +9492,16 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/google/auto/value/auto-value-annotations/1.10.1",
|
||||
"path": "com/google/auto/value/auto-value-annotations/1.10.2",
|
||||
"repo": "https://repo.maven.apache.org/maven2",
|
||||
"files": {
|
||||
"auto-value-annotations-1.10.1.pom": {
|
||||
"sha1": "72aa2e866fd52dc58222aacc490b6f469ff8a50f",
|
||||
"sha256": "sha256-n7rMhpTRkE37TVrx5KVGD9ZMHKnQBJ0YFFQs0q0osEc="
|
||||
"auto-value-annotations-1.10.2.pom": {
|
||||
"sha1": "bdae7d62039b58f8e6099403bd8d663064e00805",
|
||||
"sha256": "sha256-ck+V7NRFowDEx39LIHU+xe2rcLmth1Hez3CcgWUKdyE="
|
||||
},
|
||||
"auto-value-annotations-1.10.1.jar": {
|
||||
"sha1": "9e5162c15f6033c524134cba05a5e93dc1d37c4b",
|
||||
"sha256": "sha256-pP4KIRkl6TioUQ10F2PuEXGhG/kx9Yke9NTuhPynK+I="
|
||||
"auto-value-annotations-1.10.2.jar": {
|
||||
"sha1": "337954851fc17058d9b4b692b6e67e57b20e14f0",
|
||||
"sha256": "sha256-Pzt+369/u9iGQve9WwlIe43PK55fOhnx63s+U/IPFLo="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -9529,12 +9529,12 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/google/auto/value/auto-value-parent/1.10.1",
|
||||
"path": "com/google/auto/value/auto-value-parent/1.10.2",
|
||||
"repo": "https://repo.maven.apache.org/maven2",
|
||||
"files": {
|
||||
"auto-value-parent-1.10.1.pom": {
|
||||
"sha1": "cfd31b18489357b9f2b0acee57d6674394575c37",
|
||||
"sha256": "sha256-9y2jrhi84YuHRM1yM6qDSjLTvR4LRTsV9tujP3lzz+k="
|
||||
"auto-value-parent-1.10.2.pom": {
|
||||
"sha1": "8828fce3eb0708d36059af557545ab9b0c5a82de",
|
||||
"sha256": "sha256-kdaz5RX4jKobwFyqsbvciU/27dY1Se8PCaVYTJeT7mk="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -10186,27 +10186,27 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/google/guava/guava-parent/32.0.1-jre",
|
||||
"path": "com/google/guava/guava-parent/32.1.1-jre",
|
||||
"repo": "https://repo.maven.apache.org/maven2",
|
||||
"files": {
|
||||
"guava-parent-32.0.1-jre.pom": {
|
||||
"sha1": "88c9e60e238868208ca8e375a475a23142e52ac6",
|
||||
"sha256": "sha256-Q+0ONrNT9B5et1zXVmZ8ni35fO8G6xYGaWcVih0DTSo="
|
||||
"guava-parent-32.1.1-jre.pom": {
|
||||
"sha1": "01c4a3f0686592f40c1052b273c9b533f6a71e6d",
|
||||
"sha256": "sha256-BqpdGsBo8vgJUw8/9T+1yMlAFSolNiPQtTxPU/WhOj0="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/google/guava/guava-testlib/32.0.1-jre",
|
||||
"path": "com/google/guava/guava-testlib/32.1.1-jre",
|
||||
"repo": "https://repo.maven.apache.org/maven2",
|
||||
"files": {
|
||||
"guava-testlib-32.0.1-jre.pom": {
|
||||
"sha1": "a15680d2a8dd88549afda6094b5dc79ec008a5bb",
|
||||
"sha256": "sha256-kPF5mSKi2TRJl+1qpiD6HnzEJuOleB9/ufksEPWFAhs="
|
||||
"guava-testlib-32.1.1-jre.pom": {
|
||||
"sha1": "db7f2a81be1c208ea156572f3e344b6e47b4402f",
|
||||
"sha256": "sha256-8vbywCb/80CvDqzmn1SHRUG62UPLj8nvh7rm0z5yT1w="
|
||||
},
|
||||
"guava-testlib-32.0.1-jre.jar": {
|
||||
"sha1": "53ebb9303be258ba8fda12881f04be811e0f496e",
|
||||
"sha256": "sha256-yXURhJpeCFKA8QbfKwWVZv69KAsRjTPWqeBo0jgQC2M="
|
||||
"guava-testlib-32.1.1-jre.jar": {
|
||||
"sha1": "7cf13628fd8fedd5c612b928858912d9d6573d28",
|
||||
"sha256": "sha256-d+b5cAvGPxiz2iTScB9BucnhzEpXNG8hztZssAZtojU="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -10377,16 +10377,16 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/google/guava/guava/32.0.1-jre",
|
||||
"path": "com/google/guava/guava/32.1.1-jre",
|
||||
"repo": "https://repo.maven.apache.org/maven2",
|
||||
"files": {
|
||||
"guava-32.0.1-jre.pom": {
|
||||
"sha1": "4b29ff9dfc268252e73839b0f7324ef705e07108",
|
||||
"sha256": "sha256-QsJX9/c203ezGv7u6XirJtcwzXCvYN3nZi4YI1LiSCo="
|
||||
"guava-32.1.1-jre.pom": {
|
||||
"sha1": "0e5cbc6d9046ce986b121a842f8d30ee6d81a900",
|
||||
"sha256": "sha256-LJBx19FSKwx2IFfDToub+uOZJ6DrdVw2qnZRlyGHDXs="
|
||||
},
|
||||
"guava-32.0.1-jre.jar": {
|
||||
"sha1": "6e5d51a72d142f2d40a57dfb897188b36a95b489",
|
||||
"sha256": "sha256-vX+iJ1kfuFCWd9DREiz5UVjzuKn0VlP1goHYefbcSMU="
|
||||
"guava-32.1.1-jre.jar": {
|
||||
"sha1": "ad575652d84153075dd41ec6177ccb15251262b2",
|
||||
"sha256": "sha256-kfu6N/HIslHPnqnn06Np63nrHmpd8dS79IPdA4B0AoE="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -11044,16 +11044,16 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/squareup/okio/okio-jvm/3.3.0",
|
||||
"path": "com/squareup/okio/okio-jvm/3.4.0",
|
||||
"repo": "https://repo.maven.apache.org/maven2",
|
||||
"files": {
|
||||
"okio-jvm-3.3.0.pom": {
|
||||
"sha1": "441db5e3f85f26d8891b7ae05cffb9a1a67ee54f",
|
||||
"sha256": "sha256-RgAOC5D+UbfbTA6YseP5IxVWJqh7vD9N3ItWwNM3GM4="
|
||||
"okio-jvm-3.4.0.pom": {
|
||||
"sha1": "5863f748d245d922f99b22c24e3d0c00455f6687",
|
||||
"sha256": "sha256-ZqiFeYHqbD7IuGE6QJvxLxR5Ze+UmMt6jzcXKMTi2k0="
|
||||
},
|
||||
"okio-jvm-3.3.0.jar": {
|
||||
"sha1": "2d175add2d06a67bda111ae5455e49b42d0bb287",
|
||||
"sha256": "sha256-3/qEF+wg19Rrx0xq16QiazjaJYipdU9imGJPBN8jciI="
|
||||
"okio-jvm-3.4.0.jar": {
|
||||
"sha1": "4e8bd78a52ab935ce383d0092646922154295e54",
|
||||
"sha256": "sha256-ATnselBtu9VMrWIpGwGcuFBTS+CXyMZsEADV++jt7z4="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -11115,16 +11115,16 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/squareup/okio/okio/3.3.0",
|
||||
"path": "com/squareup/okio/okio/3.4.0",
|
||||
"repo": "https://repo.maven.apache.org/maven2",
|
||||
"files": {
|
||||
"okio-3.3.0.pom": {
|
||||
"sha1": "8b5abd4bc3965b81e4c8c718bfabdac9afbebe7b",
|
||||
"sha256": "sha256-1aiEoZkyN9rnxa9t5C+vkxzzO9pwLm2qmdOrCKi8xZ8="
|
||||
"okio-3.4.0.pom": {
|
||||
"sha1": "10df463795f884e8f616849ef57229603f116f80",
|
||||
"sha256": "sha256-QOr9s+epasxcFR3pzL7BKFDy37XL53Ph90zrU2JVggM="
|
||||
},
|
||||
"okio-3.3.0.jar": {
|
||||
"sha1": "c3ad4568143c88518e82eb63de30e2d3de011439",
|
||||
"sha256": "sha256-DyFSCU7lcwFZ4Yu6aZBdAk6cep9Ij2AhGh3Sg3N/q8U="
|
||||
"okio-3.4.0.jar": {
|
||||
"sha1": "cdbfd045ea8fb402b78e3b3a1177ce6f19d8b2f3",
|
||||
"sha256": "sha256-GHgMXSKb0AiVzyi5E8Wh5YXb8Kq49BD8SDkuF4OrtEI="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -14254,16 +14254,16 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/checkerframework/checker-qual/3.35.0",
|
||||
"path": "org/checkerframework/checker-qual/3.36.0",
|
||||
"repo": "https://repo.maven.apache.org/maven2",
|
||||
"files": {
|
||||
"checker-qual-3.35.0.pom": {
|
||||
"sha1": "5211a7196b70c37b573e3405d14661cd82e1eddb",
|
||||
"sha256": "sha256-CzlY7JehFV7QAHwXbMICwUrdZm1PV1gPuhzpy2mb+KM="
|
||||
"checker-qual-3.36.0.pom": {
|
||||
"sha1": "6718527e5d8619731637618c68b4d49aa1649c0d",
|
||||
"sha256": "sha256-kLwP0YLqKfP2kkuLYmzMaqTmSm1Apw7klU1j4gb/zvQ="
|
||||
},
|
||||
"checker-qual-3.35.0.jar": {
|
||||
"sha1": "3baabaf8eecea6e9e22b8e39cd25953ff4813e0e",
|
||||
"sha256": "sha256-IQYPqght/eyDCkD5RgZ3p1673P/nzcASrRBp6cwwqVk="
|
||||
"checker-qual-3.36.0.jar": {
|
||||
"sha1": "62ea2b911acf3a3eecd25a1a2986864b7403f6d2",
|
||||
"sha256": "sha256-uj7BaeB28uXYLfpRQubunxbnayvvMMrc5FV+1fq3gu0="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -15875,16 +15875,16 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-reflect/1.9.0-RC",
|
||||
"path": "org/jetbrains/kotlin/kotlin-reflect/1.9.0",
|
||||
"repo": "https://repo.maven.apache.org/maven2",
|
||||
"files": {
|
||||
"kotlin-reflect-1.9.0-RC.pom": {
|
||||
"sha1": "3a1dca889c37677ab1031646e99190406b48b60d",
|
||||
"sha256": "sha256-AaWDwwugU0BM/4qe7iGCL2kBfXUCbOXqzFCXjKcBuiA="
|
||||
"kotlin-reflect-1.9.0.pom": {
|
||||
"sha1": "eb198069ed7e9e8458d900c47325475ec581507a",
|
||||
"sha256": "sha256-hXFWVnbRiXIEcTBs7ppV2RbAgDgvNabaaBk6x7EvTNs="
|
||||
},
|
||||
"kotlin-reflect-1.9.0-RC.jar": {
|
||||
"sha1": "2a7a69e82364a9e6f26b8d7053c0e4f1095693e5",
|
||||
"sha256": "sha256-RCoElBkwb/CgCVHMmCTorhyB1HWKo/v5ineCxM68O/c="
|
||||
"kotlin-reflect-1.9.0.jar": {
|
||||
"sha1": "2891f552979d4bf4d4ec516acb9df769fb62dbe9",
|
||||
"sha256": "sha256-IHAVm+UU6o6jziyLHueZPm/2CpNWWimfIAYpqn339YE="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -16325,16 +16325,16 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib-common/1.9.0-RC",
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib-common/1.9.0",
|
||||
"repo": "https://repo.maven.apache.org/maven2",
|
||||
"files": {
|
||||
"kotlin-stdlib-common-1.9.0-RC.pom": {
|
||||
"sha1": "1eee188e6e339347cb905505ba0884504b7d271c",
|
||||
"sha256": "sha256-jybwbbD1aQ6epaWjeA9hyEAVaRnYpXqOGvnt8cvQjD0="
|
||||
"kotlin-stdlib-common-1.9.0.pom": {
|
||||
"sha1": "0a865a0c5a64618fd1dcca13d05dea4cba44c832",
|
||||
"sha256": "sha256-NmDTanD+s6vknxG5BjPkHTYnNXbwcbDhCdqbOg3wgqU="
|
||||
},
|
||||
"kotlin-stdlib-common-1.9.0-RC.jar": {
|
||||
"sha1": "0d9bdb03665199f3548ff91464625d943f816594",
|
||||
"sha256": "sha256-2nsa2F4a/WQ9riwPDVFaUTZiW839GD7YbFeVrhfgWpk="
|
||||
"kotlin-stdlib-common-1.9.0.jar": {
|
||||
"sha1": "cd65c21cfd1eec4d44ef09f9f52b6d9f8a720636",
|
||||
"sha256": "sha256-KDJ0IEvXwCB4nsRvj45yr0JE1/VQszkqV+XKAGrXqiw="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -17030,16 +17030,16 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib/1.9.0-RC",
|
||||
"path": "org/jetbrains/kotlin/kotlin-stdlib/1.9.0",
|
||||
"repo": "https://repo.maven.apache.org/maven2",
|
||||
"files": {
|
||||
"kotlin-stdlib-1.9.0-RC.pom": {
|
||||
"sha1": "9b8fee0f61426896867f6bbeff6cd80c5e364789",
|
||||
"sha256": "sha256-Ljsx4IQ1ngB2u5q9jpoBUDQ8wdLA81Zx4gKhy1Rqp6A="
|
||||
"kotlin-stdlib-1.9.0.pom": {
|
||||
"sha1": "4aea0493dfd3ee18df73bcd97db791c2ea5bb383",
|
||||
"sha256": "sha256-N3UiY/Ysw+MlCFbiiO5Kc9QQLXJqd2JwNPlIBsjBCso="
|
||||
},
|
||||
"kotlin-stdlib-1.9.0-RC.jar": {
|
||||
"sha1": "f42325be451f7f28ec68e1e60227035beae7ca9b",
|
||||
"sha256": "sha256-x+O9exwYsJnuUeNXIOxgSndh2fpFEmlkQgQOPb9X0Oo="
|
||||
"kotlin-stdlib-1.9.0.jar": {
|
||||
"sha1": "8ee15ef0c67dc83d874f412d84378d7f0eb50b63",
|
||||
"sha256": "sha256-Na7/vi21qkRgcs7lD87ki3+p4vxRyjfAzH19C8OdlS4="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -17232,12 +17232,12 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/junit/junit-bom/5.10.0-M1",
|
||||
"path": "org/junit/junit-bom/5.10.0",
|
||||
"repo": "https://repo.maven.apache.org/maven2",
|
||||
"files": {
|
||||
"junit-bom-5.10.0-M1.pom": {
|
||||
"sha1": "32146a4e02dff4367f085571d9157924622888a2",
|
||||
"sha256": "sha256-2ltnOOp1EcGyT/z0h2UMPcB1aihjLktKfA2qbiTt7O0="
|
||||
"junit-bom-5.10.0.pom": {
|
||||
"sha1": "1136f35a5438634393bf628f69b8ca43c8518f7c",
|
||||
"sha256": "sha256-4AbdiJT5/Ht1/DK7Ev5e2L5lZn1bRU+Z4uC4xbuNMLM="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -634,10 +634,10 @@ https://repo.maven.apache.org/maven2/com/google/auto/auto-parent/6/auto-parent-6
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/auto-parent/7/auto-parent-7.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.6.2/auto-value-annotations-1.6.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.6.3/auto-value-annotations-1.6.3.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.10.1/auto-value-annotations-1.10.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.10.2/auto-value-annotations-1.10.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-parent/1.6.2/auto-value-parent-1.6.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-parent/1.6.3/auto-value-parent-1.6.3.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-parent/1.10.1/auto-value-parent-1.10.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-parent/1.10.2/auto-value-parent-1.10.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value/1.5.2/auto-value-1.5.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/3.0.1/jsr305-3.0.1.pom
|
||||
@@ -688,8 +688,8 @@ https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/29.0-jre/guav
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/30.1-android/guava-parent-30.1-android.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/30.1-jre/guava-parent-30.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/31.0.1-jre/guava-parent-31.0.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/32.0.1-jre/guava-parent-32.0.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-testlib/32.0.1-jre/guava-testlib-32.0.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/32.1.1-jre/guava-parent-32.1.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-testlib/32.1.1-jre/guava-testlib-32.1.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/17.0/guava-17.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/22.0/guava-22.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/23.0/guava-23.0.pom
|
||||
@@ -701,7 +701,7 @@ https://repo.maven.apache.org/maven2/com/google/guava/guava/29.0-jre/guava-29.0-
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/30.1-android/guava-30.1-android.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/30.1-jre/guava-30.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/32.0.1-jre/guava-32.0.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/32.1.1-jre/guava-32.1.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/listenablefuture/1.0/listenablefuture-1.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.pom
|
||||
@@ -750,12 +750,12 @@ https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/3.12.1/okhttp-3
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/4.9.2/okhttp-4.9.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.9.1/parent-3.9.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.12.1/parent-3.12.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.3.0/okio-jvm-3.3.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.4.0/okio-jvm-3.4.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.17.4/okio-parent-1.17.4.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.17.4/okio-1.17.4.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.8.0/okio-2.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.9.0/okio-2.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.3.0/okio-3.3.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.4.0/okio-3.4.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.0/all-1.2.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.1/all-1.2.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.2/all-1.2.2.pom
|
||||
@@ -988,7 +988,7 @@ https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/2.8.1/che
|
||||
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/2.11.1/checker-qual-2.11.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.5.0/checker-qual-3.5.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.35.0/checker-qual-3.35.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.36.0/checker-qual-3.36.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/codehaus/codehaus-parent/4/codehaus-parent-4.pom
|
||||
https://repo.maven.apache.org/maven2/org/codehaus/groovy/groovy-xml/3.0.10/groovy-xml-3.0.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/codehaus/groovy/groovy/3.0.9/groovy-3.0.9.pom
|
||||
@@ -1103,7 +1103,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.4.32/
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.5.31/kotlin-reflect-1.5.31.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.6.10/kotlin-reflect-1.6.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.6.20/kotlin-reflect-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.9.0-RC/kotlin-reflect-1.9.0-RC.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.9.0/kotlin-reflect-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.6.10/kotlin-scripting-common-1.6.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.6.20/kotlin-scripting-common-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.6.10/kotlin-scripting-compiler-embeddable-1.6.10.pom
|
||||
@@ -1133,7 +1133,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.6.20/kotlin-stdlib-common-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.6.21/kotlin-stdlib-common-1.6.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.0/kotlin-stdlib-common-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.9.0-RC/kotlin-stdlib-common-1.9.0-RC.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.9.0/kotlin-stdlib-common-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.2.71/kotlin-stdlib-jdk7-1.2.71.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.3.20/kotlin-stdlib-jdk7-1.3.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.3.50/kotlin-stdlib-jdk7-1.3.50.pom
|
||||
@@ -1180,7 +1180,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.6.10/k
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.6.20/kotlin-stdlib-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.6.21/kotlin-stdlib-1.6.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.8.0/kotlin-stdlib-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.0-RC/kotlin-stdlib-1.9.0-RC.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.0/kotlin-stdlib-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-tooling-metadata/1.6.10/kotlin-tooling-metadata-1.6.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-tooling-metadata/1.6.20/kotlin-tooling-metadata-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-util-io/1.6.10/kotlin-util-io-1.6.10.pom
|
||||
@@ -1194,7 +1194,7 @@ https://repo.maven.apache.org/maven2/org/json/json/20180813/json-20180813.pom
|
||||
https://repo.maven.apache.org/maven2/org/json/json/20230618/json-20230618.pom
|
||||
https://repo.maven.apache.org/maven2/org/jsoup/jsoup/1.13.1/jsoup-1.13.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.9.2/junit-bom-5.9.2.pom
|
||||
https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.10.0-M1/junit-bom-5.10.0-M1.pom
|
||||
https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.10.0/junit-bom-5.10.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/1.7.7/stax-ex-1.7.7.pom
|
||||
https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/1.8.1/stax-ex-1.8.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/1.8/stax-ex-1.8.pom
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{ lib, config }:
|
||||
{ lib }:
|
||||
|
||||
{
|
||||
getConfig = import ./getConfig.nix { inherit lib config; };
|
||||
getEnvWithDefault = import ./getEnvWithDefault.nix;
|
||||
mkFilter = import ./mkFilter.nix { inherit lib; };
|
||||
mergeSh = import ./mergeSh.nix { inherit lib; };
|
||||
checkEnvVarSet = import ./checkEnvVarSet.nix;
|
||||
sanitizeVersion = import ./sanitizeVersion.nix { inherit lib; };
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# helper for getting status-im config values in a safe way
|
||||
#
|
||||
|
||||
{ lib, config }:
|
||||
|
||||
let inherit (lib) splitString attrByPath;
|
||||
in name: default:
|
||||
let
|
||||
path = [ "status-im" ] ++ (splitString "." name);
|
||||
value = attrByPath path default config;
|
||||
in if value != null then value else default
|
||||
@@ -0,0 +1,8 @@
|
||||
name: default: let
|
||||
envOverride = builtins.getEnv name;
|
||||
logEnvOverride = value:
|
||||
builtins.trace "getEnvWithDefault ${name} (default: ${toString default}): ${value}" value;
|
||||
in
|
||||
if envOverride != ""
|
||||
then logEnvOverride envOverride
|
||||
else default
|
||||
@@ -0,0 +1,14 @@
|
||||
{ lib }:
|
||||
|
||||
version:
|
||||
let
|
||||
# paths don't like slashes in them
|
||||
dropSlashes = builtins.replaceStrings [ "/" ] [ "_" ];
|
||||
# if version doesn't match this it's probably a commit, it's lax semver
|
||||
versionRegex = "^v?[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+[[:alnum:]+_.-]*$";
|
||||
in
|
||||
if (builtins.match versionRegex version) != null
|
||||
# Geth forces a 'v' prefix for all versions
|
||||
then lib.removePrefix "v" (dropSlashes version)
|
||||
# reduce metrics cardinality in Prometheus
|
||||
else lib.traceValFn (_: "WARNING: Marking build version as 'develop'!") "develop"
|
||||
@@ -6,20 +6,30 @@
|
||||
buildEnv ? "prod",
|
||||
# Path to the file containing secret environment variables
|
||||
secretsFile ? "",
|
||||
# Build type (influences which .env file gets used for feature flags)
|
||||
# TODO: pr or relase for default?
|
||||
buildType ? lib.getEnvWithDefault "BUILD_TYPE" "release",
|
||||
# Used for versionCode
|
||||
buildNumber ? lib.getEnvWithDefault "BUILD_NUMBER" 9999,
|
||||
# Included in APK Manifest for easier identification.
|
||||
# TODO: or GIT_COMMIT from Jenkins?
|
||||
commitHash ? lib.getEnvWithDefault "COMMIT_HASH" "unknown",
|
||||
# Gradle options passed for Android builds
|
||||
androidGradleOpts ? lib.getEnvWithDefault "ANDROID_GRADLE_OPTS" null,
|
||||
statusGoSrcOverride ? lib.getEnvWithDefault "STATUS_GO_SRC_OVERRIDE" null,
|
||||
# If APKs should be split based on architectures
|
||||
androidAbiSplit ? lib.getEnvWithDefault "ANDROID_ABI_SPLIT" "false",
|
||||
# Android architectures to build for
|
||||
# Used to detect end-to-end builds
|
||||
androidAbiInclude ? lib.getEnvWithDefault "ANDROID_ABI_INCLUDE" "armeabi-v7a;arm64-v8a;x86",
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) toLower optionalString stringLength getConfig makeLibraryPath elem;
|
||||
inherit (lib) toLower optionalString stringLength makeLibraryPath elem;
|
||||
|
||||
# Pass secretsFile for POKT_TOKEN to jsbundle build
|
||||
builtJsBundle = jsbundle { inherit secretsFile; };
|
||||
|
||||
buildType = getConfig "build-type" "release";
|
||||
buildNumber = getConfig "build-number" 9999;
|
||||
commitHash = getConfig "commit-hash" "unknown";
|
||||
gradleOpts = getConfig "android.gradle-opts" null;
|
||||
# Used to detect end-to-end builds
|
||||
androidAbiInclude = getConfig "android.abi-include" "armeabi-v7a;arm64-v8a;x86";
|
||||
|
||||
envFileName =
|
||||
if androidAbiInclude == "x86" then ".env.e2e"
|
||||
@@ -63,9 +73,8 @@ in stdenv.mkDerivation rec {
|
||||
# Used by Clojure at compile time to include JS modules
|
||||
BUILD_ENV = buildEnv;
|
||||
|
||||
# custom env variables derived from config
|
||||
STATUS_GO_SRC_OVERRIDE = getConfig "status-go.src-override" null;
|
||||
ANDROID_ABI_SPLIT = getConfig "android.abi-split" "false";
|
||||
STATUS_GO_SRC_OVERRIDE = statusGoSrcOverride;
|
||||
ANDROID_ABI_SPLIT = androidAbiSplit;
|
||||
ANDROID_ABI_INCLUDE = androidAbiInclude;
|
||||
|
||||
# Android SDK/NDK for use by Gradle
|
||||
@@ -122,17 +131,9 @@ in stdenv.mkDerivation rec {
|
||||
buildPhase = let
|
||||
adhocEnvVars = optionalString stdenv.isLinux
|
||||
"LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${makeLibraryPath [ pkgs.zlib ]}";
|
||||
in
|
||||
assert ANDROID_ABI_SPLIT != null && ANDROID_ABI_SPLIT != "";
|
||||
assert stringLength ANDROID_ABI_INCLUDE > 0;
|
||||
''
|
||||
# Fixes issue with failing to load libnative-platform.so
|
||||
export GRADLE_USER_HOME=$(mktemp -d)
|
||||
export ANDROID_SDK_HOME=$(mktemp -d)
|
||||
|
||||
pushd ./android
|
||||
${adhocEnvVars} ${pkgs.gradle}/bin/gradle \
|
||||
${toString gradleOpts} \
|
||||
gradleCommand = ''
|
||||
${pkgs.gradle}/bin/gradle \
|
||||
${toString androidGradleOpts} \
|
||||
--console=plain \
|
||||
--offline \
|
||||
--no-daemon \
|
||||
@@ -142,8 +143,21 @@ in stdenv.mkDerivation rec {
|
||||
-Dmaven.repo.local='${deps.gradle}' \
|
||||
-PversionCode=${toString buildNumber} \
|
||||
-PcommitHash=${commitHash} \
|
||||
assemble${gradleBuildType} \
|
||||
|| exit 1
|
||||
assemble${gradleBuildType}
|
||||
'';
|
||||
in
|
||||
assert ANDROID_ABI_SPLIT != null && ANDROID_ABI_SPLIT != "";
|
||||
assert stringLength ANDROID_ABI_INCLUDE > 0;
|
||||
''
|
||||
# Fixes issue with failing to load libnative-platform.so
|
||||
export GRADLE_USER_HOME=$(mktemp -d)
|
||||
export ANDROID_SDK_HOME=$(mktemp -d)
|
||||
|
||||
echo "Adhoc ENV: ${adhocEnvVars}"
|
||||
echo "Running: ${gradleCommand}"
|
||||
|
||||
pushd ./android
|
||||
${adhocEnvVars} ${gradleCommand}
|
||||
popd > /dev/null
|
||||
'';
|
||||
doCheck = true;
|
||||
|
||||
@@ -13,11 +13,8 @@ in {
|
||||
# Fix for MacOS
|
||||
mkShell = super.mkShell.override { stdenv = stdenvNoCC; };
|
||||
|
||||
# Various utilities
|
||||
utils = callPackage ./tools/utils.nix { };
|
||||
lib = (super.lib or { }) // (import ./lib {
|
||||
inherit (super) lib;
|
||||
inherit (self) config;
|
||||
});
|
||||
|
||||
# Project dependencies
|
||||
@@ -29,9 +26,6 @@ in {
|
||||
react-native = callPackage ./deps/react-native { };
|
||||
};
|
||||
|
||||
# For parsing gradle.properties into an attrset
|
||||
gradlePropParser = callPackage ./tools/gradlePropParser.nix { };
|
||||
|
||||
# Fix for missing libarclite_macosx.a in Xcode 14.3.
|
||||
# https://github.com/ios-control/ios-deploy/issues/580
|
||||
ios-deploy = super.darwin.ios-deploy.overrideAttrs (old: rec {
|
||||
|
||||
@@ -13,7 +13,10 @@ let
|
||||
};
|
||||
|
||||
# Status specific configuration defaults
|
||||
defaultConfig = import ./config.nix;
|
||||
defaultConfig = {
|
||||
android_sdk.accept_license = true;
|
||||
allowUnfree = true;
|
||||
};
|
||||
|
||||
# Override some packages and utilities
|
||||
pkgsOverlay = import ./overlay.nix;
|
||||
|
||||
@@ -41,16 +41,6 @@ nixArgs=(
|
||||
"--attr shells.${TARGET}"
|
||||
)
|
||||
|
||||
config=''
|
||||
if [[ -n "${STATUS_GO_SRC_OVERRIDE}" ]]; then
|
||||
config+="status-im.status-go.src-override=\"${STATUS_GO_SRC_OVERRIDE}\";"
|
||||
fi
|
||||
config+="status-im.build-type=\"${BUILD_TYPE}\";"
|
||||
|
||||
if [[ -n "$config" ]]; then
|
||||
nixArgs+=("--arg config {$config}")
|
||||
fi
|
||||
|
||||
# This variable allows specifying which env vars to keep for Nix pure shell
|
||||
# The separator is a colon
|
||||
if [[ -n "${_NIX_KEEP}" ]]; then
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{ lib, callPackage, mkShell }:
|
||||
|
||||
let
|
||||
inherit (lib) getConfig attrValues mapAttrs;
|
||||
inherit (lib) getEnvWithDefault attrValues mapAttrs;
|
||||
|
||||
# Metadata common to all builds of status-go
|
||||
meta = {
|
||||
@@ -18,7 +18,7 @@ let
|
||||
GitCommit = source.rev;
|
||||
Version = source.cleanVersion;
|
||||
# FIXME: This should be moved to status-go config.
|
||||
IpfsGatewayURL = getConfig "status-go.ipfs-gateway-url" "https://ipfs.status.im/";
|
||||
IpfsGatewayURL = getEnvWithDefault "STATUS_GO_IPFS_GATEWAY_URL" "https://ipfs.status.im/";
|
||||
};
|
||||
|
||||
# These are necessary for status-go to show correct version
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{ lib, utils, buildGoPackage
|
||||
{ callPackage, lib, buildGoPackage
|
||||
, androidPkgs, openjdk, gomobile, xcodeWrapper, removeReferencesTo
|
||||
, meta
|
||||
, source
|
||||
@@ -13,6 +13,7 @@ let
|
||||
inherit (lib) concatStringsSep optionalString optional;
|
||||
isIOS = platform == "ios";
|
||||
isAndroid = platform == "android";
|
||||
enforceXCodeAvailable = callPackage ./enforceXCodeAvailable.nix { };
|
||||
|
||||
in buildGoPackage {
|
||||
pname = source.repo;
|
||||
@@ -35,7 +36,7 @@ in buildGoPackage {
|
||||
ANDROID_HOME = optionalString isAndroid androidPkgs.sdk;
|
||||
|
||||
# Ensure XCode is present for iOS, instead of failing at the end of the build.
|
||||
preConfigure = optionalString isIOS utils.enforceXCodeAvailable;
|
||||
preConfigure = optionalString isIOS enforceXCodeAvailable;
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
{ xcodeWrapper }:
|
||||
|
||||
let
|
||||
RED = "\\033[0;31m";
|
||||
GREEN = "\\033[0;32m";
|
||||
NC = "\\033[0m";
|
||||
|
||||
_xcodeToolsTest = ''
|
||||
xcode=0
|
||||
iPhoneSDK=0
|
||||
export PATH=${xcodeWrapper}/bin:$PATH
|
||||
xcrun xcodebuild -version && xcode=1
|
||||
[ $xcode -eq 1 ] && xcrun --sdk iphoneos --show-sdk-version > /dev/null && iPhoneSDK=1
|
||||
'';
|
||||
_xcodeToolReportScript = tool-name: ''[ $SELECTED -eq 0 ] && echo -e "${NC}- ${RED}[ ] ${tool-name}" || echo -e "${NC}- ${GREEN}[√] ${tool-name}${RED}"'';
|
||||
_xcodeToolsReportScript = ''
|
||||
echo -e "${RED}There are some required tools missing in the system:"
|
||||
export SELECTED=$xcode; ${_xcodeToolReportScript "Xcode ${_xcodeVersion}"}
|
||||
export SELECTED=$iPhoneSDK; ${_xcodeToolReportScript "iPhone SDK"}
|
||||
'';
|
||||
_xcodeVersion = builtins.replaceStrings ["xcode-wrapper-"] [""] xcodeWrapper.name;
|
||||
in
|
||||
''
|
||||
${_xcodeToolsTest}
|
||||
if [ $xcode -eq 0 ]; then
|
||||
${_xcodeToolsReportScript}
|
||||
echo -e "Please install Xcode ${_xcodeVersion} from the App Store.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
''
|
||||
@@ -1,9 +1,10 @@
|
||||
{ utils, lib, fetchFromGitHub }:
|
||||
{ lib, fetchFromGitHub }:
|
||||
|
||||
let
|
||||
inherit (lib) strings traceValFn importJSON getConfig;
|
||||
inherit (lib) strings traceValFn importJSON getEnvWithDefault;
|
||||
|
||||
srcOverride = getConfig "status-go.src-override" null;
|
||||
# TODO: move to default?
|
||||
srcOverride = getEnvWithDefault "STATUS_GO_SRC_OVERRIDE" null;
|
||||
# Warning message about using local sources
|
||||
localSrcWarn = (path: "Using local status-go sources from ${path}");
|
||||
|
||||
@@ -43,7 +44,7 @@ let
|
||||
rev = versionJSON.commit-sha1;
|
||||
shortRev = strings.substring 0 7 rev;
|
||||
rawVersion = versionJSON.version;
|
||||
cleanVersion = utils.sanitizeVersion versionJSON.version;
|
||||
cleanVersion = lib.sanitizeVersion versionJSON.version;
|
||||
# Need to pretend this is from status-im to let Go build it.
|
||||
goPackagePath = "github.com/status-im/${repo}";
|
||||
src = fetchFromGitHub {
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# This Nix expression takes care of reading/parsing the correct .env configuration file and return it as an attr set
|
||||
{ config, lib }:
|
||||
|
||||
let
|
||||
inherit (builtins) listToAttrs head tail readFile;
|
||||
inherit (lib) attrByPath filter hasPrefix nameValuePair splitString;
|
||||
|
||||
build-type = attrByPath ["status-im" "build-type"] "" config;
|
||||
|
||||
readLinesFromFile =
|
||||
file:
|
||||
let
|
||||
lines = splitString "\n" (readFile file);
|
||||
removeComments = filter (line: line != "" && !(hasPrefix "#" line));
|
||||
meaningfulLines = removeComments lines;
|
||||
in
|
||||
meaningfulLines;
|
||||
readFlagsFromFile =
|
||||
file:
|
||||
let
|
||||
lines = readLinesFromFile file;
|
||||
genAttrs = lines:
|
||||
listToAttrs (map (line:
|
||||
let flag = splitString "=" line;
|
||||
in nameValuePair (head flag) (head (tail flag))) lines);
|
||||
in
|
||||
genAttrs lines;
|
||||
envFileName =
|
||||
if build-type == "release" then ../../.env.release else
|
||||
if build-type == "nightly" then ../../.env.nightly else
|
||||
if build-type == "e2e" then ../../.env.e2e else
|
||||
if build-type == "pr" then ../../.env.jenkins else ../../.env;
|
||||
flags = readFlagsFromFile envFileName; # TODO: Simplify this path search with lib.locateDominatingFile
|
||||
|
||||
in flags
|
||||
@@ -1,20 +0,0 @@
|
||||
# Parser for android/gradle.properties file.
|
||||
# Returns an attrset with keys and values from it.
|
||||
{ lib }:
|
||||
|
||||
gradlePropsFile:
|
||||
|
||||
let
|
||||
inherit (lib) head last filter listToAttrs splitString nameValuePair hasPrefix readFile;
|
||||
|
||||
# Read lines
|
||||
lines = splitString "\n" (readFile gradlePropsFile);
|
||||
|
||||
isKeyValueLine = line: line != "" && !hasPrefix "#" line;
|
||||
cleanup = filter isKeyValueLine;
|
||||
extractKeyValues = line:
|
||||
let flag = splitString "=" line;
|
||||
in nameValuePair (head flag) (last flag);
|
||||
parseAttrs = lines: listToAttrs (map extractKeyValues lines);
|
||||
in
|
||||
parseAttrs (cleanup lines)
|
||||
@@ -1,64 +0,0 @@
|
||||
{ xcodeWrapper, lib }:
|
||||
|
||||
#
|
||||
# This is a collection of various utilities used throught this repo.
|
||||
#
|
||||
|
||||
let
|
||||
RED = "\\033[0;31m";
|
||||
GREEN = "\\033[0;32m";
|
||||
NC = "\\033[0m";
|
||||
|
||||
_xcodeToolsTest = ''
|
||||
xcode=0
|
||||
iPhoneSDK=0
|
||||
export PATH=${xcodeWrapper}/bin:$PATH
|
||||
xcrun xcodebuild -version && xcode=1
|
||||
[ $xcode -eq 1 ] && xcrun --sdk iphoneos --show-sdk-version > /dev/null && iPhoneSDK=1
|
||||
'';
|
||||
_xcodeToolReportScript = tool-name: ''[ $SELECTED -eq 0 ] && echo -e "${NC}- ${RED}[ ] ${tool-name}" || echo -e "${NC}- ${GREEN}[√] ${tool-name}${RED}"'';
|
||||
_xcodeToolsReportScript = ''
|
||||
echo -e "${RED}There are some required tools missing in the system:"
|
||||
export SELECTED=$xcode; ${_xcodeToolReportScript "Xcode ${_xcodeVersion}"}
|
||||
export SELECTED=$iPhoneSDK; ${_xcodeToolReportScript "iPhone SDK"}
|
||||
'';
|
||||
_xcodeVersion = builtins.replaceStrings ["xcode-wrapper-"] [""] xcodeWrapper.name;
|
||||
|
||||
enforceXCodeAvailable = ''
|
||||
${_xcodeToolsTest}
|
||||
if [ $xcode -eq 0 ]; then
|
||||
${_xcodeToolsReportScript}
|
||||
echo -e "Please install Xcode ${_xcodeVersion} from the App Store.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
|
||||
enforceiPhoneSDKAvailable = ''
|
||||
${_xcodeToolsTest}
|
||||
if [ $iPhoneSDK -eq 0 ]; then
|
||||
${_xcodeToolsReportScript}
|
||||
if [ $xcode -eq 1 ]; then
|
||||
echo -e "Please install the iPhone SDK in Xcode.${NC}""
|
||||
else
|
||||
echo -e "Please install Xcode ${_xcodeVersion} from the App Store, and then the iPhone SDK.${NC}""
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
|
||||
# paths don't like slashes in them
|
||||
dropSlashes = builtins.replaceStrings [ "/" ] [ "_" ];
|
||||
# if version doesn't match this it's probably a commit, it's lax semver
|
||||
versionRegex = "^v?[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+[[:alnum:]+_.-]*$";
|
||||
sanitizeVersion = version:
|
||||
if (builtins.match versionRegex version) != null
|
||||
# Geth forces a 'v' prefix for all versions
|
||||
then lib.removePrefix "v" (dropSlashes version)
|
||||
# reduce metrics cardinality in Prometheus
|
||||
else lib.traceValFn (_: "WARNING: Marking build version as 'develop'!") "develop";
|
||||
|
||||
in {
|
||||
inherit sanitizeVersion
|
||||
enforceXCodeAvailable
|
||||
enforceiPhoneSDKAvailable;
|
||||
}
|
||||
@@ -49,6 +49,7 @@
|
||||
"react-native-fetch-polyfill": "^1.1.2",
|
||||
"react-native-fs": "^2.14.1",
|
||||
"react-native-gesture-handler": "2.6.1",
|
||||
"react-native-gifted-charts": "^1.3.2",
|
||||
"react-native-haptic-feedback": "^1.9.0",
|
||||
"react-native-hole-view": "git+https://github.com/status-im/react-native-hole-view.git#refs/tags/v2.1.3-status",
|
||||
"react-native-image-crop-picker": "git+https://github.com/status-im/react-native-image-crop-picker.git#refs/tags/v0.36.2-status.0",
|
||||
@@ -56,7 +57,7 @@
|
||||
"react-native-image-viewing": "git+https://github.com/status-im/react-native-image-viewing.git#refs/tags/v0.2.1.status",
|
||||
"react-native-keychain": "git+https://github.com/status-im/react-native-keychain.git#refs/tags/v.3.0.0-5-status",
|
||||
"react-native-languages": "^3.0.2",
|
||||
"react-native-linear-gradient": "^2.5.6",
|
||||
"react-native-linear-gradient": "^2.8.0",
|
||||
"react-native-lottie-splash-screen": "^1.0.1",
|
||||
"react-native-mail": "git+https://github.com/status-im/react-native-mail.git#refs/tags/v6.1.2-status",
|
||||
"react-native-navigation": "^7.27.1",
|
||||
@@ -65,11 +66,11 @@
|
||||
"react-native-randombytes": "^3.6.1",
|
||||
"react-native-reanimated": "2.11.0",
|
||||
"react-native-redash": "^16.0.11",
|
||||
"react-native-svg": "13.10.0",
|
||||
"react-native-shake": "^3.3.1",
|
||||
"react-native-share": "^8.2.2",
|
||||
"react-native-static-safe-area-insets": "^2.2.0",
|
||||
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.5.39",
|
||||
"react-native-svg": "^9.8.4",
|
||||
"react-native-touch-id": "^4.4.1",
|
||||
"react-native-transparent-video": "git+https://github.com/status-im/react-native-transparent-video.git#refs/tags/0.0.9",
|
||||
"react-native-webview": "git+https://github.com/status-im/react-native-webview.git#refs/tags/v11.16.0-status",
|
||||
|
||||
|
Before Width: | Height: | Size: 527 B |
|
Before Width: | Height: | Size: 899 B |
|
Before Width: | Height: | Size: 607 B After Width: | Height: | Size: 607 B |
|
Before Width: | Height: | Size: 752 B After Width: | Height: | Size: 752 B |
|
After Width: | Height: | Size: 731 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 797 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 439 B |
|
After Width: | Height: | Size: 582 B |
|
Before Width: | Height: | Size: 947 B After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1006 B After Width: | Height: | Size: 809 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 749 B |
|
After Width: | Height: | Size: 1007 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 923 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 721 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 140 B |
|
After Width: | Height: | Size: 143 B |
@@ -22,15 +22,7 @@ function append_env_export() {
|
||||
echo "export ${VAR_NAME}=\"${VAR_VALUE}\";" >> "${SECRETS_FILE_PATH}"
|
||||
}
|
||||
|
||||
config=''
|
||||
if [[ -n "${STATUS_GO_SRC_OVERRIDE}" ]]; then
|
||||
config+="status-im.status-go.src-override=\"${STATUS_GO_SRC_OVERRIDE}\";"
|
||||
fi
|
||||
config+="status-im.commit-hash=\"$(git rev-parse --verify HEAD)\";"
|
||||
config+="status-im.build-type=\"$(must_get_env BUILD_TYPE)\";"
|
||||
config+="status-im.build-number=\"$(must_get_env BUILD_NUMBER)\";"
|
||||
config+="status-im.android.abi-split=\"$(must_get_env ANDROID_ABI_SPLIT)\";"
|
||||
config+="status-im.android.abi-include=\"$(must_get_env ANDROID_ABI_INCLUDE)\";"
|
||||
export COMMIT_HASH="$(git rev-parse --verify HEAD)"
|
||||
nixOpts=()
|
||||
|
||||
# We create if now so the trap knows its location
|
||||
@@ -73,6 +65,5 @@ else
|
||||
nixOpts+=("--option" "build-use-sandbox" "true")
|
||||
fi
|
||||
|
||||
nixOpts+=("--arg" "config" "{${config}}")
|
||||
|
||||
"${GIT_ROOT}/nix/scripts/build.sh" targets.mobile.android.release "${nixOpts[@]}"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
INVALID_CHANGES=$(grep -E -r '(re-frame/dispatch|rf/dispatch|re-frame/subscribe|rf/subscribe|rf/sub|<sub|>evt|status-im\.|status-im2\.)' './src/quo2')
|
||||
INVALID_CHANGES=$(grep -E -r '(re-frame/dispatch|rf/dispatch|re-frame/subscribe|rf/subscribe|rf/sub|<sub|>evt|status-im\.|status-im2\.)' --include '*.cljs' --include '*.clj' './src/quo2')
|
||||
|
||||
if test -n "$INVALID_CHANGES"; then
|
||||
echo "WARNING: re-frame, status-im are not allowed in quo2 components"
|
||||
|
||||
@@ -346,6 +346,13 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
|
||||
|
||||
(def react-native-transparent-video #js {:default #js {}})
|
||||
|
||||
(def react-native-gifted-charts
|
||||
#js
|
||||
{:BarChart #js {}
|
||||
:PieChart #js {}
|
||||
:LineChart #js {}
|
||||
:LineChartBicolor #js {}})
|
||||
|
||||
(def wallet-connect-client
|
||||
#js
|
||||
{:default #js {}
|
||||
@@ -409,6 +416,7 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
|
||||
"react-native-svg" react-native-svg
|
||||
"react-native-transparent-video" react-native-transparent-video
|
||||
"react-native-orientation-locker" react-native-orientation-locker
|
||||
"react-native-gifted-charts" react-native-gifted-charts
|
||||
"../src/js/worklets/core.js" worklet-factory
|
||||
"../src/js/worklets/shell/bottom_tabs.js" #js {}
|
||||
"../src/js/worklets/shell/home_stack.js" #js {}
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
# Quo Library
|
||||
|
||||
Quo is the name of our mobile *component library* that implements the [Status
|
||||
Design System for Mobile](https://www.figma.com/file/WQZcp6S0EnzxdTL4taoKDv/Design-System-for-Mobile).
|
||||
|
||||
The overarching goals of having this component library are:
|
||||
|
||||
- Achieve the highest possible fidelity between code and the design system in
|
||||
Figma.
|
||||
- Decouple components from ever-changing business requirements.
|
||||
|
||||
> [!NOTE]
|
||||
> This document captures our current practices and guidelines for implementing
|
||||
> the design system. For guidelines that apply across the entire project, take
|
||||
> a look at [new-guidelines](/doc/new-guidelines.md).
|
||||
|
||||
## Directory structure and file names
|
||||
|
||||
We follow one basic rule: mirror Figma *pages* and their *component names* in
|
||||
the directory structure.
|
||||
|
||||
For example, in the screenshot below we see the Figma page is `Banners`
|
||||
and the component name is `Banner`.
|
||||
|
||||
<img src="/doc/images/quo-component.png" width="600" />
|
||||
|
||||
Therefore, the structure should look like:
|
||||
|
||||
```
|
||||
quo2/
|
||||
└── components/
|
||||
└── banners/
|
||||
└── banner/
|
||||
├── component_spec.cljs
|
||||
├── style.cljs
|
||||
└── view.cljs
|
||||
```
|
||||
|
||||
Files `view.cljs`, `style.cljs`, and `component_spec.cljs` should always have
|
||||
the same name, regardless of component.
|
||||
|
||||
## Component API
|
||||
|
||||
Adhere to the **same component properties and values** used in a Figma component
|
||||
when translating it to Clojure. This means using the same names for props and
|
||||
the same values. If the Figma property is a boolean, use a question mark suffix
|
||||
to make the name more idiomatic in Clojure.
|
||||
|
||||
We have found over time that the less we drift from the design system the
|
||||
better. Some key benefits:
|
||||
|
||||
- It helps developers quickly check for issues when comparing the code with the
|
||||
source of truth in Figma.
|
||||
- It is easier for pull-request reviewers to double-check components for
|
||||
correctness.
|
||||
- It helps developers create preview screens that are identical or very similar
|
||||
to Figma, which aids in spotting bugs more easily.
|
||||
- It helps designers review all component variations in preview screens.
|
||||
|
||||
<img src="/doc/images/figma-properties.png" width="600" />
|
||||
|
||||
In the image above we can see the properties are `Type`, `State`, `Size`,
|
||||
`Icon`, `Theme`, and `Background`. Translated to Clojure:
|
||||
|
||||
```clojure
|
||||
;; ns quo2.components.buttons.button.view
|
||||
(def view
|
||||
[{:keys [type state size icon theme background]}]
|
||||
...)
|
||||
```
|
||||
|
||||
## Clojure var conventions
|
||||
|
||||
- Due to the fact that every `view` namespace should export only one component
|
||||
and to avoid the redundancy of `[some-component/some-component ...]`, name the
|
||||
public var `view` as well.
|
||||
- Try to make all other vars private because they should almost never be used
|
||||
directly.
|
||||
|
||||
## Component tests
|
||||
|
||||
We don't attempt to write component tests verifying how components look on the
|
||||
screen. Instead, we have found a middle ground, where the focus is on verifying
|
||||
if events are triggered as intended and that all component variations are
|
||||
rendered. We use [React Native Testing Library](https://callstack.github.io/react-native-testing-library/).
|
||||
|
||||
There are dozens of examples in the repository, so use them as a reference. A
|
||||
good and complete example is [quo2.components.avatars.user-avatar.component-spec](/src/quo2/components/avatars/user_avatar/component_spec.cljs)
|
||||
|
||||
## Do not couple the library with re-frame
|
||||
|
||||
Don't use re-frame inside this library (e.g. dispatch & subscribe). If a
|
||||
component needs to be stateful, the state should be local to its rendering
|
||||
lifecycle (using `reagent.core/atom`). Additionally, if the component requires
|
||||
any other data, it should be passed as arguments.
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
(defn view []
|
||||
(let [window-width (rf/sub [:dimensions/window-width])]
|
||||
[rn/pressable {:on-press #(rf/dispatch [:do-xyz])}
|
||||
(do-something window-width)]))
|
||||
|
||||
;; good
|
||||
(defn view [{:keys [window-width on-press]}]
|
||||
[rn/pressable {:on-press on-press}
|
||||
(do-something window-width)])
|
||||
```
|
||||
|
||||
## Themes
|
||||
|
||||
Our goal is to make all design system components *themeable*, which means they
|
||||
should not use, nor fallback to the OS theme, because themes are *contextual*
|
||||
and can be overridden in specific parts of the app.
|
||||
|
||||
To achieve this, use the higher-order function `quo2.theme/with-theme` to
|
||||
automatically inject the current theme context (based on the [React Context
|
||||
API](https://react.dev/learn/passing-data-deeply-with-context)).
|
||||
|
||||
Use the following pattern:
|
||||
|
||||
```clojure
|
||||
(ns quo2.components.<figma page>.<component name>.view
|
||||
(:require [quo2.theme :as quo.theme]))
|
||||
|
||||
(defn- view-internal [{:keys [theme]}]
|
||||
...)
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
```
|
||||
|
||||
Then pass the `theme` value down to all functions that may rely on the OS theme,
|
||||
like `quo2.foundations.colors/theme-colors` or `quo2.foundations.shadows/get`.
|
||||
|
||||
## Avoid using quo's version number in namespace aliases
|
||||
|
||||
When requiring quo2 namespaces, don't use the version number in the
|
||||
[alias](https://clojure.org/guides/learn/namespaces#_require), unless for a
|
||||
special reason you need to require both the old and new namespaces in the same
|
||||
file.
|
||||
|
||||
> [!NOTE]
|
||||
> Keep in mind that, at the moment, we need to keep both `src/quo/` and
|
||||
> `src/quo2/` directories in the repository, but eventually the old one will go
|
||||
> away and the version number will lose its meaning.
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
(ns ...
|
||||
(require [quo2.theme :as quo2.theme]
|
||||
[quo2.core :as quo2]))
|
||||
|
||||
;; good
|
||||
(ns ...
|
||||
(require [quo2.theme :as quo.theme]
|
||||
[quo2.core :as quo]))
|
||||
```
|
||||
|
||||
## Preview screens
|
||||
|
||||
Every component should be accompanied by a preview screen in
|
||||
`src/status_im2/contexts/quo_preview/`. Ideally, **all possible variations in
|
||||
Figma should be achievable in the preview screen** by changing the input values
|
||||
without resorting to code changes. Designers will also use this capability to
|
||||
review components in PR builds.
|
||||
|
||||
## Allow outermost containers to have their styles overridden
|
||||
|
||||
If a component needs to be wrapped in a `rn/view` instance to force it to be
|
||||
styled differently, consider changing the component to accept a
|
||||
`container-style` argument. This will help reduce the number of nodes to be
|
||||
rendered.
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
[rn/view {:style {:margin-right 12}}
|
||||
[quo/button
|
||||
{:size 32}
|
||||
:i/info]]
|
||||
|
||||
;; good
|
||||
[quo/button
|
||||
{:size 32
|
||||
:container-style {:margin-right 12}}
|
||||
:i/info]
|
||||
```
|
||||
@@ -1,41 +0,0 @@
|
||||
(ns quo2.components.avatars.account-avatar
|
||||
(:require [quo2.components.icon :as icons]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn get-border-radius
|
||||
[size]
|
||||
(case size
|
||||
80 16
|
||||
48 12
|
||||
32 10
|
||||
24 8
|
||||
20 6))
|
||||
|
||||
(defn get-inner-icon-sizes
|
||||
[size]
|
||||
(case size
|
||||
80 36
|
||||
48 24
|
||||
32 15
|
||||
24 11
|
||||
20 11))
|
||||
|
||||
(defn account-avatar
|
||||
[{:keys [size icon color]
|
||||
:or {size 80
|
||||
icon :i/placeholder
|
||||
color :purple}}]
|
||||
(let [icon-color (colors/custom-color-by-theme color 50 60)
|
||||
avatar-border-radius (get-border-radius size)
|
||||
inner-icon-size (get-inner-icon-sizes size)]
|
||||
[rn/view
|
||||
{:style {:width size
|
||||
:background-color icon-color
|
||||
:height size
|
||||
:border-radius avatar-border-radius
|
||||
:justify-content :center
|
||||
:align-items :center}}
|
||||
[icons/icon icon
|
||||
{:no-color true
|
||||
:size inner-icon-size}]]))
|
||||
@@ -0,0 +1,90 @@
|
||||
(ns quo2.components.avatars.account-avatar.component-spec
|
||||
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo2.components.avatars.account-avatar.style :as style]
|
||||
[test-helpers.component :as h]
|
||||
[quo2.foundations.colors :as colors]))
|
||||
|
||||
(h/describe "Account Avatar"
|
||||
(h/test "default render"
|
||||
(h/render [account-avatar/view])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji)))
|
||||
|
||||
(h/test "with emoji"
|
||||
(let [emoji "💸"]
|
||||
(h/render [account-avatar/view {:emoji emoji :size 80}])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/is-truthy (h/query-by-text emoji))))
|
||||
|
||||
(h/test "size 80 with emoji, with type - default"
|
||||
(let [opts {:emoji "🏝️"
|
||||
:size 80
|
||||
:type :default
|
||||
:customization-color :blue}]
|
||||
(h/render [account-avatar/view opts])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/has-style (h/get-by-label-text :account-avatar)
|
||||
{:height (:size opts)
|
||||
:width (:size opts)
|
||||
:borderRadius (style/get-border-radius (:size opts))
|
||||
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 60)})
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/has-style (h/query-by-label-text :account-emoji)
|
||||
{:fontSize (style/get-emoji-size (:size opts))})
|
||||
(h/is-truthy (h/query-by-text (:emoji opts)))))
|
||||
|
||||
(h/test "size 48 with emoji, with type - watch only"
|
||||
(let [opts {:emoji "💵"
|
||||
:size 48
|
||||
:type :watch-only
|
||||
:customization-color :purple}]
|
||||
(h/render [account-avatar/view opts])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/has-style
|
||||
(h/get-by-label-text :account-avatar)
|
||||
{:height (:size opts)
|
||||
:width (:size opts)
|
||||
:borderRadius (style/get-border-radius (:size opts))
|
||||
:borderWidth 1
|
||||
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 50 10 10)})
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/has-style (h/query-by-label-text :account-emoji)
|
||||
{:fontSize (style/get-emoji-size (:size opts))})
|
||||
(h/is-truthy (h/query-by-text (:emoji opts)))))
|
||||
|
||||
(h/test "size 28 with emoji, with type - default"
|
||||
(let [opts {:emoji "🏝️"
|
||||
:size 28
|
||||
:type :default
|
||||
:customization-color :turquoise}]
|
||||
(h/render [account-avatar/view opts])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/has-style (h/get-by-label-text :account-avatar)
|
||||
{:height (:size opts)
|
||||
:width (:size opts)
|
||||
:borderRadius (style/get-border-radius (:size opts))
|
||||
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 60)})
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/has-style (h/query-by-label-text :account-emoji)
|
||||
{:fontSize (style/get-emoji-size (:size opts))})
|
||||
(h/is-truthy (h/query-by-text (:emoji opts)))))
|
||||
|
||||
(h/test "size 16 with emoji, with type - watch only"
|
||||
(let [opts {:emoji "🎉"
|
||||
:size 16
|
||||
:type :watch-only
|
||||
:customization-color :copper}]
|
||||
(h/render [account-avatar/view opts])
|
||||
(h/is-truthy (h/query-by-label-text :account-avatar))
|
||||
(h/has-style
|
||||
(h/get-by-label-text :account-avatar)
|
||||
{:height (:size opts)
|
||||
:width (:size opts)
|
||||
:borderRadius (style/get-border-radius (:size opts))
|
||||
:borderWidth 0.8
|
||||
:backgroundColor (colors/custom-color-by-theme (:customization-color opts) 50 50 10 10)})
|
||||
(h/is-truthy (h/query-by-label-text :account-emoji))
|
||||
(h/has-style (h/query-by-label-text :account-emoji)
|
||||
{:fontSize (style/get-emoji-size (:size opts))})
|
||||
(h/is-truthy (h/query-by-text (:emoji opts))))))
|
||||
@@ -0,0 +1,69 @@
|
||||
(ns quo2.components.avatars.account-avatar.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def default-size 80)
|
||||
(def default-border-radius 16)
|
||||
(def default-padding 16)
|
||||
(def default-emoji-size 36)
|
||||
|
||||
(defn get-border-radius
|
||||
[size]
|
||||
(case size
|
||||
80 16
|
||||
48 12
|
||||
32 10
|
||||
28 8
|
||||
24 8
|
||||
20 6
|
||||
16 4
|
||||
default-border-radius))
|
||||
|
||||
(defn get-padding
|
||||
[size]
|
||||
(case size
|
||||
80 16
|
||||
48 8
|
||||
32 6
|
||||
28 6
|
||||
24 6
|
||||
20 4
|
||||
16 2
|
||||
default-padding))
|
||||
|
||||
(defn get-emoji-size
|
||||
[size]
|
||||
(case size
|
||||
80 36
|
||||
48 24
|
||||
32 15
|
||||
28 12
|
||||
24 11
|
||||
20 11
|
||||
16 11
|
||||
default-emoji-size))
|
||||
|
||||
(defn get-border-width
|
||||
[size]
|
||||
(case size
|
||||
16 0.8 ;; 0.8 px is for only size 16
|
||||
;; Rest of the size will have 1 px
|
||||
1))
|
||||
|
||||
(defn root-container
|
||||
[{:keys [type size theme customization-color]
|
||||
:or {size default-size
|
||||
customization-color :blue}}]
|
||||
(let [watch-only? (= type :watch-only)]
|
||||
(cond-> {:width size
|
||||
:height size
|
||||
:background-color (colors/custom-color-by-theme customization-color 50 60 nil nil theme)
|
||||
:border-radius (get-border-radius size)
|
||||
:border-color (if (= theme :light) colors/neutral-80-opa-5 colors/white-opa-5)
|
||||
:padding (get-padding size)
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
|
||||
watch-only?
|
||||
(assoc :border-width (get-border-width size)
|
||||
:background-color (colors/custom-color-by-theme customization-color 50 50 10 10 theme)))))
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
(ns quo2.components.avatars.account-avatar.view
|
||||
(:require [clojure.string :as string]
|
||||
[quo2.components.avatars.account-avatar.style :as style]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- view-internal
|
||||
"Opts:
|
||||
|
||||
:type - keyword -> :default/:watch-only
|
||||
|
||||
:emoji - string -> 🍑 [default]
|
||||
|
||||
:size - number -> 80 [default] /48/32/28/24/20/16
|
||||
|
||||
:customization-color - keyword or hexstring -> :blue/:army/... or #ABCEDF
|
||||
|
||||
:theme - keyword -> :light/:dark"
|
||||
[{:keys [size emoji]
|
||||
:or {size style/default-size
|
||||
emoji "🍑"}
|
||||
:as opts}]
|
||||
(let [emoji-size (style/get-emoji-size size)]
|
||||
[rn/view
|
||||
{:accessible true
|
||||
:accessibility-label :account-avatar
|
||||
:style (style/root-container opts)}
|
||||
[rn/text
|
||||
{:accessibility-label :account-emoji
|
||||
:adjusts-font-size-to-fit true
|
||||
:style {:font-size emoji-size}}
|
||||
(string/trim emoji)]]))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -9,13 +9,14 @@
|
||||
|
||||
(defn- initials
|
||||
[full-name size color]
|
||||
(let [amount-initials (if (= size :size/l) 2 1)]
|
||||
(let [amount-initials (if (= size :size/l) 2 1)
|
||||
channel-name (string/replace full-name "#" "")]
|
||||
[text/text
|
||||
{:accessibility-label :initials
|
||||
:size :paragraph-2
|
||||
:weight :semi-bold
|
||||
:style {:color color}}
|
||||
(utils.string/get-initials full-name amount-initials)]))
|
||||
(utils.string/get-initials channel-name amount-initials)]))
|
||||
|
||||
(defn- lock
|
||||
[locked? size]
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
(ns quo2.components.avatars.group-avatar
|
||||
(:require [quo2.components.icon :as icon]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def sizes
|
||||
{:icon {:small 12
|
||||
:medium 16
|
||||
:large 20}
|
||||
:container {:small 20
|
||||
:medium 32
|
||||
:large 48}})
|
||||
|
||||
;; TODO: this implementation does not support group display picture (can only display default group
|
||||
;; icon).
|
||||
(defn group-avatar
|
||||
[_]
|
||||
(fn [{:keys [color size]}]
|
||||
(let [container-size (get-in sizes [:container size])
|
||||
icon-size (get-in sizes [:icon size])]
|
||||
[rn/view
|
||||
{:width container-size
|
||||
:height container-size
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:border-radius (/ container-size 2)
|
||||
;:background-color (colors/custom-color-by-theme color 50 60) ; TODO: this is temporary only.
|
||||
;Issue: https://github.com/status-im/status-mobile/issues/14566
|
||||
:background-color color}
|
||||
[icon/icon :i/group
|
||||
{:size icon-size
|
||||
:color colors/white-opa-70}]])))
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
(ns quo2.components.avatars.group-avatar.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn container
|
||||
[{:keys [container-size customization-color theme]}]
|
||||
{:width container-size
|
||||
:height container-size
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:border-radius (/ container-size 2)
|
||||
:background-color
|
||||
(colors/theme-colors (colors/custom-color customization-color 50)
|
||||
(colors/custom-color customization-color 60)
|
||||
theme)})
|
||||
@@ -0,0 +1,43 @@
|
||||
(ns quo2.components.avatars.group-avatar.view
|
||||
(:require [quo2.components.icon :as icon]
|
||||
[quo2.theme :as quo.theme]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[quo2.components.avatars.group-avatar.style :as style]))
|
||||
|
||||
(def sizes
|
||||
{:icon {:x-small 12
|
||||
:small 16
|
||||
:medium 16
|
||||
:large 20
|
||||
:x-large 32}
|
||||
:container {:x-small 20
|
||||
:small 28
|
||||
:medium 32
|
||||
:large 48
|
||||
:x-large 80}})
|
||||
|
||||
(defn- view-internal
|
||||
[_]
|
||||
(fn [{:keys [size theme customization-color picture icon-name]
|
||||
:or {size :x-small
|
||||
customization-color :blue
|
||||
picture nil
|
||||
icon-name :i/group}}]
|
||||
(let [container-size (get-in sizes [:container size])
|
||||
icon-size (get-in sizes [:icon size])]
|
||||
[rn/view
|
||||
{:style (style/container {:container-size container-size
|
||||
:customization-color customization-color
|
||||
:theme theme})}
|
||||
(if picture
|
||||
[fast-image/fast-image
|
||||
{:source picture
|
||||
:style {:width container-size
|
||||
:height container-size}}]
|
||||
[icon/icon icon-name
|
||||
{:size icon-size
|
||||
:color colors/white-opa-70}])])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -17,6 +17,11 @@
|
||||
:status-indicator 12
|
||||
:status-indicator-border 2
|
||||
:font-size :paragraph-2}
|
||||
28 {:outer 28
|
||||
:inner 28
|
||||
:status-indicator 0
|
||||
:status-indicator-border 0
|
||||
:font-size :paragraph-2}
|
||||
:xs {:outer 24
|
||||
:inner 24
|
||||
:status-indicator 0
|
||||
|
||||
@@ -26,13 +26,14 @@
|
||||
uses `ring-background` to display the ring behind the initials when given. Otherwise,
|
||||
shows the `profile-picture` which already comes with the ring drawn."
|
||||
[{:keys [full-name status-indicator? online? size profile-picture ring-background
|
||||
customization-color static? muted? theme]
|
||||
customization-color static? muted? theme ring?]
|
||||
:or {status-indicator? true
|
||||
online? true
|
||||
ring? true
|
||||
size :big
|
||||
customization-color :turquoise}}]
|
||||
(let [full-name (or full-name "empty name")
|
||||
draw-ring? (when-not muted? (and ring-background (valid-ring-sizes size)))
|
||||
draw-ring? (and ring? (when-not muted? (and ring-background (valid-ring-sizes size))))
|
||||
outer-styles (style/outer size)
|
||||
;; Once image is loaded, fast image rerenders view with the help of reagent atom,
|
||||
;; But dynamic updates don't work when user-avatar is used inside hole-view
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
(defn render-banner
|
||||
[opts]
|
||||
(rtl/render (reagent/as-element [banner/banner opts])))
|
||||
(rtl/render (reagent/as-element [banner/view opts])))
|
||||
|
||||
(js/global.test "basic render of banner component"
|
||||
(fn []
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
(ns quo2.components.banners.banner.view
|
||||
(:require [quo2.components.banners.banner.style :as style]
|
||||
[quo2.components.counter.counter :as counter]
|
||||
[quo2.components.counter.counter.view :as counter]
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(defn banner
|
||||
[{:keys [hide-pin? latest-pin-text pins-count on-press]}]
|
||||
(defn- view-internal
|
||||
[{:keys [hide-pin? latest-pin-text pins-count on-press theme]}]
|
||||
(when (pos? pins-count)
|
||||
[rn/touchable-opacity
|
||||
{:accessibility-label :pinned-banner
|
||||
@@ -17,7 +18,7 @@
|
||||
(when-not hide-pin?
|
||||
[rn/view {:style style/icon}
|
||||
[icons/icon :i/pin
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white)
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:size 20}]])
|
||||
[rn/view {:style (style/text hide-pin?)}
|
||||
[text/text
|
||||
@@ -27,4 +28,6 @@
|
||||
[rn/view
|
||||
{:accessibility-label :pins-count
|
||||
:style style/counter}
|
||||
[counter/counter {:type :secondary} pins-count]]]))
|
||||
[counter/view {:type :secondary} pins-count]]]))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
|
||||
(h/describe "Browser input"
|
||||
(h/test "Renders empty in default state"
|
||||
(h/render [browser-input/browser-input
|
||||
(h/render [browser-input/view
|
||||
{:on-change-text (h/mock-fn)
|
||||
:value ""}])
|
||||
(h/is-truthy (h/get-by-label-text :browser-input)))
|
||||
|
||||
(h/test "On change text is fired"
|
||||
(let [on-change-text (h/mock-fn)]
|
||||
(h/render [browser-input/browser-input
|
||||
(h/render [browser-input/view
|
||||
{:on-change-text on-change-text
|
||||
:value "mock text"}])
|
||||
(h/fire-event :change-text (h/get-by-label-text :browser-input) "mock-text-new")
|
||||
@@ -19,38 +19,38 @@
|
||||
|
||||
(h/describe "Input Label"
|
||||
(h/test "Doesn't render label text when input is focused"
|
||||
(h/render [browser-input/browser-input
|
||||
(h/render [browser-input/view
|
||||
{:auto-focus true}])
|
||||
(h/is-null (h/query-by-label-text :browser-input-label)))
|
||||
|
||||
(h/test "Renders label text when input has a value and input is not focused"
|
||||
(h/render [browser-input/browser-input
|
||||
(h/render [browser-input/view
|
||||
{:default-value "mock default"}])
|
||||
(h/is-truthy (h/query-by-label-text :browser-input-label)))
|
||||
|
||||
(h/test "Renders site favicon when specified"
|
||||
(h/render [browser-input/browser-input
|
||||
(h/render [browser-input/view
|
||||
{:default-value "mock default" :favicon :i/verified}])
|
||||
(h/is-truthy (h/query-by-label-text :browser-input-favicon)))
|
||||
|
||||
(h/test "Renders lock icon when lock is enabled"
|
||||
(h/render [browser-input/browser-input
|
||||
(h/render [browser-input/view
|
||||
{:default-value "mock default" :locked? true}])
|
||||
(h/is-truthy (h/query-by-label-text :browser-input-locked-icon))))
|
||||
|
||||
(h/describe "Clear button"
|
||||
(h/test "Doesn't render in default state"
|
||||
(h/render [browser-input/browser-input])
|
||||
(h/render [browser-input/view])
|
||||
(h/is-null (h/query-by-label-text :browser-input-clear-button)))
|
||||
|
||||
(h/test "Renders when there is a value"
|
||||
(h/render [browser-input/browser-input
|
||||
(h/render [browser-input/view
|
||||
{:default-value "mock text"}])
|
||||
(h/is-truthy (h/query-by-label-text :browser-input-clear-button)))
|
||||
|
||||
(h/test "Is pressable"
|
||||
(let [on-clear (h/mock-fn)]
|
||||
(h/render [browser-input/browser-input
|
||||
(h/render [browser-input/view
|
||||
{:default-value "mock text"
|
||||
:on-clear on-clear}])
|
||||
(h/is-truthy (h/query-by-label-text :browser-input-clear-button))
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
[:cursor-color :placeholder-text-color :editable :on-change-text :on-focus
|
||||
:on-blur :on-clear :value :disabled? :blur? :customization-color :theme])
|
||||
|
||||
(defn browser-input-internal
|
||||
(defn- view-internal
|
||||
[{:keys [default-value]
|
||||
:or {default-value ""}}]
|
||||
(let [state (reagent/atom :default)
|
||||
@@ -141,4 +141,4 @@
|
||||
(when on-clear (on-clear)))
|
||||
:theme theme}])]]))))
|
||||
|
||||
(def browser-input (quo2.theme/with-theme browser-input-internal))
|
||||
(def view (quo2.theme/with-theme view-internal))
|
||||
|
||||
@@ -3,101 +3,87 @@
|
||||
|
||||
(defn custom-color-type
|
||||
[customization-color icon-only?]
|
||||
{:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color (colors/custom-color customization-color 50)
|
||||
:border-radius (when icon-only? 24)})
|
||||
{:icon-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color (colors/custom-color customization-color 50)
|
||||
:border-radius (when icon-only? 24)})
|
||||
|
||||
(defn grey-photo
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-70 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:icon-background-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
|
||||
:blur-overlay-color (if pressed?
|
||||
(colors/theme-colors colors/white-opa-50
|
||||
colors/neutral-80-opa-50
|
||||
theme)
|
||||
(colors/theme-colors colors/white-opa-40
|
||||
colors/neutral-80-opa-40
|
||||
theme))
|
||||
:blur-type (if (= theme :light) :light :dark)})
|
||||
{:icon-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-70 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:blur-overlay-color (if pressed?
|
||||
(colors/theme-colors colors/white-opa-50
|
||||
colors/neutral-80-opa-50
|
||||
theme)
|
||||
(colors/theme-colors colors/white-opa-40
|
||||
colors/neutral-80-opa-40
|
||||
theme))
|
||||
:blur-type (if (= theme :light) :light :dark)})
|
||||
|
||||
(defn grey-blur
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-70 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:background-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
|
||||
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme))})
|
||||
{:icon-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-70 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:background-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
|
||||
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme))})
|
||||
|
||||
(defn outline-blur
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:border-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
|
||||
(colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme))})
|
||||
{:icon-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:border-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
|
||||
(colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme))})
|
||||
|
||||
(defn grey
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:background-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-20 colors/neutral-60 theme)
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
|
||||
{:icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:background-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-20 colors/neutral-60 theme)
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
|
||||
|
||||
(defn dark-grey
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:background-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme)
|
||||
(colors/theme-colors colors/neutral-20 colors/neutral-90 theme))})
|
||||
{:icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:background-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme)
|
||||
(colors/theme-colors colors/neutral-20 colors/neutral-90 theme))})
|
||||
|
||||
(defn outline
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:border-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-70 theme))})
|
||||
{:icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:border-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-70 theme))})
|
||||
|
||||
(defn ghost
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:background-color (when pressed?
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
|
||||
{:icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:background-color (when pressed?
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
|
||||
|
||||
(defn black
|
||||
[pressed?]
|
||||
{:icon-color colors/white
|
||||
:label-color colors/white
|
||||
{:label-color colors/white
|
||||
:background-color (if pressed? colors/neutral-80 colors/neutral-95)})
|
||||
|
||||
(defn get-values
|
||||
[{:keys [customization-color theme type background pressed? icon-only?]}]
|
||||
(cond
|
||||
(= type :primary) (custom-color-type customization-color icon-only?)
|
||||
(= type :positive) (custom-color-type customization-color icon-only?)
|
||||
(= type :danger) (custom-color-type customization-color icon-only?)
|
||||
;; TODO Remove type blurred - https://github.com/status-im/status-mobile/issues/16535
|
||||
(and (= :photo background) (= type :grey)) (grey-photo theme pressed?)
|
||||
;; TODO Remove type blur-bg - https://github.com/status-im/status-mobile/issues/16535
|
||||
(or (= type :blur-bg)
|
||||
(and (= :blur background) (= type :grey))) (grey-blur theme pressed?)
|
||||
(and (= :blur background) (= type :outline)) (outline-blur theme pressed?)
|
||||
(= type :grey) (grey theme pressed?)
|
||||
(= type :dark-grey) (dark-grey theme pressed?)
|
||||
(= type :outline) (outline theme pressed?)
|
||||
(= type :ghost) (ghost theme pressed?)
|
||||
;; TODO: remove type shell - https://github.com/status-im/status-mobile/issues/16535
|
||||
(or (= type :shell) (= type :black)) (black pressed?)))
|
||||
(= type :primary) (custom-color-type customization-color icon-only?)
|
||||
(= type :positive) (custom-color-type customization-color icon-only?)
|
||||
(= type :danger) (custom-color-type customization-color icon-only?)
|
||||
(and (= :photo background) (= type :grey)) (grey-photo theme pressed?)
|
||||
(and (= :blur background) (= type :grey)) (grey-blur theme pressed?)
|
||||
(and (= :blur background) (= type :outline)) (outline-blur theme pressed?)
|
||||
(= type :grey) (grey theme pressed?)
|
||||
(= type :dark-grey) (dark-grey theme pressed?)
|
||||
(= type :outline) (outline theme pressed?)
|
||||
(= type :ghost) (ghost theme pressed?)
|
||||
(= type :black) (black pressed?)))
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
:bottom 0})
|
||||
|
||||
(defn icon-style
|
||||
[{:keys [icon-container-size icon-background-color icon-container-rounded?
|
||||
[{:keys [icon-container-size icon-container-rounded?
|
||||
icon-size margin-left margin-right]}]
|
||||
(cond-> (merge {:margin-left margin-left
|
||||
:margin-right margin-right
|
||||
@@ -16,31 +16,27 @@
|
||||
:justify-content :center})
|
||||
icon-container-size
|
||||
(assoc :width icon-container-size :height icon-container-size)
|
||||
icon-background-color
|
||||
(assoc :background-color icon-background-color)
|
||||
icon-container-rounded?
|
||||
(assoc :border-radius (/ (or icon-container-size icon-size) 2))))
|
||||
|
||||
(defn icon-left-icon-style
|
||||
[{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded?
|
||||
[{:keys [override-margins size icon-container-size icon-container-rounded?
|
||||
icon-size]}]
|
||||
(icon-style
|
||||
{:margin-left (or (get override-margins :left)
|
||||
(if (= size 40) 12 8))
|
||||
:margin-right (or (get override-margins :right) 4)
|
||||
:icon-container-size icon-container-size
|
||||
:icon-background-color icon-background-color
|
||||
:icon-container-rounded? icon-container-rounded?
|
||||
:icon-size icon-size}))
|
||||
|
||||
(defn icon-right-icon-style
|
||||
[{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded?
|
||||
[{:keys [override-margins size icon-container-size icon-container-rounded?
|
||||
icon-size]}]
|
||||
(icon-style {:margin-left (or (get override-margins :left) 4)
|
||||
:margin-right (or (get override-margins :right)
|
||||
(if (= size 40) 12 8))
|
||||
:icon-container-size icon-container-size
|
||||
:icon-background-color icon-background-color
|
||||
:icon-container-rounded? icon-container-rounded?
|
||||
:icon-size icon-size}))
|
||||
|
||||
@@ -53,54 +49,67 @@
|
||||
56 12
|
||||
40 12
|
||||
32 10
|
||||
8))})
|
||||
24 8
|
||||
12))})
|
||||
|
||||
(defn style-container
|
||||
[{:keys [size disabled border-radius background-color border-color icon-only? icon-above width
|
||||
[{:keys [size disabled? border-radius background-color border-color icon-only? icon-top
|
||||
icon-left icon-right]}]
|
||||
(merge {:height size
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction (if icon-above :column :row)
|
||||
:flex-direction (if icon-top :column :row)
|
||||
:padding-horizontal (when-not (or icon-only? icon-left icon-right)
|
||||
(case size
|
||||
56 16
|
||||
56 (if border-color 10 11)
|
||||
40 16
|
||||
32 12
|
||||
8))
|
||||
24 7
|
||||
16))
|
||||
:padding-left (when-not (or icon-only? icon-left)
|
||||
(case size
|
||||
56 16
|
||||
56 nil
|
||||
40 16
|
||||
32 12
|
||||
8))
|
||||
24 8
|
||||
16))
|
||||
:padding-right (when-not (or icon-only? icon-right)
|
||||
(case size
|
||||
56 16
|
||||
56 nil
|
||||
40 16
|
||||
32 12
|
||||
8))
|
||||
24 8
|
||||
16))
|
||||
:padding-top (when-not (or icon-only? icon-left icon-right)
|
||||
(case size
|
||||
56 0
|
||||
40 9
|
||||
32 5
|
||||
3))
|
||||
40 (if border-color 8 9)
|
||||
32 (if border-color 4 5)
|
||||
24 (if border-color 0 1)
|
||||
(if border-color 8 9)))
|
||||
:padding-bottom (when-not (or icon-only? icon-left icon-right)
|
||||
(case size
|
||||
56 0
|
||||
40 9
|
||||
32 5
|
||||
4))
|
||||
24 4
|
||||
9))
|
||||
:overflow :hidden
|
||||
:background-color background-color}
|
||||
(shape-style-container size border-radius)
|
||||
(when width
|
||||
{:width width})
|
||||
:background-color background-color
|
||||
:border-radius (if border-radius
|
||||
border-radius
|
||||
(case size
|
||||
56 12
|
||||
40 12
|
||||
32 10
|
||||
24 8
|
||||
12))
|
||||
:border-color border-color
|
||||
:border-width (when border-color 1)}
|
||||
(when icon-only?
|
||||
{:width size})
|
||||
(when border-color
|
||||
{:border-color border-color
|
||||
:border-width 1})
|
||||
(when disabled
|
||||
(when disabled?
|
||||
{:opacity 0.3})))
|
||||
|
||||
@@ -15,25 +15,24 @@
|
||||
opts
|
||||
{on-press callback
|
||||
on-long-press callback
|
||||
disabled boolean
|
||||
:type :primary/:positive:grey/:dark-grey/:outline/:ghost/
|
||||
:danger/:black (TODO remove :photo-bg/:blur-bg/:blur-bg-outline/:shell/:community)
|
||||
disabled? boolean
|
||||
:type :primary/:positive/:grey/:dark-grey/:outline/:ghost/
|
||||
:danger/:black
|
||||
background :photo/:blur or nil
|
||||
:size 40 [default] /32/24/56
|
||||
:icon true/false
|
||||
:above :icon-keyword
|
||||
:before :icon-keyword
|
||||
:after :icon-keyword}
|
||||
:icon-only? true/false
|
||||
:icon-top :icon-keyword
|
||||
:icon-left :icon-keyword
|
||||
:icon-right :icon-keyword}
|
||||
:customization-color keyword or hexstring
|
||||
:theme :light/:dark
|
||||
only icon
|
||||
[button {:icon true} :i/close-circle]"
|
||||
[button {:icon-only? true} :i/close-circle]"
|
||||
[_ _]
|
||||
(let [pressed? (reagent/atom false)]
|
||||
(fn
|
||||
[{:keys [on-press on-long-press disabled type background size before after above
|
||||
width customization-color theme override-background-color
|
||||
accessibility-label icon style inner-style]
|
||||
[{:keys [on-press on-long-press disabled? type background size icon-left icon-right icon-top
|
||||
customization-color theme accessibility-label icon-only? container-style inner-style]
|
||||
:or {type :primary
|
||||
size 40
|
||||
customization-color (cond (= type :primary) :blue
|
||||
@@ -41,24 +40,17 @@
|
||||
(= type :danger) :danger
|
||||
:else nil)}}
|
||||
children]
|
||||
(let [icon-only? icon ;; TODO Update external api to icon-only? -
|
||||
;; https://github.com/status-im/status-mobile/issues/16535
|
||||
container-style style ;; TODO Update external api to container-style and remove prop width
|
||||
icon-left before ;; TODO Update external api to icon-left
|
||||
icon-right after ;; TODO Update external api to icon-right
|
||||
icon-above above ;; TODO Update external api to icon-above
|
||||
{:keys [icon-color icon-secondary-color background-color label-color border-color blur-type
|
||||
blur-overlay-color icon-background-color border-radius]}
|
||||
(let [{:keys [icon-color background-color label-color border-color blur-type
|
||||
blur-overlay-color border-radius]}
|
||||
(button-properties/get-values {:customization-color customization-color
|
||||
:background background
|
||||
:type type
|
||||
:theme theme
|
||||
:pressed? @pressed?
|
||||
:icon-only? icon-only?})
|
||||
icon-size (when (= 24 size) 12)
|
||||
icon-secondary-color (or icon-secondary-color icon-color)]
|
||||
icon-size (when (= 24 size) 12)]
|
||||
[rn/touchable-without-feedback
|
||||
{:disabled disabled
|
||||
{:disabled disabled?
|
||||
:accessibility-label accessibility-label
|
||||
:on-press-in #(reset! pressed? true)
|
||||
:on-press-out #(reset! pressed? nil)
|
||||
@@ -67,21 +59,18 @@
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(style/shape-style-container size border-radius)
|
||||
{:width width}
|
||||
container-style)}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(style/style-container {:size size
|
||||
:disabled disabled
|
||||
:border-radius border-radius
|
||||
:background-color
|
||||
(or override-background-color background-color)
|
||||
:border-color border-color
|
||||
:icon-only? icon-only?
|
||||
:icon-above icon-above
|
||||
:width width
|
||||
:icon-left icon-left
|
||||
:icon-right icon-right})
|
||||
(style/style-container {:size size
|
||||
:disabled? disabled?
|
||||
:border-radius border-radius
|
||||
:background-color background-color
|
||||
:border-color border-color
|
||||
:icon-only? icon-only?
|
||||
:icon-top icon-top
|
||||
:icon-left icon-left
|
||||
:icon-right icon-right})
|
||||
inner-style)}
|
||||
(when customization-color
|
||||
[customization-colors/overlay
|
||||
@@ -94,26 +83,25 @@
|
||||
:blur-type blur-type
|
||||
:overlay-color blur-overlay-color
|
||||
:style style/blur-view}])
|
||||
(when icon-above
|
||||
(when icon-top
|
||||
[rn/view
|
||||
[quo2.icons/icon icon-above
|
||||
[quo2.icons/icon icon-top
|
||||
{:container-style {:margin-bottom 2}
|
||||
:color icon-secondary-color
|
||||
:color icon-color
|
||||
:size icon-size}]])
|
||||
(when icon-left
|
||||
[rn/view
|
||||
{:style (style/icon-left-icon-style
|
||||
{:size size
|
||||
:icon-background-color icon-background-color
|
||||
:icon-size icon-size})}
|
||||
{:size size
|
||||
:icon-size icon-size})}
|
||||
[quo2.icons/icon icon-left
|
||||
{:color icon-secondary-color
|
||||
{:color icon-color
|
||||
:size icon-size}]])
|
||||
[rn/view
|
||||
(cond
|
||||
icon-only?
|
||||
[quo2.icons/icon children
|
||||
{:color icon-color
|
||||
{:color label-color
|
||||
:size icon-size}]
|
||||
|
||||
(string? children)
|
||||
@@ -129,11 +117,10 @@
|
||||
(when icon-right
|
||||
[rn/view
|
||||
{:style (style/icon-right-icon-style
|
||||
{:size size
|
||||
:icon-background-color icon-background-color
|
||||
:icon-size icon-size})}
|
||||
{:size size
|
||||
:icon-size icon-size})}
|
||||
[quo2.icons/icon icon-right
|
||||
{:color icon-secondary-color
|
||||
{:color icon-color
|
||||
:size icon-size}]])]]]))))
|
||||
|
||||
(def button (theme/with-theme button-internal))
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
(ns quo2.components.buttons.composer-button.component-spec
|
||||
(:require [quo2.components.buttons.composer-button.view :as composer-button]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "button tests"
|
||||
(h/test "default render of composer button component"
|
||||
(h/render [composer-button/view
|
||||
{:icon :i/placeholder
|
||||
:accessibility-label "test-button"}])
|
||||
(h/is-truthy (h/get-by-label-text "test-button")))
|
||||
|
||||
(h/test "button on-press works"
|
||||
(let [event (h/mock-fn)]
|
||||
(h/render [composer-button/view
|
||||
{:icon :i/placeholder
|
||||
:on-press event
|
||||
:accessibility-label "test-button"}])
|
||||
(h/fire-event :press (h/get-by-label-text "test-button"))
|
||||
(h/was-called event)))
|
||||
|
||||
(h/test "button on-press disabled when disabled"
|
||||
(let [event (h/mock-fn)]
|
||||
(h/render [composer-button/view
|
||||
{:icon :i/placeholder
|
||||
:on-press event
|
||||
:accessibility-label "test-button"
|
||||
:disabled? true}])
|
||||
(h/fire-event :press (h/get-by-label-text "test-button"))
|
||||
(h/was-not-called event)))
|
||||
|
||||
(h/test "button on-long-press works"
|
||||
(let [event (h/mock-fn)]
|
||||
(h/render [composer-button/view
|
||||
{:icon :i/placeholder
|
||||
:on-long-press event
|
||||
:accessibility-label "test-button"}])
|
||||
(h/fire-event :long-press (h/get-by-label-text "test-button"))
|
||||
(h/was-called event))))
|
||||