Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5bcaa6562f | ||
|
|
71532be5f8 | ||
|
|
2c44882c35 | ||
|
|
2493b8ad4b | ||
|
|
56d0913d4b | ||
|
|
a3ce2aa578 | ||
|
|
446d71063c | ||
|
|
b1aec54e4c | ||
|
|
cb19a31a5f | ||
|
|
0890b1b1b5 | ||
|
|
2191f68883 | ||
|
|
d1941fe002 | ||
|
|
540e5be290 | ||
|
|
7e47057b2e | ||
|
|
86d5a3c4e6 | ||
|
|
6975d6ac48 | ||
|
|
e8ced0a714 | ||
|
|
c5d74dc758 | ||
|
|
4fe2ccaa84 | ||
|
|
d042f40e69 | ||
|
|
58d20967ae | ||
|
|
6858884c83 | ||
|
|
78621207e1 | ||
|
|
d3b4f60848 | ||
|
|
694591ad5c | ||
|
|
e8682ccbf6 | ||
|
|
3973e886f8 | ||
|
|
7e8f1fac8a | ||
|
|
77ddd8688f | ||
|
|
62945205a0 | ||
|
|
adc458d8ff | ||
|
|
b4bb9c50fa | ||
|
|
19526508f2 | ||
|
|
a17efa7299 | ||
|
|
c7bc16608a | ||
|
|
3c9ad509cd | ||
|
|
eea55b22d7 | ||
|
|
7efd1e5d6b | ||
|
|
b264d25b69 | ||
|
|
03f501ca7b | ||
|
|
6598873343 | ||
|
|
a60235abf3 | ||
|
|
b5a8f0a127 | ||
|
|
7d0dfec22c | ||
|
|
51fa99affa | ||
|
|
369aed389c | ||
|
|
10d9c34559 | ||
|
|
8ccf2d1596 |
@@ -5,7 +5,6 @@ project-board:
|
|||||||
min-reviewers: 1
|
min-reviewers: 1
|
||||||
tested-pr-label-name: 'Tested - Issues'
|
tested-pr-label-name: 'Tested - Issues'
|
||||||
contributor-column-name: 'CONTRIBUTOR'
|
contributor-column-name: 'CONTRIBUTOR'
|
||||||
to-rebase-column-name: 'TO REBASE'
|
|
||||||
review-column-name: 'REVIEW'
|
review-column-name: 'REVIEW'
|
||||||
test-column-name: 'E2E Tests'
|
test-column-name: 'E2E Tests'
|
||||||
|
|
||||||
|
|||||||
@@ -218,23 +218,18 @@ release-android: keystore build-android ##@build Build signed Android APK
|
|||||||
|
|
||||||
release-ios: export TARGET := ios
|
release-ios: export TARGET := ios
|
||||||
release-ios: export BUILD_ENV ?= prod
|
release-ios: export BUILD_ENV ?= prod
|
||||||
release-ios: watchman-clean ##@build Build release for iOS release
|
release-ios: watchman-clean ios-clean jsbundle ##@build Build release for iOS release
|
||||||
@git clean -dxf -f target/ios && \
|
xcodebuild \
|
||||||
$(MAKE) jsbundle-ios && \
|
-scheme StatusIm \
|
||||||
xcodebuild -workspace ios/StatusIm.xcworkspace -scheme StatusIm -configuration Release -destination 'generic/platform=iOS' -UseModernBuildSystem=N clean archive
|
-configuration Release \
|
||||||
|
-workspace ios/StatusIm.xcworkspace \
|
||||||
|
-destination 'generic/platform=iOS' \
|
||||||
|
-UseModernBuildSystem=N clean archive
|
||||||
|
|
||||||
jsbundle-android: SHELL := /bin/sh
|
jsbundle: SHELL := /bin/sh
|
||||||
jsbundle-android: export TARGET := android
|
jsbundle: export BUILD_ENV ?= prod
|
||||||
jsbundle-android: export BUILD_ENV ?= prod
|
jsbundle: ##@build Build JavaScript and Clojurescript bundle for iOS and Android
|
||||||
jsbundle-android: ##@jsbundle Compile JavaScript and Clojurescript into app directory
|
nix/scripts/build.sh targets.mobile.jsbundle
|
||||||
# Call nix-build to build the 'targets.mobile.android.jsbundle' attribute and copy the.js files to the project root
|
|
||||||
nix/scripts/build.sh targets.mobile.android.jsbundle && \
|
|
||||||
mv result/*.js ./
|
|
||||||
|
|
||||||
jsbundle-ios: export TARGET := ios
|
|
||||||
jsbundle-ios: export BUILD_ENV ?= prod
|
|
||||||
jsbundle-ios: ##@jsbundle Compile JavaScript and Clojure into index.ios.js
|
|
||||||
yarn shadow-cljs release mobile
|
|
||||||
|
|
||||||
#--------------
|
#--------------
|
||||||
# status-go lib
|
# status-go lib
|
||||||
@@ -365,6 +360,7 @@ component-test: ##@test Run component tests once in NodeJS
|
|||||||
yarn shadow-cljs compile component-test && \
|
yarn shadow-cljs compile component-test && \
|
||||||
jest --config=test/jest/jest.config.js
|
jest --config=test/jest/jest.config.js
|
||||||
|
|
||||||
|
#--------------
|
||||||
# Other
|
# Other
|
||||||
#--------------
|
#--------------
|
||||||
|
|
||||||
@@ -373,6 +369,10 @@ geth-connect: ##@other Connect to Geth on the device
|
|||||||
adb forward tcp:8545 tcp:8545 && \
|
adb forward tcp:8545 tcp:8545 && \
|
||||||
build/bin/geth attach http://localhost:8545
|
build/bin/geth attach http://localhost:8545
|
||||||
|
|
||||||
|
ios-clean: SHELL := /bin/sh
|
||||||
|
ios-clean: ##@prepare Clean iOS build artifacts
|
||||||
|
git clean -dxf -f target/ios
|
||||||
|
|
||||||
android-clean: export TARGET := gradle
|
android-clean: export TARGET := gradle
|
||||||
android-clean: ##@prepare Clean Gradle state
|
android-clean: ##@prepare Clean Gradle state
|
||||||
git clean -dxf -f ./android/app/build; \
|
git clean -dxf -f ./android/app/build; \
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
library 'status-jenkins-lib@v1.7.3'
|
library 'status-jenkins-lib@v1.7.9'
|
||||||
|
|
||||||
/* Options section can't access functions in objects. */
|
/* Options section can't access functions in objects. */
|
||||||
def isPRBuild = utils.isPRBuild()
|
def isPRBuild = utils.isPRBuild()
|
||||||
@@ -49,7 +49,6 @@ pipeline {
|
|||||||
stage('Prep') {
|
stage('Prep') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
utils.doGitRebasePR()
|
|
||||||
utils.symlinkEnv()
|
utils.symlinkEnv()
|
||||||
println("Build Number: ${utils.genBuildNumber()}")
|
println("Build Number: ${utils.genBuildNumber()}")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
library 'status-jenkins-lib@v1.7.3'
|
library 'status-jenkins-lib@v1.7.9'
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent { label 'linux' }
|
agent { label 'linux' }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
library 'status-jenkins-lib@v1.7.3'
|
library 'status-jenkins-lib@v1.7.9'
|
||||||
|
|
||||||
/* Options section can't access functions in objects. */
|
/* Options section can't access functions in objects. */
|
||||||
def isPRBuild = utils.isPRBuild()
|
def isPRBuild = utils.isPRBuild()
|
||||||
@@ -48,7 +48,6 @@ pipeline {
|
|||||||
stage('Prep') {
|
stage('Prep') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
utils.doGitRebasePR()
|
|
||||||
utils.symlinkEnv()
|
utils.symlinkEnv()
|
||||||
println("Build Number: ${utils.genBuildNumber()}")
|
println("Build Number: ${utils.genBuildNumber()}")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
library 'status-jenkins-lib@v1.7.3'
|
library 'status-jenkins-lib@v1.7.9'
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent { label params.AGENT_LABEL }
|
agent { label params.AGENT_LABEL }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
library 'status-jenkins-lib@v1.7.3'
|
library 'status-jenkins-lib@v1.7.9'
|
||||||
|
|
||||||
/* Options section can't access functions in objects. */
|
/* Options section can't access functions in objects. */
|
||||||
def isPRBuild = utils.isPRBuild()
|
def isPRBuild = utils.isPRBuild()
|
||||||
@@ -41,13 +41,6 @@ pipeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
stage('Prep') {
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
utils.doGitRebasePR()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Checks') {
|
stage('Checks') {
|
||||||
parallel {
|
parallel {
|
||||||
stage('Lint') {
|
stage('Lint') {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
library 'status-jenkins-lib@v1.7.3'
|
library 'status-jenkins-lib@v1.7.9'
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
library 'status-jenkins-lib@v1.7.3'
|
library 'status-jenkins-lib@v1.7.9'
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
library 'status-jenkins-lib@v1.7.3'
|
library 'status-jenkins-lib@v1.7.9'
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
library 'status-jenkins-lib@v1.7.3'
|
library 'status-jenkins-lib@v1.7.9'
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent { label 'macos' }
|
agent { label 'macos' }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
library 'status-jenkins-lib@v1.7.3'
|
library 'status-jenkins-lib@v1.7.9'
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent { label 'linux' }
|
agent { label 'linux' }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
library 'status-jenkins-lib@v1.7.3'
|
library 'status-jenkins-lib@v1.7.9'
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent {
|
agent {
|
||||||
|
|||||||
@@ -365,6 +365,43 @@ dispatch.
|
|||||||
(str "Hello " username)]])
|
(str "Hello " username)]])
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Registering effects
|
||||||
|
|
||||||
|
When registering re-frame effects (`reg-fx`), prefer to expose a data-only
|
||||||
|
interface because that will allow event handlers to stay pure.
|
||||||
|
|
||||||
|
For instance, if an effect needs a `on-success` callback, allow it to receive a
|
||||||
|
*re-frame event vector*. This approach is used by us in the [json-rpc/call
|
||||||
|
effect](src/status_im2/common/json_rpc/events.cljs), but also by third-party
|
||||||
|
effects, such as https://github.com/Day8/re-frame-http-fx. For the complete
|
||||||
|
rationale, see [PR #15936](https://github.com/status-im/status-mobile/pull/15936).
|
||||||
|
|
||||||
|
### Using the effect `:json-rpc/call`
|
||||||
|
|
||||||
|
Prefer the pure version of `:json-rpc/call` (no callbacks).
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
;; not as good
|
||||||
|
(rf/defn accept-contact-request
|
||||||
|
{:events [:activity-center.contact-requests/accept]}
|
||||||
|
[_ contact-id]
|
||||||
|
{:json-rpc/call
|
||||||
|
[{:method "wakuext_acceptContactRequest"
|
||||||
|
:params [{:id contact-id}]
|
||||||
|
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
|
||||||
|
:on-error #(rf/dispatch [:activity-center.contact-requests/accept-error contact-id %])}]})
|
||||||
|
|
||||||
|
;; better
|
||||||
|
(rf/defn accept-contact-request
|
||||||
|
{:events [:activity-center.contact-requests/accept]}
|
||||||
|
[_ contact-id]
|
||||||
|
{:json-rpc/call
|
||||||
|
[{:method "wakuext_acceptContactRequest"
|
||||||
|
:params [{:id contact-id}]
|
||||||
|
:on-success [:sanitize-messages-and-process-response]
|
||||||
|
:on-error [:activity-center.contact-requests/accept-error contact-id]}]})
|
||||||
|
```
|
||||||
|
|
||||||
### Registering event handlers
|
### Registering event handlers
|
||||||
|
|
||||||
Events must always be declared with the `utils.fx/defn` macro. Also, don't use
|
Events must always be declared with the `utils.fx/defn` macro. Also, don't use
|
||||||
|
|||||||
@@ -182,17 +182,6 @@ def build_ios_e2e
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def upload_to_diawi(source)
|
|
||||||
diawi(
|
|
||||||
file: source,
|
|
||||||
timeout: 120,
|
|
||||||
check_status_delay: 5,
|
|
||||||
token: ENV['DIAWI_TOKEN']
|
|
||||||
)
|
|
||||||
# save the URL to a file for use in CI
|
|
||||||
File.write('diawi.out', lane_context[SharedValues::UPLOADED_FILE_LINK_TO_DIAWI])
|
|
||||||
end
|
|
||||||
|
|
||||||
platform :ios do
|
platform :ios do
|
||||||
desc '`fastlane ios adhoc` - ad-hoc lane for iOS.'
|
desc '`fastlane ios adhoc` - ad-hoc lane for iOS.'
|
||||||
desc 'This lane is used for PRs, Releases, etc.'
|
desc 'This lane is used for PRs, Releases, etc.'
|
||||||
@@ -265,18 +254,6 @@ platform :ios do
|
|||||||
# In the future we can try using 'oldest_build_allowed'
|
# In the future we can try using 'oldest_build_allowed'
|
||||||
end
|
end
|
||||||
|
|
||||||
desc '`fastlane ios upload-diawi` - upload .ipa to diawi'
|
|
||||||
desc 'expects to have an .ipa prepared: `status-ios/StatusIm.ipa`'
|
|
||||||
desc 'expects to have a diawi token as DIAWI_TOKEN env variable'
|
|
||||||
desc 'expects to have a github token as GITHUB_TOKEN env variable'
|
|
||||||
desc "will fails if file isn't there"
|
|
||||||
desc '---'
|
|
||||||
desc 'Output: writes `fastlane/diawi.out` file url of the uploded file'
|
|
||||||
lane :upload_diawi do
|
|
||||||
ipa = ENV['DIAWI_IPA'] || 'status-ios/StatusIm.ipa'
|
|
||||||
upload_to_diawi(ipa)
|
|
||||||
end
|
|
||||||
|
|
||||||
desc '`fastlane ios saucelabs` - upload .app to sauce labs'
|
desc '`fastlane ios saucelabs` - upload .app to sauce labs'
|
||||||
desc 'also notifies in a GitHub comments'
|
desc 'also notifies in a GitHub comments'
|
||||||
desc 'expects to have an .apk prepared: `result/app.apk`'
|
desc 'expects to have an .apk prepared: `result/app.apk`'
|
||||||
|
|||||||
@@ -3,21 +3,21 @@ GEM
|
|||||||
specs:
|
specs:
|
||||||
CFPropertyList (3.0.6)
|
CFPropertyList (3.0.6)
|
||||||
rexml
|
rexml
|
||||||
addressable (2.8.1)
|
addressable (2.8.4)
|
||||||
public_suffix (>= 2.0.2, < 6.0)
|
public_suffix (>= 2.0.2, < 6.0)
|
||||||
artifactory (3.0.15)
|
artifactory (3.0.15)
|
||||||
atomos (0.1.3)
|
atomos (0.1.3)
|
||||||
aws-eventstream (1.2.0)
|
aws-eventstream (1.2.0)
|
||||||
aws-partitions (1.728.0)
|
aws-partitions (1.766.0)
|
||||||
aws-sdk-core (3.170.0)
|
aws-sdk-core (3.173.0)
|
||||||
aws-eventstream (~> 1, >= 1.0.2)
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
aws-partitions (~> 1, >= 1.651.0)
|
aws-partitions (~> 1, >= 1.651.0)
|
||||||
aws-sigv4 (~> 1.5)
|
aws-sigv4 (~> 1.5)
|
||||||
jmespath (~> 1, >= 1.6.1)
|
jmespath (~> 1, >= 1.6.1)
|
||||||
aws-sdk-kms (1.63.0)
|
aws-sdk-kms (1.64.0)
|
||||||
aws-sdk-core (~> 3, >= 3.165.0)
|
aws-sdk-core (~> 3, >= 3.165.0)
|
||||||
aws-sigv4 (~> 1.1)
|
aws-sigv4 (~> 1.1)
|
||||||
aws-sdk-s3 (1.119.1)
|
aws-sdk-s3 (1.122.0)
|
||||||
aws-sdk-core (~> 3, >= 3.165.0)
|
aws-sdk-core (~> 3, >= 3.165.0)
|
||||||
aws-sdk-kms (~> 1)
|
aws-sdk-kms (~> 1)
|
||||||
aws-sigv4 (~> 1.4)
|
aws-sigv4 (~> 1.4)
|
||||||
@@ -66,7 +66,7 @@ GEM
|
|||||||
faraday_middleware (1.2.0)
|
faraday_middleware (1.2.0)
|
||||||
faraday (~> 1.0)
|
faraday (~> 1.0)
|
||||||
fastimage (2.2.6)
|
fastimage (2.2.6)
|
||||||
fastlane (2.212.1)
|
fastlane (2.212.2)
|
||||||
CFPropertyList (>= 2.3, < 4.0.0)
|
CFPropertyList (>= 2.3, < 4.0.0)
|
||||||
addressable (>= 2.8, < 3.0.0)
|
addressable (>= 2.8, < 3.0.0)
|
||||||
artifactory (~> 3.0)
|
artifactory (~> 3.0)
|
||||||
@@ -106,10 +106,8 @@ GEM
|
|||||||
xcpretty (~> 0.3.0)
|
xcpretty (~> 0.3.0)
|
||||||
xcpretty-travis-formatter (>= 0.0.3)
|
xcpretty-travis-formatter (>= 0.0.3)
|
||||||
fastlane-plugin-clean_testflight_testers (0.3.0)
|
fastlane-plugin-clean_testflight_testers (0.3.0)
|
||||||
fastlane-plugin-diawi (2.1.0)
|
|
||||||
rest-client (>= 2.0.0)
|
|
||||||
gh_inspector (1.1.3)
|
gh_inspector (1.1.3)
|
||||||
google-apis-androidpublisher_v3 (0.36.0)
|
google-apis-androidpublisher_v3 (0.42.0)
|
||||||
google-apis-core (>= 0.11.0, < 2.a)
|
google-apis-core (>= 0.11.0, < 2.a)
|
||||||
google-apis-core (0.11.0)
|
google-apis-core (0.11.0)
|
||||||
addressable (~> 2.5, >= 2.5.1)
|
addressable (~> 2.5, >= 2.5.1)
|
||||||
@@ -140,7 +138,7 @@ GEM
|
|||||||
google-cloud-core (~> 1.6)
|
google-cloud-core (~> 1.6)
|
||||||
googleauth (>= 0.16.2, < 2.a)
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
mini_mime (~> 1.0)
|
mini_mime (~> 1.0)
|
||||||
googleauth (1.3.0)
|
googleauth (1.5.2)
|
||||||
faraday (>= 0.17.3, < 3.a)
|
faraday (>= 0.17.3, < 3.a)
|
||||||
jwt (>= 1.4, < 3.0)
|
jwt (>= 1.4, < 3.0)
|
||||||
memoist (~> 0.16)
|
memoist (~> 0.16)
|
||||||
@@ -148,7 +146,6 @@ GEM
|
|||||||
os (>= 0.9, < 2.0)
|
os (>= 0.9, < 2.0)
|
||||||
signet (>= 0.16, < 2.a)
|
signet (>= 0.16, < 2.a)
|
||||||
highline (2.0.3)
|
highline (2.0.3)
|
||||||
http-accept (1.7.0)
|
|
||||||
http-cookie (1.0.5)
|
http-cookie (1.0.5)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
httpclient (2.8.3)
|
httpclient (2.8.3)
|
||||||
@@ -156,16 +153,12 @@ GEM
|
|||||||
json (2.6.3)
|
json (2.6.3)
|
||||||
jwt (2.7.0)
|
jwt (2.7.0)
|
||||||
memoist (0.16.2)
|
memoist (0.16.2)
|
||||||
mime-types (3.4.1)
|
|
||||||
mime-types-data (~> 3.2015)
|
|
||||||
mime-types-data (3.2023.0218.1)
|
|
||||||
mini_magick (4.12.0)
|
mini_magick (4.12.0)
|
||||||
mini_mime (1.1.2)
|
mini_mime (1.1.2)
|
||||||
multi_json (1.15.0)
|
multi_json (1.15.0)
|
||||||
multipart-post (2.0.0)
|
multipart-post (2.0.0)
|
||||||
nanaimo (0.3.0)
|
nanaimo (0.3.0)
|
||||||
naturally (2.2.1)
|
naturally (2.2.1)
|
||||||
netrc (0.11.0)
|
|
||||||
optparse (0.1.1)
|
optparse (0.1.1)
|
||||||
os (1.1.4)
|
os (1.1.4)
|
||||||
plist (3.7.0)
|
plist (3.7.0)
|
||||||
@@ -175,11 +168,6 @@ GEM
|
|||||||
declarative (< 0.1.0)
|
declarative (< 0.1.0)
|
||||||
trailblazer-option (>= 0.1.1, < 0.2.0)
|
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||||
uber (< 0.2.0)
|
uber (< 0.2.0)
|
||||||
rest-client (2.1.0)
|
|
||||||
http-accept (>= 1.7.0, < 2.0)
|
|
||||||
http-cookie (>= 1.0.2, < 2.0)
|
|
||||||
mime-types (>= 1.16, < 4.0)
|
|
||||||
netrc (~> 0.8)
|
|
||||||
retriable (3.1.2)
|
retriable (3.1.2)
|
||||||
rexml (3.2.5)
|
rexml (3.2.5)
|
||||||
rouge (2.0.7)
|
rouge (2.0.7)
|
||||||
@@ -227,7 +215,6 @@ PLATFORMS
|
|||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
fastlane (>= 2.131.0)
|
fastlane (>= 2.131.0)
|
||||||
fastlane-plugin-clean_testflight_testers
|
fastlane-plugin-clean_testflight_testers
|
||||||
fastlane-plugin-diawi
|
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.4.6
|
2.3.9
|
||||||
|
|||||||
@@ -3,4 +3,3 @@
|
|||||||
# Ensure this file is checked in to source control!
|
# Ensure this file is checked in to source control!
|
||||||
|
|
||||||
gem 'fastlane-plugin-clean_testflight_testers'
|
gem 'fastlane-plugin-clean_testflight_testers'
|
||||||
gem 'fastlane-plugin-diawi'
|
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
platforms = [];
|
platforms = [];
|
||||||
source = {
|
source = {
|
||||||
remotes = ["https://rubygems.org"];
|
remotes = ["https://rubygems.org"];
|
||||||
sha256 = "1ypdmpdn20hxp5vwxz3zc04r5xcwqc25qszdlg41h8ghdqbllwmw";
|
sha256 = "15s8van7r2ad3dq6i03l3z4hqnvxcq75a3h72kxvf9an53sqma20";
|
||||||
type = "gem";
|
type = "gem";
|
||||||
};
|
};
|
||||||
version = "2.8.1";
|
version = "2.8.4";
|
||||||
};
|
};
|
||||||
artifactory = {
|
artifactory = {
|
||||||
groups = ["default"];
|
groups = ["default"];
|
||||||
@@ -45,10 +45,10 @@
|
|||||||
platforms = [];
|
platforms = [];
|
||||||
source = {
|
source = {
|
||||||
remotes = ["https://rubygems.org"];
|
remotes = ["https://rubygems.org"];
|
||||||
sha256 = "0q3q19insq5ablmr6ypq033qg1gsar5mdphhp7xg80rd615cnq97";
|
sha256 = "0x7v4v8hj0pbzw3x1iv07x8v93fcs74svlhzv7vl6laxm4mc6858";
|
||||||
type = "gem";
|
type = "gem";
|
||||||
};
|
};
|
||||||
version = "1.728.0";
|
version = "1.766.0";
|
||||||
};
|
};
|
||||||
aws-sdk-core = {
|
aws-sdk-core = {
|
||||||
dependencies = ["aws-eventstream" "aws-partitions" "aws-sigv4" "jmespath"];
|
dependencies = ["aws-eventstream" "aws-partitions" "aws-sigv4" "jmespath"];
|
||||||
@@ -56,10 +56,10 @@
|
|||||||
platforms = [];
|
platforms = [];
|
||||||
source = {
|
source = {
|
||||||
remotes = ["https://rubygems.org"];
|
remotes = ["https://rubygems.org"];
|
||||||
sha256 = "0zc4zhv2wq7s5p8c9iaplama1lpg2kwldg81j83c8w4xydf1wd2r";
|
sha256 = "10djgbz4k9w3axka8xrhf97h9yh9svi5g5xvncfwnkg6h22w2177";
|
||||||
type = "gem";
|
type = "gem";
|
||||||
};
|
};
|
||||||
version = "3.170.0";
|
version = "3.173.0";
|
||||||
};
|
};
|
||||||
aws-sdk-kms = {
|
aws-sdk-kms = {
|
||||||
dependencies = ["aws-sdk-core" "aws-sigv4"];
|
dependencies = ["aws-sdk-core" "aws-sigv4"];
|
||||||
@@ -67,10 +67,10 @@
|
|||||||
platforms = [];
|
platforms = [];
|
||||||
source = {
|
source = {
|
||||||
remotes = ["https://rubygems.org"];
|
remotes = ["https://rubygems.org"];
|
||||||
sha256 = "0v87zi28dfmrv7bv91yfldccnpd63n295siirbz7wqv1rajn8n02";
|
sha256 = "1bcm0c9f7xy5qj5f0z3gddqslhb2vzrj9smc39pgqyq4jmn5kpj0";
|
||||||
type = "gem";
|
type = "gem";
|
||||||
};
|
};
|
||||||
version = "1.63.0";
|
version = "1.64.0";
|
||||||
};
|
};
|
||||||
aws-sdk-s3 = {
|
aws-sdk-s3 = {
|
||||||
dependencies = ["aws-sdk-core" "aws-sdk-kms" "aws-sigv4"];
|
dependencies = ["aws-sdk-core" "aws-sdk-kms" "aws-sigv4"];
|
||||||
@@ -78,10 +78,10 @@
|
|||||||
platforms = [];
|
platforms = [];
|
||||||
source = {
|
source = {
|
||||||
remotes = ["https://rubygems.org"];
|
remotes = ["https://rubygems.org"];
|
||||||
sha256 = "1rpnlzsl52znhcki13jkwdshgwf51pn26267481f4fa842gr7xgp";
|
sha256 = "01cryf8kfkmlsxb327szcwcagsp7lss5gmk6zxlgap65lv8bc7rx";
|
||||||
type = "gem";
|
type = "gem";
|
||||||
};
|
};
|
||||||
version = "1.119.1";
|
version = "1.122.0";
|
||||||
};
|
};
|
||||||
aws-sigv4 = {
|
aws-sigv4 = {
|
||||||
dependencies = ["aws-eventstream"];
|
dependencies = ["aws-eventstream"];
|
||||||
@@ -368,10 +368,10 @@
|
|||||||
platforms = [];
|
platforms = [];
|
||||||
source = {
|
source = {
|
||||||
remotes = ["https://rubygems.org"];
|
remotes = ["https://rubygems.org"];
|
||||||
sha256 = "0b22m2dkydyv2si55b1jzznzgxf2ycx2aarv1j5p25k861h2gsml";
|
sha256 = "15sa3v3aaslympg9nmadmpxpbzykdiybzxn3navc7mf0iscb3q7s";
|
||||||
type = "gem";
|
type = "gem";
|
||||||
};
|
};
|
||||||
version = "2.212.1";
|
version = "2.212.2";
|
||||||
};
|
};
|
||||||
fastlane-plugin-clean_testflight_testers = {
|
fastlane-plugin-clean_testflight_testers = {
|
||||||
groups = ["default"];
|
groups = ["default"];
|
||||||
@@ -383,17 +383,6 @@
|
|||||||
};
|
};
|
||||||
version = "0.3.0";
|
version = "0.3.0";
|
||||||
};
|
};
|
||||||
fastlane-plugin-diawi = {
|
|
||||||
dependencies = ["rest-client"];
|
|
||||||
groups = ["default"];
|
|
||||||
platforms = [];
|
|
||||||
source = {
|
|
||||||
remotes = ["https://rubygems.org"];
|
|
||||||
sha256 = "1sjznx9hwlfa7ndv7av870dvl0cvmh68yk381r55ylw4jjvk5mwl";
|
|
||||||
type = "gem";
|
|
||||||
};
|
|
||||||
version = "2.1.0";
|
|
||||||
};
|
|
||||||
gh_inspector = {
|
gh_inspector = {
|
||||||
groups = ["default"];
|
groups = ["default"];
|
||||||
platforms = [];
|
platforms = [];
|
||||||
@@ -410,10 +399,10 @@
|
|||||||
platforms = [];
|
platforms = [];
|
||||||
source = {
|
source = {
|
||||||
remotes = ["https://rubygems.org"];
|
remotes = ["https://rubygems.org"];
|
||||||
sha256 = "1mbnmn36z1cnsd6ar76p9wvqi0ac6wlpm1p1lqczivain16qma76";
|
sha256 = "0ks2ak4fcvlflhyinykvd88g2ybxwsbc347aww349zhn1mqprbvg";
|
||||||
type = "gem";
|
type = "gem";
|
||||||
};
|
};
|
||||||
version = "0.36.0";
|
version = "0.42.0";
|
||||||
};
|
};
|
||||||
google-apis-core = {
|
google-apis-core = {
|
||||||
dependencies = ["addressable" "googleauth" "httpclient" "mini_mime" "representable" "retriable" "rexml" "webrick"];
|
dependencies = ["addressable" "googleauth" "httpclient" "mini_mime" "representable" "retriable" "rexml" "webrick"];
|
||||||
@@ -508,10 +497,10 @@
|
|||||||
platforms = [];
|
platforms = [];
|
||||||
source = {
|
source = {
|
||||||
remotes = ["https://rubygems.org"];
|
remotes = ["https://rubygems.org"];
|
||||||
sha256 = "1hpwgwhk0lmnknkw8kbdfxn95qqs6aagpq815l5fkw9w6mi77pai";
|
sha256 = "1lj5haarpn7rybbq9s031zcn9ji3rlz5bk64bwa2j34q5s1h5gis";
|
||||||
type = "gem";
|
type = "gem";
|
||||||
};
|
};
|
||||||
version = "1.3.0";
|
version = "1.5.2";
|
||||||
};
|
};
|
||||||
highline = {
|
highline = {
|
||||||
groups = ["default"];
|
groups = ["default"];
|
||||||
@@ -523,16 +512,6 @@
|
|||||||
};
|
};
|
||||||
version = "2.0.3";
|
version = "2.0.3";
|
||||||
};
|
};
|
||||||
http-accept = {
|
|
||||||
groups = ["default"];
|
|
||||||
platforms = [];
|
|
||||||
source = {
|
|
||||||
remotes = ["https://rubygems.org"];
|
|
||||||
sha256 = "09m1facypsdjynfwrcv19xcb1mqg8z6kk31g8r33pfxzh838c9n6";
|
|
||||||
type = "gem";
|
|
||||||
};
|
|
||||||
version = "1.7.0";
|
|
||||||
};
|
|
||||||
http-cookie = {
|
http-cookie = {
|
||||||
dependencies = ["domain_name"];
|
dependencies = ["domain_name"];
|
||||||
groups = ["default"];
|
groups = ["default"];
|
||||||
@@ -594,27 +573,6 @@
|
|||||||
};
|
};
|
||||||
version = "0.16.2";
|
version = "0.16.2";
|
||||||
};
|
};
|
||||||
mime-types = {
|
|
||||||
dependencies = ["mime-types-data"];
|
|
||||||
groups = ["default"];
|
|
||||||
platforms = [];
|
|
||||||
source = {
|
|
||||||
remotes = ["https://rubygems.org"];
|
|
||||||
sha256 = "0ipw892jbksbxxcrlx9g5ljq60qx47pm24ywgfbyjskbcl78pkvb";
|
|
||||||
type = "gem";
|
|
||||||
};
|
|
||||||
version = "3.4.1";
|
|
||||||
};
|
|
||||||
mime-types-data = {
|
|
||||||
groups = ["default"];
|
|
||||||
platforms = [];
|
|
||||||
source = {
|
|
||||||
remotes = ["https://rubygems.org"];
|
|
||||||
sha256 = "1pky3vzaxlgm9gw5wlqwwi7wsw3jrglrfflrppvvnsrlaiz043z9";
|
|
||||||
type = "gem";
|
|
||||||
};
|
|
||||||
version = "3.2023.0218.1";
|
|
||||||
};
|
|
||||||
mini_magick = {
|
mini_magick = {
|
||||||
groups = ["default"];
|
groups = ["default"];
|
||||||
platforms = [];
|
platforms = [];
|
||||||
@@ -675,16 +633,6 @@
|
|||||||
};
|
};
|
||||||
version = "2.2.1";
|
version = "2.2.1";
|
||||||
};
|
};
|
||||||
netrc = {
|
|
||||||
groups = ["default"];
|
|
||||||
platforms = [];
|
|
||||||
source = {
|
|
||||||
remotes = ["https://rubygems.org"];
|
|
||||||
sha256 = "0gzfmcywp1da8nzfqsql2zqi648mfnx6qwkig3cv36n9m0yy676y";
|
|
||||||
type = "gem";
|
|
||||||
};
|
|
||||||
version = "0.11.0";
|
|
||||||
};
|
|
||||||
optparse = {
|
optparse = {
|
||||||
groups = ["default"];
|
groups = ["default"];
|
||||||
platforms = [];
|
platforms = [];
|
||||||
@@ -746,17 +694,6 @@
|
|||||||
};
|
};
|
||||||
version = "3.2.0";
|
version = "3.2.0";
|
||||||
};
|
};
|
||||||
rest-client = {
|
|
||||||
dependencies = ["http-accept" "http-cookie" "mime-types" "netrc"];
|
|
||||||
groups = ["default"];
|
|
||||||
platforms = [];
|
|
||||||
source = {
|
|
||||||
remotes = ["https://rubygems.org"];
|
|
||||||
sha256 = "1qs74yzl58agzx9dgjhcpgmzfn61fqkk33k1js2y5yhlvc5l19im";
|
|
||||||
type = "gem";
|
|
||||||
};
|
|
||||||
version = "2.1.0";
|
|
||||||
};
|
|
||||||
retriable = {
|
retriable = {
|
||||||
groups = ["default"];
|
groups = ["default"];
|
||||||
platforms = [];
|
platforms = [];
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
import "node-libs-react-native/globals";
|
import "node-libs-react-native/globals";
|
||||||
import "./app/index.js";
|
import "./result/index.js";
|
||||||
|
|||||||
@@ -55,12 +55,12 @@ The [`nix/scripts/shell.sh`](./scripts/shell.sh) script is essentially a wrapper
|
|||||||
|
|
||||||
# Building
|
# Building
|
||||||
|
|
||||||
We will use the `make jsbundle-android` target as an example of a derivation you can build using Nix:
|
We will use the `make jsbundle` target as an example of a derivation you can build using Nix:
|
||||||
|
|
||||||
1. `make jsbundle-android` is called by developer
|
1. `make jsbundle` is called by developer
|
||||||
2. `make` calls `nix/scripts/build.sh targets.mobile.android.jsbundle`
|
2. `make` calls `nix/scripts/build.sh targets.mobile.jsbundle`
|
||||||
3. [`build.sh`](/nix/scripts/build.sh) calls `nix-build --attr targets.mobile.android.jsbundle` with extra arguments
|
3. [`build.sh`](/nix/scripts/build.sh) calls `nix-build --attr targets.mobile.jsbundle` with extra arguments
|
||||||
4. `nix-build` builds the derivation from [`nix/mobile/android/jsbundle/default.nix`](/nix/mobile/android/jsbundle/default.nix)
|
4. `nix-build` builds the derivation from [`nix/mobile/jsbundle/default.nix`](/nix/mobile/jsbundle/default.nix)
|
||||||
|
|
||||||
The same can be done for other targets like `targets.mobile.android.release`.
|
The same can be done for other targets like `targets.mobile.android.release`.
|
||||||
Except in that case extra arguments are required which is why the [`scripts/release-android.sh`](/scripts/release-android.sh) is used in the `make release-android` target.
|
Except in that case extra arguments are required which is why the [`scripts/release-android.sh`](/scripts/release-android.sh) is used in the `make release-android` target.
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
{ pkgs, deps, callPackage, mkShell
|
{ pkgs, deps, callPackage, mkShell
|
||||||
, status-go, androidPkgs, androidShell }:
|
, jsbundle, status-go, androidPkgs, androidShell }:
|
||||||
|
|
||||||
let
|
rec {
|
||||||
# Import a jsbundle compiled out of clojure codebase
|
release = callPackage ./release.nix {
|
||||||
jsbundle = callPackage ./jsbundle { };
|
inherit jsbundle status-go;
|
||||||
|
};
|
||||||
release = callPackage ./release.nix { inherit jsbundle status-go; };
|
|
||||||
in {
|
|
||||||
# TARGETS
|
|
||||||
inherit release jsbundle;
|
|
||||||
|
|
||||||
shell = mkShell {
|
shell = mkShell {
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ in stdenv.mkDerivation rec {
|
|||||||
root = path;
|
root = path;
|
||||||
include = [
|
include = [
|
||||||
"package.json" "yarn.lock" "metro.config.js" "babel.config.js"
|
"package.json" "yarn.lock" "metro.config.js" "babel.config.js"
|
||||||
"resources/.*" "translations/.*" "src/js/.*"
|
"resources/.*" "translations/.*" "src/js/.*" "index.js"
|
||||||
"modules/react-native-status/android.*" "android/.*"
|
"modules/react-native-status/android.*" "android/.*"
|
||||||
envFileName "VERSION" "status-go-version.json" "react-native.config.js"
|
envFileName "VERSION" "status-go-version.json" "react-native.config.js"
|
||||||
];
|
];
|
||||||
@@ -94,8 +94,10 @@ in stdenv.mkDerivation rec {
|
|||||||
# Export all vars from .env file
|
# Export all vars from .env file
|
||||||
export $(cut -d= -f1 .env)
|
export $(cut -d= -f1 .env)
|
||||||
|
|
||||||
# Copy index.js and app/ input files
|
# Symlink React Native entrypoint.
|
||||||
cp -ra --no-preserve=ownership ${builtJsBundle}/* ./
|
cp -Lr ${builtJsBundle} ./result
|
||||||
|
pwd
|
||||||
|
find -L result
|
||||||
|
|
||||||
# Copy android/ directory
|
# Copy android/ directory
|
||||||
mkdir -p ./android/build
|
mkdir -p ./android/build
|
||||||
|
|||||||
@@ -3,7 +3,10 @@
|
|||||||
let
|
let
|
||||||
fastlane = callPackage ./fastlane { };
|
fastlane = callPackage ./fastlane { };
|
||||||
|
|
||||||
|
jsbundle = callPackage ./jsbundle { };
|
||||||
|
|
||||||
android = callPackage ./android {
|
android = callPackage ./android {
|
||||||
|
inherit jsbundle;
|
||||||
status-go = status-go.mobile.android;
|
status-go = status-go.mobile.android;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -26,5 +29,5 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
# TARGETS
|
# TARGETS
|
||||||
inherit android ios fastlane;
|
inherit android ios fastlane jsbundle;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
{ secretsFile ? "" }:
|
{ secretsFile ? "" }:
|
||||||
|
|
||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
name = "status-mobile-build-jsbundle-android";
|
name = "status-mobile-jsbundle";
|
||||||
src =
|
src =
|
||||||
let path = ./../../../..;
|
let path = ./../../..;
|
||||||
# We use builtins.path so that we can name the resulting derivation,
|
# We use builtins.path so that we can name the resulting derivation,
|
||||||
# otherwise the name would be taken from the checkout directory,
|
# otherwise the name would be taken from the checkout directory,
|
||||||
# which is outside of our control inherit path;
|
# which is outside of our control inherit path;
|
||||||
@@ -25,7 +25,7 @@ stdenv.mkDerivation {
|
|||||||
ignoreVCS = false;
|
ignoreVCS = false;
|
||||||
include = [
|
include = [
|
||||||
"VERSION" "BUILD_NUMBER" "scripts/version/.*"
|
"VERSION" "BUILD_NUMBER" "scripts/version/.*"
|
||||||
"src/.*" "shadow-cljs.edn" "index.js"
|
"src/.*" "shadow-cljs.edn"
|
||||||
# I want to avoid including the whole .git directory
|
# I want to avoid including the whole .git directory
|
||||||
".git/HEAD" ".git/objects" ".git/refs/heads/.*"
|
".git/HEAD" ".git/objects" ".git/refs/heads/.*"
|
||||||
# shadow-cljs expects these for deps resolution
|
# shadow-cljs expects these for deps resolution
|
||||||
@@ -77,6 +77,6 @@ stdenv.mkDerivation {
|
|||||||
'';
|
'';
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp -r index.js app $out/
|
cp -r result/* $out/
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
"@react-native-community/blur": "git+https://github.com/status-im/react-native-blur#refs/tags/v4.3.3-status",
|
"@react-native-community/blur": "git+https://github.com/status-im/react-native-blur#refs/tags/v4.3.3-status",
|
||||||
"@react-native-community/cameraroll": "git+https://github.com/status-im/react-native-cameraroll.git#refs/tags/v4.0.4-status.0",
|
"@react-native-community/cameraroll": "git+https://github.com/status-im/react-native-cameraroll.git#refs/tags/v4.0.4-status.0",
|
||||||
"@react-native-community/clipboard": "^1.2.2",
|
"@react-native-community/clipboard": "^1.2.2",
|
||||||
"@react-native-community/hooks": "^2.5.1",
|
"@react-native-community/hooks": "^3.0.0",
|
||||||
"@react-native-community/masked-view": "^0.1.6",
|
"@react-native-community/masked-view": "^0.1.6",
|
||||||
"@react-native-community/netinfo": "^4.4.0",
|
"@react-native-community/netinfo": "^4.4.0",
|
||||||
"@react-native-community/push-notification-ios": "^1.4.1",
|
"@react-native-community/push-notification-ios": "^1.4.1",
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 944 B After Width: | Height: | Size: 838 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 692 B After Width: | Height: | Size: 784 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 685 B After Width: | Height: | Size: 788 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 771 B After Width: | Height: | Size: 834 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 744 B After Width: | Height: | Size: 880 B |
|
Before Width: | Height: | Size: 1017 B After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 745 B After Width: | Height: | Size: 806 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 801 B After Width: | Height: | Size: 868 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
@@ -0,0 +1,119 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import https from 'node:https'
|
||||||
|
import { basename } from 'node:path'
|
||||||
|
import { promisify } from 'node:util'
|
||||||
|
import { createReadStream } from 'node:fs'
|
||||||
|
|
||||||
|
import log from 'npmlog'
|
||||||
|
import FormData from 'form-data'
|
||||||
|
|
||||||
|
const UPLOAD_URL = 'https://upload.diawi.com/'
|
||||||
|
const STATUS_URL = 'https://upload.diawi.com/status'
|
||||||
|
const POLL_MAX_COUNT = 10
|
||||||
|
const POLL_INTERVAL_MS = 700
|
||||||
|
|
||||||
|
const sleep = (ms) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
setTimeout(resolve, (ms))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRequest = async (url) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let data = []
|
||||||
|
https.get(url, res => {
|
||||||
|
res.on('error', err => reject(err))
|
||||||
|
res.on('data', chunk => { data.push(chunk) })
|
||||||
|
res.on('end', () => {
|
||||||
|
let payload = Buffer.concat(data).toString()
|
||||||
|
resolve({
|
||||||
|
code: res.statusCode,
|
||||||
|
message: res.statusMessage,
|
||||||
|
payload: payload,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const uploadIpa = async (ipaPath, comment, token) => {
|
||||||
|
let form = new FormData()
|
||||||
|
form.append('token', token)
|
||||||
|
form.append('file', createReadStream(ipaPath))
|
||||||
|
form.append('comment', comment || basename(ipaPath))
|
||||||
|
|
||||||
|
const formSubmitPromise = promisify(form.submit.bind(form))
|
||||||
|
|
||||||
|
const res = await formSubmitPromise(UPLOAD_URL)
|
||||||
|
if (res.statusCode != 200) {
|
||||||
|
log.error('uploadIpa', 'Upload failed: %d %s', res.statusCode, res.statusMessage)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const jobId = res.on('data', async (data) => {
|
||||||
|
resolve(JSON.parse(data)['job'])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkStatus = async (jobId, token) => {
|
||||||
|
let params = new URLSearchParams({
|
||||||
|
token: token, job: jobId,
|
||||||
|
})
|
||||||
|
let rval = await getRequest(`${STATUS_URL}?${params.toString()}`)
|
||||||
|
if (rval.code != 200) {
|
||||||
|
log.error('checkStatus', 'Check query failed: %d %s', rval.code, rval.message)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
return JSON.parse(rval.payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
const pollStatus = async (jobId, token) => {
|
||||||
|
let interval = POLL_INTERVAL_MS
|
||||||
|
for (let i = 0; i <= POLL_MAX_COUNT; i++) {
|
||||||
|
let json = await checkStatus(jobId, token)
|
||||||
|
switch (json.status) {
|
||||||
|
case 2000:
|
||||||
|
return json
|
||||||
|
case 2001:
|
||||||
|
log.verbose('pollStatus', 'Waiting: %s', json.message)
|
||||||
|
break /* Nothing, just poll again. */
|
||||||
|
case 4000000:
|
||||||
|
log.warning('pollStatus', 'Doubling polling interval: %s', json.message)
|
||||||
|
interval *= 2
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
log.error('pollStatus', `Error in status response: ${json.message}`)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
await sleep(interval)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const main = async () => {
|
||||||
|
const token = process.env.DIAWI_TOKEN
|
||||||
|
const targetFile = process.argv[2]
|
||||||
|
const comment = process.argv[3]
|
||||||
|
log.level = process.env.VERBOSE ? 'verbose' : 'info'
|
||||||
|
|
||||||
|
if (token === undefined) {
|
||||||
|
log.error('main', 'No DIAWI_TOKEN env var provided!')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
if (targetFile === undefined) {
|
||||||
|
log.error('main', 'No file path provided!')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info('main', 'Uploading: %s', targetFile)
|
||||||
|
let jobId = await uploadIpa(targetFile, comment, token)
|
||||||
|
|
||||||
|
log.info('main', 'Polling upload job status: %s', jobId)
|
||||||
|
let uploadMeta = await pollStatus(jobId, token)
|
||||||
|
|
||||||
|
console.log(uploadMeta)
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
@@ -37,7 +37,8 @@
|
|||||||
:builds
|
:builds
|
||||||
{:mobile
|
{:mobile
|
||||||
{:target :react-native
|
{:target :react-native
|
||||||
:output-dir "app"
|
;; To match the folder created by Nix build of JSBundle.
|
||||||
|
:output-dir "result"
|
||||||
:init-fn status-im2.core/init
|
:init-fn status-im2.core/init
|
||||||
;; When false, the Shadow-CLJS watcher won't automatically refresh
|
;; When false, the Shadow-CLJS watcher won't automatically refresh
|
||||||
;; the target files (a.k.a hot reload). When false, you can manually
|
;; the target files (a.k.a hot reload). When false, you can manually
|
||||||
@@ -53,8 +54,13 @@
|
|||||||
;; @testing-library/react-native.
|
;; @testing-library/react-native.
|
||||||
test-helpers.component]}
|
test-helpers.component]}
|
||||||
:closure-defines
|
:closure-defines
|
||||||
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||||
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
|
status-im2.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
|
||||||
|
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
|
||||||
|
status-im2.config/ALCHEMY_ARBITRUM_GOERLI_TOKEN #shadow/env "ALCHEMY_ARBITRUM_GOERLI_TOKEN"
|
||||||
|
status-im2.config/ALCHEMY_OPTIMISM_GOERLI_TOKEN #shadow/env "ALCHEMY_OPTIMISM_GOERLI_TOKEN"
|
||||||
|
status-im2.config/ALCHEMY_OPTIMISM_MAINNET_TOKEN #shadow/env "ALCHEMY_OPTIMISM_MAINNET_TOKEN"
|
||||||
|
status-im2.config/ALCHEMY_ARBITRUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ARBITRUM_MAINNET_TOKEN"}
|
||||||
:compiler-options {:output-feature-set :es5
|
:compiler-options {:output-feature-set :es5
|
||||||
:closure-defines
|
:closure-defines
|
||||||
{re-frame.trace/trace-enabled? true}
|
{re-frame.trace/trace-enabled? true}
|
||||||
@@ -67,8 +73,13 @@
|
|||||||
:chunks {:fleets status-im.fleet.default-fleet/default-fleets}
|
:chunks {:fleets status-im.fleet.default-fleet/default-fleets}
|
||||||
:release
|
:release
|
||||||
{:closure-defines
|
{:closure-defines
|
||||||
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||||
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
|
status-im2.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
|
||||||
|
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
|
||||||
|
status-im2.config/ALCHEMY_ARBITRUM_GOERLI_TOKEN #shadow/env "ALCHEMY_ARBITRUM_GOERLI_TOKEN"
|
||||||
|
status-im2.config/ALCHEMY_OPTIMISM_GOERLI_TOKEN #shadow/env "ALCHEMY_OPTIMISM_GOERLI_TOKEN"
|
||||||
|
status-im2.config/ALCHEMY_OPTIMISM_MAINNET_TOKEN #shadow/env "ALCHEMY_OPTIMISM_MAINNET_TOKEN"
|
||||||
|
status-im2.config/ALCHEMY_ARBITRUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ARBITRUM_MAINNET_TOKEN"}
|
||||||
:compiler-options {:output-feature-set :es6
|
:compiler-options {:output-feature-set :es6
|
||||||
;;disable for android build as there
|
;;disable for android build as there
|
||||||
;;is an intermittent warning with deftype
|
;;is an intermittent warning with deftype
|
||||||
@@ -95,8 +106,13 @@
|
|||||||
:ui-driven
|
:ui-driven
|
||||||
true
|
true
|
||||||
:closure-defines
|
:closure-defines
|
||||||
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||||
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
|
status-im2.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
|
||||||
|
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
|
||||||
|
status-im2.config/ALCHEMY_ARBITRUM_GOERLI_TOKEN #shadow/env "ALCHEMY_ARBITRUM_GOERLI_TOKEN"
|
||||||
|
status-im2.config/ALCHEMY_OPTIMISM_GOERLI_TOKEN #shadow/env "ALCHEMY_OPTIMISM_GOERLI_TOKEN"
|
||||||
|
status-im2.config/ALCHEMY_OPTIMISM_MAINNET_TOKEN #shadow/env "ALCHEMY_OPTIMISM_MAINNET_TOKEN"
|
||||||
|
status-im2.config/ALCHEMY_ARBITRUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ARBITRUM_MAINNET_TOKEN"}
|
||||||
:compiler-options
|
:compiler-options
|
||||||
{;; needed because we override require and it
|
{;; needed because we override require and it
|
||||||
;; messes with source-map which reports callstack
|
;; messes with source-map which reports callstack
|
||||||
|
|||||||
@@ -57,10 +57,18 @@
|
|||||||
(def initials-avatar-text
|
(def initials-avatar-text
|
||||||
{:color colors/white-opa-70})
|
{:color colors/white-opa-70})
|
||||||
|
|
||||||
|
(defn inner-dot
|
||||||
|
[size online?]
|
||||||
|
(let [background (if online? colors/success-50 colors/neutral-40)
|
||||||
|
dimensions (get-in sizes [size :status-indicator])]
|
||||||
|
{:width (- dimensions 4)
|
||||||
|
:height (- dimensions 4)
|
||||||
|
:border-radius (- dimensions 4)
|
||||||
|
:background-color background}))
|
||||||
|
|
||||||
(defn dot
|
(defn dot
|
||||||
[size online? ring?]
|
[size ring?]
|
||||||
(let [background (if online? colors/success-50 colors/neutral-40)
|
(let [dimensions (get-in sizes [size :status-indicator])
|
||||||
dimensions (get-in sizes [size :status-indicator])
|
|
||||||
border-width (get-in sizes [size :status-indicator-border])
|
border-width (get-in sizes [size :status-indicator-border])
|
||||||
right (case size
|
right (case size
|
||||||
:big 2
|
:big 2
|
||||||
@@ -73,11 +81,13 @@
|
|||||||
:small -2
|
:small -2
|
||||||
0)]
|
0)]
|
||||||
{:position :absolute
|
{:position :absolute
|
||||||
|
:justify-content :center
|
||||||
|
:align-items :center
|
||||||
:bottom bottom
|
:bottom bottom
|
||||||
:right right
|
:right right
|
||||||
:width dimensions
|
:width dimensions
|
||||||
:height dimensions
|
:height dimensions
|
||||||
:border-width border-width
|
:border-width border-width
|
||||||
:border-radius dimensions
|
:border-radius dimensions
|
||||||
:border-color (colors/theme-colors colors/white colors/neutral-100)
|
:background-color (colors/theme-colors colors/white colors/neutral-100)
|
||||||
:background-color background}))
|
:border-color (colors/theme-colors colors/white colors/neutral-100)}))
|
||||||
|
|||||||
@@ -38,18 +38,22 @@
|
|||||||
uses `ring-background` to display the ring behind the initials when given. Otherwise,
|
uses `ring-background` to display the ring behind the initials when given. Otherwise,
|
||||||
shows the `profile-picture` which already comes with the ring drawn."
|
shows the `profile-picture` which already comes with the ring drawn."
|
||||||
[{:keys [full-name status-indicator? online? size profile-picture ring-background
|
[{:keys [full-name status-indicator? online? size profile-picture ring-background
|
||||||
customization-color]
|
customization-color static?]
|
||||||
:or {status-indicator? true
|
:or {status-indicator? true
|
||||||
online? true
|
online? true
|
||||||
size :big
|
size :big
|
||||||
customization-color :turquoise}}]
|
customization-color :turquoise}}]
|
||||||
(let [full-name (or full-name "empty name")
|
(let [full-name (or full-name "empty name")
|
||||||
draw-ring? (and ring-background (valid-ring-sizes size))
|
draw-ring? (and ring-background (valid-ring-sizes size))
|
||||||
outer-styles (style/outer 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
|
||||||
|
;; https://github.com/status-im/status-mobile/issues/15553
|
||||||
|
image-view (if static? rn/image fast-image/fast-image)]
|
||||||
[rn/view {:style outer-styles :accessibility-label :user-avatar}
|
[rn/view {:style outer-styles :accessibility-label :user-avatar}
|
||||||
;; The `profile-picture` already has the ring in it
|
;; The `profile-picture` already has the ring in it
|
||||||
(when-let [image (or profile-picture ring-background)]
|
(when-let [image (or profile-picture ring-background)]
|
||||||
[fast-image/fast-image
|
[image-view
|
||||||
{:accessibility-label (if draw-ring? :ring-background :profile-picture)
|
{:accessibility-label (if draw-ring? :ring-background :profile-picture)
|
||||||
:style outer-styles
|
:style outer-styles
|
||||||
:source image}])
|
:source image}])
|
||||||
@@ -62,4 +66,7 @@
|
|||||||
(when status-indicator?
|
(when status-indicator?
|
||||||
[rn/view
|
[rn/view
|
||||||
{:accessibility-label :status-indicator
|
{:accessibility-label :status-indicator
|
||||||
:style (style/dot size online? draw-ring?)}])]))
|
:style (style/dot size draw-ring?)}
|
||||||
|
[rn/view
|
||||||
|
{:accessibility-label :inner-status-indicator-dot
|
||||||
|
:style (style/inner-dot size online?)}]])]))
|
||||||
|
|||||||
@@ -8,134 +8,142 @@
|
|||||||
|
|
||||||
(defn themes
|
(defn themes
|
||||||
[customization-color]
|
[customization-color]
|
||||||
{:light {:primary {:icon-color colors/white
|
{:light
|
||||||
:label-color colors/white
|
{:primary {:icon-color colors/white
|
||||||
:background-color {:default (colors/custom-color customization-color 50)
|
:icon-secondary-color colors/white-opa-70
|
||||||
:pressed (colors/custom-color customization-color 60)
|
:label-color colors/white
|
||||||
:disabled (colors/custom-color customization-color 50)}}
|
:background-color {:default (colors/custom-color customization-color 50)
|
||||||
:secondary {:icon-color colors/primary-50
|
:pressed (colors/custom-color customization-color 60)
|
||||||
:label-color colors/primary-50
|
:disabled (colors/custom-color customization-color 50)}}
|
||||||
:background-color {:default colors/primary-50-opa-20
|
:secondary {:icon-color colors/primary-50
|
||||||
:pressed colors/primary-50-opa-40
|
:label-color colors/primary-50
|
||||||
:disabled colors/primary-50-opa-20}}
|
:background-color {:default colors/primary-50-opa-20
|
||||||
:grey {:icon-color colors/neutral-100
|
:pressed colors/primary-50-opa-40
|
||||||
:icon-secondary-color colors/neutral-50
|
:disabled colors/primary-50-opa-20}}
|
||||||
:label-color colors/neutral-100
|
:grey {:icon-color colors/neutral-100
|
||||||
:background-color {:default colors/neutral-10
|
:icon-secondary-color colors/neutral-50
|
||||||
:pressed colors/neutral-20
|
:label-color colors/neutral-100
|
||||||
:disabled colors/neutral-10}}
|
:background-color {:default colors/neutral-10
|
||||||
:dark-grey {:icon-color colors/neutral-100
|
:pressed colors/neutral-20
|
||||||
:icon-secondary-color colors/neutral-50
|
:disabled colors/neutral-10}}
|
||||||
:label-color colors/neutral-100
|
:dark-grey {:icon-color colors/neutral-100
|
||||||
:background-color {:default colors/neutral-20
|
:icon-secondary-color colors/neutral-50
|
||||||
:pressed colors/neutral-30
|
:label-color colors/neutral-100
|
||||||
:disabled colors/neutral-20}}
|
:background-color {:default colors/neutral-20
|
||||||
:outline {:icon-color colors/neutral-50
|
:pressed colors/neutral-30
|
||||||
:icon-secondary-color colors/neutral-50
|
:disabled colors/neutral-20}}
|
||||||
:label-color colors/neutral-100
|
:outline {:icon-color colors/neutral-50
|
||||||
:border-color {:default colors/neutral-30
|
:icon-secondary-color colors/neutral-50
|
||||||
:pressed colors/neutral-40
|
:label-color colors/neutral-100
|
||||||
:disabled colors/neutral-30}}
|
:border-color {:default colors/neutral-30
|
||||||
:ghost {:icon-color colors/neutral-50
|
:pressed colors/neutral-40
|
||||||
:icon-secondary-color colors/neutral-50
|
:disabled colors/neutral-30}}
|
||||||
:label-color colors/neutral-100
|
:ghost {:icon-color colors/neutral-50
|
||||||
:background-color {:pressed colors/neutral-10}}
|
:icon-secondary-color colors/neutral-50
|
||||||
:danger {:icon-color colors/white
|
:label-color colors/neutral-100
|
||||||
:label-color colors/white
|
:background-color {:pressed colors/neutral-10}}
|
||||||
:background-color {:default colors/danger-50
|
:danger {:icon-color colors/white
|
||||||
:pressed colors/danger-60
|
:icon-secondary-color colors/white-opa-70
|
||||||
:disabled colors/danger-50}}
|
:label-color colors/white
|
||||||
:positive {:icon-color colors/white
|
:background-color {:default colors/danger-50
|
||||||
:label-color colors/white
|
:pressed colors/danger-60
|
||||||
:background-color {:default colors/success-50
|
:disabled colors/danger-50}}
|
||||||
:pressed colors/success-60
|
:positive {:icon-color colors/white
|
||||||
:disabled colors/success-50-opa-30}}
|
:icon-secondary-color colors/white-opa-70
|
||||||
:photo-bg {:icon-color colors/neutral-100
|
:label-color colors/white
|
||||||
:icon-secondary-color colors/neutral-80-opa-40
|
:background-color {:default colors/success-50
|
||||||
:label-color colors/neutral-100
|
:pressed colors/success-60
|
||||||
:background-color {:default colors/white-opa-40
|
:disabled colors/success-50-opa-30}}
|
||||||
:pressed colors/white-opa-50
|
:photo-bg {:icon-color colors/neutral-100
|
||||||
:disabled colors/white-opa-40}}
|
:icon-secondary-color colors/neutral-80-opa-40
|
||||||
:blur-bg {:icon-color colors/neutral-100
|
:label-color colors/neutral-100
|
||||||
:icon-secondary-color colors/neutral-80-opa-40
|
:background-color {:default colors/white-opa-40
|
||||||
:label-color colors/neutral-100
|
:pressed colors/white-opa-50
|
||||||
:background-color {:default colors/neutral-80-opa-5
|
:disabled colors/white-opa-40}}
|
||||||
:pressed colors/neutral-80-opa-10
|
:blur-bg {:icon-color colors/neutral-100
|
||||||
:disabled colors/neutral-80-opa-5}}
|
:icon-secondary-color colors/neutral-80-opa-40
|
||||||
:blur-bg-outline {:icon-color colors/neutral-100
|
:label-color colors/neutral-100
|
||||||
:icon-secondary-color colors/neutral-80-opa-40
|
:background-color {:default colors/neutral-80-opa-5
|
||||||
:label-color colors/neutral-100
|
:pressed colors/neutral-80-opa-10
|
||||||
:border-color {:default colors/neutral-80-opa-10
|
:disabled colors/neutral-80-opa-5}}
|
||||||
:pressed colors/neutral-80-opa-20
|
:blur-bg-outline {:icon-color colors/neutral-100
|
||||||
:disabled colors/neutral-80-opa-10}}
|
:icon-secondary-color colors/neutral-80-opa-40
|
||||||
:shell {:icon-color colors/white
|
:label-color colors/neutral-100
|
||||||
:label-color colors/white
|
:border-color {:default colors/neutral-80-opa-10
|
||||||
:background-color {:default colors/neutral-95
|
:pressed colors/neutral-80-opa-20
|
||||||
:pressed colors/neutral-95
|
:disabled colors/neutral-80-opa-10}}
|
||||||
:disabled colors/neutral-95}}}
|
:shell {:icon-color colors/white
|
||||||
:dark {:primary {:icon-color colors/white
|
:label-color colors/white
|
||||||
:label-color colors/white
|
:background-color {:default colors/neutral-95
|
||||||
:background-color {:default (colors/custom-color customization-color 60)
|
:pressed colors/neutral-95
|
||||||
:pressed (colors/custom-color customization-color 50)
|
:disabled colors/neutral-95}}}
|
||||||
:disabled (colors/custom-color customization-color 60)}}
|
:dark
|
||||||
:secondary {:icon-color colors/primary-50
|
{:primary {:icon-color colors/white
|
||||||
:label-color colors/primary-50
|
:icon-secondary-color colors/white-opa-70
|
||||||
:background-color {:default colors/primary-50-opa-20
|
:label-color colors/white
|
||||||
:pressed colors/primary-50-opa-30
|
:background-color {:default (colors/custom-color customization-color 60)
|
||||||
:disabled colors/primary-50-opa-20}}
|
:pressed (colors/custom-color customization-color 50)
|
||||||
:grey {:icon-color colors/white
|
:disabled (colors/custom-color customization-color 60)}}
|
||||||
:icon-secondary-color colors/neutral-40
|
:secondary {:icon-color colors/primary-50
|
||||||
:label-color colors/white
|
:label-color colors/primary-50
|
||||||
:background-color {:default colors/neutral-80
|
:background-color {:default colors/primary-50-opa-20
|
||||||
:pressed colors/neutral-60
|
:pressed colors/primary-50-opa-30
|
||||||
:disabled colors/neutral-80}}
|
:disabled colors/primary-50-opa-20}}
|
||||||
:dark-grey {:icon-color colors/white
|
:grey {:icon-color colors/white
|
||||||
:icon-secondary-color colors/neutral-40
|
:icon-secondary-color colors/neutral-40
|
||||||
:label-color colors/white
|
:label-color colors/white
|
||||||
:background-color {:default colors/neutral-70
|
:background-color {:default colors/neutral-90
|
||||||
:pressed colors/neutral-60
|
:pressed colors/neutral-60
|
||||||
:disabled colors/neutral-70}}
|
:disabled colors/neutral-90}}
|
||||||
:outline {:icon-color colors/neutral-40
|
:dark-grey {:icon-color colors/white
|
||||||
:icon-secondary-color colors/neutral-40
|
:icon-secondary-color colors/neutral-40
|
||||||
:label-color colors/white
|
:label-color colors/white
|
||||||
:border-color {:default colors/neutral-70
|
:background-color {:default colors/neutral-70
|
||||||
:pressed colors/neutral-60
|
:pressed colors/neutral-60
|
||||||
:disabled colors/neutral-70}}
|
:disabled colors/neutral-70}}
|
||||||
:ghost {:icon-color colors/neutral-40
|
:outline {:icon-color colors/neutral-40
|
||||||
:icon-secondary-color colors/neutral-40
|
:icon-secondary-color colors/neutral-40
|
||||||
:label-color colors/white
|
:label-color colors/white
|
||||||
:background-color {:pressed colors/neutral-80}}
|
:border-color {:default colors/neutral-70
|
||||||
:danger {:icon-color colors/white
|
:pressed colors/neutral-60
|
||||||
:label-color colors/white
|
:disabled colors/neutral-70}}
|
||||||
:background-color {:default colors/danger-60
|
:ghost {:icon-color colors/neutral-40
|
||||||
:pressed colors/danger-50
|
:icon-secondary-color colors/neutral-40
|
||||||
:disabled colors/danger-60}}
|
:label-color colors/white
|
||||||
:positive {:icon-color colors/white
|
:background-color {:pressed colors/neutral-80}}
|
||||||
:label-color colors/white
|
:danger {:icon-color colors/white
|
||||||
:background-color {:default colors/success-60
|
:icon-secondary-color colors/white-opa-70
|
||||||
:pressed colors/success-50
|
:label-color colors/white
|
||||||
:disabled colors/success-60-opa-30}}
|
:background-color {:default colors/danger-60
|
||||||
:photo-bg {:icon-color colors/white
|
:pressed colors/danger-50
|
||||||
:icon-secondary-color colors/neutral-30
|
:disabled colors/danger-60}}
|
||||||
:label-color colors/white
|
:positive {:icon-color colors/white
|
||||||
:background-color {:default colors/neutral-80-opa-40
|
:icon-secondary-color colors/white-opa-70
|
||||||
:pressed colors/neutral-80-opa-50
|
:label-color colors/white
|
||||||
:disabled colors/neutral-80-opa-40}}
|
:background-color {:default colors/success-60
|
||||||
:blur-bg {:icon-color colors/white
|
:pressed colors/success-50
|
||||||
:icon-secondary-color colors/white-opa-40
|
:disabled colors/success-60-opa-30}}
|
||||||
:label-color colors/white
|
:photo-bg {:icon-color colors/white
|
||||||
:background-color {:default colors/white-opa-5
|
:icon-secondary-color colors/neutral-30
|
||||||
:pressed colors/white-opa-10
|
:label-color colors/white
|
||||||
:disabled colors/white-opa-5}}
|
:background-color {:default colors/neutral-80-opa-40
|
||||||
:blur-bg-outline {:icon-color colors/white
|
:pressed colors/neutral-80-opa-50
|
||||||
:icon-secondary-color colors/white-opa-40
|
:disabled colors/neutral-80-opa-40}}
|
||||||
:label-color colors/white
|
:blur-bg {:icon-color colors/white
|
||||||
:border-color {:default colors/white-opa-10
|
:icon-secondary-color colors/white-opa-40
|
||||||
:pressed colors/white-opa-20
|
:label-color colors/white
|
||||||
:disabled colors/white-opa-5}}
|
:background-color {:default colors/white-opa-5
|
||||||
:shell {:icon-color colors/white
|
:pressed colors/white-opa-10
|
||||||
:label-color colors/white
|
:disabled colors/white-opa-5}}
|
||||||
:background-color {:default colors/neutral-95}}}})
|
:blur-bg-outline {:icon-color colors/white
|
||||||
|
:icon-secondary-color colors/white-opa-40
|
||||||
|
:label-color colors/white
|
||||||
|
:border-color {:default colors/white-opa-10
|
||||||
|
:pressed colors/white-opa-20
|
||||||
|
:disabled colors/white-opa-5}}
|
||||||
|
:shell {:icon-color colors/white
|
||||||
|
:label-color colors/white
|
||||||
|
:background-color {:default colors/neutral-95}}}})
|
||||||
|
|
||||||
(defn shape-style-container
|
(defn shape-style-container
|
||||||
[type icon size]
|
[type icon size]
|
||||||
@@ -196,17 +204,13 @@
|
|||||||
(when disabled
|
(when disabled
|
||||||
{:opacity 0.3})))
|
{:opacity 0.3})))
|
||||||
|
|
||||||
(defn community-themed?
|
|
||||||
[type community-color]
|
|
||||||
(and (= type :community) (string? community-color)))
|
|
||||||
|
|
||||||
(defn button
|
(defn button
|
||||||
"with label
|
"with label
|
||||||
[button opts \"label\"]
|
[button opts \"label\"]
|
||||||
opts
|
opts
|
||||||
{:type :primary/:secondary/:grey/:dark-grey/:outline/:ghost/
|
{:type :primary/:secondary/:grey/:dark-grey/:outline/:ghost/
|
||||||
:danger/:photo-bg/:blur-bg/:blur-bg-outline/:shell/:community
|
:danger/:photo-bg/:blur-bg/:blur-bg-outline/:shell/:community
|
||||||
:size 40/32/24
|
:size 40 [default] /32/24
|
||||||
:icon true/false
|
:icon true/false
|
||||||
:community-color '#FFFFFF'
|
:community-color '#FFFFFF'
|
||||||
:community-text-color '#000000'
|
:community-text-color '#000000'
|
||||||
@@ -218,9 +222,8 @@
|
|||||||
[_ _]
|
[_ _]
|
||||||
(let [pressed (reagent/atom false)]
|
(let [pressed (reagent/atom false)]
|
||||||
(fn
|
(fn
|
||||||
[{:keys [on-press disabled type size community-color community-text-color before after above
|
[{:keys [on-press disabled type size before after above
|
||||||
width customization-color
|
width customization-color override-theme override-background-color
|
||||||
override-theme override-background-color
|
|
||||||
on-long-press accessibility-label icon icon-no-color style inner-style test-ID]
|
on-long-press accessibility-label icon icon-no-color style inner-style test-ID]
|
||||||
:or {type :primary
|
:or {type :primary
|
||||||
size 40
|
size 40
|
||||||
@@ -239,18 +242,13 @@
|
|||||||
[rn/touchable-without-feedback
|
[rn/touchable-without-feedback
|
||||||
(merge {:test-ID test-ID
|
(merge {:test-ID test-ID
|
||||||
:disabled disabled
|
:disabled disabled
|
||||||
:accessibility-label accessibility-label}
|
:accessibility-label accessibility-label
|
||||||
|
:on-press-in #(reset! pressed true)
|
||||||
|
:on-press-out #(reset! pressed nil)}
|
||||||
(when on-press
|
(when on-press
|
||||||
{:on-press (fn []
|
{:on-press on-press})
|
||||||
(on-press))})
|
|
||||||
(when on-long-press
|
(when on-long-press
|
||||||
{:on-long-press (fn []
|
{:on-long-press on-long-press}))
|
||||||
(on-long-press))})
|
|
||||||
{:on-press-in (fn []
|
|
||||||
(reset! pressed true))}
|
|
||||||
{:on-press-out (fn []
|
|
||||||
(reset! pressed nil))})
|
|
||||||
|
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style (merge
|
{:style (merge
|
||||||
(shape-style-container type icon size)
|
(shape-style-container type icon size)
|
||||||
@@ -269,11 +267,7 @@
|
|||||||
width
|
width
|
||||||
before
|
before
|
||||||
after)
|
after)
|
||||||
(when
|
(when (= state :pressed) {:opacity 0.9})
|
||||||
(community-themed? type community-color)
|
|
||||||
(merge
|
|
||||||
{:background-color community-color}
|
|
||||||
(when (= state :pressed) {:opacity 0.9})))
|
|
||||||
inner-style)}
|
inner-style)}
|
||||||
(when above
|
(when above
|
||||||
[rn/view
|
[rn/view
|
||||||
@@ -301,12 +295,7 @@
|
|||||||
{:size (when (#{56 24} size) :paragraph-2)
|
{:size (when (#{56 24} size) :paragraph-2)
|
||||||
:weight :medium
|
:weight :medium
|
||||||
:number-of-lines 1
|
:number-of-lines 1
|
||||||
:style {:color (if
|
:style {:color label-color}}
|
||||||
(and
|
|
||||||
(community-themed? type community-color)
|
|
||||||
(string? community-text-color))
|
|
||||||
community-text-color
|
|
||||||
label-color)}}
|
|
||||||
|
|
||||||
children]
|
children]
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
(ns quo2.components.community.banner.style
|
||||||
|
(:require [quo2.foundations.colors :as colors]))
|
||||||
|
|
||||||
|
(defn community-card
|
||||||
|
[radius]
|
||||||
|
{:shadow-offset {:width 0
|
||||||
|
:height 2}
|
||||||
|
:shadow-radius radius
|
||||||
|
:shadow-opacity 1
|
||||||
|
:shadow-color colors/shadow
|
||||||
|
:elevation 1
|
||||||
|
:border-radius radius
|
||||||
|
:justify-content :space-between
|
||||||
|
:background-color (colors/theme-colors
|
||||||
|
colors/white
|
||||||
|
colors/neutral-90)})
|
||||||
|
|
||||||
|
(def banner-content
|
||||||
|
{:flex 1
|
||||||
|
:padding-top 8
|
||||||
|
:padding-bottom 8
|
||||||
|
:border-radius 12})
|
||||||
|
|
||||||
|
(def banner-title
|
||||||
|
{:flex 1
|
||||||
|
:padding-horizontal 12})
|
||||||
|
|
||||||
|
(def banner-card
|
||||||
|
{:flex-direction :row
|
||||||
|
:margin-horizontal 20
|
||||||
|
:margin-vertical 8
|
||||||
|
:height 56
|
||||||
|
:padding-right 12})
|
||||||
|
|
||||||
|
(def discover-illustration
|
||||||
|
{:position :absolute
|
||||||
|
:top -4
|
||||||
|
:right 0})
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
(ns quo2.components.community.banner.view
|
||||||
|
(:require [quo2.components.community.banner.style :as style]
|
||||||
|
[quo2.components.markdown.text :as text]
|
||||||
|
[quo2.foundations.colors :as colors]
|
||||||
|
[react-native.core :as rn]))
|
||||||
|
|
||||||
|
(defn- card-title-and-description
|
||||||
|
[title description]
|
||||||
|
[rn/view
|
||||||
|
{:style style/banner-content}
|
||||||
|
[rn/view
|
||||||
|
{:style style/banner-title}
|
||||||
|
[text/text
|
||||||
|
{:accessibility-label :community-name-text
|
||||||
|
:ellipsize-mode :tail
|
||||||
|
:number-of-lines 1
|
||||||
|
:weight :semi-bold
|
||||||
|
:size :paragraph-1}
|
||||||
|
title]
|
||||||
|
[text/text
|
||||||
|
{:accessibility-label :community-name-text
|
||||||
|
:ellipsize-mode :tail
|
||||||
|
:number-of-lines 1
|
||||||
|
:color (colors/theme-colors
|
||||||
|
colors/neutral-50
|
||||||
|
colors/neutral-40)
|
||||||
|
:weight :regular
|
||||||
|
:size :paragraph-2}
|
||||||
|
description]]])
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[{:keys [title description on-press accessibility-label banner]}]
|
||||||
|
[rn/touchable-without-feedback
|
||||||
|
{:on-press on-press
|
||||||
|
:accessibility-label accessibility-label}
|
||||||
|
[rn/view
|
||||||
|
(merge (style/community-card 16)
|
||||||
|
{:background-color (colors/theme-colors
|
||||||
|
colors/white
|
||||||
|
colors/neutral-90)}
|
||||||
|
style/banner-card)
|
||||||
|
[card-title-and-description title description]
|
||||||
|
[rn/image
|
||||||
|
{:style style/discover-illustration
|
||||||
|
:source banner
|
||||||
|
:accessibility-label :discover-communities-illustration}]]])
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
(ns quo2.components.community.discover-card
|
|
||||||
(:require [quo2.components.community.style :as style]
|
|
||||||
[quo2.components.markdown.text :as text]
|
|
||||||
[quo2.foundations.colors :as colors]
|
|
||||||
[react-native.core :as rn]))
|
|
||||||
|
|
||||||
;; Discover card placeholders images.
|
|
||||||
;; TODO replaced when real data is available
|
|
||||||
(def images
|
|
||||||
{:images [{:id 1 :column-images [{:id 1 :image ""}]}
|
|
||||||
{:id 2 :column-images [{}]}]})
|
|
||||||
|
|
||||||
(defn card-title-and-description
|
|
||||||
[title description]
|
|
||||||
[rn/view
|
|
||||||
{:flex 1
|
|
||||||
:padding-top 8
|
|
||||||
:padding-bottom 8
|
|
||||||
:border-radius 12}
|
|
||||||
[rn/view
|
|
||||||
{:flex 1
|
|
||||||
:padding-horizontal 12}
|
|
||||||
[text/text
|
|
||||||
{:accessibility-label :community-name-text
|
|
||||||
:ellipsize-mode :tail
|
|
||||||
:number-of-lines 1
|
|
||||||
:weight :semi-bold
|
|
||||||
:size :paragraph-1}
|
|
||||||
title]
|
|
||||||
[text/text
|
|
||||||
{:accessibility-label :community-name-text
|
|
||||||
:ellipsize-mode :tail
|
|
||||||
:number-of-lines 1
|
|
||||||
:color (colors/theme-colors
|
|
||||||
colors/neutral-50
|
|
||||||
colors/neutral-40)
|
|
||||||
:weight :regular
|
|
||||||
:size :paragraph-2}
|
|
||||||
description]]])
|
|
||||||
|
|
||||||
(defn placeholder-list-images
|
|
||||||
[{:keys [images width height border-radius]}]
|
|
||||||
[rn/view
|
|
||||||
[rn/view {:justify-content :center}
|
|
||||||
(for [{:keys [id]} images]
|
|
||||||
^{:key id}
|
|
||||||
[rn/view
|
|
||||||
{:border-radius border-radius
|
|
||||||
:margin-top 4
|
|
||||||
:margin-right 4
|
|
||||||
:width width
|
|
||||||
:height height
|
|
||||||
:background-color colors/neutral-10}])]])
|
|
||||||
|
|
||||||
(defn placeholder-row-images
|
|
||||||
[{:keys [first-image last-image images width height
|
|
||||||
border-radius]}]
|
|
||||||
[rn/view
|
|
||||||
(when first-image
|
|
||||||
[rn/view
|
|
||||||
{:border-bottom-right-radius 6
|
|
||||||
:border-bottom-left-radius 6
|
|
||||||
:margin-right 4
|
|
||||||
:width width
|
|
||||||
:height height
|
|
||||||
:background-color colors/neutral-10}])
|
|
||||||
(when images
|
|
||||||
[placeholder-list-images
|
|
||||||
{:images images
|
|
||||||
:width 32
|
|
||||||
:height 32
|
|
||||||
:border-radius 6}])
|
|
||||||
(when last-image
|
|
||||||
[rn/view
|
|
||||||
{:border-top-left-radius border-radius
|
|
||||||
:border-top-right-radius 6
|
|
||||||
:margin-top 4
|
|
||||||
:width width
|
|
||||||
:height height
|
|
||||||
:background-color colors/neutral-10}])])
|
|
||||||
|
|
||||||
(defn discover-card
|
|
||||||
[{:keys [title description on-press accessibility-label]}]
|
|
||||||
(let [on-joined-images (get images :images)]
|
|
||||||
[rn/touchable-without-feedback
|
|
||||||
{:on-press on-press
|
|
||||||
:accessibility-label accessibility-label}
|
|
||||||
[rn/view
|
|
||||||
(merge (style/community-card 16)
|
|
||||||
{:background-color (colors/theme-colors
|
|
||||||
colors/white
|
|
||||||
colors/neutral-90)}
|
|
||||||
{:flex-direction :row
|
|
||||||
:margin-horizontal 20
|
|
||||||
:margin-vertical 8
|
|
||||||
:height 56
|
|
||||||
:padding-right 12})
|
|
||||||
[card-title-and-description title description]
|
|
||||||
(for [{:keys [id column-images]} on-joined-images]
|
|
||||||
^{:key id}
|
|
||||||
[placeholder-row-images
|
|
||||||
{:images (when (= id 1)
|
|
||||||
column-images)
|
|
||||||
:width 32
|
|
||||||
:height (if (= id 1) 8 26)
|
|
||||||
:border-radius 6
|
|
||||||
:first-image "" ; TODO replace with real data
|
|
||||||
:last-image ""}])]])) ; TODO replace with real data
|
|
||||||
@@ -112,3 +112,39 @@
|
|||||||
{:position :absolute
|
{:position :absolute
|
||||||
:top 8
|
:top 8
|
||||||
:right 8})
|
:right 8})
|
||||||
|
|
||||||
|
(def token-tag-spacing
|
||||||
|
{:margin-top 10
|
||||||
|
:margin-right 8})
|
||||||
|
|
||||||
|
(defn token-row
|
||||||
|
[padding?]
|
||||||
|
(merge
|
||||||
|
{:flex-direction :row
|
||||||
|
:flex-wrap :wrap
|
||||||
|
:align-items :center}
|
||||||
|
(when padding?
|
||||||
|
{:padding-horizontal 12})))
|
||||||
|
|
||||||
|
(def token-row-container
|
||||||
|
{:flex-direction :row
|
||||||
|
:align-items :center
|
||||||
|
:margin-bottom 12})
|
||||||
|
|
||||||
|
(defn token-row-or-text
|
||||||
|
[padding?]
|
||||||
|
(merge
|
||||||
|
{:margin-top 4
|
||||||
|
:color (colors/theme-colors
|
||||||
|
colors/neutral-50
|
||||||
|
colors/neutral-40)}
|
||||||
|
(when padding?
|
||||||
|
{:padding-left 12})))
|
||||||
|
|
||||||
|
(defn token-row-or-border
|
||||||
|
[]
|
||||||
|
{:height 1
|
||||||
|
:background-color (colors/theme-colors
|
||||||
|
colors/neutral-20
|
||||||
|
colors/neutral-80)})
|
||||||
|
|
||||||
|
|||||||
@@ -1,295 +1,45 @@
|
|||||||
(ns quo2.components.community.token-gating
|
(ns quo2.components.community.token-gating
|
||||||
(:require [quo2.components.avatars.channel-avatar :as channel-avatar]
|
(:require [quo2.components.markdown.text :as text]
|
||||||
[quo2.components.buttons.button :as button]
|
|
||||||
[quo2.components.icon :as icon]
|
|
||||||
[quo2.components.info.information-box :as information-box]
|
|
||||||
[quo2.components.markdown.text :as text]
|
|
||||||
[quo2.components.tags.token-tag :as token-tag]
|
[quo2.components.tags.token-tag :as token-tag]
|
||||||
[quo2.foundations.colors :as colors]
|
[react-native.core :as rn]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[react-native.fast-image :as fast-image]
|
[clojure.string :as string]
|
||||||
[react-native.core :as rn]))
|
[quo2.components.community.style :as style]))
|
||||||
|
|
||||||
(def ^:private token-tag-horizontal-spacing 7)
|
|
||||||
(def token-tag-vertical-spacing 5)
|
|
||||||
|
|
||||||
(def styles
|
|
||||||
{:container {:flex 1
|
|
||||||
:padding-horizontal 20}
|
|
||||||
:header-container {:flex-direction :row
|
|
||||||
:align-items :center}
|
|
||||||
:header-spacing-community {:margin-bottom 16}
|
|
||||||
:header-spacing-channel {:margin-bottom 24}
|
|
||||||
:header-avatar {:margin-right 8}
|
|
||||||
:header-community-avatar-image {:width 32 :height 32}
|
|
||||||
:header-title-container {:flex 1
|
|
||||||
:flex-direction :row
|
|
||||||
:align-items :center}
|
|
||||||
:header-title-lock {:margin-left 6}
|
|
||||||
:header-info-button {:margin-left 8}
|
|
||||||
:token-requirement-text-spacing {:margin-vertical 8}
|
|
||||||
:token-requirement-list-spacing {:padding-vertical (- 8 token-tag-vertical-spacing)}
|
|
||||||
:token-row {:flex-direction :row
|
|
||||||
:flex-wrap :wrap
|
|
||||||
:align-items :center}
|
|
||||||
:token-row-container {:flex-direction :row
|
|
||||||
:align-items :center
|
|
||||||
:margin-horizontal (- token-tag-horizontal-spacing)}
|
|
||||||
:token-row-container-no-shift {:margin-left 0}
|
|
||||||
:token-row-or-text {:margin-right 3}
|
|
||||||
:token-tag-spacing {:margin-horizontal token-tag-horizontal-spacing
|
|
||||||
:margin-vertical token-tag-vertical-spacing}
|
|
||||||
:divider {:height 1
|
|
||||||
:margin-horizontal -20
|
|
||||||
:margin-top (- 12 token-tag-vertical-spacing)
|
|
||||||
:margin-bottom 8}
|
|
||||||
:membership-request-denied {:margin-top 13}
|
|
||||||
:enter-button {:margin-top 16}
|
|
||||||
:info-text {:margin-top 12
|
|
||||||
:text-align :center
|
|
||||||
:padding-horizontal 20}})
|
|
||||||
|
|
||||||
(defn multiple-token-requirements?
|
|
||||||
[token-requirement-lists]
|
|
||||||
(when (vector? (first token-requirement-lists))
|
|
||||||
(> (count token-requirement-lists) 1)))
|
|
||||||
|
|
||||||
(defn is-token-requirement-met?
|
|
||||||
[token-requirement-list]
|
|
||||||
(and (seq token-requirement-list)
|
|
||||||
(every?
|
|
||||||
(fn [token]
|
|
||||||
(get token :is-sufficient?))
|
|
||||||
token-requirement-list)))
|
|
||||||
|
|
||||||
(defn are-multiple-token-requirements-met?
|
|
||||||
[token-requirement-lists]
|
|
||||||
(if (multiple-token-requirements? token-requirement-lists)
|
|
||||||
(some is-token-requirement-met? token-requirement-lists)
|
|
||||||
(is-token-requirement-met? token-requirement-lists)))
|
|
||||||
|
|
||||||
(defn token-requirement-list-row
|
(defn token-requirement-list-row
|
||||||
[tokens community-color]
|
[tokens padding?]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style (merge
|
{:style (style/token-row padding?)}
|
||||||
(get styles :token-row)
|
(doall
|
||||||
(get styles :token-requirement-list-spacing))}
|
(map-indexed (fn [token-index token]
|
||||||
(map-indexed (fn [token-index token]
|
(let [{:keys [img-src symbol amount sufficient? purchasable? loading?]} token]
|
||||||
(let [{:keys [token-img-src token amount is-sufficient? is-purchasable?]} token]
|
^{:key token-index}
|
||||||
^{:key token-index}
|
[rn/view {:style style/token-tag-spacing}
|
||||||
[rn/view {:style (get styles :token-tag-spacing)}
|
[token-tag/token-tag
|
||||||
[token-tag/token-tag
|
{:symbol symbol
|
||||||
{:token token
|
:value amount
|
||||||
:value amount
|
:size 24
|
||||||
:size 24
|
:sufficient? sufficient?
|
||||||
:border-color community-color
|
:purchasable purchasable?
|
||||||
:is-required is-sufficient?
|
:loading? loading?
|
||||||
:is-purchasable is-purchasable?
|
:img-src img-src}]]))
|
||||||
:token-img-src token-img-src}]]))
|
tokens))])
|
||||||
tokens)])
|
|
||||||
|
|
||||||
(defn token-requirement-list
|
(defn token-requirement-list
|
||||||
[props community-color]
|
[{:keys [tokens padding?]}]
|
||||||
(let [{:keys [gate token-requirements-changed?
|
[:<>
|
||||||
required-tokens-lost?]} props
|
(if (> (count tokens) 1)
|
||||||
[gate-type token-requirement-lists] gate
|
(doall
|
||||||
multiple-token-requirements? (multiple-token-requirements? token-requirement-lists)
|
(map-indexed
|
||||||
is-sufficient? (are-multiple-token-requirements-met?
|
(fn [token-requirement-index tokens]
|
||||||
token-requirement-lists)
|
^{:key token-requirement-index}
|
||||||
you-must-hold-label (if (= gate-type :join)
|
[rn/view {:margin-bottom 12}
|
||||||
(cond
|
(when-not (= token-requirement-index 0)
|
||||||
token-requirements-changed? :t/you-must-now-hold
|
[rn/view {:style (style/token-row-or-border)}])
|
||||||
required-tokens-lost? :t/you-must-always-hold
|
(when-not (= token-requirement-index 0)
|
||||||
:else :t/you-must-hold)
|
|
||||||
:t/you-must-hold)
|
|
||||||
message-label (cond
|
|
||||||
(= gate-type :join)
|
|
||||||
(cond
|
|
||||||
token-requirements-changed?
|
|
||||||
:t/community-join-requirements-changed
|
|
||||||
required-tokens-lost?
|
|
||||||
:t/community-join-requirements-tokens-lost
|
|
||||||
:else (if is-sufficient?
|
|
||||||
:t/community-join-requirements-met
|
|
||||||
:t/community-join-requirements-not-met))
|
|
||||||
(= gate-type :read)
|
|
||||||
(if is-sufficient?
|
|
||||||
:t/community-channel-read-requirements-met
|
|
||||||
:t/community-channel-read-requirements-not-met)
|
|
||||||
(= gate-type :write)
|
|
||||||
(if is-sufficient?
|
|
||||||
:t/community-channel-write-requirements-met
|
|
||||||
:t/community-channel-write-requirements-not-met))]
|
|
||||||
[rn/view
|
|
||||||
[rn/view {:style (get styles :token-requirement-text-spacing)}
|
|
||||||
[text/text
|
|
||||||
{:weight :medium
|
|
||||||
:number-of-lines 1}
|
|
||||||
(i18n/label
|
|
||||||
message-label)]
|
|
||||||
[text/text
|
|
||||||
{:size :paragraph-2
|
|
||||||
:number-of-lines 1}
|
|
||||||
(i18n/label
|
|
||||||
you-must-hold-label)]]
|
|
||||||
|
|
||||||
(if multiple-token-requirements?
|
|
||||||
(map-indexed
|
|
||||||
(fn [token-requirement-index tokens]
|
|
||||||
^{:key token-requirement-index}
|
|
||||||
[rn/view
|
|
||||||
{:style (merge
|
|
||||||
(get styles :token-row-container)
|
|
||||||
(when-not (= token-requirement-index 0)
|
|
||||||
(get styles :token-row-container-no-shift)))}
|
|
||||||
(when-not (= token-requirement-index 0)
|
|
||||||
[text/text
|
|
||||||
{:style (get styles :token-row-or-text)
|
|
||||||
:size :paragraph-2} "or"])
|
|
||||||
[token-requirement-list-row tokens community-color]])
|
|
||||||
token-requirement-lists)
|
|
||||||
[rn/view {:style (get styles :token-row-container)}
|
|
||||||
[token-requirement-list-row token-requirement-lists community-color]])]))
|
|
||||||
|
|
||||||
(defn is-community-locked?
|
|
||||||
[community]
|
|
||||||
(not (are-multiple-token-requirements-met? (get-in community [:gates :join]))))
|
|
||||||
|
|
||||||
(defn is-channel-locked?
|
|
||||||
[channel]
|
|
||||||
(not (are-multiple-token-requirements-met?
|
|
||||||
(or (get-in channel [:gates :read])
|
|
||||||
(get-in channel [:gates :write])))))
|
|
||||||
|
|
||||||
(defn token-gating
|
|
||||||
"[token-gating opts]
|
|
||||||
opts
|
|
||||||
{
|
|
||||||
:community {
|
|
||||||
:name string
|
|
||||||
:community-avatar-img-src string
|
|
||||||
:community-color string
|
|
||||||
:community-text-color string
|
|
||||||
:token-requirements-changed? boolean
|
|
||||||
:required-tokens-lost? boolean
|
|
||||||
}
|
|
||||||
:channel {
|
|
||||||
:name string
|
|
||||||
:emoji string
|
|
||||||
:emoji-background-color :string
|
|
||||||
:on-enter-channel callback
|
|
||||||
:membership-request-denied? boolean
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
[_ _]
|
|
||||||
(fn [{:keys [community channel]}]
|
|
||||||
(let [type (if (some? community) :community :channel)
|
|
||||||
{:keys [name
|
|
||||||
emoji
|
|
||||||
emoji-background-color
|
|
||||||
on-enter-channel
|
|
||||||
community-avatar-img-src
|
|
||||||
community-color
|
|
||||||
community-text-color
|
|
||||||
membership-request-denied?
|
|
||||||
token-requirements-changed?
|
|
||||||
required-tokens-lost?
|
|
||||||
gates]}
|
|
||||||
(if (= type :community) community channel)
|
|
||||||
locked? (if
|
|
||||||
(= type :community)
|
|
||||||
(is-community-locked? community)
|
|
||||||
(is-channel-locked? channel))]
|
|
||||||
|
|
||||||
[rn/view
|
|
||||||
{:style (merge (get styles :container)
|
|
||||||
{:background-color (colors/theme-colors colors/white colors/neutral-90)})}
|
|
||||||
[rn/view
|
|
||||||
{:style (merge
|
|
||||||
(get styles :header-container)
|
|
||||||
(if
|
|
||||||
(= type :community)
|
|
||||||
(get styles :header-spacing-community)
|
|
||||||
(get styles :header-spacing-channel)))}
|
|
||||||
|
|
||||||
[rn/view {:style (get styles :header-avatar)}
|
|
||||||
(if (= type :community)
|
|
||||||
[fast-image/fast-image
|
|
||||||
{:source community-avatar-img-src
|
|
||||||
:style (get styles :header-community-avatar-image)}]
|
|
||||||
|
|
||||||
[channel-avatar/channel-avatar
|
|
||||||
{:big? true
|
|
||||||
:locked? locked?
|
|
||||||
:emoji emoji
|
|
||||||
:emoji-background-color emoji-background-color}])]
|
|
||||||
|
|
||||||
[rn/view {:style (get styles :header-title-container)}
|
|
||||||
[text/text
|
|
||||||
{:weight :semi-bold
|
|
||||||
:number-of-lines 1
|
|
||||||
:size :heading-1
|
|
||||||
:style (get styles :header-text)} (if (= type :community) name (str "# " name))]
|
|
||||||
|
|
||||||
(when (= type :community)
|
|
||||||
[icon/icon
|
|
||||||
(if locked?
|
|
||||||
:main-icons2/locked
|
|
||||||
:main-icons2/unlocked)
|
|
||||||
{:container-style (get styles :header-title-lock)
|
|
||||||
:color (colors/theme-colors
|
|
||||||
colors/neutral-50
|
|
||||||
colors/neutral-40)}])]
|
|
||||||
|
|
||||||
[button/button
|
|
||||||
{:type :outline
|
|
||||||
:size 32
|
|
||||||
:icon true
|
|
||||||
:style (get styles :header-info-button)} :main-icons2/info]]
|
|
||||||
|
|
||||||
(map-indexed (fn [gate-index gate]
|
|
||||||
^{:key gate-index}
|
|
||||||
[:<>
|
|
||||||
(when-not (= gate-index 0)
|
|
||||||
[rn/view
|
|
||||||
{:style (merge
|
|
||||||
(get styles :divider)
|
|
||||||
{:background-color (colors/theme-colors
|
|
||||||
colors/neutral-10
|
|
||||||
colors/neutral-80)})}])
|
|
||||||
[token-requirement-list
|
|
||||||
{:gate gate
|
|
||||||
:token-requirements-changed? token-requirements-changed?
|
|
||||||
:required-tokens-lost? required-tokens-lost?} community-color]])
|
|
||||||
gates)
|
|
||||||
|
|
||||||
(when (= type :channel)
|
|
||||||
(if membership-request-denied?
|
|
||||||
[information-box/information-box
|
|
||||||
{:type :error
|
|
||||||
:icon :main-icons2/untrustworthy
|
|
||||||
:no-icon-color? true
|
|
||||||
:style (get styles :membership-request-denied)}
|
|
||||||
(i18n/label
|
|
||||||
:t/membership-request-denied)]
|
|
||||||
|
|
||||||
[:<>
|
|
||||||
[button/button
|
|
||||||
{:type :community
|
|
||||||
:community-color community-color
|
|
||||||
:community-text-color community-text-color
|
|
||||||
:style (get styles :enter-button)
|
|
||||||
:disabled locked?
|
|
||||||
:on-press on-enter-channel}
|
|
||||||
(str "# "
|
|
||||||
(i18n/label
|
|
||||||
:t/enter-channel))]
|
|
||||||
[text/text
|
[text/text
|
||||||
{:size :paragraph-2
|
{:style (style/token-row-or-text padding?)
|
||||||
:style (merge
|
:size :label} (string/lower-case (i18n/label :t/or))])
|
||||||
(get styles :info-text)
|
[token-requirement-list-row tokens padding?]])
|
||||||
{:color (colors/theme-colors
|
tokens))
|
||||||
colors/neutral-50
|
[token-requirement-list-row (first tokens) padding?])])
|
||||||
colors/neutral-40)})}
|
|
||||||
(i18n/label
|
|
||||||
:t/community-enter-channel-info)]]))])))
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
(ns quo2.components.drawers.action-drawers.style
|
(ns quo2.components.drawers.action-drawers.style
|
||||||
(:require [quo2.foundations.colors :as colors]))
|
(:require [quo2.foundations.colors :as colors]))
|
||||||
|
|
||||||
(def divider
|
(defn divider
|
||||||
|
[]
|
||||||
{:border-top-width 1
|
{:border-top-width 1
|
||||||
:border-top-color (colors/theme-colors
|
:border-top-color (colors/theme-colors colors/neutral-10 colors/neutral-90)
|
||||||
colors/neutral-10
|
|
||||||
colors/neutral-90)
|
|
||||||
:margin-top 8
|
:margin-top 8
|
||||||
:margin-bottom 7
|
:margin-bottom 7
|
||||||
:align-items :center
|
:align-items :center
|
||||||
|
|||||||
@@ -8,12 +8,13 @@
|
|||||||
(defn- get-icon-color
|
(defn- get-icon-color
|
||||||
[danger? override-theme]
|
[danger? override-theme]
|
||||||
(if danger?
|
(if danger?
|
||||||
colors/danger-50
|
colors/danger-60
|
||||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)))
|
(colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)))
|
||||||
|
|
||||||
(def divider
|
(defn divider
|
||||||
|
[]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/divider
|
{:style (style/divider)
|
||||||
:accessible true
|
:accessible true
|
||||||
:accessibility-label :divider}])
|
:accessibility-label :divider}])
|
||||||
|
|
||||||
@@ -30,7 +31,8 @@
|
|||||||
:as action-props}]
|
:as action-props}]
|
||||||
(when action-props
|
(when action-props
|
||||||
[:<> {:key label}
|
[:<> {:key label}
|
||||||
(when add-divider? divider)
|
(when add-divider?
|
||||||
|
[divider])
|
||||||
[rn/touchable-highlight
|
[rn/touchable-highlight
|
||||||
{:accessibility-label accessibility-label
|
{:accessibility-label accessibility-label
|
||||||
:style (style/container sub-label)
|
:style (style/container sub-label)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
{:label (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 override-theme)
|
{:label (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 override-theme)
|
||||||
:icon (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 override-theme)
|
:icon (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 override-theme)
|
||||||
:button-border (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 override-theme)
|
:button-border (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 override-theme)
|
||||||
:password-icon (colors/theme-colors colors/neutral-100 colors/white override-theme)
|
:password-icon (colors/theme-colors colors/neutral-100 colors/white-opa-70 override-theme)
|
||||||
:clear-icon (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 override-theme)
|
:clear-icon (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 override-theme)
|
||||||
:cursor (colors/theme-colors (colors/custom-color :blue 50)
|
:cursor (colors/theme-colors (colors/custom-color :blue 50)
|
||||||
colors/white
|
colors/white
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
[quo2.components.inputs.input.style :as style]
|
[quo2.components.inputs.input.style :as style]
|
||||||
[quo2.components.markdown.text :as text]
|
[quo2.components.markdown.text :as text]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]))
|
[reagent.core :as reagent]
|
||||||
|
[quo2.theme :as theme]))
|
||||||
|
|
||||||
(defn- label-&-counter
|
(defn- label-&-counter
|
||||||
[{:keys [label current-chars char-limit variant-colors]}]
|
[{:keys [label current-chars char-limit variant-colors]}]
|
||||||
@@ -100,6 +101,7 @@
|
|||||||
(cond-> {:style (style/input colors-by-status small? @multiple-lines?)
|
(cond-> {:style (style/input colors-by-status small? @multiple-lines?)
|
||||||
:accessibility-label :input
|
:accessibility-label :input
|
||||||
:placeholder-text-color (:placeholder colors-by-status)
|
:placeholder-text-color (:placeholder colors-by-status)
|
||||||
|
:keyboard-appearance (theme/theme-value :light :dark override-theme)
|
||||||
:cursor-color (:cursor variant-colors)
|
:cursor-color (:cursor variant-colors)
|
||||||
:editable (not disabled?)
|
:editable (not disabled?)
|
||||||
:on-focus (fn []
|
:on-focus (fn []
|
||||||
@@ -140,7 +142,7 @@
|
|||||||
(assoc props
|
(assoc props
|
||||||
:accessibility-label :password-input
|
:accessibility-label :password-input
|
||||||
:auto-capitalize :none
|
:auto-capitalize :none
|
||||||
:auto-complete :password-new
|
:auto-complete :password
|
||||||
:secure-text-entry (not @password-shown?)
|
:secure-text-entry (not @password-shown?)
|
||||||
:right-icon {:style-fn style/password-icon
|
:right-icon {:style-fn style/password-icon
|
||||||
:icon-name (if @password-shown? :i/hide :i/reveal)
|
:icon-name (if @password-shown? :i/hide :i/reveal)
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
[quo2.components.inputs.recovery-phrase.style :as style]
|
[quo2.components.inputs.recovery-phrase.style :as style]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]))
|
[reagent.core :as reagent]
|
||||||
|
[quo2.theme :as theme]))
|
||||||
|
|
||||||
(def ^:private custom-props
|
(def ^:private custom-props
|
||||||
[:customization-color :override-theme :blur? :cursor-color :multiline :on-focus :on-blur
|
[:customization-color :override-theme :blur? :cursor-color :multiline :on-focus :on-blur
|
||||||
@@ -42,6 +43,7 @@
|
|||||||
:style (style/input)
|
:style (style/input)
|
||||||
:placeholder-text-color (style/placeholder-color @state override-theme blur?)
|
:placeholder-text-color (style/placeholder-color @state override-theme blur?)
|
||||||
:cursor-color (style/cursor-color customization-color override-theme)
|
:cursor-color (style/cursor-color customization-color override-theme)
|
||||||
|
:keyboard-appearance (theme/theme-value :light :dark override-theme)
|
||||||
:multiline true
|
:multiline true
|
||||||
:on-focus (fn []
|
:on-focus (fn []
|
||||||
(set-focused)
|
(set-focused)
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
[quo2.components.icon :as icon]
|
[quo2.components.icon :as icon]
|
||||||
[quo2.components.inputs.search-input.style :as style]
|
[quo2.components.inputs.search-input.style :as style]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]))
|
[reagent.core :as reagent]
|
||||||
|
[quo2.foundations.colors :as colors]))
|
||||||
|
|
||||||
(def ^:private tag-separator [rn/view {:style style/tag-separator}])
|
(def ^:private tag-separator [rn/view {:style style/tag-separator}])
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@
|
|||||||
:placeholder-text-color (style/placeholder-color @state blur? override-theme)
|
:placeholder-text-color (style/placeholder-color @state blur? override-theme)
|
||||||
:editable (not disabled?)
|
:editable (not disabled?)
|
||||||
:on-key-press #(handle-backspace % @scroll-view-ref)
|
:on-key-press #(handle-backspace % @scroll-view-ref)
|
||||||
|
:keyboard-appearance (colors/theme-colors :light :dark override-theme)
|
||||||
:on-change-text (fn [new-text]
|
:on-change-text (fn [new-text]
|
||||||
(when on-change-text
|
(when on-change-text
|
||||||
(on-change-text new-text))
|
(on-change-text new-text))
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
[quo2.components.inputs.title-input.style :as style]
|
[quo2.components.inputs.title-input.style :as style]
|
||||||
[quo2.components.markdown.text :as text]
|
[quo2.components.markdown.text :as text]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[react-native.core :as rn]))
|
[react-native.core :as rn]
|
||||||
|
[quo2.theme :as theme]))
|
||||||
|
|
||||||
(defn- pad-0
|
(defn- pad-0
|
||||||
[value]
|
[value]
|
||||||
@@ -38,6 +39,7 @@
|
|||||||
:style (style/title-text disabled? blur? override-theme)})
|
:style (style/title-text disabled? blur? override-theme)})
|
||||||
:default-value default-value
|
:default-value default-value
|
||||||
:accessibility-label :profile-title-input
|
:accessibility-label :profile-title-input
|
||||||
|
:keyboard-appearance (theme/theme-value :light :dark override-theme)
|
||||||
:on-focus #(swap! focused? (fn [] true))
|
:on-focus #(swap! focused? (fn [] true))
|
||||||
:on-blur #(swap! focused? (fn [] false))
|
:on-blur #(swap! focused? (fn [] false))
|
||||||
:input-mode :text
|
:input-mode :text
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
(ns quo2.components.keycard.component-spec
|
||||||
|
(:require [quo2.components.keycard.view :as keycard]
|
||||||
|
[test-helpers.component :as h]))
|
||||||
|
|
||||||
|
(h/describe "keycard component"
|
||||||
|
(h/test "Render of keycard component when: holder-name prop is not set"
|
||||||
|
(h/render [keycard/keycard])
|
||||||
|
(h/is-truthy (h/get-by-translation-text :empty-keycard)))
|
||||||
|
(h/test "Render of keycard component when: holder-name prop is set"
|
||||||
|
(h/render [keycard/keycard {:holder-name "Alisha"}])
|
||||||
|
(h/is-truthy (h/get-by-translation-text :user-keycard))))
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
(ns quo2.components.keycard.style
|
||||||
|
(:require [quo2.foundations.colors :as colors]))
|
||||||
|
|
||||||
|
(def keycard-height 210)
|
||||||
|
(def keycard-chip-height 28)
|
||||||
|
|
||||||
|
(defn card-container
|
||||||
|
[locked?]
|
||||||
|
{:overflow :hidden
|
||||||
|
:height keycard-height
|
||||||
|
:align-items :flex-start
|
||||||
|
:justify-content :space-between
|
||||||
|
:border-width 1
|
||||||
|
:border-color (if locked?
|
||||||
|
colors/white-opa-5
|
||||||
|
(colors/theme-colors colors/neutral-20 colors/neutral-80))
|
||||||
|
:border-style :solid
|
||||||
|
:border-radius 16
|
||||||
|
:padding 16
|
||||||
|
:background-color (if locked?
|
||||||
|
(colors/theme-colors colors/danger colors/danger-opa-40)
|
||||||
|
(colors/theme-colors colors/neutral-5 colors/neutral-90))})
|
||||||
|
|
||||||
|
(defn keycard-logo
|
||||||
|
[locked?]
|
||||||
|
{:tint-color (if locked? colors/white (colors/theme-colors colors/neutral-100 colors/white))})
|
||||||
|
|
||||||
|
(defn keycard-watermark
|
||||||
|
[locked?]
|
||||||
|
{:position :absolute
|
||||||
|
:tint-color (if locked? colors/white-opa-5 (colors/theme-colors colors/neutral-100 colors/white))
|
||||||
|
:align-self :center
|
||||||
|
:height 280.48
|
||||||
|
:transform [{:rotate "-30deg"} {:translateY -30}]
|
||||||
|
:opacity (when-not locked? 0.02)
|
||||||
|
:z-index 1})
|
||||||
|
|
||||||
|
(def keycard-chip
|
||||||
|
{:height keycard-chip-height
|
||||||
|
:position :absolute
|
||||||
|
:right 16
|
||||||
|
:top (/ (- keycard-height 28) 2)})
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
(ns quo2.components.keycard.view
|
||||||
|
(:require [react-native.core :as rn]
|
||||||
|
[quo2.components.keycard.style :as style]
|
||||||
|
[quo2.components.tags.tag :as tag]
|
||||||
|
[quo2.foundations.colors :as colors]
|
||||||
|
[quo2.foundations.resources :as resources]
|
||||||
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
|
(defn keycard
|
||||||
|
"This component based on the following properties:
|
||||||
|
- :holder-name - Can be owner's name. Default is Empty
|
||||||
|
- :locked? - Boolean to specify whether the keycard is locked or not
|
||||||
|
"
|
||||||
|
[{:keys [holder-name locked?]}]
|
||||||
|
(let [label (if (boolean holder-name)
|
||||||
|
(i18n/label :t/user-keycard {:name holder-name})
|
||||||
|
(i18n/label :t/empty-keycard))]
|
||||||
|
[rn/view {:style (style/card-container locked?)}
|
||||||
|
[rn/image
|
||||||
|
{:source (resources/get-image :keycard-logo)
|
||||||
|
:style (style/keycard-logo locked?)}]
|
||||||
|
[rn/image
|
||||||
|
{:source (resources/get-image
|
||||||
|
(if (or locked? (colors/dark?)) :keycard-chip-dark :keycard-chip-light))
|
||||||
|
:style style/keycard-chip}]
|
||||||
|
[rn/image
|
||||||
|
{:source (resources/get-image :keycard-watermark)
|
||||||
|
:style (style/keycard-watermark locked?)}]
|
||||||
|
[tag/tag
|
||||||
|
{:size 32
|
||||||
|
:type (when locked? :icon)
|
||||||
|
:label label
|
||||||
|
:labelled? true
|
||||||
|
:blurred? true
|
||||||
|
:resource (when locked? :i/locked)
|
||||||
|
:accessibility-label :holder-name
|
||||||
|
:icon-color colors/white-70-blur
|
||||||
|
:override-theme (when locked? :dark)}]]))
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
{:title "Some title"
|
{:title "Some title"
|
||||||
:description "Some description"
|
:description "Some description"
|
||||||
:link "status.im"
|
:link "status.im"
|
||||||
|
:logo "data:image/png,logo-x"
|
||||||
:thumbnail "data:image/png,whatever"})
|
:thumbnail "data:image/png,whatever"})
|
||||||
|
|
||||||
(h/describe "Links - Link Preview"
|
(h/describe "Links - Link Preview"
|
||||||
@@ -19,12 +20,17 @@
|
|||||||
(h/is-truthy (h/query-by-text (:title props)))
|
(h/is-truthy (h/query-by-text (:title props)))
|
||||||
(h/is-truthy (h/query-by-text (:description props)))
|
(h/is-truthy (h/query-by-text (:description props)))
|
||||||
(h/is-truthy (h/query-by-text (:link props)))
|
(h/is-truthy (h/query-by-text (:link props)))
|
||||||
|
(h/is-truthy (h/query-by-label-text :logo))
|
||||||
(h/is-truthy (h/query-by-label-text :thumbnail)))
|
(h/is-truthy (h/query-by-label-text :thumbnail)))
|
||||||
|
|
||||||
(h/test "does not render thumbnail if prop is not present"
|
(h/test "does not render thumbnail if prop is not present"
|
||||||
(h/render [view/view (dissoc props :thumbnail)])
|
(h/render [view/view (dissoc props :thumbnail)])
|
||||||
(h/is-null (h/query-by-label-text :thumbnail)))
|
(h/is-null (h/query-by-label-text :thumbnail)))
|
||||||
|
|
||||||
|
(h/test "does not render logo if prop is not present"
|
||||||
|
(h/render [view/view (dissoc props :logo)])
|
||||||
|
(h/is-null (h/query-by-label-text :logo)))
|
||||||
|
|
||||||
(h/test "shows button to enable preview when preview is disabled"
|
(h/test "shows button to enable preview when preview is disabled"
|
||||||
(h/render [view/view
|
(h/render [view/view
|
||||||
(assoc props
|
(assoc props
|
||||||
|
|||||||
@@ -54,7 +54,9 @@
|
|||||||
[logo]
|
[logo]
|
||||||
[rn/image
|
[rn/image
|
||||||
{:accessibility-label :logo
|
{:accessibility-label :logo
|
||||||
:source logo
|
:source (if (string? logo)
|
||||||
|
{:uri logo}
|
||||||
|
logo)
|
||||||
:style style/logo}])
|
:style style/logo}])
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
@@ -68,9 +70,11 @@
|
|||||||
(if enabled?
|
(if enabled?
|
||||||
[:<>
|
[:<>
|
||||||
[rn/view {:style style/header-container}
|
[rn/view {:style style/header-container}
|
||||||
[logo-comp logo]
|
(when logo
|
||||||
|
[logo-comp logo])
|
||||||
[title-comp title]]
|
[title-comp title]]
|
||||||
[description-comp description]
|
(when description
|
||||||
|
[description-comp description])
|
||||||
[link-comp link]
|
[link-comp link]
|
||||||
(when thumbnail
|
(when thumbnail
|
||||||
[thumbnail-comp thumbnail thumbnail-size])]
|
[thumbnail-comp thumbnail thumbnail-size])]
|
||||||
|
|||||||
@@ -7,10 +7,14 @@
|
|||||||
(h/test "default render"
|
(h/test "default render"
|
||||||
(h/render [view/view])
|
(h/render [view/view])
|
||||||
(h/is-truthy (h/query-by-label-text :title))
|
(h/is-truthy (h/query-by-label-text :title))
|
||||||
(h/is-truthy (h/query-by-label-text :logo))
|
|
||||||
(h/is-truthy (h/query-by-label-text :button-clear-preview))
|
(h/is-truthy (h/query-by-label-text :button-clear-preview))
|
||||||
|
(h/is-null (h/query-by-label-text :logo))
|
||||||
(h/is-null (h/query-by-label-text :url-preview-loading)))
|
(h/is-null (h/query-by-label-text :url-preview-loading)))
|
||||||
|
|
||||||
|
(h/test "renders logo when prop is present"
|
||||||
|
(h/render [view/view {:logo "data:image/png,logo"}])
|
||||||
|
(h/is-truthy (h/query-by-label-text :logo)))
|
||||||
|
|
||||||
(h/test "on-clear event"
|
(h/test "on-clear event"
|
||||||
(let [on-clear (h/mock-fn)]
|
(let [on-clear (h/mock-fn)]
|
||||||
(h/render [view/view {:on-clear on-clear}])
|
(h/render [view/view {:on-clear on-clear}])
|
||||||
|
|||||||
@@ -6,11 +6,13 @@
|
|||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
[react-native.core :as rn]))
|
[react-native.core :as rn]))
|
||||||
|
|
||||||
(defn- logo-component
|
(defn- logo-comp
|
||||||
[{:keys [logo]}]
|
[{:keys [logo]}]
|
||||||
[rn/image
|
[rn/image
|
||||||
{:accessibility-label :logo
|
{:accessibility-label :logo
|
||||||
:source logo
|
:source (if (string? logo)
|
||||||
|
{:uri logo}
|
||||||
|
logo)
|
||||||
:style style/logo}])
|
:style style/logo}])
|
||||||
|
|
||||||
(defn- content
|
(defn- content
|
||||||
@@ -57,6 +59,7 @@
|
|||||||
[rn/view
|
[rn/view
|
||||||
{:accessibility-label :url-preview
|
{:accessibility-label :url-preview
|
||||||
:style (merge (style/container) container-style)}
|
:style (merge (style/container) container-style)}
|
||||||
[logo-component {:logo logo}]
|
(when logo
|
||||||
|
[logo-comp {:logo logo}])
|
||||||
[content {:title title :body body}]
|
[content {:title title :body body}]
|
||||||
[clear-button {:on-press on-clear}]]))
|
[clear-button {:on-press on-clear}]]))
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
(ns quo2.components.links.url-preview-list.view
|
(ns quo2.components.links.url-preview-list.view
|
||||||
(:require
|
(:require
|
||||||
[oops.core :as oops]
|
|
||||||
[quo2.components.links.url-preview-list.style :as style]
|
[quo2.components.links.url-preview-list.style :as style]
|
||||||
[quo2.components.links.url-preview.view :as url-preview]
|
[quo2.components.links.url-preview.view :as url-preview]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]))
|
[react-native.gesture :as gesture]))
|
||||||
|
|
||||||
(defn- use-scroll-to-last-item
|
(defn- use-scroll-to-last-item
|
||||||
[flat-list-ref item-count item-width]
|
[flat-list-ref item-count item-width]
|
||||||
@@ -44,39 +43,33 @@
|
|||||||
:on-clear on-clear
|
:on-clear on-clear
|
||||||
:container-style (merge container-style {:width width})}])
|
:container-style (merge container-style {:width width})}])
|
||||||
|
|
||||||
(defn- calculate-width
|
|
||||||
[preview-width horizontal-spacing ^js e]
|
|
||||||
(reset! preview-width
|
|
||||||
(- (oops/oget e "nativeEvent.layout.width")
|
|
||||||
(* 2 horizontal-spacing))))
|
|
||||||
|
|
||||||
(defn- f-view
|
(defn- f-view
|
||||||
[]
|
[]
|
||||||
(let [preview-width (reagent/atom 0)
|
(let [flat-list-ref (atom nil)]
|
||||||
flat-list-ref (atom nil)]
|
|
||||||
(fn [{:keys [data key-fn horizontal-spacing on-clear loading-message
|
(fn [{:keys [data key-fn horizontal-spacing on-clear loading-message
|
||||||
container-style container-style-item]}]
|
container-style container-style-item
|
||||||
(use-scroll-to-last-item flat-list-ref (count data) @preview-width)
|
preview-width]}]
|
||||||
|
(use-scroll-to-last-item flat-list-ref (count data) preview-width)
|
||||||
;; We need to use a wrapping view expanded to 100% instead of "flex 1",
|
;; We need to use a wrapping view expanded to 100% instead of "flex 1",
|
||||||
;; otherwise `on-layout` will be triggered multiple times as the flat list
|
;; otherwise `on-layout` will be triggered multiple times as the flat list
|
||||||
;; renders its children.
|
;; renders its children.
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style (merge container-style {:width "100%"})
|
{:style container-style
|
||||||
:accessibility-label :url-preview-list}
|
:accessibility-label :url-preview-list}
|
||||||
[rn/flat-list
|
[gesture/flat-list
|
||||||
{:ref #(reset! flat-list-ref %)
|
{:ref #(reset! flat-list-ref %)
|
||||||
|
:keyboard-should-persist-taps :always
|
||||||
:key-fn key-fn
|
:key-fn key-fn
|
||||||
:on-layout #(calculate-width preview-width horizontal-spacing %)
|
|
||||||
:horizontal true
|
:horizontal true
|
||||||
:deceleration-rate :fast
|
:deceleration-rate :fast
|
||||||
:on-scroll-to-index-failed identity
|
:on-scroll-to-index-failed identity
|
||||||
:content-container-style {:padding-horizontal horizontal-spacing}
|
:content-container-style {:padding-horizontal horizontal-spacing}
|
||||||
:separator [separator]
|
:separator [separator]
|
||||||
:snap-to-interval (+ @preview-width style/url-preview-gap)
|
:snap-to-interval (+ preview-width style/url-preview-gap)
|
||||||
:shows-horizontal-scroll-indicator false
|
:shows-horizontal-scroll-indicator false
|
||||||
:data data
|
:data data
|
||||||
:render-fn item-component
|
:render-fn item-component
|
||||||
:render-data {:width @preview-width
|
:render-data {:width preview-width
|
||||||
:on-clear on-clear
|
:on-clear on-clear
|
||||||
:loading-message loading-message
|
:loading-message loading-message
|
||||||
:container-style container-style-item}}]])))
|
:container-style container-style-item}}]])))
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
:override-theme :dark
|
:override-theme :dark
|
||||||
:size :medium
|
:size :medium
|
||||||
:status-indicator? false
|
:status-indicator? false
|
||||||
:customization-color customization-color}]
|
:customization-color customization-color
|
||||||
|
:static? true}]
|
||||||
[rn/view {:flex-direction :row}
|
[rn/view {:flex-direction :row}
|
||||||
(when show-logged-in?
|
(when show-logged-in?
|
||||||
[tag/tag
|
[tag/tag
|
||||||
|
|||||||
@@ -26,9 +26,10 @@
|
|||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-start-should-set-responder
|
:on-start-should-set-responder
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 70
|
{:nativeEvent {:locationX 70
|
||||||
:locationY 70
|
:locationY 70
|
||||||
:timestamp 0}})
|
:timestamp 0
|
||||||
|
:identifier 0}})
|
||||||
(-> (h/expect event)
|
(-> (h/expect event)
|
||||||
(.toHaveBeenCalledTimes 1))))
|
(.toHaveBeenCalledTimes 1))))
|
||||||
|
|
||||||
@@ -43,16 +44,18 @@
|
|||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-start-should-set-responder
|
:on-start-should-set-responder
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 70
|
{:nativeEvent {:locationX 70
|
||||||
:locationY 70
|
:locationY 70
|
||||||
:timestamp 0}})
|
:timestamp 0
|
||||||
|
:identifier 0}})
|
||||||
(h/advance-timers-by-time 500)
|
(h/advance-timers-by-time 500)
|
||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-responder-release
|
:on-responder-release
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 70
|
{:nativeEvent {:locationX 70
|
||||||
:locationY 70
|
:locationY 70
|
||||||
:timestamp 200}})
|
:timestamp 200
|
||||||
|
:identifier 0}})
|
||||||
(h/advance-timers-by-time 250)
|
(h/advance-timers-by-time 250)
|
||||||
(-> (h/expect event)
|
(-> (h/expect event)
|
||||||
(.toHaveBeenCalledTimes 1)))))
|
(.toHaveBeenCalledTimes 1)))))
|
||||||
@@ -69,29 +72,33 @@
|
|||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-start-should-set-responder
|
:on-start-should-set-responder
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 70
|
{:nativeEvent {:locationX 70
|
||||||
:locationY 70
|
:locationY 70
|
||||||
:timestamp 0}})
|
:timestamp 0
|
||||||
|
:identifier 0}})
|
||||||
(h/advance-timers-by-time 500)
|
(h/advance-timers-by-time 500)
|
||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-responder-release
|
:on-responder-release
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 70
|
{:nativeEvent {:locationX 70
|
||||||
:locationY 70
|
:locationY 70
|
||||||
:timestamp 200}})
|
:timestamp 200
|
||||||
|
:identifier 0}})
|
||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-start-should-set-responder
|
:on-start-should-set-responder
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 70
|
{:nativeEvent {:locationX 70
|
||||||
:locationY 70
|
:locationY 70
|
||||||
:timestamp 0}})
|
:timestamp 0
|
||||||
|
:identifier 0}})
|
||||||
(h/advance-timers-by-time 500)
|
(h/advance-timers-by-time 500)
|
||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-responder-release
|
:on-responder-release
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 80
|
{:nativeEvent {:locationX 80
|
||||||
:locationY 80
|
:locationY 80
|
||||||
:timestamp 200}})
|
:timestamp 200
|
||||||
|
:identifier 0}})
|
||||||
(h/advance-timers-by-time 250)
|
(h/advance-timers-by-time 250)
|
||||||
(-> (js/expect event)
|
(-> (js/expect event)
|
||||||
(.toHaveBeenCalledTimes 1))
|
(.toHaveBeenCalledTimes 1))
|
||||||
@@ -112,23 +119,26 @@
|
|||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-start-should-set-responder
|
:on-start-should-set-responder
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 70
|
{:nativeEvent {:locationX 70
|
||||||
:locationY 70
|
:locationY 70
|
||||||
:timestamp 0}})
|
:timestamp 0
|
||||||
|
:identifier 0}})
|
||||||
(h/advance-timers-by-time 500)
|
(h/advance-timers-by-time 500)
|
||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-responder-move
|
:on-responder-move
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 80
|
{:nativeEvent {:locationX 80
|
||||||
:locationY -30
|
:locationY -30
|
||||||
:pageX 80
|
:pageX 80
|
||||||
:pageY -30}})
|
:pageY -30
|
||||||
|
:identifier 0}})
|
||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-responder-release
|
:on-responder-release
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 40
|
{:nativeEvent {:locationX 40
|
||||||
:locationY 80
|
:locationY 80
|
||||||
:timestamp 200}})
|
:timestamp 200
|
||||||
|
:identifier 0}})
|
||||||
(h/advance-timers-by-time 250)
|
(h/advance-timers-by-time 250)
|
||||||
(-> (js/expect event)
|
(-> (js/expect event)
|
||||||
(.toHaveBeenCalledTimes 1))
|
(.toHaveBeenCalledTimes 1))
|
||||||
@@ -146,22 +156,25 @@
|
|||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-start-should-set-responder
|
:on-start-should-set-responder
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 70
|
{:nativeEvent {:locationX 70
|
||||||
:locationY 70
|
:locationY 70
|
||||||
:timestamp 0}})
|
:timestamp 0
|
||||||
|
:identifier 0}})
|
||||||
(h/advance-timers-by-time 500)
|
(h/advance-timers-by-time 500)
|
||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-responder-release
|
:on-responder-release
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 70
|
{:nativeEvent {:locationX 70
|
||||||
:locationY 70
|
:locationY 70
|
||||||
:timestamp 200}})
|
:timestamp 200
|
||||||
|
:identifier 0}})
|
||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-responder-release
|
:on-responder-release
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 40
|
{:nativeEvent {:locationX 40
|
||||||
:locationY 80
|
:locationY 80
|
||||||
:timestamp 200}})
|
:timestamp 200
|
||||||
|
:identifier 0}})
|
||||||
(h/advance-timers-by-time 250)
|
(h/advance-timers-by-time 250)
|
||||||
(-> (js/expect event)
|
(-> (js/expect event)
|
||||||
(.toHaveBeenCalledTimes 1)))))
|
(.toHaveBeenCalledTimes 1)))))
|
||||||
@@ -178,23 +191,26 @@
|
|||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-start-should-set-responder
|
:on-start-should-set-responder
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX 70
|
{:nativeEvent {:locationX 70
|
||||||
:locationY 70
|
:locationY 70
|
||||||
:timestamp 0}})
|
:timestamp 0
|
||||||
|
:identifier 0}})
|
||||||
(h/advance-timers-by-time 500)
|
(h/advance-timers-by-time 500)
|
||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-responder-move
|
:on-responder-move
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX -30
|
{:nativeEvent {:locationX -30
|
||||||
:locationY 80
|
:locationY 80
|
||||||
:pageX -30
|
:pageX -30
|
||||||
:pageY 80}})
|
:pageY 80
|
||||||
|
:identifier 0}})
|
||||||
(h/fire-event
|
(h/fire-event
|
||||||
:on-responder-release
|
:on-responder-release
|
||||||
(h/get-by-test-id "record-audio")
|
(h/get-by-test-id "record-audio")
|
||||||
{:nativeEvent {:locationX -10
|
{:nativeEvent {:locationX -10
|
||||||
:locationY 70
|
:locationY 70
|
||||||
:timestamp 200}})
|
:timestamp 200
|
||||||
|
:identifier 0}})
|
||||||
(h/advance-timers-by-time 250)
|
(h/advance-timers-by-time 250)
|
||||||
(-> (js/expect event)
|
(-> (js/expect event)
|
||||||
(.toHaveBeenCalledTimes 1))))))
|
(.toHaveBeenCalledTimes 1))))))
|
||||||
|
|||||||