Compare commits

..
Author SHA1 Message Date
Omar Basem dd7c8b9363 update blur 2023-03-06 14:11:38 +04:00
Omar Basem 1942a320fa fix prop name 2023-03-06 13:59:23 +04:00
Omar Basem cd8622a7f6 lint 2023-03-06 13:59:23 +04:00
Omar Basem c5aa75c925 feat: activity centre animations
updates

updates

updates

updates

updates

updates

updates

updates
2023-03-06 13:59:23 +04:00
93 changed files with 1231 additions and 1081 deletions
@@ -28,4 +28,12 @@
<item name="android:textColorPrimary">@color/alert_text</item>
<item name="android:background">@color/alert_background</item>
</style>
<style name="Theme.FullScreenDialog">
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
</resources>
+2 -8
View File
@@ -228,8 +228,6 @@ PODS:
- React-Core
- react-native-netinfo (4.7.0):
- React
- react-native-orientation-locker (1.5.0):
- React-Core
- react-native-randombytes (3.6.1):
- React-Core
- react-native-safe-area-context (2.0.0):
@@ -240,7 +238,7 @@ PODS:
- React
- react-native-status (1.0.0):
- React
- react-native-status-keycard (2.5.39):
- react-native-status-keycard (2.5.38):
- Keycard
- React
- react-native-webview (11.16.0):
@@ -435,7 +433,6 @@ DEPENDENCIES:
- react-native-lottie-splash-screen (from `../node_modules/react-native-lottie-splash-screen`)
- react-native-mail (from `../node_modules/react-native-mail`)
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
- react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
- react-native-randombytes (from `../node_modules/react-native-randombytes`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- react-native-shake (from `../node_modules/react-native-shake`)
@@ -548,8 +545,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-mail"
react-native-netinfo:
:path: "../node_modules/@react-native-community/netinfo"
react-native-orientation-locker:
:path: "../node_modules/react-native-orientation-locker"
react-native-randombytes:
:path: "../node_modules/react-native-randombytes"
react-native-safe-area-context:
@@ -671,13 +666,12 @@ SPEC CHECKSUMS:
react-native-lottie-splash-screen: 068688c15dd478301fda00f8d87d7fb7d5b9a93e
react-native-mail: 8fdcd3aef007c33a6877a18eb4cf7447a1d4ce4a
react-native-netinfo: ddaca8bbb9e6e914b1a23787ccb879bc642931c9
react-native-orientation-locker: 851f6510d8046ea2f14aa169b1e01fcd309a94ba
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
react-native-safe-area-context: 60f654e00b6cc416573f6d5dbfce3839958eb57a
react-native-shake: de052eaa3eadc4a326b8ddd7ac80c06e8d84528c
react-native-slider: 12bd76d3d568c9c5500825db54123d44b48e4ad4
react-native-status: 21f75d492fd311dc111303da38a7a2b23a8a8466
react-native-status-keycard: f1c1227b2d5984c10fb44db68e4bfd2937f31e98
react-native-status-keycard: f60ca57d789aad6875c64ece81ab06ef0609e0d3
react-native-webview: 28a8636d97ee641f2ee8f20492d7a6c269c1d703
React-RCTActionSheet: e911b99f0d6fa7711ffc2f62d236b12a32771835
React-RCTAnimation: ad8b853170a059faf31d6add34f67d22391bbe01
@@ -1139,6 +1139,11 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
executeRunnableStatusGoMethod(() -> Statusgo.generateAlias(seed), callback);
}
@ReactMethod
public void emojiHash(final String publicKey, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.emojiHash(publicKey), callback);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String identicon(final String seed) {
return Statusgo.identicon(seed);
@@ -866,6 +866,12 @@ RCT_EXPORT_METHOD(generateAliasAsync:(NSString *)publicKey
callback(@[result]);
}
RCT_EXPORT_METHOD(emojiHash:(NSString *)publicKey
callback:(RCTResponseSenderBlock)callback) {
NSString *result = StatusgoEmojiHash(publicKey);
callback(@[result]);
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(identicon:(NSString *)publicKey) {
return StatusgoIdenticon(publicKey);
}
+1
View File
@@ -60,6 +60,7 @@
"react-native-linear-gradient": "^2.5.6",
"react-native-lottie-splash-screen": "^1.0.1",
"react-native-mail": "^6.1.1",
"react-native-modal": "^13.0.1",
"react-native-navigation": "^7.27.1",
"react-native-orientation-locker": "^1.5.0",
"react-native-permissions": "^2.1.5",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 788 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 2.4 MiB

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

+4
View File
@@ -338,6 +338,9 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
(clj->js {:default #js {}
:useDeviceOrientationChange #js {}}))
(def react-native-modal
(clj->js {:default #js {}}))
(def wallet-connect-client
#js
{:default #js {}
@@ -404,6 +407,7 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
"@react-native-async-storage/async-storage" async-storage
"react-native-svg" react-native-svg
"react-native-orientation-locker" react-native-orientation-locker
"react-native-modal" react-native-modal
"../src/js/worklet_factory.js" worklet-factory
"../src/js/shell_worklets.js" shell-worklets
"../src/js/bottom_sheet.js" bottom-sheet
@@ -1,6 +1,6 @@
(ns quo2.components.animated-header-flatlist.style
(:require [quo2.foundations.colors :as colors]
[react-native.reanimated :as ra]))
[react-native.reanimated :as reanimated]))
(defn container-view
[view-height]
@@ -27,7 +27,7 @@
(defn blur-view
[animation]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:opacity animation}
{:position :absolute
:top 0
@@ -39,7 +39,7 @@
(defn entity-picture
[animation]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:width animation
:height animation}
{:transform [{:scale 1}]
@@ -54,7 +54,7 @@
(defn header-bottom-part
[animation]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:border-top-right-radius animation
:border-top-left-radius animation}
{:position :absolute
@@ -66,9 +66,9 @@
(defn header-comp
[y-animation opacity-animation]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
;; here using `left` won't work on Android, so we are using `translateX`
{:transform [{:translateX (ra/use-val 64)} {:translateY y-animation}]
{:transform [{:translateX (reanimated/use-shared-value 64)} {:translateY y-animation}]
:opacity opacity-animation}
{:position :absolute
:z-index 3}))
@@ -3,7 +3,7 @@
[quo2.core :as quo]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[react-native.fast-image :as fast-image]
[reagent.core :as reagent]
@@ -18,16 +18,16 @@
(defn interpolate
[value input-range output-range]
(ra/interpolate value
input-range
output-range
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"}))
(reanimated/interpolate value
input-range
output-range
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"}))
(defn scroll-handler
[event initial-y scroll-y]
(let [current-y (- (oops/oget event "nativeEvent.contentOffset.y") initial-y)]
(ra/set-val scroll-y current-y)))
(reanimated/set-shared-value scroll-y current-y)))
(defn header
[{:keys [theme-color display-picture-comp cover-uri title-comp]} top-inset scroll-y]
@@ -45,9 +45,9 @@
{:style {:width "100%"
:height cover-height}
:source {:uri cover-uri}}])
[ra/view {:style (style/header-bottom-part border-animation)}
[reanimated/view {:style (style/header-bottom-part border-animation)}
[title-comp]]
[ra/view {:style (style/entity-picture size-animation)}
[reanimated/view {:style (style/entity-picture size-animation)}
[display-picture-comp image-animation]]]))
(defn animated-header-list
@@ -64,7 +64,7 @@
initial-y (if platform/ios? (- (:top insets)) 0)]
[:f>
(fn []
(let [scroll-y (ra/use-val initial-y)
(let [scroll-y (reanimated/use-shared-value initial-y)
opacity-animation (interpolate scroll-y
[(* threshold 0.33) (* threshold 0.66)]
[0 1])
@@ -80,14 +80,14 @@
{:active-opacity 1
:style (style/button-container {:right 20})}
[quo/icon :i/options {:size 20 :color (colors/theme-colors colors/black colors/white)}]]
[ra/blur-view
[reanimated/blur-view
{:blurAmount 32
:blurType :light
:overlayColor (if platform/ios? colors/white-opa-70 :transparent)
:style (style/blur-view opacity-animation)}
[ra/view {:style (style/header-comp translate-animation title-opacity-animation)}
[reanimated/view {:style (style/header-comp translate-animation title-opacity-animation)}
[header-comp]]]
[ra/flat-list
[reanimated/flat-list
{:data [nil]
:render-fn main-comp
:key-fn str
@@ -5,8 +5,8 @@
[react-native.core :as rn]))
(defn community-card-view-item
[{:keys [name description locked images cover
status tokens tags width]} on-press]
[{:keys [name description locked images
status tokens cover tags width]} on-press]
[rn/touchable-without-feedback
{:accessibility-label :community-card-item
:on-press on-press}
@@ -18,16 +18,16 @@
:on-press on-press}
[rn/view
{:flex 1}
[rn/view (style/community-cover-container 60)
[rn/view (style/community-cover-container 40)
[rn/image
{:source cover
:style
{:flex 1
:border-top-right-radius 20
:border-top-left-radius 20}}]]
{:flex 1
:border-radius 20}}]]
[rn/view (style/card-view-content-container 12)
[rn/view (style/card-view-chat-icon 48)
[icon/community-icon {:images images} 48]]
(when (= status :gated)
[rn/view (style/permission-tag-styles)
[community-view/permission-tag-container
@@ -42,15 +42,16 @@
(defn community-tags
[tags]
[rn/view (style/community-tags-container)
(for [{:keys [name emoji]} tags]
^{:key name}
(for [{:keys [id tag-label resource]} tags]
^{:key id}
[rn/view {:margin-right 8}
[tag/tag
{:size 24
:label name
{:id id
:size 24
:label tag-label
:type :emoji
:labelled? true
:resource emoji}]])])
:resource resource}]])])
(defn community-title
[{:keys [title description size] :or {size :small}}]
@@ -81,5 +82,6 @@
colors/neutral-80)
:locked? locked?
:tokens tokens
:size 24
:on-press on-press}])
+8 -12
View File
@@ -57,18 +57,14 @@
(defn card-view-content-container
[padding-horizontal]
{:position :absolute
:top 40
:bottom 0
:left 0
:right 0
:height 20
:padding-horizontal padding-horizontal
:border-top-right-radius 16
:border-top-left-radius 16
:background-color (colors/theme-colors
colors/white
colors/neutral-90)})
{:flex 1
:height 20
:padding-left padding-horizontal
:padding-right padding-horizontal
:border-radius 16
:background-color (colors/theme-colors
colors/white
colors/neutral-90)})
(defn card-view-chat-icon
[icon-size]
@@ -4,24 +4,22 @@
(def outer-container {:height 216})
(def top-card
{:flex 1
:padding-vertical 12
:padding-horizontal 20
:border-top-left-radius 20
:border-top-right-radius 20
:background-color colors/neutral-80})
{:flex 1
:padding-vertical 12
:padding-horizontal 20
:border-radius 20
:background-color colors/neutral-80})
(def bottom-card
{:position :absolute
:top 80
:left 0
:right 0
:bottom 0
:padding-vertical 12
:padding-horizontal 20
:border-top-left-radius 20
:border-top-right-radius 20
:background-color (colors/alpha colors/white 0.05)})
{:position :absolute
:top 80
:left 0
:right 0
:bottom 0
:padding-vertical 12
:padding-horizontal 20
:border-radius 20
:background-color (colors/alpha colors/white 0.05)})
(def bottom-container
{:flex-direction :row
@@ -39,14 +39,13 @@
children))
(defn card
[{:keys [on-press style heading gap accessibility-label top?]} children]
[{:keys [on-press style heading gap top?]} children]
[rn/touchable-highlight
{:accessibility-label accessibility-label
:on-press on-press
:border-radius 20
:style style
:underlay-color (:background-color style)}
[rn/view
{:on-press on-press
:border-radius 20
:style style
:underlay-color (:background-color style)}
[rn/view {}
[text/text
{:size :heading-1
:style (style/heading-text gap)
@@ -61,11 +60,9 @@
opts
{:container-style style-object
:top-card { :on-press event
:heading string
:accessibility-label keyword}
:heading string}
:bottom-card { :on-press event
:heading string
:accessibility-label keyword}}
:heading string}}
child-1 string, keyword or hiccup
child-2 string, keyword or hiccup
"
+9 -9
View File
@@ -3,16 +3,16 @@
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]))
(defn apply-anim
[dd-height val]
(ra/animate-delay dd-height
val
0
300
:easing1))
(reanimated/animate-shared-value-with-delay dd-height
val
300
:easing1
0))
(def sizes
{:big {:icon-size 20
@@ -141,7 +141,7 @@
[:f>
(fn []
(let [open? (reagent/atom false)
dd-height (ra/use-val 0)]
dd-height (reanimated/use-shared-value 0)]
[rn/view {:style {:flex-grow 1}}
[dropdown-comp
{:items items
@@ -155,8 +155,8 @@
:default-item default-item
:open? open?
:dd-height dd-height}]
[ra/view
{:style (ra/apply-animations-to-style
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:height dd-height}
{:height dd-height})}
[items-comp
+2 -2
View File
@@ -4,7 +4,7 @@
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]))
(def header-height 56)
@@ -162,7 +162,7 @@
border-bottom false}}]
(let [status-bar-height (get insets :top 0)
height (+ header-height status-bar-height)]
[ra/view
[reanimated/view
{:style (header-wrapper-style {:height height
:background background
:border-bottom border-bottom})}
+5 -5
View File
@@ -2,7 +2,7 @@
(:require [quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.masked-view :as masked-view]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]))
(def message-skeleton-height 54)
@@ -30,12 +30,12 @@
author-width (content-width :author)
message-width (content-width :message)
{window-width :width} (rn/use-window-dimensions)
translate-x (ra/use-val (- window-width))
animated-gradient-style (ra/apply-animations-to-style
translate-x (reanimated/use-shared-value (- window-width))
animated-gradient-style (reanimated/apply-animations-to-style
{:transform [{:translateX translate-x}]}
{:width window-width
:height "100%"})]
(ra/animate-repeat translate-x window-width (- 1) false 1000 :linear)
(reanimated/animate-shared-value-with-repeat translate-x window-width 1000 :linear (- 1) false)
[masked-view/masked-view
{:style {:height message-skeleton-height}
:maskElement (reagent/as-element
@@ -70,7 +70,7 @@
[rn/view
{:style {:flex 1
:background-color color}}
[ra/linear-gradient
[reanimated/linear-gradient
{:colors [color color loading-color color color]
:start {:x 0 :y 0}
:end {:x 1 :y 0}
@@ -5,7 +5,7 @@
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[utils.string :as utils]))
(def themes-landed
@@ -176,20 +176,20 @@
[{:keys [type style non-pressable? animate-landing? labels on-long-press] :as message}]
[:f>
(fn []
(let [sv-color (ra/use-val
(let [sv-color (reanimated/use-shared-value
(get-color :bg (if animate-landing? :landed :default) type))]
(when animate-landing?
(ra/animate-delay
(reanimated/animate-shared-value-with-delay
sv-color
(get-color :bg :default type)
1000
0
:linear))
[ra/touchable-opacity
:linear
1000))
[reanimated/touchable-opacity
{:on-press #(when-not non-pressable?
(ra/set-val sv-color (get-color :bg :pressed type)))
(reanimated/set-shared-value sv-color (get-color :bg :pressed type)))
:on-long-press on-long-press
:style (ra/apply-animations-to-style
:style (reanimated/apply-animations-to-style
{:background-color sv-color}
(merge
{:flex-direction :row
@@ -5,11 +5,11 @@
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.hole-view :as hole-view]
[react-native.reanimated :as ra]))
[react-native.reanimated :as reanimated]))
(defn toggle-background-color
[background-color press-out? pass-through?]
(ra/set-val
(reanimated/set-shared-value
background-color
(cond
press-out? "transparent"
@@ -31,14 +31,14 @@
on-press pass-through? icon-color-anim accessibility-label test-ID]}]
[:f>
(fn []
(let [icon-animated-style (ra/apply-animations-to-style
(let [icon-animated-style (reanimated/apply-animations-to-style
{:tint-color icon-color-anim}
{:width 24
:height 24
:margin-left 33
:margin-top 8})
background-color (ra/use-val "transparent")
background-animated-style (ra/apply-animations-to-style
background-color (reanimated/use-shared-value "transparent")
background-animated-style (reanimated/apply-animations-to-style
{:background-color background-color}
{:width 90
:height 40
@@ -49,7 +49,7 @@
:on-press-in #(toggle-background-color background-color false pass-through?)
:on-press-out #(toggle-background-color background-color true pass-through?)
:accessibility-label accessibility-label}
[ra/view {:style background-animated-style}
[reanimated/view {:style background-animated-style}
;; In android animations are not working for the animated components which are nested by
;; hole-view,
;; Interestingly this only happens when hole view and blur view are used together
@@ -69,10 +69,10 @@
:else
[{:x 47 :y 1 :width 18 :height 18 :borderRadius 7}])}
[ra/image
[reanimated/image
{:style icon-animated-style
:source (icons/icon-source (keyword (str icon 24)))}]]
[ra/image
[reanimated/image
{:style icon-animated-style
:source (icons/icon-source (keyword (str icon 24)))}])
(when new-notifications?
@@ -1,7 +1,7 @@
(ns quo2.components.navigation.floating-shell-button
(:require [quo2.components.buttons.dynamic-button :as dynamic-button]
[react-native.core :as rn]
[react-native.reanimated :as ra]))
[react-native.reanimated :as reanimated]))
(defn dynamic-button-view
[type dynamic-buttons style]
@@ -28,12 +28,12 @@
:margin-horizontal 12
:pointer-events :box-none}
style)
animated-style (ra/apply-animations-to-style
animated-style (reanimated/apply-animations-to-style
(if opacity-anim
{:opacity opacity-anim}
{})
original-style)]
[ra/view {:style animated-style}
[reanimated/view {:style animated-style}
;; Left Section
[rn/view {:style {:flex 1}}
[dynamic-button-view :search dynamic-buttons
@@ -2,7 +2,7 @@
(:require [quo2.components.icon :as icons]
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[react-native.core :refer [use-effect]]
[quo2.components.record-audio.record-audio.helpers :refer
[animate-linear-with-delay
@@ -14,14 +14,14 @@
[recording? ready-to-delete? reviewing-audio?]
[:f>
(fn []
(let [opacity (ra/use-val 0)
translate-x (ra/use-val 20)
scale (ra/use-val 1)
connector-opacity (ra/use-val 0)
connector-width (ra/use-val 24)
connector-height (ra/use-val 12)
border-radius-first-half (ra/use-val 8)
border-radius-second-half (ra/use-val 8)
(let [opacity (reanimated/use-shared-value 0)
translate-x (reanimated/use-shared-value 20)
scale (reanimated/use-shared-value 1)
connector-opacity (reanimated/use-shared-value 0)
connector-width (reanimated/use-shared-value 24)
connector-height (reanimated/use-shared-value 12)
border-radius-first-half (reanimated/use-shared-value 8)
border-radius-second-half (reanimated/use-shared-value 8)
start-x-animation (fn []
(animate-linear-with-delay translate-x 12 50 133.33)
(animate-easing-with-delay connector-opacity 1 0 93.33)
@@ -73,14 +73,14 @@
(reset-x-animation)))
[@ready-to-delete?])
[:<>
[ra/view {:style (style/delete-button-container opacity)}
[ra/view
[reanimated/view {:style (style/delete-button-container opacity)}
[reanimated/view
{:style (style/delete-button-connector connector-opacity
connector-width
connector-height
border-radius-first-half
border-radius-second-half)}]]
[ra/view
[reanimated/view
{:style (style/delete-button scale translate-x opacity)
:pointer-events :none}
[icons/icon :i/delete
@@ -2,7 +2,7 @@
(:require [quo2.components.icon :as icons]
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[react-native.core :refer [use-effect]]
[quo2.components.record-audio.record-audio.helpers :refer
[animate-linear-with-delay
@@ -14,13 +14,13 @@
[recording? ready-to-lock? locked?]
[:f>
(fn []
(let [translate-x-y (ra/use-val 20)
opacity (ra/use-val 0)
connector-opacity (ra/use-val 0)
width (ra/use-val 24)
height (ra/use-val 12)
border-radius-first-half (ra/use-val 8)
border-radius-second-half (ra/use-val 8)
(let [translate-x-y (reanimated/use-shared-value 20)
opacity (reanimated/use-shared-value 0)
connector-opacity (reanimated/use-shared-value 0)
width (reanimated/use-shared-value 24)
height (reanimated/use-shared-value 12)
border-radius-first-half (reanimated/use-shared-value 8)
border-radius-second-half (reanimated/use-shared-value 8)
start-x-y-animation (fn []
(animate-linear-with-delay translate-x-y 8 50 116.66)
(animate-easing-with-delay connector-opacity 1 0 80)
@@ -70,14 +70,14 @@
(reset-x-y-animation)))
[@locked?])
[:<>
[ra/view {:style (style/lock-button-container opacity)}
[ra/view
[reanimated/view {:style (style/lock-button-container opacity)}
[reanimated/view
{:style (style/lock-button-connector connector-opacity
width
height
border-radius-first-half
border-radius-second-half)}]]
[ra/view
[reanimated/view
{:style (style/lock-button translate-x-y opacity)
:pointer-events :none}
[icons/icon (if @ready-to-lock? :i/locked :i/unlocked)
@@ -3,7 +3,7 @@
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.core :as rn :refer [use-effect]]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[quo2.components.buttons.button :as button]
[quo2.components.record-audio.record-audio.helpers :refer [set-value]]))
@@ -11,7 +11,7 @@
[recording? reviewing-audio?]
[:f>
(fn []
(let [opacity (ra/use-val 1)
(let [opacity (reanimated/use-shared-value 1)
show-animation #(set-value opacity 1)
hide-animation #(set-value opacity 0)]
(use-effect (fn []
@@ -19,7 +19,7 @@
(hide-animation)
(show-animation)))
[@recording? @reviewing-audio?])
[ra/view {:style (style/record-button-container opacity)}
[reanimated/view {:style (style/record-button-container opacity)}
[button/button
{:type :outline
:size 32
@@ -3,7 +3,7 @@
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.core :as rn :refer [use-effect]]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[react-native.audio-toolkit :as audio]
[taoensso.timbre :as log]
[cljs-bean.core :as bean]
@@ -37,7 +37,7 @@
(fn [props]
(let [{:keys [scale opacity color]} (bean/bean props)]
(reagent/as-element
[ra/view {:style (style/animated-circle scale opacity color)}]))))))
[reanimated/view {:style (style/animated-circle scale opacity color)}]))))))
(defn record-button-big
[recording? ready-to-send? ready-to-lock? ready-to-delete? record-button-is-animating?
@@ -45,29 +45,29 @@
clear-timeout touch-active? recorder-ref reload-recorder-fn idle? on-send on-cancel]
[:f>
(fn []
(let [scale (ra/use-val 1)
opacity (ra/use-val 0)
(let [scale (reanimated/use-shared-value 1)
opacity (reanimated/use-shared-value 0)
opacity-from (if @ready-to-lock? opacity-from-lock opacity-from-default)
animations (map
(fn [index]
(let [ring-scale (ring-scale scale (* scale-padding index))]
{:scale ring-scale
:opacity (ra/interpolate ring-scale
[1 scale-to-each]
[opacity-from 0])}))
:opacity (reanimated/interpolate ring-scale
[1 scale-to-each]
[opacity-from 0])}))
(range 0 5))
rings-color (cond
@ready-to-lock? (colors/theme-colors colors/neutral-80-opa-5-opaque
colors/neutral-80)
@ready-to-delete? colors/danger-50
:else colors/primary-50)
translate-y (ra/use-val 0)
translate-x (ra/use-val 0)
translate-y (reanimated/use-shared-value 0)
translate-x (reanimated/use-shared-value 0)
button-color colors/primary-50
icon-color (if (and (not (colors/dark?)) @ready-to-lock?) colors/black colors/white)
icon-opacity (ra/use-val 1)
red-overlay-opacity (ra/use-val 0)
gray-overlay-opacity (ra/use-val 0)
icon-opacity (reanimated/use-shared-value 1)
red-overlay-opacity (reanimated/use-shared-value 0)
gray-overlay-opacity (reanimated/use-shared-value 0)
complete-animation (fn []
(cond
(and @ready-to-lock? (not @record-button-is-animating?))
@@ -114,7 +114,7 @@
signal-anim-duration)))
stop-animation (fn []
(set-value opacity 0)
(ra/cancel-animation scale)
(reanimated/cancel-animation scale)
(set-value scale 1)
(when @clear-timeout (js/clearTimeout @clear-timeout)))
start-y-animation (fn []
@@ -190,7 +190,7 @@
(start-x-animation)
(reset-x-animation)))
[@ready-to-delete?])
[ra/view
[reanimated/view
{:style (style/record-button-big-container translate-x translate-y opacity)
:pointer-events :none}
[:<>
@@ -203,9 +203,9 @@
:color rings-color}])
animations)]
[rn/view {:style (style/record-button-big-body button-color)}
[ra/view {:style (style/record-button-big-red-overlay red-overlay-opacity)}]
[ra/view {:style (style/record-button-big-gray-overlay gray-overlay-opacity)}]
[ra/view {:style (style/record-button-big-icon-container icon-opacity)}
[reanimated/view {:style (style/record-button-big-red-overlay red-overlay-opacity)}]
[reanimated/view {:style (style/record-button-big-gray-overlay gray-overlay-opacity)}]
[reanimated/view {:style (style/record-button-big-icon-container icon-opacity)}
(if @locked?
[rn/view {:style style/stop-icon}]
[icons/icon :i/audio {:color icon-color}])]]]))])
@@ -2,7 +2,7 @@
(:require [quo2.components.icon :as icons]
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[react-native.core :refer [use-effect]]
[quo2.components.record-audio.record-audio.helpers :refer
[animate-linear
@@ -14,13 +14,13 @@
[recording? ready-to-send? reviewing-audio?]
[:f>
(fn []
(let [opacity (ra/use-val 0)
translate-y (ra/use-val 20)
connector-opacity (ra/use-val 0)
width (ra/use-val 12)
height (ra/use-val 24)
border-radius-first-half (ra/use-val 16)
border-radius-second-half (ra/use-val 8)
(let [opacity (reanimated/use-shared-value 0)
translate-y (reanimated/use-shared-value 20)
connector-opacity (reanimated/use-shared-value 0)
width (reanimated/use-shared-value 12)
height (reanimated/use-shared-value 24)
border-radius-first-half (reanimated/use-shared-value 16)
border-radius-second-half (reanimated/use-shared-value 8)
start-y-animation (fn []
(animate-linear-with-delay translate-y 12 50 133.33)
(animate-easing-with-delay connector-opacity 1 0 93.33)
@@ -74,14 +74,14 @@
@recording? (reset-y-animation)))
[@ready-to-send?])
[:<>
[ra/view {:style (style/send-button-container opacity)}
[ra/view
[reanimated/view {:style (style/send-button-container opacity)}
[reanimated/view
{:style (style/send-button-connector connector-opacity
width
height
border-radius-first-half
border-radius-second-half)}]]
[ra/view
[reanimated/view
{:style (style/send-button translate-y opacity)
:pointer-events :none}
[icons/icon :i/arrow-up
@@ -1,9 +1,9 @@
(ns quo2.components.record-audio.record-audio.helpers
(:require [react-native.reanimated :as ra]))
(:require [react-native.reanimated :as reanimated]))
(defn animate-linear
[shared-value value duration]
(ra/animate
(reanimated/animate-shared-value-with-timing
shared-value
value
duration
@@ -11,26 +11,26 @@
(defn animate-linear-with-delay
[shared-value value duration delay]
(ra/animate-delay
(reanimated/animate-shared-value-with-delay
shared-value
value
delay
duration
:linear))
:linear
delay))
(defn animate-linear-with-delay-loop
[shared-value value duration delay]
(ra/animate-delay-repeat
(reanimated/animate-shared-value-with-delay-repeat
shared-value
value
delay
-1
duration
:linear))
:linear
delay
-1))
(defn animate-easing
[shared-value value duration]
(ra/animate
(reanimated/animate-shared-value-with-timing
shared-value
value
duration
@@ -38,13 +38,13 @@
(defn animate-easing-with-delay
[shared-value value duration delay]
(ra/animate-delay
(reanimated/animate-shared-value-with-delay
shared-value
value
delay
duration
:easing1))
:easing1
delay))
(defn set-value
[shared-value value]
(ra/set-val shared-value value))
(reanimated/set-shared-value shared-value value))
@@ -1,10 +1,10 @@
(ns quo2.components.record-audio.record-audio.style
(:require [quo2.foundations.colors :as colors]
[react-native.reanimated :as ra]))
[react-native.reanimated :as reanimated]))
(defn animated-circle
[scale opacity color]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:transform [{:scale scale}]
:opacity opacity}
{:width 56
@@ -19,7 +19,7 @@
(defn record-button-big-container
[translate-x translate-y opacity]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:transform [{:translateY translate-y}
{:translateX translate-x}]
:opacity opacity}
@@ -44,7 +44,7 @@
(defn record-button-big-red-overlay
[red-overlay-opacity]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:opacity red-overlay-opacity}
{:position :absolute
:top 0
@@ -55,7 +55,7 @@
(defn record-button-big-gray-overlay
[gray-overlay-opacity]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:opacity gray-overlay-opacity}
{:position :absolute
:top 0
@@ -66,7 +66,7 @@
(defn record-button-big-icon-container
[icon-opacity]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:opacity icon-opacity}
{}))
@@ -78,7 +78,7 @@
(defn send-button-container
[opacity]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:opacity opacity}
{:justify-content :center
:align-items :center
@@ -90,7 +90,7 @@
(defn send-button-connector
[opacity width height border-radius-first-half border-radius-second-half]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:opacity opacity
:width width
:height height
@@ -106,7 +106,7 @@
(defn send-button
[translate-y opacity]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:transform [{:translateY translate-y}]
:opacity opacity}
{:justify-content :center
@@ -125,7 +125,7 @@
(defn lock-button-container
[opacity]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:opacity opacity}
{:transform [{:rotate "45deg"}]
:justify-content :center
@@ -138,7 +138,7 @@
(defn lock-button-connector
[opacity width height border-radius-first-half border-radius-second-half]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:opacity opacity
:width width
:height height
@@ -154,7 +154,7 @@
(defn lock-button
[translate-x-y opacity]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:transform [{:translateX translate-x-y}
{:translateY translate-x-y}]
:opacity opacity}
@@ -172,7 +172,7 @@
(defn delete-button-container
[opacity]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:opacity opacity}
{:justify-content :center
:align-items :center
@@ -184,7 +184,7 @@
(defn delete-button-connector
[opacity width height border-radius-first-half border-radius-second-half]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:opacity opacity
:width width
:height height
@@ -200,7 +200,7 @@
(defn delete-button
[scale translate-x opacity]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:transform [{:translateX translate-x}
{:scale scale}]
:opacity opacity}
@@ -217,7 +217,7 @@
(defn record-button-container
[opacity]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:opacity opacity}
{:margin-bottom 32
:margin-right 32}))
+5 -14
View File
@@ -2,7 +2,7 @@
(:require [react-native.core :as rn]))
(defn style-container
[size disabled border-color border-width background-color labelled? type]
[size disabled border-color border-width background-color label type]
(merge {:height size
:border-color border-color
:background-color background-color
@@ -12,23 +12,14 @@
:justify-content :center}
(when disabled
{:opacity 0.3})
(when (and (or (= type :icon) (= type :emoji)) (not labelled?))
(when (and (or (= type :icon) (= type :emoji)) (not label))
{:width size})))
(defn base-tag
[_]
(fn
[{:keys [id
size
disabled?
border-color
border-width
background-color
on-press
accessibility-label
type
labelled?]
:or {size 32}} children]
(fn [{:keys [id size disabled? border-color border-width background-color on-press
accessibility-label labelled? type]
:or {size 32}} children]
[rn/touchable-without-feedback
(merge {:disabled disabled?
:accessibility-label accessibility-label}
+14 -25
View File
@@ -27,7 +27,7 @@
:text-color {:style {:color colors/white}}}}})
(defn tag-resources
[size type resource icon-color label text-color labelled?]
[size type resource icon-color label text-color labelled]
[rn/view
{:style (merge {:flex-direction :row
:align-items :center
@@ -46,14 +46,16 @@
24 12)
:color icon-color}])
(when (= type :emoji)
[text/text
{:style {:margin-right 4}
:size (case size
32 :paragraph-1
24 :paragraph-2
nil)}
resource])
(when labelled?
[rn/image
{:source resource
:style (merge (case size
32 {:height 20
:width 20}
24 {:height 12
:width 12})
(when label
{:margin-right 4}))}])
(when labelled
[text/text
(merge {:size (case size
32 :paragraph-1
@@ -68,7 +70,6 @@
(defn tag
"opts
{:type :icon/:emoji/:label
:label string
:size 32/24
:on-press fn
:blurred? true/false
@@ -81,21 +82,9 @@
- `type` can be icon or emoji with or without a tag label
- `labelled` boolean: is true if tag has label else false"
[_ _]
(fn
[{:keys [id
on-press
disabled?
size
active
accessibility-label
label
resource
type
labelled?
blurred?
icon-color
override-theme]
:or {size 32}}]
(fn [{:keys [id on-press disabled? size resource active accessibility-label
label type labelled? blurred? icon-color override-theme]
:or {size 32}}]
(let [state (cond disabled? :disabled
active :active
:else :default)
+5 -8
View File
@@ -138,9 +138,7 @@
:blurred? blurred?
:icon-color icon-color
:disabled? disabled?
:label (if labelled?
label
(when (= type :label) label))
:label label
:type type
:labelled? labelled?
:on-press (fn [id]
@@ -152,18 +150,17 @@
:index index
:viewPosition 0.5}))
(when on-change
(on-change id)))}]])})])
(on-change id)))}
label]])})])
[rn/view {:style {:flex-direction :row}}
(for [{:keys [id label resource]} data]
(for [{:keys [label id resource]} data]
^{:key id}
[rn/view {:style {:margin-right 8}}
[tag/tag
(merge {:id id
:size size
:type type
:label (if labelled?
label
(when (= type :label) label))
:label (if labelled? label (when (= type :label) label))
:active (= id active-tab-id)
:disabled? disabled?
:blurred? blurred?
+5 -8
View File
@@ -58,6 +58,11 @@
(def neutral-95 "#0D1625")
(def neutral-100 "#09101C")
;;Blur
(def neutral-5-opa-70 (alpha neutral-5 0.7))
(def neutral-80-blur-opa-80 "rgba(25,36,56,0.8)")
(def neutral-90-opa-70 (alpha neutral-90 0.7))
;;80 with transparency
(def neutral-80-opa-5 (alpha neutral-80 0.05))
(def neutral-80-opa-10 (alpha neutral-80 0.1))
@@ -110,14 +115,6 @@
(def white-opa-90 (alpha white 0.9))
(def white-opa-95 (alpha white 0.95))
;;;;Blur
(def white-70-blur (alpha white 0.7))
(def neutral-5-opa-70-blur (alpha neutral-5 0.7))
(def neutral-80-opa-80-blur (alpha "#192438" 0.8))
(def neutral-90-opa-70-blur (alpha neutral-90 0.7))
(def neutral-95-opa-70-blur neutral-95-opa-70)
(def neutral-100-opa-70-blur neutral-100-opa-70)
;;;;Black
;;Solid
+3 -1
View File
@@ -1,6 +1,7 @@
(ns react-native.core
(:require ["react" :as react]
["react-native" :as react-native]
["react-native-modal" :default Modal]
[cljs-bean.core :as bean]
[oops.core :as oops]
[react-native.flat-list :as flat-list]
@@ -31,7 +32,8 @@
(def activity-indicator (reagent/adapt-react-class (.-ActivityIndicator ^js react-native)))
(def modal (reagent/adapt-react-class (.-Modal ^js react-native)))
;; "react-native-modal" is a superset to the Modal component from RN, no need to define it separately
(def modal (reagent/adapt-react-class Modal))
(def keyboard ^js (.-Keyboard ^js react-native))
+98 -94
View File
@@ -20,13 +20,12 @@
[react-native.flat-list :as rn-flat-list]
[utils.collection]))
;;; Constants
(def ^:const default-duration 300)
;; Animations
(def slide-in-up-animation SlideInUp)
(def slide-out-up-animation SlideOutUp)
(def linear-transition LinearTransition)
;;; Worklets
(def worklet-factory (js/require "../src/js/worklet_factory.js"))
;;; Animated Components
;; Animated Components
(def create-animated-component (comp reagent/adapt-react-class (.-createAnimatedComponent reanimated)))
(def view (reagent/adapt-react-class (.-View reanimated)))
@@ -35,22 +34,18 @@
(defn flat-list
[props]
[reanimated-flat-list (rn-flat-list/base-list-props props)])
(def touchable-opacity (create-animated-component (.-TouchableOpacity ^js rn)))
(def linear-gradient (create-animated-component LinearGradient))
(def fast-image (create-animated-component FastImage))
(def blur-view (create-animated-component (.-BlurView blur)))
;;; Easings
(def in-out (.-inOut ^js Easing))
(def bezier (.-bezier ^js Easing))
(def easings
{:default (in-out (.-quad ^js Easing))
:linear (bezier 0 0 1 1)
:easing1 (bezier 0.25 0.1 0.25 1)
:easing2 (bezier 0 0.3 0.6 0.9)
:easing3 (bezier 0.3 0.3 0.3 0.9)})
;; Hooks
(def use-shared-value useSharedValue)
(def use-animated-style useAnimatedStyle)
;;; Animations
;; Animations
(def with-timing withTiming)
(def with-delay withDelay)
(def with-spring withSpring)
@@ -58,103 +53,112 @@
(def key-frame Keyframe)
(def with-repeat withRepeat)
(def cancel-animation cancelAnimation)
(defn with-repeat-timing
[val reps reverse? duration easing]
(with-repeat
(with-timing val
(clj->js {:duration duration
:easing (get easings easing)}))
reps
reverse?))
;; Easings
(def bezier (.-bezier ^js Easing))
;;; Hooks and Helpers
(def use-val useSharedValue)
(defn get-val
(def in-out
(.-inOut ^js Easing))
(def easings
{:linear (bezier 0 0 1 1)
:easing1 (bezier 0.25 0.1 0.25 1)
:easing2 (bezier 0 0.3 0.6 0.9)
:easing3 (bezier 0.3 0.3 0.3 0.9)})
;; Helper functions
(defn get-shared-value
[anim]
(when anim
(.-value anim)))
(defn set-val
(defn set-shared-value
[anim val]
(when (and anim (some? val))
(set! (.-value anim) val)))
;;; Executing animation functions
(defn animate
([animation value]
(animate animation value default-duration :default))
([animation value duration]
(animate animation value duration :default))
([animation value duration easing]
(set-val animation
(with-timing value
(clj->js {:duration duration
:easing (get easings easing)})))))
(defn animate-spring
[animation val {:keys [damping mass stiffness]}]
(set-val animation
(with-spring val
(clj->js {:damping damping
:mass mass
:stiffness stiffness}))))
(defn animate-decay
([animation velocity]
(animate-decay animation velocity []))
([animation velocity clamp]
(set-val animation
(with-decay (clj->js {:velocity velocity
:clamp clamp})))))
(defn animate-delay
([animation val delay]
(animate-delay animation val delay default-duration :default))
([animation val delay duration]
(animate-delay animation val delay duration :default))
([animation val delay duration easing]
(set-val animation
(with-delay delay
(with-timing val
(clj->js {:duration duration
:easing (get easings easing)}))))))
(defn animate-repeat
([animation val reps]
(animate-repeat animation val reps false default-duration :default))
([animation val reps reverse?]
(animate-repeat animation val reps reverse? default-duration :default))
([animation val reps reverse? duration]
(animate-repeat animation val reps reverse? duration :default))
([animation val reps reverse? duration easing]
(set-val animation (with-repeat-timing val reps reverse? duration easing))))
(defn animate-delay-repeat
([animation val duration easing delay reps]
(animate-delay-repeat animation val duration easing delay reps false))
([animation val duration easing delay reps reverse?]
(set-val animation (with-delay delay (with-repeat-timing val reps reverse? duration easing)))))
;; Worklets
(def worklet-factory (js/require "../src/js/worklet_factory.js"))
(defn interpolate
([val input-range output-range]
(interpolate val input-range output-range nil))
([val input-range output-range extrapolation]
([shared-value input-range output-range]
(interpolate shared-value input-range output-range nil))
([shared-value input-range output-range extrapolation]
(.interpolateValue ^js worklet-factory
val
shared-value
(clj->js input-range)
(clj->js output-range)
(clj->js extrapolation))))
;;; Styling
(def use-animated-style useAnimatedStyle)
;;;; Component Animations
(defn apply-animations-to-style
[animations style]
(use-animated-style
(.applyAnimationsToStyle ^js worklet-factory (clj->js animations) (clj->js style))))
;; Animators
(defn animate-shared-value-with-timing
[anim val duration easing]
(set-shared-value anim
(with-timing val
(js-obj "duration" duration
"easing" (get easings easing)))))
;;; Built-in Animations
(def slide-in-up-animation SlideInUp)
(def slide-out-up-animation SlideOutUp)
(def linear-transition LinearTransition)
(defn animate-shared-value-with-delay
[anim val duration easing delay]
(set-shared-value anim
(with-delay delay
(with-timing val
(js-obj "duration" duration
"easing" (get easings easing))))))
(defn animate-shared-value-with-delay-default-easing
[anim val duration delay]
(set-shared-value anim
(with-delay delay
(with-timing val
(js-obj "duration" duration
"easing" (in-out (.-quad ^js Easing)))))))
(defn animate-shared-value-with-repeat
[anim val duration easing number-of-repetitions reverse?]
(set-shared-value anim
(with-repeat (with-timing val
(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?]
(set-shared-value anim
(with-delay delay
(with-repeat
(with-timing val
#js
{:duration duration
:easing (get easings easing)})
number-of-repetitions
reverse?)))))
(defn animate-shared-value-with-spring
[anim val {:keys [mass stiffness damping]}]
(set-shared-value anim
(with-spring val
(js-obj "mass" mass
"damping" damping
"stiffness" stiffness))))
(defn animate-shared-value-with-decay
[anim velocity clamp]
(set-shared-value anim
(with-decay (clj->js {:velocity velocity
:clamp clamp}))))
(defn with-timing-duration
[val duration]
(with-timing val
(clj->js {:duration duration
:easing (in-out (.-quad ^js Easing))})))
+2 -1
View File
@@ -18,7 +18,8 @@
{:db (-> db
(assoc-in [:keycard :creating-backup?] backup-type))}
(when (:multiaccount db)
(navigation/navigate-to-cofx :my-profile nil))
(navigation/change-tab :browser-stack)) ;; Profile tab - Currently browser tab is used for
;; profile
(navigation/navigate-to-cofx :seed-phrase nil)))
(rf/defn recovery-card-pressed
+1 -1
View File
@@ -70,7 +70,7 @@
:status nil))
:hide-popover nil})
(when (:multiaccount db)
(navigation/navigate-to-cofx :my-profile nil))
(navigation/change-tab :browser-stack)) ;; Profile tab - Currently browser tab is used for profile
(when-not (:multiaccounts/login db)
(if (:popover/popover db)
(navigation/navigate-replace :keycard-pin nil)
+4 -6
View File
@@ -1,7 +1,6 @@
(ns status-im.multiaccounts.login.core
(:require
[clojure.string :as string]
[clojure.set :as set]
[re-frame.core :as re-frame]
[status-im.async-storage.core :as async-storage]
[status-im.communities.core :as communities]
@@ -44,7 +43,8 @@
[status-im2.navigation.events :as navigation]
[status-im2.common.log :as logging]
[taoensso.timbre :as log]
[utils.security.core :as security]))
[utils.security.core :as security]
[status-im2.contexts.emoji-hash.events :as emoji-hash]))
(re-frame/reg-fx
::initialize-communities-enabled
@@ -388,10 +388,7 @@
(let [{:networks/keys [current-network networks]
:as settings}
(data-store.settings/rpc->settings settings)
multiaccount (-> settings
(dissoc :networks/current-network :networks/networks)
(set/rename-keys {:compressedKey :compressed-key
:emojiHash :emoji-hash}))
multiaccount (dissoc settings :networks/current-network :networks/networks)
;;for some reason we save default networks in db, in case when we want to modify default-networks
;;for
;; existing accounts we have to merge them again into networks
@@ -475,6 +472,7 @@
(get-group-chat-invitations)
(multiaccounts/get-profile-picture)
(multiaccounts/switch-preview-privacy-mode-flag)
(emoji-hash/fetch-for-current-public-key)
(link-preview/request-link-preview-whitelist)
(visibility-status-updates-store/fetch-visibility-status-updates-rpc)
(switcher-cards-store/fetch-switcher-cards-rpc))))
+6
View File
@@ -481,6 +481,12 @@
(when (validators/valid-public-key? public-key)
(.generateAliasAsync ^js (status) public-key callback)))
(defn public-key->emoji-hash
"Generate an emoji hash from the multiaccount public key"
[public-key callback]
(when (validators/valid-public-key? public-key)
(.emojiHash ^js (status) public-key callback)))
(defn identicon
"Generate a icon based on a string, synchronously"
[seed]
+2 -3
View File
@@ -64,9 +64,8 @@
(let [own (new-chat.db/own-public-key? db public-key)]
(cond
(and public-key own)
(rf/merge cofx
{:pop-to-root-fx :shell-stack}
(navigation/navigate-to-cofx :my-profile nil))
{:shell/change-tab-fx :browser-stack ;; Profile tab - Currently browser tab is used for profile
:pop-to-root-fx :shell-stack}
(and public-key (not own))
(rf/merge cofx
@@ -0,0 +1,47 @@
(ns status-im.ui.screens.onboarding.intro.styles
(:require [quo.animated :as animated]
[quo.design-system.colors :as colors]))
(def dot-size 6)
(def progress-size 36)
(def intro-view
{:flex 1
:justify-content :flex-end
:margin-bottom 12})
(defn dot-selector
[]
{:flex-direction :row
:justify-content :space-between
:margin-bottom 16
:align-items :center})
(defn dot-style
[active]
{:background-color colors/blue-light
:overflow :hidden
:opacity 1
:margin-horizontal 2
:width (animated/mix active dot-size progress-size)
:height dot-size
:border-radius 3})
(defn dot-progress
[active progress]
{:background-color colors/blue
:height dot-size
:width progress-size
:opacity (animated/mix active 0 1)
:transform [{:translateX (animated/mix progress (- progress-size) 0)}]})
(defn wizard-text-with-height
[height]
(merge {:color colors/gray
:text-align :center}
(when-not (zero? height)
{:height height})))
(def wizard-title
{:margin-bottom 16
:text-align :center})
@@ -0,0 +1,204 @@
(ns status-im.ui.screens.onboarding.intro.views
(:require [quo.animated :as animated]
[quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.design-system.typography :as typography]
[quo.react-native :as rn]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[utils.i18n :as i18n]
[status-im.react-native.resources :as resources]
[status-im.ui.components.react :as react]
[status-im.ui.screens.onboarding.intro.styles :as styles]))
(defonce index (reagent/atom 0))
(defn code
[val]
^{:key val}
[animated/code {:exec val}])
(defn dot
[]
(let [active (animated/value 0)
active-transition (animated/with-timing-transition active {:duration 100})]
(fn [{:keys [selected progress]}]
[animated/view {:style (styles/dot-style active-transition)}
[code (animated/set active (if selected 1 0))]
[animated/view {:style (styles/dot-progress active-transition progress)}]])))
(defn dots-selector
[{:keys [n progress]}]
(let [selected @index]
[react/view {:style (styles/dot-selector)}
(for [i (range n)]
^{:key i}
[dot
{:progress progress
:selected (= selected i)}])]))
(defn slides-view
[slides width]
(let [height (reagent/atom 0)
text-height (reagent/atom 0)
text-temp-height (atom 0)
text-temp-timer (atom nil)]
(fn [_]
[:<>
(doall
(for [s slides]
^{:key (:title s)}
[react/view
{:style {:flex 1
:width width
:justify-content :flex-end
:align-items :center
:padding-horizontal 32}}
(let [size (min width @height)]
[react/view
{:style {:flex 1}
:on-layout (fn [^js e]
(let [new-height (-> e .-nativeEvent .-layout .-height)]
(swap! height #(if (pos? %) (min % new-height) new-height))))}
[react/image
{:source (:image s)
:resize-mode :contain
:style {:width size
:height size}}]])
[quo/text
{:style styles/wizard-title
:align :center
:weight :bold
:size :x-large}
(i18n/label (:title s))]
[quo/text
{:style (styles/wizard-text-with-height @text-height)
:on-layout
(fn [^js e]
(let [new-height (-> e .-nativeEvent .-layout .-height)]
(when (and (not= new-height @text-temp-height)
(not (zero? new-height))
(< new-height 200))
(swap! text-temp-height #(if (pos? %) (max % new-height) new-height))
(when @text-temp-timer (js/clearTimeout @text-temp-timer))
(reset! text-temp-timer
(js/setTimeout #(reset! text-height @text-temp-height) 500)))))}
(i18n/label (:text s))]]))])))
(defn carousel
[slides width]
;;TODO this is really not the best implementation, must be a better way
(let [scroll-x (reagent/atom 0)
scroll-view-ref (atom nil)
manual-scroll (atom false)
progress (animated/value 1)
autoscroll (animated/value 1)
finished (animated/value 0)
clock (animated/clock)
go-next (fn []
(let [x (if (>= @scroll-x
(- (* (dec (count slides))
width)
5))
0
(+ @scroll-x width))]
(reset! index (Math/round (/ x width)))
(some-> ^js @scroll-view-ref
(.scrollTo #js {:x x :animated true}))))
code (animated/block
[(animated/cond* (animated/and* (animated/not* (animated/clock-running clock))
autoscroll)
(animated/start-clock clock))
(animated/cond* (animated/and* (animated/clock-running clock)
(animated/not* autoscroll))
[(animated/stop-clock clock)
(animated/set finished 1)])
(animated/set progress
(animated/cancelable-loop
{:clock clock
:finished finished
:duration 4000
:on-reach go-next}))])
cancel-animation (fn []
(reset! manual-scroll true)
(animated/set-value autoscroll 0))
restart-animation (fn []
(animated/set-value autoscroll 1))]
(fn [_ _]
[react/view
{:style {:align-items :center
:flex 1
:justify-content :flex-end}}
[animated/code {:exec code}]
[react/scroll-view
{:horizontal true
:paging-enabled true
:ref #(reset! scroll-view-ref %)
:shows-vertical-scroll-indicator false
:shows-horizontal-scroll-indicator false
:pinch-gesture-enabled false
:scroll-event-throttle 16
:on-scroll #(let [x (.-nativeEvent.contentOffset.x ^js %)]
(when @manual-scroll
;; NOTE: Will be not synced if velocity is big
(reset! index (Math/round (/ x width))))
(reset! scroll-x x))
:on-scroll-begin-drag cancel-animation
:on-scroll-end-drag restart-animation
:on-momentum-scroll-end #(reset! manual-scroll false)
:style {:margin-bottom 16}}
[slides-view slides width]]
[dots-selector
{:progress progress
:n (count slides)}]])))
(defonce tos-accepted (reagent/atom false))
(defn intro
[]
[react/view {:style styles/intro-view}
[carousel
[{:image (resources/get-theme-image :chat)
:title :intro-title1
:text :intro-text1}
{:image (resources/get-theme-image :wallet)
:title :intro-title2
:text :intro-text2}
{:image (resources/get-theme-image :browser)
:title :intro-title3
:text :intro-text3}]
@(re-frame/subscribe [:dimensions/window-width])]
[react/view {:style {:align-items :center}}
[react/view
{:flex-direction :row
:justify-content :space-between
:align-items :center
:margin-top 36
:margin-bottom 24}
[quo/checkbox
{:value @tos-accepted
:on-change #(swap! tos-accepted not)}]
[rn/touchable-opacity {:test-ID :terms-of-service :on-press #(swap! tos-accepted not)}
[react/nested-text {:style {:margin-left 12}}
(i18n/label :t/accept-status-tos-prefix)
[{:style (merge {:color colors/blue}
typography/font-medium)
:on-press #(re-frame/dispatch [:open-modal :terms-of-service])
:accessibility-label :terms-of-service-link}
" "
(i18n/label :t/terms-of-service)]]]]
[react/view {:style {:margin-bottom 24}}
[quo/button
{:test-ID :get-started
:disabled (not @tos-accepted)
:on-press #(do (re-frame/dispatch [:init-root :onboarding])
;; clear atom state for next use
(reset! tos-accepted false)
(re-frame/dispatch [:hide-terms-of-services-opt-in-screen]))}
(i18n/label :t/get-started)]]
[react/text
{:style {:color colors/blue}
:on-press #(re-frame/dispatch [:open-modal :privacy-policy])
:accessibility-label :privacy-policy-link}
(i18n/label :t/privacy-policy)]]])
+6
View File
@@ -60,6 +60,7 @@
[status-im.ui.screens.notifications-settings.views :as notifications-settings]
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.views :as edit-mailserver]
[status-im.ui.screens.offline-messaging-settings.views :as offline-messaging-settings]
[status-im.ui.screens.onboarding.intro.views :as onboarding.intro]
[status-im.ui.screens.onboarding.keys.views :as onboarding.keys]
[status-im.ui.screens.onboarding.notifications.views :as onboarding.notifications]
[status-im.ui.screens.onboarding.password.views :as onboarding.password]
@@ -129,6 +130,11 @@
{:name :progress
:component progress/progress}
;[Onboarding]
{:name :intro
:insets {:bottom true}
:component onboarding.intro/intro}
;[Onboarding]
{:name :get-your-keys
:insets {:bottom true}
@@ -4,7 +4,7 @@
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[status-im.ui2.screens.chat.pin-limit-popover.style :as style]
[utils.re-frame :as rf]))
@@ -16,17 +16,17 @@
(fn []
(let [width (rf/sub [:dimensions/window-width])
show-pin-limit-modal? (rf/sub [:chats/pin-modal chat-id])
opacity-animation (ra/use-val 0)
z-index-animation (ra/use-val -1)]
opacity-animation (reanimated/use-shared-value 0)
z-index-animation (reanimated/use-shared-value -1)]
(react/effect!
#(do
(ra/set-val opacity-animation
(ra/with-timing (if show-pin-limit-modal? 1 0)))
(ra/set-val z-index-animation
(ra/with-timing (if show-pin-limit-modal? 10 -1)))))
(reanimated/set-shared-value opacity-animation
(reanimated/with-timing (if show-pin-limit-modal? 1 0)))
(reanimated/set-shared-value z-index-animation
(reanimated/with-timing (if show-pin-limit-modal? 10 -1)))))
(when show-pin-limit-modal?
[ra/view
{:style (ra/apply-animations-to-style
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:opacity opacity-animation
:z-index z-index-animation}
(style/pin-popover width))
@@ -109,9 +109,8 @@
(log/info "universal-links: handling view profile" public-key)
(cond
(and public-key (new-chat.db/own-public-key? db public-key))
(rf/merge cofx
{:pop-to-root-fx :shell-stack}
(navigation/navigate-to-cofx :my-profile nil))
{:shell/change-tab-fx :browser-stack ;; Profile tab - Currently browser tab is used for profile
:pop-to-root-fx :shell-stack}
public-key
{:dispatch [:chat.ui/show-profile public-key ens-name]}))
+23 -23
View File
@@ -8,7 +8,7 @@
[react-native.gesture :as gesture]
[react-native.hooks :as hooks]
[react-native.platform :as platform]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]))
@@ -18,7 +18,7 @@
(defn with-animation
[value & [options callback]]
(ra/with-spring
(reanimated/with-spring
value
(clj->js (merge {:mass 2
:stiffness 500
@@ -45,12 +45,12 @@
max-pan-down (if @expanded?
bg-height-expanded
bg-height)]
(ra/set-val pan-y
(max
(min
(.-translationY evt)
max-pan-down)
max-pan-up))))))
(reanimated/set-shared-value pan-y
(max
(min
(.-translationY evt)
max-pan-down)
max-pan-up))))))
(gesture/on-end
(fn [_]
(reset! gesture-running? false)
@@ -127,8 +127,8 @@
{:keys [keyboard-shown]} (hooks/use-keyboard)
bg-height-expanded (- window-height (:top insets))
bg-height (max (min @content-height bg-height-expanded) 109)
bottom-sheet-dy (ra/use-val 0)
pan-y (ra/use-val 0)
bottom-sheet-dy (reanimated/use-shared-value 0)
pan-y (reanimated/use-shared-value 0)
translate-y (.useTranslateY ^js bottom-sheet-js window-height bottom-sheet-dy pan-y)
bg-opacity
(.useBackgroundOpacity ^js bottom-sheet-js translate-y bg-height window-height)
@@ -136,11 +136,11 @@
(let [height (oget evt "nativeEvent" "layout" "height")]
(reset! content-height height)))
on-expanded (fn []
(ra/set-val bottom-sheet-dy bg-height-expanded)
(ra/set-val pan-y 0))
(reanimated/set-shared-value bottom-sheet-dy bg-height-expanded)
(reanimated/set-shared-value pan-y 0))
on-collapsed (fn []
(ra/set-val bottom-sheet-dy bg-height)
(ra/set-val pan-y 0))
(reanimated/set-shared-value bottom-sheet-dy bg-height)
(reanimated/set-shared-value pan-y 0))
bottom-sheet-gesture (get-bottom-sheet-gesture
pan-y
translate-y
@@ -185,38 +185,38 @@
@show-bottom-sheet?
(if @expanded?
(do
(ra/set-val
(reanimated/set-shared-value
bottom-sheet-dy
(with-animation (+ bg-height-expanded (.-value pan-y))))
;; Workaround for
;; https://github.com/software-mansion/react-native-ra/issues/1758#issue-817145741
;; https://github.com/software-mansion/react-native-reanimated/issues/1758#issue-817145741
;; withTiming/withSpring callback not working
;; on-expanded should be called as a callback of
;; with-animation instead, once this issue has been resolved
(timer/set-timeout on-expanded animation-delay))
(do
(ra/set-val
(reanimated/set-shared-value
bottom-sheet-dy
(with-animation (+ bg-height (.-value pan-y))))
;; Workaround for
;; https://github.com/software-mansion/react-native-ra/issues/1758#issue-817145741
;; https://github.com/software-mansion/react-native-reanimated/issues/1758#issue-817145741
;; withTiming/withSpring callback not working
;; on-collapsed should be called as a callback of
;; with-animation instead, once this issue has been resolved
(timer/set-timeout on-collapsed animation-delay)))
(= @show-bottom-sheet? false)
(ra/set-val bottom-sheet-dy (with-animation 0)))))
(reanimated/set-shared-value bottom-sheet-dy (with-animation 0)))))
[@show-bottom-sheet? @expanded? @gesture-running?])
[:<>
[rn/touchable-without-feedback {:on-press (when backdrop-dismiss? close-bottom-sheet)}
[ra/view
{:style (ra/apply-animations-to-style
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:opacity bg-opacity}
styles/backdrop)}]]
(cond->> [ra/view
{:style (ra/apply-animations-to-style
(cond->> [reanimated/view
{:style (reanimated/apply-animations-to-style
{:transform [{:translateY translate-y}]}
{:width window-width
:height window-height})}
+40 -4
View File
@@ -3,8 +3,12 @@
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.hole-view :as hole-view]
[react-native.navigation :as navigation]
[reagent.core :as reagent]
[status-im2.common.home.style :as style]
[status-im2.common.plus-button.view :as components.plus-button]
[status-im2.contexts.activity-center.view :as ac]
[status-im2.contexts.shell.animation :as shell]
[utils.re-frame :as rf]))
(defn title-column
@@ -39,6 +43,29 @@
button-common-props)
icon])
(defn ac-modal
[visible? view-id]
(let [status-bar-style (if (or (colors/dark?)
(not (shell/home-stack-open?)))
:light
:dark)
close-modal (fn []
(reset! visible? false)
(navigation/merge-options (clj->js view-id)
(clj->js {:statusBar {:style status-bar-style}})))]
[rn/modal
{:visible @visible?
:cover-screen true
:transparent true
:status-bar-translucent true
:hardware-accelerated true
:animation-type :slide
:style {:margin 0
:width "100%"}
:on-back-button-press close-modal}
[ac/view close-modal]]))
(defn top-nav
"[top-nav opts]
opts
@@ -51,8 +78,18 @@
notif-count (rf/sub [:activity-center/unread-count])
new-notifications? (pos? notif-count)
notification-indicator :unread-dot
counter-label "0"]
counter-label "0"
visible? (reagent/atom false)
view-id (rf/sub [:view-id])
open-ac (fn []
;; delaying status-bar style update looks nicer
(js/setTimeout
#(navigation/merge-options (clj->js view-id)
(clj->js {:statusBar {:style :light}}))
20)
(reset! visible? (not @visible?)))]
[rn/view {:style (assoc style :height 56)}
[ac-modal visible? view-id]
;; Left Section
[rn/touchable-without-feedback {:on-press #(rf/dispatch [:navigate-to :my-profile])}
[rn/view
@@ -75,7 +112,7 @@
[base-button :i/search #() :open-search-button button-common-props])
[base-button :i/scan #() :open-scanner-button button-common-props]
[base-button :i/qr-code #() :show-qr-button button-common-props]
[rn/view ;; Keep view instead of "[:<>" to make sure relative
[rn/view ;; Keep view instead of "[:<>" to make sure relative
;; position is calculated from this view instead of its parent
[hole-view/hole-view
{:key new-notifications? ;; Key is required to force removal of holes
@@ -88,8 +125,7 @@
:else
[{:x 33 :y -7 :width 18 :height 18 :borderRadius 7}])}
[base-button :i/activity-center #(rf/dispatch [:activity-center/open])
:open-activity-center-button button-common-props]]
[base-button :i/activity-center open-ac :open-activity-center-button button-common-props]]
(when new-notifications?
(if (= notification-indicator :counter)
[quo/counter
+1 -6
View File
@@ -2,15 +2,10 @@
(def ui
{:add-new-contact (js/require "../resources/images/ui2/add-contact.png")
:intro-1 (js/require "../resources/images/ui2/intro-1.png")
:intro-2 (js/require "../resources/images/ui2/intro-2.png")
:intro-3 (js/require "../resources/images/ui2/intro-3.png")
:intro-4 (js/require "../resources/images/ui2/intro-4.png")
:lifestyle (js/require "../resources/images/ui2/lifestyle.png")
:music (js/require "../resources/images/ui2/music.png")
:podcasts (js/require "../resources/images/ui2/podcasts.png")
:sync-device (js/require "../resources/images/ui2/sync-new-device-cover-background.png")
:onboarding-bg-1 (js/require "../resources/images/ui2/onboarding-bg-1.png")})
:sync-device (js/require "../resources/images/ui2/sync-new-device-cover-background.png")})
(def mock-images
{:coinbase (js/require "../resources/images/mock2/coinbase.png")
+4 -4
View File
@@ -1,7 +1,7 @@
(ns status-im2.common.scroll-page.style
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]
[react-native.reanimated :as ra]))
[react-native.reanimated :as reanimated]))
(defn image-slider
[size]
@@ -13,7 +13,7 @@
(defn blur-slider
[animation height]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:transform [{:translateY animation}]}
{:z-index 5
:position :absolute
@@ -39,7 +39,7 @@
(defn sticky-header-title
[animation]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:opacity animation}
{:position :absolute
:flex-direction :row
@@ -57,7 +57,7 @@
(defn display-picture-container
[animation]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:transform [{:scale animation}]}
{:border-radius 50
:border-width 1
+27 -28
View File
@@ -7,7 +7,7 @@
[reagent.core :as reagent]
[status-im2.common.scroll-page.style :as style]
[utils.re-frame :as rf]
[react-native.reanimated :as ra]))
[react-native.reanimated :as reanimated]))
(defn icon-color
[]
@@ -31,30 +31,30 @@
height
name
page-nav
logo
cover
sticky-header
top-nav
title-colum
navigate-back?]
(let [input-range (if platform/ios? [-47 10] [0 10])
output-range (if platform/ios? [-208 0] [-208 -45])
y (ra/use-val scroll-height)
translate-animation (ra/interpolate y
input-range
output-range
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})
opacity-animation (ra/use-val 0)
y (reanimated/use-shared-value scroll-height)
translate-animation (reanimated/interpolate y
input-range
output-range
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})
opacity-animation (reanimated/use-shared-value 0)
threshold (if platform/ios? 30 170)]
(rn/use-effect
#(do
(ra/set-val y scroll-height)
(ra/set-val opacity-animation
(ra/with-timing (if (>= scroll-height threshold) 1 0)
(clj->js {:duration 300}))))
(reanimated/set-shared-value y scroll-height)
(reanimated/set-shared-value opacity-animation
(reanimated/with-timing (if (>= scroll-height threshold) 1 0)
(clj->js {:duration 300}))))
[scroll-height])
[:<>
[ra/blur-view
[reanimated/blur-view
{:blur-amount 20
:blur-type :transparent
:overlay-color :transparent
@@ -65,11 +65,11 @@
:top 0
:left 0
:right 0}}
(when logo
[ra/view
(when cover
[reanimated/view
{:style (style/sticky-header-title opacity-animation)}
[rn/image
{:source logo
{:source cover
:style style/sticky-header-image}]
[quo/text
{:size :paragraph-1
@@ -101,17 +101,17 @@
(defn display-picture
[scroll-height cover]
(let [input-range (if platform/ios? [-67 10] [0 150])
y (ra/use-val scroll-height)
animation (ra/interpolate y
input-range
[1.2 0.5]
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})]
y (reanimated/use-shared-value scroll-height)
animation (reanimated/interpolate y
input-range
[1.2 0.5]
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})]
(rn/use-effect #(do
(ra/set-val y scroll-height)
(reanimated/set-shared-value y scroll-height)
js/undefined)
[scroll-height])
[ra/view
[reanimated/view
{:style (style/display-picture-container animation)}
[rn/image
{:source cover
@@ -122,7 +122,6 @@
(let [scroll-height (reagent/atom negative-scroll-position-0)]
(fn
[{:keys [cover-image
logo
page-nav-right-section-buttons
name
on-scroll
@@ -135,7 +134,7 @@
children]
[:<>
[:f> scroll-page-header @scroll-height height name page-nav-right-section-buttons
logo sticky-header top-nav title-colum navigate-back?]
cover-image sticky-header top-nav title-colum navigate-back?]
[rn/scroll-view
{:content-container-style (style/scroll-view-container
(diff-with-max-min @scroll-height 16 0))
@@ -163,5 +162,5 @@
:border-radius (diff-with-max-min @scroll-height 16 0)
:background-color background-color}
(when cover-image
[:f> display-picture @scroll-height logo])
[:f> display-picture @scroll-height cover-image])
children])]])))
+17 -17
View File
@@ -2,26 +2,26 @@
(:require [quo2.core :as quo]
[react-native.core :as rn]
[react-native.gesture :as gesture]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]
[status-im.utils.utils :as utils.utils]
[status-im2.common.toasts.style :as style]
[utils.re-frame :as rf]))
;; (def ^:private slide-out-up-animation
;; (-> ^js ra/slide-out-up-animation
;; (-> ^js reanimated/slide-out-up-animation
;; .springify
;; (.damping 20)
;; (.stiffness 300)))
;; (def ^:private slide-in-up-animation
;; (-> ^js ra/slide-in-up-animation
;; (-> ^js reanimated/slide-in-up-animation
;; .springify
;; (.damping 20)
;; (.stiffness 300)))
;; (def ^:private linear-transition
;; (-> ^js ra/linear-transition
;; (-> ^js reanimated/linear-transition
;; .springify
;; (.damping 20)
;; (.stiffness 300)))
@@ -44,7 +44,7 @@
on-dismissed #((or (rf/sub [:toasts/toast-cursor id :on-dismissed]) identity) id)
create-timer (fn []
(reset! timer (utils.utils/set-timeout close! duration)))
translate-y (ra/use-val 0)
translate-y (reanimated/use-shared-value 0)
pan
(->
(gesture/gesture-pan)
@@ -56,38 +56,38 @@
(cond
;; reset translate y on pan down
(> evt-translation-y 100)
(ra/animate-spring translate-y
0
{:mass 1
:damping 20
:stiffness 300})
(reanimated/animate-shared-value-with-spring translate-y
0
{:mass 1
:damping 20
:stiffness 300})
;; dismiss on pan up
(< evt-translation-y -30)
(do (ra/animate-spring
(do (reanimated/animate-shared-value-with-spring
translate-y
-500
{:mass 1 :damping 20 :stiffness 300})
(reset! dismissed-locally? true)
(close!))
:else
(ra/set-val translate-y
evt-translation-y)))))
(reanimated/set-shared-value translate-y
evt-translation-y)))))
(gesture/on-end (fn [_]
(when-not @dismissed-locally?
(ra/set-val translate-y 0)
(reanimated/set-shared-value translate-y 0)
(create-timer)))))]
;; create auto dismiss timer, clear timer when unmount or duration changed
(rn/use-effect (fn [] (create-timer) clear-timer) [duration])
(rn/use-unmount on-dismissed)
[gesture/gesture-detector {:gesture pan}
[ra/view
[reanimated/view
{;; TODO: this will eanble layout animation at runtime and causing flicker on android
;; we need to resolve this and re-enable layout animation
;; issue at https://github.com/status-im/status-mobile/issues/14752
;; :entering slide-in-up-animation
;; :exiting slide-out-up-animation
;; :layout ra/linear-transition
:style (ra/apply-animations-to-style
;; :layout reanimated/linear-transition
:style (reanimated/apply-animations-to-style
{:transform [{:translateY translate-y}]}
style/each-toast-container)}
[toast id]]]))])))
@@ -1,5 +1,6 @@
(ns status-im2.contexts.activity-center.style
(:require [quo2.foundations.colors :as colors]))
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]))
(def screen-padding 20)
@@ -60,3 +61,25 @@
:height 120
:background-color colors/danger-50
:margin-bottom 20})
(def blur-background
{:position :absolute
:background-color colors/neutral-80-opa-80
:top 0
:bottom 0
:left 0
:right 0})
(defn options-content-container
[bottom-inset]
{:background-color colors/neutral-100
:padding-bottom (if platform/ios? bottom-inset 20)
:padding-top 20
:border-top-left-radius 20
:border-top-right-radius 20})
(def options-modal-container
{:justify-content :flex-end
:margin 0
:width "100%"
:align-self :center})
@@ -4,6 +4,7 @@
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
[status-im2.contexts.activity-center.notification-types :as types]
[status-im2.contexts.activity-center.notification.admin.view :as admin]
[status-im2.contexts.activity-center.notification.contact-requests.view :as contact-requests]
@@ -14,6 +15,7 @@
[status-im2.contexts.activity-center.notification.reply.view :as reply]
[status-im2.contexts.activity-center.style :as style]
[utils.i18n :as i18n]
[react-native.blur :as blur]
[utils.re-frame :as rf]))
(defn filter-selector-read-toggle
@@ -28,27 +30,44 @@
:all
:unread)}])}]))
(defn options-bottom-sheet-content
[]
(defn options-content
[bottom-inset]
(let [unread-count (rf/sub [:activity-center/unread-count])]
[quo/action-drawer
[[{:icon :i/check
:override-theme :dark
:label (i18n/label :t/mark-all-notifications-as-read)
:on-press (fn []
(if (pos? unread-count)
(rf/dispatch [:activity-center.notifications/mark-all-as-read-locally
(fn []
{:icon :up-to-date
:icon-color colors/success-50
:text (i18n/label :t/notifications-marked-as-read
{:count unread-count})
:override-theme :dark})])
;; Need design improvements if there is NO unread
;; notifications to mark as read
;; https://github.com/status-im/status-mobile/issues/14983
(js/alert "No unread notifications to mark as read"))
(rf/dispatch [:bottom-sheet/hide]))}]]]))
[rn/view
{:style (style/options-content-container bottom-inset)}
[quo/action-drawer
[[{:icon :i/check
:override-theme :dark
:label (i18n/label :t/mark-all-notifications-as-read)
:on-press (fn []
(if (pos? unread-count)
(rf/dispatch [:activity-center.notifications/mark-all-as-read-locally
(fn []
{:icon :up-to-date
:icon-color colors/success-50
:text (i18n/label :t/notifications-marked-as-read
{:count unread-count})
:override-theme :dark})])
;; Need design improvements if there is NO unread
;; notifications to mark as read
;; https://github.com/status-im/status-mobile/issues/14983
(js/alert "No unread notifications to mark as read"))
(rf/dispatch [:bottom-sheet/hide]))}]]]]))
(defn options-bottom-sheet
[visible? bottom-inset]
;; not using the `bottom-sheet` component as it renders behind the full screen `Modal` component on
;; Android
[rn/modal
{:is-visible @visible?
:use-native-driver true
:use-native-driver-for-backdrop true
:hide-modal-content-while-animating true
:backdrop-opacity 0.5
:on-backdrop-press #(reset! visible? false)
:style style/options-modal-container}
[options-content bottom-inset]])
(defn empty-tab
[]
@@ -134,7 +153,7 @@
(contains? types-with-unread types/system))}]}]))
(defn header
[request-close]
[request-close open-options]
[rn/view
[rn/view {:style style/header-container}
[quo/button
@@ -151,9 +170,7 @@
:size 32
:accessibility-label :activity-center-open-more
:override-theme :dark
:on-press #(rf/dispatch [:bottom-sheet/show-sheet
{:content options-bottom-sheet-content
:override-theme :dark}])}
:on-press open-options}
:i/options]]
[quo/text
{:size :heading-1
@@ -203,7 +220,8 @@
(defn view
[request-close]
(let [active-swipeable (atom nil)]
(let [active-swipeable (atom nil)
visible? (reagent/atom false)]
[:f>
(fn []
(rn/use-effect-once #(rf/dispatch [:activity-center.notifications/fetch-first-page]))
@@ -212,7 +230,11 @@
(let [notifications (rf/sub [:activity-center/notifications])
window-width (rf/sub [:dimensions/window-width])]
[rn/view {:style (style/screen-container window-width top bottom)}
[header request-close]
[blur/view
{:blurAmount 5
:style style/blur-background}]
[options-bottom-sheet visible? bottom]
[header request-close #(reset! visible? true)]
[rn/flat-list
{:data notifications
:render-data active-swipeable
@@ -2,9 +2,10 @@
(:require
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[status-im2.contexts.chat.lightbox.style :as style]
[utils.re-frame :as rf]))
[utils.re-frame :as rf]
[status-im2.contexts.chat.lightbox.common :as common]))
(def small-image-size 40)
@@ -24,10 +25,10 @@
[:f>
(fn []
(let [size (if (= @scroll-index index) focused-image-size small-image-size)
size-value (ra/use-val size)
size-value (common/use-val size)
{:keys [scroll-index-lock? small-list-ref
flat-list-ref]} atoms]
(ra/animate size-value size)
(common/set-val-timing size-value size)
[rn/touchable-opacity
{:active-opacity 1
:on-press (fn []
@@ -43,11 +44,11 @@
#js {:animated true :index index}))
(if platform/ios? 50 150))
(rf/dispatch [:chat.ui/update-shared-element-id (:message-id item)]))}
[ra/fast-image
[reanimated/fast-image
{:source {:uri (:image (:content item))}
:style (ra/apply-animations-to-style {:width size-value
:height size-value}
{:border-radius 10})}]]))])
:style (reanimated/apply-animations-to-style {:width size-value
:height size-value}
{:border-radius 10})}]]))])
(defn bottom-view
[messages index scroll-index insets animations item-width atoms]
@@ -55,7 +56,7 @@
(fn []
(let [text (get-in (first messages) [:content :text])
padding-horizontal (- (/ item-width 2) (/ focused-image-size 2))]
[ra/linear-gradient
[reanimated/linear-gradient
{:colors [:black :transparent]
:start {:x 0 :y 1}
:end {:x 0 :y 0}
@@ -0,0 +1,14 @@
(ns status-im2.contexts.chat.lightbox.common
(:require [react-native.reanimated :as reanimated]))
(def top-view-height 56)
;; TODO: Abstract Reanimated methods in a better way, issue:
;; https://github.com/status-im/status-mobile/issues/15176
(defn set-val-timing
[animation value]
(reanimated/set-shared-value animation (reanimated/with-timing value)))
(defn use-val
[value]
(reanimated/use-shared-value value))
@@ -1,7 +1,8 @@
(ns status-im2.contexts.chat.lightbox.style
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]
[react-native.reanimated :as ra]))
[react-native.reanimated :as reanimated]
[status-im2.contexts.chat.lightbox.common :as common]))
;;;; MAIN-VIEW
(def container-view
@@ -12,7 +13,7 @@
[top-inset {:keys [opacity rotate top-view-y top-view-x top-view-width top-view-bg top-layout]}
window-width
bg-color]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
(if platform/ios?
{:transform [{:translateY top-layout}
{:rotate rotate}
@@ -26,8 +27,7 @@
{:position :absolute
:padding-horizontal 20
:top (if platform/ios? top-inset 0)
;; height defined in top_view.cljs, but can't import due to circular dependency
:height 56
:height common/top-view-height
:z-index 4
:flex-direction :row
:justify-content :space-between
@@ -49,7 +49,7 @@
;;;; BOTTOM-VIEW
(defn gradient-container
[insets {:keys [opacity bottom-layout]}]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:transform [{:translateY bottom-layout}]
:opacity opacity}
{:position :absolute
@@ -5,39 +5,38 @@
[react-native.core :as rn]
[react-native.orientation :as orientation]
[react-native.platform :as platform]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[status-im2.contexts.chat.lightbox.common :as common]
[status-im2.contexts.chat.lightbox.style :as style]
[utils.datetime :as datetime]
[utils.re-frame :as rf]))
(def ^:const top-view-height 56)
(defn animate-rotation
[result screen-width screen-height insets-atom
{:keys [rotate top-view-y top-view-x top-view-width top-view-bg]}]
(let [top-x (+ (/ top-view-height 2) (:top insets-atom))]
(let [top-x (+ (/ common/top-view-height 2) (:top insets-atom))]
(cond
(= result orientation/landscape-left)
(do
(ra/animate rotate "90deg")
(ra/animate top-view-y 60)
(ra/animate top-view-x (- (/ screen-height 2) top-x))
(ra/animate top-view-width screen-height)
(ra/animate top-view-bg colors/neutral-100-opa-70))
(common/set-val-timing rotate "90deg")
(common/set-val-timing top-view-y 60)
(common/set-val-timing top-view-x (- (/ screen-height 2) top-x))
(common/set-val-timing top-view-width screen-height)
(common/set-val-timing top-view-bg colors/neutral-100-opa-70))
(= result orientation/landscape-right)
(do
(ra/animate rotate "-90deg")
(ra/animate top-view-y (- (- screen-width) 4))
(ra/animate top-view-x (+ (/ screen-height -2) top-x))
(ra/animate top-view-width screen-height)
(ra/animate top-view-bg colors/neutral-100-opa-70))
(common/set-val-timing rotate "-90deg")
(common/set-val-timing top-view-y (- (- screen-width) 4))
(common/set-val-timing top-view-x (+ (/ screen-height -2) top-x))
(common/set-val-timing top-view-width screen-height)
(common/set-val-timing top-view-bg colors/neutral-100-opa-70))
(= result orientation/portrait)
(do
(ra/animate rotate "0deg")
(ra/animate top-view-y 0)
(ra/animate top-view-x 0)
(ra/animate top-view-width screen-width)
(ra/animate top-view-bg colors/neutral-100-opa-0)))))
(common/set-val-timing rotate "0deg")
(common/set-val-timing top-view-y 0)
(common/set-val-timing top-view-x 0)
(common/set-val-timing top-view-width screen-width)
(common/set-val-timing top-view-bg colors/neutral-100-opa-0)))))
(defn top-view
[{:keys [from timestamp]} insets index animations landscape? screen-width]
@@ -45,14 +44,14 @@
(fn []
(let [display-name (first (rf/sub [:contacts/contact-two-names-by-identity from]))
bg-color (if landscape? colors/neutral-100-opa-70 colors/neutral-100-opa-0)]
[ra/view
[reanimated/view
{:style (style/top-view-container (:top insets) animations screen-width bg-color)}
[rn/view
{:style {:flex-direction :row
:align-items :center}}
[rn/touchable-opacity
{:on-press (fn []
(ra/animate (:opacity animations) 0)
(common/set-val-timing (:opacity animations) 0)
(rf/dispatch (if platform/ios?
[:chat.ui/exit-lightbox-signal @index]
[:navigate-back])))
+19 -19
View File
@@ -5,7 +5,8 @@
[react-native.core :as rn]
[react-native.orientation :as orientation]
[react-native.platform :as platform]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[status-im2.contexts.chat.lightbox.common :as common]
[utils.re-frame :as rf]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
@@ -19,18 +20,18 @@
(defn toggle-opacity
[opacity-value border-value transparent? index {:keys [small-list-ref]}]
(let [opacity (ra/get-val opacity-value)]
(let [opacity (reanimated/get-shared-value opacity-value)]
(if (= opacity 1)
(do
(ra/animate opacity-value 0)
(common/set-val-timing opacity-value 0)
(js/setTimeout #(reset! transparent? (not @transparent?)) 400))
(do
(reset! transparent? (not @transparent?))
(ra/animate-delay opacity-value 1 50)
(reanimated/animate-shared-value-with-delay-default-easing opacity-value 1 300 50)
(js/setTimeout #(when @small-list-ref
(.scrollToIndex ^js @small-list-ref #js {:animated false :index index}))
100)))
(ra/animate border-value (if (= opacity 1) 0 12))))
(common/set-val-timing border-value (if (= opacity 1) 0 12))))
(defn handle-orientation
[result index window animations {:keys [flat-list-ref insets-atom]}]
@@ -102,19 +103,18 @@
scroll-index (reagent/atom index)
transparent? (reagent/atom false)
window (rf/sub [:dimensions/window])
animations {:border (ra/use-val (if platform/ios? 0 12))
:opacity (ra/use-val 0)
:rotate (ra/use-val "0deg")
:top-layout (ra/use-val -10)
:bottom-layout (ra/use-val 10)
:top-view-y (ra/use-val 0)
:top-view-x (ra/use-val 0)
:top-view-width (ra/use-val (:width window))
:top-view-bg (ra/use-val colors/neutral-100-opa-0)}
animations {:border (common/use-val (if platform/ios? 0 12))
:opacity (common/use-val 0)
:rotate (common/use-val "0deg")
:top-layout (common/use-val -10)
:bottom-layout (common/use-val 10)
:top-view-y (common/use-val 0)
:top-view-x (common/use-val 0)
:top-view-width (common/use-val (:width window))
:top-view-bg (common/use-val colors/neutral-100-opa-0)}
callback (fn [e]
(on-viewable-items-changed e scroll-index atoms))]
(println "aims" (ra/get-val (:opacity animations)))
(reset! data messages)
(orientation/use-device-orientation-change
(fn [result]
@@ -131,10 +131,10 @@
(.scrollToIndex ^js @(:flat-list-ref atoms)
#js {:animated false :index index}))
(js/setTimeout (fn []
(ra/animate (:opacity animations) 1)
(ra/animate (:top-layout animations) 0)
(ra/animate (:bottom-layout animations) 0)
(ra/animate (:border animations) 12))
(common/set-val-timing (:opacity animations) 1)
(common/set-val-timing (:top-layout animations) 0)
(common/set-val-timing (:bottom-layout animations) 0)
(common/set-val-timing (:border animations) 12))
(if platform/ios? 250 100))
(js/setTimeout #(reset! (:scroll-index-lock? atoms) false) 300)
(fn []
@@ -1,13 +1,13 @@
(ns status-im2.contexts.chat.lightbox.zoomable-image.style
(:require
[react-native.platform :as platform]
[react-native.reanimated :as ra]))
[react-native.reanimated :as reanimated]))
(defn container
[{:keys [width height]}
{:keys [pan-x pan-y pinch-x pinch-y scale]}
set-full-height?]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:transform [{:translateX pan-x}
{:translateY pan-y}
{:translateX pinch-x}
@@ -22,7 +22,7 @@
[{:keys [image-width image-height]}
{:keys [rotate rotate-scale]}
border-radius]
(ra/apply-animations-to-style
(reanimated/apply-animations-to-style
{:transform [{:rotate rotate}
{:scale rotate-scale}]
:border-radius border-radius}
@@ -3,96 +3,10 @@
[clojure.string :as string]
[react-native.orientation :as orientation]
[react-native.platform :as platform]
[react-native.reanimated :as ra]
[status-im2.contexts.chat.lightbox.zoomable-image.constants :as c]
[utils.re-frame :as rf]))
;;; Helpers
(defn center-x
[{:keys [pinch-x pinch-x-start pan-x pan-x-start]} exit?]
(let [duration (if exit? 100 c/default-duration)]
(ra/animate pinch-x c/init-offset duration)
(ra/set-val pinch-x-start c/init-offset)
(ra/animate pan-x c/init-offset duration)
(ra/set-val pan-x-start c/init-offset)))
(defn center-y
[{:keys [pinch-y pinch-y-start pan-y pan-y-start]} exit?]
(let [duration (if exit? 100 c/default-duration)]
(ra/animate pinch-y c/init-offset duration)
(ra/set-val pinch-y-start c/init-offset)
(ra/animate pan-y c/init-offset duration)
(ra/set-val pan-y-start c/init-offset)))
(defn reset-values
[exit? animations {:keys [focal-x focal-y]}]
(center-x animations exit?)
(center-y animations exit?)
(reset! focal-x nil)
(reset! focal-y nil))
(defn rescale-image
[value
exit?
{:keys [x-threshold-scale y-threshold-scale]}
{:keys [scale saved-scale] :as animations}
{:keys [pan-x-enabled? pan-y-enabled?] :as props}]
(ra/animate scale value (if exit? 100 c/default-duration))
(ra/set-val saved-scale value)
(when (= value c/min-scale)
(reset-values exit? animations props))
(reset! pan-x-enabled? (> value x-threshold-scale))
(reset! pan-y-enabled? (> value y-threshold-scale))
(when platform/android?
(rf/dispatch [:chat.ui/lightbox-scale value])))
;;; Handlers
(defn handle-orientation-change
[curr-orientation
focused?
{:keys [landscape-scale-val x-threshold-scale y-threshold-scale]}
{:keys [rotate rotate-scale scale] :as animations}
{:keys [pan-x-enabled? pan-y-enabled?]}]
(let [duration (when focused? c/default-duration)]
(cond
(= curr-orientation orientation/landscape-left)
(do
(ra/animate rotate "90deg" duration)
(ra/animate rotate-scale landscape-scale-val duration))
(= curr-orientation orientation/landscape-right)
(do
(ra/animate rotate "-90deg" duration)
(ra/animate rotate-scale landscape-scale-val duration))
(= curr-orientation orientation/portrait)
(do
(ra/animate rotate c/init-rotation duration)
(ra/animate rotate-scale c/min-scale duration)))
(center-x animations false)
(center-y animations false)
(reset! pan-x-enabled? (> (ra/get-val scale) x-threshold-scale))
(reset! pan-y-enabled? (> (ra/get-val scale) y-threshold-scale))))
(defn handle-exit-lightbox-signal
"On ios, when attempting to navigate back while zoomed in, the shared-element transition animation
doesn't execute properly, so we need to zoom out first"
[exit-lightbox-signal index scale rescale set-full-height?]
(when (= exit-lightbox-signal index)
(reset! set-full-height? false)
(if (> scale c/min-scale)
(do
(rescale c/min-scale true)
(js/setTimeout #(rf/dispatch [:navigate-back]) 70))
(rf/dispatch [:navigate-back]))
(js/setTimeout #(rf/dispatch [:chat.ui/exit-lightbox-signal nil]) 500)))
(defn handle-zoom-out-signal
"Zooms out when pressing on another photo from the small bottom list"
[zoom-out-signal index scale rescale]
(when (and (= zoom-out-signal index) (> scale c/min-scale))
(rescale c/min-scale true)))
;;; Dimensions
(defn get-dimensions
"Calculates all required dimensions. Dimensions calculations are different on iOS and Android because landscape
mode is implemented differently.On Android, we just need to resize the content, and the OS takes care of the
@@ -125,6 +39,25 @@
:y-threshold-scale (/ screen-height (min screen-height container-height))
:landscape-scale-val (/ portrait-image-width portrait-image-height)}))
(defn handle-exit-lightbox-signal
"On ios, when attempting to navigate back while zoomed in, the shared-element transition animation
doesn't execute properly, so we need to zoom out first"
[exit-lightbox-signal index scale rescale set-full-height?]
(when (= exit-lightbox-signal index)
(reset! set-full-height? false)
(if (> scale c/min-scale)
(do
(rescale c/min-scale true)
(js/setTimeout #(rf/dispatch [:navigate-back]) 70))
(rf/dispatch [:navigate-back]))
(js/setTimeout #(rf/dispatch [:chat.ui/exit-lightbox-signal nil]) 500)))
(defn handle-zoom-out-signal
"Zooms out when pressing on another photo from the small bottom list"
[zoom-out-signal index scale rescale]
(when (and (= zoom-out-signal index) (> scale c/min-scale))
(rescale c/min-scale true)))
;;; MATH
(defn get-max-offset
@@ -12,6 +12,98 @@
[status-im2.contexts.chat.lightbox.zoomable-image.style :as style]
[status-im2.contexts.chat.lightbox.zoomable-image.utils :as utils]))
;;;; Some aliases for reanimated methods, as they are used 10s of times in this file
;; TODO: Abstract Reanimated methods in a better way, issue:
;; https://github.com/status-im/status-mobile/issues/15176
(defn get-val
[animation]
(reanimated/get-shared-value animation))
(defn set-val
[animation value]
(reanimated/set-shared-value animation value))
(defn use-val
[value]
(reanimated/use-shared-value value))
(defn timing
([value]
(timing value c/default-duration))
([value duration]
(if (= duration nil)
value
(reanimated/with-timing-duration value duration))))
(defn set-val-decay
[animation velocity bounds]
(reanimated/animate-shared-value-with-decay animation (* velocity c/velocity-factor) bounds))
;;;; Helpers
(defn center-x
[{:keys [pinch-x pinch-x-start pan-x pan-x-start]} exit?]
(let [duration (if exit? 100 c/default-duration)]
(set-val pinch-x (timing c/init-offset duration))
(set-val pinch-x-start c/init-offset)
(set-val pan-x (timing c/init-offset duration))
(set-val pan-x-start c/init-offset)))
(defn center-y
[{:keys [pinch-y pinch-y-start pan-y pan-y-start]} exit?]
(let [duration (if exit? 100 c/default-duration)]
(set-val pinch-y (timing c/init-offset duration))
(set-val pinch-y-start c/init-offset)
(set-val pan-y (timing c/init-offset duration))
(set-val pan-y-start c/init-offset)))
(defn reset-values
[exit? animations {:keys [focal-x focal-y]}]
(center-x animations exit?)
(center-y animations exit?)
(reset! focal-x nil)
(reset! focal-y nil))
(defn rescale-image
[value
exit?
{:keys [x-threshold-scale y-threshold-scale]}
{:keys [scale saved-scale] :as animations}
{:keys [pan-x-enabled? pan-y-enabled?] :as props}]
(set-val scale (timing value (if exit? 100 c/default-duration)))
(set-val saved-scale value)
(when (= value c/min-scale)
(reset-values exit? animations props))
(reset! pan-x-enabled? (> value x-threshold-scale))
(reset! pan-y-enabled? (> value y-threshold-scale))
(when platform/android?
(rf/dispatch [:chat.ui/lightbox-scale value])))
(defn handle-orientation-change
[curr-orientation
focused?
{:keys [landscape-scale-val x-threshold-scale y-threshold-scale]}
{:keys [rotate rotate-scale scale] :as animations}
{:keys [pan-x-enabled? pan-y-enabled?]}]
(let [duration (when focused? c/default-duration)]
(cond
(= curr-orientation orientation/landscape-left)
(do
(set-val rotate (timing "90deg" duration))
(set-val rotate-scale (timing landscape-scale-val duration)))
(= curr-orientation orientation/landscape-right)
(do
(set-val rotate (timing "-90deg" duration))
(set-val rotate-scale (timing landscape-scale-val duration)))
(= curr-orientation orientation/portrait)
(do
(set-val rotate (timing c/init-rotation duration))
(set-val rotate-scale (timing c/min-scale duration))))
(center-x animations false)
(center-y animations false)
(reset! pan-x-enabled? (> (get-val scale) x-threshold-scale))
(reset! pan-y-enabled? (> (get-val scale) y-threshold-scale))))
;;;; Gestures
(defn tap-gesture
[on-tap]
(->
@@ -27,15 +119,15 @@
(gesture/number-of-taps 2)
(gesture/on-start
(fn [e]
(if (= (reanimated/get-shared-value scale) c/min-scale)
(if (= (get-val scale) c/min-scale)
(let [translate-x (utils/get-double-tap-offset width screen-width (oget e "x"))
translate-y (utils/get-double-tap-offset height screen-height (oget e "y"))]
(when (> c/double-tap-scale x-threshold-scale)
(reanimated/set-shared-value pan-x (reanimated/with-timing translate-x))
(reanimated/set-shared-value pan-x-start translate-x))
(set-val pan-x (timing translate-x))
(set-val pan-x-start translate-x))
(when (> c/double-tap-scale y-threshold-scale)
(reanimated/set-shared-value pan-y (reanimated/with-timing translate-y))
(reanimated/set-shared-value pan-y-start translate-y))
(set-val pan-y (timing translate-y))
(set-val pan-y-start translate-y))
(rescale c/double-tap-scale))
(rescale c/min-scale))))))
@@ -45,30 +137,30 @@
{:keys [saved-scale scale pinch-x pinch-y pinch-x-start pinch-y-start pan-y pan-y-start pan-x
pan-x-start]}
{:keys [pan-x-enabled? pan-y-enabled?]}]
(let [curr-offset-y (+ (reanimated/get-shared-value pan-y) (reanimated/get-shared-value pinch-y))
max-offset-y (utils/get-max-offset height screen-height (reanimated/get-shared-value scale))
(let [curr-offset-y (+ (get-val pan-y) (get-val pinch-y))
max-offset-y (utils/get-max-offset height screen-height (get-val scale))
max-offset-y (if (neg? curr-offset-y) (- max-offset-y) max-offset-y)
curr-offset-x (+ (reanimated/get-shared-value pan-x) (reanimated/get-shared-value pinch-x))
max-offset-x (utils/get-max-offset width screen-width (reanimated/get-shared-value scale))
curr-offset-x (+ (get-val pan-x) (get-val pinch-x))
max-offset-x (utils/get-max-offset width screen-width (get-val scale))
max-offset-x (if (neg? curr-offset-x) (- max-offset-x) max-offset-x)]
(when (and (> (reanimated/get-shared-value scale) y-threshold-scale)
(< (reanimated/get-shared-value scale) c/max-scale)
(when (and (> (get-val scale) y-threshold-scale)
(< (get-val scale) c/max-scale)
(> (Math/abs curr-offset-y) (Math/abs max-offset-y)))
(reanimated/set-shared-value pinch-y (reanimated/with-timing c/init-offset))
(reanimated/set-shared-value pinch-y-start c/init-offset)
(reanimated/set-shared-value pan-y (reanimated/with-timing max-offset-y))
(reanimated/set-shared-value pan-y-start max-offset-y))
(when (and (> (reanimated/get-shared-value scale) x-threshold-scale)
(< (reanimated/get-shared-value scale) c/max-scale)
(set-val pinch-y (timing c/init-offset))
(set-val pinch-y-start c/init-offset)
(set-val pan-y (timing max-offset-y))
(set-val pan-y-start max-offset-y))
(when (and (> (get-val scale) x-threshold-scale)
(< (get-val scale) c/max-scale)
(> (Math/abs curr-offset-x) (Math/abs max-offset-x)))
(reanimated/set-shared-value pinch-x (reanimated/with-timing c/init-offset))
(reanimated/set-shared-value pinch-x-start c/init-offset)
(reanimated/set-shared-value pan-x (reanimated/with-timing max-offset-x))
(reanimated/set-shared-value pan-x-start max-offset-x))
(reset! pan-x-enabled? (> (reanimated/get-shared-value scale) x-threshold-scale))
(reset! pan-y-enabled? (> (reanimated/get-shared-value scale) y-threshold-scale))
(set-val pinch-x (timing c/init-offset))
(set-val pinch-x-start c/init-offset)
(set-val pan-x (timing max-offset-x))
(set-val pan-x-start max-offset-x))
(reset! pan-x-enabled? (> (get-val scale) x-threshold-scale))
(reset! pan-y-enabled? (> (get-val scale) y-threshold-scale))
(when platform/android?
(rf/dispatch [:chat.ui/lightbox-scale (reanimated/get-shared-value saved-scale)]))))
(rf/dispatch [:chat.ui/lightbox-scale (get-val saved-scale)]))))
(defn pinch-gesture
[{:keys [width height screen-height screen-width x-threshold-scale y-threshold-scale] :as dimensions}
@@ -86,49 +178,41 @@
(when platform/android?
(reset! focal-x (utils/get-focal (oget e "focalX") width screen-width))
(reset! focal-y (utils/get-focal (oget e "focalY") height screen-height)))))
(gesture/on-update
(fn [e]
(let [new-scale (* (oget e "scale") (reanimated/get-shared-value saved-scale))
scale-diff (utils/get-scale-diff new-scale (reanimated/get-shared-value saved-scale))
new-pinch-x (utils/get-pinch-position scale-diff screen-width @focal-x)
new-pinch-y (utils/get-pinch-position scale-diff screen-height @focal-y)]
(when (and (>= new-scale c/max-scale)
(= (reanimated/get-shared-value pinch-x-max) js/Infinity))
(reanimated/set-shared-value pinch-x-max (reanimated/get-shared-value pinch-x))
(reanimated/set-shared-value pinch-y-max (reanimated/get-shared-value pinch-y)))
(reanimated/set-shared-value pinch-x
(+ new-pinch-x (reanimated/get-shared-value pinch-x-start)))
(reanimated/set-shared-value pinch-y
(+ new-pinch-y (reanimated/get-shared-value pinch-y-start)))
(reanimated/set-shared-value scale new-scale))))
(gesture/on-update (fn [e]
(let [new-scale (* (oget e "scale") (get-val saved-scale))
scale-diff (utils/get-scale-diff new-scale (get-val saved-scale))
new-pinch-x (utils/get-pinch-position scale-diff screen-width @focal-x)
new-pinch-y (utils/get-pinch-position scale-diff screen-height @focal-y)]
(when (and (>= new-scale c/max-scale) (= (get-val pinch-x-max) js/Infinity))
(set-val pinch-x-max (get-val pinch-x))
(set-val pinch-y-max (get-val pinch-y)))
(set-val pinch-x (+ new-pinch-x (get-val pinch-x-start)))
(set-val pinch-y (+ new-pinch-y (get-val pinch-y-start)))
(set-val scale new-scale))))
(gesture/on-end
(fn []
(cond
(< (reanimated/get-shared-value scale) c/min-scale)
(< (get-val scale) c/min-scale)
(rescale c/min-scale)
(> (reanimated/get-shared-value scale) c/max-scale)
(> (get-val scale) c/max-scale)
(do
(reanimated/set-shared-value pinch-x
(reanimated/with-timing (reanimated/get-shared-value
pinch-x-max)))
(reanimated/set-shared-value pinch-x-start (reanimated/get-shared-value pinch-x-max))
(reanimated/set-shared-value pinch-x-max js/Infinity)
(reanimated/set-shared-value pinch-y
(reanimated/with-timing (reanimated/get-shared-value
pinch-y-max)))
(reanimated/set-shared-value pinch-y-start (reanimated/get-shared-value pinch-y-max))
(reanimated/set-shared-value pinch-y-max js/Infinity)
(reanimated/set-shared-value scale (reanimated/with-timing c/max-scale))
(reanimated/set-shared-value saved-scale c/max-scale))
(set-val pinch-x (timing (get-val pinch-x-max)))
(set-val pinch-x-start (get-val pinch-x-max))
(set-val pinch-x-max js/Infinity)
(set-val pinch-y (timing (get-val pinch-y-max)))
(set-val pinch-y-start (get-val pinch-y-max))
(set-val pinch-y-max js/Infinity)
(set-val scale (timing c/max-scale))
(set-val saved-scale c/max-scale))
:else
(do
(reanimated/set-shared-value saved-scale (reanimated/get-shared-value scale))
(reanimated/set-shared-value pinch-x-start (reanimated/get-shared-value pinch-x))
(reanimated/set-shared-value pinch-y-start (reanimated/get-shared-value pinch-y))
(when (< (reanimated/get-shared-value scale) x-threshold-scale)
(utils/center-x animations false))
(when (< (reanimated/get-shared-value scale) y-threshold-scale)
(utils/center-y animations false))))
(set-val saved-scale (get-val scale))
(set-val pinch-x-start (get-val pinch-x))
(set-val pinch-y-start (get-val pinch-y))
(when (< (get-val scale) x-threshold-scale)
(center-x animations false))
(when (< (get-val scale) y-threshold-scale)
(center-y animations false))))
(finalize-pinch dimensions animations props)))))
(defn pan-x-gesture
@@ -141,33 +225,27 @@
(gesture/enabled @pan-x-enabled?)
(gesture/average-touches false)
(gesture/on-update (fn [e]
(reanimated/set-shared-value pan-x
(+ (reanimated/get-shared-value pan-x-start)
(oget e "translationX")))))
(set-val pan-x (+ (get-val pan-x-start) (oget e "translationX")))))
(gesture/on-end
(fn [e]
(let [curr-offset (+ (reanimated/get-shared-value pan-x)
(reanimated/get-shared-value pinch-x-start))
max-offset (utils/get-max-offset width screen-width (reanimated/get-shared-value scale))
max-offset (if (neg? curr-offset) (- max-offset) max-offset)
velocity (* (oget e "velocityX") c/velocity-factor)]
(let [curr-offset (+ (get-val pan-x) (get-val pinch-x-start))
max-offset (utils/get-max-offset width screen-width (get-val scale))
max-offset (if (neg? curr-offset) (- max-offset) max-offset)]
(cond
(< (reanimated/get-shared-value scale) x-threshold-scale)
(< (get-val scale) x-threshold-scale)
(rescale c/min-scale)
(> (Math/abs curr-offset) (Math/abs max-offset))
(do
(reanimated/set-shared-value pan-x (reanimated/with-timing max-offset))
(reanimated/set-shared-value pan-x-start max-offset)
(reanimated/set-shared-value pinch-x (reanimated/with-timing c/init-offset))
(reanimated/set-shared-value pinch-x-start c/init-offset))
(set-val pan-x (timing max-offset))
(set-val pan-x-start max-offset)
(set-val pinch-x (timing c/init-offset))
(set-val pinch-x-start c/init-offset))
:else
(let [lower-bound (- (- (Math/abs max-offset)) (reanimated/get-shared-value pinch-x-start))
upper-bound (- (Math/abs max-offset) (reanimated/get-shared-value pinch-x-start))]
(reanimated/set-shared-value pan-x-start (reanimated/get-shared-value pan-x))
(reanimated/animate-shared-value-with-decay pan-x velocity [lower-bound upper-bound])
(reanimated/animate-shared-value-with-decay pan-x-start
velocity
[lower-bound upper-bound]))))))))
(let [lower-bound (- (- (Math/abs max-offset)) (get-val pinch-x-start))
upper-bound (- (Math/abs max-offset) (get-val pinch-x-start))]
(set-val pan-x-start (get-val pan-x))
(set-val-decay pan-x (oget e "velocityX") [lower-bound upper-bound])
(set-val-decay pan-x-start (oget e "velocityX") [lower-bound upper-bound]))))))))
(defn pan-y-gesture
@@ -180,34 +258,30 @@
(gesture/enabled @pan-y-enabled?)
(gesture/average-touches false)
(gesture/on-update (fn [e]
(reanimated/set-shared-value pan-y
(+ (reanimated/get-shared-value pan-y-start)
(oget e "translationY")))))
(set-val pan-y (+ (get-val pan-y-start) (oget e "translationY")))))
(gesture/on-end
(fn [e]
(let [curr-offset (+ (reanimated/get-shared-value pan-y)
(reanimated/get-shared-value pinch-y-start))
max-offset (utils/get-max-offset height screen-height (reanimated/get-shared-value scale))
max-offset (if (neg? curr-offset) (- max-offset) max-offset)
velocity (* (oget e "velocityY") c/velocity-factor)]
(let [curr-offset (+ (get-val pan-y) (get-val pinch-y-start))
max-offset (utils/get-max-offset height screen-height (get-val scale))
max-offset (if (neg? curr-offset) (- max-offset) max-offset)]
(cond
(< (reanimated/get-shared-value scale) y-threshold-scale)
(< (get-val scale) y-threshold-scale)
(rescale c/min-scale)
(> (Math/abs curr-offset) (Math/abs max-offset))
(do
(reanimated/set-shared-value pan-y (reanimated/with-timing max-offset))
(reanimated/set-shared-value pan-y-start max-offset)
(reanimated/set-shared-value pinch-y (reanimated/with-timing c/init-offset))
(reanimated/set-shared-value pinch-y-start c/init-offset))
(set-val pan-y (timing max-offset))
(set-val pan-y-start max-offset)
(set-val pinch-y (timing c/init-offset))
(set-val pinch-y-start c/init-offset))
:else
(let [lower-bound (- (- (Math/abs max-offset)) (reanimated/get-shared-value pinch-y-start))
upper-bound (- (Math/abs max-offset) (reanimated/get-shared-value pinch-y-start))]
(reanimated/set-shared-value pan-y-start (reanimated/get-shared-value pan-y))
(reanimated/animate-shared-value-with-decay pan-y velocity [lower-bound upper-bound])
(reanimated/animate-shared-value-with-decay pan-y-start
velocity
[lower-bound upper-bound]))))))))
(let [lower-bound (- (- (Math/abs max-offset)) (get-val pinch-y-start))
upper-bound (- (Math/abs max-offset) (get-val pinch-y-start))]
(set-val pan-y-start (get-val pan-y))
(set-val-decay pan-y (oget e "velocityY") [lower-bound upper-bound])
(set-val-decay pan-y-start (oget e "velocityY") [lower-bound upper-bound]))))))))
;;;; Finally, the component
(defn zoomable-image
[{:keys [image-width image-height content message-id]} index border-radius on-tap]
(let [set-full-height? (reagent/atom false)]
@@ -220,40 +294,37 @@
curr-orientation (or (rf/sub [:lightbox/orientation]) orientation/portrait)
focused? (= shared-element-id message-id)
dimensions (utils/get-dimensions image-width image-height curr-orientation)
animations {:scale (reanimated/use-shared-value initial-scale)
:saved-scale (reanimated/use-shared-value initial-scale)
:pan-x-start (reanimated/use-shared-value c/init-offset)
:pan-x (reanimated/use-shared-value c/init-offset)
:pan-y-start (reanimated/use-shared-value c/init-offset)
:pan-y (reanimated/use-shared-value c/init-offset)
:pinch-x-start (reanimated/use-shared-value c/init-offset)
:pinch-x (reanimated/use-shared-value c/init-offset)
:pinch-y-start (reanimated/use-shared-value c/init-offset)
:pinch-y (reanimated/use-shared-value c/init-offset)
:pinch-x-max (reanimated/use-shared-value js/Infinity)
:pinch-y-max (reanimated/use-shared-value js/Infinity)
:rotate (reanimated/use-shared-value c/init-rotation)
:rotate-scale (reanimated/use-shared-value c/min-scale)}
animations {:scale (use-val initial-scale)
:saved-scale (use-val initial-scale)
:pan-x-start (use-val c/init-offset)
:pan-x (use-val c/init-offset)
:pan-y-start (use-val c/init-offset)
:pan-y (use-val c/init-offset)
:pinch-x-start (use-val c/init-offset)
:pinch-x (use-val c/init-offset)
:pinch-y-start (use-val c/init-offset)
:pinch-y (use-val c/init-offset)
:pinch-x-max (use-val js/Infinity)
:pinch-y-max (use-val js/Infinity)
:rotate (use-val c/init-rotation)
:rotate-scale (use-val c/min-scale)}
props {:pan-x-enabled? (reagent/atom false)
:pan-y-enabled? (reagent/atom false)
:focal-x (reagent/atom nil)
:focal-y (reagent/atom nil)}
rescale (fn [value exit?]
(utils/rescale-image value exit? dimensions animations props))]
(rescale-image value exit? dimensions animations props))]
(rn/use-effect-once (fn []
(js/setTimeout #(reset! set-full-height? true) 500)
js/undefined))
(when platform/ios?
(utils/handle-orientation-change curr-orientation focused? dimensions animations props)
(handle-orientation-change curr-orientation focused? dimensions animations props)
(utils/handle-exit-lightbox-signal exit-lightbox-signal
index
(reanimated/get-shared-value (:scale animations))
(get-val (:scale animations))
rescale
set-full-height?))
(utils/handle-zoom-out-signal zoom-out-signal
index
(reanimated/get-shared-value (:scale animations))
rescale)
(utils/handle-zoom-out-signal zoom-out-signal index (get-val (:scale animations)) rescale)
[:f>
(fn []
(let [tap (tap-gesture on-tap)
@@ -265,9 +336,10 @@
(gesture/simultaneous pinch pan-x pan-y)
(gesture/exclusive double-tap tap))]
[gesture/gesture-detector {:gesture composed-gestures}
[ra/view
[reanimated/view
{:style (style/container dimensions animations @set-full-height?)}
[ra/fast-image
[reanimated/fast-image
{:source {:uri (:image content)}
:native-ID (when focused? :shared-element)
:style (style/image dimensions animations border-radius)}]]]))]))]))
@@ -1,7 +1,7 @@
(ns status-im2.contexts.chat.messages.composer.mentions.view
(:require [utils.re-frame :as rf]
[react-native.core :as rn]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[status-im2.common.contact-list-item.view :as contact-list-item]))
(defn mention-item
@@ -13,13 +13,13 @@
[{:keys [refs suggestions max-y]} insets]
[:f>
(fn []
(let [translate-y (ra/use-val 0)]
(let [translate-y (reanimated/use-shared-value 0)]
(rn/use-effect
(fn []
(ra/set-val translate-y
(ra/with-timing (if (seq suggestions) 0 200)))))
[ra/view
{:style (ra/apply-animations-to-style
(reanimated/set-shared-value translate-y
(reanimated/with-timing (if (seq suggestions) 0 200)))))
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:transform [{:translateY translate-y}]}
{:bottom (or (:bottom insets) 0)
:position :absolute
@@ -4,7 +4,7 @@
[react-native.core :as rn]
[react-native.hooks :as hooks]
[react-native.gesture :as gesture]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[react-native.background-timer :as background-timer]
[utils.re-frame :as rf]
[status-im2.contexts.chat.messages.composer.style :as style]
@@ -43,7 +43,7 @@
(gesture/on-start
(fn [_]
(if keyboard-shown
(swap! gesture-values assoc :pan-y (ra/get-val translate-y))
(swap! gesture-values assoc :pan-y (reanimated/get-shared-value translate-y))
(input/input-focus text-input-ref))))
(gesture/on-update
(fn [evt]
@@ -51,7 +51,7 @@
(let [tY (oget evt "translationY")]
(swap! gesture-values assoc :dy (- tY (:pdy @gesture-values)))
(swap! gesture-values assoc :pdy tY)
(ra/set-val
(reanimated/set-shared-value
translate-y
(max (min (+ tY (:pan-y @gesture-values)) (- min-y)) (- max-y)))))))
(gesture/on-end
@@ -129,12 +129,12 @@
:bg-bottom bg-bottom
:window-height window-height
:set-bg-opacity (fn [value]
(ra/set-val bg-bottom (if (= value 1) 0 (- window-height)))
(ra/set-val bg-opacity (ra/with-timing value)))
(reanimated/set-shared-value bg-bottom (if (= value 1) 0 (- window-height)))
(reanimated/set-shared-value bg-opacity (reanimated/with-timing value)))
:set-translate-y (fn [value]
(ra/set-val translate-y (ra/with-timing value)))
(reanimated/set-shared-value translate-y (reanimated/with-timing value)))
:set-parent-height (fn [value]
(ra/set-val parent-height (ra/with-timing value)))})
(reanimated/set-shared-value parent-height (reanimated/with-timing value)))})
;; IMPORTANT! PLEASE READ BEFORE MAKING CHANGES
@@ -165,9 +165,9 @@
{window-height :height} (rn/use-window-dimensions)
{:keys [keyboard-shown keyboard-height]} (hooks/use-keyboard)
translate-y (ra/use-val 0)
bg-opacity (ra/use-val 0)
bg-bottom (ra/use-val (- window-height))
translate-y (reanimated/use-shared-value 0)
bg-opacity (reanimated/use-shared-value 0)
bg-bottom (reanimated/use-shared-value (- window-height))
suggestions? (and (seq suggestions)
keyboard-shown
@@ -190,7 +190,7 @@
(when (or edit reply) 38)
(when (seq images) 80))))
parent-height (ra/use-val min-y)
parent-height (reanimated/use-shared-value min-y)
max-parent-height (Math/abs (- max-y 110 (:bottom insets)))
params
@@ -201,14 +201,14 @@
input-content-change (get-input-content-change params)
bottom-sheet-gesture (get-bottom-sheet-gesture params)]
(effect! params)
[ra/view
{:style (ra/apply-animations-to-style
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:height parent-height}
{})}
;;;;input
[gesture/gesture-detector {:gesture bottom-sheet-gesture}
[ra/view
{:style (ra/apply-animations-to-style
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:transform [{:translateY translate-y}]}
(style/input-bottom-sheet window-height))}
[rn/view {:style (style/bottom-sheet-handle)}]
@@ -225,8 +225,8 @@
[mentions/mentions params insets]
[controls/view send-ref params insets chat-id images #(clean-and-minimize params)])
;;;;black background
[ra/view
{:style (ra/apply-animations-to-style
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:opacity bg-opacity
:transform [{:translateY bg-bottom}]}
(style/bottom-sheet-background window-height))}]]))])))
@@ -2,10 +2,9 @@
(:require [react-native.platform :as platform]))
(def screen-title-container
{:height 56
:padding-vertical 12
:justify-content :center
:margin-horizontal 20})
{:height 56
:padding-vertical 12
:justify-content :center})
(def featured-communities-header
{:flex-direction :row
@@ -13,7 +12,6 @@
:padding-top 8
:margin-bottom 8
:padding-right 20
:margin-left 20
:justify-content :space-between})
(def featured-communities-title-container
@@ -23,13 +21,7 @@
(def featured-list-container
{:flex-direction :row
:overflow :hidden
:margin-bottom 24
:margin-left 20
:padding-right 20})
(def other-communities-container
{:flex 1
:margin-horizontal 20})
:margin-bottom 24})
(defn discover-communities-segments
[fixed?]
@@ -38,9 +30,8 @@
:height 56
:background-color :transparent}
(when-not fixed?
{:margin-top 12
:margin-horizontal 20
:margin-bottom 4})))
{:margin-top 12
:margin-bottom 4})))
(defn discover-screen-container
[background-color]
@@ -56,7 +47,8 @@
:justify-content :center})
(def render-communities-container
{:margin-top 100})
{:padding-horizontal 20
:margin-top 100})
(defn blur-tabs-header
[]
@@ -18,17 +18,26 @@
{:data {:community-color "#0052FF"
:status :gated
:locked? true
:cover (resources/get-mock-image :community-cover)
:tokens [{:id 1
:group [{:id 1
:token-icon (resources/get-mock-image :status-logo)}]}]}})
:token-icon (resources/get-mock-image :status-logo)}]}]
:tags [{:id 1
:tag-label (i18n/label :t/music)
:resource (resources/get-image :music)}
{:id 2
:tag-label (i18n/label :t/lifestyle)
:resource (resources/get-image :lifestyle)}
{:id 3
:tag-label (i18n/label :t/podcasts)
:resource (resources/get-image :podcasts)}]}})
(defn render-fn
[community-item _ _ {:keys [width view-type]}]
(let [item (merge community-item
(get mock-community-item-data :data))
cover {:uri (get-in (:images item) [:banner :uri])}]
(let [item (merge community-item
(get mock-community-item-data :data))]
(if (= view-type :card-view)
[quo/community-card-view-item (assoc item :width width :cover cover)
[quo/community-card-view-item (assoc item :width width)
#(rf/dispatch [:navigate-to :community-overview (:id item)])]
[quo/communities-list-view-item
{:on-press (fn []
@@ -125,7 +134,7 @@
(defn other-communities-list
[{:keys [communities communities-ids view-type]}]
[rn/view {:style style/other-communities-container}
[rn/view {:flex 1}
(map-indexed
(fn [inner-index item]
(let [community-id (when communities-ids item)
@@ -288,12 +288,10 @@
(let [categories-heights (reagent/atom [])
first-channel-height (reagent/atom 0)
scroll-height (reagent/atom 0)
cover {:uri (get-in images [:banner :uri])}
logo {:uri (get-in images [:thumbnail :uri])}]
cover {:uri (get-in images [:large :uri])}]
(fn [community]
[scroll-page/scroll-page
{:cover-image cover
:logo logo
:page-nav-right-section-buttons (page-nav-right-section-buttons id)
:name name
:on-scroll #(reset! scroll-height %)
@@ -0,0 +1,19 @@
(ns status-im2.contexts.emoji-hash.events
(:require [utils.re-frame :as rf]
[status-im.native-module.core :as native-module]
[utils.transforms :as transform]))
(defn fetch-for-current-public-key
[]
(let [public-key (rf/sub [:multiaccount/public-key])]
(native-module/public-key->emoji-hash
public-key
(fn [response]
(let [response-clj (transform/json->clj response)
emoji-hash (get response-clj :result)]
(rf/dispatch [:emoji-hash/add-to-multiaccount emoji-hash]))))))
(rf/defn add-emoji-hash-to-multiaccount
{:events [:emoji-hash/add-to-multiaccount]}
[{:keys [db]} emoji-hash]
{:db (assoc db :multiaccount/emoji-hash emoji-hash)})
@@ -1,26 +0,0 @@
(ns status-im2.contexts.onboarding.common.background
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[status-im2.common.resources :as resources]
[react-native.linear-gradient :as linear-gradient]
[status-im2.contexts.onboarding.common.style :as style]))
(defn view
[dark-overlay?]
[rn/view
{:style style/background-container}
;; Todo - add carousel component as background once ready
;; https://github.com/status-im/status-mobile/issues/15012
[rn/image
{:blur-radius (if dark-overlay? 13 0)
:style {:flex 1}
:source (resources/get-image :onboarding-bg-1)}]
[linear-gradient/linear-gradient
{:colors [(if dark-overlay? (colors/custom-color :yin 50) "#000716")
(if dark-overlay? (colors/custom-color :yin 50 0) "#000716")]
:start {:x 0 :y 0}
:end {:x 0 :y 1}
:style (style/background-gradient-overlay dark-overlay?)}]
(when dark-overlay?
[rn/view
{:style style/background-blur-overlay}])])
@@ -1,61 +0,0 @@
(ns status-im2.contexts.onboarding.common.intro.style
(:require
[react-native.platform :as platform]
[quo2.foundations.colors :as colors]))
(def progress-bar-container
{:background-color colors/neutral-100
:flex-direction :row
:margin-vertical 16})
(defn progress-bar-item
[index position end?]
{:height 2
:flex 1
:border-width 1
:border-color (if (= index position) colors/white colors/white-opa-10)
:margin-right (if end? 0 8)})
(def carousel
{:height 92
;; (padding-top) This insets issue needs a consistent implementation across all screens.
:padding-top (if platform/android? 0 44)
:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:z-index 2
:background-color colors/neutral-100
:padding-vertical 12
:padding-horizontal 20})
(def carousel-text
{:background-color colors/neutral-100
:color colors/white})
(def page-container
{:flex 1
:justify-content :flex-end})
(def page-image
{:position :absolute
:background-color colors/neutral-100
:top 0
:bottom 0
:left 0
:right 0
:width "100%"
:aspect-ratio 1})
(def text-container
{:flex 1
:flex-wrap :wrap})
(def plain-text
{:flex 1
:color (colors/alpha colors/white 0.7)})
(def highlighted-text
{:flex 1
:color colors/white})
@@ -1,88 +0,0 @@
(ns status-im2.contexts.onboarding.common.intro.view
(:require [utils.i18n :as i18n]
[quo2.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[utils.re-frame :as rf]
[status-im2.contexts.onboarding.common.intro.style :as style]
[status-im2.common.resources :as resources]))
(def carousels
[{:image (resources/get-image :intro-1)
:text (i18n/label :t/join-decentralised-communities)
:sub-text (i18n/label :t/participate-in-the-metaverse)}
{:image (resources/get-image :intro-2)
:text (i18n/label :t/chat-with-friends)
:sub-text (i18n/label :t/with-full-encryption)}
{:image (resources/get-image :intro-3)
:text (i18n/label :t/own-your-crypto)
:sub-text (i18n/label :t/use-the-multichain-wallet)}
{:image (resources/get-image :intro-4)
:text (i18n/label :t/discover-web3)
:sub-text (i18n/label :t/explore-the-decentralized-web)}])
(defn progress-bar
[index]
[rn/view style/progress-bar-container
[rn/view {:style (style/progress-bar-item index 0 false)}]
[rn/view {:style (style/progress-bar-item index 1 false)}]
[rn/view {:style (style/progress-bar-item index 2 false)}]
[rn/view {:style (style/progress-bar-item index 3 true)}]])
;; TODO: carousel component is to be correctly implemented as quo2 component with animations etc in:
;; https://github.com/status-im/status-mobile/issues/15012
(defn carousel
[index]
[rn/view {:style style/carousel}
[progress-bar index]
[quo/text
{:style style/carousel-text
:weight :semi-bold
:size :heading-2} (get-in carousels [index :text])]
[quo/text
{:style style/carousel-text
:size :paragraph-1} (get-in carousels [index :sub-text])]])
(defn set-index
[old-index]
(mod (inc old-index) 4))
(defn view
[]
(reagent/with-let
[carousel-index (reagent/atom 0)
interval-id
(js/setInterval
#(swap! carousel-index set-index)
1500)]
[rn/view {:style style/page-container}
[carousel @carousel-index]
[rn/image
{:style style/page-image
:source (get-in carousels [@carousel-index :image])}]
[quo/drawer-buttons
{:top-card {:on-press (fn []
(rf/dispatch [:init-root :onboarding])
(rf/dispatch [:hide-terms-of-services-opt-in-screen]))
:heading (i18n/label :t/sign-in)
:accessibility-label :already-use-status-button}
:bottom-card {:on-press (fn []
(rf/dispatch [:init-root :onboarding])
(rf/dispatch [:hide-terms-of-services-opt-in-screen]))
:heading (i18n/label :t/im-new-to-status)
:accessibility-label :new-to-status-button}}
(i18n/label :t/you-already-use-status)
[quo/text
{:style style/text-container}
[quo/text
{:size :paragraph-2
:style style/plain-text
:weight :semi-bold}
(i18n/label :t/by-continuing-you-accept)]
[quo/text
{:on-press #(rf/dispatch [:open-modal :privacy-policy])
:size :paragraph-2
:style style/highlighted-text
:weight :semi-bold}
(i18n/label :t/terms-of-service)]]]]
(finally (js/clearInterval interval-id))))
@@ -1,23 +0,0 @@
(ns status-im2.contexts.onboarding.common.style
(:require [quo2.foundations.colors :as colors]))
(def background-container
{:background-color colors/neutral-95
:flex-direction :row})
(defn background-gradient-overlay
[dark-overlay?]
{:position :absolute
:height (if dark-overlay? 240 136)
:top 0
:left 0
:right 0
:bottom 0})
(def background-blur-overlay
{:position :absolute
:left 0
:top 0
:bottom 0
:right 0
:background-color colors/neutral-80-opa-80-blur})
@@ -1,7 +0,0 @@
(ns status-im2.contexts.onboarding.profiles.view
(:require [status-im2.contexts.onboarding.common.background :as background]))
(defn views
[]
[:<>
[background/view true]])
@@ -4,7 +4,7 @@
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[quo2.components.animated-header-flatlist.view :as animated-header-list]))
(def data [0 1 2 3 4 5 6 7 8 9 10])
@@ -38,8 +38,8 @@
[animation]
[:f>
(fn []
[ra/fast-image
{:style (ra/apply-animations-to-style
[reanimated/fast-image
{:style (reanimated/apply-animations-to-style
{:width animation
:height animation}
{:border-radius 72})
@@ -2,7 +2,7 @@
(:require [quo2.components.navigation.bottom-nav-tab :as quo2]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
@@ -56,8 +56,8 @@
pass-through? (reagent/cursor state [:pass-through?])]
[:f>
(fn []
(let [icon-color-anim (ra/use-val colors/white)]
(ra/set-val
(let [icon-color-anim (reanimated/use-shared-value colors/white)]
(reanimated/set-shared-value
icon-color-anim
(get-icon-color @selected? @pass-through?))
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
@@ -2,7 +2,7 @@
(:require [quo2.components.navigation.floating-shell-button :as quo2]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]
[utils.i18n :as i18n]
[status-im2.contexts.quo-preview.preview :as preview]))
@@ -56,7 +56,7 @@
{:padding-vertical 60
:align-items :center}
[quo2/floating-shell-button (mock-data @state)
nil (ra/use-val 1)]]]])]))
nil (reanimated/use-shared-value 1)]]]])]))
(defn preview-floating-shell-button
[]
@@ -92,7 +92,9 @@
@state
{:default-active 1
:component :tags
:labelled? (if (= :label (:type @state)) true (:labelled? @state))
:labelled? (if (= :label type) true (:labelled? @state))
:resource (when (= type :icon)
:main-icons2/placeholder)
:data [{:id 1 :label "Music" :resource (resources/get-image :music)}
{:id 2 :label "Lifestyle" :resource (resources/get-image :lifestyle)}
{:id 2 :label "Podcasts" :resource (resources/get-image :podcasts)}
+11 -11
View File
@@ -1,7 +1,7 @@
(ns status-im2.contexts.shell.animation
(:require [quo2.foundations.colors :as colors]
[utils.re-frame :as rf]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]
[status-im.async-storage.core :as async-storage] ;;TODO remove when not used anymore
[status-im2.contexts.shell.constants :as shell.constants]))
@@ -71,12 +71,12 @@
;; Shared Values
(defn calculate-shared-values
[]
(let [selected-stack-id-sv (ra/use-val
(let [selected-stack-id-sv (reanimated/use-shared-value
;; passing keywords or nil is not working with reanimated
(name (or @selected-stack-id :communities-stack)))
pass-through-sv (ra/use-val false)
home-stack-state-sv (ra/use-val @home-stack-state)
animate-home-stack-left (ra/use-val (not (home-stack-open?)))
pass-through-sv (reanimated/use-shared-value false)
home-stack-state-sv (reanimated/use-shared-value @home-stack-state)
animate-home-stack-left (reanimated/use-shared-value (not (home-stack-open?)))
home-stack-position (calculate-home-stack-position)]
(reset! shared-values-atom
(reduce
@@ -153,10 +153,10 @@
(let [home-stack-state-value (if animate?
shell.constants/open-with-animation
shell.constants/open-without-animation)]
(ra/set-val
(reanimated/set-shared-value
(:selected-stack-id @shared-values-atom)
(name stack-id))
(ra/set-val
(reanimated/set-shared-value
(:home-stack-state @shared-values-atom)
home-stack-state-value)
(reset! home-stack-state home-stack-state-value)
@@ -168,8 +168,8 @@
(defn change-tab
[stack-id]
(ra/set-val (:animate-home-stack-left @shared-values-atom) false)
(ra/set-val (:selected-stack-id @shared-values-atom) (name stack-id))
(reanimated/set-shared-value (:animate-home-stack-left @shared-values-atom) false)
(reanimated/set-shared-value (:selected-stack-id @shared-values-atom) (name stack-id))
(reset! selected-stack-id stack-id)
(async-storage/set-item! :selected-stack-id stack-id))
@@ -189,10 +189,10 @@
(let [home-stack-state-value (if animate?
shell.constants/close-with-animation
shell.constants/close-without-animation)]
(ra/set-val
(reanimated/set-shared-value
(:animate-home-stack-left @shared-values-atom)
true)
(ra/set-val
(reanimated/set-shared-value
(:home-stack-state @shared-values-atom)
home-stack-state-value)
(reset! home-stack-state home-stack-state-value)
@@ -2,7 +2,7 @@
(:require [utils.re-frame :as rf]
[react-native.core :as rn]
[react-native.blur :as blur]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[status-im2.contexts.shell.style :as style]
[status-im2.contexts.shell.animation :as animation]
[status-im2.contexts.shell.constants :as shell.constants]
@@ -36,12 +36,12 @@
pass-through? (rf/sub [:shell/shell-pass-through?])
shared-values @animation/shared-values-atom
original-style (style/bottom-tabs-container pass-through?)
animated-style (ra/apply-animations-to-style
animated-style (reanimated/apply-animations-to-style
{:height (:bottom-tabs-height shared-values)}
original-style)]
(animation/load-stack @animation/selected-stack-id)
(ra/set-val (:pass-through? shared-values) pass-through?)
[ra/view {:style animated-style}
(reanimated/set-shared-value (:pass-through? shared-values) pass-through?)
[reanimated/view {:style animated-style}
(when pass-through?
[blur/view (blur-overlay-params style/bottom-tabs-blur-overlay)])
[rn/view {:style (style/bottom-tabs)}
@@ -1,6 +1,6 @@
(ns status-im2.contexts.shell.home-stack
(:require [react-native.core :as rn]
[react-native.reanimated :as ra]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[status-im.ui.screens.wallet.accounts.views :as wallet.accounts]
[status-im2.contexts.chat.home.view :as chat] ;; TODO move to status-im2
@@ -23,8 +23,8 @@
(when (load-stack? stack-id)
[:f>
(fn []
[ra/view
{:style (ra/apply-animations-to-style
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:opacity (get shared-values
(get shell.constants/stacks-opacity-keywords stack-id))
:pointer-events (get shared-values
@@ -49,14 +49,14 @@
(fn []
(let [shared-values @animation/shared-values-atom
home-stack-original-style (styles/home-stack @animation/screen-height)
home-stack-animated-style (ra/apply-animations-to-style
home-stack-animated-style (reanimated/apply-animations-to-style
{:top (:home-stack-top shared-values)
:left (:home-stack-left shared-values)
:opacity (:home-stack-opacity shared-values)
:pointer-events (:home-stack-pointer shared-values)
:transform [{:scale (:home-stack-scale shared-values)}]}
home-stack-original-style)]
[ra/view {:style home-stack-animated-style}
[reanimated/view {:style home-stack-animated-style}
[rn/view {:margin-top (:top insets) :flex 1}
[stack-view :communities-stack shared-values]
[stack-view :chats-stack shared-values]
+1 -1
View File
@@ -49,7 +49,7 @@
multiaccount
[:key-uid :name :public-key :identicon :images]))
(keychain/get-auth-method (:key-uid multiaccount))))
(navigation/init-root cofx :intro-stack))))
(navigation/init-root cofx :intro))))
(rf/defn initialize-multiaccounts
{:events [:setup/initialize-multiaccounts]}
+11 -20
View File
@@ -62,7 +62,16 @@
(defn old-roots
[]
;;TABS
{;; ONBOARDING
{;;INTRO (onboarding carousel)
:intro
{:root {:stack {:children [{:component {:name :intro
:id :intro
:options (status-bar-options)}}]
:options (merge (default-root)
(status-bar-options)
{:topBar (assoc (topbar-options) :visible false)})}}}
;; ONBOARDING
:onboarding
{:root {:stack {:id :onboarding
:children [{:component {:name :get-your-keys
@@ -139,28 +148,10 @@
[]
;;TABS
(merge (old-roots)
;;INTRO (onboarding carousel)
{:intro-stack
{:root {:stack {:id :intro
:children [{:component {:name :intro
:id :intro
:options
{:statusBar (merge
(status-bar-options)
{:style :light})
:topBar {:visible false}}}}]}}}}
{:shell-stack
{:root
{:stack {:id :shell-stack
:children [{:component {:name :shell-stack
:id :shell-stack
:options (merge (status-bar-options)
{:topBar {:visible false}})}}]}}}
:profiles
{:root
{:stack {:id :profiles
:children [{:component {:name :profiles
:id :profiles
:options (merge
(status-bar-options)
{:topBar {:visible false}})}}]}}}}))
{:topBar {:visible false}})}}]}}}}))
+3 -15
View File
@@ -1,7 +1,6 @@
(ns status-im2.navigation.screens
(:require [utils.i18n :as i18n] ;; TODO remove when not used anymore
[status-im.ui.screens.screens :as old-screens]
[status-im2.contexts.onboarding.common.intro.view :as intro]
[status-im2.contexts.activity-center.view :as activity-center]
[status-im2.contexts.chat.messages.view :as chat]
[status-im2.contexts.add-new-contact.views :as add-new-contact]
@@ -15,8 +14,7 @@
[quo.design-system.colors :as colors]
[status-im2.contexts.chat.photo-selector.album-selector.view :as album-selector]
[react-native.platform :as platform]
[status-im2.contexts.chat.photo-selector.view :as photo-selector]
[status-im2.contexts.onboarding.profiles.view :as profiles]))
[status-im2.contexts.chat.photo-selector.view :as photo-selector]))
(def components
[])
@@ -25,12 +23,7 @@
[]
(concat
(old-screens/screens)
[{:name :intro
:options {:topBar {:visible false}}
:insets {:top false}
:component intro/view}
{:name :activity-center
[{:name :activity-center
:options {:topBar {:visible false}}
:component activity-center/view}
@@ -83,12 +76,7 @@
{:name :settings-syncing
:insets {:bottom true}
:options {:topBar {:title {:text (i18n/label :t/syncing)}}}
:component settings-syncing/views}
;; Onboarding
{:name :profiles
:insets {:top false}
:component profiles/views}]
:component settings-syncing/views}]
(when config/quo-preview-enabled?
quo.preview/screens)
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.136.3",
"commit-sha1": "27a76f43ba5b43a28a95f8df086daa640cea0da6",
"src-sha256": "0pidsbgn9hnwmz896j0x6y550k37i3kmg391yp7qj4m2dns3n5w2"
"version": "v0.136.1",
"commit-sha1": "9fbc4d51eeb54a1ce3a51066e792e29210bc5496",
"src-sha256": "0aqgq5x360n06mn8qzb925r0wg943ga1b0csbzda9blvya3vznh5"
}
@@ -365,6 +365,8 @@ class TestDeeplinkOneDeviceNewUI(MultipleSharedDeviceTestCase):
deep_link = 'status-im://u/%s' % self.public_key
self.sign_in.open_weblink_and_login(deep_link)
profile = self.home.get_profile_view()
self.home.chats_tab.click()
self.home.profile_button.click()
if profile.default_username_text.text != self.default_username:
self.errors.append("Can't navigate to profile from deep link with own public key")
self.errors.verify_no_errors()
+10 -5
View File
@@ -125,10 +125,6 @@ class SignInView(BaseView):
super().__init__(driver)
self.driver = driver
# intro screen
self.sign_in_intro_button = Button(self.driver, accessibility_id="already-use-status-button")
self.i_m_new_in_status_button = Button(self.driver, accessibility_id="new-to-status-button")
self.password_input = EditBox(self.driver, accessibility_id="password-input")
self.migration_password_input = EditBox(self.driver, accessibility_id="enter-password-input")
self.sign_in_button = SignInButton(self.driver)
@@ -181,7 +177,8 @@ class SignInView(BaseView):
self.driver.info("## Creating new multiaccount (password:'%s', keycard:'%s')" % (password, str(keycard)),
device=False)
if not second_user:
self.i_m_new_in_status_button.click_until_presence_of_element(self.generate_key_button)
self.accept_tos_checkbox.enable()
self.get_started_button.click_until_presence_of_element(self.generate_key_button)
self.generate_key_button.click()
self.next_button.click_until_absense_of_element(self.element_by_translation_id("intro-wizard-title2"))
@@ -195,6 +192,14 @@ class SignInView(BaseView):
self.confirm_your_password_input.set_value(password)
self.next_button.click()
# Old UI
# self.maybe_later_button.wait_for_visibility_of_element(30)
# if enable_notifications:
# self.enable_notifications_button.click()
# else:
# self.maybe_later_button.click_until_presence_of_element(self.lets_go_button)
# self.lets_go_button.click_until_absense_of_element(self.lets_go_button)
# self.profile_button.wait_for_visibility_of_element(30)
self.chats_tab.wait_for_visibility_of_element(30)
-11
View File
@@ -122,7 +122,6 @@
"bug-report-submit-email": "Submit by email with logs archive",
"bug-report-submit-gh-issue": "Submit a GitHub issue without logs",
"bug-report-too-short-description": "Description is too short",
"by-continuing-you-accept": "By continuing you accept our ",
"camera-access-error": "To grant the required camera permission, please go to your system settings and make sure that Status > Camera is selected.",
"can-not-add-yourself": "That's you, to start a chat choose someone else",
"cancel": "Cancel",
@@ -153,7 +152,6 @@
"chat-key": "Chat key",
"chat-name": "Chat name",
"chat-settings": "Chat settings",
"chat-with-friends": "Chat privately with friends",
"chats": "Chats",
"check-your-recovery-phrase": "Check your seed phrase",
"choose-authentication-method": "Choose an authentication method",
@@ -204,7 +202,6 @@
"invite": "Invite",
"invite-contacts": "Invite people from contacts list",
"create-channel": "Create a channel",
"im-new-to-status": "I'm new to status",
"import-community": "Import a community",
"import-community-title": "Import a community",
"name-your-community": "Name your community",
@@ -466,7 +463,6 @@
"disabled": "Disabled",
"disconnected": "Chat offline",
"discover": "Discover",
"discover-web3": "Discover web3",
"dismiss": "Dismiss",
"discover-communities": "Discover Communities",
"done": "Done",
@@ -595,7 +591,6 @@
"ethereum-node-started-incorrectly-description": "Ethereum node was started with incorrect configuration, application will be stopped to recover from that condition. Configured network id = {{network-id}}, actual = {{fetched-network-id}}",
"ethereum-node-started-incorrectly-title": "Ethereum node started incorrectly",
"etherscan-lookup": "Look up on Etherscan",
"explore-the-decentralized-web": "Explore and interact with the decentralized web",
"export-account": "Export account",
"export-key": "Export private key",
"community-private-key": "Community private key",
@@ -714,7 +709,6 @@
"join-a-community": "or join a community",
"join-open-community": "Join Community",
"joined-community": "You joined “{{community}}”",
"join-decentralised-communities": "Join Decentralized Communities",
"http-gateway-error": "Oops, request failed!",
"sign-request-failed": "Could not sign message",
"invite-friends": "Invite friends",
@@ -1048,7 +1042,6 @@
"or": "OR",
"outgoing": "Outgoing",
"outgoing-transaction": "Outgoing transaction",
"own-your-crypto": "Own your crypto",
"pair": "Pair devices",
"pair-card": "Pair to this device",
"pair-code": "Pair code",
@@ -1069,7 +1062,6 @@
"pairing-new-installation-detected-title": "New device detected",
"pairing-no-info": "No info",
"pairing-please-set-a-name": "Please set a name for your device.",
"participate-in-the-metaverse": "Participate in the truly free metaverse",
"passphrase": "Passphrase",
"password": "Password",
"password-description": "At least 6 characters. Your password protects your keys. You need it to unlock Status and transact.",
@@ -1373,7 +1365,6 @@
"update": "Update",
"url": "URL",
"usd-currency": "USD",
"use-the-multichain-wallet": "Use the leading multi-chain self-custodial wallet",
"use-valid-contact-code": "Please enter or scan a valid chat key or username",
"validation-amount-invalid-number": "Amount is not a valid number",
"validation-amount-is-too-precise": "Amount is too precise. Max number of decimals is {{decimals}}.",
@@ -1426,7 +1417,6 @@
"welcome-community-blank-message": "Your channels will appear here. To create a new channel, click on the ⊕ button and select \"Create a channel\"",
"welcome-community-blank-message-edit-chats": "Your channels will appear here. To create a new channel, go back to the community screen, click on the ⊕ button and select \"Create a channel\"",
"welcome-blank-community-message": "Your communities will appear here.",
"with-full-encryption": "With full metadata privacy and e2e encryption",
"fetch-community": "Fetch community",
"fetching-community": "Fetching community...",
"seed-phrase-placeholder": "Seed phrase...",
@@ -1451,7 +1441,6 @@
"You": "You",
"you": "you",
"you-already-have-an-asset": "You already have an asset {{value}}",
"you-already-use-status": "You already use Status",
"you-are-all-set": "Youre all set!",
"you-are-all-set-description": "If you lose your phone, you can now access your funds and chat key using your seed phrase",
"you-can-change-account": "You can change the account name and color to what you wish",
+15
View File
@@ -9330,6 +9330,13 @@ react-lifecycles-compat@2.0.0:
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-2.0.0.tgz#71d9c4cde47114c4102454f76da055c2bc48c948"
integrity sha512-txfpPCQYiazVdcbMRhatqWKcAxJweUu2wDXvts5/7Wyp6+Y9cHojqXHsLPEckzutfHlxZhG8Oiundbmp8Fd6eQ==
react-native-animatable@1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/react-native-animatable/-/react-native-animatable-1.3.3.tgz#a13a4af8258e3bb14d0a9d839917e9bb9274ec8a"
integrity sha512-2ckIxZQAsvWn25Ho+DK3d1mXIgj7tITkrS4pYDvx96WyOttSvzzFeQnM2od0+FUMzILbdHDsDEqZvnz1DYNQ1w==
dependencies:
prop-types "^15.7.2"
react-native-background-timer@^2.1.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/react-native-background-timer/-/react-native-background-timer-2.2.0.tgz#ff82d30899209b924983cc00e6ce174b8de5054a"
@@ -9458,6 +9465,14 @@ react-native-mail@^6.1.1:
resolved "https://registry.yarnpkg.com/react-native-mail/-/react-native-mail-6.1.1.tgz#f1b1f8034c84d2510a93e4a2a795f0db5a13595e"
integrity sha512-pTs180wwyh7hN/iyTC9SfOX579U4YhDlHOLxi47IGvhPJENqO/QFdBq+wWKxyhNqdQuVSy+LoeIxLreWnIeYmg==
react-native-modal@^13.0.1:
version "13.0.1"
resolved "https://registry.yarnpkg.com/react-native-modal/-/react-native-modal-13.0.1.tgz#691f1e646abb96fa82c1788bf18a16d585da37cd"
integrity sha512-UB+mjmUtf+miaG/sDhOikRfBOv0gJdBU2ZE1HtFWp6UixW9jCk/bhGdHUgmZljbPpp0RaO/6YiMmQSSK3kkMaw==
dependencies:
prop-types "^15.6.2"
react-native-animatable "1.3.3"
react-native-navigation@^7.27.1:
version "7.27.1"
resolved "https://registry.yarnpkg.com/react-native-navigation/-/react-native-navigation-7.27.1.tgz#90bfac2a400109cc036394b4ee807a997da6a7b4"