Compare commits

..
Author SHA1 Message Date
J.M.N 244c48bcf2 Fix: Update last chat message preview and unread messages counter 2022-09-13 10:57:03 +03:00
55 changed files with 772 additions and 1211 deletions
+5 -4
View File
@@ -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)
}
}
}
+2 -2
View File
@@ -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
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.5.5'
library 'status-jenkins-lib@v1.5.3'
pipeline {
agent { label params.AGENT_LABEL }
+5 -2
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.5.5'
library 'status-jenkins-lib@v1.5.3'
pipeline {
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.5.5'
library 'status-jenkins-lib@v1.5.3'
pipeline {
agent { label 'macos' }
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.5.5'
library 'status-jenkins-lib@v1.5.3'
pipeline {
agent { label 'linux' }
@@ -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]]]))
+10 -12
View File
@@ -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)]]))
+11 -79
View File
@@ -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}]])
+1 -9
View File
@@ -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}
-69
View File
@@ -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?)})
+1 -13
View File
@@ -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]))}})
+2 -9
View File
@@ -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
+396
View File
@@ -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 twos 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)))))))
+69
View File
@@ -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"))))
+6 -4
View File
@@ -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"])))
+2 -2
View File
@@ -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]
-1
View File
@@ -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
+6 -9
View File
@@ -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]}
+2 -2
View File
@@ -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"))))))
-27
View File
@@ -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]
-1
View File
@@ -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))
+19 -12
View File
@@ -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
+4 -4
View File
@@ -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}}
+5 -4
View File
@@ -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
View File
@@ -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)]]]))
+8 -5
View File
@@ -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
+34 -38
View File
@@ -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
-31
View File
@@ -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"))))
-18
View File
@@ -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}))
+52
View File
@@ -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))
+28
View File
@@ -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)))
+2 -3
View File
@@ -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 -3
View File
@@ -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"
}
+2 -6
View File
@@ -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"
}