Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e8ce65167 | ||
|
|
8090f37bdd | ||
|
|
54825c6735 | ||
|
|
030f17fc49 | ||
|
|
2bc7d15683 |
@@ -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
|
||||
#--------------
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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.
|
||||
|
||||
@@ -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}
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 153 KiB |
|
After Width: | Height: | Size: 377 KiB |
|
After Width: | Height: | Size: 738 KiB |
@@ -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}]]))
|
||||
|
||||
@@ -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}]])
|
||||
|
||||
@@ -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}]])
|
||||
|
||||
@@ -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}]])
|
||||
|
||||
@@ -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}]])
|
||||
|
||||
@@ -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}]])
|
||||
|
||||
@@ -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}]])
|
||||
|
||||
@@ -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]]))
|
||||
@@ -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}])]))))
|
||||
@@ -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}])
|
||||
@@ -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})
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,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])))
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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))}))
|
||||
|
||||
@@ -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})}]})
|
||||
|
||||
@@ -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)}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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}]]]))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))}]]))
|
||||
@@ -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")
|
||||
|
||||
@@ -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)})
|
||||
@@ -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}]])
|
||||
|
||||