Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
244c48bcf2 |
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.5.5'
|
||||
library 'status-jenkins-lib@v1.5.3'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
@@ -49,9 +49,10 @@ pipeline {
|
||||
stage('Prep') {
|
||||
steps {
|
||||
script {
|
||||
utils.doGitRebasePR()
|
||||
utils.symlinkEnv()
|
||||
println("Build Number: ${utils.genBuildNumber()}")
|
||||
btype = utils.getBuildType()
|
||||
print "Running ${btype} build!"
|
||||
/* Cleanup and Prep */
|
||||
commonPrep(btype)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.5.5'
|
||||
library 'status-jenkins-lib@v1.5.3'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
@@ -33,7 +33,7 @@ pipeline {
|
||||
stages {
|
||||
stage('Prep') {
|
||||
steps { script {
|
||||
println("Current JOB: ${env.JOB_NAME}")
|
||||
println "Current JOB: ${env.JOB_NAME}"
|
||||
/* just for a shorter access */
|
||||
btype = utils.getBuildType()
|
||||
} }
|
||||
|
||||
+5
-4
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.5.5'
|
||||
library 'status-jenkins-lib@v1.5.3'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
@@ -48,9 +48,10 @@ pipeline {
|
||||
stage('Prep') {
|
||||
steps {
|
||||
script {
|
||||
utils.doGitRebasePR()
|
||||
utils.symlinkEnv()
|
||||
println("Build Number: ${utils.genBuildNumber()}")
|
||||
btype = utils.getBuildType()
|
||||
print "Running ${btype} build!"
|
||||
/* Cleanup and Prep */
|
||||
commonPrep(btype)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.5.5'
|
||||
library 'status-jenkins-lib@v1.5.3'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.5.5'
|
||||
library 'status-jenkins-lib@v1.5.0'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
@@ -44,7 +44,10 @@ pipeline {
|
||||
stage('Prep') {
|
||||
steps {
|
||||
script {
|
||||
utils.doGitRebasePR()
|
||||
btype = utils.getBuildType()
|
||||
print "Running ${btype} build!"
|
||||
/* Cleanup and Prep */
|
||||
commonPrep(btype)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.5.5'
|
||||
library 'status-jenkins-lib@v1.5.3'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.5.5'
|
||||
library 'status-jenkins-lib@v1.5.3'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.5.5'
|
||||
library 'status-jenkins-lib@v1.5.3'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
-26
@@ -1411,31 +1411,6 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
return Statusgo.identicon(seed);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String encodeTransfer(final String to, final String value) {
|
||||
return Statusgo.encodeTransfer(to, value);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String encodeFunctionCall(final String method, final String paramsJSON) {
|
||||
return Statusgo.encodeFunctionCall(method, paramsJSON);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String decodeParameters(final String decodeParamJSON) {
|
||||
return Statusgo.decodeParameters(decodeParamJSON);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String hexToNumber(final String hex) {
|
||||
return Statusgo.hexToNumber(hex);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String numberToHex(final String numString) {
|
||||
return Statusgo.numberToHex(numString);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void identiconAsync(final String seed, final Callback callback) {
|
||||
Log.d(TAG, "identiconAsync");
|
||||
@@ -1597,6 +1572,5 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
|
||||
StatusThreadPoolExecutor.getInstance().execute(r);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -820,28 +820,6 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(identicon:(NSString *)publicKey) {
|
||||
return StatusgoIdenticon(publicKey);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(encodeTransfer:(NSString *)to
|
||||
value:(NSString *)value) {
|
||||
return StatusgoEncodeTransfer(to,value);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(encodeFunctionCall:(NSString *)method
|
||||
paramsJSON:(NSString *)paramsJSON) {
|
||||
return StatusgoEncodeFunctionCall(method,paramsJSON);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(decodeParameters:(NSString *)decodeParamJSON) {
|
||||
return StatusgoDecodeParameters(decodeParamJSON);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(hexToNumber:(NSString *)hex) {
|
||||
return StatusgoHexToNumber(hex);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(numberToHex:(NSString *)numString) {
|
||||
return StatusgoNumberToHex(numString);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(validateMnemonic:(NSString *)seed
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
|
||||
@@ -386,182 +386,6 @@ void _Identicon(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
}
|
||||
|
||||
void _EncodeTransfer(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (args.Length() != 2) {
|
||||
// Throw an Error that is passed back to JavaScript
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for EncodeTransfer")));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the argument types
|
||||
|
||||
if (!args[0]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'to'")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args[1]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'value'")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
|
||||
char *arg0 = *arg0Obj;
|
||||
String::Utf8Value arg1Obj(isolate, args[1]->ToString(context).ToLocalChecked());
|
||||
char *arg1 = *arg1Obj;
|
||||
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = EncodeTransfer(arg0, arg1);
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
delete c;
|
||||
|
||||
}
|
||||
|
||||
void _EncodeFunctionCall(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (args.Length() != 2) {
|
||||
// Throw an Error that is passed back to JavaScript
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for EncodeFunctionCall")));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the argument types
|
||||
|
||||
if (!args[0]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'method'")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args[1]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'paramsJSON'")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
|
||||
char *arg0 = *arg0Obj;
|
||||
String::Utf8Value arg1Obj(isolate, args[1]->ToString(context).ToLocalChecked());
|
||||
char *arg1 = *arg1Obj;
|
||||
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = EncodeFunctionCall(arg0, arg1);
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
delete c;
|
||||
|
||||
}
|
||||
|
||||
void _DecodeParameters(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (args.Length() != 1) {
|
||||
// Throw an Error that is passed back to JavaScript
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for DecodeParameters")));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the argument types
|
||||
|
||||
if (!args[0]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'decodeParamJSON'")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
|
||||
char *arg0 = *arg0Obj;
|
||||
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = DecodeParameters(arg0);
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
delete c;
|
||||
|
||||
}
|
||||
|
||||
void _HexToNumber(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (args.Length() != 1) {
|
||||
// Throw an Error that is passed back to JavaScript
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for HexToNumber")));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the argument types
|
||||
|
||||
if (!args[0]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'hex'")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
|
||||
char *arg0 = *arg0Obj;
|
||||
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = HexToNumber(arg0);
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
delete c;
|
||||
|
||||
}
|
||||
|
||||
void _NumberToHex(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (args.Length() != 1) {
|
||||
// Throw an Error that is passed back to JavaScript
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for NumberToHex")));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the argument types
|
||||
|
||||
if (!args[0]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'numString'")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
|
||||
char *arg0 = *arg0Obj;
|
||||
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = NumberToHex(arg0);
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
delete c;
|
||||
|
||||
}
|
||||
|
||||
void _Logout(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
|
||||
@@ -1759,11 +1583,6 @@ void init(Local<Object> exports) {
|
||||
NODE_SET_METHOD(exports, "initKeystore", _InitKeystore);
|
||||
NODE_SET_METHOD(exports, "stopCPUProfiling", _StopCPUProfiling);
|
||||
NODE_SET_METHOD(exports, "identicon", _Identicon);
|
||||
NODE_SET_METHOD(exports, "encodeTransfer", _EncodeTransfer);
|
||||
NODE_SET_METHOD(exports, "encodeFunctionCall", _EncodeFunctionCall);
|
||||
NODE_SET_METHOD(exports, "decodeParameters", _DecodeParameters);
|
||||
NODE_SET_METHOD(exports, "hexToNumber", _HexToNumber);
|
||||
NODE_SET_METHOD(exports, "numberToHex", _NumberToHex);
|
||||
NODE_SET_METHOD(exports, "logout", _Logout);
|
||||
NODE_SET_METHOD(exports, "hashMessage", _HashMessage);
|
||||
NODE_SET_METHOD(exports, "resetChainData", _ResetChainData);
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 340 B |
Binary file not shown.
|
Before Width: | Height: | Size: 488 B |
Binary file not shown.
|
Before Width: | Height: | Size: 352 B |
Binary file not shown.
|
Before Width: | Height: | Size: 491 B |
@@ -1,45 +0,0 @@
|
||||
(ns quo2.components.avatars.channel-avatar
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[quo.react-native :as rn]
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo.theme :as theme]))
|
||||
|
||||
(defn channel-avatar [{:keys [big? lock-status emoji-background-color emoji]}]
|
||||
(let [locked? (= :locked lock-status)
|
||||
lock-exists? (not= :none lock-status)
|
||||
dark? (theme/dark?)]
|
||||
[rn/view {:style {:width (if big? 32 24)
|
||||
:height (if big? 32 24)
|
||||
:border-radius (if big? 32 24)
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color emoji-background-color}}
|
||||
[rn/view {:style {:display :flex
|
||||
:justify-content :center
|
||||
:align-items :center}}
|
||||
[text/text {:size (if big?
|
||||
:paragraph-1
|
||||
:label)} emoji]
|
||||
(when lock-exists?
|
||||
[rn/view {:style {:position :absolute
|
||||
:left (if big?
|
||||
13
|
||||
5)
|
||||
:top (if big?
|
||||
14
|
||||
5)
|
||||
:background-color (if dark?
|
||||
colors/neutral-90
|
||||
colors/white)
|
||||
:border-radius 15
|
||||
:padding 2}}
|
||||
[icons/icon (if locked?
|
||||
:main-icons/locked
|
||||
:main-icons/unlocked)
|
||||
{:color (if dark?
|
||||
colors/neutral-40
|
||||
colors/neutral-50)
|
||||
:container-style {:width 16
|
||||
:height 16}
|
||||
:size 12}]])]]))
|
||||
@@ -1,74 +0,0 @@
|
||||
(ns quo2.components.dividers.new-messages
|
||||
(:require [quo.react-native :as rn]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[status-im.ui.components.react :as react]))
|
||||
|
||||
(def themes
|
||||
{:light {:primary {:text-color colors/primary-50
|
||||
:background-color colors/primary-50-opa-5}
|
||||
:purple {:text-color colors/purple-50
|
||||
:background-color colors/purple-50-opa-5}
|
||||
:indigo {:text-color colors/indigo-50
|
||||
:background-color colors/indigo-50-opa-5}
|
||||
:turquoise {:text-color colors/turquoise-50
|
||||
:background-color colors/turquoise-50-opa-5}
|
||||
:blue {:text-color colors/blue-50
|
||||
:background-color colors/blue-50-opa-5}
|
||||
:green {:text-color colors/green-50
|
||||
:background-color colors/green-50-opa-5}
|
||||
:yellow {:text-color colors/yellow-50
|
||||
:background-color colors/yellow-50-opa-5}
|
||||
:orange {:text-color colors/orange-50
|
||||
:background-color colors/orange-50-opa-5}
|
||||
:red {:text-color colors/red-50
|
||||
:background-color colors/red-50-opa-5}
|
||||
:pink {:text-color colors/pink-50
|
||||
:background-color colors/pink-50-opa-5}
|
||||
:brown {:text-color colors/brown-50
|
||||
:background-color colors/brown-50-opa-5}
|
||||
:beige {:text-color colors/beige-50
|
||||
:background-color colors/beige-50-opa-5}}
|
||||
:dark {:primary {:text-color colors/primary-60
|
||||
:background-color colors/primary-60-opa-5}
|
||||
:purple {:text-color colors/purple-60
|
||||
:background-color colors/purple-60-opa-5}
|
||||
:indigo {:text-color colors/indigo-60
|
||||
:background-color colors/indigo-60-opa-5}
|
||||
:turquoise {:text-color colors/turquoise-60
|
||||
:background-color colors/turquoise-60-opa-5}
|
||||
:blue {:text-color colors/blue-60
|
||||
:background-color colors/blue-60-opa-5}
|
||||
:green {:text-color colors/green-60
|
||||
:background-color colors/green-60-opa-5}
|
||||
:yellow {:text-color colors/yellow-60
|
||||
:background-color colors/yellow-60-opa-5}
|
||||
:orange {:text-color colors/orange-60
|
||||
:background-color colors/orange-60-opa-5}
|
||||
:red {:text-color colors/red-60
|
||||
:background-color colors/red-60-opa-5}
|
||||
:pink {:text-color colors/pink-60
|
||||
:background-color colors/pink-60-opa-5}
|
||||
:brown {:text-color colors/brown-60
|
||||
:background-color colors/brown-60-opa-5}
|
||||
:beige {:text-color colors/beige-60
|
||||
:background-color colors/beige-60-opa-5}}})
|
||||
|
||||
(defn new-messages
|
||||
"new-messages params - label, color"
|
||||
[{:keys [label color] :or {label (i18n/label :new-messages-header)
|
||||
color :primary}}]
|
||||
(let [colors (colors/theme-colors (themes :light) (themes :dark))
|
||||
bg-color (get-in colors [color :background-color])
|
||||
text-color (get-in colors [color :text-color])]
|
||||
[react/linear-gradient {:colors [bg-color "rgba(0,0,0,0)"]
|
||||
:start {:x 0 :y 0} :end {:x 0 :y 1}}
|
||||
[rn/view {:style {:padding-left 60
|
||||
:padding-vertical 12
|
||||
:padding-right 24}}
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style {:color text-color}}
|
||||
label]]]))
|
||||
@@ -47,17 +47,15 @@
|
||||
:size :paragraph-2}
|
||||
(trim-public-key public-key)]]))
|
||||
|
||||
(defn context-tag [params photo name]
|
||||
[base-tag (assoc-in params [:style :padding-left] 3)
|
||||
[rn/image {:style {:width 20
|
||||
:border-radius 10
|
||||
:background-color :white
|
||||
:height 20}
|
||||
:source photo}]
|
||||
[text/text {:weight :medium
|
||||
:size :paragraph-2}
|
||||
(str " " name)]])
|
||||
|
||||
(defn user-avatar-tag []
|
||||
(fn [params username photo]
|
||||
[context-tag params {:uri photo} username]))
|
||||
[base-tag (assoc-in params [:style :padding-left] 3)
|
||||
[rn/image {:style {:width 20
|
||||
:border-radius 10
|
||||
:background-color :white
|
||||
:height 20}
|
||||
:source {:uri photo}}]
|
||||
[text/text {:weight :medium
|
||||
:size :paragraph-2}
|
||||
|
||||
(str " " username)]]))
|
||||
|
||||
@@ -105,9 +105,6 @@
|
||||
(def primary-50-opa-30 (alpha primary-50 0.3))
|
||||
(def primary-50-opa-40 (alpha primary-50 0.4))
|
||||
|
||||
;;60 with transparency
|
||||
(def primary-60-opa-5 (alpha primary-60 0.05))
|
||||
|
||||
;;;;Success
|
||||
|
||||
;;Solid
|
||||
@@ -189,104 +186,39 @@
|
||||
(def info-50-opa-40 (alpha info-50 0.4))
|
||||
|
||||
;; Customization
|
||||
;;;;Purple
|
||||
(def purple-20 (alpha "#8661C1" 0.2))
|
||||
(def purple-50 "#8661C1")
|
||||
(def purple-60 "#5E478C")
|
||||
|
||||
;;with transparency
|
||||
(def purple-50-opa-5 (alpha purple-50 0.05))
|
||||
(def purple-60-opa-5 (alpha purple-60 0.05))
|
||||
|
||||
;;;;Indigo
|
||||
(def purple-60 (alpha "#8661C1" 0.6))
|
||||
(def indigo-20 (alpha "#496289" 0.2))
|
||||
(def indigo-50 "#496289")
|
||||
(def indigo-60 "#3D5273")
|
||||
|
||||
;;with transparency
|
||||
(def indigo-50-opa-5 (alpha indigo-50 0.05))
|
||||
(def indigo-60-opa-5 (alpha indigo-60 0.05))
|
||||
|
||||
;;;;Turquoise
|
||||
(def indigo-60 (alpha "#496289" 0.6))
|
||||
(def turquoise-20 (alpha "#448EA2" 0.2))
|
||||
(def turquoise-50 "#448EA2")
|
||||
(def turquoise-60 "#397788")
|
||||
|
||||
;;with transparency
|
||||
(def turquoise-50-opa-5 (alpha turquoise-50 0.05))
|
||||
(def turquoise-60-opa-5 (alpha turquoise-60 0.05))
|
||||
|
||||
;;;;Blue
|
||||
(def turquoise-60 (alpha "#448EA2" 0.6))
|
||||
(def blue-20 (alpha "#4CB4EF" 0.2))
|
||||
(def blue-50 "#4CB4EF")
|
||||
(def blue-60 "#4097C9")
|
||||
|
||||
;;with transparency
|
||||
(def blue-50-opa-5 (alpha blue-50 0.05))
|
||||
(def blue-60-opa-5 (alpha blue-60 0.05))
|
||||
|
||||
;;;;Green
|
||||
(def blue-60 (alpha "#4CB4EF" 0.6))
|
||||
(def green-20 (alpha "#5BCC95" 0.2))
|
||||
(def green-50 "#5BCC95")
|
||||
(def green-60 "#4CAB7D")
|
||||
|
||||
;;with transparency
|
||||
(def green-50-opa-5 (alpha green-50 0.05))
|
||||
(def green-60-opa-5 (alpha green-60 0.05))
|
||||
|
||||
;;;;Yellow
|
||||
(def green-60 (alpha "#5BCC95" 0.6))
|
||||
(def yellow-20 (alpha "#FFCB53" 0.2))
|
||||
(def yellow-50 "#FFCB53")
|
||||
(def yellow-60 "#D6AA46")
|
||||
|
||||
;;with transparency
|
||||
(def yellow-50-opa-5 (alpha yellow-50 0.05))
|
||||
(def yellow-60-opa-5 (alpha yellow-60 0.05))
|
||||
|
||||
;;;;Orange
|
||||
(def yellow-60 (alpha "#FFCB53" 0.6))
|
||||
(def orange-20 (alpha "#FB8F61" 0.2))
|
||||
(def orange-50 "#FB8F61")
|
||||
(def orange-60 "#D37851")
|
||||
|
||||
;;with transparency
|
||||
(def orange-50-opa-5 (alpha orange-50 0.05))
|
||||
(def orange-60-opa-5 (alpha orange-60 0.05))
|
||||
|
||||
;;;;Red
|
||||
(def orange-60 (alpha "#FB8F61" 0.6))
|
||||
(def red-20 (alpha "#F46666" 0.2))
|
||||
(def red-50 "#F46666")
|
||||
(def red-60 "#CD5656")
|
||||
|
||||
;;with transparency
|
||||
(def red-50-opa-5 (alpha red-50 0.05))
|
||||
(def red-60-opa-5 (alpha red-60 0.05))
|
||||
|
||||
;;;;Pink
|
||||
(def red-60 (alpha "#F46666" 0.6))
|
||||
(def pink-20 (alpha "#FC7BAB" 0.2))
|
||||
(def pink-50 "#FC7BAB")
|
||||
(def pink-60 "#D46790")
|
||||
|
||||
;;with transparency
|
||||
(def pink-50-opa-5 (alpha pink-50 0.05))
|
||||
(def pink-60-opa-5 (alpha pink-60 0.05))
|
||||
|
||||
;;;;Brown
|
||||
(def pink-60 (alpha "#FC7BAB" 0.6))
|
||||
(def brown-20 (alpha "#99604D" 0.2))
|
||||
(def brown-50 "#99604D")
|
||||
(def brown-60 "#805141")
|
||||
|
||||
;;with transparency
|
||||
(def brown-50-opa-5 (alpha brown-50 0.05))
|
||||
(def brown-60-opa-5 (alpha brown-60 0.05))
|
||||
|
||||
;;;;Beige
|
||||
(def brown-60 (alpha "#805141" 0.6))
|
||||
(def beige-20 (alpha "#CAAE93" 0.2))
|
||||
(def beige-50 "#CAAE93")
|
||||
(def beige-60 "#AA927C")
|
||||
|
||||
;;with transparency
|
||||
(def beige-50-opa-5 (alpha beige-50 0.05))
|
||||
(def beige-60-opa-5 (alpha beige-60 0.05))
|
||||
(def beige-60 (alpha "#CAAE93" 0.6))
|
||||
|
||||
(def shadow "rgba(9,16,28,0.04)")
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
(ns quo2.screens.avatars.channel-avatar
|
||||
(:require [reagent.core :as reagent]
|
||||
[quo.react-native :as rn]
|
||||
[quo.previews.preview :as preview]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.avatars.channel-avatar :as quo2]))
|
||||
|
||||
(def descriptor [{:label "Big?"
|
||||
:key :big?
|
||||
:type :boolean}
|
||||
{:label "Avatar color"
|
||||
:key :emoji-background-color
|
||||
:type :text}
|
||||
{:label "Avatar color"
|
||||
:key :emoji
|
||||
:type :text}
|
||||
{:label "Lock status"
|
||||
:key :lock-status
|
||||
:type :select
|
||||
:options [{:key :unlocked
|
||||
:value "Unlocked"}
|
||||
{:key :locked
|
||||
:value "Locked"}]}])
|
||||
|
||||
(defn cool-preview []
|
||||
(let [state (reagent/atom {:big? true
|
||||
:lock-status :none
|
||||
:emoji "🍑"
|
||||
:emoji-background-color :gray})]
|
||||
(fn []
|
||||
[rn/view {:margin-bottom 50
|
||||
:padding 16}
|
||||
[rn/view {:flex 1}
|
||||
[preview/customizer state descriptor]]
|
||||
[rn/view {:padding-vertical 60
|
||||
:flex-direction :row
|
||||
:justify-content :center}
|
||||
[quo2/channel-avatar @state]]])))
|
||||
|
||||
(defn preview-channel-avatar []
|
||||
[rn/view {:background-color (colors/theme-colors colors/white
|
||||
colors/neutral-90)
|
||||
:flex 1}
|
||||
[rn/flat-list {:flex 1
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|
||||
@@ -1,56 +0,0 @@
|
||||
(ns quo2.screens.dividers.new-messages
|
||||
(:require [quo.react-native :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[quo.previews.preview :as preview]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.dividers.new-messages :as new-messages]))
|
||||
|
||||
(def descriptor [{:label "Label"
|
||||
:key :label
|
||||
:type :text}
|
||||
{:label "Color"
|
||||
:key :color
|
||||
:type :select
|
||||
:options [{:key :primary
|
||||
:value "Primary"}
|
||||
{:key :purple
|
||||
:value "Purple"}
|
||||
{:key :indigo
|
||||
:value "Indigo"}
|
||||
{:key :turquoise
|
||||
:value "Turquoise"}
|
||||
{:key :blue
|
||||
:value "Blue"}
|
||||
{:key :green
|
||||
:value "Green"}
|
||||
{:key :yellow
|
||||
:value "yellow"}
|
||||
{:key :orange
|
||||
:value "Orange"}
|
||||
{:key :red
|
||||
:value "Red"}
|
||||
{:key :pink
|
||||
:value "Pink"}
|
||||
{:key :brown
|
||||
:value "Brown"}
|
||||
{:key :beige
|
||||
:value "Beige"}]}])
|
||||
(defn cool-preview []
|
||||
(let [state (reagent/atom {:label "New messages"
|
||||
:color :primary})]
|
||||
(fn []
|
||||
[rn/view {:margin-bottom 50
|
||||
:padding 16}
|
||||
[preview/customizer state descriptor]
|
||||
[rn/view {:padding-vertical 60}
|
||||
[new-messages/new-messages @state]]])))
|
||||
|
||||
(defn preview-new-messages []
|
||||
[rn/view {:background-color (colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-90)
|
||||
:flex 1}
|
||||
[rn/flat-list {:flex 1
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|
||||
@@ -13,7 +13,6 @@
|
||||
[quo2.screens.buttons.button :as button]
|
||||
[quo2.screens.counter.counter :as counter]
|
||||
[quo2.screens.community.community-card-view :as community-card]
|
||||
[quo2.screens.dividers.new-messages :as new-messages]
|
||||
[quo2.screens.info.info-message :as info-message]
|
||||
[quo2.screens.info.information-box :as information-box]
|
||||
[quo2.screens.markdown.text :as text]
|
||||
@@ -30,7 +29,6 @@
|
||||
[quo2.screens.wallet.token-overview :as token-overview]
|
||||
[quo2.screens.list-items.preview-lists :as preview-lists]
|
||||
[quo2.screens.info.lowest-price :as lowest-price]
|
||||
[quo2.screens.avatars.channel-avatar :as channel-avatar]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(def screens-categories
|
||||
@@ -45,10 +43,7 @@
|
||||
:component user-avatar/preview-user-avatar}
|
||||
{:name :wallet-user-avatar
|
||||
:insets {:top false}
|
||||
:component wallet-user-avatar/preview-wallet-user-avatar}
|
||||
{:name :channel-avatar
|
||||
:insets {:top false}
|
||||
:component channel-avatar/preview-channel-avatar}]
|
||||
:component wallet-user-avatar/preview-wallet-user-avatar}]
|
||||
:buttons [{:name :button
|
||||
:insets {:top false}
|
||||
:component button/preview-button}]
|
||||
@@ -58,9 +53,6 @@
|
||||
:counter [{:name :counter
|
||||
:insets {:top false}
|
||||
:component counter/preview-counter}]
|
||||
:dividers [{:name :new-messages
|
||||
:insets {:top false}
|
||||
:component new-messages/preview-new-messages}]
|
||||
:info [{:name :info-message
|
||||
:insets {:top false}
|
||||
:component info-message/preview-info-message}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
(ns status-im.activity-center.core
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.data-store.activities :as data-store.activities]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.utils.fx :as fx]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def notifications-per-page
|
||||
20)
|
||||
|
||||
(def start-or-end-cursor
|
||||
"")
|
||||
|
||||
(defn notifications-group->rpc-method
|
||||
[notifications-group]
|
||||
(if (= notifications-group :notifications-read)
|
||||
"wakuext_readActivityCenterNotifications"
|
||||
"wakuext_unreadActivityCenterNotifications"))
|
||||
|
||||
(defn notifications-read-status->group
|
||||
[status-filter]
|
||||
(if (= status-filter :read)
|
||||
:notifications-read
|
||||
:notifications-unread))
|
||||
|
||||
(fx/defn notifications-fetch
|
||||
[{:keys [db]} cursor notifications-group]
|
||||
(when-not (get-in db [:activity-center notifications-group :loading?])
|
||||
{:db (assoc-in db [:activity-center notifications-group :loading?] true)
|
||||
::json-rpc/call [{:method (notifications-group->rpc-method notifications-group)
|
||||
:params [cursor notifications-per-page]
|
||||
:on-success #(re-frame/dispatch [:activity-center/notifications-fetch-success notifications-group %])
|
||||
:on-error #(re-frame/dispatch [:activity-center/notifications-fetch-error notifications-group %])}]}))
|
||||
|
||||
(fx/defn notifications-fetch-first-page
|
||||
{:events [:activity-center/notifications-fetch-first-page]}
|
||||
[{:keys [db] :as cofx} {:keys [status-filter] :or {status-filter :unread}}]
|
||||
(let [notifications-group (notifications-read-status->group status-filter)]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:activity-center :current-status-filter] status-filter)
|
||||
(update-in [:activity-center notifications-group] dissoc :loading?)
|
||||
(update-in [:activity-center notifications-group] dissoc :data))}
|
||||
(notifications-fetch start-or-end-cursor notifications-group))))
|
||||
|
||||
(fx/defn notifications-fetch-next-page
|
||||
{:events [:activity-center/notifications-fetch-next-page]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [status-filter (get-in db [:activity-center :current-status-filter])
|
||||
notifications-group (notifications-read-status->group status-filter)
|
||||
{:keys [cursor]} (get-in db [:activity-center notifications-group])]
|
||||
(when-not (= cursor start-or-end-cursor)
|
||||
(notifications-fetch cofx cursor notifications-group))))
|
||||
|
||||
(fx/defn notifications-fetch-success
|
||||
{:events [:activity-center/notifications-fetch-success]}
|
||||
[{:keys [db]} notifications-group {:keys [cursor notifications]}]
|
||||
{:db (-> db
|
||||
(update-in [:activity-center notifications-group] dissoc :loading?)
|
||||
(assoc-in [:activity-center notifications-group :cursor] cursor)
|
||||
(update-in [:activity-center notifications-group :data]
|
||||
concat
|
||||
(map data-store.activities/<-rpc notifications)))})
|
||||
|
||||
(fx/defn notifications-fetch-error
|
||||
{:events [:activity-center/notifications-fetch-error]}
|
||||
[{:keys [db]} notifications-group error]
|
||||
(log/warn "Failed to load Activity Center notifications" error)
|
||||
{:db (update-in db [:activity-center notifications-group] dissoc :loading?)})
|
||||
@@ -484,16 +484,4 @@
|
||||
:confirm-button-text (i18n/label :t/delete)
|
||||
:on-accept #(do
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(re-frame/dispatch [:chat.ui/remove-chat chat-id]))}})
|
||||
|
||||
(fx/defn decrease-unviewed-count
|
||||
{:events [:chat/decrease-unviewed-count]}
|
||||
[{:keys [db]} chat-id {:keys [count countWithMentions]}]
|
||||
{:db (-> db
|
||||
;; There might be some other requests being fired,
|
||||
;; so we need to make sure the count has not been set to
|
||||
;; 0 in the meantime
|
||||
(update-in [:chats chat-id :unviewed-messages-count]
|
||||
#(max (- % count) 0))
|
||||
(update-in [:chats chat-id :unviewed-mentions-count]
|
||||
#(max (- % countWithMentions) 0)))})
|
||||
(re-frame/dispatch [:chat.ui/remove-chat chat-id]))}})
|
||||
@@ -1,6 +1,5 @@
|
||||
(ns status-im.chat.models.message
|
||||
(:require [status-im.chat.models :as chat-model]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.chat.models.message-list :as message-list]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.data-store.messages :as data-store.messages]
|
||||
@@ -201,19 +200,13 @@
|
||||
(fx/defn handle-removed-messages
|
||||
{:events [::handle-removed-messages]}
|
||||
[{:keys [db] :as cofx} removed-messages]
|
||||
(let [mark-as-seen-fx (mapv (fn [removed-message]
|
||||
(let [chat-id (:chatId removed-message)
|
||||
message-id (:messageId removed-message)]
|
||||
(data-store.messages/mark-messages-seen chat-id
|
||||
[message-id]
|
||||
#(re-frame/dispatch [:chat/decrease-unviewed-count chat-id %3])))) removed-messages)
|
||||
remove-messages-fx (fn [{:keys [db]}]
|
||||
(let [remove-messages-fx (fn [{:keys [db]}]
|
||||
{:db (reduce (fn [acc current]
|
||||
(update-in acc [:messages (:chatId current)] dissoc (:messageId current)))
|
||||
db removed-messages)
|
||||
:dispatch-n [[:get-activity-center-notifications]
|
||||
[:get-activity-center-notifications-count]]})]
|
||||
(apply fx/merge cofx (conj mark-as-seen-fx remove-messages-fx))))
|
||||
(fx/merge cofx remove-messages-fx)))
|
||||
|
||||
(comment
|
||||
(handle-removed-messages
|
||||
|
||||
@@ -0,0 +1,396 @@
|
||||
(ns status-im.ethereum.abi-spec
|
||||
(:require ["web3-utils" :as utils]
|
||||
[cljs.spec.alpha :as spec]
|
||||
[clojure.string :as string]
|
||||
[status-im.ethereum.core :as ethereum]))
|
||||
|
||||
;; Utility functions for encoding
|
||||
|
||||
(defn right-pad [x]
|
||||
(let [len (count x)
|
||||
to-pad (- 64 (mod len 64))]
|
||||
(if (= 64 to-pad)
|
||||
x
|
||||
(.rightPad utils x (+ len to-pad)))))
|
||||
|
||||
(defn left-pad [x]
|
||||
(let [len (count x)
|
||||
to-pad (- 64 (mod len 64))]
|
||||
(if (= 64 to-pad)
|
||||
x
|
||||
(.leftPad utils x (+ len to-pad)))))
|
||||
|
||||
(defn to-two-complement [x]
|
||||
(when x
|
||||
(subs (.toTwosComplement utils x) 2)))
|
||||
|
||||
(defn utf8-to-hex [x]
|
||||
(when x
|
||||
(subs (ethereum/utf8-to-hex x) 2)))
|
||||
|
||||
(defn hex-to-boolean [x]
|
||||
(= x "0x0"))
|
||||
|
||||
(defn bytes-to-hex [x]
|
||||
(when x
|
||||
(subs (.bytesToHex utils x) 2)))
|
||||
|
||||
(defn number-to-hex [x]
|
||||
(when x
|
||||
(subs (.numberToHex utils x) 2)))
|
||||
|
||||
(defn hex-to-utf8 [x]
|
||||
(ethereum/hex-to-utf8 (str "0x" x)))
|
||||
|
||||
(defn hex-to-number [x]
|
||||
(when x
|
||||
(let [hex-x (str "0x" x)]
|
||||
(try
|
||||
(.hexToNumber utils hex-x)
|
||||
(catch :default _
|
||||
(.hexToNumberString utils hex-x))))))
|
||||
|
||||
(defn is-hex? [value]
|
||||
(when value
|
||||
(string/starts-with? value "0x")))
|
||||
|
||||
;; Encoder for parsed abi spec
|
||||
|
||||
(defmulti enc :type)
|
||||
|
||||
;; bool: as in the uint8 case, where 1 is used for true and 0 for false
|
||||
(defmethod enc :bool
|
||||
[{:keys [value]}]
|
||||
(left-pad (if value "1" "0")))
|
||||
|
||||
;; int<M>: enc(X) is the big-endian two’s complement encoding of X, padded on the
|
||||
;; higher-order (left) side with 0xff for negative X and with zero bytes for
|
||||
;; positive X such that the length is 32 bytes.
|
||||
(defmethod enc :int
|
||||
[{:keys [value]}]
|
||||
(to-two-complement value))
|
||||
|
||||
;; uint<M>: enc(X) is the big-endian encoding of X, padded on the
|
||||
;; higher-order (left) side with zero-bytes such that the length is 32 bytes.
|
||||
(defmethod enc :uint
|
||||
[{:keys [value]}]
|
||||
(left-pad (number-to-hex value)))
|
||||
|
||||
;; address: as in the uint160 case
|
||||
(defmethod enc :address
|
||||
[{:keys [value]}]
|
||||
(when (string? value)
|
||||
(left-pad (string/replace value "0x" ""))))
|
||||
|
||||
;; bytes, of length k (which is assumed to be of type uint256):
|
||||
;; enc(X) = enc(k) pad_right(X), i.e. the number of bytes is encoded as a
|
||||
;; uint256 followed by the actual value of X as a byte sequence,
|
||||
;; followed by the minimum number of zero-bytes such that len(enc(X))
|
||||
;; is a multiple of 32.
|
||||
;; bytes<M>: enc(X) is the sequence of bytes in X padded with trailing
|
||||
;; zero-bytes to a length of 32 bytes.
|
||||
(defmethod enc :bytes
|
||||
[{:keys [value dynamic?]}]
|
||||
;; in the examples of the abi specifications strings are passed for
|
||||
;; bytes parameters, in our ens resolver we pass encoded bytes directly
|
||||
;; for namehash, this handles both cases by checking if the value is already
|
||||
;; hex
|
||||
(let [encoded-value? (is-hex? value)
|
||||
encoded-value (if encoded-value?
|
||||
(subs value 2)
|
||||
(utf8-to-hex value))]
|
||||
(str (when dynamic? (enc {:type :int :value (/ (count encoded-value) 2)}))
|
||||
(right-pad encoded-value))))
|
||||
|
||||
;; string: enc(X) = enc(enc_utf8(X)), i.e. X is utf-8 encoded and this
|
||||
;; value is interpreted as of bytes type and encoded further.
|
||||
;; Note that the length used in this subsequent encoding is the number
|
||||
;; of bytes of the utf-8 encoded string, not its number of characters.
|
||||
(defmethod enc :string
|
||||
[{:keys [value dynamic?]}]
|
||||
(enc {:type :bytes :value value :dynamic? dynamic?}))
|
||||
|
||||
;; fixed<M>x<N>: enc(X) is enc(X * 10**N) where X * 10**N is
|
||||
;; interpreted as a int256.
|
||||
(defmethod enc :fixed
|
||||
[{:keys [value power]
|
||||
:or {power 18}}]
|
||||
(enc {:type :int
|
||||
:value (* value (Math/pow 10 power))}))
|
||||
|
||||
;; ufixed: as in the ufixed128x18 case
|
||||
(defmethod enc :ufixed
|
||||
[{:keys [value power]
|
||||
:or {power 18}}]
|
||||
(enc {:type :uint
|
||||
:value (* value (Math/pow 10 power))}))
|
||||
|
||||
;; T[k] for any T and k:
|
||||
;; enc(X) = enc((X[0], ..., X[k-1]))
|
||||
;; i.e. it is encoded as if it were a tuple with k elements of the same type.
|
||||
|
||||
;; T[] where X has k elements (k is assumed to be of type uint256):
|
||||
;; enc(X) = enc(k) enc([X[0], ..., X[k-1]])
|
||||
;; i.e. it is encoded as if it were an array of static size k,
|
||||
;; prefixed with the number of elements.
|
||||
(defmethod enc :array
|
||||
[{:keys [value dynamic? array-of]}]
|
||||
(str (when dynamic?
|
||||
(enc {:type :int
|
||||
:value (count value)}))
|
||||
(enc {:type :tuple
|
||||
:value (map #(assoc array-of :value %)
|
||||
value)})))
|
||||
|
||||
;; (T1,...,Tk) for k >= 0 and any types T1, …, Tk
|
||||
;; enc(X) = head(X(1)) ... head(X(k)) tail(X(1)) ... tail(X(k))
|
||||
;; where X = (X(1), ..., X(k))
|
||||
|
||||
;; for Ti being static type:
|
||||
;; head(X(i)) = enc(X(i))
|
||||
;; tail(X(i)) = "" (the empty string)
|
||||
|
||||
;; for dynamic types:
|
||||
;; head(X(i)) = enc(len(head(X(1)) ... head(X(k))
|
||||
;; tail(X(1)) ... tail(X(i-1)) ))
|
||||
;; tail(X(i)) = enc(X(i))
|
||||
|
||||
;; Note that in the dynamic case, head(X(i)) is well-defined since
|
||||
;; the lengths of the head parts only depend on the types and not
|
||||
;; the values. Its value is the offset of the beginning of tail(X(i))
|
||||
;; relative to the start of enc(X).
|
||||
(defmethod enc :tuple
|
||||
[{:keys [value]}]
|
||||
(let [[len x] (reduce
|
||||
(fn [[len acc] {:keys [dynamic?] :as x}]
|
||||
(let [enc-x (enc x)]
|
||||
(if dynamic?
|
||||
[(+ len 32)
|
||||
(conj acc (assoc x :tail enc-x))]
|
||||
[(+ len (/ (count enc-x) 2))
|
||||
(conj acc (assoc x :head enc-x))])))
|
||||
[0 []]
|
||||
value)
|
||||
[_ heads tails] (reduce (fn [[len heads tails] {:keys [head tail]}]
|
||||
(if tail
|
||||
[(+ len (/ (count tail) 2))
|
||||
(conj heads (enc {:type :int :value len}))
|
||||
(conj tails tail)]
|
||||
[len
|
||||
(conj heads head)
|
||||
tails]))
|
||||
[len [] []]
|
||||
x)]
|
||||
(apply str (concat heads tails))))
|
||||
|
||||
;;
|
||||
;; Parser for method signatures
|
||||
;;
|
||||
|
||||
(spec/def ::params (spec/* (spec/cat ::param ::param
|
||||
::separator (spec/? ::comma))))
|
||||
|
||||
(spec/def ::param (spec/cat ::type ::string
|
||||
::size (spec/? ::number)
|
||||
::x (spec/? ::x)
|
||||
::power (spec/? ::number)
|
||||
::array (spec/* ::array)))
|
||||
|
||||
(spec/def ::array (spec/cat ::open-bracket ::open-bracket
|
||||
::size (spec/? ::number)
|
||||
::close-bracket ::close-bracket))
|
||||
|
||||
(spec/def ::x #{\x})
|
||||
|
||||
(spec/def ::open-bracket #{\[})
|
||||
|
||||
(spec/def ::close-bracket #{\]})
|
||||
|
||||
(spec/def ::comma #{\,})
|
||||
|
||||
(spec/def ::number int?)
|
||||
|
||||
(spec/def ::string string?)
|
||||
|
||||
(defn- single-char [code]
|
||||
(when-let [m (#{\, \[ \] \x} (first code))]
|
||||
[1 m]))
|
||||
|
||||
(defn- number [code]
|
||||
(when-let [m (re-find #"^[0-9]+" code)]
|
||||
[(count m) (js/parseInt m)]))
|
||||
|
||||
(defn- string [s]
|
||||
(when-let [m (re-find #"^[a-z]+" s)]
|
||||
[(count m) m]))
|
||||
|
||||
(defn tokenise [code]
|
||||
(when (seq code)
|
||||
(if-let [[len token] (or (string code)
|
||||
(single-char code)
|
||||
(number code))]
|
||||
(cons token (tokenise (subs code len)))
|
||||
(throw (ex-info "Unexpected token" {:code code})))))
|
||||
|
||||
;; Definition: The following types are called “dynamic”:
|
||||
;; - bytes
|
||||
;; - string
|
||||
;; - T[] for any T
|
||||
;; - T[k] for any dynamic T and any k >= 0
|
||||
;; - (T1,...,Tk) if Ti is dynamic for some 1 <= i <= k
|
||||
(defn parse-param
|
||||
"Takes a parsed parameter and returns a parameter that can
|
||||
be encoded by associng the :dynamic? key for dynamic parameters
|
||||
and recursively defining arrays"
|
||||
[{::keys [type size array power] :as param}]
|
||||
(if array
|
||||
(let [{::keys [size]} (last array)]
|
||||
{:type :array
|
||||
:dynamic? (nil? size)
|
||||
:array-of (parse-param (update param ::array butlast))})
|
||||
(let [type (keyword type)
|
||||
param {:type type
|
||||
:dynamic? (or (= type :string)
|
||||
(and (= type :bytes)
|
||||
(nil? size)))
|
||||
:size size}]
|
||||
(if power
|
||||
(assoc param :power power)
|
||||
param))))
|
||||
|
||||
(defn parse-params [method-signature]
|
||||
(let [tokens (tokenise (second (re-find #"\((.*)\)" method-signature)))
|
||||
params (spec/conform ::params tokens)]
|
||||
(if (spec/invalid? params)
|
||||
(spec/explain-data ::params tokens)
|
||||
(map #(parse-param (::param %))
|
||||
params))))
|
||||
|
||||
(defn signature->method-id [signature]
|
||||
(apply str (take 10 (ethereum/sha3 signature))))
|
||||
|
||||
(defn encode [method params]
|
||||
(let [method-id (signature->method-id method)
|
||||
params (map #(assoc %1 :value %2)
|
||||
(parse-params method)
|
||||
params)]
|
||||
(str method-id (enc {:type :tuple
|
||||
:value params}))))
|
||||
|
||||
;; ======= decode
|
||||
|
||||
(defn substr [val s l]
|
||||
(subs val s (+ s l)))
|
||||
|
||||
;; "[]" -> 0 , "[1]" -> 1
|
||||
(defn arr-size [val]
|
||||
(int (apply str (rest (butlast val)))))
|
||||
|
||||
;; [2] -> 2 , [1] -> 1 , [] - > 1
|
||||
(defn nested-size [val]
|
||||
(let [num (arr-size val)]
|
||||
(if (zero? num) 1 num)))
|
||||
|
||||
;; '("[1]" "[]") or nil
|
||||
(defn list-of-nested-types [type]
|
||||
(when-let [res (re-seq #"(\[[0-9]*\])" type)]
|
||||
(map first res)))
|
||||
|
||||
(defn nested-name [type]
|
||||
(let [ntypes (list-of-nested-types type)]
|
||||
(if ntypes
|
||||
(subs type 0 (- (count type) (count (last ntypes))))
|
||||
type)))
|
||||
|
||||
(defn is-arr? [type]
|
||||
(boolean (list-of-nested-types type)))
|
||||
|
||||
(defn is-dynamic-arr? [type]
|
||||
(let [ntypes (list-of-nested-types type)]
|
||||
(and ntypes (zero? (arr-size (last ntypes))))))
|
||||
|
||||
(defn static-arr-len [type]
|
||||
(let [ntypes (list-of-nested-types type)]
|
||||
(if ntypes
|
||||
(nested-size (last ntypes))
|
||||
1)))
|
||||
|
||||
(defn static-part-length [type]
|
||||
(apply * (conj (map nested-size (or (list-of-nested-types type) '("1"))) 32)))
|
||||
|
||||
(defn offset-reducer [{:keys [cnt coll]} val]
|
||||
(let [cnt' (+ cnt val)]
|
||||
{:cnt cnt'
|
||||
:coll (conj coll cnt')}))
|
||||
|
||||
(defn get-offsets [types]
|
||||
(let [lengths (map static-part-length types)]
|
||||
(conj (butlast (:coll (reduce offset-reducer {:cnt 0 :coll []} lengths))) 0)))
|
||||
|
||||
(defn hex-to-bytes [hex]
|
||||
(let [number (hex-to-number (subs hex 0 64))
|
||||
len (* (if (nil? number) 0 number) 2)]
|
||||
(substr hex 64 len)))
|
||||
|
||||
(defn dyn-hex-to-value [hex type]
|
||||
(cond
|
||||
(string/starts-with? type "bytes")
|
||||
(str "0x" (hex-to-bytes hex))
|
||||
|
||||
(string/starts-with? type "string")
|
||||
(hex-to-utf8 (hex-to-bytes hex))))
|
||||
|
||||
(defn hex-to-bytesM [hex type]
|
||||
(let [size (int (second (re-matches #"^bytes([0-9]*)" type)))]
|
||||
(subs hex 0 (* 2 size))))
|
||||
|
||||
(defn hex-to-value [hex type]
|
||||
(cond
|
||||
(= "bool" type) (= hex "0000000000000000000000000000000000000000000000000000000000000001")
|
||||
(string/starts-with? type "uint") (hex-to-number hex)
|
||||
(string/starts-with? type "int") (hex-to-number hex)
|
||||
(string/starts-with? type "address") (str "0x" (subs hex (- (count hex) 40)))
|
||||
(string/starts-with? type "bytes") (hex-to-bytesM hex type)))
|
||||
|
||||
(defn dec-type [bytes]
|
||||
(fn [offset type]
|
||||
(cond
|
||||
(is-arr? type)
|
||||
|
||||
(let [dyn-arr? (is-dynamic-arr? type)
|
||||
arr-off (js/parseInt (str "0x" (substr bytes (* offset 2) 64)))
|
||||
len (if dyn-arr?
|
||||
(js/parseInt (str "0x" (substr bytes (* arr-off 2) 64)))
|
||||
(static-arr-len type))
|
||||
arr-start (if dyn-arr? (+ arr-off 32) offset)
|
||||
|
||||
nname (nested-name type)
|
||||
nstatpartlen (static-part-length nname)
|
||||
rnstatpartlen (* (js/Math.floor (/ (+ nstatpartlen 31) 32)) 32)]
|
||||
(loop [res [] i 0]
|
||||
(if (>= i (* len rnstatpartlen))
|
||||
res
|
||||
(recur (conj res ((dec-type bytes) (+ arr-start i) nname)) (+ i rnstatpartlen)))))
|
||||
|
||||
(or (re-matches #"^bytes(\[([0-9]*)\])*$" type)
|
||||
(string/starts-with? type "string"))
|
||||
|
||||
(let [dyn-off (js/parseInt (str "0x" (substr bytes (* offset 2) 64)))
|
||||
len (js/parseInt (str "0x" (substr bytes (* dyn-off 2) 64)))
|
||||
rlen (js/Math.floor (/ (+ len 31) 32))
|
||||
val (substr bytes (* dyn-off 2) (* (+ rlen 1) 64))]
|
||||
(dyn-hex-to-value val type))
|
||||
|
||||
:else
|
||||
|
||||
(let [len (static-part-length type)
|
||||
val (substr bytes (* offset 2) (* len 2))]
|
||||
(hex-to-value val type)))))
|
||||
|
||||
(defn decode [bytes types]
|
||||
(when bytes
|
||||
(let [bytes (subs bytes 2)]
|
||||
(when-not (empty? bytes)
|
||||
(let [offsets (get-offsets types)]
|
||||
(map #(when-not (= "0x" %) %)
|
||||
(map (dec-type bytes) offsets types)))))))
|
||||
@@ -0,0 +1,69 @@
|
||||
(ns status-im.ethereum.abi-spec-test
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.ethereum.abi-spec :as abi-spec]))
|
||||
|
||||
(deftest hex-to-number
|
||||
(testing "hex number is less than 53 bits, it returns a number")
|
||||
(is (= (abi-spec/hex-to-number "9")
|
||||
9))
|
||||
(is (= (abi-spec/hex-to-number "99999999")
|
||||
2576980377))
|
||||
(testing "hex number is less than 53 bits, it returns a string")
|
||||
(is (= (abi-spec/hex-to-number "9999999999999999")
|
||||
"11068046444225730969")))
|
||||
|
||||
(deftest enc
|
||||
(is (= "000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" (abi-spec/enc {:type :address :value "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}))))
|
||||
|
||||
(deftest test-encode
|
||||
(is (= (abi-spec/encode "baz(uint32,bool)" [69 true])
|
||||
"0xcdcd77c000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001"))
|
||||
|
||||
(is (= (abi-spec/encode "bar(bytes3[2])" [["abc" "def"]])
|
||||
"0xfce353f661626300000000000000000000000000000000000000000000000000000000006465660000000000000000000000000000000000000000000000000000000000"))
|
||||
|
||||
(is (= (abi-spec/encode "sam(bytes,bool,uint256[])" ["dave" true [1 2 3]])
|
||||
"0xa5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003"))
|
||||
|
||||
(is (= (abi-spec/encode "f(uint256,uint32[],bytes10,bytes)" [0x123 [0x456 0x789] "1234567890" "Hello, world!"])
|
||||
"0x8be6524600000000000000000000000000000000000000000000000000000000000001230000000000000000000000000000000000000000000000000000000000000080313233343536373839300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004560000000000000000000000000000000000000000000000000000000000000789000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20776f726c642100000000000000000000000000000000000000"))
|
||||
|
||||
(is (= (abi-spec/encode "g(uint[][],string[])" [[[1 2] [3]] ["one" "two" "three"]])
|
||||
"0xad6a3446000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000036f6e650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000374776f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057468726565000000000000000000000000000000000000000000000000000000"))
|
||||
|
||||
(is (= (abi-spec/encode "getExpectedRate(address,address,uint256)" ["0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" 1000])
|
||||
"0x809a9e55000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000003e8")))
|
||||
|
||||
(deftest test-decode
|
||||
(is (= (abi-spec/decode "0x000000000000000000000000000000000000000000000000000000005bc741cd00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000013b86dbf1a83c9e6a492914a0ee39e8a5b7eb60700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d533152484e4a57414b356e426f6f57454d34654d644268707a35666e325764557473457357754a4b79356147000000000000000000000000000000000000"
|
||||
["uint256" "bytes" "address" "uint256" "uint256"])
|
||||
'(1539785165
|
||||
"0x516d533152484e4a57414b356e426f6f57454d34654d644268707a35666e325764557473457357754a4b79356147"
|
||||
"0x13b86dbf1a83c9e6a492914a0ee39e8a5b7eb607"
|
||||
0
|
||||
0)))
|
||||
|
||||
(is (= (abi-spec/decode "0x0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000d7621dc58210001"
|
||||
["uint256" "uint256"])
|
||||
'("1000000000000000000" "970000000000000001")))
|
||||
|
||||
(is (= (abi-spec/decode "0x000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000003e8"
|
||||
["address" "address" "uint256"])
|
||||
'("0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" 1000)))
|
||||
|
||||
(is (= (abi-spec/decode "0x00000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001"
|
||||
["uint32" "bool"])
|
||||
'(69 true)))
|
||||
|
||||
(is (= (map abi-spec/hex-to-utf8
|
||||
(first (abi-spec/decode "0x61626300000000000000000000000000000000000000000000000000000000006465660000000000000000000000000000000000000000000000000000000000"
|
||||
["bytes3[2]"])))
|
||||
'("abc" "def")))
|
||||
|
||||
(is (= (abi-spec/decode "0x0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003"
|
||||
["string" "bool" "uint256[]"])
|
||||
'("dave" true [1 2 3])))
|
||||
|
||||
(is (= (abi-spec/decode "0x00000000000000000000000000000000000000000000000000000000000001230000000000000000000000000000000000000000000000000000000000000080313233343536373839300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004560000000000000000000000000000000000000000000000000000000000000789000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20776f726c642100000000000000000000000000000000000000"
|
||||
["uint" "uint32[]" "bytes10" "bytes"])
|
||||
'(291 [1110 1929] "31323334353637383930" "0x48656c6c6f2c20776f726c6421"))))
|
||||
@@ -1,8 +1,10 @@
|
||||
(ns status-im.ethereum.decode
|
||||
(:require [status-im.utils.money :as money]))
|
||||
(:require [status-im.ethereum.abi-spec :as abi-spec]))
|
||||
|
||||
(defn uint
|
||||
[hex]
|
||||
(let [n (money/bignumber hex)]
|
||||
(when n
|
||||
(.toString n 10))))
|
||||
(first (abi-spec/decode hex ["uint"])))
|
||||
|
||||
(defn string
|
||||
[hex]
|
||||
(first (abi-spec/decode hex ["string"])))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns status-im.ethereum.ens
|
||||
(:require [clojure.string :as string]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.native-module.core :as status]))
|
||||
[status-im.ethereum.abi-spec :as abi-spec]))
|
||||
|
||||
;; this is the addresses of ens registries for the different networks
|
||||
(def ens-registries
|
||||
@@ -65,7 +65,7 @@
|
||||
:params [chain-id ens-name]
|
||||
:on-success
|
||||
;;NOTE: returns a timestamp in s and we want ms
|
||||
#(cb (* (js/Number (status/hex-to-number %)) 1000))}))
|
||||
#(cb (* (js/Number (abi-spec/hex-to-number %)) 1000))}))
|
||||
|
||||
(defn register-prepare-tx
|
||||
[chain-id from ens-name pubkey cb]
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
[status-im.native-module.core :as status]
|
||||
[status-im.navigation :as navigation]
|
||||
status-im.notifications-center.core
|
||||
status-im.activity-center.core
|
||||
status-im.pairing.core
|
||||
[status-im.popover.core :as popover]
|
||||
status-im.profile.core
|
||||
|
||||
@@ -126,15 +126,12 @@
|
||||
(fx/defn intro-wizard
|
||||
{:events [:multiaccounts.create.ui/intro-wizard]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [accs (get db :multiaccounts/multiaccounts)]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(update :keycard dissoc :flow)
|
||||
(dissoc :restored-account?))}
|
||||
(multiaccounts.create/prepare-intro-wizard)
|
||||
(if (pos? (count accs))
|
||||
(navigation/navigate-to-cofx :get-your-keys nil)
|
||||
(navigation/set-stack-root :onboarding [:get-your-keys])))))
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(update :keycard dissoc :flow)
|
||||
(dissoc :restored-account?))}
|
||||
(multiaccounts.create/prepare-intro-wizard)
|
||||
(navigation/set-stack-root :onboarding [:get-your-keys])))
|
||||
|
||||
(fx/defn recovery-no-key
|
||||
{:events [:keycard.recovery.no-key.ui/generate-key-pressed]}
|
||||
|
||||
@@ -315,14 +315,14 @@
|
||||
:on-error reject})))
|
||||
(js/Promise.
|
||||
(fn [resolve reject]
|
||||
(json-rpc/call {:method "wallet_getSavedAddresses"
|
||||
(json-rpc/call {:method "wallet_getFavourites"
|
||||
:on-success resolve
|
||||
:on-error reject})))]))
|
||||
(.then (fn [[accounts tokens custom-tokens favourites]]
|
||||
(callback accounts
|
||||
(normalize-tokens network-id tokens)
|
||||
(mapv #(update % :symbol keyword) custom-tokens)
|
||||
(filter :favourite favourites))))
|
||||
favourites)))
|
||||
(.catch (fn [_]
|
||||
(log/error "Failed to initialize wallet"))))))
|
||||
|
||||
|
||||
@@ -391,33 +391,6 @@
|
||||
(log/debug "[native-module] identicon")
|
||||
(.identicon ^js (status) seed))
|
||||
|
||||
(defn encode-transfer
|
||||
[to-norm amount-hex]
|
||||
(log/debug "[native-module] encode-transfer")
|
||||
(.encodeTransfer ^js (status) to-norm amount-hex))
|
||||
|
||||
(defn encode-function-call
|
||||
[method params]
|
||||
(log/debug "[native-module] encode-function-call")
|
||||
(.encodeFunctionCall ^js (status) method (types/clj->json params)))
|
||||
|
||||
(defn decode-parameters
|
||||
[bytes-string types]
|
||||
(log/debug "[native-module] decode-parameters")
|
||||
(let [json-str (.decodeParameters ^js (status) (types/clj->json {:bytesString bytes-string :types types}))]
|
||||
(types/json->clj json-str)))
|
||||
|
||||
(defn hex-to-number
|
||||
[hex]
|
||||
(log/debug "[native-module] hex-to-number")
|
||||
(let [json-str (.hexToNumber ^js (status) hex)]
|
||||
(types/json->clj json-str)))
|
||||
|
||||
(defn number-to-hex
|
||||
[num]
|
||||
(log/debug "[native-module] number-to-hex")
|
||||
(.numberToHex ^js (status) (str num)))
|
||||
|
||||
(defn identicon-async
|
||||
"Generate a icon based on a string, asynchronously"
|
||||
[seed callback]
|
||||
|
||||
@@ -70,7 +70,6 @@
|
||||
"mailserver.available" (mailserver/handle-mailserver-available cofx (.-id event-js))
|
||||
"mailserver.not.working" (mailserver/handle-mailserver-not-working cofx)
|
||||
"discovery.summary" (summary cofx (js->clj event-js :keywordize-keys true))
|
||||
"mediaserver.started" {:db (assoc db :mediaserver/port (.-port event-js))}
|
||||
"wakuv2.peerstats" (wakuv2-peer-stats cofx (js->clj event-js :keywordize-keys true))
|
||||
"messages.new" (transport.message/sanitize-messages-and-process-response cofx event-js true)
|
||||
"wallet" (ethereum.subscriptions/new-wallet-event cofx (js->clj event-js :keywordize-keys true))
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ethereum.abi-spec :as abi-spec]
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.ethereum.eip55 :as eip55]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
@@ -104,16 +105,16 @@
|
||||
(sign-message cofx)
|
||||
(let [tx-obj-to-send (merge tx-obj
|
||||
(when gas
|
||||
{:gas (str "0x" (status/number-to-hex gas))})
|
||||
{:gas (str "0x" (abi-spec/number-to-hex gas))})
|
||||
(when gasPrice
|
||||
{:gasPrice (str "0x" (status/number-to-hex gasPrice))})
|
||||
{:gasPrice (str "0x" (abi-spec/number-to-hex gasPrice))})
|
||||
(when nonce
|
||||
{:nonce (str "0x" (status/number-to-hex nonce))})
|
||||
{:nonce (str "0x" (abi-spec/number-to-hex nonce))})
|
||||
(when maxPriorityFeePerGas
|
||||
{:maxPriorityFeePerGas (str "0x" (status/number-to-hex
|
||||
{:maxPriorityFeePerGas (str "0x" (abi-spec/number-to-hex
|
||||
(js/parseInt maxPriorityFeePerGas)))})
|
||||
(when maxFeePerGas
|
||||
{:maxFeePerGas (str "0x" (status/number-to-hex
|
||||
{:maxFeePerGas (str "0x" (abi-spec/number-to-hex
|
||||
(js/parseInt maxFeePerGas)))}))]
|
||||
(when-not in-progress?
|
||||
{:db (update db :signing/sign assoc :error nil :in-progress? true)
|
||||
@@ -173,7 +174,7 @@
|
||||
(let [{:keys [symbol decimals] :as token} (tokens/address->token (:wallet/all-tokens db) to)]
|
||||
(when (and token data (string? data))
|
||||
(when-let [type (get-method-type data)]
|
||||
(let [[address value _] (status/decode-parameters
|
||||
(let [[address value _] (abi-spec/decode
|
||||
(str "0x" (subs data 10))
|
||||
(if (= type :approve-and-call) ["address" "uint256" "bytes"] ["address" "uint256"]))]
|
||||
(when (and address value)
|
||||
@@ -448,7 +449,7 @@
|
||||
{:events [:wallet.ui/sign-transaction-button-clicked-from-chat]}
|
||||
[{:keys [db] :as cofx} {:keys [to amount from token]}]
|
||||
(let [{:keys [symbol address]} token
|
||||
amount-hex (str "0x" (status/number-to-hex amount))
|
||||
amount-hex (str "0x" (abi-spec/number-to-hex amount))
|
||||
to-norm (ethereum/normalized-hex (if (string? to) to (:address to)))
|
||||
from-address (:address from)
|
||||
identity (:current-chat-id db)
|
||||
@@ -467,7 +468,9 @@
|
||||
:from from-address
|
||||
:chat-id identity
|
||||
:command? true
|
||||
:data (status/encode-transfer to-norm amount-hex)})}))
|
||||
:data (abi-spec/encode
|
||||
"transfer(address,uint256)"
|
||||
[to-norm amount-hex])})}))
|
||||
{:db db
|
||||
::json-rpc/call
|
||||
[{:method "wakuext_requestAddressForTransaction"
|
||||
@@ -484,7 +487,7 @@
|
||||
[{:keys [db] :as cofx} {:keys [amount from token]}]
|
||||
(let [{:keys [request-parameters chat-id]} (:wallet/prepare-transaction db)
|
||||
{:keys [symbol address]} token
|
||||
amount-hex (str "0x" (status/number-to-hex amount))
|
||||
amount-hex (str "0x" (abi-spec/number-to-hex amount))
|
||||
to-norm (:address request-parameters)
|
||||
from-address (:address from)]
|
||||
(fx/merge cofx
|
||||
@@ -504,13 +507,15 @@
|
||||
:command? true
|
||||
:message-id (:id request-parameters)
|
||||
:chat-id chat-id
|
||||
:data (status/encode-transfer to-norm amount-hex)})})))))
|
||||
:data (abi-spec/encode
|
||||
"transfer(address,uint256)"
|
||||
[to-norm amount-hex])})})))))
|
||||
|
||||
(fx/defn sign-transaction-button-clicked
|
||||
{:events [:wallet.ui/sign-transaction-button-clicked]}
|
||||
[{:keys [db] :as cofx} {:keys [to amount from token gas gasPrice maxFeePerGas maxPriorityFeePerGas]}]
|
||||
(let [{:keys [symbol address]} token
|
||||
amount-hex (str "0x" (status/number-to-hex amount))
|
||||
amount-hex (str "0x" (abi-spec/number-to-hex amount))
|
||||
to-norm (ethereum/normalized-hex (if (string? to) to (:address to)))
|
||||
from-address (:address from)]
|
||||
(fx/merge cofx
|
||||
@@ -530,7 +535,9 @@
|
||||
{:to to-norm
|
||||
:value amount-hex}
|
||||
{:to (ethereum/normalized-hex address)
|
||||
:data (status/encode-transfer to-norm amount-hex)}))}))))
|
||||
:data (abi-spec/encode
|
||||
"transfer(address,uint256)"
|
||||
[to-norm amount-hex])}))}))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:signing/get-transaction-by-hash-fx
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
(ns status-im.signing.core-test
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.signing.core :as signing]
|
||||
[status-im.native-module.core :as status]))
|
||||
[status-im.ethereum.abi-spec :as abi-spec]))
|
||||
|
||||
(deftest signing-test
|
||||
(testing "showing sheet"
|
||||
(let [to "0x2f88d65f3cb52605a54a833ae118fb1363acccd2"
|
||||
contract "0xc55cf4b03948d7ebc8b9e8bad92643703811d162"
|
||||
amount1-hex (str "0x" (status/number-to-hex "10000000000000000000"))
|
||||
amount2-hex (str "0x" (status/number-to-hex "100000000000000000000"))
|
||||
data (status/encode-transfer to amount2-hex)
|
||||
amount1-hex (str "0x" (abi-spec/number-to-hex "10000000000000000000"))
|
||||
amount2-hex (str "0x" (abi-spec/number-to-hex "100000000000000000000"))
|
||||
data (abi-spec/encode "transfer(address,uint256)" [to amount2-hex])
|
||||
first-tx {:tx-obj {:to to
|
||||
:from nil
|
||||
:value amount1-hex}}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns status-im.signing.keycard
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ethereum.abi-spec :as abi-spec]
|
||||
[status-im.native-module.core :as status]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
@@ -35,15 +36,15 @@
|
||||
:message-id message-id
|
||||
:command? command?}
|
||||
maxPriorityFeePerGas
|
||||
(assoc :maxPriorityFeePerGas (str "0x" (status/number-to-hex
|
||||
(assoc :maxPriorityFeePerGas (str "0x" (abi-spec/number-to-hex
|
||||
(js/parseInt maxPriorityFeePerGas))))
|
||||
maxFeePerGas
|
||||
(assoc :maxFeePerGas (str "0x" (status/number-to-hex
|
||||
(assoc :maxFeePerGas (str "0x" (abi-spec/number-to-hex
|
||||
(js/parseInt maxFeePerGas))))
|
||||
gas
|
||||
(assoc :gas (str "0x" (status/number-to-hex gas)))
|
||||
(assoc :gas (str "0x" (abi-spec/number-to-hex gas)))
|
||||
gasPrice
|
||||
(assoc :gasPrice (str "0x" (status/number-to-hex gasPrice)))
|
||||
(assoc :gasPrice (str "0x" (abi-spec/number-to-hex gasPrice)))
|
||||
data
|
||||
(assoc :data data)
|
||||
nonce
|
||||
|
||||
+12
-101
@@ -41,8 +41,7 @@
|
||||
[status-im.utils.money :as money]
|
||||
[status-im.utils.security :as security]
|
||||
[status-im.wallet.db :as wallet.db]
|
||||
[status-im.wallet.utils :as wallet.utils]
|
||||
[status-im.utils.image-server :as image-server]))
|
||||
[status-im.wallet.utils :as wallet.utils]))
|
||||
|
||||
;; TOP LEVEL ===========================================================================================================
|
||||
|
||||
@@ -268,9 +267,6 @@
|
||||
(reg-root-key-sub :wallet-connect/session-managed :wallet-connect/session-managed)
|
||||
(reg-root-key-sub :contact-requests/pending :contact-requests/pending)
|
||||
|
||||
; media-server
|
||||
(reg-root-key-sub :mediaserver/port :mediaserver/port)
|
||||
|
||||
; Testing
|
||||
|
||||
(reg-root-key-sub :messenger/started? :messenger/started?)
|
||||
@@ -1307,27 +1303,15 @@
|
||||
(re-frame/reg-sub
|
||||
:chats/photo-path
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:profile/multiaccount]
|
||||
:<- [:mediaserver/port]
|
||||
(fn [[contacts multiaccount port] [_ id]]
|
||||
(let [contact (or (get contacts id)
|
||||
(when (= id (:public-key multiaccount))
|
||||
multiaccount))]
|
||||
(if (nil? contact)
|
||||
(image-server/get-identicons-uri port id)
|
||||
(multiaccounts/displayed-photo contact)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/name-and-photo
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:multiaccount]
|
||||
(fn [[contacts multiaccount] [_ id]]
|
||||
(fn [[contacts multiaccount] [_ id identicon]]
|
||||
(let [contact (or (get contacts id)
|
||||
(when (= id (:public-key multiaccount))
|
||||
multiaccount)
|
||||
(contact.db/public-key->new-contact id))]
|
||||
{:name (multiaccounts/displayed-name contact)
|
||||
:photo (multiaccounts/displayed-photo contact)})))
|
||||
(if (not (string/blank? identicon))
|
||||
{:identicon identicon}
|
||||
(contact.db/public-key->new-contact id)))]
|
||||
(multiaccounts/displayed-photo contact))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/unread-messages-number
|
||||
@@ -1951,31 +1935,6 @@
|
||||
|
||||
;;ACTIVITY CENTER NOTIFICATIONS ========================================================================================
|
||||
|
||||
(re-frame/reg-sub
|
||||
:activity-center/notifications-read
|
||||
(fn [db]
|
||||
(get-in db [:activity-center :notifications-read :data])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:activity-center/notifications-unread
|
||||
(fn [db]
|
||||
(get-in db [:activity-center :notifications-unread :data])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:activity-center/current-status-filter
|
||||
(fn [db]
|
||||
(get-in db [:activity-center :current-status-filter])))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:activity-center/notifications-per-read-status
|
||||
:<- [:activity-center/notifications-read]
|
||||
:<- [:activity-center/notifications-unread]
|
||||
:<- [:activity-center/current-status-filter]
|
||||
(fn [[notifications-read notifications-unread status-filter]]
|
||||
(if (= status-filter :unread)
|
||||
notifications-unread
|
||||
notifications-read)))
|
||||
|
||||
(defn- group-notifications-by-date
|
||||
[notifications]
|
||||
(->> notifications
|
||||
@@ -2336,34 +2295,13 @@
|
||||
(fn [multiaccount]
|
||||
(get multiaccount :profile-pictures-visibility)))
|
||||
|
||||
(defn- replace-contact-image-uri [contact port identity]
|
||||
(let [identicon (image-server/get-identicons-uri port identity)
|
||||
contact-images (:images contact)
|
||||
contact-images (reduce (fn [acc image] (let [image-name (:type image)
|
||||
; We pass the clock so that we reload the image if the image is updated
|
||||
clock (:clock image)
|
||||
uri (image-server/get-contact-image-uri port identity image-name clock)]
|
||||
(assoc-in acc [(keyword image-name) :uri] uri)))
|
||||
contact-images
|
||||
(vals contact-images))]
|
||||
(assoc contact :identicon identicon :images contact-images)))
|
||||
|
||||
(defn- reduce-contacts-image-uri [contacts port]
|
||||
(reduce-kv (fn [acc public-key contact]
|
||||
(let [contact (replace-contact-image-uri contact port public-key)]
|
||||
(assoc acc public-key contact)))
|
||||
{}
|
||||
contacts))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contacts
|
||||
:<- [::contacts]
|
||||
:<- [::profile-pictures-visibility]
|
||||
:<- [:multiaccount/public-key]
|
||||
:<- [:mediaserver/port]
|
||||
(fn [[contacts profile-pictures-visibility public-key port]]
|
||||
(let [contacts (contact.db/enrich-contacts contacts profile-pictures-visibility public-key)]
|
||||
(reduce-contacts-image-uri contacts port))))
|
||||
(fn [[contacts profile-pictures-visibility public-key]]
|
||||
(contact.db/enrich-contacts contacts profile-pictures-visibility public-key)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/active
|
||||
@@ -2423,21 +2361,15 @@
|
||||
(string/lower-case search-filter))
|
||||
contacts)))))
|
||||
|
||||
(defn- enrich-contact [_ identity ens-name port]
|
||||
(let [contact (contact.db/enrich-contact
|
||||
(contact.db/public-key-and-ens-name->new-contact identity ens-name))]
|
||||
(replace-contact-image-uri contact port identity)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/current-contact
|
||||
:<- [:contacts/contacts]
|
||||
:<- [:contacts/current-contact-identity]
|
||||
:<- [:contacts/current-contact-ens-name]
|
||||
:<- [:mediaserver/port]
|
||||
(fn [[contacts identity ens-name port]]
|
||||
(let [contact (get contacts identity)]
|
||||
(cond-> contact
|
||||
(nil? contact) (enrich-contact identity ens-name port)))))
|
||||
(fn [[contacts identity ens-name]]
|
||||
(or (get contacts identity)
|
||||
(contact.db/enrich-contact
|
||||
(contact.db/public-key-and-ens-name->new-contact identity ens-name)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contact-by-identity
|
||||
@@ -3048,27 +2980,6 @@
|
||||
(fn [multiaccount]
|
||||
(pos? (count (get multiaccount :images)))))
|
||||
|
||||
(defn- replace-multiaccount-image-uri [multiaccount port]
|
||||
(let [public-key (:public-key multiaccount)
|
||||
identicon (image-server/get-identicons-uri port public-key)
|
||||
multiaccount (assoc multiaccount :identicon identicon)
|
||||
images (:images multiaccount)
|
||||
images (reduce (fn [acc current]
|
||||
(let [key-uid (:keyUid current)
|
||||
image-name (:type current)
|
||||
uri (image-server/get-account-image-uri port public-key image-name key-uid)]
|
||||
(conj acc (assoc current :uri uri))))
|
||||
[]
|
||||
images)]
|
||||
(assoc multiaccount :images images)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:profile/multiaccount
|
||||
:<- [:multiaccount]
|
||||
:<- [:mediaserver/port]
|
||||
(fn [[multiaccount port]]
|
||||
(replace-multiaccount-image-uri multiaccount port)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:mobile-network/syncing-allowed?
|
||||
:<- [:network/type]
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
(ns status-im.ui.screens.activity-center.views
|
||||
(:require [quo.react-native :as rn]
|
||||
[quo2.components.buttons.button :as button]
|
||||
[quo2.components.notifications.activity-logs :as activity-logs]
|
||||
[quo2.components.tags.context-tags :as context-tags]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.i18n.i18n :as i18n]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.utils.handlers :refer [<sub >evt]]))
|
||||
|
||||
(defn render-notification
|
||||
[notification index]
|
||||
[rn/view {:flex 1
|
||||
:flex-direction :column
|
||||
:margin-top (if (= 0 index) 0 4)}
|
||||
[activity-logs/activity-log {:context [[context-tags/group-avatar-tag "Name" {:color :purple
|
||||
:override-theme :dark
|
||||
:size :small
|
||||
:style {:background-color colors/white-opa-10}
|
||||
:text-style {:color colors/white}}]
|
||||
[rn/text {:style {:color colors/white}} "did something here."]]
|
||||
:icon :placeholder
|
||||
:message {:body (get-in notification [:message :content :text])}
|
||||
:timestamp (:timestamp notification)
|
||||
:title "Activity Title"
|
||||
:unread? (not (:read notification))}]])
|
||||
|
||||
(defn notifications-list
|
||||
[]
|
||||
(let [notifications (<sub [:activity-center/notifications-per-read-status])]
|
||||
[rn/flat-list {:style {:padding-horizontal 8}
|
||||
:data notifications
|
||||
:key-fn :id
|
||||
:on-end-reached #(>evt [:activity-center/notifications-fetch-next-page])
|
||||
:render-fn render-notification}]))
|
||||
|
||||
(defn activity-center []
|
||||
(reagent/create-class
|
||||
{:component-did-mount #(>evt [:activity-center/notifications-fetch-first-page {:status-filter :unread}])
|
||||
:reagent-render
|
||||
(fn []
|
||||
[:<>
|
||||
[topbar/topbar {:navigation {:on-press #(>evt [:navigate-back])}
|
||||
:title (i18n/label :t/activity)}]
|
||||
;; TODO(ilmotta): Temporary solution to switch between read/unread
|
||||
;; notifications while the Design team works on the mockups.
|
||||
[button/button {:on-press #(>evt [:activity-center/notifications-fetch-first-page {:status-filter :unread}])}
|
||||
"Unread"]
|
||||
[button/button {:on-press #(>evt [:activity-center/notifications-fetch-first-page {:status-filter :read}])}
|
||||
"Read"]
|
||||
[notifications-list]])}))
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
(defn pin-limit-popover []
|
||||
(let [{:keys [message]} (<sub [:popover/popover])]
|
||||
[react/view {:style {:flex-shrink 1}}
|
||||
[react/view
|
||||
[react/view {:style {:height 60
|
||||
:justify-content :center}}
|
||||
[react/text {:style {:padding-horizontal 40
|
||||
@@ -85,4 +85,4 @@
|
||||
:type :secondary
|
||||
:disabled (nil? @selected-unpin)
|
||||
:theme (if (nil? @selected-unpin) :disabled :negative)}
|
||||
(i18n/label :t/unpin)]]]))
|
||||
(i18n/label :t/unpin)]]]))
|
||||
@@ -4,17 +4,20 @@
|
||||
[status-im.ui.screens.chat.styles.photos :as style]
|
||||
[status-im.profile.db :as profile.db]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.utils.image :as utils.image]
|
||||
[quo.design-system.colors :as colors]
|
||||
[status-im.ui.components.fast-image :as fast-image]))
|
||||
|
||||
(def memo-photo-rend
|
||||
(memoize
|
||||
(fn [photo-path size accessibility-label _]
|
||||
[react/view {:style (style/photo-container size)}
|
||||
[fast-image/fast-image {:source {:uri photo-path}
|
||||
:style (style/photo size)
|
||||
:accessibility-label (or accessibility-label :chat-icon)}]
|
||||
[react/view {:style (style/photo-border size)}]])))
|
||||
(let [identicon? (when photo-path (profile.db/base64-png? photo-path))]
|
||||
[react/view {:style (style/photo-container size)}
|
||||
[fast-image/fast-image {:source (utils.image/source photo-path)
|
||||
:style (style/photo size)
|
||||
:accessibility-label (or accessibility-label :chat-icon)}]
|
||||
(when identicon?
|
||||
[react/view {:style (style/photo-border size)}])]))))
|
||||
|
||||
;; "(colors/dark?)" is passed to memoized function to avoid previous themes cache
|
||||
(defn photo [photo-path {:keys [size accessibility-label]}]
|
||||
|
||||
@@ -28,10 +28,9 @@
|
||||
(def view-type (reagent/atom :card-view))
|
||||
(def sort-list-by (reagent/atom :name))
|
||||
|
||||
(def mock-community-item-data ;; TODO: remove once communities are loaded with this data.
|
||||
{:data {:status :gated
|
||||
(def mock-community-item-data ;; TO Do remove once communities are loaded with this data.
|
||||
{:data {:status :gated
|
||||
:locked true
|
||||
:images {:thumbnail {:uri (resources/get-image :status-logo)}}
|
||||
:cover (resources/get-image :community-cover)
|
||||
:tokens [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}]
|
||||
:tags [{:id 1 :tag-label (i18n/label :t/music) :resource (resources/get-image :music)}
|
||||
@@ -60,6 +59,9 @@
|
||||
{:featured true})]
|
||||
[community-card/community-card-view-item item #(>evt [:navigate-to :community-overview item])]))
|
||||
|
||||
(defn community-list-key-fn [item]
|
||||
(:id item))
|
||||
|
||||
(defn get-item-layout-js [_ index]
|
||||
#js {:length 64 :offset (* 64 index) :index index})
|
||||
|
||||
@@ -67,42 +69,39 @@
|
||||
[react/view {:flex 1
|
||||
:margin-bottom 8
|
||||
:padding-horizontal 20}
|
||||
[react/view {:flex-direction :row
|
||||
:padding-top 20
|
||||
:padding-bottom 8
|
||||
:height 60}
|
||||
[react/view {:flex 1}
|
||||
[quo2.tabs/tabs {:size 32
|
||||
:on-change #(reset! selected-tab %)
|
||||
:default-active :all
|
||||
:data [{:id :all
|
||||
:label (i18n/label :t/all)}
|
||||
{:id :open
|
||||
:label (i18n/label :t/open)}
|
||||
{:id :gated
|
||||
:label (i18n/label :t/gated)}]}]]
|
||||
[react/view {:flex-direction :row
|
||||
:padding-top 20
|
||||
:padding-bottom 8
|
||||
:height 60}
|
||||
[react/view {:flex 1}
|
||||
[quo2.tabs/tabs {:size 32
|
||||
:on-change #(reset! selected-tab %)
|
||||
:default-active :all
|
||||
:data [{:id :all :label (i18n/label :t/all)}
|
||||
{:id :open :label (i18n/label :t/open)}
|
||||
{:id :gated :label (i18n/label :t/gated)}]}]]
|
||||
[react/view {:flex-direction :row}
|
||||
[quo2.button/button
|
||||
{:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:style {:margin-right 12}
|
||||
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet :sort-communities {}])}
|
||||
{:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:style {:margin-right 12}
|
||||
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet :sort-communities {}])}
|
||||
:main-icons2/lightning]
|
||||
[quo2.button/button
|
||||
{:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:on-press #(if (= @view-type :card-view)
|
||||
(reset! view-type :list-view)
|
||||
(reset! view-type :card-view))}
|
||||
{:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:on-press #(if (= @view-type :card-view)
|
||||
(reset! view-type :list-view)
|
||||
(reset! view-type :card-view))}
|
||||
(if (= @view-type :card-view)
|
||||
:main-icons2/card-view
|
||||
:main-icons2/list-view)]]]])
|
||||
|
||||
(defn featured-communities [communities]
|
||||
[list/flat-list
|
||||
{:key-fn :id
|
||||
{:key-fn str
|
||||
:horizontal true
|
||||
:getItemLayout get-item-layout-js
|
||||
:keyboard-should-persist-taps :always
|
||||
@@ -113,7 +112,7 @@
|
||||
(defn other-communities [communities sort-list-by]
|
||||
(let [sorted-communities (sort-by sort-list-by communities)]
|
||||
[list/flat-list
|
||||
{:key-fn :id
|
||||
{:key-fn str
|
||||
:getItemLayout get-item-layout-js
|
||||
:keyboard-should-persist-taps :always
|
||||
:shows-horizontal-scroll-indicator false
|
||||
@@ -207,34 +206,34 @@
|
||||
(let [multiaccount (<sub [:multiaccount])
|
||||
communities (<sub [:communities/communities])
|
||||
featured-communities (<sub [:communities/featured-communities])]
|
||||
|
||||
[safe-area/consumer
|
||||
(fn [insets]
|
||||
[react/view {:style {:flex 1
|
||||
:padding-top (:top insets)
|
||||
:background-color (quo2.colors/theme-colors
|
||||
quo2.colors/neutral-5
|
||||
quo2.colors/neutral-95)}}
|
||||
[topbar/topbar
|
||||
{:navigation :none
|
||||
:left-component [react/view {:margin-left 16}
|
||||
[photos/photo (multiaccounts/displayed-photo multiaccount)
|
||||
{:size 32}]]
|
||||
:right-component [react/view {:flex-direction :row
|
||||
:margin-right 16}
|
||||
[topnav/qr-scanner]
|
||||
[topnav/qr-code]
|
||||
[topnav/notifications-button]]
|
||||
:new-ui? true
|
||||
:border-bottom false}]
|
||||
[title-column]
|
||||
[react/scroll-view
|
||||
[community-filter-tags]
|
||||
[featured-communities-section featured-communities]
|
||||
(when communities
|
||||
[:<>
|
||||
[react/view {:margin-vertical 4
|
||||
:padding-horizontal 20}
|
||||
[separator/separator]]
|
||||
[community-segments]])
|
||||
[community-segments-view communities]]])]))
|
||||
(fn []
|
||||
[safe-area/consumer
|
||||
(fn [insets]
|
||||
[react/view {:style {:flex 1
|
||||
:padding-top (:top insets)
|
||||
:background-color (quo2.colors/theme-colors
|
||||
quo2.colors/neutral-5
|
||||
quo2.colors/neutral-95)}}
|
||||
[topbar/topbar
|
||||
{:navigation :none
|
||||
:left-component [react/view {:margin-left 16}
|
||||
[photos/photo (multiaccounts/displayed-photo multiaccount)
|
||||
{:size 32}]]
|
||||
:right-component [react/view {:flex-direction :row
|
||||
:margin-right 16}
|
||||
[topnav/qr-scanner]
|
||||
[topnav/qr-code]
|
||||
[topnav/notifications-button]]
|
||||
:new-ui? true
|
||||
:border-bottom false}]
|
||||
[title-column]
|
||||
[react/scroll-view
|
||||
[community-filter-tags]
|
||||
[featured-communities-section featured-communities]
|
||||
(when communities
|
||||
[:<>
|
||||
[react/view {:margin-vertical 4
|
||||
:padding-horizontal 20}
|
||||
[separator/separator]]
|
||||
[community-segments]])
|
||||
[community-segments-view communities]]])])))
|
||||
@@ -4,8 +4,7 @@
|
||||
[quo2.components.markdown.text :as quo2.text]
|
||||
[quo2.components.buttons.button :as quo2.button]
|
||||
[quo2.components.community.community-view :as community-view]
|
||||
[status-im.ui.screens.communities.request-to-join-bottom-sheet-redesign :as request-to-join]
|
||||
[status-im.utils.handlers :refer [<sub >evt]]
|
||||
[status-im.utils.handlers :refer [<sub]]
|
||||
[status-im.ui.screens.communities.styles :as styles]
|
||||
[status-im.ui.screens.communities.icon :as communities.icon]))
|
||||
|
||||
@@ -23,7 +22,7 @@
|
||||
:size :label}
|
||||
"placeholder for channel list component"]])
|
||||
|
||||
(defn community-card-page-view [{:keys [name description locked joined
|
||||
(defn community-card-page-view [{:keys [name description locked
|
||||
status tokens cover tags] :as community}]
|
||||
[react/view
|
||||
{:style
|
||||
@@ -50,18 +49,14 @@
|
||||
[community-view/community-stats-column :card-view]
|
||||
[community-view/community-tags tags]
|
||||
[preview-list-component]
|
||||
(when (not joined)
|
||||
[quo2.button/button
|
||||
{:on-press #(>evt [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [request-to-join/request-to-join community])
|
||||
:content-height 300}])
|
||||
:style
|
||||
{:width "100%"
|
||||
:margin-top 20
|
||||
:margin-left :auto
|
||||
:margin-right :auto}
|
||||
:before :main-icons/community}
|
||||
(i18n/label :join-open-community)])
|
||||
[quo2.button/button
|
||||
{:style
|
||||
{:width "100%"
|
||||
:margin-top 20
|
||||
:margin-left :auto
|
||||
:margin-right :auto}
|
||||
:before :main-icons/community}
|
||||
(i18n/label :join-open-community)]
|
||||
[channel-list-component]]])
|
||||
|
||||
(defn overview []
|
||||
|
||||
@@ -60,15 +60,6 @@
|
||||
:t/invite-people
|
||||
:t/community-share-title))
|
||||
:modal? true}]
|
||||
(when-not (seq contacts)
|
||||
[rn/view {:style {:justifyContent :center
|
||||
:alignItems :center
|
||||
:flex 1}}
|
||||
[rn/text {:size :large
|
||||
:weight :bold
|
||||
:style {:text-align :center
|
||||
:margin-top :auto}}
|
||||
(i18n/label :t/add-contacts-to-invite)]])
|
||||
[rn/flat-list {:style {:flex 1}
|
||||
:content-container-style {:padding-vertical 16}
|
||||
;:header [header user-pk]
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
(ns status-im.ui.screens.communities.request-to-join-bottom-sheet-redesign
|
||||
(:require [status-im.i18n.i18n :as i18n]
|
||||
[quo.core :as quo]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[quo2.components.markdown.text :as quo2.text]
|
||||
[quo2.components.buttons.button :as quo2.button]
|
||||
[quo2.components.icon :as quo2.icon]
|
||||
[status-im.utils.handlers :refer [>evt]]
|
||||
[quo2.components.tags.context-tags :as quo2.context-tags]
|
||||
[status-im.communities.core :as communities]
|
||||
[quo2.foundations.colors :as quo2.colors]))
|
||||
|
||||
;; TODO: update with real data
|
||||
(def community-rules [{:index 1
|
||||
:title "Be respectful"
|
||||
:content "You must respect all users, regardless of your liking towards them. Treat others the way you want to be treated."}
|
||||
{:index 2
|
||||
:title "No Inappropriate Language"
|
||||
:content "The use of profanity should be kept to a minimum. However, any derogatory language towards any user is prohibited."}
|
||||
{:index 3
|
||||
:title "No spamming"
|
||||
:content "Don't send a lot of small messages right after each other. Do not disrupt chat by spamming."}
|
||||
{:index 4
|
||||
:title "No pornographic, adult or NSFW material"
|
||||
:content "This is a community server and not meant to share this kind of material."}
|
||||
{:index 5
|
||||
:title "No advertisements"
|
||||
:content "We do not tolerate any kind of advertisements, whether it be for other communities or streams."}
|
||||
{:index 6
|
||||
:title "No offensive names and profile pictures"
|
||||
:content "You will be asked to change your name or picture if the staff deems them inappropriate."}])
|
||||
|
||||
(defn community-rule-item [{:keys [title content index]}]
|
||||
[react/view
|
||||
{:style {:flex 1 :margin-top 16}}
|
||||
[react/view
|
||||
{:style
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center}}
|
||||
[react/view
|
||||
{:style
|
||||
{:height 18
|
||||
:width 18
|
||||
:margin-left 1
|
||||
:margin-right 9
|
||||
:background-color quo2.colors/white
|
||||
:border-color quo2.colors/neutral-20
|
||||
:border-width 1
|
||||
:border-radius 6}}
|
||||
[quo2.text/text {:style
|
||||
{:margin-left :auto
|
||||
:margin-right :auto
|
||||
:margin-top :auto
|
||||
:margin-bottom :auto}
|
||||
:accessibility-label :communities-rule-index
|
||||
:weight :medium
|
||||
:size :label}
|
||||
|
||||
(str index)]]
|
||||
[quo2.text/text
|
||||
{:accessibility-label :communities-rule-title
|
||||
:weight :semi-bold
|
||||
:size :paragraph-2}
|
||||
title]]
|
||||
[quo2.text/text
|
||||
{:style {:margin-left 28}
|
||||
:accessibility-label :communities-rule-content
|
||||
:size :paragraph-2}
|
||||
content]])
|
||||
|
||||
(defn community-rules-list [rules]
|
||||
|
||||
[list/flat-list
|
||||
{:shows-horizontal-scroll-indicator false
|
||||
:data rules
|
||||
:render-fn community-rule-item}])
|
||||
|
||||
(defn rules-checkbox [agreed-to-rules?]
|
||||
[react/view {:style
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:margin-top 20
|
||||
:background-color quo2.colors/neutral-20
|
||||
:padding 12
|
||||
:border-radius 12
|
||||
:border-width 1
|
||||
:border-color quo2.colors/neutral-30}}
|
||||
[quo/checkbox {:value @agreed-to-rules?
|
||||
:on-change #(swap! agreed-to-rules? not)}]
|
||||
[quo2.text/text {:accessibility-label :communities-accept-rules
|
||||
:size :paragraph-2
|
||||
:style {:margin-left 8}}
|
||||
(i18n/label :t/accept-community-rules)]])
|
||||
|
||||
(defn request-to-join [community]
|
||||
(let [agreed-to-rules? (reagent/atom false)]
|
||||
(fn []
|
||||
[react/view {:style {:flex 1 :margin-left 20 :margin-right 20 :margin-bottom 20}}
|
||||
[react/view {:style {:flex 1 :flex-direction :row :align-items :center :justify-content :space-between}}
|
||||
|
||||
[quo2.text/text {:accessibility-label :communities-join-community
|
||||
:weight :semi-bold
|
||||
:size :heading-1}
|
||||
(i18n/label :t/join-open-community)]
|
||||
[react/view {:style {:height 32
|
||||
:width 32
|
||||
:align-items :center
|
||||
:background-color quo2.colors/white
|
||||
:border-color quo2.colors/neutral-20
|
||||
:border-width 1
|
||||
:border-radius 6
|
||||
:display :flex
|
||||
:justify-content :center}}
|
||||
[quo2.icon/icon :main-icons2/info]]]
|
||||
|
||||
[quo2.context-tags/context-tag {:style {:margin-right :auto :margin-top 8}} (get-in community [:images :thumbnail :uri]) (:name community)]
|
||||
|
||||
[quo2.text/text {:style {:margin-top 24}
|
||||
:accessibility-label :communities-rules-title
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1}
|
||||
(i18n/label :t/community-rules)]
|
||||
[community-rules-list community-rules]
|
||||
[rules-checkbox agreed-to-rules?]
|
||||
|
||||
[react/view {:style {:width "100%"
|
||||
:margin-top 32 :margin-bottom 16
|
||||
:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :space-evenly}}
|
||||
[quo2.button/button {:on-press #(>evt [:bottom-sheet/hide])
|
||||
:type :grey :style {:flex 1 :margin-right 12}} (i18n/label :t/cancel)]
|
||||
[quo2.button/button
|
||||
{:on-press #(>evt [::communities/join (:id community)])
|
||||
:disabled (not agreed-to-rules?) :style {:flex 1}} (i18n/label :t/join-open-community)]]])))
|
||||
@@ -4,8 +4,8 @@
|
||||
[reagent.core :as reagent]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.ethereum.decode :as decode]
|
||||
[status-im.utils.datetime :as time]
|
||||
[status-im.native-module.core :as status]))
|
||||
[status-im.ethereum.abi-spec :as abi-spec]
|
||||
[status-im.utils.datetime :as time]))
|
||||
|
||||
(defn get-block [block callback]
|
||||
(json-rpc/call
|
||||
@@ -31,7 +31,7 @@
|
||||
(fn [res]
|
||||
(reset! latest-block res)
|
||||
(get-block
|
||||
(str "0x" (status/number-to-hex
|
||||
(str "0x" (abi-spec/number-to-hex
|
||||
(last-loaded-block-number)))
|
||||
(fn [res]
|
||||
(reset! last-loaded-block res))))))]
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
(defn my-profile []
|
||||
(fn []
|
||||
(let [{:keys [public-key ens-verified preferred-name]
|
||||
:as account} @(re-frame/subscribe [:profile/multiaccount])
|
||||
:as account} @(re-frame/subscribe [:multiaccount])
|
||||
on-share #(re-frame/dispatch [:show-popover
|
||||
{:view :share-chat-key
|
||||
:address public-key
|
||||
|
||||
@@ -80,7 +80,6 @@
|
||||
[status-im.ui.screens.network.network-details.views :as network-details]
|
||||
[status-im.ui.screens.network.views :as network]
|
||||
[status-im.ui.screens.notifications-center.views :as notifications-center]
|
||||
[status-im.ui.screens.activity-center.views :as activity-center]
|
||||
[status-im.ui.screens.notifications-settings.views :as notifications-settings]
|
||||
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.views
|
||||
:as
|
||||
@@ -135,7 +134,7 @@
|
||||
(defn screens []
|
||||
(concat [;;INTRO, ONBOARDING, LOGIN
|
||||
|
||||
;Multiaccounts
|
||||
;Multiaccounts
|
||||
{:name :multiaccounts
|
||||
:insets {:bottom true}
|
||||
:options {:topBar {:title {:text (i18n/label :t/your-keys)}
|
||||
@@ -143,7 +142,7 @@
|
||||
:right-handler multiaccounts/topbar-button
|
||||
:component multiaccounts/multiaccounts}
|
||||
|
||||
;Login
|
||||
;Login
|
||||
{:name :login
|
||||
:insets {:bottom true}
|
||||
:options {:topBar {:rightButtons (right-button-options :login :more)}}
|
||||
@@ -153,17 +152,17 @@
|
||||
{:name :progress
|
||||
:component progress/progress}
|
||||
|
||||
;[Onboarding]
|
||||
;[Onboarding]
|
||||
{:name :intro
|
||||
:insets {:bottom true}
|
||||
:component onboarding.intro/intro}
|
||||
|
||||
;[Onboarding]
|
||||
;[Onboarding]
|
||||
{:name :get-your-keys
|
||||
:insets {:bottom true}
|
||||
:component onboarding.keys/get-your-keys}
|
||||
|
||||
;[Onboarding]
|
||||
;[Onboarding]
|
||||
{:name :choose-name
|
||||
:options {:topBar {:visible false}
|
||||
:popGesture false
|
||||
@@ -172,7 +171,7 @@
|
||||
:insets {:bottom true}
|
||||
:component onboarding.keys/choose-a-chat-name}
|
||||
|
||||
;[Onboarding]
|
||||
;[Onboarding]
|
||||
{:name :select-key-storage
|
||||
:insets {:bottom true}
|
||||
:options {:popGesture false
|
||||
@@ -180,7 +179,7 @@
|
||||
:popStackOnPress false}}
|
||||
:component onboarding.storage/select-key-storage}
|
||||
|
||||
;[Onboarding] Create Password
|
||||
;[Onboarding] Create Password
|
||||
{:name :create-password
|
||||
:options {:popGesture false
|
||||
:hardwareBackButton {:dismissModalOnPress false
|
||||
@@ -188,7 +187,7 @@
|
||||
:insets {:bottom true}
|
||||
:component onboarding.password/screen}
|
||||
|
||||
;[Onboarding] Welcome
|
||||
;[Onboarding] Welcome
|
||||
{:name :welcome
|
||||
:options {:popGesture false
|
||||
:hardwareBackButton {:dismissModalOnPress false
|
||||
@@ -196,7 +195,7 @@
|
||||
:insets {:bottom true}
|
||||
:component onboarding.welcome/welcome}
|
||||
|
||||
;[Onboarding] Notification
|
||||
;[Onboarding] Notification
|
||||
{:name :onboarding-notification
|
||||
:options {:popGesture false
|
||||
:hardwareBackButton {:dismissModalOnPress false
|
||||
@@ -204,7 +203,7 @@
|
||||
:insets {:bottom true}
|
||||
:component onboarding.notifications/notifications-onboarding}
|
||||
|
||||
;[Onboarding] Recovery
|
||||
;[Onboarding] Recovery
|
||||
{:name :recover-multiaccount-enter-phrase
|
||||
:insets {:bottom true}
|
||||
:component onboarding.phrase/enter-phrase}
|
||||
@@ -217,11 +216,11 @@
|
||||
|
||||
;;CHAT
|
||||
|
||||
;Home
|
||||
;Home
|
||||
{:name :home
|
||||
:component home/home-old}
|
||||
|
||||
;Chat
|
||||
;Chat
|
||||
{:name :chat
|
||||
:options {:popGesture false
|
||||
:hardwareBackButton {:dismissModalOnPress false
|
||||
@@ -229,7 +228,7 @@
|
||||
:topBar {:visible false}}
|
||||
:component chat/chat-old}
|
||||
|
||||
;Pinned messages
|
||||
;Pinned messages
|
||||
{:name :chat-pinned-messages
|
||||
;TODO custom subtitle
|
||||
:options {:topBar {:visible false}}
|
||||
@@ -256,9 +255,6 @@
|
||||
;;TODO custom nav
|
||||
:options {:topBar {:visible false}}
|
||||
:component notifications-center/center}
|
||||
{:name :activity-center
|
||||
:options {:topBar {:visible false}}
|
||||
:component activity-center/activity-center}
|
||||
;; Community
|
||||
{:name :community
|
||||
;;TODO custom
|
||||
@@ -594,38 +590,38 @@
|
||||
|
||||
;;MODALS
|
||||
|
||||
;[Chat] New Chat
|
||||
;[Chat] New Chat
|
||||
{:name :new-chat
|
||||
:on-focus [::new-chat.events/new-chat-focus]
|
||||
;;TODO accessories
|
||||
:options {:topBar {:visible false}}
|
||||
:component new-chat/new-chat}
|
||||
|
||||
;[Chat] New Public chat
|
||||
;[Chat] New Public chat
|
||||
{:name :new-public-chat
|
||||
:insets {:bottom true}
|
||||
:options {:topBar {:title {:text (i18n/label :t/new-public-group-chat)}}}
|
||||
:component new-public-chat/new-public-chat}
|
||||
|
||||
;[Chat] Link preview settings
|
||||
;[Chat] Link preview settings
|
||||
{:name :link-preview-settings
|
||||
:options {:topBar {:title {:text (i18n/label :t/chat-link-previews)}}}
|
||||
:component link-previews-settings/link-previews-settings}
|
||||
|
||||
;[Chat] Edit nickname
|
||||
;[Chat] Edit nickname
|
||||
{:name :nickname
|
||||
:insets {:bottom true}
|
||||
;;TODO dyn subtitle
|
||||
:options {:topBar {:visible false}}
|
||||
:component contact/nickname}
|
||||
|
||||
;[Group chat] Edit group chat name
|
||||
;[Group chat] Edit group chat name
|
||||
{:name :edit-group-chat-name
|
||||
:insets {:bottom true}
|
||||
:options {:topBar {:title {:text (i18n/label :t/edit-group)}}}
|
||||
:component group-chat/edit-group-chat-name}
|
||||
|
||||
;[Group chat] Add participants
|
||||
;[Group chat] Add participants
|
||||
{:name :add-participants-toggle-list
|
||||
:on-focus [:group/add-participants-toggle-list]
|
||||
:insets {:bottom true}
|
||||
@@ -633,34 +629,34 @@
|
||||
:options {:topBar {:visible false}}
|
||||
:component group-chat/add-participants-toggle-list}
|
||||
|
||||
;[Communities] Invite people
|
||||
;[Communities] Invite people
|
||||
{:name :invite-people-community
|
||||
;;TODO dyn title
|
||||
:options {:topBar {:visible false}}
|
||||
:component communities.invite/invite
|
||||
:insets {:bottom true}}
|
||||
|
||||
;New Contact
|
||||
;New Contact
|
||||
{:name :new-contact
|
||||
:on-focus [::new-chat.events/new-chat-focus]
|
||||
;;TODO accessories
|
||||
:options {:topBar {:visible false}}
|
||||
:component new-chat/new-contact}
|
||||
|
||||
;[Wallet] Recipient
|
||||
;[Wallet] Recipient
|
||||
{:name :recipient
|
||||
:insets {:bottom true}
|
||||
;;TODO accessories
|
||||
:options {:topBar {:visible false}}
|
||||
:component recipient/recipient}
|
||||
|
||||
;[Wallet] New favourite
|
||||
;[Wallet] New favourite
|
||||
{:name :new-favourite
|
||||
:insets {:bottom true}
|
||||
:options {:topBar {:title {:text (i18n/label :t/new-favourite)}}}
|
||||
:component recipient/new-favourite}
|
||||
|
||||
;QR Scanner
|
||||
;QR Scanner
|
||||
{:name :qr-scanner
|
||||
:insets {:top false :bottom false}
|
||||
;;TODO custom topbar
|
||||
@@ -671,7 +667,7 @@
|
||||
:component qr-scanner/qr-scanner}
|
||||
|
||||
;;TODO WHY MODAL?
|
||||
;[Profile] Notifications settings
|
||||
;[Profile] Notifications settings
|
||||
{:name :notifications-settings
|
||||
:options {:topBar {:title {:text (i18n/label :t/notification-settings)}}
|
||||
:popGesture false
|
||||
@@ -681,7 +677,7 @@
|
||||
:component notifications-settings/notifications-settings}
|
||||
|
||||
;;TODO WHY MODAL?
|
||||
;[Profile] Notifications Advanced settings
|
||||
;[Profile] Notifications Advanced settings
|
||||
{:name :notifications-advanced-settings
|
||||
:options {:topBar {:title {:text (i18n/label :t/notification-settings)}}
|
||||
:popGesture false
|
||||
@@ -690,7 +686,7 @@
|
||||
:insets {:bottom true}
|
||||
:component notifications-settings/notifications-advanced-settings}
|
||||
|
||||
;[Wallet] Prepare Transaction
|
||||
;[Wallet] Prepare Transaction
|
||||
{:name :prepare-send-transaction
|
||||
:insets {:bottom true}
|
||||
:on-dissmiss [:wallet/cancel-transaction-command]
|
||||
@@ -699,7 +695,7 @@
|
||||
:hardwareBackButton {:dismissModalOnPress false}}
|
||||
:component wallet.send/prepare-send-transaction}
|
||||
|
||||
;[Wallet] Request Transaction
|
||||
;[Wallet] Request Transaction
|
||||
{:name :request-transaction
|
||||
:insets {:bottom true}
|
||||
:on-dissmiss [:wallet/cancel-transaction-command]
|
||||
@@ -708,12 +704,12 @@
|
||||
:hardwareBackButton {:dismissModalOnPress false}}
|
||||
:component wallet.send/request-transaction}
|
||||
|
||||
;[Wallet] Buy crypto
|
||||
;[Wallet] Buy crypto
|
||||
{:name :buy-crypto
|
||||
:insets {:bottom true}
|
||||
:component wallet.buy-crypto/container}
|
||||
|
||||
;[Wallet] Buy crypto website
|
||||
;[Wallet] Buy crypto website
|
||||
{:name :buy-crypto-website
|
||||
:insets {:bottom true}
|
||||
;;TODO subtitle
|
||||
@@ -726,27 +722,27 @@
|
||||
:options {:topBar {:visible false}}
|
||||
:component wallet.collectibles/nft-details-modal}
|
||||
|
||||
;My Status
|
||||
;My Status
|
||||
{:name :my-status
|
||||
:insets {:bottom true}
|
||||
:options {:topBar {:title {:text (i18n/label :t/my-status)}}}
|
||||
:component status.new/my-status}
|
||||
|
||||
;[Browser] New bookmark
|
||||
;[Browser] New bookmark
|
||||
{:name :new-bookmark
|
||||
:insets {:bottom true}
|
||||
;;TODO dynamic title
|
||||
:options {:topBar {:visible false}}
|
||||
:component bookmarks/new-bookmark}
|
||||
|
||||
;Profile
|
||||
;Profile
|
||||
{:name :profile
|
||||
:insets {:bottom true}
|
||||
;;TODO custom toolbar
|
||||
:options {:topBar {:visible false}}
|
||||
:component contact/profile}
|
||||
|
||||
;KEYCARD
|
||||
;KEYCARD
|
||||
{:name :keycard-onboarding-intro
|
||||
:insets {:bottom true}
|
||||
:back-handler keycard.core/onboarding-intro-back-handler
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
(ns status-im.utils.image-server
|
||||
(:require [quo.design-system.colors :as colors]
|
||||
[status-im.utils.config :as config]))
|
||||
|
||||
(def ^:const image-server-uri-prefix "https://localhost:")
|
||||
(def ^:const identicons-action "/messages/identicons")
|
||||
(def ^:const account-images-action "/accountImages")
|
||||
(def ^:const contact-images-action "/contactImages")
|
||||
|
||||
(defn current-theme []
|
||||
(case @colors/theme-type
|
||||
:light 1
|
||||
:dark 2))
|
||||
|
||||
(defn- timestamp []
|
||||
(.getTime (js/Date.)))
|
||||
|
||||
(defn get-identicons-uri [port public-key]
|
||||
(let [base (str image-server-uri-prefix port identicons-action "?publicKey=" public-key "&theme=" (current-theme) "&clock=" (timestamp))]
|
||||
(cond-> base
|
||||
@config/new-ui-enabled? (str "&addRing=1"))))
|
||||
|
||||
(defn get-account-image-uri [port public-key image-name key-uid]
|
||||
(let [base (str image-server-uri-prefix port account-images-action "?publicKey=" public-key "&keyUid=" key-uid "&imageName=" image-name "&theme=" (current-theme) "&clock=" (timestamp))]
|
||||
(cond-> base
|
||||
@config/new-ui-enabled? (str "&addRing=1"))))
|
||||
|
||||
(defn get-contact-image-uri [port public-key image-name clock]
|
||||
(let [base (str image-server-uri-prefix port contact-images-action "?publicKey=" public-key "&imageName=" image-name "&theme=" (current-theme) "&clock=" clock)]
|
||||
(cond-> base
|
||||
@config/new-ui-enabled? (str "&addRing=1"))))
|
||||
@@ -79,29 +79,11 @@
|
||||
(.initKeystore
|
||||
native-status
|
||||
(str test-dir "/keystore/" key-uid))))
|
||||
|
||||
:identicon (fn [pk]
|
||||
(.identicon native-status pk))
|
||||
|
||||
:encodeTransfer (fn [to-norm amount-hex]
|
||||
(.encodeTransfer native-status to-norm amount-hex))
|
||||
|
||||
:encodeFunctionCall (fn [method params-json]
|
||||
(.encodeFunctionCall native-status method params-json))
|
||||
|
||||
:decodeParameters (fn [decode-param-json]
|
||||
(.decodeParameters native-status decode-param-json))
|
||||
|
||||
:hexToNumber (fn [hex]
|
||||
(.hexToNumber native-status hex))
|
||||
|
||||
:numberToHex (fn [num-str]
|
||||
(.numberToHex native-status num-str))
|
||||
|
||||
:validateMnemonic (fn [json callback]
|
||||
(callback
|
||||
(.validateMnemonic
|
||||
native-status
|
||||
json)))
|
||||
|
||||
:startLocalNotifications identity}))
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
(ns ^{:doc "Implementation of varint based on https://github.com/chrisdickinson/varint"}
|
||||
status-im.utils.varint
|
||||
(:require [status-im.ethereum.abi-spec :as abi-spec]
|
||||
["web3-utils" :as utils]))
|
||||
|
||||
(def most-significant-bit 0x80)
|
||||
(def biggest-int-per-byte 0x7F)
|
||||
(def biggest-int 2147483648) ;; 2^31
|
||||
|
||||
(defn encode [num]
|
||||
(loop [num num
|
||||
out []]
|
||||
(if (>= num 128)
|
||||
(recur (if (>= num biggest-int)
|
||||
(/ num 128)
|
||||
(bit-shift-right num 7))
|
||||
(conj out (bit-or (bit-and num 0xFF)
|
||||
most-significant-bit)))
|
||||
(conj out (bit-or num 0)))))
|
||||
|
||||
(defn encode-hex [num]
|
||||
(reduce (fn [hex current-bit]
|
||||
(str hex
|
||||
(.leftPad utils
|
||||
(abi-spec/number-to-hex current-bit)
|
||||
2)))
|
||||
""
|
||||
(encode num)))
|
||||
|
||||
(defn add-b-to-res
|
||||
[res b shift]
|
||||
(+ res (if (< shift 28)
|
||||
(bit-shift-left (bit-and b biggest-int-per-byte)
|
||||
shift)
|
||||
(* (bit-and b biggest-int-per-byte)
|
||||
shift shift))))
|
||||
|
||||
(defn decode [buf]
|
||||
(loop [res 0
|
||||
shift 0
|
||||
[b & rest-buf] buf]
|
||||
(if (>= b most-significant-bit)
|
||||
(recur (add-b-to-res res b shift)
|
||||
(+ shift 7)
|
||||
rest-buf)
|
||||
(add-b-to-res res b shift))))
|
||||
|
||||
(defn decode-hex [hex]
|
||||
(->> hex
|
||||
(partition 2)
|
||||
(mapv #(abi-spec/hex-to-number (apply str %)))
|
||||
decode))
|
||||
@@ -0,0 +1,28 @@
|
||||
(ns status-im.utils.varint-test
|
||||
(:require [cljs.test :refer-macros [deftest is]]
|
||||
[status-im.utils.varint :as varint]))
|
||||
|
||||
(deftest encode
|
||||
(is (= (varint/encode-hex 0x0)
|
||||
"00"))
|
||||
(is (= (varint/encode-hex 0x70)
|
||||
"70"))
|
||||
(is (= (varint/encode-hex 0xe3)
|
||||
"e301")))
|
||||
|
||||
(deftest decode
|
||||
(is (= (varint/decode-hex "00")
|
||||
0x0))
|
||||
(is (= (varint/decode-hex "70")
|
||||
0x70))
|
||||
(is (= (varint/decode-hex "e301")
|
||||
0xe3)))
|
||||
|
||||
(defn test-roundtrip [n]
|
||||
(= (varint/decode-hex (varint/encode-hex n))
|
||||
n))
|
||||
|
||||
(deftest roundtrip
|
||||
(is (test-roundtrip 0))
|
||||
(is (test-roundtrip 23948))
|
||||
(is (test-roundtrip 2684453)))
|
||||
@@ -88,11 +88,10 @@
|
||||
{:events [:wallet/add-favourite]}
|
||||
[{:keys [db] :as cofx} address name]
|
||||
(let [new-favourite {:address address
|
||||
:name (or name "")
|
||||
:favourite true}]
|
||||
:name (or name "")}]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:wallet/favourites address] new-favourite)
|
||||
::json-rpc/call [{:method "wallet_addSavedAddress"
|
||||
::json-rpc/call [{:method "wallet_addFavourite"
|
||||
:params [new-favourite]
|
||||
:on-success #()}]}
|
||||
(navigation/navigate-back))))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.110.1",
|
||||
"commit-sha1": "a182f3e699f290776a1f1b3df8e2341c67b3f814",
|
||||
"src-sha256": "1hrqmm4db4vbgwjmvqzbilza6fwgb2hns1bsx4vzdpvjqfy3akrv"
|
||||
"version": "unread-messages",
|
||||
"commit-sha1": "0865dc182aa70b76a21aab06798bd2d6763d13ac",
|
||||
"src-sha256": "0kpczsf5lzdaxm2m50g255f8bqqdyq3dp72x4s9qfc3m31jz4adc"
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
"access-key": "Access key",
|
||||
"access-existing-keys": "Access existing keys",
|
||||
"accept-and-share-address": "Accept and share address",
|
||||
"accept-community-rules": "I agree with the community rules",
|
||||
"account-added": "Account added",
|
||||
"account-color": "Account color",
|
||||
"anyone": "Anyone",
|
||||
@@ -168,7 +167,6 @@
|
||||
"one": "{{count}} member",
|
||||
"other": "{{count}} members"
|
||||
},
|
||||
"community-rules": "Community rules",
|
||||
"members-label": "Members",
|
||||
"open-membership": "Open membership",
|
||||
"member-kick": "Kick member",
|
||||
@@ -685,12 +683,11 @@
|
||||
"invalid-username-or-key": "Invalid username or chat key",
|
||||
"join-me": "Hey join me on Status: {{url}}",
|
||||
"join-a-community": "or join a community",
|
||||
"join-open-community": "Join Community",
|
||||
"join-open-community": "Join community",
|
||||
"http-gateway-error": "Oops, request failed!",
|
||||
"sign-request-failed": "Could not sign message",
|
||||
"invite-friends": "Invite friends",
|
||||
"invite-people": "Invite people",
|
||||
"add-contacts-to-invite": "Add contacts to invite them to this community",
|
||||
"invite-reward": "Earn crypto for every friend you invite!",
|
||||
"invite-select-account": "Select an account to receive your referral bonus",
|
||||
"invited": "invited",
|
||||
@@ -1781,7 +1778,6 @@
|
||||
"music": "Music",
|
||||
"lifestyle": "Lifestyle",
|
||||
"podcasts": "Podcasts",
|
||||
"NFT":"NFT",
|
||||
"new-messages-header": "New Messages"
|
||||
"NFT":"NFT"
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user