Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cdbfc1ed1f | ||
|
|
63ead3d588 | ||
|
|
5d2b0c026e | ||
|
|
1083547561 | ||
|
|
bf7d71d716 | ||
|
|
922c4d6128 | ||
|
|
9ff1e054c9 | ||
|
|
6c79f158b3 | ||
|
|
ff0d042e60 | ||
|
|
178d65795b | ||
|
|
8e1e0a77c9 | ||
|
|
7659c43372 | ||
|
|
92b2f50630 | ||
|
|
f84f0312af | ||
|
|
6a8035967f | ||
|
|
56a5570c20 |
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"presets": [
|
||||
"module:metro-react-native-babel-preset"
|
||||
],
|
||||
"plugins": [
|
||||
"react-native-reanimated/plugin"
|
||||
]
|
||||
}
|
||||
@@ -200,7 +200,7 @@ status-im.utils.platform/isMacOs?
|
||||
status-im.utils.platform/isNix?
|
||||
status-im.utils.platform/isWin?
|
||||
status-im.utils.platform/android-version>=
|
||||
utils.debounce/clear-all
|
||||
status-im.utils.debounce/clear-all
|
||||
status-im.transport.db/create-chat
|
||||
status-im.utils.priority-map/priority-map
|
||||
status-im.utils.priority-map/priority-map-by
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
status-im.utils.views/letsubs clojure.core/let
|
||||
reagent.core/with-let clojure.core/let
|
||||
status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
|
||||
utils.re-frame/defn clj-kondo.lint-as/def-catch-all
|
||||
quo.react/with-deps-check clojure.core/fn
|
||||
quo.previews.preview/list-comp clojure.core/for
|
||||
status-im.utils.styles/def clojure.core/def
|
||||
status-im.utils.styles/defn clojure.core/defn
|
||||
taoensso.tufte/defnp clojure.core/defn}
|
||||
:linters {:invalid-arity {:skip-args [status-im.utils.fx/defn utils.re-frame/defn]}
|
||||
:linters {:invalid-arity {:skip-args [status-im.utils.fx/defn]}
|
||||
;;TODO remove number when this is fixed
|
||||
;;https://github.com/borkdude/clj-kondo/issues/867
|
||||
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY number]}}}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
module.exports = {
|
||||
"testRunner": "jest",
|
||||
"testRegex": "\\.visual\\.js$",
|
||||
"runner-config": "visual-test/config.json",
|
||||
"devices": {
|
||||
"simulator": {
|
||||
"type": "ios.simulator",
|
||||
"device": {
|
||||
"type": "iPhone 11 Pro"
|
||||
}
|
||||
}
|
||||
},
|
||||
"apps": {
|
||||
"ios.release": {
|
||||
"name": "StatusIm",
|
||||
"type": "ios.app",
|
||||
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/StatusIm.app",
|
||||
"build": "make release-ios"
|
||||
},
|
||||
"ios.debug": {
|
||||
"name": "StatusIm",
|
||||
"type": "ios.app",
|
||||
"binaryPath": process.env.TEST_BINARY_PATH,
|
||||
"build": "make run-ios SIMULATOR='iPhone 11 Pro'"
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
"ios.sim.release": {
|
||||
"device": "simulator",
|
||||
"app": "ios.release"
|
||||
},
|
||||
"ios.sim.debug": {
|
||||
"device": "simulator",
|
||||
"app": "ios.debug"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
# Xcode
|
||||
#
|
||||
/component-spec
|
||||
result/
|
||||
build/
|
||||
*.pbxuser
|
||||
@@ -176,8 +175,3 @@ test/appium/tests/users.py
|
||||
##node bindings
|
||||
/bin/
|
||||
/lib/
|
||||
|
||||
## visual tests
|
||||
/artifacts
|
||||
|
||||
/.calva/
|
||||
|
||||
@@ -48,7 +48,7 @@ export _NIX_GCROOTS = /nix/var/nix/gcroots/per-user/$(USER)/status-mobile
|
||||
# Defines which variables will be kept for Nix pure shell, use semicolon as divider
|
||||
export _NIX_KEEP ?= TMPDIR,BUILD_ENV,STATUS_GO_SRC_OVERRIDE
|
||||
|
||||
# Useful for Android release builds
|
||||
# Useful for Andoird release builds
|
||||
TMP_BUILD_NUMBER := $(shell ./scripts/version/gen_build_no.sh | cut -c1-10)
|
||||
|
||||
# MacOS root is read-only, read nix/README.md for details
|
||||
@@ -307,36 +307,13 @@ test-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||
|
||||
test: export TARGET := clojure
|
||||
test: ##@test Run tests once in NodeJS
|
||||
# Here we create the gyp bindings for nodejs
|
||||
# Here we creates the gyp bindings for nodejs
|
||||
yarn install
|
||||
yarn shadow-cljs compile mocks && \
|
||||
yarn shadow-cljs compile test && \
|
||||
node --require ./test-resources/override.js target/test/test.js
|
||||
|
||||
|
||||
run-visual-test-ios: export TARGET := clojure
|
||||
run-visual-test-ios: XCODE_DERIVED_DATA := $(HOME)/Library/Developer/Xcode/DerivedData
|
||||
run-visual-test-ios: APPLICATION_NAME := StatusIm-brfnruzfrkkycpbndmdoeyrigthc
|
||||
run-visual-test-ios: export TEST_BINARY_PATH := $(XCODE_DERIVED_DATA)/$(APPLICATION_NAME)/Build/Products/Debug-iphonesimulator/StatusIm.app
|
||||
run-visual-test-ios: ##@test Run tests once in NodeJS
|
||||
detox test --configuration ios.sim.debug
|
||||
|
||||
component-test-watch: export TARGET := clojure
|
||||
component-test-watch: export COMPONENT_TEST := true
|
||||
component-test-watch: export BABEL_ENV := test
|
||||
component-test-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||
yarn install
|
||||
nodemon --exec 'yarn shadow-cljs compile component-test && jest --config=test/jest/jest.config.js' -e cljs
|
||||
|
||||
component-test: export TARGET := clojure
|
||||
component-test: export COMPONENT_TEST := true
|
||||
component-test: export BABEL_ENV := test
|
||||
component-test: ##@test Run tests once in NodeJS
|
||||
# Here we create the gyp bindings for nodejs
|
||||
yarn install
|
||||
yarn shadow-cljs compile component-test && \
|
||||
jest --config=test/jest/jest.config.js
|
||||
|
||||
#--------------
|
||||
# Other
|
||||
#--------------
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
module.exports = {
|
||||
|
||||
"presets": [
|
||||
"module:metro-react-native-babel-preset"
|
||||
],
|
||||
"plugins": [
|
||||
"react-native-reanimated/plugin"
|
||||
],
|
||||
"env": {
|
||||
"test": {
|
||||
"presets": [
|
||||
'@babel/preset-react',
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
node: '14',
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
library 'status-jenkins-lib@v1.6.1'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
@@ -36,7 +36,7 @@ pipeline {
|
||||
LANG = "en_US.UTF-8"
|
||||
LC_ALL = "en_US.UTF-8"
|
||||
LANGUAGE = "en_US.UTF-8"
|
||||
TARGET = "android${utils.isE2EBuild() ? "-e2e" : ""}"
|
||||
TARGET = 'android'
|
||||
BUILD_ENV = 'prod'
|
||||
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
|
||||
FASTLANE_DISABLE_COLORS = 1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
library 'status-jenkins-lib@v1.6.1'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
library 'status-jenkins-lib@v1.6.1'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
library 'status-jenkins-lib@v1.6.1'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
library 'status-jenkins-lib@v1.6.1'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -62,7 +62,7 @@ pipeline {
|
||||
--rerun_count=2 \
|
||||
--testrail_report=True \
|
||||
-m testrail_id \
|
||||
-m \"new_ui_critical or new_ui_medium\" \
|
||||
-m \"new_ui_critical\" \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--apk=${params.APK_NAME}
|
||||
"""
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
library 'status-jenkins-lib@v1.6.1'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
library 'status-jenkins-lib@v1.6.1'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.6.3'
|
||||
library 'status-jenkins-lib@v1.6.1'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -62,31 +62,6 @@ with the source file using it. For a real example, see
|
||||
(do-something)]])
|
||||
```
|
||||
|
||||
#### Styles def vs defn
|
||||
|
||||
Always use `def` over `defn`, unless the style relies on dynamic values, such as
|
||||
deref'ed atoms.
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
(defn title-column []
|
||||
{:height 56})
|
||||
|
||||
;; good
|
||||
(def title-column
|
||||
{:height 56})
|
||||
```
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
(def community-card
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-90)})
|
||||
|
||||
;; good
|
||||
(defn community-card []
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-90)})
|
||||
```
|
||||
|
||||
### Using TODOs comments
|
||||
|
||||
_TODO_ comments are used extensively in the codebase, but prefer to use them
|
||||
@@ -274,31 +249,6 @@ test macros `deftest` and `is`, which are ubiquitous in the Clojure community.
|
||||
(:require [cljs-time.coerce :as time.coerce]))
|
||||
```
|
||||
|
||||
### Namespace aliases
|
||||
|
||||
Prefer the following namespace aliases:
|
||||
|
||||
```clojure
|
||||
[clojure.string :as string]
|
||||
[taoensso.timbre :as log]
|
||||
```
|
||||
|
||||
### Javascript interop
|
||||
|
||||
Use [binaryage/oops](https://github.com/binaryage/cljs-oops) macros instead of
|
||||
core interop macros.
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
(fn [^js event]
|
||||
(.-width (.-nativeEvent event)))
|
||||
|
||||
;; good
|
||||
(require '[oops.core :as oops])
|
||||
(fn [event]
|
||||
(oops/oget event "nativeEvent.width"))
|
||||
```
|
||||
|
||||
### Accessibility labels
|
||||
|
||||
Use keywords instead of strings. As a bonus, remember keywords are cached in
|
||||
|
||||
@@ -640,7 +640,7 @@ SPEC CHECKSUMS:
|
||||
FBLazyVector: 352a8ca9bbc8e2f097d680747a8c97ecef12d469
|
||||
FBReactNativeSpec: 7dfb84f624136a45727c813ed21d130cd3e61beb
|
||||
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
|
||||
glog: 36ce0530c6d2c3a5a4326885ef4069564887a1db
|
||||
glog: 997518ea2aa2d8cd5df9797b641b758d52ecf2bc
|
||||
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
|
||||
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
|
||||
libwebp: 60305b2e989864154bd9be3d772730f08fc6a59c
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
package im.status.ethereum.module;
|
||||
|
||||
import android.view.ActionMode;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.uimanager.NativeViewHierarchyManager;
|
||||
import com.facebook.react.uimanager.UIBlock;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.views.textinput.ReactEditText;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
class RNSelectableTextInputModule extends ReactContextBaseJavaModule {
|
||||
|
||||
private ActionMode lastActionMode;
|
||||
|
||||
public RNSelectableTextInputModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "RNSelectableTextInputManager";
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setupMenuItems(final Integer selectableTextViewReactTag, final Integer textInputReactTag) {
|
||||
ReactApplicationContext reactContext = this.getReactApplicationContext();
|
||||
UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class);
|
||||
uiManager.addUIBlock(new UIBlock() {
|
||||
public void execute (NativeViewHierarchyManager nvhm) {
|
||||
RNSelectableTextInputViewManager rnSelectableTextManager = (RNSelectableTextInputViewManager) nvhm.resolveViewManager(selectableTextViewReactTag);
|
||||
ReactEditText reactTextView = (ReactEditText) nvhm.resolveView(textInputReactTag);
|
||||
rnSelectableTextManager.registerSelectionListener(reactTextView);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void startActionMode(final Integer textInputReactTag) {
|
||||
ReactApplicationContext reactContext = this.getReactApplicationContext();
|
||||
UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class);
|
||||
uiManager.addUIBlock(new UIBlock() {
|
||||
public void execute (NativeViewHierarchyManager nvhm) {
|
||||
ReactEditText reactTextView = (ReactEditText) nvhm.resolveView(textInputReactTag);
|
||||
lastActionMode = reactTextView.startActionMode(reactTextView.getCustomSelectionActionModeCallback(), ActionMode.TYPE_FLOATING);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void hideLastActionMode(){
|
||||
ReactApplicationContext reactContext = this.getReactApplicationContext();
|
||||
UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class);
|
||||
uiManager.addUIBlock(new UIBlock() {
|
||||
public void execute (NativeViewHierarchyManager nvhm) {
|
||||
if(lastActionMode!=null){
|
||||
lastActionMode.finish();
|
||||
lastActionMode = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setSelection(final Integer textInputReactTag, final Integer start, final Integer end){
|
||||
ReactApplicationContext reactContext = this.getReactApplicationContext();
|
||||
UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class);
|
||||
uiManager.addUIBlock(new UIBlock() {
|
||||
public void execute (NativeViewHierarchyManager nvhm) {
|
||||
ReactEditText reactTextView = (ReactEditText) nvhm.resolveView(textInputReactTag);
|
||||
reactTextView.setSelection(start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
package im.status.ethereum.module;
|
||||
|
||||
import android.view.ActionMode;
|
||||
import android.view.ActionMode.Callback;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||
import com.facebook.react.views.textinput.ReactEditText;
|
||||
import com.facebook.react.views.view.ReactViewGroup;
|
||||
import com.facebook.react.views.view.ReactViewManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class RNSelectableTextInputViewManager extends ReactViewManager {
|
||||
public static final String REACT_CLASS = "RNSelectableTextInput";
|
||||
private String[] _menuItems = new String[0];
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return REACT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReactViewGroup createViewInstance(ThemedReactContext context) {
|
||||
return new ReactViewGroup(context);
|
||||
}
|
||||
|
||||
@ReactProp(name = "menuItems")
|
||||
public void setMenuItems(ReactViewGroup reactViewGroup, ReadableArray items) {
|
||||
if(items != null) {
|
||||
List<String> result = new ArrayList<String>(items.size());
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
result.add(items.getString(i));
|
||||
}
|
||||
this._menuItems = result.toArray(new String[items.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerSelectionListener(final ReactEditText view) {
|
||||
view.setCustomSelectionActionModeCallback(new Callback() {
|
||||
@Override
|
||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||
menu.clear();
|
||||
for (int i = 0; i < _menuItems.length; i++) {
|
||||
menu.add(0, i, 0, _menuItems[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(ActionMode mode) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||
int selectionStart = view.getSelectionStart();
|
||||
int selectionEnd = view.getSelectionEnd();
|
||||
String selectedText = view.getText().toString().substring(selectionStart, selectionEnd);
|
||||
|
||||
// Dispatch event
|
||||
onSelectNativeEvent(view, item.getItemId(), selectedText, selectionStart, selectionEnd);
|
||||
|
||||
mode.finish();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public void onSelectNativeEvent(ReactEditText view, int eventType, String content, int selectionStart, int selectionEnd) {
|
||||
WritableMap event = Arguments.createMap();
|
||||
event.putInt("eventType", eventType);
|
||||
event.putString("content", content);
|
||||
event.putInt("selectionStart", selectionStart);
|
||||
event.putInt("selectionEnd", selectionEnd);
|
||||
|
||||
// Dispatch
|
||||
ReactContext reactContext = (ReactContext) view.getContext();
|
||||
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(view.getId(), "topSelection", event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map getExportedCustomDirectEventTypeConstants() {
|
||||
return MapBuilder.builder()
|
||||
.put("topSelection", MapBuilder.of("registrationName","onSelection"))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -30,15 +29,12 @@ public class StatusPackage implements ReactPackage {
|
||||
List<NativeModule> modules = new ArrayList<>();
|
||||
|
||||
modules.add(new StatusModule(reactContext, this.rootedDevice));
|
||||
modules.add(new RNSelectableTextInputModule(reactContext));
|
||||
|
||||
return modules;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||
return Arrays.<ViewManager>asList(
|
||||
new RNSelectableTextInputViewManager()
|
||||
);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
status-go = {
|
||||
src-override = null;
|
||||
gomobile-src-override = null;
|
||||
ipfs-gateway-url = "https://ipfs.status.im/";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -45,8 +45,8 @@ in stdenv.mkDerivation rec {
|
||||
filter = lib.mkFilter {
|
||||
root = path;
|
||||
include = [
|
||||
"package.json" "yarn.lock" "metro.config.js" "babel.config.js"
|
||||
"resources/.*" "translations/.*" "src/js/.*"
|
||||
"package.json" "yarn.lock" "metro.config.js" ".babelrc"
|
||||
"resources/.*" "translations/.*" "src/js/worklet_factory.js"
|
||||
"modules/react-native-status/android.*" "android/.*"
|
||||
envFileName "VERSION" "status-go-version.json" "react-native.config.js"
|
||||
];
|
||||
|
||||
@@ -9,17 +9,47 @@ self: super:
|
||||
|
||||
let
|
||||
inherit (super) stdenv stdenvNoCC callPackage;
|
||||
in {
|
||||
# Fix for MacOS
|
||||
mkShell = super.mkShell.override { stdenv = stdenvNoCC; };
|
||||
|
||||
# Various utilities
|
||||
utils = callPackage ./tools/utils.nix { };
|
||||
lib = (super.lib or { }) // (import ./lib {
|
||||
inherit (super) lib;
|
||||
inherit (self) config;
|
||||
});
|
||||
|
||||
gomobileSrcOverride = "/Users/vvlasov/c/mobile";
|
||||
# Warning message about using local sources
|
||||
localSrcWarn = (path: "Using local gomobile sources from ${path}");
|
||||
localGomobileSrc = rec {
|
||||
owner = "status-im";
|
||||
repo = "mobile";
|
||||
rev = "unknown";
|
||||
shortRev = rev;
|
||||
rawVersion = "develop";
|
||||
cleanVersion = rawVersion;
|
||||
goPackagePath = "github.com/${owner}/${repo}";
|
||||
# We use builtins.path so that we can name the resulting derivation,
|
||||
# Normally the name would not be deterministic, taken from the checkout directory.
|
||||
src = builtins.path rec {
|
||||
path = lib.traceValFn localSrcWarn gomobileSrcOverride;
|
||||
name = "${repo}-source-${shortRev}";
|
||||
# Keep this filter as restrictive as possible in order
|
||||
# to avoid unnecessary rebuilds and limit closure size
|
||||
filter = lib.mkFilter {
|
||||
root = path;
|
||||
include = [ ".*" ];
|
||||
exclude = [
|
||||
".*/[.]git.*" ".*[.]md" ".*[.]yml" ".*/.*_test.go$"
|
||||
"VERSION" "_assets/.*" "build/.*"
|
||||
".*/.*LICENSE.*" ".*/CONTRIB.*" ".*/AUTHOR.*"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
in {
|
||||
inherit lib;
|
||||
# Fix for MacOS
|
||||
mkShell = super.mkShell.override { stdenv = stdenvNoCC; };
|
||||
|
||||
# Various utilities
|
||||
utils = callPackage ./tools/utils.nix { };
|
||||
# Project dependencies
|
||||
deps = {
|
||||
clojure = callPackage ./deps/clojure { };
|
||||
@@ -45,11 +75,17 @@ in {
|
||||
buildGoPackage = super.buildGo118Package;
|
||||
buildGoModule = super.buildGo118Module;
|
||||
gomobile = (super.gomobile.overrideAttrs (old: {
|
||||
patches = self.fetchurl { # https://github.com/golang/mobile/pull/84
|
||||
url = "https://github.com/golang/mobile/commit/f20e966e05b8f7e06bed500fa0da81cf6ebca307.patch";
|
||||
sha256 = "sha256-TZ/Yhe8gMRQUZFAs9G5/cf2b9QGtTHRSObBFD5Pbh7Y=";
|
||||
};
|
||||
})).override {
|
||||
src = "/Users/vvlasov/c/mobile";
|
||||
vendorSha256 = "sha256-TZ/Yhe8gMRQUZFAs9G5/cf2b9QGtTHRSObBFD5Pbh7Y=";
|
||||
# patches = self.fetchurl { # https://github.com/golang/mobile/pull/84
|
||||
# url = "https://github.com/golang/mobile/commit/f20e966e05b8f7e06bed500fa0da81cf6ebca307.patch";
|
||||
# sha256 = "sha256-TZ/Yhe8gMRQUZFAs9G5/cf2b9QGtTHRSObBFD5Pbh7Y=";
|
||||
# };
|
||||
})).override rec {
|
||||
buildGoModule = args: super.buildGoModule ( args // {
|
||||
src = "/Users/vvlasov/c/mobile";
|
||||
vendorSha256 = "sha256-C6GD3NMolRIve1siG8wpcQav7ZWTugjce8K22EQDD7M=";
|
||||
});
|
||||
# FIXME: No Android SDK packages for aarch64-darwin.
|
||||
withAndroidPkgs = stdenv.system != "aarch64-darwin";
|
||||
androidPkgs = self.androidEnvCustom.compose;
|
||||
|
||||
@@ -46,6 +46,9 @@ config=''
|
||||
if [[ -n "${STATUS_GO_SRC_OVERRIDE}" ]]; then
|
||||
config+="status-im.status-go.src-override=\"${STATUS_GO_SRC_OVERRIDE}\";"
|
||||
fi
|
||||
if [[ -n "${GOMOBILE_SRC_OVERRIDE}" ]]; then
|
||||
config+="status-im.status-go.gomobile-src-override=\"${GOMOBILE_SRC_OVERRIDE}\";"
|
||||
fi
|
||||
config+="status-im.build-type=\"${BUILD_TYPE}\";"
|
||||
|
||||
if [[ -n "$config" ]]; then
|
||||
|
||||
@@ -12,6 +12,7 @@ let
|
||||
|
||||
# Source can be changed with a local override from config
|
||||
source = callPackage ./source.nix { };
|
||||
nimbusSource = callPackage ./nimbus_source.nix { };
|
||||
|
||||
# Params to be set at build time, important for About section and metrics
|
||||
goBuildParams = {
|
||||
@@ -31,14 +32,55 @@ let
|
||||
"-w" # -w disables DWARF debugging information
|
||||
];
|
||||
in rec {
|
||||
inherit nimbusSource;
|
||||
|
||||
mobile = callPackage ./mobile {
|
||||
inherit meta source goBuildLdFlags;
|
||||
inherit meta source nimbusSource nimCompiler goBuildLdFlags;
|
||||
};
|
||||
|
||||
library = callPackage ./library {
|
||||
inherit meta source;
|
||||
};
|
||||
|
||||
nimCompiler = callPackage ./mobile/buildNim.nix {
|
||||
srcRaw = nimbusSource;
|
||||
};
|
||||
|
||||
liblcproxy-android-arm = callPackage ./mobile/buildNimbus.nix {
|
||||
srcRaw = nimbusSource;
|
||||
nimCompiler = nimCompiler;
|
||||
platform = "android";
|
||||
arch = "arm";
|
||||
};
|
||||
|
||||
liblcproxy-android-arm64 = callPackage ./mobile/buildNimbus.nix {
|
||||
srcRaw = nimbusSource;
|
||||
nimCompiler = nimCompiler;
|
||||
platform = "android";
|
||||
arch = "arm64";
|
||||
};
|
||||
|
||||
liblcproxy-android-x86 = callPackage ./mobile/buildNimbus.nix {
|
||||
srcRaw = nimbusSource;
|
||||
nimCompiler = nimCompiler;
|
||||
platform = "android";
|
||||
arch = "x86";
|
||||
};
|
||||
|
||||
liblcproxy-ios-x86 = callPackage ./mobile/buildNimbus.nix {
|
||||
srcRaw = nimbusSource;
|
||||
nimCompiler = nimCompiler;
|
||||
platform = "ios";
|
||||
arch = "x86";
|
||||
};
|
||||
|
||||
liblcproxy-ios-arm64 = callPackage ./mobile/buildNimbus.nix {
|
||||
srcRaw = nimbusSource;
|
||||
nimCompiler = nimCompiler;
|
||||
platform = "ios";
|
||||
arch = "arm64";
|
||||
};
|
||||
|
||||
shell = mkShell {
|
||||
inputsFrom = [ mobile.android mobile.ios ];
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
, androidPkgs, openjdk, gomobile, xcodeWrapper, removeReferencesTo
|
||||
, meta
|
||||
, source
|
||||
, buildNimbusLc
|
||||
, platform ? "android"
|
||||
, platformVersion ? "23"
|
||||
, targets ? [ "android/arm64" "android/arm" ]
|
||||
@@ -13,7 +14,14 @@ let
|
||||
inherit (lib) concatStringsSep optionalString optional;
|
||||
isIOS = platform == "ios";
|
||||
isAndroid = platform == "android";
|
||||
lc = buildNimbusLc {inherit platform targets;};
|
||||
cgoCflags = "-I" + (builtins.elemAt lc 0);
|
||||
|
||||
lcDirs = (builtins.concatStringsSep " " (builtins.map (s: "-L" + s) lc));
|
||||
|
||||
goBuildLdFlagsModified =
|
||||
goBuildLdFlags ++ [("-extldflags \"-lverifproxy " + lcDirs + "\"")];
|
||||
ldflags = concatStringsSep " " goBuildLdFlagsModified;
|
||||
in buildGoPackage {
|
||||
pname = source.repo;
|
||||
version = "${source.cleanVersion}-${source.shortRev}-${platform}";
|
||||
@@ -30,8 +38,6 @@ in buildGoPackage {
|
||||
++ optional isAndroid openjdk
|
||||
++ optional isIOS xcodeWrapper;
|
||||
|
||||
ldflags = concatStringsSep " " goBuildLdFlags;
|
||||
|
||||
ANDROID_HOME = optionalString isAndroid androidPkgs.sdk;
|
||||
|
||||
# Ensure XCode is present for iOS, instead of failing at the end of the build.
|
||||
@@ -40,11 +46,13 @@ in buildGoPackage {
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
echo -e "\nBuilding $pname for: ${concatStringsSep "," targets}"
|
||||
|
||||
echo -e "\n LC dirs: ${lcDirs}"
|
||||
echo -e "\n ldflags: ${ldflags}"
|
||||
set -x
|
||||
export CGO_CFLAGS=\"${cgoCflags}\"
|
||||
gomobile bind \
|
||||
${concatStringsSep " " goBuildFlags} \
|
||||
-ldflags="$ldflags" \
|
||||
-ldflags ''\'${ldflags}''\' \
|
||||
-target=${concatStringsSep "," targets} \
|
||||
${optionalString isAndroid "-androidapi=${platformVersion}" } \
|
||||
${optionalString isIOS "-iosversion=${platformVersion}" } \
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
{ pkgs, stdenv, lib, fetchFromGitHub
|
||||
# Dependencies
|
||||
, xcodeWrapper
|
||||
, srcRaw
|
||||
, writeScript
|
||||
, writeTextFile
|
||||
, androidPkgs
|
||||
, git
|
||||
, platform ? "android"
|
||||
, arch ? "386"
|
||||
, api ? "29" }:
|
||||
|
||||
let
|
||||
osId = builtins.elemAt (builtins.split "\-" stdenv.hostPlatform.system) 2;
|
||||
osArch = builtins.elemAt (builtins.split "\-" stdenv.hostPlatform.system) 0;
|
||||
|
||||
nimHostOs = if osId == "darwin" then "Darwin"
|
||||
else if osId == "linux" then "Linux"
|
||||
else "Windows_NT";
|
||||
|
||||
createNimbleLink = writeTextFile {
|
||||
name = "createNimbleLink.sh";
|
||||
text = ''
|
||||
mkdir -p vendor/.nimble/pkgs
|
||||
|
||||
curdir=`pwd`
|
||||
for dir in vendor/*/;
|
||||
do
|
||||
baseDirName=`basename ''${dir}`
|
||||
dirName=vendor/.nimble/pkgs/$baseDirName-\#head
|
||||
echo $dirName
|
||||
mkdir -p $dirName
|
||||
|
||||
packageDir="''${curdir}/vendor/''${baseDirName}"
|
||||
if [ -d "''${packageDir}/src" ]; then
|
||||
packageDir="''${packageDir}/src"
|
||||
fi
|
||||
echo "''${packageDir}" > ''${dirName}/''${baseDirName}.nimble-link
|
||||
echo "''${packageDir}" >> ''${dirName}/''${baseDirName}.nimble-link
|
||||
done
|
||||
'';
|
||||
executable = true;
|
||||
};
|
||||
|
||||
in stdenv.mkDerivation rec {
|
||||
pname = "nimCompiler";
|
||||
name = "nimCompiler";
|
||||
src = srcRaw.src;
|
||||
#version = lib.strings.substring 0 7 src.rev;
|
||||
buildInputs = with pkgs; [ wget git clang which tcl curl];
|
||||
|
||||
phases = [ "unpackPhase" "buildPhase" "installPhase" ];
|
||||
|
||||
|
||||
buildPhase = ''
|
||||
${createNimbleLink}
|
||||
export HOME=$PWD
|
||||
unset SSL_CERT_FILE
|
||||
make V=3 CC=clang build-nim
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp -r vendor/nimbus-build-system/vendor/Nim/* $out/
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
{ pkgs, stdenv, lib, fetchFromGitHub
|
||||
# Dependencies
|
||||
, xcodeWrapper
|
||||
, srcRaw
|
||||
, writeScript
|
||||
, writeTextFile
|
||||
, androidPkgs
|
||||
, git
|
||||
, nimCompiler
|
||||
, platform ? "android"
|
||||
, arch ? "386"
|
||||
, api ? "29" }:
|
||||
|
||||
let
|
||||
osId = builtins.elemAt (builtins.split "\-" stdenv.hostPlatform.system) 2;
|
||||
osArch = builtins.elemAt (builtins.split "\-" stdenv.hostPlatform.system) 0;
|
||||
|
||||
|
||||
# Arg arch -> Nim arch
|
||||
nimCpuMap = {
|
||||
"x86" = "i386";
|
||||
"x86-64" = "amd64";
|
||||
"arm" = "arm";
|
||||
"arm64" = "arm64";
|
||||
};
|
||||
|
||||
iosArchMap = {
|
||||
"x86" = "x86_64";
|
||||
"x86-64" = "x86_64";
|
||||
"arm" = "armv7";
|
||||
"arm64" = "arm64";
|
||||
};
|
||||
|
||||
nimCpu = if platform == "ios" && arch == "x86"
|
||||
then "amd64" else "${lib.getAttr arch nimCpuMap}";
|
||||
nimPlatform = "${(if platform == "ios" then "ios" else "android")}";
|
||||
|
||||
iosSdk = if arch == "x86" then "iphonesimulator" else "iphoneos";
|
||||
iosArch = lib.getAttr arch iosArchMap;
|
||||
|
||||
isAndroid = lib.hasPrefix "android" platform;
|
||||
isIOS = platform == "ios";
|
||||
|
||||
|
||||
buildType = lib.getConfig "build-type" "";
|
||||
|
||||
|
||||
routeHeader = builtins.readFile ./route.h;
|
||||
|
||||
PROJECT_ROOT = srcRaw.src;
|
||||
|
||||
iosIncludes = stdenv.mkDerivation {
|
||||
name = "nim-status-ios-includes";
|
||||
buildInputs = [ pkgs.coreutils ];
|
||||
builder = writeScript "nim-ios-includes.sh"
|
||||
''
|
||||
export PATH=${pkgs.coreutils}/bin
|
||||
mkdir $out
|
||||
cd $out
|
||||
mkdir net
|
||||
echo "${routeHeader}" > net/route.h
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
ANDROID_NDK_HOME = "${androidPkgs.sdk}/ndk-bundle";
|
||||
|
||||
|
||||
androidToolchain = "${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/${osId}-${osArch}";
|
||||
androidTargetArchMap = {
|
||||
"x86" = "i686-linux-android";
|
||||
"x86-64" = "x86_64-linux-android";
|
||||
"arm" = "armv7a-linux-androideabi";
|
||||
"arm64" = "aarch64-linux-android";
|
||||
};
|
||||
|
||||
androidTargetArch = lib.getAttr arch androidTargetArchMap;
|
||||
|
||||
iosVersion = "9.0";
|
||||
|
||||
sysroot = if isAndroid then "${androidToolchain}/sysroot" else "$(xcrun --sdk ${iosSdk} --show-sdk-path)";
|
||||
compilerFlags = if isAndroid then
|
||||
"--sysroot ${sysroot} -fPIC -target ${androidTargetArch}${api}"
|
||||
else if isIOS then
|
||||
# TODO The conditional for -miphoneos-version-min=8.0 is required,
|
||||
# otherwise Nim will complain that thread-local storage is not supported for the current target
|
||||
# when expanding 'NIM_THREADVAR' macro
|
||||
"-isysroot ${sysroot} -fembed-bitcode -target ${iosArch}-apple-ios${iosVersion} ${if arch == "arm" then "" else "-miphoneos-version-min=${iosVersion}"} -I${iosIncludes}"
|
||||
else throw "Unsupported platform!";
|
||||
|
||||
linkerFlags = if isAndroid then
|
||||
"--sysroot ${sysroot} -target ${androidTargetArch}${api}"
|
||||
else if isIOS then
|
||||
"--sysroot ${sysroot} -fembed-bitcode -target ${iosArch}-apple-ios${iosVersion} ${if arch == "arm" then "" else "-miphoneos-version-min=${iosVersion}"} -v"
|
||||
else throw "Unsupported platform!";
|
||||
|
||||
ldDirMap = {
|
||||
"x86" = "i686";
|
||||
"x86-64" = "x86_64";
|
||||
"arm" = "armeabi-v7a";
|
||||
"arm64" = "arm64-v8a";
|
||||
};
|
||||
|
||||
cmakeArgs = if isAndroid then
|
||||
"-DCMAKE_SYSTEM_NAME=Android -DCMAKE_SYSTEM_VERSION=${api} -DCMAKE_ANDROID_ARCH_ABI=${lib.getAttr arch ldDirMap} -DCMAKE_ANDROID_NDK=${ANDROID_NDK_HOME}"
|
||||
else if isIOS then "-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=\"$(CMAKE_SYSROOT)\" -DCMAKE_OSX_ARCHITECTURES=${iosArch} -DCMAKE_OSX_DEPLOYMENT_TARGET=9.3 -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO -DCMAKE_IOS_INSTALL_COMBINED=YES"
|
||||
else throw "Unsupported platform!";
|
||||
#clangPath = if isAndroid then "${androidToolchain}/bin" else "";
|
||||
#clangName = if isAndroid then "${androidTargetArch}${api}-clang" else "";
|
||||
|
||||
compilerVars = if isAndroid then
|
||||
''
|
||||
export PATH=${androidToolchain}/bin:$PATH
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
export AR=${androidToolchain}/bin/llvm-ar
|
||||
export NM=${androidToolchain}/bin/llvm-nm
|
||||
export RANLIB=${androidToolchain}/bin/llvm-ranlib
|
||||
export LD=${androidToolchain}/bin/ld
|
||||
export AS=$CC
|
||||
export CFLAGS="${compilerFlags}"
|
||||
export LDFLAGS="${linkerFlags}"
|
||||
|
||||
mkdir bin
|
||||
touch bin/git
|
||||
chmod +x bin/git
|
||||
export PATH=./bin:$PATH
|
||||
''
|
||||
else if isIOS then
|
||||
''
|
||||
export PATH=${xcodeWrapper}/bin:$PATH
|
||||
export CC=clang #$(xcrun --sdk ${iosSdk} --find clang)
|
||||
export CXX=clang++ #$(xcrun --sdk ${iosSdk} --find clang++)
|
||||
export LD=clang
|
||||
export CFLAGS="${compilerFlags}"
|
||||
export LDFLAGS="${linkerFlags}"
|
||||
|
||||
mkdir bin
|
||||
touch bin/git
|
||||
chmod +x bin/git
|
||||
export PATH=./bin:$PATH
|
||||
|
||||
export CMAKE_SYSROOT=${sysroot}
|
||||
''
|
||||
else throw "Unsupported platform!";
|
||||
|
||||
src = srcRaw;
|
||||
|
||||
|
||||
nimHostOs = if osId == "darwin" then "Darwin"
|
||||
else if osId == "linux" then "Linux"
|
||||
else "Windows_NT";
|
||||
createNimbleLink = writeTextFile {
|
||||
name = "createNimbleLink.sh";
|
||||
text = ''
|
||||
mkdir -p vendor/.nimble/pkgs
|
||||
|
||||
curdir=`pwd`
|
||||
for dir in vendor/*/;
|
||||
do
|
||||
baseDirName=`basename ''${dir}`
|
||||
dirName=vendor/.nimble/pkgs/$baseDirName-\#head
|
||||
echo $dirName
|
||||
mkdir -p $dirName
|
||||
|
||||
packageDir="''${curdir}/vendor/''${baseDirName}"
|
||||
if [ -d "''${packageDir}/src" ]; then
|
||||
packageDir="''${packageDir}/src"
|
||||
fi
|
||||
echo "''${packageDir}" > ''${dirName}/''${baseDirName}.nimble-link
|
||||
echo "''${packageDir}" >> ''${dirName}/''${baseDirName}.nimble-link
|
||||
done
|
||||
'';
|
||||
executable = true;
|
||||
};
|
||||
|
||||
in stdenv.mkDerivation rec {
|
||||
pname = "libverifproxy";
|
||||
name = "libverifproxy";
|
||||
src = srcRaw.src;
|
||||
#version = lib.strings.substring 0 7 src.rev;
|
||||
buildInputs = with pkgs; [ wget git which tcl cmake libtool binutils];
|
||||
|
||||
phases = [ "unpackPhase" "preBuildPhase" "buildPhase" "installPhase" ];
|
||||
|
||||
preBuildPhase = ''
|
||||
|
||||
sed -E -i 's|^(LIBBACKTRACE_SED := true.*)|\1\nCMAKE_ARGS := ${cmakeArgs}|g' vendor/nim-libbacktrace/Makefile
|
||||
|
||||
sed -E -i 's|^(.*)(useNews\* = )(.*)|\1\2 false|g' vendor/nim-json-rpc/json_rpc/clients/config.nim
|
||||
sed -E -i 's|(.*XOPEN_SOURCE.*)|#\1|g' vendor/nim-nat-traversal/vendor/miniupnp/miniupnpc/Makefile
|
||||
|
||||
export HOME=$PWD
|
||||
|
||||
${createNimbleLink}
|
||||
|
||||
${compilerVars}
|
||||
export PATH=${nimCompiler}/bin:$PATH
|
||||
#export PATH=${pkgs.binutils}/bin:$PATH
|
||||
ln -sf ${pkgs.binutils}/bin/ar bin/ar
|
||||
'';
|
||||
|
||||
|
||||
buildPhase = ''
|
||||
which ar
|
||||
make V=3 OS=${nimHostOs} \
|
||||
CC=clang CXX=clang USE_SYSTEM_NIM=1 \
|
||||
NIMFLAGS="\
|
||||
--passC:\"${compilerFlags}\" \
|
||||
--passL:\"${linkerFlags}\" \
|
||||
--debuginfo:off \
|
||||
--cc:clang \
|
||||
--listcmd \
|
||||
--cpu:${nimCpu} \
|
||||
--os:${nimPlatform} \
|
||||
-d:disableMarchNative" \
|
||||
libverifproxy
|
||||
|
||||
echo "### ls build/libverifproxy"
|
||||
ls -l build/libverifproxy/*
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
set -x
|
||||
mkdir -p $out
|
||||
cp libverifproxy* $out/
|
||||
cp build/libverifproxy/verifproxy.h $out/
|
||||
cp build/libverifproxy/nimbase.h $out/
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -1,19 +1,44 @@
|
||||
{ callPackage, meta, source, goBuildLdFlags }:
|
||||
{ stdenv, callPackage, meta, source, nimbusSource, nimCompiler, goBuildLdFlags }:
|
||||
|
||||
let
|
||||
buildNimbusLc = { platform, targets }: builtins.map
|
||||
(target:
|
||||
let
|
||||
arch =
|
||||
if platform == "ios" then
|
||||
(if target == "iossimulator" && stdenv.hostPlatform.isx86
|
||||
then "x86" else "arm64")
|
||||
else builtins.elemAt (builtins.split "\/" target) 2 ;
|
||||
in
|
||||
callPackage ./buildNimbus.nix {
|
||||
inherit nimCompiler platform arch;
|
||||
srcRaw = nimbusSource;
|
||||
}
|
||||
)
|
||||
targets;
|
||||
in {
|
||||
|
||||
#ios-x86 = buildNimbusLc {platform = "ios"; targets = ["ios" "iossimulator"];};
|
||||
ios-x86 = buildNimbusLc {platform = "ios"; targets = ["iossimulator"];};
|
||||
ios-arm = buildNimbusLc {platform = "ios"; targets = ["ios"];};
|
||||
android-arm64 = buildNimbusLc {platform = "android"; targets = ["android/arm64"];};
|
||||
android-arm = buildNimbusLc {platform = "android"; targets = ["android/arm"];};
|
||||
|
||||
|
||||
{
|
||||
android = callPackage ./build.nix {
|
||||
platform = "android";
|
||||
platformVersion = "23";
|
||||
targets = [ "android/arm" "android/arm64" "android/386" ];
|
||||
#targets = [ "android/arm" "android/arm64" "android/386" ];
|
||||
targets = [ "android/arm64" ];
|
||||
outputFileName = "status-go-${source.shortRev}.aar";
|
||||
inherit meta source goBuildLdFlags;
|
||||
inherit meta source buildNimbusLc goBuildLdFlags;
|
||||
};
|
||||
|
||||
ios = callPackage ./build.nix {
|
||||
platform = "ios";
|
||||
platformVersion = "8.0";
|
||||
targets = [ "ios" "iossimulator" ];
|
||||
targets = [ "iossimulator" ];
|
||||
outputFileName = "Statusgo.xcframework";
|
||||
inherit meta source goBuildLdFlags;
|
||||
inherit meta source buildNimbusLc goBuildLdFlags;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2017 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. The rights granted to you under the License
|
||||
* may not be used to create, or enable the creation or redistribution of,
|
||||
* unlawful or unlicensed copies of an Apple operating system, or to
|
||||
* circumvent, violate, or enable the circumvention or violation of, any
|
||||
* terms of an Apple operating system software license agreement.
|
||||
*
|
||||
* Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)route.h 8.3 (Berkeley) 4/19/94
|
||||
* $FreeBSD: src/sys/net/route.h,v 1.36.2.1 2000/08/16 06:14:23 jayanth Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NET_ROUTE_H_
|
||||
#define _NET_ROUTE_H_
|
||||
#include <sys/appleapiopts.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
/*
|
||||
* These numbers are used by reliable protocols for determining
|
||||
* retransmission behavior and are included in the routing structure.
|
||||
*/
|
||||
struct rt_metrics {
|
||||
u_int32_t rmx_locks; /* Kernel leaves these values alone */
|
||||
u_int32_t rmx_mtu; /* MTU for this path */
|
||||
u_int32_t rmx_hopcount; /* max hops expected */
|
||||
int32_t rmx_expire; /* lifetime for route, e.g. redirect */
|
||||
u_int32_t rmx_recvpipe; /* inbound delay-bandwidth product */
|
||||
u_int32_t rmx_sendpipe; /* outbound delay-bandwidth product */
|
||||
u_int32_t rmx_ssthresh; /* outbound gateway buffer limit */
|
||||
u_int32_t rmx_rtt; /* estimated round trip time */
|
||||
u_int32_t rmx_rttvar; /* estimated rtt variance */
|
||||
u_int32_t rmx_pksent; /* packets sent using this route */
|
||||
u_int32_t rmx_state; /* route state */
|
||||
u_int32_t rmx_filler[3]; /* will be used for T/TCP later */
|
||||
};
|
||||
|
||||
/*
|
||||
* rmx_rtt and rmx_rttvar are stored as microseconds;
|
||||
*/
|
||||
#define RTM_RTTUNIT 1000000 /* units for rtt, rttvar, as units per sec */
|
||||
|
||||
|
||||
|
||||
#define RTF_UP 0x1 /* route usable */
|
||||
#define RTF_GATEWAY 0x2 /* destination is a gateway */
|
||||
#define RTF_HOST 0x4 /* host entry (net otherwise) */
|
||||
#define RTF_REJECT 0x8 /* host or net unreachable */
|
||||
#define RTF_DYNAMIC 0x10 /* created dynamically (by redirect) */
|
||||
#define RTF_MODIFIED 0x20 /* modified dynamically (by redirect) */
|
||||
#define RTF_DONE 0x40 /* message confirmed */
|
||||
#define RTF_DELCLONE 0x80 /* delete cloned route */
|
||||
#define RTF_CLONING 0x100 /* generate new routes on use */
|
||||
#define RTF_XRESOLVE 0x200 /* external daemon resolves name */
|
||||
#define RTF_LLINFO 0x400 /* DEPRECATED - exists ONLY for backward
|
||||
* compatibility */
|
||||
#define RTF_LLDATA 0x400 /* used by apps to add/del L2 entries */
|
||||
#define RTF_STATIC 0x800 /* manually added */
|
||||
#define RTF_BLACKHOLE 0x1000 /* just discard pkts (during updates) */
|
||||
#define RTF_NOIFREF 0x2000 /* not eligible for RTF_IFREF */
|
||||
#define RTF_PROTO2 0x4000 /* protocol specific routing flag */
|
||||
#define RTF_PROTO1 0x8000 /* protocol specific routing flag */
|
||||
|
||||
#define RTF_PRCLONING 0x10000 /* protocol requires cloning */
|
||||
#define RTF_WASCLONED 0x20000 /* route generated through cloning */
|
||||
#define RTF_PROTO3 0x40000 /* protocol specific routing flag */
|
||||
/* 0x80000 unused */
|
||||
#define RTF_PINNED 0x100000 /* future use */
|
||||
#define RTF_LOCAL 0x200000 /* route represents a local address */
|
||||
#define RTF_BROADCAST 0x400000 /* route represents a bcast address */
|
||||
#define RTF_MULTICAST 0x800000 /* route represents a mcast address */
|
||||
#define RTF_IFSCOPE 0x1000000 /* has valid interface scope */
|
||||
#define RTF_CONDEMNED 0x2000000 /* defunct; no longer modifiable */
|
||||
#define RTF_IFREF 0x4000000 /* route holds a ref to interface */
|
||||
#define RTF_PROXY 0x8000000 /* proxying, no interface scope */
|
||||
#define RTF_ROUTER 0x10000000 /* host is a router */
|
||||
#define RTF_DEAD 0x20000000 /* Route entry is being freed */
|
||||
/* 0x40000000 and up unassigned */
|
||||
|
||||
#define RTPRF_OURS RTF_PROTO3 /* set on routes we manage */
|
||||
#define RTF_BITS \
|
||||
"\020\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE" \
|
||||
"\10DELCLONE\11CLONING\12XRESOLVE\13LLINFO\14STATIC\15BLACKHOLE" \
|
||||
"\16NOIFREF\17PROTO2\20PROTO1\21PRCLONING\22WASCLONED\23PROTO3" \
|
||||
"\25PINNED\26LOCAL\27BROADCAST\30MULTICAST\31IFSCOPE\32CONDEMNED" \
|
||||
"\33IFREF\34PROXY\35ROUTER"
|
||||
|
||||
#define IS_DIRECT_HOSTROUTE(rt) \
|
||||
(((rt)->rt_flags & (RTF_HOST | RTF_GATEWAY)) == RTF_HOST)
|
||||
/*
|
||||
* Routing statistics.
|
||||
*/
|
||||
struct rtstat {
|
||||
short rts_badredirect; /* bogus redirect calls */
|
||||
short rts_dynamic; /* routes created by redirects */
|
||||
short rts_newgateway; /* routes modified by redirects */
|
||||
short rts_unreach; /* lookups which failed */
|
||||
short rts_wildcard; /* lookups satisfied by a wildcard */
|
||||
short rts_badrtgwroute; /* route to gateway is not direct */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structures for routing messages.
|
||||
*/
|
||||
struct rt_msghdr {
|
||||
u_short rtm_msglen; /* to skip over non-understood messages */
|
||||
u_char rtm_version; /* future binary compatibility */
|
||||
u_char rtm_type; /* message type */
|
||||
u_short rtm_index; /* index for associated ifp */
|
||||
int rtm_flags; /* flags, incl. kern & message, e.g. DONE */
|
||||
int rtm_addrs; /* bitmask identifying sockaddrs in msg */
|
||||
pid_t rtm_pid; /* identify sender */
|
||||
int rtm_seq; /* for sender to identify action */
|
||||
int rtm_errno; /* why failed */
|
||||
int rtm_use; /* from rtentry */
|
||||
u_int32_t rtm_inits; /* which metrics we are initializing */
|
||||
struct rt_metrics rtm_rmx; /* metrics themselves */
|
||||
};
|
||||
|
||||
struct rt_msghdr2 {
|
||||
u_short rtm_msglen; /* to skip over non-understood messages */
|
||||
u_char rtm_version; /* future binary compatibility */
|
||||
u_char rtm_type; /* message type */
|
||||
u_short rtm_index; /* index for associated ifp */
|
||||
int rtm_flags; /* flags, incl. kern & message, e.g. DONE */
|
||||
int rtm_addrs; /* bitmask identifying sockaddrs in msg */
|
||||
int32_t rtm_refcnt; /* reference count */
|
||||
int rtm_parentflags; /* flags of the parent route */
|
||||
int rtm_reserved; /* reserved field set to 0 */
|
||||
int rtm_use; /* from rtentry */
|
||||
u_int32_t rtm_inits; /* which metrics we are initializing */
|
||||
struct rt_metrics rtm_rmx; /* metrics themselves */
|
||||
};
|
||||
|
||||
|
||||
#define RTM_VERSION 5 /* Up the ante and ignore older versions */
|
||||
|
||||
/*
|
||||
* Message types.
|
||||
*/
|
||||
#define RTM_ADD 0x1 /* Add Route */
|
||||
#define RTM_DELETE 0x2 /* Delete Route */
|
||||
#define RTM_CHANGE 0x3 /* Change Metrics or flags */
|
||||
#define RTM_GET 0x4 /* Report Metrics */
|
||||
#define RTM_LOSING 0x5 /* RTM_LOSING is no longer generated by xnu
|
||||
* and is deprecated */
|
||||
#define RTM_REDIRECT 0x6 /* Told to use different route */
|
||||
#define RTM_MISS 0x7 /* Lookup failed on this address */
|
||||
#define RTM_LOCK 0x8 /* fix specified metrics */
|
||||
#define RTM_OLDADD 0x9 /* caused by SIOCADDRT */
|
||||
#define RTM_OLDDEL 0xa /* caused by SIOCDELRT */
|
||||
#define RTM_RESOLVE 0xb /* req to resolve dst to LL addr */
|
||||
#define RTM_NEWADDR 0xc /* address being added to iface */
|
||||
#define RTM_DELADDR 0xd /* address being removed from iface */
|
||||
#define RTM_IFINFO 0xe /* iface going up/down etc. */
|
||||
#define RTM_NEWMADDR 0xf /* mcast group membership being added to if */
|
||||
#define RTM_DELMADDR 0x10 /* mcast group membership being deleted */
|
||||
#define RTM_IFINFO2 0x12 /* */
|
||||
#define RTM_NEWMADDR2 0x13 /* */
|
||||
#define RTM_GET2 0x14 /* */
|
||||
|
||||
/*
|
||||
* Bitmask values for rtm_inits and rmx_locks.
|
||||
*/
|
||||
#define RTV_MTU 0x1 /* init or lock _mtu */
|
||||
#define RTV_HOPCOUNT 0x2 /* init or lock _hopcount */
|
||||
#define RTV_EXPIRE 0x4 /* init or lock _expire */
|
||||
#define RTV_RPIPE 0x8 /* init or lock _recvpipe */
|
||||
#define RTV_SPIPE 0x10 /* init or lock _sendpipe */
|
||||
#define RTV_SSTHRESH 0x20 /* init or lock _ssthresh */
|
||||
#define RTV_RTT 0x40 /* init or lock _rtt */
|
||||
#define RTV_RTTVAR 0x80 /* init or lock _rttvar */
|
||||
|
||||
/*
|
||||
* Bitmask values for rtm_addrs.
|
||||
*/
|
||||
#define RTA_DST 0x1 /* destination sockaddr present */
|
||||
#define RTA_GATEWAY 0x2 /* gateway sockaddr present */
|
||||
#define RTA_NETMASK 0x4 /* netmask sockaddr present */
|
||||
#define RTA_GENMASK 0x8 /* cloning mask sockaddr present */
|
||||
#define RTA_IFP 0x10 /* interface name sockaddr present */
|
||||
#define RTA_IFA 0x20 /* interface addr sockaddr present */
|
||||
#define RTA_AUTHOR 0x40 /* sockaddr for author of redirect */
|
||||
#define RTA_BRD 0x80 /* for NEWADDR, broadcast or p-p dest addr */
|
||||
|
||||
/*
|
||||
* Index offsets for sockaddr array for alternate internal encoding.
|
||||
*/
|
||||
#define RTAX_DST 0 /* destination sockaddr present */
|
||||
#define RTAX_GATEWAY 1 /* gateway sockaddr present */
|
||||
#define RTAX_NETMASK 2 /* netmask sockaddr present */
|
||||
#define RTAX_GENMASK 3 /* cloning mask sockaddr present */
|
||||
#define RTAX_IFP 4 /* interface name sockaddr present */
|
||||
#define RTAX_IFA 5 /* interface addr sockaddr present */
|
||||
#define RTAX_AUTHOR 6 /* sockaddr for author of redirect */
|
||||
#define RTAX_BRD 7 /* for NEWADDR, broadcast or p-p dest addr */
|
||||
#define RTAX_MAX 8 /* size of array to allocate */
|
||||
|
||||
struct rt_addrinfo {
|
||||
int rti_addrs;
|
||||
struct sockaddr *rti_info[RTAX_MAX];
|
||||
};
|
||||
|
||||
|
||||
#endif /* _NET_ROUTE_H_ */
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
{ utils, lib, fetchFromGitHub }:
|
||||
|
||||
let
|
||||
inherit (lib) strings traceValFn importJSON getConfig;
|
||||
|
||||
srcOverride = getConfig "nimbus-eth1.src-override" null;
|
||||
# Warning message about using local sources
|
||||
localSrcWarn = (path: "Using local nimbus-eth1 sources from ${path}");
|
||||
|
||||
localSrc = rec {
|
||||
owner = "status-im";
|
||||
repo = "nimbus-eth1";
|
||||
rev = "unknown";
|
||||
shortRev = rev;
|
||||
rawVersion = "develop";
|
||||
cleanVersion = rawVersion;
|
||||
goPackagePath = "github.com/${owner}/${repo}";
|
||||
# We use builtins.path so that we can name the resulting derivation,
|
||||
# Normally the name would not be deterministic, taken from the checkout directory.
|
||||
src = builtins.path rec {
|
||||
path = traceValFn localSrcWarn srcOverride;
|
||||
name = "${repo}-source-${shortRev}";
|
||||
# Keep this filter as restrictive as possible in order
|
||||
# to avoid unnecessary rebuilds and limit closure size
|
||||
filter = lib.mkFilter {
|
||||
root = path;
|
||||
include = [ ".*" ];
|
||||
exclude = [
|
||||
".*/[.]git.*" ".*[.]md" ".*[.]yml" ".*/.*_test.go$"
|
||||
"VERSION" "_assets/.*" "build/.*"
|
||||
".*/.*LICENSE.*" ".*/CONTRIB.*" ".*/AUTHOR.*"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
githubSrc = let
|
||||
owner = "status-im";
|
||||
repo = "nimbus-eth1";
|
||||
# Static lib
|
||||
# rev = "211a0ed1e89bc836a79759e35db4a45f23a79b14";
|
||||
# sha256 = "sha256-Z+PoQMoYJK9ort2ZiXE1oLeoNu2H44HHNnL4pbp+uI8=";
|
||||
# Dynamic lib
|
||||
rev = "1199e476397e271b889e54680dc632e47bc01dd6";
|
||||
sha256 = "sha256-egx+I4h/V/56QRBtlaZffc3hrq7IaZCqL2Lm5XNqH1c=";
|
||||
version = "0.1";
|
||||
in rec {
|
||||
inherit owner repo rev sha256 version;
|
||||
shortRev = strings.substring 0 7 rev;
|
||||
rawVersion = version;
|
||||
cleanVersion = utils.sanitizeVersion version;
|
||||
src = fetchFromGitHub {
|
||||
inherit rev owner repo sha256;
|
||||
name = "${repo}-${shortRev}-source-with-submodules";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
};
|
||||
in
|
||||
if srcOverride != null
|
||||
# If config.status-im.status-go.src-override is defined,
|
||||
# instruct Nix to use that path to build status-go
|
||||
then localSrc
|
||||
# Otherwise grab it from the location defined by status-go-version.json
|
||||
else githubSrc
|
||||
@@ -74,7 +74,7 @@
|
||||
"react-native-touch-id": "^4.4.1",
|
||||
"react-native-webview": "git+https://github.com/status-im/react-native-webview.git#refs/tags/v11.16.0-status",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
"rn-emoji-keyboard": "0.7.0",
|
||||
"rn-emoji-keyboard": "git+https://github.com/status-im/rn-emoji-keyboard.git#refs/tags/v0.4.3",
|
||||
"tdigest": "^0.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -82,21 +82,12 @@
|
||||
"@babel/helper-builder-react-jsx": "7.0.0",
|
||||
"@babel/plugin-transform-block-scoping": "7.0.0",
|
||||
"@babel/preset-env": "7.1.0",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@babel/register": "7.0.0",
|
||||
"@jest/globals": "^25.1.0",
|
||||
"@mapbox/node-pre-gyp": "^1.0.9",
|
||||
"@testing-library/jest-native": "^5.0.0",
|
||||
"@testing-library/react-native": "^11.2.0",
|
||||
"@types/jest": "^28.1.6",
|
||||
"detox": "^19.9.1",
|
||||
"jest": "^25.1.0",
|
||||
"jest-circus": "^26.0.0",
|
||||
"jest-image-snapshot": "^5.1.0",
|
||||
"nodemon": "^2.0.16",
|
||||
"nyc": "^14.1.1",
|
||||
"process": "0.11.10",
|
||||
"react-test-renderer": "16.13.1",
|
||||
"rn-snoopy": "git+https://github.com/status-im/rn-snoopy.git#refs/tags/v2.0.2-status",
|
||||
"shadow-cljs": "2.11.16"
|
||||
},
|
||||
|
||||
@@ -1,165 +1,131 @@
|
||||
{
|
||||
"fleets": {
|
||||
"eth.prod": {
|
||||
"boot": {
|
||||
"boot-01.ac-cn-hongkong-c.eth.prod": "enode://6e6554fb3034b211398fcd0f0082cbb6bd13619e1a7e76ba66e1809aaa0c5f1ac53c9ae79cf2fd4a7bacb10d12010899b370c75fed19b991d9c0cdd02891abad@47.75.99.169:443",
|
||||
"boot-01.do-ams3.eth.prod": "enode://436cc6f674928fdc9a9f7990f2944002b685d1c37f025c1be425185b5b1f0900feaf1ccc2a6130268f9901be4a7d252f37302c8335a2c1a62736e9232691cc3a@178.128.138.128:443",
|
||||
"boot-01.gc-us-central1-a.eth.prod": "enode://32ff6d88760b0947a3dee54ceff4d8d7f0b4c023c6dad34568615fcae89e26cc2753f28f12485a4116c977be937a72665116596265aa0736b53d46b27446296a@34.70.75.208:443",
|
||||
"boot-02.ac-cn-hongkong-c.eth.prod": "enode://23d0740b11919358625d79d4cac7d50a34d79e9c69e16831c5c70573757a1f5d7d884510bc595d7ee4da3c1508adf87bbc9e9260d804ef03f8c1e37f2fb2fc69@47.52.106.107:443",
|
||||
"boot-02.do-ams3.eth.prod": "enode://5395aab7833f1ecb671b59bf0521cf20224fe8162fc3d2675de4ee4d5636a75ec32d13268fc184df8d1ddfa803943906882da62a4df42d4fccf6d17808156a87@178.128.140.188:443",
|
||||
"boot-02.gc-us-central1-a.eth.prod": "enode://5405c509df683c962e7c9470b251bb679dd6978f82d5b469f1f6c64d11d50fbd5dd9f7801c6ad51f3b20a5f6c7ffe248cc9ab223f8bcbaeaf14bb1c0ef295fd0@35.223.215.156:443"
|
||||
},
|
||||
"mail": {
|
||||
"mail-01.ac-cn-hongkong-c.eth.prod": "enode://606ae04a71e5db868a722c77a21c8244ae38f1bd6e81687cc6cfe88a3063fa1c245692232f64f45bd5408fed5133eab8ed78049332b04f9c110eac7f71c1b429@47.75.247.214:443",
|
||||
"mail-01.do-ams3.eth.prod": "enode://c42f368a23fa98ee546fd247220759062323249ef657d26d357a777443aec04db1b29a3a22ef3e7c548e18493ddaf51a31b0aed6079bd6ebe5ae838fcfaf3a49@178.128.142.54:443",
|
||||
"mail-01.gc-us-central1-a.eth.prod": "enode://ee2b53b0ace9692167a410514bca3024695dbf0e1a68e1dff9716da620efb195f04a4b9e873fb9b74ac84de801106c465b8e2b6c4f0d93b8749d1578bfcaf03e@104.197.238.144:443",
|
||||
"mail-02.ac-cn-hongkong-c.eth.prod": "enode://2c8de3cbb27a3d30cbb5b3e003bc722b126f5aef82e2052aaef032ca94e0c7ad219e533ba88c70585ebd802de206693255335b100307645ab5170e88620d2a81@47.244.221.14:443",
|
||||
"mail-02.do-ams3.eth.prod": "enode://7aa648d6e855950b2e3d3bf220c496e0cae4adfddef3e1e6062e6b177aec93bc6cdcf1282cb40d1656932ebfdd565729da440368d7c4da7dbd4d004b1ac02bf8@178.128.142.26:443",
|
||||
"mail-02.gc-us-central1-a.eth.prod": "enode://30211cbd81c25f07b03a0196d56e6ce4604bb13db773ff1c0ea2253547fafd6c06eae6ad3533e2ba39d59564cfbdbb5e2ce7c137a5ebb85e99dcfc7a75f99f55@23.236.58.92:443",
|
||||
"mail-03.ac-cn-hongkong-c.eth.prod": "enode://e85f1d4209f2f99da801af18db8716e584a28ad0bdc47fbdcd8f26af74dbd97fc279144680553ec7cd9092afe683ddea1e0f9fc571ebcb4b1d857c03a088853d@47.244.129.82:443",
|
||||
"mail-03.do-ams3.eth.prod": "enode://8a64b3c349a2e0ef4a32ea49609ed6eb3364be1110253c20adc17a3cebbc39a219e5d3e13b151c0eee5d8e0f9a8ba2cd026014e67b41a4ab7d1d5dd67ca27427@178.128.142.94:443",
|
||||
"mail-03.gc-us-central1-a.eth.prod": "enode://44160e22e8b42bd32a06c1532165fa9e096eebedd7fa6d6e5f8bbef0440bc4a4591fe3651be68193a7ec029021cdb496cfe1d7f9f1dc69eb99226e6f39a7a5d4@35.225.221.245:443"
|
||||
},
|
||||
"rendezvous": {
|
||||
"boot-01.ac-cn-hongkong-c.eth.prod": "/ip4/47.75.99.169/tcp/30703/ethv4/16Uiu2HAmV8Hq9e3zm9TMVP4zrVHo3BjqW5D6bDVV6VQntQd687e4",
|
||||
"boot-01.do-ams3.eth.prod": "/ip4/178.128.138.128/tcp/30703/ethv4/16Uiu2HAmRHPzF3rQg55PgYPcQkyvPVH9n2hWsYPhUJBZ6kVjJgdV",
|
||||
"boot-01.gc-us-central1-a.eth.prod": "/ip4/34.70.75.208/tcp/30703/ethv4/16Uiu2HAm6ZsERLx2BwVD2UM9SVPnnMU6NBycG8XPtu8qKys5awsU",
|
||||
"boot-02.ac-cn-hongkong-c.eth.prod": "/ip4/47.52.106.107/tcp/30703/ethv4/16Uiu2HAmEHiptiDDd9gqNY8oQqo8hHUWMHJzfwt5aLRdD6W2zcXR",
|
||||
"boot-02.do-ams3.eth.prod": "/ip4/178.128.140.188/tcp/30703/ethv4/16Uiu2HAmLqTXuY4Sb6G28HNooaFUXUKzpzKXCcgyJxgaEE2i5vnf",
|
||||
"boot-02.gc-us-central1-a.eth.prod": "/ip4/35.223.215.156/tcp/30703/ethv4/16Uiu2HAmQEUFE2YaJohavWtHxPTEFv3sEGJtDqvtGEv78DFoEWQF"
|
||||
},
|
||||
"whisper": {
|
||||
"node-01.ac-cn-hongkong-c.eth.prod": "enode://b957e51f41e4abab8382e1ea7229e88c6e18f34672694c6eae389eac22dab8655622bbd4a08192c321416b9becffaab11c8e2b7a5d0813b922aa128b82990dab@47.75.222.178:443",
|
||||
"node-01.do-ams3.eth.prod": "enode://66ba15600cda86009689354c3a77bdf1a97f4f4fb3ab50ffe34dbc904fac561040496828397be18d9744c75881ffc6ac53729ddbd2cdbdadc5f45c400e2622f7@178.128.141.87:443",
|
||||
"node-01.gc-us-central1-a.eth.prod": "enode://182ed5d658d1a1a4382c9e9f7c9e5d8d9fec9db4c71ae346b9e23e1a589116aeffb3342299bdd00e0ab98dbf804f7b2d8ae564ed18da9f45650b444aed79d509@34.68.132.118:443",
|
||||
"node-02.ac-cn-hongkong-c.eth.prod": "enode://8bebe73ddf7cf09e77602c7d04c93a73f455b51f24ae0d572917a4792f1dec0bb4c562759b8830cc3615a658d38c1a4a38597a1d7ae3ba35111479fc42d65dec@47.75.85.212:443",
|
||||
"node-02.do-ams3.eth.prod": "enode://4ea35352702027984a13274f241a56a47854a7fd4b3ba674a596cff917d3c825506431cf149f9f2312a293bb7c2b1cca55db742027090916d01529fe0729643b@134.209.136.79:443",
|
||||
"node-02.gc-us-central1-a.eth.prod": "enode://fbeddac99d396b91d59f2c63a3cb5fc7e0f8a9f7ce6fe5f2eed5e787a0154161b7173a6a73124a4275ef338b8966dc70a611e9ae2192f0f2340395661fad81c0@34.67.230.193:443",
|
||||
"node-03.ac-cn-hongkong-c.eth.prod": "enode://ac3948b2c0786ada7d17b80cf869cf59b1909ea3accd45944aae35bf864cc069126da8b82dfef4ddf23f1d6d6b44b1565c4cf81c8b98022253c6aea1a89d3ce2@47.75.88.12:443",
|
||||
"node-03.do-ams3.eth.prod": "enode://ce559a37a9c344d7109bd4907802dd690008381d51f658c43056ec36ac043338bd92f1ac6043e645b64953b06f27202d679756a9c7cf62fdefa01b2e6ac5098e@134.209.136.123:443",
|
||||
"node-03.gc-us-central1-a.eth.prod": "enode://c07aa0deea3b7056c5d45a85bca42f0d8d3b1404eeb9577610f386e0a4744a0e7b2845ae328efc4aa4b28075af838b59b5b3985bffddeec0090b3b7669abc1f3@35.226.92.155:443",
|
||||
"node-04.ac-cn-hongkong-c.eth.prod": "enode://385579fc5b14e04d5b04af7eee835d426d3d40ccf11f99dbd95340405f37cf3bbbf830b3eb8f70924be0c2909790120682c9c3e791646e2d5413e7801545d353@47.244.221.249:443",
|
||||
"node-04.do-ams3.eth.prod": "enode://4e0a8db9b73403c9339a2077e911851750fc955db1fc1e09f81a4a56725946884dd5e4d11258eac961f9078a393c45bcab78dd0e3bc74e37ce773b3471d2e29c@134.209.136.101:443",
|
||||
"node-04.gc-us-central1-a.eth.prod": "enode://0624b4a90063923c5cc27d12624b6a49a86dfb3623fcb106801217fdbab95f7617b83fa2468b9ae3de593ff6c1cf556ccf9bc705bfae9cb4625999765127b423@35.222.158.246:443",
|
||||
"node-05.ac-cn-hongkong-c.eth.prod": "enode://b77bffc29e2592f30180311dd81204ab845e5f78953b5ba0587c6631be9c0862963dea5eb64c90617cf0efd75308e22a42e30bc4eb3cd1bbddbd1da38ff6483e@47.75.10.177:443",
|
||||
"node-05.do-ams3.eth.prod": "enode://a8bddfa24e1e92a82609b390766faa56cf7a5eef85b22a2b51e79b333c8aaeec84f7b4267e432edd1cf45b63a3ad0fc7d6c3a16f046aa6bc07ebe50e80b63b8c@178.128.141.249:443",
|
||||
"node-05.gc-us-central1-a.eth.prod": "enode://a5fe9c82ad1ffb16ae60cb5d4ffe746b9de4c5fbf20911992b7dd651b1c08ba17dd2c0b27ee6b03162c52d92f219961cc3eb14286aca8a90b75cf425826c3bd8@104.154.230.58:443",
|
||||
"node-06.ac-cn-hongkong-c.eth.prod": "enode://cf5f7a7e64e3b306d1bc16073fba45be3344cb6695b0b616ccc2da66ea35b9f35b3b231c6cf335fdfaba523519659a440752fc2e061d1e5bc4ef33864aac2f19@47.75.221.196:443",
|
||||
"node-06.do-ams3.eth.prod": "enode://887cbd92d95afc2c5f1e227356314a53d3d18855880ac0509e0c0870362aee03939d4074e6ad31365915af41d34320b5094bfcc12a67c381788cd7298d06c875@178.128.141.0:443",
|
||||
"node-06.gc-us-central1-a.eth.prod": "enode://282e009967f9f132a5c2dd366a76319f0d22d60d0c51f7e99795a1e40f213c2705a2c10e4cc6f3890319f59da1a535b8835ed9b9c4b57c3aad342bf312fd7379@35.223.240.17:443",
|
||||
"node-07.ac-cn-hongkong-c.eth.prod": "enode://13d63a1f85ccdcbd2fb6861b9bd9d03f94bdba973608951f7c36e5df5114c91de2b8194d71288f24bfd17908c48468e89dd8f0fb8ccc2b2dedae84acdf65f62a@47.244.210.80:443",
|
||||
"node-07.do-ams3.eth.prod": "enode://2b01955d7e11e29dce07343b456e4e96c081760022d1652b1c4b641eaf320e3747871870fa682e9e9cfb85b819ce94ed2fee1ac458904d54fd0b97d33ba2c4a4@134.209.136.112:443",
|
||||
"node-07.gc-us-central1-a.eth.prod": "enode://b706a60572634760f18a27dd407b2b3582f7e065110dae10e3998498f1ae3f29ba04db198460d83ed6d2bfb254bb06b29aab3c91415d75d3b869cd0037f3853c@35.239.5.162:443",
|
||||
"node-08.ac-cn-hongkong-c.eth.prod": "enode://32915c8841faaef21a6b75ab6ed7c2b6f0790eb177ad0f4ea6d731bacc19b938624d220d937ebd95e0f6596b7232bbb672905ee12601747a12ee71a15bfdf31c@47.75.59.11:443",
|
||||
"node-08.do-ams3.eth.prod": "enode://0d9d65fcd5592df33ed4507ce862b9c748b6dbd1ea3a1deb94e3750052760b4850aa527265bbaf357021d64d5cc53c02b410458e732fafc5b53f257944247760@178.128.141.42:443",
|
||||
"node-08.gc-us-central1-a.eth.prod": "enode://e87f1d8093d304c3a9d6f1165b85d6b374f1c0cc907d39c0879eb67f0a39d779be7a85cbd52920b6f53a94da43099c58837034afa6a7be4b099bfcd79ad13999@35.238.106.101:443"
|
||||
}
|
||||
"fleets": {
|
||||
"eth.prod": {
|
||||
"boot": {
|
||||
"boot-01.ac-cn-hongkong-c.eth.prod": "enode://6e6554fb3034b211398fcd0f0082cbb6bd13619e1a7e76ba66e1809aaa0c5f1ac53c9ae79cf2fd4a7bacb10d12010899b370c75fed19b991d9c0cdd02891abad@47.75.99.169:443",
|
||||
"boot-01.do-ams3.eth.prod": "enode://436cc6f674928fdc9a9f7990f2944002b685d1c37f025c1be425185b5b1f0900feaf1ccc2a6130268f9901be4a7d252f37302c8335a2c1a62736e9232691cc3a@178.128.138.128:443",
|
||||
"boot-01.gc-us-central1-a.eth.prod": "enode://32ff6d88760b0947a3dee54ceff4d8d7f0b4c023c6dad34568615fcae89e26cc2753f28f12485a4116c977be937a72665116596265aa0736b53d46b27446296a@34.70.75.208:443",
|
||||
"boot-02.ac-cn-hongkong-c.eth.prod": "enode://23d0740b11919358625d79d4cac7d50a34d79e9c69e16831c5c70573757a1f5d7d884510bc595d7ee4da3c1508adf87bbc9e9260d804ef03f8c1e37f2fb2fc69@47.52.106.107:443",
|
||||
"boot-02.do-ams3.eth.prod": "enode://5395aab7833f1ecb671b59bf0521cf20224fe8162fc3d2675de4ee4d5636a75ec32d13268fc184df8d1ddfa803943906882da62a4df42d4fccf6d17808156a87@178.128.140.188:443",
|
||||
"boot-02.gc-us-central1-a.eth.prod": "enode://5405c509df683c962e7c9470b251bb679dd6978f82d5b469f1f6c64d11d50fbd5dd9f7801c6ad51f3b20a5f6c7ffe248cc9ab223f8bcbaeaf14bb1c0ef295fd0@35.223.215.156:443"
|
||||
},
|
||||
"mail": {
|
||||
"mail-01.ac-cn-hongkong-c.eth.prod": "enode://606ae04a71e5db868a722c77a21c8244ae38f1bd6e81687cc6cfe88a3063fa1c245692232f64f45bd5408fed5133eab8ed78049332b04f9c110eac7f71c1b429@47.75.247.214:443",
|
||||
"mail-01.do-ams3.eth.prod": "enode://c42f368a23fa98ee546fd247220759062323249ef657d26d357a777443aec04db1b29a3a22ef3e7c548e18493ddaf51a31b0aed6079bd6ebe5ae838fcfaf3a49@178.128.142.54:443",
|
||||
"mail-01.gc-us-central1-a.eth.prod": "enode://ee2b53b0ace9692167a410514bca3024695dbf0e1a68e1dff9716da620efb195f04a4b9e873fb9b74ac84de801106c465b8e2b6c4f0d93b8749d1578bfcaf03e@104.197.238.144:443",
|
||||
"mail-02.ac-cn-hongkong-c.eth.prod": "enode://2c8de3cbb27a3d30cbb5b3e003bc722b126f5aef82e2052aaef032ca94e0c7ad219e533ba88c70585ebd802de206693255335b100307645ab5170e88620d2a81@47.244.221.14:443",
|
||||
"mail-02.do-ams3.eth.prod": "enode://7aa648d6e855950b2e3d3bf220c496e0cae4adfddef3e1e6062e6b177aec93bc6cdcf1282cb40d1656932ebfdd565729da440368d7c4da7dbd4d004b1ac02bf8@178.128.142.26:443",
|
||||
"mail-02.gc-us-central1-a.eth.prod": "enode://30211cbd81c25f07b03a0196d56e6ce4604bb13db773ff1c0ea2253547fafd6c06eae6ad3533e2ba39d59564cfbdbb5e2ce7c137a5ebb85e99dcfc7a75f99f55@23.236.58.92:443",
|
||||
"mail-03.ac-cn-hongkong-c.eth.prod": "enode://e85f1d4209f2f99da801af18db8716e584a28ad0bdc47fbdcd8f26af74dbd97fc279144680553ec7cd9092afe683ddea1e0f9fc571ebcb4b1d857c03a088853d@47.244.129.82:443",
|
||||
"mail-03.do-ams3.eth.prod": "enode://8a64b3c349a2e0ef4a32ea49609ed6eb3364be1110253c20adc17a3cebbc39a219e5d3e13b151c0eee5d8e0f9a8ba2cd026014e67b41a4ab7d1d5dd67ca27427@178.128.142.94:443",
|
||||
"mail-03.gc-us-central1-a.eth.prod": "enode://44160e22e8b42bd32a06c1532165fa9e096eebedd7fa6d6e5f8bbef0440bc4a4591fe3651be68193a7ec029021cdb496cfe1d7f9f1dc69eb99226e6f39a7a5d4@35.225.221.245:443"
|
||||
},
|
||||
"rendezvous": {
|
||||
"boot-01.ac-cn-hongkong-c.eth.prod": "/ip4/47.75.99.169/tcp/30703/ethv4/16Uiu2HAmV8Hq9e3zm9TMVP4zrVHo3BjqW5D6bDVV6VQntQd687e4",
|
||||
"boot-01.do-ams3.eth.prod": "/ip4/178.128.138.128/tcp/30703/ethv4/16Uiu2HAmRHPzF3rQg55PgYPcQkyvPVH9n2hWsYPhUJBZ6kVjJgdV",
|
||||
"boot-01.gc-us-central1-a.eth.prod": "/ip4/34.70.75.208/tcp/30703/ethv4/16Uiu2HAm6ZsERLx2BwVD2UM9SVPnnMU6NBycG8XPtu8qKys5awsU",
|
||||
"boot-02.ac-cn-hongkong-c.eth.prod": "/ip4/47.52.106.107/tcp/30703/ethv4/16Uiu2HAmEHiptiDDd9gqNY8oQqo8hHUWMHJzfwt5aLRdD6W2zcXR",
|
||||
"boot-02.do-ams3.eth.prod": "/ip4/178.128.140.188/tcp/30703/ethv4/16Uiu2HAmLqTXuY4Sb6G28HNooaFUXUKzpzKXCcgyJxgaEE2i5vnf",
|
||||
"boot-02.gc-us-central1-a.eth.prod": "/ip4/35.223.215.156/tcp/30703/ethv4/16Uiu2HAmQEUFE2YaJohavWtHxPTEFv3sEGJtDqvtGEv78DFoEWQF"
|
||||
},
|
||||
"whisper": {
|
||||
"node-01.ac-cn-hongkong-c.eth.prod": "enode://b957e51f41e4abab8382e1ea7229e88c6e18f34672694c6eae389eac22dab8655622bbd4a08192c321416b9becffaab11c8e2b7a5d0813b922aa128b82990dab@47.75.222.178:443",
|
||||
"node-01.do-ams3.eth.prod": "enode://66ba15600cda86009689354c3a77bdf1a97f4f4fb3ab50ffe34dbc904fac561040496828397be18d9744c75881ffc6ac53729ddbd2cdbdadc5f45c400e2622f7@178.128.141.87:443",
|
||||
"node-01.gc-us-central1-a.eth.prod": "enode://182ed5d658d1a1a4382c9e9f7c9e5d8d9fec9db4c71ae346b9e23e1a589116aeffb3342299bdd00e0ab98dbf804f7b2d8ae564ed18da9f45650b444aed79d509@34.68.132.118:443",
|
||||
"node-02.ac-cn-hongkong-c.eth.prod": "enode://8bebe73ddf7cf09e77602c7d04c93a73f455b51f24ae0d572917a4792f1dec0bb4c562759b8830cc3615a658d38c1a4a38597a1d7ae3ba35111479fc42d65dec@47.75.85.212:443",
|
||||
"node-02.do-ams3.eth.prod": "enode://4ea35352702027984a13274f241a56a47854a7fd4b3ba674a596cff917d3c825506431cf149f9f2312a293bb7c2b1cca55db742027090916d01529fe0729643b@134.209.136.79:443",
|
||||
"node-02.gc-us-central1-a.eth.prod": "enode://fbeddac99d396b91d59f2c63a3cb5fc7e0f8a9f7ce6fe5f2eed5e787a0154161b7173a6a73124a4275ef338b8966dc70a611e9ae2192f0f2340395661fad81c0@34.67.230.193:443",
|
||||
"node-03.ac-cn-hongkong-c.eth.prod": "enode://ac3948b2c0786ada7d17b80cf869cf59b1909ea3accd45944aae35bf864cc069126da8b82dfef4ddf23f1d6d6b44b1565c4cf81c8b98022253c6aea1a89d3ce2@47.75.88.12:443",
|
||||
"node-03.do-ams3.eth.prod": "enode://ce559a37a9c344d7109bd4907802dd690008381d51f658c43056ec36ac043338bd92f1ac6043e645b64953b06f27202d679756a9c7cf62fdefa01b2e6ac5098e@134.209.136.123:443",
|
||||
"node-03.gc-us-central1-a.eth.prod": "enode://c07aa0deea3b7056c5d45a85bca42f0d8d3b1404eeb9577610f386e0a4744a0e7b2845ae328efc4aa4b28075af838b59b5b3985bffddeec0090b3b7669abc1f3@35.226.92.155:443",
|
||||
"node-04.ac-cn-hongkong-c.eth.prod": "enode://385579fc5b14e04d5b04af7eee835d426d3d40ccf11f99dbd95340405f37cf3bbbf830b3eb8f70924be0c2909790120682c9c3e791646e2d5413e7801545d353@47.244.221.249:443",
|
||||
"node-04.do-ams3.eth.prod": "enode://4e0a8db9b73403c9339a2077e911851750fc955db1fc1e09f81a4a56725946884dd5e4d11258eac961f9078a393c45bcab78dd0e3bc74e37ce773b3471d2e29c@134.209.136.101:443",
|
||||
"node-04.gc-us-central1-a.eth.prod": "enode://0624b4a90063923c5cc27d12624b6a49a86dfb3623fcb106801217fdbab95f7617b83fa2468b9ae3de593ff6c1cf556ccf9bc705bfae9cb4625999765127b423@35.222.158.246:443",
|
||||
"node-05.ac-cn-hongkong-c.eth.prod": "enode://b77bffc29e2592f30180311dd81204ab845e5f78953b5ba0587c6631be9c0862963dea5eb64c90617cf0efd75308e22a42e30bc4eb3cd1bbddbd1da38ff6483e@47.75.10.177:443",
|
||||
"node-05.do-ams3.eth.prod": "enode://a8bddfa24e1e92a82609b390766faa56cf7a5eef85b22a2b51e79b333c8aaeec84f7b4267e432edd1cf45b63a3ad0fc7d6c3a16f046aa6bc07ebe50e80b63b8c@178.128.141.249:443",
|
||||
"node-05.gc-us-central1-a.eth.prod": "enode://a5fe9c82ad1ffb16ae60cb5d4ffe746b9de4c5fbf20911992b7dd651b1c08ba17dd2c0b27ee6b03162c52d92f219961cc3eb14286aca8a90b75cf425826c3bd8@104.154.230.58:443",
|
||||
"node-06.ac-cn-hongkong-c.eth.prod": "enode://cf5f7a7e64e3b306d1bc16073fba45be3344cb6695b0b616ccc2da66ea35b9f35b3b231c6cf335fdfaba523519659a440752fc2e061d1e5bc4ef33864aac2f19@47.75.221.196:443",
|
||||
"node-06.do-ams3.eth.prod": "enode://887cbd92d95afc2c5f1e227356314a53d3d18855880ac0509e0c0870362aee03939d4074e6ad31365915af41d34320b5094bfcc12a67c381788cd7298d06c875@178.128.141.0:443",
|
||||
"node-06.gc-us-central1-a.eth.prod": "enode://282e009967f9f132a5c2dd366a76319f0d22d60d0c51f7e99795a1e40f213c2705a2c10e4cc6f3890319f59da1a535b8835ed9b9c4b57c3aad342bf312fd7379@35.223.240.17:443",
|
||||
"node-07.ac-cn-hongkong-c.eth.prod": "enode://13d63a1f85ccdcbd2fb6861b9bd9d03f94bdba973608951f7c36e5df5114c91de2b8194d71288f24bfd17908c48468e89dd8f0fb8ccc2b2dedae84acdf65f62a@47.244.210.80:443",
|
||||
"node-07.do-ams3.eth.prod": "enode://2b01955d7e11e29dce07343b456e4e96c081760022d1652b1c4b641eaf320e3747871870fa682e9e9cfb85b819ce94ed2fee1ac458904d54fd0b97d33ba2c4a4@134.209.136.112:443",
|
||||
"node-07.gc-us-central1-a.eth.prod": "enode://b706a60572634760f18a27dd407b2b3582f7e065110dae10e3998498f1ae3f29ba04db198460d83ed6d2bfb254bb06b29aab3c91415d75d3b869cd0037f3853c@35.239.5.162:443",
|
||||
"node-08.ac-cn-hongkong-c.eth.prod": "enode://32915c8841faaef21a6b75ab6ed7c2b6f0790eb177ad0f4ea6d731bacc19b938624d220d937ebd95e0f6596b7232bbb672905ee12601747a12ee71a15bfdf31c@47.75.59.11:443",
|
||||
"node-08.do-ams3.eth.prod": "enode://0d9d65fcd5592df33ed4507ce862b9c748b6dbd1ea3a1deb94e3750052760b4850aa527265bbaf357021d64d5cc53c02b410458e732fafc5b53f257944247760@178.128.141.42:443",
|
||||
"node-08.gc-us-central1-a.eth.prod": "enode://e87f1d8093d304c3a9d6f1165b85d6b374f1c0cc907d39c0879eb67f0a39d779be7a85cbd52920b6f53a94da43099c58837034afa6a7be4b099bfcd79ad13999@35.238.106.101:443"
|
||||
}
|
||||
},
|
||||
"eth.staging": {
|
||||
"boot": {
|
||||
"boot-01.ac-cn-hongkong-c.eth.staging": "enode://630b0342ca4e9552f50714b6c8e28d6955bc0fd14e7950f93bc3b2b8cc8c1f3b6d103df66f51a13d773b5db0f130661fb5c7b8fa21c48890c64c79b41a56a490@47.91.229.44:443",
|
||||
"boot-01.do-ams3.eth.staging": "enode://f79fb3919f72ca560ad0434dcc387abfe41e0666201ebdada8ede0462454a13deb05cda15f287d2c4bd85da81f0eb25d0a486bbbc8df427b971ac51533bd00fe@174.138.107.239:443",
|
||||
"boot-01.gc-us-central1-a.eth.staging": "enode://10a78c17929a7019ef4aa2249d7302f76ae8a06f40b2dc88b7b31ebff4a623fbb44b4a627acba296c1ced3775d91fbe18463c15097a6a36fdb2c804ff3fc5b35@35.238.97.234:443"
|
||||
},
|
||||
"mail": {
|
||||
"mail-01.ac-cn-hongkong-c.eth.staging": "enode://b74859176c9751d314aeeffc26ec9f866a412752e7ddec91b19018a18e7cca8d637cfe2cedcb972f8eb64d816fbd5b4e89c7e8c7fd7df8a1329fa43db80b0bfe@47.52.90.156:443",
|
||||
"mail-01.do-ams3.eth.staging": "enode://69f72baa7f1722d111a8c9c68c39a31430e9d567695f6108f31ccb6cd8f0adff4991e7fdca8fa770e75bc8a511a87d24690cbc80e008175f40c157d6f6788d48@206.189.240.16:443",
|
||||
"mail-01.gc-us-central1-a.eth.staging": "enode://e4fc10c1f65c8aed83ac26bc1bfb21a45cc1a8550a58077c8d2de2a0e0cd18e40fd40f7e6f7d02dc6cd06982b014ce88d6e468725ffe2c138e958788d0002a7f@35.239.193.41:443"
|
||||
},
|
||||
"rendezvous": {
|
||||
"boot-01.ac-cn-hongkong-c.eth.staging": "/ip4/47.91.229.44/tcp/30703/ethv4/16Uiu2HAmRnt2Eyoknh3auxh4fJwkRgqkH1gqrWGes8Pk1k3MV4xu",
|
||||
"boot-01.do-ams3.eth.staging": "/ip4/174.138.107.239/tcp/30703/ethv4/16Uiu2HAm8UZXUHEPZrpJbcQ3yVFH6UtKrwsG6jH4ai72PsbLfVFb",
|
||||
"boot-01.gc-us-central1-a.eth.staging": "/ip4/35.238.97.234/tcp/30703/ethv4/16Uiu2HAm6G9sDMkrB4Xa5EH3Zx2dysCxFgBTSRzghic3Z9tRFRNE"
|
||||
},
|
||||
"whisper": {
|
||||
"node-01.ac-cn-hongkong-c.eth.staging": "enode://088cf5a93c576fae52f6f075178467b8ff98bacf72f59e88efb16dfba5b30f80a4db78f8e3cb3d87f2f6521746ef4a8768465ef2896c6af24fd77a425e95b6dd@47.52.226.137:443",
|
||||
"node-01.do-ams3.eth.staging": "enode://914c0b30f27bab30c1dfd31dad7652a46fda9370542aee1b062498b1345ee0913614b8b9e3e84622e84a7203c5858ae1d9819f63aece13ee668e4f6668063989@167.99.19.148:443",
|
||||
"node-01.gc-us-central1-a.eth.staging": "enode://d3878441652f010326889f28360e69f2d09d06540f934fada0e17b374ce5319de64279aba3c44a5bf807d9967c6d705b3b4c6b03fa70763240e2ee6af01a539e@35.192.0.86:443"
|
||||
}
|
||||
},
|
||||
"eth.test": {
|
||||
"boot": {
|
||||
"boot-01.ac-cn-hongkong-c.eth.test": "enode://daae2e72820e86e942fa2a8aa7d6e9954d4043a753483d8bd338e16be82cf962392d5c0e1ae57c3d793c3d3dddd8fd58339262e4234dc966f953cd73b535f5fa@47.52.188.149:443",
|
||||
"boot-01.do-ams3.eth.test": "enode://9e0988575eb7717c25dea72fd11c7b37767dc09c1a7686f7c2ec577d308d24b377ceb675de4317474a1a870e47882732967f4fa785b02ba95d669b31d464dec0@206.189.243.164:443",
|
||||
"boot-01.gc-us-central1-a.eth.test": "enode://c1e5018887c863d64e431b69bf617561087825430e4401733f5ba77c70db14236df381fefb0ebe1ac42294b9e261bbe233dbdb83e32c586c66ae26c8de70cb4c@35.188.168.137:443"
|
||||
},
|
||||
"mail": {
|
||||
"mail-01.ac-cn-hongkong-c.eth.test": "enode://619dbb5dda12e85bf0eb5db40fb3de625609043242737c0e975f7dfd659d85dc6d9a84f9461a728c5ab68c072fed38ca6a53917ca24b8e93cc27bdef3a1e79ac@47.52.188.196:443",
|
||||
"mail-01.do-ams3.eth.test": "enode://e4865fe6c2a9c1a563a6447990d8e9ce672644ae3e08277ce38ec1f1b690eef6320c07a5d60c3b629f5d4494f93d6b86a745a0bf64ab295bbf6579017adc6ed8@206.189.243.161:443",
|
||||
"mail-01.gc-us-central1-a.eth.test": "enode://707e57453acd3e488c44b9d0e17975371e2f8fb67525eae5baca9b9c8e06c86cde7c794a6c2e36203bf9f56cae8b0e50f3b33c4c2b694a7baeea1754464ce4e3@35.192.229.172:443"
|
||||
},
|
||||
"rendezvous": {
|
||||
"boot-01.ac-cn-hongkong-c.eth.test": "/ip4/47.52.188.149/tcp/30703/ethv4/16Uiu2HAm9Vatqr4GfVCqnyeaPtCF3q8fz8kDDUgqXVfFG7ZfSA7w",
|
||||
"boot-01.do-ams3.eth.test": "/ip4/206.189.243.164/tcp/30703/ethv4/16Uiu2HAmBCh5bgYr6V3fDuLqUzvtSAsFTQJCQ3TVHT8ta8bTu2Jm",
|
||||
"boot-01.gc-us-central1-a.eth.test": "/ip4/35.188.168.137/tcp/30703/ethv4/16Uiu2HAm3MUqtGjmetyZ9L4SN2R8oHDWvACUcec25LjtDD5euiRH"
|
||||
},
|
||||
"whisper": {
|
||||
"node-01.ac-cn-hongkong-c.eth.test": "enode://ad38f94030a846cc7005b7a1f3b6b01bf4ef59d34e8d3d6f4d12df23d14ba8656702a435d34cf4df3b412c0c1923df5adcce8461321a0d8ffb9435b26e572c2a@47.52.255.194:443",
|
||||
"node-01.do-ams3.eth.test": "enode://1d193635e015918fb85bbaf774863d12f65d70c6977506187ef04420d74ec06c9e8f0dcb57ea042f85df87433dab17a1260ed8dde1bdf9d6d5d2de4b7bf8e993@206.189.243.163:443",
|
||||
"node-01.gc-us-central1-a.eth.test": "enode://f593a27731bc0f8eb088e2d39222c2d59dfb9bf0b3950d7a828d51e8ab9e08fffbd9916a82fd993c1a080c57c2bd70ed6c36f489a969de697aff93088dbee1a9@35.194.31.108:443"
|
||||
}
|
||||
},
|
||||
"wakuv2.prod": {
|
||||
"waku": {
|
||||
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/ip4/8.210.222.231/tcp/30303/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD",
|
||||
"node-01.do-ams3.wakuv2.prod": "/ip4/188.166.135.145/tcp/30303/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
|
||||
"node-01.gc-us-central1-a.wakuv2.prod": "/ip4/34.121.100.108/tcp/30303/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA"
|
||||
},
|
||||
"waku-websocket": {
|
||||
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD",
|
||||
"node-01.do-ams3.wakuv2.prod": "/dns4/node-01.do-ams3.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
|
||||
"node-01.gc-us-central1-a.wakuv2.prod": "/dns4/node-01.gc-us-central1-a.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA"
|
||||
}
|
||||
},
|
||||
"wakuv2.test": {
|
||||
"waku": {
|
||||
"node-01.ac-cn-hongkong-c.wakuv2.test": "/ip4/47.242.210.73/tcp/30303/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm",
|
||||
"node-01.do-ams3.wakuv2.test": "/ip4/134.209.139.210/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
|
||||
"node-01.gc-us-central1-a.wakuv2.test": "/ip4/104.154.239.128/tcp/30303/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS"
|
||||
},
|
||||
"waku-websocket": {
|
||||
"node-01.ac-cn-hongkong-c.wakuv2.test": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm",
|
||||
"node-01.do-ams3.wakuv2.test": "/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
|
||||
"node-01.gc-us-central1-a.wakuv2.test": "/dns4/node-01.gc-us-central1-a.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS"
|
||||
}
|
||||
}
|
||||
},
|
||||
"eth.staging": {
|
||||
"boot": {
|
||||
"boot-01.ac-cn-hongkong-c.eth.staging": "enode://630b0342ca4e9552f50714b6c8e28d6955bc0fd14e7950f93bc3b2b8cc8c1f3b6d103df66f51a13d773b5db0f130661fb5c7b8fa21c48890c64c79b41a56a490@47.91.229.44:443",
|
||||
"boot-01.do-ams3.eth.staging": "enode://f79fb3919f72ca560ad0434dcc387abfe41e0666201ebdada8ede0462454a13deb05cda15f287d2c4bd85da81f0eb25d0a486bbbc8df427b971ac51533bd00fe@174.138.107.239:443",
|
||||
"boot-01.gc-us-central1-a.eth.staging": "enode://10a78c17929a7019ef4aa2249d7302f76ae8a06f40b2dc88b7b31ebff4a623fbb44b4a627acba296c1ced3775d91fbe18463c15097a6a36fdb2c804ff3fc5b35@35.238.97.234:443"
|
||||
},
|
||||
"mail": {
|
||||
"mail-01.ac-cn-hongkong-c.eth.staging": "enode://b74859176c9751d314aeeffc26ec9f866a412752e7ddec91b19018a18e7cca8d637cfe2cedcb972f8eb64d816fbd5b4e89c7e8c7fd7df8a1329fa43db80b0bfe@47.52.90.156:443",
|
||||
"mail-01.do-ams3.eth.staging": "enode://69f72baa7f1722d111a8c9c68c39a31430e9d567695f6108f31ccb6cd8f0adff4991e7fdca8fa770e75bc8a511a87d24690cbc80e008175f40c157d6f6788d48@206.189.240.16:443",
|
||||
"mail-01.gc-us-central1-a.eth.staging": "enode://e4fc10c1f65c8aed83ac26bc1bfb21a45cc1a8550a58077c8d2de2a0e0cd18e40fd40f7e6f7d02dc6cd06982b014ce88d6e468725ffe2c138e958788d0002a7f@35.239.193.41:443"
|
||||
},
|
||||
"rendezvous": {
|
||||
"boot-01.ac-cn-hongkong-c.eth.staging": "/ip4/47.91.229.44/tcp/30703/ethv4/16Uiu2HAmRnt2Eyoknh3auxh4fJwkRgqkH1gqrWGes8Pk1k3MV4xu",
|
||||
"boot-01.do-ams3.eth.staging": "/ip4/174.138.107.239/tcp/30703/ethv4/16Uiu2HAm8UZXUHEPZrpJbcQ3yVFH6UtKrwsG6jH4ai72PsbLfVFb",
|
||||
"boot-01.gc-us-central1-a.eth.staging": "/ip4/35.238.97.234/tcp/30703/ethv4/16Uiu2HAm6G9sDMkrB4Xa5EH3Zx2dysCxFgBTSRzghic3Z9tRFRNE"
|
||||
},
|
||||
"whisper": {
|
||||
"node-01.ac-cn-hongkong-c.eth.staging": "enode://088cf5a93c576fae52f6f075178467b8ff98bacf72f59e88efb16dfba5b30f80a4db78f8e3cb3d87f2f6521746ef4a8768465ef2896c6af24fd77a425e95b6dd@47.52.226.137:443",
|
||||
"node-01.do-ams3.eth.staging": "enode://914c0b30f27bab30c1dfd31dad7652a46fda9370542aee1b062498b1345ee0913614b8b9e3e84622e84a7203c5858ae1d9819f63aece13ee668e4f6668063989@167.99.19.148:443",
|
||||
"node-01.gc-us-central1-a.eth.staging": "enode://d3878441652f010326889f28360e69f2d09d06540f934fada0e17b374ce5319de64279aba3c44a5bf807d9967c6d705b3b4c6b03fa70763240e2ee6af01a539e@35.192.0.86:443"
|
||||
}
|
||||
},
|
||||
"eth.test": {
|
||||
"boot": {
|
||||
"boot-01.ac-cn-hongkong-c.eth.test": "enode://daae2e72820e86e942fa2a8aa7d6e9954d4043a753483d8bd338e16be82cf962392d5c0e1ae57c3d793c3d3dddd8fd58339262e4234dc966f953cd73b535f5fa@47.52.188.149:443",
|
||||
"boot-01.do-ams3.eth.test": "enode://9e0988575eb7717c25dea72fd11c7b37767dc09c1a7686f7c2ec577d308d24b377ceb675de4317474a1a870e47882732967f4fa785b02ba95d669b31d464dec0@206.189.243.164:443",
|
||||
"boot-01.gc-us-central1-a.eth.test": "enode://c1e5018887c863d64e431b69bf617561087825430e4401733f5ba77c70db14236df381fefb0ebe1ac42294b9e261bbe233dbdb83e32c586c66ae26c8de70cb4c@35.188.168.137:443"
|
||||
},
|
||||
"mail": {
|
||||
"mail-01.ac-cn-hongkong-c.eth.test": "enode://619dbb5dda12e85bf0eb5db40fb3de625609043242737c0e975f7dfd659d85dc6d9a84f9461a728c5ab68c072fed38ca6a53917ca24b8e93cc27bdef3a1e79ac@47.52.188.196:443",
|
||||
"mail-01.do-ams3.eth.test": "enode://e4865fe6c2a9c1a563a6447990d8e9ce672644ae3e08277ce38ec1f1b690eef6320c07a5d60c3b629f5d4494f93d6b86a745a0bf64ab295bbf6579017adc6ed8@206.189.243.161:443",
|
||||
"mail-01.gc-us-central1-a.eth.test": "enode://707e57453acd3e488c44b9d0e17975371e2f8fb67525eae5baca9b9c8e06c86cde7c794a6c2e36203bf9f56cae8b0e50f3b33c4c2b694a7baeea1754464ce4e3@35.192.229.172:443"
|
||||
},
|
||||
"rendezvous": {
|
||||
"boot-01.ac-cn-hongkong-c.eth.test": "/ip4/47.52.188.149/tcp/30703/ethv4/16Uiu2HAm9Vatqr4GfVCqnyeaPtCF3q8fz8kDDUgqXVfFG7ZfSA7w",
|
||||
"boot-01.do-ams3.eth.test": "/ip4/206.189.243.164/tcp/30703/ethv4/16Uiu2HAmBCh5bgYr6V3fDuLqUzvtSAsFTQJCQ3TVHT8ta8bTu2Jm",
|
||||
"boot-01.gc-us-central1-a.eth.test": "/ip4/35.188.168.137/tcp/30703/ethv4/16Uiu2HAm3MUqtGjmetyZ9L4SN2R8oHDWvACUcec25LjtDD5euiRH"
|
||||
},
|
||||
"whisper": {
|
||||
"node-01.ac-cn-hongkong-c.eth.test": "enode://ad38f94030a846cc7005b7a1f3b6b01bf4ef59d34e8d3d6f4d12df23d14ba8656702a435d34cf4df3b412c0c1923df5adcce8461321a0d8ffb9435b26e572c2a@47.52.255.194:443",
|
||||
"node-01.do-ams3.eth.test": "enode://1d193635e015918fb85bbaf774863d12f65d70c6977506187ef04420d74ec06c9e8f0dcb57ea042f85df87433dab17a1260ed8dde1bdf9d6d5d2de4b7bf8e993@206.189.243.163:443",
|
||||
"node-01.gc-us-central1-a.eth.test": "enode://f593a27731bc0f8eb088e2d39222c2d59dfb9bf0b3950d7a828d51e8ab9e08fffbd9916a82fd993c1a080c57c2bd70ed6c36f489a969de697aff93088dbee1a9@35.194.31.108:443"
|
||||
}
|
||||
},
|
||||
"status.prod": {
|
||||
"waku": {
|
||||
"node-01.ac-cn-hongkong-c.status.prod": "/dns4/node-01.ac-cn-hongkong-c.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAkvEZgh3KLwhLwXg95e5ojM8XykJ4Kxi2T7hk22rnA7pJC",
|
||||
"node-01.do-ams3.status.prod": "/dns4/node-01.do-ams3.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAm6HZZr7aToTvEBPpiys4UxajCTU97zj5v7RNR2gbniy1D",
|
||||
"node-01.gc-us-central1-a.status.prod": "/dns4/node-01.gc-us-central1-a.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAkwBp8T6G77kQXSNMnxgaMky1JeyML5yqoTHRM8dbeCBNb",
|
||||
"node-02.ac-cn-hongkong-c.status.prod": "/dns4/node-02.ac-cn-hongkong-c.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmFy8BrJhCEmCYrUfBdSNkrPw6VHExtv4rRp1DSBnCPgx8",
|
||||
"node-02.do-ams3.status.prod": "/dns4/node-02.do-ams3.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmSve7tR5YZugpskMv2dmJAsMUKmfWYEKRXNUxRaTCnsXV",
|
||||
"node-02.gc-us-central1-a.status.prod": "/dns4/node-02.gc-us-central1-a.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmDQugwDHM3YeUp86iGjrUvbdw3JPRgikC7YoGBsT2ymMg"
|
||||
},
|
||||
"waku-websocket": {
|
||||
"node-01.ac-cn-hongkong-c.status.prod": "/dns4/node-01.ac-cn-hongkong-c.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvEZgh3KLwhLwXg95e5ojM8XykJ4Kxi2T7hk22rnA7pJC",
|
||||
"node-01.do-ams3.status.prod": "/dns4/node-01.do-ams3.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAm6HZZr7aToTvEBPpiys4UxajCTU97zj5v7RNR2gbniy1D",
|
||||
"node-01.gc-us-central1-a.status.prod": "/dns4/node-01.gc-us-central1-a.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAkwBp8T6G77kQXSNMnxgaMky1JeyML5yqoTHRM8dbeCBNb",
|
||||
"node-02.ac-cn-hongkong-c.status.prod": "/dns4/node-02.ac-cn-hongkong-c.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmFy8BrJhCEmCYrUfBdSNkrPw6VHExtv4rRp1DSBnCPgx8",
|
||||
"node-02.do-ams3.status.prod": "/dns4/node-02.do-ams3.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmSve7tR5YZugpskMv2dmJAsMUKmfWYEKRXNUxRaTCnsXV",
|
||||
"node-02.gc-us-central1-a.status.prod": "/dns4/node-02.gc-us-central1-a.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmDQugwDHM3YeUp86iGjrUvbdw3JPRgikC7YoGBsT2ymMg"
|
||||
},
|
||||
"waku-nodes": ["enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@prod.nodes.status.im"]
|
||||
},
|
||||
"status.test": {
|
||||
"waku": {
|
||||
"node-01.ac-cn-hongkong-c.status.test": "/dns4/node-01.ac-cn-hongkong-c.status.test.statusim.net/tcp/30303/p2p/16Uiu2HAm2BjXxCp1sYFJQKpLLbPbwd5juxbsYofu3TsS3auvT9Yi",
|
||||
"node-01.do-ams3.status.test": "/dns4/node-01.do-ams3.status.test.statusim.net/tcp/30303/p2p/16Uiu2HAkukebeXjTQ9QDBeNDWuGfbaSg79wkkhK4vPocLgR6QFDf",
|
||||
"node-01.gc-us-central1-a.status.test": "/dns4/node-01.gc-us-central1-a.status.test.statusim.net/tcp/30303/p2p/16Uiu2HAmGDX3iAFox93PupVYaHa88kULGqMpJ7AEHGwj3jbMtt76"
|
||||
},
|
||||
"waku-websocket": {
|
||||
"node-01.ac-cn-hongkong-c.status.test": "/dns4/node-01.ac-cn-hongkong-c.status.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAm2BjXxCp1sYFJQKpLLbPbwd5juxbsYofu3TsS3auvT9Yi",
|
||||
"node-01.do-ams3.status.test": "/dns4/node-01.do-ams3.status.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkukebeXjTQ9QDBeNDWuGfbaSg79wkkhK4vPocLgR6QFDf",
|
||||
"node-01.gc-us-central1-a.status.test": "/dns4/node-01.gc-us-central1-a.status.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmGDX3iAFox93PupVYaHa88kULGqMpJ7AEHGwj3jbMtt76"
|
||||
},
|
||||
"waku-nodes": ["enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@test.nodes.status.im"]
|
||||
},
|
||||
"wakuv2.prod": {
|
||||
"waku": {
|
||||
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/ip4/8.210.222.231/tcp/30303/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD",
|
||||
"node-01.do-ams3.wakuv2.prod": "/ip4/188.166.135.145/tcp/30303/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
|
||||
"node-01.gc-us-central1-a.wakuv2.prod": "/ip4/34.121.100.108/tcp/30303/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA"
|
||||
},
|
||||
"waku-websocket": {
|
||||
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD",
|
||||
"node-01.do-ams3.wakuv2.prod": "/dns4/node-01.do-ams3.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
|
||||
"node-01.gc-us-central1-a.wakuv2.prod": "/dns4/node-01.gc-us-central1-a.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA"
|
||||
},
|
||||
"waku-nodes": ["enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@prod.waku.nodes.status.im"]
|
||||
},
|
||||
"wakuv2.test": {
|
||||
"waku": {
|
||||
"node-01.ac-cn-hongkong-c.wakuv2.test": "/ip4/47.242.210.73/tcp/30303/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm",
|
||||
"node-01.do-ams3.wakuv2.test": "/ip4/134.209.139.210/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
|
||||
"node-01.gc-us-central1-a.wakuv2.test": "/ip4/104.154.239.128/tcp/30303/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS"
|
||||
},
|
||||
"waku-websocket": {
|
||||
"node-01.ac-cn-hongkong-c.wakuv2.test": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm",
|
||||
"node-01.do-ams3.wakuv2.test": "/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
|
||||
"node-01.gc-us-central1-a.wakuv2.test": "/dns4/node-01.gc-us-central1-a.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS"
|
||||
},
|
||||
"waku-nodes": ["enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@test.waku.nodes.status.im"]
|
||||
"meta": {
|
||||
"hostname": "node-01.do-ams3.proxy.misc",
|
||||
"timestamp": "2021-06-07T00:00:09.836740"
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"hostname": "node-01.do-ams3.proxy.misc",
|
||||
"timestamp": "2021-06-07T00:00:09.836740"
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 469 B |
|
Before Width: | Height: | Size: 758 B |
|
Before Width: | Height: | Size: 525 B |
|
Before Width: | Height: | Size: 759 B |
|
Before Width: | Height: | Size: 924 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 12 KiB |
@@ -2,10 +2,10 @@
|
||||
|
||||
CHANGES=$(git diff --no-ext-diff --diff-filter=d --cached --unified=0 --no-prefix --minimal --exit-code src/quo src/quo2 | grep '^+' || echo '')
|
||||
|
||||
INVALID_CHANGES=$(echo "$CHANGES" | grep -E '(re-frame/dispatch|rf/dispatch|re-frame/subscribe|rf/subscribe|rf/sub|<sub|>evt|status-im)')
|
||||
INVALID_CHANGES=$(echo "$CHANGES" | grep -E '(re-frame/dispatch|rf/dispatch|re-frame/subscribe|rf/subscribe|rf/sub|<sub|>evt)')
|
||||
|
||||
if test -n "$INVALID_CHANGES"; then
|
||||
echo "re-frame dispatch/subscribe and status-im are not allowed in quo/quo2 components"
|
||||
echo "re-frame dispatch/subscribe is not allowed in quo/quo2 components"
|
||||
echo ''
|
||||
echo "$INVALID_CHANGES"
|
||||
exit 1
|
||||
|
||||
@@ -64,15 +64,15 @@
|
||||
{:closure-defines
|
||||
{status-im.utils.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
status-im.utils.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
|
||||
:compiler-options {:output-feature-set :es6
|
||||
:compiler-options {:output-feature-set :es6
|
||||
;;disable for android build as there
|
||||
;;is an intermittent warning with deftype
|
||||
:warnings-as-errors false
|
||||
:infer-externs :auto
|
||||
:static-fns true
|
||||
:fn-invoke-direct true
|
||||
:optimizations :advanced
|
||||
:js-options {:js-provider :closure}}}}
|
||||
:warnings-as-errors false
|
||||
:infer-externs :auto
|
||||
:static-fns true
|
||||
:fn-invoke-direct true
|
||||
:optimizations :advanced
|
||||
:js-options {:js-provider :closure}}}}
|
||||
;; the tests are ran with node, react-native dependencies are mocked
|
||||
;; by using node --require override.js, which uses the node-library
|
||||
;; produced by the target :mocks below and redefines node require
|
||||
@@ -82,7 +82,6 @@
|
||||
:output-dir "target/test"
|
||||
:optimizations :simple
|
||||
:target :node-test
|
||||
:ns-regexp "status-im.chat.models-test$"
|
||||
:main status-im.test-runner/main
|
||||
;; set :ui-driven to true to let shadow-cljs inject node-repl
|
||||
:ui-driven true
|
||||
@@ -107,11 +106,4 @@
|
||||
:output-to "target/mocks/mocks.js"
|
||||
:output-dir "target/mocks"
|
||||
:compiler-options {:optimizations :simple
|
||||
:source-map false}}
|
||||
:component-test {:target :npm-module
|
||||
:entries [quo2.core-spec]
|
||||
:ns-regexp "-component-spec$"
|
||||
:output-dir "component-spec"
|
||||
:compiler-options {:warnings-as-errors false
|
||||
:static-fns false
|
||||
:infer-externs true}}}}
|
||||
:source-map false}}}}
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
import { useDerivedValue, withTiming, withSequence, withDelay, Easing } from 'react-native-reanimated';
|
||||
|
||||
// Shell Worklets
|
||||
|
||||
// Home Stack States
|
||||
const CLOSE_WITH_ANIMATION = 0;
|
||||
const OPEN_WITH_ANIMATION = 1;
|
||||
const CLOSE_WITHOUT_ANIMATION = 3;
|
||||
const OPEN_WITHOUT_ANIMATION = 4;
|
||||
|
||||
// Derived Values
|
||||
export function stackOpacity (stackId, selectedStackId) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
return selectedStackId.value == stackId ? 1 : 0;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function stackPointer (stackId, selectedStackId) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
return selectedStackId.value == stackId ? "auto" : "none";
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function bottomTabIconColor (stackId, selectedStackId, homeStackState,
|
||||
passThrough, selectedTabColor, defaultColor,
|
||||
passThroughColor) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
var homeStackStateValue = homeStackState.value;
|
||||
if (selectedStackId.value == stackId &&
|
||||
(homeStackStateValue == OPEN_WITH_ANIMATION ||
|
||||
homeStackStateValue == OPEN_WITHOUT_ANIMATION)){
|
||||
return selectedTabColor;
|
||||
}
|
||||
else if (passThrough.value){
|
||||
return passThroughColor;
|
||||
}
|
||||
else {
|
||||
return defaultColor;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function bottomTabsHeight(homeStackState, height, extendedHeight) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
switch (homeStackState.value) {
|
||||
case OPEN_WITH_ANIMATION:
|
||||
return withTiming(extendedHeight, defaultDurationAndEasing);
|
||||
break;
|
||||
case CLOSE_WITH_ANIMATION:
|
||||
return withTiming(height, defaultDurationAndEasing);
|
||||
break;
|
||||
case OPEN_WITHOUT_ANIMATION:
|
||||
return extendedHeight;
|
||||
break;
|
||||
case CLOSE_WITHOUT_ANIMATION:
|
||||
return height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// Home Stack
|
||||
|
||||
const shellAnimationTime = 200;
|
||||
|
||||
const defaultDurationAndEasing = {
|
||||
duration: shellAnimationTime,
|
||||
easing: Easing.bezier(0, 0, 1, 1),
|
||||
}
|
||||
|
||||
export function homeStackOpacity (homeStackState) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
switch (homeStackState.value) {
|
||||
case OPEN_WITH_ANIMATION:
|
||||
return withTiming(1, defaultDurationAndEasing);
|
||||
break;
|
||||
case CLOSE_WITH_ANIMATION:
|
||||
return withTiming(0, defaultDurationAndEasing);
|
||||
break;
|
||||
case OPEN_WITHOUT_ANIMATION:
|
||||
return 1;
|
||||
break;
|
||||
case CLOSE_WITHOUT_ANIMATION:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function homeStackTop (homeStackState, top) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
switch (homeStackState.value) {
|
||||
case OPEN_WITH_ANIMATION:
|
||||
return withTiming(0, defaultDurationAndEasing);
|
||||
break;
|
||||
case CLOSE_WITH_ANIMATION:
|
||||
return withTiming(top, defaultDurationAndEasing);
|
||||
break;
|
||||
case OPEN_WITHOUT_ANIMATION:
|
||||
return 0;
|
||||
break;
|
||||
case CLOSE_WITHOUT_ANIMATION:
|
||||
return top;
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function homeStackLeft (selectedStackId, animateHomeStackLeft, homeStackState, left) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
if (animateHomeStackLeft.value) {
|
||||
var leftValue = left[selectedStackId.value];
|
||||
switch (homeStackState.value) {
|
||||
case OPEN_WITH_ANIMATION:
|
||||
return withSequence(withTiming(leftValue, {duration: 0}), withTiming(0, defaultDurationAndEasing))
|
||||
break;
|
||||
case CLOSE_WITH_ANIMATION:
|
||||
return withTiming(leftValue, defaultDurationAndEasing);
|
||||
break;
|
||||
case OPEN_WITHOUT_ANIMATION:
|
||||
return 0;
|
||||
break;
|
||||
case CLOSE_WITHOUT_ANIMATION:
|
||||
return leftValue;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function homeStackPointer (homeStackState) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
var homeStackStateValue = homeStackState.value;
|
||||
return (homeStackStateValue == OPEN_WITH_ANIMATION ||
|
||||
homeStackStateValue == OPEN_WITHOUT_ANIMATION) ? "auto" : "none";
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function homeStackScale (homeStackState, minimizeScale) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
switch (homeStackState.value) {
|
||||
case OPEN_WITH_ANIMATION:
|
||||
return withTiming(1, defaultDurationAndEasing);
|
||||
break;
|
||||
case CLOSE_WITH_ANIMATION:
|
||||
return withTiming(minimizeScale, defaultDurationAndEasing);
|
||||
break;
|
||||
case OPEN_WITHOUT_ANIMATION:
|
||||
return 1;
|
||||
break;
|
||||
case CLOSE_WITHOUT_ANIMATION:
|
||||
return minimizeScale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { useDerivedValue, withTiming, withSequence, withDelay, Easing } from 'react-native-reanimated';
|
||||
|
||||
// Generic Worklets
|
||||
|
||||
export function applyAnimationsToStyle(animations, style) {
|
||||
@@ -27,3 +29,106 @@ export function applyAnimationsToStyle(animations, style) {
|
||||
return Object.assign(animatedStyle, style);
|
||||
};
|
||||
};
|
||||
|
||||
// Switcher Worklets
|
||||
|
||||
export function stackOpacity (stackId, selectedStackId) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
return selectedStackId.value == stackId ? 1 : 0;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function stackPointer (stackId, selectedStackId) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
return selectedStackId.value == stackId ? "auto" : "none";
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function bottomTabIconColor (stackId, selectedStackId, homeStackOpen,
|
||||
passThrough, selectedTabColor, defaultColor,
|
||||
passThroughColor) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
if (selectedStackId.value == stackId && homeStackOpen.value){
|
||||
return selectedTabColor;
|
||||
}
|
||||
else if (passThrough.value){
|
||||
return passThroughColor;
|
||||
}
|
||||
else {
|
||||
return defaultColor;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Home Stack
|
||||
|
||||
const shellAnimationTime = 200;
|
||||
|
||||
const defaultDurationAndEasing = {
|
||||
duration: shellAnimationTime,
|
||||
easing: Easing.bezier(0, 0, 1, 1),
|
||||
}
|
||||
|
||||
export function homeStackOpacity (homeStackOpen) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
return withTiming(homeStackOpen.value ? 1 : 0, defaultDurationAndEasing);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function homeStackTop (homeStackOpen, top) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
return withTiming(homeStackOpen.value ? 0 : top, defaultDurationAndEasing);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function homeStackLeft (selectedStackId, animateHomeStackLeft, homeStackOpen, left) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
if (animateHomeStackLeft.value) {
|
||||
var leftValue = left[selectedStackId.value];
|
||||
if (homeStackOpen.value) {
|
||||
return withSequence(withTiming(leftValue, {duration: 0}), withTiming(0, defaultDurationAndEasing))
|
||||
} else {
|
||||
return withTiming(leftValue, defaultDurationAndEasing);
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function homeStackPointer (homeStackOpen) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
return homeStackOpen.value ? "auto" : "none";
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function homeStackScale (homeStackOpen, minimizeScale) {
|
||||
return useDerivedValue(
|
||||
function () {
|
||||
'worklet'
|
||||
return withTiming(homeStackOpen.value ? 1 : minimizeScale, defaultDurationAndEasing);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -282,8 +282,6 @@
|
||||
(def worklet-factory
|
||||
#js {:applyAnimationsToStyle (fn [])})
|
||||
|
||||
(def shell-worklets #js {})
|
||||
|
||||
;; Update i18n_resources.cljs
|
||||
(defn mock [module]
|
||||
(case module
|
||||
@@ -330,7 +328,6 @@
|
||||
"@react-native-async-storage/async-storage" async-storage
|
||||
"react-native-svg" react-native-svg
|
||||
"../src/js/worklet_factory.js" worklet-factory
|
||||
"../src/js/shell_worklets.js" shell-worklets
|
||||
"./fleets.js" default-fleets
|
||||
"./chats.js" default-chats
|
||||
"@walletconnect/client" wallet-connect-client
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
(defn button [{:keys [on-press disabled type theme before after
|
||||
haptic-feedback haptic-type on-long-press on-press-start
|
||||
accessibility-label loading border-radius style test-ID]
|
||||
accessibility-label loading border-radius style]
|
||||
:or {theme :main
|
||||
type :primary
|
||||
haptic-feedback true
|
||||
@@ -92,7 +92,7 @@
|
||||
{:on-press-start (fn []
|
||||
(optional-haptic)
|
||||
(on-press-start))}))
|
||||
[rn/view {:test-ID test-ID :style (merge (style-container type) style)}
|
||||
[rn/view {:style (merge (style-container type) style)}
|
||||
(when before
|
||||
[rn/view
|
||||
[icons/icon before {:color icon-color}]])
|
||||
|
||||
|
Before Width: | Height: | Size: 142 KiB |
@@ -1,44 +0,0 @@
|
||||
const waitToNavigate = duration => new Promise(resolve => setTimeout(() => resolve(), duration));
|
||||
|
||||
const SUPER_SECRET_PASSWORD = 'password'
|
||||
|
||||
const loginToHomePage = async () => {
|
||||
if (device.getPlatform() === 'ios') {
|
||||
await device.setStatusBar({ time: '12:34', dataNetwork: 'wifi', wifiBars: '3', batteryState: 'charging', batteryLevel: '100' });
|
||||
}
|
||||
await device.reloadReactNative();
|
||||
await element(by.id('terms-of-service')).tap();
|
||||
await waitToNavigate(400);
|
||||
await element(by.id('get-started')).tap();
|
||||
await waitToNavigate(300);
|
||||
await element(by.id('generate-keys')).tap();
|
||||
await waitToNavigate(200);
|
||||
await element(by.text('Next')).tap();
|
||||
await waitToNavigate(700);
|
||||
await element(by.text('Next')).tap();
|
||||
await waitToNavigate(700);
|
||||
await element(by.id('password-placeholder')).typeText(SUPER_SECRET_PASSWORD);
|
||||
await element(by.id('confirm-password-placeholder')).typeText(SUPER_SECRET_PASSWORD);
|
||||
await element(by.text('Next')).tap();
|
||||
await waitToNavigate(200);
|
||||
await element(by.id("browser-stack")).tap();
|
||||
await waitToNavigate(400);
|
||||
await element(by.text("Quo2.0 Preview")).tap();
|
||||
await waitToNavigate(400);
|
||||
}
|
||||
|
||||
describe('Default Renders', () => {
|
||||
beforeAll(async () => loginToHomePage())
|
||||
beforeEach(async () => {
|
||||
});
|
||||
afterEach(async () => {
|
||||
await element(by.id("back-button")).tap();
|
||||
await waitToNavigate(200);
|
||||
});
|
||||
|
||||
it(`button page should match image render`, async () => {
|
||||
await element(by.id(`quo2-:button`)).tap();
|
||||
await waitToNavigate(200);
|
||||
const res = await jestExpect(`button`).toMatchImageSnapshot();
|
||||
})
|
||||
});
|
||||
@@ -4,23 +4,25 @@
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def sizes
|
||||
{:icon {:small 12
|
||||
:medium 16
|
||||
:large 20}
|
||||
:container {:small 20
|
||||
{:icon {:small 12
|
||||
:medium 16
|
||||
:large 20}
|
||||
:container {:small 20
|
||||
:medium 32
|
||||
:large 48}})
|
||||
:large 48}})
|
||||
|
||||
;; TODO: this implementation does not support group display picture (can only display default group icon).
|
||||
(defn group-avatar [_]
|
||||
(fn [{:keys [color size]}]
|
||||
(let [container-size (get-in sizes [:container size])
|
||||
(fn [{:keys [color size override-theme]}]
|
||||
(let [theme (or override-theme (if (colors/dark?) :dark :light))
|
||||
container-size (get-in sizes [:container size])
|
||||
icon-size (get-in sizes [:icon size])]
|
||||
[rn/view {:width container-size
|
||||
:height container-size
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:border-radius (/ container-size 2)
|
||||
:background-color (colors/custom-color-by-theme color 50 60)}
|
||||
[icon/icon :i/group {:size icon-size
|
||||
:color colors/white-opa-70}]])))
|
||||
:background-color (if (= theme :light)
|
||||
(colors/custom-color color 50)
|
||||
(colors/custom-color color 60))}
|
||||
[icon/icon :total-members {:size icon-size
|
||||
:color colors/white-opa-70}]])))
|
||||
|
||||
@@ -122,20 +122,20 @@
|
||||
first-initial-letter
|
||||
initials)
|
||||
"")]
|
||||
[rn/view {:accessibility-label :user-avatar
|
||||
:style {:width outer-dimensions
|
||||
:height outer-dimensions
|
||||
:border-radius outer-dimensions}}
|
||||
[rn/view {:style {:width outer-dimensions
|
||||
:height outer-dimensions
|
||||
:border-radius outer-dimensions}}
|
||||
(when (and ring? identicon?)
|
||||
[icons/icon :i/identicon-ring {:size outer-dimensions
|
||||
:no-color true}])
|
||||
[icons/icon :main-icons/identicon-ring {:width outer-dimensions
|
||||
:height outer-dimensions
|
||||
:size outer-dimensions
|
||||
:no-color true}])
|
||||
(if profile-picture
|
||||
;; display image
|
||||
[fast-image/fast-image {:source {:uri profile-picture}
|
||||
:style (container-styling inner-dimensions outer-dimensions)}]
|
||||
;; else display initials
|
||||
[container inner-dimensions outer-dimensions
|
||||
^{:key :icon-text}
|
||||
[text/text {:weight :semi-bold
|
||||
:size font-size
|
||||
:style {:color colors/white-opa-70}}
|
||||
|
||||
@@ -7,149 +7,147 @@
|
||||
[quo2.components.icon :as quo2.icons]))
|
||||
|
||||
(def themes
|
||||
{:light {:primary {:icon-color colors/white
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/primary-50
|
||||
:pressed colors/primary-60
|
||||
:disabled colors/primary-50}}
|
||||
:secondary {:icon-color colors/primary-50
|
||||
:label-color colors/primary-50
|
||||
:background-color {:default colors/primary-50-opa-20
|
||||
:pressed colors/primary-50-opa-40
|
||||
:disabled colors/primary-50-opa-20}}
|
||||
:grey {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/neutral-10
|
||||
:pressed colors/neutral-20
|
||||
:disabled colors/neutral-10}}
|
||||
:dark-grey {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/neutral-20
|
||||
:pressed colors/neutral-30
|
||||
:disabled colors/neutral-20}}
|
||||
:outline {:icon-color colors/neutral-50
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label-color colors/neutral-100
|
||||
:border-color {:default colors/neutral-20
|
||||
:pressed colors/neutral-40
|
||||
:disabled colors/neutral-20}}
|
||||
:ghost {:icon-color colors/neutral-50
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:pressed colors/neutral-10}}
|
||||
:danger {:icon-color colors/white
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/danger-50
|
||||
:pressed colors/danger-60
|
||||
:disabled colors/danger-50}}
|
||||
:positive {:icon-color colors/white
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/success-50
|
||||
:pressed colors/success-60
|
||||
:disabled colors/success-50-opa-30}}
|
||||
:photo-bg {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-80-opa-40
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/white-opa-40
|
||||
:pressed colors/white-opa-50
|
||||
:disabled colors/white-opa-40}}
|
||||
:blur-bg {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-80-opa-40
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/neutral-80-opa-5
|
||||
:pressed colors/neutral-80-opa-10
|
||||
:disabled colors/neutral-80-opa-5}}
|
||||
:blur-bg-outline {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-80-opa-40
|
||||
:label-color colors/neutral-100
|
||||
:border-color {:default colors/neutral-80-opa-10
|
||||
:pressed colors/neutral-80-opa-20
|
||||
:disabled colors/neutral-80-opa-10}}
|
||||
{:light {:primary {:icon-color colors/white
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/primary-50
|
||||
:pressed colors/primary-60
|
||||
:disabled colors/primary-50}}
|
||||
:secondary {:icon-color colors/primary-50
|
||||
:label {:style {:color colors/primary-50}}
|
||||
:background-color {:default colors/primary-50-opa-20
|
||||
:pressed colors/primary-50-opa-40
|
||||
:disabled colors/primary-50-opa-20}}
|
||||
:grey {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label {:style {:color colors/neutral-100}}
|
||||
:background-color {:default colors/neutral-10
|
||||
:pressed colors/neutral-20
|
||||
:disabled colors/neutral-10}}
|
||||
:dark-grey {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label {:style {:color colors/neutral-100}}
|
||||
:background-color {:default colors/neutral-20
|
||||
:pressed colors/neutral-30
|
||||
:disabled colors/neutral-20}}
|
||||
:outline {:icon-color colors/neutral-50
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label {:style {:color colors/neutral-100}}
|
||||
:border-color {:default colors/neutral-20
|
||||
:pressed colors/neutral-40
|
||||
:disabled colors/neutral-20}}
|
||||
:ghost {:icon-color colors/neutral-50
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label {:style {:color colors/neutral-100}}
|
||||
:background-color {:pressed colors/neutral-10}}
|
||||
:danger {:icon-color colors/white
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/danger-50
|
||||
:pressed colors/danger-60
|
||||
:disabled colors/danger-50}}
|
||||
:positive {:icon-color colors/white
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/success-50
|
||||
:pressed colors/success-60
|
||||
:disabled colors/success-50-opa-30}}
|
||||
:photo-bg {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-80-opa-40
|
||||
:label {:style {:color colors/neutral-100}}
|
||||
:background-color {:default colors/white-opa-40
|
||||
:pressed colors/white-opa-50
|
||||
:disabled colors/white-opa-40}}
|
||||
:blur-bg {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-80-opa-40
|
||||
:label {:style {:color colors/neutral-100}}
|
||||
:background-color {:default colors/neutral-80-opa-5
|
||||
:pressed colors/neutral-80-opa-10
|
||||
:disabled colors/neutral-80-opa-5}}
|
||||
:blur-bg-outline {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-80-opa-40
|
||||
:label {:style {:color colors/neutral-100}}
|
||||
:border-color {:default colors/neutral-80-opa-10
|
||||
:pressed colors/neutral-80-opa-20
|
||||
:disabled colors/neutral-80-opa-10}}
|
||||
:shell {:icon-color colors/white
|
||||
:label-color colors/white
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/neutral-95
|
||||
:pressed colors/neutral-95
|
||||
:disabled colors/neutral-95}}}
|
||||
:dark {:primary {:icon-color colors/white
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/primary-60
|
||||
:pressed colors/primary-50
|
||||
:disabled colors/primary-60}}
|
||||
:secondary {:icon-color colors/primary-50
|
||||
:label-color colors/primary-50
|
||||
:background-color {:default colors/primary-50-opa-20
|
||||
:pressed colors/primary-50-opa-30
|
||||
:disabled colors/primary-50-opa-20}}
|
||||
:grey {:icon-color colors/white
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-80
|
||||
:pressed colors/neutral-60
|
||||
:disabled colors/neutral-80}}
|
||||
:dark-grey {:icon-color colors/white
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-70
|
||||
:pressed colors/neutral-60
|
||||
:disabled colors/neutral-70}}
|
||||
:outline {:icon-color colors/neutral-40
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label-color colors/white
|
||||
:border-color {:default colors/neutral-70
|
||||
:pressed colors/neutral-60
|
||||
:disabled colors/neutral-70}}
|
||||
:ghost {:icon-color colors/neutral-40
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label-color colors/white
|
||||
:background-color {:pressed colors/neutral-80}}
|
||||
:danger {:icon-color colors/white
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/danger-60
|
||||
:pressed colors/danger-50
|
||||
:disabled colors/danger-60}}
|
||||
:positive {:icon-color colors/white
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/success-60
|
||||
:pressed colors/success-50
|
||||
:disabled colors/success-60-opa-30}}
|
||||
:photo-bg {:icon-color colors/white
|
||||
:icon-secondary-color colors/neutral-30
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-80-opa-40
|
||||
:pressed colors/neutral-80-opa-50
|
||||
:disabled colors/neutral-80-opa-40}}
|
||||
:blur-bg {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-40
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/white-opa-5
|
||||
:pressed colors/white-opa-10
|
||||
:disabled colors/white-opa-5}}
|
||||
:blur-bg-outline {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-40
|
||||
:label-color colors/white
|
||||
:border-color {:default colors/white-opa-10
|
||||
:pressed colors/white-opa-20
|
||||
:disabled colors/white-opa-5}}
|
||||
:shell {:icon-color colors/white
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-95}}}})
|
||||
|
||||
(defn shape-style-container [type icon size]
|
||||
{:border-radius (if (and icon (#{:primary :secondary :danger} type))
|
||||
24
|
||||
(case size
|
||||
56 12
|
||||
40 12
|
||||
32 10
|
||||
24 8))})
|
||||
:dark {:primary {:icon-color colors/white
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/primary-60
|
||||
:pressed colors/primary-50
|
||||
:disabled colors/primary-60}}
|
||||
:secondary {:icon-color colors/primary-50
|
||||
:label {:style {:color colors/primary-50}}
|
||||
:background-color {:default colors/primary-50-opa-20
|
||||
:pressed colors/primary-50-opa-30
|
||||
:disabled colors/primary-50-opa-20}}
|
||||
:grey {:icon-color colors/white
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/neutral-80
|
||||
:pressed colors/neutral-60
|
||||
:disabled colors/neutral-80}}
|
||||
:dark-grey {:icon-color colors/white
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/neutral-70
|
||||
:pressed colors/neutral-60
|
||||
:disabled colors/neutral-70}}
|
||||
:outline {:icon-color colors/neutral-40
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label {:style {:color colors/white}}
|
||||
:border-color {:default colors/neutral-70
|
||||
:pressed colors/neutral-60
|
||||
:disabled colors/neutral-70}}
|
||||
:ghost {:icon-color colors/neutral-40
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:pressed colors/neutral-80}}
|
||||
:danger {:icon-color colors/white
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/danger-60
|
||||
:pressed colors/danger-50
|
||||
:disabled colors/danger-60}}
|
||||
:positive {:icon-color colors/white
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/success-60
|
||||
:pressed colors/success-50
|
||||
:disabled colors/success-60-opa-30}}
|
||||
:photo-bg {:icon-color colors/white
|
||||
:icon-secondary-color colors/neutral-30
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/neutral-80-opa-40
|
||||
:pressed colors/neutral-80-opa-50
|
||||
:disabled colors/neutral-80-opa-40}}
|
||||
:blur-bg {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-40
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/white-opa-5
|
||||
:pressed colors/white-opa-10
|
||||
:disabled colors/white-opa-5}}
|
||||
:blur-bg-outline {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-40
|
||||
:label {:style {:color colors/white}}
|
||||
:border-color {:default colors/white-opa-10
|
||||
:pressed colors/white-opa-20
|
||||
:disabled colors/white-opa-5}}
|
||||
:shell {:icon-color colors/white
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/neutral-95}}}})
|
||||
|
||||
(defn style-container [type size disabled background-color border-color icon above width before after]
|
||||
(merge {:height size
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction (if above :column :row)
|
||||
:border-radius (if (and icon (#{:primary :secondary :danger} type))
|
||||
24
|
||||
(case size
|
||||
56 12
|
||||
40 12
|
||||
32 10
|
||||
24 8))
|
||||
:background-color background-color
|
||||
:padding-horizontal (when-not (or icon before after)
|
||||
(case size 56 16 40 16 32 12 24 8))
|
||||
@@ -161,7 +159,6 @@
|
||||
(case size 56 0 40 9 32 5 24 3))
|
||||
:padding-bottom (when-not (or icon before after)
|
||||
(case size 56 0 40 9 32 5 24 4))}
|
||||
(shape-style-container type icon size)
|
||||
(when width
|
||||
{:width width})
|
||||
(when icon
|
||||
@@ -172,19 +169,14 @@
|
||||
(when disabled
|
||||
{:opacity 0.3})))
|
||||
|
||||
(defn community-themed? [type community-color]
|
||||
(and (= type :community) (string? community-color)))
|
||||
|
||||
(defn button
|
||||
"with label
|
||||
[button opts \"label\"]
|
||||
opts
|
||||
{:type :primary/:secondary/:grey/:dark-grey/:outline/:ghost/
|
||||
:danger/:photo-bg/:blur-bg/:blur-bg-ouline/:shell/:community
|
||||
:danger/:photo-bg/:blur-bg/:blur-bg-ouline/:shell
|
||||
:size 40/32/24
|
||||
:icon true/false
|
||||
:community-color '#FFFFFF'
|
||||
:community-text-color '#000000'
|
||||
:before :icon-keyword
|
||||
:after :icon-keyword}
|
||||
|
||||
@@ -192,21 +184,20 @@
|
||||
[button {:icon true} :main-icons/close-circle]"
|
||||
[_ _]
|
||||
(let [pressed (reagent/atom false)]
|
||||
(fn [{:keys [on-press disabled type size community-color community-text-color before after above width
|
||||
(fn [{:keys [on-press disabled type size before after above width
|
||||
override-theme override-background-color
|
||||
on-long-press accessibility-label icon icon-no-color style test-ID]
|
||||
on-long-press accessibility-label icon icon-no-color style]
|
||||
:or {type :primary
|
||||
size 40}}
|
||||
children]
|
||||
(let [{:keys [icon-color icon-secondary-color background-color label-color border-color]}
|
||||
(let [{:keys [icon-color icon-secondary-color background-color label border-color]}
|
||||
(get-in themes [(or
|
||||
override-theme
|
||||
(theme/get-theme)) type])
|
||||
state (cond disabled :disabled @pressed :pressed :else :default)
|
||||
icon-size (when (= 24 size) 12)
|
||||
icon-secondary-color (or icon-secondary-color icon-color)]
|
||||
[rn/touchable-without-feedback (merge {:test-ID test-ID
|
||||
:disabled disabled
|
||||
[rn/touchable-without-feedback (merge {:disabled disabled
|
||||
:accessibility-label accessibility-label}
|
||||
(when on-press
|
||||
{:on-press (fn []
|
||||
@@ -220,65 +211,48 @@
|
||||
(reset! pressed nil))})
|
||||
|
||||
[rn/view {:style (merge
|
||||
(shape-style-container type icon size)
|
||||
{:background-color
|
||||
(if (= state :pressed)
|
||||
(colors/theme-colors colors/neutral-100 colors/white)
|
||||
:transparent)}
|
||||
(style-container
|
||||
type
|
||||
size
|
||||
disabled
|
||||
(or override-background-color (get background-color state))
|
||||
(get border-color state)
|
||||
icon
|
||||
above
|
||||
width
|
||||
before
|
||||
after)
|
||||
style)}
|
||||
[rn/view {:style (merge
|
||||
(style-container
|
||||
type
|
||||
size
|
||||
disabled
|
||||
(or override-background-color (get background-color state))
|
||||
(get border-color state)
|
||||
icon
|
||||
above
|
||||
width
|
||||
before
|
||||
after)
|
||||
(when
|
||||
(community-themed? type community-color)
|
||||
(merge
|
||||
{:background-color community-color}
|
||||
(when (= state :pressed) {:opacity 0.9}))))}
|
||||
(when above
|
||||
[rn/view
|
||||
[quo2.icons/icon above {:container-style {:margin-bottom 2}
|
||||
(when above
|
||||
[rn/view
|
||||
[quo2.icons/icon above {:container-style {:margin-bottom 2}
|
||||
:color icon-secondary-color
|
||||
:size icon-size}]])
|
||||
(when before
|
||||
[rn/view
|
||||
[quo2.icons/icon before {:container-style {:margin-left (if (= size 40) 12 8)
|
||||
:margin-right 4}
|
||||
:color icon-secondary-color
|
||||
:size icon-size}]])
|
||||
(when before
|
||||
[rn/view
|
||||
[quo2.icons/icon before {:container-style {:margin-left (if (= size 40) 12 8)
|
||||
:margin-right 4}
|
||||
:color icon-secondary-color
|
||||
:size icon-size}]])
|
||||
[rn/view
|
||||
(cond
|
||||
(or icon icon-no-color)
|
||||
[quo2.icons/icon children {:color icon-color
|
||||
:no-color icon-no-color
|
||||
:size icon-size}]
|
||||
[rn/view
|
||||
(cond
|
||||
(or icon icon-no-color)
|
||||
[quo2.icons/icon children {:color icon-color
|
||||
:no-color icon-no-color
|
||||
:size icon-size}]
|
||||
|
||||
(string? children)
|
||||
[text/text {:size (when (#{56 24} size) :paragraph-2)
|
||||
:weight :medium
|
||||
:number-of-lines 1
|
||||
:style {:color (if
|
||||
(and
|
||||
(community-themed? type community-color)
|
||||
(string? community-text-color))
|
||||
community-text-color
|
||||
label-color)}}
|
||||
(string? children)
|
||||
[text/text (merge {:size (when (#{56 24} size) :paragraph-2)
|
||||
:weight :medium
|
||||
:number-of-lines 1}
|
||||
label)
|
||||
children]
|
||||
|
||||
children]
|
||||
|
||||
(vector? children)
|
||||
children)]
|
||||
(when after
|
||||
[rn/view
|
||||
[quo2.icons/icon after {:container-style {:margin-left 4
|
||||
:margin-right (if (= size 40) 12 8)}
|
||||
:color icon-secondary-color
|
||||
:size icon-size}]])]]]))))
|
||||
(vector? children)
|
||||
children)]
|
||||
(when after
|
||||
[rn/view
|
||||
[quo2.icons/icon after {:container-style {:margin-left 4
|
||||
:margin-right (if (= size 40) 12 8)}
|
||||
:color icon-secondary-color
|
||||
:size icon-size}]])]]))))
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
|
||||
(defn community-card-view-item
|
||||
[{:keys [name description locked
|
||||
status tokens cover tags width]} on-press]
|
||||
status tokens cover tags featured]} on-press]
|
||||
[rn/touchable-opacity {:on-press on-press}
|
||||
[rn/view {:style (style/community-card 20)}
|
||||
[rn/view {:style {:width width
|
||||
:height 230
|
||||
[rn/view {:style (merge (style/community-card 20)
|
||||
{:margin-bottom 16}
|
||||
(if featured
|
||||
{:margin-right 12}
|
||||
{:flex 1
|
||||
:margin-horizontal 20}))}
|
||||
[rn/view {:style {:height 230
|
||||
:border-radius 20}
|
||||
:on-press on-press}
|
||||
[rn/view
|
||||
|
||||
@@ -6,49 +6,10 @@
|
||||
[quo2.components.counter.counter :as counter]
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.components.community.style :as style]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn community-icon-view [community-icon]
|
||||
[rn/view {:width 32
|
||||
:height 32}
|
||||
[fast-image/fast-image {:source {:uri community-icon}
|
||||
:style {:height 32
|
||||
:border-radius 16
|
||||
:width 32}}]])
|
||||
|
||||
(defn notification-view [{:keys [muted?
|
||||
unread-messages?
|
||||
unread-mentions-count]}]
|
||||
(cond
|
||||
muted?
|
||||
[icons/icon :i/muted {:container-style {:align-items :center
|
||||
:justify-content :center}
|
||||
:resize-mode :center
|
||||
:size 20
|
||||
:color (colors/theme-colors
|
||||
colors/neutral-40
|
||||
colors/neutral-50)}]
|
||||
(pos? unread-mentions-count)
|
||||
[counter/counter {:type :default} unread-mentions-count]
|
||||
|
||||
unread-messages?
|
||||
[rn/view {:style {:width 8
|
||||
:height 8
|
||||
:border-radius 4
|
||||
:background-color (colors/theme-colors
|
||||
colors/neutral-40
|
||||
colors/neutral-60)}}]))
|
||||
|
||||
(defn communities-list-view-item [props {:keys [name
|
||||
locked?
|
||||
status
|
||||
muted?
|
||||
unread-messages?
|
||||
unread-mentions-count
|
||||
community-icon
|
||||
tokens
|
||||
background-color]}]
|
||||
(defn communities-list-view-item [props {:keys [name locked? status notifications
|
||||
tokens background-color]}]
|
||||
[rn/view {:style (merge (style/community-card 16)
|
||||
{:margin-bottom 12
|
||||
:margin-horizontal 20})}
|
||||
@@ -63,8 +24,8 @@
|
||||
:padding-vertical 8
|
||||
:background-color background-color}
|
||||
[rn/view]
|
||||
(when community-icon
|
||||
[community-icon-view community-icon])
|
||||
;;TODO new pure component based on quo2 should be implemented without status-im usage
|
||||
;[communities.icon/community-icon-redesign community 32]]
|
||||
[rn/view {:flex 1
|
||||
:margin-horizontal 12}
|
||||
[text/text {:weight :semi-bold
|
||||
@@ -72,7 +33,7 @@
|
||||
:accessibility-label :community-name-text
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :tail
|
||||
:style {:color (when muted?
|
||||
:style {:color (when (= notifications :muted)
|
||||
(colors/theme-colors
|
||||
colors/neutral-40
|
||||
colors/neutral-60))}}
|
||||
@@ -81,18 +42,28 @@
|
||||
(if (= status :gated)
|
||||
[community-view/permission-tag-container {:locked? locked?
|
||||
:tokens tokens}]
|
||||
[notification-view {:muted? muted?
|
||||
:unread-mentions-count unread-mentions-count
|
||||
:unread-messages? unread-messages?}])]]]])
|
||||
(cond
|
||||
(= notifications :unread-messages-count)
|
||||
[rn/view {:style {:width 8
|
||||
:height 8
|
||||
:border-radius 4
|
||||
:background-color (colors/theme-colors
|
||||
colors/neutral-40
|
||||
colors/neutral-60)}}]
|
||||
|
||||
(defn communities-membership-list-item [props {:keys [name
|
||||
muted?
|
||||
unread-messages?
|
||||
unread-mentions-count
|
||||
status
|
||||
community-icon
|
||||
tokens
|
||||
locked?]}]
|
||||
(= notifications :unread-mentions-count)
|
||||
[counter/counter {:type :default} 5]
|
||||
|
||||
(= notifications :muted)
|
||||
[icons/icon :i/muted {:container-style {:align-items :center
|
||||
:justify-content :center}
|
||||
:resize-mode :center
|
||||
:size 20
|
||||
:color (colors/theme-colors
|
||||
colors/neutral-40
|
||||
colors/neutral-50)}]))]]]])
|
||||
|
||||
(defn communities-membership-list-item [props {:keys [name status tokens locked?]}]
|
||||
[rn/view {:margin-bottom 20}
|
||||
[rn/touchable-highlight (merge {:underlay-color colors/primary-50-opa-5
|
||||
:style {:border-radius 12}}
|
||||
@@ -101,9 +72,8 @@
|
||||
[rn/view {:flex-direction :row
|
||||
:border-radius 16
|
||||
:align-items :center}
|
||||
|
||||
(when community-icon
|
||||
[community-icon-view community-icon])
|
||||
;;TODO new pure component based on quo2 should be implemented without status-im usage
|
||||
;[communities.icon/community-icon-redesign community 32]
|
||||
[rn/view {:flex 1
|
||||
:margin-left 12
|
||||
:justify-content :center}
|
||||
@@ -114,12 +84,8 @@
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1}
|
||||
name]]
|
||||
|
||||
[rn/view {:justify-content :center
|
||||
:margin-right 16}
|
||||
(if (= status :gated)
|
||||
(when (= status :gated)
|
||||
[rn/view {:justify-content :center
|
||||
:margin-right 12}
|
||||
[community-view/permission-tag-container {:locked? locked?
|
||||
:tokens tokens}]
|
||||
[notification-view {:muted? muted?
|
||||
:unread-mentions-count unread-mentions-count
|
||||
:unread-messages? unread-messages?}])]]]]])
|
||||
:tokens tokens}]])]]]])
|
||||
|
||||
@@ -69,12 +69,10 @@
|
||||
:style {:margin-top (if (= size :large) 8 2)}}
|
||||
description])])
|
||||
|
||||
(defn permission-tag-container [{:keys [locked? tokens on-press]}]
|
||||
(defn permission-tag-container [{:keys [locked? tokens]}]
|
||||
[permission/tag {:background-color (colors/theme-colors
|
||||
colors/neutral-10
|
||||
colors/neutral-80)
|
||||
:locked? locked?
|
||||
:tokens tokens
|
||||
|
||||
:size 24
|
||||
:on-press on-press}])
|
||||
:size 24}])
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
(ns quo2.components.community.token-gating
|
||||
(:require [quo.react-native :as rn]
|
||||
[quo2.components.avatars.channel-avatar :as channel-avatar]
|
||||
[quo2.components.buttons.button :as button]
|
||||
[quo2.components.icon :as icon]
|
||||
[quo2.components.info.information-box :as information-box]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.tags.token-tag :as token-tag]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[status-im.ui.components.fast-image :as fast-image]))
|
||||
|
||||
(def ^:private token-tag-horizontal-spacing 7)
|
||||
(def token-tag-vertical-spacing 5)
|
||||
|
||||
(def styles {:container {:flex 1
|
||||
:padding-horizontal 20}
|
||||
:header-container {:flex-direction :row
|
||||
:align-items :center}
|
||||
:header-spacing-community {:margin-bottom 16}
|
||||
:header-spacing-channel {:margin-bottom 24}
|
||||
:header-avatar {:margin-right 8}
|
||||
:header-community-avatar-image {:width 32 :height 32}
|
||||
:header-title-container {:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center}
|
||||
:header-title-lock {:margin-left 6}
|
||||
:header-info-button {:margin-left 8}
|
||||
:token-requirement-text-spacing {:margin-vertical 8}
|
||||
:token-requirement-list-spacing {:padding-vertical (- 8 token-tag-vertical-spacing)}
|
||||
:token-row {:flex-direction :row
|
||||
:flex-wrap :wrap
|
||||
:align-items :center}
|
||||
:token-row-container {:flex-direction :row
|
||||
:align-items :center
|
||||
:margin-horizontal (- token-tag-horizontal-spacing)}
|
||||
:token-row-container-no-shift {:margin-left 0}
|
||||
:token-row-or-text {:margin-right 3}
|
||||
:token-tag-spacing {:margin-horizontal token-tag-horizontal-spacing
|
||||
:margin-vertical token-tag-vertical-spacing}
|
||||
:divider {:height 1
|
||||
:margin-horizontal -20
|
||||
:margin-top (- 12 token-tag-vertical-spacing)
|
||||
:margin-bottom 8}
|
||||
:membership-request-denied {:margin-top 13}
|
||||
:enter-button {:margin-top 16}
|
||||
:info-text {:margin-top 12
|
||||
:text-align :center
|
||||
:padding-horizontal 20}})
|
||||
|
||||
(defn multiple-token-requirements? [token-requirement-lists]
|
||||
(when (vector? (first token-requirement-lists))
|
||||
(> (count token-requirement-lists) 1)))
|
||||
|
||||
(defn is-token-requirement-met? [token-requirement-list]
|
||||
(and (seq token-requirement-list)
|
||||
(every?
|
||||
(fn [token]
|
||||
(get token :is-sufficient?))
|
||||
token-requirement-list)))
|
||||
|
||||
(defn are-multiple-token-requirements-met? [token-requirement-lists]
|
||||
(if (multiple-token-requirements? token-requirement-lists)
|
||||
(some is-token-requirement-met? token-requirement-lists)
|
||||
(is-token-requirement-met? token-requirement-lists)))
|
||||
|
||||
(defn token-requirement-list-row [tokens community-color]
|
||||
[rn/view {:style (merge
|
||||
(get styles :token-row)
|
||||
(get styles :token-requirement-list-spacing))}
|
||||
(map-indexed (fn [token-index token]
|
||||
(let [{:keys [token-img-src token amount is-sufficient? is-purchasable?]} token]
|
||||
^{:key token-index}
|
||||
[rn/view {:style (get styles :token-tag-spacing)}
|
||||
[token-tag/token-tag {:token token
|
||||
:value amount
|
||||
:size 24
|
||||
:border-color community-color
|
||||
:is-required is-sufficient?
|
||||
:is-purchasable is-purchasable?
|
||||
:token-img-src token-img-src}]]))
|
||||
tokens)])
|
||||
|
||||
(defn token-requirement-list [props community-color]
|
||||
(let [{:keys [gate token-requirements-changed? required-tokens-lost?]} props
|
||||
[gate-type token-requirement-lists] gate
|
||||
multiple-token-requirements? (multiple-token-requirements? token-requirement-lists)
|
||||
is-sufficient? (are-multiple-token-requirements-met? token-requirement-lists)
|
||||
you-must-hold-label (if (= gate-type :join)
|
||||
(cond
|
||||
token-requirements-changed? :t/you-must-now-hold
|
||||
required-tokens-lost? :t/you-must-always-hold
|
||||
:else :t/you-must-hold)
|
||||
:t/you-must-hold)
|
||||
message-label (cond
|
||||
(= gate-type :join)
|
||||
(cond
|
||||
token-requirements-changed? :t/community-join-requirements-changed
|
||||
required-tokens-lost? :t/community-join-requirements-tokens-lost
|
||||
:else (if is-sufficient? :t/community-join-requirements-met :t/community-join-requirements-not-met))
|
||||
(= gate-type :read)
|
||||
(if is-sufficient?
|
||||
:t/community-channel-read-requirements-met
|
||||
:t/community-channel-read-requirements-not-met)
|
||||
(= gate-type :write)
|
||||
(if is-sufficient?
|
||||
:t/community-channel-write-requirements-met
|
||||
:t/community-channel-write-requirements-not-met))]
|
||||
[rn/view
|
||||
[rn/view {:style (get styles :token-requirement-text-spacing)}
|
||||
[text/text {:weight :medium
|
||||
:number-of-lines 1}
|
||||
(i18n/label
|
||||
message-label)]
|
||||
[text/text {:size :paragraph-2
|
||||
:number-of-lines 1}
|
||||
(i18n/label
|
||||
you-must-hold-label)]]
|
||||
|
||||
(if multiple-token-requirements?
|
||||
(map-indexed
|
||||
(fn [token-requirement-index tokens]
|
||||
^{:key token-requirement-index}
|
||||
[rn/view {:style (merge
|
||||
(get styles :token-row-container)
|
||||
(when-not (= token-requirement-index 0)
|
||||
(get styles :token-row-container-no-shift)))}
|
||||
(when-not (= token-requirement-index 0)
|
||||
[text/text {:style (get styles :token-row-or-text)
|
||||
:size :paragraph-2} "or"])
|
||||
[token-requirement-list-row tokens community-color]])
|
||||
token-requirement-lists)
|
||||
[rn/view {:style (get styles :token-row-container)}
|
||||
[token-requirement-list-row token-requirement-lists community-color]])]))
|
||||
|
||||
(defn is-community-locked? [community]
|
||||
(not (are-multiple-token-requirements-met? (get-in community [:gates :join]))))
|
||||
|
||||
(defn is-channel-locked? [channel]
|
||||
(not (are-multiple-token-requirements-met?
|
||||
(or (get-in channel [:gates :read])
|
||||
(get-in channel [:gates :write])))))
|
||||
|
||||
(defn token-gating
|
||||
"[token-gating opts]
|
||||
opts
|
||||
{
|
||||
:community {
|
||||
:name string
|
||||
:community-avatar-img-src string
|
||||
:community-color string
|
||||
:community-text-color string
|
||||
:token-requirements-changed? boolean
|
||||
:required-tokens-lost? boolean
|
||||
}
|
||||
:channel {
|
||||
:name string
|
||||
:emoji string
|
||||
:emoji-background-color :string
|
||||
:on-enter-channel callback
|
||||
:membership-request-denied? boolean
|
||||
}
|
||||
}"
|
||||
[_ _]
|
||||
(fn [{:keys [community channel]}]
|
||||
(let [type (if (some? community) :community :channel)
|
||||
{:keys [name
|
||||
emoji
|
||||
emoji-background-color
|
||||
on-enter-channel
|
||||
community-avatar-img-src
|
||||
community-color
|
||||
community-text-color
|
||||
membership-request-denied?
|
||||
token-requirements-changed?
|
||||
required-tokens-lost?
|
||||
gates]} (if (= type :community) community channel)
|
||||
locked? (if
|
||||
(= type :community)
|
||||
(is-community-locked? community)
|
||||
(is-channel-locked? channel))]
|
||||
|
||||
[rn/view {:style (merge (get styles :container) {:background-color (colors/theme-colors colors/white colors/neutral-90)})}
|
||||
[rn/view {:style (merge
|
||||
(get styles :header-container)
|
||||
(if
|
||||
(= type :community)
|
||||
(get styles :header-spacing-community)
|
||||
(get styles :header-spacing-channel)))}
|
||||
|
||||
[rn/view {:style (get styles :header-avatar)}
|
||||
(if (= type :community)
|
||||
[fast-image/fast-image {:source community-avatar-img-src
|
||||
:style (get styles :header-community-avatar-image)}]
|
||||
|
||||
[channel-avatar/channel-avatar {:big? true
|
||||
:locked? locked?
|
||||
:emoji emoji
|
||||
:emoji-background-color emoji-background-color}])]
|
||||
|
||||
[rn/view {:style (get styles :header-title-container)}
|
||||
[text/text {:weight :semi-bold
|
||||
:number-of-lines 1
|
||||
:size :heading-1
|
||||
:style (get styles :header-text)} (if (= type :community) name (str "# " name))]
|
||||
|
||||
(when (= type :community)
|
||||
[icon/icon (if locked?
|
||||
:main-icons2/locked
|
||||
:main-icons2/unlocked)
|
||||
{:container-style (get styles :header-title-lock)
|
||||
:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
colors/neutral-40)}])]
|
||||
|
||||
[button/button {:type :outline
|
||||
:size 32
|
||||
:icon true
|
||||
:style (get styles :header-info-button)} :main-icons2/info]]
|
||||
|
||||
(map-indexed (fn [gate-index gate]
|
||||
^{:key gate-index}
|
||||
[:<>
|
||||
(when-not (= gate-index 0)
|
||||
[rn/view {:style (merge
|
||||
(get styles :divider)
|
||||
{:background-color (colors/theme-colors
|
||||
colors/neutral-10
|
||||
colors/neutral-80)})}])
|
||||
[token-requirement-list {:gate gate :token-requirements-changed? token-requirements-changed? :required-tokens-lost? required-tokens-lost?} community-color]])
|
||||
gates)
|
||||
|
||||
(when (= type :channel)
|
||||
(if membership-request-denied?
|
||||
[information-box/information-box {:type :error
|
||||
:icon :main-icons2/untrustworthy
|
||||
:no-icon-color? true
|
||||
:style (get styles :membership-request-denied)}
|
||||
(i18n/label
|
||||
:t/membership-request-denied)]
|
||||
|
||||
[:<>
|
||||
[button/button {:type :community
|
||||
:community-color community-color
|
||||
:community-text-color community-text-color
|
||||
:style (get styles :enter-button)
|
||||
:disabled locked?
|
||||
:on-press on-enter-channel}
|
||||
(str "# " (i18n/label
|
||||
:t/enter-channel))]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style (merge
|
||||
(get styles :info-text)
|
||||
{:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
colors/neutral-40)})}
|
||||
(i18n/label
|
||||
:t/community-enter-channel-info)]]))])))
|
||||
@@ -20,7 +20,7 @@
|
||||
(defn counter
|
||||
"type: default, secondary, grey, outline
|
||||
value: integer"
|
||||
[{:keys [type override-text-color override-bg-color style accessibility-label]} value]
|
||||
[{:keys [type override-text-color override-bg-color style]} value]
|
||||
(let [type (or type :default)
|
||||
text-color (or override-text-color
|
||||
(if (or
|
||||
@@ -38,9 +38,7 @@
|
||||
1 16
|
||||
2 20
|
||||
28)]
|
||||
[rn/view {:accessible true
|
||||
:accessibility-label accessibility-label
|
||||
:style (cond-> (merge
|
||||
[rn/view {:style (cond-> (merge
|
||||
{:align-items :center
|
||||
:justify-content :center
|
||||
:border-radius 6
|
||||
|
||||
@@ -6,77 +6,69 @@
|
||||
|
||||
(defn- get-icon-color [danger?]
|
||||
(if danger?
|
||||
colors/danger-50
|
||||
(colors/theme-colors colors/danger-50 colors/danger-60)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40)))
|
||||
|
||||
(defn divider []
|
||||
[rn/view {:style {:border-top-width 1
|
||||
:border-top-color (colors/theme-colors
|
||||
colors/neutral-10 colors/neutral-90)
|
||||
:margin-top 8
|
||||
:margin-bottom 7
|
||||
:align-items :center
|
||||
:flex-direction :row}}])
|
||||
|
||||
(defn action [{:keys [icon
|
||||
label
|
||||
sub-label
|
||||
right-icon
|
||||
danger?
|
||||
on-press
|
||||
add-divider?] :as action-props}]
|
||||
on-press] :as action-props}]
|
||||
(when action-props
|
||||
[:<> {:key label}
|
||||
(when add-divider? [divider])
|
||||
[rn/touchable-highlight {:style {:border-radius 12
|
||||
:height (if sub-label 58 50)
|
||||
:margin-horizontal 8}
|
||||
:underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90)
|
||||
:on-press on-press}
|
||||
[rn/touchable-opacity {:on-press on-press}
|
||||
[rn/view {:style
|
||||
{:height (if sub-label 56 47)
|
||||
:margin-horizontal 20
|
||||
:flex-direction :row}}
|
||||
[rn/view {:style
|
||||
{:height (if sub-label 58 50)
|
||||
{:height 20
|
||||
:margin-top :auto
|
||||
:margin-bottom :auto
|
||||
:margin-right 12
|
||||
:width 20}}
|
||||
[icon/icon icon
|
||||
{:color (get-icon-color danger?)
|
||||
:size 20}]]
|
||||
[rn/view
|
||||
{:style
|
||||
{:flex 1
|
||||
:justify-content :center}}
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight :medium
|
||||
:style {:color
|
||||
(when danger?
|
||||
(colors/theme-colors colors/danger-50 colors/danger-60))}}
|
||||
label]
|
||||
(when sub-label
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style {:color
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40)}}
|
||||
sub-label])]
|
||||
(when right-icon
|
||||
[rn/view {:style
|
||||
{:height 20
|
||||
:margin-top :auto
|
||||
:margin-bottom :auto
|
||||
:width 20}}
|
||||
[icon/icon right-icon
|
||||
{:color (get-icon-color danger?)
|
||||
:size 20}]])]]))
|
||||
|
||||
:margin-horizontal 12
|
||||
:flex-direction :row}}
|
||||
[rn/view {:style
|
||||
{:height 20
|
||||
:margin-top :auto
|
||||
:margin-bottom :auto
|
||||
:margin-right 12
|
||||
:width 20}}
|
||||
[icon/icon icon
|
||||
{:color (get-icon-color danger?)
|
||||
:size 20}]]
|
||||
[rn/view
|
||||
{:style
|
||||
{:flex 1
|
||||
:justify-content :center}}
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight :medium
|
||||
:style {:color
|
||||
(when danger?
|
||||
(colors/theme-colors colors/danger-50 colors/danger-60))}}
|
||||
label]
|
||||
(when sub-label
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style {:color
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40)}}
|
||||
sub-label])]
|
||||
(when right-icon
|
||||
[rn/view {:style
|
||||
{:height 20
|
||||
:margin-top :auto
|
||||
:margin-bottom :auto
|
||||
:width 20}}
|
||||
[icon/icon right-icon
|
||||
{:color (get-icon-color danger?)
|
||||
:size 20}]])]]]))
|
||||
(defn divider []
|
||||
[rn/view {:style {:border-top-width 1
|
||||
:border-top-color (colors/theme-colors colors/neutral-10 colors/neutral-80)
|
||||
:margin-top 8
|
||||
:margin-bottom 7
|
||||
:align-items :center
|
||||
:flex-direction :row}}])
|
||||
|
||||
(defn action-drawer [sections]
|
||||
[:<>
|
||||
(doall
|
||||
[:<> {:style
|
||||
{:flex 1}}
|
||||
(interpose
|
||||
[divider]
|
||||
(for [actions sections]
|
||||
(doall
|
||||
(map action actions))))])
|
||||
(map action actions)))])
|
||||
|
||||
@@ -4,14 +4,9 @@
|
||||
|
||||
(def icon-path "./resources/images/icons2/")
|
||||
|
||||
(defn combine-path [path el]
|
||||
(if (System/getenv "COMPONENT_TEST")
|
||||
(str "." path el "@2x.png")
|
||||
(str "." path el ".png")))
|
||||
|
||||
(defn require-icon [size path]
|
||||
(fn [el]
|
||||
(let [s (combine-path path el)
|
||||
(let [s (str "." path el ".png")
|
||||
k (-> el
|
||||
(cstr/replace "_" "-")
|
||||
(cstr/replace " " "-")
|
||||
@@ -35,5 +30,4 @@
|
||||
(get-icons 12)
|
||||
(get-icons 16)
|
||||
(get-icons 20)
|
||||
(get-icons 24)
|
||||
(get-icons 32)))
|
||||
(get-icons 24)))
|
||||
|
||||
@@ -19,21 +19,19 @@
|
||||
(defn info-message
|
||||
"[info-message opts \"message\"]
|
||||
opts
|
||||
{:type :default/:success/:error
|
||||
:size :default/:tiny
|
||||
:icon :main-icons/info ;; info message icon
|
||||
:text-color colors/white ;; text color override
|
||||
:icon-color colors/white ;; icon color override
|
||||
:no-icon-color? false ;; disable tint color for icon"
|
||||
[{:keys [type size icon text-color icon-color no-icon-color?]} message]
|
||||
{:type :default/:success/:error
|
||||
:size :default/:tiny
|
||||
:icon :main-icons/info ;; info message icon
|
||||
:text-color colors/white ;; text color override
|
||||
:icon-color colors/white ;; icon color override"
|
||||
[{:keys [type size icon text-color icon-color]} message]
|
||||
(let [weight (if (= size :default) :regular :medium)
|
||||
size (if (= size :default) :paragraph-2 :label)
|
||||
text-color (or text-color (get-color type))
|
||||
icon-color (or icon-color text-color)]
|
||||
[rn/view {:style {:flex-direction :row
|
||||
:flex 1}}
|
||||
[quo2.icons/icon icon {:color icon-color
|
||||
:no-color no-icon-color?
|
||||
[quo2.icons/icon icon {:color icon-color
|
||||
:size 12
|
||||
:container-style {:margin-top 3}}]
|
||||
[text/text {:size size
|
||||
|
||||
@@ -49,12 +49,11 @@
|
||||
:closed? true/false ;; information box's state
|
||||
:id :information-box-id ;; unique id (required for closable? information box)
|
||||
:icon :main-icons/info ;; information box icon
|
||||
:no-icon-color? false ;; disable tint color for icon
|
||||
:style style
|
||||
:button-label \"PressMe\" ;; add action button with label
|
||||
:on-button-press action ;; (required for information box with button-label)
|
||||
:on-close on-close ;; (optional on-close call)"
|
||||
[{:keys [type closable? closed? id icon style button-label on-button-press on-close no-icon-color?]} message]
|
||||
[{:keys [type closable? closed? id icon style button-label on-button-press on-close]} message]
|
||||
(let [background-color (get-color-by-type type :bg)
|
||||
border-color (get-color-by-type type :border)
|
||||
icon-color (get-color-by-type type :icon)
|
||||
@@ -74,8 +73,7 @@
|
||||
[info-message/info-message {:size :default
|
||||
:icon icon
|
||||
:text-color text-color
|
||||
:icon-color icon-color
|
||||
:no-icon-color? no-icon-color?} message]
|
||||
:icon-color icon-color} message]
|
||||
(when closable?
|
||||
[rn/touchable-opacity
|
||||
{:on-press on-close
|
||||
|
||||
@@ -1,57 +1,56 @@
|
||||
(ns quo2.components.list-items.channel
|
||||
(:require [quo2.components.avatars.channel-avatar :as channel-avatar]
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.counter.counter :as quo2.counter]
|
||||
[quo2.components.icon :as quo2.icons]
|
||||
[quo2.components.avatars.channel-avatar :as channel-avatar]
|
||||
[quo2.components.markdown.text :as quo2.text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.core :as rn]))
|
||||
[quo2.theme :as theme]))
|
||||
|
||||
(defn list-item [{:keys [name locked? mentions-count unread-messages?
|
||||
muted? is-active-channel? emoji channel-color on-press]
|
||||
muted? is-active-channel? emoji channel-color]
|
||||
:or {channel-color colors/primary-50}}]
|
||||
[rn/touchable-opacity {:on-press on-press}
|
||||
[rn/view {:style (merge {:height 48
|
||||
:display :flex
|
||||
:border-radius 12
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:width "100%"
|
||||
:padding-left 12
|
||||
:padding-right 12}
|
||||
(when is-active-channel?
|
||||
{:background-color (colors/theme-alpha channel-color 0.05 0.05)}))}
|
||||
[rn/view {:display :flex
|
||||
:flex-direction :row
|
||||
:justify-content :flex-start
|
||||
:align-items :center}
|
||||
[channel-avatar/channel-avatar
|
||||
{:big? true
|
||||
:locked? locked?
|
||||
:emoji-background-color (colors/theme-alpha channel-color 0.1 0.1)
|
||||
:emoji emoji}]
|
||||
[quo2.text/text
|
||||
{:style (merge {:margin-left 12}
|
||||
(when (and (not locked?) muted?)
|
||||
{:color (if (theme/dark?) colors/neutral-60 colors/neutral-40)}))
|
||||
:weight :medium :size :paragraph-1} (str "# " name)]]
|
||||
[rn/view {:style {:height 20}}
|
||||
(when (and (not locked?)
|
||||
muted?)
|
||||
[quo2.icons/icon :i/muted
|
||||
{:size 20
|
||||
:no-color true}])
|
||||
(when (and (not locked?)
|
||||
(not muted?)
|
||||
(pos? (int mentions-count)))
|
||||
[rn/view {:style {:margin-right 2
|
||||
:margin-top 2}}
|
||||
[quo2.counter/counter {:override-bg-color channel-color} mentions-count]])
|
||||
(when (and (not locked?)
|
||||
(not muted?)
|
||||
(not (pos? (int mentions-count)))
|
||||
unread-messages?)
|
||||
[quo2.icons/icon :i/channel-notification
|
||||
{:size 20
|
||||
:no-color true}])]]])
|
||||
[rn/view {:style (merge {:height 48
|
||||
:display :flex
|
||||
:border-radius 12
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:width "100%"
|
||||
:padding-left 12
|
||||
:padding-right 12}
|
||||
(when is-active-channel?
|
||||
{:background-color (colors/theme-alpha channel-color 0.05 0.05)}))}
|
||||
[rn/view {:display :flex
|
||||
:flex-direction :row
|
||||
:justify-content :flex-start
|
||||
:align-items :center}
|
||||
[channel-avatar/channel-avatar
|
||||
{:big? true
|
||||
:locked? locked?
|
||||
:emoji-background-color (colors/theme-alpha channel-color 0.1 0.1)
|
||||
:emoji emoji}]
|
||||
[quo2.text/text
|
||||
{:style (merge {:margin-left 12}
|
||||
(when (and (not locked?) muted?)
|
||||
{:color (if (theme/dark?) colors/neutral-60 colors/neutral-40)}))
|
||||
:weight :medium :size :paragraph-1} (str "# " name)]]
|
||||
[rn/view {:style {:height 20}}
|
||||
(when (and (not locked?)
|
||||
muted?)
|
||||
[quo2.icons/icon :i/muted
|
||||
{:size 20
|
||||
:no-color true}])
|
||||
(when (and (not locked?)
|
||||
(not muted?)
|
||||
(pos? (int mentions-count)))
|
||||
[rn/view {:style {:margin-right 2
|
||||
:margin-top 2}}
|
||||
[quo2.counter/counter {:override-bg-color channel-color} mentions-count]])
|
||||
(when (and (not locked?)
|
||||
(not muted?)
|
||||
(not (pos? (int mentions-count)))
|
||||
unread-messages?)
|
||||
[quo2.icons/icon :i/channel-notification
|
||||
{:size 20
|
||||
:no-color true}])]])
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
(ns quo2.components.messages.author.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def container
|
||||
{:flex 1
|
||||
:flex-wrap :wrap
|
||||
:height 18
|
||||
:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(defn ens-text []
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white)})
|
||||
|
||||
(defn nickname-text []
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white)})
|
||||
|
||||
(def middle-dot-nickname
|
||||
{:color colors/neutral-50
|
||||
:margin-horizontal 4})
|
||||
|
||||
(def chat-key-text
|
||||
{:color colors/neutral-50
|
||||
:margin-left 8})
|
||||
|
||||
(def middle-dot-chat-key
|
||||
{:color colors/neutral-50
|
||||
:margin-left 4})
|
||||
|
||||
(defn profile-name-text [nickname?]
|
||||
{:color (if nickname?
|
||||
(colors/theme-colors colors/neutral-60 colors/neutral-40)
|
||||
(colors/theme-colors colors/neutral-100 colors/white))})
|
||||
|
||||
(def icon-container
|
||||
{:margin-left 4})
|
||||
|
||||
(defn time-text [ens?]
|
||||
{:color colors/neutral-50
|
||||
:margin-left (if ens? 8 4)})
|
||||
@@ -1,88 +0,0 @@
|
||||
(ns quo2.components.messages.author.view
|
||||
(:require
|
||||
[quo2.components.messages.author.style :as style]
|
||||
[react-native.core :as rn]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.icon :as icons]
|
||||
[status-im.utils.utils :as utils]
|
||||
[clojure.string :as string]))
|
||||
|
||||
(def middle-dot "·")
|
||||
|
||||
(defn display-name [{:keys [profile-name nickname ens-name text-style]}]
|
||||
(let [ens? (-> ens-name string/blank? not)
|
||||
nickname? (-> nickname string/blank? not)]
|
||||
(if ens?
|
||||
[text/text (merge {:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:style (style/ens-text)}
|
||||
text-style)
|
||||
ens-name]
|
||||
[:<>
|
||||
(if nickname?
|
||||
[text/text (merge {:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:style (style/nickname-text)}
|
||||
text-style)
|
||||
nickname]
|
||||
[text/text (merge {:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:style (style/profile-name-text nickname?)}
|
||||
text-style)
|
||||
profile-name])])))
|
||||
|
||||
(defn author [{:keys [profile-name nickname chat-key ens-name time-str contact? verified? untrustworthy?]}]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [ens? (-> ens-name string/blank? not)
|
||||
nickname? (-> nickname string/blank? not)]
|
||||
[rn/view {:style style/container}
|
||||
(if ens?
|
||||
[text/text {:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:style (style/ens-text)}
|
||||
ens-name]
|
||||
[:<>
|
||||
(when nickname?
|
||||
[:<>
|
||||
[text/text {:weight :semi-bold
|
||||
:size :paragraph-2
|
||||
:style (style/nickname-text)}
|
||||
nickname]
|
||||
[text/text {:size :paragraph-2
|
||||
:style style/middle-dot-nickname}
|
||||
middle-dot]])
|
||||
[text/text {:weight (if nickname? :medium :semi-bold)
|
||||
:size :paragraph-2
|
||||
:style (style/profile-name-text nickname?)}
|
||||
profile-name]])
|
||||
(when contact?
|
||||
[icons/icon :main-icons2/contact
|
||||
{:size 12
|
||||
:no-color true
|
||||
:container-style style/icon-container}])
|
||||
(cond
|
||||
verified?
|
||||
[icons/icon :main-icons2/verified
|
||||
{:size 12
|
||||
:no-color true
|
||||
:container-style style/icon-container}]
|
||||
untrustworthy?
|
||||
[icons/icon :main-icons2/untrustworthy
|
||||
{:size 12
|
||||
:no-color true
|
||||
:container-style style/icon-container}])
|
||||
(when-not ens?
|
||||
[text/text {:monospace true
|
||||
:size :paragraph-2
|
||||
:style style/chat-key-text}
|
||||
(utils/get-shortened-address chat-key)])
|
||||
(when-not ens?
|
||||
[text/text {:monospace true
|
||||
:size :paragraph-2
|
||||
:style style/middle-dot-chat-key}
|
||||
middle-dot])
|
||||
[text/text {:monospace true
|
||||
:size :paragraph-2
|
||||
:style (style/time-text ens?)}
|
||||
time-str]]))])
|
||||
@@ -6,7 +6,7 @@
|
||||
[quo2.components.avatars.user-avatar :as user-avatar]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[utils.string :as utils]))
|
||||
[utils :as utils]))
|
||||
|
||||
(def themes-landed {:pinned colors/primary-50-opa-5
|
||||
:added colors/primary-50-opa-5
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
:icon-color-anim reanimated shared value
|
||||
"
|
||||
[{:keys [icon new-notifications? notification-indicator counter-label
|
||||
on-press pass-through? icon-color-anim accessibility-label test-ID]}]
|
||||
on-press pass-through? icon-color-anim accessibility-label]}]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [icon-animated-style (reanimated/apply-animations-to-style
|
||||
@@ -40,8 +40,7 @@
|
||||
:height 40
|
||||
:border-radius 10})]
|
||||
[rn/touchable-without-feedback
|
||||
{:test-ID test-ID
|
||||
:on-press on-press
|
||||
{:on-press on-press
|
||||
:on-press-in #(toggle-background-color background-color false pass-through?)
|
||||
:on-press-out #(toggle-background-color background-color true pass-through?)
|
||||
:accessibility-label accessibility-label}
|
||||
|
||||
@@ -14,35 +14,31 @@
|
||||
:customization-color customization-color}]))
|
||||
|
||||
(defn floating-shell-button
|
||||
"[floating-shell-button dynamic-buttons style opacity-anim pointer-anim]
|
||||
dynamic-buttons {:button-type {:on-press on-press :count count}}
|
||||
style override style
|
||||
opacity-anim reanimated value (optional)"
|
||||
([dynamic-button style]
|
||||
(floating-shell-button dynamic-button style nil))
|
||||
([dynamic-buttons style opacity-anim]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [original-style (merge {:flex-direction :row
|
||||
:margin-horizontal 12
|
||||
:pointer-events :box-none} style)
|
||||
animated-style (reanimated/apply-animations-to-style
|
||||
(if opacity-anim
|
||||
{:opacity opacity-anim} {})
|
||||
original-style)]
|
||||
[reanimated/view {:style animated-style}
|
||||
;; Left Section
|
||||
[rn/view {:style {:flex 1}}
|
||||
[dynamic-button-view :search dynamic-buttons {:position :absolute
|
||||
:right 8}]]
|
||||
;; Mid Section (jump-to)
|
||||
[dynamic-button-view :jump-to dynamic-buttons nil]
|
||||
"[floating-shell-button dynamic-buttons style]
|
||||
dynamic-buttons
|
||||
{:button-type {:on-press on-press :count count}}"
|
||||
[dynamic-buttons style opacity-anim pointer-anim]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [original-style (merge {:flex-direction :row
|
||||
:margin-horizontal 12} style)
|
||||
animated-style (reanimated/apply-animations-to-style
|
||||
{:opacity opacity-anim
|
||||
:pointer-events pointer-anim}
|
||||
original-style)]
|
||||
[reanimated/view {:style animated-style}
|
||||
;; Left Section
|
||||
[rn/view {:style {:flex 1}}
|
||||
[dynamic-button-view :search dynamic-buttons {:position :absolute
|
||||
:right 8}]]
|
||||
;; Mid Section (jump-to)
|
||||
[dynamic-button-view :jump-to dynamic-buttons nil]
|
||||
;; Right Section
|
||||
[rn/view {:style {:flex 1}}
|
||||
[rn/view {:style {:position :absolute
|
||||
:flex-direction :row
|
||||
:right 0}}
|
||||
[dynamic-button-view :mention dynamic-buttons {:margin-left 8}]
|
||||
[dynamic-button-view :notification-down dynamic-buttons {:margin-left 8}]
|
||||
[dynamic-button-view :notification-up dynamic-buttons {:margin-left 8}]
|
||||
[dynamic-button-view :bottom dynamic-buttons {:margin-left 8}]]]]))]))
|
||||
[rn/view {:style {:flex 1}}
|
||||
[rn/view {:style {:position :absolute
|
||||
:flex-direction :row
|
||||
:right 0}}
|
||||
[dynamic-button-view :mention dynamic-buttons {:margin-left 8}]
|
||||
[dynamic-button-view :notification-down dynamic-buttons {:margin-left 8}]
|
||||
[dynamic-button-view :notification-up dynamic-buttons {:margin-left 8}]
|
||||
[dynamic-button-view :bottom dynamic-buttons {:margin-left 8}]]]]))])
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[clojure.string :as string]
|
||||
[quo2.components.buttons.button :as button]
|
||||
[quo2.components.avatars.user-avatar :as user-avatar]))
|
||||
[clojure.string :as string]))
|
||||
|
||||
(def ^:private centrify-style
|
||||
{:display :flex
|
||||
@@ -14,10 +12,12 @@
|
||||
|
||||
(def ^:private align-left (assoc centrify-style :align-items :flex-start))
|
||||
|
||||
(def ^:private icon-styles (assoc centrify-style :width 32 :height 32 :border-radius 10))
|
||||
|
||||
(defn- big? [size] (= size :big))
|
||||
|
||||
(defn- icon-props [color size]
|
||||
(merge {:size 20
|
||||
(merge {:size 20
|
||||
:container-style {:width (if (big? size)
|
||||
20
|
||||
16)
|
||||
@@ -28,33 +28,34 @@
|
||||
{:color color}
|
||||
{:no-color true})))
|
||||
|
||||
(defn left-section-view [{:keys [on-press icon accessibility-label type] :or {type :grey}}
|
||||
put-middle-section-on-left?]
|
||||
(defn render-left-section [{:keys [on-press icon
|
||||
icon-color icon-background-color]}
|
||||
put-middle-section-on-left?]
|
||||
[rn/view {:style (merge
|
||||
{:accessibility-label accessibility-label}
|
||||
icon-styles
|
||||
{:background-color icon-background-color
|
||||
:width 32
|
||||
:height 32}
|
||||
(when put-middle-section-on-left? {:margin-right 5}))}
|
||||
[button/button {:on-press on-press :icon true :type type :size 32}
|
||||
icon]])
|
||||
[rn/touchable-opacity {:on-press on-press}
|
||||
[icons/icon icon (icon-props icon-color :big)]]])
|
||||
|
||||
(defn- mid-section-comp
|
||||
[{:keys [description-img description-user-icon horizontal-description?
|
||||
text-secondary-color align-mid? text-color icon main-text type description]}]
|
||||
[rn/view {:style (assoc centrify-style
|
||||
:flex-direction :row
|
||||
:margin-horizontal 2)}
|
||||
[{:keys [description-user-icon horizontal-description? text-secondary-color align-mid? text-color icon main-text type description]}]
|
||||
[rn/view {:style (assoc
|
||||
centrify-style
|
||||
:flex-direction :row
|
||||
:margin-horizontal 2)}
|
||||
(when (or (and (not horizontal-description?)
|
||||
align-mid?
|
||||
(not= :text-with-description type))
|
||||
(and (or description-img description-user-icon)
|
||||
(and description-user-icon
|
||||
(not icon)))
|
||||
(if description-img
|
||||
[rn/view {:margin-right 8}
|
||||
[description-img]]
|
||||
[rn/image {:source {:uri description-user-icon}
|
||||
:style {:width 32
|
||||
:height 32
|
||||
:border-radius 32
|
||||
:margin-right 8}}]))
|
||||
[rn/image {:source {:uri description-user-icon}
|
||||
:style {:width 32
|
||||
:height 32
|
||||
:border-radius 32
|
||||
:margin-right 8}}])
|
||||
[rn/view {:style {:flex-direction (if horizontal-description?
|
||||
:row
|
||||
:column)}}
|
||||
@@ -72,69 +73,76 @@
|
||||
horizontal-description? (assoc :margin-left 4 :margin-top 2))}
|
||||
description])]])
|
||||
|
||||
(defn- mid-section-view
|
||||
(defn- render-mid-section
|
||||
[{:keys [horizontal-description? one-icon-align-left? type left-align?
|
||||
main-text right-icon main-text-icon-color left-icon on-press avatar] :as props}]
|
||||
(let [text-color (if (colors/dark?) colors/neutral-5 colors/neutral-95)
|
||||
text-secondary-color (if (colors/dark?) colors/neutral-40 colors/neutral-50)
|
||||
main-text right-icon main-text-icon-color left-icon] :as props}]
|
||||
(let [text-color (if (colors/dark?) colors/neutral-5 colors/neutral-95)
|
||||
text-secondary-color (if (colors/dark?) colors/neutral-40 colors/neutral-50)
|
||||
component-instance [mid-section-comp (assoc props :text-secondary-color text-secondary-color)]]
|
||||
[rn/touchable-opacity {:on-press on-press}
|
||||
[rn/view {:style (merge
|
||||
(if left-align?
|
||||
align-left
|
||||
centrify-style)
|
||||
{:flex 1
|
||||
:margin-left 4
|
||||
:text-align-vertical :center})}
|
||||
(case type
|
||||
:text-only [text/text {:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:style {:color text-color}}
|
||||
main-text]
|
||||
:user-avatar [rn/view {:style (assoc centrify-style :flex-direction :row)}
|
||||
[user-avatar/user-avatar avatar]
|
||||
[text/text {:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:style {:padding-horizontal 4
|
||||
:color text-color}}
|
||||
main-text]]
|
||||
:text-with-two-icons [rn/view {:style (assoc centrify-style :flex-direction :row)}
|
||||
[icons/icon left-icon
|
||||
(icon-props main-text-icon-color :big)]
|
||||
[text/text {:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:style {:padding-horizontal 4
|
||||
:color text-color}}
|
||||
main-text]
|
||||
[icons/icon right-icon
|
||||
(icon-props main-text-icon-color :big)]]
|
||||
:text-with-one-icon [rn/view {:style {:flex-direction :row}}
|
||||
(if one-icon-align-left?
|
||||
[rn/view {:style {:flex-direction :row
|
||||
:align-items :center}}
|
||||
(when horizontal-description?
|
||||
[icons/icon left-icon
|
||||
(icon-props main-text-icon-color :big)])
|
||||
component-instance]
|
||||
[rn/view {:style {:flex-direction :row
|
||||
:align-items :center}}
|
||||
component-instance
|
||||
(when horizontal-description?
|
||||
[icons/icon left-icon
|
||||
(icon-props main-text-icon-color :big)])])]
|
||||
:text-with-description component-instance)]]))
|
||||
[rn/view {:style (merge
|
||||
(if left-align?
|
||||
align-left
|
||||
centrify-style)
|
||||
{:flex 1
|
||||
:margin-left 4
|
||||
:text-align-vertical :center})}
|
||||
(case type
|
||||
:text-only [text/text {:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:style {:color text-color}}
|
||||
main-text]
|
||||
:text-with-two-icons [rn/view {:style (assoc centrify-style :flex-direction :row)}
|
||||
[icons/icon left-icon
|
||||
(icon-props main-text-icon-color :big)]
|
||||
[text/text {:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:style {:padding-horizontal 4
|
||||
:color text-color}}
|
||||
main-text]
|
||||
|
||||
(defn- right-section-view [right-section-buttons]
|
||||
[rn/view {:style (assoc centrify-style
|
||||
:flex-direction :row
|
||||
:flex 1
|
||||
:justify-content :flex-end)}
|
||||
[icons/icon right-icon
|
||||
(icon-props main-text-icon-color :big)]]
|
||||
:text-with-one-icon [rn/view {:style {:flex-direction :row}}
|
||||
(if one-icon-align-left?
|
||||
[rn/view {:style {:flex-direction :row
|
||||
:align-items :center}}
|
||||
(when horizontal-description?
|
||||
[icons/icon left-icon
|
||||
(icon-props main-text-icon-color :big)])
|
||||
component-instance]
|
||||
[rn/view {:style {:flex-direction :row
|
||||
:align-items :center}}
|
||||
component-instance
|
||||
(when horizontal-description?
|
||||
[icons/icon left-icon
|
||||
(icon-props main-text-icon-color :big)])])]
|
||||
:text-with-description component-instance)]))
|
||||
|
||||
(defn- right-section-icon
|
||||
[{:keys [background-color icon icon-color push-to-the-left?] :or {push-to-the-left? false}}]
|
||||
[rn/view {:style (assoc
|
||||
icon-styles
|
||||
:background-color background-color
|
||||
:width 32
|
||||
:height 32
|
||||
:margin-right (if push-to-the-left? 8 0))}
|
||||
[icons/icon icon (icon-props icon-color :big)]])
|
||||
|
||||
(defn- render-right-section [right-section-buttons]
|
||||
[rn/view {:style (assoc
|
||||
centrify-style
|
||||
:flex-direction :row
|
||||
:flex 1
|
||||
:justify-content :flex-end)}
|
||||
(let [last-icon-index (-> right-section-buttons count dec)]
|
||||
(map-indexed (fn [index {:keys [icon on-press type] :or {type :grey}}]
|
||||
(map-indexed (fn [index {:keys [icon background-color icon-color on-press]}]
|
||||
^{:key index}
|
||||
[rn/view {:style {:margin-right (if (not= index last-icon-index) 8 0)}}
|
||||
[button/button {:on-press on-press :icon true :type type :size 32}
|
||||
icon]])
|
||||
[rn/touchable-opacity {:on-press on-press}
|
||||
[right-section-icon
|
||||
{:icon icon
|
||||
:background-color background-color
|
||||
:icon-color icon-color
|
||||
:push-to-the-left? (not= index last-icon-index)}]])
|
||||
right-section-buttons))])
|
||||
|
||||
(defn page-nav
|
||||
@@ -146,7 +154,7 @@
|
||||
:page-nav-color color
|
||||
:page-nav-background-uri image-uri
|
||||
:mid-section
|
||||
{:type one-of :text-only :text-with-two-icons :text-with-one-icon :text-with-description :user-avatar
|
||||
{:type one-of :text-only :text-with-two-icons :text-with-one-icon :text-with-description
|
||||
:icon icon
|
||||
:main-text string
|
||||
:left-icon icon
|
||||
@@ -155,19 +163,16 @@
|
||||
:description-color color
|
||||
:description-icon icon
|
||||
:description-user-icon icon
|
||||
:description-img a render prop which will be used in place of :description-user-icon
|
||||
:main-text-icon-color color
|
||||
}
|
||||
:left-section
|
||||
{:type button-type
|
||||
:on-press event
|
||||
{:on-press event
|
||||
:icon icon
|
||||
:icon-color color
|
||||
:icon-background-color color
|
||||
}
|
||||
:right-section-buttons vector of
|
||||
{:type button-type
|
||||
:on-press event
|
||||
{:on-press event
|
||||
:icon icon
|
||||
:icon-color color
|
||||
:icon-background-color color
|
||||
@@ -184,35 +189,32 @@
|
||||
mid-section-props
|
||||
{:type (:type mid-section)
|
||||
:horizontal-description? horizontal-description?
|
||||
:description-img (:description-img mid-section)
|
||||
:main-text (:main-text mid-section)
|
||||
:main-text-icon-color (:main-text-icon-color mid-section)
|
||||
:one-icon-align-left? one-icon-align-left?
|
||||
:right-icon (:right-icon mid-section)
|
||||
:icon (:icon mid-section)
|
||||
:left-icon (:left-icon mid-section)
|
||||
:avatar (:avatar mid-section)}]
|
||||
:left-icon (:left-icon mid-section)}]
|
||||
[rn/view {:style (cond-> {:display :flex
|
||||
:flex-direction :row
|
||||
;; iPhone 11 Pro's height in Figma divided by Component height 56/1125
|
||||
:align-items :center
|
||||
:padding-horizontal 20
|
||||
:height 56
|
||||
:justify-content :space-between}
|
||||
page-nav-background-uri (assoc :background-color page-nav-color)
|
||||
page-nav-color (assoc :background page-nav-background-uri))}
|
||||
[rn/view {:style {:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center}}
|
||||
[left-section-view left-section put-middle-section-on-left?]
|
||||
(render-left-section left-section put-middle-section-on-left?)
|
||||
(when put-middle-section-on-left?
|
||||
[mid-section-view (assoc mid-section-props
|
||||
:left-align? true
|
||||
:description (:description mid-section)
|
||||
:description-color (:description-color mid-section)
|
||||
:description-icon (:description-icon mid-section)
|
||||
:align-mid? align-mid?
|
||||
:description-user-icon (:description-user-icon mid-section))])]
|
||||
[render-mid-section (assoc mid-section-props
|
||||
:left-align? true
|
||||
:description (:description mid-section)
|
||||
:description-color (:description-color mid-section)
|
||||
:description-icon (:description-icon mid-section)
|
||||
:align-mid? align-mid?
|
||||
:description-user-icon (:description-user-icon mid-section))])]
|
||||
(when-not put-middle-section-on-left?
|
||||
[mid-section-view mid-section-props])
|
||||
[right-section-view right-section-buttons]]))
|
||||
[render-mid-section mid-section-props])
|
||||
(render-right-section right-section-buttons)]))
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
(ns quo2.components.navigation.top-nav
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.counter.counter :as counter]
|
||||
[quo2.components.buttons.button :as quo2.button]
|
||||
[quo2.components.avatars.user-avatar :as user-avatar]
|
||||
[react-native.hole-view :as hole-view]))
|
||||
|
||||
(defn- get-button-common-props [type]
|
||||
(let [default? (= type :default)
|
||||
dark? (colors/dark?)]
|
||||
{:icon true
|
||||
:size 32
|
||||
:style {:margin-left 12}
|
||||
:type (if default?
|
||||
(if dark? :grey :dark-grey)
|
||||
type)
|
||||
:override-background-color (when (and dark? default?)
|
||||
colors/neutral-90)}))
|
||||
|
||||
(defn- base-button [icon on-press accessibility-label button-common-props]
|
||||
[quo2.button/button
|
||||
(merge
|
||||
{:on-press on-press
|
||||
:accessibility-label accessibility-label}
|
||||
button-common-props)
|
||||
icon])
|
||||
|
||||
(defn top-nav
|
||||
"[top-nav opts]
|
||||
opts
|
||||
{:type :default/:blurred/:shell
|
||||
:new-notifications? true/false
|
||||
:notification-indicator :unread-dot/:counter
|
||||
:open-profile fn
|
||||
:open-search fn
|
||||
:open-scanner fn
|
||||
:show-qr fn
|
||||
:open-activity-center fn
|
||||
:style override-style
|
||||
:avatar user-avatar
|
||||
:counter-label number}
|
||||
"
|
||||
[{:keys [type new-notifications? notification-indicator open-profile open-search
|
||||
open-scanner show-qr open-activity-center style avatar counter-label]}]
|
||||
(let [button-common-props (get-button-common-props type)]
|
||||
[rn/view {:style (merge
|
||||
{:height 56}
|
||||
style)}
|
||||
;; Left Section
|
||||
[rn/touchable-without-feedback {:on-press open-profile}
|
||||
[rn/view {:style {:position :absolute
|
||||
:left 20
|
||||
:top 12}}
|
||||
[user-avatar/user-avatar
|
||||
(merge
|
||||
{:ring? true
|
||||
:status-indicator? true
|
||||
:size :small}
|
||||
avatar)]]]
|
||||
;; Right Section
|
||||
[rn/view {:style {:position :absolute
|
||||
:right 20
|
||||
:top 12
|
||||
:flex-direction :row}}
|
||||
[base-button :i/search open-search :open-search-button button-common-props]
|
||||
[base-button :i/scan open-scanner :open-scanner-button button-common-props]
|
||||
[base-button :i/qr-code show-qr :show-qr-button button-common-props]
|
||||
[rn/view ;; Keep view instead of "[:<>" to make sure relative
|
||||
;; position is calculated from this view instead of its parent
|
||||
[hole-view/hole-view {:key new-notifications? ;; Key is required to force removal of holes
|
||||
:holes (cond
|
||||
(not new-notifications?) ;; No new notifications, remove holes
|
||||
[]
|
||||
|
||||
(= notification-indicator :unread-dot)
|
||||
[{:x 37 :y -3 :width 10 :height 10 :borderRadius 5}]
|
||||
|
||||
:else
|
||||
[{:x 33 :y -7 :width 18 :height 18 :borderRadius 7}])}
|
||||
[base-button :i/activity-center open-activity-center
|
||||
:open-activity-center-button button-common-props]]
|
||||
(when new-notifications?
|
||||
(if (= notification-indicator :counter)
|
||||
[counter/counter {:outline false
|
||||
:override-text-color colors/white
|
||||
:override-bg-color colors/primary-50
|
||||
:style {:position :absolute
|
||||
:left 34
|
||||
:top -6}}
|
||||
counter-label]
|
||||
[rn/view {:style {:width 8
|
||||
:height 8
|
||||
:border-radius 4
|
||||
:top -2
|
||||
:left 38
|
||||
:position :absolute
|
||||
:background-color colors/primary-50}}]))]]]))
|
||||
@@ -1,76 +0,0 @@
|
||||
(ns quo2.components.notifications.activity-log.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def container
|
||||
{:flex-direction :row
|
||||
:flex-grow 1
|
||||
:align-items :flex-start
|
||||
:padding-top 8
|
||||
:padding-horizontal 12
|
||||
:padding-bottom 12})
|
||||
|
||||
(def icon
|
||||
{:height 32
|
||||
:width 32
|
||||
:border-radius 100
|
||||
:margin-top 10
|
||||
:border-width 1
|
||||
:border-color colors/white-opa-5
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(def message-title
|
||||
{:color colors/white-opa-40
|
||||
:margin-bottom 2})
|
||||
|
||||
(def message-body
|
||||
{:color colors/white})
|
||||
|
||||
(def message-container
|
||||
{:border-radius 12
|
||||
:margin-top 12
|
||||
:padding-horizontal 12
|
||||
:padding-vertical 8
|
||||
:background-color colors/white-opa-5})
|
||||
|
||||
(def buttons-container
|
||||
{:margin-top 12
|
||||
:flex-direction :row
|
||||
:align-items :flex-start})
|
||||
|
||||
(def status
|
||||
{:margin-top 12
|
||||
:align-items :flex-start
|
||||
:flex 1})
|
||||
|
||||
(defn title [replying?]
|
||||
{:color colors/white
|
||||
:flex-shrink 1
|
||||
:max-width (when-not replying? "60%")})
|
||||
|
||||
(def timestamp
|
||||
{:text-transform :none
|
||||
:flex-grow 1
|
||||
:margin-left 8
|
||||
:color colors/neutral-40})
|
||||
|
||||
(def unread-dot
|
||||
{:background-color colors/primary-50
|
||||
:border-radius 4
|
||||
:width 8
|
||||
:height 8})
|
||||
|
||||
(def unread-dot-container
|
||||
{:margin-left 8
|
||||
:padding-horizontal 12
|
||||
:padding-vertical 7})
|
||||
|
||||
(def context-container
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :flex-start
|
||||
:flex-wrap :wrap})
|
||||
|
||||
(def top-section-container
|
||||
{:align-items :center
|
||||
:flex-direction :row})
|
||||
@@ -1,178 +0,0 @@
|
||||
(ns quo2.components.notifications.activity-log.view
|
||||
(:require [clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo2.components.buttons.button :as button]
|
||||
[quo2.components.icon :as icon]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.tags.status-tags :as status-tags]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.notifications.activity-log.style :as style]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.i18n.i18n :as i18n]))
|
||||
|
||||
(def ^:private max-reply-length
|
||||
280)
|
||||
|
||||
(defn- valid-reply?
|
||||
[reply]
|
||||
(<= (count reply) max-reply-length))
|
||||
|
||||
(defn- activity-reply-text-input
|
||||
[reply-input on-update-reply]
|
||||
[rn/view
|
||||
[rn/view {:style {:margin-top 16
|
||||
:margin-bottom 8
|
||||
:flex-direction :row}}
|
||||
[text/text {:weight :medium
|
||||
:style {:flex-grow 1
|
||||
:color colors/neutral-40}}
|
||||
(i18n/label :t/your-answer)]
|
||||
[text/text {:style {:flex-shrink 1
|
||||
:color (if (valid-reply? @reply-input)
|
||||
colors/neutral-40
|
||||
colors/danger-60)}}
|
||||
(str (count @reply-input) "/" max-reply-length)]]
|
||||
[rn/view
|
||||
;; TODO(@ilmotta): Replace with quo2 component when available.
|
||||
;; https://github.com/status-im/status-mobile/issues/14364
|
||||
[quo/text-input
|
||||
{:on-change-text #(do (reset! reply-input %)
|
||||
(when on-update-reply
|
||||
(on-update-reply %)))
|
||||
:auto-capitalize :none
|
||||
:auto-focus true
|
||||
:accessibility-label :identity-verification-reply-text-input
|
||||
:placeholder (i18n/label :t/type-something)
|
||||
:return-key-type :none
|
||||
:multiline false
|
||||
:auto-correct false}]]])
|
||||
|
||||
(defn- activity-icon
|
||||
[icon]
|
||||
[rn/view {:style style/icon}
|
||||
[icon/icon icon {:color colors/white}]])
|
||||
|
||||
(defn- activity-context
|
||||
[context replying?]
|
||||
(let [first-line-offset (if replying? 4 0)
|
||||
gap-between-lines 4]
|
||||
(into [rn/view {:style (assoc style/context-container :margin-top first-line-offset)}]
|
||||
(mapcat (fn [detail]
|
||||
^{:key (hash detail)}
|
||||
(if (string? detail)
|
||||
(map (fn [s]
|
||||
[rn/view {:style {:margin-right 4
|
||||
:margin-top 0}}
|
||||
[text/text {:size :paragraph-2}
|
||||
s]])
|
||||
(string/split detail #"\s+"))
|
||||
[[rn/view {:margin-right 4
|
||||
:margin-top gap-between-lines}
|
||||
detail]]))
|
||||
context))))
|
||||
|
||||
(defn- activity-message
|
||||
[{:keys [title body]}]
|
||||
[rn/view {:style style/message-container}
|
||||
(when title
|
||||
[text/text {:size :paragraph-2
|
||||
:accessibility-label :activity-message-title
|
||||
:style style/message-title}
|
||||
title])
|
||||
(if (string? body)
|
||||
[text/text {:style style/message-body
|
||||
:accessibility-label :activity-message-body
|
||||
:size :paragraph-1}
|
||||
body]
|
||||
body)])
|
||||
|
||||
(defn- activity-buttons
|
||||
[button-1 button-2 replying? reply-input]
|
||||
(let [size (if replying? 40 24)
|
||||
common-style (when replying?
|
||||
{:padding-vertical 9
|
||||
:flex-grow 1
|
||||
:flex-basis 0})]
|
||||
[rn/view style/buttons-container
|
||||
(when button-1
|
||||
[button/button (-> button-1
|
||||
(assoc :size size)
|
||||
(update :style merge common-style {:margin-right 8}))
|
||||
(:label button-1)])
|
||||
(when button-2
|
||||
[button/button (-> button-2
|
||||
(assoc :size size)
|
||||
(assoc :disabled (and replying? (not (valid-reply? @reply-input))))
|
||||
(update :style merge common-style))
|
||||
(:label button-2)])]))
|
||||
|
||||
(defn- activity-status
|
||||
[status]
|
||||
[rn/view {:style style/status
|
||||
:accessibility-label :activity-status}
|
||||
[status-tags/status-tag {:size :small
|
||||
:label (:label status)
|
||||
:status status}]])
|
||||
|
||||
(defn- activity-title
|
||||
[title replying?]
|
||||
[text/text {:weight :semi-bold
|
||||
:accessibility-label :activity-title
|
||||
:style (style/title replying?)
|
||||
:size (if replying? :heading-2 :paragraph-1)}
|
||||
title])
|
||||
|
||||
(defn- activity-timestamp
|
||||
[timestamp]
|
||||
[text/text {:size :label
|
||||
:accessibility-label :activity-timestamp
|
||||
:style style/timestamp}
|
||||
timestamp])
|
||||
|
||||
(defn- activity-unread-dot
|
||||
[]
|
||||
[rn/view {:accessibility-label :activity-unread-indicator
|
||||
:style style/unread-dot-container}
|
||||
[rn/view {:style style/unread-dot}]])
|
||||
|
||||
(defn- footer
|
||||
[_]
|
||||
(let [reply-input (reagent/atom "")]
|
||||
(fn [{:keys [replying? on-update-reply status button-1 button-2]}]
|
||||
[:<>
|
||||
(when replying?
|
||||
[activity-reply-text-input reply-input on-update-reply])
|
||||
(cond (some? status)
|
||||
[activity-status status]
|
||||
|
||||
(or button-1 button-2)
|
||||
[activity-buttons button-1 button-2 replying? reply-input])])))
|
||||
|
||||
(defn view
|
||||
[{:keys [icon
|
||||
message
|
||||
context
|
||||
timestamp
|
||||
title
|
||||
replying?
|
||||
unread?]
|
||||
:as props}]
|
||||
[rn/view {:accessibility-label :activity
|
||||
:style style/container}
|
||||
(when-not replying?
|
||||
[activity-icon icon])
|
||||
[rn/view {:style {:padding-left (when-not replying? 8)
|
||||
:flex 1}}
|
||||
[rn/view
|
||||
[rn/view {:style style/top-section-container}
|
||||
[activity-title title replying?]
|
||||
(when-not replying?
|
||||
[activity-timestamp timestamp])
|
||||
(when (and unread? (not replying?))
|
||||
[activity-unread-dot])]
|
||||
(when context
|
||||
[activity-context context replying?])]
|
||||
(when message
|
||||
[activity-message message])
|
||||
[footer props]]])
|
||||
@@ -0,0 +1,157 @@
|
||||
(ns quo2.components.notifications.activity-logs
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.components.buttons.button :as button]
|
||||
[quo2.components.icon :as icon]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.tags.status-tags :as status-tags]
|
||||
[quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn- activity-icon
|
||||
[icon]
|
||||
[rn/view {:height 32
|
||||
:width 32
|
||||
:border-radius 100
|
||||
:margin-top 10
|
||||
:border-width 1
|
||||
:border-color colors/white-opa-5
|
||||
:flex-direction :column
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
[icon/icon icon {:color colors/white}]])
|
||||
|
||||
(defn- activity-unread-dot
|
||||
[]
|
||||
[rn/view {:margin-left 14
|
||||
:margin-right 6
|
||||
:background-color colors/primary-50
|
||||
:width 8
|
||||
:height 8
|
||||
:border-radius 4}])
|
||||
|
||||
(defn- activity-context
|
||||
[context]
|
||||
(let [margin-top 4]
|
||||
(into [rn/view {:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:flex-wrap :wrap
|
||||
:margin-top (+ 4 (- margin-top))}]
|
||||
(map-indexed (fn [index detail]
|
||||
^{:key index}
|
||||
[rn/view {:margin-right 4
|
||||
:margin-top margin-top}
|
||||
(if (string? detail)
|
||||
[text/text {:size :paragraph-2}
|
||||
detail]
|
||||
detail)])
|
||||
context))))
|
||||
|
||||
(defn- activity-message
|
||||
[{:keys [title body]}]
|
||||
[rn/view {:border-radius 12
|
||||
:margin-top 12
|
||||
:padding-horizontal 12
|
||||
:padding-vertical 8
|
||||
:background-color colors/white-opa-5
|
||||
:flex 1
|
||||
:flex-direction :column}
|
||||
(when title
|
||||
[text/text {:size :paragraph-2
|
||||
:style {:color colors/white-opa-40}}
|
||||
title])
|
||||
(if (string? body)
|
||||
[text/text {:style {:color colors/white}
|
||||
:size :paragraph-1}
|
||||
body]
|
||||
body)])
|
||||
|
||||
(defn- activity-buttons
|
||||
[button-1 button-2]
|
||||
(let [size 24
|
||||
common-style {:padding-top 3
|
||||
:padding-right 8
|
||||
:padding-bottom 4
|
||||
:padding-left 8}]
|
||||
[rn/view {:margin-top 12
|
||||
:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :flex-start}
|
||||
(when button-1
|
||||
[button/button (-> button-1
|
||||
(assoc :size size)
|
||||
(assoc-in [:style :margin-right] 8)
|
||||
(update :style merge common-style))
|
||||
(:label button-1)])
|
||||
(when button-2
|
||||
[button/button (-> button-2
|
||||
(assoc :size size)
|
||||
(update :style merge common-style))
|
||||
(:label button-2)])]))
|
||||
|
||||
(defn- activity-status
|
||||
[status]
|
||||
[rn/view {:margin-top 12
|
||||
:align-items :flex-start
|
||||
:flex 1}
|
||||
[status-tags/status-tag {:size :small
|
||||
:label (:label status)
|
||||
:status status}]])
|
||||
|
||||
(defn- activity-title
|
||||
[title]
|
||||
[text/text {:weight :semi-bold
|
||||
:style {:color colors/white}
|
||||
:size :paragraph-1}
|
||||
title])
|
||||
|
||||
(defn- activity-timestamp
|
||||
[timestamp]
|
||||
[rn/view {:margin-left 8}
|
||||
[text/text {:size :label
|
||||
:style {:text-transform :none
|
||||
:color colors/neutral-40}}
|
||||
timestamp]])
|
||||
|
||||
(defn activity-log
|
||||
[{:keys [button-1
|
||||
button-2
|
||||
icon
|
||||
message
|
||||
status
|
||||
context
|
||||
timestamp
|
||||
title
|
||||
unread?]}]
|
||||
[rn/view {:flex-direction :row
|
||||
:flex 1
|
||||
:border-radius 16
|
||||
:padding-top 8
|
||||
:padding-horizontal 12
|
||||
:padding-bottom 12
|
||||
:background-color (when unread?
|
||||
colors/primary-50-opa-10)}
|
||||
[activity-icon icon]
|
||||
[rn/view {:flex-direction :column
|
||||
:padding-left 8
|
||||
:flex 1}
|
||||
[rn/view {:flex 1
|
||||
:align-items :center
|
||||
:flex-direction :row}
|
||||
[rn/view {:flex 1
|
||||
:align-items :center
|
||||
:flex-direction :row}
|
||||
[rn/view {:flex-shrink 1}
|
||||
[activity-title title]]
|
||||
[activity-timestamp timestamp]]
|
||||
(when unread?
|
||||
[activity-unread-dot])]
|
||||
(when context
|
||||
[activity-context context])
|
||||
(when message
|
||||
[activity-message message])
|
||||
(cond
|
||||
(some? status)
|
||||
[activity-status status]
|
||||
|
||||
(or button-1 button-2)
|
||||
[activity-buttons button-1 button-2])]])
|
||||
@@ -10,8 +10,6 @@
|
||||
:position :absolute
|
||||
:right 22
|
||||
:border-radius 6
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color (colors/theme-colors colors/primary-50 colors/primary-60)}
|
||||
style)}
|
||||
[rn/text {:style (merge typography/font-medium typography/label {:color colors/white :text-align :center})} count]]))
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
(ns quo2.components.selectors.--tests--.selectors-component-spec
|
||||
(:require ["@testing-library/react-native" :as rtl]
|
||||
[quo2.components.selectors.selectors :as selectors]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn render-toggle
|
||||
([]
|
||||
(rtl/render (reagent/as-element [selectors/toggle {:disabled? (:disabled? false)}]))))
|
||||
|
||||
(js/global.test "default render of toggle component"
|
||||
(fn []
|
||||
(render-toggle)
|
||||
(-> (js/expect (rtl/screen.getByTestId "toggle-component"))
|
||||
(.toBeTruthy))))
|
||||
@@ -133,8 +133,7 @@
|
||||
:border-radius 20
|
||||
:background-color (get-color @checked? disabled? blurred-background?)})
|
||||
:accessibility-label (str "toggle-" (if @checked? "on" "off"))
|
||||
:accessibility-role :checkbox
|
||||
:testID "toggle-component"}
|
||||
:accessibility-role :checkbox}
|
||||
[rn/view {:style
|
||||
{:margin-left (if @checked? 12 2)
|
||||
:height 16
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
[react-native.core :as rn]
|
||||
[quo2.components.tabs.tab :as tab]
|
||||
[reagent.core :as reagent]
|
||||
[utils.number :as utils.number]
|
||||
[utils.collection :as utils.collection]
|
||||
[utils :as utils]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.notifications.notification-dot :refer [notification-dot]]
|
||||
[react-native.masked-view :as masked-view]
|
||||
@@ -12,29 +11,26 @@
|
||||
|
||||
(def default-tab-size 32)
|
||||
|
||||
(defn indicator []
|
||||
[rn/view {:position :absolute
|
||||
:z-index 1
|
||||
:right -2
|
||||
:top -2
|
||||
:width 10
|
||||
:height 10
|
||||
:border-radius 5
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color (colors/theme-colors colors/neutral-5 colors/neutral-95)}
|
||||
[notification-dot]])
|
||||
|
||||
(defn tabs [{:keys [default-active on-change style]}]
|
||||
(let [active-tab-id (reagent/atom default-active)]
|
||||
(fn [{:keys [data size] :or {size default-tab-size}}]
|
||||
[rn/view (merge {:flex-direction :row} style)
|
||||
(doall
|
||||
(for [{:keys [label id notification-dot? accessibility-label]} data]
|
||||
(for [{:keys [label id new-info accessibility-label]} data]
|
||||
^{:key id}
|
||||
[rn/view {:style {:margin-right (if (= size default-tab-size) 12 8)}}
|
||||
(when notification-dot?
|
||||
[indicator])
|
||||
(when new-info
|
||||
[rn/view {:position :absolute
|
||||
:z-index 1
|
||||
:right -2
|
||||
:top -2
|
||||
:width 10
|
||||
:height 10
|
||||
:border-radius 5
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color (colors/theme-colors colors/neutral-5 colors/neutral-95)}
|
||||
[notification-dot]])
|
||||
[tab/tab
|
||||
{:id id
|
||||
:size size
|
||||
@@ -54,7 +50,7 @@
|
||||
;; Truncate to avoid unnecessary rendering.
|
||||
(if (> fade-percentage 0.99)
|
||||
0.99
|
||||
(utils.number/naive-round fade-percentage 2))))
|
||||
(utils/naive-round fade-percentage 2))))
|
||||
|
||||
(defn scrollable-tabs
|
||||
"Just like the component `tabs`, displays horizontally scrollable tabs with
|
||||
@@ -124,7 +120,7 @@
|
||||
:scroll-on-press?
|
||||
:size)
|
||||
(when scroll-on-press?
|
||||
{:initial-scroll-index (utils.collection/first-index #(= @active-tab-id (:id %)) data)})
|
||||
{:initial-scroll-index (utils/first-index #(= @active-tab-id (:id %)) data)})
|
||||
{:ref #(reset! flat-list-ref %)
|
||||
:extra-data (str @active-tab-id)
|
||||
:horizontal true
|
||||
|
||||
@@ -104,12 +104,11 @@
|
||||
|
||||
(defn tag
|
||||
[_ _]
|
||||
(fn [{:keys [locked tokens size background-color on-press]
|
||||
(fn [{:keys [locked tokens size background-color]
|
||||
:or {size 24}}]
|
||||
[base-tag/base-tag {:background-color background-color
|
||||
:size size
|
||||
:type :permission
|
||||
:on-press on-press}
|
||||
:type :permission}
|
||||
[rn/view {:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :flex-end}
|
||||
|
||||
@@ -28,18 +28,12 @@
|
||||
quo2.components.messages.gap
|
||||
quo2.components.messages.system-message
|
||||
quo2.components.reactions.reaction
|
||||
quo2.components.notifications.activity-log.view
|
||||
quo2.components.notifications.activity-logs
|
||||
quo2.components.notifications.info-count
|
||||
quo2.components.notifications.notification-dot
|
||||
quo2.components.tags.tags
|
||||
quo2.components.tags.context-tags
|
||||
quo2.components.tabs.tabs
|
||||
quo2.components.tabs.account-selector
|
||||
quo2.components.navigation.floating-shell-button
|
||||
quo2.components.tags.status-tags
|
||||
quo2.components.navigation.page-nav
|
||||
quo2.components.selectors.disclaimer
|
||||
quo2.components.selectors.selectors))
|
||||
quo2.components.tabs.account-selector))
|
||||
|
||||
(def button quo2.components.buttons.button/button)
|
||||
(def dynamic-button quo2.components.buttons.dynamic-button/dynamic-button)
|
||||
@@ -56,17 +50,10 @@
|
||||
(def system-message quo2.components.messages.system-message/system-message)
|
||||
(def reaction quo2.components.reactions.reaction/reaction)
|
||||
(def tags quo2.components.tags.tags/tags)
|
||||
(def user-avatar-tag quo2.components.tags.context-tags/user-avatar-tag)
|
||||
(def context-tag quo2.components.tags.context-tags/context-tag)
|
||||
(def group-avatar-tag quo2.components.tags.context-tags/group-avatar-tag)
|
||||
(def tabs quo2.components.tabs.tabs/tabs)
|
||||
(def scrollable-tabs quo2.components.tabs.tabs/scrollable-tabs)
|
||||
(def account-selector quo2.components.tabs.account-selector/account-selector)
|
||||
(def floating-shell-button quo2.components.navigation.floating-shell-button/floating-shell-button)
|
||||
(def status-tag quo2.components.tags.status-tags/status-tag)
|
||||
(def page-nav quo2.components.navigation.page-nav/page-nav)
|
||||
(def disclaimer quo2.components.selectors.disclaimer/disclaimer)
|
||||
(def checkbox quo2.components.selectors.selectors/checkbox)
|
||||
|
||||
;;;; AVATAR
|
||||
(def account-avatar quo2.components.avatars.account-avatar/account-avatar)
|
||||
(def channel-avatar quo2.components.avatars.channel-avatar/channel-avatar)
|
||||
@@ -83,7 +70,6 @@
|
||||
(def community-stats quo2.components.community.community-view/community-stats)
|
||||
(def community-tags quo2.components.community.community-view/community-tags)
|
||||
(def community-title quo2.components.community.community-view/community-title)
|
||||
(def permission-tag-container quo2.components.community.community-view/permission-tag-container)
|
||||
(def discover-card quo2.components.community.discover-card/discover-card)
|
||||
|
||||
;;;; DIVIDERS
|
||||
@@ -96,6 +82,6 @@
|
||||
(def preview-list quo2.components.list-items.preview-list/preview-list)
|
||||
|
||||
;;;; NOTIFICATIONS
|
||||
(def activity-log quo2.components.notifications.activity-log.view/view)
|
||||
(def activity-log quo2.components.notifications.activity-logs/activity-log)
|
||||
(def info-count quo2.components.notifications.info-count/info-count)
|
||||
(def notification-dot quo2.components.notifications.notification-dot/notification-dot)
|
||||
(def notification-dot quo2.components.notifications.notification-dot/notification-dot)
|
||||
@@ -1,2 +0,0 @@
|
||||
(ns quo2.core-spec
|
||||
(:require [quo2.components.selectors.--tests--.selectors-component-spec]))
|
||||
@@ -1,19 +1,15 @@
|
||||
(ns react-native.core
|
||||
(:require [reagent.core :as reagent]
|
||||
["react-native" :as react-native]
|
||||
["@react-native-community/blur" :as blur]
|
||||
[react-native.flat-list :as flat-list]
|
||||
[react-native.section-list :as section-list]
|
||||
[react-native.platform :as platform]))
|
||||
[react-native.flat-list :as flat-list]))
|
||||
|
||||
(def app-state ^js (.-AppState ^js react-native))
|
||||
(def blur-view (reagent/adapt-react-class (.-BlurView blur)))
|
||||
|
||||
(def view (reagent/adapt-react-class (.-View ^js react-native)))
|
||||
(def scroll-view (reagent/adapt-react-class (.-ScrollView ^js react-native)))
|
||||
(def image (reagent/adapt-react-class (.-Image ^js react-native)))
|
||||
(def text (reagent/adapt-react-class (.-Text ^js react-native)))
|
||||
(def text-input (reagent/adapt-react-class (.-TextInput ^js react-native)))
|
||||
(def text-input (reagent/adapt-react-class (.-TextInput ^js react-native)))
|
||||
|
||||
(def touchable-opacity (reagent/adapt-react-class (.-TouchableOpacity ^js react-native)))
|
||||
(def touchable-highlight (reagent/adapt-react-class (.-TouchableHighlight ^js react-native)))
|
||||
@@ -21,8 +17,6 @@
|
||||
|
||||
(def flat-list flat-list/flat-list)
|
||||
|
||||
(def section-list section-list/section-list)
|
||||
|
||||
(def activity-indicator (reagent/adapt-react-class (.-ActivityIndicator ^js react-native)))
|
||||
|
||||
(def modal (reagent/adapt-react-class (.-Modal ^js react-native)))
|
||||
@@ -54,19 +48,3 @@
|
||||
|
||||
(defn get-window []
|
||||
(js->clj (.get (.-Dimensions ^js react-native) "window") :keywordize-keys true))
|
||||
|
||||
(def status-bar (.-StatusBar ^js react-native))
|
||||
|
||||
(defn hw-back-add-listener [callback]
|
||||
(.addEventListener (.-BackHandler ^js react-native) "hardwareBackPress" callback))
|
||||
|
||||
(defn hw-back-remove-listener [callback]
|
||||
(.removeEventListener (.-BackHandler ^js react-native) "hardwareBackPress" callback))
|
||||
|
||||
(def keyboard-avoiding-view-class (reagent/adapt-react-class (.-KeyboardAvoidingView react-native)))
|
||||
|
||||
(defn keyboard-avoiding-view [props & children]
|
||||
(into [keyboard-avoiding-view-class
|
||||
(merge (when platform/ios? {:behavior :padding})
|
||||
props)]
|
||||
children))
|
||||
|
||||
@@ -27,9 +27,6 @@
|
||||
(defn show-overlay [comp]
|
||||
(.showOverlay Navigation (clj->js comp)))
|
||||
|
||||
(defn pop-to-root [tab]
|
||||
(.popToRoot Navigation (clj->js tab)))
|
||||
|
||||
(defn dissmiss-overlay [comp]
|
||||
(.catch (.dismissOverlay Navigation comp) #()))
|
||||
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
(:require ["react-native" :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[clojure.string :as string]
|
||||
["react-native-linear-gradient" :default LinearGradient]
|
||||
["react-native-reanimated" :default reanimated
|
||||
:refer (useSharedValue useAnimatedStyle withTiming withDelay withSpring withRepeat Easing Keyframe)]))
|
||||
:refer (useSharedValue useAnimatedStyle withTiming withDelay withSpring Easing Keyframe)]))
|
||||
|
||||
;; Animated Components
|
||||
(def create-animated-component (comp reagent/adapt-react-class (.-createAnimatedComponent reanimated)))
|
||||
@@ -13,8 +12,6 @@
|
||||
(def image (reagent/adapt-react-class (.-Image reanimated)))
|
||||
(def touchable-opacity (create-animated-component (.-TouchableOpacity ^js rn)))
|
||||
|
||||
(def linear-gradient (create-animated-component LinearGradient))
|
||||
|
||||
;; Hooks
|
||||
(def use-shared-value useSharedValue)
|
||||
(def use-animated-style useAnimatedStyle)
|
||||
@@ -24,7 +21,6 @@
|
||||
(def with-delay withDelay)
|
||||
(def with-spring withSpring)
|
||||
(def key-frame Keyframe)
|
||||
(def with-repeat withRepeat)
|
||||
|
||||
;; Easings
|
||||
(def bezier (.-bezier ^js Easing))
|
||||
@@ -72,7 +68,3 @@
|
||||
(defn animate-shared-value-with-delay [anim val duration easing delay]
|
||||
(set-shared-value anim (with-delay delay (with-timing val (js-obj "duration" duration
|
||||
"easing" (get easings easing))))))
|
||||
|
||||
(defn animate-shared-value-with-repeat [anim val duration easing number-of-repetitions reverse?]
|
||||
(set-shared-value anim (with-repeat (with-timing val (js-obj "duration" duration
|
||||
"easing" (get easings easing))) number-of-repetitions reverse?)))
|
||||
@@ -1,40 +0,0 @@
|
||||
(ns react-native.section-list
|
||||
(:require [reagent.core :as reagent]
|
||||
[react-native.flat-list :as flat-list]
|
||||
["react-native" :as react-native]))
|
||||
|
||||
(def section-list-class (reagent/adapt-react-class (.-SectionList react-native)))
|
||||
|
||||
(def memo-wrap-render-fn
|
||||
(memoize
|
||||
(fn [f render-data]
|
||||
(fn [^js data]
|
||||
(reagent/as-element [f (.-item data) (.-index data) (.-separators data) render-data])))))
|
||||
|
||||
(defn- wrap-render-section-header-fn [f]
|
||||
(fn [^js data]
|
||||
(let [^js section (.-section data)]
|
||||
(reagent/as-element [f {:title (.-title section)
|
||||
:data (.-data section)}]))))
|
||||
|
||||
(defn- wrap-per-section-render-fn [props]
|
||||
(update
|
||||
(if-let [f (:render-fn props)]
|
||||
(assoc (dissoc props :render-fn :render-data) :renderItem (memo-wrap-render-fn f (:render-data props)))
|
||||
props)
|
||||
:data to-array))
|
||||
|
||||
(defn section-list
|
||||
"A wrapper for SectionList.
|
||||
To render something on empty sections, use renderSectionFooter and conditionaly
|
||||
render on empty data
|
||||
See https://facebook.github.io/react-native/docs/sectionlist.html"
|
||||
[{:keys [sections render-section-header-fn render-section-footer-fn style] :as props}]
|
||||
[section-list-class
|
||||
(merge (flat-list/base-list-props props)
|
||||
props
|
||||
(when render-section-footer-fn
|
||||
{:renderSectionFooter (wrap-render-section-header-fn render-section-footer-fn)})
|
||||
{:sections (clj->js (map wrap-per-section-render-fn sections))
|
||||
:renderSectionHeader (wrap-render-section-header-fn render-section-header-fn)
|
||||
:style style})])
|
||||
@@ -6,34 +6,6 @@
|
||||
[status-im.utils.fx :as fx]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def defaults
|
||||
{:filter-status :unread
|
||||
:filter-type types/no-type
|
||||
;; Choose the maximum number of notifications that *usually/safely* fit on
|
||||
;; most screens, so that the UI doesn't have to needlessly render
|
||||
;; notifications.
|
||||
:notifications-per-page 8})
|
||||
|
||||
;;;; Navigation
|
||||
|
||||
(fx/defn open-activity-center
|
||||
{:events [:activity-center/open]}
|
||||
[_]
|
||||
(rf/dispatch [:show-popover {:view :activity-center
|
||||
:style {:margin 0}
|
||||
:disable-touchable-overlay? true
|
||||
:blur-view? true
|
||||
:blur-view-props {:blur-amount 20
|
||||
:blur-type :dark}}]))
|
||||
|
||||
;;;; Misc
|
||||
|
||||
(fx/defn process-notification-failure
|
||||
{:events [:activity-center/process-notification-failure]}
|
||||
[_ notification-id action error]
|
||||
(log/warn (str "Failed to " action)
|
||||
{:notification-id notification-id :error error}))
|
||||
|
||||
;;;; Notification reconciliation
|
||||
|
||||
(defn- update-notifications
|
||||
@@ -46,7 +18,8 @@
|
||||
~excessively~ big, this implementation will probably need to be revisited."
|
||||
[db-notifications new-notifications]
|
||||
(reduce (fn [acc {:keys [id type read] :as notification}]
|
||||
(let [remove-notification (fn [data]
|
||||
(let [filter-status (if read :read :unread)
|
||||
remove-notification (fn [data]
|
||||
(remove #(= id (:id %)) data))
|
||||
insert-and-sort (fn [data]
|
||||
(->> notification
|
||||
@@ -54,17 +27,14 @@
|
||||
(sort-by (juxt :timestamp :id))
|
||||
reverse))]
|
||||
(as-> acc $
|
||||
(update-in $ [type :all :data] remove-notification)
|
||||
(update-in $ [types/no-type :all :data] remove-notification)
|
||||
(update-in $ [type :read :data] remove-notification)
|
||||
(update-in $ [type :unread :data] remove-notification)
|
||||
(update-in $ [types/no-type :read :data] remove-notification)
|
||||
(update-in $ [types/no-type :unread :data] remove-notification)
|
||||
(if (or (:dismissed notification) (:accepted notification))
|
||||
$
|
||||
(cond-> (-> $
|
||||
(update-in [type :all :data] insert-and-sort)
|
||||
(update-in [types/no-type :all :data] insert-and-sort))
|
||||
(not read) (update-in [type :unread :data] insert-and-sort)
|
||||
(not read) (update-in [types/no-type :unread :data] insert-and-sort))))))
|
||||
(-> $ (update-in [type filter-status :data] insert-and-sort)
|
||||
(update-in [types/no-type filter-status :data] insert-and-sort))))))
|
||||
db-notifications
|
||||
new-notifications))
|
||||
|
||||
@@ -75,91 +45,39 @@
|
||||
{:db (update-in db [:activity-center :notifications]
|
||||
update-notifications new-notifications)}))
|
||||
|
||||
(fx/defn notifications-reconcile-from-response
|
||||
{:events [:activity-center/reconcile-notifications-from-response]}
|
||||
;;;; Contact verification
|
||||
|
||||
(fx/defn contact-verification-decline
|
||||
{:events [:activity-center.contact-verification/decline]}
|
||||
[_ contact-verification-id]
|
||||
{::json-rpc/call [{:method "wakuext_declineContactVerificationRequest"
|
||||
:params [contact-verification-id]
|
||||
:on-success #(rf/dispatch [:activity-center.contact-verification/decline-success %])
|
||||
:on-error #(rf/dispatch [:activity-center.contact-verification/decline-error contact-verification-id %])}]})
|
||||
|
||||
(fx/defn contact-verification-decline-success
|
||||
{:events [:activity-center.contact-verification/decline-success]}
|
||||
[cofx response]
|
||||
(->> response
|
||||
:activityCenterNotifications
|
||||
(map data-store.activities/<-rpc)
|
||||
(notifications-reconcile cofx)))
|
||||
|
||||
;;;; Mark notifications as read
|
||||
|
||||
(defn- get-notification
|
||||
[db notification-id]
|
||||
(->> (get-in db [:activity-center
|
||||
:notifications
|
||||
(get-in db [:activity-center :filter :type])
|
||||
(get-in db [:activity-center :filter :status])
|
||||
:data])
|
||||
(filter #(= notification-id (:id %)))
|
||||
first))
|
||||
|
||||
(fx/defn mark-as-read
|
||||
{:events [:activity-center.notifications/mark-as-read]}
|
||||
[{:keys [db]} notification-id]
|
||||
(when-let [notification (get-notification db notification-id)]
|
||||
{::json-rpc/call [{:method "wakuext_markActivityCenterNotificationsRead"
|
||||
:params [[notification-id]]
|
||||
:on-success #(rf/dispatch [:activity-center.notifications/mark-as-read-success notification])
|
||||
:on-error #(rf/dispatch [:activity-center/process-notification-failure
|
||||
notification-id
|
||||
:notification/mark-as-read
|
||||
%])}]}))
|
||||
|
||||
(fx/defn mark-as-read-success
|
||||
{:events [:activity-center.notifications/mark-as-read-success]}
|
||||
[cofx notification]
|
||||
(notifications-reconcile cofx [(assoc notification :read true)]))
|
||||
|
||||
;;;; Contact verification
|
||||
|
||||
(fx/defn contact-verification-decline
|
||||
{:events [:activity-center.contact-verification/decline]}
|
||||
[_ notification-id]
|
||||
{::json-rpc/call [{:method "wakuext_declineContactVerificationRequest"
|
||||
:params [notification-id]
|
||||
:on-success #(rf/dispatch [:activity-center/reconcile-notifications-from-response %])
|
||||
:on-error #(rf/dispatch [:activity-center/process-notification-failure
|
||||
notification-id
|
||||
:contact-verification/decline
|
||||
%])}]})
|
||||
|
||||
(fx/defn contact-verification-reply
|
||||
{:events [:activity-center.contact-verification/reply]}
|
||||
[_ notification-id reply]
|
||||
{::json-rpc/call [{:method "wakuext_acceptContactVerificationRequest"
|
||||
:params [notification-id reply]
|
||||
:on-success #(rf/dispatch [:activity-center/reconcile-notifications-from-response %])
|
||||
:on-error #(rf/dispatch [:activity-center/process-notification-failure
|
||||
notification-id
|
||||
:contact-verification/reply
|
||||
%])}]})
|
||||
|
||||
(fx/defn contact-verification-mark-as-trusted
|
||||
{:events [:activity-center.contact-verification/mark-as-trusted]}
|
||||
[_ notification-id]
|
||||
{::json-rpc/call [{:method "wakuext_verifiedTrusted"
|
||||
:params [{:id notification-id}]
|
||||
:on-success #(rf/dispatch [:activity-center/reconcile-notifications-from-response %])
|
||||
:on-error #(rf/dispatch [:activity-center/process-notification-failure
|
||||
notification-id
|
||||
:contact-verification/mark-as-trusted
|
||||
%])}]})
|
||||
|
||||
(fx/defn contact-verification-mark-as-untrustworthy
|
||||
{:events [:activity-center.contact-verification/mark-as-untrustworthy]}
|
||||
[_ notification-id]
|
||||
{::json-rpc/call [{:method "wakuext_verifiedUntrustworthy"
|
||||
:params [{:id notification-id}]
|
||||
:on-success #(rf/dispatch [:activity-center/reconcile-notifications-from-response %])
|
||||
:on-error #(rf/dispatch [:activity-center/process-notification-failure
|
||||
notification-id
|
||||
:contact-verification/mark-as-untrustworthy
|
||||
%])}]})
|
||||
(fx/defn contact-verification-decline-error
|
||||
{:events [:activity-center.contact-verification/decline-error]}
|
||||
[_ contact-verification-id error]
|
||||
(log/warn "Failed to decline contact verification"
|
||||
{:contact-verification-id contact-verification-id
|
||||
:error error})
|
||||
nil)
|
||||
|
||||
;;;; Notifications fetching and pagination
|
||||
|
||||
(def defaults
|
||||
{:filter-status :unread
|
||||
:filter-type types/no-type
|
||||
:notifications-per-page 10})
|
||||
|
||||
(def start-or-end-cursor
|
||||
"")
|
||||
|
||||
@@ -168,13 +86,15 @@
|
||||
(and (some? cursor)
|
||||
(not= cursor start-or-end-cursor)))
|
||||
|
||||
(def ^:const status-read 1)
|
||||
(def ^:const status-unread 2)
|
||||
(def ^:const status-all 3)
|
||||
|
||||
(defn status [filter-status]
|
||||
(case filter-status
|
||||
:read status-read
|
||||
:unread status-unread
|
||||
:all status-all
|
||||
:all status-all
|
||||
99))
|
||||
|
||||
(fx/defn notifications-fetch
|
||||
|
||||
@@ -3,228 +3,98 @@
|
||||
[day8.re-frame.test :as rf-test]
|
||||
[re-frame.core :as rf]
|
||||
[status-im.activity-center.notification-types :as types]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
status-im.events
|
||||
[status-im.test-helpers :as h]
|
||||
[status-im2.setup.config :as config]))
|
||||
|
||||
(def notification-id "0x1")
|
||||
[status-im.utils.config :as config]))
|
||||
|
||||
(defn setup []
|
||||
(h/register-helper-events)
|
||||
(rf/dispatch [:setup/app-started]))
|
||||
|
||||
(defn test-log-on-failure
|
||||
[{:keys [before-test notification-id event action]}]
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(h/using-log-test-appender
|
||||
(fn [logs]
|
||||
(when before-test
|
||||
(before-test))
|
||||
(h/stub-fx-with-callbacks ::json-rpc/call :on-error (constantly :fake-error))
|
||||
|
||||
(rf/dispatch event)
|
||||
|
||||
(is (= {:args [(str "Failed to " action)
|
||||
{:notification-id notification-id
|
||||
:error :fake-error}]
|
||||
:level :warn}
|
||||
(last @logs)))))))
|
||||
|
||||
;;;; Misc
|
||||
|
||||
(deftest mark-as-read-test
|
||||
(testing "does nothing if the notification ID cannot be found in the app db"
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(let [spy-queue (atom [])]
|
||||
(h/spy-fx spy-queue ::json-rpc/call)
|
||||
(let [notifications {types/one-to-one-chat
|
||||
{:all {:cursor "" :data [{:id notification-id
|
||||
:read false
|
||||
:type types/one-to-one-chat}]}
|
||||
:unread {:cursor "" :data []}}}]
|
||||
(rf/dispatch [:test/assoc-in [:activity-center]
|
||||
{:notifications notifications
|
||||
:filter {:type types/one-to-one-chat
|
||||
:status :all}}])
|
||||
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read "0x666"])
|
||||
|
||||
(is (= [] @spy-queue))
|
||||
(is (= notifications (get-in (h/db) [:activity-center :notifications])))))))
|
||||
|
||||
(testing "marks notifications as read and updates app db"
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(let [notif-1 {:id "0x1" :read true :type types/one-to-one-chat}
|
||||
notif-2 {:id "0x2" :read false :type types/one-to-one-chat}
|
||||
notif-3 {:id "0x3" :read false :type types/one-to-one-chat}
|
||||
new-notif-3 (assoc notif-3 :read true)
|
||||
new-notif-2 (assoc notif-2 :read true)]
|
||||
(h/stub-fx-with-callbacks ::json-rpc/call :on-success (constantly nil))
|
||||
(rf/dispatch [:test/assoc-in [:activity-center]
|
||||
{:notifications {types/one-to-one-chat
|
||||
{:all {:cursor "" :data [notif-3 notif-2 notif-1]}
|
||||
:unread {:cursor "" :data [notif-3 notif-2]}}}
|
||||
:filter {:type types/one-to-one-chat
|
||||
:status :unread}}])
|
||||
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read (:id notif-2)])
|
||||
(is (= {types/one-to-one-chat
|
||||
{:all {:cursor "" :data [notif-3 new-notif-2 notif-1]}
|
||||
:unread {:cursor "" :data [notif-3]}}
|
||||
|
||||
types/no-type
|
||||
{:all {:data [new-notif-2]}
|
||||
:unread {:data []}}}
|
||||
(get-in (h/db) [:activity-center :notifications])))
|
||||
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read (:id notif-3)])
|
||||
(is (= {types/one-to-one-chat
|
||||
{:all {:cursor "" :data [new-notif-3 new-notif-2 notif-1]}
|
||||
:unread {:cursor "" :data []}}
|
||||
|
||||
types/no-type
|
||||
{:all {:data [new-notif-3 new-notif-2]}
|
||||
:unread {:data []}}}
|
||||
(get-in (h/db) [:activity-center :notifications]))))))
|
||||
|
||||
(testing "logs on failure"
|
||||
(test-log-on-failure
|
||||
{:notification-id notification-id
|
||||
:event [:activity-center.notifications/mark-as-read notification-id]
|
||||
:action :notification/mark-as-read
|
||||
:before-test (fn []
|
||||
(rf/dispatch [:test/assoc-in [:activity-center]
|
||||
{:notifications {types/one-to-one-chat
|
||||
{:all {:cursor "" :data [{:id notification-id
|
||||
:read false
|
||||
:type types/one-to-one-chat}]}
|
||||
:unread {:cursor "" :data []}}}
|
||||
:filter {:type types/one-to-one-chat
|
||||
:status :all}}]))})))
|
||||
|
||||
;;;; Contact verification
|
||||
|
||||
(def contact-verification-rpc-response
|
||||
{:activityCenterNotifications
|
||||
[{:accepted false
|
||||
:author "0x04d03f"
|
||||
:chatId "0x04d03f"
|
||||
:contactVerificationStatus constants/contact-verification-status-pending
|
||||
:dismissed false
|
||||
:id notification-id
|
||||
:message {}
|
||||
:name "0x04d03f"
|
||||
:read true
|
||||
:timestamp 1666647286000
|
||||
:type types/contact-verification}]})
|
||||
|
||||
(def contact-verification-expected-notification
|
||||
{:accepted false
|
||||
:author "0x04d03f"
|
||||
:chat-id "0x04d03f"
|
||||
:contact-verification-status constants/contact-verification-status-pending
|
||||
:dismissed false
|
||||
:id notification-id
|
||||
:last-message nil
|
||||
:message {:command-parameters nil
|
||||
:content {:chat-id nil
|
||||
:ens-name nil
|
||||
:image nil
|
||||
:line-count nil
|
||||
:links nil
|
||||
:parsed-text nil
|
||||
:response-to nil
|
||||
:rtl? nil
|
||||
:sticker nil
|
||||
:text nil}
|
||||
:outgoing false
|
||||
:outgoing-status nil
|
||||
:quoted-message nil}
|
||||
:name "0x04d03f"
|
||||
:read true
|
||||
:reply-message nil
|
||||
:timestamp 1666647286000
|
||||
:type types/contact-verification})
|
||||
|
||||
(defn test-contact-verification-event
|
||||
[{:keys [event expected-rpc-call]}]
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(let [spy-queue (atom [])]
|
||||
(h/stub-fx-with-callbacks ::json-rpc/call :on-success (constantly contact-verification-rpc-response))
|
||||
(h/spy-fx spy-queue ::json-rpc/call)
|
||||
(rf/dispatch event)
|
||||
|
||||
(is (= {types/no-type
|
||||
{:all {:data [contact-verification-expected-notification]}
|
||||
:unread {:data []}}
|
||||
types/contact-verification
|
||||
{:all {:data [contact-verification-expected-notification]}
|
||||
:unread {:data []}}}
|
||||
(get-in (h/db) [:activity-center :notifications])))
|
||||
|
||||
(is (= expected-rpc-call
|
||||
(-> @spy-queue
|
||||
(get-in [0 :args 0])
|
||||
(select-keys [:method :params])))))))
|
||||
|
||||
(deftest contact-verification-decline-test
|
||||
(with-redefs [config/new-activity-center-enabled? true]
|
||||
(testing "declines notification and reconciles"
|
||||
(test-contact-verification-event
|
||||
{:event [:activity-center.contact-verification/decline notification-id]
|
||||
:expected-rpc-call {:method "wakuext_declineContactVerificationRequest"
|
||||
:params [notification-id]}}))
|
||||
(testing "logs on failure"
|
||||
(test-log-on-failure
|
||||
{:notification-id notification-id
|
||||
:event [:activity-center.contact-verification/decline notification-id]
|
||||
:action :contact-verification/decline}))))
|
||||
(testing "successfully declines and reconciles returned notification"
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(let [spy-queue (atom [])
|
||||
contact-verification-id 24
|
||||
expected-notification {:accepted false
|
||||
:author "0x04d03f"
|
||||
:chat-id "0x04d03f"
|
||||
:contact-verification-status 3
|
||||
:dismissed false
|
||||
:id 24
|
||||
:last-message nil
|
||||
:message {:command-parameters nil
|
||||
:content {:chat-id nil
|
||||
:ens-name nil
|
||||
:image nil
|
||||
:line-count nil
|
||||
:links nil
|
||||
:parsed-text nil
|
||||
:response-to nil
|
||||
:rtl? nil
|
||||
:sticker nil
|
||||
:text nil}
|
||||
:outgoing false
|
||||
:outgoing-status nil
|
||||
:quoted-message nil}
|
||||
:name "0x04d03f"
|
||||
:read true
|
||||
:reply-message nil
|
||||
:timestamp 1666647286000
|
||||
:type types/contact-verification}]
|
||||
(h/stub-fx-with-callbacks
|
||||
::json-rpc/call
|
||||
:on-success (constantly {:activityCenterNotifications
|
||||
[{:accepted false
|
||||
:author "0x04d03f"
|
||||
:chatId "0x04d03f"
|
||||
:contactVerificationStatus 3
|
||||
:dismissed false
|
||||
:id contact-verification-id
|
||||
:message {}
|
||||
:name "0x04d03f"
|
||||
:read true
|
||||
:timestamp 1666647286000
|
||||
:type types/contact-verification}]}))
|
||||
|
||||
(deftest contact-verification-reply-test
|
||||
(with-redefs [config/new-activity-center-enabled? true]
|
||||
(testing "sends reply and reconciles"
|
||||
(let [reply "any answer"]
|
||||
(test-contact-verification-event
|
||||
{:event [:activity-center.contact-verification/reply notification-id reply]
|
||||
:expected-rpc-call {:method "wakuext_acceptContactVerificationRequest"
|
||||
:params [notification-id reply]}})))
|
||||
(testing "logs on failure"
|
||||
(test-log-on-failure
|
||||
{:notification-id notification-id
|
||||
:event [:activity-center.contact-verification/reply notification-id "any answer"]
|
||||
:action :contact-verification/reply}))))
|
||||
(h/spy-fx spy-queue ::json-rpc/call)
|
||||
|
||||
(deftest contact-verification-mark-as-trusted-test
|
||||
(with-redefs [config/new-activity-center-enabled? true]
|
||||
(testing "marks notification as trusted and reconciles"
|
||||
(test-contact-verification-event
|
||||
{:event [:activity-center.contact-verification/mark-as-trusted notification-id]
|
||||
:expected-rpc-call {:method "wakuext_verifiedTrusted"
|
||||
:params [{:id notification-id}]}}))
|
||||
(testing "logs on failure"
|
||||
(test-log-on-failure
|
||||
{:notification-id notification-id
|
||||
:event [:activity-center.contact-verification/mark-as-trusted notification-id]
|
||||
:action :contact-verification/mark-as-trusted}))))
|
||||
(rf/dispatch [:activity-center.contact-verification/decline contact-verification-id])
|
||||
|
||||
(deftest contact-verification-mark-as-untrustworthy-test
|
||||
(with-redefs [config/new-activity-center-enabled? true]
|
||||
(testing "marks notification as untrustworthy and reconciles"
|
||||
(test-contact-verification-event
|
||||
{:event [:activity-center.contact-verification/mark-as-untrustworthy notification-id]
|
||||
:expected-rpc-call {:method "wakuext_verifiedUntrustworthy"
|
||||
:params [{:id notification-id}]}}))
|
||||
(testing "logs on failure"
|
||||
(test-log-on-failure
|
||||
{:notification-id notification-id
|
||||
:event [:activity-center.contact-verification/mark-as-untrustworthy notification-id]
|
||||
:action :contact-verification/mark-as-untrustworthy}))))
|
||||
(is (= {:method "wakuext_declineContactVerificationRequest"
|
||||
:params [contact-verification-id]}
|
||||
(-> @spy-queue
|
||||
(get-in [0 :args 0])
|
||||
(select-keys [:method :params]))))
|
||||
|
||||
(is (= {types/no-type
|
||||
{:read {:data [expected-notification]}
|
||||
:unread {:data []}}
|
||||
types/contact-verification
|
||||
{:read {:data [expected-notification]}
|
||||
:unread {:data []}}}
|
||||
(get-in (h/db) [:activity-center :notifications]))))))
|
||||
|
||||
(testing "logs failure"
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(let [contact-verification-id 666]
|
||||
(h/using-log-test-appender
|
||||
(fn [logs]
|
||||
(h/stub-fx-with-callbacks ::json-rpc/call :on-error (constantly :fake-error))
|
||||
|
||||
(rf/dispatch [:activity-center.contact-verification/decline contact-verification-id])
|
||||
|
||||
(is (= {:args ["Failed to decline contact verification"
|
||||
{:contact-verification-id contact-verification-id
|
||||
:error :fake-error}]
|
||||
:level :warn}
|
||||
(last @logs))))))))))
|
||||
|
||||
;;;; Notification reconciliation
|
||||
|
||||
@@ -234,12 +104,12 @@
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(let [notifications {types/one-to-one-chat
|
||||
{:all {:cursor ""
|
||||
{:read {:cursor ""
|
||||
:data [{:id "0x1"
|
||||
:read true
|
||||
:type types/one-to-one-chat}
|
||||
{:id "0x2"
|
||||
:read false
|
||||
:read true
|
||||
:type types/one-to-one-chat}]}
|
||||
:unread {:cursor ""
|
||||
:data [{:id "0x3"
|
||||
@@ -259,112 +129,216 @@
|
||||
(testing "removes dismissed or accepted notifications"
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(let [notif-1 {:id "0x1" :read true :type types/one-to-one-chat}
|
||||
notif-2 {:id "0x2" :read false :type types/one-to-one-chat}
|
||||
notif-3 {:id "0x3" :read false :type types/one-to-one-chat}
|
||||
notif-4 {:id "0x4" :read false :type types/private-group-chat}
|
||||
notif-5 {:id "0x5" :read true :type types/private-group-chat}
|
||||
notif-6 {:id "0x6" :read false :type types/private-group-chat}]
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
|
||||
{types/one-to-one-chat
|
||||
{:all {:cursor "" :data [notif-1 notif-2]}
|
||||
:unread {:cursor "" :data [notif-3]}}
|
||||
types/private-group-chat
|
||||
{:unread {:cursor "" :data [notif-4 notif-6]}}}])
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
|
||||
{types/one-to-one-chat
|
||||
{:read {:cursor ""
|
||||
:data [{:id "0x1" :read true :type types/one-to-one-chat}
|
||||
{:id "0x2" :read true :type types/one-to-one-chat}]}
|
||||
:unread {:cursor ""
|
||||
:data [{:id "0x3" :read false :type types/one-to-one-chat}]}}
|
||||
types/private-group-chat
|
||||
{:unread {:cursor ""
|
||||
:data [{:id "0x4" :read false :type types/private-group-chat}
|
||||
{:id "0x6" :read false :type types/private-group-chat}]}}}])
|
||||
|
||||
(rf/dispatch [:activity-center.notifications/reconcile
|
||||
[(assoc notif-1 :dismissed true)
|
||||
(assoc notif-3 :accepted true)
|
||||
(assoc notif-4 :dismissed true)
|
||||
notif-5]])
|
||||
(rf/dispatch [:activity-center.notifications/reconcile
|
||||
[{:id "0x1"
|
||||
:read true
|
||||
:type types/one-to-one-chat
|
||||
:dismissed true}
|
||||
{:id "0x3"
|
||||
:read false
|
||||
:type types/one-to-one-chat
|
||||
:accepted true}
|
||||
{:id "0x4"
|
||||
:read false
|
||||
:type types/private-group-chat
|
||||
:dismissed true}
|
||||
{:id "0x5"
|
||||
:read false
|
||||
:type types/private-group-chat
|
||||
:accepted true}]])
|
||||
|
||||
(is (= {types/no-type
|
||||
{:all {:data [notif-5]}
|
||||
:unread {:data []}}
|
||||
types/one-to-one-chat
|
||||
{:all {:cursor "" :data [notif-2]}
|
||||
:unread {:cursor "" :data []}}
|
||||
types/private-group-chat
|
||||
{:all {:data [notif-5]}
|
||||
:unread {:cursor "" :data [notif-6]}}}
|
||||
(get-in (h/db) [:activity-center :notifications]))))))
|
||||
(is (= {types/no-type
|
||||
{:read {:data []}
|
||||
:unread {:data []}}
|
||||
|
||||
types/one-to-one-chat
|
||||
{:read {:cursor ""
|
||||
:data [{:id "0x2"
|
||||
:read true
|
||||
:type types/one-to-one-chat}]}
|
||||
:unread {:cursor ""
|
||||
:data []}}
|
||||
types/private-group-chat
|
||||
{:read {:data []}
|
||||
:unread {:cursor ""
|
||||
:data [{:id "0x6"
|
||||
:read false
|
||||
:type types/private-group-chat}]}}}
|
||||
(get-in (h/db) [:activity-center :notifications])))))
|
||||
|
||||
(testing "replaces old notifications with newly arrived ones"
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(let [notif-1 {:id "0x1" :read true :type types/one-to-one-chat}
|
||||
notif-4 {:id "0x4" :read false :type types/private-group-chat}
|
||||
notif-6 {:id "0x6" :read false :type types/private-group-chat}
|
||||
new-notif-1 (assoc notif-1 :last-message {})
|
||||
new-notif-4 (assoc notif-4 :author "0xabc")]
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
|
||||
{types/no-type
|
||||
{:all {:cursor "" :data [notif-1]}
|
||||
:unread {:cursor "" :data [notif-4 notif-6]}}
|
||||
types/one-to-one-chat
|
||||
{:all {:cursor "" :data [notif-1]}}
|
||||
types/private-group-chat
|
||||
{:unread {:cursor "" :data [notif-4 notif-6]}}}])
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
|
||||
{types/no-type
|
||||
{:read {:cursor ""
|
||||
:data [{:id "0x1"
|
||||
:read true
|
||||
:type types/one-to-one-chat}]}
|
||||
:unread {:cursor ""
|
||||
:data [{:id "0x4"
|
||||
:read false
|
||||
:type types/private-group-chat}
|
||||
{:id "0x6"
|
||||
:read false
|
||||
:type types/private-group-chat}]}}
|
||||
types/one-to-one-chat
|
||||
{:read {:cursor ""
|
||||
:data [{:id "0x1"
|
||||
:read true
|
||||
:type types/one-to-one-chat}]}}
|
||||
types/private-group-chat
|
||||
{:unread {:cursor ""
|
||||
:data [{:id "0x4"
|
||||
:read false
|
||||
:type types/private-group-chat}
|
||||
{:id "0x6"
|
||||
:read false
|
||||
:type types/private-group-chat}]}}}])
|
||||
|
||||
(rf/dispatch [:activity-center.notifications/reconcile [new-notif-1 new-notif-4 notif-6]])
|
||||
(rf/dispatch [:activity-center.notifications/reconcile
|
||||
[{:id "0x1"
|
||||
:read true
|
||||
:type types/one-to-one-chat
|
||||
:last-message {}}
|
||||
{:id "0x4"
|
||||
:read false
|
||||
:type types/private-group-chat
|
||||
:author "0xabc"}
|
||||
{:id "0x6"
|
||||
:read false
|
||||
:type types/private-group-chat}]])
|
||||
|
||||
(is (= {types/no-type
|
||||
{:all {:cursor "" :data [notif-6 new-notif-4 new-notif-1]}
|
||||
:unread {:cursor "" :data [notif-6 new-notif-4]}}
|
||||
types/one-to-one-chat
|
||||
{:all {:cursor "" :data [new-notif-1]}
|
||||
:unread {:data []}}
|
||||
types/private-group-chat
|
||||
{:all {:data [notif-6 new-notif-4]}
|
||||
:unread {:cursor "" :data [notif-6 new-notif-4]}}}
|
||||
(get-in (h/db) [:activity-center :notifications]))))))
|
||||
(is (= {types/no-type
|
||||
{:read {:cursor ""
|
||||
:data [{:id "0x1"
|
||||
:read true
|
||||
:type types/one-to-one-chat
|
||||
:last-message {}}]}
|
||||
:unread {:cursor ""
|
||||
:data [{:id "0x6"
|
||||
:read false
|
||||
:type types/private-group-chat}
|
||||
{:id "0x4"
|
||||
:read false
|
||||
:type types/private-group-chat
|
||||
:author "0xabc"}]}}
|
||||
types/one-to-one-chat
|
||||
{:read {:cursor ""
|
||||
:data [{:id "0x1"
|
||||
:read true
|
||||
:type types/one-to-one-chat
|
||||
:last-message {}}]}
|
||||
:unread {:data []}}
|
||||
types/private-group-chat
|
||||
{:read {:data []}
|
||||
:unread {:cursor ""
|
||||
:data [{:id "0x6"
|
||||
:read false
|
||||
:type types/private-group-chat}
|
||||
{:id "0x4"
|
||||
:read false
|
||||
:type types/private-group-chat
|
||||
:author "0xabc"}]}}}
|
||||
(get-in (h/db) [:activity-center :notifications])))))
|
||||
|
||||
(testing "reconciles notifications that switched their read/unread status"
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(let [notif-1 {:id "0x1" :read true :type types/one-to-one-chat}
|
||||
new-notif-1 (assoc notif-1 :read false)]
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
|
||||
{types/one-to-one-chat
|
||||
{:all {:cursor "" :data [notif-1]}}}])
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
|
||||
{types/one-to-one-chat
|
||||
{:read {:cursor ""
|
||||
:data [{:id "0x1"
|
||||
:read true
|
||||
:type types/one-to-one-chat}]}}}])
|
||||
|
||||
(rf/dispatch [:activity-center.notifications/reconcile [new-notif-1]])
|
||||
(rf/dispatch [:activity-center.notifications/reconcile
|
||||
[{:id "0x1"
|
||||
:read false
|
||||
:type types/one-to-one-chat}]])
|
||||
|
||||
(is (= {types/no-type
|
||||
{:all {:data [new-notif-1]}
|
||||
:unread {:data [new-notif-1]}}
|
||||
(is (= {types/no-type
|
||||
{:read {:data []}
|
||||
:unread {:data [{:id "0x1"
|
||||
:read false
|
||||
:type types/one-to-one-chat}]}}
|
||||
|
||||
types/one-to-one-chat
|
||||
{:all {:cursor "" :data [new-notif-1]}
|
||||
:unread {:data [new-notif-1]}}}
|
||||
(get-in (h/db) [:activity-center :notifications]))))))
|
||||
types/one-to-one-chat
|
||||
{:read {:cursor ""
|
||||
:data []}
|
||||
:unread {:data [{:id "0x1"
|
||||
:read false
|
||||
:type types/one-to-one-chat}]}}}
|
||||
(get-in (h/db) [:activity-center :notifications])))))
|
||||
|
||||
;; Sorting by timestamp and ID is compatible with what the backend does when
|
||||
;; returning paginated results.
|
||||
(testing "sorts notifications by timestamp and id in descending order"
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(let [notif-1 {:id "0x1" :read true :type types/one-to-one-chat :timestamp 1}
|
||||
notif-2 {:id "0x2" :read true :type types/one-to-one-chat :timestamp 1}
|
||||
notif-3 {:id "0x3" :read false :type types/one-to-one-chat :timestamp 50}
|
||||
notif-4 {:id "0x4" :read false :type types/one-to-one-chat :timestamp 100}
|
||||
notif-5 {:id "0x5" :read false :type types/one-to-one-chat :timestamp 100}
|
||||
new-notif-1 (assoc notif-1 :last-message {})
|
||||
new-notif-4 (assoc notif-4 :last-message {})]
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
|
||||
{types/one-to-one-chat
|
||||
{:all {:cursor "" :data [notif-1 notif-2]}
|
||||
:unread {:cursor "" :data [notif-3 notif-4 notif-5]}}}])
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
|
||||
{types/one-to-one-chat
|
||||
{:read {:cursor ""
|
||||
:data [{:id "0x1" :read true :type types/one-to-one-chat :timestamp 1}
|
||||
{:id "0x2" :read true :type types/one-to-one-chat :timestamp 1}]}
|
||||
:unread {:cursor ""
|
||||
:data [{:id "0x3" :read false :type types/one-to-one-chat :timestamp 50}
|
||||
{:id "0x4" :read false :type types/one-to-one-chat :timestamp 100}
|
||||
{:id "0x5" :read false :type types/one-to-one-chat :timestamp 100}]}}}])
|
||||
|
||||
(rf/dispatch [:activity-center.notifications/reconcile [new-notif-1 new-notif-4]])
|
||||
(rf/dispatch [:activity-center.notifications/reconcile
|
||||
[{:id "0x1" :read true :type types/one-to-one-chat :timestamp 1 :last-message {}}
|
||||
{:id "0x4" :read false :type types/one-to-one-chat :timestamp 100 :last-message {}}]])
|
||||
|
||||
(is (= {types/no-type
|
||||
{:all {:data [new-notif-4 new-notif-1]}
|
||||
:unread {:data [new-notif-4]}}
|
||||
types/one-to-one-chat
|
||||
{:all {:cursor "" :data [new-notif-4 notif-2 new-notif-1]}
|
||||
:unread {:cursor "" :data [notif-5 new-notif-4 notif-3]}}}
|
||||
(get-in (h/db) [:activity-center :notifications]))))))))
|
||||
(is (= {types/no-type
|
||||
{:read {:data [{:id "0x1"
|
||||
:read true
|
||||
:type types/one-to-one-chat
|
||||
:timestamp 1
|
||||
:last-message {}}]}
|
||||
:unread {:data [{:id "0x4"
|
||||
:read false
|
||||
:type types/one-to-one-chat
|
||||
:timestamp 100
|
||||
:last-message {}}]}}
|
||||
types/one-to-one-chat
|
||||
{:read {:cursor ""
|
||||
:data [{:id "0x2"
|
||||
:read true
|
||||
:type types/one-to-one-chat
|
||||
:timestamp 1}
|
||||
{:id "0x1"
|
||||
:read true
|
||||
:type types/one-to-one-chat
|
||||
:timestamp 1
|
||||
:last-message {}}]}
|
||||
:unread {:cursor ""
|
||||
:data [{:id "0x5"
|
||||
:read false
|
||||
:type types/one-to-one-chat
|
||||
:timestamp 100}
|
||||
{:id "0x4"
|
||||
:read false
|
||||
:type types/one-to-one-chat
|
||||
:timestamp 100
|
||||
:last-message {}}
|
||||
{:id "0x3"
|
||||
:read false
|
||||
:type types/one-to-one-chat
|
||||
:timestamp 50}]}}}
|
||||
(get-in (h/db) [:activity-center :notifications])))))))
|
||||
|
||||
;;;; Notifications fetching and pagination
|
||||
|
||||
@@ -482,12 +456,12 @@
|
||||
(let [spy-queue (atom [])]
|
||||
(h/spy-fx spy-queue ::json-rpc/call)
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :filter :status]
|
||||
:all])
|
||||
:read])
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :filter :type]
|
||||
types/one-to-one-chat])
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :all :cursor]
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :read :cursor]
|
||||
"10"])
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :all :loading?]
|
||||
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :read :loading?]
|
||||
true])
|
||||
|
||||
(rf/dispatch [:activity-center.notifications/fetch-next-page])
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
(def ^:const mention 3)
|
||||
(def ^:const reply 4)
|
||||
(def ^:const contact-request 5)
|
||||
(def ^:const contact-verification 10)
|
||||
(def ^:const contact-verification 6)
|
||||
|
||||
;; TODO: Remove this constant once the old Notification Center code is removed.
|
||||
;; Its value clashes with the new constant `-contact-verification`
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
[status-im.bottom-sheet.core :as bottom-sheet]
|
||||
[status-im.browser.webview-ref :as webview-ref]
|
||||
["eth-phishing-detect" :as eth-phishing-detect]
|
||||
[utils.debounce :as debounce]
|
||||
[status-im.utils.debounce :as debounce]
|
||||
[status-im.browser.eip3085 :as eip3085]
|
||||
[status-im.browser.eip3326 :as eip3326]))
|
||||
|
||||
|
||||
@@ -265,18 +265,12 @@
|
||||
(fx/defn navigate-to-chat-nav2
|
||||
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
|
||||
{:events [:chat.ui/navigate-to-chat-nav2]}
|
||||
[{db :db :as cofx} chat-id from-shell?]
|
||||
[{db :db :as cofx} chat-id from-switcher?]
|
||||
(fx/merge cofx
|
||||
{:dispatch [:navigate-to-nav2 :chat chat-id from-shell?]}
|
||||
(when-not (= (:view-id db) :community)
|
||||
(navigation/pop-to-root-tab :shell-stack))
|
||||
(close-chat)
|
||||
(force-close-chat chat-id)
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc db :current-chat-id chat-id)})
|
||||
{:db (assoc db :current-chat-id chat-id)}
|
||||
(offload-messages chat-id)
|
||||
(preload-chat-data chat-id)
|
||||
#(when (group-chat? cofx chat-id)
|
||||
(loading/load-chat % chat-id))))
|
||||
(navigation/navigate-to-nav2 :chat chat-id nil from-switcher?)))
|
||||
|
||||
(fx/defn handle-clear-history-response
|
||||
{:events [::history-cleared]}
|
||||
|
||||
@@ -20,19 +20,19 @@
|
||||
|
||||
(defn- resize-and-call [uri cb]
|
||||
(react/image-get-size
|
||||
uri
|
||||
(fn [width height]
|
||||
(let [resize? (> (max width height) maximum-image-size-px)]
|
||||
(image-processing/resize
|
||||
uri
|
||||
(if resize? maximum-image-size-px width)
|
||||
(if resize? maximum-image-size-px height)
|
||||
60
|
||||
(fn [^js resized-image]
|
||||
(let [path (.-path resized-image)
|
||||
path (if (string/starts-with? path "file") path (str "file://" path))]
|
||||
(cb path)))
|
||||
#(log/error "could not resize image" %))))))
|
||||
uri
|
||||
(fn [width height]
|
||||
(let [resize? (> (max width height) maximum-image-size-px)]
|
||||
(image-processing/resize
|
||||
uri
|
||||
(if resize? maximum-image-size-px width)
|
||||
(if resize? maximum-image-size-px height)
|
||||
60
|
||||
(fn [^js resized-image]
|
||||
(let [path (.-path resized-image)
|
||||
path (if (string/starts-with? path "file") path (str "file://" path))]
|
||||
(cb path)))
|
||||
#(log/error "could not resize image" %))))))
|
||||
|
||||
(defn result->id [^js result]
|
||||
(if platform/ios?
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
(defn download-image-http [base64-uri on-success]
|
||||
(-> (.config ReactNativeBlobUtil (clj->js {:trusty platform/ios?
|
||||
:path temp-image-url}))
|
||||
:path temp-image-url}))
|
||||
(.fetch "GET" base64-uri)
|
||||
(.then #(on-success (.path %)))
|
||||
(.catch #(log/error "could not save image"))))
|
||||
@@ -51,64 +51,62 @@
|
||||
(defn save-to-gallery [path] (.save CameraRoll path))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::save-image-to-gallery
|
||||
(fn [base64-uri]
|
||||
(if platform/ios?
|
||||
(-> (download-image-http base64-uri save-to-gallery)
|
||||
(.catch #(utils/show-popup (i18n/label :t/error)
|
||||
(i18n/label :t/external-storage-denied))))
|
||||
(permissions/request-permissions
|
||||
{:permissions [:write-external-storage]
|
||||
:on-allowed #(download-image-http base64-uri save-to-gallery)
|
||||
:on-denied (fn []
|
||||
(utils/set-timeout
|
||||
#(utils/show-popup (i18n/label :t/error)
|
||||
(i18n/label :t/external-storage-denied))
|
||||
50))}))))
|
||||
::save-image-to-gallery
|
||||
(fn [base64-uri]
|
||||
(if platform/ios?
|
||||
(-> (download-image-http base64-uri save-to-gallery)
|
||||
(.catch #(utils/show-popup (i18n/label :t/error)
|
||||
(i18n/label :t/external-storage-denied))))
|
||||
(permissions/request-permissions
|
||||
{:permissions [:write-external-storage]
|
||||
:on-allowed #(download-image-http base64-uri save-to-gallery)
|
||||
:on-denied (fn []
|
||||
(utils/set-timeout
|
||||
#(utils/show-popup (i18n/label :t/error)
|
||||
(i18n/label :t/external-storage-denied))
|
||||
50))}))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::chat-open-image-picker-camera
|
||||
(fn [current-chat-id]
|
||||
(react/show-image-picker-camera
|
||||
#(re-frame/dispatch [:chat.ui/image-captured current-chat-id (.-path %)]) {})))
|
||||
::chat-open-image-picker-camera
|
||||
(fn [current-chat-id]
|
||||
(react/show-image-picker-camera
|
||||
#(re-frame/dispatch [:chat.ui/image-captured current-chat-id (.-path %)]) {})))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::chat-open-image-picker
|
||||
(fn [chat-id]
|
||||
(react/show-image-picker
|
||||
(fn [^js images]
|
||||
;; NOTE(Ferossgp): Because we can't highlight the already selected images inside
|
||||
;; gallery, we just clean previous state and set all newly picked images
|
||||
(when (and platform/ios? (pos? (count images)))
|
||||
(re-frame/dispatch [:chat.ui/clear-sending-images chat-id]))
|
||||
(doseq [^js result (if platform/ios?
|
||||
(take config/max-images-batch images)
|
||||
[images])]
|
||||
(resize-and-call (.-path result)
|
||||
#(re-frame/dispatch [:chat.ui/image-selected chat-id (result->id result) %]))))
|
||||
;; NOTE(Ferossgp): On android you cannot set max limit on images, when a user
|
||||
;; selects too many images the app crashes.
|
||||
{:media-type "photo"
|
||||
:multiple platform/ios?})))
|
||||
::chat-open-image-picker
|
||||
(fn [chat-id]
|
||||
(react/show-image-picker
|
||||
(fn [^js images]
|
||||
;; NOTE(Ferossgp): Because we can't highlight the already selected images inside
|
||||
;; gallery, we just clean previous state and set all newly picked images
|
||||
(when (and platform/ios? (pos? (count images)))
|
||||
(re-frame/dispatch [:chat.ui/clear-sending-images chat-id]))
|
||||
(doseq [^js result (if platform/ios?
|
||||
(take config/max-images-batch images)
|
||||
[images])]
|
||||
(resize-and-call (.-path result)
|
||||
#(re-frame/dispatch [:chat.ui/image-selected chat-id (result->id result) %]))))
|
||||
;; NOTE(Ferossgp): On android you cannot set max limit on images, when a user
|
||||
;; selects too many images the app crashes.
|
||||
{:media-type "photo"
|
||||
:multiple platform/ios?})))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::image-selected
|
||||
(fn [[uri chat-id]]
|
||||
(resize-and-call
|
||||
uri
|
||||
#(re-frame/dispatch [:chat.ui/image-selected chat-id uri %]))))
|
||||
::image-selected
|
||||
(fn [[uri chat-id]]
|
||||
(resize-and-call
|
||||
uri
|
||||
#(re-frame/dispatch [:chat.ui/image-selected chat-id uri %]))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::camera-roll-get-photos
|
||||
(fn [[num end-cursor]]
|
||||
(permissions/request-permissions
|
||||
{:permissions [:read-external-storage]
|
||||
:on-allowed (fn []
|
||||
(-> (if end-cursor
|
||||
(.getPhotos CameraRoll #js {:first num :after end-cursor :assetType "Photos" :groupTypes "All"})
|
||||
(.getPhotos CameraRoll #js {:first num :assetType "Photos" :groupTypes "All"}))
|
||||
(.then #(re-frame/dispatch [:on-camera-roll-get-photos (:edges (types/js->clj %)) (:page_info (types/js->clj %)) end-cursor]))
|
||||
(.catch #(log/warn "could not get camera roll photos"))))})))
|
||||
::camera-roll-get-photos
|
||||
(fn [num]
|
||||
(permissions/request-permissions
|
||||
{:permissions [:read-external-storage]
|
||||
:on-allowed (fn []
|
||||
(-> (.getPhotos CameraRoll #js {:first num :assetType "Photos" :groupTypes "All"})
|
||||
(.then #(re-frame/dispatch [:on-camera-roll-get-photos (:edges (types/js->clj %))]))
|
||||
(.catch #(log/warn "could not get cameraroll photos"))))})))
|
||||
|
||||
(fx/defn image-captured
|
||||
{:events [:chat.ui/image-captured]}
|
||||
@@ -121,23 +119,13 @@
|
||||
|
||||
(fx/defn camera-roll-get-photos
|
||||
{:events [:chat.ui/camera-roll-get-photos]}
|
||||
[_ num end-cursor]
|
||||
{::camera-roll-get-photos [num end-cursor]})
|
||||
|
||||
(fx/defn camera-roll-loading-more
|
||||
{:events [:chat.ui/camera-roll-loading-more]}
|
||||
[{:keys [db]} is-loading]
|
||||
{:db (assoc db :camera-roll-loading-more is-loading)})
|
||||
[_ num]
|
||||
{::camera-roll-get-photos num})
|
||||
|
||||
(fx/defn on-camera-roll-get-photos
|
||||
{:events [:on-camera-roll-get-photos]}
|
||||
[{:keys [db] :as cofx} photos page-info end-cursor]
|
||||
(let [photos_x (when end-cursor (:camera-roll-photos db))]
|
||||
{:db (-> db
|
||||
(assoc :camera-roll-photos (concat photos_x (map #(get-in % [:node :image :uri]) photos)))
|
||||
(assoc :camera-roll-end-cursor (:end_cursor page-info))
|
||||
(assoc :camera-roll-has-next-page (:has_next_page page-info))
|
||||
(assoc :camera-roll-loading-more false))}))
|
||||
[{db :db} photos]
|
||||
{:db (assoc db :camera-roll-photos (mapv #(get-in % [:node :image :uri]) photos))})
|
||||
|
||||
(fx/defn clear-sending-images
|
||||
{:events [:chat.ui/clear-sending-images]}
|
||||
|
||||
@@ -126,7 +126,6 @@
|
||||
|
||||
text (get-in message [:content :text])]
|
||||
{:dispatch [:chat.ui.input/set-chat-input-text text current-chat-id]
|
||||
:set-input-text [current-chat-id text]
|
||||
:db (-> db
|
||||
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message]
|
||||
message)
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
(ns status-im.chat.models-test
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.utils.clocks :as utils.clocks]
|
||||
[status-im.chat.models :as chat]
|
||||
[status-im.chat.models.images :as images]))
|
||||
[status-im.chat.models :as chat]))
|
||||
|
||||
(deftest clear-history-test
|
||||
(let [chat-id "1"
|
||||
@@ -92,9 +91,3 @@
|
||||
(testing "Pagination info should be reset on navigation"
|
||||
(let [res (chat/navigate-to-chat-nav2 {:db db} chat-id false)]
|
||||
(is (nil? (get-in res [:db :pagination-info chat-id :all-loaded?])))))))
|
||||
|
||||
|
||||
|
||||
(deftest camera-roll-loading-more
|
||||
(let [cofx {:db {:camera-roll-loading-more false}}]
|
||||
(is (= true (images/camera-roll-loading-more cofx true)))))
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
|
||||
(def featured
|
||||
[{:name "Status"
|
||||
:id constants/status-community-id}])
|
||||
:id constants/status-community-id}])
|
||||
|
||||
(defn <-request-to-join-community-rpc [r]
|
||||
(clojure.set/rename-keys r {:communityId :community-id
|
||||
:publicKey :public-key
|
||||
:chatId :chat-id}))
|
||||
:publicKey :public-key
|
||||
:chatId :chat-id}))
|
||||
|
||||
(defn <-requests-to-join-community-rpc [requests]
|
||||
(reduce (fn [acc r]
|
||||
@@ -60,12 +60,11 @@
|
||||
|
||||
(defn <-rpc [c]
|
||||
(-> c
|
||||
(clojure.set/rename-keys {:canRequestAccess :can-request-access?
|
||||
:canManageUsers :can-manage-users?
|
||||
:canDeleteMessageForEveryone :can-delete-message-for-everyone?
|
||||
:canJoin :can-join?
|
||||
:requestedToJoinAt :requested-to-join-at
|
||||
:isMember :is-member?})
|
||||
(clojure.set/rename-keys {:canRequestAccess :can-request-access?
|
||||
:canManageUsers :can-manage-users?
|
||||
:canJoin :can-join?
|
||||
:requestedToJoinAt :requested-to-join-at
|
||||
:isMember :is-member?})
|
||||
(update :members walk/stringify-keys)
|
||||
(update :chats <-chats-rpc)
|
||||
(update :categories <-categories-rpc)))
|
||||
@@ -126,67 +125,67 @@
|
||||
(fx/defn import-community
|
||||
{:events [::import]}
|
||||
[cofx community-key]
|
||||
{::json-rpc/call [{:method "wakuext_importCommunity"
|
||||
:params [community-key]
|
||||
{::json-rpc/call [{:method "wakuext_importCommunity"
|
||||
:params [community-key]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::community-imported %])
|
||||
:on-error #(do
|
||||
(log/error "failed to import community" %)
|
||||
(re-frame/dispatch [::failed-to-import %]))}]})
|
||||
:on-success #(re-frame/dispatch [::community-imported %])
|
||||
:on-error #(do
|
||||
(log/error "failed to import community" %)
|
||||
(re-frame/dispatch [::failed-to-import %]))}]})
|
||||
|
||||
(fx/defn join
|
||||
{:events [:communities/join]}
|
||||
{:events [::join]}
|
||||
[cofx community-id]
|
||||
{::json-rpc/call [{:method "wakuext_joinCommunity"
|
||||
:params [community-id]
|
||||
{::json-rpc/call [{:method "wakuext_joinCommunity"
|
||||
:params [community-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::joined %])
|
||||
:on-error #(do
|
||||
(log/error "failed to join community" community-id %)
|
||||
(re-frame/dispatch [::failed-to-join %]))}]})
|
||||
:on-success #(re-frame/dispatch [::joined %])
|
||||
:on-error #(do
|
||||
(log/error "failed to join community" community-id %)
|
||||
(re-frame/dispatch [::failed-to-join %]))}]})
|
||||
|
||||
(fx/defn request-to-join
|
||||
{:events [::request-to-join]}
|
||||
[cofx community-id]
|
||||
{::json-rpc/call [{:method "wakuext_requestToJoinCommunity"
|
||||
:params [{:communityId community-id}]
|
||||
{::json-rpc/call [{:method "wakuext_requestToJoinCommunity"
|
||||
:params [{:communityId community-id}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::requested-to-join %])
|
||||
:on-error #(do
|
||||
(log/error "failed to request to join community" community-id %)
|
||||
(re-frame/dispatch [::failed-to-request-to-join %]))}]})
|
||||
:on-success #(re-frame/dispatch [::requested-to-join %])
|
||||
:on-error #(do
|
||||
(log/error "failed to request to join community" community-id %)
|
||||
(re-frame/dispatch [::failed-to-request-to-join %]))}]})
|
||||
|
||||
(fx/defn leave
|
||||
{:events [:communities/leave]}
|
||||
[{:keys [db]} community-id]
|
||||
{:events [::leave]}
|
||||
[{:keys [db] :as cofx} community-id]
|
||||
(let [community-chat-ids (map #(str community-id %)
|
||||
(keys (get-in db [:communities community-id :chats])))]
|
||||
{:clear-message-notifications [community-chat-ids
|
||||
(get-in db [:multiaccount :remote-push-notifications-enabled?])]
|
||||
::json-rpc/call [{:method "wakuext_leaveCommunity"
|
||||
:params [community-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::left %])
|
||||
:on-error #(do
|
||||
(log/error "failed to leave community" community-id %)
|
||||
(re-frame/dispatch [::failed-to-leave %]))}]}))
|
||||
{:clear-message-notifications [community-chat-ids
|
||||
(get-in db [:multiaccount :remote-push-notifications-enabled?])]
|
||||
::json-rpc/call [{:method "wakuext_leaveCommunity"
|
||||
:params [community-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::left %])
|
||||
:on-error #(do
|
||||
(log/error "failed to leave community" community-id %)
|
||||
(re-frame/dispatch [::failed-to-leave %]))}]}))
|
||||
|
||||
(fx/defn fetch [_]
|
||||
{::json-rpc/call [{:method "wakuext_communities"
|
||||
:params []
|
||||
{::json-rpc/call [{:method "wakuext_communities"
|
||||
:params []
|
||||
:on-success #(re-frame/dispatch [::fetched %])
|
||||
:on-error #(do
|
||||
(log/error "failed to fetch communities" %)
|
||||
(re-frame/dispatch [::failed-to-fetch %]))}]})
|
||||
:on-error #(do
|
||||
(log/error "failed to fetch communities" %)
|
||||
(re-frame/dispatch [::failed-to-fetch %]))}]})
|
||||
|
||||
(fx/defn chat-created
|
||||
{:events [::chat-created]}
|
||||
[_ community-id user-pk]
|
||||
{::json-rpc/call [{:method "wakuext_sendChatMessage"
|
||||
:params [{:chatId user-pk
|
||||
:text "Upgrade here to see an invitation to community"
|
||||
:communityId community-id
|
||||
:contentType constants/content-type-community}]
|
||||
{::json-rpc/call [{:method "wakuext_sendChatMessage"
|
||||
:params [{:chatId user-pk
|
||||
:text "Upgrade here to see an invitation to community"
|
||||
:communityId community-id
|
||||
:contentType constants/content-type-community}]
|
||||
:js-response true
|
||||
:on-success
|
||||
#(re-frame/dispatch [:transport/message-sent %])
|
||||
@@ -197,56 +196,56 @@
|
||||
{:events [::invite-people-confirmation-pressed]}
|
||||
[cofx user-pk contacts]
|
||||
(let [community-id (fetch-community-id-input cofx)
|
||||
pks (if (seq user-pk)
|
||||
(conj contacts user-pk)
|
||||
contacts)]
|
||||
pks (if (seq user-pk)
|
||||
(conj contacts user-pk)
|
||||
contacts)]
|
||||
(when (seq pks)
|
||||
{::json-rpc/call [{:method "wakuext_inviteUsersToCommunity"
|
||||
:params [{:communityId community-id
|
||||
:users pks}]
|
||||
{::json-rpc/call [{:method "wakuext_inviteUsersToCommunity"
|
||||
:params [{:communityId community-id
|
||||
:users pks}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::people-invited %])
|
||||
:on-error #(do
|
||||
(log/error "failed to invite-user community" %)
|
||||
(re-frame/dispatch [::failed-to-invite-people %]))}]})))
|
||||
:on-success #(re-frame/dispatch [::people-invited %])
|
||||
:on-error #(do
|
||||
(log/error "failed to invite-user community" %)
|
||||
(re-frame/dispatch [::failed-to-invite-people %]))}]})))
|
||||
(fx/defn share-community
|
||||
{:events [::share-community-confirmation-pressed]}
|
||||
[cofx user-pk contacts]
|
||||
(let [community-id (fetch-community-id-input cofx)
|
||||
pks (if (seq user-pk)
|
||||
(conj contacts user-pk)
|
||||
contacts)]
|
||||
pks (if (seq user-pk)
|
||||
(conj contacts user-pk)
|
||||
contacts)]
|
||||
(when (seq pks)
|
||||
{::json-rpc/call [{:method "wakuext_shareCommunity"
|
||||
:params [{:communityId community-id
|
||||
:users pks}]
|
||||
{::json-rpc/call [{:method "wakuext_shareCommunity"
|
||||
:params [{:communityId community-id
|
||||
:users pks}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::people-invited %])
|
||||
:on-error #(do
|
||||
(log/error "failed to invite-user community" %)
|
||||
(re-frame/dispatch [::failed-to-share-community %]))}]})))
|
||||
:on-success #(re-frame/dispatch [::people-invited %])
|
||||
:on-error #(do
|
||||
(log/error "failed to invite-user community" %)
|
||||
(re-frame/dispatch [::failed-to-share-community %]))}]})))
|
||||
|
||||
(fx/defn create
|
||||
{:events [::create-confirmation-pressed]}
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [name description membership image]} (get db :communities/create)]
|
||||
(let [params {:name name
|
||||
(let [params {:name name
|
||||
:description description
|
||||
:membership membership
|
||||
:color (rand-nth colors/chat-colors)
|
||||
:image (string/replace-first (str image) #"file://" "")
|
||||
:imageAx 0
|
||||
:imageAy 0
|
||||
:imageBx crop-size
|
||||
:imageBy crop-size}]
|
||||
:membership membership
|
||||
:color (rand-nth colors/chat-colors)
|
||||
:image (string/replace-first (str image) #"file://" "")
|
||||
:imageAx 0
|
||||
:imageAy 0
|
||||
:imageBx crop-size
|
||||
:imageBy crop-size}]
|
||||
|
||||
{::json-rpc/call [{:method "wakuext_createCommunity"
|
||||
:params [params]
|
||||
{::json-rpc/call [{:method "wakuext_createCommunity"
|
||||
:params [params]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::community-created %])
|
||||
:on-error #(do
|
||||
(log/error "failed to create community" %)
|
||||
(re-frame/dispatch [::failed-to-create-community %]))}]})))
|
||||
:on-success #(re-frame/dispatch [::community-created %])
|
||||
:on-error #(do
|
||||
(log/error "failed to create community" %)
|
||||
(re-frame/dispatch [::failed-to-create-community %]))}]})))
|
||||
|
||||
(fx/defn edit
|
||||
{:events [::edit-confirmation-pressed]}
|
||||
@@ -254,15 +253,15 @@
|
||||
(let [{:keys [id name description membership new-image color]} (get db :communities/create)]
|
||||
{::json-rpc/call [{:method "wakuext_editCommunity"
|
||||
:params [{:communityID id
|
||||
:name name
|
||||
:name name
|
||||
:description description
|
||||
:color color
|
||||
:image (string/replace-first (str new-image) #"file://" "")
|
||||
:imageAx 0
|
||||
:imageAy 0
|
||||
:imageBx crop-size
|
||||
:imageBy crop-size
|
||||
:membership membership}]
|
||||
:color color
|
||||
:image (string/replace-first (str new-image) #"file://" "")
|
||||
:imageAx 0
|
||||
:imageAy 0
|
||||
:imageBx crop-size
|
||||
:imageBy crop-size
|
||||
:membership membership}]
|
||||
:on-success #(re-frame/dispatch [::community-edited %])
|
||||
:on-error #(do
|
||||
(log/error "failed to edit community" %)
|
||||
@@ -273,18 +272,18 @@
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [community-id (fetch-community-id-input cofx)
|
||||
{:keys [name description color emoji]} (get db :communities/create-channel)]
|
||||
{::json-rpc/call [{:method "wakuext_createCommunityChat"
|
||||
:params [community-id
|
||||
{:identity {:display_name name
|
||||
:description description
|
||||
:color color
|
||||
:emoji emoji}
|
||||
:permissions {:access constants/community-channel-access-no-membership}}]
|
||||
{::json-rpc/call [{:method "wakuext_createCommunityChat"
|
||||
:params [community-id
|
||||
{:identity {:display_name name
|
||||
:description description
|
||||
:color color
|
||||
:emoji emoji}
|
||||
:permissions {:access constants/community-channel-access-no-membership}}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::community-channel-created %])
|
||||
:on-error #(do
|
||||
(log/error "failed to create community channel" %)
|
||||
(re-frame/dispatch [::failed-to-create-community-channel %]))}]}))
|
||||
:on-success #(re-frame/dispatch [::community-channel-created %])
|
||||
:on-error #(do
|
||||
(log/error "failed to create community channel" %)
|
||||
(re-frame/dispatch [::failed-to-create-community-channel %]))}]}))
|
||||
|
||||
(def community-chat-id-length 68)
|
||||
|
||||
@@ -296,21 +295,21 @@
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:keys [name description color community-id emoji edit-channel-id category-id position]}
|
||||
(get db :communities/create-channel)]
|
||||
{::json-rpc/call [{:method "wakuext_editCommunityChat"
|
||||
:params [community-id
|
||||
edit-channel-id
|
||||
{:identity {:display_name name
|
||||
:description description
|
||||
:color color
|
||||
:emoji emoji}
|
||||
:category_id category-id
|
||||
:position position
|
||||
:permissions {:access constants/community-channel-access-no-membership}}]
|
||||
{::json-rpc/call [{:method "wakuext_editCommunityChat"
|
||||
:params [community-id
|
||||
edit-channel-id
|
||||
{:identity {:display_name name
|
||||
:description description
|
||||
:color color
|
||||
:emoji emoji}
|
||||
:category_id category-id
|
||||
:position position
|
||||
:permissions {:access constants/community-channel-access-no-membership}}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::community-channel-edited %])
|
||||
:on-error #(do
|
||||
(log/error "failed to edit community channel" %)
|
||||
(re-frame/dispatch [::failed-to-edit-community-channel %]))}]}))
|
||||
:on-success #(re-frame/dispatch [::community-channel-edited %])
|
||||
:on-error #(do
|
||||
(log/error "failed to edit community channel" %)
|
||||
(re-frame/dispatch [::failed-to-edit-community-channel %]))}]}))
|
||||
|
||||
(defn require-membership? [permissions]
|
||||
(not= constants/community-no-membership-access (:access permissions)))
|
||||
@@ -326,7 +325,7 @@
|
||||
{:db (assoc db :communities/create-channel {})})
|
||||
|
||||
(fx/defn invite-people-pressed
|
||||
{:events [:communities/invite-people-pressed]}
|
||||
{:events [::invite-people-pressed]}
|
||||
[cofx id]
|
||||
(fx/merge cofx
|
||||
(reset-community-id-input id)
|
||||
@@ -334,7 +333,7 @@
|
||||
(navigation/open-modal :invite-people-community {:invite? true})))
|
||||
|
||||
(fx/defn share-community-pressed
|
||||
{:events [:communities/share-community-pressed]}
|
||||
{:events [::share-community-pressed]}
|
||||
[cofx id]
|
||||
(fx/merge cofx
|
||||
(reset-community-id-input id)
|
||||
@@ -462,12 +461,12 @@
|
||||
(fx/defn member-ban
|
||||
{:events [::member-ban]}
|
||||
[cofx community-id public-key]
|
||||
{::json-rpc/call [{:method "wakuext_banUserFromCommunity"
|
||||
:params [{:communityId community-id
|
||||
:user public-key}]
|
||||
{::json-rpc/call [{:method "wakuext_banUserFromCommunity"
|
||||
:params [{:communityId community-id
|
||||
:user public-key}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::member-banned %])
|
||||
:on-error #(log/error "failed to ban user from community" community-id public-key %)}]})
|
||||
:on-success #(re-frame/dispatch [::member-banned %])
|
||||
:on-error #(log/error "failed to ban user from community" community-id public-key %)}]})
|
||||
|
||||
(fx/defn member-kicked
|
||||
{:events [::member-kicked]}
|
||||
@@ -479,11 +478,11 @@
|
||||
(fx/defn member-kick
|
||||
{:events [::member-kick]}
|
||||
[cofx community-id public-key]
|
||||
{::json-rpc/call [{:method "wakuext_removeUserFromCommunity"
|
||||
:params [community-id public-key]
|
||||
{::json-rpc/call [{:method "wakuext_removeUserFromCommunity"
|
||||
:params [community-id public-key]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::member-kicked %])
|
||||
:on-error #(log/error "failed to remove user from community" community-id public-key %)}]})
|
||||
:on-success #(re-frame/dispatch [::member-kicked %])
|
||||
:on-error #(log/error "failed to remove user from community" community-id public-key %)}]})
|
||||
|
||||
(fx/defn delete-community
|
||||
{:events [::delete-community]}
|
||||
@@ -523,88 +522,88 @@
|
||||
(fx/defn accept-request-to-join-pressed
|
||||
{:events [:communities.ui/accept-request-to-join-pressed]}
|
||||
[cofx community-id request-id]
|
||||
{::json-rpc/call [{:method "wakuext_acceptRequestToJoinCommunity"
|
||||
:params [{:id request-id}]
|
||||
{::json-rpc/call [{:method "wakuext_acceptRequestToJoinCommunity"
|
||||
:params [{:id request-id}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::request-to-join-accepted community-id request-id %])
|
||||
:on-error #(log/error "failed to accept requests-to-join" community-id request-id %)}]})
|
||||
:on-success #(re-frame/dispatch [::request-to-join-accepted community-id request-id %])
|
||||
:on-error #(log/error "failed to accept requests-to-join" community-id request-id %)}]})
|
||||
|
||||
(fx/defn decline-request-to-join-pressed
|
||||
{:events [:communities.ui/decline-request-to-join-pressed]}
|
||||
[cofx community-id request-id]
|
||||
{::json-rpc/call [{:method "wakuext_declineRequestToJoinCommunity"
|
||||
:params [{:id request-id}]
|
||||
{::json-rpc/call [{:method "wakuext_declineRequestToJoinCommunity"
|
||||
:params [{:id request-id}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::request-to-join-declined community-id request-id %])
|
||||
:on-error #(log/error "failed to decline requests-to-join" community-id request-id)}]})
|
||||
:on-success #(re-frame/dispatch [::request-to-join-declined community-id request-id %])
|
||||
:on-error #(log/error "failed to decline requests-to-join" community-id request-id)}]})
|
||||
|
||||
(fx/defn switch-communities-enabled
|
||||
{:events [:multiaccounts.ui/switch-communities-enabled]}
|
||||
[{:keys [db]} enabled?]
|
||||
{::async-storage/set! {:communities-enabled? enabled?}
|
||||
:db (assoc db :communities/enabled? enabled?)})
|
||||
:db (assoc db :communities/enabled? enabled?)})
|
||||
|
||||
(fx/defn create-category
|
||||
{:events [::create-category-confirmation-pressed]}
|
||||
[_ community-id category-title chat-ids]
|
||||
{::json-rpc/call [{:method "wakuext_createCommunityCategory"
|
||||
:params [{:communityId community-id
|
||||
:categoryName category-title
|
||||
:chatIds (map #(string/replace % community-id "") chat-ids)}]
|
||||
{::json-rpc/call [{:method "wakuext_createCommunityCategory"
|
||||
:params [{:communityId community-id
|
||||
:categoryName category-title
|
||||
:chatIds (map #(string/replace % community-id "") chat-ids)}]
|
||||
:js-response true
|
||||
:on-success #(do
|
||||
(re-frame/dispatch [:navigate-back])
|
||||
(re-frame/dispatch [:sanitize-messages-and-process-response %]))
|
||||
:on-error #(log/error "failed to create community category" %)}]})
|
||||
:on-success #(do
|
||||
(re-frame/dispatch [:navigate-back])
|
||||
(re-frame/dispatch [:sanitize-messages-and-process-response %]))
|
||||
:on-error #(log/error "failed to create community category" %)}]})
|
||||
|
||||
(fx/defn remove-chat-from-category
|
||||
{:events [:remove-chat-from-community-category]}
|
||||
[{:keys [db]} community-id id categoryID]
|
||||
(let [category (get-in db [:communities community-id :categories categoryID])
|
||||
(let [category (get-in db [:communities community-id :categories categoryID])
|
||||
category-chats (map :id (filter #(and (= (:categoryID %) categoryID) (not= id (:id %)))
|
||||
(vals (get-in db [:communities community-id :chats]))))]
|
||||
{::json-rpc/call [{:method "wakuext_editCommunityCategory"
|
||||
:params [{:communityId community-id
|
||||
:categoryId categoryID
|
||||
:categoryName (:name category)
|
||||
:chatIds category-chats}]
|
||||
{::json-rpc/call [{:method "wakuext_editCommunityCategory"
|
||||
:params [{:communityId community-id
|
||||
:categoryId categoryID
|
||||
:categoryName (:name category)
|
||||
:chatIds category-chats}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to remove chat from community" %)}]}))
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to remove chat from community" %)}]}))
|
||||
|
||||
(fx/defn delete-community-chat
|
||||
{:events [:delete-community-chat]}
|
||||
[_ community-id chat-id]
|
||||
{::json-rpc/call [{:method "wakuext_deleteCommunityChat"
|
||||
:params [community-id chat-id]
|
||||
{::json-rpc/call [{:method "wakuext_deleteCommunityChat"
|
||||
:params [community-id chat-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to delete community chat" %)}]})
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to delete community chat" %)}]})
|
||||
|
||||
(fx/defn delete-category
|
||||
{:events [:delete-community-category]}
|
||||
[_ community-id category-id]
|
||||
{::json-rpc/call [{:method "wakuext_deleteCommunityCategory"
|
||||
:params [{:communityId community-id
|
||||
:categoryId category-id}]
|
||||
{::json-rpc/call [{:method "wakuext_deleteCommunityCategory"
|
||||
:params [{:communityId community-id
|
||||
:categoryId category-id}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to delete community category" %)}]})
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to delete community category" %)}]})
|
||||
|
||||
(fx/defn change-category
|
||||
{:events [::change-category-confirmation-pressed]}
|
||||
[cofx community-id category-id {:keys [id position categoryID]}]
|
||||
(if (not (string/blank? category-id))
|
||||
{::json-rpc/call [{:method "wakuext_reorderCommunityChat"
|
||||
:params [{:communityId community-id
|
||||
:categoryId category-id
|
||||
:chatId id
|
||||
:position position}]
|
||||
{::json-rpc/call [{:method "wakuext_reorderCommunityChat"
|
||||
:params [{:communityId community-id
|
||||
:categoryId category-id
|
||||
:chatId id
|
||||
:position position}]
|
||||
:js-response true
|
||||
:on-success #(do
|
||||
(re-frame/dispatch [:navigate-back])
|
||||
(re-frame/dispatch [:sanitize-messages-and-process-response %]))
|
||||
:on-error #(log/error "failed to change community category" %)}]}
|
||||
:on-success #(do
|
||||
(re-frame/dispatch [:navigate-back])
|
||||
(re-frame/dispatch [:sanitize-messages-and-process-response %]))
|
||||
:on-error #(log/error "failed to change community category" %)}]}
|
||||
(fx/merge cofx
|
||||
(navigation/navigate-back)
|
||||
(remove-chat-from-category community-id id categoryID))))
|
||||
@@ -612,22 +611,22 @@
|
||||
(fx/defn reorder-category-chat
|
||||
{:events [::reorder-community-category-chat]}
|
||||
[_ community-id category-id chat-id new-position]
|
||||
{::json-rpc/call [{:method "wakuext_reorderCommunityChat"
|
||||
:params [{:communityId community-id
|
||||
:categoryId category-id
|
||||
:chatId chat-id
|
||||
:position new-position}]
|
||||
{::json-rpc/call [{:method "wakuext_reorderCommunityChat"
|
||||
:params [{:communityId community-id
|
||||
:categoryId category-id
|
||||
:chatId chat-id
|
||||
:position new-position}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to reorder community category chat" %)}]})
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to reorder community category chat" %)}]})
|
||||
|
||||
(fx/defn reorder-category
|
||||
{:events [::reorder-community-category]}
|
||||
[_ community-id category-id new-position]
|
||||
{::json-rpc/call [{:method "wakuext_reorderCommunityCategories"
|
||||
:params [{:communityId community-id
|
||||
:categoryId category-id
|
||||
:position new-position}]
|
||||
{::json-rpc/call [{:method "wakuext_reorderCommunityCategories"
|
||||
:params [{:communityId community-id
|
||||
:categoryId category-id
|
||||
:position new-position}]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to reorder community category" %)}]})
|
||||
@@ -673,45 +672,3 @@
|
||||
{::async-storage/get {:keys keys
|
||||
:cb #(re-frame/dispatch
|
||||
[::category-states-loaded community-id hashes %])}}))
|
||||
|
||||
(fx/defn navigate-to-community
|
||||
{:events [:communities/navigate-to-community]}
|
||||
[cofx community-id]
|
||||
(fx/merge cofx
|
||||
(navigation/pop-to-root-tab :shell-stack)
|
||||
(navigation/navigate-to-nav2 :community community-id true)))
|
||||
|
||||
(fx/defn member-role-updated
|
||||
{:events [:community.member/role-updated]}
|
||||
[cofx response-js]
|
||||
(fx/merge cofx
|
||||
(bottom-sheet/hide-bottom-sheet)
|
||||
(handle-response response-js)))
|
||||
|
||||
(fx/defn add-role-to-member
|
||||
{:events [:community.member/add-role]}
|
||||
[cofx community-id public-key role-id]
|
||||
{::json-rpc/call [{:method "wakuext_addRoleToMember"
|
||||
:params [{:communityId community-id
|
||||
:user public-key
|
||||
:role role-id}]
|
||||
:on-success #(re-frame/dispatch [:community.member/role-updated %])
|
||||
:on-error #(log/error "failed to add role to member"
|
||||
{:error %
|
||||
:community-id community-id
|
||||
:public-key public-key
|
||||
:role-id role-id})}]})
|
||||
|
||||
(fx/defn remove-role-from-member
|
||||
{:events [:community.member/remove-role]}
|
||||
[_ community-id public-key role-id]
|
||||
{::json-rpc/call [{:method "wakuext_removeRoleFromMember"
|
||||
:params [{:communityId community-id
|
||||
:user public-key
|
||||
:role role-id}]}
|
||||
:on-success #(re-frame/dispatch [:community.member/role-updated %])
|
||||
:on-error #(log/error "failed to remove role from member"
|
||||
{:error %
|
||||
:community-id community-id
|
||||
:public-key public-key
|
||||
:role-id role-id})]})
|
||||
|
||||
@@ -21,13 +21,12 @@
|
||||
(def ^:const contact-request-state-received 3)
|
||||
(def ^:const contact-request-state-dismissed 4)
|
||||
|
||||
(def ^:const contact-verification-status-unknown 0)
|
||||
(def ^:const contact-verification-status-pending 1)
|
||||
(def ^:const contact-verification-status-accepted 2)
|
||||
(def ^:const contact-verification-status-declined 3)
|
||||
(def ^:const contact-verification-status-cancelled 4)
|
||||
(def ^:const contact-verification-status-trusted 5)
|
||||
(def ^:const contact-verification-status-untrustworthy 6)
|
||||
(def ^:const contact-verification-state-unknown 0)
|
||||
(def ^:const contact-verification-state-pending 1)
|
||||
(def ^:const contact-verification-state-accepted 2)
|
||||
(def ^:const contact-verification-state-declined 3)
|
||||
(def ^:const contact-verification-state-cancelled 4)
|
||||
(def ^:const contact-verification-state-trusted 5)
|
||||
|
||||
(def ^:const emoji-reaction-love 1)
|
||||
(def ^:const emoji-reaction-thumbs-up 2)
|
||||
@@ -198,7 +197,3 @@
|
||||
(def ^:const sticker-pack-status-owned 3)
|
||||
|
||||
(def ^:const delete-message-for-me-undo-time-limit-ms 4000)
|
||||
|
||||
(def ^:const community-member-role-all 1)
|
||||
(def ^:const community-member-role-manage-users 2)
|
||||
(def ^:const community-member-role-moderator 3)
|
||||
|
||||
@@ -151,8 +151,3 @@
|
||||
:mutual-contact-enabled?
|
||||
enabled?
|
||||
nil))
|
||||
|
||||
(fx/defn set-search-query
|
||||
{:events [:contacts/set-search-query]}
|
||||
[{:keys [db] :as cofx} value]
|
||||
{:db (assoc db :contacts/search-query value)})
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[status-im.constants :as constants]
|
||||
[status-im.activity-center.notification-types :as notification-types]
|
||||
[status-im.data-store.messages :as messages]
|
||||
[status-im2.setup.config :as config]))
|
||||
[status-im.utils.config :as config]))
|
||||
|
||||
(defn- rpc->type [{:keys [type name] :as chat}]
|
||||
(case type
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[status-im.constants :as constants]
|
||||
[status-im.activity-center.notification-types :as notification-types]
|
||||
[status-im.data-store.activities :as store]
|
||||
[status-im2.setup.config :as config]))
|
||||
[status-im.utils.config :as config]))
|
||||
|
||||
(def chat-id
|
||||
"0x04c66155")
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
(def raw-notification
|
||||
{:chatId chat-id
|
||||
:contactVerificationStatus constants/contact-verification-status-pending
|
||||
:contactVerificationStatus constants/contact-verification-state-pending
|
||||
:lastMessage {}
|
||||
:name chat-name
|
||||
:replyMessage {}})
|
||||
@@ -23,7 +23,7 @@
|
||||
(testing "renames keys"
|
||||
(is (= {:name chat-name
|
||||
:chat-id chat-id
|
||||
:contact-verification-status constants/contact-verification-status-pending}
|
||||
:contact-verification-status constants/contact-verification-state-pending}
|
||||
(-> raw-notification
|
||||
store/<-rpc
|
||||
(dissoc :last-message :message :reply-message)))))
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
status-im.mailserver.constants
|
||||
[status-im.mailserver.core :as mailserver]
|
||||
[status-im.multiaccounts.biometric.core :as biometric]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
status-im.multiaccounts.login.core
|
||||
status-im.multiaccounts.logout.core
|
||||
status-im.multiaccounts.update.core
|
||||
@@ -45,7 +46,6 @@
|
||||
status-im.ui.screens.privacy-and-security-settings.events
|
||||
[status-im.utils.dimensions :as dimensions]
|
||||
[status-im.utils.fx :as fx]
|
||||
status-im.utils.logging.core
|
||||
[status-im.utils.universal-links.core :as universal-links]
|
||||
[status-im.utils.utils :as utils]
|
||||
status-im.visibility-status-updates.core
|
||||
@@ -56,10 +56,7 @@
|
||||
status-im.wallet.custom-tokens.core
|
||||
status-im.wallet-connect.core
|
||||
status-im.wallet-connect-legacy.core
|
||||
status-im.network.net-info
|
||||
status-im.visibility-status-popover.core
|
||||
status-im2.contexts.shell.events
|
||||
[status-im.multiaccounts.model :as multiaccounts.model]))
|
||||
status-im.network.net-info))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:dismiss-keyboard
|
||||
@@ -113,10 +110,9 @@
|
||||
|
||||
(fx/defn system-theme-mode-changed
|
||||
{:events [:system-theme-mode-changed]}
|
||||
[cofx _]
|
||||
(when (multiaccounts.model/logged-in? cofx)
|
||||
{:multiaccounts.ui/switch-theme (get-in cofx [:db :multiaccount :appearance])
|
||||
:dispatch [:reload-new-ui]}))
|
||||
[_ theme]
|
||||
{::multiaccounts/switch-theme (if (= :dark theme) 2 1)
|
||||
:dispatch [:reload-new-ui]})
|
||||
|
||||
(def authentication-options
|
||||
{:reason (i18n/label :t/biometric-auth-reason-login)})
|
||||
|
||||