Compare commits

..
Author SHA1 Message Date
Siddarth Kumar 75c68bcc60 list high level deps 2023-08-30 11:58:37 +05:30
Siddarth Kumar 8375eebe71 first attempt at listing dependencies 2023-08-30 10:46:01 +05:30
367 changed files with 3897 additions and 6375 deletions
+9 -1
View File
@@ -20,7 +20,15 @@
;; future, as we progressively fix shadowed
;; vars, we should be able to delete this
;; option and lint all vars.
:exclude [type name]}
:include [comparator
count
identity
iter
key
str
symbol
time
val]}
:invalid-arity {:skip-args [status-im.utils.fx/defn utils.re-frame/defn]}
;; TODO remove number when this is fixed
;; https://github.com/borkdude/clj-kondo/issues/867
+2 -11
View File
@@ -224,7 +224,6 @@ release-android: keystore build-android ##@build Build signed Android APK
@scripts/sign-android.sh result/app-release-unsigned.apk
release-ios: export TARGET := ios
release-ios: export IOS_STATUS_GO_TARGETS := ios/arm64
release-ios: export BUILD_ENV ?= prod
release-ios: watchman-clean ios-clean jsbundle ##@build Build release for iOS release
xcodebuild \
@@ -273,14 +272,11 @@ run-re-frisk: ##@run Start re-frisk server
# TODO: Migrate this to a Nix recipe, much the same way as nix/mobile/android/targets/release-android.nix
run-android: export TARGET := android
# INFO: If it's empty (no devices attached, parsing issues, script error) - for Nix it's the same as not set.
run-android: export ANDROID_ABI_INCLUDE ?= $(shell ./scripts/adb_devices_arch.sh)
run-android: ##@run Build Android APK and start it on the device
npx react-native run-android --appIdSuffix debug
SIMULATOR=iPhone 11 Pro
run-ios: export TARGET := ios
run-ios: export IOS_STATUS_GO_TARGETS := iossimulator/amd64
run-ios: ##@run Build iOS app and start it in a simulator/device
ifneq ("$(SIMULATOR)", "")
npx react-native run-ios --simulator="$(SIMULATOR)"
@@ -288,11 +284,11 @@ else
npx react-native run-ios
endif
show-ios-devices: export TARGET := ios
show-ios-devices: ##@other shows connected ios device and its name
xcrun xctrace list devices
run-ios-device: export TARGET := ios
run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64
run-ios-device: ##@run iOS app and start it on a connected device by its name
ifndef DEVICE_NAME
$(error Usage: make run-ios-device DEVICE_NAME=your-device-name)
@@ -311,7 +307,7 @@ endef
lint: export TARGET := clojure
lint: ##@test Run code style checks
@sh scripts/lint-re-frame-in-quo-components.sh && \
clj-kondo --config .clj-kondo/config.edn --cache false --fail-level error --lint src && \
clj-kondo --config .clj-kondo/config.edn --cache false --lint src && \
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
sh scripts/lint-trailing-newline.sh && \
@@ -351,11 +347,6 @@ test: ##@test Run tests once in NodeJS
yarn shadow-cljs compile test && \
node --require ./test-resources/override.js target/test/test.js
android-test: jsbundle
android-test: export TARGET := android
android-test:
cd android && ./gradlew test
component-test-watch: export TARGET := clojure
component-test-watch: export COMPONENT_TEST := true
component-test-watch: export BABEL_ENV := test
+1 -1
View File
@@ -1 +1 @@
1.25.0
1.23.0
+28
View File
@@ -4,6 +4,8 @@ apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.grad
import com.android.build.OutputFile
import com.sun.org.apache.xalan.internal.xsltc.compiler.Copy
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
/**
* The react.gradle file registers a task for each build variant:
@@ -463,6 +465,32 @@ task hemroidBuild(type: Exec) {
executable execPath
}
// Add this task definition at the bottom of your build.gradle file
task printAllDependencies {
doLast {
println "Listing all dependencies for project..."
// Iterate through all configurations
configurations.all { config ->
int dependencyCount = 0
// Count the dependencies for this configuration
config.allDependencies.each { dependency ->
dependencyCount++
}
// Print the configuration name and dependency count
println "Configuration: ${config.name} (Total Dependencies: ${dependencyCount})"
// Iterate through all dependencies in the current configuration
config.allDependencies.each { dependency ->
println " - ${dependency.group}:${dependency.name}:${dependency.version}"
}
}
}
}
preBuild.dependsOn hemroidBuild
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
+1 -1
View File
@@ -1,6 +1,6 @@
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: ['react-native-reanimated/plugin', '@babel/plugin-transform-named-capturing-groups-regex'],
plugins: ['react-native-reanimated/plugin'],
env: {
test: {
presets: [
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.14'
library 'status-jenkins-lib@v1.7.12'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.14'
library 'status-jenkins-lib@v1.7.12'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.14'
library 'status-jenkins-lib@v1.7.12'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@set_ios_status_go_targets'
library 'status-jenkins-lib@v1.7.12'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.14'
library 'status-jenkins-lib@v1.7.12'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.14'
library 'status-jenkins-lib@v1.7.12'
pipeline {
@@ -83,7 +83,7 @@ pipeline {
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
sh """
python3 -m pytest \
--numprocesses 8 \
--numprocesses 6 \
--rerun_count=2 \
--testrail_report=True \
-m testrail_id \
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.14'
library 'status-jenkins-lib@v1.7.12'
pipeline {
@@ -123,7 +123,7 @@ pipeline {
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
sh """
python3 -m pytest \
--numprocesses 8 \
--numprocesses 6 \
--rerun_count=2 \
--testrail_report=True \
-k \"${params.KEYWORD_EXPRESSION}\" \
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.14'
library 'status-jenkins-lib@v1.7.12'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.14'
library 'status-jenkins-lib@v1.7.12'
pipeline {
agent { label 'macos' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.14'
library 'status-jenkins-lib@v1.7.12'
pipeline {
agent { label params.AGENT_LABEL }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.14'
library 'status-jenkins-lib@v1.7.12'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.14'
library 'status-jenkins-lib@v1.7.12'
pipeline {
agent {
+2 -3
View File
@@ -4,11 +4,10 @@
2) Add some reviewers to the PR and wait for feedback
3) Address feedback
4) Make sure builds and tests are green (run `make test` locally, `make lint-fix` to fix any indentation issue and `make lint`)
5) Once the PR has been reviewed by the dev team, run e2e tests on it by going to https://github.com/status-im/status-mobile/projects/7 and move the pr under the column E2E tests. This will trigger tests. **Running E2E tests is required for all PRs.**
5) Once the PR has been reviewed by the dev team you can run e2e tests on it by going to https://github.com/status-im/status-mobile/projects/7 and move the pr under the column E2E tests. This will trigger tests.
1) Read our [PR Review Policy](pr-review-policy.md) for more details on our approach to PR reviews.
2) Learn more about our [Pipeline for QA](pipeline_process.md) process
6) Once e2e tests have run, they will report the result on the PR, if it's less than 100%, ask QA to take a look to make sure everything is in order (some might fail for legitimate reasons)
7) Ask QA for manual testing if the PR requires it (more details [here](pipeline_process.md))
7) Ask QA for manual testing if the PR requires it
8) Once it has been tested successfully, squash everything into one commit. rebase and merge. The commands we use:
```
git checkout develop
-22
View File
@@ -784,28 +784,6 @@ src
└── view.cljs
```
## Deprecation process
To deprecate a var, add the `:deprecated` metadata and, if necessary, suggest an
alternative.
```clojure
;; Good if there's no better alternative yet, but we want to deprecate it anyway.
(defn ^:deprecated foo
[]
(bar))
;; Good
(defn foo
{:deprecated "Use some.namespace/var-name instead."}
[]
(bar))
```
Please check the [Clojure Style](https://guide.clojure.style/#deprecated) documentation
To reduce visual clutter from deprecated methods in your text editor, consult this [example](https://rider-support.jetbrains.com/hc/en-us/community/posts/4419728641810-How-to-disable-the-the-strike-thru-for-deprecated-methods-in-Javascript-#:~:text=Try%20disabling%20%22Preferences%20%7C%20Editor%20%7C,It%20works%20for%20me). The approach can be adapted for settings in VSCode, Emacs, VIM, and others.
### Test structure
[Unit tests](#glossary) should be created alongside their respective source
+6 -7
View File
@@ -1,6 +1,6 @@
# Pipeline process
[Pipeline for QA](https://github.com/status-im/status-mobile/projects/7) is a project board for developers and testers used to track the status of a pull request, get reviews and manual testing, and run autotests.
[Pipeline for QA](https://github.com/status-im/status-mobile/projects/7) is a project board for developers and testers used to track the status of a pull request, get reviews and manual testing, _and run autotests_ (_temporary disabled_).
The generally accepted recommendations for its use are described below:
@@ -53,7 +53,7 @@ _**How do I know if a design review is needed?**_
There are three cases here depending on the changes in the PR:
1. **Functional PRs with UI changes:** after the ```Tested - OK``` label is added, the QA moves the PR to the ```Design review``` column + mentions ```@Francesca-G``` in comments.
2. **Component PRs:** once the PR has received a review from developers and e2e tests results, it can be moved directly to the ```Design review``` column by the developer (manual testing step can be skipped) + the developer mentions ```@Francesca-G``` in comments.
2. **Component PRs:** can be moved directly to the ```Design review``` column by the developer when get a review from devs (manual testing step can be skipped) + the developer mentions ```@Francesca-G``` in comments.
3. **Functional PRs changes in which are not related to UI (e.g. a crash fix):** skip the ```Design review``` step (the PR should only be manually tested by QA).
There are three possible scenarios when the design review is completed:
@@ -75,11 +75,10 @@ In the second case - after fixing of all found issues, the developer should ping
## Merging a PR
**Merge conditions:**
1. Required number of reviews received
2. E2E results are received and reviewed
3. All commits are squashed into one.
4. No conflicting files in PR
5. No issues from lint
6. Pay attention to automation checks (some of them are not blockers, best to check before merge anyway)
2. All commits are squashed into one.
3. No conflicting files in PR
4. No issues from lint
5. Pay attention to automation checks (some of them are not blockers, best to check before merge anyway)
![](images/pipeline-process/automation-checks.png)
@@ -37,7 +37,4 @@ dependencies {
implementation 'com.github.status-im:function:0.0.1'
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation(group: 'status-im', name: 'status-go', version: getStatusGoSHA1(), ext: 'aar')
testImplementation 'junit:junit:4.13.2'
testImplementation "org.mockito:mockito-core:3.+"
}
@@ -45,8 +45,7 @@ public class PushNotification extends ReactContextBaseJavaModule implements Acti
reactContext.addActivityEventListener(this);
Application applicationContext = (Application) reactContext.getApplicationContext();
IntentFilter intentFilter = new IntentFilter();
pushNotificationHelper = new PushNotificationHelper(applicationContext, intentFilter);
pushNotificationHelper = new PushNotificationHelper(applicationContext);
delivery = new PushNotificationJsDelivery(reactContext);
}
@@ -6,7 +6,6 @@ import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -52,9 +51,7 @@ public class PushNotificationActions extends BroadcastReceiver {
// Notify the action.
if(invokeApp) {
IntentFilter intentFilter = new IntentFilter();
PushNotificationHelper helper = new PushNotificationHelper((Application) context.getApplicationContext(), intentFilter);
PushNotificationHelper helper = new PushNotificationHelper((Application) context.getApplicationContext());
helper.invokeApp(bundle);
} else {
@@ -76,11 +76,8 @@ public class PushNotificationHelper {
private HashMap<String, Person> persons;
private HashMap<String, StatusMessageGroup> messageGroups;
private IntentFilter intentFilter;
public PushNotificationHelper(Application context, IntentFilter intentFilter) {
public PushNotificationHelper(Application context) {
this.context = context;
this.intentFilter = intentFilter;
this.persons = new HashMap<String, Person>();
this.messageGroups = new HashMap<String, StatusMessageGroup>();
this.notificationManager = context.getSystemService(NotificationManager.class);
@@ -136,10 +133,11 @@ public class PushNotificationHelper {
}
};
public void registerBroadcastReceiver() {
this.intentFilter.addAction(ACTION_DELETE_NOTIFICATION);
this.intentFilter.addAction(ACTION_TAP_STOP);
context.registerReceiver(notificationActionReceiver, this.intentFilter);
private void registerBroadcastReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_DELETE_NOTIFICATION);
filter.addAction(ACTION_TAP_STOP);
context.registerReceiver(notificationActionReceiver, filter);
Log.e(LOG_TAG, "Broadcast Receiver registered");
}
@@ -686,9 +684,13 @@ public class PushNotificationHelper {
}
private Person getPerson(Bundle bundle) {
String name = bundle.getString("name");
String base64Image = bundle.getString("icon").split(",")[1];
byte[] decodedString = Base64.decode(base64Image, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
return new Person.Builder().setName(name).build();
String name = bundle.getString("name");
return new Person.Builder().setIcon(IconCompat.createWithBitmap(getCircleBitmap(decodedByte))).setName(name).build();
}
private StatusMessage createMessage(Bundle data) {
@@ -737,10 +739,6 @@ public class PushNotificationHelper {
this.showMessages(bundle);
}
public StatusMessageGroup getMessageGroup(String conversationId) {
return this.messageGroups.get(conversationId);
}
public void addStatusMessage(Bundle bundle) {
String conversationId = bundle.getString("conversationId");
StatusMessageGroup group = this.messageGroups.get(conversationId);
@@ -1,23 +0,0 @@
package android.util;
public class Log {
public static int d(String tag, String msg) {
System.out.println("DEBUG: " + tag + ": " + msg);
return 0;
}
public static int i(String tag, String msg) {
System.out.println("INFO: " + tag + ": " + msg);
return 0;
}
public static int w(String tag, String msg) {
System.out.println("WARN: " + tag + ": " + msg);
return 0;
}
public static int e(String tag, String msg) {
System.out.println("ERROR: " + tag + ": " + msg);
return 0;
}
}
@@ -1,54 +0,0 @@
package im.status.ethereum.pushnotifications;
import org.junit.Test;
import static org.junit.Assert.*;
import android.app.Application;
import android.app.NotificationManager;
import android.os.Bundle;
import android.content.Intent;
import android.app.PendingIntent;
import android.content.IntentFilter;
import static org.mockito.Mockito.*;
import org.mockito.Spy;
public class PushNotificationHelperTest {
PushNotificationHelper helper;
@Test
public void testAddStatusMessage() {
final Application context = mock(Application.class);
final NotificationManager manager = mock(NotificationManager.class);
final IntentFilter filter = mock(IntentFilter.class);
when(context.getSystemService(NotificationManager.class)).thenReturn(manager);
// Create a spy for PushNotificationHelper
PushNotificationHelper realHelper = new PushNotificationHelper(context, filter);
helper = spy(realHelper);
Bundle bundle = mock(Bundle.class);
Bundle personBundle = mock(Bundle.class);
String conversationId = "conversation-id";
String deepLink = "deep-link";
when(bundle.getString("conversationId")).thenReturn(conversationId);
when(bundle.getString("id")).thenReturn("id");
when(bundle.getString("message")).thenReturn("message");
when(bundle.getDouble("timestamp")).thenReturn(100000.0);
when(bundle.getString("deepLink")).thenReturn(deepLink);
when(personBundle.getString("name")).thenReturn("name");
when(bundle.getBundle("notificationAuthor")).thenReturn(personBundle);
doNothing().when(helper).showMessages(bundle);
helper.addStatusMessage(bundle);
assertNotNull(helper.getMessageGroup(conversationId));
}
}
+192 -505
View File
File diff suppressed because it is too large Load Diff
-5
View File
@@ -631,10 +631,7 @@ javax.inject:javax.inject:1
javax.xml.bind:jaxb-api:2.2.12-b140109.1041
javax.xml.bind:jaxb-api:2.3.1
junit:junit:4.12
junit:junit:4.13.2
me.zhanghai.android.materialprogressbar:library:1.4.2
net.bytebuddy:byte-buddy-agent:1.11.13
net.bytebuddy:byte-buddy:1.11.13
net.java.dev.jna:jna-platform:5.6.0
net.java.dev.jna:jna:5.6.0
net.sf.jopt-simple:jopt-simple:4.9
@@ -791,8 +788,6 @@ org.jsoup:jsoup:1.13.1
org.jvnet.staxex:stax-ex:1.7.7
org.jvnet.staxex:stax-ex:1.8
org.jvnet.staxex:stax-ex:1.8.1
org.mockito:mockito-core:3.12.4
org.objenesis:objenesis:3.2
org.ow2.asm:asm-analysis:5.0.3
org.ow2.asm:asm-analysis:5.1
org.ow2.asm:asm-analysis:6.0
+25 -32
View File
@@ -634,10 +634,10 @@ https://repo.maven.apache.org/maven2/com/google/auto/auto-parent/6/auto-parent-6
https://repo.maven.apache.org/maven2/com/google/auto/auto-parent/7/auto-parent-7.pom
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.6.2/auto-value-annotations-1.6.2.pom
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.6.3/auto-value-annotations-1.6.3.pom
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.10.3/auto-value-annotations-1.10.3.pom
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-annotations/1.10.2/auto-value-annotations-1.10.2.pom
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-parent/1.6.2/auto-value-parent-1.6.2.pom
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-parent/1.6.3/auto-value-parent-1.6.3.pom
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-parent/1.10.3/auto-value-parent-1.10.3.pom
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value-parent/1.10.2/auto-value-parent-1.10.2.pom
https://repo.maven.apache.org/maven2/com/google/auto/value/auto-value/1.5.2/auto-value-1.5.2.pom
https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.pom
https://repo.maven.apache.org/maven2/com/google/code/findbugs/jsr305/3.0.1/jsr305-3.0.1.pom
@@ -665,7 +665,7 @@ https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotatio
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.4.0/error_prone_annotations-2.4.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.7.1/error_prone_annotations-2.7.1.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.21.1/error_prone_annotations-2.21.1.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.20.0/error_prone_annotations-2.20.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.0.18/error_prone_parent-2.0.18.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.2.0/error_prone_parent-2.2.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.3.1/error_prone_parent-2.3.1.pom
@@ -673,7 +673,7 @@ https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.3.4/error_prone_parent-2.3.4.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.4.0/error_prone_parent-2.4.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.7.1/error_prone_parent-2.7.1.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.21.1/error_prone_parent-2.21.1.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.20.0/error_prone_parent-2.20.0.pom
https://repo.maven.apache.org/maven2/com/google/flatbuffers/flatbuffers-java/1.12.0/flatbuffers-java-1.12.0.pom
https://repo.maven.apache.org/maven2/com/google/google/1/google-1.pom
https://repo.maven.apache.org/maven2/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.pom
@@ -688,8 +688,8 @@ https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/29.0-jre/guav
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/30.1-android/guava-parent-30.1-android.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/30.1-jre/guava-parent-30.1-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/31.0.1-jre/guava-parent-31.0.1-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/32.1.2-jre/guava-parent-32.1.2-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava-testlib/32.1.2-jre/guava-testlib-32.1.2-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/32.1.1-jre/guava-parent-32.1.1-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava-testlib/32.1.1-jre/guava-testlib-32.1.1-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/17.0/guava-17.0.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/22.0/guava-22.0.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/23.0/guava-23.0.pom
@@ -701,7 +701,7 @@ https://repo.maven.apache.org/maven2/com/google/guava/guava/29.0-jre/guava-29.0-
https://repo.maven.apache.org/maven2/com/google/guava/guava/30.1-android/guava-30.1-android.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/30.1-jre/guava-30.1-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/32.1.2-jre/guava-32.1.2-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/32.1.1-jre/guava-32.1.1-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/listenablefuture/1.0/listenablefuture-1.0.pom
https://repo.maven.apache.org/maven2/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.pom
https://repo.maven.apache.org/maven2/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.pom
@@ -750,12 +750,12 @@ https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/3.12.1/okhttp-3
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/4.9.2/okhttp-4.9.2.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.9.1/parent-3.9.1.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.12.1/parent-3.12.1.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.5.0/okio-jvm-3.5.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.4.0/okio-jvm-3.4.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.17.4/okio-parent-1.17.4.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.17.4/okio-1.17.4.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.8.0/okio-2.8.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.9.0/okio-2.9.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.5.0/okio-3.5.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.4.0/okio-3.4.0.pom
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.0/all-1.2.0.pom
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.1/all-1.2.1.pom
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.2/all-1.2.2.pom
@@ -871,12 +871,9 @@ https://repo.maven.apache.org/maven2/javax/xml/stream/stax-api/1.0-2/stax-api-1.
https://repo.maven.apache.org/maven2/junit/junit/4.12/junit-4.12.pom
https://repo.maven.apache.org/maven2/junit/junit/4.13.2/junit-4.13.2.pom
https://repo.maven.apache.org/maven2/me/zhanghai/android/materialprogressbar/library/1.4.2/library-1.4.2.pom
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.11.13/byte-buddy-agent-1.11.13.pom
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.14.6/byte-buddy-agent-1.14.6.pom
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-parent/1.11.13/byte-buddy-parent-1.11.13.pom
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-parent/1.14.6/byte-buddy-parent-1.14.6.pom
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.11.13/byte-buddy-1.11.13.pom
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.14.6/byte-buddy-1.14.6.pom
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.14.5/byte-buddy-agent-1.14.5.pom
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-parent/1.14.5/byte-buddy-parent-1.14.5.pom
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.14.5/byte-buddy-1.14.5.pom
https://repo.maven.apache.org/maven2/net/java/dev/jna/jna-platform/5.6.0/jna-platform-5.6.0.pom
https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.pom
https://repo.maven.apache.org/maven2/net/java/jvnet-parent/1/jvnet-parent-1.pom
@@ -903,8 +900,8 @@ https://repo.maven.apache.org/maven2/org/abego/treelayout/org.abego.treelayout.c
https://repo.maven.apache.org/maven2/org/antlr/ST4/4.0.8/ST4-4.0.8.pom
https://repo.maven.apache.org/maven2/org/antlr/ST4/4.3.4/ST4-4.3.4.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4-master/4.5.3/antlr4-master-4.5.3.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4-master/4.13.1/antlr4-master-4.13.1.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4-runtime/4.13.1/antlr4-runtime-4.13.1.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4-master/4.13.0/antlr4-master-4.13.0.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4-runtime/4.13.0/antlr4-runtime-4.13.0.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4/4.5.3/antlr4-4.5.3.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr-master/3.3/antlr-master-3.3.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr-master/3.5.2/antlr-master-3.5.2.pom
@@ -991,7 +988,7 @@ https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/2.8.1/che
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/2.11.1/checker-qual-2.11.1.pom
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.5.0/checker-qual-3.5.0.pom
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.pom
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.38.0/checker-qual-3.38.0.pom
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.36.0/checker-qual-3.36.0.pom
https://repo.maven.apache.org/maven2/org/codehaus/codehaus-parent/4/codehaus-parent-4.pom
https://repo.maven.apache.org/maven2/org/codehaus/groovy/groovy-xml/3.0.10/groovy-xml-3.0.10.pom
https://repo.maven.apache.org/maven2/org/codehaus/groovy/groovy/3.0.9/groovy-3.0.9.pom
@@ -1014,8 +1011,8 @@ https://repo.maven.apache.org/maven2/org/codehaus/woodstox/stax2-api/4.2.1/stax2
https://repo.maven.apache.org/maven2/org/conscrypt/conscrypt-android/2.0.0/conscrypt-android-2.0.0.pom
https://repo.maven.apache.org/maven2/org/easymock/easymockclassextension/3.2/easymockclassextension-3.2.pom
https://repo.maven.apache.org/maven2/org/easymock/easymock-parent/3.2/easymock-parent-3.2.pom
https://repo.maven.apache.org/maven2/org/easymock/easymock-parent/5.2.0/easymock-parent-5.2.0.pom
https://repo.maven.apache.org/maven2/org/easymock/easymock/5.2.0/easymock-5.2.0.pom
https://repo.maven.apache.org/maven2/org/easymock/easymock-parent/5.1.0/easymock-parent-5.1.0.pom
https://repo.maven.apache.org/maven2/org/easymock/easymock/5.1.0/easymock-5.1.0.pom
https://repo.maven.apache.org/maven2/org/eclipse/angus/angus-activation-project/2.0.1/angus-activation-project-2.0.1.pom
https://repo.maven.apache.org/maven2/org/eclipse/angus/angus-activation/2.0.1/angus-activation-2.0.1.pom
https://repo.maven.apache.org/maven2/org/eclipse/ee4j/project/1.0.2/project-1.0.2.pom
@@ -1106,7 +1103,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.4.32/
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.5.31/kotlin-reflect-1.5.31.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.6.10/kotlin-reflect-1.6.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.6.20/kotlin-reflect-1.6.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.9.10/kotlin-reflect-1.9.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.9.0/kotlin-reflect-1.9.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.6.10/kotlin-scripting-common-1.6.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.6.20/kotlin-scripting-common-1.6.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.6.10/kotlin-scripting-compiler-embeddable-1.6.10.pom
@@ -1135,8 +1132,8 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.6.10/kotlin-stdlib-common-1.6.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.6.20/kotlin-stdlib-common-1.6.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.6.21/kotlin-stdlib-common-1.6.21.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.0/kotlin-stdlib-common-1.8.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.9.0/kotlin-stdlib-common-1.9.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.9.10/kotlin-stdlib-common-1.9.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.2.71/kotlin-stdlib-jdk7-1.2.71.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.3.20/kotlin-stdlib-jdk7-1.3.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.3.50/kotlin-stdlib-jdk7-1.3.50.pom
@@ -1148,7 +1145,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.5
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.5.31/kotlin-stdlib-jdk7-1.5.31.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.10/kotlin-stdlib-jdk7-1.6.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.20/kotlin-stdlib-jdk7-1.6.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.0/kotlin-stdlib-jdk7-1.9.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.0/kotlin-stdlib-jdk7-1.8.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.2.71/kotlin-stdlib-jdk8-1.2.71.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.3.20/kotlin-stdlib-jdk8-1.3.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.3.50/kotlin-stdlib-jdk8-1.3.50.pom
@@ -1160,7 +1157,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.5
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.5.31/kotlin-stdlib-jdk8-1.5.31.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6.10/kotlin-stdlib-jdk8-1.6.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6.20/kotlin-stdlib-jdk8-1.6.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.0/kotlin-stdlib-jdk8-1.9.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.0/kotlin-stdlib-jdk8-1.8.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.1.3-2/kotlin-stdlib-1.1.3-2.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.2.0/kotlin-stdlib-1.2.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.2.20/kotlin-stdlib-1.2.20.pom
@@ -1182,8 +1179,8 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.5.31/k
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.6.10/kotlin-stdlib-1.6.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.6.20/kotlin-stdlib-1.6.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.6.21/kotlin-stdlib-1.6.21.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.8.0/kotlin-stdlib-1.8.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.0/kotlin-stdlib-1.9.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.10/kotlin-stdlib-1.9.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-tooling-metadata/1.6.10/kotlin-tooling-metadata-1.6.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-tooling-metadata/1.6.20/kotlin-tooling-metadata-1.6.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-util-io/1.6.10/kotlin-util-io-1.6.10.pom
@@ -1202,11 +1199,8 @@ https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/1.7.7/stax-ex-1.7.
https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/1.8.1/stax-ex-1.8.1.pom
https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/1.8/stax-ex-1.8.pom
https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/2.1.0/stax-ex-2.1.0.pom
https://repo.maven.apache.org/maven2/org/mockito/mockito-core/3.12.4/mockito-core-3.12.4.pom
https://repo.maven.apache.org/maven2/org/mockito/mockito-core/5.5.0/mockito-core-5.5.0.pom
https://repo.maven.apache.org/maven2/org/objenesis/objenesis-parent/3.2/objenesis-parent-3.2.pom
https://repo.maven.apache.org/maven2/org/mockito/mockito-core/5.4.0/mockito-core-5.4.0.pom
https://repo.maven.apache.org/maven2/org/objenesis/objenesis-parent/3.3/objenesis-parent-3.3.pom
https://repo.maven.apache.org/maven2/org/objenesis/objenesis/3.2/objenesis-3.2.pom
https://repo.maven.apache.org/maven2/org/objenesis/objenesis/3.3/objenesis-3.3.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-analysis/5.0.3/asm-analysis-5.0.3.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-analysis/5.1/asm-analysis-5.1.pom
@@ -1252,11 +1246,10 @@ https://repo.maven.apache.org/maven2/org/ow2/ow2/1.5.1/ow2-1.5.1.pom
https://repo.maven.apache.org/maven2/org/ow2/ow2/1.5/ow2-1.5.pom
https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.pom
https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.pom
https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/2.0.9/slf4j-api-2.0.9.pom
https://repo.maven.apache.org/maven2/org/slf4j/slf4j-bom/2.0.9/slf4j-bom-2.0.9.pom
https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/2.0.7/slf4j-api-2.0.7.pom
https://repo.maven.apache.org/maven2/org/slf4j/slf4j-parent/1.7.21/slf4j-parent-1.7.21.pom
https://repo.maven.apache.org/maven2/org/slf4j/slf4j-parent/1.7.30/slf4j-parent-1.7.30.pom
https://repo.maven.apache.org/maven2/org/slf4j/slf4j-parent/2.0.9/slf4j-parent-2.0.9.pom
https://repo.maven.apache.org/maven2/org/slf4j/slf4j-parent/2.0.7/slf4j-parent-2.0.7.pom
https://repo.maven.apache.org/maven2/org/sonatype/oss/oss-parent/5/oss-parent-5.pom
https://repo.maven.apache.org/maven2/org/sonatype/oss/oss-parent/7/oss-parent-7.pom
https://repo.maven.apache.org/maven2/org/sonatype/oss/oss-parent/9/oss-parent-9.pom
+13 -52
View File
@@ -14,11 +14,6 @@ declare -a REPOS=(
"https://jitpack.io"
)
# These files are not necessary for the build process.
FILENAMES_BLACKLIST='-(javadoc|runtime|gwt|headers|sources|src|tests|adapters|modular|site|bin)\.'
FILETYPES_BLACKLIST='(pom|json|zip|module|xml|md5|sha1|sha256|sha512)$'
SIGNATURE_BLACKLIST='(pom|jar|json|zip|module|xml|md5|asc).asc$'
function nix_prefetch() {
nix store prefetch-file --json "${1}" 2>/dev/null
}
@@ -41,49 +36,7 @@ function match_repo_url() {
function pom_has_nodeps_jar() {
grep '<shadedClassifierName>nodeps</shadedClassifierName>' "${1}" \
>/dev/null 2>&1
}
function guess_pkg_files() {
# Some deps are just POMs, in which case there is no JAR to fetch.
[[ "${OBJ_TYPE}" == "" ]] && echo "${PKG_NAME}.jar"
[[ "${OBJ_TYPE}" == "jar" ]] && echo "${PKG_NAME}.jar"
[[ "${OBJ_TYPE}" == "bundle" ]] && echo "${PKG_NAME}.jar"
[[ "${OBJ_TYPE}" =~ aar* ]] && echo "${PKG_NAME}.aar"
[[ "${OBJ_TYPE}" == "aar.asc" ]] && echo "${PKG_NAME}.${OBJ_TYPE}"
pom_has_nodeps_jar "${POM_PATH}" && echo "${PKG_NAME}-nodeps.jar"
}
function get_pkg_files() {
REPO_URL="${1}"
PKG_PATH="${2}"
PKG_NAME="${3}"
# Google Maven repo doesn't have normal HTML directory listing.
if [[ "${REPO_URL}" == "https://dl.google.com/dl/android/maven2" ]]; then
FOUND=$(curl --fail -s "${REPO_URL}/${PKG_PATH}/artifact-metadata.json")
# Some older packages do not have artifacts-metadata.json.
if [[ "$?" -eq 0 ]]; then
FOUND=$(echo "${FOUND}" | jq -r '.artifacts[].name')
else
FOUND=''
fi
else
FOUND=$(
curl -s "${REPO_URL}/${PKG_PATH}/" \
| htmlq a -a href \
| grep -e "^${PKG_NAME}"
)
fi
if [[ "${FOUND}" == '' ]]; then
guess_pkg_files
else
# Filter out files we don't actually need for builds.
echo "${FOUND}" \
| grep -v -E \
-e "${FILENAMES_BLACKLIST}" \
-e "${FILETYPES_BLACKLIST}" \
-e "${SIGNATURE_BLACKLIST}"
fi
>/dev/null 2>&1
}
function fetch_and_template_file() {
@@ -105,6 +58,10 @@ function fetch_and_template_file() {
}"
}
function fetch_and_template_file_no_fail() {
fetch_and_template_file "${1}" 2>/dev/null || true
}
if [[ -z "${1}" ]]; then
echo "Required POM URL argument not given!" >&2
exit 1
@@ -120,7 +77,7 @@ echo -en "${CLR} - Nix entry for: ${1##*/}\r" >&2
REPO_URL=$(match_repo_url "${PKG_URL_NO_EXT}")
if [[ -z "${REPO_URL}" ]]; then
echo " ! Repo URL not found for: ${POM_URL}" >&2
echo " ! Repo URL not found: %s" "${REPO_URL}" >&2
exit 1
fi
# Get the relative path without full URL
@@ -157,8 +114,12 @@ echo -ne "
\"sha256\": \"${POM_SHA256}\"
}"
for FILE in $(get_pkg_files "${REPO_URL}" "${PKG_PATH}" "${PKG_NAME}"); do
fetch_and_template_file "${FILE}"
done
# Some deps are just POMs, in which case there is no JAR to fetch.
[[ "${OBJ_TYPE}" == "" ]] && fetch_and_template_file_no_fail "${PKG_NAME}.jar"
[[ "${OBJ_TYPE}" == "jar" ]] && fetch_and_template_file "${PKG_NAME}.jar"
[[ "${OBJ_TYPE}" == "bundle" ]] && fetch_and_template_file "${PKG_NAME}.jar"
[[ "${OBJ_TYPE}" =~ aar* ]] && fetch_and_template_file "${PKG_NAME}.aar"
[[ "${OBJ_TYPE}" == "aar.asc" ]] && fetch_and_template_file "${PKG_NAME}.${OBJ_TYPE}"
pom_has_nodeps_jar "${POM_PATH}" && fetch_and_template_file "${PKG_NAME}-nodeps.jar"
echo -e '\n }\n },'
+22 -27
View File
@@ -3,33 +3,28 @@
# It copies the status-go build result to 'modules/react-native-status/ios/RCTStatus'.
#
{ lib, mkShell, status-go }:
{ mkShell, status-go }:
let
targets = let
targetsString = lib.getEnvWithDefault "IOS_STATUS_GO_TARGETS" "ios/arm64;iossimulator/amd64";
in lib.splitString ";" targetsString;
in
mkShell {
shellHook = ''
export STATUS_GO_IOS_LIBDIR=${status-go { inherit targets; } }/Statusgo.xcframework
RCTSTATUS_DIR="$STATUS_MOBILE_HOME/modules/react-native-status/ios/RCTStatus"
targetBasename='Statusgo.xcframework'
# Compare target folder with source to see if copying is required
if [ -d "$RCTSTATUS_DIR/$targetBasename" ] && [ -d $STATUS_MOBILE_HOME/ios/Pods/ ] && \
diff -qr --no-dereference $RCTSTATUS_DIR/$targetBasename/ $STATUS_GO_IOS_LIBDIR/ > /dev/null; then
echo "$RCTSTATUS_DIR/$targetBasename already in place"
else
sourceBasename="$(basename $STATUS_GO_IOS_LIBDIR)"
echo "Copying $sourceBasename from Nix store to $RCTSTATUS_DIR"
rm -rf "$RCTSTATUS_DIR/$targetBasename/"
cp -a $STATUS_GO_IOS_LIBDIR $RCTSTATUS_DIR
chmod -R 755 "$RCTSTATUS_DIR/$targetBasename"
if [ "$sourceBasename" != "$targetBasename" ]; then
mv "$RCTSTATUS_DIR/$sourceBasename" "$RCTSTATUS_DIR/$targetBasename"
fi
mkShell {
shellHook = ''
export STATUS_GO_IOS_LIBDIR=${status-go}/Statusgo.xcframework
RCTSTATUS_DIR="$STATUS_MOBILE_HOME/modules/react-native-status/ios/RCTStatus"
targetBasename='Statusgo.xcframework'
# Compare target folder with source to see if copying is required
if [ -d "$RCTSTATUS_DIR/$targetBasename" ] && [ -d $STATUS_MOBILE_HOME/ios/Pods/ ] && \
diff -qr --no-dereference $RCTSTATUS_DIR/$targetBasename/ $STATUS_GO_IOS_LIBDIR/ > /dev/null; then
echo "$RCTSTATUS_DIR/$targetBasename already in place"
else
sourceBasename="$(basename $STATUS_GO_IOS_LIBDIR)"
echo "Copying $sourceBasename from Nix store to $RCTSTATUS_DIR"
rm -rf "$RCTSTATUS_DIR/$targetBasename/"
cp -a $STATUS_GO_IOS_LIBDIR $RCTSTATUS_DIR
chmod -R 755 "$RCTSTATUS_DIR/$targetBasename"
if [ "$sourceBasename" != "$targetBasename" ]; then
mv "$RCTSTATUS_DIR/$sourceBasename" "$RCTSTATUS_DIR/$targetBasename"
fi
'';
fi
'';
}
+1 -1
View File
@@ -38,7 +38,7 @@ let
# for running gradle by hand
gradle = mkShell {
buildInputs = with pkgs; [ gradle maven goMavenResolver htmlq ];
buildInputs = with pkgs; [ gradle maven goMavenResolver ];
shellHook = ''
export STATUS_GO_ANDROID_LIBDIR="DUMMY"
export STATUS_NIX_MAVEN_REPO="${pkgs.deps.gradle}"
+3 -2
View File
@@ -17,10 +17,11 @@
inherit meta source goBuildLdFlags;
};
ios = {targets ? [ "ios/arm64" "iossimulator/amd64"]}: callPackage ./build.nix {
ios = callPackage ./build.nix {
platform = "ios";
platformVersion = "8.0";
targets = [ "ios" "iossimulator" ];
outputFileName = "Statusgo.xcframework";
inherit meta source goBuildLdFlags targets;
inherit meta source goBuildLdFlags;
};
}
+1 -2
View File
@@ -49,7 +49,7 @@
"react-native-fetch-polyfill": "^1.1.2",
"react-native-fs": "^2.14.1",
"react-native-gesture-handler": "2.6.1",
"react-native-gifted-charts": "git+https://github.com/status-im/react-native-gifted-charts.git#refs/tags/1.3.2-status.1",
"react-native-gifted-charts": "^1.3.2",
"react-native-haptic-feedback": "^1.9.0",
"react-native-hole-view": "git+https://github.com/status-im/react-native-hole-view.git#refs/tags/v2.1.3-status",
"react-native-image-crop-picker": "git+https://github.com/status-im/react-native-image-crop-picker.git#refs/tags/v0.36.2-status.0",
@@ -82,7 +82,6 @@
"@babel/generator": "7.0.0",
"@babel/helper-builder-react-jsx": "7.0.0",
"@babel/plugin-transform-block-scoping": "7.0.0",
"@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5",
"@babel/preset-env": "7.1.0",
"@babel/preset-react": "^7.18.6",
"@babel/register": "7.0.0",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 731 B

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 873 B

After

Width:  |  Height:  |  Size: 879 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 443 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

-41
View File
@@ -1,41 +0,0 @@
#!/usr/bin/env bash
set -e
typeset -a abis
SCRIPT_NAME=$(basename $0)
function log() {
echo "${SCRIPT_NAME} ${1}: ${2}" >&2
}
# make sure server is running, otherwise sdb will show devices offline
adb start-server
while IFS= read line; do
read -a arr <<< "${line}"
device_name="${arr[0]}"
device_status=${arr[1]}
log "DEBUG" "device_name=${device_name}"
log "DEBUG" "device_status=${device_status}"
if [[ "${device_status}" != "device" ]]; then
continue
fi
device_product_abi=$(adb -s ${device_name} shell -n getprop ro.product.cpu.abi)
log "DEBUG" "device_product_abi=${device_product_abi}"
if [[ ! ${abis[*]} =~ ${device_product_abi} ]]; then
abis+=("${device_product_abi}")
fi
done <<< "$(adb devices | tail -n+2)"
if [[ ! "${abis[*]}" ]]; then
log "ERROR" "no devices found. Check 'adb devices -l' output and share with Infra team if needed."
exit 3
fi
log "DEBUG" "resulting abis:"
IFS=\;; echo "${abis[*]}"
+4 -8
View File
@@ -66,14 +66,10 @@
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
;; We disable `:fn-deprecated` warnings because we
;; are managing deprecation via clj-kondo and we
;; don't want the terminal output to be littered
;; with warnings on every code reload.
:warnings {:fn-deprecated false}
:closure-defines {re-frame.trace/trace-enabled? true}
:source-map false
:infer-externs true}
:closure-defines
{re-frame.trace/trace-enabled? true}
:source-map false
:infer-externs true}
;; if you want to use a real device, set your local ip
;; in the SHADOW_HOST env variable to make sure that
;; it will use the right interface
+5 -5
View File
@@ -389,11 +389,11 @@
[]
(log/debug "[native-module] get-device-model-info")
;;NOTE: we have to check for status module because of tests
(when-let [^js status-module (status)]
{:model (.-model status-module)
:brand (.-brand status-module)
:build-id (.-buildId status-module)
:device-id (.-deviceId status-module)}))
(when-let [^js status (status)]
{:model (.-model status)
:brand (.-brand status)
:build-id (.-buildId status)
:device-id (.-deviceId status)}))
(defn get-installation-name
[]
+4 -4
View File
@@ -35,7 +35,7 @@
:align-items :center
:justify-content :center})
(def left-style
(def left
{:position :absolute
:left 0
:top 0
@@ -43,7 +43,7 @@
:justify-content :center
:align-items :flex-start})
(def right-style
(def right
{:position :absolute
:right 0
:top 0
@@ -179,7 +179,7 @@
{:style content
:pointer-events :box-none}
[rn/view
{:style left-style
{:style left
:on-layout (handle-layout :left get-layout)
:pointer-events :box-none}
[header-actions
@@ -197,7 +197,7 @@
:component title-component}]]
[rn/view
{:style right-style
{:style right
:on-layout (handle-layout :right get-layout)
:pointer-events :box-none}
[header-actions
+3 -3
View File
@@ -1,10 +1,10 @@
(ns quo.previews.preview)
(defmacro list-comp
[[the-binding seq-expr & bindings] body-expr]
(cond (not the-binding)
[[binding seq-expr & bindings] body-expr]
(cond (not binding)
`(list ~body-expr)
:else
`(mapcat (fn [~the-binding] (list-comp ~bindings ~body-expr))
`(mapcat (fn [~binding] (list-comp ~bindings ~body-expr))
~seq-expr)))
+12 -14
View File
@@ -4,23 +4,21 @@
[quo2.theme :as quo.theme]
[react-native.core :as rn]))
(def ^:private sizes
{:size/s-48 {:component 48
:icon 20}
:size/s-32 {:component 32
:icon 20}
:size/s-24 {:component 24
:icon 16}
:size/s-20 {:component 20
:icon 12}})
(def sizes
{:big 48
:medium 32
:small 20})
(defn icon-avatar-internal
[{:keys [size icon color opacity border? theme]
:or {opacity 20
size :size/s-32}}]
(let [{component-size :component icon-size :icon} (get sizes size)
circle-color (colors/custom-color color 50 opacity)
icon-color (colors/custom-color-by-theme color 50 60)]
:or {opacity 20}}]
(let [component-size (size sizes)
circle-color (colors/custom-color color 50 opacity)
icon-color (colors/custom-color-by-theme color 50 60)
icon-size (case size
:big 20
:medium 16
:small 12)]
[rn/view
{:style {:width component-size
:height component-size
@@ -2,48 +2,34 @@
(:require [quo2.foundations.colors :as colors]))
(def sizes
{:big {:dimensions 80
:status-indicator 12
:status-indicator-border 4
:status-indicator-center-to-edge 12
:font-size :heading-1
:ring-width 4}
:medium {:dimensions 48
:status-indicator 8
:status-indicator-border 2
:status-indicator-center-to-edge 6
:font-size :heading-2
:ring-width 2}
:small {:dimensions 32
:status-indicator 8
:status-indicator-border 2
:status-indicator-center-to-edge 4
:font-size :paragraph-2
:ring-width 2}
28 {:dimensions 28
:status-indicator 0
:status-indicator-border 0
:status-indicator-center-to-edge 0
:font-size :paragraph-2
:ring-width 0}
:xs {:dimensions 24
:status-indicator 0
:status-indicator-border 0
:status-indicator-center-to-edge 0
:font-size :paragraph-2
:ring-width 2}
:xxs {:dimensions 20
:status-indicator 0
:status-indicator-border 0
:status-indicator-center-to-edge 0
:font-size :label
:ring-width 2}
:xxxs {:dimensions 16
:status-indicator 0
:status-indicator-border 0
:status-indicator-center-to-edge 0
:font-size :label
:ring-width 2}})
{:big {:dimensions 80
:status-indicator 20
:status-indicator-border 4
:font-size :heading-1}
:medium {:dimensions 48
:status-indicator 12
:status-indicator-border 2
:font-size :heading-2}
:small {:dimensions 32
:status-indicator 12
:status-indicator-border 2
:font-size :paragraph-2}
28 {:dimensions 28
:status-indicator 0
:status-indicator-border 0
:font-size :paragraph-2}
:xs {:dimensions 24
:status-indicator 0
:status-indicator-border 0
:font-size :paragraph-2}
:xxs {:dimensions 20
:status-indicator 0
:status-indicator-border 0
:font-size :label}
:xxxs {:dimensions 16
:status-indicator 0
:status-indicator-border 0
:font-size :label}})
(defn initials-avatar
[size customization-color theme]
@@ -35,7 +35,7 @@
:indicator-size status indicator outer radius, set to nil or 0 when no indicator
:indicator-border `indicator-size`-`indicator-border` is the inner radius
:indicator-color color for status indicator
:theme :light or :dark
:override-theme override theme for ring
:background-color intials avatar background color
:color intials avatar text color
:size intials avatar radius
@@ -55,7 +55,7 @@
status-indicator? true
online? true
ring? true
customization-color :blue}
customization-color :turquoise}
:as props}]
(let [full-name (or full-name "Your Name")
;; image generated with profile-picture-fn is round cropped
@@ -83,23 +83,20 @@
:source
(cond profile-picture-fn
{:uri (profile-picture-fn
{:length amount-initials
:full-name full-name
:font-size (:font-size (text/text-style {:size
font-size}))
:indicator-size (when status-indicator?
(:status-indicator sizes))
:indicator-border (when status-indicator?
(:status-indicator-border sizes))
:indicator-center-to-edge (when status-indicator?
(:status-indicator-center-to-edge sizes))
:indicator-color indicator-color
:override-theme theme
:background-color (style/customization-color customization-color theme)
:color (:color style/initials-avatar-text)
:size (:width outer-styles)
:ring? ring?
:ring-width (:ring-width sizes)})}
{:length amount-initials
:full-name full-name
:font-size (:font-size (text/text-style {:size
font-size}))
:indicator-size (when status-indicator?
(:status-indicator sizes))
:indicator-border (when status-indicator?
(:status-indicator-border sizes))
:indicator-color indicator-color
:override-theme theme
:background-color (style/customization-color customization-color theme)
:color (:color style/initials-avatar-text)
:size (:width outer-styles)
:ring? ring?})}
(:uri profile-picture)
profile-picture
@@ -85,14 +85,14 @@
56 0
40 (if border-color 8 9)
32 (if border-color 4 5)
24 0
24 (if border-color 0 1)
(if border-color 8 9)))
:padding-bottom (when-not (or icon-only? icon-left icon-right)
(case size
56 0
40 9
32 5
24 0
24 4
9))
:overflow :hidden
:background-color background-color
@@ -19,15 +19,15 @@
Reagent and React render."
[f]
(js/Promise.
(fn [resolve-fn reject]
(fn [resolve reject]
(try
(.then (rtl/act
#(let [p (js/Promise. (fn [resolve-fn2 _reject]
#(let [p (js/Promise. (fn [resolve _reject]
(r/after-render (fn reagent-act-after-reagent-flush []
(resolve-fn2)))))]
(resolve)))))]
(f)
p))
resolve-fn
resolve
reject)
(catch :default e
(reject e))))))
@@ -117,3 +117,4 @@
gesture-events)))]
(h/advance-timers-by-time 250)
(-> promise (.then #(h/was-not-called (:on-complete props))))))))
@@ -4,18 +4,17 @@
(def ^:const size 8)
(defn dot-background-color
[customization-color theme blur?]
(cond
customization-color (colors/theme-colors
(colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme)
blur? (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
:else (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
[customization-color theme]
(if customization-color
(colors/theme-colors
(colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme)
(colors/theme-colors colors/primary-50 colors/primary-60 theme)))
(defn notification-dot
[customization-color theme blur?]
{:background-color (dot-background-color customization-color theme blur?)
[customization-color theme]
{:background-color (dot-background-color customization-color theme)
:width size
:height size
:border-radius (/ size 2)
@@ -4,11 +4,11 @@
[quo2.theme :as quo.theme]))
(defn view-internal
[{:keys [customization-color style theme blur?]}]
[{:keys [customization-color style theme]}]
[rn/view
{:accessibility-label :notification-dot
:style (merge
(style/notification-dot customization-color theme blur?)
(style/notification-dot customization-color theme)
style)}])
(def view (quo.theme/with-theme view-internal))
@@ -1,11 +0,0 @@
(ns quo2.components.dividers.divider-line.style
(:require [quo2.foundations.colors :as colors]))
(defn divider-line
[blur? theme]
{:border-color (if blur?
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme)
(colors/theme-colors colors/neutral-10 colors/neutral-90 theme))
:padding-top 12
:padding-bottom 8
:border-bottom-width 1})
@@ -1,11 +0,0 @@
(ns quo2.components.dividers.divider-line.view
(:require
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[quo2.components.dividers.divider-line.style :as style]))
(defn- view-internal
[{:keys [blur? theme]}]
[rn/view {:style (style/divider-line blur? theme)}])
(def view (quo.theme/with-theme view-internal))
@@ -1,13 +0,0 @@
(ns quo2.components.graph.interactive-graph.component-spec
(:require [test-helpers.component :as h]
[quo2.components.graph.interactive-graph.view :as interactive-graph]))
(defn data
[num-elements]
(vec (take num-elements (repeat {:value 10}))))
(h/describe "interactive-graph"
(h/test "render interactive graph"
(h/render [interactive-graph/view
{:data data}])
(h/is-truthy (h/get-by-label-text :interactive-graph))))
@@ -1,49 +0,0 @@
(ns quo2.components.graph.interactive-graph.style
(:require [quo2.foundations.typography :as typography]))
(defn x-axis-label-text
[width y-axis-label-text-color]
(merge
typography/label
{:color y-axis-label-text-color
:height 16
:text-align :center
:width width}))
(defn y-axis-text
[y-axis-label-text-color y-axis-label-background-color]
(merge
typography/label
{:color y-axis-label-text-color
:padding-horizontal 3
:margin-left 23
:height 16
:border-radius 6
:overflow :hidden
:background-color y-axis-label-background-color}))
(defn pointer-component
[customization-color]
{:width 8
:height 8
:border-radius 4
:margin-left 1
:background-color customization-color})
(defn reference-line-label
[border-color background-color text-color]
(merge
typography/label
{:align-self :flex-end
:right 10
:margin-top -9
:padding-horizontal 5
:padding-top -10
:height 19
:line-height 14.62
:border-radius 6
:overflow :hidden
:border-color border-color
:border-width 2
:background-color background-color
:color text-color}))
@@ -1,141 +0,0 @@
(ns quo2.components.graph.interactive-graph.view
(:require [quo2.components.graph.utils :as utils]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.charts :as charts]
[react-native.core :as rn]
[reagent.core :as reagent]
[quo2.components.graph.interactive-graph.style :as style]))
(def chart-height 375)
(def max-data-points 500)
(def no-of-sections 4)
(def initial-spacing 56)
(def end-spacing 22)
(def y-axis-label-width -33)
(def inspecting? (reagent/atom false))
(defn- pointer
[customization-color]
(reagent/as-element
[rn/view
{:style
(style/pointer-component
customization-color)}]))
(defn- pointer-config
[customization-color]
{:stroke-dash-array [2 2]
:pointer-component #(pointer customization-color)
:pointer-strip-color customization-color
:pointer-color customization-color
:pointer-strip-enable-gradient true})
(defn- get-pointer-props
[pointer-props]
(let [pointer-index (.-pointerIndex ^js pointer-props)]
(reset! inspecting? (not= pointer-index -1))))
(defn- get-line-color
[state theme]
(if @inspecting?
(colors/theme-colors colors/neutral-80-opa-40
colors/white-opa-20
theme)
(if (= state :positive)
(colors/theme-colors colors/success-50
colors/success-60
theme)
(colors/theme-colors colors/danger-50
colors/danger-60
theme))))
(defn- view-internal
[{:keys [data state customization-color theme reference-value reference-prefix decimal-separator]
:or {reference-prefix "$"
decimal-separator :dot}}]
(let [data (if (> (count data) max-data-points)
(utils/downsample-data data max-data-points)
data)
highest-value (utils/find-highest-value data)
lowest-value (utils/find-lowest-value data)
min-value (utils/calculate-rounded-min lowest-value)
max-value (- (utils/calculate-rounded-max highest-value) min-value)
step-value (/ max-value 4)
width (:width (rn/get-window))
line-color (get-line-color state theme)
rules-color (colors/theme-colors colors/neutral-80-opa-10
colors/white-opa-5
theme)
y-axis-label-text-color (colors/theme-colors colors/neutral-80-opa-40
colors/white-opa-40
theme)
price-reference-label-text-color (colors/theme-colors colors/neutral-100 colors/white theme)
reference-label-border-color (colors/theme-colors colors/white colors/neutral-95 theme)
y-axis-label-background-color (colors/theme-colors colors/white-70-blur-opaque
colors/neutral-95
theme)
customization-color (colors/theme-colors
(colors/custom-color customization-color 60)
(colors/custom-color customization-color 50)
theme)
y-axis-label-texts (utils/calculate-y-axis-labels min-value step-value 4)
x-axis-label-texts (utils/calculate-x-axis-labels data 5)
reference-label-background-color (colors/theme-colors colors/neutral-80-opa-5-opaque
colors/neutral-80
theme)
reference-value (or reference-value (/ (+ highest-value lowest-value) 2))
formatted-reference-value (utils/format-currency-number reference-value decimal-separator)
chart-width (+ width 13)]
[rn/view {:accessibility-label :interactive-graph}
[charts/line-chart
{:height chart-height
:width chart-width
:max-value max-value
:x-axis-length chart-width
:y-axis-offset min-value
:y-axis-label-texts y-axis-label-texts
:y-axis-label-texts-ignore-offset true
:adjust-to-width true
:data data
:hide-data-points true
:no-of-sections no-of-sections
:step-value step-value
:rules-color rules-color
:dash-width 2
:dash-gap 2
:hide-y-axis-text false
:thickness 1
:color line-color
:y-axis-thickness 0
:x-axis-thickness 0
:initial-spacing initial-spacing
:end-spacing end-spacing
:disable-scroll true
:hide-origin true
:show-reference-line-1 true
:get-pointer-props get-pointer-props
:show-strip-on-focus true
:reference-line-1-config {:color rules-color}
:reference-line-1-position 0
:show-reference-line-2 (and (not @inspecting?)
(<= reference-value highest-value)
(>= reference-value lowest-value))
:reference-line-2-config {:color y-axis-label-text-color
:label-text-style (style/reference-line-label
reference-label-border-color
reference-label-background-color
price-reference-label-text-color)
:label-text (str reference-prefix
formatted-reference-value)
:dash-width 2}
:reference-line-2-position (- reference-value min-value)
:y-axis-text-style (style/y-axis-text y-axis-label-text-color
y-axis-label-background-color)
:y-axis-label-width y-axis-label-width
:pointer-config (pointer-config customization-color)
:x-axis-label-text-style (style/x-axis-label-text (/ width (count x-axis-label-texts))
y-axis-label-text-color)
:x-axis-label-texts x-axis-label-texts}]]))
(def view (quo.theme/with-theme view-internal))
-95
View File
@@ -1,95 +0,0 @@
(ns quo2.components.graph.utils
(:require [clojure.string :as string]
[goog.string :as gstring]))
(defn find-highest-value
[coll]
(apply max (map :value coll)))
(defn find-lowest-value
[coll]
(apply min (map :value coll)))
(defn downsample-data
[data max-array-size]
(let [data-size (count data)]
(if (> data-size max-array-size)
(let [step-size (max (/ data-size max-array-size) 1)]
(vec (take-nth step-size data)))
data)))
(defn format-compact-number
[number]
(let [abbreviations ["" "k" "M" "B" "T"]
log-base-1000 (js/Math.log10 1000) ; Calculate the logarithm base 1000
magnitude (int (/ (js/Math.log10 number) log-base-1000))
suffix (nth abbreviations magnitude)
scaled-number (/ number (js/Math.pow 1000.0 magnitude))
formatted-scaled-number (if (zero? (rem scaled-number 1))
(int scaled-number)
(-> (gstring/format "%.2f" scaled-number)
(string/replace #"\.?0+$" "")))]
(if (zero? magnitude)
(str number)
(if (and (>= scaled-number 1) (< scaled-number 1000))
(str formatted-scaled-number suffix)
(str formatted-scaled-number "0" suffix)))))
(defn calculate-x-axis-labels
[coll num-elements]
(let [array-length (count coll)
partitions (partition-all (js/Math.floor (/ array-length (min array-length num-elements)))
coll)]
(->> partitions
(map first)
(map :date))))
(defn calculate-y-axis-labels
[min-value step-value no-of-steps]
(let [labels-array (for [i (range (inc no-of-steps))]
(let [value (+ min-value (* step-value i))
compact-number (format-compact-number value)]
compact-number))]
(vec labels-array)))
(defn calculate-rounded-max
[highest-value]
(let [min-percentage-above 1.05 ; 5% above
rounded-divisor 4 ; Divisor for even division by 4
target-max (* min-percentage-above highest-value)
rounded-up (js/Math.ceil target-max)
remainder (mod rounded-up rounded-divisor)
y-axis-max (if (zero? remainder)
rounded-up
(+ rounded-up (- rounded-divisor remainder)))]
y-axis-max))
(defn calculate-rounded-min
[lowest]
(let [order-of-magnitude (js/Math.pow 10 (js/Math.floor (js/Math.log10 lowest)))
rounded-min (cond
(and (< lowest 1) (>= lowest 0)) 0
(>= lowest 1)
(* (js/Math.floor (/ lowest
order-of-magnitude))
order-of-magnitude)
(< lowest 0)
(* (calculate-rounded-max (* -1 lowest))
-1))]
rounded-min))
(defn format-currency-number
[number decimal-separator]
(let [formatted (-> (if (= decimal-separator :comma)
(js/Intl.NumberFormat
"de-DE"
{:style "currency" :currency "EUR" :minimumFractionDigits 2})
(js/Intl.NumberFormat
"en-US"
{:style "currency" :currency "USD" :minimumFractionDigits 2}))
(.format number))
separator-char (if (= decimal-separator :comma) "," ".")
formatted-with-decimals (if (.includes formatted separator-char)
formatted
(str formatted separator-char "00"))]
formatted-with-decimals))
-179
View File
@@ -1,179 +0,0 @@
(ns quo2.components.graph.utils-test
(:require [cljs.test :refer-macros [deftest is testing]]
[quo2.components.graph.utils :as utils]))
(deftest find-highest-value
(testing "Find highest value with a single map"
(let [data [{:value 5}]]
(is (= (utils/find-highest-value data) 5))))
(testing "Find highest value with multiple maps"
(let [data [{:value 5} {:value 10} {:value 3} {:value 7}]]
(is (= (utils/find-highest-value data) 10))))
(testing "Find highest value with negative values"
(let [data [{:value -2} {:value -10} {:value -3} {:value -7}]]
(is (= (utils/find-highest-value data) -2))))
(testing "Find highest value with decimal values"
(let [data [{:value 3.5} {:value 7.2} {:value 2.9}]]
(is (= (utils/find-highest-value data) 7.2))))
(testing "Find highest value with a large data set"
(let [data (vec (for [num (range 1000)] {:value num}))]
(is (= (utils/find-highest-value data) 999)))))
(deftest find-lowest-value
(testing "Find lowest value with a single map"
(let [data [{:value 5}]]
(is (= (utils/find-lowest-value data) 5))))
(testing "Find lowest value with multiple maps"
(let [data [{:value 5} {:value 10} {:value 3} {:value 7}]]
(is (= (utils/find-lowest-value data) 3))))
(testing "Find lowest value with negative values"
(let [data [{:value -2} {:value -10} {:value -3} {:value -7}]]
(is (= (utils/find-lowest-value data) -10))))
(testing "Find lowest value with decimal values"
(let [data [{:value 3.5} {:value 7.2} {:value 2.9}]]
(is (= (utils/find-lowest-value data) 2.9))))
(testing "Find lowest value with a large data set"
(let [data (vec (for [num (range 1000)] {:value num}))]
(is (= (utils/find-lowest-value data) 0)))))
(deftest downsample-data
(testing "Downsampling is applied correctly when needed"
(let [input-data [1 2 3 4 5 6 7 8 9 10]
max-array-size 5
expected-output [1 3 5 7 9]]
(is (= (utils/downsample-data input-data max-array-size) expected-output))))
(testing "Downsampling is not applied when not needed"
(let [input-data [1 2 3 4 5 6 7 8 9 10]
max-array-size 10
expected-output [1 2 3 4 5 6 7 8 9 10]]
(is (= (utils/downsample-data input-data max-array-size) expected-output))))
(testing "Downsampling works with empty input data"
(let [input-data []
max-array-size 5
expected-output []]
(is (= (utils/downsample-data input-data max-array-size) expected-output))))
(testing "Downsampling works with max-array-size of 1 (edge case)"
(let [input-data [1 2 3 4 5]
max-array-size 1
expected-output [1]]
(is (= (utils/downsample-data input-data max-array-size) expected-output))))
(testing "Downsampling works with large input data and max-array-size (randomized test)"
(let [large-data (range 1000)
max-array-size 500
expected-output (range 0 1000 2)] ; expected-output contains every 2nd element from 0 to 1000
(is (= (utils/downsample-data large-data max-array-size) expected-output)))))
(deftest format-compact-number
(testing "Format a whole number less than 1000"
(is (= (utils/format-compact-number 567) "567")))
(testing "Format a whole number exactly 1000"
(is (= (utils/format-compact-number 1000) "1k")))
(testing "Format a whole number greater than 1000"
(is (= (utils/format-compact-number 2500) "2.5k")))
(testing "Format a decimal number less than 1000"
(is (= (utils/format-compact-number 123.45) "123.45")))
(testing "Format a decimal number exactly 1000"
(is (= (utils/format-compact-number 1000) "1k")))
(testing "Format a decimal number greater than 1000"
(is (= (utils/format-compact-number 7890.123) "7.89k")))
(testing "Format a number in millions"
(is (= (utils/format-compact-number 123456789) "123.46M")))
(testing "Format a number in billions"
(is (= (utils/format-compact-number 1234567890) "1.23B")))
(testing "Format a number in trillions"
(is (= (utils/format-compact-number 1234567890000) "1.23T"))))
(deftest calculate-x-axis-labels
(testing "Calculate x-axis labels with a small array and fewer elements"
(let [data [{:date "2023-01-01"} {:date "2023-01-02"} {:date "2023-01-03"} {:date "2023-01-04"}]]
(is (= (utils/calculate-x-axis-labels data 2) '("2023-01-01" "2023-01-03")))))
(testing "Calculate x-axis labels with a larger array and more elements"
(let [data (vec (for [i (range 10)] {:date (str "2023-01-0" (inc i))}))]
(is (= (utils/calculate-x-axis-labels data 5)
'("2023-01-01" "2023-01-03" "2023-01-05" "2023-01-07" "2023-01-09")))))
(testing "Calculate x-axis labels with a very small array"
(let [data [{:date "2023-01-01"}]]
(is (= (utils/calculate-x-axis-labels data 3) '("2023-01-01")))))
(testing "Calculate x-axis labels with a larger array and a single element"
(let [data (vec (for [i (range 10)] {:date (str "2023-01-0" (inc i))}))]
(is (= (utils/calculate-x-axis-labels data 1) '("2023-01-01"))))))
(deftest calculate-y-axis-labels
(testing "Calculate y-axis labels with positive values"
(is (= (utils/calculate-y-axis-labels 0 10 5) ["0" "10" "20" "30" "40" "50"])))
(testing "Calculate y-axis labels with negative values"
(is (= (utils/calculate-y-axis-labels -20 5 4) ["-20" "-15" "-10" "-5" "0"])))
(testing "Calculate y-axis labels with decimal step value"
(is (= (utils/calculate-y-axis-labels 2.5 0.5 4) ["2.5" "3" "3.5" "4" "4.5"])))
(testing "Calculate y-axis labels with a single step"
(is (= (utils/calculate-y-axis-labels 5 1 1) ["5" "6"])))
(testing "Calculate y-axis labels with large step value and number of steps"
(is (= (utils/calculate-y-axis-labels 100 1000 3) ["100" "1.1k" "2.1k" "3.1k"]))))
(deftest calculate-rounded-max
(testing "Calculate rounded max with a whole number"
(is (= (utils/calculate-rounded-max 100) 108)))
(testing "Calculate rounded max with a decimal number"
(is (= (utils/calculate-rounded-max 50.5) 56)))
(testing "Calculate rounded max with a number already divisible by divisor"
(is (= (utils/calculate-rounded-max 108) 116)))
(testing "Calculate rounded max with a number close to the next divisor"
(is (= (utils/calculate-rounded-max 250) 264)))
(testing "Calculate rounded max with a large number"
(is (= (utils/calculate-rounded-max 1000) 1052))))
(deftest calculate-rounded-min
(testing "Calculate rounded min with a whole number"
(is (= (utils/calculate-rounded-min 157) 100)))
(testing "Calculate rounded min with a decimal number"
(is (= (utils/calculate-rounded-min 49.8) 40)))
(testing "Calculate rounded min with a small number"
(is (= (utils/calculate-rounded-min 0.007) 0)))
(testing "Calculate rounded min with a number already rounded"
(is (= (utils/calculate-rounded-min 500) 500)))
(testing "Calculate rounded min with a negative number"
(is (= (utils/calculate-rounded-min -63) -68))))
(deftest format-currency-number-test
(testing "Format currency number with comma decimal separator"
(is (= (utils/format-currency-number 12345 :comma) "12.345,00"))
(is (= (utils/format-currency-number 12345.67 :comma) "12.345,67")))
(testing "Format currency number with dot decimal separator"
(is (= (utils/format-currency-number 12345 :dot) "12,345.00"))
(is (= (utils/format-currency-number 12345.67 :dot) "12,345.67"))))
@@ -0,0 +1,13 @@
(ns quo2.components.graph.wallet-graph.utils)
(defn find-highest-value
[coll]
(apply max (map :value coll)))
(defn downsample-data
[data max-array-size]
(let [data-size (count data)]
(if (> data-size max-array-size)
(let [step-size (max (/ data-size max-array-size) 1)]
(vec (take-nth step-size data)))
data)))
@@ -0,0 +1,55 @@
(ns quo2.components.graph.wallet-graph.utils-test
(:require [cljs.test :refer-macros [deftest is testing]]
[quo2.components.graph.wallet-graph.utils :as utils]))
(deftest find-highest-value
(testing "Find highest value with a single map"
(let [data [{:value 5}]]
(is (= (utils/find-highest-value data) 5))))
(testing "Find highest value with multiple maps"
(let [data [{:value 5} {:value 10} {:value 3} {:value 7}]]
(is (= (utils/find-highest-value data) 10))))
(testing "Find highest value with negative values"
(let [data [{:value -2} {:value -10} {:value -3} {:value -7}]]
(is (= (utils/find-highest-value data) -2))))
(testing "Find highest value with decimal values"
(let [data [{:value 3.5} {:value 7.2} {:value 2.9}]]
(is (= (utils/find-highest-value data) 7.2))))
(testing "Find highest value with a large data set"
(let [data (vec (for [num (range 1000)] {:value num}))]
(is (= (utils/find-highest-value data) 999)))))
(deftest downsample-data
(testing "Downsampling is applied correctly when needed"
(let [input-data [1 2 3 4 5 6 7 8 9 10]
max-array-size 5
expected-output [1 3 5 7 9]]
(is (= (utils/downsample-data input-data max-array-size) expected-output))))
(testing "Downsampling is not applied when not needed"
(let [input-data [1 2 3 4 5 6 7 8 9 10]
max-array-size 10
expected-output [1 2 3 4 5 6 7 8 9 10]]
(is (= (utils/downsample-data input-data max-array-size) expected-output))))
(testing "Downsampling works with empty input data"
(let [input-data []
max-array-size 5
expected-output []]
(is (= (utils/downsample-data input-data max-array-size) expected-output))))
(testing "Downsampling works with max-array-size of 1 (edge case)"
(let [input-data [1 2 3 4 5]
max-array-size 1
expected-output [1]]
(is (= (utils/downsample-data input-data max-array-size) expected-output))))
(testing "Downsampling works with large input data and max-array-size (randomized test)"
(let [large-data (range 1000)
max-array-size 500
expected-output (range 0 1000 2)] ;; expected-output contains every 2nd element from 0 to 1000
(is (= (utils/downsample-data large-data max-array-size) expected-output)))))
@@ -6,9 +6,9 @@
[quo2.components.graph.wallet-graph.style :as style]
[quo2.foundations.colors :as colors]
[quo2.components.markdown.text :as text]
[quo2.components.graph.utils :as utils]))
[quo2.components.graph.wallet-graph.utils :as utils]))
(defn- time-frame->max-data-points
(defn- max-data-points
[time-frame]
(case time-frame
:empty 0
@@ -18,26 +18,17 @@
:1-year 365
500))
(defn- get-line-color
[customization-color state theme]
(let [color-keyword (cond
customization-color customization-color
(= state :positive) :success
:else :danger)]
(colors/theme-colors
(colors/custom-color color-keyword 50)
(colors/custom-color color-keyword 60)
theme)))
(defn- view-internal
[{:keys [data state time-frame customization-color theme]}]
(let [max-data-points (time-frame->max-data-points time-frame)
[{:keys [data state time-frame theme]}]
(let [max-data-points (max-data-points time-frame)
data (if (and (not= time-frame :empty) (> (count data) max-data-points))
(utils/downsample-data data max-data-points)
data)
max-value (when-not (= time-frame :empty) (utils/find-highest-value data))
width (:width (rn/get-window))
line-color (get-line-color customization-color state theme)
line-color (if (= state :positive)
(colors/theme-colors colors/success-50 colors/success-60 theme)
(colors/theme-colors colors/danger-50 colors/danger-60 theme))
gradient-colors [(colors/alpha line-color 0.1) (colors/alpha line-color 0)]
fill-color (colors/theme-colors colors/white colors/neutral-95)]
(if (= time-frame :empty)
+4 -4
View File
@@ -37,7 +37,7 @@
:align-items :center
:justify-content :center})
(def left-style
(def left
{:position :absolute
:left 0
:top 0
@@ -45,7 +45,7 @@
:justify-content :center
:align-items :flex-start})
(def right-style
(def right
{:position :absolute
:right 0
:top 0
@@ -176,7 +176,7 @@
{:style content
:pointer-events :box-none}
[rn/view
{:style left-style
{:style left
:on-layout (handle-layout :left get-layout)
:pointer-events :box-none}
[header-actions
@@ -194,7 +194,7 @@
:component title-component}]]
[rn/view
{:style right-style
{:style right
:on-layout (handle-layout :right get-layout)
:pointer-events :box-none}
[header-actions
@@ -9,4 +9,5 @@
{:placeholder "Your Name"
:on-press event}])
(h/fire-event :press (h/get-by-label-text :select-profile-picture-button))
(h/was-called-times event 1))))
(-> (js/expect event)
(.toHaveBeenCalledTimes 1)))))
@@ -1,12 +1,13 @@
(ns quo2.components.inputs.profile-input.style
(:require [quo2.foundations.colors :as colors]))
(:require [react-native.platform :as platform]
[quo2.foundations.colors :as colors]))
(defn container
[customization-color]
{:background-color (colors/custom-color customization-color 50 40)
:padding-horizontal 12
:padding-top 12
:padding-bottom 10
:padding-bottom (if platform/ios? 10 0)
:border-radius 16
:flex 1})
@@ -31,11 +31,10 @@
:borderRadius 12}]}
[user-avatar/user-avatar
(assoc image-picker-props
:customization-color customization-color
:static? true
:status-indicator? false
:full-name (if (seq full-name) full-name placeholder)
:size :medium)]]
:static? true
:status-indicator? false
:full-name (if (seq full-name) full-name placeholder)
:size :medium)]]
[buttons/button
{:accessibility-label :select-profile-picture-button
:type :grey
@@ -46,7 +45,7 @@
:container-style style/button
:inner-style style/button-inner} :i/camera]]
[rn/view {:style style/input-container}
[title-input/view
[title-input/title-input
(merge title-input-props
{:blur? true
:placeholder placeholder
@@ -2,31 +2,39 @@
(:require [quo2.components.inputs.title-input.view :as title-input]
[test-helpers.component :as h]))
(h/describe "input -> title-input component"
(h/describe "profile: title-input"
(h/test "renders empty"
(h/render [title-input/view {:value ""}])
(h/is-truthy (h/query-by-label-text :profile-title-input)))
(h/render [title-input/title-input
{:value ""
:on-change-text (h/mock-fn)}])
(-> (js/expect (h/get-by-label-text :profile-title-input))
(.toBeTruthy)))
(h/test "empty text renders with max length digits and 00"
(h/render [title-input/view
{:value ""
:max-length 24}])
(h/fire-event :on-focus (h/query-by-label-text :profile-title-input))
(h/wait-for #(h/is-truthy (h/query-by-text "00")))
(h/is-truthy (h/query-by-text "/24")))
(h/render [title-input/title-input
{:value ""
:max-length 24
:on-change-text (h/mock-fn)}])
(-> (js/expect (h/get-by-text "00"))
(.toBeTruthy))
(-> (js/expect (h/get-by-text "/24"))
(.toBeTruthy)))
(h/test "renders with max length digits and character count"
(h/render [title-input/view
{:default-value "abc"
:max-length 24} "abc"])
(h/fire-event :on-focus (h/query-by-label-text :profile-title-input))
(h/wait-for #(h/is-truthy (h/query-by-text "03")))
(h/is-truthy (h/query-by-text "/24")))
(h/render [title-input/title-input
{:default-value "abc"
:max-length 24
:on-change-text (h/mock-fn)} "abc"])
(-> (js/expect (h/get-by-text "03"))
(.toBeTruthy))
(-> (js/expect (h/get-by-text "/24"))
(.toBeTruthy)))
(h/test "text updates on change"
(let [on-change-text (h/mock-fn)]
(h/render [title-input/view
(h/render [title-input/title-input
{:value "mock text"
:on-change-text on-change-text}])
(h/fire-event :change-text (h/get-by-label-text :profile-title-input) "mock-text-new")
(h/was-called on-change-text))))
(-> (js/expect on-change-text)
(.toHaveBeenCalled)))))
@@ -6,7 +6,8 @@
[blur? theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme)))
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme))
)
(defn get-placeholder-color
[blur? theme]
@@ -14,7 +15,13 @@
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30 theme)
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
(defn get-char-count-color
(defn- get-disabled-color
[blur? theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30)
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
(defn- get-char-count-color
[blur? theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40)
@@ -31,23 +38,21 @@
(def text-input-container {:flex 1})
(defn title-text
[theme]
[disabled? blur? theme]
{:text-align-vertical :bottom
:padding 0
:color (colors/theme-colors colors/neutral-100 colors/white theme)})
:color (if disabled?
(get-disabled-color blur? theme)
(colors/theme-colors colors/neutral-100 colors/white theme))})
(defn char-count
[blur? theme]
{:color (get-char-count-color blur? theme)})
(defn container
[disabled?]
(def container
{:flex-direction :row
:opacity (if disabled? 0.3 1)
:justify-content :center
:align-items :center})
(defn counter-container
[focused?]
{:padding-top (if focused? 12 9)
:padding-bottom (if focused? 2 3)})
(def counter-container
{:padding-top 8})
@@ -4,8 +4,7 @@
[quo2.components.markdown.text :as text]
[reagent.core :as reagent]
[react-native.core :as rn]
[quo2.theme :as quo.theme]
[quo2.components.icon :as icon]))
[quo2.theme :as theme]))
(defn- pad-0
[value]
@@ -13,7 +12,7 @@
(str 0 value)
value))
(defn- view-internal
(defn- title-input-internal
[{:keys [blur?
on-change-text
auto-focus
@@ -27,24 +26,23 @@
default-value ""}}]
(let [focused? (reagent/atom auto-focus)
value (reagent/atom default-value)
input-ref (atom nil)
on-change (fn [v]
(reset! value v)
(when on-change-text
(on-change-text v)))]
(fn [{:keys [customization-color disabled?]}]
[rn/view
{:style (merge (style/container disabled?) container-style)}
{:style (merge style/container container-style)}
[rn/view {:style style/text-input-container}
[rn/text-input
{:style
(text/text-style
{:size :heading-2
:weight :semi-bold
:style (style/title-text theme)})
:style (style/title-text disabled? blur? theme)})
:default-value default-value
:accessibility-label :profile-title-input
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
:keyboard-appearance (theme/theme-value :light :dark theme)
:on-focus #(swap! focused? (constantly true))
:on-blur #(swap! focused? (constantly false))
:auto-focus auto-focus
@@ -53,30 +51,24 @@
:editable (not disabled?)
:max-length max-length
:placeholder placeholder
:ref #(reset! input-ref %)
:selection-color (style/get-selection-color customization-color blur? theme)
:placeholder-text-color (if @focused?
(style/get-focused-placeholder-color blur? theme)
(style/get-placeholder-color blur? theme))}]]
[rn/view
{:style (style/counter-container @focused?)}
(if @focused?
[text/text
[text/text
{:style (style/char-count blur? theme)
:size :paragraph-2}
(pad-0
(str
(count @value)))]
[text/text
{:style (style/char-count blur? theme)
:size :paragraph-2}
(str "/"
(pad-0
(str max-length)))]]
[rn/pressable
{:on-press #(when-not disabled?
(.focus ^js @input-ref))}
[icon/icon :i/edit {:color (style/get-char-count-color blur? theme)}]])]])))
{:style style/counter-container}
[text/text
[text/text
{:style (style/char-count blur? theme)
:size :paragraph-2}
(pad-0
(str
(count @value)))]
[text/text
{:style (style/char-count blur? theme)
:size :paragraph-2}
(str "/"
(pad-0
(str max-length)))]]]])))
(def view (quo.theme/with-theme view-internal))
(def title-input (theme/with-theme title-input-internal))
@@ -0,0 +1,68 @@
(ns quo2.components.list-items.channel
(:require [quo2.components.avatars.channel-avatar.view :as channel-avatar]
[quo2.components.common.unread-grey-dot.view :as unread-grey-dot]
[quo2.components.counter.counter.view :as counter]
[quo2.components.icon :as quo2.icons]
[quo2.components.markdown.text :as quo2.text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
(def ^:private custom-props
[:name :locked? :mentions-count :unread-messages?
:muted? :is-active-channel? :emoji :channel-color])
(defn list-item
[{:keys [locked? mentions-count unread-messages?
muted? is-active-channel? emoji channel-color
default-color]
:as props}]
(let [channel-color (or channel-color default-color)
standard-props (apply dissoc props custom-props)
name-text (:name props)]
[rn/touchable-opacity standard-props
[rn/view
{:style (cond-> {:height 48
:border-radius 12
:flex-direction :row
:justify-content :space-between
:align-items :center
:width "100%"
:padding-left 12
:padding-right 12}
is-active-channel? (assoc :background-color
(colors/theme-alpha channel-color 0.05 0.05)))}
[rn/view
{:style {:flex-direction :row
:justify-content :flex-start
:align-items :center}
:accessible true
:accessibility-label :chat-name-text}
[channel-avatar/view
{:size :size/l
:locked? locked?
:full-name (:name props)
:customization-color channel-color
:emoji emoji}]
[quo2.text/text
{:style (cond-> {:margin-left 12}
(and (not locked?) muted?)
(assoc :color (colors/theme-colors colors/neutral-40 colors/neutral-60)))
:weight :medium
:size :paragraph-1}
(str "# " name-text)]]
(when-not locked?
[rn/view {:style {:height 20 :justify-content :center}}
(cond
muted?
[quo2.icons/icon :i/muted
{:size 20
:color colors/neutral-40
:container-style {:margin-right 1 :margin-top 2}}]
(pos? (int mentions-count))
[rn/view {:style {:margin-right 2 :margin-top 2}}
[counter/view {:customization-color channel-color}
mentions-count]]
unread-messages?
[unread-grey-dot/unread-grey-dot :unviewed-messages-public])])]]))
@@ -1,44 +0,0 @@
(ns quo2.components.list-items.channel.component-spec
(:require [test-helpers.component :as h]
[quo2.components.list-items.channel.view :as channel]))
(h/describe "list-items/channel Component"
(h/test "default render"
(h/render [channel/view {:name "general"}])
(h/is-truthy (h/query-by-label-text :channel-list-item)))
(h/test "with name & emoji"
(h/render [channel/view
{:name "general"
:emoji "👋"}])
(h/is-truthy (h/query-by-text "# general"))
(h/is-truthy (h/query-by-text "👋")))
(h/test "notification & mentions count"
(h/render [channel/view
{:name "general"
:mentions-count 10
:notification :mention}])
(h/is-truthy (h/query-by-text "10")))
(h/test "unread indicator"
(h/render [channel/view
{:name "general"
:notification :notification}])
(h/is-truthy (h/query-by-label-text :unviewed-messages-public)))
(h/test "on-press event"
(let [on-press (h/mock-fn)]
(h/render [channel/view
{:name "general"
:on-press on-press}])
(h/fire-event :press (h/query-by-label-text :channel-list-item))
(h/was-called on-press)))
(h/test "on-long-press event"
(let [on-long-press (h/mock-fn)]
(h/render [channel/view
{:name "general"
:on-long-press on-long-press}])
(h/fire-event :long-press (h/query-by-label-text :channel-list-item))
(h/was-called on-long-press))))
@@ -1,50 +0,0 @@
(ns quo2.components.list-items.channel.style
(:require [quo2.foundations.colors :as colors]))
(defn- get-label-color
[notification theme]
(let [colors {:notification (colors/theme-colors colors/neutral-100
colors/white
theme)
:mention (colors/theme-colors colors/neutral-100
colors/white
theme)
:mute (colors/theme-colors colors/neutral-40
colors/neutral-60
theme)
:default (colors/theme-colors colors/neutral-50
colors/neutral-40
theme)}]
(colors (or notification :default))))
(defn mute-notification-icon-color
[theme]
(colors/theme-colors colors/neutral-40
colors/neutral-60
theme))
(defn container
[pressed? customization-color theme]
{:height 48
:border-radius 12
:padding-horizontal 12
:padding-vertical 8
:align-items :center
:overflow :hidden
:background-color (if pressed?
(colors/theme-colors
(colors/custom-color customization-color 50 5)
(colors/custom-color customization-color 60 5)
theme)
:transparent)
:flex-direction :row})
(defn label
[notification theme]
{:margin-horizontal 12
:color (get-label-color notification theme)
:flex 1})
(defn counter
[mentions]
{:margin-horizontal (if (= (count (str mentions)) 1) 2 0)})
@@ -1,63 +0,0 @@
(ns quo2.components.list-items.channel.view
(:require [quo2.components.list-items.channel.style :as style]
[quo2.theme :as theme]
[react-native.core :as rn]
[quo2.components.avatars.channel-avatar.view :as channel-avatar]
[quo2.components.markdown.text :as quo.text]
[quo2.components.icon :as quo2.icons]
[quo2.components.counter.counter.view :as counter]
[reagent.core :as reagent]))
(defn- view-internal
"Options:
- notification - (nil/:notification/:mention/:mute, default: nil):
- :notification - Display a grey dot.
- :mention - Display a counter.
- :mute - Display a mute icon.
- locked? - (nil/boolean, default: nil):
- When true, display a locked icon.
- When false, display an unlocked icon.
- mentions-count - (default: nil) - Number of mentions to display in the counter with :mention notification.
- customization-color - (default: nil) - Community color.
- emoji - (string, default: nil):
- Emoji to be displayed on the channel avatar.
- If blank, initials of the channel name are displayed.
- name - (string, default: nil) - Channel name.
- on-press - (function, default: nil) - Function called when the component is pressed.
- on-long-press - (function, default: nil) - Function called when the component is long pressed.
- theme - Theme value from with-theme HOC"
[]
(let [pressed? (reagent/atom false)]
(fn [{:keys [notification locked? mentions-count customization-color emoji name on-press
on-long-press theme]}]
[rn/pressable
{:style (style/container @pressed? customization-color theme)
:accessibility-label :channel-list-item
:on-press on-press
:on-long-press on-long-press
:on-press-in #(reset! pressed? true)
:on-press-out #(reset! pressed? false)}
[channel-avatar/view
{:size :size/l
:locked? locked?
:full-name name
:customization-color customization-color
:emoji emoji}]
[quo.text/text
{:style (style/label notification theme)
:weight :medium
:size :paragraph-1} (str "# " name)]
(when-not locked?
(condp = notification
:mute [quo2.icons/icon :i/muted
{:color (style/mute-notification-icon-color theme)}]
:mention [counter/view
{:customization-color customization-color
:container-style (style/counter mentions-count)}
mentions-count]
:notification [quo2.icons/icon :i/notification
{:color (style/mute-notification-icon-color theme)
:accessibility-label :unviewed-messages-public}]
nil))])))
(def view (theme/with-theme view-internal))
@@ -21,9 +21,7 @@
;; Standlone message skeleton
(defn- f-message-skeleton
{:deprecated "quo2.components.loaders.skeleton-list.view should be used instead"}
[]
(let [color (colors/theme-colors colors/neutral-5 colors/neutral-70)
loading-color (colors/theme-colors colors/neutral-10 colors/neutral-60)
content-width (rand-nth message-content-width)
@@ -12,7 +12,7 @@
[{:keys [primary-name secondary-name style short-chat-key time-str contact? verified? untrustworthy?
muted? size]
:or {size 13}}]
[rn/view {:style (merge style/container style {:height (if (= size 15) 21.75 18.2)})}
[rn/view {:style (merge style/container style)}
[text/text
{:weight :semi-bold
:size (if (= size 15) :paragraph-1 :paragraph-2)
@@ -1,12 +1,13 @@
(ns quo2.components.messages.system-message
(:require [clojure.string :as string]
[quo2.components.avatars.icon-avatar :as icon-avatar]
(:require [quo2.components.avatars.icon-avatar :as icon-avatar]
[quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.markdown.text :as text]
[quo2.components.messages.author.view :as author]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[utils.i18n :as i18n]))
[utils.i18n :as i18n]
[quo2.theme :as quo.theme]
[clojure.string :as string]))
(defn text-color
[theme]
@@ -14,24 +15,24 @@
(defn time-color
[theme]
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme))
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))
(defn sm-icon
[{:keys [icon color opacity]}]
[rn/view
{:margin-right 8}
[icon-avatar/icon-avatar
{:size :size/s-32
{:size :medium
:icon icon
:color color
:opacity opacity}]])
(defn sm-timestamp
[timestamp theme]
[rn/view {:margin-left 8}
[timestamp]
[rn/view {:margin-left 8 :margin-top 2}
[text/text
{:size :label
:style {:color (time-color theme)
:style {:color (time-color :time)
:text-transform :none}}
timestamp]])
@@ -47,72 +48,66 @@
(defn split-text
[label theme add-pred?]
(let [color (text-color theme)
label-vector (map-indexed vector (string/split label " "))]
[rn/view {:style {:flex-direction :row :flex-shrink 0 :align-items :center}}
(let [color (text-color theme)]
[:<>
(when add-pred?
[text/text {} " "])
(for [[indx item] label-vector]
(for [[indx item] (map-indexed vector (string/split label " "))]
^{:key indx}
[text/text
{:size :paragraph-2
:style {:color color
:margin-right (if (= indx (dec (count label-vector)))
0
3)}}
:margin-right 3}}
item])]))
(defn system-message-base
[{:keys [icon]} child]
[{:keys [icon timestamp]} child]
[rn/view
{:flex-direction :row
:flex 1
:align-items :center}
:flex 1}
[sm-icon icon]
[rn/view
{:align-self :center
:flex-direction :row
:margin-right 40 ;; dirty hack, flexbox won't work as expected
:flex 1}
child]])
child
[sm-timestamp timestamp]]])
(defn system-message-deleted-internal
[{:keys [label child theme timestamp]}]
[system-message-base
{:icon {:icon :i/delete
:color :danger
:opacity 5}}
[rn/view {:style {:flex-direction :row :align-items :center}}
(if child
child
[text/text
{:size :paragraph-2
:style {:color (text-color theme)}}
(or label (i18n/label :t/message-deleted))])
[sm-timestamp timestamp theme]]])
{:icon {:icon :i/delete
:color :danger
:opacity 5}
:timestamp timestamp}
(if child
child
[text/text
{:size :paragraph-2
:style {:color (text-color theme)}}
(or label (i18n/label :t/message-deleted))])])
(def system-message-deleted (quo.theme/with-theme system-message-deleted-internal))
(defn system-message-contact-internal
[{:keys [display-name photo-path customization-color theme timestamp]} label icon]
[system-message-base
{:icon {:icon icon
:color (or customization-color :primary)
:opacity 5}}
{:icon {:icon icon
:color (or customization-color :primary)
:opacity 5}
:timestamp timestamp}
[rn/view
{:flex-direction :row
:align-items :center
:flex-shrink 1
:flex-wrap :nowrap}
[rn/view {:flex-direction :row :align-items :center :flex-shrink 1}
:flex-wrap :wrap}
[rn/view {:flex-direction :row :align-items :center}
[sm-user-avatar display-name photo-path]
[text/text
{:weight :semi-bold
:number-of-lines 1
:style {:flex-shrink 1}
:size :paragraph-2}
{:weight :semi-bold
:size :paragraph-2}
display-name]]
[split-text label theme true]
[sm-timestamp timestamp theme]]])
[split-text label theme true]]])
(def system-message-contact (quo.theme/with-theme system-message-contact-internal))
@@ -132,47 +127,38 @@
(defn system-message-contact-request-internal
[{:keys [display-name photo-path customization-color theme timestamp incoming?]}]
[system-message-base
{:icon {:icon :i/add-user
:color (or customization-color :primary)
:opacity 5}}
{:icon {:icon :i/add-user
:color (or customization-color :primary)
:opacity 5}
:timestamp timestamp}
[rn/view
{:flex-direction :row
:align-items :center
:flex-shrink 1
:flex-wrap :nowrap}
:flex-wrap :wrap}
(when-not incoming? [split-text "Contact request sent to" theme false])
[rn/view {:flex-direction :row :align-items :center :flex-shrink 1}
[rn/view {:flex-direction :row :align-items :center}
[sm-user-avatar display-name photo-path]
[text/text
{:weight :semi-bold
:number-of-lines 1
:style {:flex-shrink 1}
:size :paragraph-2}
{:weight :semi-bold
:size :paragraph-2}
display-name]]
(when incoming? [split-text "sent you a contact request" theme true])
[sm-timestamp timestamp theme]]])
(when incoming? [split-text "sent you a contact request" theme true])]])
(def system-message-contact-request (quo.theme/with-theme system-message-contact-request-internal))
(defn system-message-pinned-internal
[{:keys [pinned-by child customization-color theme timestamp]}]
[system-message-base
{:icon {:icon :i/pin
:color (or customization-color :primary)
:opacity 5}}
[rn/view {:style {:flex 1}}
{:icon {:icon :i/pin
:color (or customization-color :primary)
:opacity 5}
:timestamp timestamp}
[rn/view
[rn/view
{:flex-direction :row
:align-items :center
:flex-wrap :nowrap}
[text/text
{:weight :semi-bold
:number-of-lines 1
:style {:flex-shrink 1}
:size :paragraph-2}
pinned-by]
[split-text (i18n/label :pinned-a-message) theme true]
[sm-timestamp timestamp theme]]
:flex-wrap :wrap}
[author/author {:primary-name pinned-by}]
[split-text (i18n/label :pinned-a-message) theme true]]
(when child child)]])
(def system-message-pinned (quo.theme/with-theme system-message-pinned-internal))
@@ -1,37 +0,0 @@
(ns quo2.components.navigation.top-nav.component-spec
(:require [quo2.components.navigation.top-nav.view :as top-nav]
[test-helpers.component :as h]))
(h/describe "Top Nav component"
(h/test "Renders default"
(h/render [top-nav/view])
(h/is-truthy (h/get-by-label-text :open-scanner-button))
(h/is-truthy (h/get-by-label-text :open-activity-center-button))
(h/is-truthy (h/get-by-label-text :show-qr-button))
(h/is-truthy (h/get-by-label-text :open-profile)))
(h/test "On press works for all buttons and avatar"
(let [avatar-on-press (h/mock-fn)
scan-on-press (h/mock-fn)
activity-center-on-press (h/mock-fn)
qr-code-on-press (h/mock-fn)]
(h/render [top-nav/view
{:avatar-on-press avatar-on-press
:scan-on-press scan-on-press
:activity-center-on-press activity-center-on-press
:qr-code-on-press qr-code-on-press}])
(h/fire-event :press (h/get-by-label-text :open-scanner-button))
(h/was-called scan-on-press)
(h/fire-event :press (h/get-by-label-text :open-activity-center-button))
(h/was-called activity-center-on-press)
(h/fire-event :press (h/get-by-label-text :show-qr-button))
(h/was-called qr-code-on-press)
(h/fire-event :press (h/get-by-label-text :open-profile))
(h/was-called avatar-on-press))))
@@ -1,35 +0,0 @@
(ns quo2.components.navigation.top-nav.style)
(defn unread-indicator
[unread-count max-value]
(let [right-offset (cond
(> unread-count max-value)
-14
;; Greater than 9 means we'll need 2 digits to represent
;; the text.
(> unread-count 9)
-10
:else -6)]
{:position :absolute
:top -6
:right right-offset
:z-index 4}))
(def unread-dot
{:position :absolute
:top -2
:bottom 0
:right 0
:left 38})
(def right-section
{:flex-direction :row})
(def top-nav-container
{:height 56})
(def top-nav-inner-container
{:flex 1
:flex-direction :row
:justify-content :space-between
:align-items :center})
@@ -1,166 +0,0 @@
(ns quo2.components.navigation.top-nav.view
(:require [react-native.core :as rn]
[quo2.components.buttons.button.view :as button]
[quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.counter.counter.view :as counter]
[quo2.components.navigation.top-nav.style :as style]
[react-native.hole-view :as hole-view]
[quo2.theme :as quo.theme]
[quo2.components.common.notification-dot.view :as notification-dot]))
(def notification-dot-hole
[{:x 37
:y -2
:width 9
:height 9
:borderRadius 4}])
(defn unread-counter-hole
[notification-count]
(let [x (case (count (str notification-count))
(1 2) 33
29)
width (case (count (str notification-count))
1 16
2 20
28)]
(if (pos? (js/Number notification-count))
[{:x x
:y -5
:width width
:height 16
:borderRadius 6}]
[])))
(defn- get-button-common-props
[{:keys [jump-to? theme blur?]}]
{:icon-only? true
:size 32
:container-style {:margin-left 12}
:type (cond
jump-to? :black
(and (not blur?) (= :dark theme)) :dark-grey
:else :grey)
:background (when blur? :blur)})
(defn- unread-indicator
[{:keys [notification-count max-value customization-color type]}]
(when (pos? notification-count)
[counter/view
{:accessibility-label :activity-center-unread-count
:type type
:customization-color customization-color
:container-style (style/unread-indicator notification-count
max-value)}
notification-count]))
(defn unread-dot
[{:keys [customization-color blur? notification]}]
[notification-dot/view
{:style style/unread-dot
:blur? blur?
:customization-color (when (= notification :notification) customization-color)}])
(defn notification-highlight
[{:keys [notification notification-count
max-unread-notifications customization-color]
:as props}]
(case notification
(:seen :notification) [unread-dot props]
(:mention :mention-seen) [unread-indicator
{:type (if (= notification :mention-seen) :grey :default)
:notification-count notification-count
:max-value max-unread-notifications
:customization-color customization-color}]
[:<>]))
(defn- left-section
[{:keys [avatar-props on-press customization-color]}]
[rn/touchable-without-feedback {:on-press on-press}
[rn/view
{:accessibility-label :open-profile}
[user-avatar/user-avatar
(merge {:status-indicator? true
:ring? true
:customization-color customization-color
:size :small}
avatar-props)]]])
(defn- right-section
[{:keys [theme
jump-to?
blur?
notification
notification-count
activity-center-on-press
scan-on-press
qr-code-on-press
for-qa-only-cellular-network
for-qa-only-no-network
for-qa-only-network-type]
:as props}]
(let [button-common-props (get-button-common-props {:theme theme
:jump-to? jump-to?
:blur? blur?})]
[rn/view {:style style/right-section}
(when (= for-qa-only-network-type "cellular")
[button/button
(merge (dissoc button-common-props :icon-only?)
for-qa-only-cellular-network)
"🦄"])
(when (= for-qa-only-network-type "none")
[button/button
(merge (dissoc button-common-props :icon-only?)
for-qa-only-no-network)
"💀"])
[button/button
(assoc button-common-props :accessibility-label :open-scanner-button :on-press scan-on-press)
:i/scan]
[button/button
(merge button-common-props
{:accessibility-label :show-qr-button
:on-press qr-code-on-press})
:i/qr-code]
[rn/view
[hole-view/hole-view
{:key (hash (str notification notification-count))
:holes (case notification
(:seen :notification) notification-dot-hole
(:mention :mention-seen) (unread-counter-hole notification-count)
[])}
[button/button
(merge button-common-props
{:accessibility-label :open-activity-center-button
:on-press activity-center-on-press})
:i/activity-center]]
[notification-highlight props]]]))
(defn view-internal
[{:keys [avatar-on-press avatar-props customization-color container-style] :as props}]
[rn/view {:style (merge style/top-nav-container container-style)}
[rn/view {:style style/top-nav-inner-container}
[left-section
{:avatar-props avatar-props
:on-press avatar-on-press
:customization-color customization-color}]
[right-section (dissoc props :avatar-props :avatar-on-press)]]])
(def view
":container-style style map merged with outer view for margins/paddings
:customization-color custom colors
:blur? true/false
:jump-to? true/false
:theme :light/:dark
:notification :mention/:seen/:notification (TODO :mention-seen temporarily used while resolving https://github.com/status-im/status-mobile/issues/17102 )
:avatar-props qu2/user-avatar props
:avatar-on-press callback
:scan-on-press callback
:activity-center-on-press callback
:qr-code-on-press callback
:notification-count number
:max-unread-notifications used to specify max number for counter
:for-qa-only-cellular-network used for testing purposed
:for-qa-only-no-network used for testing purposed
:for-qa-only-network-type used for testing purposed
"
(quo.theme/with-theme view-internal))
@@ -11,7 +11,7 @@
[quo2.components.avatars.user-avatar.view :as user-avatar]))
(defn- f-profile-card-component
[{:keys [keycard-account? profile-picture name
[{:keys [keycard-account? profile-picture name hash
customization-color emoji-hash on-options-press
show-emoji-hash? show-options-button? show-user-hash?
show-logged-in? on-card-press login-card? last-item? card-style]
@@ -24,8 +24,7 @@
login-card? false
last-item? false
card-style {:padding-horizontal 20
:flex 1}}
:as args}]
:flex 1}}}]
(let [{:keys [width]} (rn/get-window)
padding-bottom (cond
login-card? 38
@@ -95,8 +94,7 @@
(when show-user-hash?
[text/text
{:weight :monospace
:style style/user-hash}
(:hash args)])
:style style/user-hash} hash])
(when (and show-emoji-hash? emoji-hash)
[text/text
{:weight :monospace
@@ -10,22 +10,22 @@
:linear))
(defn animate-linear-with-delay
[shared-value value duration delay-ms]
[shared-value value duration delay]
(reanimated/animate-shared-value-with-delay
shared-value
value
duration
:linear
delay-ms))
delay))
(defn animate-linear-with-delay-loop
[shared-value value duration delay-ms]
[shared-value value duration delay]
(reanimated/animate-shared-value-with-delay-repeat
shared-value
value
duration
:linear
delay-ms
delay
-1))
(defn animate-easing
@@ -37,13 +37,13 @@
:easing1))
(defn animate-easing-with-delay
[shared-value value duration delay-ms]
[shared-value value duration delay]
(reanimated/animate-shared-value-with-delay
shared-value
value
duration
:easing1
delay-ms))
delay))
(defn set-value
[shared-value value]
@@ -1,7 +1,7 @@
(ns quo2.components.settings.category.settings.view
(:require
[quo2.components.markdown.text :as text]
[quo2.components.settings.settings-item.view :as settings-item]
[quo2.components.settings.settings-list.view :as settings-list]
[quo2.foundations.colors :as colors]
[react-native.blur :as blur]
[react-native.core :as rn]
@@ -21,7 +21,7 @@
[rn/flat-list
{:data data
:style (style/settings-items theme blur?)
:render-fn (fn [item] [settings-item/view item])
:render-fn (fn [item] [settings-list/settings-list item])
:separator [rn/view {:style (style/settings-separator theme blur?)}]}]])
(def settings-category (quo.theme/with-theme category-internal))
@@ -1,57 +0,0 @@
(ns quo2.components.settings.settings-item.component-spec
(:require [quo2.components.settings.settings-item.view :as settings-item]
[test-helpers.component :as h]))
(def props
{:title "Account"
:accessibility-label :settings-item
:action :arrow
:image :icon
:image-props :i/browser})
(h/describe "Settings list tests"
(h/test "Default render of Setting list component"
(h/render [settings-item/view props])
(h/is-truthy (h/get-by-label-text :settings-item)))
(h/test "It renders a title"
(h/render [settings-item/view props])
(h/is-truthy (h/get-by-text "Account")))
(h/test "its gets passed an on press event"
(let [event (h/mock-fn)]
(h/render [settings-item/view
(merge props {:on-press event})])
(h/fire-event :press (h/get-by-text "Account"))
(h/was-called event)))
(h/test "on change event gets fired for toggle"
(let [on-change (h/mock-fn)]
(h/render [settings-item/view
(merge props
{:action :selector
:action-props {:on-change on-change}})])
(h/fire-event :press (h/get-by-label-text :toggle-off))
(h/was-called on-change)))
(h/test "It renders a label"
(h/render [settings-item/view (merge props {:label :color})])
(h/is-truthy (h/get-by-label-text :label-component)))
(h/test "It renders a status tag component"
(h/render [settings-item/view
(merge props
{:tag :context
:tag-props {:context "Test Tag"
:icon :i/placeholder}})])
(h/is-truthy (h/get-by-text "Test Tag")))
(h/test "on press event gets fired for button"
(let [event (h/mock-fn)]
(h/render [settings-item/view
(merge props
{:action :button
:action-props {:button-text "test button"
:on-press event}})])
(h/fire-event :press (h/get-by-text "test button"))
(h/was-called event))))
@@ -1,57 +0,0 @@
(ns quo2.components.settings.settings-item.style
(:require [quo2.foundations.colors :as colors]))
(defn find-icon-height
[description tag image]
(let [icon-height (if (= image :icon-avatar) 32 20)
icon-height (if description 40 icon-height)]
(if tag 72 icon-height)))
(defn container
[{:keys [in-card? tag]}]
{:padding-horizontal 12
:padding-vertical (if in-card? 12 13)
:flex-direction :row
:justify-content :space-between
:height (if tag 96 48)})
(def sub-container
{:flex-direction :row
:align-items :center})
(def left-container
{:margin-left 12
:height "100%"
:justify-content :center})
(defn image-container
[description tag image]
{:height (find-icon-height description tag image)
:justify-content :flex-start})
(def status-container
{:flex-direction :row
:align-items :center})
(defn status-dot
[online? theme]
{:width 8
:height 8
:border-radius 8
:margin-right 6
:background-color (if online?
(colors/theme-colors colors/success-50 colors/success-60 theme)
(colors/theme-colors colors/danger-50 colors/danger-60 theme))})
(defn color
[blur? theme]
{:color (if blur?
colors/white-opa-70
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
(defn label-dot
[background-color]
{:width 15
:height 15
:border-radius 12
:background-color background-color})
@@ -1,117 +0,0 @@
(ns quo2.components.settings.settings-item.view
(:require
[quo2.components.icon :as icon]
[quo2.components.list-items.preview-list.view :as preview-list]
[quo2.components.selectors.selectors.view :as selectors]
[quo2.components.buttons.button.view :as button]
[quo2.components.markdown.text :as text]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[quo2.components.avatars.icon-avatar :as icon-avatar]
[quo2.components.tags.status-tags :as status-tags]
[quo2.components.tags.context-tag.view :as context-tag]
[quo2.components.settings.settings-item.style :as style]
[quo2.components.avatars.user-avatar.view :as user-avatar]
[utils.i18n :as i18n]))
(defn status-description
[{:keys [description-props blur? theme]}]
(let [{:keys [online? text]} description-props]
[rn/view {:style style/status-container}
[rn/view {:style (style/status-dot online? blur?)}]
[text/text
{:size :paragraph-2
:style (style/color blur? theme)}
(if online? (i18n/label :t/online-now) text)]]))
(defn text-description
[{:keys [description-props blur? theme]}]
(let [{:keys [text icon]} description-props]
[rn/view
{:style style/sub-container}
[text/text
{:size :paragraph-2
:style (style/color blur? theme)}
text]
(when icon
[icon/icon icon
(merge (style/color blur? theme)
{:size 16
:container-style {:margin-left 4}})])]))
(defn description-component
[{:keys [description] :as props}]
(case description
:text [text-description props]
:text-plus-icon [text-description props]
:status [status-description props]
nil))
(defn image-component
[{:keys [image image-props description tag blur? theme]}]
[rn/view
{:style (style/image-container description tag image)}
(case image
:icon [icon/icon image-props (style/color blur? theme)]
:avatar [user-avatar/user-avatar image-props]
:icon-avatar [icon-avatar/icon-avatar image-props]
nil)])
(defn tag-component
[{:keys [tag tag-props]}]
(case tag
:positive [status-tags/status-tag
{:status {:type :positive}
:label (i18n/label :t/positive)
:size :small
:container-style {:margin-top 8}}]
:context [context-tag/view
(merge tag-props
{:type :icon
:size 24
:container-style {:margin-top 8
:align-self :flex-start}})]
nil))
(defn label-component
[{:keys [label label-props blur? theme]}]
[rn/view {:accessibility-label :label-component}
(case label
:text [text/text
{:style (style/color blur? theme)}
label-props]
:color [rn/view
{:style (style/label-dot label-props)}]
:preview [preview-list/view {:type (:type label-props)} (:data label-props)]
nil)])
(defn action-component
[{:keys [action action-props blur? theme]}]
[rn/view {:style {:margin-left 12}}
(case action
:arrow [icon/icon :i/chevron-right (style/color blur? theme)]
:button [button/button
{:type :outline
:size 24
:on-press (:on-press action-props)}
(:button-text action-props)]
:selector [selectors/toggle action-props]
nil)])
(defn- internal-view
[{:keys [title on-press accessibility-label] :as props}]
[rn/pressable
{:style (style/container props)
:on-press on-press
:accessibility-label accessibility-label}
[rn/view {:style style/sub-container}
[image-component props]
[rn/view {:style style/left-container}
[text/text {:weight :medium} title]
[description-component props]
[tag-component props]]]
[rn/view {:style style/sub-container}
[label-component props]
[action-component props]]])
(def view (quo.theme/with-theme internal-view))
@@ -0,0 +1,58 @@
(ns quo2.components.settings.settings-list.component-spec
(:require [quo2.components.settings.settings-list.view :as settings-list]
[test-helpers.component :as h]))
(h/describe "Settings list tests"
(h/test "Default render of Setting list component"
(h/render [settings-list/settings-list {:accessibility-label "test"}])
(h/is-truthy (h/get-by-label-text :test)))
(h/test "It renders a title"
(h/render [settings-list/settings-list {:title "test"}])
(h/is-truthy (h/get-by-text "test")))
(h/test "its gets passed an on press event"
(let [event (h/mock-fn)]
(h/render [settings-list/settings-list
{:title "test"
:on-press event}])
(h/fire-event :press (h/get-by-text "test"))
(h/was-called event)))
(h/test "on change event gets fired for toggle"
(let [on-change (h/mock-fn)]
(h/render [settings-list/settings-list
{:title "test"
:toggle-props {:on-change on-change}}])
(h/fire-event :press (h/get-by-label-text :toggle-off))
(h/was-called on-change)))
(h/test "It renders a badge"
(h/render [settings-list/settings-list {:badge? true}])
(h/is-truthy (h/get-by-label-text :setting-list-badge)))
(h/test "It renders a status tag component"
(h/render [settings-list/settings-list
{:status-tag-props
{:size :small
:status {:type :positive}
:label "test tag"}}])
(h/is-truthy (h/get-by-text "test tag")))
(h/test "on press event gets fired for button"
(let [event (h/mock-fn)]
(h/render [settings-list/settings-list
{:button-props {:title "test button"
:on-press event}}])
(h/fire-event :press (h/get-by-text "test button"))
(h/was-called event)))
(h/test "It renders a list of community icons"
(h/render [settings-list/settings-list
{:communities-props {:data
[{:source "1"
:accessibility-label :community-1}
{:source "2"
:accessibility-label :community-2}]}}])
(h/is-truthy (h/get-by-label-text :community-1))
(h/is-truthy (h/get-by-label-text :community-2))))
@@ -52,5 +52,4 @@
:margin-right 12})
(def tag-container
{:margin-top 8
:margin-left -1})
{:margin-top 8})
@@ -0,0 +1,135 @@
(ns quo2.components.settings.settings-list.view
(:require [quo2.components.settings.settings-list.style :as style]
[quo2.components.icon :as icons]
[quo2.components.selectors.selectors.view :as selectors]
[quo2.components.buttons.button.view :as button]
[quo2.components.markdown.text :as text]
[quo2.components.tags.status-tags :as status-tag]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
(defn settings-title
[title status-tag-props override-theme]
[rn/view
{:style style/title-container}
(when title
[text/text
{:accessibility-label :setting-item-name-text
:ellipsize-mode :tail
:style (style/title override-theme)
:override-theme override-theme
:number-of-lines 1
:weight :medium
:size :paragraph-1}
title])
(when status-tag-props
[rn/view {:style style/tag-container}
[status-tag/status-tag
status-tag-props]])])
(defn left-icon-comp
[icon]
[rn/view {:style style/icon}
[icons/icon icon
{:color (colors/theme-colors
colors/neutral-50
colors/neutral-40)}]])
(def chevron-icon
[rn/view
[icons/icon :chevron-right
{:color (colors/theme-colors
colors/neutral-50
colors/neutral-40)}]])
(defn toggle-button
[{:keys [checked?
on-change]}]
[selectors/toggle
{:checked? checked?
:on-change (fn [new-value] (on-change new-value))}])
(defn badge-icon
[override-theme]
[rn/view
{:accessible :true
:accessibility-label :setting-list-badge
:style (style/dot override-theme)}])
(defn right-button
[{:keys [title
on-press]}]
[button/button
{:type :outline
:on-press on-press
:size 24}
title])
(defn communities-icons
[{:keys [data
icon-style]}
override-theme]
(let [communities-count (dec (count data))]
[rn/view
{:style style/communities-container}
(map-indexed
(fn [index {:keys [source accessibility-label]}]
[rn/image
{:key source
:source (if (string? source)
{:uri source}
source)
:accessibility-label accessibility-label
:style (merge (style/community-icon (- communities-count index) override-theme)
icon-style)}])
data)]))
(defn settings-list
"Options
- `title` String to show in the center of the component, right to the icon and left to optional gadgets.
- `on-press` Callback called when the component is pressed.
- `accessibility-label` String to use as accessibility-label for VoiceOver.
- `left-icon` icon keyword for icon on left.
- `chevron?` Boolean to show/hide chevron at the right border of the component.
- `toggle-prop` Map with the following keys:
`checked?` Boolean value to set check or unchecked toggle.
`on-change` Callback called when user toggles toggle. Will pass the new toggle value to the callback
- `badge?` Boolean to show/hide badge.
- `button-props` Map with the following keys:
`title` String to show as button text.
`on-press` Callback called when button is pressed.
- `communities-props` Map with the following keys:
`data` Array of maps containg source of the community asset.
- `style` Styles map to be merge with default container styles.
- `overide-theme` :dark or :light
- `status-tag-props see the spec for status-tag component
"
[{:keys [title
on-press
accessibility-label
left-icon
chevron?
toggle-props
badge?
button-props
communities-props
container-style
override-theme
status-tag-props]}]
[rn/touchable-without-feedback
{:on-press on-press
:accessibility-label accessibility-label}
[rn/view
{:style (merge style/item-container container-style)}
[rn/view {:style style/inner-container}
(when left-icon
[left-icon-comp left-icon])
[settings-title title status-tag-props override-theme]
(when toggle-props
[toggle-button toggle-props])
(when badge? [badge-icon override-theme])
(when button-props
[right-button button-props])
(when communities-props (communities-icons communities-props override-theme))
(when chevron? chevron-icon)]]])
@@ -28,6 +28,10 @@
:background-color background-color
:border-radius 12})
(def account-emoji
{:height 16
:width 16})
(def account-avatar-container
{:margin-left 4
:margin-right 8})
+3 -3
View File
@@ -3,7 +3,7 @@
[quo2.components.markdown.text :as text]
[quo2.components.common.notification-dot.view :as notification-dot]
[quo2.components.tabs.tab.style :as style]
[quo2.theme :as quo.theme]
[quo2.theme :as theme]
[react-native.core :as rn]
[react-native.svg :as svg]))
@@ -47,7 +47,7 @@
(vector? children)
children)])
(defn- view-internal
(defn- themed-view
[{:keys [accessibility-label
active
before
@@ -104,4 +104,4 @@
:disabled disabled
:background-color background-color}])]]))
(def view (quo.theme/with-theme view-internal))
(def view (theme/with-theme themed-view))
+20 -19
View File
@@ -21,7 +21,7 @@
;; Truncate to avoid unnecessary rendering.
(if (> fade-percentage 0.99)
0.99
max-fade-percentage)))
(utils.number/naive-round fade-percentage 2))))
(defn- masked-view-wrapper
[{:keys [fade-end-percentage fade-end?]} & children]
@@ -59,10 +59,8 @@
(when on-scroll
(on-scroll e)))
(defn- tab-view
[{:keys [id label notification-dot? accessibility-label]}
index _
{:keys [active-tab-id
(defn- render-tab
[{:keys [active-tab-id
blur?
customization-color
flat-list-ref
@@ -70,8 +68,9 @@
on-change
scroll-on-press?
size
style
]}]
style]}
{:keys [id label notification-dot? accessibility-label]}
index]
[rn/view
{:style (style/tab {:size size
:default-tab-size default-tab-size
@@ -167,6 +166,7 @@
;; just one about this topic:
;; https://github.com/facebook/react-native/issues/31218
:content-container-style {:padding-top (dec unread-count-offset)}
:extra-data (str @active-tab-id)
:horizontal true
:scroll-event-throttle 64
:shows-horizontal-scroll-indicator false
@@ -178,20 +178,20 @@
:fade-end? fade-end?
:fading fading
:on-scroll on-scroll})
:render-fn tab-view
:render-data {:active-tab-id active-tab-id
:blur? blur?
:customization-color customization-color
:flat-list-ref flat-list-ref
:number-of-items (count data)
:on-change on-change
:scroll-on-press? scroll-on-press?
:size size
:style style}})]]]
:render-fn (partial render-tab
{:active-tab-id active-tab-id
:blur? blur?
:customization-color customization-color
:flat-list-ref flat-list-ref
:number-of-items (count data)
:on-change on-change
:scroll-on-press? scroll-on-press?
:size size
:style style})})]]]
[rn/view (merge style {:flex-direction :row})
(map-indexed (fn [index item]
^{:key (:id item)}
[tab-view item index nil
[render-tab
{:active-tab-id active-tab-id
:blur? blur?
:customization-color customization-color
@@ -199,5 +199,6 @@
:on-change on-change
:size size
:style style}
])
item
index])
data)]))))
+8 -10
View File
@@ -73,19 +73,18 @@
(defn- view-internal
[{:keys [theme type size state blur? customization-color profile-picture full-name users
group-name token-logo amount token-name network-logo network-name networks
account-name emoji collectible collectible-name collectible-number duration container-style]
account-name emoji collectible collectible-name collectible-number duration]
:or {customization-color :blue
type :default
state :default}
:as props}]
[rn/view
{:style (merge (style/container {:theme theme
:type type
:size size
:state state
:blur? blur?
:customization-color customization-color})
container-style)}
{:style (style/container {:theme theme
:type type
:size size
:state state
:blur? blur?
:customization-color customization-color})}
(case type
:default
[tag-skeleton {:theme theme :size size :text full-name}
@@ -93,8 +92,7 @@
{:full-name full-name
:profile-picture profile-picture
:size (if (= size 24) :xxs 28)
:status-indicator? false
:ring? false}]]
:status-indicator? false}]]
:multiuser
[preview-list/view {:type :user :size 20}
@@ -1,19 +0,0 @@
(ns quo2.components.tags.network-tags.component-spec
(:require [quo2.components.tags.network-tags.view :as network-tags]
[test-helpers.component :as h]))
(h/describe "network-tags component"
(h/test "renders network tags with single network"
(h/render [network-tags/view
{:title "Network Tags"
:networks [{:source "network-icon.png"}]}])
(h/is-truthy (h/get-by-text "Network Tags")))
(h/test "renders network tags with multiple networks"
(h/render [network-tags/view
{:title "Multiple Networks"
:networks [{:source "network-icon1.png"}
{:source "network-icon2.png"}
{:source "network-icon3.png"}]
:size :size/s-32}])
(h/is-truthy (h/get-by-text "Multiple Networks"))))
@@ -1,41 +0,0 @@
(ns quo2.components.tags.network-tags.style
(:require [quo2.foundations.colors :as colors]))
(defn container
[{:keys [status theme blur?]}]
{:flex-direction :row
:align-self :flex-start
:background-color (when (= status :error)
(colors/theme-colors
(colors/custom-color :danger 50 10)
(colors/custom-color :danger 60 10)
theme))
:border-width 1
:border-color (cond (= status :error)
(colors/theme-colors
(colors/custom-color :danger 50 20)
(colors/custom-color :danger 60 20)
theme)
(and blur? (= status :default)) (colors/theme-colors
colors/neutral-80-opa-5
colors/white-opa-5
theme)
:else (colors/theme-colors
colors/neutral-20
colors/neutral-80
theme))
:border-radius 8
:padding-left 5
:padding-right 5
:padding-top 3
:padding-bottom 2})
(defn title-style
[{:keys [status theme]}]
{:padding-left 4
:margin-top -1
:color (when (= status :error)
(colors/theme-colors
(colors/custom-color :danger 50)
(colors/custom-color :danger 60)
theme))})
@@ -1,25 +0,0 @@
(ns quo2.components.tags.network-tags.view
(:require [quo2.components.list-items.preview-list.view :as preview-list]
[quo2.components.tags.network-tags.style :as style]
[quo2.components.markdown.text :as text]
[react-native.core :as rn]
[quo2.theme :as quo.theme]))
(defn- view-internal
[{:keys [title networks status theme blur?] :or {status :default}}]
[rn/view
{:style (style/container {:status status
:theme theme
:blur? blur?})}
[preview-list/view
{:type :network
:number (count networks)
:size :size/s-16} networks]
[text/text
{:weight :medium
:size :paragraph-2
:style (style/title-style {:status status
:theme theme})}
title]])
(def view (quo.theme/with-theme view-internal))
@@ -1,20 +0,0 @@
(ns quo2.components.tags.number-tag.component-spec
(:require [quo2.components.tags.number-tag.view :as number-tag]
[test-helpers.component :as h]))
(h/describe
"number tag component test"
(h/test "+3 render"
(h/render [number-tag/view
{:type :rounded
:number "3"
:size :size/s-32
:blur? false}])
(h/is-truthy (h/get-by-text "+3")))
(h/test "+48 render"
(h/render [number-tag/view
{:type :squared
:number "48"
:size :size/s-24
:blur? true}])
(h/is-truthy (h/get-by-text "+48"))))

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