Skip to content

Commit

Permalink
feat: implement wallet graph component
Browse files Browse the repository at this point in the history
Signed-off-by: Brian Sztamfater <brian@status.im>
  • Loading branch information
briansztamfater committed Jul 28, 2023
1 parent ac3b397 commit d31d813
Show file tree
Hide file tree
Showing 11 changed files with 298 additions and 64 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@
"react-native-fetch-polyfill": "^1.1.2",
"react-native-fs": "^2.14.1",
"react-native-gesture-handler": "2.6.1",
"react-native-gifted-charts": "^1.3.2",
"react-native-haptic-feedback": "^1.9.0",
"react-native-hole-view": "git+https://github.com/status-im/react-native-hole-view.git#refs/tags/v2.1.3-status",
"react-native-image-crop-picker": "git+https://github.com/status-im/react-native-image-crop-picker.git#refs/tags/v0.36.2-status.0",
"react-native-image-resizer": "^1.2.3",
"react-native-image-viewing": "git+https://github.com/status-im/react-native-image-viewing.git#refs/tags/v0.2.1.status",
"react-native-keychain": "git+https://github.com/status-im/react-native-keychain.git#refs/tags/v.3.0.0-5-status",
"react-native-languages": "^3.0.2",
"react-native-linear-gradient": "^2.5.6",
"react-native-linear-gradient": "2.8.0",
"react-native-lottie-splash-screen": "^1.0.1",
"react-native-mail": "git+https://github.com/status-im/react-native-mail.git#refs/tags/v6.1.2-status",
"react-native-navigation": "^7.27.1",
Expand All @@ -65,11 +66,11 @@
"react-native-randombytes": "^3.6.1",
"react-native-reanimated": "2.11.0",
"react-native-redash": "^16.0.11",
"react-native-svg": "13.10.0",
"react-native-shake": "^3.3.1",
"react-native-share": "^8.2.2",
"react-native-static-safe-area-insets": "^2.2.0",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.5.39",
"react-native-svg": "^9.8.4",
"react-native-touch-id": "^4.4.1",
"react-native-transparent-video": "git+https://github.com/status-im/react-native-transparent-video.git#refs/tags/0.0.9",
"react-native-webview": "git+https://github.com/status-im/react-native-webview.git#refs/tags/v11.16.0-status",
Expand Down
8 changes: 8 additions & 0 deletions src/mocks/js_dependencies.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,13 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (

(def react-native-transparent-video #js {:default #js {}})

(def react-native-gifted-charts
#js
{:BarChart #js {}
:PieChart #js {}
:LineChart #js {}
:LineChartBicolor #js {}})

(def wallet-connect-client
#js
{:default #js {}
Expand Down Expand Up @@ -409,6 +416,7 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
"react-native-svg" react-native-svg
"react-native-transparent-video" react-native-transparent-video
"react-native-orientation-locker" react-native-orientation-locker
"react-native-gifted-charts" react-native-gifted-charts
"../src/js/worklets/core.js" worklet-factory
"../src/js/worklets/shell/bottom_tabs.js" #js {}
"../src/js/worklets/shell/home_stack.js" #js {}
Expand Down
10 changes: 10 additions & 0 deletions src/quo2/components/graph/wallet_graph/style.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
(ns quo2.components.graph.wallet-graph.style)

(def gradient-background
{:height 294
:justify-content :flex-end})

(def x-axis-label-text-style
{:margin-bottom -3
:padding-top -10
:height 0})
86 changes: 86 additions & 0 deletions src/quo2/components/graph/wallet_graph/view.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
(ns quo2.components.graph.wallet-graph.view
(:require [quo2.theme :as theme]
[react-native.linear-gradient :as linear-gradient]
[react-native.charts :as charts]
[react-native.core :as rn]
[quo2.components.graph.wallet-graph.style :as style]
[quo2.foundations.colors :as colors]))

(defn find-highest-value
[maps]
(reduce (fn [max-value map]
(let [value (:value map)]
(if (nil? max-value) ; Check if it's the first element
value
(if (> value max-value)
value
max-value))))
nil
maps))

(defn downsample-data
[data max-array-size]
(let [data-size (count data)
aggregation-interval (max (/ data-size max-array-size) 1)]
(loop [i 0
aggregated-data []
current-aggregation []
num-points 0]
(if (>= i data-size)
(vec (reverse aggregated-data))
(let [point (nth data i)]
(if (< num-points aggregation-interval)
(recur (inc i) aggregated-data (conj current-aggregation point) (inc num-points))
(let [aggregated-value (/ (reduce + (map :value current-aggregation)) aggregation-interval)]
(recur (inc i) (conj aggregated-data {:value aggregated-value}) [point] 1))))))))

(defn- wallet-graph-internal
[{:keys [data state time-frame theme]}]
(let [max-data-points (case time-frame
:empty 0
:1-week 7
:1-month 30
:3-months 90
:1-year 365
500)
data (if (> (count data) max-data-points)
(downsample-data data max-data-points)
data)
max-value (find-highest-value data)
width (:width (rn/get-screen))
line-color (if (= state :positive)
(colors/theme-colors colors/success-50 colors/success-60 theme)
(colors/theme-colors colors/danger-50 colors/danger-60 theme))
gradient-colors [(colors/alpha line-color 0.1) (colors/alpha line-color 0)]
fill-color (colors/theme-colors colors/white colors/neutral-95)]
[linear-gradient/linear-gradient
{:colors gradient-colors
:start {:x 0 :y 1}
:end {:x 0 :y 0}
:style style/gradient-background}
[charts/line-chart
{:height 96
:width (+ width 1)
:max-value max-value
:min-value 0
:adjust-to-width true
:data data
:area-chart true
:start-fill-color fill-color
:end-fill-color fill-color
:hide-data-points true
:hide-rules true
:hide-y-axis-text true
:x-axis-indices-height 100
:thickness 2
:color line-color
:y-axis-thickness 0
:x-axis-thickness 0
:initial-spacing 0
:end-spacing 0
:disable-scroll true
:y-axis-label-width 0.01
:labels-extra-height -36
:x-axis-label-text-style style/x-axis-label-text-style}]]))

(def wallet-graph (theme/with-theme wallet-graph-internal))
4 changes: 4 additions & 0 deletions src/quo2/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
quo2.components.drawers.permission-context.view
quo2.components.dropdowns.dropdown
quo2.components.empty-state.empty-state.view
quo2.components.graph.wallet-graph.view
quo2.components.header
quo2.components.icon
quo2.components.info.info-message
Expand Down Expand Up @@ -167,6 +168,9 @@
;;;; EMPTY STATE
(def empty-state quo2.components.empty-state.empty-state.view/empty-state)

;;;; GRAPH
(def wallet-graph quo2.components.graph.wallet-graph.view/wallet-graph)

;;;; HEADER
(def header quo2.components.header/header)

Expand Down
5 changes: 5 additions & 0 deletions src/react_native/charts.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(ns react-native.charts
(:require ["react-native-gifted-charts" :as gifted-charts]
[reagent.core :as reagent]))

(def line-chart (reagent/adapt-react-class (.-LineChart gifted-charts)))
91 changes: 91 additions & 0 deletions src/status_im2/contexts/quo_preview/graph/wallet_graph.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
(ns status-im2.contexts.quo-preview.graph.wallet-graph
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))

(defn generate-crypto-token-prices
[num-elements volatility]
(loop [n num-elements
prices []
prev-price (rand-int 100000)
volatility volatility]
(if (zero? n)
(vec (reverse prices))
(let [fluctuation (* prev-price volatility)
random-delta (- (rand fluctuation) (/ fluctuation 2))
new-price (+ prev-price random-delta)
new-price (if (< new-price 1) 1 new-price)
new-prices (conj prices {:value new-price})]
(recur (dec n) new-prices new-price volatility)))))

(def descriptor
[{:label "State:"
:key :state
:type :select
:options [{:key :positive
:value "Positive"}
{:key :negative
:value "Negative"}]}
{:label "Time frame:"
:key :time-frame
:type :select
:options [{:key :empty
:value "Empty"}
{:key :1-week
:value "1 Week"}
{:key :1-month
:value "1 Month"}
{:key :3-months
:value "3 Months"}
{:key :1-year
:value "1 Year"}
{:key :all-time
:value "All time (500 years data)"}]}])

(defn generate-data
[time-frame]
(let [data-points (case time-frame
:empty 0
:1-week 7
:1-month 30
:3-months 90
:1-year 365
(* 365 500))
volatility (case time-frame
:empty 0
:1-week 2
:1-month 1
:3-months 0.5
:1-year 0.05
0.005)]
(generate-crypto-token-prices data-points volatility)))

(defn cool-preview
[]
(let [state (reagent/atom {:state :positive
:time-frame :1-week})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:padding-bottom 150}
[preview/customizer state descriptor]
[:<>
[quo/wallet-graph
{:data (generate-data (:time-frame @state))
:state (:state @state)
:time-frame (:time-frame @state)}]]]])))

(defn preview-wallet-graph
[]
[rn/view
{:background-color (colors/theme-colors
colors/white
colors/neutral-95)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str
:scroll-enabled false}]])
4 changes: 4 additions & 0 deletions src/status_im2/contexts/quo_preview/main.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
[status-im2.contexts.quo-preview.buttons.predictive-keyboard :as predictive-keyboard]
[status-im2.contexts.quo-preview.browser.browser-input :as browser-input]
[status-im2.contexts.quo-preview.code.snippet :as code-snippet]
[status-im2.contexts.quo-preview.graph.wallet-graph :as wallet-graph]
[status-im2.contexts.quo-preview.colors.color-picker :as color-picker]
[status-im2.contexts.quo-preview.community.community-card-view :as community-card]
[status-im2.contexts.quo-preview.community.community-membership-list-view :as
Expand Down Expand Up @@ -204,6 +205,9 @@
:empty-state [{:name :empty-state
:options {:topBar {:visible true}}
:component empty-state/preview-empty-state}]
:graph [{:name :wallet-graph
:options {:topBar {:visible true}}
:component wallet-graph/preview-wallet-graph}]
:info [{:name :info-message
:options {:topBar {:visible true}}
:component info-message/preview-info-message}
Expand Down
2 changes: 1 addition & 1 deletion test/jest/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module.exports = {
},
testTimeout: 60000,
transformIgnorePatterns: [
'/node_modules/(?!(@react-native|react-native-haptic-feedback|react-native-redash|react-native-image-crop-picker|@react-native-community|react-native-linear-gradient|react-native-background-timer|react-native|rn-emoji-keyboard|react-native-languages|react-native-shake|react-native-reanimated|react-native-redash|react-native-permissions|@react-native-community/blur|react-native-static-safe-area-insets)/).*/',
'/node_modules/(?!(@react-native|react-native-haptic-feedback|react-native-redash|react-native-image-crop-picker|@react-native-community|react-native-linear-gradient|react-native-background-timer|react-native|rn-emoji-keyboard|react-native-languages|react-native-shake|react-native-reanimated|react-native-redash|react-native-permissions|@react-native-community/blur|react-native-static-safe-area-insets|react-native-gifted-charts)/).*/',
],
globals: {
__TEST__: true,
Expand Down
7 changes: 7 additions & 0 deletions test/jest/jestSetup.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ jest.mock('react-native-blob-util', () => ({

jest.mock('react-native-reanimated', () => require('react-native-reanimated/mock'));

jest.mock('react-native-gifted-charts', () => ({
BarChart: {},
PieChart: {},
LineChart: {},
LineChartBicolor: {}
}));

NativeModules.ReactLocalization = {
language: 'en',
locale: 'en',
Expand Down
Loading

0 comments on commit d31d813

Please sign in to comment.