Compare commits

..
192 changed files with 1397 additions and 2340 deletions
-11
View File
@@ -282,17 +282,6 @@ else
npx react-native run-ios
endif
show-ios-devices: export TARGET := ios
show-ios-devices: ##@other shows connected ios device and its name
xcrun xctrace list devices
run-ios-device: export TARGET := ios
run-ios-device: ##@run iOS app and start it on a connected device by its name
ifndef DEVICE_NAME
$(error Usage: make run-ios-device DEVICE_NAME=your-device-name)
endif
react-native run-ios --device "$(DEVICE_NAME)"
#--------------
# Tests
#--------------
+1 -1
View File
@@ -4,7 +4,7 @@ library 'status-jenkins-lib@v1.6.9'
def isPRBuild = utils.isPRBuild()
pipeline {
agent { label 'macos && arm64 && nix-2.11 && xcode-14.3' }
agent { label 'macos && arm64 && nix-2.11 && xcode-14.2' }
parameters {
string(
+3 -3
View File
@@ -23,13 +23,13 @@ setups and runs the test suite once.
setups and runs the test suite and watches for code changes will then retrigger the test suite.
## Writing Tests
New test files will need their namespace added to either the file "src/quo2/core_spec.cljs" or "src/status_im2/core_spec.cljs. These locations may update overtime but it is dependent on the entrypoint in shadow-cljs config discussed below.
New test files will need their namespace added to either the file "src/quo2/core_spec.cljs" or "src/status_im2/core_spec.cljs. These locations may update overtime but it is dependent on the entrypoint in shadowcljs config discussed below.
### Best practices
For the moment we will keep best practices for tests in our other guidelines document:
To that point these guidelines will follow the conventions of Jest and React Native Testing Library recommendations and Status mobile will just stack their preferences on top.
To that point these guidelines will follow the conventions of Jest and React Native Testing Library recomendations and Status mobile will just stack their preferences on top.
### Utilities
There is a file of utility functions defined in "src/test_helpers/component.cljs" and "src/test_helpers/component.clj". It will be great to use these utilities and to add any common testing tools to these files as it should make writing tests easier and faster.
@@ -52,4 +52,4 @@ It's worth knowing that our tests are compiled to JS and then run in the tempora
### Jest
There is also further configuration for Jest in "test/jest". There is a jest config file which has some mostly standard configuration pieces, where the tests live, what environment variables are set etc. This is documented by Jest here: https://jestjs.io/docs/configuration
There is also a setup file which is used to set some global and default values. Additionally this file is used to mock some of the react native (among other) dependencies
There is also a setup file which is used to set some global and default values. Additionally this file is used to mock some of the react native (among other) dependencies
+7 -3
View File
@@ -417,7 +417,9 @@
TestTargetID = 13B07F861A680F5B00A75B9A;
};
13B07F861A680F5B00A75B9A = {
DevelopmentTeam = 8B5X2M6H2Y;
LastSwiftMigration = 1140;
ProvisioningStyle = Manual;
SystemCapabilities = {
com.apple.BackgroundModes = {
enabled = 1;
@@ -841,8 +843,9 @@
BUNDLE_ID_SUFFIX = .debug;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = StatusIm/StatusIm.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_IDENTITY = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CUSTOM_PRODUCT_NAME = "Status Debug";
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 8B5X2M6H2Y;
@@ -896,7 +899,8 @@
PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES;
PRODUCT_BUNDLE_IDENTIFIER = im.status.ethereum;
PRODUCT_NAME = StatusIm;
PROVISIONING_PROFILE_SPECIFIER = "";
PROVISIONING_PROFILE = "9da75626-9594-43d9-a827-0f6d43c28f54";
PROVISIONING_PROFILE_SPECIFIER = "match Development im.status.ethereum";
SWIFT_OBJC_BRIDGING_HEADER = "StatusIm-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
-13
View File
@@ -15,7 +15,6 @@ stdenv.mkDerivation {
"patchYogaNodePackagePhase"
"patchReactNativePhase"
"patchPodPhase"
"patchReactNativeXcodeScriptPhase"
"installPhase"
];
@@ -107,18 +106,6 @@ stdenv.mkDerivation {
'[RCTConvert UIColor:options.tintColor() ? @(*options.tintColor()) : nil];'
'';
# Patch React Native Xcode Script that searches for nvm
# FIXME: Remove this once we upgrade react-native to 0.69.x
patchReactNativeXcodeScriptPhase = ''
substituteInPlace ./node_modules/react-native/scripts/find-node.sh --replace \
'# Define NVM_DIR and source the nvm.sh setup script' \
'<<MULTI_LINE_COMMENT${"\n"}# Define NVM_DIR and source the nvm.sh setup script'
substituteInPlace ./node_modules/react-native/scripts/find-node.sh --replace \
'# Set up the nodenv node version manager if present' \
'MULTI_LINE_COMMENT${"\n"}# Set up the nodenv node version manager if present'
'';
# The ELF types are incompatible with the host platform, so let's not even try
# TODO: Use Android NDK to strip binaries manually
+1 -5
View File
@@ -1,9 +1,6 @@
{ callPackage, lib, mkShell, pkgs, stdenv
{ callPackage, lib, mkShell, pkgs
, status-go, fastlane }:
assert lib.assertMsg stdenv.isDarwin
"iOS development shell supported only on OSX.";
let
inherit (lib) catAttrs unique;
@@ -20,7 +17,6 @@ in {
buildInputs = with pkgs; [
xcodeWrapper watchman procps
flock # used in nix/scripts/node_modules.sh
ios-deploy # used in 'make run-ios-device'
];
# WARNING: Executes shellHook in reverse order.
+3 -1
View File
@@ -1,15 +1,17 @@
{ mkShell, nodejs, deps }:
mkShell {
# Check if node modules changed and if so install them.
shellHook = ''
# Fix for ERR_OSSL_EVP_UNSUPPORTED error.
export NODE_OPTIONS="--openssl-legacy-provider";
# Same fix but for Xcode React Native script.
export NODE_ARGS="--openssl-legacy-provider --max-old-space-size=16384";
# Fix Xcode using system Node.js version.
export NODE_BINARY="${nodejs}/bin/node";
# Check if node modules changed and if so install them.
export STATUS_MOBILE_HOME=$(git rev-parse --show-toplevel)
"$STATUS_MOBILE_HOME/nix/scripts/node_modules.sh" ${deps.nodejs-patched}
'';
}
+1 -13
View File
@@ -44,25 +44,13 @@ in {
});
};
# Fix for missing libarclite_macosx.a in Xcode 14.3.
# https://github.com/ios-control/ios-deploy/issues/580
ios-deploy = super.darwin.ios-deploy.overrideAttrs (old: rec {
version = "1.12.2";
src = super.fetchFromGitHub {
owner = "ios-control";
repo = "ios-deploy";
rev = version;
sha256 = "sha256-TVGC+f+1ow3b93CK3PhIL70le5SZxxb2ug5OkIg8XCA";
};
});
# Package version adjustments
gradle = super.gradle_6;
nodejs = super.nodejs-18_x;
yarn = super.yarn.override { nodejs = super.nodejs-18_x; };
openjdk = super.openjdk8_headless;
xcodeWrapper = callPackage ./pkgs/xcodeenv/compose-xcodewrapper.nix { } {
version = "14.0";
version = "13.3";
allowHigher = true;
};
go = super.go_1_19;
+6 -3
View File
@@ -12,19 +12,22 @@ let
# the default shell with most commonly used tools
default = callPackage ./shell.nix { };
# Combines with many other shells
nodejs-sh = targets.mobile.ios.nodejs-sh;
# An attrset for easier merging with default shell
shells = {
inherit default;
nodejs = nodejs-sh;
# for calling clojure targets in CI or Makefile
clojure = mkShell {
buildInputs = with pkgs; [ clojure flock maven openjdk ];
inputsFrom = [ nodejs-sh ];
# CLASSPATH from clojure deps with 'src' appended to find local sources.
shellHook = with pkgs; ''
export CLASS_PATH="$(find ${deps.clojure} -iname '*.jar' | tr '\n' ':')src"
# Check if node modules changed and if so install them.
"$STATUS_MOBILE_HOME/nix/scripts/node_modules.sh" ${pkgs.deps.nodejs-patched}
'';
};

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before

Width:  |  Height:  |  Size: 539 KiB

After

Width:  |  Height:  |  Size: 539 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 KiB

+4 -4
View File
@@ -71,7 +71,7 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]]))
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]]))
+4 -4
View File
@@ -79,7 +79,7 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
+5 -5
View File
@@ -44,8 +44,8 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:data all-props
:render-fn render-item
:key-fn str}]])
{:flex 1
:keyboardShouldPersistTaps :always
:data all-props
:render-fn render-item
:key-fn str}]])
+6 -6
View File
@@ -113,9 +113,9 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
+6 -6
View File
@@ -91,9 +91,9 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
+6 -6
View File
@@ -83,9 +83,9 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
+5 -5
View File
@@ -31,8 +31,8 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:data all-props
:render-fn render-item
:key-fn str}]])
{:flex 1
:keyboardShouldPersistTaps :always
:data all-props
:render-fn render-item
:key-fn str}]])
+2 -2
View File
@@ -4,7 +4,7 @@
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]
[utils.number]))
[utils.number :as utils-number]))
(def themes
{:light {:default colors/primary-50
@@ -31,7 +31,7 @@
(= type :default))
colors/white
colors/neutral-100))
value (utils.number/parse-int value)
value (utils-number/parse-int value)
label (if (> value max-value)
(str max-value "+")
(str value))
@@ -1,19 +0,0 @@
(ns quo2.components.counter.step.component-spec
(:require [quo2.components.counter.step.view :as step]
[test-helpers.component :as h]))
(h/describe "step component"
(h/test "default render of step component"
(h/render [step/step {} nil])
(-> (h/expect (h/query-by-label-text :step-counter))
(h/is-truthy)))
(h/test "renders step with a string value"
(h/render [step/step {} "1"])
(-> (h/expect (h/get-by-text "1"))
(h/is-truthy)))
(h/test "renders step with an integer value"
(h/render [step/step {} 1])
(-> (h/expect (h/get-by-text "1"))
(h/is-truthy))))
@@ -1,41 +0,0 @@
(ns quo2.components.counter.step.style
(:require
[quo2.foundations.colors :as colors]))
(def container-base
{:align-items :center
:justify-content :center
:border-radius 6
:height 20})
(defn neutral-border-color
[in-blur-view? override-theme]
(if in-blur-view?
(colors/theme-colors colors/white-opa-10 colors/neutral-80-opa-5 override-theme)
(colors/theme-colors colors/neutral-20 colors/neutral-80 override-theme)))
(def active-background-color (colors/custom-color :blue 50 10))
(def complete-background-color (colors/custom-color :blue 50))
(defn container
[size type in-blur-view? override-theme]
(cond-> container-base
(#{1 2} size) (assoc :width 20)
(= size 3) (assoc :width 28)
(= type :neutral)
(assoc :border-width 1
:border-color (neutral-border-color in-blur-view? override-theme))
(= type :active)
(assoc :background-color active-background-color)
(= type :complete)
(assoc :background-color complete-background-color)))
(defn text-color
([type] (text-color type nil))
([type override-theme]
(case type
(:neutral :active) (colors/theme-colors colors/neutral-100-opa-100 colors/white override-theme)
:complete colors/white)))
@@ -1,21 +0,0 @@
(ns quo2.components.counter.step.view
(:require
[quo2.components.counter.step.style :as style]
[quo2.components.markdown.text :as text]
[react-native.core :as rn]
[utils.number]))
(defn step
[{:keys [type accessibility-label override-theme in-blur-view?]} value]
(let [type (or type :neutral)
value (utils.number/parse-int value)
label (str value)
size (count label)]
[rn/view
{:accessible true
:accessibility-label (or accessibility-label :step-counter)
:style (style/container size type in-blur-view? override-theme)}
[text/text
{:weight :medium
:size :label
:style {:color (style/text-color type override-theme)}} label]]))
+2 -4
View File
@@ -132,9 +132,8 @@
:text text}])]]))))
(defn- password-input
[{:keys [default-shown?]
:or {default-shown? false}}]
(let [password-shown? (reagent/atom default-shown?)]
[_]
(let [password-shown? (reagent/atom false)]
(fn [props]
[base-input
(assoc props
@@ -162,7 +161,6 @@
- :label - A string to set as label for this input.
- :char-limit - A number to set a maximum char limit for this input.
- :on-char-limit-reach - Function executed each time char limit is reached or exceeded.
- :default-shown? - boolean to show password input initially
and supports the usual React Native's TextInput properties to control its behaviour:
- :value
- :default-value
@@ -1,68 +0,0 @@
(ns quo2.components.inputs.search-input.style
(:require [quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]))
(defn placeholder-color
[state blur? override-theme]
(cond
(and blur? (= state :active))
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 override-theme)
blur? ; state is default
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30 override-theme)
(= state :active)
(colors/theme-colors colors/neutral-30 colors/neutral-60 override-theme)
:else ; Not blur and state is default
(colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)))
(def clear-icon-container
{:justify-content :center
:align-items :center
:margin-left 8
:height 20
:width 20})
(defn clear-icon
[blur? override-theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 override-theme)
(colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)))
(defn cursor
[customization-color override-theme]
(colors/theme-colors (colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
override-theme))
(def tag-separator {:width 8})
(def tag-container
{:flex-direction :row
:margin-right 8})
(def container
{:flex 1
:flex-direction :row
:align-items :center})
(def scroll-container
{:flex-direction :row
:flex 1
:height 32})
(def scroll-content
{:flex-grow 1
:align-items :center
:justify-content :flex-start})
(defn input-text
[disabled?]
(assoc (text/text-style {:size :paragraph-1
:weight :regular})
:flex 1
:padding-vertical 5
:min-width 120
:opacity (if disabled? 0.3 1)
:min-height 32))
@@ -1,89 +0,0 @@
(ns quo2.components.inputs.search-input.view
(:require [oops.core :as oops]
[quo2.components.icon :as icon]
[quo2.components.inputs.search-input.style :as style]
[react-native.core :as rn]
[reagent.core :as reagent]))
(def ^:private tag-separator [rn/view {:style style/tag-separator}])
(defn- inner-tags
[tags-coll]
(into [rn/view {:style style/tag-container}]
(interpose tag-separator)
tags-coll))
(defn- clear-button
[{:keys [on-press blur? override-theme]}]
[rn/touchable-opacity
{:style style/clear-icon-container
:on-press on-press}
[icon/icon :i/clear
{:color (style/clear-icon blur? override-theme)
:size 20}]])
(defn- handle-backspace
[event ^js/Object scroll-view-ref]
(when (and (= (oops/oget event "nativeEvent.key") "Backspace")
scroll-view-ref)
(.scrollToEnd scroll-view-ref #js {:animated false})))
(def ^:private props-to-remove
[:cursor-color :placeholder-text-color :editable :on-change-text :on-focus
:on-blur :on-clear :value :tags :disabled? :blur? :customization-color :override-theme])
(defn- add-children
[text-input children]
(if (seq children)
(into text-input children)
text-input))
(defn search-input
[{:keys [value]}]
(let [state (reagent/atom :default)
set-active #(reset! state :active)
set-default #(reset! state :default)
scroll-view-ref (atom nil)
use-value? (boolean value)]
(fn [{:keys [value tags disabled? blur? on-change-text customization-color
on-clear on-focus on-blur override-theme]
:or {customization-color :blue}
:as props}
& children]
(let [clean-props (apply dissoc props props-to-remove)]
[rn/view {:style style/container}
[rn/scroll-view
{:ref #(reset! scroll-view-ref %)
:style style/scroll-container
:content-container-style style/scroll-content
:horizontal true
:shows-horizontal-scroll-indicator false}
(when (seq tags)
[inner-tags tags])
(add-children
[rn/text-input
(cond-> {:style (style/input-text disabled?)
:cursor-color (style/cursor customization-color override-theme)
:placeholder-text-color (style/placeholder-color @state blur? override-theme)
:editable (not disabled?)
:on-key-press #(handle-backspace % @scroll-view-ref)
:on-change-text (fn [new-text]
(when on-change-text
(on-change-text new-text))
(reagent/flush))
:on-focus (fn []
(set-active)
(when on-focus (on-focus)))
:on-blur (fn []
(set-default)
(when on-blur (on-blur)))}
use-value? (assoc :value value)
(seq clean-props) (merge clean-props))]
(when-not use-value? children))]
(when (or (seq value) (seq children))
[clear-button
{:on-press on-clear
:blur? blur?
:override-theme override-theme}])]))))
+4 -7
View File
@@ -30,8 +30,7 @@
{:no-color true})))
(defn left-section-view
[{:keys [on-press icon accessibility-label type icon-background-color icon-override-theme]
:or {type :grey}}
[{:keys [on-press icon accessibility-label type icon-background-color] :or {type :grey}}
put-middle-section-on-left?]
[rn/view {:style (when put-middle-section-on-left? {:margin-right 5})}
[button/button
@@ -40,7 +39,6 @@
:type type
:size 32
:accessibility-label accessibility-label
:override-theme icon-override-theme
:override-background-color icon-background-color}
icon]])
@@ -152,7 +150,7 @@
:justify-content :flex-end)}
(let [last-icon-index (-> right-section-buttons count dec)]
(map-indexed (fn [index
{:keys [icon on-press type style icon-override-theme accessibility-label label]
{:keys [icon on-press type style icon-override-theme accessibility-label]
:or {type :grey}}]
^{:key index}
[rn/view
@@ -163,12 +161,11 @@
:accessible true))
[button/button
{:on-press on-press
:icon (not label)
:icon true
:type type
:before (when label icon)
:size 32
:override-theme icon-override-theme}
(if label label icon)]])
icon]])
right-section-buttons))])
(defn page-nav
@@ -1,38 +0,0 @@
(ns quo2.components.notifications.notification.component-spec
(:require
[quo2.components.markdown.text :as text]
[quo2.components.notifications.notification.view :as notification]
[test-helpers.component :as h]))
(h/describe "notification"
(h/test "empty notification"
(h/render [notification/notification {}])
(h/is-null (h/query-by-label-text :notification-avatar))
(h/is-null (h/query-by-label-text :notification-header))
(h/is-null (h/query-by-label-text :notification-body)))
(h/test "notification with title and text"
(h/render [notification/notification
{:title "title"
:title-weight :medium
:text "text"}])
(-> (h/expect (h/get-by-label-text :notification-header))
(.toHaveTextContent "title"))
(-> (h/expect (h/get-by-label-text :notification-body))
(.toHaveTextContent "text")))
(h/test "notification with custom input"
(h/render [notification/notification
{:header [text/text {:accessibility-label :header} "custom header"]
:avatar [text/text {:accessibility-label :avatar} "custom avatar"]
:body [text/text {:accessibility-label :body} "custom body"]}])
(h/is-truthy (h/get-by-label-text :notification-avatar))
(h/is-truthy (h/get-by-label-text :notification-header))
(h/is-truthy (h/get-by-label-text :notification-body))
(h/is-truthy (h/get-by-label-text :avatar))
(h/is-truthy (h/get-by-label-text :header))
(h/is-truthy (h/get-by-label-text :body))
(-> (h/expect (h/get-by-label-text :notification-header))
(.toHaveTextContent "custom header"))
(-> (h/expect (h/get-by-label-text :notification-avatar))
(.toHaveTextContent "custom avatar"))
(-> (h/expect (h/get-by-label-text :notification-body))
(.toHaveTextContent "custom body"))))
@@ -1,39 +0,0 @@
(ns quo2.components.notifications.notification.style
(:require
[quo2.foundations.colors :as colors]
[quo2.foundations.shadows :as shadows]))
(def box-container
{:margin-horizontal 8
:border-radius 16
:overflow :hidden})
(def blur-container
{:height "100%"
:width "100%"
:position :absolute
:padding-vertical 8
:padding-left 10
:padding-right 8
:background-color :transparent})
(defn content-container
[override-theme]
(merge
(:shadow-1 shadows/normal-scale)
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 override-theme)
:flex-direction :row
:padding-vertical 8
:padding-horizontal 12}))
(def right-side-container {:flex 1})
(defn title
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
(defn text
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
(def avatar-container {:margin-right 8 :margin-top 4})
@@ -1,74 +0,0 @@
(ns quo2.components.notifications.notification.view
(:require [quo2.components.markdown.text :as text]
[quo2.components.notifications.notification.style :as style]
[react-native.blur :as blur]
[react-native.core :as rn]))
(defn header-container
[& children]
[into
[rn/view {:accessibility-label :notification-header}] children])
(defn body-container
[& children]
[into [rn/view {:accessibility-label :notification-body}] children])
(defn avatar-container
[& children]
[into
[rn/view
{:style style/avatar-container
:accessibility-label :notification-avatar}]
children])
(defn title
([text weight] (title text weight nil))
([text weight override-theme]
[text/text
{:size :paragraph-1
:weight (or weight :semi-bold)
:style (style/title override-theme)
:accessibility-label :notification-title}
text]))
(defn message
[text override-theme]
[text/text
{:size :paragraph-2
:style (style/text override-theme)
:accessibility-label :notification-content}
text])
(defn- notification-container
[{:keys [avatar header body container-style override-theme]}]
[rn/view
{:style (merge style/box-container container-style)}
[blur/view
{:style style/blur-container
:blur-amount 13
:blur-radius 10
:blur-type :transparent
:overlay-color :transparent}]
[rn/view
{:style (style/content-container override-theme)}
avatar
[rn/view
{:style style/right-side-container}
header
body]]])
(defn notification
[{title-text :title :keys [avatar header title-weight text body container-style override-theme]}]
(let [header (or header
(when title-text
[title title-text title-weight override-theme]))
header (when header [header-container header])
body (or body (when text [message text override-theme]))
body (when body [body-container body])
avatar (when avatar [avatar-container avatar])]
[notification-container
{:avatar avatar
:header header
:body body
:container-style container-style
:override-theme override-theme}]))
@@ -0,0 +1,122 @@
(ns quo2.components.notifications.toast
(:require [quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.components.notifications.count-down-circle :as count-down-circle]
[quo2.foundations.colors :as colors]
[quo2.foundations.shadows :as shadows]
[quo2.theme :as theme]
[utils.i18n :as i18n]
[react-native.blur :as blur]
[react-native.core :as rn]))
(def ^:private themes
{:container {:dark {:background-color colors/white-opa-70}
:light {:background-color colors/neutral-80-opa-70}}
:title {:dark {:color colors/neutral-100}
:light {:color colors/white}}
:text {:dark {:color colors/neutral-100}
:light {:color colors/white}}
:icon {:dark {:color colors/neutral-100}
:light {:color colors/white}}
:action-container {:dark {:background-color colors/neutral-80-opa-5}
:light {:background-color colors/white-opa-5}}})
(defn- merge-theme-style
[component-key styles override-theme]
(merge (get-in themes [component-key (or override-theme (theme/get-theme))]) styles))
(defn toast-action-container
[{:keys [on-press style]} & children]
[rn/touchable-highlight
{:on-press on-press
:underlay-color :transparent}
[into
[rn/view
{:style (merge
{:flex-direction :row
:padding-vertical 3
:padding-horizontal 8
:align-items :center
:border-radius 8
:background-color (get-in themes
[:action-container (theme/get-theme)
:background-color])}
style)}]
children]])
(defn toast-undo-action
[duration on-press override-theme]
[toast-action-container
{:on-press on-press :accessibility-label :toast-undo-action}
[rn/view {:style {:margin-right 5}}
[count-down-circle/circle-timer {:duration duration}]]
[text/text
{:size :paragraph-2 :weight :medium :style (merge-theme-style :text {} override-theme)}
[i18n/label :t/undo]]])
(defn- toast-container
[{:keys [left title text right container-style override-theme]}]
[rn/view
{:style (merge {:margin-horizontal 12
:border-radius 12
:overflow :hidden}
container-style)}
[blur/view
{:style {:height "100%"
:width "100%"
:position :absolute
:padding-vertical 8
:padding-left 10
:padding-right 8
:background-color :transparent}
:blur-amount 13
:blur-radius 10
:blur-type :transparent
:overlay-color :transparent}]
[rn/view
{:style (merge-theme-style :container
(merge
(:shadow-1 shadows/normal-scale)
{:flex-direction :row
:justify-content :space-between
:padding-vertical 8
:padding-left 10
:padding-right 8
:border-radius 12})
override-theme)}
[rn/view {:style {:padding 2}} left]
[rn/view {:style {:padding 4 :flex 1}}
(when title
[text/text
{:size :paragraph-1
:weight :semi-bold
:style (merge-theme-style :title {} override-theme)
:accessibility-label :toast-title}
title])
(when text
[text/text
{:size :paragraph-2
:weight :medium
:style (merge-theme-style :text {} override-theme)
:accessibility-label :toast-content}
text])]
(when right right)]])
(defn toast
[{:keys [icon icon-color title text action undo-duration undo-on-press container-style
override-theme]}]
[toast-container
{:left (when icon
[icon/icon icon
{:container-style {:width 20 :height 20}
:color (or icon-color
(get-in themes
[:icon (or override-theme (theme/get-theme))
:color]))}])
:title title
:text text
:right (if undo-duration
[toast-undo-action undo-duration undo-on-press override-theme]
action)
:container-style container-style
:override-theme override-theme}])
@@ -1,55 +0,0 @@
(ns quo2.components.notifications.toast.style
(:require
[quo2.foundations.colors :as colors]
[quo2.foundations.shadows :as shadows]))
(def box-container
{:margin-horizontal 12
:border-radius 12
:overflow :hidden})
(def blur-container
{:height "100%"
:width "100%"
:position :absolute
:padding-vertical 8
:padding-left 10
:padding-right 8
:background-color :transparent})
(defn content-container
[override-theme]
(merge
(:shadow-1 shadows/normal-scale)
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 override-theme)
:flex-direction :row
:justify-content :space-between
:padding-vertical 8
:padding-left 10
:padding-right 8
:border-radius 12}))
(defn title
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
(defn text
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
(defn icon
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)
:container-style {:width 20 :height 20}})
(def left-side-container {:padding 2})
(def right-side-container {:padding 4 :flex 1})
(defn action-container
[override-theme]
{:background-color (colors/theme-colors colors/white-opa-5 colors/neutral-80-opa-5 override-theme)
:flex-direction :row
:padding-vertical 3
:padding-horizontal 8
:align-items :center
:border-radius 8})
@@ -1,80 +0,0 @@
(ns quo2.components.notifications.toast.view
(:require [quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.components.notifications.count-down-circle :as count-down-circle]
[quo2.components.notifications.toast.style :as style]
[quo2.theme :as theme]
[react-native.blur :as blur]
[react-native.core :as rn]
[utils.i18n :as i18n]))
(defn toast-action-container
[{:keys [on-press style]} & children]
[rn/touchable-highlight
{:on-press on-press
:underlay-color :transparent}
[into
[rn/view
{:style (merge (style/action-container (theme/get-theme)) style)}]
children]])
(defn toast-undo-action
[duration on-press override-theme]
[toast-action-container
{:on-press on-press :accessibility-label :toast-undo-action}
[rn/view {:style {:margin-right 5}}
[count-down-circle/circle-timer {:duration duration}]]
[text/text
{:size :paragraph-2 :weight :medium :style (style/text override-theme)}
[i18n/label :t/undo]]])
(defn- toast-container
[{:keys [left title text right container-style override-theme]}]
[rn/view
{:style (merge style/box-container container-style)}
[blur/view
{:style style/blur-container
:blur-amount 13
:blur-radius 10
:blur-type :transparent
:overlay-color :transparent}]
[rn/view
{:style (style/content-container override-theme)}
[rn/view {:style style/left-side-container} left]
[rn/view {:style style/right-side-container}
(when title
[text/text
{:size :paragraph-1
:weight :semi-bold
:style (style/title override-theme)
:accessibility-label :toast-title}
title])
(when text
[text/text
{:size :paragraph-2
:weight :medium
:style (style/text override-theme)
:accessibility-label :toast-content}
text])]
(when right right)]])
(defn toast
[{:keys [icon icon-color title text action undo-duration undo-on-press container-style
override-theme user]}]
[toast-container
{:left (cond icon
[icon/icon icon
(cond-> (style/icon override-theme)
icon-color
(assoc :color icon-color))]
user
[user-avatar/user-avatar user])
:title title
:text text
:right (if undo-duration
[toast-undo-action undo-duration undo-on-press override-theme]
action)
:container-style container-style
:override-theme override-theme}])
+5 -7
View File
@@ -1,5 +1,4 @@
(ns quo2.components.share.qr-code.style
(:require [quo2.foundations.colors :as colors]))
(ns quo2.components.share.qr-code.style)
(def container
{:flex-direction :row
@@ -7,8 +6,7 @@
(defn image
[width height]
{:width width
:height height
:background-color colors/white-opa-70
:border-radius 12
:aspect-ratio 1})
{:width width
:height height
:border-radius 12
:aspect-ratio 1})
+10 -18
View File
@@ -18,7 +18,6 @@
quo2.components.community.icon
quo2.components.community.token-gating
quo2.components.counter.counter
quo2.components.counter.step.view
quo2.components.dividers.date
quo2.components.dividers.divider-label
quo2.components.dividers.new-messages
@@ -32,15 +31,13 @@
quo2.components.info.info-message
quo2.components.info.information-box
quo2.components.inputs.input.view
quo2.components.inputs.profile-input.view
quo2.components.inputs.search-input.view
quo2.components.inputs.title-input.view
quo2.components.links.url-preview-list.view
quo2.components.inputs.profile-input.view
quo2.components.links.url-preview.view
quo2.components.links.url-preview-list.view
quo2.components.list-items.channel
quo2.components.list-items.menu-item
quo2.components.list-items.preview-list
quo2.components.list-items.user-list
quo2.components.loaders.skeleton
quo2.components.markdown.text
quo2.components.messages.author.view
@@ -52,9 +49,7 @@
quo2.components.notifications.count-down-circle
quo2.components.notifications.info-count
quo2.components.notifications.notification-dot
quo2.components.notifications.notification.view
quo2.components.notifications.toast.view
quo2.components.onboarding.small-option-card.view
quo2.components.notifications.toast
quo2.components.password.tips.view
quo2.components.profile.profile-card.view
quo2.components.profile.select-profile.view
@@ -68,22 +63,26 @@
quo2.components.settings.privacy-option
quo2.components.share.qr-code.view
quo2.components.share.share-qr-code.view
quo2.components.tabs.account-selector
quo2.components.onboarding.small-option-card.view
quo2.components.tabs.segmented-tab
quo2.components.tabs.account-selector
quo2.components.tabs.tabs
quo2.components.tags.context-tag.view
quo2.components.tags.permission-tag
quo2.components.tags.status-tags
quo2.components.tags.permission-tag
quo2.components.tags.tag
quo2.components.tags.tags
quo2.components.tags.token-tag
quo2.components.text-combinations.title.view))
quo2.components.text-combinations.title.view
quo2.components.list-items.user-list))
(def toast quo2.components.notifications.toast/toast)
(def button quo2.components.buttons.button/button)
(def dynamic-button quo2.components.buttons.dynamic-button/dynamic-button)
(def text quo2.components.markdown.text/text)
(def icon quo2.components.icon/icon)
(def separator quo2.components.separator/separator)
(def counter quo2.components.counter.counter/counter)
(def header quo2.components.header/header)
(def dropdown quo2.components.dropdowns.dropdown/dropdown)
(def info-message quo2.components.info.info-message/info-message)
@@ -137,10 +136,6 @@
(def token-gating quo2.components.community.token-gating/token-gating)
(def community-icon quo2.components.community.icon/community-icon)
;;;; COUNTER
(def counter quo2.components.counter.counter/counter)
(def step quo2.components.counter.step.view/step)
;;;; DIVIDERS
(def divider-label quo2.components.dividers.divider-label/divider-label)
(def new-messages quo2.components.dividers.new-messages/new-messages)
@@ -154,7 +149,6 @@
;;;; INPUTS
(def input quo2.components.inputs.input.view/input)
(def search-input quo2.components.inputs.search-input.view/search-input)
(def profile-input quo2.components.inputs.profile-input.view/profile-input)
(def title-input quo2.components.inputs.title-input.view/title-input)
@@ -169,8 +163,6 @@
(def info-count quo2.components.notifications.info-count/info-count)
(def notification-dot quo2.components.notifications.notification-dot/notification-dot)
(def count-down-circle quo2.components.notifications.count-down-circle/circle-timer)
(def notification quo2.components.notifications.notification.view/notification)
(def toast quo2.components.notifications.toast.view/toast)
;;;; PASSWORD
(def tips quo2.components.password.tips.view/view)
-2
View File
@@ -5,7 +5,6 @@
[quo2.components.buttons.--tests--.buttons-component-spec]
[quo2.components.colors.color-picker.component-spec]
[quo2.components.counter.--tests--.counter-component-spec]
[quo2.components.counter.step.component-spec]
[quo2.components.dividers.--tests--.divider-label-component-spec]
[quo2.components.dividers.strength-divider.component-spec]
[quo2.components.drawers.action-drawers.component-spec]
@@ -17,7 +16,6 @@
[quo2.components.links.url-preview-list.component-spec]
[quo2.components.links.url-preview.component-spec]
[quo2.components.markdown.--tests--.text-component-spec]
[quo2.components.notifications.notification.component-spec]
[quo2.components.onboarding.small-option-card.component-spec]
[quo2.components.password.tips.component-spec]
[quo2.components.profile.select-profile.component-spec]
+1 -21
View File
@@ -1,7 +1,5 @@
(ns react-native.hooks
(:require ["@react-native-community/hooks" :as hooks]
[react-native.core :as rn]
[oops.core :as oops]))
(:require ["@react-native-community/hooks" :as hooks]))
(defn use-keyboard
[]
@@ -12,21 +10,3 @@
(defn use-back-handler
[handler]
(.useBackHandler hooks handler))
(defn use-interval
[cb cleanup-cb delay]
(let [saved-callback (rn/use-ref)]
(rn/use-effect
(fn []
(oops/oset! saved-callback "current" cb))
[cb])
(rn/use-effect
(fn []
(let [tick (oops/oget saved-callback "current")]
(when delay
(let [id (js/setInterval tick delay)]
(fn []
(cleanup-cb)
(js/clearInterval id))))))
[delay])))
+1 -1
View File
@@ -8,4 +8,4 @@
(def clippath (reagent/adapt-react-class Svg/ClipPath))
(def defs (reagent/adapt-react-class Svg/Defs))
(def circle (reagent/adapt-react-class Svg/Circle))
(def svgxml (reagent/adapt-react-class Svg/SvgXml))
+22 -64
View File
@@ -4,7 +4,6 @@
[quo.react-native :as rn]
[re-frame.core :as re-frame]
[utils.re-frame :as rf]
[status-im.utils.platform :as platform]
[taoensso.timbre :as log]
[status-im.native-module.core :as status]))
@@ -91,38 +90,29 @@
(assoc-in [:chats/mentions chat-id :mentions] state)
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
(rf/defn on-text-input
{:events [:mention/on-text-input]}
[{:keys [db]} {:keys [previous-text start end] :as args}]
(let [previous-text
;; NOTE(rasom): on iOS `previous-text` contains entire input's text. To
;; get only removed part of text we have cut it.
(if platform/android?
previous-text
(subs previous-text start end))
chat-id (:current-chat-id db)
state (merge args {:previous-text previous-text})
state (set/rename-keys state
{:previous-text :PreviousText
:new-text :NewText
:start :Start
:end :End})
params [chat-id state]
method "wakuext_chatMentionOnTextInput"]
(log/debug "[mentions] on-text-input" {:params params})
(rf/defn on-change-text
{:events [:mention/on-change-text]}
[{:keys [db]} text]
(let [chat-id (:current-chat-id db)
params [chat-id text]
method "wakuext_chatMentionOnChangeText"]
(log/debug "[mentions] on-change-text" {:params params})
{:json-rpc/call [{:method method
:params [chat-id state]
:on-success #(rf/dispatch [:mention/on-text-input-success %])
:params params
:on-success #(rf/dispatch [:mention/on-change-text-success %])
:on-error #(rf/dispatch [:mention/on-error
{:method method
:params params} %])}]}))
(rf/defn on-text-input-success
{:events [:mention/on-text-input-success]}
(rf/defn on-change-text-success
{:events [:mention/on-change-text-success]}
[{:keys [db]} result]
(log/debug "[mentions] on-text-input-success" {:result result})
(let [{:keys [state chat-id]} (transfer-mention-result result)]
{:db (assoc-in db [:chats/mentions chat-id :mentions] state)}))
(let [{:keys [state chat-id mentionable-users input-segments]} (transfer-mention-result result)]
{:db (-> db
(assoc-in [:chats/mention-suggestions chat-id] mentionable-users)
(assoc-in [:chats/mentions chat-id :mentions] state)
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
(rf/defn recheck-at-idxs
[{:keys [db]} public-key]
@@ -175,16 +165,6 @@
;; programmatic change. By calling `reset-text-input-cursor` we force the
;; keyboard's cursor position to be changed before the next input.
(reset-text-input-cursor text-input-ref cursor)
;; NOTE(roman): on-text-input event is not dispatched when we change input
;; programmatically, so we have to call `on-text-input` manually
(on-text-input
(let [match-len (count match)
start (inc at-sign-idx)
end (+ start match-len)]
{:new-text match
:previous-text searched-text
:start start
:end end}))
(recheck-at-idxs public-key))))
(rf/defn clear-suggestions
@@ -220,7 +200,7 @@
(when text
(log/debug "[mentions] check-selection" {:params params})
{:json-rpc/call [{:method method
:params [chat-id text start end]
:params params
:on-success #(rf/dispatch [:mention/on-handle-selection-change-success %])
:on-error #(rf/dispatch [:mention/on-error
{:method method
@@ -230,8 +210,11 @@
{:events [:mention/on-handle-selection-change-success]}
[{:keys [db]} result]
(log/debug "[mentions] on-check-selection-success" {:result result})
(let [{:keys [state chat-id]} (transfer-mention-result result)]
{:db (assoc-in db [:chats/mentions chat-id :mentions] (rename-state state))}))
(let [{:keys [state chat-id mentionable-users input-segments]} (transfer-mention-result result)]
{:db (-> db
(assoc-in [:chats/mention-suggestions chat-id] mentionable-users)
(assoc-in [:chats/mentions chat-id :mentions] state)
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
(re-frame/reg-fx
::reset-text-input-cursor
@@ -240,28 +223,3 @@
(status/reset-keyboard-input
(rn/find-node-handle (react/current-ref ref))
cursor))))
(rf/defn calculate-suggestions
{:events [:mention/calculate-suggestions]}
[{:keys [db]}]
(let [chat-id (:current-chat-id db)
text (get-in db [:chat/inputs chat-id :input-text])
params [chat-id text]
method "wakuext_chatMentionCalculateSuggestions"]
(log/debug "[mentions] calculate-suggestions" {:params params})
{:json-rpc/call [{:method method
:params [chat-id text]
:on-success #(rf/dispatch [:mention/on-calculate-suggestions-success %])
:on-error #(rf/dispatch [:mention/on-error
{:method method
:params params} %])}]}))
(rf/defn on-calculate-suggestions-success
{:events [:mention/on-calculate-suggestions-success]}
[{:keys [db]} result]
(log/debug "[mentions] on-calculate-suggestions-success" {:result result})
(let [{:keys [state chat-id mentionable-users input-segments]} (transfer-mention-result result)]
{:db (-> db
(assoc-in [:chats/mention-suggestions chat-id] mentionable-users)
(assoc-in [:chats/mentions chat-id :mentions] state)
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
+14 -32
View File
@@ -87,27 +87,23 @@
(:communities/community-id-input db))
(defn- handle-my-request
[db {:keys [community-id state deleted] :as request}]
(if (and (= constants/community-request-to-join-state-pending state) (not deleted))
(assoc-in db [:communities/my-pending-requests-to-join community-id] request)
(update-in db [:communities/my-pending-requests-to-join] dissoc community-id)))
[db {:keys [community-id state] :as request}]
{:db (if (= constants/community-request-to-join-state-pending state)
(assoc-in db [:communities/my-pending-requests-to-join community-id] request)
(update-in db [:communities/my-pending-requests-to-join] dissoc community-id))})
(defn handle-admin-request
[db {:keys [id community-id deleted] :as request}]
(if deleted
(update-in db [:communities/requests-to-join community-id] dissoc id)
(assoc-in db [:communities/requests-to-join community-id id] request)))
[db {:keys [id community-id] :as request}]
{:db (assoc-in db [:communities/requests-to-join community-id id] request)})
(rf/defn handle-requests-to-join
[{:keys [db]} requests]
(let [my-public-key (get-in db [:multiaccount :public-key])]
{:db (reduce (fn [db {:keys [public-key] :as request}]
(let [my-request? (= my-public-key public-key)]
(if my-request?
(handle-my-request db request)
(handle-admin-request db request))))
db
requests)}))
(rf/defn handle-request-to-join
[{:keys [db]} r]
(let [my-public-key (get-in db [:multiaccount :public-key])
{:keys [id community-id public-key] :as request} (<-request-to-join-community-rpc r)
my-request? (= my-public-key public-key)]
(if my-request?
(handle-my-request db request)
(handle-admin-request db request))))
(rf/defn handle-removed-chats
[{:keys [db]} chat-ids]
@@ -321,7 +317,6 @@
:on-error #(do
(log/error "failed to invite-user community" %)
(re-frame/dispatch [::failed-to-invite-people %]))}]})))
(rf/defn share-community
{:events [::share-community-confirmation-pressed]}
[cofx user-pk contacts]
@@ -903,16 +898,3 @@
:event :communities/toggle-collapsed-category
:category-id category-id
:collapse? collapse?})}]})
(rf/defn check-and-delete-pending-request-to-join
{:events [:communities/check-and-delete-pending-request-to-join]}
[_]
{:json-rpc/call [{:method "wakuext_checkAndDeletePendingRequestToJoinCommunity"
:params []
:js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/info
"failed to fetch communities"
{:error %
:event
:communities/check-and-delete-pending-request-to-join-community})}]})
+1 -2
View File
@@ -60,8 +60,7 @@
(:contacts/contacts db)
public-key)
(assoc :blocked? true
:added? false
:active? false))
:added? false))
from-one-to-one-chat? (not (get-in db [:chats (:current-chat-id db) :group-chat]))]
(rf/merge cofx
{:db (assoc-in db [:contacts/contacts public-key] contact)}
+1 -2
View File
@@ -59,8 +59,7 @@
status-im2.contexts.shell.events
status-im2.contexts.onboarding.events
status-im.chat.models.gaps
[status-im2.navigation.events :as navigation]
status-im2.contexts.chat.home.events))
[status-im2.navigation.events :as navigation]))
(re-frame/reg-fx
:dismiss-keyboard
+18 -22
View File
@@ -365,25 +365,9 @@
[_]
(status/get-node-config #(re-frame/dispatch [::get-node-config-callback %])))
(rf/defn redirect-to-root
"Decides which root should be initialised depending on user and app state"
[{:keys [db] :as cofx}]
(cond
(get db :onboarding-2/new-account?)
{:dispatch [:onboarding-2/finalize-setup]}
(get db :tos/accepted?)
(rf/merge
cofx
(multiaccounts/switch-theme nil :shell-stack)
(navigation/init-root :shell-stack))
:else
{:dispatch [:init-root :tos]}))
(rf/defn get-settings-callback
{:events [::get-settings-callback]}
[{:keys [db] :as cofx} settings pairing-in-progress?]
[{:keys [db] :as cofx} settings]
(let [{:networks/keys [current-network networks]
:as settings}
(data-store.settings/rpc->settings settings)
@@ -410,13 +394,10 @@
(get-node-config)
(communities/fetch)
(communities/fetch-collapsed-community-categories)
(communities/check-and-delete-pending-request-to-join)
(logging/set-log-level (:log-level multiaccount))
(activity-center/notifications-fetch-pending-contact-requests)
(activity-center/update-seen-state)
(activity-center/notifications-fetch-unread-count)
(when-not pairing-in-progress?
(redirect-to-root)))))
(activity-center/notifications-fetch-unread-count))))
(re-frame/reg-fx
::open-last-chat
@@ -491,6 +472,19 @@
keychain/auth-method-biometric
keychain/auth-method-password))))
(defn redirect-to-root
"Decides which root should be initialised depending on user and app state"
[db]
(cond
(get db :onboarding-2/new-account?)
(re-frame/dispatch [:onboarding-2/finalize-setup])
(get db :tos/accepted?)
(re-frame/dispatch [:init-root :shell-stack])
:else
(re-frame/dispatch [:init-root :tos])))
(rf/defn login-only-events
[{:keys [db] :as cofx} key-uid password save-password?]
(let [auth-method (:auth-method db)
@@ -503,7 +497,9 @@
{:db (assoc db :chats/loading? true)
:json-rpc/call
[{:method "settings_getSettings"
:on-success #(re-frame/dispatch [::get-settings-callback % pairing-in-progress?])}]}
:on-success #(do (re-frame/dispatch [::get-settings-callback %])
(when-not pairing-in-progress?
(redirect-to-root db)))}]}
(notifications/load-notification-preferences)
(when save-password?
(keychain/save-user-password key-uid password))
+5
View File
@@ -1,6 +1,11 @@
(ns status-im.search.core
(:require [utils.re-frame :as rf]))
(rf/defn home-filter-changed
{:events [:search/home-filter-changed]}
[cofx search-filter]
{:db (assoc-in (:db cofx) [:ui/search :home-filter] search-filter)})
(rf/defn currency-filter-changed
{:events [:search/currency-filter-changed]}
[cofx search-filter]
+2 -5
View File
@@ -124,13 +124,10 @@
(models.communities/handle-removed-chats removed-chats-clj)))
(seq requests-to-join-community)
(let [requests (->> requests-to-join-community
types/js->clj
(map models.communities/<-request-to-join-community-rpc))]
(js-delete response-js "requestsToJoinCommunity")
(let [request-js (types/js->clj (.pop requests-to-join-community))]
(rf/merge cofx
(process-next response-js sync-handler)
(models.communities/handle-requests-to-join requests)))
(models.communities/handle-request-to-join request-js)))
(seq emoji-reactions)
(let [reactions (types/js->clj emoji-reactions)]
@@ -1,4 +1,4 @@
(ns status-im2.common.qr-code-viewer.style
(ns status-im.ui.components.qr-code-viewer.styles
(:require [quo.design-system.colors :as colors]))
(def qr-code-padding 16)
@@ -14,4 +14,4 @@
:align-items :center
:justify-content :center
:border-width 1
:border-radius 8})
:border-radius 8})
@@ -0,0 +1,33 @@
(ns status-im.ui.components.qr-code-viewer.views
(:require ["qrcode" :as qr-code-js]
["react-native-svg" :refer (SvgXml)]
[cljs-bean.core :as bean]
[reagent.core :as reagent]
[status-im.ui.components.qr-code-viewer.styles :as styles]
[status-im.ui.components.react :as react]))
(def svgxml (reagent/adapt-react-class SvgXml))
(defn qr-code
[{:keys [size value]}]
(let [uri (reagent/atom nil)]
(.toString
qr-code-js
value
(bean/->js {:margin 0 :width size})
#(reset! uri %2))
(fn []
(when @uri
[svgxml {:xml @uri :width size :height size}]))))
(defn qr-code-view
"Qr Code view including the frame.
Note: `size` includes frame with `styles/qr-code-padding.`"
[size value]
(when (and size value)
[react/view
{:style (styles/qr-code-container size)
:accessibility-label :qr-code-image}
[qr-code
{:value value
:size (- size (* styles/qr-code-padding 2))}]]))
@@ -198,11 +198,7 @@
(when platform/android?
(reset! last-text-change (js/Date.now)))
(on-text-change text chat-id)
;; NOTE(rasom): on iOS `on-change` is dispatched after `on-text-input`,
;; that's why mention suggestions are calculated on `on-change`
(when platform/ios?
(re-frame/dispatch [:mention/calculate-suggestions]))))
(on-text-change text chat-id)))
(rf/defn set-input-text
"Set input text for current-chat. Takes db and input text and cofx
@@ -220,26 +216,10 @@
(defn on-text-input
[chat-id args]
(let [native-event (.-nativeEvent ^js args)
text (.-text ^js native-event)
previous-text (.-previousText ^js native-event)
range (.-range ^js native-event)
start (.-start ^js range)
end (.-end ^js range)]
(let [native-event (.-nativeEvent ^js args)
text (.-text ^js native-event)]
(when (and (not (get @mentions-enabled chat-id)) (string/index-of text "@"))
(swap! mentions-enabled assoc chat-id true))
(re-frame/dispatch
[:mention/on-text-input
{:new-text text
:previous-text previous-text
:start start
:end end}])
;; NOTE(rasom): on Android `on-text-input` is dispatched after
;; `on-change`, that's why mention suggestions are calculated
;; on `on-change`
(when platform/android?
(re-frame/dispatch [:mention/calculate-suggestions]))))
(swap! mentions-enabled assoc chat-id true))))
(defn text-input
[{:keys [set-active-panel refs chat-id sending-image]}]
@@ -331,13 +311,13 @@
[rn/view
{:style {:height height}}
[list/flat-list
{:keyboard-should-persist-taps :always
:footer [rn/view {:style {:height 8}}]
:header [rn/view {:style {:height 8}}]
:data suggestions
:key-fn first
:render-data text-input-ref
:render-fn mention-item}]]]))))
{:keyboardShouldPersistTaps :always
:footer [rn/view {:style {:height 8}}]
:header [rn/view {:style {:height 8}}]
:data suggestions
:key-fn first
:render-data text-input-ref
:render-fn mention-item}]]]))))
(defn on-chat-toolbar-layout
[^js ev]
@@ -65,9 +65,9 @@
[]
(letsubs [blocked-contacts [:contacts/blocked]]
[list.views/flat-list
{:data blocked-contacts
:key-fn :address
:render-fn contacts-list-item
:default-separator? true
:enableEmptySections true
:keyboard-should-persist-taps :always}]))
{:data blocked-contacts
:key-fn :address
:render-fn contacts-list-item
:default-separator? true
:enableEmptySections true
:keyboardShouldPersistTaps :always}]))
@@ -44,10 +44,10 @@
:on-change (fn [text]
(re-frame/dispatch [:search/currency-filter-changed text]))}]]
[list/flat-list
{:data (->> currencies
vals
(sort #(compare (:code %1) (:code %2))))
:key-fn :code
:render-data currency-id
:render-fn render-currency
:keyboard-should-persist-taps :always}]]]))
{:data (->> currencies
vals
(sort #(compare (:code %1) (:code %2))))
:key-fn :code
:render-data currency-id
:render-fn render-currency
:keyboardShouldPersistTaps :always}]]]))
+2 -2
View File
@@ -219,11 +219,11 @@
[:ens/search-screen]]
[react/keyboard-avoiding-view {:flex 1}
[react/scroll-view
{:style {:flex 1}
{:style {:flex 1}
;;NOTE required so that switching custom-domain
;;works on first tap and persists keyboard
;;instead of dismissing keyboard and requiring two taps
:keyboard-should-persist-taps :always}
:keyboardShouldPersistTaps :always}
[react/view {:style {:flex 1}}
[react/view
{:style {:flex 1
+5 -5
View File
@@ -76,11 +76,11 @@
(defn toggle-list
[{:keys [contacts render-fn render-data]}]
[list/flat-list
{:data contacts
:key-fn :public-key
:render-data render-data
:render-fn render-fn
:keyboard-should-persist-taps :always}])
{:data contacts
:key-fn :public-key
:render-data render-data
:render-fn render-fn
:keyboardShouldPersistTaps :always}])
(defn no-contacts
[{:keys [no-contacts]}]
@@ -58,8 +58,8 @@
banner-hidden [:keycard/banner-hidden]]
[react/keyboard-avoiding-view {:style ast/multiaccounts-view}
[react/scroll-view
{:keyboard-should-persist-taps :always
:style styles/login-view}
{:keyboardShouldPersistTaps :always
:style styles/login-view}
[react/view styles/login-badge-container
[multiaccount-login-badge multiaccount]
[react/view {:style styles/password-container}
@@ -11,7 +11,7 @@
[status-im.ui.components.copyable-text :as copyable-text]
[status-im.ui.components.list-selection :as list-selection]
[status-im.ui.components.profile-header.view :as profile-header]
[status-im2.common.qr-code-viewer.view :as qr-code-viewer]
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
[status-im.ui.components.react :as react]
[status-im.ui.screens.profile.user.edit-picture :as edit]
[status-im.ui.screens.profile.user.styles :as styles]
@@ -6,7 +6,7 @@
[status-im.ethereum.eip681 :as eip681]
[utils.i18n :as i18n]
[status-im.ui.components.copyable-text :as copyable-text]
[status-im2.common.qr-code-viewer.view :as qr-code-viewer]
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
[status-im.ui.components.react :as react])
(:require-macros [status-im.utils.views :as views]))
@@ -141,33 +141,15 @@
(reset! last-text-change (js/Date.now)))
(on-text-change text chat-id)
;; NOTE(rasom): on iOS `on-change` is dispatched after `on-text-input`,
;; that's why mention suggestions are calculated on `on-change`
(when platform/ios?
(rf/dispatch [:mention/calculate-suggestions]))))
(rf/dispatch [:mention/on-change-text text])))
(defn on-text-input
[chat-id args]
(let [native-event (.-nativeEvent ^js args)
text (.-text ^js native-event)
previous-text (.-previousText ^js native-event)
range (.-range ^js native-event)
start (.-start ^js range)
end (.-end ^js range)]
(let [native-event (.-nativeEvent ^js args)
text (.-text ^js native-event)]
(when (and (not (get @mentions-enabled? chat-id)) (string/index-of text "@"))
(swap! mentions-enabled? assoc chat-id true))
(rf/dispatch
[:mention/on-text-input
{:new-text text
:previous-text previous-text
:start start
:end end}])
;; NOTE(rasom): on Android `on-text-input` is dispatched after
;; `on-change`, that's why mention suggestions are calculated
;; on `on-change`
(when platform/android?
(rf/dispatch [:mention/calculate-suggestions]))))
(swap! mentions-enabled? assoc chat-id true))))
(defn text-input-style
[chat-id]
@@ -1,34 +1,36 @@
(ns utils.image-server
(:require [utils.datetime :as datetime]))
(ns status-im.utils.image-server
(:require [quo.design-system.colors :as colors]))
(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 timestamp [] (datetime/timestamp))
(defn current-theme-index
[theme]
(case theme
(defn current-theme
[]
(case @colors/theme-type
:light 1
:dark 2))
(defn- timestamp
[]
(.getTime (js/Date.)))
(defn get-identicons-uri
[port public-key theme]
[port public-key]
(str image-server-uri-prefix
port
identicons-action
"?publicKey="
public-key
"&theme="
(current-theme-index theme)
(current-theme)
"&clock="
(timestamp)
"&addRing=1"))
(defn get-account-image-uri
[port public-key image-name key-uid theme]
[port public-key image-name key-uid]
(str image-server-uri-prefix
port
account-images-action
@@ -39,13 +41,13 @@
"&imageName="
image-name
"&theme="
(current-theme-index theme)
(current-theme)
"&clock="
(timestamp)
"&addRing=1"))
(defn get-contact-image-uri
[port public-key image-name clock theme]
[port public-key image-name clock]
(str image-server-uri-prefix
port
contact-images-action
@@ -54,7 +56,7 @@
"&imageName="
image-name
"&theme="
(current-theme-index theme)
(current-theme)
"&clock="
clock
"&addRing=1"))
@@ -1,31 +0,0 @@
(ns status-im2.common.qr-code-viewer.view
(:require ["qrcode" :as qr-code-js]
[cljs-bean.core :as bean]
[reagent.core :as reagent]
[status-im2.common.qr-code-viewer.style :as style]
[react-native.core :as rn]
[react-native.svg :as svg]))
(defn qr-code
[{:keys [size value]}]
(let [uri (reagent/atom nil)]
(.toString
qr-code-js
value
(bean/->js {:margin 0 :width size})
#(reset! uri %2))
(fn []
(when @uri
[svg/svgxml {:xml @uri :width size :height size}]))))
(defn qr-code-view
"Qr Code view including the frame.
Note: `size` includes frame with `style/qr-code-padding.`"
[size value]
(when (and size value)
[rn/view
{:style (style/qr-code-container size)
:accessibility-label :qr-code-image}
[qr-code
{:value value
:size (- size (* style/qr-code-padding 2))}]]))
+4 -5
View File
@@ -5,12 +5,11 @@
:lifestyle (js/require "../resources/images/ui2/lifestyle.png")
:music (js/require "../resources/images/ui2/music.png")
:podcasts (js/require "../resources/images/ui2/podcasts.png")
:generate-keys (js/require "../resources/images/ui2/generate-keys.png")
:ethereum-address (js/require "../resources/images/ui2/ethereum-address.png")
:sync-device (js/require "../resources/images/ui2/sync-new-device-cover-background.png")
:generate-keys (js/require "../resources/images/ui2/generate_keys.png")
:ethereum-address (js/require "../resources/images/ui2/ethereum_address.png")
:use-keycard (js/require "../resources/images/ui2/keycard.png")
:onboarding-illustration (js/require "../resources/images/ui2/onboarding_illustration.png")
:qr-code (js/require "../resources/images/ui2/qr-code.png")
})
:onboarding-illustration (js/require "../resources/images/ui2/onboarding_illustration.png")})
(def mock-images
{:coinbase (js/require "../resources/images/mock2/coinbase.png")
+6 -9
View File
@@ -28,10 +28,8 @@
(defn toast
[id]
(let [{:keys [type] :as toast-opts} (rf/sub [:toasts/toast id])]
(if (= type :notification)
[quo/notification toast-opts]
[quo/toast toast-opts])))
(let [toast-opts (rf/sub [:toasts/toast id])]
[quo/toast toast-opts]))
(defn container
[id]
@@ -43,7 +41,7 @@
[:f>
(fn []
(let [duration (or (rf/sub [:toasts/toast-cursor id :duration]) 3000)
on-dismissed (or (rf/sub [:toasts/toast-cursor id :on-dismissed]) identity)
on-dismissed #((or (rf/sub [:toasts/toast-cursor id :on-dismissed]) identity) id)
create-timer (fn []
(reset! timer (utils.utils/set-timeout close! duration)))
translate-y (reanimated/use-shared-value 0)
@@ -80,10 +78,10 @@
(create-timer)))))]
;; create auto dismiss timer, clear timer when unmount or duration changed
(rn/use-effect (fn [] (create-timer) clear-timer) [duration])
(rn/use-unmount #(on-dismissed id))
(rn/use-unmount on-dismissed)
[gesture/gesture-detector {:gesture pan}
[reanimated/view
{;; TODO: this will enable layout animation at runtime and causing flicker on android
{;; TODO: this will eanble layout animation at runtime and causing flicker on android
;; we need to resolve this and re-enable layout animation
;; issue at https://github.com/status-im/status-mobile/issues/14752
;; :entering slide-in-up-animation
@@ -100,5 +98,4 @@
[into
[rn/view
{:style style/outmost-transparent-container}]
(doall
(map (fn [id] ^{:key id} [container id]) toasts-ordered))]))
(map (fn [id] ^{:key id} [container id]) toasts-ordered)]))
@@ -532,33 +532,29 @@
[{:keys [db]} new-notifications]
(let [my-public-key (get-in db [:multiaccount :public-key])]
(reduce (fn [cofx {:keys [author type accepted dismissed message name] :as x}]
(let [user-avatar {:full-name name
:status-indicator? true
:online? nil
:size :small
:ring? false}]
(cond
(and (not= author my-public-key)
(= type types/contact-request)
(not accepted)
(not dismissed))
(toasts/upsert cofx
{:user user-avatar
:icon-color colors/primary-50-opa-40
:title (i18n/label :t/contact-request-sent-toast
{:name name})
:text (get-in message [:content :text])})
(cond
(and (not= author my-public-key)
(= type types/contact-request)
(not accepted)
(not dismissed))
(toasts/upsert cofx
{:icon :placeholder
:icon-color colors/primary-50-opa-40
:title (i18n/label :t/contact-request-sent-toast
{:name name})
:text (get-in message [:content :text])})
(and (= author my-public-key) ;; we show it for user who sent the request
(= type types/contact-request)
accepted
(not dismissed))
(toasts/upsert cofx
{:user user-avatar
:icon-color colors/success-50-opa-40
:title (i18n/label :t/contact-request-accepted-toast
{:name (or name (:alias message))})})
:else
cofx)))
(and (= author my-public-key) ;; we show it for user who sent the request
(= type types/contact-request)
accepted
(not dismissed))
(toasts/upsert cofx
{:icon :placeholder
:icon-color colors/primary-50-opa-40
:title (i18n/label :t/contact-request-accepted-toast
{:name (or name (:alias message))})})
:else
cofx))
{:db db}
new-notifications)))
@@ -8,13 +8,6 @@
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(def tag-params
{:size :small
:override-theme :dark
:color colors/primary-50
:style style/user-avatar-tag
:text-style style/user-avatar-tag-text})
(defn user-avatar-tag
[user-id]
(let [contact (rf/sub [:contacts/contact-by-identity user-id])]
@@ -1,64 +0,0 @@
(ns status-im2.contexts.activity-center.notification.community-request.view
(:require [quo2.core :as quo]
[status-im2.constants :as constants]
[status-im2.contexts.activity-center.notification.common.style :as common-style]
[status-im2.contexts.activity-center.notification.common.view :as common]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- swipeable
[{:keys [active-swipeable extra-fn]} child]
[common/swipeable
{:left-button common/swipe-button-read-or-unread
:left-on-press common/swipe-on-press-toggle-read
:right-button common/swipe-button-delete
:right-on-press common/swipe-on-press-delete
:active-swipeable active-swipeable
:extra-fn extra-fn}
child])
(defn- get-header-text-and-context
[community membership-status]
(let [community-name (:name community)
community-image (get-in community [:images :thumbnail :uri])
community-context-tag [quo/context-tag common/tag-params {:uri community-image}
community-name]]
(cond
(= membership-status constants/activity-center-membership-status-idle)
{:header-text (i18n/label :t/community-request-not-accepted)
:context [[quo/text {:style common-style/user-avatar-tag-text}
(i18n/label :t/community-request-not-accepted-body-text-prefix)]
community-context-tag
[quo/text {:style common-style/user-avatar-tag-text}
(i18n/label :t/community-request-not-accepted-body-text-suffix)]]}
(= membership-status constants/activity-center-membership-status-pending)
{:header-text (i18n/label :t/community-request-pending)
:context [[quo/text {:style common-style/user-avatar-tag-text}
(i18n/label :t/community-request-pending-body-text)]
community-context-tag]}
(= membership-status constants/activity-center-membership-status-accepted)
{:header-text (i18n/label :t/community-request-accepted)
:context [[quo/text {:style common-style/user-avatar-tag-text}
(i18n/label :t/community-request-accepted-body-text)]
community-context-tag]}
:else nil)))
(defn view
[{:keys [notification set-swipeable-height] :as props}]
(let [{:keys [community-id membership-status read
timestamp]} notification
community (rf/sub [:communities/community community-id])
{:keys [header-text context]} (get-header-text-and-context community
membership-status)]
[swipeable props
[quo/activity-log
{:title header-text
:icon :i/communities
:on-layout set-swipeable-height
:timestamp (datetime/timestamp->relative timestamp)
:unread? (not read)
:context context}]]))
@@ -6,7 +6,6 @@
(def ^:const mention 3)
(def ^:const reply 4)
(def ^:const contact-request 5)
(def ^:const community-request 7)
(def ^:const admin 8)
(def ^:const contact-verification 10)
@@ -16,7 +15,6 @@
mention
reply
contact-request
community-request
admin
contact-verification})
@@ -28,5 +26,4 @@
"Membership is like a logical group of notifications with different types, i.e.
it doesn't have a corresponding type in the backend. Think of the collection
as a composite key of actual types."
#{private-group-chat
community-request})
#{private-group-chat})
@@ -12,8 +12,6 @@
[status-im2.contexts.activity-center.notification.membership.view :as membership]
[status-im2.contexts.activity-center.notification.mentions.view :as mentions]
[status-im2.contexts.activity-center.notification.reply.view :as reply]
[status-im2.contexts.activity-center.notification.community-request.view :as
community-request]
[status-im2.contexts.activity-center.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
@@ -198,12 +196,7 @@
[admin/view props]
(some types/membership [type])
(case type
types/private-group-chat [membership/view props]
types/community-request [community-request/view props]
nil)
[membership/view props]
:else
nil)]))))
@@ -3,6 +3,18 @@
[react-native.platform :as platform]
[quo2.foundations.typography :as typography]))
(defn container-kbd
[]
{:style {:flex 1}
:keyboardVerticalOffset 60})
(def container-image
{:style {:flex 1
:flex-direction :row}})
(def image
{:flex 1})
(defn container-outer
[]
{:style {:flex (if platform/ios? 4.5 5)
@@ -29,8 +41,7 @@
[]
{:size :heading-1
:weight :semi-bold
:style {:margin-top 32
:margin-bottom 6
:style {:margin-bottom 6
:color (colors/theme-colors
colors/neutral-100
colors/white)}})
@@ -116,8 +127,11 @@
:accessibility-label :new-contact-close-button
:size 32
:override-background-color (colors/theme-colors
colors/neutral-10
colors/neutral-90)})
colors/white-opa-60
colors/neutral-80-opa-60)
:style {:position :absolute
:left 20
:top 20}})
(def button-qr
{:type :outline
@@ -5,6 +5,7 @@
[react-native.core :as rn]
[react-native.clipboard :as clipboard]
[reagent.core :as reagent]
[status-im2.common.resources :as resources]
[status-im.qr-scanner.core :as qr-scanner]
[status-im.utils.utils :as utils]
[status-im2.contexts.add-new-contact.style :as style]
@@ -54,9 +55,11 @@
show-paste-button? (and (not (string/blank? @clipboard))
(string/blank? @default-value)
(string/blank? input))]
[rn/view (style/container-outer)
[rn/view style/container-inner
[rn/keyboard-avoiding-view (style/container-kbd)
[rn/view style/container-image
[rn/image
{:source (resources/get-image :add-new-contact)
:style style/image}]
[quo/button
(merge (style/button-close)
{:on-press
@@ -64,54 +67,56 @@
(reset! clipboard nil)
(reset! default-value nil)
(rf/dispatch [:contacts/clear-new-identity])
(rf/dispatch [:navigate-back]))}) :i/close]
[quo/text (style/text-title)
(i18n/label :t/add-a-contact)]
[quo/text (style/text-subtitle)
(i18n/label :t/find-your-friends)]
[quo/text (style/text-description)
(i18n/label :t/ens-or-chat-key)]
[rn/view style/container-text-input
[rn/view (style/text-input-container invalid?)
[rn/text-input
(merge (style/text-input)
{:default-value (or scanned @default-value input)
:placeholder (i18n/label :t/type-some-chat-key)
:on-change-text (fn [v]
(reset! default-value v)
(debounce/debounce-and-dispatch
[:contacts/set-new-identity v nil]
600))})]
(when show-paste-button?
[quo/button
(merge style/button-paste
{:on-press
(fn []
(reset! default-value @clipboard)
(rf/dispatch
[:contacts/set-new-identity @clipboard nil]))})
(i18n/label :t/paste)])]
(rf/dispatch [:navigate-back]))}) :i/close]]
[rn/view (style/container-outer)
[rn/view style/container-inner
[quo/text (style/text-title)
(i18n/label :t/add-a-contact)]
[quo/text (style/text-subtitle)
(i18n/label :t/find-your-friends)]
[quo/text (style/text-description)
(i18n/label :t/ens-or-chat-key)]
[rn/view style/container-text-input
[rn/view (style/text-input-container invalid?)
[rn/text-input
(merge (style/text-input)
{:default-value (or scanned @default-value input)
:placeholder (i18n/label :t/type-some-chat-key)
:on-change-text (fn [v]
(reset! default-value v)
(debounce/debounce-and-dispatch
[:contacts/set-new-identity v nil]
600))})]
(when show-paste-button?
[quo/button
(merge style/button-paste
{:on-press
(fn []
(reset! default-value @clipboard)
(rf/dispatch
[:contacts/set-new-identity @clipboard nil]))})
(i18n/label :t/paste)])]
[quo/button
(merge style/button-qr
{:on-press #(rf/dispatch
[::qr-scanner/scan-code
{:handler :contacts/qr-code-scanned}])})
:i/scan]]
(when invalid?
[rn/view style/container-invalid
[quo/icon :i/alert style/icon-invalid]
[quo/text style/text-invalid
(i18n/label (or msg :t/invalid-ens-or-key))]])
(when (= state :valid)
[found-contact public-key])]
[rn/view
[quo/button
(merge style/button-qr
{:on-press #(rf/dispatch
[::qr-scanner/scan-code
{:handler :contacts/qr-code-scanned}])})
:i/scan]]
(when invalid?
[rn/view style/container-invalid
[quo/icon :i/alert style/icon-invalid]
[quo/text style/text-invalid
(i18n/label (or msg :t/invalid-ens-or-key))]])
(when (= state :valid)
[found-contact public-key])]
[rn/view
[quo/button
(merge (style/button-view-profile state)
{:on-press
(fn []
(reset! clipboard nil)
(reset! default-value nil)
(rf/dispatch [:contacts/clear-new-identity])
(rf/dispatch [:navigate-back])
(rf/dispatch [:chat.ui/show-profile public-key ens]))})
(i18n/label :t/view-profile)]]]))))
(merge (style/button-view-profile state)
{:on-press
(fn []
(reset! clipboard nil)
(reset! default-value nil)
(rf/dispatch [:contacts/clear-new-identity])
(rf/dispatch [:navigate-back])
(rf/dispatch [:chat.ui/show-profile public-key ens]))})
(i18n/label :t/view-profile)]]]]))))
@@ -14,7 +14,8 @@
[chat-id]
(fn []
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:chat/navigate-to-chat chat-id])))
(rf/dispatch [:chat/navigate-to-chat chat-id])
(rf/dispatch [:search/home-filter-changed nil])))
(defn truncate-literal
[literal]
@@ -45,12 +45,8 @@
[rn/view {:style (style/contact-requests-icon)}
[quo/icon :i/pending-user {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]]
[rn/view {:style {:margin-left 8}}
[quo/text
{:size :paragraph-1
:weight :semi-bold
:style {:color (colors/theme-colors colors/neutral-100 colors/white)}}
(i18n/label :t/pending-requests)]
[quo/text
[rn/text {:weight :semi-bold} (i18n/label :t/pending-requests)]
[rn/text
{:size :paragraph-2
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}}
(requests-summary requests)]]
@@ -1,8 +0,0 @@
(ns status-im2.contexts.chat.home.events
(:require
[utils.re-frame :as rf]))
(rf/defn messages-home-select-tab-event
{:events [:messages-home/select-tab]}
[{:keys [db]} tab]
{:db (assoc db :messages-home/selected-tab tab)})
+39 -38
View File
@@ -3,6 +3,7 @@
[quo2.core :as quo]
[re-frame.core :as re-frame]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.common.contact-list.view :as contact-list]
[status-im2.common.home.view :as common.home]
[status-im2.contexts.chat.home.chat-list-item.view :as chat-list-item]
@@ -23,7 +24,7 @@
(defn filter-items-by-tab
[tab items]
(if (= tab :tab/groups)
(if (= tab :groups)
(filter :group-chat items)
(filter :chat-id items)))
@@ -36,9 +37,10 @@
(defn chats
[selected-tab top]
(let [unfiltered-items (rf/sub [:chats-stack-items])
items (filter-items-by-tab selected-tab unfiltered-items)]
(if (empty? items)
(let [{:keys [items search-filter]} (rf/sub [:home-items])
items (filter-items-by-tab selected-tab items)]
(if (and (empty? items)
(empty? search-filter))
[welcome-blank-chats]
[rn/flat-list
{:key-fn #(or (:chat-id %) (:public-key %) (:id %))
@@ -91,43 +93,42 @@
(defn get-tabs-data
[dot?]
[{:id :tab/recent :label (i18n/label :t/recent) :accessibility-label :tab-recent}
{:id :tab/groups :label (i18n/label :t/groups) :accessibility-label :tab-groups}
{:id :tab/contacts
[{:id :recent :label (i18n/label :t/recent) :accessibility-label :tab-recent}
{:id :groups :label (i18n/label :t/groups) :accessibility-label :tab-groups}
{:id :contacts
:label (i18n/label :t/contacts)
:accessibility-label :tab-contacts
:notification-dot? dot?}])
(defn home
[]
(fn []
(let [pending-contact-requests (rf/sub [:activity-center/pending-contact-requests])
selected-tab (or (rf/sub [:messages-home/selected-tab]) :tab/recent)]
[safe-area/consumer
(fn [{:keys [top]}]
[:<>
(if (= selected-tab :tab/contacts)
[contacts pending-contact-requests top]
[chats selected-tab top])
[rn/view
{:style (style/blur-container top)}
[blur/view
{:blur-amount (if platform/ios? 20 10)
:blur-type (if (colors/dark?) :dark (if platform/ios? :light :xlight))
:style style/blur}]
[common.home/top-nav]
[common.home/title-column
{:label (i18n/label :t/messages)
:handler #(rf/dispatch [:show-bottom-sheet
{:content home.sheet/new-chat-bottom-sheet}])
:accessibility-label :new-chat-button}]
[quo/discover-card
{:title (i18n/label :t/invite-friends-to-status)
:description (i18n/label :t/share-invite-link)}]
[quo/tabs
{:style style/tabs
:size 32
:on-change (fn [tab]
(rf/dispatch [:messages-home/select-tab tab]))
:default-active selected-tab
:data (get-tabs-data (pos? (count pending-contact-requests)))}]]])])))
(let [selected-tab (reagent/atom :recent)]
(fn []
(let [pending-contact-requests (rf/sub [:activity-center/pending-contact-requests])]
[safe-area/consumer
(fn [{:keys [top]}]
[:<>
(if (= @selected-tab :contacts)
[contacts pending-contact-requests top]
[chats @selected-tab top])
[rn/view
{:style (style/blur-container top)}
[blur/view
{:blur-amount (if platform/ios? 20 10)
:blur-type (if (colors/dark?) :dark (if platform/ios? :light :xlight))
:style style/blur}]
[common.home/top-nav]
[common.home/title-column
{:label (i18n/label :t/messages)
:handler #(rf/dispatch [:show-bottom-sheet
{:content home.sheet/new-chat-bottom-sheet}])
:accessibility-label :new-chat-button}]
[quo/discover-card
{:title (i18n/label :t/invite-friends-to-status)
:description (i18n/label :t/share-invite-link)}]
[quo/tabs
{:style style/tabs
:size 32
:on-change #(reset! selected-tab %)
:default-active @selected-tab
:data (get-tabs-data (pos? (count pending-contact-requests)))}]]])]))))
@@ -29,9 +29,9 @@
:elevation 5
:max-height (/ max-y 2)})}
[rn/flat-list
{:keyboard-should-persist-taps :always
:data (vals suggestions)
:key-fn :key
:render-fn mention-item
:render-data (:text-input-ref refs)
:accessibility-label :mentions-list}]]))])
{:keyboardShouldPersistTaps :always
:data (vals suggestions)
:key-fn :key
:render-fn mention-item
:render-data (:text-input-ref refs)
:accessibility-label :mentions-list}]]))])
@@ -26,10 +26,10 @@
(i18n/label :t/deleted-this-message)]])
(defn- compute-on-long-press-fn
[{:keys [deleted? pinned deleted-for-me?] :as message}
[{:keys [deleted? pinned] :as message}
{:keys [message-pin-enabled] :as context}]
;; only show drawer for user who has the permission to unpin messages
(when (and pinned (or deleted? deleted-for-me?) message-pin-enabled)
(when (and pinned deleted? message-pin-enabled)
(fn []
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:show-bottom-sheet
@@ -89,54 +89,45 @@
(defn link-preview-loader
[link _]
(let [measured-width (reagent/atom 0)
measured-height (reagent/atom 0)]
(reagent/create-class
{:component-did-mount
(fn []
(rf/dispatch [:chat.ui/load-link-preview-data link]))
:component-did-update
(fn [this [_ previous-props]]
(let [[_ props] (.-argv (.-props ^js this))
refresh-photo? (not= previous-props props)]
(when refresh-photo?
(rf/dispatch [:chat.ui/load-link-preview-data props]))))
:reagent-render
(fn [link {:keys [on-long-press]}]
(let [cached-preview-data (rf/sub [:link-preview/cache link])]
(when-let [{:keys [site title thumbnail-url error]} cached-preview-data]
(when (and (not error) site title)
[rn/touchable-opacity
{:style (when-not (is-gif? thumbnail-url)
{:align-self :stretch})
:on-press #(when (security/safe-link? link)
(rf/dispatch [:browser.ui/message-link-pressed link]))
:on-long-press on-long-press}
[rn/view (style/wrapper)
(when-not (is-gif? thumbnail-url)
[:<>
[rn/view (style/title-wrapper)
[rn/image {:style (style/title-site-image)}]
[rn/text {:style (style/title-text)}
site]]
[rn/text {:style (style/main-text)}
title]
[rn/text {:style (style/extra-text)}
link]])
(when-not (string/blank? thumbnail-url)
[:<>
[rn/view (style/separator)]
[fast-image/fast-image
{:source {:uri thumbnail-url}
:on-load (fn [e]
(let [{:keys [width height]} (js->clj (.-nativeEvent e)
:keywordize-keys
true)]
(reset! measured-width width)
(reset! measured-height height)))
:style (style/image {:width @measured-width
:height @measured-height})
:accessibility-label :member-photo}]])]]))))})))
(reagent/create-class
{:component-did-mount
(fn []
(rf/dispatch [:chat.ui/load-link-preview-data link]))
:component-did-update
(fn [this [_ previous-props]]
(let [[_ props] (.-argv (.-props ^js this))
refresh-photo? (not= previous-props props)]
(when refresh-photo?
(rf/dispatch [:chat.ui/load-link-preview-data props]))))
:reagent-render
(fn [link {:keys [on-long-press]}]
(let [cached-preview-data (rf/sub [:link-preview/cache link])]
(when-let [{:keys [site title thumbnail-url error] :as preview-data} cached-preview-data]
(when (and (not error) site title)
[rn/touchable-opacity
{:style (when-not (is-gif? thumbnail-url)
{:align-self :stretch})
:on-press #(when (security/safe-link? link)
(rf/dispatch [:browser.ui/message-link-pressed link]))
:on-long-press on-long-press}
[rn/view (style/wrapper)
(when-not (is-gif? thumbnail-url)
[:<>
[rn/view (style/title-wrapper)
[rn/image {:style (style/title-site-image)}]
[rn/text {:style (style/title-text)}
site]]
[rn/text {:style (style/main-text)}
title]
[rn/text {:style (style/extra-text)}
link]])
(when-not (string/blank? thumbnail-url)
[:<>
[rn/view (style/separator)]
[fast-image/fast-image
{:source {:uri thumbnail-url}
:style (style/image (select-keys preview-data [:height :width]))
:accessibility-label :member-photo}]])]]))))}))
(defn link-preview-enable-request
[]
@@ -186,7 +186,8 @@
(when (and (not locked?) id)
{:on-press (fn []
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:chat/navigate-to-chat (str community-id id)]))}))))
(rf/dispatch [:chat/navigate-to-chat (str community-id id)])
(rf/dispatch [:search/home-filter-changed nil]))}))))
(defn add-on-press-handler-to-chats
[community-id chats]
@@ -9,15 +9,14 @@
[dark-overlay?]
[:f>
(fn []
(let [animate? (not dark-overlay?)]
(when animate? (carousel.animation/initialize-animation))
[rn/view
{:style style/background-container}
[carousel/view animate?]
(when dark-overlay?
[blur/view
{:style style/background-blur-overlay
:blur-amount 30
:blur-radius 25
:blur-type :transparent
:overlay-color :transparent}])]))])
(carousel.animation/initialize-animation)
[rn/view
{:style style/background-container}
[carousel/view dark-overlay?]
(when dark-overlay?
[blur/view
{:style style/background-blur-overlay
:blur-amount 30
:blur-radius 25
:blur-type :transparent
:overlay-color :transparent}])])])
@@ -35,22 +35,16 @@
(defn initialize-animation
[]
(reset! progress (reanimated/use-shared-value 0))
(reset! paused (reanimated/use-shared-value false))
(animate-progress @progress @paused))
(when-not @progress
(reset! progress (reanimated/use-shared-value 0))
(reset! paused (reanimated/use-shared-value false))
(animate-progress @progress @paused)))
;; Derived Values
(defn carousel-left-position
[window-width animate?]
(if animate?
(worklets.onboarding-carousel/carousel-left-position window-width @progress)
(-> (or (reanimated/get-shared-value @progress) 0)
(quot -25)
(* window-width))))
[window-width]
(worklets.onboarding-carousel/carousel-left-position window-width @progress))
(defn dynamic-progress-bar-width
[progress-bar-width animate?]
(if animate?
(worklets.onboarding-carousel/dynamic-progress-bar-width progress-bar-width @progress)
(-> (or (reanimated/get-shared-value @progress) 0)
(* progress-bar-width)
(/ 100))))
[progress-bar-width]
(worklets.onboarding-carousel/dynamic-progress-bar-width progress-bar-width @progress))
@@ -48,16 +48,12 @@
:flex-direction :row})
(defn dynamic-progress-bar
[width animate?]
(let [normal-style {:height 2
:border-radius 4
:overflow :hidden
:width width}]
(if animate?
(reanimated/apply-animations-to-style
{:width width}
normal-style)
normal-style)))
[width]
(reanimated/apply-animations-to-style
{:width width}
{:height 2
:border-radius 4
:overflow :hidden}))
(defn progress-bar-container
[progress-bar-width status-bar-height]
@@ -67,15 +63,11 @@
:top (+ 12 status-bar-height)})
(defn carousel-container
[left animate?]
(let [normal-style {:position :absolute
:right 0
:top 0
:bottom 0
:flex-direction :row
:left left}]
(if animate?
(reanimated/apply-animations-to-style
{:left left}
normal-style)
normal-style)))
[left]
(reanimated/apply-animations-to-style
{:left left}
{:position :absolute
:right 0
:top 0
:bottom 0
:flex-direction :row}))
@@ -54,33 +54,30 @@
[rn/view {:style (style/progress-bar-item static? true)}]])
(defn dynamic-progress-bar
[progress-bar-width animate?]
[progress-bar-width]
[:f>
(fn []
(let [width (animation/dynamic-progress-bar-width progress-bar-width animate?)
container-view (if animate? reanimated/view rn/view)]
[container-view {:style (style/dynamic-progress-bar width animate?)}
(let [width (animation/dynamic-progress-bar-width progress-bar-width)]
[reanimated/view {:style (style/dynamic-progress-bar width)}
[progress-bar
{:static? false
:progress-bar-width progress-bar-width}]]))])
(defn view
[animate?]
[]
[:f>
(fn []
(let [window-width (rf/sub [:dimensions/window-width])
view-id (rf/sub [:view-id])
status-bar-height (:status-bar-height @navigation/constants)
progress-bar-width (- window-width 40)
carousel-left (animation/carousel-left-position window-width animate?)
container-view (if animate? reanimated/view rn/view)]
(when animate?
(rn/use-effect
(fn []
(reanimated/set-shared-value @animation/paused (not= view-id :intro)))
[view-id]))
carousel-left (animation/carousel-left-position window-width)]
(rn/use-effect
(fn []
(reanimated/set-shared-value @animation/paused (not= view-id :intro)))
[view-id])
[:<>
[container-view {:style (style/carousel-container carousel-left animate?)}
[reanimated/view {:style (style/carousel-container carousel-left)}
(for [index (range 2)]
^{:key index}
[content-view
@@ -94,5 +91,5 @@
[progress-bar
{:static? true
:progress-bar-width progress-bar-width}]
[dynamic-progress-bar progress-bar-width animate?]]]))])
[dynamic-progress-bar progress-bar-width]]]))])
@@ -4,16 +4,16 @@
[utils.re-frame :as rf]))
(defn navigation-bar
[{:keys [top right-section-buttons disable-back-button?]}]
[rn/view
{:style {:height 56
:margin-top top}}
[{:keys [on-press-info]}]
[rn/view {:style {:height 56}}
[quo/page-nav
{:align-mid? true
:mid-section {:type :text-only :main-text ""}
:mid-section {:type :text-only}
:left-section {:type :blur-bg
:icon :i/arrow-left
:icon-override-theme :dark
:on-press (when-not disable-back-button?
#(rf/dispatch [:navigate-back]))}
:right-section-buttons right-section-buttons}]])
:on-press #(rf/dispatch [:navigate-back])}
:right-section-buttons [{:type :blur-bg
:icon :i/info
:icon-override-theme :dark
:on-press on-press-info}]}]])
@@ -3,7 +3,6 @@
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
[status-im2.contexts.onboarding.common.background.view :as background]
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]
@@ -66,7 +65,7 @@
:shown true}
:placeholder (i18n/label :t/password-creation-placeholder-1)
:on-change-text on-change-password
:on-focus on-input-focus}]
:on-focus #(on-input-focus :password)}]
[rn/view {:style style/space-between-inputs}]
[password-with-hint
{:hint {:text hint-2-text
@@ -76,7 +75,7 @@
:error? error?
:placeholder (i18n/label :t/password-creation-placeholder-2)
:on-change-text on-change-repeat-password
:on-focus on-input-focus
:on-focus #(on-input-focus :repeat-password)
:on-blur on-blur-repeat-password}]]))
(def strength-status
@@ -147,9 +146,9 @@
:passwords-match? same-passwords?
:empty-password? empty-password?
:show-password-validation? @show-password-validation?
:on-input-focus (fn []
:on-input-focus (fn [input-id]
(scroll-to-end-fn)
(reset! focused-input :password))
(reset! focused-input input-id))
:on-change-password (fn [new-value]
(reset! password new-value)
(when (same-password-length?)
@@ -163,18 +162,19 @@
(reset! show-password-validation? true))}]]
[rn/view {:style style/bottom-part}
[rn/view {:style style/disclaimer-container}
[quo/disclaimer
{:blur? true
:on-change #(reset! accepts-disclaimer? %)
:checked? @accepts-disclaimer?}
(i18n/label :t/password-creation-disclaimer)]]
(when (= @focused-input :password)
[help
{:validations validations
:password-strength password-strength}])
(when (= @focused-input :repeat-password)
[rn/view {:style style/disclaimer-container}
[quo/disclaimer
{:blur? true
:checked? @accepts-disclaimer?
:on-change #(reset! accepts-disclaimer? %)}
(i18n/label :t/password-creation-disclaimer)]])
[rn/view {:style style/button-container}
[quo/button
{:disabled (not meet-requirements?)
@@ -186,21 +186,14 @@
(defn create-password
[]
[:f>
(let [scroll-view-ref (atom nil)
scroll-to-end-fn #(js/setTimeout ^js/Function (.-scrollToEnd @scroll-view-ref) 250)]
(fn []
(let [{:keys [top]} (safe-area/use-safe-area)]
[:<>
[background/view true]
[rn/scroll-view
{:ref #(reset! scroll-view-ref %)
:style style/overlay
:content-container-style style/content-style}
[navigation-bar/navigation-bar
{:top top
:right-section-buttons [{:type :blur-bg
:icon :i/info
:icon-override-theme :dark
:on-press #(js/alert "Info pressed")}]}]
[password-form {:scroll-to-end-fn scroll-to-end-fn}]]])))])
(let [scroll-view-ref (atom nil)
scroll-to-end-fn #(js/setTimeout ^js/Function (.-scrollToEnd @scroll-view-ref) 250)]
(fn []
[:<>
[background/view true]
[rn/scroll-view
{:ref #(reset! scroll-view-ref %)
:style style/overlay
:content-container-style style/content-style}
[navigation-bar/navigation-bar {:on-press-info #(js/alert "Info pressed")}]
[password-form {:scroll-to-end-fn scroll-to-end-fn}]]])))
@@ -30,6 +30,8 @@
:left 0
:right 0})
(def navigation-bar {:height 56})
(def info-message
{:margin-top 8})
@@ -5,9 +5,7 @@
[status-im2.contexts.onboarding.create-profile.style :as style]
[utils.i18n :as i18n]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]
[status-im2.contexts.onboarding.common.background.view :as background]
[status-im2.contexts.onboarding.select-photo.method-menu.view :as method-menu]
[utils.re-frame :as rf]
@@ -15,6 +13,18 @@
[react-native.blur :as blur]
[status-im2.constants :as c]))
(defn navigation-bar
[]
[rn/view {:style style/navigation-bar}
[quo/page-nav
{:container-style {:padding-horizontal 0}
:align-mid? true
:mid-section {:type :text-only :main-text ""}
:left-section {:type :blur-bg
:icon :i/arrow-left
:icon-override-theme :dark
:on-press #(rf/dispatch [:navigate-back])}}]])
(def emoji-regex
(new
js/RegExp
@@ -56,20 +66,19 @@
children]))
(defn page
[{:keys [onboarding-profile-data navigation-bar-top]}]
[{:keys [image-path display-name color]}]
[:f>
(fn []
(let [{:keys [image-path display-name color]} onboarding-profile-data
full-name (reagent/atom display-name)
keyboard-shown? (reagent/atom false)
validation-msg (reagent/atom (validation-message @full-name))
on-change-text (fn [s]
(reset! validation-msg (validation-message s))
(reset! full-name (string/trim s)))
custom-color (reagent/atom (or color c/profile-default-color))
profile-pic (reagent/atom image-path)
on-change-profile-pic #(reset! profile-pic %)
on-change #(reset! custom-color %)]
(let [full-name (reagent/atom display-name)
keyboard-shown? (reagent/atom false)
validation-msg (reagent/atom (validation-message @full-name))
on-change-text (fn [s]
(reset! validation-msg (validation-message s))
(reset! full-name (string/trim s)))
custom-color (reagent/atom (or color c/profile-default-color))
profile-pic (reagent/atom image-path)
on-change-profile-pic #(reset! profile-pic %)
on-change #(reset! custom-color %)]
(fn []
(rn/use-effect
(let [will-show-listener (oops/ocall rn/keyboard
@@ -86,13 +95,13 @@
(oops/ocall will-hide-listener "remove"))))
[])
[rn/view {:style style/page-container}
[navigation-bar/navigation-bar {:top navigation-bar-top}]
[rn/scroll-view
{:keyboard-should-persist-taps :always
:content-container-style {:flex-grow 1}}
[rn/view {:style style/page-container}
[rn/view
{:style style/content-container}
[navigation-bar]
[quo/text
{:size :heading-1
:weight :semi-bold
@@ -150,12 +159,7 @@
(defn create-profile
[]
[:f>
(fn []
(let [{:keys [top]} (safe-area/use-safe-area)
onboarding-profile-data (rf/sub [:onboarding-2/profile])]
[:<>
[background/view true]
[page
{:navigation-bar-top top
:onboarding-profile-data onboarding-profile-data}]]))])
(let [onboarding-profile-data (rf/sub [:onboarding-2/profile])]
[:<>
[background/view true]
[page onboarding-profile-data]]))
@@ -1,24 +1,23 @@
(ns status-im2.contexts.onboarding.enable-biometrics.style
(:require [quo2.foundations.colors :as colors]))
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]))
(def default-margin 20)
(defn page-container
[insets]
{:flex 1
:padding-top (:top insets)
(def page-container
{:padding-top (if platform/ios? 44 0)
:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:background-color colors/neutral-80-opa-80-blur})
(def page-illustration
{:flex 1
:background-color colors/danger-50
:align-items :center
:margin-horizontal default-margin
:border-radius 20
:margin-top default-margin
:justify-content :center})
(def navigation-bar {:height 56})
(defn buttons
[insets]
{:margin default-margin
:margin-bottom (+ default-margin (:bottom insets))})
(def image-container
{:margin-top 20
:margin-bottom 24
:background-color colors/danger-50
:border-radius 20
:flex 1
:align-items :center
:justify-content :center})
@@ -2,49 +2,58 @@
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im2.contexts.onboarding.enable-biometrics.style :as style]
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]
[status-im.multiaccounts.biometric.core :as biometric]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
[status-im2.contexts.onboarding.common.background.view :as background]
[utils.re-frame :as rf]
[status-im.multiaccounts.biometric.core :as biometric]))
(defn page-title
(defn navigation-bar
[]
[quo/title
{:title (i18n/label :t/enable-biometrics)
:title-accessibility-label :enable-biometrics-title
:subtitle (i18n/label :t/use-biometrics)
:subtitle-accessibility-label :enable-biometrics-sub-title}])
[rn/view {:style style/navigation-bar}
[quo/page-nav
{:align-mid? true
:mid-section {:type :text-only :main-text ""}
}]])
(defn enable-biometrics-buttons
[{:keys [insets]}]
(defn page
[]
(let [supported-biometric (rf/sub [:supported-biometric-auth])
bio-type-label (biometric/get-label supported-biometric)
profile-color (:color (rf/sub [:onboarding-2/profile]))]
[rn/view {:style (style/buttons insets)}
[quo/button
{:accessibility-label :enable-biometrics-button
:on-press #(rf/dispatch [:onboarding-2/enable-biometrics])
:before :i/face-id
:override-background-color (colors/custom-color profile-color 50)}
(i18n/label :t/biometric-enable-button {:bio-type-label bio-type-label})]
[quo/button
{:accessibility-label :maybe-later-button
:on-press #(rf/dispatch [:onboarding-2/create-account-and-login])
:override-background-color colors/white-opa-5
:style {:margin-top 12}}
(i18n/label :t/maybe-later)]]))
[rn/view {:style style/page-container}
[navigation-bar]
[rn/view
{:style {:padding-horizontal 20
:flex 1}}
[quo/text
{:size :heading-1
:weight :semi-bold
:style {:color colors/white}} (i18n/label :t/enable-biometrics)]
[quo/text
{:size :paragraph-1
:style {:color colors/white
:margin-top 8}}
(i18n/label :t/use-biometrics)]
;; TODO(@briansztamfater): Replace view with image view with the real illustration,
;; https://github.com/status-im/status-mobile/issues/15445
[rn/view {:style style/image-container}
[quo/text {:size :paragraph-1}
"Illustration here"]]
[rn/view {:style {:margin-bottom 55}}
[quo/button
{:on-press #(rf/dispatch [:onboarding-2/enable-biometrics])
:before :i/face-id
:override-background-color (colors/custom-color profile-color 50)}
(i18n/label :t/biometric-enable-button {:bio-type-label bio-type-label})]
[quo/button
{:on-press #(rf/dispatch [:onboarding-2/create-account-and-login])
:override-background-color colors/white-opa-5
:style {:margin-top 12}}
(i18n/label :t/maybe-later)]]]]))
(defn enable-biometrics
[]
[:f>
(fn []
(let [insets (safe-area/use-safe-area)]
[rn/view {:style (style/page-container insets)}
[navigation-bar/navigation-bar {:disable-back-button? true}]
[page-title]
[rn/view {:style style/page-illustration}
[quo/text
"Illustration here"]]
[enable-biometrics-buttons {:insets insets}]]))])
[rn/view {:style {:flex 1}}
[background/view true]
[page]])
@@ -9,10 +9,22 @@
[react-native.safe-area :as safe-area]
[status-im.notifications.core :as notifications]
[status-im2.contexts.onboarding.common.background.view :as background]
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]
[status-im2.contexts.onboarding.enable-notifications.style :as style]
[status-im2.contexts.shell.animation :as shell.animation]))
(defn navigation-bar
[]
[quo/page-nav
(merge {:horizontal-description? false
:one-icon-align-left? true
:align-mid? false
:page-nav-color :transparent
:left-section {:icon :i/arrow-left
:icon-background-color colors/white-opa-5
:icon-override-theme :dark
:type :shell
:on-press #()}})])
(defn page-title
[]
[quo/title
@@ -46,14 +58,13 @@
(defn enable-notifications
[]
[:f>
(fn []
(let [insets (safe-area/use-safe-area)]
[rn/view {:style (style/page-container insets)}
[background/view true]
[navigation-bar/navigation-bar {:disable-back-button? true}]
[page-title]
[rn/view {:style style/page-illustration}
[quo/text
"Illustration here"]]
[enable-notification-buttons {:insets insets}]]))])
[safe-area/consumer
(fn [insets]
[rn/view {:style (style/page-container insets)}
[background/view true]
[navigation-bar]
[page-title]
[rn/view {:style style/page-illustration}
[quo/text
"Illustration here"]]
[enable-notification-buttons {:insets insets}]])])
@@ -1,10 +1,14 @@
(ns status-im2.contexts.onboarding.enter-seed-phrase.style
(:require [quo2.foundations.colors :as colors]))
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]))
(def page-container
{:position :absolute
{:padding-top (if platform/ios? 44 0)
:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:background-color colors/neutral-80-opa-80-blur})
(def navigation-bar {:height 56})
@@ -8,12 +8,21 @@
[utils.re-frame :as rf]
[reagent.core :as reagent]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im2.contexts.onboarding.enter-seed-phrase.style :as style]
[status-im2.contexts.onboarding.common.background.view :as background]
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]
[utils.i18n :as i18n]))
(defn navigation-bar
[]
[rn/view {:style style/navigation-bar}
[quo/page-nav
{:align-mid? true
:left-section {:type :blur-bg
:icon :i/arrow-left
:icon-override-theme :dark
:on-press #(rf/dispatch [:navigate-back])}
:mid-section {:type :text-only :main-text ""}}]])
(def button-disabled?
(comp not constants/seed-phrase-valid-length mnemonic/words-count))
@@ -26,13 +35,13 @@
(string/join " " $)))
(defn page
[{:keys [navigation-bar-top]}]
[]
(let [seed-phrase (reagent/atom "")
error-message (reagent/atom "")
on-invalid-seed-phrase #(reset! error-message (i18n/label :t/custom-seed-phrase))]
(fn []
[rn/view {:style style/page-container}
[navigation-bar/navigation-bar {:top navigation-bar-top}]
[navigation-bar]
[rn/view {:style {:padding-horizontal 20}}
[quo/text
{:weight :bold
@@ -65,9 +74,6 @@
(defn enter-seed-phrase
[]
[:f>
(fn []
(let [{:keys [top]} (safe-area/use-safe-area)]
[rn/view {:style {:flex 1}}
[background/view true]
[page {:navigation-bar-top top}]]))])
[rn/view {:style {:flex 1}}
[background/view true]
[page]])
@@ -105,10 +105,7 @@
:previewPrivacy config/blank-preview?}]
{effect request
:dispatch [:navigate-to :generating-keys]
:db (-> db
(dissoc :multiaccounts/login)
(dissoc :auth-method)
(assoc :onboarding-2/new-account? true))}))
:db (assoc db :onboarding-2/new-account? true)}))
(rf/defn on-delete-profile-success
{:events [:onboarding-2/on-delete-profile-success]}
@@ -1,10 +1,14 @@
(ns status-im2.contexts.onboarding.generating-keys.style
(:require [quo2.foundations.colors :as colors]))
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]))
(def page-container
{:position :absolute
{:padding-top (if platform/ios? 44 0)
:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:background-color colors/neutral-80-opa-80-blur})
(def navigation-bar {:height 56})
@@ -2,17 +2,21 @@
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im2.contexts.onboarding.generating-keys.style :as style]
[status-im2.contexts.onboarding.common.background.view :as background]
[utils.i18n :as i18n]))
(defn navigation-bar
[]
[rn/view {:style style/navigation-bar}
[quo/page-nav
{:align-mid? true
:mid-section {:type :text-only :main-text ""}}]])
(defn page
[{:keys [navigation-bar-top]}]
[]
[rn/view {:style style/page-container}
[rn/view
{:style {:height 56
:margin-top navigation-bar-top}}]
[navigation-bar]
[rn/view {:style {:padding-horizontal 20}}
[quo/text
{:size :heading-1
@@ -21,9 +25,6 @@
(defn generating-keys
[]
[:f>
(fn []
(let [{:keys [top]} (safe-area/use-safe-area)]
[rn/view {:style {:flex 1}}
[background/view true]
[page {:navigation-bar-top top}]]))])
[rn/view {:style {:flex 1}}
[background/view true]
[page]])
@@ -1,14 +1,16 @@
(ns status-im2.contexts.onboarding.new-to-status.style
(:require [quo2.foundations.colors :as colors]))
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]))
(def full-screen {:flex 1})
(def content-container
{:position :absolute
:top 0
:bottom 0
:left 0
:right 0})
{:padding-top (if platform/ios? 44 0)
:position :absolute
:top 0
:bottom 0
:left 0
:right 0})
(def options-container
{:padding-top 12
@@ -2,7 +2,6 @@
(:require
[quo2.core :as quo]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im.keycard.recovery :as keycard]
[status-im2.common.resources :as resources]
[status-im2.contexts.onboarding.new-to-status.style :as style]
@@ -56,16 +55,8 @@
(defn new-to-status
[]
[:f>
(fn []
(let [{:keys [top]} (safe-area/use-safe-area)]
[:<>
[background/view true]
[rn/view {:style style/content-container}
[navigation-bar/navigation-bar
{:top top
:right-section-buttons [{:type :blur-bg
:icon :i/info
:icon-override-theme :dark
:on-press #(js/alert "Info pressed")}]}]
[sign-in-options]]]))])
[:<>
[background/view true]
[rn/view {:style style/content-container}
[navigation-bar/navigation-bar {:on-press-info #(js/alert "Info pressed")}]
[sign-in-options]]])
@@ -1,8 +1,12 @@
(ns status-im2.contexts.onboarding.syncing.syncing-devices.style
(:require [quo2.foundations.colors :as colors]))
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]))
(def navigation-bar {:height 56})
(def page-container
{:position :absolute
{:padding-top (if platform/ios? 44 0)
:position :absolute
:top 0
:bottom 0
:left 0
@@ -2,20 +2,25 @@
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im2.contexts.onboarding.syncing.syncing-devices.style :as style]
[status-im2.contexts.onboarding.common.background.view :as background]
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]))
[status-im2.contexts.onboarding.common.background.view :as background]))
(defn page
[{:keys [navigation-bar-top]}]
[rn/view {:style style/page-container}
[navigation-bar/navigation-bar
{:top navigation-bar-top
(defn navigation-bar
[]
[rn/view {:style style/navigation-bar}
[quo/page-nav
{:align-mid? true
:mid-section {:type :text-only :main-text ""}
:right-section-buttons [{:type :blur-bg
:icon :i/info
:icon-override-theme :dark
:on-press #(js/alert "Pending")}]}]
:on-press #(js/alert "Pending")}]}]])
(defn page
[]
[rn/view {:style style/page-container}
[navigation-bar]
[rn/view {:style {:padding-horizontal 20}}
[quo/text
{:size :heading-1
@@ -32,9 +37,6 @@
(defn syncing-devices
[]
(fn []
[safe-area/consumer
(fn [{:keys [top]}]
[rn/view {:style {:flex 1}}
[background/view true]
[page {:navigation-bar-top top}]])]))
[rn/view {:style {:flex 1}}
[background/view true]
[page]])
@@ -46,7 +46,7 @@
[]
[rn/view {:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])

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