Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41cf687b3f | ||
|
|
a8303dbe50 | ||
|
|
43cba161d6 | ||
|
|
ce08131c01 | ||
|
|
4f044765e1 | ||
|
|
7cd9f76043 | ||
|
|
238e35a281 | ||
|
|
57c538e9d0 | ||
|
|
e49a3ab5cd |
@@ -20,7 +20,15 @@
|
||||
;; future, as we progressively fix shadowed
|
||||
;; vars, we should be able to delete this
|
||||
;; option and lint all vars.
|
||||
:include [count iter key time]}
|
||||
:include [comparator
|
||||
count
|
||||
identity
|
||||
iter
|
||||
key
|
||||
str
|
||||
symbol
|
||||
time
|
||||
val]}
|
||||
:invalid-arity {:skip-args [status-im.utils.fx/defn utils.re-frame/defn]}
|
||||
;; TODO remove number when this is fixed
|
||||
;; https://github.com/borkdude/clj-kondo/issues/867
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name: MVPBug Report
|
||||
about: MVPBug Report
|
||||
title: ''
|
||||
labels: E:MobileBugfixesMVP
|
||||
labels: 'E:Mobile Bugfixes MVP'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@
|
||||
"react-native-camera-kit": "^13.0.0",
|
||||
"react-native-config": "^1.5.0",
|
||||
"react-native-dialogs": "^1.0.4",
|
||||
"react-native-draggable-flatlist": "^3.0.3",
|
||||
"react-native-draggable-flatlist": "^4.0.1",
|
||||
"react-native-fast-image": "^8.5.11",
|
||||
"react-native-fetch-polyfill": "^1.1.2",
|
||||
"react-native-fs": "^2.14.1",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 421 KiB |
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Please provide the full branch URL as an argument."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$2" ]; then
|
||||
echo "Please provide the full pull request URL as second argument."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract PR number from the URL
|
||||
PR_URL="$2"
|
||||
PR_NUMBER=$(echo "$PR_URL" | awk -F '/' '{print $NF}')
|
||||
|
||||
# Fetch PR Info
|
||||
PR_TITLE=$(gh pr view "$PR_NUMBER" --json title -q '.title')
|
||||
PR_DESCRIPTION=$(gh pr view "$PR_NUMBER" --json body -q '.body')
|
||||
BRANCH_NAME=$(gh pr view "$PR_NUMBER" --json headRefName -q '.headRefName')
|
||||
|
||||
# Extracting the repo URL and branch name
|
||||
FULL_URL="$1"
|
||||
REPO_URL=$(echo "$FULL_URL" | awk -F "/tree/" '{print $1}')
|
||||
REPO_NAME=$(basename "$REPO_URL")
|
||||
NEW_REMOTE_URL="https://github.com/status-im/status-mobile"
|
||||
|
||||
# Clone the repo if not already cloned
|
||||
if [ ! -d "$REPO_NAME" ]; then
|
||||
git clone "$REPO_URL"
|
||||
cd "$REPO_NAME" || exit
|
||||
gh repo set-default "$REPO_URL"
|
||||
else
|
||||
cd "$REPO_NAME" || exit
|
||||
gh repo set-default "$REPO_URL"
|
||||
git fetch
|
||||
fi
|
||||
|
||||
# Check if branch already exists
|
||||
BRANCH_EXISTS=$(git show-ref refs/heads/"$BRANCH_NAME" 2>/dev/null)
|
||||
|
||||
if [ -z "$BRANCH_EXISTS" ]; then
|
||||
# New Import
|
||||
git checkout -b "$BRANCH_NAME" "origin/$BRANCH_NAME"
|
||||
git remote add source "$REPO_URL"
|
||||
git remote set-url origin $NEW_REMOTE_URL
|
||||
git push -u origin "$BRANCH_NAME"
|
||||
gh pr create --base develop --head "$BRANCH_NAME" --title "[IMPORTED] $PR_TITLE" --body "$PR_DESCRIPTION"
|
||||
else
|
||||
# Sync Existing Import
|
||||
git checkout "$BRANCH_NAME"
|
||||
git fetch source "$BRANCH_NAME"
|
||||
git rebase source/"$BRANCH_NAME" # Rebase instead of merge
|
||||
git push origin "$BRANCH_NAME" # Push updates to your imported branch
|
||||
fi
|
||||
@@ -461,19 +461,19 @@
|
||||
(.numberToHex ^js (status) (str num)))
|
||||
|
||||
(defn sha3
|
||||
[str]
|
||||
[s]
|
||||
(log/debug "[native-module] sha3")
|
||||
(.sha3 ^js (status) str))
|
||||
(.sha3 ^js (status) s))
|
||||
|
||||
(defn utf8-to-hex
|
||||
[str]
|
||||
[s]
|
||||
(log/debug "[native-module] utf8-to-hex")
|
||||
(.utf8ToHex ^js (status) str))
|
||||
(.utf8ToHex ^js (status) s))
|
||||
|
||||
(defn hex-to-utf8
|
||||
[str]
|
||||
[s]
|
||||
(log/debug "[native-module] hex-to-utf8")
|
||||
(.hexToUtf8 ^js (status) str))
|
||||
(.hexToUtf8 ^js (status) s))
|
||||
|
||||
(defn check-address-checksum
|
||||
[address]
|
||||
|
||||
+14
-14
@@ -82,8 +82,8 @@
|
||||
:restDisplacementThreshold 0.001}})
|
||||
|
||||
(defn set-value
|
||||
[anim val]
|
||||
(ocall anim "setValue" val))
|
||||
[anim v]
|
||||
(ocall anim "setValue" v))
|
||||
|
||||
(def Value (oget animated "Value"))
|
||||
|
||||
@@ -178,20 +178,20 @@
|
||||
(.withOffset ^js redash (clj->js config)))
|
||||
|
||||
(defn with-spring-transition
|
||||
[val config]
|
||||
(.withSpringTransition ^js redash val (clj->js config)))
|
||||
[v config]
|
||||
(.withSpringTransition ^js redash v (clj->js config)))
|
||||
|
||||
(defn with-timing-transition
|
||||
[val config]
|
||||
(.withTimingTransition ^js redash val (clj->js config)))
|
||||
[v config]
|
||||
(.withTimingTransition ^js redash v (clj->js config)))
|
||||
|
||||
(defn use-spring-transition
|
||||
[val config]
|
||||
(.useSpringTransition ^js redash val (clj->js config)))
|
||||
[v config]
|
||||
(.useSpringTransition ^js redash v (clj->js config)))
|
||||
|
||||
(defn use-timing-transition
|
||||
[val config]
|
||||
(.useTimingTransition ^js redash val (clj->js config)))
|
||||
[v config]
|
||||
(.useTimingTransition ^js redash v (clj->js config)))
|
||||
|
||||
(defn re-timing
|
||||
[config]
|
||||
@@ -232,11 +232,11 @@
|
||||
:onGestureEvent (.-onGestureEvent ^js gesture)}))
|
||||
|
||||
(defn snap-point
|
||||
[value velocity snap-points]
|
||||
(.snapPoint ^js redash value velocity (to-array snap-points)))
|
||||
[v velocity snap-points]
|
||||
(.snapPoint ^js redash v velocity (to-array snap-points)))
|
||||
|
||||
(defn with-easing
|
||||
[{val :value
|
||||
[{v :value
|
||||
:keys [snap-points velocity offset state easing duration
|
||||
animation-over]
|
||||
:or {duration 250
|
||||
@@ -257,7 +257,7 @@
|
||||
(set position offset))
|
||||
(cond* (neq state (:end gh/states))
|
||||
[(set animation-over 0)
|
||||
(set position (add offset val))])
|
||||
(set position (add offset v))])
|
||||
(cond* (and* (eq state (:end gh/states))
|
||||
(not* animation-over))
|
||||
[(set position
|
||||
|
||||
+5
-5
@@ -12,9 +12,9 @@
|
||||
|
||||
;; Inspired from UIX, Rum and Rumext
|
||||
(defn set-ref-val!
|
||||
[ref val]
|
||||
(oset! ref "current" val)
|
||||
val)
|
||||
[ref v]
|
||||
(oset! ref "current" v)
|
||||
v)
|
||||
|
||||
(defn set-native-props
|
||||
[^js ref ^js props]
|
||||
@@ -54,8 +54,8 @@
|
||||
#js [value set-value])))
|
||||
|
||||
(defn use-ref
|
||||
[val]
|
||||
(let [ref (react/useRef val)]
|
||||
[v]
|
||||
(let [ref (react/useRef v)]
|
||||
(reify
|
||||
cljs.core/IHash
|
||||
(-hash [_] (goog/getUid ref))
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
{:style (style/token-row padding?)}
|
||||
(doall
|
||||
(map-indexed (fn [token-index token]
|
||||
(let [{:keys [img-src symbol amount sufficient? purchasable? loading?]} token]
|
||||
(let [{:keys [img-src amount sufficient? purchasable? loading?]} token]
|
||||
^{:key token-index}
|
||||
[rn/view {:style style/token-tag-spacing}
|
||||
[token-tag/token-tag
|
||||
{:symbol symbol
|
||||
{:symbol (:symbol token)
|
||||
:value amount
|
||||
:size 24
|
||||
:sufficient? sufficient?
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
:margin-bottom (+ (safe-area/get-bottom) 8)})
|
||||
|
||||
(defn title
|
||||
[shell?]
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/neutral-100
|
||||
colors/white
|
||||
(when shell? :dark))})
|
||||
theme)})
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
[quo2.components.drawers.documentation-drawers.style :as style]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]))
|
||||
[react-native.gesture :as gesture]
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(defn view
|
||||
(defn- view-internal
|
||||
"Options
|
||||
- `title` Title text
|
||||
- `show-button?` Show button
|
||||
@@ -15,7 +16,7 @@
|
||||
- `shell?` use shell theme
|
||||
`content` Content of the drawer
|
||||
"
|
||||
[{:keys [title show-button? on-press-button button-label button-icon shell?]} content]
|
||||
[{:keys [title show-button? on-press-button button-label button-icon theme shell?]} content]
|
||||
[gesture/scroll-view
|
||||
{:style style/outer-container
|
||||
:always-bounce-vertical false
|
||||
@@ -24,18 +25,18 @@
|
||||
[text/text
|
||||
{:size :heading-2
|
||||
:accessibility-label :documentation-drawer-title
|
||||
:style (style/title shell?)
|
||||
:style (style/title theme)
|
||||
:weight :semi-bold}
|
||||
title]
|
||||
[rn/view {:style style/content :accessibility-label :documentation-drawer-content}
|
||||
content]
|
||||
(when show-button?
|
||||
[button/button
|
||||
(cond-> {:size 24
|
||||
:type (if shell? :blur-bg-outline :outline)
|
||||
:on-press on-press-button
|
||||
:accessibility-label :documentation-drawer-button
|
||||
:after button-icon}
|
||||
shell? (assoc :override-theme :dark))
|
||||
{:size 24
|
||||
:type (if shell? :blur-bg-outline :outline)
|
||||
:on-press on-press-button
|
||||
:accessibility-label :documentation-drawer-button
|
||||
:after button-icon}
|
||||
button-label])]])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -3,62 +3,62 @@
|
||||
[quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn variants-colors
|
||||
[blur? override-theme]
|
||||
[blur? theme]
|
||||
(if blur?
|
||||
{:label (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 override-theme)
|
||||
:icon (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 override-theme)
|
||||
:button-border (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 override-theme)
|
||||
:password-icon (colors/theme-colors colors/neutral-100 colors/white-opa-70 override-theme)
|
||||
:clear-icon (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 override-theme)
|
||||
{:label (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
:icon (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
|
||||
:button-border (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 theme)
|
||||
:password-icon (colors/theme-colors colors/neutral-100 colors/white-opa-70 theme)
|
||||
:clear-icon (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 theme)
|
||||
:cursor (colors/theme-colors (colors/custom-color :blue 50)
|
||||
colors/white
|
||||
override-theme)}
|
||||
{:label (colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)
|
||||
:icon (colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)
|
||||
:button-border (colors/theme-colors colors/neutral-30 colors/neutral-70 override-theme)
|
||||
:clear-icon (colors/theme-colors colors/neutral-40 colors/neutral-60 override-theme)
|
||||
:password-icon (colors/theme-colors colors/neutral-50 colors/white override-theme)
|
||||
theme)}
|
||||
{:label (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:icon (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:button-border (colors/theme-colors colors/neutral-30 colors/neutral-70 theme)
|
||||
:clear-icon (colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
|
||||
:password-icon (colors/theme-colors colors/neutral-50 colors/white theme)
|
||||
:cursor (colors/theme-colors (colors/custom-color :blue 50)
|
||||
(colors/custom-color :blue 60)
|
||||
override-theme)}))
|
||||
theme)}))
|
||||
|
||||
(defn status-colors
|
||||
[status blur? override-theme]
|
||||
[status blur? theme]
|
||||
(if blur?
|
||||
(case status
|
||||
:focus
|
||||
{:border-color (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-40 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white override-theme)}
|
||||
{:border-color (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-40 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)}
|
||||
:error
|
||||
{:border-color (colors/theme-colors colors/danger-opa-40 colors/danger-opa-40 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white override-theme)}
|
||||
{:border-color (colors/theme-colors colors/danger-opa-40 colors/danger-opa-40 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)}
|
||||
:disabled
|
||||
{:border-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-20 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-20 override-theme)}
|
||||
{:border-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-20 theme)
|
||||
:text (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-20 theme)}
|
||||
;; :default
|
||||
{:border-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white override-theme)})
|
||||
{:border-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)})
|
||||
(case status
|
||||
:focus
|
||||
{:border-color (colors/theme-colors colors/neutral-40 colors/neutral-60 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-30 colors/neutral-60 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white override-theme)}
|
||||
{:border-color (colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-30 colors/neutral-60 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)}
|
||||
:error
|
||||
{:border-color (colors/theme-colors colors/danger-opa-40 colors/danger-opa-40 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-40 colors/white-opa-40 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white override-theme)}
|
||||
{:border-color (colors/theme-colors colors/danger-opa-40 colors/danger-opa-40 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-40 colors/white-opa-40 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)}
|
||||
:disabled
|
||||
{:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-40 colors/neutral-40 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-40 colors/neutral-40 override-theme)}
|
||||
{:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-40 colors/neutral-40 theme)
|
||||
:text (colors/theme-colors colors/neutral-40 colors/neutral-40 theme)}
|
||||
;; :default
|
||||
{:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white override-theme)})))
|
||||
{:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)})))
|
||||
|
||||
(defn input-container
|
||||
[colors-by-status small? disabled?]
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
[quo2.components.markdown.text :as text]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[quo2.theme :as theme]))
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(defn- label-&-counter
|
||||
[{:keys [label current-chars char-limit variant-colors]}]
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
(def ^:private custom-props
|
||||
"Custom properties that must be removed from properties map passed to InputText."
|
||||
[:type :blur? :override-theme :error? :right-icon :left-icon :disabled? :small? :button
|
||||
[:type :blur? :theme :error? :right-icon :left-icon :disabled? :small? :button
|
||||
:label :char-limit :on-char-limit-reach :icon-name :multiline? :on-focus :on-blur])
|
||||
|
||||
(defn- base-input
|
||||
@@ -74,15 +74,15 @@
|
||||
(reset! char-count amount-chars)
|
||||
(when (>= amount-chars char-limit)
|
||||
(on-char-limit-reach amount-chars))))]
|
||||
(fn [{:keys [blur? override-theme error? right-icon left-icon disabled? small? button
|
||||
(fn [{:keys [blur? theme error? right-icon left-icon disabled? small? button
|
||||
label char-limit multiline? clearable? on-focus on-blur]
|
||||
:as props}]
|
||||
(let [status-kw (cond
|
||||
disabled? :disabled
|
||||
error? :error
|
||||
:else @status)
|
||||
colors-by-status (style/status-colors status-kw blur? override-theme)
|
||||
variant-colors (style/variants-colors blur? override-theme)
|
||||
colors-by-status (style/status-colors status-kw blur? theme)
|
||||
variant-colors (style/variants-colors blur? theme)
|
||||
clean-props (apply dissoc props custom-props)]
|
||||
[:<>
|
||||
(when (or label char-limit)
|
||||
@@ -101,7 +101,7 @@
|
||||
(cond-> {:style (style/input colors-by-status small? @multiple-lines?)
|
||||
:accessibility-label :input
|
||||
:placeholder-text-color (:placeholder colors-by-status)
|
||||
:keyboard-appearance (theme/theme-value :light :dark override-theme)
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
:cursor-color (:cursor variant-colors)
|
||||
:editable (not disabled?)
|
||||
:on-focus (fn []
|
||||
@@ -148,11 +148,11 @@
|
||||
:icon-name (if @password-shown? :i/hide :i/reveal)
|
||||
:on-press #(swap! password-shown? not)})])))
|
||||
|
||||
(defn input
|
||||
(defn input-internal
|
||||
"This input supports the following properties:
|
||||
- :type - Can be `:text`(default) or `:password`.
|
||||
- :blur? - Boolean to set the blur color variant.
|
||||
- :override-theme - Can be `light` or `:dark`.
|
||||
- :theme - Can be `light` or `:dark`.
|
||||
- :small? - Boolean to specify if this input is rendered in its small version.
|
||||
- :multiline? - Boolean to specify if this input support multiple lines.
|
||||
- :icon-name - The name of an icon to display at the left of the input.
|
||||
@@ -188,3 +188,5 @@
|
||||
(if (= type :password)
|
||||
[password-input base-props]
|
||||
[base-input base-props])))
|
||||
|
||||
(def input (quo.theme/with-theme input-internal))
|
||||
|
||||
@@ -17,29 +17,29 @@
|
||||
:text-align-vertical :top))
|
||||
|
||||
(defn placeholder-color
|
||||
[input-state override-theme blur?]
|
||||
[input-state theme blur?]
|
||||
(cond
|
||||
(and (= input-state :focused) blur?)
|
||||
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 override-theme)
|
||||
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
|
||||
|
||||
(= input-state :focused) ; Not blur
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-60 override-theme)
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme)
|
||||
|
||||
blur? ; :default & blur
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30 override-theme)
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30 theme)
|
||||
|
||||
:else ; :default & not blur
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)))
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
|
||||
|
||||
(defn cursor-color
|
||||
[customization-color override-theme]
|
||||
[customization-color theme]
|
||||
(colors/theme-colors (colors/custom-color customization-color 50)
|
||||
(colors/custom-color customization-color 60)
|
||||
override-theme))
|
||||
theme))
|
||||
|
||||
(defn error-word
|
||||
[]
|
||||
[theme]
|
||||
{:height 22
|
||||
:padding-horizontal 20
|
||||
:background-color colors/danger-50-opa-10
|
||||
:color (colors/theme-colors colors/danger-50 colors/danger-60)})
|
||||
:color (colors/theme-colors colors/danger-50 colors/danger-60 theme)})
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
[quo2.components.inputs.recovery-phrase.style :as style]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[quo2.theme :as theme]))
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(def ^:private custom-props
|
||||
[:customization-color :override-theme :blur? :cursor-color :multiline :on-focus :on-blur
|
||||
[:customization-color :theme :blur? :cursor-color :multiline :on-focus :on-blur
|
||||
:placeholder-text-color :mark-errors? :error-pred :word-limit])
|
||||
|
||||
(defn- error-word
|
||||
[text]
|
||||
[rn/text {:style (style/error-word)}
|
||||
[text theme]
|
||||
[rn/text {:style (style/error-word theme)}
|
||||
text])
|
||||
|
||||
(defn- mark-error-words
|
||||
[pred-last-word pred-previous-words text word-limit]
|
||||
[{:keys [pred-last-word pred-previous-words text word-limit theme]}]
|
||||
(let [last-index (dec (count (string/split text #"\s+")))
|
||||
words (map #(apply str %)
|
||||
(partition-by #(= " " %) text))]
|
||||
@@ -31,18 +31,18 @@
|
||||
:always (update :result
|
||||
conj
|
||||
(if invalid-word?
|
||||
[error-word word]
|
||||
[error-word word theme]
|
||||
word)))))
|
||||
{:result [:<>]
|
||||
:idx 0})
|
||||
:result)))
|
||||
|
||||
(defn recovery-phrase-input
|
||||
(defn recovery-phrase-input-internal
|
||||
[_ _]
|
||||
(let [state (reagent/atom :default)
|
||||
set-focused #(reset! state :focused)
|
||||
set-default #(reset! state :default)]
|
||||
(fn [{:keys [customization-color override-theme blur? on-focus on-blur mark-errors?
|
||||
(fn [{:keys [customization-color theme blur? on-focus on-blur mark-errors?
|
||||
error-pred-current-word error-pred-written-words word-limit]
|
||||
:or {customization-color :blue
|
||||
word-limit ##Inf
|
||||
@@ -55,9 +55,9 @@
|
||||
[rn/text-input
|
||||
(merge {:accessibility-label :recovery-phrase-input
|
||||
:style (style/input)
|
||||
:placeholder-text-color (style/placeholder-color @state override-theme blur?)
|
||||
:cursor-color (style/cursor-color customization-color override-theme)
|
||||
:keyboard-appearance (theme/theme-value :light :dark override-theme)
|
||||
:placeholder-text-color (style/placeholder-color @state theme blur?)
|
||||
:cursor-color (style/cursor-color customization-color theme)
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
:multiline true
|
||||
:on-focus (fn []
|
||||
(set-focused)
|
||||
@@ -67,5 +67,11 @@
|
||||
(when on-blur (on-blur)))}
|
||||
extra-props)
|
||||
(if mark-errors?
|
||||
(mark-error-words error-pred-current-word error-pred-written-words text word-limit)
|
||||
(mark-error-words {:pred-last-word error-pred-current-word
|
||||
:pred-previous-words error-pred-written-words
|
||||
:text text
|
||||
:word-limit word-limit
|
||||
:theme theme})
|
||||
text)]]))))
|
||||
|
||||
(def recovery-phrase-input (quo.theme/with-theme recovery-phrase-input-internal))
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[react-native.hole-view :as hole-view]))
|
||||
[react-native.hole-view :as hole-view]
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(def params
|
||||
{32 {:border-radius {:circular 16 :rounded 10}
|
||||
@@ -61,13 +62,13 @@
|
||||
[avatar item type size border-radius]]))
|
||||
|
||||
(defn get-overflow-color
|
||||
[transparent? transparent-color light-color dark-color override-theme]
|
||||
[transparent? transparent-color light-color dark-color theme]
|
||||
(if transparent?
|
||||
transparent-color
|
||||
(colors/theme-colors light-color dark-color override-theme)))
|
||||
(colors/theme-colors light-color dark-color theme)))
|
||||
|
||||
(defn overflow-label
|
||||
[label size transparent? border-radius margin-left override-theme more-than-99-label]
|
||||
[{:keys [label size transparent? border-radius margin-left theme more-than-99-label]}]
|
||||
[rn/view
|
||||
{:style {:width size
|
||||
:height size
|
||||
@@ -80,7 +81,7 @@
|
||||
colors/white-opa-10
|
||||
colors/neutral-20
|
||||
colors/neutral-70
|
||||
override-theme)}}
|
||||
theme)}}
|
||||
(if (= size 16)
|
||||
[quo2.icons/icon :i/more
|
||||
{:size 12
|
||||
@@ -89,7 +90,7 @@
|
||||
colors/white-opa-70
|
||||
colors/neutral-50
|
||||
colors/neutral-40
|
||||
override-theme)}]
|
||||
theme)}]
|
||||
[quo2.text/text
|
||||
{:size (if (= size 32) :paragraph-2 :label)
|
||||
:weight :medium
|
||||
@@ -98,7 +99,7 @@
|
||||
colors/white-opa-70
|
||||
colors/neutral-60
|
||||
colors/neutral-40
|
||||
override-theme)
|
||||
theme)
|
||||
:margin-left -2}}
|
||||
;; If overflow label is below 100, show label as +label (ex. +30), else just show 99+
|
||||
(if (< label 100)
|
||||
@@ -111,7 +112,7 @@
|
||||
(:account :collectible :photo) :rounded
|
||||
:circular))
|
||||
|
||||
(defn preview-list
|
||||
(defn- preview-list-internal
|
||||
"[preview-list opts items]
|
||||
opts
|
||||
{:type :user/:community/:account/:token/:collectible/:dapp
|
||||
@@ -120,7 +121,7 @@
|
||||
:transparent? overflow-label transparent?}
|
||||
items preview list items (only 4 items is required for preview)
|
||||
"
|
||||
[{:keys [type size list-size transparent? override-theme more-than-99-label]} items]
|
||||
[{:keys [type size list-size transparent? theme more-than-99-label]} items]
|
||||
(let [items-arr (into [] items)
|
||||
list-size (or list-size (count items))
|
||||
margin-left (get-in params [size :margin-left])
|
||||
@@ -135,5 +136,13 @@
|
||||
[list-item index type size (get items-arr index) list-size
|
||||
margin-left hole-size hole-radius hole-x hole-y border-radius])
|
||||
(when (> list-size 4)
|
||||
[overflow-label (- list-size 3) size transparent? border-radius margin-left override-theme
|
||||
more-than-99-label])]))
|
||||
[overflow-label
|
||||
{:label (- list-size 3)
|
||||
:size size
|
||||
:transparent? transparent?
|
||||
:border-radius border-radius
|
||||
:margin-left margin-left
|
||||
:theme theme
|
||||
:more-than-99-label more-than-99-label}])]))
|
||||
|
||||
(def preview-list (quo.theme/with-theme preview-list-internal))
|
||||
|
||||
@@ -82,11 +82,12 @@
|
||||
:border-radius 50}])
|
||||
|
||||
(defn timestamp
|
||||
[str]
|
||||
[s]
|
||||
[text/text
|
||||
{:size :label
|
||||
:style {:text-transform :none
|
||||
:color (get-color :time)}} str])
|
||||
:color (get-color :time)}}
|
||||
s])
|
||||
|
||||
(defn info-button
|
||||
[on-press]
|
||||
|
||||
@@ -25,11 +25,12 @@
|
||||
(def message-body
|
||||
{:color colors/white})
|
||||
|
||||
(def message-container
|
||||
(defn message-container
|
||||
[attachment]
|
||||
{:border-radius 12
|
||||
:margin-top 12
|
||||
:padding-horizontal 12
|
||||
:padding-vertical 8
|
||||
:padding-vertical (if (#{:photo :gif} attachment) 12 8)
|
||||
:background-color colors/white-opa-5})
|
||||
|
||||
(def footer-container
|
||||
|
||||
@@ -74,8 +74,8 @@
|
||||
context))))
|
||||
|
||||
(defn- activity-message
|
||||
[{:keys [title body title-number-of-lines body-number-of-lines]}]
|
||||
[rn/view {:style style/message-container}
|
||||
[{:keys [title body title-number-of-lines body-number-of-lines attachment]}]
|
||||
[rn/view {:style (style/message-container attachment)}
|
||||
(when title
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
:padding 6})
|
||||
|
||||
(defn container-border-color
|
||||
[pressed? blur? override-theme]
|
||||
(let [dark? (= :dark override-theme)]
|
||||
[pressed? blur? theme]
|
||||
(let [dark? (= :dark theme)]
|
||||
(cond
|
||||
(and (not pressed?) (not dark?) (not blur?))
|
||||
colors/neutral-20
|
||||
@@ -35,26 +35,24 @@
|
||||
nil)))
|
||||
|
||||
(defn container-background-color
|
||||
[pressed? override-theme]
|
||||
[pressed? theme]
|
||||
(when pressed?
|
||||
(if (= :dark override-theme)
|
||||
colors/primary-60
|
||||
colors/primary-50)))
|
||||
(colors/theme-colors colors/primary-50 colors/primary-60 theme)))
|
||||
|
||||
(defn container-outer
|
||||
[pressed? override-theme]
|
||||
[pressed? theme]
|
||||
(merge container-default
|
||||
{:background-color (container-background-color pressed? override-theme)}))
|
||||
{:background-color (container-background-color pressed? theme)}))
|
||||
|
||||
(defn container-inner
|
||||
[pressed? blur? override-theme]
|
||||
[pressed? blur? theme]
|
||||
(merge container-default
|
||||
{:border-width 1
|
||||
:border-color (container-border-color pressed? blur? override-theme)}))
|
||||
:border-color (container-border-color pressed? blur? theme)}))
|
||||
|
||||
(defn icon-color
|
||||
[pressed? override-theme]
|
||||
[pressed? theme]
|
||||
(if (and (not pressed?)
|
||||
(= :light override-theme))
|
||||
(= :light theme))
|
||||
colors/neutral-100
|
||||
colors/white))
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
(ns quo2.components.selectors.filter.view
|
||||
(:require [quo2.components.icon :as icon]
|
||||
[quo2.components.selectors.filter.style :as style]
|
||||
[quo2.theme :as theme]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn view
|
||||
(defn view-internal
|
||||
[initial-props]
|
||||
(let [pressed? (reagent/atom (:pressed? initial-props))]
|
||||
(fn [{:keys [blur? override-theme on-press-out]
|
||||
:or {override-theme (theme/get-theme)}}]
|
||||
(fn [{:keys [blur? theme on-press-out]}]
|
||||
[rn/touchable-without-feedback
|
||||
{:accessibility-label :selector-filter
|
||||
:on-press-out (fn []
|
||||
(swap! pressed? not)
|
||||
(when on-press-out
|
||||
(on-press-out @pressed?)))}
|
||||
[rn/view {:style (style/container-outer @pressed? override-theme)}
|
||||
[rn/view {:style (style/container-inner @pressed? blur? override-theme)}
|
||||
[rn/view {:style (style/container-outer @pressed? theme)}
|
||||
[rn/view {:style (style/container-inner @pressed? blur? theme)}
|
||||
[icon/icon :i/unread
|
||||
{:color (style/icon-color @pressed? override-theme)
|
||||
{:color (style/icon-color @pressed? theme)
|
||||
:size 20}]]]])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -1,20 +1,53 @@
|
||||
(ns quo2.components.settings.category.component-spec
|
||||
(:require [test-helpers.component :as h]
|
||||
[quo2.components.settings.category.view :as category]))
|
||||
(:require
|
||||
[quo2.components.settings.category.view :as category]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "category tests"
|
||||
(h/describe "Settings Category tests"
|
||||
(h/test "category label renders"
|
||||
(h/render [category/category
|
||||
{:label "label"
|
||||
:data [{:title "Item 1"
|
||||
:left-icon :i/browser
|
||||
:chevron? true}]}])
|
||||
(h/is-truthy (h/get-by-text "label")))
|
||||
{:list-type :settings
|
||||
:label "Label"
|
||||
:data [{:title "Item 1"
|
||||
:left-icon :i/browser
|
||||
:chevron? true}]}])
|
||||
(h/is-truthy (h/get-by-text "Label")))
|
||||
|
||||
(h/test "category item renders"
|
||||
(h/render [category/category
|
||||
{:label "label"
|
||||
:data [{:title "Item 1"
|
||||
:left-icon :i/browser
|
||||
:chevron? true}]}])
|
||||
{:list-type :settings
|
||||
:label "Label"
|
||||
:data [{:title "Item 1"
|
||||
:left-icon :i/browser
|
||||
:chevron? true}]}])
|
||||
(h/is-truthy (h/get-by-text "Item 1"))))
|
||||
|
||||
|
||||
(h/describe "Reorder Category tests"
|
||||
(h/test "category label renders"
|
||||
(h/render [category/category
|
||||
{:list-type :reorder
|
||||
:label "Label"
|
||||
:data [{:title "Item 1"
|
||||
:right-icon :i/globe
|
||||
:chevron? true}]}])
|
||||
(h/is-truthy (h/get-by-text "Label")))
|
||||
|
||||
(h/test "category item renders"
|
||||
(h/render [category/category
|
||||
{:list-type :reorder
|
||||
:label "Label"
|
||||
:data [{:title "Item 1"
|
||||
:right-icon :i/globe
|
||||
:chevron? true}]}])
|
||||
(h/is-truthy (h/get-by-text "Item 1")))
|
||||
|
||||
(h/test "category item subtitle renders"
|
||||
(h/render [category/category
|
||||
{:list-type :reorder
|
||||
:label "Label"
|
||||
:data [{:title "Item 1"
|
||||
:subtitle "subtitle"
|
||||
:right-icon :i/globe
|
||||
:chevron? true}]}])
|
||||
(h/is-truthy (h/get-by-text "subtitle"))))
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
(ns quo2.components.settings.category.reorder.view
|
||||
(:require
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.settings.reorder-item.types :as types]
|
||||
[quo2.components.settings.reorder-item.view :as reorder-item]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[quo2.components.settings.category.style :as style]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.draggable-flatlist :as draggable-flatlist]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn on-drag-end-fn
|
||||
[data atom-data]
|
||||
(reset! atom-data data)
|
||||
(reagent/flush))
|
||||
|
||||
(defn- reorder-category-internal
|
||||
[{:keys [label data blur? theme]}]
|
||||
(reagent/with-let [atom-data (reagent/atom data)]
|
||||
[rn/view {:style style/container}
|
||||
(when blur?
|
||||
[rn/view (style/blur-container) [blur/view (style/blur-view)]])
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||
label]
|
||||
[draggable-flatlist/draggable-flatlist
|
||||
{:data @atom-data
|
||||
:key-fn (fn [item index] (str (:title item) index))
|
||||
:style style/reorder-items
|
||||
:render-fn (fn [item _ _ _ _ drag] [reorder-item/reorder-item item types/item
|
||||
{:blur? blur? :drag drag}])
|
||||
:on-drag-end-fn (fn [_ _ data]
|
||||
(on-drag-end-fn data atom-data))
|
||||
:separator [rn/view
|
||||
{:style (style/reorder-separator blur? theme)}]}]]))
|
||||
|
||||
(def reorder-category (quo.theme/with-theme reorder-category-internal))
|
||||
@@ -0,0 +1,27 @@
|
||||
(ns quo2.components.settings.category.settings.view
|
||||
(:require
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.settings.settings-list.view :as settings-list]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[quo2.components.settings.category.style :as style]
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(defn- category-internal
|
||||
[{:keys [label data blur? theme]}]
|
||||
[rn/view {:style style/container}
|
||||
(when blur?
|
||||
[rn/view (style/blur-container) [blur/view (style/blur-view)]])
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||
label]
|
||||
[rn/flat-list
|
||||
{:data data
|
||||
:style (style/settings-items theme blur?)
|
||||
:render-fn (fn [item] [settings-list/settings-list item])
|
||||
:separator [rn/view {:style (style/settings-separator theme blur?)}]}]])
|
||||
|
||||
(def settings-category (quo.theme/with-theme category-internal))
|
||||
@@ -8,7 +8,7 @@
|
||||
:padding-top 12
|
||||
:padding-bottom 8})
|
||||
|
||||
(defn items
|
||||
(defn settings-items
|
||||
[theme blur?]
|
||||
{:margin-top 12
|
||||
:border-radius 16
|
||||
@@ -20,13 +20,23 @@
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
|
||||
|
||||
(defn separator
|
||||
(def reorder-items
|
||||
{:margin-top 12})
|
||||
|
||||
(defn settings-separator
|
||||
[theme blur?]
|
||||
{:height 1
|
||||
:background-color (if blur?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
|
||||
|
||||
(defn reorder-separator
|
||||
[blur? theme]
|
||||
{:height 4
|
||||
:background-color (if blur?
|
||||
:transparent
|
||||
(colors/theme-colors colors/neutral-5 colors/neutral-95 theme))})
|
||||
|
||||
(defn blur-container
|
||||
[]
|
||||
{:position :absolute
|
||||
|
||||
@@ -1,27 +1,9 @@
|
||||
(ns quo2.components.settings.category.view
|
||||
(:require
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.settings.settings-list.view :as settings-list]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[quo2.components.settings.category.style :as style]
|
||||
[quo2.theme :as quo.theme]))
|
||||
(:require [quo2.components.settings.category.settings.view :as settings]
|
||||
[quo2.components.settings.category.reorder.view :as reorder]))
|
||||
|
||||
(defn- category-internal
|
||||
[{:keys [label data blur? theme]}]
|
||||
[rn/view {:style style/container}
|
||||
(when blur?
|
||||
[rn/view (style/blur-container) [blur/view (style/blur-view)]])
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||
label]
|
||||
[rn/flat-list
|
||||
{:data data
|
||||
:style (style/items theme blur?)
|
||||
:render-fn (fn [item] [settings-list/settings-list item])
|
||||
:separator [rn/view {:style (style/separator theme blur?)}]}]])
|
||||
|
||||
(def category (quo.theme/with-theme category-internal))
|
||||
(defn category
|
||||
[{:keys [list-type] :as props}]
|
||||
(if (= list-type :settings)
|
||||
[settings/settings-category props]
|
||||
[reorder/reorder-category props]))
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
(ns quo2.components.settings.reorder-item.items.item
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.components.settings.reorder-item.style :as style]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.icon :as icon]
|
||||
[quo2.foundations.colors :as colors]))
|
||||
(:require
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[quo2.components.settings.reorder-item.style :as style]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.icon :as icon]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.fast-image :as fast-image]))
|
||||
|
||||
(defn view
|
||||
(defn- view-internal
|
||||
[{:keys
|
||||
[title
|
||||
subtitle
|
||||
@@ -13,10 +16,14 @@
|
||||
image-size
|
||||
right-text
|
||||
right-icon
|
||||
on-press]}]
|
||||
on-press
|
||||
theme]}
|
||||
blur?
|
||||
drag]
|
||||
[rn/touchable-opacity
|
||||
{:on-press on-press
|
||||
:style (merge (style/item-container) (when subtitle style/item-container-extended))}
|
||||
{:on-press on-press
|
||||
:on-long-press drag
|
||||
:style (merge (style/item-container blur?) (when subtitle style/item-container-extended))}
|
||||
[icon/icon :main-icons/drag
|
||||
{:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
@@ -25,23 +32,25 @@
|
||||
{:style style/body-container}
|
||||
[rn/view
|
||||
{:style style/image-container}
|
||||
[rn/image
|
||||
[fast-image/fast-image
|
||||
{:source image
|
||||
:style (style/image image-size)}]]
|
||||
[rn/view
|
||||
{:style style/text-container}
|
||||
[rn/view
|
||||
[text/text
|
||||
{:style style/item-text
|
||||
:weight :medium}
|
||||
{:weight :medium}
|
||||
title]
|
||||
(when subtitle
|
||||
[text/text
|
||||
{:style style/item-subtitle
|
||||
:weight :regular}
|
||||
{:style style/item-subtitle
|
||||
:size :paragraph-2}
|
||||
subtitle])]
|
||||
(when right-text
|
||||
[text/text {:style style/right-text} right-text])
|
||||
(when right-icon
|
||||
[rn/view {:style style/right-icon-container} [icon/icon right-icon (style/right-icon)]])]]
|
||||
[icon/icon :tiny-icons/chevron-right (style/chevron)]])
|
||||
[icon/icon :tiny-icons/chevron-right (style/chevron theme)]])
|
||||
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -2,19 +2,21 @@
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn item-container
|
||||
[]
|
||||
[blur?]
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:padding-horizontal 10
|
||||
:border-radius 14
|
||||
:margin-bottom 23
|
||||
:height 45
|
||||
:background-color (colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-90)})
|
||||
:border-radius 16
|
||||
:padding-horizontal 12
|
||||
:padding-vertical 12
|
||||
:height 48
|
||||
:background-color (if blur?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-90))})
|
||||
|
||||
(def item-container-extended
|
||||
{:height 52})
|
||||
{:height 56})
|
||||
|
||||
(def body-container
|
||||
{:flex 1
|
||||
@@ -31,20 +33,17 @@
|
||||
{:width size
|
||||
:height size})
|
||||
|
||||
(def item-text
|
||||
{:font-size 14})
|
||||
|
||||
(defn chevron
|
||||
[]
|
||||
[theme]
|
||||
{:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
colors/neutral-40)
|
||||
colors/neutral-40
|
||||
theme)
|
||||
:height 14
|
||||
:width 14})
|
||||
|
||||
(def item-subtitle
|
||||
{:color colors/neutral-50
|
||||
:font-size 13})
|
||||
{:color colors/neutral-50})
|
||||
|
||||
(def right-text
|
||||
{:font-size 15
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
[quo2.components.settings.reorder-item.types :as types]))
|
||||
|
||||
(defn reorder-item
|
||||
[item type]
|
||||
[item type {:keys [blur? drag]}]
|
||||
(case type
|
||||
types/item [item/view item]
|
||||
types/item [item/view item blur? drag]
|
||||
types/placeholder [placeholder/view item]
|
||||
types/skeleton [skeleton/view]
|
||||
types/tab [tab/view item]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(ns quo2.components.tabs.segmented-tab
|
||||
(:require [quo2.components.tabs.tab.view :as tab]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
[reagent.core :as reagent]
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(def themes-for-blur
|
||||
{:light {:background-color colors/neutral-80-opa-5}
|
||||
@@ -13,17 +13,17 @@
|
||||
{:light {:background-color colors/neutral-10}
|
||||
:dark {:background-color colors/neutral-90}})
|
||||
|
||||
(defn segmented-control
|
||||
(defn- segmented-control-internal
|
||||
[{:keys [default-active on-change]}]
|
||||
(let [active-tab-id (reagent/atom default-active)]
|
||||
(fn [{:keys [data size override-theme blur? container-style item-container-style
|
||||
(fn [{:keys [data size theme blur? container-style item-container-style
|
||||
active-item-container-style]}]
|
||||
(let [active-id @active-tab-id]
|
||||
[rn/view
|
||||
(merge
|
||||
{:flex-direction :row
|
||||
:background-color (get-in (if blur? themes-for-blur themes)
|
||||
[(or override-theme (theme/get-theme)) :background-color])
|
||||
[theme :background-color])
|
||||
:border-radius (case size
|
||||
32 10
|
||||
28 8
|
||||
@@ -42,7 +42,6 @@
|
||||
:item-container-style item-container-style
|
||||
:segmented? true
|
||||
:size size
|
||||
:override-theme override-theme
|
||||
:blur? blur?
|
||||
:active (= id active-id)
|
||||
:on-press (fn [tab-id]
|
||||
@@ -50,3 +49,5 @@
|
||||
(when on-change
|
||||
(on-change tab-id)))}
|
||||
label]])]))))
|
||||
|
||||
(def segmented-control (quo.theme/with-theme segmented-control-internal))
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
(:require [quo2.components.icon :as icon]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as quo2.theme]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(def default-container-style
|
||||
{:border-radius 20
|
||||
@@ -81,7 +81,7 @@
|
||||
:border-color colors/danger-50-opa-20
|
||||
:label label
|
||||
;; The negative tag uses the same color for `dark` and `dark blur` variant
|
||||
:text-color (if (= theme :light) colors/danger-50 colors/danger-60)}])
|
||||
:text-color (colors/theme-colors colors/danger-50 colors/danger-60 theme)}])
|
||||
|
||||
(defn- pending
|
||||
[size theme label blur? no-icon?]
|
||||
@@ -104,8 +104,8 @@
|
||||
colors/white-opa-70
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}])
|
||||
|
||||
(defn status-tag
|
||||
[{:keys [status size override-theme label blur? no-icon?]}]
|
||||
(defn- status-tag-internal
|
||||
[{:keys [status size theme label blur? no-icon?]}]
|
||||
(when status
|
||||
(when-let [status-component (case (:type status)
|
||||
:positive positive
|
||||
@@ -114,7 +114,9 @@
|
||||
nil)]
|
||||
[status-component
|
||||
size
|
||||
(or override-theme (quo2.theme/get-theme))
|
||||
theme
|
||||
label
|
||||
blur?
|
||||
no-icon?])))
|
||||
|
||||
(def status-tag (quo.theme/with-theme status-tag-internal))
|
||||
|
||||
@@ -105,10 +105,11 @@
|
||||
:loading? true/false
|
||||
}"
|
||||
[_ _]
|
||||
(fn [{:keys [symbol value size img-src border-color purchasable? sufficient? loading?]
|
||||
:or
|
||||
{size :small}}]
|
||||
(let [sufficient? (when-not loading? sufficient?)
|
||||
(fn [{:keys [value size img-src border-color purchasable? sufficient? loading?]
|
||||
:or {size :small}
|
||||
:as props}]
|
||||
(let [sym (:symbol props)
|
||||
sufficient? (when-not loading? sufficient?)
|
||||
border-color (if sufficient? colors/success-50 border-color)]
|
||||
[tag
|
||||
{:size size
|
||||
@@ -119,4 +120,4 @@
|
||||
[loading-icon]
|
||||
(when (or purchasable? sufficient?)
|
||||
[icon size border-color sufficient?]))}
|
||||
(str value " " symbol)])))
|
||||
(str value " " sym)])))
|
||||
|
||||
+33
-23
@@ -98,30 +98,7 @@
|
||||
quo2.components.tags.token-tag
|
||||
quo2.components.text-combinations.title.view))
|
||||
|
||||
(def icon quo2.components.icon/icon)
|
||||
(def separator quo2.components.common.separator.view/separator)
|
||||
(def header quo2.components.header/header)
|
||||
(def dropdown quo2.components.dropdowns.dropdown/dropdown)
|
||||
(def info-message quo2.components.info.info-message/info-message)
|
||||
(def information-box quo2.components.info.information-box.view/view)
|
||||
(def gap quo2.components.messages.gap/gap)
|
||||
(def system-message quo2.components.messages.system-message/system-message)
|
||||
(def reaction quo2.components.reactions.reaction/reaction)
|
||||
(def add-reaction quo2.components.reactions.reaction/add-reaction)
|
||||
(def user-avatar-tag quo2.components.tags.context-tag.view/user-avatar-tag)
|
||||
(def context-tag quo2.components.tags.context-tag.view/context-tag)
|
||||
(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 disclaimer quo2.components.selectors.disclaimer.view/view)
|
||||
(def checkbox quo2.components.selectors.selectors.view/checkbox)
|
||||
(def filter quo2.components.selectors.filter.view/view)
|
||||
(def author quo2.components.messages.author.view/author)
|
||||
|
||||
;;;; SELECTORS
|
||||
(def reactions quo2.components.selectors.reactions.view/view)
|
||||
|
||||
;;;; AVATAR
|
||||
(def account-avatar quo2.components.avatars.account-avatar/account-avatar)
|
||||
@@ -184,9 +161,22 @@
|
||||
(def drawer-buttons quo2.components.drawers.drawer-buttons.view/view)
|
||||
(def permission-context quo2.components.drawers.permission-context.view/view)
|
||||
|
||||
;;;; DROPDOWNS
|
||||
(def dropdown quo2.components.dropdowns.dropdown/dropdown)
|
||||
|
||||
;;;; EMPTY STATE
|
||||
(def empty-state quo2.components.empty-state.empty-state.view/empty-state)
|
||||
|
||||
;;;; HEADER
|
||||
(def header quo2.components.header/header)
|
||||
|
||||
;;;; ICON
|
||||
(def icon quo2.components.icon/icon)
|
||||
|
||||
;;;; INFO
|
||||
(def info-message quo2.components.info.info-message/info-message)
|
||||
(def information-box quo2.components.info.information-box.view/view)
|
||||
|
||||
;;;; INPUTS
|
||||
(def input quo2.components.inputs.input.view/input)
|
||||
(def profile-input quo2.components.inputs.profile-input.view/profile-input)
|
||||
@@ -213,6 +203,10 @@
|
||||
(def markdown-list quo2.components.markdown.list.view/view)
|
||||
(def text quo2.components.markdown.text/text)
|
||||
|
||||
;;;; MESSAGES
|
||||
(def gap quo2.components.messages.gap/gap)
|
||||
(def system-message quo2.components.messages.system-message/system-message)
|
||||
|
||||
;;;; NOTIFICATIONS
|
||||
(def activity-log quo2.components.notifications.activity-log.view/view)
|
||||
(def activity-logs-photos quo2.components.notifications.activity-logs-photos.view/view)
|
||||
@@ -229,10 +223,21 @@
|
||||
(def profile-card quo2.components.profile.profile-card.view/profile-card)
|
||||
(def select-profile quo2.components.profile.select-profile.view/view)
|
||||
|
||||
;;;; REACTIONS
|
||||
(def reaction quo2.components.reactions.reaction/reaction)
|
||||
(def add-reaction quo2.components.reactions.reaction/add-reaction)
|
||||
|
||||
;;;; RECORD AUDIO
|
||||
(def record-audio quo2.components.record-audio.record-audio.view/record-audio)
|
||||
(def soundtrack quo2.components.record-audio.soundtrack.view/f-soundtrack)
|
||||
|
||||
;;;; SELECTORS
|
||||
(def author quo2.components.messages.author.view/author)
|
||||
(def disclaimer quo2.components.selectors.disclaimer.view/view)
|
||||
(def filter quo2.components.selectors.filter.view/view)
|
||||
(def reactions quo2.components.selectors.reactions.view/view)
|
||||
(def checkbox quo2.components.selectors.selectors.view/checkbox)
|
||||
|
||||
;;;; SETTINGS
|
||||
(def privacy-option quo2.components.settings.privacy-option/card)
|
||||
(def account quo2.components.settings.accounts.view/account)
|
||||
@@ -255,6 +260,11 @@
|
||||
(def permission-tag quo2.components.tags.permission-tag/tag)
|
||||
(def status-tag quo2.components.tags.status-tags/status-tag)
|
||||
(def token-tag quo2.components.tags.token-tag/tag)
|
||||
(def user-avatar-tag quo2.components.tags.context-tag.view/user-avatar-tag)
|
||||
(def context-tag quo2.components.tags.context-tag.view/context-tag)
|
||||
(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)
|
||||
|
||||
;;;; TITLE
|
||||
(def title quo2.components.text-combinations.title.view/title)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
(ns react-native.draggable-flatlist
|
||||
(:require
|
||||
[react-native.flat-list :as rn-flat-list]
|
||||
[reagent.core :as reagent]
|
||||
["react-native-draggable-flatlist" :default DraggableFlatList]))
|
||||
|
||||
(def rn-draggable-flatlist (reagent/adapt-react-class DraggableFlatList))
|
||||
|
||||
(defn draggable-flatlist
|
||||
[props]
|
||||
[rn-draggable-flatlist (rn-flat-list/base-list-props props)])
|
||||
@@ -91,9 +91,9 @@
|
||||
(.-value anim)))
|
||||
|
||||
(defn set-shared-value
|
||||
[anim val]
|
||||
(when (and anim (some? val))
|
||||
(set! (.-value anim) val)))
|
||||
[anim v]
|
||||
(when (and anim (some? v))
|
||||
(set! (.-value anim) v)))
|
||||
|
||||
(defn interpolate
|
||||
([shared-value input-range output-range]
|
||||
@@ -112,47 +112,47 @@
|
||||
|
||||
;; Animators
|
||||
(defn animate-shared-value-with-timing
|
||||
[anim val duration easing]
|
||||
[anim v duration easing]
|
||||
(set-shared-value anim
|
||||
(with-timing val
|
||||
(with-timing v
|
||||
(js-obj "duration" duration
|
||||
"easing" (get easings easing)))))
|
||||
|
||||
(defn animate-shared-value-with-delay
|
||||
[anim val duration easing delay]
|
||||
[anim v duration easing delay]
|
||||
(set-shared-value anim
|
||||
(with-delay delay
|
||||
(with-timing val
|
||||
(with-timing v
|
||||
(js-obj "duration" duration
|
||||
"easing" (get easings easing))))))
|
||||
|
||||
(defn animate-delay
|
||||
([animation val delay]
|
||||
(animate-delay animation val delay default-duration))
|
||||
([animation val delay duration]
|
||||
([animation v delay]
|
||||
(animate-delay animation v delay default-duration))
|
||||
([animation v delay duration]
|
||||
(set-shared-value animation
|
||||
(with-delay delay
|
||||
(with-timing val
|
||||
(with-timing v
|
||||
(clj->js {:duration duration
|
||||
:easing (default-easing)}))))))
|
||||
|
||||
(defn animate-shared-value-with-repeat
|
||||
[anim val duration easing number-of-repetitions reverse?]
|
||||
[anim v duration easing number-of-repetitions reverse?]
|
||||
(set-shared-value anim
|
||||
(with-repeat (with-timing val
|
||||
(with-repeat (with-timing v
|
||||
(js-obj "duration" duration
|
||||
"easing" (get easings easing)))
|
||||
number-of-repetitions
|
||||
reverse?)))
|
||||
|
||||
(defn animate-shared-value-with-delay-repeat
|
||||
([anim val duration easing delay number-of-repetitions]
|
||||
(animate-shared-value-with-delay-repeat anim val duration easing delay number-of-repetitions false))
|
||||
([anim val duration easing delay number-of-repetitions reverse?]
|
||||
([anim v duration easing delay number-of-repetitions]
|
||||
(animate-shared-value-with-delay-repeat anim v duration easing delay number-of-repetitions false))
|
||||
([anim v duration easing delay number-of-repetitions reverse?]
|
||||
(set-shared-value anim
|
||||
(with-delay delay
|
||||
(with-repeat
|
||||
(with-timing val
|
||||
(with-timing v
|
||||
#js
|
||||
{:duration duration
|
||||
:easing (get easings easing)})
|
||||
@@ -160,9 +160,9 @@
|
||||
reverse?)))))
|
||||
|
||||
(defn animate-shared-value-with-spring
|
||||
[anim val {:keys [mass stiffness damping]}]
|
||||
[anim v {:keys [mass stiffness damping]}]
|
||||
(set-shared-value anim
|
||||
(with-spring val
|
||||
(with-spring v
|
||||
(js-obj "mass" mass
|
||||
"damping" damping
|
||||
"stiffness" stiffness))))
|
||||
@@ -183,7 +183,7 @@
|
||||
:easing (default-easing)})))))
|
||||
|
||||
(defn with-timing-duration
|
||||
[val duration]
|
||||
(with-timing val
|
||||
[v duration]
|
||||
(with-timing v
|
||||
(clj->js {:duration duration
|
||||
:easing (in-out (.-quad ^js Easing))})))
|
||||
|
||||
@@ -40,10 +40,10 @@
|
||||
; referenced function: contact-list-item
|
||||
(defn- rename-mentionable-users
|
||||
[mentionable-users]
|
||||
(reduce (fn [acc [id val]]
|
||||
(reduce (fn [acc [id v]]
|
||||
(assoc acc
|
||||
id
|
||||
(set/rename-keys val
|
||||
(set/rename-keys v
|
||||
{:id :public-key
|
||||
:primaryName :primary-name
|
||||
:secondaryName :secondary-name
|
||||
@@ -55,6 +55,7 @@
|
||||
|
||||
{}
|
||||
mentionable-users))
|
||||
|
||||
(defn- transfer-mention-result
|
||||
[result]
|
||||
(let [{:keys [input-segments mentionable-users state chat-id new-text]}
|
||||
|
||||
@@ -83,7 +83,8 @@
|
||||
(update :chats <-chats-rpc)
|
||||
(update :categories <-categories-rpc)
|
||||
(assoc :token-images
|
||||
(reduce (fn [acc {:keys [symbol image]}] (assoc acc symbol image))
|
||||
(reduce (fn [acc {sym :symbol image :image}]
|
||||
(assoc acc sym image))
|
||||
{}
|
||||
(:communityTokensMetadata c)))))
|
||||
|
||||
|
||||
@@ -143,8 +143,8 @@
|
||||
|
||||
(defn generate-erc20-uri
|
||||
"Generate a EIP 681 URI encapsulating ERC20 token transfer"
|
||||
[address {:keys [symbol value] :as m} all-tokens]
|
||||
(when-let [token (tokens/symbol->token all-tokens symbol)]
|
||||
[address {sym :symbol value :value :as m} all-tokens]
|
||||
(when-let [token (tokens/symbol->token all-tokens sym)]
|
||||
(generate-uri (:address token)
|
||||
(merge (dissoc m :value :symbol)
|
||||
{:function-name "transfer"
|
||||
|
||||
@@ -190,18 +190,23 @@
|
||||
(is (.equals (money/bignumber "111122223333441239") (eip681/parse-eth-value "111122223333441239"))))
|
||||
|
||||
(deftest extract-request-details
|
||||
(let [{:keys [value symbol address]} (eip681/extract-request-details
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"
|
||||
:value "1ETH"}
|
||||
{})]
|
||||
(let [{value :value
|
||||
sym :symbol
|
||||
address :address}
|
||||
(eip681/extract-request-details
|
||||
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"
|
||||
:value "1ETH"}
|
||||
{})]
|
||||
(is (.equals (money/ether->wei (money/bignumber 1)) value))
|
||||
(is (= :ETH symbol))
|
||||
(is (= :ETH sym))
|
||||
(is (= "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" address)))
|
||||
(is (= (eip681/extract-request-details
|
||||
{:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e" :chain-id 1 :function-name "unknown"}
|
||||
{})
|
||||
{:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e" :chain-id 1 :function-name "unknown"}))
|
||||
(let [{:keys [value symbol address]}
|
||||
(let [{value :value
|
||||
sym :symbol
|
||||
address :address}
|
||||
(eip681/extract-request-details
|
||||
{:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e"
|
||||
:chain-id 1
|
||||
@@ -213,5 +218,5 @@
|
||||
:symbol :SNT
|
||||
:decimals 18}})]
|
||||
(is (.equals (money/bignumber 1000) value))
|
||||
(is (= :SNT symbol))
|
||||
(is (= :SNT sym))
|
||||
(is (= "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" address))))
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
(def default-native-currency
|
||||
(memoize
|
||||
(fn [symbol]
|
||||
(fn [sym]
|
||||
{:name "Native"
|
||||
:symbol :ETH
|
||||
:symbol-display symbol
|
||||
:symbol-display sym
|
||||
:decimals 18
|
||||
:icon {:source (js/require "../resources/images/tokens/default-token.png")}})))
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
(set (map #(-> % val :symbol) all-native-currencies)))
|
||||
|
||||
(defn native-currency
|
||||
[{:keys [symbol] :as current-network}]
|
||||
[{sym :symbol :as current-network}]
|
||||
(let [chain (ethereum/network->chain-keyword current-network)]
|
||||
(get all-native-currencies chain (default-native-currency symbol))))
|
||||
(get all-native-currencies chain (default-native-currency sym))))
|
||||
|
||||
(defn ethereum?
|
||||
[symbol]
|
||||
(native-currency-symbols symbol))
|
||||
[sym]
|
||||
(native-currency-symbols sym))
|
||||
|
||||
(def token-icons
|
||||
{:mainnet (resolve-icons :mainnet)
|
||||
@@ -74,17 +74,17 @@
|
||||
(string/lower-case (:name %2))))))
|
||||
|
||||
(defn symbol->token
|
||||
[all-tokens symbol]
|
||||
(some #(when (= symbol (:symbol %)) %) (vals all-tokens)))
|
||||
[all-tokens sym]
|
||||
(some #(when (= sym (:symbol %)) %) (vals all-tokens)))
|
||||
|
||||
(defn address->token
|
||||
[all-tokens address]
|
||||
(get all-tokens (string/lower-case address)))
|
||||
|
||||
(defn asset-for
|
||||
[all-tokens current-network symbol]
|
||||
[all-tokens current-network sym]
|
||||
(let [native-coin (native-currency current-network)]
|
||||
(if (or (= (:symbol-display native-coin) symbol)
|
||||
(= (:symbol native-coin) symbol))
|
||||
(if (or (= (:symbol-display native-coin) sym)
|
||||
(= (:symbol native-coin) sym))
|
||||
native-coin
|
||||
(symbol->token all-tokens symbol))))
|
||||
(symbol->token all-tokens sym))))
|
||||
|
||||
@@ -52,10 +52,8 @@
|
||||
|
||||
(defn- parse-token-transfer
|
||||
[chain-tokens contract]
|
||||
(let [{:keys [symbol] :as token} (get chain-tokens
|
||||
contract
|
||||
default-erc20-token)]
|
||||
{:symbol symbol
|
||||
(let [token (get chain-tokens contract default-erc20-token)]
|
||||
{:symbol (:symbol token)
|
||||
:token token
|
||||
;; NOTE(goranjovic) - just a flag we need when we merge this entry
|
||||
;; with the existing entry in the app, e.g. transaction info with
|
||||
@@ -387,11 +385,10 @@
|
||||
:addresses [address]
|
||||
:before-block min-known-block
|
||||
:fetch-more? (utils.mobile-sync/syncing-allowed? cofx)
|
||||
;; Transfers are requested before and including `min-known-block` because
|
||||
;; there is no guarantee that all transfers from that block are shown
|
||||
;; already. To make sure that we fetch the whole `default-transfers-limit`
|
||||
;; of transfers the number of transfers already received for
|
||||
;; `min-known-block` is added to the page size.
|
||||
;; Transfers are requested before and including `min-known-block` because there is no
|
||||
;; guarantee that all transfers from that block are shown already. To make sure that we fetch
|
||||
;; the whole `default-transfers-limit` of transfers the number of transfers already received
|
||||
;; for `min-known-block` is added to the page size.
|
||||
:limit-per-address {address (+ default-transfers-limit
|
||||
min-block-transfers-count)}}}
|
||||
(tx-fetching-in-progress [address]))))
|
||||
|
||||
@@ -34,18 +34,18 @@
|
||||
(or display-name primary-name alias (gfycat/generate-gfy public-key)))))
|
||||
|
||||
(defn contact-by-identity
|
||||
[contacts identity]
|
||||
(or (get contacts identity)
|
||||
(contact.db/public-key->new-contact identity)))
|
||||
[contacts contact-identity]
|
||||
(or (get contacts contact-identity)
|
||||
(contact.db/public-key->new-contact contact-identity)))
|
||||
|
||||
(defn contact-two-names-by-identity
|
||||
[contact profile identity]
|
||||
(let [me? (= (:public-key profile) identity)]
|
||||
[contact profile contact-identity]
|
||||
(let [me? (= (:public-key profile) contact-identity)]
|
||||
(if me?
|
||||
[(or (:preferred-name profile)
|
||||
(:display-name profile)
|
||||
(:primary-name contact)
|
||||
(gfycat/generate-gfy identity))]
|
||||
(gfycat/generate-gfy contact-identity))]
|
||||
[(:primary-name contact) (:secondary-name contact)])))
|
||||
|
||||
(defn displayed-photo
|
||||
@@ -212,8 +212,8 @@
|
||||
(rf/merge cofx
|
||||
{:json-rpc/call [{:method "multiaccounts_deleteIdentityImage"
|
||||
:params [key-uid]
|
||||
;; NOTE: In case of an error we could fallback to previous image in UI
|
||||
;; with a toast error
|
||||
;; NOTE: In case of an error we could fallback to previous image in
|
||||
;; UI with a toast error
|
||||
:on-success #(log/info "[multiaccount] Delete profile image" %)}]}
|
||||
(multiaccounts.update/optimistic :images nil)
|
||||
(bottom-sheet/hide-bottom-sheet-old))))
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
:on-success #(re-frame/dispatch [:navigate-back])}]}))
|
||||
|
||||
(defn new-network
|
||||
[random-id network-name symbol upstream-url chain-type chain-id]
|
||||
[random-id network-name sym upstream-url chain-type chain-id]
|
||||
(let [data-dir (str "/ethereum/" (name chain-type) "_rpc")
|
||||
config {:NetworkId (or (when chain-id (int chain-id))
|
||||
(ethereum/chain-keyword->chain-id chain-type))
|
||||
@@ -167,7 +167,7 @@
|
||||
:URL upstream-url}}]
|
||||
{:id random-id
|
||||
:name network-name
|
||||
:symbol symbol
|
||||
:symbol sym
|
||||
:config config}))
|
||||
|
||||
(rf/defn save
|
||||
|
||||
@@ -181,7 +181,7 @@
|
||||
|
||||
(defn get-transfer-token
|
||||
[db to data]
|
||||
(let [{:keys [symbol decimals] :as token} (tokens/address->token (:wallet/all-tokens db) to)]
|
||||
(let [{:keys [decimals] :as token} (tokens/address->token (:wallet/all-tokens db) to)]
|
||||
(when (and token data (string? data))
|
||||
(when-let [type (get-method-type data)]
|
||||
(let [[address value _] (native-module/decode-parameters
|
||||
@@ -197,7 +197,7 @@
|
||||
:value value
|
||||
:amount (money/to-fixed (money/token->unit value decimals))
|
||||
:token token
|
||||
:symbol symbol}))))))
|
||||
:symbol (:symbol token)}))))))
|
||||
|
||||
(defn parse-tx-obj
|
||||
[db {:keys [from to value data cancel? hash]}]
|
||||
|
||||
@@ -140,11 +140,11 @@
|
||||
nil)))})))
|
||||
|
||||
(views/defview animated-bottom-panel
|
||||
[val view on-close on-touch-outside show-overlay?]
|
||||
[m view on-close on-touch-outside show-overlay?]
|
||||
(views/letsubs [{window-height :height} [:dimensions/window]]
|
||||
[bottom-panel
|
||||
(when val
|
||||
(select-keys val
|
||||
(when m
|
||||
(select-keys m
|
||||
[:from :contact :amount :token :approve? :message :cancel? :hash :name :url :icons
|
||||
:wc-version :params :connector :description :topic :relay :self :peer :permissions
|
||||
:state])) view window-height on-close on-touch-outside
|
||||
|
||||
@@ -298,8 +298,10 @@
|
||||
(i18n/label :t/save)]]]))
|
||||
|
||||
(defn gwei
|
||||
[val]
|
||||
(str (money/to-fixed val 2) " " (i18n/label :t/gwei)))
|
||||
[amount]
|
||||
(str (money/to-fixed amount 2)
|
||||
" "
|
||||
(i18n/label :t/gwei)))
|
||||
|
||||
(defn fees-warning
|
||||
[]
|
||||
|
||||
@@ -23,102 +23,104 @@
|
||||
|
||||
(defview add-custom-token
|
||||
[]
|
||||
(letsubs [{:keys [contract name symbol decimals in-progress? error error-name error-symbol]}
|
||||
(letsubs [{:keys [contract name decimals in-progress? error error-name error-symbol]
|
||||
:as m}
|
||||
[:wallet/custom-token-screen]]
|
||||
[react/keyboard-avoiding-view {:flex 1 :background-color colors/white}
|
||||
[react/scroll-view
|
||||
{:keyboard-should-persist-taps :handled
|
||||
:style {:flex 1
|
||||
:padding-horizontal 16}}
|
||||
[react/view {:padding-vertical 8}
|
||||
[react/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-vertical 10}}
|
||||
[react/text (i18n/label :t/contract-address)]
|
||||
(when in-progress?
|
||||
[react/view {:flex-direction :row :justify-content :center}
|
||||
[react/view {:height 20}
|
||||
[react/activity-indicator {:width 24 :height 24 :animating true}]]
|
||||
[react/text {:style {:color colors/gray :margin-left 5}}
|
||||
(i18n/label :t/processing)]])]
|
||||
(when-not in-progress?
|
||||
;;tooltip covers button
|
||||
[react/view {:position :absolute :z-index 1000 :right 0 :top 10}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:wallet.custom-token.ui/contract-address-paste])}
|
||||
[react/text {:style {:color colors/blue}}
|
||||
(i18n/label :t/paste)]]])
|
||||
[quo/text-input
|
||||
{:on-change-text #(debounce-and-save :contract %)
|
||||
:error error
|
||||
:default-value contract
|
||||
:monospace true
|
||||
:multiline true
|
||||
:height 78
|
||||
:auto-focus false
|
||||
:placeholder (i18n/label :t/specify-address)}]]
|
||||
[react/view {:padding-vertical 8}
|
||||
[quo/text-input
|
||||
{:on-change-text #(debounce-and-save :name %)
|
||||
:label (i18n/label :t/name)
|
||||
:default-value name
|
||||
:error error-name
|
||||
:auto-focus false
|
||||
:placeholder (i18n/label :t/name-of-token)}]]
|
||||
[react/view {:padding-vertical 8}
|
||||
[react/view {:style {:flex-direction :row}}
|
||||
[react/view
|
||||
{:flex 1
|
||||
:padding-right 8}
|
||||
(let [sym (:symbol m)]
|
||||
[react/keyboard-avoiding-view {:flex 1 :background-color colors/white}
|
||||
[react/scroll-view
|
||||
{:keyboard-should-persist-taps :handled
|
||||
:style {:flex 1
|
||||
:padding-horizontal 16}}
|
||||
[react/view {:padding-vertical 8}
|
||||
[react/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-vertical 10}}
|
||||
[react/text (i18n/label :t/contract-address)]
|
||||
(when in-progress?
|
||||
[react/view {:flex-direction :row :justify-content :center}
|
||||
[react/view {:height 20}
|
||||
[react/activity-indicator {:width 24 :height 24 :animating true}]]
|
||||
[react/text {:style {:color colors/gray :margin-left 5}}
|
||||
(i18n/label :t/processing)]])]
|
||||
(when-not in-progress?
|
||||
;;tooltip covers button
|
||||
[react/view {:position :absolute :z-index 1000 :right 0 :top 10}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:wallet.custom-token.ui/contract-address-paste])}
|
||||
[react/text {:style {:color colors/blue}}
|
||||
(i18n/label :t/paste)]]])
|
||||
[quo/text-input
|
||||
{:on-change-text #(debounce-and-save :symbol %)
|
||||
:label (i18n/label :t/symbol)
|
||||
:error error-symbol
|
||||
:default-value symbol
|
||||
{:on-change-text #(debounce-and-save :contract %)
|
||||
:error error
|
||||
:default-value contract
|
||||
:monospace true
|
||||
:multiline true
|
||||
:height 78
|
||||
:auto-focus false
|
||||
:show-cancel false
|
||||
:placeholder "ABC"}]]
|
||||
[react/view
|
||||
{:flex 1
|
||||
:padding-left 8}
|
||||
:placeholder (i18n/label :t/specify-address)}]]
|
||||
[react/view {:padding-vertical 8}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/decimals)
|
||||
:on-change-text #(debounce-and-save :decimals %)
|
||||
:default-value decimals
|
||||
:keyboard-type :number-pad
|
||||
:max-length 2
|
||||
{:on-change-text #(debounce-and-save :name %)
|
||||
:label (i18n/label :t/name)
|
||||
:default-value name
|
||||
:error error-name
|
||||
:auto-focus false
|
||||
:show-cancel false
|
||||
:placeholder "18"}]]]]
|
||||
#_[quo/text-input
|
||||
{:label (i18n/label :t/balance)
|
||||
:default-value (when (and balance decimals)
|
||||
(wallet.utils/format-amount balance decimals))
|
||||
:editable false
|
||||
:placeholder (i18n/label :t/no-tokens-found)}]]
|
||||
:placeholder (i18n/label :t/name-of-token)}]]
|
||||
[react/view {:padding-vertical 8}
|
||||
[react/view {:style {:flex-direction :row}}
|
||||
[react/view
|
||||
{:flex 1
|
||||
:padding-right 8}
|
||||
[quo/text-input
|
||||
{:on-change-text #(debounce-and-save :symbol %)
|
||||
:label (i18n/label :t/symbol)
|
||||
:error error-symbol
|
||||
:default-value sym
|
||||
:auto-focus false
|
||||
:show-cancel false
|
||||
:placeholder "ABC"}]]
|
||||
[react/view
|
||||
{:flex 1
|
||||
:padding-left 8}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/decimals)
|
||||
:on-change-text #(debounce-and-save :decimals %)
|
||||
:default-value decimals
|
||||
:keyboard-type :number-pad
|
||||
:max-length 2
|
||||
:auto-focus false
|
||||
:show-cancel false
|
||||
:placeholder "18"}]]]]
|
||||
#_[quo/text-input
|
||||
{:label (i18n/label :t/balance)
|
||||
:default-value (when (and balance decimals)
|
||||
(wallet.utils/format-amount balance decimals))
|
||||
:editable false
|
||||
:placeholder (i18n/label :t/no-tokens-found)}]]
|
||||
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:right
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:after :main-icon/next
|
||||
:disabled (boolean
|
||||
(or in-progress?
|
||||
error
|
||||
error-name
|
||||
error-symbol
|
||||
(string/blank? contract)
|
||||
(string/blank? name)
|
||||
(string/blank? symbol)
|
||||
(string/blank? decimals)))
|
||||
:on-press #(re-frame/dispatch [:wallet.custom-token.ui/add-pressed])}
|
||||
(i18n/label :t/add)]}]]))
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:right
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:after :main-icon/next
|
||||
:disabled (boolean
|
||||
(or in-progress?
|
||||
error
|
||||
error-name
|
||||
error-symbol
|
||||
(string/blank? contract)
|
||||
(string/blank? name)
|
||||
(string/blank? sym)
|
||||
(string/blank? decimals)))
|
||||
:on-press #(re-frame/dispatch [:wallet.custom-token.ui/add-pressed])}
|
||||
(i18n/label :t/add)]}]])))
|
||||
|
||||
(defview custom-token-details
|
||||
[]
|
||||
(letsubs [{:keys [address name symbol decimals custom?] :as token}
|
||||
(letsubs [{:keys [address name decimals custom?] :as token}
|
||||
[:get-screen-params]]
|
||||
[react/keyboard-avoiding-view
|
||||
{:style {:flex 1}
|
||||
@@ -149,7 +151,7 @@
|
||||
{:label (i18n/label :t/symbol)
|
||||
:editable false
|
||||
:show-cancel false
|
||||
:default-value symbol}]]
|
||||
:default-value (:symbol token)}]]
|
||||
[react/view {:flex 1 :padding-left 8}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/decimals)
|
||||
|
||||
@@ -112,8 +112,8 @@
|
||||
[react/text {:style {:color colors/blue}} (i18n/label :t/set-max)]]])
|
||||
|
||||
(defn fiat-value
|
||||
[amount {:keys [symbol]} prices wallet-currency]
|
||||
(when-let [price (get-in prices [(keyword symbol) (keyword (:code wallet-currency)) :price])]
|
||||
[amount {sym :symbol} prices wallet-currency]
|
||||
(when-let [price (get-in prices [(keyword sym) (keyword (:code wallet-currency)) :price])]
|
||||
(let [norm-amount (js/parseFloat (money/normalize amount))
|
||||
amount (if (js/isNaN norm-amount) 0 norm-amount)]
|
||||
[react/text
|
||||
|
||||
@@ -51,7 +51,12 @@
|
||||
(fn [_ [_ old-token] [_ new-token]]
|
||||
(not= (:checked? old-token) (:checked? new-token)))
|
||||
:reagent-render
|
||||
(fn [{:keys [symbol name icon color checked?] :as token}]
|
||||
(fn [{sym :symbol
|
||||
title :name
|
||||
icon :icon
|
||||
color :color
|
||||
checked? :checked?
|
||||
:as token}]
|
||||
[quo/list-item
|
||||
{:active checked?
|
||||
:accessory :checkbox
|
||||
@@ -59,14 +64,13 @@
|
||||
:animated false
|
||||
:icon (if icon
|
||||
[wallet.components/token-icon icon]
|
||||
[chat-icon/custom-icon-view-list name color])
|
||||
:title name
|
||||
:subtitle (clojure.core/name symbol)
|
||||
:on-press #(re-frame/dispatch
|
||||
[:wallet.settings/toggle-visible-token (keyword symbol) (not checked?)])
|
||||
:on-long-press #(re-frame/dispatch
|
||||
[:bottom-sheet/show-sheet-old
|
||||
{:content (custom-token-actions-view token)}])}])}))
|
||||
[chat-icon/custom-icon-view-list title color])
|
||||
:title title
|
||||
:subtitle (name sym)
|
||||
:on-press #(re-frame/dispatch [:wallet.settings/toggle-visible-token (keyword sym)
|
||||
(not checked?)])
|
||||
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
|
||||
{:content (custom-token-actions-view token)}])}])}))
|
||||
|
||||
(defn- render-token-wrapper
|
||||
[token]
|
||||
|
||||
@@ -132,9 +132,9 @@
|
||||
(catch :default _ nil)))
|
||||
|
||||
(defn url?
|
||||
[str]
|
||||
[s]
|
||||
(try
|
||||
(when-let [host (.getDomain ^js (goog.Uri. str))]
|
||||
(when-let [host (.getDomain ^js (goog.Uri. s))]
|
||||
(not (string/blank? host)))
|
||||
(catch :default _ nil)))
|
||||
|
||||
|
||||
@@ -191,12 +191,14 @@
|
||||
(PersistentPriorityMap. (sorted-map) {} {} identity nil))
|
||||
|
||||
(defn- pm-empty-by
|
||||
[comparator]
|
||||
(PersistentPriorityMap. (sorted-map-by comparator) {} {} identity nil))
|
||||
[f-comparator]
|
||||
(PersistentPriorityMap. (sorted-map-by f-comparator) {} {} identity nil))
|
||||
|
||||
(defn- pm-empty-keyfn
|
||||
([keyfn] (PersistentPriorityMap. (sorted-map) {} {} keyfn nil))
|
||||
([keyfn comparator] (PersistentPriorityMap. (sorted-map-by comparator) {} {} keyfn nil)))
|
||||
([keyfn]
|
||||
(PersistentPriorityMap. (sorted-map) {} {} keyfn nil))
|
||||
([keyfn f-comparator]
|
||||
(PersistentPriorityMap. (sorted-map-by f-comparator) {} {} keyfn nil)))
|
||||
|
||||
(defn- read-priority-map
|
||||
[elems]
|
||||
@@ -221,9 +223,9 @@
|
||||
"keyval => key val
|
||||
Returns a new priority map with supplied
|
||||
mappings, using the supplied comparator."
|
||||
([comparator & keyvals]
|
||||
([f-comparator & keyvals]
|
||||
(loop [in (seq keyvals)
|
||||
out (pm-empty-by comparator)]
|
||||
out (pm-empty-by f-comparator)]
|
||||
(if in
|
||||
(recur (nnext in) (assoc out (first in) (second in)))
|
||||
out))))
|
||||
@@ -243,9 +245,9 @@
|
||||
"keyval => key val
|
||||
Returns a new priority map with supplied
|
||||
mappings, using the supplied keyfn and comparator."
|
||||
([keyfn comparator & keyvals]
|
||||
([keyfn f-comparator & keyvals]
|
||||
(loop [in (seq keyvals)
|
||||
out (pm-empty-keyfn keyfn comparator)]
|
||||
out (pm-empty-keyfn keyfn f-comparator)]
|
||||
(if in
|
||||
(recur (nnext in) (assoc out (first in) (second in)))
|
||||
out))))
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
(fn [address] (.checkAddressChecksum native-status address))
|
||||
|
||||
:sha3
|
||||
(fn [str] (.sha3 native-status str))
|
||||
(fn [s] (.sha3 native-status s))
|
||||
|
||||
:toChecksumAddress
|
||||
(fn [address] (.toChecksumAddress native-status address))
|
||||
|
||||
@@ -53,8 +53,14 @@
|
||||
|
||||
(defn- fill-prepare-transaction-details
|
||||
[db
|
||||
{:keys [address name value symbol gas gasPrice gasLimit]
|
||||
:or {symbol :ETH}}
|
||||
{address :address
|
||||
name :name
|
||||
value :value
|
||||
sym :symbol
|
||||
gas :gas
|
||||
gas-price :gasPrice
|
||||
gas-limit :gasLimit
|
||||
:or {sym :ETH}}
|
||||
all-tokens]
|
||||
(assoc db
|
||||
:wallet/prepare-transaction
|
||||
@@ -62,14 +68,14 @@
|
||||
:to-name (or name (find-address-name db address))
|
||||
:from (ethereum/get-default-account
|
||||
(get db :profile/wallet-accounts))}
|
||||
gas (assoc :gas (money/bignumber gas))
|
||||
gasLimit (assoc :gas (money/bignumber gasLimit))
|
||||
gasPrice (assoc :gasPrice (money/bignumber gasPrice))
|
||||
value (assoc :amount-text
|
||||
(if (= :ETH symbol)
|
||||
(str (money/internal->formatted value symbol (get all-tokens symbol)))
|
||||
(str value)))
|
||||
symbol (assoc :symbol symbol))))
|
||||
gas (assoc :gas (money/bignumber gas))
|
||||
gas-limit (assoc :gas (money/bignumber gas-limit))
|
||||
gas-price (assoc :gasPrice (money/bignumber gas-price))
|
||||
value (assoc :amount-text
|
||||
(if (= :ETH sym)
|
||||
(str (money/internal->formatted value sym (get all-tokens sym)))
|
||||
(str value)))
|
||||
sym (assoc :symbol sym))))
|
||||
|
||||
(rf/defn request-uri-parsed
|
||||
{:events [:wallet/request-uri-parsed]}
|
||||
|
||||
@@ -987,15 +987,15 @@
|
||||
{::get-pending-transactions nil})
|
||||
|
||||
(defn normalize-transaction
|
||||
[db {:keys [symbol gasPrice gasLimit value from to] :as transaction}]
|
||||
(let [symbol (keyword symbol)
|
||||
token (tokens/symbol->token (:wallet/all-tokens db) symbol)]
|
||||
[db {:keys [gasPrice gasLimit value from to] :as transaction}]
|
||||
(let [sym (-> transaction :symbol keyword)
|
||||
token (tokens/symbol->token (:wallet/all-tokens db) sym)]
|
||||
(-> transaction
|
||||
(select-keys [:timestamp :hash :data])
|
||||
(assoc :from (eip55/address->checksum from)
|
||||
:to (eip55/address->checksum to)
|
||||
:type :pending
|
||||
:symbol symbol
|
||||
:symbol sym
|
||||
:token token
|
||||
:value (money/bignumber value)
|
||||
:gas-price (money/bignumber gasPrice)
|
||||
|
||||
@@ -12,13 +12,15 @@
|
||||
;; some sidechains have different names for this native currency, which we handle with `symbol-display`
|
||||
;; override.
|
||||
(defn display-symbol
|
||||
[{:keys [symbol-display symbol]}]
|
||||
(when-let [name (or symbol-display symbol)]
|
||||
(clojure.core/name name)))
|
||||
[m]
|
||||
(when-let [some-symbol (or (:symbol-display m) (:symbol m))]
|
||||
(name some-symbol)))
|
||||
|
||||
;;NOTE(goranjovic) - in addition to custom symbol display, some sidechain native currencies are listed
|
||||
;;under a different
|
||||
;; 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)))
|
||||
[m]
|
||||
(name (or (:symbol-exchange m)
|
||||
(:symbol-display m)
|
||||
(:symbol m))))
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
:community-banner (js/require "../resources/images/mock2/community-banner.png")
|
||||
:community-logo (js/require "../resources/images/mock2/community-logo.png")
|
||||
:community-cover (js/require "../resources/images/mock2/community-cover.png")
|
||||
:dark-blur-bg (js/require "../resources/images/mock2/dark_blur_bg.png")
|
||||
:decentraland (js/require "../resources/images/mock2/decentraland.png")
|
||||
:gif (js/require "../resources/images/mock2/gif.png")
|
||||
:monkey (js/require "../resources/images/mock2/monkey.png")
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn bounded-val
|
||||
[val min-val max-val]
|
||||
(max min-val (min val max-val)))
|
||||
[v min-v max-v]
|
||||
(max min-v (min v max-v)))
|
||||
|
||||
(defn update-height?
|
||||
[content-size height max-height maximized?]
|
||||
|
||||
@@ -69,16 +69,15 @@
|
||||
|
||||
(defn map-chats
|
||||
[{:keys [db] :as cofx}]
|
||||
(fn [val]
|
||||
(let [chat (or (get (:chats db) (:chat-id val))
|
||||
(create-new-chat (:chat-id val) cofx))]
|
||||
(assoc
|
||||
(merge
|
||||
(cond-> chat
|
||||
(comp not :muted) (dissoc chat :muted-till))
|
||||
val)
|
||||
:invitation-admin
|
||||
(:invitation-admin val)))))
|
||||
(fn [chat]
|
||||
(let [base-chat (or (get (:chats db) (:chat-id chat))
|
||||
(create-new-chat (:chat-id chat) cofx))]
|
||||
(assoc (merge
|
||||
(cond-> base-chat
|
||||
(comp not :muted) (dissoc base-chat :muted-till))
|
||||
chat)
|
||||
:invitation-admin
|
||||
(:invitation-admin chat)))))
|
||||
|
||||
(rf/defn leave-removed-chat
|
||||
[{{:keys [view-id current-chat-id chats]} :db
|
||||
@@ -180,8 +179,8 @@
|
||||
(let [community-id (get-in db [:chats chat-id :community-id])]
|
||||
;; When navigating back from community chat to community, update switcher card
|
||||
;; A close chat event is also called while opening any chat.
|
||||
;; That might lead to duplicate :dispatch keys in fx/merge, that's why dispatch-n is
|
||||
;; used here.
|
||||
;; That might lead to duplicate :dispatch keys in fx/merge, that's why dispatch-n
|
||||
;; is used here.
|
||||
(when (and community-id config/shell-navigation-disabled? (not navigate-to-shell?))
|
||||
{:dispatch-n [[:shell/add-switcher-card
|
||||
:community-overview community-id]]})))
|
||||
@@ -251,8 +250,8 @@
|
||||
{:events [:chat/decrease-unviewed-count]}
|
||||
[{:keys [db]} chat-id {:keys [count countWithMentions]}]
|
||||
{:db (-> db
|
||||
;; There might be some other requests being fired,
|
||||
;; so we need to make sure the count has not been set to
|
||||
;; There might be some other requests being fired, so we need to make sure the count has
|
||||
;; not been set to
|
||||
;; 0 in the meantime
|
||||
(update-in [:chats chat-id :unviewed-messages-count]
|
||||
#(max (- % count) 0))
|
||||
|
||||
@@ -16,23 +16,24 @@
|
||||
:background-color (colors/theme-colors colors/white-opa-40 colors/neutral-80-opa-40)}
|
||||
position))
|
||||
|
||||
(def background-view
|
||||
(defn background-view
|
||||
[theme]
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:left 0
|
||||
:right 0
|
||||
:height navigation-bar-height
|
||||
:background-color (colors/theme-colors colors/white-opa-70 :transparent)
|
||||
:background-color (colors/theme-colors colors/white-opa-70 colors/neutral-100-opa-70 theme)
|
||||
:display :flex
|
||||
:flex-direction :row
|
||||
:overflow :hidden})
|
||||
|
||||
(defn animated-background-view
|
||||
[enabled? animation]
|
||||
[enabled? animation theme]
|
||||
(reanimated/apply-animations-to-style
|
||||
(when enabled?
|
||||
{:opacity animation})
|
||||
background-view))
|
||||
(background-view theme)))
|
||||
|
||||
(def blur-view
|
||||
{:position :absolute
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns status-im2.contexts.chat.messages.navigation.view
|
||||
(:require [quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[re-frame.db]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
@@ -14,7 +15,7 @@
|
||||
[utils.i18n :as i18n]
|
||||
[status-im2.common.home.actions.view :as actions]))
|
||||
|
||||
(defn f-navigation-view
|
||||
(defn f-view
|
||||
[{:keys [scroll-y]}]
|
||||
(let [{:keys [group-chat chat-id chat-name emoji
|
||||
chat-type]
|
||||
@@ -55,7 +56,7 @@
|
||||
:extrapolateRight "clamp"})]
|
||||
[rn/view {:style style/navigation-view}
|
||||
[reanimated/view
|
||||
{:style (style/animated-background-view all-loaded? opacity-animation)}]
|
||||
{:style (style/animated-background-view all-loaded? opacity-animation nil)}]
|
||||
|
||||
[reanimated/view {:style (style/animated-blur-view all-loaded? opacity-animation)}
|
||||
[blur/view
|
||||
@@ -114,3 +115,9 @@
|
||||
:opacity-animation banner-opacity-animation
|
||||
:all-loaded? all-loaded?
|
||||
:top-offset style/navigation-bar-height}]]))
|
||||
|
||||
(defn- internal-navigation-view
|
||||
[params]
|
||||
[:f> f-view params])
|
||||
|
||||
(def navigation-view (theme/with-theme internal-navigation-view))
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
{:cover-bg-color :turquoise
|
||||
:chat chat
|
||||
:header-comp (fn [{:keys [scroll-y]}]
|
||||
[:f>
|
||||
messages.navigation/f-navigation-view
|
||||
{:scroll-y scroll-y}])
|
||||
[messages.navigation/navigation-view {:scroll-y scroll-y}])
|
||||
:footer-comp (fn [{:keys [insets]}]
|
||||
(if-not able-to-send-message?
|
||||
[contact-requests.bottom-drawer/view chat-id contact-request-state
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
[quo/user-avatar
|
||||
{:full-name name
|
||||
:profile-picture profile-picture
|
||||
:override-theme :dark
|
||||
:size :medium
|
||||
:status-indicator? false
|
||||
:customization-color customization-color}]]
|
||||
|
||||
@@ -17,13 +17,6 @@
|
||||
{:label "Blur:"
|
||||
:key :blur?
|
||||
:type :boolean}
|
||||
{:label "Override Theme:"
|
||||
:key :override-theme
|
||||
:type :select
|
||||
:options [{:key :dark
|
||||
:value "Dark"}
|
||||
{:key :light
|
||||
:value "Light"}]}
|
||||
{:label "Error:"
|
||||
:key :error?
|
||||
:type :boolean}
|
||||
@@ -65,7 +58,6 @@
|
||||
[]
|
||||
(let [state (reagent/atom {:type :text
|
||||
:blur false
|
||||
:override-theme nil
|
||||
:placeholder "Type something"
|
||||
:error false
|
||||
:icon-name false
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
[status-im2.contexts.quo-preview.settings.settings-list :as settings-list]
|
||||
[status-im2.contexts.quo-preview.settings.privacy-option :as privacy-option]
|
||||
[status-im2.contexts.quo-preview.settings.reorder-item :as reorder-item]
|
||||
[status-im2.contexts.quo-preview.settings.category :as category]
|
||||
[status-im2.contexts.quo-preview.share.qr-code :as qr-code]
|
||||
[status-im2.contexts.quo-preview.share.share-qr-code :as share-qr-code]
|
||||
[status-im2.contexts.quo-preview.switcher.switcher-cards :as switcher-cards]
|
||||
@@ -97,7 +98,6 @@
|
||||
[status-im2.contexts.quo-preview.wallet.network-amount :as network-amount]
|
||||
[status-im2.contexts.quo-preview.wallet.network-breakdown :as network-breakdown]
|
||||
[status-im2.contexts.quo-preview.wallet.token-overview :as token-overview]
|
||||
[status-im2.contexts.quo-preview.settings.category :as category]
|
||||
[status-im2.contexts.quo-preview.keycard.keycard :as keycard]
|
||||
[status-im2.contexts.quo-preview.loaders.skeleton :as skeleton]
|
||||
[status-im2.contexts.quo-preview.community.channel-actions :as channel-actions]))
|
||||
|
||||
@@ -77,11 +77,10 @@
|
||||
"did something here."])
|
||||
|
||||
(def complex-user-action
|
||||
(let [tag-props {:color :purple
|
||||
:override-theme :dark
|
||||
:size :small
|
||||
:style {:background-color colors/white-opa-10}
|
||||
:text-style {:color colors/white}}]
|
||||
(let [tag-props {:color :purple
|
||||
:size :small
|
||||
:style {:background-color colors/white-opa-10}
|
||||
:text-style {:color colors/white}}]
|
||||
[[quo2/user-avatar-tag tag-props "Alice"]
|
||||
"from"
|
||||
[quo2/user-avatar-tag tag-props "Mainnet"]
|
||||
|
||||
@@ -6,60 +6,91 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
|
||||
(def item
|
||||
{:title "Item 1"
|
||||
:left-icon :i/browser
|
||||
:chevron? true})
|
||||
(defn create-item-array
|
||||
[n {:keys [right-icon? image? subtitle?]}]
|
||||
(vec (for [i (range n)]
|
||||
{:title (str "Item " i)
|
||||
:subtitle (when subtitle? "subtitle")
|
||||
:chevron? true
|
||||
:right-icon (when right-icon? :i/globe)
|
||||
:left-icon :i/browser
|
||||
:image-size (if image? 32 0)
|
||||
:image (when image? (resources/get-mock-image :diamond))})))
|
||||
|
||||
(def descriptor
|
||||
[{:label "Category label:"
|
||||
:key :label
|
||||
:type :text}
|
||||
{:label "Category size:"
|
||||
:key :size
|
||||
:type :text}
|
||||
(def reorder-descriptor
|
||||
[{:label "Right icon:"
|
||||
:key :right-icon?
|
||||
:type :boolean}
|
||||
{:label "Image:"
|
||||
:key :image?
|
||||
:type :boolean}
|
||||
{:label "Subtitle:"
|
||||
:key :subtitle?
|
||||
:type :boolean}
|
||||
{:label "Blur:"
|
||||
:key :blur?
|
||||
:type :boolean}])
|
||||
:type :boolean}
|
||||
{:label "List type:"
|
||||
:key :list-type
|
||||
:type :select
|
||||
:options [{:key :settings :value :settings} {:key :reorder :value :reorder}]}])
|
||||
|
||||
(def image-uri
|
||||
"https://4kwallpapers.com/images/wallpapers/giau-pass-mountain-pass-italy-dolomites-landscape-mountain-750x1334-4282.jpg")
|
||||
|
||||
(def label "Label")
|
||||
(def settings-descriptor
|
||||
[{:label "Blur:"
|
||||
:key :blur?
|
||||
:type :boolean}
|
||||
{:label "List type:"
|
||||
:key :list-type
|
||||
:type :select
|
||||
:options [{:key :settings :value :settings} {:key :reorder :value :reorder}]}])
|
||||
|
||||
(defn preview
|
||||
[]
|
||||
(let [state (reagent/atom {:label "Label"
|
||||
:size "5"
|
||||
:blur? false})
|
||||
(let [state (reagent/atom {:label "Label"
|
||||
:size "5"
|
||||
:blur? false
|
||||
:right-icon? true
|
||||
:image? true
|
||||
:subtitle? true
|
||||
:list-type :settings})
|
||||
{:keys [width height]} (rn/get-window)]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [data (repeat (js/parseInt (:size @state)) item)]
|
||||
(rn/use-effect (fn []
|
||||
(if (:blur? @state)
|
||||
(theme/set-theme :dark)
|
||||
(theme/set-theme :light)))
|
||||
[(:blur? @state)])
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
[rn/view
|
||||
{:style {:flex 1
|
||||
:padding-bottom 150
|
||||
:margin-bottom 50
|
||||
:background-color (colors/theme-colors colors/neutral-5 colors/neutral-95)}}
|
||||
[rn/view
|
||||
{:style {:min-height 180
|
||||
:z-index 1}} [preview/customizer state descriptor]]
|
||||
(when (:blur? @state)
|
||||
[fast-image/fast-image
|
||||
{:source {:uri image-uri}
|
||||
:style {:width width
|
||||
:height height
|
||||
:position :absolute}}])
|
||||
[rn/view
|
||||
{:style {:background-color (if (:blur? @state)
|
||||
colors/neutral-80-opa-80
|
||||
(colors/theme-colors colors/neutral-5 colors/neutral-95))}}
|
||||
[quo/category {:label (:label @state) :data data :blur? (:blur? @state)}]]]]))]))
|
||||
(fn []
|
||||
(let [data (reagent/atom (create-item-array (max (js/parseInt (:size @state)) 1) @state))]
|
||||
[:f>
|
||||
(fn []
|
||||
(rn/use-effect (fn []
|
||||
(if (:blur? @state)
|
||||
(theme/set-theme :dark)
|
||||
(theme/set-theme :light))
|
||||
(reset! data (create-item-array (max (js/parseInt (:size @state)) 1)
|
||||
@state)))
|
||||
[(:blur? @state) (:right-icon? @state) (:image? @state) (:subtitle? @state)])
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
[rn/view
|
||||
{:style {:flex 1
|
||||
:padding-bottom 150
|
||||
:margin-bottom 50
|
||||
:background-color (colors/theme-colors colors/neutral-5 colors/neutral-95)}}
|
||||
[rn/view
|
||||
{:style {:min-height 200
|
||||
:z-index 1}}
|
||||
[preview/customizer state
|
||||
(if (= (:list-type @state) :settings) settings-descriptor reorder-descriptor)]]
|
||||
(when (:blur? @state)
|
||||
[fast-image/fast-image
|
||||
{:source (resources/get-mock-image :dark-blur-bg)
|
||||
:style {:width width
|
||||
:height height
|
||||
:position :absolute}}])
|
||||
[rn/view
|
||||
{:style {:background-color (if (:blur? @state)
|
||||
colors/neutral-80-opa-80
|
||||
(colors/theme-colors colors/neutral-5 colors/neutral-95))}}
|
||||
[quo/category
|
||||
{:list-type (:list-type @state)
|
||||
:label (:label @state)
|
||||
:data @data
|
||||
:blur? (:blur? @state)}]]]])]))))
|
||||
|
||||
@@ -11,13 +11,12 @@
|
||||
[]
|
||||
(let [unread-filter-enabled? (rf/sub [:activity-center/filter-status-unread-enabled?])]
|
||||
[quo/filter
|
||||
{:pressed? unread-filter-enabled?
|
||||
:blur? true
|
||||
:override-theme :dark
|
||||
:on-press-out #(rf/dispatch [:activity-center.notifications/fetch-first-page
|
||||
{:filter-status (if unread-filter-enabled?
|
||||
:all
|
||||
:unread)}])}]))
|
||||
{:pressed? unread-filter-enabled?
|
||||
:blur? true
|
||||
:on-press-out #(rf/dispatch [:activity-center.notifications/fetch-first-page
|
||||
{:filter-status (if unread-filter-enabled?
|
||||
:all
|
||||
:unread)}])}]))
|
||||
|
||||
(defn header
|
||||
[]
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
(def tag-params
|
||||
{:size :small
|
||||
:override-theme :dark
|
||||
:color colors/primary-50
|
||||
:style style/user-avatar-tag
|
||||
:text-style style/user-avatar-tag-text
|
||||
@@ -20,11 +19,10 @@
|
||||
[user-id]
|
||||
(let [{:keys [primary-name] :as contact} (rf/sub [:contacts/contact-by-identity user-id])]
|
||||
[quo/user-avatar-tag
|
||||
{:color :purple
|
||||
:override-theme :dark
|
||||
:size :small
|
||||
:style style/user-avatar-tag
|
||||
:text-style style/user-avatar-tag-text}
|
||||
{:color :purple
|
||||
:size :small
|
||||
:style style/user-avatar-tag
|
||||
:text-style style/user-avatar-tag-text}
|
||||
primary-name
|
||||
(multiaccounts/displayed-photo contact)]))
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
[utils.datetime :as datetime]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.contexts.chat.messages.content.image.view :as image]))
|
||||
[status-im.utils.http :as http]))
|
||||
|
||||
;; NOTE: Replies support text, image and stickers only.
|
||||
(defn- get-message-content
|
||||
@@ -19,7 +19,11 @@
|
||||
constants/content-type-text [quo/text {:style style/tag-text}
|
||||
(get-in message [:content :text])]
|
||||
|
||||
constants/content-type-image [image/image-message 0 message nil]
|
||||
constants/content-type-image
|
||||
(let [image (get-in message [:content :image])
|
||||
image-local-url (http/replace-port image (rf/sub [:mediaserver/port]))
|
||||
photos (when image-local-url [{:uri image-local-url}])]
|
||||
[quo/activity-logs-photos {:photos photos}])
|
||||
|
||||
constants/content-type-sticker [old-message/sticker message]
|
||||
|
||||
@@ -72,4 +76,19 @@
|
||||
[quo/context-tag common/tag-params community-image community-name chat-name]
|
||||
[quo/group-avatar-tag chat-name common/tag-params])]
|
||||
:message {:body-number-of-lines 1
|
||||
:attachment (cond
|
||||
(= (:content-type message) constants/content-type-text)
|
||||
:text
|
||||
|
||||
(= (:content-type message) constants/content-type-image)
|
||||
:photo
|
||||
|
||||
(= (:content-type message) constants/content-type-sticker)
|
||||
:sticker
|
||||
|
||||
(= (:content-type message) constants/content-type-gif)
|
||||
:gif
|
||||
|
||||
:else
|
||||
nil)
|
||||
:body (get-message-content message)}}]]]))
|
||||
|
||||
@@ -38,15 +38,13 @@
|
||||
shell.constants/community-card
|
||||
(case (:type community-info)
|
||||
:pending [quo/status-tag
|
||||
{:status {:type :pending}
|
||||
:label (i18n/label :t/pending)
|
||||
:size :small
|
||||
:override-theme :dark}]
|
||||
{:status {:type :pending}
|
||||
:label (i18n/label :t/pending)
|
||||
:size :small}]
|
||||
:kicked [quo/status-tag
|
||||
{:status {:type :negative}
|
||||
:size :small
|
||||
:override-theme :dark
|
||||
:label (i18n/label :t/kicked)}]
|
||||
{:status {:type :negative}
|
||||
:size :small
|
||||
:label (i18n/label :t/kicked)}]
|
||||
(:count :permission) [:<>] ;; Add components for these cases
|
||||
nil)
|
||||
|
||||
@@ -69,8 +67,8 @@
|
||||
[quo/preview-list
|
||||
{:type :photo
|
||||
:more-than-99-label (i18n/label :counter-99-plus)
|
||||
:size 24
|
||||
:override-theme :dark} data]
|
||||
:size 24}
|
||||
data]
|
||||
|
||||
constants/content-type-sticker
|
||||
[fast-image/fast-image
|
||||
@@ -262,12 +260,11 @@
|
||||
[rn/view {:style style/avatar-container}
|
||||
[avatar avatar-params type customization-color]])
|
||||
[quo/button
|
||||
{:size 24
|
||||
:type :grey
|
||||
:icon true
|
||||
:on-press #(rf/dispatch [:shell/close-switcher-card id])
|
||||
:override-theme :dark
|
||||
:style style/close-button}
|
||||
{:size 24
|
||||
:type :grey
|
||||
:icon true
|
||||
:on-press #(rf/dispatch [:shell/close-switcher-card id])
|
||||
:style style/close-button}
|
||||
:i/close]]]))))
|
||||
|
||||
;; browser Card
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
:type :blur-bg
|
||||
:size 32
|
||||
:accessibility-label :close-shell-share-tab
|
||||
:override-theme :dark
|
||||
:style style/header-button
|
||||
:on-press #(rf/dispatch [:navigate-back])}
|
||||
:i/close]
|
||||
@@ -84,7 +83,6 @@
|
||||
:type :blur-bg
|
||||
:size 32
|
||||
:accessibility-label :link-to-profile
|
||||
:override-theme :dark
|
||||
:on-press #(list-selection/open-share {:message profile-url})}
|
||||
:i/share]]]]
|
||||
|
||||
@@ -113,7 +111,6 @@
|
||||
:type :blur-bg
|
||||
:size 32
|
||||
:accessibility-label :link-to-profile
|
||||
:override-theme :dark
|
||||
:style {:margin-right 12}
|
||||
:on-press #(rf/dispatch [:share/copy-text-and-show-toast
|
||||
{:text-to-copy emoji-hash-string
|
||||
@@ -137,7 +134,6 @@
|
||||
[quo/segmented-control
|
||||
{:size 28
|
||||
:blur? true
|
||||
:override-theme :dark
|
||||
:on-change #(reset! selected-tab %)
|
||||
:default-active :profile
|
||||
:data [{:id :profile
|
||||
|
||||
@@ -77,29 +77,37 @@
|
||||
:top (- (+ (:y viewfinder) (:height viewfinder)) flash-button-size flash-button-spacing)
|
||||
:right (+ screen-padding flash-button-spacing)})
|
||||
|
||||
(defn border
|
||||
[border1 border2 corner]
|
||||
(assoc {:border-color colors/white
|
||||
:width 78
|
||||
:height 78}
|
||||
border1
|
||||
2
|
||||
border2
|
||||
2
|
||||
corner
|
||||
16))
|
||||
(defn- get-border
|
||||
[border-vertical-width border-horizontal-width corner-radius]
|
||||
{:border-color colors/white
|
||||
:width 78
|
||||
:height 78
|
||||
border-vertical-width 2
|
||||
border-horizontal-width 2
|
||||
corner-radius 16})
|
||||
|
||||
(defn border-tip
|
||||
[top bottom right left]
|
||||
{:background-color colors/white
|
||||
:position :absolute
|
||||
:top top
|
||||
:bottom bottom
|
||||
:right right
|
||||
:left left
|
||||
:height 2
|
||||
:width 2
|
||||
:border-radius 2})
|
||||
(def white-border
|
||||
(let [base-tip {:background-color colors/white
|
||||
:position :absolute
|
||||
:height 1.9 ; 1.9 instead of 2 to fix the tips protruding
|
||||
:width 1.9
|
||||
:border-radius 1}]
|
||||
{:top-left
|
||||
{:border (get-border :border-top-width :border-left-width :border-top-left-radius)
|
||||
:tip-1 (assoc base-tip :right -1 :top 0)
|
||||
:tip-2 (assoc base-tip :left 0 :bottom -1)}
|
||||
:top-right
|
||||
{:border (get-border :border-top-width :border-right-width :border-top-right-radius)
|
||||
:tip-1 (assoc base-tip :right 0 :bottom -1)
|
||||
:tip-2 (assoc base-tip :left -1 :top 0)}
|
||||
:bottom-left
|
||||
{:border (get-border :border-bottom-width :border-left-width :border-bottom-left-radius)
|
||||
:tip-1 (assoc base-tip :right -1 :bottom 0)
|
||||
:tip-2 (assoc base-tip :left 0 :top -1)}
|
||||
:bottom-right
|
||||
{:border (get-border :border-bottom-width :border-right-width :border-bottom-right-radius)
|
||||
:tip-1 (assoc base-tip :right 0 :top -1)
|
||||
:tip-2 (assoc base-tip :left -1 :bottom 0)}}))
|
||||
|
||||
(def viewfinder-text
|
||||
{:color colors/white-opa-70
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
[]
|
||||
(rf/dispatch [:syncing/preflight-outbound-check #(reset! preflight-check-passed? %)]))
|
||||
|
||||
(defn- f-header
|
||||
(defn- header
|
||||
[{:keys [active-tab read-qr-once? title title-opacity subtitle-opacity reset-animations-fn animated?]}]
|
||||
(let [subtitle-translate-x (reanimated/interpolate subtitle-opacity [0 1] [-13 0])
|
||||
subtitle-translate-y (reanimated/interpolate subtitle-opacity [0 1] [-85 0])
|
||||
@@ -54,7 +54,6 @@
|
||||
:type :blur-bg
|
||||
:size 32
|
||||
:accessibility-label :close-sign-in-by-syncing
|
||||
:override-theme :dark
|
||||
:on-press (fn []
|
||||
(if (and animated? reset-animations-fn)
|
||||
(reset-animations-fn)
|
||||
@@ -70,7 +69,6 @@
|
||||
:type :blur-bg
|
||||
:size 32
|
||||
:accessibility-label :find-sync-code
|
||||
:override-theme :dark
|
||||
:on-press #(rf/dispatch [:open-modal :find-sync-code])}
|
||||
(i18n/label :t/find-sync-code)]]]
|
||||
[reanimated/view
|
||||
@@ -101,7 +99,6 @@
|
||||
style/tabs-container)}
|
||||
[quo/segmented-control
|
||||
{:size 32
|
||||
:override-theme :dark
|
||||
:blur? true
|
||||
:default-active @active-tab
|
||||
:data [{:id 1 :label (i18n/label :t/scan-sync-qr-code)}
|
||||
@@ -110,10 +107,6 @@
|
||||
(reset! active-tab id)
|
||||
(reset! read-qr-once? false))}]]]))
|
||||
|
||||
(defn- header
|
||||
[props]
|
||||
[:f> f-header props])
|
||||
|
||||
(defn get-labels-and-on-press-method
|
||||
[]
|
||||
(if @camera-permission-granted?
|
||||
@@ -155,7 +148,6 @@
|
||||
:type :primary
|
||||
:size 32
|
||||
:accessibility-label accessibility-label
|
||||
:override-theme :dark
|
||||
:customization-color :blue
|
||||
:on-press on-press}
|
||||
(i18n/label button-label)]]))
|
||||
@@ -169,55 +161,42 @@
|
||||
view-finder (assoc layout :height (:width layout))]
|
||||
(reset! qr-view-finder view-finder)))}])
|
||||
|
||||
(defn- border
|
||||
[border1 border2 corner]
|
||||
[rn/view {:style (style/border border1 border2 corner)}])
|
||||
(defn- white-border
|
||||
[corner]
|
||||
(let [border-styles (style/white-border corner)]
|
||||
[rn/view
|
||||
[rn/view {:style (border-styles :border)}]
|
||||
[rn/view {:style (border-styles :tip-1)}]
|
||||
[rn/view {:style (border-styles :tip-2)}]]))
|
||||
|
||||
(defn- border-tip
|
||||
[{:keys [top bottom left right]}]
|
||||
[rn/view
|
||||
{:style (style/border-tip top bottom right left)}])
|
||||
(defn- white-square
|
||||
[layout-size]
|
||||
[rn/view {:style (style/qr-view-finder-container layout-size)}
|
||||
[rn/view {:style style/view-finder-border-container}
|
||||
[white-border :top-left]
|
||||
[white-border :top-right]]
|
||||
[rn/view {:style style/view-finder-border-container}
|
||||
[white-border :bottom-left]
|
||||
[white-border :bottom-right]]])
|
||||
|
||||
(defn- viewfinder
|
||||
[qr-view-finder]
|
||||
(let [size (+ (:width qr-view-finder) 2)]
|
||||
[:<>
|
||||
[rn/view {:style (style/viewfinder-container qr-view-finder)}
|
||||
[rn/view
|
||||
{:style (style/qr-view-finder-container size)}
|
||||
[rn/view
|
||||
{:style style/view-finder-border-container}
|
||||
[rn/view
|
||||
[border :border-top-width :border-left-width :border-top-left-radius]
|
||||
[border-tip {:right -1 :top 0}]
|
||||
[border-tip {:left 0 :bottom -1}]]
|
||||
[rn/view
|
||||
[border :border-top-width :border-right-width :border-top-right-radius]
|
||||
[border-tip {:right 0 :bottom -1}]
|
||||
[border-tip {:left -1 :top 0}]]]
|
||||
[rn/view {:flex-direction :row :justify-content :space-between}
|
||||
[rn/view
|
||||
[border :border-bottom-width :border-left-width :border-bottom-left-radius]
|
||||
[border-tip {:right -1 :bottom 0}]
|
||||
[border-tip {:left 0 :top -1}]]
|
||||
[rn/view
|
||||
[border :border-bottom-width :border-right-width :border-bottom-right-radius]
|
||||
[border-tip {:right 0 :top -1}]
|
||||
[border-tip {:left -1 :bottom 0}]]]]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :regular
|
||||
:style style/viewfinder-text}
|
||||
(i18n/label :t/ensure-qr-code-is-in-focus-to-scan)]]]))
|
||||
(let [layout-size (+ (:width qr-view-finder) 2)]
|
||||
[rn/view {:style (style/viewfinder-container qr-view-finder)}
|
||||
[white-square layout-size]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :regular
|
||||
:style style/viewfinder-text}
|
||||
(i18n/label :t/ensure-qr-code-is-in-focus-to-scan)]]))
|
||||
|
||||
(defn- scan-qr-code-tab
|
||||
[qr-view-finder]
|
||||
[:<>
|
||||
(if (and @preflight-check-passed?
|
||||
@camera-permission-granted?
|
||||
(boolean (not-empty @qr-view-finder)))
|
||||
[viewfinder @qr-view-finder]
|
||||
[camera-and-local-network-access-permission-view])])
|
||||
(if (and @preflight-check-passed?
|
||||
@camera-permission-granted?
|
||||
(boolean (not-empty qr-view-finder)))
|
||||
[viewfinder qr-view-finder]
|
||||
[camera-and-local-network-access-permission-view]))
|
||||
|
||||
(defn- enter-sync-code-tab
|
||||
[]
|
||||
@@ -273,8 +252,7 @@
|
||||
:on-read-code on-read-code}]]
|
||||
[hole-view/hole-view
|
||||
{:style style/hole
|
||||
:holes [(merge qr-view-finder
|
||||
{:borderRadius 16})]}
|
||||
:holes [(assoc qr-view-finder :borderRadius 16)]}
|
||||
[blur/view
|
||||
{:style style/absolute-fill
|
||||
:blur-amount 10
|
||||
@@ -388,7 +366,7 @@
|
||||
(when (or (not animated?) @render-camera?)
|
||||
[render-camera show-camera? torch-mode @qr-view-finder camera-ref on-read-code])
|
||||
[rn/view {:style (style/root-container (:top insets))}
|
||||
[header
|
||||
[:f> header
|
||||
{:active-tab active-tab
|
||||
:read-qr-once? read-qr-once?
|
||||
:title title
|
||||
@@ -406,7 +384,7 @@
|
||||
:transform [{:translate-y content-translate-y}]}
|
||||
{})}
|
||||
(case @active-tab
|
||||
1 [scan-qr-code-tab qr-view-finder]
|
||||
1 [scan-qr-code-tab @qr-view-finder]
|
||||
2 [enter-sync-code-tab]
|
||||
nil)]
|
||||
[rn/view {:style style/flex-spacer}]
|
||||
|
||||
@@ -115,7 +115,6 @@
|
||||
[quo/input
|
||||
{:default-value @code
|
||||
:type :password
|
||||
:override-theme :dark
|
||||
:default-shown? true
|
||||
:editable false}]
|
||||
[quo/button
|
||||
|
||||
@@ -26,19 +26,17 @@
|
||||
|
||||
:button-grey
|
||||
[quo/button
|
||||
{:type :grey
|
||||
:override-theme :dark
|
||||
:size 24
|
||||
:style style/button-grey}
|
||||
{:type :grey
|
||||
:size 24
|
||||
:style style/button-grey}
|
||||
(i18n/label value)]
|
||||
|
||||
:button-grey-placeholder
|
||||
[quo/button
|
||||
{:type :grey
|
||||
:override-theme :dark
|
||||
:size 24
|
||||
:before :i/placeholder
|
||||
:style style/button-grey-placeholder}
|
||||
{:type :grey
|
||||
:size 24
|
||||
:before :i/placeholder
|
||||
:style style/button-grey-placeholder}
|
||||
(i18n/label value)]
|
||||
|
||||
:context-tag
|
||||
@@ -111,7 +109,6 @@
|
||||
[rn/view {:style style/tabs-container}
|
||||
[quo/segmented-control
|
||||
{:size 28
|
||||
:override-theme :dark
|
||||
:blur? true
|
||||
:default-active :mobile
|
||||
:data platform-data
|
||||
|
||||
@@ -88,13 +88,11 @@
|
||||
:component add-new-contact/new-contact}
|
||||
|
||||
{:name :how-to-pair
|
||||
:options {:theme :dark
|
||||
:sheet? true}
|
||||
:options (assoc options/dark-screen :sheet? true)
|
||||
:component how-to-pair/view}
|
||||
|
||||
{:name :find-sync-code
|
||||
:options {:theme :dark
|
||||
:sheet? true}
|
||||
:options (assoc options/dark-screen :sheet? true)
|
||||
:component find-sync-code/view}
|
||||
|
||||
{:name :discover-communities
|
||||
|
||||
@@ -56,14 +56,15 @@
|
||||
members (re-frame/subscribe [:communities/community-members community-id])]
|
||||
[contacts multiaccount members]))
|
||||
(fn [[contacts multiaccount members] _]
|
||||
(let [names (reduce (fn [acc identity]
|
||||
(let [me? (= (:public-key multiaccount) identity)
|
||||
(let [names (reduce (fn [acc contact-identity]
|
||||
(let [me? (= (:public-key multiaccount) contact-identity)
|
||||
contact (when-not me?
|
||||
(multiaccounts/contact-by-identity contacts identity))
|
||||
name (first (multiaccounts/contact-two-names-by-identity contact
|
||||
multiaccount
|
||||
identity))]
|
||||
(assoc acc identity name)))
|
||||
(multiaccounts/contact-by-identity contacts contact-identity))
|
||||
name (first (multiaccounts/contact-two-names-by-identity
|
||||
contact
|
||||
multiaccount
|
||||
contact-identity))]
|
||||
(assoc acc contact-identity name)))
|
||||
{}
|
||||
(keys members))]
|
||||
(->> members
|
||||
@@ -95,10 +96,9 @@
|
||||
:<- [:view-id]
|
||||
:<- [:communities]
|
||||
:<- [:communities/my-pending-requests-to-join]
|
||||
;; Return communities splitted by level of user participation. Some communities user
|
||||
;; already joined, to some of them join request sent and others were opened one day
|
||||
;; and their data remained in app-db.
|
||||
;; Result map has form: {:joined [id1, id2] :pending [id3, id5] :opened [id4]}"
|
||||
;; Return communities splitted by level of user participation. Some communities user already
|
||||
;; joined, to some of them join request sent and others were opened one day and their data remained
|
||||
;; in app-db. Result map has form: {:joined [id1, id2] :pending [id3, id5] :opened [id4]}"
|
||||
(fn [[view-id communities requests]]
|
||||
(if (or (empty? @memo-communities-stack-items) (= view-id :communities-stack))
|
||||
(let [grouped-communities (reduce (fn [acc community]
|
||||
@@ -128,9 +128,9 @@
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:communities])
|
||||
(re-frame/subscribe [:communities/unviewed-counts community-id])])
|
||||
(fn [[communities counts] [_ identity]]
|
||||
(fn [[communities counts] [_ community-identity]]
|
||||
(community->home-item
|
||||
(get communities identity)
|
||||
(get communities community-identity)
|
||||
counts)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
@@ -288,12 +288,12 @@
|
||||
(let [check-criteria (get-in token-permissions-check
|
||||
[:permissions perm-key :criteria])]
|
||||
(map
|
||||
(fn [{:keys [symbol amount]} sufficient?]
|
||||
{:symbol symbol
|
||||
(fn [{sym :symbol amount :amount} sufficient?]
|
||||
{:symbol sym
|
||||
:sufficient? (when (seq check-criteria) sufficient?)
|
||||
:loading? checking-permissions?
|
||||
:amount amount
|
||||
:img-src (get token-images symbol)})
|
||||
:img-src (get token-images sym)})
|
||||
token_criteria
|
||||
(or check-criteria token_criteria))))
|
||||
token-permissions)}))
|
||||
|
||||
@@ -32,16 +32,16 @@
|
||||
(get multiaccount :profile-pictures-visibility)))
|
||||
|
||||
(defn- replace-contact-image-uri
|
||||
[contact port identity]
|
||||
[contact port contact-identity]
|
||||
(let [theme (theme/get-theme)
|
||||
contact-images (:images contact)
|
||||
contact-images (reduce (fn [acc image]
|
||||
(let [image-name (:type image)
|
||||
; We pass the clock so that we reload the image if the image is
|
||||
; updated
|
||||
; We pass the clock so that we reload the image if the image
|
||||
; is updated
|
||||
clock (:clock image)
|
||||
uri (image-server/get-contact-image-uri port
|
||||
identity
|
||||
contact-identity
|
||||
image-name
|
||||
clock
|
||||
theme)]
|
||||
@@ -175,10 +175,10 @@
|
||||
contacts)))))
|
||||
|
||||
(defn- enrich-contact
|
||||
[_ identity ens-name port]
|
||||
[_ contact-identity ens-name port]
|
||||
(let [contact (contact.db/enrich-contact
|
||||
(contact.db/public-key-and-ens-name->new-contact identity ens-name))]
|
||||
(replace-contact-image-uri contact port identity)))
|
||||
(contact.db/public-key-and-ens-name->new-contact contact-identity ens-name))]
|
||||
(replace-contact-image-uri contact port contact-identity)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/current-contact
|
||||
@@ -186,46 +186,46 @@
|
||||
:<- [:contacts/current-contact-identity]
|
||||
:<- [:contacts/current-contact-ens-name]
|
||||
:<- [:mediaserver/port]
|
||||
(fn [[contacts identity ens-name port]]
|
||||
(let [contact (get contacts identity)]
|
||||
(fn [[contacts contact-identity ens-name port]]
|
||||
(let [contact (get contacts contact-identity)]
|
||||
(cond-> contact
|
||||
(nil? contact)
|
||||
(enrich-contact identity ens-name port)))))
|
||||
(enrich-contact contact-identity ens-name port)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contact-by-identity
|
||||
:<- [:contacts/contacts]
|
||||
(fn [contacts [_ identity]]
|
||||
(multiaccounts/contact-by-identity contacts identity)))
|
||||
(fn [contacts [_ contact-identity]]
|
||||
(multiaccounts/contact-by-identity contacts contact-identity)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contact-added?
|
||||
(fn [[_ identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-by-identity identity])])
|
||||
(fn [[_ contact-identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-by-identity contact-identity])])
|
||||
(fn [[contact] _]
|
||||
(:added? contact)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contact-blocked?
|
||||
(fn [[_ identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-by-identity identity])])
|
||||
(fn [[_ contact-identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-by-identity contact-identity])])
|
||||
(fn [[contact] _]
|
||||
(:blocked contact)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contact-two-names-by-identity
|
||||
(fn [[_ identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-by-identity identity])
|
||||
(fn [[_ contact-identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-by-identity contact-identity])
|
||||
(re-frame/subscribe [:profile/profile])])
|
||||
(fn [[contact current-multiaccount] [_ identity]]
|
||||
(fn [[contact current-multiaccount] [_ contact-identity]]
|
||||
(multiaccounts/contact-two-names-by-identity contact
|
||||
current-multiaccount
|
||||
identity)))
|
||||
contact-identity)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/contact-name-by-identity
|
||||
(fn [[_ identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-two-names-by-identity identity])])
|
||||
(fn [[_ contact-identity] _]
|
||||
[(re-frame/subscribe [:contacts/contact-two-names-by-identity contact-identity])])
|
||||
(fn [[names] _]
|
||||
(first names)))
|
||||
|
||||
@@ -236,21 +236,21 @@
|
||||
:<- [:profile/profile]
|
||||
(fn [[messages contacts current-multiaccount] [_ message-id]]
|
||||
(when-let [message (get messages message-id)]
|
||||
(let [identity (:from message)
|
||||
me? (= (:public-key current-multiaccount) identity)]
|
||||
(let [from-identity (:from message)
|
||||
me? (= (:public-key current-multiaccount) from-identity)]
|
||||
(if me?
|
||||
{:quote {:from identity
|
||||
{:quote {:from from-identity
|
||||
:text (get-in message [:content :text])}
|
||||
:ens-name (:preferred-name current-multiaccount)
|
||||
:alias (gfycat/generate-gfy identity)}
|
||||
(let [contact (or (contacts identity)
|
||||
(contact.db/public-key->new-contact identity))]
|
||||
{:quote {:from identity
|
||||
:alias (gfycat/generate-gfy from-identity)}
|
||||
(let [contact (or (contacts from-identity)
|
||||
(contact.db/public-key->new-contact from-identity))]
|
||||
{:quote {:from from-identity
|
||||
:text (get-in message [:content :text])}
|
||||
:ens-name (when (:ens-verified contact)
|
||||
(:name contact))
|
||||
:alias (or (:alias contact)
|
||||
(gfycat/generate-gfy identity))}))))))
|
||||
(gfycat/generate-gfy from-identity))}))))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:contacts/all-contacts-not-in-current-chat
|
||||
@@ -323,5 +323,3 @@
|
||||
(seq admins) (assoc :owner {:title (i18n/label :t/owner) :data admins})
|
||||
(seq online) (assoc :online {:title (i18n/label :t/online) :data online})
|
||||
(seq offline) (assoc :offline {:title (i18n/label :t/offline) :data offline}))))))
|
||||
|
||||
|
||||
|
||||
@@ -52,8 +52,7 @@
|
||||
|
||||
(defn extract-token-attributes
|
||||
[token]
|
||||
(let [{:keys [symbol name]} token]
|
||||
[symbol name]))
|
||||
[(:symbol token) (:name token)])
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/filtered-grouped-chain-tokens
|
||||
|
||||
@@ -54,10 +54,10 @@
|
||||
:<- [:prices]
|
||||
:<- [:wallet/currency]
|
||||
:<- [:ethereum/native-currency]
|
||||
(fn [[prices {:keys [code]} {:keys [symbol]}]]
|
||||
[(name symbol)
|
||||
(fn [[prices {:keys [code]} {sym :symbol}]]
|
||||
[(name sym)
|
||||
code
|
||||
(get-in prices [symbol (keyword code)])]))
|
||||
(get-in prices [sym (keyword code)])]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:signing/priority-fee-suggestions-range
|
||||
@@ -131,8 +131,8 @@
|
||||
:else nil))))
|
||||
|
||||
(defn get-sufficient-funds-error
|
||||
[balance symbol amount]
|
||||
(when-not (money/sufficient-funds? amount (get balance symbol))
|
||||
[balance sym amount]
|
||||
(when-not (money/sufficient-funds? amount (get balance sym))
|
||||
{:amount-error (i18n/label :t/wallet-insufficient-funds)}))
|
||||
|
||||
(defn gas-required-exceeds-allowance?
|
||||
@@ -143,11 +143,11 @@
|
||||
"gas required exceeds allowance")))
|
||||
|
||||
(defn get-sufficient-gas-error
|
||||
[gas-error-message balance symbol amount ^js gas ^js gasPrice]
|
||||
[gas-error-message balance sym amount ^js gas ^js gasPrice]
|
||||
(if (and gas gasPrice)
|
||||
(let [^js fee (.times gas gasPrice)
|
||||
^js available-ether (money/bignumber (get balance :ETH 0))
|
||||
^js available-for-gas (if (= :ETH symbol)
|
||||
^js available-for-gas (if (= :ETH sym)
|
||||
(.minus available-ether (money/bignumber amount))
|
||||
available-ether)]
|
||||
(merge {:gas-error-state (when gas-error-message :gas-is-set)}
|
||||
@@ -186,17 +186,18 @@
|
||||
:<- [:offline?]
|
||||
:<- [:wallet/all-tokens]
|
||||
:<- [:current-network]
|
||||
(fn [[{:keys [symbol from to amount-text] :as transaction}
|
||||
(fn [[{:keys [from to amount-text] :as transaction}
|
||||
wallet offline? all-tokens current-network]]
|
||||
(let [balance (get-in wallet [:accounts (:address from) :balance])
|
||||
{:keys [decimals] :as token} (tokens/asset-for all-tokens current-network symbol)
|
||||
(let [sym (:symbol transaction)
|
||||
balance (get-in wallet [:accounts (:address from) :balance])
|
||||
{:keys [decimals] :as token} (tokens/asset-for all-tokens current-network sym)
|
||||
{:keys [value error]} (wallet.db/parse-amount amount-text decimals)
|
||||
amount (money/formatted->internal value symbol decimals)
|
||||
amount (money/formatted->internal value sym decimals)
|
||||
{:keys [amount-error] :as transaction-new}
|
||||
(merge transaction
|
||||
{:amount-error error}
|
||||
(when amount
|
||||
(get-sufficient-funds-error balance symbol amount)))]
|
||||
(get-sufficient-funds-error balance sym amount)))]
|
||||
(assoc transaction-new
|
||||
:amount amount
|
||||
:balance balance
|
||||
@@ -213,12 +214,13 @@
|
||||
:<- [:offline?]
|
||||
:<- [:wallet/all-tokens]
|
||||
:<- [:current-network]
|
||||
(fn [[{:keys [symbol from to amount-text] :as transaction}
|
||||
(fn [[{:keys [from to amount-text] :as transaction}
|
||||
wallet offline? all-tokens current-network]]
|
||||
(let [balance (get-in wallet [:accounts (:address from) :balance])
|
||||
{:keys [decimals] :as token} (tokens/asset-for all-tokens current-network symbol)
|
||||
(let [sym (:symbol transaction)
|
||||
balance (get-in wallet [:accounts (:address from) :balance])
|
||||
{:keys [decimals] :as token} (tokens/asset-for all-tokens current-network sym)
|
||||
{:keys [value error]} (wallet.db/parse-amount amount-text decimals)
|
||||
amount (money/formatted->internal value symbol decimals)
|
||||
amount (money/formatted->internal value sym decimals)
|
||||
{:keys [amount-error] :as transaction-new}
|
||||
(assoc transaction :amount-error error)]
|
||||
(assoc transaction-new
|
||||
|
||||
@@ -44,14 +44,14 @@
|
||||
[to :to-contact :from-wallet])
|
||||
wallet (i18n/label :main-wallet)
|
||||
contact (get contacts contact-address)
|
||||
{:keys [symbol-display symbol decimals] :as asset}
|
||||
{:keys [symbol-display decimals] :as asset}
|
||||
(or token native-currency)
|
||||
amount-text (if value
|
||||
(wallet.utils/format-amount value decimals)
|
||||
"...")
|
||||
currency-text (when asset
|
||||
(clojure.core/name (or symbol-display
|
||||
symbol)))]
|
||||
(:symbol asset))))]
|
||||
(cond-> transaction
|
||||
contact (assoc key-contact (:name contact))
|
||||
:always (assoc key-wallet
|
||||
|
||||
@@ -61,10 +61,10 @@
|
||||
|
||||
(defn get-balance-total-value
|
||||
[balance prices currency token->decimals]
|
||||
(reduce-kv (fn [acc symbol value]
|
||||
(if-let [price (get-in prices [symbol currency])]
|
||||
(reduce-kv (fn [acc sym value]
|
||||
(if-let [price (get-in prices [sym currency])]
|
||||
(+ acc
|
||||
(or (some-> (money/internal->formatted value symbol (token->decimals symbol))
|
||||
(or (some-> (money/internal->formatted value sym (token->decimals sym))
|
||||
^js (money/crypto->fiat price)
|
||||
.toNumber)
|
||||
0))
|
||||
@@ -193,13 +193,14 @@
|
||||
|
||||
(defn update-value
|
||||
[prices currency]
|
||||
(fn [{:keys [symbol decimals amount] :as token}]
|
||||
(let [currency-kw (-> currency :code keyword)
|
||||
price (get-in prices [symbol currency-kw])]
|
||||
(fn [{:keys [decimals amount] :as token}]
|
||||
(let [sym (:symbol token)
|
||||
currency-kw (-> currency :code keyword)
|
||||
price (get-in prices [sym currency-kw])]
|
||||
(assoc token
|
||||
:price price
|
||||
:value (when (and amount price)
|
||||
(-> (money/internal->formatted amount symbol decimals)
|
||||
(-> (money/internal->formatted amount sym decimals)
|
||||
(money/crypto->fiat price)
|
||||
(money/with-precision 2)
|
||||
str
|
||||
|
||||
@@ -155,14 +155,14 @@
|
||||
;; to get the amount scale right.
|
||||
|
||||
(defn formatted->internal
|
||||
[n symbol decimals]
|
||||
(if (= :ETH symbol)
|
||||
[n sym decimals]
|
||||
(if (= :ETH sym)
|
||||
(ether->wei n)
|
||||
(unit->token n decimals)))
|
||||
|
||||
(defn internal->formatted
|
||||
[n symbol decimals]
|
||||
(if (= :ETH symbol)
|
||||
[n sym decimals]
|
||||
(if (= :ETH sym)
|
||||
(wei->ether n)
|
||||
(token->unit n decimals)))
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
(def ^:private mergeable-keys (atom nil))
|
||||
|
||||
(defn set-mergeable-keys
|
||||
[val]
|
||||
(reset! mergeable-keys val))
|
||||
[v]
|
||||
(reset! mergeable-keys v))
|
||||
|
||||
(defn- safe-merge
|
||||
[fx new-fx]
|
||||
|
||||
@@ -1401,10 +1401,9 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
|
||||
chat.long_press_element()
|
||||
if self.home_1.mute_chat_button.text != transl["unmute-chat"]:
|
||||
self.errors.append("Chat is not muted")
|
||||
# ToDo: enable the next check when https://github.com/status-im/status-mobile/issues/16768 is fixed
|
||||
# expected_text = "%s %s" % (transl["muted-until"], transl["until-you-turn-it-back-on"])
|
||||
# if not self.home_1.element_by_text(expected_text).is_element_displayed():
|
||||
# self.errors.append("Text '%s' is not shown for muted chat" %expected_text)
|
||||
expected_text = "Muted until you turn it back on"
|
||||
if not self.home_1.element_by_text(expected_text).is_element_displayed():
|
||||
self.errors.append("Text '%s' is not shown for muted chat" %expected_text)
|
||||
self.home_1.mute_chat_button.click()
|
||||
|
||||
unmuted_message = "after unmute"
|
||||
|
||||
@@ -558,11 +558,10 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
|
||||
chat.long_press_element()
|
||||
if self.homes[1].mute_chat_button.text != transl["unmute-chat"]:
|
||||
self.errors.append("Chat is not muted")
|
||||
# ToDo: enable the next check when https://github.com/status-im/status-mobile/issues/16768 is fixed
|
||||
# # expected_text = "Muted until %s today" % device_time + 1
|
||||
# expected_text = "%s %s" % (transl["muted-until"], transl["until-you-turn-it-back-on"])
|
||||
# if not self.homes[1].element_by_text(expected_text).is_element_displayed():
|
||||
# self.errors.append("Text '%s' is not shown for muted chat" % expected_text)
|
||||
# expected_text = "Muted until %s today" % device_time + 1
|
||||
expected_text = "Muted until you turn it back on"
|
||||
if not self.homes[1].element_by_text(expected_text).is_element_displayed():
|
||||
self.errors.append("Text '%s' is not shown for muted chat" % expected_text)
|
||||
self.chats[1].just_fyi("Member 1 unmutes the chat")
|
||||
# self.chats[1].just_fyi("Close app and change device time so chat will be unmuted by timer")
|
||||
# self.homes[1].put_app_to_background()
|
||||
|
||||
@@ -349,6 +349,22 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
|
||||
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
@marks.testrail_id(702869)
|
||||
def test_community_undo_delete_message(self):
|
||||
if not self.channel.chat_message_input.is_element_displayed():
|
||||
self.home.click_system_back_button_until_element_is_shown()
|
||||
self.home.get_to_community_channel_from_home(self.community_name)
|
||||
message_to_delete = "message to delete and undo"
|
||||
self.channel.send_message(message_to_delete)
|
||||
self.channel.delete_message_in_chat(message_to_delete)
|
||||
self.channel.element_by_text("Undo").click()
|
||||
try:
|
||||
self.channel.chat_element_by_text(message_to_delete).wait_for_visibility_of_element()
|
||||
except TimeoutException:
|
||||
pytest.fail("Message was not restored by clicking 'Undo' button")
|
||||
if self.channel.element_starts_with_text("Message deleted").is_element_displayed():
|
||||
pytest.fail("Text about deleted message is shown in the chat")
|
||||
|
||||
@marks.testrail_id(703382)
|
||||
def test_community_mute_community_and_channel(self):
|
||||
self.home.jump_to_communities_home()
|
||||
@@ -386,7 +402,7 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
|
||||
device_time = self.home.driver.device_time
|
||||
current_time = datetime.datetime.strptime(device_time, "%Y-%m-%dT%H:%M:%S%z")
|
||||
expected_time = current_time + datetime.timedelta(days=7)
|
||||
expected_text = "Muted until %s" % expected_time.strftime('%H:%M %a %d %b')
|
||||
expected_text = "Muted until %s" % expected_time.strftime('%H:%M %a %-d %b')
|
||||
self.community_view.get_channel(self.channel_name).long_press_element()
|
||||
if not self.home.element_by_text(expected_text).is_element_displayed():
|
||||
self.errors.append("Text '%s' is not shown for a muted community channel" % expected_text)
|
||||
@@ -402,21 +418,17 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
@marks.testrail_id(703133)
|
||||
@marks.xfail(reason="Restoring communities issue: 16787; "
|
||||
"restoring contacts issue: 15500",
|
||||
run=False)
|
||||
def test_restore_multiaccount_with_waku_backup_remove_switch(self):
|
||||
self.home.jump_to_communities_home()
|
||||
profile = self.home.profile_button.click()
|
||||
profile.logout()
|
||||
self.home.just_fyi("Restore user with predefined communities and contacts")
|
||||
self.sign_in.recover_access(passphrase=waku_user.seed, second_user=True)
|
||||
|
||||
self.home.just_fyi("Restore user with predefined communities, check communities")
|
||||
self.home.communities_tab.click()
|
||||
for key in ['admin_open', 'member_open', 'admin_closed', 'member_closed']:
|
||||
if not self.home.element_by_text(waku_user.communities[key]).is_element_displayed(30):
|
||||
self.errors.append("%s was not restored from waku-backup!!" % key)
|
||||
# TODO: there is a bug when pending community sometimes restored as joined; needs investigation
|
||||
# self.home.opened_communities_tab.click()
|
||||
# if not self.home.element_by_text(waku_user.communities['member_pending']).is_element_displayed(30):
|
||||
# self.errors.append("Pending community %s was not restored from waku-backup!" % waku_user.communities['member_pending'])
|
||||
self.home.just_fyi("Restore user with predefined communities and contacts")
|
||||
|
||||
self.home.just_fyi("Check contacts/blocked users")
|
||||
self.home.chats_tab.click()
|
||||
@@ -433,23 +445,33 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
|
||||
if shown_name_text in waku_user.contacts:
|
||||
waku_user.contacts.remove(shown_name_text)
|
||||
continue
|
||||
else:
|
||||
contact_row.click()
|
||||
shown_name_text = profile.default_username_text.text
|
||||
if shown_name_text in waku_user.contacts:
|
||||
waku_user.contacts.remove(shown_name_text)
|
||||
continue
|
||||
else:
|
||||
chat = self.home.get_chat_view()
|
||||
chat.profile_send_message_button.click()
|
||||
for name in waku_user.contacts:
|
||||
if chat.element_starts_with_text(name).is_element_displayed(sec=20):
|
||||
waku_user.contacts.remove(name)
|
||||
continue
|
||||
# else:
|
||||
# contact_row.click()
|
||||
# shown_name_text = profile.default_username_text.text
|
||||
# if shown_name_text in waku_user.contacts:
|
||||
# waku_user.contacts.remove(shown_name_text)
|
||||
# continue
|
||||
# else:
|
||||
# chat = self.home.get_chat_view()
|
||||
# chat.profile_send_message_button.click()
|
||||
# for name in waku_user.contacts:
|
||||
# if chat.element_starts_with_text(name).is_element_displayed(sec=20):
|
||||
# waku_user.contacts.remove(name)
|
||||
# continue
|
||||
if waku_user.contacts:
|
||||
self.errors.append(
|
||||
"Contact(s) was (were) not restored from backup: %s!" % ", ".join(waku_user.contacts))
|
||||
|
||||
self.home.just_fyi("Check restored communities")
|
||||
self.home.communities_tab.click()
|
||||
for key in ['admin_open', 'member_open', 'admin_closed', 'member_closed']:
|
||||
if not self.home.element_by_text(waku_user.communities[key]).is_element_displayed(30):
|
||||
self.errors.append("%s was not restored from waku-backup!!" % key)
|
||||
# TODO: there is a bug when pending community sometimes restored as joined; needs investigation
|
||||
# self.home.opened_communities_tab.click()
|
||||
# if not self.home.element_by_text(waku_user.communities['member_pending']).is_element_displayed(30):
|
||||
# self.errors.append("Pending community %s was not restored from waku-backup!" % waku_user.communities['member_pending'])
|
||||
|
||||
if not pytest_config_global['pr_number']:
|
||||
self.home.just_fyi("Perform back up")
|
||||
self.home.click_system_back_button_until_element_is_shown()
|
||||
@@ -498,7 +520,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
|
||||
'username': self.username_1}),
|
||||
(self.device_2.create_user, {'username': self.username_2}))))
|
||||
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||
self.public_key_2 = self.home_2.get_public_key()
|
||||
self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
|
||||
self.profile_1 = self.home_1.get_profile_view()
|
||||
[home.click_system_back_button_until_element_is_shown() for home in self.homes]
|
||||
[home.chats_tab.click() for home in self.homes]
|
||||
|
||||
@@ -19,7 +19,8 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
|
||||
(self.device_2.create_user, {'username': self.username_2}))))
|
||||
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
|
||||
self.profile_1, self.profile_2 = self.home_1.get_profile_view(), self.home_2.get_profile_view()
|
||||
self.public_key_1, self.public_key_2 = (home.get_public_key() for home in self.homes)
|
||||
self.public_key_1 = self.home_1.get_public_key()
|
||||
self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
|
||||
[home.click_system_back_button_until_element_is_shown() for home in self.homes]
|
||||
[home.chats_tab.click() for home in self.homes]
|
||||
|
||||
@@ -78,9 +79,22 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
|
||||
|
||||
@marks.testrail_id(702851)
|
||||
def test_activity_center_contact_request_accept_swipe_mark_all_as_read(self):
|
||||
self.device_2.just_fyi('Device2 re-sends a contact request to Device1')
|
||||
self.device_2.just_fyi('Creating a new user on Device2')
|
||||
self.home_2.jump_to_messages_home()
|
||||
self.home_2.add_contact(self.public_key_1, remove_from_contacts=True)
|
||||
self.home_2.profile_button.click()
|
||||
self.profile_2.logout()
|
||||
new_username = "new user"
|
||||
self.device_2.create_user(second_user=True, username=new_username)
|
||||
|
||||
self.device_2.just_fyi('Device2 sends a contact request to Device1 via Paste button and check user details')
|
||||
self.home_2.driver.set_clipboard_text(self.public_key_1)
|
||||
self.home_2.new_chat_button.click_until_presence_of_element(self.home_2.add_a_contact_chat_bottom_sheet_button)
|
||||
self.home_2.add_a_contact_chat_bottom_sheet_button.click()
|
||||
self.home_2.element_by_translation_id("paste").click()
|
||||
self.home_2.element_by_translation_id("user-found").wait_for_visibility_of_element(10)
|
||||
chat = self.home_2.get_chat_view()
|
||||
chat.view_profile_new_contact_button.click_until_presence_of_element(chat.profile_block_contact_button)
|
||||
chat.profile_add_to_contacts_button.click()
|
||||
|
||||
self.device_1.just_fyi('Device1 accepts pending contact request by swiping')
|
||||
self.home_1.chats_tab.click()
|
||||
@@ -88,7 +102,7 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
|
||||
self.home_1.open_activity_center_button.click()
|
||||
|
||||
self.home_1.just_fyi("Mark all as read")
|
||||
cr_element = self.home_1.get_element_from_activity_center_view(self.username_2)
|
||||
cr_element = self.home_1.get_element_from_activity_center_view(new_username)
|
||||
self.home_1.more_options_activity_button.click()
|
||||
self.home_1.mark_all_read_activity_button.click()
|
||||
if cr_element.is_element_displayed():
|
||||
@@ -100,7 +114,7 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
|
||||
self.home_1.activity_notification_swipe_button.click_inside_element_by_coordinate(rel_x=0.5, rel_y=0.5)
|
||||
self.home_1.close_activity_centre.click()
|
||||
self.home_1.contacts_tab.click()
|
||||
if not self.home_1.contact_details_row(username=self.username_2).is_element_displayed(20):
|
||||
if not self.home_1.contact_details_row(username=new_username).is_element_displayed(20):
|
||||
self.errors.append("Contact was not added to contact list after accepting contact request (as receiver)")
|
||||
|
||||
self.device_2.just_fyi('Device1 check that contact appeared in contact list mutually')
|
||||
|
||||
@@ -7,5 +7,6 @@ communities = {
|
||||
'member_closed': 'test_comm_enc',
|
||||
'member_pending': 'RC1 testing community'
|
||||
}
|
||||
contacts = ['Test_contact', 'MyCustomNickname']
|
||||
blocked_user = 'Clear Flat Milkweedbug'
|
||||
# contacts = ['Test_contact', 'MyCustomNickname'] # enable back when https://github.com/status-im/status-mobile/issues/15500 is fixed
|
||||
contacts = ['Used Bulky Wirehair', 'Vengeful Healthy Arcticseal']
|
||||
blocked_user = 'Clear Flat Milkweedbug'
|
||||
|
||||
@@ -240,6 +240,7 @@ class HomeView(BaseView):
|
||||
# Notification centre
|
||||
self.notifications_button = Button(self.driver, accessibility_id="notifications-button")
|
||||
self.notifications_unread_badge = BaseElement(self.driver, accessibility_id="activity-center-unread-count")
|
||||
self.show_qr_code_button = Button(self.driver, accessibility_id="show-qr-button")
|
||||
self.open_activity_center_button = Button(self.driver, accessibility_id="open-activity-center-button")
|
||||
self.close_activity_centre = Button(self.driver, accessibility_id="close-activity-center")
|
||||
|
||||
@@ -313,6 +314,11 @@ class HomeView(BaseView):
|
||||
self.more_options_activity_button = Button(self.driver, accessibility_id="activity-center-open-more")
|
||||
self.mark_all_read_activity_button = Button(self.driver, translation_id="mark-all-notifications-as-read")
|
||||
|
||||
# Share tab
|
||||
self.link_to_profile_text = Text(
|
||||
self.driver,
|
||||
xpath="(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]")
|
||||
|
||||
def wait_for_syncing_complete(self):
|
||||
self.driver.info('Waiting for syncing to complete')
|
||||
while True:
|
||||
@@ -518,3 +524,11 @@ class HomeView(BaseView):
|
||||
|
||||
def get_contact_rows_count(self):
|
||||
return len(ContactDetailsRow(self.driver).find_elements())
|
||||
|
||||
def get_public_key_via_share_profile_tab(self):
|
||||
self.driver.info("Getting public key via Share tab")
|
||||
self.show_qr_code_button.click()
|
||||
self.link_to_profile_text.click()
|
||||
c_text = self.driver.get_clipboard_text()
|
||||
self.click_system_back_button()
|
||||
return c_text.split("/")[-1]
|
||||
|
||||
@@ -224,7 +224,11 @@ class SignInView(BaseView):
|
||||
username="test user"):
|
||||
self.driver.info("## Creating new multiaccount (password:'%s', keycard:'%s', enable_notification: '%s')" %
|
||||
(password, str(keycard), str(enable_notifications)), device=False)
|
||||
if not second_user:
|
||||
if second_user:
|
||||
self.show_profiles_button.wait_and_click(20)
|
||||
self.plus_profiles_button.click()
|
||||
self.create_new_profile_button.click()
|
||||
else:
|
||||
self.i_m_new_in_status_button.click_until_presence_of_element(self.generate_keys_button)
|
||||
self.generate_keys_button.click_until_presence_of_element(self.profile_your_name_edit_box)
|
||||
self.set_profile(username)
|
||||
|
||||
@@ -76,6 +76,8 @@ jest.mock('react-native-blob-util', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('react-native-reanimated', () => require('react-native-reanimated/mock'));
|
||||
|
||||
NativeModules.ReactLocalization = {
|
||||
language: 'en',
|
||||
locale: 'en',
|
||||
|
||||
@@ -8813,10 +8813,12 @@ react-native-dialogs@^1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/react-native-dialogs/-/react-native-dialogs-1.1.0.tgz#8f7ee7f9d96574fc878fb7c1be101611fb4af517"
|
||||
integrity sha512-clnxO0nMyML/6+G5dja3Yt34gPxegLY2OHTwb8BwYTEvQ2UhRKR49Uq91XqU0q6g7Ur9DiYxC0tqV3rcZWUrjQ==
|
||||
|
||||
react-native-draggable-flatlist@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/react-native-draggable-flatlist/-/react-native-draggable-flatlist-3.0.3.tgz#e85503585253be01ad251f78d5b341ac22f9d952"
|
||||
integrity sha512-bDro6aqQMvvTm/CuHre9dAjSBKosAfZRLDx3nmrjOz799kxcn0bq+uCB6yF6m+g1Xd/gVPl7E3Ss4uX+oPUlHg==
|
||||
react-native-draggable-flatlist@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-native-draggable-flatlist/-/react-native-draggable-flatlist-4.0.1.tgz#2f027d387ba4b8f3eb0907340e32cb85e6460df2"
|
||||
integrity sha512-ZO1QUTNx64KZfXGXeXcBfql67l38X7kBcJ3rxUVZzPHt5r035GnGzIC0F8rqSXp6zgnwgUYMfB6zQc5PKmPL9Q==
|
||||
dependencies:
|
||||
"@babel/preset-typescript" "^7.17.12"
|
||||
|
||||
react-native-fast-image@^8.5.11:
|
||||
version "8.5.11"
|
||||
|
||||
Reference in New Issue
Block a user