Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a58cb42007 | ||
|
|
2e68a71957 | ||
|
|
66cfd62b06 | ||
|
|
e7dee9b3ce | ||
|
|
c52bf965f7 | ||
|
|
e260187cf5 | ||
|
|
ca0915c940 | ||
|
|
2b4b357c32 | ||
|
|
19ca8e28a5 | ||
|
|
8978e92042 | ||
|
|
c2c79cc1ac | ||
|
|
affd2a5e76 | ||
|
|
ef99bf2ad6 | ||
|
|
1f6f907d57 | ||
|
|
97b254c514 | ||
|
|
ca2ed9d37e | ||
|
|
e64ff76e0b | ||
|
|
88884064b1 | ||
|
|
a6e6716311 | ||
|
|
07d037f2e1 | ||
|
|
36a72f2d63 | ||
|
|
4c0a8d9f6d | ||
|
|
2d860c363a | ||
|
|
186ac482ee | ||
|
|
f015eb929a |
@@ -43,4 +43,4 @@ As a <user|developer|...>, I want to <task> so that <goal>.
|
||||
[comment]: # (if on Android please replicate bug whilst running adb logcat)
|
||||
```
|
||||
...
|
||||
```
|
||||
```
|
||||
|
||||
@@ -14,17 +14,17 @@ WHITE := $(shell tput -Txterm setaf 7)
|
||||
YELLOW := $(shell tput -Txterm setaf 3)
|
||||
RESET := $(shell tput -Txterm sgr0)
|
||||
HELP_FUN = \
|
||||
%help; \
|
||||
while(<>) { push @{$$help{$$2 // 'options'}}, [$$1, $$3] if /^([a-zA-Z\-]+)\s*:.*\#\#(?:@([a-zA-Z\-]+))?\s(.*)$$/ }; \
|
||||
print "Usage: make [target]\n\nSee STARTING_GUIDE.md for more info.\n\n"; \
|
||||
for (sort keys %help) { \
|
||||
print "${WHITE}$$_:${RESET}\n"; \
|
||||
for (@{$$help{$$_}}) { \
|
||||
$$sep = " " x (32 - length $$_->[0]); \
|
||||
print " ${YELLOW}$$_->[0]${RESET}$$sep${GREEN}$$_->[1]${RESET}\n"; \
|
||||
}; \
|
||||
print "\n"; \
|
||||
}
|
||||
%help; \
|
||||
while(<>) { push @{$$help{$$2 // 'options'}}, [$$1, $$3] if /^([a-zA-Z\-]+)\s*:.*\#\#(?:@([a-zA-Z\-]+))?\s(.*)$$/ }; \
|
||||
print "Usage: make [target]\n\nSee STARTING_GUIDE.md for more info.\n\n"; \
|
||||
for (sort keys %help) { \
|
||||
print "${WHITE}$$_:${RESET}\n"; \
|
||||
for (@{$$help{$$_}}) { \
|
||||
$$sep = " " x (32 - length $$_->[0]); \
|
||||
print " ${YELLOW}$$_->[0]${RESET}$$sep${GREEN}$$_->[1]${RESET}\n"; \
|
||||
}; \
|
||||
print "\n"; \
|
||||
}
|
||||
HOST_OS := $(shell uname | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
# This can come from Jenkins
|
||||
@@ -307,6 +307,7 @@ lint: ##@test Run code style checks
|
||||
clj-kondo --config .clj-kondo/config.edn --cache false --lint src && \
|
||||
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
|
||||
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
|
||||
sh scripts/lint-trailing-newline.sh && \
|
||||
yarn prettier
|
||||
|
||||
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
|
||||
@@ -315,9 +316,9 @@ lint-fix: ##@test Run code style checks and fix issues
|
||||
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
|
||||
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
||||
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
||||
sh scripts/lint-trailing-newline.sh --fix && \
|
||||
yarn prettier
|
||||
|
||||
|
||||
shadow-server: export TARGET := clojure
|
||||
shadow-server:##@ Start shadow-cljs in server mode for watching
|
||||
yarn shadow-cljs server
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
pipeline {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
pipeline {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
pipeline {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
pipeline {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
pipeline {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
pipeline {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
pipeline {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
/**
|
||||
* This job runs daily and executes `pod repo update` on MacOS
|
||||
* This is done to avoid issues with out of date repo causing errors like:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.7.9'
|
||||
|
||||
pipeline {
|
||||
|
||||
@@ -45,4 +45,4 @@ The `State` field in the Pivotal story is used to track the progress of a Pivota
|
||||
| 5 points | 2 - 3 days |
|
||||
| 8 points | ~1 week |
|
||||
|
||||
We should avoid 8 point stories by breaking them down into smaller stories as much as possible.
|
||||
We should avoid 8 point stories by breaking them down into smaller stories as much as possible.
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,4 +18,4 @@
|
||||
"url": "https://github.com/status-im/react-native-status/issues"
|
||||
},
|
||||
"homepage": "https://github.com/status-im/react-native-status#readme"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,12 @@ in {
|
||||
doCheck = false;
|
||||
});
|
||||
|
||||
# Downgrade watchman in attempt to fix "too many files open issue"
|
||||
watchman = callPackage ./pkgs/watchman {
|
||||
inherit (super.darwin.apple_sdk.frameworks) CoreServices;
|
||||
autoconf = super.buildPackages.autoconf269;
|
||||
};
|
||||
|
||||
# Package version adjustments
|
||||
gradle = super.gradle_7;
|
||||
nodejs = super.nodejs-18_x;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# Issue
|
||||
|
||||
`watchman` was upgraded significantly during the last nixpkgs upgrade (`4.9.0` (Aug 16, 2017) to `2023.01.30.00` - 6 years between):
|
||||
- https://github.com/status-im/status-mobile/pull/14944
|
||||
- https://github.com/status-im/nixpkgs/commit/4e9c02bcc709fe1737a746add0e8e0109133d808
|
||||
|
||||
Probably causing developers to have "too many files open" issue:
|
||||
https://github.com/status-im/status-mobile/issues/16341
|
||||
|
||||
```
|
||||
Error: A non-recoverable condition has triggered. Watchman needs your help!
|
||||
The triggering condition was at timestamp=1687286390: opendir(/Users/javid/Projects/status-mobile/node_modules/metro-core/node_modules/jest-regex-util/build) -> Too many open files
|
||||
All requests will continue to fail with this message until you resolve
|
||||
the underlying problem. You will find more information on fixing this at
|
||||
https://facebook.github.io/watchman/docs/troubleshooting.html#poison-opendir
|
||||
```
|
||||
|
||||
# Fix
|
||||
This is an attempt to fix the issue by downgrading the watchman
|
||||
|
||||
# Upgrade
|
||||
When upgrading in the future, please read the comments:
|
||||
https://github.com/status-im/status-mobile/issues/16341
|
||||
@@ -0,0 +1,48 @@
|
||||
{ stdenv, lib, config, fetchFromGitHub, autoconf, automake, pcre
|
||||
, libtool, pkg-config, openssl
|
||||
, confFile ? config.watchman.confFile or null
|
||||
, withApple ? stdenv.isDarwin, CoreServices
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "watchman";
|
||||
version = "4.9.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "facebook";
|
||||
repo = "watchman";
|
||||
rev = "v${version}";
|
||||
sha256 = "0fdaj5pmicm6j17d5q7px800m5rmam1a400x3hv1iiifnmhgnkal";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ autoconf automake pkg-config libtool ];
|
||||
buildInputs = [ pcre openssl ]
|
||||
#++ lib.optionals withApple [ CoreServices ];
|
||||
++ lib.optionals stdenv.isDarwin [ CoreServices ];
|
||||
|
||||
configureFlags = [
|
||||
"--enable-lenient"
|
||||
"--enable-conffile=${if confFile == null then "no" else confFile}"
|
||||
"--with-pcre=yes"
|
||||
|
||||
# For security considerations re: --disable-statedir, see:
|
||||
# https://github.com/facebook/watchman/issues/178
|
||||
"--disable-statedir"
|
||||
];
|
||||
|
||||
prePatch = ''
|
||||
patchShebangs .
|
||||
'';
|
||||
|
||||
preConfigure = ''
|
||||
./autogen.sh
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "Watches files and takes action when they change";
|
||||
homepage = "https://facebook.github.io/watchman";
|
||||
maintainers = with maintainers; [ cstrahan ];
|
||||
platforms = with platforms; linux ++ darwin;
|
||||
license = licenses.asl20;
|
||||
};
|
||||
}
|
||||
@@ -194,4 +194,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eof pipefail
|
||||
|
||||
FILES=$(comm -23 <(sort <(git ls-files --cached --others --exclude-standard)) <(sort <(git ls-files --deleted)) | grep --ignore-case -E '\.(java|cpp|nix|json|sh|md|js|clj|cljs|cljc|edn)$')
|
||||
N_FILES=$(echo "$FILES" | wc -l)
|
||||
LINT_SHOULD_FIX=0
|
||||
|
||||
if [[ -n $1 && $1 != '--fix' ]]; then
|
||||
echo "Unknown option '$1'" >&2
|
||||
exit 1
|
||||
elif [[ $1 == '--fix' ]]; then
|
||||
LINT_SHOULD_FIX=1
|
||||
fi
|
||||
|
||||
echo "Checking ${N_FILES} files for missing trailing newlines."
|
||||
|
||||
# Do not process the whole file and only check the last character. Ignore empty
|
||||
# files. Taken from https://stackoverflow.com/a/10082466.
|
||||
for file in $FILES; do
|
||||
if [ -s "$file" ] && [ "$(tail -c1 "$file"; echo x)" != $'\nx' ]; then
|
||||
if [[ $LINT_SHOULD_FIX -eq 1 ]]; then
|
||||
echo "" >>"$file"
|
||||
else
|
||||
LINT_ERROR=1
|
||||
echo "No trailing newline: $file" >&2
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $LINT_ERROR -eq 1 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
@@ -11,4 +11,4 @@
|
||||
(for [i (keys icons/icons)]
|
||||
[rn/view {:flex-direction :row}
|
||||
[icons/icon (keyword i)]
|
||||
[rn/text i]])])
|
||||
[rn/text i]])])
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.components.buttons.predictive-keyboard.style :as style]
|
||||
[quo2.components.info.info-message :as info-message]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.linear-gradient :as linear-gradient]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.buttons.button :as button]))
|
||||
@@ -12,32 +13,33 @@
|
||||
:blur [colors/white-opa-5 colors/white-opa-0]})
|
||||
|
||||
(defn- word-component
|
||||
[word _ _ {:keys [blur? on-press]}]
|
||||
[word _ _ {:keys [on-press]}]
|
||||
[button/button
|
||||
(merge {:type :blur-bg
|
||||
:size 32
|
||||
:on-press #(on-press word)}
|
||||
(when blur? {:override-theme :dark}))
|
||||
{:type :blur-bg
|
||||
:size 32
|
||||
:on-press #(on-press word)}
|
||||
|
||||
word])
|
||||
|
||||
(defn- separator
|
||||
[]
|
||||
[rn/view {:style {:width 8}}])
|
||||
|
||||
(defn view
|
||||
(defn- view-internal
|
||||
"Options
|
||||
- `type` `:words`/`:error`/`:info`/`:empty`.
|
||||
- `blur?` Boolean to enable blur background support.
|
||||
- `text` error/info text.
|
||||
- `words` List of words to display in the keyboard.
|
||||
- `on-press` Callback called when a word is pressed `(fn [word])`."
|
||||
[{:keys [type blur? text words on-press]}]
|
||||
- `on-press` Callback called when a word is pressed `(fn [word])`
|
||||
- `theme` :light or :dark, received from with-theme HOC."
|
||||
[{:keys [type blur? text words on-press theme]}]
|
||||
[linear-gradient/linear-gradient
|
||||
{:style {:flex-direction :row}
|
||||
:accessibility-label :predictive-keyboard
|
||||
:colors (if blur?
|
||||
(gradients :blur)
|
||||
(colors/theme-colors (gradients :light) (gradients :dark)))}
|
||||
(colors/theme-colors (gradients :light) (gradients :dark) theme))}
|
||||
[rn/view {:style (style/wrapper type)}
|
||||
(case type
|
||||
:words
|
||||
@@ -46,8 +48,7 @@
|
||||
:data words
|
||||
:content-container-style style/word-list
|
||||
:render-fn word-component
|
||||
:render-data {:blur? blur?
|
||||
:on-press on-press}
|
||||
:render-data {:on-press on-press}
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:separator [separator]
|
||||
:horizontal true
|
||||
@@ -70,3 +71,5 @@
|
||||
:icon-color colors/white-opa-70}))
|
||||
text]
|
||||
nil)]])
|
||||
|
||||
(def view (theme/with-theme view-internal))
|
||||
|
||||
@@ -9,33 +9,33 @@
|
||||
:height 20})
|
||||
|
||||
(defn neutral-border-color
|
||||
[in-blur-view? override-theme]
|
||||
[in-blur-view? theme]
|
||||
(if in-blur-view?
|
||||
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-10 override-theme)
|
||||
(colors/theme-colors colors/neutral-20 colors/neutral-80 override-theme)))
|
||||
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-10 theme)
|
||||
(colors/theme-colors colors/neutral-20 colors/neutral-80 theme)))
|
||||
|
||||
(def active-background-color (colors/custom-color :blue 50 10))
|
||||
(def complete-background-color (colors/custom-color :blue 50))
|
||||
(defn active-background-color [customization-color] (colors/custom-color customization-color 50 10))
|
||||
(defn complete-background-color [customization-color] (colors/custom-color customization-color 50))
|
||||
|
||||
(defn container
|
||||
[size type in-blur-view? override-theme]
|
||||
[{:keys [size type in-blur-view? theme customization-color]}]
|
||||
(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))
|
||||
:border-color (neutral-border-color in-blur-view? theme))
|
||||
|
||||
(= type :active)
|
||||
(assoc :background-color active-background-color)
|
||||
(assoc :background-color (active-background-color customization-color))
|
||||
|
||||
(= type :complete)
|
||||
(assoc :background-color complete-background-color)))
|
||||
(assoc :background-color (complete-background-color customization-color))))
|
||||
|
||||
(defn text-color
|
||||
([type] (text-color type nil))
|
||||
([type override-theme]
|
||||
([type theme]
|
||||
(case type
|
||||
(:neutral :active) (colors/theme-colors colors/neutral-100-opa-100 colors/white override-theme)
|
||||
(:neutral :active) (colors/theme-colors colors/neutral-100-opa-100 colors/white theme)
|
||||
:complete colors/white)))
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
(:require
|
||||
[quo2.components.counter.step.style :as style]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.core :as rn]
|
||||
[utils.number]))
|
||||
|
||||
(defn step
|
||||
[{:keys [type accessibility-label override-theme in-blur-view?]} value]
|
||||
(defn step-internal
|
||||
[{:keys [type accessibility-label theme in-blur-view? customization-color]} value]
|
||||
(let [type (or type :neutral)
|
||||
value (utils.number/parse-int value)
|
||||
label (str value)
|
||||
@@ -14,8 +15,14 @@
|
||||
[rn/view
|
||||
{:accessible true
|
||||
:accessibility-label (or accessibility-label :step-counter)
|
||||
:style (style/container size type in-blur-view? override-theme)}
|
||||
:style (style/container {:size size
|
||||
:type type
|
||||
:in-blur-view? in-blur-view?
|
||||
:theme theme
|
||||
:customization-color customization-color})}
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :label
|
||||
:style {:color (style/text-color type override-theme)}} label]]))
|
||||
:style {:color (style/text-color type theme)}} label]]))
|
||||
|
||||
(def step (theme/with-theme step-internal))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(ns quo2.components.dividers.divider-label
|
||||
(:require [quo2.theme :as theme]
|
||||
[quo2.components.icon :as icons]
|
||||
(:require [quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as markdown.text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def chevron-icon-container-width 20)
|
||||
@@ -36,18 +36,18 @@
|
||||
padding-top (if increase-padding-top? 16 8)
|
||||
text-and-icon-color (if dark? colors/neutral-40 colors/neutral-50)
|
||||
counter-text-color (if dark? colors/white colors/neutral-100)]
|
||||
[rn/touchable-without-feedback
|
||||
{:on-press on-press}
|
||||
[rn/touchable-without-feedback {:on-press on-press}
|
||||
[rn/view
|
||||
{:accessible true
|
||||
:accessibility-label :divider-label
|
||||
:style (merge {:border-top-width 1
|
||||
:border-top-color border-and-counter-bg-color
|
||||
:padding-top padding-top
|
||||
:padding-bottom padding-bottom
|
||||
:padding-horizontal 16
|
||||
:align-items :center
|
||||
:flex-direction :row}
|
||||
:style (merge {:border-top-width 1
|
||||
:border-top-color border-and-counter-bg-color
|
||||
:padding-top padding-top
|
||||
:padding-bottom padding-bottom
|
||||
:padding-left 16
|
||||
:padding-right 16
|
||||
:align-items :center
|
||||
:flex-direction :row}
|
||||
container-style)}
|
||||
(when (= chevron-position :left)
|
||||
[rn/view
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
(ns quo2.components.drawers.documentation-drawers.style)
|
||||
(ns quo2.components.drawers.documentation-drawers.style
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[react-native.safe-area :as safe-area]))
|
||||
|
||||
(def outer-container
|
||||
;; Margin negative to fill the bottom-sheet container where this component is used
|
||||
{:margin-bottom (- (+ (safe-area/get-bottom) 8))})
|
||||
|
||||
(def container
|
||||
{:align-items :flex-start
|
||||
@@ -6,4 +12,10 @@
|
||||
|
||||
(def content
|
||||
{:margin-top 8
|
||||
:margin-bottom 16})
|
||||
:margin-bottom (+ (safe-area/get-bottom) 8)})
|
||||
|
||||
(defn title
|
||||
[shell?]
|
||||
{:color (colors/theme-colors colors/neutral-100
|
||||
colors/white
|
||||
(when shell? :dark))})
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
(ns quo2.components.drawers.documentation-drawers.view
|
||||
(:require [quo2.components.markdown.text :as text]
|
||||
(:require [quo2.components.buttons.button :as button]
|
||||
[quo2.components.drawers.documentation-drawers.style :as style]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[quo2.components.buttons.button :as button]
|
||||
[quo2.foundations.colors :as colors]))
|
||||
[react-native.gesture :as gesture]))
|
||||
|
||||
(defn view
|
||||
"Options
|
||||
@@ -14,18 +13,18 @@
|
||||
- `button-icon` button icon
|
||||
- `on-press-button` On press handler for the button
|
||||
- `shell?` use shell theme
|
||||
|
||||
`content` Content of the drawer
|
||||
"
|
||||
[{:keys [title show-button? on-press-button button-label button-icon shell?]} content]
|
||||
[gesture/scroll-view
|
||||
{:style style/outer-container
|
||||
:always-bounce-vertical false
|
||||
:content-inset-adjustment-behavior :never}
|
||||
[rn/view {:style style/container}
|
||||
[text/text
|
||||
{:size :heading-2
|
||||
:accessibility-label :documentation-drawer-title
|
||||
:style {:color (colors/theme-colors colors/neutral-100
|
||||
colors/white
|
||||
(when shell? :dark))}
|
||||
:style (style/title shell?)
|
||||
:weight :semi-bold}
|
||||
title]
|
||||
[rn/view {:style style/content :accessibility-label :documentation-drawer-content}
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
(ns quo2.components.drawers.drawer-buttons.component-spec
|
||||
(:require [quo2.components.drawers.drawer-buttons.view :as drawer-buttons]
|
||||
[react-native.core :as rn]
|
||||
[test-helpers.component :as h]))
|
||||
[test-helpers.component :as h]
|
||||
[react-native.safe-area :as safe-area]))
|
||||
|
||||
(h/describe "drawer-buttons"
|
||||
(h/before-each
|
||||
(fn []
|
||||
(h/use-fake-timers)))
|
||||
|
||||
(h/after-each
|
||||
(fn []
|
||||
(h/clear-all-timers)
|
||||
(h/use-real-timers)))
|
||||
|
||||
(h/test "the top heading and subheading render"
|
||||
(h/render [drawer-buttons/view
|
||||
{:top-card {:heading :top-heading}
|
||||
@@ -29,15 +39,16 @@
|
||||
|
||||
(h/test "it clicks the top card"
|
||||
(let [event (h/mock-fn)]
|
||||
(h/render [drawer-buttons/view
|
||||
{:top-card {:on-press event
|
||||
:heading :top-heading}
|
||||
:bottom-card {:heading :bottom-heading}}
|
||||
:top-sub-heading
|
||||
:bottom-sub-heading])
|
||||
(h/fire-event :press (h/get-by-text "top-heading"))
|
||||
(-> (js/expect event)
|
||||
(.toHaveBeenCalled))))
|
||||
(with-redefs [safe-area/get-top (fn [] 10)]
|
||||
(h/render [drawer-buttons/view
|
||||
{:top-card {:on-press event
|
||||
:heading :top-heading}
|
||||
:bottom-card {:heading :bottom-heading}}
|
||||
:top-sub-heading
|
||||
:bottom-sub-heading])
|
||||
(h/fire-event :press (h/get-by-text "top-heading"))
|
||||
(-> (js/expect event)
|
||||
(.toHaveBeenCalled)))))
|
||||
|
||||
(h/test "it clicks the bottom card"
|
||||
(let [event (h/mock-fn)]
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
(ns quo2.components.drawers.drawer-buttons.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
|
||||
(def outer-container
|
||||
{:height 216
|
||||
:border-top-left-radius 20
|
||||
:border-top-right-radius 20
|
||||
:overflow :hidden})
|
||||
(defn outer-container
|
||||
[height border-radius container-style]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:height height
|
||||
:border-top-left-radius border-radius
|
||||
:border-top-right-radius border-radius}
|
||||
(assoc
|
||||
container-style
|
||||
:position :absolute
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0
|
||||
:overflow :hidden)))
|
||||
|
||||
(def top-card
|
||||
{:flex 1
|
||||
@@ -17,7 +26,6 @@
|
||||
|
||||
(def bottom-card
|
||||
{:position :absolute
|
||||
:top 80
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0
|
||||
@@ -41,6 +49,20 @@
|
||||
:align-items :center
|
||||
:border-color colors/white-opa-5})
|
||||
|
||||
(def blur-view-style
|
||||
{:flex 1
|
||||
:border-top-left-radius 20
|
||||
:border-top-right-radius 20})
|
||||
|
||||
(def blur-content-style
|
||||
{:flex 1
|
||||
:background-color :transparent
|
||||
:position :absolute
|
||||
:top 0
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0})
|
||||
|
||||
(def bottom-text
|
||||
{:flex 1
|
||||
:color colors/white-70-blur})
|
||||
@@ -51,4 +73,4 @@
|
||||
(defn heading-text
|
||||
[gap]
|
||||
{:color colors/white
|
||||
:margin-bottom gap})
|
||||
:margin-bottom gap})
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.blur :as blur]
|
||||
[quo2.components.drawers.drawer-buttons.style :as style]))
|
||||
[quo2.components.drawers.drawer-buttons.style :as style]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]))
|
||||
|
||||
(def default-height 216)
|
||||
|
||||
(defn render-bottom
|
||||
[children]
|
||||
@@ -29,35 +34,74 @@
|
||||
children]]
|
||||
[render-bottom children]))
|
||||
|
||||
(defn render-children-top
|
||||
[children]
|
||||
(if (label? children)
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style style/top-text
|
||||
:weight :semi-bold}
|
||||
children]
|
||||
children))
|
||||
(defn- f-render-children-top
|
||||
[children top-children-opacity]
|
||||
(let [scale (reanimated/interpolate top-children-opacity [1 0] [1 1.1])
|
||||
padding-left (reanimated/interpolate scale [1 1.1] [0 14])]
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:opacity top-children-opacity
|
||||
:transform [{:scale scale}
|
||||
{:translate-x padding-left}]}
|
||||
{})}
|
||||
(if (label? children)
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style style/top-text
|
||||
:weight :semi-bold}
|
||||
children]
|
||||
children)]))
|
||||
|
||||
(defn card
|
||||
[{:keys [on-press style heading gap accessibility-label top?]} children]
|
||||
(defn- f-card
|
||||
[{:keys [on-press default-on-press style heading gap accessibility-label top? top-title-opacity
|
||||
top-children-opacity
|
||||
animated-heading]
|
||||
:or {top-title-opacity (reanimated/use-shared-value 1)}}
|
||||
children]
|
||||
[rn/touchable-highlight
|
||||
{:accessibility-label accessibility-label
|
||||
:on-press on-press
|
||||
:on-press (fn []
|
||||
(when on-press
|
||||
(on-press))
|
||||
(when default-on-press
|
||||
(default-on-press)))
|
||||
:border-radius 20
|
||||
:style style
|
||||
:underlay-color (:background-color style)}
|
||||
[rn/view
|
||||
[text/text
|
||||
{:size :heading-1
|
||||
:style (style/heading-text gap)
|
||||
:weight :semi-bold}
|
||||
heading]
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:opacity top-title-opacity}
|
||||
{})}
|
||||
[text/text
|
||||
{:size :heading-1
|
||||
:style (style/heading-text gap)
|
||||
:weight :semi-bold}
|
||||
heading]]
|
||||
(when animated-heading
|
||||
(let [animated-heading-opacity (reanimated/interpolate top-children-opacity [1 0] [0 1])]
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:opacity top-title-opacity}
|
||||
{:position :absolute})}
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:opacity animated-heading-opacity}
|
||||
{})}
|
||||
[text/text
|
||||
{:size :heading-1
|
||||
:style (style/heading-text gap)
|
||||
:weight :semi-bold}
|
||||
animated-heading]]]))
|
||||
(if top?
|
||||
[render-children-top children]
|
||||
[:f> f-render-children-top children top-children-opacity]
|
||||
[render-children-bottom children])]])
|
||||
|
||||
(defn view
|
||||
(defn card
|
||||
[props children]
|
||||
[:f> f-card props children])
|
||||
|
||||
(defn f-view
|
||||
"[view opts]
|
||||
opts
|
||||
{:container-style style-object
|
||||
@@ -70,29 +114,101 @@
|
||||
child-1 string, keyword or hiccup
|
||||
child-2 string, keyword or hiccup
|
||||
"
|
||||
[{:keys [container-style top-card bottom-card]} child-1 child-2]
|
||||
[rn/view
|
||||
{:style (merge container-style style/outer-container)}
|
||||
[blur/view
|
||||
{:blur-type :dark
|
||||
:blur-amount 10
|
||||
:style {:flex 1
|
||||
:border-top-left-radius 20
|
||||
:border-top-right-radius 20}}]
|
||||
[rn/view
|
||||
{:style {:flex 1
|
||||
:background-color :transparent
|
||||
:position :absolute
|
||||
:top 0
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0}}
|
||||
[card
|
||||
(merge {:gap 4
|
||||
:top? true
|
||||
:style style/top-card}
|
||||
top-card) child-1]
|
||||
[card
|
||||
(merge {:style style/bottom-card
|
||||
:gap 20}
|
||||
bottom-card) child-2]]])
|
||||
[{:keys [container-style top-card bottom-card on-init animations-duration animations-delay]}
|
||||
child-1
|
||||
child-2]
|
||||
(let [max-height (+ (:height (rn/get-window)) (if platform/android? (safe-area/get-top) 0))
|
||||
height (reanimated/use-shared-value default-height)
|
||||
top-padding (reanimated/use-shared-value 12)
|
||||
border-radius (reanimated/use-shared-value 20)
|
||||
bottom-view-top (reanimated/use-shared-value 80)
|
||||
top-title-opacity (reanimated/use-shared-value 1)
|
||||
top-children-opacity (reanimated/use-shared-value 1)
|
||||
animations-delay (/ animations-delay 1.4)
|
||||
start-top-animation (fn []
|
||||
(reanimated/animate-shared-value-with-delay bottom-view-top
|
||||
(:height (rn/get-screen))
|
||||
animations-duration
|
||||
:easing4
|
||||
animations-delay)
|
||||
(reanimated/animate-shared-value-with-delay
|
||||
height
|
||||
max-height
|
||||
animations-duration
|
||||
:easing4
|
||||
animations-delay)
|
||||
(reanimated/animate-shared-value-with-delay
|
||||
top-padding
|
||||
(+ 68 (safe-area/get-top))
|
||||
animations-duration
|
||||
:easing4
|
||||
animations-delay)
|
||||
(reanimated/animate-shared-value-with-delay
|
||||
top-children-opacity
|
||||
0
|
||||
animations-duration
|
||||
:easing4 animations-delay)
|
||||
(reanimated/animate-shared-value-with-delay
|
||||
top-title-opacity
|
||||
0
|
||||
0
|
||||
:linear
|
||||
(+ animations-delay animations-duration 500)))
|
||||
reset-top-animation (fn []
|
||||
(reanimated/set-shared-value top-title-opacity 1)
|
||||
(reanimated/animate-shared-value-with-delay bottom-view-top
|
||||
80
|
||||
animations-duration
|
||||
:easing4
|
||||
50)
|
||||
(reanimated/animate-shared-value-with-timing
|
||||
height
|
||||
default-height
|
||||
animations-duration
|
||||
:easing4)
|
||||
(reanimated/animate-shared-value-with-timing
|
||||
top-padding
|
||||
12
|
||||
animations-duration
|
||||
:easing4)
|
||||
(reanimated/animate-shared-value-with-timing
|
||||
top-children-opacity
|
||||
1
|
||||
animations-duration
|
||||
:easing4))]
|
||||
(rn/use-effect (fn []
|
||||
(when on-init
|
||||
(on-init reset-top-animation))))
|
||||
[reanimated/view {:style (style/outer-container height border-radius container-style)}
|
||||
[blur/view
|
||||
{:blur-type :dark
|
||||
:blur-amount 10
|
||||
:style style/blur-view-style}
|
||||
[rn/view
|
||||
{:style style/blur-content-style}
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:padding-top top-padding}
|
||||
style/top-card)}
|
||||
[card
|
||||
(merge {:gap 4
|
||||
:top? true
|
||||
:style {:flex 1}
|
||||
:top-children-opacity top-children-opacity
|
||||
:top-title-opacity top-title-opacity
|
||||
:default-on-press start-top-animation}
|
||||
top-card)
|
||||
child-1]]
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:top bottom-view-top}
|
||||
style/bottom-card)}
|
||||
[card
|
||||
(merge {:style {:flex 1}
|
||||
:gap 10}
|
||||
bottom-card)
|
||||
child-2]]]]]))
|
||||
|
||||
(defn view
|
||||
[props child-1 child-2]
|
||||
[:f> f-view props child-1 child-2])
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
[quo2.components.empty-state.empty-state.styles :as styles]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]))
|
||||
[react-native.fast-image :as fast-image]
|
||||
[quo2.theme :as theme]))
|
||||
|
||||
(defn empty-state
|
||||
(defn- empty-state-internal
|
||||
[{:keys [customization-color image title description blur?]
|
||||
upper-button :upper-button
|
||||
lower-button :lower-button
|
||||
@@ -32,19 +33,18 @@
|
||||
upper-button-on-press :on-press} upper-button]
|
||||
[rn/view {:style styles/button-container}
|
||||
[button/button
|
||||
(cond-> {:type :primary
|
||||
:size 32
|
||||
:override-background-color (styles/upper-button-color customization-color)
|
||||
:on-press upper-button-on-press}
|
||||
blur? (assoc :override-theme :dark))
|
||||
{:type :primary
|
||||
:size 32
|
||||
:override-background-color (styles/upper-button-color customization-color)
|
||||
:on-press upper-button-on-press}
|
||||
upper-button-text]
|
||||
|
||||
(when-let [{lower-button-text :text
|
||||
lower-button-on-press :on-press} lower-button]
|
||||
[button/button
|
||||
(cond-> {:style {:margin-top 12}
|
||||
:size 32
|
||||
:type :blur-bg
|
||||
:on-press lower-button-on-press}
|
||||
blur? (assoc :override-theme :dark))
|
||||
{:style {:margin-top 12}
|
||||
:size 32
|
||||
:type :blur-bg
|
||||
:on-press lower-button-on-press}
|
||||
lower-button-text])])])
|
||||
|
||||
(def empty-state (theme/with-theme empty-state-internal))
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
[buttons/button
|
||||
{:accessibility-label :select-profile-picture-button
|
||||
:type :grey
|
||||
:override-theme :dark
|
||||
:override-background-color (colors/alpha colors/white 0.05)
|
||||
:on-press on-press
|
||||
:icon-size 20
|
||||
@@ -50,6 +49,5 @@
|
||||
[title-input/title-input
|
||||
(merge title-input-props
|
||||
{:blur? true
|
||||
:override-theme :dark
|
||||
:placeholder placeholder
|
||||
:customization-color customization-color})]]])
|
||||
|
||||
@@ -3,50 +3,50 @@
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(defn get-focused-placeholder-color
|
||||
[blur? override-theme]
|
||||
[blur? theme]
|
||||
(if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 override-theme)
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-60 override-theme))
|
||||
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme))
|
||||
)
|
||||
|
||||
(defn get-placeholder-color
|
||||
[blur? override-theme]
|
||||
[blur? theme]
|
||||
(if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30 override-theme)
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)))
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30 theme)
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
|
||||
|
||||
(defn- get-disabled-color
|
||||
[blur? override-theme]
|
||||
[blur? theme]
|
||||
(if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30)
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)))
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
|
||||
|
||||
(defn- get-char-count-color
|
||||
[blur? override-theme]
|
||||
[blur? theme]
|
||||
(if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40)
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)))
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
|
||||
|
||||
(defn get-selection-color
|
||||
[customization-color blur? override-theme]
|
||||
[customization-color blur? theme]
|
||||
(colors/alpha (if blur?
|
||||
(colors/theme-colors colors/neutral-100 colors/white override-theme)
|
||||
(colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
(colors/custom-color customization-color
|
||||
(if (or (= :dark override-theme) colors/dark?) 60 50)))
|
||||
(if (or (= :dark theme) colors/dark?) 60 50)))
|
||||
(if platform/ios? 1 0.2)))
|
||||
|
||||
(def text-input-container {:flex 1})
|
||||
|
||||
(defn title-text
|
||||
[disabled? blur? override-theme]
|
||||
[disabled? blur? theme]
|
||||
{:text-align-vertical :bottom
|
||||
:color (if disabled?
|
||||
(get-disabled-color blur? override-theme)
|
||||
(colors/theme-colors colors/neutral-100 colors/white override-theme))})
|
||||
(get-disabled-color blur? theme)
|
||||
(colors/theme-colors colors/neutral-100 colors/white theme))})
|
||||
|
||||
(defn char-count
|
||||
[blur? override-theme]
|
||||
{:color (get-char-count-color blur? override-theme)})
|
||||
[blur? theme]
|
||||
{:color (get-char-count-color blur? theme)})
|
||||
|
||||
(def container
|
||||
{:flex-direction :row
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
(str 0 value)
|
||||
value))
|
||||
|
||||
(defn title-input
|
||||
(defn- title-input-internal
|
||||
[{:keys [blur?
|
||||
on-change-text
|
||||
auto-focus
|
||||
placeholder
|
||||
max-length
|
||||
default-value
|
||||
override-theme]
|
||||
theme]
|
||||
:or {max-length 0
|
||||
auto-focus false
|
||||
default-value ""}}]
|
||||
@@ -38,10 +38,10 @@
|
||||
(text/text-style
|
||||
{:size :heading-2
|
||||
:weight :semi-bold
|
||||
:style (style/title-text disabled? blur? override-theme)})
|
||||
:style (style/title-text disabled? blur? theme)})
|
||||
:default-value default-value
|
||||
:accessibility-label :profile-title-input
|
||||
:keyboard-appearance (theme/theme-value :light :dark override-theme)
|
||||
:keyboard-appearance (theme/theme-value :light :dark theme)
|
||||
:on-focus #(swap! focused? (constantly true))
|
||||
:on-blur #(swap! focused? (constantly false))
|
||||
:auto-focus auto-focus
|
||||
@@ -50,22 +50,24 @@
|
||||
:editable (not disabled?)
|
||||
:max-length max-length
|
||||
:placeholder placeholder
|
||||
:selection-color (style/get-selection-color customization-color blur? override-theme)
|
||||
:selection-color (style/get-selection-color customization-color blur? theme)
|
||||
:placeholder-text-color (if @focused?
|
||||
(style/get-focused-placeholder-color blur? override-theme)
|
||||
(style/get-placeholder-color blur? override-theme))}]]
|
||||
(style/get-focused-placeholder-color blur? theme)
|
||||
(style/get-placeholder-color blur? theme))}]]
|
||||
[rn/view
|
||||
{:style style/counter-container}
|
||||
[text/text
|
||||
[text/text
|
||||
{:style (style/char-count blur? override-theme)
|
||||
{:style (style/char-count blur? theme)
|
||||
:size :paragraph-2}
|
||||
(pad-0
|
||||
(str
|
||||
(count @value)))]
|
||||
[text/text
|
||||
{:style (style/char-count blur? override-theme)
|
||||
{:style (style/char-count blur? theme)
|
||||
:size :paragraph-2}
|
||||
(str "/"
|
||||
(pad-0
|
||||
(str max-length)))]]]])))
|
||||
|
||||
(def title-input (theme/with-theme title-input-internal))
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
(ns quo2.components.list-items.channel
|
||||
(:require [quo2.components.avatars.channel-avatar :as channel-avatar]
|
||||
[quo2.components.common.unread-grey-dot.view :refer [unread-grey-dot]]
|
||||
[quo2.components.counter.counter :as quo2.counter]
|
||||
[quo2.components.icon :as quo2.icons]
|
||||
[quo2.components.markdown.text :as quo2.text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.core :as rn]
|
||||
[quo2.components.common.unread-grey-dot.view :refer [unread-grey-dot]]))
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def ^:private custom-props
|
||||
[:name :locked? :mentions-count :unread-messages?
|
||||
@@ -21,22 +20,20 @@
|
||||
name-text (:name props)]
|
||||
[rn/touchable-opacity standard-props
|
||||
[rn/view
|
||||
{:style (merge {:height 48
|
||||
:display :flex
|
||||
:border-radius 12
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:width "100%"
|
||||
:padding-left 12
|
||||
:padding-right 12}
|
||||
(when is-active-channel?
|
||||
{:background-color (colors/theme-alpha channel-color 0.05 0.05)}))}
|
||||
{:style (cond-> {:height 48
|
||||
:border-radius 12
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:width "100%"
|
||||
:padding-left 12
|
||||
:padding-right 12}
|
||||
is-active-channel? (assoc :background-color
|
||||
(colors/theme-alpha channel-color 0.05 0.05)))}
|
||||
[rn/view
|
||||
{:display :flex
|
||||
:flex-direction :row
|
||||
:justify-content :flex-start
|
||||
:align-items :center
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :flex-start
|
||||
:align-items :center}
|
||||
:accessible true
|
||||
:accessibility-label :chat-name-text}
|
||||
[channel-avatar/channel-avatar
|
||||
@@ -45,30 +42,25 @@
|
||||
:emoji-background-color (colors/theme-alpha channel-color 0.1 0.1)
|
||||
:emoji emoji}]
|
||||
[quo2.text/text
|
||||
{:style (merge {:margin-left 12}
|
||||
(when (and (not locked?) muted?)
|
||||
{:color (if (theme/dark?) colors/neutral-60 colors/neutral-40)}))
|
||||
{:style (cond-> {:margin-left 12}
|
||||
(and (not locked?) muted?)
|
||||
(assoc :color (colors/theme-colors colors/neutral-40 colors/neutral-60)))
|
||||
:weight :medium
|
||||
:size :paragraph-1} (str "# " name-text)]]
|
||||
[rn/view
|
||||
{:style {:height 20
|
||||
:justify-content :center}}
|
||||
(when (and (not locked?)
|
||||
muted?)
|
||||
[quo2.icons/icon :i/muted
|
||||
{:size 20
|
||||
:color colors/neutral-40
|
||||
:container-style {:margin-right 1
|
||||
:margin-top 2}}])
|
||||
(when (and (not locked?)
|
||||
(not muted?)
|
||||
(pos? (int mentions-count)))
|
||||
[rn/view
|
||||
{:style {:margin-right 2
|
||||
:margin-top 2}}
|
||||
[quo2.counter/counter {:override-bg-color channel-color} mentions-count]])
|
||||
(when (and (not locked?)
|
||||
(not muted?)
|
||||
(not (pos? (int mentions-count)))
|
||||
unread-messages?)
|
||||
[unread-grey-dot :unviewed-messages-public])]]]))
|
||||
:size :paragraph-1}
|
||||
(str "# " name-text)]]
|
||||
(when-not locked?
|
||||
[rn/view {:style {:height 20 :justify-content :center}}
|
||||
(cond
|
||||
muted?
|
||||
[quo2.icons/icon :i/muted
|
||||
{:size 20
|
||||
:color colors/neutral-40
|
||||
:container-style {:margin-right 1 :margin-top 2}}]
|
||||
|
||||
(pos? (int mentions-count))
|
||||
[rn/view {:style {:margin-right 2 :margin-top 2}}
|
||||
[quo2.counter/counter {:override-bg-color channel-color}
|
||||
mentions-count]]
|
||||
|
||||
unread-messages?
|
||||
[unread-grey-dot :unviewed-messages-public])])]]))
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
(ns quo2.components.loaders.skeleton.constants)
|
||||
|
||||
(def ^:const layout-dimensions
|
||||
{:messages {:height 56
|
||||
:padding-top 12}
|
||||
:list-items {:height 56
|
||||
:padding-top 12}
|
||||
:notifications {:height 90
|
||||
:padding-top 8}})
|
||||
|
||||
(def ^:const content-dimensions
|
||||
{:messages {0 {:author {:width 112
|
||||
:height 8
|
||||
:margin-bottom 8}
|
||||
:message {:width 144
|
||||
:height 16
|
||||
:margin-bottom 0}}
|
||||
1 {:author {:width 96
|
||||
:height 8
|
||||
:margin-bottom 8}
|
||||
:message {:width 212
|
||||
:height 16
|
||||
:margin-bottom 0}}
|
||||
2 {:author {:width 80
|
||||
:height 8
|
||||
:margin-bottom 8}
|
||||
:message {:width 249
|
||||
:height 16
|
||||
:margin-bottom 0}}
|
||||
3 {:author {:width 124
|
||||
:height 8
|
||||
:margin-bottom 8}
|
||||
:message {:width 156
|
||||
:height 16
|
||||
:margin-bottom 0}}}
|
||||
:list-items {0 {:author {:width 112
|
||||
:height 8
|
||||
:margin-bottom 0}
|
||||
:message {:width 144
|
||||
:height 16
|
||||
:margin-bottom 8}}
|
||||
1 {:author {:width 96
|
||||
:height 8
|
||||
:margin-bottom 0}
|
||||
:message {:width 212
|
||||
:height 16
|
||||
:margin-bottom 8}}
|
||||
2 {:author {:width 80
|
||||
:height 8
|
||||
:margin-bottom 0}
|
||||
:message {:width 249
|
||||
:height 16
|
||||
:margin-bottom 8}}
|
||||
3 {:author {:width 124
|
||||
:height 8
|
||||
:margin-bottom 0}
|
||||
:message {:width 156
|
||||
:height 16
|
||||
:margin-bottom 8}}}
|
||||
:notifications {0 {:author {:width 109
|
||||
:height 8
|
||||
:margin-bottom 8}
|
||||
:message {:width 167
|
||||
:height 16
|
||||
:margin-bottom 8}
|
||||
:message2 {:width 242
|
||||
:height 30
|
||||
:margin-bottom 0}}
|
||||
1 {:author {:width 165
|
||||
:height 8
|
||||
:margin-bottom 8}
|
||||
:message {:width 112
|
||||
:height 16
|
||||
:margin-bottom 8}
|
||||
:message2 {:width 294
|
||||
:height 30
|
||||
:margin-bottom 0}}
|
||||
2 {:author {:width 136
|
||||
:height 8
|
||||
:margin-bottom 8}
|
||||
:message {:width 178
|
||||
:height 16
|
||||
:margin-bottom 8}
|
||||
:message2 {:width 178
|
||||
:height 30
|
||||
:margin-bottom 0}}
|
||||
3 {:author {:width 136
|
||||
:height 8
|
||||
:margin-bottom 8}
|
||||
:message {:width 166
|
||||
:height 16
|
||||
:margin-bottom 8}
|
||||
:message2 {:width 256
|
||||
:height 30
|
||||
:margin-bottom 0}}}})
|
||||
@@ -0,0 +1,29 @@
|
||||
(ns quo2.components.loaders.skeleton.style
|
||||
(:require [quo2.components.loaders.skeleton.constants :as constants]))
|
||||
|
||||
(defn container
|
||||
[content]
|
||||
{:flex-direction :row
|
||||
:padding 12
|
||||
:padding-top (get-in constants/layout-dimensions [content :padding-top])
|
||||
:height (get-in constants/layout-dimensions [content :height])})
|
||||
|
||||
(defn avatar
|
||||
[color]
|
||||
{:height 32
|
||||
:width 32
|
||||
:border-radius 16
|
||||
:background-color color})
|
||||
|
||||
(def content-container
|
||||
{:padding-left 8})
|
||||
|
||||
(defn content-view
|
||||
[{:keys [type index content color]}]
|
||||
(let [{:keys [width height margin-bottom]}
|
||||
(get-in constants/content-dimensions [content index type])]
|
||||
{:height height
|
||||
:width width
|
||||
:border-radius 6
|
||||
:background-color color
|
||||
:margin-bottom margin-bottom}))
|
||||
@@ -0,0 +1,46 @@
|
||||
(ns quo2.components.loaders.skeleton.view
|
||||
(:require [quo2.theme :as theme]
|
||||
[react-native.core :as rn]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.loaders.skeleton.style :as style]
|
||||
[quo2.components.loaders.skeleton.constants :as constants]))
|
||||
|
||||
(defn- skeleton-item
|
||||
[index content color]
|
||||
[rn/view {:style (style/container content)}
|
||||
[rn/view {:style (style/avatar color)}]
|
||||
[rn/view {:style style/content-container}
|
||||
[rn/view
|
||||
{:style (style/content-view
|
||||
{:type (if (= content :list-items) :message :author)
|
||||
:index index
|
||||
:content content
|
||||
:color color})}]
|
||||
[rn/view
|
||||
{:style (style/content-view
|
||||
{:type (if (= content :list-items) :author :message)
|
||||
:index index
|
||||
:content content
|
||||
:color color})}]
|
||||
(when (= content :notifications)
|
||||
[rn/view
|
||||
{:style (style/content-view {:type :message2
|
||||
:index index
|
||||
:content content
|
||||
:color color})}])]])
|
||||
|
||||
(defn- internal-view
|
||||
[{:keys [content theme blur? parent-height]}]
|
||||
(let [number-of-skeletons (int (Math/floor (/ parent-height
|
||||
(get-in constants/layout-dimensions [content :height]))))
|
||||
color (cond
|
||||
blur? colors/white-opa-5
|
||||
(= theme :dark) colors/neutral-90
|
||||
:else colors/neutral-5)]
|
||||
[rn/view {:style {:padding 8}}
|
||||
(doall
|
||||
(for [index (range number-of-skeletons)]
|
||||
^{:key index}
|
||||
[skeleton-item (mod index 4) content color]))]))
|
||||
|
||||
(def view (theme/with-theme internal-view))
|
||||
@@ -0,0 +1,38 @@
|
||||
(ns quo2.components.markdown.list.component-spec
|
||||
(:require [quo2.components.markdown.list.view :as list]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "tests for markdown/list component"
|
||||
(h/test "renders component with title"
|
||||
(h/render [list/view {:title "test title"}])
|
||||
(h/is-truthy (h/get-by-text "test title")))
|
||||
|
||||
(h/test "renders component with description"
|
||||
(h/render [list/view
|
||||
{:title "test title"
|
||||
:description "test description"}])
|
||||
(h/is-truthy (h/get-by-text "test description")))
|
||||
|
||||
(h/test "renders component with title and description"
|
||||
(h/render [list/view
|
||||
{:title "test title"
|
||||
:description "test description"}])
|
||||
(h/is-truthy (h/get-by-text "test title"))
|
||||
(h/is-truthy (h/get-by-text "test description")))
|
||||
|
||||
(h/test "renders step component when step-number is valid and type is step"
|
||||
(h/render [list/view
|
||||
{:type :step
|
||||
:step-number 1}])
|
||||
(h/is-truthy (h/get-by-label-text :step-counter)))
|
||||
|
||||
(h/test "renders decription with a context tag component and description after the tag"
|
||||
(h/render [list/view
|
||||
{:step-number 1
|
||||
:description "Lorem ipsum "
|
||||
:tag-name "dolor"
|
||||
:description-after-tag "text after tag"}])
|
||||
(h/is-truthy (h/get-by-text "Lorem ipsum"))
|
||||
(h/is-truthy (h/get-by-label-text :user-avatar))
|
||||
(h/is-truthy (h/get-by-text "dolor"))
|
||||
(h/is-truthy (h/get-by-text "text after tag"))))
|
||||
@@ -0,0 +1,15 @@
|
||||
(ns quo2.components.markdown.list.style)
|
||||
|
||||
(defn container
|
||||
[container-style]
|
||||
(merge container-style
|
||||
{:flex-direction :row
|
||||
:flex 1
|
||||
:align-items :flex-start}))
|
||||
|
||||
(def index
|
||||
{:margin-left 5})
|
||||
|
||||
(def text-container
|
||||
{:margin-left 8
|
||||
:flex 1})
|
||||
@@ -0,0 +1,65 @@
|
||||
(ns quo2.components.markdown.list.view
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.counter.step.view :as step]
|
||||
[quo2.components.markdown.list.style :as style]
|
||||
[quo2.components.icon :as icon]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[quo2.components.tags.context-tag.view :as context-tag]))
|
||||
|
||||
(defn get-colors
|
||||
[theme blur?]
|
||||
(cond (and blur? (= theme :dark)) colors/white-opa-40
|
||||
(= theme :dark) colors/neutral-50
|
||||
:else colors/neutral-40))
|
||||
|
||||
(defn description-text
|
||||
[{:keys [description tag-name tag-picture description-after-tag blur?]}]
|
||||
(if-not tag-name
|
||||
[text/text
|
||||
{:accessibility-label :list-item-description
|
||||
:size :paragraph-2}
|
||||
description]
|
||||
[rn/view {:style {:flex-direction :row :align-items :center}}
|
||||
[text/text
|
||||
{:accessibility-label :list-item-description
|
||||
:size :paragraph-2}
|
||||
description]
|
||||
[rn/view {:style {:margin-left 4}}
|
||||
[context-tag/context-tag {:blur? blur?} tag-picture tag-name]]
|
||||
[text/text
|
||||
{:style {:margin-left 4}
|
||||
:accessibility-label :list-item-description-after-tag
|
||||
:size :paragraph-2}
|
||||
description-after-tag]]))
|
||||
|
||||
(defn- internal-view
|
||||
[{:keys [theme title description tag-picture tag-name description-after-tag step-number
|
||||
customization-color type blur? container-style]
|
||||
:or {type :bullet}}]
|
||||
[rn/view {:style (style/container container-style)}
|
||||
[rn/view {:style style/index}
|
||||
(if (= type :step)
|
||||
[step/step
|
||||
{:in-blur-view? blur?
|
||||
:customization-color customization-color
|
||||
:type (if customization-color :complete :neutral)} step-number]
|
||||
[icon/icon :i/bullet {:color (get-colors theme blur?)}])]
|
||||
[rn/view {:style style/text-container}
|
||||
(when title
|
||||
[text/text
|
||||
{:accessibility-label :list-item-title
|
||||
:weight :semi-bold
|
||||
:size :paragraph-2}
|
||||
title])
|
||||
(when description
|
||||
[rn/view (when title {:style {:margin-top 0}})
|
||||
[description-text
|
||||
{:description description
|
||||
:tag-name tag-name
|
||||
:tag-picture tag-picture
|
||||
:description-after-tag description-after-tag
|
||||
:blur? blur?}]])]])
|
||||
|
||||
(def view (theme/with-theme internal-view))
|
||||
@@ -5,7 +5,8 @@
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[quo2.theme :as theme]))
|
||||
|
||||
(def ^:private centrify-style
|
||||
{:display :flex
|
||||
@@ -30,7 +31,7 @@
|
||||
{:no-color true})))
|
||||
|
||||
(defn left-section-view
|
||||
[{:keys [on-press icon accessibility-label type icon-background-color icon-override-theme]
|
||||
[{: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})}
|
||||
@@ -40,7 +41,6 @@
|
||||
:type type
|
||||
:size 32
|
||||
:accessibility-label accessibility-label
|
||||
:override-theme icon-override-theme
|
||||
:override-background-color icon-background-color}
|
||||
icon]])
|
||||
|
||||
@@ -87,10 +87,10 @@
|
||||
|
||||
(defn- mid-section-view
|
||||
[{:keys [horizontal-description? one-icon-align-left? type left-align?
|
||||
main-text right-icon main-text-icon-color left-icon on-press avatar]
|
||||
main-text right-icon main-text-icon-color left-icon on-press avatar theme]
|
||||
:as props}]
|
||||
(let [text-color (if (colors/dark?) colors/neutral-5 colors/neutral-95)
|
||||
text-secondary-color (if (colors/dark?) colors/neutral-40 colors/neutral-50)
|
||||
(let [text-color (colors/theme-colors colors/neutral-95 colors/neutral-5 theme)
|
||||
text-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
component-instance [mid-section-comp (assoc props :text-secondary-color text-secondary-color)]]
|
||||
[rn/touchable-opacity {:on-press on-press}
|
||||
[rn/view
|
||||
@@ -152,7 +152,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 icon-background-color
|
||||
{:keys [icon on-press type style icon-background-color
|
||||
accessibility-label label]
|
||||
:or {type :grey}}]
|
||||
^{:key index}
|
||||
@@ -168,12 +168,11 @@
|
||||
:type type
|
||||
:before (when label icon)
|
||||
:size 32
|
||||
:override-theme icon-override-theme
|
||||
:override-background-color icon-background-color}
|
||||
(if label label icon)]])
|
||||
right-section-buttons))])
|
||||
|
||||
(defn page-nav
|
||||
(defn- page-nav-internal
|
||||
"[page-nav opts]
|
||||
opts
|
||||
{ :one-icon-align-left? true/false
|
||||
@@ -198,25 +197,26 @@
|
||||
{:type button-type
|
||||
:on-press event
|
||||
:icon icon
|
||||
:icon-override-theme :light/:dark
|
||||
}
|
||||
:right-section-buttons vector of
|
||||
{:type button-type
|
||||
:on-press event
|
||||
:icon icon
|
||||
:icon-override-theme :light/:dark
|
||||
}
|
||||
:theme :light or :dark
|
||||
}
|
||||
"
|
||||
[{:keys [container-style one-icon-align-left? horizontal-description?
|
||||
align-mid? page-nav-color page-nav-background-uri
|
||||
mid-section
|
||||
left-section
|
||||
right-section-buttons]}]
|
||||
right-section-buttons
|
||||
theme]}]
|
||||
(let [put-middle-section-on-left? (or align-mid?
|
||||
(> (count right-section-buttons) 1))
|
||||
mid-section-props
|
||||
{:type (:type mid-section)
|
||||
:theme theme
|
||||
:horizontal-description? horizontal-description?
|
||||
:description-img (:description-img mid-section)
|
||||
:main-text (:main-text mid-section)
|
||||
@@ -258,3 +258,5 @@
|
||||
(not put-middle-section-on-left?)
|
||||
[mid-section-view mid-section-props]))]
|
||||
[right-section-view right-section-buttons]]))
|
||||
|
||||
(def page-nav (theme/with-theme page-nav-internal))
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
|
||||
(defn toast-undo-action
|
||||
[duration on-press override-theme]
|
||||
[toast-action-container
|
||||
{:on-press on-press :accessibility-label :toast-undo-action}
|
||||
[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
|
||||
@@ -31,17 +30,17 @@
|
||||
|
||||
(defn- toast-container
|
||||
[{:keys [left title text right container-style override-theme]}]
|
||||
[rn/view
|
||||
{:style (merge style/box-container container-style)}
|
||||
[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/content-container override-theme)}
|
||||
[rn/view {:style style/left-side-container}
|
||||
left]
|
||||
[rn/view {:style style/right-side-container}
|
||||
(when title
|
||||
[text/text
|
||||
@@ -57,7 +56,7 @@
|
||||
:style (style/text override-theme)
|
||||
:accessibility-label :toast-content}
|
||||
text])]
|
||||
(when right right)]])
|
||||
right]])
|
||||
|
||||
(defn toast
|
||||
[{:keys [icon icon-color title text action undo-duration undo-on-press container-style
|
||||
|
||||
@@ -26,4 +26,4 @@
|
||||
{:data [{:id 1
|
||||
:label "Item 1"}
|
||||
]} types/tab])
|
||||
(h/is-truthy (h/get-by-text "Item 1"))))
|
||||
(h/is-truthy (h/get-by-text "Item 1"))))
|
||||
|
||||
+16
-4
@@ -49,6 +49,8 @@
|
||||
quo2.components.list-items.preview-list
|
||||
quo2.components.list-items.user-list
|
||||
quo2.components.loaders.skeleton
|
||||
quo2.components.loaders.skeleton.view
|
||||
quo2.components.markdown.list.view
|
||||
quo2.components.markdown.text
|
||||
quo2.components.messages.author.view
|
||||
quo2.components.messages.gap
|
||||
@@ -91,7 +93,6 @@
|
||||
quo2.components.settings.reorder-item.view
|
||||
quo2.components.community.channel-actions))
|
||||
|
||||
(def text quo2.components.markdown.text/text)
|
||||
(def icon quo2.components.icon/icon)
|
||||
(def separator quo2.components.separator/separator)
|
||||
(def header quo2.components.header/header)
|
||||
@@ -107,12 +108,11 @@
|
||||
(def group-avatar-tag quo2.components.tags.context-tag.view/group-avatar-tag)
|
||||
(def audio-tag quo2.components.tags.context-tag.view/audio-tag)
|
||||
(def community-tag quo2.components.tags.context-tag.view/community-tag)
|
||||
(def floating-shell-button quo2.components.navigation.floating-shell-button/floating-shell-button)
|
||||
(def page-nav quo2.components.navigation.page-nav/page-nav)
|
||||
|
||||
|
||||
(def disclaimer quo2.components.selectors.disclaimer.view/view)
|
||||
(def checkbox quo2.components.selectors.selectors.view/checkbox)
|
||||
(def filter quo2.components.selectors.filter.view/view)
|
||||
(def skeleton quo2.components.loaders.skeleton/skeleton)
|
||||
(def author quo2.components.messages.author.view/author)
|
||||
|
||||
;;;; SELECTORS
|
||||
@@ -190,6 +190,18 @@
|
||||
(def preview-list quo2.components.list-items.preview-list/preview-list)
|
||||
(def user-list quo2.components.list-items.user-list/user-list)
|
||||
|
||||
;;;; LOADERS
|
||||
(def skeleton quo2.components.loaders.skeleton/skeleton)
|
||||
(def static-skeleton quo2.components.loaders.skeleton.view/view)
|
||||
|
||||
;;;; NAVIGATION
|
||||
(def floating-shell-button quo2.components.navigation.floating-shell-button/floating-shell-button)
|
||||
(def page-nav quo2.components.navigation.page-nav/page-nav)
|
||||
|
||||
;;;; MARKDOWN
|
||||
(def markdown-list quo2.components.markdown.list.view/view)
|
||||
(def text quo2.components.markdown.text/text)
|
||||
|
||||
;;;; NOTIFICATIONS
|
||||
(def activity-log quo2.components.notifications.activity-log.view/view)
|
||||
(def info-count quo2.components.notifications.info-count/info-count)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
[quo2.components.links.url-preview-list.component-spec]
|
||||
[quo2.components.links.url-preview.component-spec]
|
||||
[quo2.components.markdown.--tests--.text-component-spec]
|
||||
[quo2.components.markdown.list.component-spec]
|
||||
[quo2.components.notifications.notification.component-spec]
|
||||
[quo2.components.onboarding.small-option-card.component-spec]
|
||||
[quo2.components.password.tips.component-spec]
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
[comp]
|
||||
(.showOverlay Navigation (clj->js comp)))
|
||||
|
||||
(defn pop-to
|
||||
[comp]
|
||||
(.popTo Navigation (clj->js comp)))
|
||||
|
||||
(defn pop-to-root
|
||||
[tab]
|
||||
(.popToRoot Navigation (clj->js tab)))
|
||||
|
||||
@@ -81,7 +81,8 @@
|
||||
{:linear (bezier 0 0 1 1)
|
||||
:easing1 (bezier 0.25 0.1 0.25 1)
|
||||
:easing2 (bezier 0 0.3 0.6 0.9)
|
||||
:easing3 (bezier 0.3 0.3 0.3 0.9)})
|
||||
:easing3 (bezier 0.3 0.3 0.3 0.9)
|
||||
:easing4 (bezier 0.3 0.3 1 1)})
|
||||
|
||||
;; Helper functions
|
||||
(defn get-shared-value
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
|
||||
(defn- get-static-bottom
|
||||
[]
|
||||
(oops/oget StaticSafeAreaInsets "safeAreaInsetsBottom"))
|
||||
(some-> StaticSafeAreaInsets
|
||||
(oops/oget "safeAreaInsetsBottom")))
|
||||
|
||||
(defn get-top
|
||||
[]
|
||||
@@ -20,8 +21,8 @@
|
||||
|
||||
(defn get-bottom
|
||||
[]
|
||||
(if platform/ios?
|
||||
(get-static-bottom)
|
||||
(if-let [bottom (and platform/ios? (get-static-bottom))]
|
||||
bottom
|
||||
0))
|
||||
|
||||
(defn get-insets
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
(-> message
|
||||
(clojure.set/rename-keys {:chatId :chat-id
|
||||
:introductionMessage :introduction-message
|
||||
:messageType :message-type})))
|
||||
:messageType :message-type})))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(ns status-im.fleet.default-fleet (:require-macros [status-im.utils.slurp :refer [slurp]]))
|
||||
|
||||
(def default-fleets
|
||||
(slurp "resources/config/fleets.json"))
|
||||
(slurp "resources/config/fleets.json"))
|
||||
|
||||
@@ -28,4 +28,4 @@
|
||||
[button "conn sell" :connect-selected-card simulated-keycard/connect-selected-card]
|
||||
[button "pair" :connect-pairing-card simulated-keycard/connect-pairing-card]
|
||||
[button "disc" :disconnect-card simulated-keycard/disconnect-card]
|
||||
[button "res" :keycard-reset-state simulated-keycard/reset-state]])
|
||||
[button "res" :keycard-reset-state simulated-keycard/reset-state]])
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
(fn [[key-uid _ hashed-password]]
|
||||
(native-module/login-account {:keyUid key-uid
|
||||
:password hashed-password
|
||||
:wakuV2Nameserver "1.1.1.1"
|
||||
:openseaAPIKey config/opensea-api-key
|
||||
|
||||
:poktToken config/POKT_TOKEN
|
||||
|
||||
@@ -80,7 +80,9 @@
|
||||
multiaccount-data (when received-account?
|
||||
(merge account {:password password}))
|
||||
navigate-to-syncing-devices? (and (or connection-success? error-on-pairing?) receiver?)
|
||||
user-in-syncing-devices-screen? (= (:view-id db) :syncing-progress)]
|
||||
user-in-syncing-devices-screen? (or (= (:view-id db) :syncing-progress)
|
||||
(= (:view-id db) :syncing-progress-intro))
|
||||
user-in-sign-in-intro-screen? (= (:view-id db) :sign-in-intro)]
|
||||
(merge {:db (cond-> db
|
||||
connection-success?
|
||||
(assoc-in [:syncing :pairing-status] :connected)
|
||||
@@ -95,7 +97,9 @@
|
||||
(assoc-in [:syncing :pairing-status] :completed))}
|
||||
(cond
|
||||
(and navigate-to-syncing-devices? (not user-in-syncing-devices-screen?))
|
||||
{:dispatch [:navigate-to :syncing-progress]}
|
||||
{:dispatch (if user-in-sign-in-intro-screen?
|
||||
[:navigate-to-within-stack [:syncing-progress-intro :sign-in-intro]]
|
||||
[:navigate-to :syncing-progress])}
|
||||
|
||||
(and completed-pairing? sender?)
|
||||
{:dispatch [:syncing/clear-states]}
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
:justify-content :center
|
||||
:border-radius 2
|
||||
:width 18
|
||||
:height 18})
|
||||
:height 18})
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
(if @error?
|
||||
[icons/icon :main-icons/cancel]
|
||||
(when-not @loaded?
|
||||
[react/activity-indicator {:animating true}]))])])))
|
||||
[react/activity-indicator {:animating true}]))])])))
|
||||
|
||||
@@ -60,4 +60,4 @@
|
||||
:android {:margin-bottom 3}
|
||||
:ios {:margin-bottom 10}})
|
||||
|
||||
(def section-header-container {})
|
||||
(def section-header-container {})
|
||||
|
||||
@@ -42,4 +42,4 @@
|
||||
[react/activity-indicator
|
||||
{:color colors/white-persist
|
||||
:animating true}]
|
||||
[icons/icon :main-icons/add {:color colors/white-persist}])]]])
|
||||
[icons/icon :main-icons/add {:color colors/white-persist}])]]])
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
(def slider (reagent/adapt-react-class Slider))
|
||||
|
||||
(def animated-slider
|
||||
(reagent/adapt-react-class (.createAnimatedComponent Animated Slider)))
|
||||
(reagent/adapt-react-class (.createAnimatedComponent Animated Slider)))
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
56
|
||||
(if platform/iphone-x?
|
||||
84
|
||||
50)))
|
||||
50)))
|
||||
|
||||
@@ -32,4 +32,4 @@
|
||||
[react/view {:padding-horizontal 12 :padding-vertical 8}
|
||||
[react/text
|
||||
{:style {:font-weight "500" :color (if active? colors/white colors/blue) :line-height 22}}
|
||||
label]]]])
|
||||
label]]]])
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
{:color colors/gray
|
||||
:padding 24
|
||||
:line-height 22
|
||||
:font-size 15})
|
||||
:font-size 15})
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
:border-radius 20
|
||||
:background-color colors/gray-lighter
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
:justify-content :center})
|
||||
|
||||
@@ -1 +1 @@
|
||||
(ns status-im.ui.screens.help-center.styles)
|
||||
(ns status-im.ui.screens.help-center.styles)
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
:justify-content :space-between})
|
||||
|
||||
(def enable-all
|
||||
{:align-self :flex-end})
|
||||
{:align-self :flex-end})
|
||||
|
||||
@@ -78,4 +78,4 @@
|
||||
(def bottom-container
|
||||
{:flex-direction :row
|
||||
:margin-horizontal 12
|
||||
:margin-vertical 15})
|
||||
:margin-vertical 15})
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
(def share-link-button
|
||||
{:margin-top 12
|
||||
:margin-horizontal 16
|
||||
:margin-bottom 16})
|
||||
:margin-bottom 16})
|
||||
|
||||
@@ -8,4 +8,4 @@
|
||||
:right 0
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex 1})
|
||||
:flex 1})
|
||||
|
||||
@@ -61,4 +61,4 @@
|
||||
:padding-left 16
|
||||
:color (if disabled? colors/black colors/white-persist)
|
||||
:padding-horizontal 16
|
||||
:padding-vertical 10})
|
||||
:padding-vertical 10})
|
||||
|
||||
@@ -26,4 +26,4 @@
|
||||
:border-radius 14
|
||||
:background-color colors/green
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
:justify-content :center})
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
(defn separator-dark
|
||||
[]
|
||||
{:height 1
|
||||
:background-color colors/black-transparent})
|
||||
:background-color colors/black-transparent})
|
||||
|
||||
@@ -18,4 +18,4 @@
|
||||
:style (merge
|
||||
{:width (or width 40)
|
||||
:height (or height 40)}
|
||||
image-style)}]])
|
||||
image-style)}]])
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
:margin-bottom 12
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:padding-horizontal 12})
|
||||
:padding-horizontal 12})
|
||||
|
||||
@@ -151,4 +151,4 @@
|
||||
|
||||
(def app-info-container
|
||||
{:flex-direction :column
|
||||
:flex 1})
|
||||
:flex 1})
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
[photo-path]
|
||||
(when-not (and (not (string/blank? photo-path))
|
||||
(string/starts-with? photo-path "contacts://"))
|
||||
{:uri photo-path}))
|
||||
{:uri photo-path}))
|
||||
|
||||
@@ -622,4 +622,4 @@
|
||||
"yoke"
|
||||
"yurt"
|
||||
"zinc"
|
||||
"zone"])
|
||||
"zone"])
|
||||
|
||||
@@ -21,4 +21,4 @@
|
||||
;; ticker on exchange networks. We handle that with `symbol-exchange` override.
|
||||
(defn exchange-symbol
|
||||
[{:keys [symbol-exchange symbol-display symbol]}]
|
||||
(clojure.core/name (or symbol-exchange symbol-display symbol)))
|
||||
(clojure.core/name (or symbol-exchange symbol-display symbol)))
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
(defn sheet
|
||||
[{:keys [top bottom]} window-height override-theme padding-bottom-override shell?]
|
||||
{:position :absolute
|
||||
:max-height (cond-> window-height
|
||||
platform/ios? (- top))
|
||||
:max-height (- window-height top)
|
||||
:z-index 1
|
||||
:bottom 0
|
||||
:left 0
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
:right 0}))
|
||||
|
||||
(defn main-view
|
||||
[translate-y override-theme]
|
||||
[translate-y theme]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:transform [{:translate-y translate-y}]}
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-95 override-theme)
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
|
||||
:border-top-left-radius 20
|
||||
:border-top-right-radius 20
|
||||
:flex 1
|
||||
@@ -36,9 +36,9 @@
|
||||
:align-items :center})
|
||||
|
||||
(defn handle
|
||||
[override-theme]
|
||||
[theme]
|
||||
{:width 32
|
||||
:height 4
|
||||
:border-radius 100
|
||||
:background-color (colors/theme-colors colors/neutral-100 colors/white override-theme)
|
||||
:background-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:opacity (theme/theme-value 0.05 0.1)})
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
(ns status-im2.common.bottom-sheet-screen.view
|
||||
(:require
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.hooks :as hooks]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[oops.core :as oops]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im2.common.bottom-sheet-screen.style :as style]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[utils.re-frame :as rf]))
|
||||
(:require [oops.core :as oops]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.hooks :as hooks]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.bottom-sheet-screen.style :as style]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def ^:const drag-threshold 200)
|
||||
|
||||
@@ -43,12 +43,11 @@
|
||||
(let [y (oops/oget e "nativeEvent.contentOffset.y")]
|
||||
(reset! curr-scroll y)))
|
||||
|
||||
(defn f-view
|
||||
[content skip-background?]
|
||||
(let [scroll-enabled (reagent/atom true)
|
||||
curr-scroll (reagent/atom 0)
|
||||
{:keys [override-theme]} (rf/sub [:get-screen-params])]
|
||||
(fn []
|
||||
(defn- f-view
|
||||
[_]
|
||||
(let [scroll-enabled (reagent/atom true)
|
||||
curr-scroll (reagent/atom 0)]
|
||||
(fn [{:keys [content skip-background? theme]}]
|
||||
(let [insets (safe-area/get-insets)
|
||||
{:keys [height]} (rn/get-window)
|
||||
padding-top (:top insets)
|
||||
@@ -71,12 +70,18 @@
|
||||
[reanimated/view {:style (style/background opacity)}])
|
||||
[gesture/gesture-detector
|
||||
{:gesture (drag-gesture translate-y opacity scroll-enabled curr-scroll close)}
|
||||
[reanimated/view {:style (style/main-view translate-y override-theme)}
|
||||
[reanimated/view {:style (style/main-view translate-y theme)}
|
||||
[rn/view {:style style/handle-container}
|
||||
[rn/view {:style (style/handle override-theme)}]]
|
||||
[rn/view {:style (style/handle theme)}]]
|
||||
[content
|
||||
{:insets insets
|
||||
:close close
|
||||
:scroll-enabled scroll-enabled
|
||||
:current-scroll curr-scroll
|
||||
:on-scroll #(on-scroll % curr-scroll)}]]]]))))
|
||||
|
||||
(defn- internal-view
|
||||
[params]
|
||||
[:f> f-view params])
|
||||
|
||||
(def view (theme/with-theme internal-view))
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
:accessibility-label (or accessibility-label :plus-button)
|
||||
:on-press on-press
|
||||
:customization-color customization-color}
|
||||
:i/add])
|
||||
:i/add])
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
(ns status-im2.common.toasts.animation
|
||||
(:require [react-native.gesture :as gesture]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
|
||||
(def slide-out-up-animation
|
||||
(-> ^js reanimated/slide-out-up-animation
|
||||
(.springify)
|
||||
(.damping 20)
|
||||
(.stiffness 12)))
|
||||
|
||||
(def slide-in-up-animation
|
||||
(-> ^js reanimated/slide-in-up-animation
|
||||
(.springify)
|
||||
(.damping 20)
|
||||
(.stiffness 150)))
|
||||
|
||||
(def linear-transition
|
||||
(-> ^js reanimated/linear-transition
|
||||
.springify
|
||||
(.damping 20)
|
||||
(.stiffness 170)))
|
||||
|
||||
(defn- reset-translate-y
|
||||
([translate-y]
|
||||
(reset-translate-y translate-y 0))
|
||||
([translate-y spring-value]
|
||||
(reanimated/animate-shared-value-with-spring
|
||||
translate-y
|
||||
spring-value
|
||||
{:mass 1 :damping 20 :stiffness 300})))
|
||||
|
||||
(defn- dismiss
|
||||
[translate-y set-dismissed-locally close-toast]
|
||||
(reset-translate-y translate-y -500)
|
||||
(set-dismissed-locally)
|
||||
(close-toast))
|
||||
|
||||
(defn on-update-gesture
|
||||
[translate-y set-dismissed-locally close-toast]
|
||||
(fn [^js evt]
|
||||
(let [evt-translation-y (.-translationY evt)
|
||||
pan-down? (> evt-translation-y 100)
|
||||
pan-up? (< evt-translation-y -30)]
|
||||
(cond
|
||||
pan-down? (reset-translate-y translate-y)
|
||||
pan-up? (dismiss translate-y set-dismissed-locally close-toast)
|
||||
:else (reanimated/set-shared-value translate-y evt-translation-y)))))
|
||||
|
||||
(defn pan-gesture
|
||||
[{:keys [clear-timer create-timer translate-y close-toast set-dismissed-locally
|
||||
dismissed-locally?]}]
|
||||
(-> (gesture/gesture-pan)
|
||||
(gesture/on-start clear-timer)
|
||||
(gesture/on-update (on-update-gesture translate-y set-dismissed-locally close-toast))
|
||||
(gesture/on-end #(when-not dismissed-locally?
|
||||
(reanimated/set-shared-value translate-y 0)
|
||||
(create-timer)))))
|
||||
@@ -1,13 +1,12 @@
|
||||
(ns status-im2.common.toasts.style)
|
||||
|
||||
(def outmost-transparent-container
|
||||
{:elevation 2
|
||||
:pointer-events :box-none
|
||||
:padding-top 52
|
||||
:flex-direction :column
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color :transparent})
|
||||
{:elevation 2
|
||||
:pointer-events :box-none
|
||||
:padding-top 52
|
||||
:flex-direction :column
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
|
||||
(def each-toast-container
|
||||
{:width "100%"
|
||||
|
||||
@@ -1,89 +1,56 @@
|
||||
(ns status-im2.common.toasts.view
|
||||
(:require [quo2.core :as quo]
|
||||
[react-native.background-timer :as background-timer]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[reagent.core :as reagent]
|
||||
[react-native.background-timer :as background-timer]
|
||||
[status-im2.common.toasts.animation :as animation]
|
||||
[status-im2.common.toasts.style :as style]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn toast
|
||||
[id]
|
||||
(let [{:keys [type] :as toast-opts} (rf/sub [:toasts/toast id])]
|
||||
[toast-id]
|
||||
(let [{:keys [type] :as toast-opts} (rf/sub [:toasts/toast toast-id])]
|
||||
(if (= type :notification)
|
||||
[quo/notification toast-opts]
|
||||
[quo/toast toast-opts])))
|
||||
|
||||
(defn reset-translate-y
|
||||
[translate-y]
|
||||
(reanimated/animate-shared-value-with-spring translate-y
|
||||
0
|
||||
{:mass 1
|
||||
:damping 20
|
||||
:stiffness 300}))
|
||||
|
||||
(defn dismiss
|
||||
[translate-y dismissed-locally? close!]
|
||||
(reanimated/animate-shared-value-with-spring
|
||||
translate-y
|
||||
-500
|
||||
{:mass 1 :damping 20 :stiffness 300})
|
||||
(reset! dismissed-locally? true)
|
||||
(close!))
|
||||
|
||||
(defn f-container
|
||||
[id]
|
||||
(let [dismissed-locally? (reagent/atom false)
|
||||
close! #(rf/dispatch [:toasts/close id])
|
||||
timer (reagent/atom nil)
|
||||
clear-timer #(background-timer/clear-timeout @timer)]
|
||||
[toast-id]
|
||||
(let [dismissed-locally? (reagent/atom false)
|
||||
set-dismissed-locally #(reset! dismissed-locally? true)
|
||||
close-toast #(rf/dispatch [:toasts/close toast-id])
|
||||
timer (reagent/atom nil)
|
||||
clear-timer #(background-timer/clear-timeout @timer)]
|
||||
(fn []
|
||||
(let [duration (or (rf/sub [:toasts/toast-cursor id :duration]) 3000)
|
||||
on-dismissed (or (rf/sub [:toasts/toast-cursor id :on-dismissed]) identity)
|
||||
create-timer (fn []
|
||||
(reset! timer (background-timer/set-timeout close! duration)))
|
||||
translate-y (reanimated/use-shared-value 0)
|
||||
pan
|
||||
(->
|
||||
(gesture/gesture-pan)
|
||||
(gesture/on-start clear-timer)
|
||||
(gesture/on-update
|
||||
(fn [^js evt]
|
||||
(let [evt-translation-y (.-translationY evt)
|
||||
pan-down? (> evt-translation-y 100)
|
||||
pan-up? (< evt-translation-y -30)]
|
||||
(cond
|
||||
pan-down? (reset-translate-y translate-y)
|
||||
pan-up? (dismiss translate-y dismissed-locally? close!)
|
||||
:else
|
||||
(reanimated/set-shared-value translate-y
|
||||
evt-translation-y)))))
|
||||
(gesture/on-end (fn [_]
|
||||
(when-not @dismissed-locally?
|
||||
(reanimated/set-shared-value translate-y 0)
|
||||
(create-timer)))))]
|
||||
(let [duration (or (rf/sub [:toasts/toast-cursor toast-id :duration]) 3000)
|
||||
on-dismissed (or (rf/sub [:toasts/toast-cursor toast-id :on-dismissed]) identity)
|
||||
create-timer #(reset! timer (background-timer/set-timeout close-toast duration))
|
||||
translate-y (reanimated/use-shared-value 0)
|
||||
pan-gesture (animation/pan-gesture {:clear-timer clear-timer
|
||||
:create-timer create-timer
|
||||
:translate-y translate-y
|
||||
:close-toast close-toast
|
||||
:set-dismissed-locally set-dismissed-locally
|
||||
:dismissed-locally? @dismissed-locally?})]
|
||||
;; 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))
|
||||
[gesture/gesture-detector {:gesture pan}
|
||||
(rn/use-unmount #(on-dismissed toast-id))
|
||||
|
||||
[gesture/gesture-detector {:gesture pan-gesture}
|
||||
[reanimated/view
|
||||
{;; TODO: this will enable 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
|
||||
;; :exiting slide-out-up-animation
|
||||
;; :layout reanimated/linear-transition
|
||||
:style (reanimated/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}]}
|
||||
style/each-toast-container)}
|
||||
[toast id]]]))))
|
||||
{:entering animation/slide-in-up-animation
|
||||
:exiting animation/slide-out-up-animation
|
||||
:layout animation/linear-transition
|
||||
:style (reanimated/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}]}
|
||||
style/each-toast-container)}
|
||||
[toast toast-id]]]))))
|
||||
|
||||
(defn toasts
|
||||
[]
|
||||
(let [toasts-ordered (:ordered (rf/sub [:toasts]))]
|
||||
[into
|
||||
[rn/view
|
||||
{:style style/outmost-transparent-container}]
|
||||
(doall
|
||||
(map (fn [id] ^{:key id} [:f> f-container id]) toasts-ordered))]))
|
||||
(->> (rf/sub [:toasts])
|
||||
:ordered
|
||||
(into [rn/view {:style style/outmost-transparent-container}]
|
||||
(map #(with-meta [:f> f-container %] {:key %})))))
|
||||
|
||||
@@ -336,3 +336,6 @@
|
||||
(def ^:const image-description-in-lightbox? false)
|
||||
|
||||
(def ^:const audio-max-duration-ms 120000)
|
||||
|
||||
(def ^:const onboarding-modal-animation-duration 300)
|
||||
(def ^:const onboarding-modal-animation-delay 400)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
(def ^:const composer-default-height (+ bar-container-height input-height actions-container-height))
|
||||
|
||||
(def ^:const line-height (:line-height typography/paragraph-1))
|
||||
(def ^:const line-height (if platform/ios? 21.5 (:line-height typography/paragraph-1)))
|
||||
|
||||
(def ^:const multiline-minimized-height (+ input-height (if platform/ios? 18 line-height)))
|
||||
|
||||
|
||||
@@ -46,4 +46,4 @@
|
||||
:border-width 1})
|
||||
|
||||
(def no-pinned-messages-text
|
||||
{:margin-top 20})
|
||||
{:margin-top 20})
|
||||
|
||||
@@ -34,4 +34,4 @@
|
||||
:pinned-by display-name
|
||||
:child [reply/quoted-message quoted-message false true]
|
||||
:timestamp-str timestamp-str
|
||||
:labels {:pinned-a-message (i18n/label :t/pinned-a-message)}}]))
|
||||
:labels {:pinned-a-message (i18n/label :t/pinned-a-message)}}]))
|
||||
|
||||
@@ -251,16 +251,18 @@
|
||||
|
||||
(defn render-fn
|
||||
[{:keys [type value content-type] :as message-data} _ _
|
||||
{:keys [context keyboard-shown?]}]
|
||||
{:keys [context keyboard-shown? insets]}]
|
||||
;;TODO temporary hide mutual-state-updates https://github.com/status-im/status-mobile/issues/16254
|
||||
(when (not= content-type constants/content-type-system-mutual-state-update)
|
||||
[rn/view
|
||||
(add-inverted-y-android {:background-color (colors/theme-colors colors/white colors/neutral-95)})
|
||||
(if (= type :datemark)
|
||||
[quo/divider-date value]
|
||||
(if (= content-type constants/content-type-gap)
|
||||
[message.gap/gap message-data]
|
||||
[message/message message-data context keyboard-shown?]))]))
|
||||
(if (= type :header)
|
||||
[list-header insets]
|
||||
[rn/view
|
||||
(add-inverted-y-android {:background-color (colors/theme-colors colors/white colors/neutral-95)})
|
||||
(if (= type :datemark)
|
||||
[quo/divider-date value]
|
||||
(if (= content-type constants/content-type-gap)
|
||||
[message.gap/gap message-data]
|
||||
[message/message message-data context keyboard-shown?]))])))
|
||||
|
||||
(defn scroll-handler
|
||||
[event scroll-y]
|
||||
@@ -291,22 +293,21 @@
|
||||
:ref list-ref
|
||||
:header [:<>
|
||||
(when (= (:chat-type chat) constants/private-group-chat-type)
|
||||
[list-group-chat-header chat])
|
||||
[list-header insets]]
|
||||
[list-group-chat-header chat])]
|
||||
:footer [list-footer
|
||||
{:chat chat
|
||||
:scroll-y scroll-y
|
||||
:cover-bg-color cover-bg-color
|
||||
:on-layout footer-on-layout
|
||||
:shell-animation-complete? shell-animation-complete?}]
|
||||
:data messages
|
||||
:data (into [{:type :header}] messages)
|
||||
:render-data {:context context
|
||||
:keyboard-shown? keyboard-shown?}
|
||||
:keyboard-shown? keyboard-shown?
|
||||
:insets insets}
|
||||
:render-fn render-fn
|
||||
:on-viewable-items-changed on-viewable-items-changed
|
||||
:on-end-reached #(list-on-end-reached scroll-y)
|
||||
:on-scroll-to-index-failed identity
|
||||
:content-container-style {:padding-bottom style/messages-list-bottom-offset}
|
||||
:scroll-indicator-insets {:top (- composer.constants/composer-default-height 16)}
|
||||
:keyboard-dismiss-mode :interactive
|
||||
:keyboard-should-persist-taps :always
|
||||
@@ -329,9 +330,6 @@
|
||||
;;TODO(rasom) https://github.com/facebook/react-native/issues/30034
|
||||
:inverted (when platform/ios? true)
|
||||
:on-layout (fn [e]
|
||||
;; FIXME: this is due to Android not triggering the initial
|
||||
;; scrollTo event
|
||||
(scroll-to-offset 1)
|
||||
(let [layout-height (oops/oget e "nativeEvent.layout.height")]
|
||||
(reset! messages-view-height layout-height)))
|
||||
:scroll-enabled (not recording?)}]]))
|
||||
|
||||
@@ -96,4 +96,4 @@
|
||||
|
||||
(defn header-online
|
||||
[]
|
||||
{:color (colors/theme-colors colors/neutral-80-opa-50 colors/white-opa-50)})
|
||||
{:color (colors/theme-colors colors/neutral-80-opa-50 colors/white-opa-50)})
|
||||
|
||||
@@ -38,4 +38,4 @@
|
||||
(reanimated/apply-animations-to-style
|
||||
(when enabled?
|
||||
{:opacity animation})
|
||||
(pinned-banner top-offset)))
|
||||
(pinned-banner top-offset)))
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.home.actions.view :as actions]
|
||||
[status-im2.common.password-authentication.view :as password-authentication]
|
||||
[status-im2.common.scroll-page.view :as scroll-page]
|
||||
[status-im2.common.scroll-page.style :as scroll-page.style]
|
||||
[status-im2.common.scroll-page.view :as scroll-page]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.communities.actions.chat.view :as chat-actions]
|
||||
[status-im2.contexts.communities.actions.community-options.view :as options]
|
||||
[status-im2.contexts.communities.overview.style :as style]
|
||||
[status-im2.contexts.communities.overview.utils :as utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.contexts.communities.actions.chat.view :as chat-actions]))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn preview-user-list
|
||||
[user-list]
|
||||
@@ -48,6 +48,20 @@
|
||||
[event]
|
||||
(oops/oget event "nativeEvent.layout.y"))
|
||||
|
||||
(defn- channel-chat-item
|
||||
[community-id {chat-id :id muted? :muted? :as chat}]
|
||||
(let [sheet-content [actions/chat-actions
|
||||
(assoc chat :chat-type constants/community-chat-type)
|
||||
false]
|
||||
channel-sheet-data {:selected-item (fn [] [quo/channel-list-item chat])
|
||||
:content (fn [] sheet-content)}]
|
||||
[rn/view {:key chat-id :style {:margin-top 4}}
|
||||
[quo/channel-list-item
|
||||
(assoc chat
|
||||
:on-long-press #(rf/dispatch [:show-bottom-sheet channel-sheet-data])
|
||||
:muted? (or muted?
|
||||
(rf/sub [:chat/check-channel-muted? community-id chat-id])))]]))
|
||||
|
||||
(defn channel-list-component
|
||||
[{:keys [on-category-layout community-id on-first-channel-height-changed]}
|
||||
channels-list]
|
||||
@@ -57,48 +71,28 @@
|
||||
(int (Math/ceil (layout-y %))))
|
||||
(into #{} (map (comp :name second) channels-list)))
|
||||
:style {:margin-top 20 :flex 1}}
|
||||
(for [[category-id {:keys [chats name collapsed?]}] channels-list]
|
||||
[rn/view
|
||||
{:flex 1
|
||||
:key category-id
|
||||
;; on-layout fires only when the component re-renders, so
|
||||
;; in case the category hasn't changed, it will not be fired
|
||||
:on-layout #(on-category-layout name (int (layout-y %)))}
|
||||
(when-not (= constants/empty-category-id category-id)
|
||||
[quo/divider-label
|
||||
{:label name
|
||||
:on-press #(collapse-category
|
||||
community-id
|
||||
category-id
|
||||
collapsed?)
|
||||
:chevron-icon (if collapsed? :main-icons/chevron-right :main-icons/chevron-down)
|
||||
:padding-bottom (if collapsed? 7 0)
|
||||
:chevron-position :left}])
|
||||
(when-not collapsed?
|
||||
[rn/view
|
||||
{:style {:margin-left 8
|
||||
:margin-top 10
|
||||
:margin-bottom 8}}
|
||||
(for [{:keys [muted? id] :as chat} chats
|
||||
:let [chat (assoc chat
|
||||
:chat-type
|
||||
constants/community-chat-type)
|
||||
channel-muted? (or muted?
|
||||
(rf/sub [:chat/check-channel-muted?
|
||||
community-id id]))]]
|
||||
[rn/view
|
||||
{:key (:id chat)
|
||||
:style {:margin-top 4}}
|
||||
[quo/channel-list-item
|
||||
(assoc chat
|
||||
:muted?
|
||||
channel-muted?
|
||||
:on-long-press
|
||||
(fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [actions/chat-actions chat false])
|
||||
:selected-item (fn []
|
||||
[quo/channel-list-item chat])}])))]])])])])
|
||||
(doall
|
||||
(for [[category-id {:keys [chats name collapsed?]}] channels-list]
|
||||
[rn/view
|
||||
{:style {:flex 1}
|
||||
:key category-id
|
||||
;; on-layout fires only when the component re-renders, so
|
||||
;; in case the category hasn't changed, it will not be fired
|
||||
:on-layout #(on-category-layout name (int (layout-y %)))}
|
||||
(when-not (= constants/empty-category-id category-id)
|
||||
[quo/divider-label
|
||||
{:container-style {:padding-left 16
|
||||
:padding-right 20
|
||||
:padding-top 6 ; Because of border width of 1
|
||||
:padding-bottom 7}
|
||||
:label name
|
||||
:on-press #(collapse-category community-id category-id collapsed?)
|
||||
:chevron-icon (if collapsed? :i/chevron-right :i/chevron-down)
|
||||
:chevron-position :left}])
|
||||
(when-not collapsed?
|
||||
(into [rn/view {:style {:padding-horizontal 8 :padding-bottom 8}}]
|
||||
(map #(channel-chat-item community-id %))
|
||||
chats))]))])
|
||||
|
||||
(defn request-to-join-text
|
||||
[is-open?]
|
||||
@@ -208,7 +202,7 @@
|
||||
(defn status-tag
|
||||
[pending? joined]
|
||||
(when (or pending? joined)
|
||||
[rn/view {:position :absolute :top 12 :right 12}
|
||||
[rn/view {:style {:position :absolute :top 12 :right 12}}
|
||||
[quo/status-tag
|
||||
{:status {:type (if joined :positive :pending)}
|
||||
:label (if joined
|
||||
@@ -317,9 +311,8 @@
|
||||
(->> categories-heights
|
||||
(sort-by (comp - second))
|
||||
(some (fn [[category height]]
|
||||
(and
|
||||
(>= scroll-height (+ height first-channel-height))
|
||||
category)))))
|
||||
(and (>= scroll-height (+ height first-channel-height))
|
||||
category)))))
|
||||
|
||||
(defn community-card-page-view
|
||||
[]
|
||||
@@ -327,11 +320,11 @@
|
||||
first-channel-height (reagent/atom 0)
|
||||
scroll-height (reagent/atom 0)]
|
||||
(fn [id]
|
||||
(let [{:keys [name images id] :as community}
|
||||
(rf/sub [:communities/community id])
|
||||
pending? (rf/sub [:communities/my-pending-request-to-join id])
|
||||
cover {:uri (get-in images [:banner :uri])}
|
||||
logo {:uri (get-in images [:thumbnail :uri])}]
|
||||
(let [{:keys [name images id]
|
||||
:as community} (rf/sub [:communities/community id])
|
||||
pending? (rf/sub [:communities/my-pending-request-to-join id])
|
||||
cover {:uri (get-in images [:banner :uri])}
|
||||
logo {:uri (get-in images [:thumbnail :uri])}]
|
||||
[scroll-page/scroll-page
|
||||
{:cover-image cover
|
||||
:logo logo
|
||||
@@ -362,8 +355,7 @@
|
||||
(defn overview
|
||||
[id]
|
||||
(let [id (or id (rf/sub [:get-screen-params :community-overview]))]
|
||||
[rn/view
|
||||
{:style style/community-overview-container}
|
||||
[rn/view {:style style/community-overview-container}
|
||||
[community-card-page-view id]
|
||||
[floating-shell-button/floating-shell-button
|
||||
{:jump-to {:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
{:background-color colors/neutral-95
|
||||
:flex-direction :row
|
||||
:position :absolute
|
||||
:overflow :hidden
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0
|
||||
|
||||
@@ -187,54 +187,44 @@
|
||||
(defn create-password-doc
|
||||
[]
|
||||
[quo/documentation-drawers
|
||||
{:title (i18n/label
|
||||
:t/create-profile-password-info-box-title)
|
||||
{:title (i18n/label :t/create-profile-password-info-box-title)
|
||||
:shell? true}
|
||||
[rn/view
|
||||
[quo/text
|
||||
{:size :paragraph-2}
|
||||
(i18n/label
|
||||
:t/create-profile-password-info-box-description)]]])
|
||||
|
||||
(defn- f-create-password
|
||||
[]
|
||||
(let [keyboard-shown? (reagent/atom false)
|
||||
{:keys [top bottom]} (safe-area/get-insets)]
|
||||
(fn []
|
||||
(rn/use-effect
|
||||
(let [will-show-listener (ocall rn/keyboard
|
||||
"addListener"
|
||||
"keyboardWillShow"
|
||||
#(reset! keyboard-shown? true))
|
||||
will-hide-listener (ocall rn/keyboard
|
||||
"addListener"
|
||||
"keyboardWillHide"
|
||||
#(reset! keyboard-shown? false))]
|
||||
(fn []
|
||||
(fn []
|
||||
(ocall will-show-listener "remove")
|
||||
(ocall will-hide-listener "remove"))))
|
||||
[])
|
||||
[rn/touchable-without-feedback
|
||||
{:on-press rn/dismiss-keyboard!
|
||||
:accessible false}
|
||||
[rn/view {:style style/flex-fill}
|
||||
[rn/keyboard-avoiding-view {:style style/flex-fill}
|
||||
[navigation-bar/navigation-bar
|
||||
{:top top
|
||||
:right-section-buttons [{:type :blur-bg
|
||||
:icon :i/info
|
||||
:icon-override-theme :dark
|
||||
:on-press (fn []
|
||||
(rn/dismiss-keyboard!)
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content create-password-doc
|
||||
:shell? true}]))}]}]
|
||||
[password-form]
|
||||
[rn/view {:style {:height (if-not @keyboard-shown? bottom 0)}}]]]])))
|
||||
[quo/text {:size :paragraph-2}
|
||||
(i18n/label :t/create-profile-password-info-box-description)]]])
|
||||
|
||||
(defn create-password
|
||||
[]
|
||||
[:<>
|
||||
[background/view true]
|
||||
[:f> f-create-password]])
|
||||
(reagent/with-let [keyboard-shown? (reagent/atom false)
|
||||
{:keys [top bottom]} (safe-area/get-insets)
|
||||
will-show-listener (ocall rn/keyboard
|
||||
"addListener"
|
||||
"keyboardWillShow"
|
||||
#(reset! keyboard-shown? true))
|
||||
will-hide-listener (ocall rn/keyboard
|
||||
"addListener"
|
||||
"keyboardWillHide"
|
||||
#(reset! keyboard-shown? false))
|
||||
on-press-info (fn []
|
||||
(rn/dismiss-keyboard!)
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content create-password-doc
|
||||
:shell? true}]))]
|
||||
[:<>
|
||||
[background/view true]
|
||||
[rn/touchable-without-feedback
|
||||
{:on-press rn/dismiss-keyboard!
|
||||
:accessible false}
|
||||
[rn/view {:style style/flex-fill}
|
||||
[rn/keyboard-avoiding-view {:style style/flex-fill}
|
||||
[navigation-bar/navigation-bar
|
||||
{:top top
|
||||
:right-section-buttons [{:type :blur-bg
|
||||
:icon :i/info
|
||||
:icon-override-theme :dark
|
||||
:on-press on-press-info}]}]
|
||||
[password-form]
|
||||
[rn/view {:style {:height (if-not @keyboard-shown? bottom 0)}}]]]]]
|
||||
(finally
|
||||
(ocall will-show-listener "remove")
|
||||
(ocall will-hide-listener "remove"))))
|
||||
|
||||
@@ -120,8 +120,7 @@
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:override-theme :dark
|
||||
:content
|
||||
{:content
|
||||
(fn []
|
||||
[method-menu/view on-change-profile-pic])}]))
|
||||
:image-picker-props {:profile-picture (when @profile-pic {:uri @profile-pic})
|
||||
|
||||
@@ -4,23 +4,34 @@
|
||||
[utils.re-frame :as rf]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.contexts.onboarding.intro.style :as style]
|
||||
[status-im2.contexts.onboarding.common.background.view :as background]))
|
||||
[status-im2.contexts.onboarding.common.background.view :as background]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.syncing.scan-sync-code.view :as scan-sync-code]
|
||||
[utils.debounce :as debounce]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
[rn/view {:style style/page-container}
|
||||
[background/view false]
|
||||
[quo/drawer-buttons
|
||||
{:top-card {:on-press (fn []
|
||||
(rf/dispatch [:navigate-to :sign-in])
|
||||
(rf/dispatch [:hide-terms-of-services-opt-in-screen]))
|
||||
:heading (i18n/label :t/sign-in)
|
||||
:accessibility-label :already-use-status-button}
|
||||
:bottom-card {:on-press (fn []
|
||||
(rf/dispatch [:navigate-to :new-to-status])
|
||||
(rf/dispatch [:hide-terms-of-services-opt-in-screen]))
|
||||
:heading (i18n/label :t/new-to-status)
|
||||
:accessibility-label :new-to-status-button}}
|
||||
{:on-init (fn [reset-top-animation-fn]
|
||||
(reset! scan-sync-code/dismiss-animations reset-top-animation-fn))
|
||||
:animations-duration constants/onboarding-modal-animation-duration
|
||||
:animations-delay constants/onboarding-modal-animation-delay
|
||||
:top-card {:on-press (fn []
|
||||
(debounce/dispatch-and-chill [:open-modal
|
||||
:sign-in-intro]
|
||||
2000)
|
||||
(rf/dispatch [:hide-terms-of-services-opt-in-screen]))
|
||||
:heading (i18n/label :t/sign-in)
|
||||
:animated-heading (i18n/label :t/sign-in-by-syncing)
|
||||
:accessibility-label :already-use-status-button}
|
||||
:bottom-card {:on-press (fn []
|
||||
(rf/dispatch [:navigate-to :new-to-status])
|
||||
(rf/dispatch
|
||||
[:hide-terms-of-services-opt-in-screen]))
|
||||
:heading (i18n/label :t/new-to-status)
|
||||
:accessibility-label :new-to-status-button}}
|
||||
[quo/text
|
||||
{:style style/plain-text}
|
||||
(i18n/label :t/you-already-use-status)]
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
:accessibility-label :create-new-profile}
|
||||
{:icon :i/multi-profile
|
||||
:label (i18n/label :t/add-existing-status-profile)
|
||||
:on-press #(rf/dispatch [:navigate-to :sign-in])
|
||||
:on-press #(rf/dispatch [:open-modal :sign-in])
|
||||
:accessibility-label :multi-profile}]]])
|
||||
|
||||
(defn show-new-account-options
|
||||
@@ -138,7 +138,7 @@
|
||||
[quo/text {:size :paragraph-2} (i18n/label :t/forgot-your-password-info-description)]
|
||||
|
||||
[rn/view {:style style/forget-password-step-container}
|
||||
[quo/step {:in-blur-view? true :override-theme :dark} 1]
|
||||
[quo/step {:in-blur-view? true} 1]
|
||||
[rn/view
|
||||
{:style style/forget-password-step-content}
|
||||
[quo/text {:size :paragraph-2 :weight :semi-bold}
|
||||
@@ -146,7 +146,7 @@
|
||||
[quo/text {:size :paragraph-2} (i18n/label :t/forgot-your-password-info-remove-app-description)]]]
|
||||
|
||||
[rn/view {:style style/forget-password-step-container}
|
||||
[quo/step {:in-blur-view? true :override-theme :dark} 2]
|
||||
[quo/step {:in-blur-view? true} 2]
|
||||
[rn/view
|
||||
{:style style/forget-password-step-content}
|
||||
[quo/text {:size :paragraph-2 :weight :semi-bold}
|
||||
@@ -155,7 +155,7 @@
|
||||
(i18n/label :t/forgot-your-password-info-reinstall-app-description)]]]
|
||||
|
||||
[rn/view {:style style/forget-password-step-container}
|
||||
[quo/step {:in-blur-view? true :override-theme :dark} 3]
|
||||
[quo/step {:in-blur-view? true} 3]
|
||||
[rn/view
|
||||
{:style style/forget-password-step-content}
|
||||
[rn/view
|
||||
@@ -167,7 +167,7 @@
|
||||
(i18n/label :t/forgot-your-password-info-signup-with-key-description)]]]
|
||||
|
||||
[rn/view {:style style/forget-password-step-container}
|
||||
[quo/step {:in-blur-view? true :override-theme :dark} 4]
|
||||
[quo/step {:in-blur-view? true} 4]
|
||||
[rn/view
|
||||
{:style style/forget-password-step-content}
|
||||
[quo/text {:size :paragraph-2 :weight :semi-bold}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user