Compare commits
36
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55d879bcd8 | ||
|
|
08fa0e6db9 | ||
|
|
a141c75634 | ||
|
|
2325f6f59e | ||
|
|
a93a3b6878 | ||
|
|
430f322f95 | ||
|
|
707cf82b8b | ||
|
|
cbba1372b3 | ||
|
|
51174f8488 | ||
|
|
cc2b6ab80c | ||
|
|
beeb72a9d5 | ||
|
|
789b24e3a4 | ||
|
|
f64a62e82d | ||
|
|
9bcbb580e1 | ||
|
|
aa71b830bc | ||
|
|
6dd1577b8a | ||
|
|
785386987b | ||
|
|
ef8a7f3fd8 | ||
|
|
366f235e31 | ||
|
|
fe7a23b7f6 | ||
|
|
5b7d0f81d4 | ||
|
|
b18547c16e | ||
|
|
f402f67b09 | ||
|
|
12437e6b7c | ||
|
|
b3a74ad7a5 | ||
|
|
7bf77efc87 | ||
|
|
8ed1797f44 | ||
|
|
117810cf44 | ||
|
|
e2fabd2386 | ||
|
|
5d9a29b3c8 | ||
|
|
bcf3e3205a | ||
|
|
8820f458c9 | ||
|
|
91f444ba80 | ||
|
|
3f4a424169 | ||
|
|
bc91512b71 | ||
|
|
a4b169efa3 |
@@ -31,4 +31,4 @@ COMMUNITIES_ENABLED=1
|
||||
COMMUNITIES_MANAGEMENT_ENABLED=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
STICKERS_TEST_ENABLED=1
|
||||
STICKERS_TEST_ENABLED=1
|
||||
|
||||
+1
-1
@@ -33,4 +33,4 @@ COMMUNITIES_MANAGEMENT_ENABLED=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
ENABLE_QUO_PREVIEW=1
|
||||
STICKERS_TEST_ENABLED=1
|
||||
STICKERS_TEST_ENABLED=1
|
||||
|
||||
@@ -12,6 +12,7 @@ PFS_TOGGLE_VISIBLE=1
|
||||
POW_TARGET=0.002
|
||||
POW_TIME=1
|
||||
SNOOPY=0
|
||||
KEYCARD_TEST_MENU=0
|
||||
RPC_NETWORKS_ONLY=0
|
||||
PARTITIONED_TOPIC=0
|
||||
CONTRACT_NODES=1
|
||||
|
||||
@@ -12,6 +12,7 @@ PFS_TOGGLE_VISIBLE=0
|
||||
POW_TARGET=0.002
|
||||
POW_TIME=1
|
||||
SNOOPY=0
|
||||
KEYCARD_TEST_MENU=0
|
||||
RPC_NETWORKS_ONLY=1
|
||||
PARTITIONED_TOPIC=0
|
||||
ENABLE_ROOT_ALERT=1
|
||||
|
||||
@@ -200,7 +200,6 @@ build-fdroid: export ANDROID_ABI_INCLUDE = armeabi-v7a;arm64-v8a;x86;x86_64
|
||||
build-fdroid: ##@build Build release for F-Droid
|
||||
@scripts/build-android.sh
|
||||
|
||||
build-android: SHELL := /bin/sh
|
||||
build-android: export BUILD_ENV ?= prod
|
||||
build-android: export BUILD_TYPE ?= nightly
|
||||
build-android: export BUILD_NUMBER ?= $(TMP_BUILD_NUMBER)
|
||||
@@ -294,6 +293,16 @@ lint-fix: export TARGET := clojure
|
||||
lint-fix: ##@test Run code style checks and fix issues
|
||||
clojure -Scp "$$CLASS_PATH" -m cljfmt.main fix src --indents indentation.edn
|
||||
|
||||
shadow-server: export TARGET := clojure
|
||||
shadow-server:##@ Start shadow-cljs in server mode for watching
|
||||
yarn shadow-cljs server
|
||||
|
||||
test-watch: export TARGET := clojure
|
||||
test-watch: status-go-library
|
||||
test-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||
yarn install
|
||||
nodemon --exec 'yarn shadow-cljs compile mocks && yarn shadow-cljs compile test && node --require ./test-resources/override.js target/test/test.js' -e cljs
|
||||
|
||||
test: export TARGET := clojure
|
||||
test: status-go-library ##@test Run tests once in NodeJS
|
||||
# Here we creates the gyp bindings for nodejs
|
||||
@@ -302,6 +311,7 @@ test: status-go-library ##@test Run tests once in NodeJS
|
||||
yarn shadow-cljs compile test && \
|
||||
node --require ./test-resources/override.js target/test/test.js
|
||||
|
||||
|
||||
coverage: ##@test Run tests once in NodeJS generating coverage
|
||||
@scripts/run-coverage.sh
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="alert_background">#141414</color>
|
||||
<color name="alert_text">#ffffff</color>
|
||||
<color name="alert_background">#141414</color>
|
||||
<color name="alert_text">#ffffff</color>
|
||||
</resources>
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
</style>
|
||||
|
||||
<style name="AlertDialogTheme" parent="Theme.AppCompat.DayNight.Dialog.Alert">
|
||||
<item name="android:textColor">@color/alert_text</item>
|
||||
<item name="android:textColorPrimary">@color/alert_text</item>
|
||||
<item name="android:background">@color/alert_background</item>
|
||||
<item name="android:textColor">@color/alert_text</item>
|
||||
<item name="android:textColorPrimary">@color/alert_text</item>
|
||||
<item name="android:background">@color/alert_background</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Testing
|
||||
|
||||
### Unit & integration tests
|
||||
|
||||
To run tests:
|
||||
|
||||
```
|
||||
make test
|
||||
```
|
||||
|
||||
|
||||
To watch the tests:
|
||||
|
||||
```
|
||||
make test-watch
|
||||
```
|
||||
|
||||
|
||||
Tests will use the bindings in `modules/react-native-status/nodejs`, if you make any changes to these you will need to restart the watcher.
|
||||
+29
-5
@@ -370,6 +370,18 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void loginWithConfig(final String accountData, final String password, final String configJSON) {
|
||||
Log.d(TAG, "loginWithConfig");
|
||||
this.migrateKeyStoreDir(accountData, password);
|
||||
String result = Statusgo.loginWithConfig(accountData, password, configJSON);
|
||||
if (result.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "LoginWithConfig result: " + result);
|
||||
} else {
|
||||
Log.e(TAG, "LoginWithConfig failed: " + result);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void exportUnencryptedDatabase(final String accountData, final String password, final Callback callback) {
|
||||
Log.d(TAG, "login");
|
||||
@@ -403,12 +415,24 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
@ReactMethod
|
||||
public void logout() {
|
||||
Log.d(TAG, "logout");
|
||||
String result = Statusgo.logout();
|
||||
if (result.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "Logout result: " + result);
|
||||
} else {
|
||||
Log.e(TAG, "Logout failed: " + result);
|
||||
if (!checkAvailability()) {
|
||||
System.exit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String result = Statusgo.logout();
|
||||
if (result.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "Logout result: " + result);
|
||||
} else {
|
||||
Log.e(TAG, "Logout failed: " + result);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
StatusThreadPoolExecutor.getInstance().execute(r);
|
||||
}
|
||||
|
||||
private void deleteDirectory(File folder) {
|
||||
|
||||
+1
-1
@@ -126,7 +126,7 @@ public class PushNotification extends ReactContextBaseJavaModule implements Acti
|
||||
|
||||
@ReactMethod
|
||||
public void clearAllMessageNotifications() {
|
||||
pushNotificationHelper.clearAllMessageNotifications();
|
||||
pushNotificationHelper.clearAllMessageNotifications();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
|
||||
+1
-1
@@ -200,7 +200,7 @@ public class PushNotificationHelper {
|
||||
}
|
||||
|
||||
public void clearAllMessageNotifications() {
|
||||
notificationManager.cancelAll();
|
||||
notificationManager.cancelAll();
|
||||
}
|
||||
|
||||
public void sendToNotificationCentreWithPicture(final Bundle bundle, Bitmap largeIconBitmap, Bitmap bigPictureBitmap) {
|
||||
|
||||
@@ -542,6 +542,19 @@ RCT_EXPORT_METHOD(login:(NSString *)accountData
|
||||
NSLog(@"%@", result);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////// loginWithConfig
|
||||
RCT_EXPORT_METHOD(loginWithConfig:(NSString *)accountData
|
||||
password:(NSString *)password
|
||||
configJSON:(NSString *)configJSON) {
|
||||
#if DEBUG
|
||||
NSLog(@"LoginWithConfig() method called");
|
||||
#endif
|
||||
[self getExportDbFilePath];
|
||||
[self migrateKeystore:accountData password:password];
|
||||
NSString *result = StatusgoLoginWithConfig(accountData, password, configJSON);
|
||||
NSLog(@"%@", result);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////// loginWithKeycard
|
||||
RCT_EXPORT_METHOD(loginWithKeycard:(NSString *)accountData
|
||||
password:(NSString *)password
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// https://github.com/divan/go2nodebinding
|
||||
|
||||
#include <node.h>
|
||||
#include <string>
|
||||
#include <queue>
|
||||
|
||||
#include "../../../result/libstatus.h"
|
||||
|
||||
@@ -833,39 +835,39 @@ Isolate* runCallbackIsolate;
|
||||
|
||||
Persistent<Function> r_call;
|
||||
|
||||
void run(char *json) {
|
||||
printf("%s\n", json);
|
||||
if(!r_call.IsEmpty()) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
v8::Local<v8::Function> func = v8::Local<v8::Function>::New(isolate, r_call);
|
||||
std::queue<std::string> q;
|
||||
|
||||
if (!func.IsEmpty()) {
|
||||
const unsigned argc = 1;
|
||||
v8::Local<v8::Value> argv[argc] =
|
||||
{ v8::String::NewFromUtf8Literal(isolate, "hello world") };
|
||||
func->Call(context, v8::Null(isolate), argc, argv);
|
||||
}
|
||||
}
|
||||
void run(char *json) {
|
||||
printf("signal received %s\n", json);
|
||||
|
||||
std::string str(json);
|
||||
q.push(str);
|
||||
}
|
||||
|
||||
|
||||
void _SetSignalEventCallback(const FunctionCallbackInfo<Value>& args) {
|
||||
// Poll signals and process queue, one at a time
|
||||
void _PollSignal(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
|
||||
if (args.Length() != 1) {
|
||||
// Throw an Error that is passed back to JavaScript
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for StartCPUProfile")));
|
||||
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for SetSignalEventCallback")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(args[0]);
|
||||
//v8::Function * ptr = *func;
|
||||
r_call.Reset(isolate, func);
|
||||
if (!q.empty()) {
|
||||
const unsigned argc = 1;
|
||||
v8::Local<v8::Value> argv[argc] =
|
||||
{ v8::String::NewFromUtf8(isolate,q.front().c_str()).ToLocalChecked()};
|
||||
|
||||
func->Call(isolate->GetCurrentContext(), v8::Null(isolate), argc, argv);
|
||||
q.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void _SetSignalEventCallback(const FunctionCallbackInfo<Value>& args) {
|
||||
SetSignalEventCallback((void *)&run);
|
||||
}
|
||||
|
||||
@@ -1569,51 +1571,51 @@ void _ConnectionChange(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
|
||||
void init(Local<Object> exports) {
|
||||
NODE_SET_METHOD(exports, "MultiAccountGenerateAndDeriveAddresses", _MultiAccountGenerateAndDeriveAddresses);
|
||||
NODE_SET_METHOD(exports, "MultiAccountImportPrivateKey", _MultiAccountImportPrivateKey);
|
||||
NODE_SET_METHOD(exports, "MultiAccountLoadAccount", _MultiAccountLoadAccount);
|
||||
NODE_SET_METHOD(exports, "MultiAccountReset", _MultiAccountReset);
|
||||
NODE_SET_METHOD(exports, "MultiAccountDeriveAddresses", _MultiAccountDeriveAddresses);
|
||||
NODE_SET_METHOD(exports, "MultiAccountImportMnemonic", _MultiAccountImportMnemonic);
|
||||
NODE_SET_METHOD(exports, "MultiAccountGenerate", _MultiAccountGenerate);
|
||||
NODE_SET_METHOD(exports, "MultiAccountStoreDerivedAccounts", _MultiAccountStoreDerivedAccounts);
|
||||
NODE_SET_METHOD(exports, "MultiAccountStoreAccount", _MultiAccountStoreAccount);
|
||||
NODE_SET_METHOD(exports, "InitKeystore", _InitKeystore);
|
||||
NODE_SET_METHOD(exports, "StopCPUProfiling", _StopCPUProfiling);
|
||||
NODE_SET_METHOD(exports, "multiAccountGenerateAndDeriveAddresses", _MultiAccountGenerateAndDeriveAddresses);
|
||||
NODE_SET_METHOD(exports, "multiAccountImportPrivateKey", _MultiAccountImportPrivateKey);
|
||||
NODE_SET_METHOD(exports, "multiAccountLoadAccount", _MultiAccountLoadAccount);
|
||||
NODE_SET_METHOD(exports, "multiAccountReset", _MultiAccountReset);
|
||||
NODE_SET_METHOD(exports, "multiAccountDeriveAddresses", _MultiAccountDeriveAddresses);
|
||||
NODE_SET_METHOD(exports, "multiAccountImportMnemonic", _MultiAccountImportMnemonic);
|
||||
NODE_SET_METHOD(exports, "multiAccountGenerate", _MultiAccountGenerate);
|
||||
NODE_SET_METHOD(exports, "multiAccountStoreDerivedAccounts", _MultiAccountStoreDerivedAccounts);
|
||||
NODE_SET_METHOD(exports, "multiAccountStoreAccount", _MultiAccountStoreAccount);
|
||||
NODE_SET_METHOD(exports, "initKeystore", _InitKeystore);
|
||||
NODE_SET_METHOD(exports, "stopCPUProfiling", _StopCPUProfiling);
|
||||
NODE_SET_METHOD(exports, "identicon", _Identicon);
|
||||
NODE_SET_METHOD(exports, "Logout", _Logout);
|
||||
NODE_SET_METHOD(exports, "HashMessage", _HashMessage);
|
||||
NODE_SET_METHOD(exports, "ResetChainData", _ResetChainData);
|
||||
NODE_SET_METHOD(exports, "SaveAccountAndLogin", _SaveAccountAndLogin);
|
||||
NODE_SET_METHOD(exports, "GenerateAlias", _GenerateAlias);
|
||||
NODE_SET_METHOD(exports, "ValidateMnemonic", _ValidateMnemonic);
|
||||
NODE_SET_METHOD(exports, "MultiformatSerializePublicKey", _MultiformatSerializePublicKey);
|
||||
NODE_SET_METHOD(exports, "SaveAccountAndLoginWithKeycard", _SaveAccountAndLoginWithKeycard);
|
||||
NODE_SET_METHOD(exports, "LoginWithKeycard", _LoginWithKeycard);
|
||||
NODE_SET_METHOD(exports, "MultiformatDeserializePublicKey", _MultiformatDeserializePublicKey);
|
||||
NODE_SET_METHOD(exports, "Login", _Login);
|
||||
NODE_SET_METHOD(exports, "StartCPUProfile", _StartCPUProfile);
|
||||
NODE_SET_METHOD(exports, "OpenAccounts", _OpenAccounts);
|
||||
NODE_SET_METHOD(exports, "ExtractGroupMembershipSignatures", _ExtractGroupMembershipSignatures);
|
||||
NODE_SET_METHOD(exports, "CallPrivateRPC", _CallPrivateRPC);
|
||||
NODE_SET_METHOD(exports, "VerifyAccountPassword", _VerifyAccountPassword);
|
||||
NODE_SET_METHOD(exports, "SendTransactionWithSignature", _SendTransactionWithSignature);
|
||||
NODE_SET_METHOD(exports, "WriteHeapProfile", _WriteHeapProfile);
|
||||
NODE_SET_METHOD(exports, "AddPeer", _AddPeer);
|
||||
NODE_SET_METHOD(exports, "SignHash", _SignHash);
|
||||
NODE_SET_METHOD(exports, "SignGroupMembership", _SignGroupMembership);
|
||||
NODE_SET_METHOD(exports, "CallRPC", _CallRPC);
|
||||
NODE_SET_METHOD(exports, "SignMessage", _SignMessage);
|
||||
NODE_SET_METHOD(exports, "SignTypedData", _SignTypedData);
|
||||
NODE_SET_METHOD(exports, "SendTransaction", _SendTransaction);
|
||||
NODE_SET_METHOD(exports, "AppStateChange", _AppStateChange);
|
||||
NODE_SET_METHOD(exports, "SetSignalEventCallback", _SetSignalEventCallback);
|
||||
NODE_SET_METHOD(exports, "ValidateNodeConfig", _ValidateNodeConfig);
|
||||
NODE_SET_METHOD(exports, "HashTypedData", _HashTypedData);
|
||||
NODE_SET_METHOD(exports, "Recover", _Recover);
|
||||
NODE_SET_METHOD(exports, "HashTransaction", _HashTransaction);
|
||||
NODE_SET_METHOD(exports, "ConnectionChange", _ConnectionChange);
|
||||
|
||||
NODE_SET_METHOD(exports, "logout", _Logout);
|
||||
NODE_SET_METHOD(exports, "hashMessage", _HashMessage);
|
||||
NODE_SET_METHOD(exports, "resetChainData", _ResetChainData);
|
||||
NODE_SET_METHOD(exports, "saveAccountAndLogin", _SaveAccountAndLogin);
|
||||
NODE_SET_METHOD(exports, "generateAlias", _GenerateAlias);
|
||||
NODE_SET_METHOD(exports, "validateMnemonic", _ValidateMnemonic);
|
||||
NODE_SET_METHOD(exports, "multiformatSerializePublicKey", _MultiformatSerializePublicKey);
|
||||
NODE_SET_METHOD(exports, "saveAccountAndLoginWithKeycard", _SaveAccountAndLoginWithKeycard);
|
||||
NODE_SET_METHOD(exports, "loginWithKeycard", _LoginWithKeycard);
|
||||
NODE_SET_METHOD(exports, "multiformatDeserializePublicKey", _MultiformatDeserializePublicKey);
|
||||
NODE_SET_METHOD(exports, "login", _Login);
|
||||
NODE_SET_METHOD(exports, "startCPUProfile", _StartCPUProfile);
|
||||
NODE_SET_METHOD(exports, "openAccounts", _OpenAccounts);
|
||||
NODE_SET_METHOD(exports, "extractGroupMembershipSignatures", _ExtractGroupMembershipSignatures);
|
||||
NODE_SET_METHOD(exports, "callPrivateRPC", _CallPrivateRPC);
|
||||
NODE_SET_METHOD(exports, "verifyAccountPassword", _VerifyAccountPassword);
|
||||
NODE_SET_METHOD(exports, "sendTransactionWithSignature", _SendTransactionWithSignature);
|
||||
NODE_SET_METHOD(exports, "writeHeapProfile", _WriteHeapProfile);
|
||||
NODE_SET_METHOD(exports, "addPeer", _AddPeer);
|
||||
NODE_SET_METHOD(exports, "signHash", _SignHash);
|
||||
NODE_SET_METHOD(exports, "signGroupMembership", _SignGroupMembership);
|
||||
NODE_SET_METHOD(exports, "callRPC", _CallRPC);
|
||||
NODE_SET_METHOD(exports, "signMessage", _SignMessage);
|
||||
NODE_SET_METHOD(exports, "signTypedData", _SignTypedData);
|
||||
NODE_SET_METHOD(exports, "sendTransaction", _SendTransaction);
|
||||
NODE_SET_METHOD(exports, "appStateChange", _AppStateChange);
|
||||
NODE_SET_METHOD(exports, "setSignalEventCallback", _SetSignalEventCallback);
|
||||
NODE_SET_METHOD(exports, "validateNodeConfig", _ValidateNodeConfig);
|
||||
NODE_SET_METHOD(exports, "hashTypedData", _HashTypedData);
|
||||
NODE_SET_METHOD(exports, "recover", _Recover);
|
||||
NODE_SET_METHOD(exports, "hashTransaction", _HashTransaction);
|
||||
NODE_SET_METHOD(exports, "connectionChange", _ConnectionChange);
|
||||
NODE_SET_METHOD(exports, "pollSignal", _PollSignal);
|
||||
}
|
||||
|
||||
NODE_MODULE(NODE_GYP_MODULE_NAME, init)
|
||||
|
||||
+10
-12
@@ -45,7 +45,7 @@ One dependency these scripts require is the [go-maven-resolver](https://github.c
|
||||
|
||||
# Known Issues
|
||||
|
||||
One edge case that is currently not handled by this setup is an addition of a new dependency that requires a version of Gradle we don't have. In that case running `make nix-update-gradle` would fail with:
|
||||
One edge case that is currently not automatically handled by this setup is an addition of a new dependency that requires a version of Gradle we don't have. In that case running `make nix-update-gradle` would fail with:
|
||||
```
|
||||
AILURE: Build failed with an exception.
|
||||
|
||||
@@ -61,16 +61,14 @@ A problem occurred configuring project ':react-native-example-project'.
|
||||
```
|
||||
This happens because `get_projects.sh` and `get_deps.sh` depend on running Gradle to generate their output, and that will not work because Gradle cannot find the matching JAR for the new dependency.
|
||||
|
||||
A manual solution would involve adding that specific Gradle version into `deps.urls`:
|
||||
You can use the `add_package.sh` script to add missing Gradle dependencies:
|
||||
```
|
||||
echo com.android.tools.build:gradle:3.4.0 | go-maven-resolver >> nix/deps/gradle/deps.urls
|
||||
> make shell TARGET=gradle
|
||||
Configuring Nix shell for target 'gradle'...
|
||||
|
||||
[nix-shell:~/status-react]$ nix/deps/gradle/add_package.sh com.android.tools.build:gradle:3.4.0
|
||||
Regenerating Nix files...
|
||||
Found 548 direct dependencies...
|
||||
Successfully added: com.android.tools.build:gradle:3.4.0
|
||||
```
|
||||
Then you'll need to remove duplicates and sort `deps.urls`:
|
||||
```
|
||||
sort -uo nix/deps/gradle/deps.urls nix/deps/gradle/deps.urls
|
||||
```
|
||||
And finally generate the `deps.json` for Nix using:
|
||||
```
|
||||
nix/deps/gradle/generate.sh gen_deps_json
|
||||
```
|
||||
After run `make nix-update-gradle` and it should work just fine.
|
||||
This may take a bit longer than normal `make nix-update-gradle` but should add the missing package.
|
||||
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -Eeu
|
||||
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "Usage: add_package.sh <package>" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! command -v go-maven-resolver &> /dev/null; then
|
||||
echo "Use 'make shell TARGET=gradle' for this script" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
|
||||
source "${GIT_ROOT}/scripts/colors.sh"
|
||||
|
||||
# Add missing package to dependencies.
|
||||
echo "${1}" | go-maven-resolver >> nix/deps/gradle/deps.urls
|
||||
|
||||
# Remove duplicates and sort.
|
||||
sort -uo nix/deps/gradle/deps.urls nix/deps/gradle/deps.urls
|
||||
|
||||
# Re-generate dependencies JSON.
|
||||
${GIT_ROOT}/nix/deps/gradle/generate.sh gen_deps_json
|
||||
|
||||
# Re-generate dependencies list.
|
||||
${GIT_ROOT}/nix/deps/gradle/generate.sh gen_deps_list
|
||||
|
||||
echo -e "${GRN}Successfully added:${RST} ${BLD}${1}${RST}" >&2
|
||||
@@ -14,10 +14,9 @@ fi
|
||||
# required to build the project
|
||||
|
||||
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
|
||||
THIS_SCRIPT=$(realpath --relative-to="${GIT_ROOT}" ${BASH_SOURCE})
|
||||
CUR_DIR=$(cd "${BASH_SOURCE%/*}" && pwd)
|
||||
source "${GIT_ROOT}/scripts/colors.sh"
|
||||
|
||||
CUR_DIR=$(cd "${BASH_SOURCE%/*}" && pwd)
|
||||
PROJ_LIST="${CUR_DIR}/proj.list"
|
||||
DEPS_LIST="${CUR_DIR}/deps.list"
|
||||
DEPS_URLS="${CUR_DIR}/deps.urls"
|
||||
|
||||
@@ -51,10 +51,6 @@ let
|
||||
{ path = "${absPath}/ios/subfile"; type = "file";
|
||||
expected = false; }
|
||||
];
|
||||
# make paths absolute
|
||||
testsAbs = builtins.map (
|
||||
t: t // { path = "${absPath}/${t.path}"; }
|
||||
) tests;
|
||||
in builtins.map (
|
||||
t: let
|
||||
rval = (filter t.path t.type);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{ lib, pkgs, deps, callPackage, mkShell
|
||||
{ pkgs, deps, callPackage, mkShell
|
||||
, status-go, androidPkgs, androidShell }:
|
||||
|
||||
let
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{ stdenv, pkgs, deps, lib, config, callPackage,
|
||||
watchmanFactory, androidPkgs, patchMavenSources,
|
||||
jsbundle, status-go }:
|
||||
{ stdenv, pkgs, deps, lib, watchmanFactory
|
||||
, androidPkgs, patchMavenSources, jsbundle, status-go }:
|
||||
|
||||
{
|
||||
# Value for BUILD_ENV checked by Clojure code at compile time
|
||||
@@ -15,9 +14,7 @@
|
||||
assert (lib.stringLength watchmanSockPath) > 0 -> stdenv.isDarwin;
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
toLower optionalString stringLength assertMsg
|
||||
getConfig makeLibraryPath checkEnvVarSet elem;
|
||||
inherit (lib) toLower optionalString stringLength getConfig makeLibraryPath elem;
|
||||
|
||||
# Pass secretsFile for INFURA_TOKEN to jsbundle build
|
||||
builtJsBundle = jsbundle { inherit secretsFile; };
|
||||
@@ -29,9 +26,6 @@ let
|
||||
# Used to detect end-to-end builds
|
||||
androidAbiInclude = getConfig "android.abi-include" "armeabi-v7a;arm64-v8a;x86";
|
||||
|
||||
baseName = "${buildType}-android";
|
||||
name = "status-react-build-${baseName}";
|
||||
|
||||
envFileName =
|
||||
if androidAbiInclude == "x86" then ".env.e2e"
|
||||
else if (elem buildType ["release" "nightly"]) then ".env.${buildType}"
|
||||
@@ -44,8 +38,10 @@ let
|
||||
apksPath = "./android/app/build/outputs/apk/${toLower gradleBuildType}";
|
||||
patchedWatchman = watchmanFactory watchmanSockPath;
|
||||
|
||||
baseName = "${buildType}-android";
|
||||
in stdenv.mkDerivation rec {
|
||||
inherit name;
|
||||
name = "status-react-build-${baseName}";
|
||||
|
||||
src = let path = ./../../..;
|
||||
# We use builtins.path so that we can name the resulting derivation
|
||||
in builtins.path {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
{ config, lib, stdenvNoCC, callPackage, mkShell, status-go }:
|
||||
{ lib, callPackage, mkShell, status-go }:
|
||||
|
||||
let
|
||||
inherit (lib) catAttrs concatStrings optional unique;
|
||||
|
||||
fastlane = callPackage ./fastlane { };
|
||||
|
||||
android = callPackage ./android {
|
||||
@@ -24,7 +22,7 @@ let
|
||||
|
||||
in {
|
||||
shell = mkShell {
|
||||
inputsFrom = (catAttrs "shell" selectedSources);
|
||||
inputsFrom = lib.catAttrs "shell" selectedSources;
|
||||
};
|
||||
|
||||
# TARGETS
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# It copies the status-go build result to 'modules/react-native-status/ios/RCTStatus'.
|
||||
#
|
||||
|
||||
{ lib, mkShell, status-go }:
|
||||
{ mkShell, status-go }:
|
||||
|
||||
mkShell {
|
||||
shellHook = ''
|
||||
|
||||
+3
-1
@@ -33,7 +33,6 @@ in {
|
||||
gradlePropParser = callPackage ./tools/gradlePropParser.nix { };
|
||||
|
||||
# Package version adjustments
|
||||
go = super.pkgs.go_1_17;
|
||||
gradle = super.pkgs.gradle_5;
|
||||
nodejs = super.pkgs.nodejs-16_x;
|
||||
openjdk = super.pkgs.openjdk8_headless;
|
||||
@@ -41,6 +40,9 @@ in {
|
||||
version = "13.3";
|
||||
allowHigher = true;
|
||||
};
|
||||
go = super.pkgs.go_1_17;
|
||||
buildGoPackage = super.pkgs.buildGo117Package;
|
||||
buildGoModule = super.pkgs.buildGo117Module;
|
||||
gomobile = super.gomobile.override {
|
||||
# FIXME: No Android SDK packages for aarch64-darwin.
|
||||
withAndroidPkgs = stdenv.system != "aarch64-darwin";
|
||||
|
||||
+3
-3
@@ -11,10 +11,10 @@ let
|
||||
# We follow the master branch of official nixpkgs.
|
||||
nixpkgsSrc = fetchFromGitHub {
|
||||
name = "nixpkgs-source";
|
||||
owner = "status-im";
|
||||
owner = "NixOS";
|
||||
repo = "nixpkgs";
|
||||
rev = "4ba5f26780e7a27aa2e97676603cd9ef04f11e74";
|
||||
sha256 = "sha256-ZpHXUuF9bvHooKwGuR1Mr/n2mE/LJ6/MCdCk2AfdD9M=";
|
||||
rev = "8a782b05cb764db86f2826995adb9128e26dffe2";
|
||||
sha256 = "sha256-9+Ys74yxniHBz2/kLVSzboqCNRx1E+Dv/yzSBtw0jDQ=";
|
||||
# To get the compressed Nix sha256, use:
|
||||
# nix-prefetch-url --unpack https://github.com/${ORG}/nixpkgs/archive/${REV}.tar.gz
|
||||
};
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
# It is used by Gradle to package Android app resources.
|
||||
# See: https://developer.android.com/studio/command-line/aapt2
|
||||
|
||||
{ lib, stdenv, deps, pkgs, fetchurl }:
|
||||
{ lib, stdenv, pkgs, fetchurl }:
|
||||
|
||||
let
|
||||
inherit (lib) getAttr optionals;
|
||||
inherit (pkgs) zip unzip patchelf;
|
||||
inherit (stdenv) isLinux isDarwin;
|
||||
|
||||
pname = "aapt2";
|
||||
@@ -53,7 +52,7 @@ in stdenv.mkDerivation {
|
||||
srcs = with urls; [ jar sha pom ];
|
||||
phases = [ "unpackPhase" ]
|
||||
++ optionals isLinux [ "patchPhase" ]; # OSX binaries don't need patchelf
|
||||
buildInputs = [ zip unzip patchelf ];
|
||||
buildInputs = with pkgs; [ zip unzip patchelf ];
|
||||
|
||||
unpackPhase = ''
|
||||
mkdir -p $out
|
||||
@@ -71,15 +70,15 @@ in stdenv.mkDerivation {
|
||||
|
||||
# Patch executables from maven dependency to use Nix's interpreter
|
||||
tmpDir=$(mktemp -d)
|
||||
${unzip}/bin/unzip $out/${filenames.jar} -d $tmpDir
|
||||
unzip $out/${filenames.jar} -d $tmpDir
|
||||
for exe in `find $tmpDir/ -type f -executable`; do
|
||||
${patchelf}/bin/patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $exe
|
||||
patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $exe
|
||||
done
|
||||
|
||||
# Rebuild the .jar file with patched binaries
|
||||
pushd $tmpDir > /dev/null
|
||||
chmod u+w $out/${filenames.jar}
|
||||
${zip}/bin/zip -fr $out/${filenames.jar}
|
||||
zip -fr $out/${filenames.jar}
|
||||
chmod $out/${filenames.jar} --reference=$out/${filenames.jar}.sha1
|
||||
popd > /dev/null
|
||||
rm -rf $tmpDir
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
# for the Android development environment.
|
||||
#
|
||||
|
||||
{ stdenv, config, callPackage, androidenv, openjdk, mkShell }:
|
||||
{ androidenv }:
|
||||
|
||||
# The "android-sdk-license" license is accepted
|
||||
# by setting android_sdk.accept_license = true.
|
||||
androidenv.composeAndroidPackages {
|
||||
toolsVersion = "26.1.1";
|
||||
platformToolsVersion = "31.0.3";
|
||||
platformToolsVersion = "33.0.1";
|
||||
buildToolsVersions = [ "31.0.0" ];
|
||||
platformVersions = [ "30" ];
|
||||
cmakeVersions = [ "3.18.1" ];
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# for the Android development environment.
|
||||
#
|
||||
|
||||
{ callPackage, stdenv, writeScript }:
|
||||
{ callPackage }:
|
||||
|
||||
let
|
||||
compose = callPackage ./compose.nix { };
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
{ lib, buildGo116Module, fetchFromGitHub }:
|
||||
{ buildGoModule, fetchFromGitHub }:
|
||||
|
||||
let
|
||||
inherit (lib) strings;
|
||||
in buildGo116Module rec {
|
||||
buildGoModule rec {
|
||||
pname = "go-maven-resolver";
|
||||
version = "v1.1.2";
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ nixOpts=(
|
||||
${GIT_ROOT}/nix/scripts/gcroots.sh "${TARGET}" "${@}"
|
||||
|
||||
# Run the actual build
|
||||
echo "${GRN}Running:${RST} nix-build "${nixOpts[@]}" "${@}" default.nix"
|
||||
echo -e "${GRN}Running:${RST} ${BLD}nix-build "${nixOpts[@]}" ${@}${RST}"
|
||||
nixResultPath=$(nix-build "${nixOpts[@]}" "${@}" default.nix)
|
||||
|
||||
echo -e "\n${YLW}Extracting result${RST}: ${BLD}${nixResultPath}${RST}"
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ let
|
||||
};
|
||||
|
||||
# for merging the default shell with others
|
||||
mergeDefaultShell = (key: val: lib.mergeSh default [ val ]);
|
||||
mergeDefaultShell = (_: val: lib.mergeSh default [ val ]);
|
||||
|
||||
# values here can be selected using `nix-shell --attr shells.$TARGET default.nix`
|
||||
# the nix/scripts/shell.sh wrapper does this for us and expects TARGET to be set
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{ lib, callPackage, mkShell, openjdk, androidPkgs }:
|
||||
{ lib, callPackage, mkShell }:
|
||||
|
||||
let
|
||||
inherit (lib) attrValues mapAttrs;
|
||||
@@ -28,19 +28,15 @@ let
|
||||
"-s" # -s disabled symbol table
|
||||
"-w" # -w disables DWARF debugging information
|
||||
];
|
||||
|
||||
goBuildFlags = [ "-v" ];
|
||||
|
||||
in rec {
|
||||
mobile = callPackage ./mobile {
|
||||
inherit meta source goBuildFlags goBuildLdFlags;
|
||||
inherit meta source goBuildLdFlags;
|
||||
};
|
||||
|
||||
library = callPackage ./library {
|
||||
inherit meta source;
|
||||
};
|
||||
|
||||
|
||||
shell = mkShell {
|
||||
inputsFrom = [ mobile.android mobile.ios ];
|
||||
};
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
{ lib, stdenv, utils, buildGo117Package
|
||||
, go, xcodeWrapper
|
||||
{ buildGoPackage
|
||||
# object with source attributes
|
||||
, meta, source}:
|
||||
|
||||
let
|
||||
inherit (stdenv) isDarwin;
|
||||
inherit (lib) optional;
|
||||
|
||||
in buildGo117Package {
|
||||
buildGoPackage {
|
||||
pname = source.repo;
|
||||
version = "${source.cleanVersion}-${source.shortRev}";
|
||||
|
||||
@@ -25,9 +20,7 @@ in buildGo117Package {
|
||||
# Build the Go library
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
go build -buildmode=c-archive -o $out/libstatus.a $NIX_BUILD_TOP/main.go
|
||||
|
||||
go build -buildmode=c-archive -o $out/libstatus.a $NIX_BUILD_TOP/main.go
|
||||
runHook postBuild
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{ lib, stdenv, utils, callPackage, buildGo116Package
|
||||
, go, androidPkgs, openjdk, gomobile, xcodeWrapper
|
||||
# object with source attributes
|
||||
, meta, source
|
||||
{ lib, utils, buildGoPackage, androidPkgs, openjdk, gomobile, xcodeWrapper
|
||||
, meta
|
||||
, source
|
||||
, platform ? "android"
|
||||
, platformVersion ? "23"
|
||||
, architectures ? [ "arm64" "arm" "x86" ]
|
||||
, goBuildFlags ? [ ]
|
||||
, goBuildFlags ? [ "-x" ]
|
||||
, goBuildLdFlags ? [ ]
|
||||
, outputFileName ? "status-go-${source.shortRev}-${platform}.aar" }:
|
||||
|
||||
@@ -12,96 +12,55 @@
|
||||
{ secretsFile ? "" }:
|
||||
|
||||
let
|
||||
inherit (stdenv) isDarwin;
|
||||
inherit (lib)
|
||||
concatStrings concatStringsSep concatMapStrings optionalString
|
||||
getAttr attrValues makeBinPath optional;
|
||||
|
||||
removeReferences = [ go ];
|
||||
removeExpr = refs: ''remove-references-to ${concatMapStrings (ref: " -t ${ref}") refs}'';
|
||||
|
||||
inherit (lib) concatStringsSep optionalString optional;
|
||||
# formatted for use with -target
|
||||
targetArchs = map (a: "${platform}/${a}") architectures;
|
||||
|
||||
in buildGo116Package {
|
||||
in buildGoPackage {
|
||||
pname = source.repo;
|
||||
version = "${source.cleanVersion}-${source.shortRev}-${platform}";
|
||||
|
||||
inherit meta;
|
||||
inherit (source) src goPackagePath;
|
||||
|
||||
extraSrcPaths = [ gomobile ];
|
||||
nativeBuildInputs = [ gomobile ]
|
||||
++ optional (platform == "android") openjdk
|
||||
++ optional isDarwin xcodeWrapper;
|
||||
++ optional (platform == "ios") xcodeWrapper;
|
||||
|
||||
# Fixes Cgo related build failures (see https://github.com/NixOS/nixpkgs/issues/25959 )
|
||||
hardeningDisable = [ "fortify" ];
|
||||
ldflags = concatStringsSep " " (goBuildLdFlags
|
||||
++ lib.optionals (secretsFile != "") ["-X node.OpenseaKeyFromEnv=$OPENSEA_API_KEY"]);
|
||||
|
||||
phases = [
|
||||
"unpackPhase" "secretsPhase" "configurePhase"
|
||||
"buildPhase" "installPhase" "fixupPhase"
|
||||
];
|
||||
ANDROID_HOME = optionalString (platform == "android") androidPkgs.sdk;
|
||||
|
||||
# if secretsFile is not set we use generate keystore
|
||||
secretsPhase = if (secretsFile != "") then ''
|
||||
# Ensure XCode is present for iOS, instead of failing at the end of the build.
|
||||
preConfigure = optionalString (platform == "ios") utils.enforceXCodeAvailable;
|
||||
|
||||
# If secretsFile is not set we use generate keystore.
|
||||
preBuild = if (secretsFile != "") then ''
|
||||
source "${secretsFile}"
|
||||
'' else ''
|
||||
echo "No secrets provided!"
|
||||
'';
|
||||
|
||||
# Ensure XCode is present for iOS build, instead of failing at the end of the build
|
||||
preConfigure = optionalString (isDarwin && platform == "ios") utils.enforceXCodeAvailable;
|
||||
|
||||
# Build mobile libraries
|
||||
preBuild = let
|
||||
NIX_GOWORKDIR = "$NIX_BUILD_TOP/go-build";
|
||||
in ''
|
||||
mkdir ${NIX_GOWORKDIR}
|
||||
|
||||
export GO111MODULE=off
|
||||
export GOPATH=${gomobile}:$GOPATH
|
||||
export NIX_GOWORKDIR=${NIX_GOWORKDIR}
|
||||
'' + optionalString (platform == "android") ''
|
||||
export ANDROID_SDK_ROOT="${androidPkgs.sdk}"
|
||||
export ANDROID_NDK_HOME="${androidPkgs.ndk}"
|
||||
export PATH="${makeBinPath [ openjdk ]}:$PATH"
|
||||
'';
|
||||
|
||||
# Build the Go library using gomobile for each of the configured platforms
|
||||
buildPhase = let
|
||||
ldFlags = [ "-extldflags=-Wl,--allow-multiple-definition" ]
|
||||
++ lib.optionals (secretsFile != "") ["-X node.OpenseaKeyFromEnv=$OPENSEA_API_KEY"]
|
||||
++ goBuildLdFlags;
|
||||
CGO_LDFLAGS = concatStringsSep " " ldFlags;
|
||||
in ''
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
runHook renameImports
|
||||
|
||||
echo -e "\nBuilding for targets: ${concatStringsSep "," targetArchs}\n"
|
||||
|
||||
${gomobile}/bin/gomobile bind \
|
||||
-target=${concatStringsSep "," targetArchs} \
|
||||
-ldflags="${CGO_LDFLAGS}" \
|
||||
${optionalString (platform == "android") "-androidapi 23"} \
|
||||
${optionalString (platform == "ios") "-iosversion=8.0"} \
|
||||
gomobile bind \
|
||||
${concatStringsSep " " goBuildFlags} \
|
||||
-ldflags="$ldflags" \
|
||||
-target=${concatStringsSep "," targetArchs} \
|
||||
${optionalString (platform == "android") "-androidapi=${platformVersion}"} \
|
||||
${optionalString (platform == "ios") "-iosversion=${platformVersion}"} \
|
||||
-o ${outputFileName} \
|
||||
${source.goPackagePath}/mobile
|
||||
|
||||
rm -rf $NIX_GOWORKDIR
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
# replace hardcoded paths to go package in /nix/store, otherwise Nix will fail the build
|
||||
fixupPhase = ''
|
||||
find $out -type f -exec ${removeExpr removeReferences} '{}' + || true
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
mv ${outputFileName} $out/
|
||||
cp -r ${outputFileName} $out/
|
||||
'';
|
||||
|
||||
outputs = [ "out" ];
|
||||
}
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
{ callPackage
|
||||
, meta, source
|
||||
, goBuildFlags
|
||||
, goBuildLdFlags }:
|
||||
{ callPackage, meta, source, goBuildLdFlags }:
|
||||
|
||||
{
|
||||
android = callPackage ./build.nix {
|
||||
platform = "android";
|
||||
# 386 is for android simulator
|
||||
architectures = [ "arm" "arm64" "386" ];
|
||||
platformVersion = "23";
|
||||
architectures = [ "arm" "arm64" "386" ]; # 386 is for android simulator.
|
||||
outputFileName = "status-go-${source.shortRev}.aar";
|
||||
inherit meta source goBuildFlags goBuildLdFlags;
|
||||
inherit meta source goBuildLdFlags;
|
||||
};
|
||||
|
||||
ios = callPackage ./build.nix {
|
||||
platform = "ios";
|
||||
# amd64 is for ios simulator
|
||||
architectures = [ "arm64" "amd64" ];
|
||||
platformVersion = "8.0";
|
||||
architectures = [ "arm64" "amd64" ]; # amd64 is for ios simulator.
|
||||
outputFileName = "Statusgo.framework";
|
||||
inherit meta source goBuildFlags goBuildLdFlags;
|
||||
inherit meta source goBuildLdFlags;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{ config, utils, lib, callPackage, fetchFromGitHub }:
|
||||
{ utils, lib, fetchFromGitHub }:
|
||||
|
||||
let
|
||||
inherit (lib) strings traceValFn attrByPath importJSON getConfig;
|
||||
inherit (lib) strings traceValFn importJSON getConfig;
|
||||
|
||||
srcOverride = getConfig "status-go.src-override" null;
|
||||
# Warning message about using local sources
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
# This Nix expression takes care of reading/parsing the correct .env configuration file and return it as an attr set
|
||||
{ config, stdenv, lib }:
|
||||
{ config, lib }:
|
||||
|
||||
let
|
||||
inherit (builtins) listToAttrs head tail readFile;
|
||||
inherit (lib) attrByPath filter hasPrefix nameValuePair splitString;
|
||||
|
||||
build-type = attrByPath ["status-im" "build-type"] "" config;
|
||||
ci = (attrByPath ["status-im" "ci"] "" config) != "";
|
||||
|
||||
readLinesFromFile =
|
||||
file:
|
||||
|
||||
@@ -11,7 +11,7 @@ let
|
||||
lines = splitString "\n" (readFile gradlePropsFile);
|
||||
|
||||
isKeyValueLine = line: line != "" && !hasPrefix "#" line;
|
||||
cleanup = lines: filter isKeyValueLine lines;
|
||||
cleanup = filter isKeyValueLine;
|
||||
extractKeyValues = line:
|
||||
let flag = splitString "=" line;
|
||||
in nameValuePair (head flag) (last flag);
|
||||
|
||||
+2
-2
@@ -53,9 +53,9 @@ let
|
||||
sanitizeVersion = version:
|
||||
if (builtins.match versionRegex version) != null
|
||||
# Geth forces a 'v' prefix for all versions
|
||||
then lib.removePrefix "v" (dropSlashes version)
|
||||
then lib.removePrefix "v" (dropSlashes version)
|
||||
# reduce metrics cardinality in Prometheus
|
||||
else lib.traceValFn (v: "WARNING: Marking build version as 'develop'!") "develop";
|
||||
else lib.traceValFn (_: "WARNING: Marking build version as 'develop'!") "develop";
|
||||
|
||||
in {
|
||||
inherit sanitizeVersion
|
||||
|
||||
+3
-1
@@ -6,13 +6,13 @@
|
||||
"scripts": {
|
||||
"start": "react-native start",
|
||||
"ios": "react-native run-ios",
|
||||
"preinstall": "make status-go-library",
|
||||
"app:compile:android": "shadow-cljs compile android",
|
||||
"app:watch": "shadow-cljs watch android",
|
||||
"app:packager": "react-native start --host 0.0.0.0 --port 8081",
|
||||
"app:android": "react-native run-android"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mapbox/node-pre-gyp": "^1.0.9",
|
||||
"@react-native-community/async-storage": "^1.11.0",
|
||||
"@react-native-community/audio-toolkit": "git+https://github.com/tbenr/react-native-audio-toolkit.git#refs/tags/v2.0.3-status-v6",
|
||||
"@react-native-community/blur": "^3.6.0",
|
||||
@@ -75,6 +75,7 @@
|
||||
"web3-utils": "^1.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mapbox/node-pre-gyp": "^1.0.9",
|
||||
"@babel/generator": "7.0.0",
|
||||
"@babel/helper-builder-react-jsx": "7.0.0",
|
||||
"@babel/plugin-transform-block-scoping": "7.0.0",
|
||||
@@ -83,6 +84,7 @@
|
||||
"clj-kondo": "^2020.1.13",
|
||||
"coveralls": "^3.0.4",
|
||||
"jest": "^25.1.0",
|
||||
"nodemon": "^2.0.16",
|
||||
"nyc": "^14.1.1",
|
||||
"process": "0.11.10",
|
||||
"rn-snoopy": "git+https://github.com/status-im/rn-snoopy.git#refs/tags/v2.0.2-status",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
@@ -10,13 +10,13 @@ GO_COMMIT_MERGE_BASE=$(git show "${MERGE_BASE}":status-go-version.json | jq -r '
|
||||
GO_COMMIT_CURRENT=$(jq -r '."commit-sha1"' status-go-version.json)
|
||||
GITHUB_LINK_PREFIX="https://github.com/status-im/status-go/compare/"
|
||||
# Link to the current StatusGo changelog being updated.
|
||||
GITHUB_LINK="${GITHUB_LINK_PREFIX}${GO_COMMIT_MERGE_BASE}...${GO_COMMIT_CURRENT}"
|
||||
GITHUB_LINK="${GITHUB_LINK_PREFIX}${GO_COMMIT_MERGE_BASE::8}...${GO_COMMIT_CURRENT::8}"
|
||||
|
||||
COMMIT_MSG_FILE=$1
|
||||
# Check if the commit message already contains the link (rebase) and update otherwise insert into line2
|
||||
if ! grep -qF "${GITHUB_LINK_PREFIX}" "${COMMIT_MSG_FILE}" >/dev/null; then
|
||||
sed -in'' -e "2i\\
|
||||
${GITHUB_LINK}\n" "${COMMIT_MSG_FILE}"
|
||||
\n${GITHUB_LINK}" "${COMMIT_MSG_FILE}"
|
||||
else
|
||||
sed -in'' -e "s;^${GITHUB_LINK_PREFIX}.*$;${GITHUB_LINK};" "${COMMIT_MSG_FILE}"
|
||||
fi
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
:View {}
|
||||
:RefreshControl {}
|
||||
:AppState {}
|
||||
:FlatList {}
|
||||
:SectionList {}
|
||||
:Text {}
|
||||
@@ -58,7 +59,7 @@
|
||||
:in (fn [])
|
||||
:inOut (fn [])}
|
||||
:DeviceEventEmitter {:addListener (fn [])}
|
||||
:Dimensions {:get (fn [])}
|
||||
:Dimensions {:get (fn []) :addEventListener identity}
|
||||
:useWindowDimensions {}
|
||||
:Platform {:select (fn [])}
|
||||
:I18nManager {:isRTL ""}
|
||||
@@ -80,7 +81,8 @@
|
||||
|
||||
(def icons #js {:default #js {}})
|
||||
(def webview #js {:WebView #js {}})
|
||||
(def status-keycard #js {:default #js {}})
|
||||
(def status-keycard #js {:default #js {:nfcIsSupported (fn [] #js {:then identity})
|
||||
:nfcIsEnabled (fn [] #js {:then identity})}})
|
||||
|
||||
(def snoopy #js {:default #js {}})
|
||||
(def snoopy-filter #js {:default #js {}})
|
||||
@@ -88,6 +90,11 @@
|
||||
(def snoopy-buffer #js {:default #js {}})
|
||||
(def fetch #js {})
|
||||
|
||||
(def async-storage-atom (atom {}))
|
||||
(def async-storage #js {:default #js {:setItem #(js/Promise.resolve)
|
||||
:multiGet #(js/Promise.resolve)
|
||||
:getItem #(js/Promise.resolve)}})
|
||||
|
||||
(def background-timer (clj->js {:default {:setTimeout js/setTimeout
|
||||
:setInterval js/setInterval
|
||||
:clearTimeout js/clearTimeout
|
||||
@@ -100,8 +107,14 @@
|
||||
(def react-native-mail #js {:mail #js {}})
|
||||
(def react-native-screens #js {})
|
||||
(def react-native-shake #js {})
|
||||
(def react-native-share #js {:default {}})
|
||||
(def react-native-svg #js {:SvgUri #js {:render identity}
|
||||
:SvgXml #js {:render identity}})
|
||||
(def react-native-webview #js {:default {}})
|
||||
(def react-native-audio-toolkit #js {:MediaStates {}})
|
||||
(def net-info #js {})
|
||||
(def touchid #js {})
|
||||
(def react-native-image-viewing #js {:default {}})
|
||||
(def safe-area-context (clj->js {:SafeAreaProvider {:_reactNativeIphoneXHelper {:getStatusBarHeight (fn [])}}
|
||||
:SafeAreaInsetsContext {:Consumer (fn [])}
|
||||
:SafeAreaView {}}))
|
||||
@@ -119,7 +132,19 @@
|
||||
:StackActions #js {}})
|
||||
|
||||
(def react-native-navigation #js {:Navigation #js {:constants (fn [] #js {:then identity})
|
||||
:events identity}})
|
||||
:setDefaultOptions identity
|
||||
:setRoot identity
|
||||
:setLazyComponentRegistrator identity
|
||||
:push identity
|
||||
:registerComponent identity
|
||||
:events
|
||||
(fn []
|
||||
#js {:registerModalDismissedListener identity
|
||||
:registerAppLaunchedListener identity
|
||||
:registerBottomTabSelectedListener identity
|
||||
:registerComponentDidDisappearListener identity
|
||||
:registerComponentDidAppearListener identity
|
||||
:registerNavigationButtonPressedListener identity})}})
|
||||
|
||||
(def react-navigation-stack #js {:createStackNavigator identity
|
||||
:TransitionPresets #js {:ModalPresentationIOS #js {}}})
|
||||
@@ -205,6 +230,8 @@
|
||||
|
||||
(def react-native-gradien #js {:default #js {}})
|
||||
|
||||
(def react-native-permissions #js {:default #js {}})
|
||||
|
||||
(def push-notification-ios #js {})
|
||||
|
||||
(def rn-emoji-keyboard
|
||||
@@ -213,9 +240,15 @@
|
||||
(def react-native-draggable-flatlist
|
||||
#js {:default #js {}})
|
||||
|
||||
(def react-native-blob-util
|
||||
#js {:default #js {}})
|
||||
|
||||
(def react-native-blur
|
||||
(clj->js {:BlurView {}}))
|
||||
|
||||
(def react-native-camera-roll
|
||||
(clj->js {:default #js {}}))
|
||||
|
||||
(def wallet-connect-client #js {:default #js {}
|
||||
:CLIENT_EVENTS #js {:session #js {:request nil
|
||||
:created nil
|
||||
@@ -251,12 +284,21 @@
|
||||
"react-native-device-info" react-native-device-info
|
||||
"react-native-push-notification" react-native-push-notification
|
||||
"react-native-linear-gradient" react-native-gradien
|
||||
"react-native-blob-util" react-native-blob-util
|
||||
"react-native-navigation" react-native-navigation
|
||||
"@react-native-community/push-notification-ios" push-notification-ios
|
||||
"@react-native-community/blur" react-native-blur
|
||||
"@react-native-community/cameraroll" react-native-camera-roll
|
||||
"react-native-camera-kit" react-native-camera-kit
|
||||
"react-native-permissions" react-native-permissions
|
||||
"rn-emoji-keyboard" rn-emoji-keyboard
|
||||
"react-native-draggable-flatlist" react-native-draggable-flatlist
|
||||
"react-native-webview" react-native-webview
|
||||
"@react-native-community/audio-toolkit" react-native-audio-toolkit
|
||||
"react-native-image-viewing" react-native-image-viewing
|
||||
"react-native-share" react-native-share
|
||||
"@react-native-community/async-storage" async-storage
|
||||
"react-native-svg" react-native-svg
|
||||
"./fleets.js" default-fleets
|
||||
"./chats.js" default-chats
|
||||
"@walletconnect/client" wallet-connect-client
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
:inherit nil)
|
||||
(case (or size :base)
|
||||
:tiny typography/tiny
|
||||
:x-small typography/x-small
|
||||
:small typography/small
|
||||
:base typography/base
|
||||
:large typography/large
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
(def tiny {:font-size 10
|
||||
:line-height 14})
|
||||
|
||||
(def x-small {:font-size 12
|
||||
:line-height 16})
|
||||
|
||||
(def small {:font-size 13
|
||||
:line-height 18})
|
||||
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
["@react-native-community/hooks" :as hooks]
|
||||
["react-native-navigation" :refer (Navigation)]
|
||||
["rn-emoji-keyboard" :refer (EmojiKeyboard)]
|
||||
["react-native-draggable-flatlist" :default DraggableFlatList]
|
||||
[status-im.utils.config :as config]))
|
||||
["react-native-draggable-flatlist" :default DraggableFlatList]))
|
||||
|
||||
(def rn-draggable-flatlist (reagent/adapt-react-class DraggableFlatList))
|
||||
|
||||
@@ -108,7 +107,7 @@
|
||||
:property (:opacity layout-animation-properties)}}})
|
||||
|
||||
(defonce enable-layout-animations
|
||||
(when (and platform/android? config/quo-preview-enabled?)
|
||||
(when platform/android?
|
||||
(.setLayoutAnimationEnabledExperimental ^js ui-manager true)))
|
||||
|
||||
(def activity-indicator (reagent/adapt-react-class (.-ActivityIndicator ^js rn)))
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
[status-im.multiaccounts.model :as multiaccounts.model]
|
||||
[status-im.chat.models.message-list :as message-list]
|
||||
[status-im.data-store.chats :as chats-store]
|
||||
[status-im.mailserver.core :as mailserver]
|
||||
[status-im.data-store.contacts :as contacts-store]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
@@ -204,14 +205,11 @@
|
||||
(fx/defn close-chat
|
||||
{:events [:close-chat]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [chat-id (:current-chat-id db)
|
||||
navigate-after-home-to-chat (:navigate-after-home-to-chat db)]
|
||||
(when-let [chat-id (:current-chat-id db)]
|
||||
(chat.state/reset-visible-item)
|
||||
(if navigate-after-home-to-chat
|
||||
{:db (dissoc db :navigate-after-home-to-chat)}
|
||||
(fx/merge cofx
|
||||
{:db (dissoc db :current-chat-id)}
|
||||
(offload-messages chat-id)))))
|
||||
(fx/merge cofx
|
||||
{:db (dissoc db :current-chat-id)}
|
||||
(offload-messages chat-id))))
|
||||
|
||||
(fx/defn force-close-chat
|
||||
[{:keys [db] :as cofx} chat-id]
|
||||
@@ -249,20 +247,17 @@
|
||||
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
|
||||
{:events [:chat.ui/navigate-to-chat]}
|
||||
[{db :db :as cofx} chat-id]
|
||||
(let [home-view? (= (get db :view-id) :home)]
|
||||
(fx/merge cofx
|
||||
(close-chat)
|
||||
(force-close-chat chat-id)
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc db :current-chat-id chat-id :navigate-after-home-to-chat (not home-view?))})
|
||||
(preload-chat-data chat-id)
|
||||
#(when (group-chat? cofx chat-id)
|
||||
(loading/load-chat % chat-id))
|
||||
#(when-not home-view?
|
||||
(navigation/change-tab % :chat))
|
||||
#(when-not home-view?
|
||||
(navigation/pop-to-root-tab % :chat-stack))
|
||||
(navigation/navigate-to-cofx :chat nil))))
|
||||
(fx/merge cofx
|
||||
{:dispatch [:navigate-to :chat]}
|
||||
(navigation/change-tab :chat)
|
||||
(navigation/pop-to-root-tab :chat-stack)
|
||||
(close-chat)
|
||||
(force-close-chat chat-id)
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc db :current-chat-id chat-id)})
|
||||
(preload-chat-data chat-id)
|
||||
#(when (group-chat? cofx chat-id)
|
||||
(loading/load-chat % chat-id))))
|
||||
|
||||
(fx/defn navigate-to-chat-nav2
|
||||
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
|
||||
@@ -319,29 +314,28 @@
|
||||
|
||||
(fx/defn handle-public-chat-created
|
||||
{:events [::public-chat-created]}
|
||||
[{:keys [db]} chat-id _ response]
|
||||
[{:keys [db]} chat-id response]
|
||||
{:db (-> db
|
||||
(assoc-in [:chats chat-id] (chats-store/<-rpc (first (:chats response))))
|
||||
(update :chats-home-list conj chat-id))
|
||||
:dispatch [:chat.ui/navigate-to-chat chat-id]})
|
||||
|
||||
(fx/defn create-public-chat-go [_ chat-id opts]
|
||||
(fx/defn create-public-chat-go [_ chat-id]
|
||||
{::json-rpc/call [{:method "wakuext_createPublicChat"
|
||||
:params [{:id chat-id}]
|
||||
:on-success #(re-frame/dispatch [::public-chat-created chat-id opts %])
|
||||
:on-success #(re-frame/dispatch [::public-chat-created chat-id %])
|
||||
:on-error #(log/error "failed to create public chat" chat-id %)}]})
|
||||
|
||||
(fx/defn start-public-chat
|
||||
"Starts a new public chat"
|
||||
{:events [:chat.ui/start-public-chat]}
|
||||
[cofx topic {:keys [profile-public-key] :as opts}]
|
||||
(if (or (new-public-chat.db/valid-topic? topic) profile-public-key)
|
||||
[cofx topic]
|
||||
(if (new-public-chat.db/valid-topic? topic)
|
||||
(if (active-chat? cofx topic)
|
||||
(navigate-to-chat cofx topic)
|
||||
(create-public-chat-go
|
||||
cofx
|
||||
topic
|
||||
opts))
|
||||
topic))
|
||||
{:utils/show-popup {:title (i18n/label :t/cant-open-public-chat)
|
||||
:content (i18n/label :t/invalid-public-chat-topic)}}))
|
||||
|
||||
@@ -472,12 +466,14 @@
|
||||
(fx/defn chat-ui-fill-gaps
|
||||
{:events [:chat.ui/fill-gaps]}
|
||||
[{:keys [db] :as cofx} chat-id gap-ids]
|
||||
(log/info "filling gaps" chat-id gap-ids)
|
||||
(fx/merge cofx
|
||||
{:db (assoc db :mailserver/fetching-gaps-in-progress gap-ids)}
|
||||
(if (= gap-ids #{:first-gap})
|
||||
(sync-chat-from-sync-from chat-id)
|
||||
(fill-gaps chat-id gap-ids))))
|
||||
(let [use-status-nodes? (mailserver/fetch-use-mailservers? {:db db})]
|
||||
(log/info "filling gaps if use-status-nodes = true" chat-id gap-ids)
|
||||
(when use-status-nodes?
|
||||
(fx/merge cofx
|
||||
{:db (assoc db :mailserver/fetching-gaps-in-progress gap-ids)}
|
||||
(if (= gap-ids #{:first-gap})
|
||||
(sync-chat-from-sync-from chat-id)
|
||||
(fill-gaps chat-id gap-ids))))))
|
||||
|
||||
(fx/defn chat-ui-remove-chat-pressed
|
||||
{:events [:chat.ui/remove-chat-pressed]}
|
||||
@@ -500,4 +496,4 @@
|
||||
(update-in [:chats chat-id :unviewed-messages-count]
|
||||
#(max (- % count) 0))
|
||||
(update-in [:chats chat-id :unviewed-mentions-count]
|
||||
#(max (- % countWithMentions) 0)))})
|
||||
#(max (- % countWithMentions) 0)))})
|
||||
@@ -143,6 +143,20 @@
|
||||
:on-error #(log/error "failed to delete message message " %)
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]})
|
||||
|
||||
(fx/defn show-contact-request-input
|
||||
"Sets reference to previous chat message and focuses on input"
|
||||
{:events [:chat.ui/send-contact-request]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [current-chat-id (:current-chat-id db)]
|
||||
{:db (-> db
|
||||
(assoc-in [:chat/inputs current-chat-id :metadata :sending-contact-request]
|
||||
current-chat-id)
|
||||
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message]
|
||||
nil)
|
||||
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message] nil)
|
||||
(update-in [:chat/inputs current-chat-id :metadata]
|
||||
dissoc :sending-image))}))
|
||||
|
||||
(fx/defn cancel-message-reply
|
||||
"Cancels stage message reply"
|
||||
{:events [:chat.ui/cancel-message-reply]}
|
||||
@@ -179,6 +193,7 @@
|
||||
(fx/defn clean-input [{:keys [db] :as cofx} current-chat-id]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:chat/inputs current-chat-id :metadata :sending-contact-request] nil)
|
||||
(assoc-in [:chat/inputs current-chat-id :metadata :sending-image] nil)
|
||||
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message] nil)
|
||||
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message] nil))}
|
||||
@@ -262,6 +277,34 @@
|
||||
(mentions/clear-mentions)
|
||||
(mentions/clear-cursor))))
|
||||
|
||||
(fx/defn send-contact-request
|
||||
{:events [:contacts/send-contact-request]}
|
||||
[{:keys [db] :as cofx} public-key message]
|
||||
(fx/merge cofx
|
||||
{::json-rpc/call [{:method "wakuext_sendContactRequest"
|
||||
:js-response true
|
||||
:params [{:id public-key :message message}]
|
||||
:on-error #(log/warn "failed to send a contact request" %)
|
||||
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent %])}]}
|
||||
|
||||
(mentions/clear-mentions)
|
||||
(mentions/clear-cursor)
|
||||
(clean-input (:current-chat-id db))
|
||||
(process-cooldown)))
|
||||
|
||||
(fx/defn cancel-contact-request
|
||||
"Cancels contact request"
|
||||
{:events [:chat.ui/cancel-contact-request]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [current-chat-id (:current-chat-id db)]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:chat/inputs current-chat-id :metadata :sending-contact-request] nil)}
|
||||
(mentions/clear-mentions)
|
||||
(mentions/clear-cursor)
|
||||
(clean-input (:current-chat-id db))
|
||||
(process-cooldown))))
|
||||
|
||||
(fx/defn chat-send-sticker
|
||||
{:events [:chat/send-sticker]}
|
||||
[{{:keys [current-chat-id] :as db} :db :as cofx} {:keys [hash packID] :as sticker}]
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
{::json-rpc/call [{:method "wakuext_chat"
|
||||
:params [chat-id]
|
||||
:on-success #(re-frame/dispatch [:chats-list/load-chat-success %])
|
||||
:on-failure #(log/error "failed to fetch chats" 0 -1 %)}]})
|
||||
:on-error #(log/error "failed to fetch chats" 0 -1 %)}]})
|
||||
|
||||
(fx/defn handle-failed-loading-messages
|
||||
{:events [::failed-loading-messages]}
|
||||
@@ -67,10 +67,8 @@
|
||||
|
||||
(fx/defn handle-mark-all-read-successful
|
||||
{:events [::mark-all-read-successful]}
|
||||
[{:keys [db] :as cofx} chat-id]
|
||||
(fx/merge cofx
|
||||
{:db (mark-chat-all-read db chat-id)}
|
||||
(notification-center/get-activity-center-notifications-count)))
|
||||
[cofx]
|
||||
(notification-center/get-activity-center-notifications-count cofx))
|
||||
|
||||
(fx/defn handle-mark-all-read-in-community-successful
|
||||
{:events [::mark-all-read-in-community-successful]}
|
||||
@@ -82,11 +80,12 @@
|
||||
(fx/defn handle-mark-all-read
|
||||
{:events [:chat.ui/mark-all-read-pressed :chat/mark-all-as-read]}
|
||||
[{db :db} chat-id]
|
||||
{:clear-message-notifications [[chat-id]
|
||||
{:db (mark-chat-all-read db chat-id)
|
||||
:clear-message-notifications [[chat-id]
|
||||
(get-in db [:multiaccount :remote-push-notifications-enabled?])]
|
||||
::json-rpc/call [{:method "wakuext_markAllRead"
|
||||
:params [chat-id]
|
||||
:on-success #(re-frame/dispatch [::mark-all-read-successful chat-id])}]})
|
||||
:on-success #(re-frame/dispatch [::mark-all-read-successful])}]})
|
||||
|
||||
(fx/defn handle-mark-mark-all-read-in-community
|
||||
{:events [:chat.ui/mark-all-read-in-community-pressed]}
|
||||
@@ -157,8 +156,7 @@
|
||||
(when (or first-request cursor)
|
||||
(merge
|
||||
{:db (assoc-in db [:pagination-info chat-id :loading-messages?] true)}
|
||||
{:utils/dispatch-later [{:ms 100 :dispatch [:load-more-reactions cursor chat-id]}
|
||||
{:ms 100 :dispatch [::models.pin-message/load-pin-messages chat-id]}]}
|
||||
{:utils/dispatch-later [{:ms 100 :dispatch [:load-more-reactions cursor chat-id]}]}
|
||||
(data-store.messages/messages-by-chat-id-rpc
|
||||
chat-id
|
||||
cursor
|
||||
@@ -176,5 +174,7 @@
|
||||
(when-not (get-in db [:pagination-info chat-id :messages-initialized?])
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:pagination-info chat-id :messages-initialized?] now)
|
||||
:utils/dispatch-later [{:ms 500 :dispatch [:chat.ui/mark-all-read-pressed chat-id]}]}
|
||||
:utils/dispatch-later [{:ms 50 :dispatch [:chat.ui/mark-all-read-pressed chat-id]}
|
||||
(when-not (get-in cofx [:db :chats chat-id :public?])
|
||||
{:ms 100 :dispatch [::models.pin-message/load-pin-messages chat-id]})]}
|
||||
(load-more-messages chat-id true))))
|
||||
|
||||
@@ -189,7 +189,8 @@
|
||||
:js-response true
|
||||
:on-success
|
||||
#(re-frame/dispatch [:transport/message-sent %])
|
||||
:on-failure #(log/error "failed to send a message" %)}]})
|
||||
:on-error
|
||||
#(log/error "failed to send a message" %)}]})
|
||||
|
||||
(fx/defn invite-users
|
||||
{:events [::invite-people-confirmation-pressed]}
|
||||
|
||||
@@ -13,6 +13,13 @@
|
||||
(def ^:const content-type-audio 8)
|
||||
(def ^:const content-type-community 9)
|
||||
(def ^:const content-type-gap 10)
|
||||
(def ^:const content-type-contact-request 11) ;; TODO: temp, will be removed
|
||||
|
||||
(def ^:const contact-request-state-none 0)
|
||||
(def ^:const contact-request-state-mutual 1)
|
||||
(def ^:const contact-request-state-sent 2)
|
||||
(def ^:const contact-request-state-received 3)
|
||||
(def ^:const contact-request-state-dismissed 4)
|
||||
|
||||
(def ^:const emoji-reaction-love 1)
|
||||
(def ^:const emoji-reaction-thumbs-up 2)
|
||||
@@ -28,6 +35,10 @@
|
||||
(def ^:const timeline-chat-type 5)
|
||||
(def ^:const community-chat-type 6)
|
||||
|
||||
(def ^:const contact-request-message-state-pending 1)
|
||||
(def ^:const contact-request-message-state-accepted 2)
|
||||
(def ^:const contact-request-message-state-declined 3)
|
||||
|
||||
(def request-to-join-pending-state 1)
|
||||
|
||||
(def reactions {emoji-reaction-love (:love resources/reactions)
|
||||
@@ -161,6 +172,8 @@
|
||||
(def ^:const activity-center-notification-type-private-group-chat 2)
|
||||
(def ^:const activity-center-notification-type-mention 3)
|
||||
(def ^:const activity-center-notification-type-reply 4)
|
||||
(def ^:const activity-center-notification-type-contact-request 5)
|
||||
(def ^:const activity-center-notification-type-contact-request-retracted 6)
|
||||
|
||||
(def ^:const visibility-status-unknown 0)
|
||||
(def ^:const visibility-status-automatic 1)
|
||||
@@ -173,4 +186,4 @@
|
||||
|
||||
(def ^:const sticker-pack-status-installed 1)
|
||||
(def ^:const sticker-pack-status-pending 2)
|
||||
(def ^:const sticker-pack-status-owned 3)
|
||||
(def ^:const sticker-pack-status-owned 3)
|
||||
|
||||
@@ -11,9 +11,8 @@
|
||||
:interceptors [(re-frame/inject-cofx :random-id-generator)]}
|
||||
[cofx {:keys [public-key ens-name]}]
|
||||
(fx/merge cofx
|
||||
{:dispatch-later [{:ms 1000 :dispatch [:chat.ui/start-chat public-key ens-name]}]}
|
||||
(notification-center/accept-all-activity-center-notifications-from-chat public-key)
|
||||
(navigation/pop-to-root-tab :chat-stack)))
|
||||
(chat/start-chat public-key ens-name)
|
||||
(notification-center/accept-all-activity-center-notifications-from-chat public-key)))
|
||||
|
||||
(fx/defn contact-code-submitted
|
||||
{:events [:contact.ui/contact-code-submitted]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
[status-im.data-store.contacts :as contacts-store]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.navigation :as navigation]
|
||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[status-im.utils.fx :as fx]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.constants :as constants]
|
||||
@@ -28,13 +29,6 @@
|
||||
(= public-key (:public-key multiaccount))
|
||||
(assoc :name (:name multiaccount))))
|
||||
|
||||
(defn- own-info
|
||||
[db]
|
||||
(let [{:keys [name preferred-name identicon address]} (:multiaccount db)]
|
||||
{:name (or preferred-name name)
|
||||
:profile-image identicon
|
||||
:address address}))
|
||||
|
||||
(fx/defn ensure-contacts
|
||||
[{:keys [db]} contacts chats]
|
||||
(let [events
|
||||
@@ -66,6 +60,13 @@
|
||||
(when (> (count events) 1)
|
||||
{:dispatch-n events}))))
|
||||
|
||||
(defn- own-info
|
||||
[db]
|
||||
(let [{:keys [name preferred-name identicon address]} (:multiaccount db)]
|
||||
{:name (or preferred-name name)
|
||||
:profile-image identicon
|
||||
:address address}))
|
||||
|
||||
(fx/defn send-contact-request
|
||||
{:events [::send-contact-request]}
|
||||
[{:keys [db] :as cofx} public-key]
|
||||
@@ -92,12 +93,33 @@
|
||||
"Remove a contact from current account's contact list"
|
||||
{:events [:contact.ui/remove-contact-pressed]}
|
||||
[{:keys [db]} {:keys [public-key]}]
|
||||
{:db (assoc-in db [:contacts/contacts public-key :added] false)
|
||||
{:db (-> db
|
||||
(assoc-in [:contacts/contacts public-key :added] false)
|
||||
(assoc-in [:contacts/contacts public-key :contact-request-state] constants/contact-request-state-none))
|
||||
::json-rpc/call [{:method "wakuext_removeContact"
|
||||
:params [public-key]
|
||||
:on-success #(log/debug "contact removed successfully")}
|
||||
{:method "wakuext_retractContactRequest"
|
||||
:params [{:contactId public-key}]
|
||||
:on-success #(log/debug "contact removed successfully")}]
|
||||
:dispatch [:offload-messages constants/timeline-chat-id]})
|
||||
|
||||
(fx/defn accept-contact-request
|
||||
{:events [:contact-requests.ui/accept-request]}
|
||||
[{:keys [db]} id]
|
||||
{::json-rpc/call [{:method "wakuext_acceptContactRequest"
|
||||
:params [{:id id}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]})
|
||||
|
||||
(fx/defn decline-contact-request
|
||||
{:events [:contact-requests.ui/decline-request]}
|
||||
[{:keys [db]} id]
|
||||
{::json-rpc/call [{:method "wakuext_dismissContactRequest"
|
||||
:params [{:id id}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]})
|
||||
|
||||
(fx/defn initialize-contacts [cofx]
|
||||
(contacts-store/fetch-contacts-rpc cofx #(re-frame/dispatch [::contacts-loaded %])))
|
||||
|
||||
@@ -119,3 +141,12 @@
|
||||
nickname
|
||||
#(re-frame/dispatch [:sanitize-messages-and-process-response %]))
|
||||
(navigation/navigate-back)))
|
||||
|
||||
(fx/defn switch-mutual-contact-requests-enabled
|
||||
{:events [:multiaccounts.ui/switch-mutual-contact-requests-enabled]}
|
||||
[cofx enabled?]
|
||||
(multiaccounts.update/multiaccount-update
|
||||
cofx
|
||||
:mutual-contact-enabled?
|
||||
enabled?
|
||||
nil))
|
||||
|
||||
@@ -40,8 +40,7 @@
|
||||
|
||||
(utils.universal-links/initialize)
|
||||
|
||||
(when config/quo-preview-enabled?
|
||||
(async-storage/get-item :new-ui-enabled? #(reset! config/new-ui-enabled? %)))
|
||||
(async-storage/get-item :new-ui-enabled? #(reset! config/new-ui-enabled? %))
|
||||
|
||||
;;DEV
|
||||
(snoopy/subscribe!)
|
||||
|
||||
@@ -107,4 +107,4 @@
|
||||
:params []
|
||||
:js-response true
|
||||
:on-success #(on-success ^js %)
|
||||
:on-failure #(log/error "failed to fetch chats" 0 -1 %)}]})
|
||||
:on-error #(log/error "failed to fetch chats" 0 -1 %)}]})
|
||||
|
||||
@@ -5,20 +5,25 @@
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn <-rpc [contact]
|
||||
(clojure.set/rename-keys contact {:id :public-key
|
||||
:ensVerifiedAt :ens-verified-at
|
||||
:ensVerified :ens-verified
|
||||
:ensVerificationRetries :ens-verification-retries
|
||||
:lastENSClockValue :last-ens-clock-value
|
||||
:lastUpdated :last-updated
|
||||
:localNickname :nickname}))
|
||||
(-> contact
|
||||
(clojure.set/rename-keys {:id :public-key
|
||||
:ensVerifiedAt :ens-verified-at
|
||||
:ensVerified :ens-verified
|
||||
:ensVerificationRetries :ens-verification-retries
|
||||
:hasAddedUs :has-added-us
|
||||
:contactRequestState :contact-request-state
|
||||
:lastENSClockValue :last-ens-clock-value
|
||||
:lastUpdated :last-updated
|
||||
:localNickname :nickname})
|
||||
(assoc :mutual? (and (:added contact)
|
||||
(:hasAddedUs contact)))))
|
||||
|
||||
(fx/defn fetch-contacts-rpc
|
||||
[_ on-success]
|
||||
{::json-rpc/call [{:method "wakuext_contacts"
|
||||
:params []
|
||||
:on-success #(on-success (map <-rpc %))
|
||||
:on-failure #(log/error "failed to fetch contacts" %)}]})
|
||||
:on-error #(log/error "failed to fetch contacts" %)}]})
|
||||
|
||||
(fx/defn add
|
||||
[_ public-key nickname ens-name on-success]
|
||||
@@ -29,7 +34,7 @@
|
||||
(log/info "saved contact" public-key "successfuly")
|
||||
(when on-success
|
||||
(on-success %)))
|
||||
:on-failure #(log/error "failed to add contact" public-key %)}]})
|
||||
:on-error #(log/error "failed to add contact" public-key %)}]})
|
||||
|
||||
(fx/defn set-nickname
|
||||
[_ public-key nickname on-success]
|
||||
@@ -40,18 +45,18 @@
|
||||
(log/debug "set contact nickname" public-key "successfuly" nickname)
|
||||
(when on-success
|
||||
(on-success %)))
|
||||
:on-failure #(log/error "failed to set contact nickname " public-key nickname %)}]})
|
||||
:on-error #(log/error "failed to set contact nickname " public-key nickname %)}]})
|
||||
|
||||
(fx/defn block [_ contact-id on-success]
|
||||
{::json-rpc/call [{:method "wakuext_blockContact"
|
||||
:params [contact-id]
|
||||
:js-response true
|
||||
:on-success on-success
|
||||
:on-failure #(log/error "failed to block contact" % contact-id)}]})
|
||||
:on-error #(log/error "failed to block contact" % contact-id)}]})
|
||||
|
||||
(fx/defn unblock [_ contact-id on-success]
|
||||
{::json-rpc/call [{:method "wakuext_unblockContact"
|
||||
:params [contact-id]
|
||||
:on-success on-success
|
||||
:js-response true
|
||||
:on-failure #(log/error "failed to unblock contact" % contact-id)}]})
|
||||
:on-error #(log/error "failed to unblock contact" % contact-id)}]})
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
:lastUpdated 1}
|
||||
expected-contact {:public-key "pk"
|
||||
:address "address"
|
||||
:mutual? nil
|
||||
:name "name"
|
||||
:identicon "identicon"
|
||||
:last-updated 1}]
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
(clojure.set/rename-keys {:id :message-id
|
||||
:whisperTimestamp :whisper-timestamp
|
||||
:editedAt :edited-at
|
||||
:contactRequestState :contact-request-state
|
||||
:commandParameters :command-parameters
|
||||
:gapParameters :gap-parameters
|
||||
:messageType :message-type
|
||||
@@ -53,12 +54,12 @@
|
||||
cursor
|
||||
limit
|
||||
on-success
|
||||
on-failure]
|
||||
on-error]
|
||||
{::json-rpc/call [{:method "wakuext_chatMessages"
|
||||
:params [chat-id cursor limit]
|
||||
:on-success (fn [result]
|
||||
(on-success (update result :messages #(map <-rpc %))))
|
||||
:on-failure on-failure}]})
|
||||
:on-error on-error}]})
|
||||
|
||||
(defn mark-seen-rpc [chat-id ids on-success]
|
||||
{::json-rpc/call [{:method "wakuext_markMessagesSeen"
|
||||
@@ -66,25 +67,25 @@
|
||||
:on-success #(do
|
||||
(log/debug "successfully marked as seen" %)
|
||||
(when on-success (on-success chat-id ids %)))
|
||||
:on-failure #(log/error "failed to get messages" %)}]})
|
||||
:on-error #(log/error "failed to get messages" %)}]})
|
||||
|
||||
(defn delete-message-rpc [id]
|
||||
{::json-rpc/call [{:method "wakuext_deleteMessage"
|
||||
:params [id]
|
||||
:on-success #(log/debug "successfully deleted message" id)
|
||||
:on-failure #(log/error "failed to delete message" % id)}]})
|
||||
:on-error #(log/error "failed to delete message" % id)}]})
|
||||
|
||||
(defn delete-messages-from-rpc [author]
|
||||
{::json-rpc/call [{:method "wakuext_deleteMessagesFrom"
|
||||
:params [author]
|
||||
:on-success #(log/debug "successfully deleted messages from" author)
|
||||
:on-failure #(log/error "failed to delete messages from" % author)}]})
|
||||
:on-error #(log/error "failed to delete messages from" % author)}]})
|
||||
|
||||
(defn delete-messages-by-chat-id-rpc [chat-id]
|
||||
{::json-rpc/call [{:method "wakuext_deleteMessagesByChatID"
|
||||
:params [chat-id]
|
||||
:on-success #(log/debug "successfully deleted messages by chat-id" chat-id)
|
||||
:on-failure #(log/error "failed to delete messages by chat-id" % chat-id)}]})
|
||||
:on-error #(log/error "failed to delete messages by chat-id" % chat-id)}]})
|
||||
|
||||
(fx/defn delete-message [cofx id]
|
||||
(delete-message-rpc id))
|
||||
|
||||
@@ -16,16 +16,16 @@
|
||||
cursor
|
||||
limit
|
||||
on-success
|
||||
on-failure]
|
||||
on-error]
|
||||
{::json-rpc/call [{:method "wakuext_chatPinnedMessages"
|
||||
:params [chat-id cursor limit]
|
||||
:on-success (fn [result]
|
||||
(let [result (clojure.set/rename-keys result {:pinnedMessages :pinned-messages})]
|
||||
(on-success (update result :pinned-messages #(map <-rpc %)))))
|
||||
:on-failure on-failure}]})
|
||||
:on-error on-error}]})
|
||||
|
||||
(fx/defn send-pin-message [cofx pin-message]
|
||||
{::json-rpc/call [{:method "wakuext_sendPinMessage"
|
||||
:params [(messages/->rpc pin-message)]
|
||||
:on-success #(log/debug "successfully pinned message" pin-message)
|
||||
:on-failure #(log/error "failed to pin message" % pin-message)}]})
|
||||
:on-error #(log/error "failed to pin message" % pin-message)}]})
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
cursor
|
||||
limit
|
||||
on-success
|
||||
on-failure]
|
||||
on-error]
|
||||
{::json-rpc/call [{:method "wakuext_emojiReactionsByChatID"
|
||||
:params [chat-id cursor limit]
|
||||
:on-success (fn [result]
|
||||
(on-success (map <-rpc result)))
|
||||
:on-failure on-failure}]})
|
||||
:on-error on-error}]})
|
||||
|
||||
@@ -20,5 +20,5 @@
|
||||
:on-success #(re-frame/dispatch
|
||||
[:visibility-status-updates/visibility-status-updates-loaded
|
||||
(:statusUpdates ^js %)])
|
||||
:on-failure #(log/error
|
||||
"failed to fetch visibility-status-updates" %)}]})
|
||||
:on-error #(log/error
|
||||
"failed to fetch visibility-status-updates" %)}]})
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
(ns status-im.ethereum.json-rpc
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ethereum.abi-spec :as abi-spec]
|
||||
[status-im.native-module.core :as status]
|
||||
[status-im.utils.types :as types]
|
||||
[status-im.utils.utils :as utils]
|
||||
@@ -40,25 +39,8 @@
|
||||
(.-result response-js)
|
||||
(types/js->clj (.-result response-js)))))))))))
|
||||
|
||||
(defn eth-call
|
||||
[{:keys [contract method params outputs on-success block]
|
||||
:or {block "latest" params []}
|
||||
:as arg}]
|
||||
(call {:method "eth_call"
|
||||
:params [{:to contract
|
||||
:data (abi-spec/encode method params)}
|
||||
(if (int? block)
|
||||
(abi-spec/number-to-hex block)
|
||||
block)]
|
||||
:on-success
|
||||
(if outputs
|
||||
#(on-success (abi-spec/decode % outputs))
|
||||
on-success)
|
||||
:on-error
|
||||
(on-error-retry eth-call arg)}))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::call
|
||||
(fn [params]
|
||||
(doseq [param params]
|
||||
(call param))))
|
||||
(call param))))
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
[status-im.wallet.core :as wallet]
|
||||
status-im.wallet.custom-tokens.core
|
||||
[status-im.navigation.core :as navigation.core]
|
||||
[status-im.multiaccounts.login.core :as login.core]
|
||||
[status-im.navigation.state :as navigation.state]
|
||||
[status-im.signing.core :as signing]
|
||||
status-im.wallet-connect.core
|
||||
status-im.wallet-connect-legacy.core
|
||||
@@ -123,7 +123,7 @@
|
||||
current-tab (get db :current-tab :chat)
|
||||
view-id (:view-id db)
|
||||
screen-params (get-in db [:navigation/screen-params view-id])
|
||||
root-id @navigation.core/root-id
|
||||
root-id @navigation.state/root-id
|
||||
dispatch-later (cond-> []
|
||||
(= view-id :chat)
|
||||
(conj {:ms 1000
|
||||
|
||||
@@ -15,15 +15,14 @@
|
||||
{:events [:navigate-chat-updated]}
|
||||
[cofx chat-id]
|
||||
(when (get-in cofx [:db :chats chat-id])
|
||||
(fx/merge cofx
|
||||
{:dispatch-later [{:ms 1000 :dispatch [:chat.ui/navigate-to-chat chat-id]}]}
|
||||
(navigation/pop-to-root-tab :chat-stack))))
|
||||
(models.chat/navigate-to-chat cofx chat-id)))
|
||||
|
||||
(fx/defn handle-chat-removed
|
||||
{:events [:chat-removed]}
|
||||
[cofx response]
|
||||
(fx/merge cofx
|
||||
{:dispatch-n [[:sanitize-messages-and-process-response response]
|
||||
{:db (dissoc (:db cofx) :current-chat-id)
|
||||
:dispatch-n [[:sanitize-messages-and-process-response response]
|
||||
[:pop-to-root-tab :chat-stack]]}
|
||||
(notification-center/get-activity-center-notifications-count)))
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
(def members-added-type 3)
|
||||
|
||||
(defn joined?
|
||||
[public-key {:keys [members-joined]}]
|
||||
(contains? members-joined public-key))
|
||||
(defn member?
|
||||
[public-key {:keys [contacts]}]
|
||||
(contains? contacts public-key))
|
||||
|
||||
(defn invited?
|
||||
[my-public-key {:keys [contacts]}]
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
(ns status-im.integration-test
|
||||
(:require [day8.re-frame.test :as rf-test]
|
||||
status-im.events
|
||||
[re-frame.core :as rf]
|
||||
[status-im.transport.core :as transport]
|
||||
[cljs.test :refer [deftest is]]
|
||||
[status-im.utils.test :as utils.test]))
|
||||
|
||||
(def password "testabc")
|
||||
|
||||
(utils.test/init!)
|
||||
|
||||
(def initialize-app!
|
||||
#(rf/dispatch-sync [:init/app-started]))
|
||||
|
||||
(def generate-and-derive-addresses!
|
||||
#(rf/dispatch [:generate-and-derive-addresses]))
|
||||
|
||||
(def create-multiaccount!
|
||||
#(rf/dispatch [:create-multiaccount password]))
|
||||
|
||||
(def assert-app-initialized
|
||||
#(let [app-state @(rf/subscribe [:app-state])
|
||||
multiaccounts-loading? @(rf/subscribe [:multiaccounts/loading])]
|
||||
(is (= "active" app-state))
|
||||
(is (false? multiaccounts-loading?))))
|
||||
|
||||
(def assert-multiaccounts-generated
|
||||
#(let [wizard-state @(rf/subscribe [:intro-wizard/choose-key])]
|
||||
(is (= 5 (count (:multiaccounts wizard-state))))))
|
||||
|
||||
(defn messenger-started []
|
||||
@(rf/subscribe [:messenger/started?]))
|
||||
|
||||
(def assert-messenger-started
|
||||
#(is (messenger-started)))
|
||||
|
||||
(deftest initialize-app-test
|
||||
(rf-test/run-test-sync
|
||||
(rf/dispatch [:init/app-started])
|
||||
(assert-app-initialized)))
|
||||
|
||||
(defn assert-multiaccount-loaded []
|
||||
(is (false? @(rf/subscribe [:multiaccounts/loading]))))
|
||||
|
||||
(deftest create-account-test
|
||||
(rf-test/run-test-async
|
||||
(initialize-app!) ; initialize app
|
||||
(rf-test/wait-for
|
||||
[:status-im.init.core/initialize-multiaccounts] ; wait so we load accounts.db
|
||||
(generate-and-derive-addresses!) ; generate 5 new keys
|
||||
(rf-test/wait-for
|
||||
[:multiaccount-generate-and-derive-addresses-success] ; wait for the keys
|
||||
(assert-multiaccount-loaded) ; assert keys are generated
|
||||
(create-multiaccount!) ; create a multiaccount
|
||||
(rf-test/wait-for ; wait for login
|
||||
[::transport/messenger-started]
|
||||
(assert-messenger-started))))))
|
||||
@@ -432,7 +432,7 @@
|
||||
(types/clj->json accounts-data)))
|
||||
|
||||
(defn login [{:keys [key-uid multiaccount-data password]}]
|
||||
(status/login key-uid multiaccount-data password))
|
||||
(status/login-with-config key-uid multiaccount-data password nil))
|
||||
|
||||
(defn send-transaction-with-signature
|
||||
[{:keys [transaction on-completed]}]
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
(re-frame/reg-fx
|
||||
::login
|
||||
(fn [[key-uid account-data hashed-password]]
|
||||
(status/login key-uid account-data hashed-password)))
|
||||
(status/login-with-config key-uid account-data hashed-password nil)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::export-db
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
(let [key-uid (get-in db [:multiaccount :key-uid])]
|
||||
(fx/merge cofx
|
||||
{:init-root-fx :progress
|
||||
:chat.ui/clear-inputs nil
|
||||
:hide-popover nil
|
||||
::logout nil
|
||||
::multiaccounts/webview-debug-changed false
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(:require [status-im.constants :as constants]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.utils.types :as types]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(fx/defn send-multiaccount-update [{:keys [db] :as cofx}]
|
||||
@@ -41,17 +42,35 @@
|
||||
:mnemonic nil
|
||||
{}))
|
||||
|
||||
(defn augment-synchronized-recent-stickers
|
||||
"Add 'url' parameter to stickers that are synchronized from other devices.
|
||||
It is not sent from aanother devices but we have it in our db."
|
||||
[synced-stickers stickers-from-db]
|
||||
(mapv #(assoc % :url (->> (get stickers-from-db (:packID %))
|
||||
(:stickers)
|
||||
(filter (fn [sticker-db] (= (:hash sticker-db) (:hash %))))
|
||||
(first)
|
||||
(:url)))
|
||||
synced-stickers))
|
||||
|
||||
(fx/defn optimistic
|
||||
[{:keys [db] :as cofx} setting setting-value]
|
||||
(let [current-multiaccount (:multiaccount db)
|
||||
setting-value (if (= :currency setting)
|
||||
(keyword setting-value)
|
||||
setting-value)
|
||||
db (if (= :stickers/packs-installed setting)
|
||||
;;updating :stickers/packs for installed stickers
|
||||
(let [packs-installed-keys (keys (js->clj setting-value))]
|
||||
(reduce #(assoc-in %1 [:stickers/packs %2 :status] constants/sticker-pack-status-installed) db packs-installed-keys))
|
||||
db)]
|
||||
db (case setting
|
||||
:stickers/packs-pending
|
||||
(let [packs-pending (keys (js->clj setting-value))]
|
||||
(update db :stickers/packs-pending conj packs-pending))
|
||||
:stickers/packs-installed
|
||||
(let [packs-installed-keys (keys (js->clj setting-value))]
|
||||
(reduce #(assoc-in %1 [:stickers/packs %2 :status] constants/sticker-pack-status-installed) db packs-installed-keys))
|
||||
:stickers/recent-stickers
|
||||
(let [recent-stickers-from-remote (augment-synchronized-recent-stickers (types/js->clj setting-value) (:stickers/packs db))
|
||||
merged (into recent-stickers-from-remote (:stickers/recent-stickers db))]
|
||||
(assoc db :stickers/recent-stickers recent-stickers-from-remote))
|
||||
db)]
|
||||
{:db (if setting-value
|
||||
(assoc-in db [:multiaccount setting] setting-value)
|
||||
(update db :multiaccount dissoc setting))}))
|
||||
|
||||
@@ -64,6 +64,16 @@
|
||||
key-uid
|
||||
#(.login ^js (status) account-data hashed-password)))
|
||||
|
||||
(defn login-with-config
|
||||
"NOTE: beware, the password has to be sha3 hashed"
|
||||
[key-uid account-data hashed-password config]
|
||||
(log/debug "[native-module] loginWithConfig")
|
||||
(clear-web-data)
|
||||
(let [config (if config (types/clj->json config) "")]
|
||||
(init-keystore
|
||||
key-uid
|
||||
#(.loginWithConfig ^js (status) account-data hashed-password config))))
|
||||
|
||||
(defn export-db
|
||||
"NOTE: beware, the password has to be sha3 hashed"
|
||||
[key-uid account-data hashed-password callback]
|
||||
|
||||
@@ -14,19 +14,13 @@
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.utils.platform :as platform]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.multiaccounts.login.core :as login-core]))
|
||||
[status-im.multiaccounts.login.core :as login-core]
|
||||
[status-im.navigation.state :as state]))
|
||||
|
||||
(def debug? ^boolean js/goog.DEBUG)
|
||||
|
||||
(def splash-screen (-> rn .-NativeModules .-SplashScreen))
|
||||
|
||||
(defonce root-comp-id (atom nil))
|
||||
(defonce root-id (atom nil))
|
||||
(defonce pushed-screen-id (atom nil))
|
||||
(defonce curr-modal (atom nil))
|
||||
(defonce modals (atom []))
|
||||
(defonce dissmissing (atom false))
|
||||
|
||||
(defonce set-navigation-default-options
|
||||
(.setDefaultOptions Navigation (clj->js {:layout {:orientation "portrait"}})))
|
||||
|
||||
@@ -43,19 +37,19 @@
|
||||
|
||||
(defn dismiss-all-modals []
|
||||
(log/debug "dissmiss-all-modals")
|
||||
(when @curr-modal
|
||||
(reset! curr-modal false)
|
||||
(reset! dissmissing true)
|
||||
(doseq [modal @modals]
|
||||
(when @state/curr-modal
|
||||
(reset! state/curr-modal false)
|
||||
(reset! state/dissmissing true)
|
||||
(doseq [modal @state/modals]
|
||||
(.dismissModal Navigation (name modal)))
|
||||
(reset! modals [])))
|
||||
(reset! state/modals [])))
|
||||
|
||||
;; PUSH SCREEN
|
||||
(defn navigate [comp]
|
||||
(log/debug "NAVIGATE" comp)
|
||||
(let [{:keys [options]} (get views/screens comp)]
|
||||
(.push Navigation
|
||||
(name @root-comp-id)
|
||||
(name @state/root-comp-id)
|
||||
(clj->js {:component {:id comp
|
||||
:name comp
|
||||
:options (merge options
|
||||
@@ -80,11 +74,11 @@
|
||||
(defn open-modal [comp]
|
||||
(log/debug "open-modal" comp)
|
||||
(let [{:keys [options]} (get views/screens comp)]
|
||||
(if @dissmissing
|
||||
(reset! dissmissing comp)
|
||||
(if @state/dissmissing
|
||||
(reset! state/dissmissing comp)
|
||||
(do
|
||||
(reset! curr-modal true)
|
||||
(swap! modals conj comp)
|
||||
(reset! state/curr-modal true)
|
||||
(swap! state/modals conj comp)
|
||||
(.showModal Navigation
|
||||
(clj->js {:stack {:children
|
||||
[{:component
|
||||
@@ -100,8 +94,8 @@
|
||||
;; DISSMISS MODAL
|
||||
(defn dissmissModal []
|
||||
(log/debug "dissmissModal")
|
||||
(reset! dissmissing true)
|
||||
(.dismissModal Navigation (name (last @modals))))
|
||||
(reset! state/dissmissing true)
|
||||
(.dismissModal Navigation (name (last @state/modals))))
|
||||
|
||||
(defonce register-nav-button-reg
|
||||
(.registerNavigationButtonPressedListener
|
||||
@@ -110,7 +104,7 @@
|
||||
(let [id (.-buttonId evn)]
|
||||
(if (= "dismiss-modal" id)
|
||||
(do
|
||||
(when-let [event (get-in views/screens [(last @modals) :on-dissmiss])]
|
||||
(when-let [event (get-in views/screens [(last @state/modals) :on-dissmiss])]
|
||||
(re-frame/dispatch event))
|
||||
(dissmissModal))
|
||||
(when-let [handler (get-in views/screens [(keyword id) :right-handler])]
|
||||
@@ -128,17 +122,17 @@
|
||||
(.registerModalDismissedListener
|
||||
(.events Navigation)
|
||||
(fn [_]
|
||||
(if (> (count @modals) 1)
|
||||
(let [new-modals (butlast @modals)]
|
||||
(reset! modals (vec new-modals))
|
||||
(if (> (count @state/modals) 1)
|
||||
(let [new-modals (butlast @state/modals)]
|
||||
(reset! state/modals (vec new-modals))
|
||||
(set-view-id (last new-modals)))
|
||||
(do
|
||||
(reset! modals [])
|
||||
(reset! curr-modal false)
|
||||
(set-view-id @pushed-screen-id)))
|
||||
(reset! state/modals [])
|
||||
(reset! state/curr-modal false)
|
||||
(set-view-id @state/pushed-screen-id)))
|
||||
|
||||
(let [comp @dissmissing]
|
||||
(reset! dissmissing false)
|
||||
(let [comp @state/dissmissing]
|
||||
(reset! state/dissmissing false)
|
||||
(when (keyword? comp)
|
||||
(open-modal comp))))))
|
||||
|
||||
@@ -154,8 +148,8 @@
|
||||
(not= view-id :popover)
|
||||
(not= view-id :visibility-status-popover))
|
||||
(set-view-id view-id)
|
||||
(when-not @curr-modal
|
||||
(reset! pushed-screen-id view-id))))))))
|
||||
(when-not @state/curr-modal
|
||||
(reset! state/pushed-screen-id view-id))))))))
|
||||
|
||||
;; SCREEN DID DISAPPEAR
|
||||
(defonce screen-disappear-reg
|
||||
@@ -176,16 +170,16 @@
|
||||
:init-root-fx
|
||||
(fn [new-root-id]
|
||||
(log/debug :init-root-fx new-root-id)
|
||||
(reset! root-comp-id new-root-id)
|
||||
(reset! root-id @root-comp-id)
|
||||
(reset! state/root-comp-id new-root-id)
|
||||
(reset! state/root-id @state/root-comp-id)
|
||||
(.setRoot Navigation (clj->js (get (roots/roots) new-root-id)))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:init-root-with-component-fx
|
||||
(fn [[new-root-id new-root-comp-id]]
|
||||
(log/debug :init-root-with-component-fx new-root-id new-root-comp-id)
|
||||
(reset! root-comp-id new-root-comp-id)
|
||||
(reset! root-id @root-comp-id)
|
||||
(reset! state/root-comp-id new-root-comp-id)
|
||||
(reset! state/root-id @state/root-comp-id)
|
||||
(.setRoot Navigation (clj->js (get (roots/roots) new-root-id)))))
|
||||
|
||||
(fx/defn set-multiaccount-root
|
||||
@@ -201,13 +195,14 @@
|
||||
(defonce rset-app-launched
|
||||
(.registerAppLaunchedListener (.events Navigation)
|
||||
(fn []
|
||||
(reset! curr-modal false)
|
||||
(reset! dissmissing false)
|
||||
(if (or (= @root-id :multiaccounts) (= @root-id :multiaccounts-keycard))
|
||||
(reset! state/curr-modal false)
|
||||
(reset! state/dissmissing false)
|
||||
(if (or (= @state/root-id :multiaccounts)
|
||||
(= @state/root-id :multiaccounts-keycard))
|
||||
(re-frame/dispatch-sync [::set-multiaccount-root])
|
||||
(when @root-id
|
||||
(reset! root-comp-id @root-id)
|
||||
(.setRoot Navigation (clj->js (get (roots/roots) @root-id)))
|
||||
(when @state/root-id
|
||||
(reset! state/root-comp-id @state/root-id)
|
||||
(.setRoot Navigation (clj->js (get (roots/roots) @state/root-id)))
|
||||
(re-frame/dispatch [::login-core/check-last-chat])))
|
||||
(.hide ^js splash-screen))))
|
||||
|
||||
@@ -248,7 +243,7 @@
|
||||
:change-tab-fx
|
||||
(fn [tab]
|
||||
(log/debug :change-tab-fx)
|
||||
(reset! root-comp-id (get tab-root-ids (get tab-key-idx tab)))
|
||||
(reset! state/root-comp-id (get tab-root-ids (get tab-key-idx tab)))
|
||||
(.mergeOptions Navigation "tabs-stack" (clj->js {:bottomTabs {:currentTabIndex (get tab-key-idx tab)}}))
|
||||
;;when we change tab we want to dismiss all modals
|
||||
(dismiss-all-modals)))
|
||||
@@ -289,9 +284,12 @@
|
||||
comp (get tab-root-ids selected-tab-index)
|
||||
tab-key (get (clojure.set/map-invert tab-key-idx) selected-tab-index)]
|
||||
(re-frame/dispatch [:set :current-tab tab-key])
|
||||
(when (and platform/android? (= @root-comp-id comp))
|
||||
(.popToRoot Navigation (name comp)))
|
||||
(reset! root-comp-id comp)))))
|
||||
(when (= @state/root-comp-id comp)
|
||||
(when (= :chat tab-key)
|
||||
(re-frame/dispatch [:close-chat]))
|
||||
(when platform/android?
|
||||
(.popToRoot Navigation (name comp))))
|
||||
(reset! state/root-comp-id comp)))))
|
||||
|
||||
;; OVERLAY (Popover and bottom sheets)
|
||||
(defn dissmiss-overlay [comp]
|
||||
@@ -405,15 +403,15 @@
|
||||
:navigate-back-fx
|
||||
(fn []
|
||||
(log/debug :navigate-back-fx)
|
||||
(if @curr-modal
|
||||
(if @state/curr-modal
|
||||
(dissmissModal)
|
||||
(.pop Navigation (name @root-comp-id)))))
|
||||
(.pop Navigation (name @state/root-comp-id)))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:navigate-replace-fx
|
||||
(fn [view-id]
|
||||
(log/debug :navigate-replace-fx view-id)
|
||||
(.pop Navigation (name @root-comp-id))
|
||||
(.pop Navigation (name @state/root-comp-id))
|
||||
(navigate view-id)))
|
||||
|
||||
(def community-screens '(:community-management
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
(ns status-im.navigation.state)
|
||||
|
||||
(defonce root-comp-id (atom nil))
|
||||
(defonce root-id (atom nil))
|
||||
(defonce pushed-screen-id (atom nil))
|
||||
(defonce curr-modal (atom nil))
|
||||
(defonce modals (atom []))
|
||||
(defonce dissmissing (atom false))
|
||||
@@ -1,23 +1,38 @@
|
||||
(ns status-im.notifications-center.core
|
||||
(:require [status-im.utils.fx :as fx]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.constants :as constants]
|
||||
[taoensso.timbre :as log]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.data-store.activities :as data-store.activities]))
|
||||
|
||||
(def non-dismissable-notifications
|
||||
#{constants/activity-center-notification-type-contact-request
|
||||
constants/activity-center-notification-type-contact-request-retracted})
|
||||
|
||||
(fx/defn handle-activities [{:keys [db]} activities]
|
||||
(let [{:keys [unread-count notifications]}
|
||||
(reduce (fn [acc {:keys [read dismissed accepted] :as notification}]
|
||||
(as-> acc a
|
||||
(if read
|
||||
(update a :unread-count dec)
|
||||
(update a :unread-count inc))
|
||||
(let [index-existing (->> (map-indexed vector (:notifications acc))
|
||||
(filter (fn [[idx {:keys [id]}]] (= id (:id notification))))
|
||||
first
|
||||
first)]
|
||||
(as-> acc a
|
||||
(if read
|
||||
(update a :unread-count dec)
|
||||
(update a :unread-count inc))
|
||||
|
||||
(if (or dismissed accepted)
|
||||
(update a :notifications (fn [items] (remove #(= (:id notification) (:id %)) items)))
|
||||
(update a :notifications conj notification))))
|
||||
(if index-existing
|
||||
(if (or dismissed accepted)
|
||||
;; Remove at specific location
|
||||
(assoc a :notifications
|
||||
(into (subvec (:notifications a) 0 index-existing) (subvec (:notifications a) (inc index-existing))))
|
||||
;; Replace element
|
||||
(do
|
||||
(assoc-in a [:notifications index-existing] notification)))
|
||||
(update a :notifications conj notification)))))
|
||||
{:unread-count (get db :activity.center/notifications-count 0)
|
||||
:notifications (get-in db [:activity.center/notifications :notifications])}
|
||||
:notifications (into [] (get-in db [:activity.center/notifications :notifications]))}
|
||||
activities)]
|
||||
(merge
|
||||
{:db (-> db
|
||||
@@ -69,14 +84,21 @@
|
||||
{:events [:accept-all-activity-center-notifications-from-chat]}
|
||||
[{:keys [db]} chat-id]
|
||||
(let [notifications (get-in db [:activity.center/notifications :notifications])
|
||||
notifications-from-chat (filter #(= chat-id (:chat-id %)) notifications)
|
||||
notifications-from-chat (filter #(and
|
||||
(= chat-id (:chat-id %))
|
||||
(not (contains? non-dismissable-notifications (:type %))))
|
||||
notifications)
|
||||
notifications-from-chat-not-read (filter #(and (= chat-id (:chat-id %))
|
||||
(not (:read %))) notifications)
|
||||
ids (map :id notifications-from-chat)]
|
||||
(not (:read %)))
|
||||
notifications)
|
||||
ids (into #{} (map :id notifications-from-chat))]
|
||||
(when (seq ids)
|
||||
{:db (-> db
|
||||
(update-in [:activity.center/notifications :notifications]
|
||||
(fn [items] (filter #(not (= chat-id (:chat-id %))) items)))
|
||||
(fn [items]
|
||||
(filter
|
||||
#(not (contains? ids (:id %)))
|
||||
items)))
|
||||
(update :activity.center/notifications-count - (min (db :activity.center/notifications-count) (count notifications-from-chat-not-read))))
|
||||
::json-rpc/call [{:method "wakuext_acceptActivityCenterNotifications"
|
||||
:params [ids]
|
||||
@@ -170,4 +192,3 @@
|
||||
(update-in [:activity.center/notifications :notifications]
|
||||
concat
|
||||
(map data-store.activities/<-rpc notifications)))})
|
||||
|
||||
|
||||
@@ -9,29 +9,29 @@
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.multiaccounts.update.core :as multiaccounts.update]))
|
||||
|
||||
(defn enable-installation-rpc [installation-id on-success on-failure]
|
||||
(defn enable-installation-rpc [installation-id on-success on-error]
|
||||
(json-rpc/call {:method "wakuext_enableInstallation"
|
||||
:params [installation-id]
|
||||
:on-success on-success
|
||||
:on-failure on-failure}))
|
||||
:on-error on-error}))
|
||||
|
||||
(defn disable-installation-rpc [installation-id on-success on-failure]
|
||||
(defn disable-installation-rpc [installation-id on-success on-error]
|
||||
(json-rpc/call {:method "wakuext_disableInstallation"
|
||||
:params [installation-id]
|
||||
:on-success on-success
|
||||
:on-failure on-failure}))
|
||||
:on-error on-error}))
|
||||
|
||||
(defn set-installation-metadata-rpc [installation-id metadata on-success on-failure]
|
||||
(defn set-installation-metadata-rpc [installation-id metadata on-success on-error]
|
||||
(json-rpc/call {:method "wakuext_setInstallationMetadata"
|
||||
:params [installation-id metadata]
|
||||
:on-success on-success
|
||||
:on-failure on-failure}))
|
||||
:on-error on-error}))
|
||||
|
||||
(defn get-our-installations-rpc [on-success on-failure]
|
||||
(defn get-our-installations-rpc [on-success on-error]
|
||||
(json-rpc/call {:method "wakuext_getOurInstallations"
|
||||
:params []
|
||||
:on-success on-success
|
||||
:on-failure on-failure}))
|
||||
:on-error on-error}))
|
||||
|
||||
(defn compare-installation
|
||||
"Sort installations, first by our installation-id, then on whether is
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
(fx/defn handle-public-chat [cofx {:keys [topic]}]
|
||||
(when (seq topic)
|
||||
(chat/start-public-chat cofx topic {})))
|
||||
(chat/start-public-chat cofx topic)))
|
||||
|
||||
(fx/defn handle-group-chat [cofx params]
|
||||
(group-chats/create-from-link cofx params))
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
:notifications (js/require "../resources/images/ui/notifications.png")
|
||||
:collectible (js/require "../resources/images/ui/collectible.png")
|
||||
:collectible-dark (js/require "../resources/images/ui/collectible-dark.png")
|
||||
:hand-wave (js/require "../resources/images/ui/hand-wave.png")
|
||||
:graph (js/require "../resources/images/ui/graph.png")})
|
||||
|
||||
(defn get-theme-image [k]
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
:gasLimit (money/to-fixed (money/bignumber gas)))
|
||||
clj->js)]
|
||||
:on-success #(log/info "pending transfer is saved")
|
||||
:on-failure #(log/info "pending transfer was not saved" %)}]}))
|
||||
:on-error #(log/info "pending transfer was not saved" %)}]}))
|
||||
|
||||
(defn get-method-type [data]
|
||||
(cond
|
||||
@@ -445,15 +445,6 @@
|
||||
{:db (update db :signing/queue conj (normalize-tx-obj db tx))}
|
||||
(check-queue)))
|
||||
|
||||
(fx/defn eth-transaction-call
|
||||
"Prepares tx-obj for contract call and show signing sheet"
|
||||
[cofx {:keys [contract method params on-result on-error from]}]
|
||||
(sign cofx {:tx-obj {:to contract
|
||||
:data (abi-spec/encode method params)
|
||||
:from from}
|
||||
:on-result on-result
|
||||
:on-error on-error}))
|
||||
|
||||
(fx/defn sign-transaction-button-clicked-from-chat
|
||||
{:events [:wallet.ui/sign-transaction-button-clicked-from-chat]}
|
||||
[{:keys [db] :as cofx} {:keys [to amount from token]}]
|
||||
|
||||
+56
-6
@@ -13,6 +13,7 @@
|
||||
[status-im.ethereum.tokens :as tokens]
|
||||
[status-im.ethereum.transactions.core :as transactions]
|
||||
[status-im.fleet.core :as fleet]
|
||||
[status-im.mailserver.core :as mailserver]
|
||||
[status-im.group-chats.db :as group-chats.db]
|
||||
[status-im.communities.core :as communities]
|
||||
[status-im.group-chats.core :as group-chat]
|
||||
@@ -264,6 +265,13 @@
|
||||
(reg-root-key-sub :wallet-connect/sessions :wallet-connect/sessions)
|
||||
(reg-root-key-sub :wallet-connect-legacy/sessions :wallet-connect-legacy/sessions)
|
||||
(reg-root-key-sub :wallet-connect/session-managed :wallet-connect/session-managed)
|
||||
(reg-root-key-sub :contact-requests/pending :contact-requests/pending)
|
||||
|
||||
|
||||
; Testing
|
||||
|
||||
|
||||
(reg-root-key-sub :messenger/started? :messenger/started?)
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities
|
||||
@@ -941,6 +949,13 @@
|
||||
(fn [ui-props [_ prop]]
|
||||
(get ui-props prop)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-contact
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:chats/current-chat-id]
|
||||
(fn [[contacts current-chat-id]]
|
||||
(get contacts current-chat-id)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/home-list-chats
|
||||
:<- [::chats]
|
||||
@@ -1033,23 +1048,34 @@
|
||||
:<- [:multiaccount/public-key]
|
||||
:<- [:communities/current-community]
|
||||
:<- [:contacts/blocked-set]
|
||||
(fn [[{:keys [group-chat chat-id] :as current-chat} my-public-key community blocked-users-set]]
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:chat/inputs]
|
||||
:<- [:mutual-contact-requests/enabled?]
|
||||
(fn [[{:keys [group-chat chat-id] :as current-chat} my-public-key community blocked-users-set contacts inputs mutual-contact-requests-enabled?]]
|
||||
(when current-chat
|
||||
(cond-> current-chat
|
||||
(chat.models/public-chat? current-chat)
|
||||
(assoc :show-input? true)
|
||||
|
||||
(and (chat.models/group-chat? current-chat)
|
||||
(group-chats.db/joined? my-public-key current-chat))
|
||||
(group-chats.db/member? my-public-key current-chat))
|
||||
(assoc :show-input? true
|
||||
:joined? true)
|
||||
:member? true)
|
||||
|
||||
(and (chat.models/community-chat? current-chat)
|
||||
(communities/can-post? community my-public-key (:chat-id current-chat)))
|
||||
(assoc :show-input? true)
|
||||
|
||||
(not group-chat)
|
||||
(assoc :show-input? (not (contains? blocked-users-set chat-id)))))))
|
||||
(assoc :show-input?
|
||||
(and
|
||||
(or
|
||||
(not mutual-contact-requests-enabled?)
|
||||
(get-in inputs [chat-id :metadata :sending-contact-request])
|
||||
(and mutual-contact-requests-enabled?
|
||||
(= constants/contact-request-state-mutual
|
||||
(get-in contacts [chat-id :contact-request-state]))))
|
||||
(not (contains? blocked-users-set chat-id))))))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-chat-view
|
||||
@@ -1300,6 +1326,12 @@
|
||||
(fn [{:keys [metadata]}]
|
||||
(:editing-message metadata)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/sending-contact-request
|
||||
:<- [:chats/current-chat-inputs]
|
||||
(fn [{:keys [metadata]}]
|
||||
(:sending-contact-request metadata)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/sending-image
|
||||
:<- [:chats/current-chat-inputs]
|
||||
@@ -1321,22 +1353,27 @@
|
||||
:<- [:current-chat/metadata]
|
||||
:<- [:chats/reply-message]
|
||||
:<- [:chats/edit-message]
|
||||
(fn [[{:keys [processing]} sending-image mainnet? one-to-one-chat? {:keys [public?]} reply edit]]
|
||||
:<- [:chats/sending-contact-request]
|
||||
(fn [[{:keys [processing]} sending-image mainnet? one-to-one-chat? {:keys [public?]} reply edit sending-contact-request]]
|
||||
(let [sending-image (seq sending-image)]
|
||||
{:send (not processing)
|
||||
:stickers (and (or config/stickers-test-enabled? mainnet?)
|
||||
(not sending-image)
|
||||
(not sending-contact-request)
|
||||
(not reply))
|
||||
:image (and (not reply)
|
||||
(not edit)
|
||||
(not sending-contact-request)
|
||||
(not public?))
|
||||
:extensions (and one-to-one-chat?
|
||||
(or config/commands-enabled? mainnet?)
|
||||
(not edit)
|
||||
(not sending-contact-request)
|
||||
(not reply))
|
||||
:audio (and (not sending-image)
|
||||
(not reply)
|
||||
(not edit)
|
||||
(not sending-contact-request)
|
||||
(not public?))
|
||||
:sending-image sending-image})))
|
||||
|
||||
@@ -1381,7 +1418,7 @@
|
||||
[(re-frame/subscribe [:chat-by-id chat-id])
|
||||
(re-frame/subscribe [:multiaccount/public-key])])
|
||||
(fn [[chat my-public-key]]
|
||||
{:joined? (group-chats.db/joined? my-public-key chat)
|
||||
{:member? (group-chats.db/member? my-public-key chat)
|
||||
:inviter-pk (group-chats.db/get-inviter-pk my-public-key chat)}))
|
||||
|
||||
(re-frame/reg-sub
|
||||
@@ -1896,6 +1933,8 @@
|
||||
(filter (fn [{:keys [type last-message]}]
|
||||
(or (and (= constants/activity-center-notification-type-one-to-one-chat type)
|
||||
(not (nil? last-message)))
|
||||
(= constants/activity-center-notification-type-contact-request type)
|
||||
(= constants/activity-center-notification-type-contact-request-retracted type)
|
||||
(= constants/activity-center-notification-type-private-group-chat type)
|
||||
(= constants/activity-center-notification-type-reply type)
|
||||
(= constants/activity-center-notification-type-mention type)))
|
||||
@@ -2217,6 +2256,12 @@
|
||||
(fn [multiaccount]
|
||||
(get multiaccount :profile-pictures-show-to)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:mutual-contact-requests/enabled?
|
||||
:<- [:multiaccount]
|
||||
(fn [settings]
|
||||
(boolean (:mutual-contact-enabled? settings))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::profile-pictures-visibility
|
||||
:<- [:multiaccount]
|
||||
@@ -2448,6 +2493,11 @@
|
||||
(= (get-in mailserver [:id :value])
|
||||
current-mailserver-id)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:mailserver/use-status-nodes?
|
||||
(fn [db _]
|
||||
(boolean (mailserver/fetch-use-mailservers? {:db db}))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:mailserver.edit/validation-errors
|
||||
:<- [:mailserver.edit/mailserver]
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
[_]
|
||||
{::json-rpc/call [{:method "wakuext_startMessenger"
|
||||
:on-success #(re-frame/dispatch [::messenger-started %])
|
||||
:on-failure #(log/error "failed to start messenger")}]})
|
||||
:on-error #(log/error "failed to start messenger")}]})
|
||||
|
||||
(fx/defn messenger-started
|
||||
{:events [::messenger-started]}
|
||||
|
||||
@@ -31,18 +31,20 @@
|
||||
:params [(mapv build-message messages)]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent %])
|
||||
:on-failure #(log/error "failed to send a message" %)}]})
|
||||
:on-error #(do
|
||||
(log/warn "failed to send a message" %)
|
||||
(js/alert (str "failed to send a message: " %)))}]})
|
||||
|
||||
(fx/defn send-reaction [_ {:keys [message-id chat-id emoji-id]}]
|
||||
{::json-rpc/call [{:method "wakuext_sendEmojiReaction"
|
||||
:params [chat-id message-id emoji-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-failure #(log/error "failed to send a reaction" %)}]})
|
||||
:on-error #(log/error "failed to send a reaction" %)}]})
|
||||
|
||||
(fx/defn send-retract-reaction [_ {:keys [emoji-reaction-id]}]
|
||||
{::json-rpc/call [{:method "wakuext_sendEmojiReactionRetraction"
|
||||
:params [emoji-reaction-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-failure #(log/error "failed to send a reaction retraction" %)}]})
|
||||
:on-error #(log/error "failed to send a reaction retraction" %)}]})
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
(ns status-im.ui.components.fast-image
|
||||
(:require [reagent.core :as reagent]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.components.react :as react]))
|
||||
|
||||
(defn placeholder [style child]
|
||||
[react/view {:style (merge style {:flex 1 :justify-content :center :align-items :center})}
|
||||
child])
|
||||
|
||||
(defn fast-image [_]
|
||||
(let [loaded? (reagent/atom false)
|
||||
error? (reagent/atom false)]
|
||||
(fn [props]
|
||||
[react/fast-image-class (merge
|
||||
props
|
||||
{:on-error (fn [e]
|
||||
(when-let [on-error (:on-error props)]
|
||||
(on-error e))
|
||||
(reset! error? true))
|
||||
:on-load (fn [e]
|
||||
(when-let [on-load (:on-load props)]
|
||||
(on-load e))
|
||||
(reset! loaded? true))})
|
||||
(when (or @error? (not @loaded?))
|
||||
[placeholder (:style props)
|
||||
(if @error?
|
||||
[icons/icon :main-icons/cancel]
|
||||
(when-not @loaded?
|
||||
[react/activity-indicator {:animating true}]))])])))
|
||||
@@ -6,7 +6,7 @@
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.utils :as utils]
|
||||
["react" :as reactjs]
|
||||
["react-native" :as react-native :refer (Keyboard)]
|
||||
["react-native" :as react-native :refer (Keyboard BackHandler)]
|
||||
["react-native-image-crop-picker" :default image-picker]
|
||||
["react-native-safe-area-context" :as safe-area-context
|
||||
:refer (SafeAreaProvider SafeAreaInsetsContext)]
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
(def image-class (reagent/adapt-react-class (reactjs/memo (.-Image react-native))))
|
||||
|
||||
(def fast-image (reagent/adapt-react-class FastImage))
|
||||
(def fast-image-class (reagent/adapt-react-class FastImage))
|
||||
|
||||
(defn image-get-size [uri callback] (.getSize (.-Image react-native) uri callback))
|
||||
(defn resolve-asset-source [uri] (js->clj (.resolveAssetSource (.-Image react-native) uri) :keywordize-keys true))
|
||||
@@ -270,3 +270,9 @@
|
||||
|
||||
(def safe-area-provider (reagent/adapt-react-class SafeAreaProvider))
|
||||
(def safe-area-consumer (reagent/adapt-react-class (.-Consumer ^js SafeAreaInsetsContext)))
|
||||
|
||||
(defn hw-back-add-listener [callback]
|
||||
(.addEventListener BackHandler "hardwareBackPress" callback))
|
||||
|
||||
(defn hw-back-remove-listener [callback]
|
||||
(.removeEventListener BackHandler "hardwareBackPress" callback))
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn- start-chat [topic]
|
||||
(re-frame/dispatch [:chat.ui/start-public-chat topic {:navigation-reset? true}])
|
||||
(re-frame/dispatch [:chat.ui/start-public-chat topic])
|
||||
(re-frame/dispatch [:set :public-group-topic nil]))
|
||||
|
||||
(defn- hash-icon []
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
wakuv2-flag
|
||||
current-fleet
|
||||
webview-debug
|
||||
wallet-connect-enabled?
|
||||
new-ui-enabled?]}]
|
||||
new-ui-enabled?
|
||||
mutual-contact-requests-enabled?
|
||||
wallet-connect-enabled?]}]
|
||||
(keep
|
||||
identity
|
||||
[{:size :small
|
||||
@@ -108,6 +109,15 @@
|
||||
[:multiaccounts.ui/waku-bloom-filter-mode-switched (not waku-bloom-filter-mode)])
|
||||
:accessory :switch
|
||||
:active waku-bloom-filter-mode}
|
||||
{:size :small
|
||||
:title (i18n/label :t/mutual-contact-requests)
|
||||
:accessibility-label :wallet-connect-settings-switch
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/switch-mutual-contact-requests-enabled (not mutual-contact-requests-enabled?)])
|
||||
:accessory :switch
|
||||
:active mutual-contact-requests-enabled?}
|
||||
{:size :small
|
||||
:title (i18n/label :t/wallet-connect)
|
||||
:accessibility-label :wallet-connect-settings-switch
|
||||
@@ -117,14 +127,13 @@
|
||||
[:multiaccounts.ui/switch-wallet-connect-enabled (not wallet-connect-enabled?)])
|
||||
:accessory :switch
|
||||
:active wallet-connect-enabled?}
|
||||
(when config/quo-preview-enabled?
|
||||
{:size :small
|
||||
:title (i18n/label :t/new-ui)
|
||||
:accessibility-label :new-ui-toggle
|
||||
:container-margin-bottom 8
|
||||
:on-press #(re-frame/dispatch [:toggle-new-ui])
|
||||
:accessory :switch
|
||||
:active new-ui-enabled?})]))
|
||||
{:size :small
|
||||
:title (i18n/label :t/new-ui)
|
||||
:accessibility-label :new-ui-toggle
|
||||
:container-margin-bottom 8
|
||||
:on-press #(re-frame/dispatch [:toggle-new-ui])
|
||||
:accessory :switch
|
||||
:active new-ui-enabled?}]))
|
||||
|
||||
(defn- flat-list-data [options]
|
||||
(normal-mode-settings-data options))
|
||||
@@ -143,6 +152,7 @@
|
||||
transactions-management-enabled? [:wallet/transactions-management-enabled?]
|
||||
current-log-level [:log-level/current-log-level]
|
||||
current-fleet [:fleets/current-fleet]
|
||||
mutual-contact-requests-enabled? [:mutual-contact-requests/enabled?]
|
||||
wallet-connect-enabled? [:wallet-connect/enabled?]]
|
||||
[list/flat-list
|
||||
{:data (flat-list-data
|
||||
@@ -155,7 +165,8 @@
|
||||
:wakuv2-flag wakuv2-flag
|
||||
:waku-bloom-filter-mode waku-bloom-filter-mode
|
||||
:webview-debug webview-debug
|
||||
:wallet-connect-enabled? wallet-connect-enabled?
|
||||
:new-ui-enabled? @config/new-ui-enabled?})
|
||||
:new-ui-enabled? @config/new-ui-enabled?
|
||||
:mutual-contact-requests-enabled? mutual-contact-requests-enabled?
|
||||
:wallet-connect-enabled? wallet-connect-enabled?})
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn render-item}]))
|
||||
|
||||
@@ -86,10 +86,7 @@
|
||||
:accessibility-label :open-chat
|
||||
:title (str "#" topic)
|
||||
:subtitle (i18n/label :t/open-chat)
|
||||
:on-press #(do
|
||||
(re-frame/dispatch [:navigate-change-tab :chat])
|
||||
(re-frame/dispatch [:pop-to-root-tab :chat-stack])
|
||||
(hide-sheet-and-dispatch [:chat.ui/start-public-chat topic {:navigation-reset? true}]))
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/start-public-chat topic])
|
||||
:chevron true}]
|
||||
[components/separator]])
|
||||
(if connected?
|
||||
|
||||
@@ -227,13 +227,13 @@
|
||||
[react/animated-view {:style (styles/rec-outer-circle outer-scale)}]
|
||||
[react/animated-view {:style (styles/rec-inner-circle inner-scale inner-border-radius)}]]]))
|
||||
|
||||
(defn- cancel-button [disabled? on-press]
|
||||
(defn- cancel-button [disabled? on-press contact-request]
|
||||
[pressable/pressable {:type :scale
|
||||
:disabled disabled?
|
||||
:on-press on-press}
|
||||
[react/view {:style (input.style/send-message-button)}
|
||||
[icons/icon :main-icons/close
|
||||
{:container-style (merge (input.style/send-message-container) {:background-color colors/gray})
|
||||
{:container-style (merge (input.style/send-message-container contact-request) {:background-color colors/gray})
|
||||
:accessibility-label :cancel-message-button
|
||||
:color colors/white-persist}]]])
|
||||
|
||||
@@ -272,13 +272,14 @@
|
||||
(reset! on-background-cb nil))}
|
||||
(let [base-params {:rec-button-anim-value rec-button-anim-value
|
||||
:ctrl-buttons-anim-value ctrl-buttons-anim-value
|
||||
:timer timer}]
|
||||
:timer timer}
|
||||
contact-request @(re-frame/subscribe [:chats/sending-contact-request])]
|
||||
[react/view {:style styles/container}
|
||||
[react/text {:style styles/timer
|
||||
:accessibility-label :audio-message-recorded-time} @timer]
|
||||
[react/view {:style styles/buttons-container}
|
||||
[react/animated-view {:style {:opacity ctrl-buttons-anim-value}}
|
||||
[cancel-button (:cancel-disabled? @state) #(stop-recording base-params)]]
|
||||
[cancel-button (:cancel-disabled? @state) #(stop-recording base-params) contact-request]]
|
||||
[rec-button-view (merge base-params {:state state})]
|
||||
[react/animated-view {:style {:opacity ctrl-buttons-anim-value}}
|
||||
[input/send-button (fn [] (cond
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
(ns status-im.ui.screens.chat.components.contact-request
|
||||
(:require [quo.core :as quo]
|
||||
[quo.react :as quo.react]
|
||||
[quo.react-native :as rn]
|
||||
[quo.design-system.colors :as quo.colors]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[status-im.ethereum.stateofus :as stateofus]
|
||||
[status-im.ui.screens.chat.components.style :as styles]
|
||||
[re-frame.core :as re-frame]
|
||||
[clojure.string :as string])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
(def ^:private contact-request-symbol "↪ ")
|
||||
|
||||
(defn input-focus [text-input-ref]
|
||||
(some-> ^js (quo.react/current-ref text-input-ref) .focus))
|
||||
|
||||
(defn format-author [contact-name]
|
||||
(let [author (if (or (= (aget contact-name 0) "@")
|
||||
;; in case of replies
|
||||
(= (aget contact-name 1) "@"))
|
||||
(or (stateofus/username contact-name)
|
||||
(subs contact-name 0 81))
|
||||
contact-name)]
|
||||
(i18n/label :contact-requesting-to {:author author})))
|
||||
|
||||
(defn format-contact-request-author [from username current-public-key]
|
||||
(or (and (= from current-public-key)
|
||||
(str contact-request-symbol (i18n/label :t/You)))
|
||||
(str contact-request-symbol (format-author username))))
|
||||
|
||||
(defn get-quoted-text-with-mentions [parsed-text]
|
||||
(string/join
|
||||
(mapv (fn [{:keys [type literal children]}]
|
||||
(cond
|
||||
(= type "paragraph")
|
||||
(get-quoted-text-with-mentions children)
|
||||
|
||||
(= type "mention")
|
||||
@(re-frame/subscribe [:contacts/contact-name-by-identity literal])
|
||||
|
||||
(seq children)
|
||||
(get-quoted-text-with-mentions children)
|
||||
|
||||
:else
|
||||
literal))
|
||||
parsed-text)))
|
||||
|
||||
(defn contact-request-message [their-public-key]
|
||||
(let [{:keys [input-text]} @(re-frame/subscribe [:chats/current-chat-inputs])]
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
[rn/view {:style (styles/contact-request-content)}
|
||||
[quo/button {:type :secondary
|
||||
:weight :medium
|
||||
:number-of-lines 1
|
||||
:style {:line-height 18}
|
||||
:on-press #(re-frame/dispatch [:chat.ui/cancel-contact-request])}
|
||||
(i18n/label :t/cancel)]
|
||||
[quo/button {:type :secondary
|
||||
:disabled (string/blank? input-text)
|
||||
:weight :medium
|
||||
:after :main-icons/send
|
||||
:on-press #(re-frame/dispatch [:contacts/send-contact-request their-public-key input-text])
|
||||
:style {:line-height 18}}
|
||||
(i18n/label :t/send-request)]]]))
|
||||
|
||||
(defn focus-input-on-contact-request [contact-request had-contact-request text-input-ref]
|
||||
;;when we show contact-request we focus input
|
||||
(when-not (= contact-request @had-contact-request)
|
||||
(reset! had-contact-request contact-request)
|
||||
(when contact-request
|
||||
(js/setTimeout #(input-focus text-input-ref) 250))))
|
||||
|
||||
(defn contact-request-message-wrapper [contact-request]
|
||||
[rn/view {:style {:padding-horizontal 15
|
||||
:border-top-width 1
|
||||
:border-top-color (:ui-01 @quo.colors/theme)
|
||||
:padding-vertical 8}}
|
||||
[contact-request-message contact-request]])
|
||||
|
||||
(defview contact-request-message-auto-focus-wrapper [text-input-ref]
|
||||
(letsubs [had-reply (atom nil)
|
||||
contact-request @(re-frame/subscribe [:chats/sending-contact-request])]
|
||||
{:component-did-mount #(focus-input-on-contact-request contact-request had-reply text-input-ref)}
|
||||
(when contact-request
|
||||
[contact-request-message-wrapper contact-request])))
|
||||
@@ -73,13 +73,14 @@
|
||||
[icons/icon :main-icons/keyboard (styles/icon false)]
|
||||
[icons/icon :main-icons/speech (styles/icon false)])]])
|
||||
|
||||
(defn send-button [on-send]
|
||||
(defn send-button [on-send contact-request]
|
||||
[rn/touchable-opacity {:on-press-in on-send}
|
||||
[rn/view {:style (styles/send-message-button)}
|
||||
[icons/icon :main-icons/arrow-up
|
||||
{:container-style (styles/send-message-container)
|
||||
:accessibility-label :send-message-button
|
||||
:color (styles/send-icon-color)}]]])
|
||||
(when-not contact-request
|
||||
[icons/icon :main-icons/arrow-up
|
||||
{:container-style (styles/send-message-container contact-request)
|
||||
:accessibility-label :send-message-button
|
||||
:color (styles/send-icon-color)}])]])
|
||||
|
||||
(defn on-selection-change [timeout-id last-text-change mentionable-users args]
|
||||
(let [selection (.-selection ^js (.-nativeEvent ^js args))
|
||||
@@ -113,6 +114,13 @@
|
||||
(defonce mentions-enabled (reagent/atom {}))
|
||||
(defonce chat-input-key (reagent/atom 1))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:chat.ui/clear-inputs
|
||||
(fn []
|
||||
(reset! input-texts {})
|
||||
(reset! mentions-enabled {})
|
||||
(reset! chat-input-key 1)))
|
||||
|
||||
(defn force-text-input-update!
|
||||
"force-text-input-update! forces the
|
||||
input to re-render, necessary when we are setting value"
|
||||
@@ -232,10 +240,11 @@
|
||||
mentionable-users @(re-frame/subscribe [:chats/mentionable-users])
|
||||
timeout-id (atom nil)
|
||||
last-text-change (atom nil)
|
||||
mentions-enabled (get @mentions-enabled chat-id)]
|
||||
mentions-enabled (get @mentions-enabled chat-id)
|
||||
contact-request @(re-frame/subscribe [:chats/sending-contact-request])]
|
||||
|
||||
[rn/text-input
|
||||
{:style (styles/text-input)
|
||||
{:style (styles/text-input contact-request)
|
||||
:ref (:text-input-ref refs)
|
||||
:max-font-size-multiplier 1
|
||||
:accessibility-label :chat-message-input
|
||||
@@ -327,8 +336,8 @@
|
||||
(when (seq sending-image)
|
||||
[reply/send-image sending-image])))
|
||||
|
||||
(defn actions [extensions image show-send actions-ref active-panel set-active-panel]
|
||||
[rn/view {:style (styles/actions-wrapper show-send)
|
||||
(defn actions [extensions image show-send actions-ref active-panel set-active-panel contact-request]
|
||||
[rn/view {:style (styles/actions-wrapper (and (not contact-request) show-send))
|
||||
:ref actions-ref}
|
||||
(when extensions
|
||||
[touchable-icon {:panel :extensions
|
||||
@@ -354,12 +363,13 @@
|
||||
:sticker-ref sticker-ref
|
||||
:text-input-ref text-input-ref}
|
||||
{:keys [send stickers image extensions audio sending-image]} @toolbar-options
|
||||
show-send (or sending-image (seq (get @input-texts chat-id)))]
|
||||
show-send (or sending-image (seq (get @input-texts chat-id)))
|
||||
contact-request @(re-frame/subscribe [:chats/sending-contact-request])]
|
||||
[rn/view {:style (styles/toolbar)
|
||||
:on-layout on-chat-toolbar-layout}
|
||||
;;EXTENSIONS and IMAGE buttons
|
||||
[actions extensions image show-send actions-ref active-panel set-active-panel]
|
||||
[rn/view {:style (styles/input-container)}
|
||||
[actions extensions image show-send actions-ref active-panel set-active-panel contact-request]
|
||||
[rn/view {:style (styles/input-container contact-request)}
|
||||
[send-image]
|
||||
[rn/view {:style styles/input-row}
|
||||
[text-input {:chat-id chat-id
|
||||
@@ -370,7 +380,8 @@
|
||||
[rn/view {:ref send-ref :style (when-not show-send {:width 0 :right -100})}
|
||||
(when send
|
||||
[send-button #(do (clear-input chat-id refs)
|
||||
(re-frame/dispatch [:chat.ui/send-current-message]))])]
|
||||
(re-frame/dispatch [:chat.ui/send-current-message]))
|
||||
contact-request])]
|
||||
|
||||
;;STICKERS and AUDIO buttons
|
||||
(when-not @(re-frame/subscribe [:chats/edit-message])
|
||||
|
||||
@@ -11,14 +11,15 @@
|
||||
:align-items :flex-end
|
||||
:flex-direction :row})
|
||||
|
||||
(defn input-container []
|
||||
(defn input-container [contact-request]
|
||||
{:background-color (:ui-01 @colors/theme)
|
||||
:flex 1
|
||||
:border-top-left-radius 16
|
||||
:border-top-right-radius 16
|
||||
:border-bottom-right-radius 4
|
||||
:border-bottom-left-radius 16
|
||||
:margin-horizontal 8})
|
||||
:height (when contact-request 44)
|
||||
:border-top-left-radius (if contact-request 8 16)
|
||||
:border-top-right-radius (if contact-request 8 16)
|
||||
:border-bottom-right-radius (if contact-request 8 4)
|
||||
:border-bottom-left-radius (if contact-request 8 16)
|
||||
:margin-horizontal (when contact-request 8)})
|
||||
|
||||
(def input-row
|
||||
{:flex-direction :row
|
||||
@@ -34,7 +35,7 @@
|
||||
(when platform/ios?
|
||||
{:padding-top 2})))
|
||||
|
||||
(defn text-input []
|
||||
(defn text-input [contact-request]
|
||||
(merge typography/font-regular
|
||||
typography/base
|
||||
{:flex 1
|
||||
@@ -46,8 +47,8 @@
|
||||
:padding-horizontal 12}
|
||||
(if platform/android?
|
||||
{:padding-vertical 2}
|
||||
{:padding-top 2
|
||||
:padding-bottom 6})))
|
||||
{:padding-top (if contact-request 10 2)
|
||||
:padding-bottom (if contact-request 5 6)})))
|
||||
|
||||
(defn actions-wrapper [show-send]
|
||||
(merge
|
||||
@@ -91,6 +92,11 @@
|
||||
:padding-horizontal 10
|
||||
:flex 1})
|
||||
|
||||
(defn contact-request-content []
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:justify-content :space-between})
|
||||
|
||||
(defn close-button []
|
||||
{:margin-top 3})
|
||||
|
||||
@@ -98,11 +104,11 @@
|
||||
{:margin-vertical 4
|
||||
:margin-horizontal 5})
|
||||
|
||||
(defn send-message-container []
|
||||
(defn send-message-container [contact-request]
|
||||
{:background-color (:interactive-01 @colors/theme)
|
||||
:width 26
|
||||
:height 26
|
||||
:border-radius 13
|
||||
:height (if contact-request 44 26)
|
||||
:border-radius (if contact-request 22 13)
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
|
||||
|
||||
@@ -12,13 +12,6 @@
|
||||
[status-im.utils.platform :as platform])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
(defn join-chat-button [chat-id]
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:accessibility-label :join-chat-button
|
||||
:on-press #(debounce/dispatch-and-chill [:group-chats.ui/join-pressed chat-id] 2000)}
|
||||
(i18n/label :t/join-group-chat)])
|
||||
|
||||
(defn decline-chat [chat-id]
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
@@ -69,16 +62,9 @@
|
||||
|
||||
(defview group-chat-footer
|
||||
[chat-id invitation-admin]
|
||||
(letsubs [{:keys [joined?]} [:group-chat/inviter-info chat-id]
|
||||
removed? [:group-chat/removed-from-current-chat?]
|
||||
invitations [:group-chat/invitations-by-chat-id chat-id]]
|
||||
(if invitation-admin
|
||||
[request-membership (first invitations)]
|
||||
(when (and (not joined?) (not removed?))
|
||||
[react/view {:style style/group-chat-join-footer}
|
||||
[react/view {:style style/group-chat-join-container}
|
||||
[join-chat-button chat-id]
|
||||
[decline-chat chat-id]]]))))
|
||||
(letsubs [invitations [:group-chat/invitations-by-chat-id chat-id]]
|
||||
(when invitation-admin
|
||||
[request-membership (first invitations)])))
|
||||
|
||||
(def group-chat-description-loading
|
||||
[react/view {:style (merge style/intro-header-description-container
|
||||
@@ -153,10 +139,10 @@
|
||||
{:group-name chat-name})])
|
||||
|
||||
(defview group-chat-inviter-description-container [chat-id chat-name]
|
||||
(letsubs [{:keys [joined? inviter-pk]}
|
||||
(letsubs [{:keys [member? inviter-pk]}
|
||||
[:group-chat/inviter-info chat-id]]
|
||||
(cond
|
||||
(not joined?)
|
||||
(not member?)
|
||||
[pending-invitation-description inviter-pk chat-name]
|
||||
inviter-pk
|
||||
[joined-group-chat-description inviter-pk chat-name]
|
||||
|
||||
@@ -17,18 +17,19 @@
|
||||
gap-ids
|
||||
chat-id]
|
||||
connected? [:mailserver/connected?]
|
||||
use-status-nodes? [:mailserver/use-status-nodes?]
|
||||
first-gap? (= gap-ids #{:first-gap})]
|
||||
(when (or (not first-gap?) public? community?)
|
||||
[react/view {:style (style/gap-container)}
|
||||
[react/touchable-highlight
|
||||
{:on-press (when (and connected? (not in-progress?))
|
||||
{:on-press (when (and (not in-progress?) use-status-nodes? connected?)
|
||||
(on-press chat-id gap-ids))
|
||||
:style style/touchable}
|
||||
[react/view {:style style/label-container}
|
||||
(if in-progress?
|
||||
[react/activity-indicator]
|
||||
[react/nested-text
|
||||
{:style (style/gap-text connected?)}
|
||||
{:style (style/gap-text (and connected? use-status-nodes?))}
|
||||
(i18n/label (if first-gap? :t/load-more-messages :t/fetch-messages))
|
||||
(when first-gap?
|
||||
[{:style style/date}
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
[status-im.ui.screens.communities.icon :as communities.icon]
|
||||
[status-im.ui.components.animation :as animation]
|
||||
[status-im.chat.models.images :as images]
|
||||
[status-im.chat.models.pin-message :as models.pin-message])
|
||||
[status-im.chat.models.pin-message :as models.pin-message]
|
||||
[status-im.ui.components.fast-image :as fast-image])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
(defn message-timestamp-anim
|
||||
@@ -99,11 +100,11 @@
|
||||
(if (and image
|
||||
;; Disabling images for public-chats
|
||||
(not public?))
|
||||
[react/fast-image {:style {:width 56
|
||||
:height 56
|
||||
:background-color :black
|
||||
:border-radius 4}
|
||||
:source {:uri image}}]
|
||||
[fast-image/fast-image {:style {:width 56
|
||||
:height 56
|
||||
:background-color :black
|
||||
:border-radius 4}
|
||||
:source {:uri image}}]
|
||||
[react/text {:style (style/quoted-message-text (and outgoing (not pinned)))
|
||||
:number-of-lines 5}
|
||||
(components.reply/get-quoted-text-with-mentions parsed-text)])]))
|
||||
@@ -159,7 +160,7 @@
|
||||
:text-decoration-line :underline}
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:chat.ui/start-public-chat literal {:navigation-reset? true}])}
|
||||
[:chat.ui/start-public-chat literal])}
|
||||
"#"
|
||||
literal])
|
||||
|
||||
@@ -374,9 +375,17 @@
|
||||
:disabled in-popover?}
|
||||
[react/view {:style (style/image-message style-opts)
|
||||
:accessibility-label :image-message}
|
||||
[react/fast-image {:style (dissoc style-opts :outgoing)
|
||||
:on-load (image-set-size dimensions)
|
||||
:source {:uri uri}}]
|
||||
(when (or (:error @dimensions) (not (:loaded @dimensions)))
|
||||
[react/view
|
||||
(merge (dissoc style-opts :opacity)
|
||||
{:flex 1 :align-items :center :justify-content :center :position :absolute})
|
||||
(if (:error @dimensions)
|
||||
[icons/icon :main-icons/cancel]
|
||||
[react/activity-indicator {:animating true}])])
|
||||
[fast-image/fast-image {:style (dissoc style-opts :outgoing)
|
||||
:on-load (image-set-size dimensions)
|
||||
:on-error #(swap! dimensions assoc :error true)
|
||||
:source {:uri uri}}]
|
||||
[react/view {:style (style/image-message-border style-opts)}]]]]))))
|
||||
|
||||
(defmulti ->message :content-type)
|
||||
@@ -511,40 +520,41 @@
|
||||
[react/text-class {:style (style/status-text)}]
|
||||
(-> content :parsed-text peek :children))]]])
|
||||
|
||||
(defmethod ->message constants/content-type-emoji
|
||||
[{:keys [content current-public-key outgoing public? pinned in-popover? message-pin-enabled] :as message} {:keys [on-long-press modal]
|
||||
:as reaction-picker}]
|
||||
(let [response-to (:response-to content)
|
||||
show-timestamp? (reagent/atom false)]
|
||||
(fn [] [message-content-wrapper message
|
||||
[react/touchable-highlight (when-not modal
|
||||
{:disabled in-popover?
|
||||
:on-press (fn []
|
||||
(react/dismiss-keyboard!)
|
||||
(reset! show-timestamp? true))
|
||||
:delay-long-press 100
|
||||
:on-long-press (fn []
|
||||
(on-long-press
|
||||
(concat
|
||||
[{:on-press #(re-frame/dispatch [:chat.ui/reply-to-message message])
|
||||
:id :reply
|
||||
:label (i18n/label :t/message-reply)}
|
||||
{:on-press #(react/copy-to-clipboard (get content :text))
|
||||
:id :copy
|
||||
:label (i18n/label :t/sharing-copy-to-clipboard)}]
|
||||
(when message-pin-enabled [{:on-press #(pin-message message)
|
||||
:label (if pinned (i18n/label :t/unpin) (i18n/label :t/pin))}]))))})
|
||||
[react/view (style/message-view-wrapper outgoing)
|
||||
[message-timestamp message show-timestamp?]
|
||||
[react/view (style/message-view message)
|
||||
[react/view {:style (style/message-view-content)}
|
||||
[react/view {:style (style/style-message-text outgoing)}
|
||||
(when (and (seq response-to) (:quoted-message message))
|
||||
[quoted-message response-to (:quoted-message message) outgoing current-public-key public? pinned])
|
||||
[react/text {:style (style/emoji-message message)}
|
||||
(:text content)]]
|
||||
[message-status message]]]]]
|
||||
reaction-picker])))
|
||||
(defmethod ->message constants/content-type-emoji []
|
||||
(let [show-timestamp? (reagent/atom false)]
|
||||
(fn [{:keys [content current-public-key outgoing public? pinned in-popover? message-pin-enabled] :as message}
|
||||
{:keys [on-long-press modal]
|
||||
:as reaction-picker}]
|
||||
(let [response-to (:response-to content)]
|
||||
[message-content-wrapper message
|
||||
[react/touchable-highlight (when-not modal
|
||||
{:disabled in-popover?
|
||||
:on-press (fn []
|
||||
(react/dismiss-keyboard!)
|
||||
(reset! show-timestamp? true))
|
||||
:delay-long-press 100
|
||||
:on-long-press (fn []
|
||||
(on-long-press
|
||||
(concat
|
||||
[{:on-press #(re-frame/dispatch [:chat.ui/reply-to-message message])
|
||||
:id :reply
|
||||
:label (i18n/label :t/message-reply)}
|
||||
{:on-press #(react/copy-to-clipboard (get content :text))
|
||||
:id :copy
|
||||
:label (i18n/label :t/sharing-copy-to-clipboard)}]
|
||||
(when message-pin-enabled [{:on-press #(pin-message message)
|
||||
:label (if pinned (i18n/label :t/unpin) (i18n/label :t/pin))}]))))})
|
||||
[react/view (style/message-view-wrapper outgoing)
|
||||
[message-timestamp message show-timestamp?]
|
||||
[react/view (style/message-view message)
|
||||
[react/view {:style (style/message-view-content)}
|
||||
[react/view {:style (style/style-message-text outgoing)}
|
||||
(when (and (seq response-to) (:quoted-message message))
|
||||
[quoted-message response-to (:quoted-message message) outgoing current-public-key public? pinned])
|
||||
[react/text {:style (style/emoji-message message)}
|
||||
(:text content)]]
|
||||
[message-status message]]]]]
|
||||
reaction-picker]))))
|
||||
|
||||
(defmethod ->message constants/content-type-sticker
|
||||
[{:keys [content from outgoing in-popover?]
|
||||
@@ -567,8 +577,8 @@
|
||||
[{:on-press #(when pack
|
||||
(re-frame/dispatch [:chat.ui/show-profile from]))
|
||||
:label (i18n/label :t/view-details)}])))})
|
||||
[react/fast-image {:style {:margin 10 :width 140 :height 140}
|
||||
:source {:uri (str (-> content :sticker :url) "&download=true")}}]]
|
||||
[fast-image/fast-image {:style {:margin 10 :width 140 :height 140}
|
||||
:source {:uri (str (-> content :sticker :url) "&download=true")}}]]
|
||||
reaction-picker]))
|
||||
|
||||
(defmethod ->message constants/content-type-image
|
||||
@@ -598,28 +608,71 @@
|
||||
:id :delete}]))))}]
|
||||
reaction-picker])
|
||||
|
||||
(defmethod ->message constants/content-type-audio
|
||||
[{:keys [outgoing] :as message}
|
||||
{:keys [on-long-press modal]
|
||||
:as reaction-picker}]
|
||||
(defmethod ->message constants/content-type-audio []
|
||||
(let [show-timestamp? (reagent/atom false)]
|
||||
(fn [] [message-content-wrapper message
|
||||
[react/touchable-highlight
|
||||
(when-not modal
|
||||
{:on-long-press
|
||||
(fn [] (on-long-press (if (and outgoing config/delete-message-enabled?)
|
||||
[{:on-press #(re-frame/dispatch [:chat.ui/soft-delete-message message])
|
||||
:label (i18n/label :t/delete)
|
||||
:id :delete}]
|
||||
[])))
|
||||
:on-press (fn []
|
||||
(reset! show-timestamp? true))})
|
||||
[react/view (style/message-view-wrapper (:outgoing message))
|
||||
[message-timestamp message show-timestamp?]
|
||||
[react/view {:style (style/message-view message) :accessibility-label :audio-message}
|
||||
[react/view {:style (style/message-view-content)}
|
||||
[message.audio/message-content message] [message-status message]]]]]
|
||||
reaction-picker])))
|
||||
(fn [{:keys [outgoing] :as message}
|
||||
{:keys [on-long-press modal]
|
||||
:as reaction-picker}]
|
||||
[message-content-wrapper message
|
||||
[react/touchable-highlight
|
||||
(when-not modal
|
||||
{:on-long-press
|
||||
(fn [] (on-long-press (if (and outgoing config/delete-message-enabled?)
|
||||
[{:on-press #(re-frame/dispatch [:chat.ui/soft-delete-message message])
|
||||
:label (i18n/label :t/delete)
|
||||
:id :delete}]
|
||||
[])))
|
||||
:on-press (fn []
|
||||
(reset! show-timestamp? true))})
|
||||
[react/view (style/message-view-wrapper (:outgoing message))
|
||||
[message-timestamp message show-timestamp?]
|
||||
[react/view {:style (style/message-view message) :accessibility-label :audio-message}
|
||||
[react/view {:style (style/message-view-content)}
|
||||
[message.audio/message-content message] [message-status message]]]]]
|
||||
reaction-picker])))
|
||||
|
||||
(defn contact-request-status-pending []
|
||||
[react/view {:style {:flex-direction :row}}
|
||||
[quo/text {:style {:margin-right 5.27}
|
||||
:weight :medium
|
||||
:color :secondary}
|
||||
(i18n/label :t/contact-request-pending)]
|
||||
[react/activity-indicator {:animating true
|
||||
:size :small
|
||||
:color colors/gray}]])
|
||||
|
||||
(defn contact-request-status-accepted []
|
||||
[quo/text {:style {:color colors/green}
|
||||
:weight :medium}
|
||||
(i18n/label :t/contact-request-accepted)])
|
||||
|
||||
(defn contact-request-status-declined []
|
||||
[quo/text {:style {:color colors/red}
|
||||
:weight :medium}
|
||||
(i18n/label :t/contact-request-declined)])
|
||||
|
||||
(defn contact-request-status-label [state]
|
||||
[react/view {:style (style/contact-request-status-label state)}
|
||||
(case state
|
||||
constants/contact-request-message-state-pending [contact-request-status-pending]
|
||||
constants/contact-request-message-state-accepted [contact-request-status-accepted]
|
||||
constants/contact-request-message-state-declined [contact-request-status-declined])])
|
||||
|
||||
(defmethod ->message constants/content-type-contact-request
|
||||
[{:keys [outgoing] :as message} _]
|
||||
[react/view {:style (style/content-type-contact-request outgoing)}
|
||||
[react/image {:source (resources/get-image :hand-wave)
|
||||
:style {:width 112
|
||||
:height 97}}]
|
||||
[quo/text {:style {:margin-top 6}
|
||||
:weight :bold
|
||||
:size :large}
|
||||
(i18n/label :t/contact-request)]
|
||||
[react/view {:style {:padding-horizontal 16}}
|
||||
[quo/text {:style {:margin-top 2
|
||||
:margin-bottom 14}}
|
||||
(get-in message [:content :text])]]
|
||||
[contact-request-status-label (:contact-request-state message)]])
|
||||
|
||||
(defmethod ->message :default [message]
|
||||
[message-content-wrapper message
|
||||
|
||||
@@ -5,16 +5,17 @@
|
||||
[status-im.profile.db :as profile.db]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.utils.image :as utils.image]
|
||||
[quo.design-system.colors :as colors]))
|
||||
[quo.design-system.colors :as colors]
|
||||
[status-im.ui.components.fast-image :as fast-image]))
|
||||
|
||||
(def memo-photo-rend
|
||||
(memoize
|
||||
(fn [photo-path size accessibility-label _]
|
||||
(let [identicon? (when photo-path (profile.db/base64-png? photo-path))]
|
||||
[react/view {:style (style/photo-container size)}
|
||||
[react/fast-image {:source (utils.image/source photo-path)
|
||||
:style (style/photo size)
|
||||
:accessibility-label (or accessibility-label :chat-icon)}]
|
||||
[fast-image/fast-image {:source (utils.image/source photo-path)
|
||||
:style (style/photo size)
|
||||
:accessibility-label (or accessibility-label :chat-icon)}]
|
||||
(when identicon?
|
||||
[react/view {:style (style/photo-border size)}])]))))
|
||||
|
||||
@@ -36,7 +37,7 @@
|
||||
(defn member-identicon [identicon]
|
||||
(let [size style/default-size]
|
||||
[react/view {:style (style/photo-container size)}
|
||||
[react/fast-image {:source {:uri identicon}
|
||||
:style (style/photo size)
|
||||
:accessibility-label :member-photo}]
|
||||
[fast-image/fast-image {:source {:uri identicon}
|
||||
:style (style/photo size)
|
||||
:accessibility-label :member-photo}]
|
||||
[react/view {:style (style/photo-border size)}]]))
|
||||
|
||||
@@ -116,4 +116,4 @@
|
||||
[connectivity/loading-indicator]
|
||||
[pinned-messages-view {:chat chat
|
||||
:pan-responder pan-responder
|
||||
:space-keeper space-keeper}]]))))
|
||||
:space-keeper space-keeper}]]))))
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
|
||||
(defn group-chat-accents []
|
||||
(fn [{:keys [chat-id group-chat chat-name color invitation-admin]}]
|
||||
(let [{:keys [joined?]} @(re-frame/subscribe [:group-chat/inviter-info chat-id])
|
||||
(let [{:keys [member?]} @(re-frame/subscribe [:group-chat/inviter-info chat-id])
|
||||
removed? @(re-frame/subscribe [:group-chat/removed-from-current-chat?])]
|
||||
(if invitation-admin
|
||||
[quo/list-item
|
||||
@@ -125,7 +125,7 @@
|
||||
:accessibility-label :mark-all-read-button
|
||||
:icon :main-icons/check
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/mark-all-read-pressed chat-id])}]
|
||||
(when joined?
|
||||
(when member?
|
||||
[quo/list-item
|
||||
{:theme :negative
|
||||
:title (i18n/label :t/leave-chat)
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.screens.chat.stickers.styles :as styles]
|
||||
[status-im.utils.debounce :as debounce]))
|
||||
[status-im.utils.debounce :as debounce]
|
||||
[status-im.ui.components.fast-image :as fast-image]))
|
||||
|
||||
(def icon-size 28)
|
||||
(def icon-horizontal-margin 8)
|
||||
@@ -35,9 +36,9 @@
|
||||
^{:key (str url)}
|
||||
[react/touchable-highlight {:style {:height 75 :width 75 :margin 5}
|
||||
:on-press #(debounce/dispatch-and-chill [:chat/send-sticker sticker] 1000)}
|
||||
[react/fast-image {:style {:width "100%" :height "100%"}
|
||||
:accessibility-label :sticker-icon
|
||||
:source {:uri (str url "&download=true")}}]])]]])
|
||||
[fast-image/fast-image {:style {:width "100%" :height "100%"}
|
||||
:accessibility-label :sticker-icon
|
||||
:source {:uri (str url "&download=true")}}]])]]])
|
||||
|
||||
(defview recent-stickers-panel [window-width]
|
||||
(letsubs [stickers [:stickers/recent-stickers]]
|
||||
@@ -137,6 +138,6 @@
|
||||
^{:key (str "pack-icon" id)}
|
||||
[pack-icon {:id id
|
||||
:background-color colors/white}
|
||||
[react/fast-image {:style {:width icon-size :height icon-size :border-radius (/ icon-size 2)}
|
||||
:source {:uri (str thumbnail "&download=true")}}]])]
|
||||
[fast-image/fast-image {:style {:width icon-size :height icon-size :border-radius (/ icon-size 2)}
|
||||
:source {:uri (str thumbnail "&download=true")}}]])]
|
||||
[scroll-indicator]]]]]))
|
||||
|
||||
@@ -53,8 +53,7 @@
|
||||
{:flex 1
|
||||
:flex-direction :column
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:height 324}
|
||||
:align-items :center}
|
||||
{:flex 1
|
||||
:flex-direction :column
|
||||
:justify-content :center
|
||||
@@ -148,3 +147,10 @@
|
||||
{:font-size 13
|
||||
:line-height 18
|
||||
:text-align :center})
|
||||
|
||||
(def contact-request
|
||||
{:width "100%"
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:border-top-width 1
|
||||
:border-color colors/gray-transparent-10})
|
||||
|
||||
@@ -400,7 +400,8 @@
|
||||
|
||||
(defn image-message-border [opts]
|
||||
(merge (image-message opts)
|
||||
{:border-width 1
|
||||
{:opacity (:opacity opts)
|
||||
:border-width 1
|
||||
:top 0
|
||||
:left 0
|
||||
:position :absolute
|
||||
@@ -435,3 +436,32 @@
|
||||
:border-bottom-left-radius 10
|
||||
:border-bottom-right-radius 10
|
||||
:border-color colors/gray-lighter})
|
||||
|
||||
(defn contact-request-status-label [state]
|
||||
{:width 136
|
||||
:border-radius 8
|
||||
:flex 1
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color (when (= :retry state)
|
||||
colors/blue-light)
|
||||
:border-width 1
|
||||
:border-color (case state
|
||||
constants/contact-request-message-state-accepted colors/green-transparent-10
|
||||
constants/contact-request-message-state-declined colors/red-light
|
||||
constants/contact-request-message-state-pending colors/gray-lighter)
|
||||
:padding-vertical 10
|
||||
:padding-horizontal 16})
|
||||
|
||||
(defn content-type-contact-request [outgoing]
|
||||
{:width 168
|
||||
:min-height 224.71
|
||||
:border-radius 8
|
||||
:border-width 1
|
||||
:border-color colors/gray-lighter
|
||||
:align-items :center
|
||||
:padding-bottom 10
|
||||
:margin-vertical 4
|
||||
:align-self (if outgoing :flex-end :flex-start)
|
||||
:margin-right (if outgoing 8 0)
|
||||
:margin-left (if outgoing 0 8)})
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user