Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb129b97f3 | ||
|
|
73e9f67dbd |
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 30 KiB |
@@ -19,3 +19,7 @@
|
||||
:background-color colors/danger-50
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(def empty-state
|
||||
{:width 375
|
||||
:height 116})
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
(:require
|
||||
[quo.components.graph.utils :as utils]
|
||||
[quo.components.graph.wallet-graph.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.resources :as resources]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.charts :as charts]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[react-native.linear-gradient :as linear-gradient]))
|
||||
|
||||
(defn- time-frame->max-data-points
|
||||
@@ -42,11 +43,10 @@
|
||||
gradient-colors [(colors/alpha line-color 0.1) (colors/alpha line-color 0)]
|
||||
fill-color (colors/theme-colors colors/white colors/neutral-95)]
|
||||
(if (= time-frame :empty)
|
||||
[rn/view
|
||||
{:accessibility-label :illustration
|
||||
:style style/illustration}
|
||||
[text/text {:style {:color colors/white}}
|
||||
"Illustration here"]]
|
||||
[fast-image/fast-image
|
||||
{:style style/empty-state
|
||||
:source (resources/get-themed-image :no-funds theme)
|
||||
:accessibility-label :illustration}]
|
||||
[rn/view
|
||||
[linear-gradient/linear-gradient
|
||||
{:colors gradient-colors
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- label->accessibility-label
|
||||
[label]
|
||||
(let [label-name (if (keyword? label) (name label) label)]
|
||||
(keyword (str "keyboard-key-" label-name))))
|
||||
|
||||
(defn- view-internal
|
||||
[]
|
||||
(let [pressed? (reagent/atom false)]
|
||||
@@ -14,9 +19,11 @@
|
||||
(let [label-color (style/get-label-color disabled? theme blur?)
|
||||
background-color (style/toggle-background-color @pressed? blur? theme)]
|
||||
[rn/pressable
|
||||
{:accessibility-label :keyboard-key
|
||||
{:accessibility-label (label->accessibility-label label)
|
||||
:disabled (or disabled? (not label))
|
||||
:on-press (fn [] (on-press label))
|
||||
:on-press (fn []
|
||||
(when on-press
|
||||
(on-press label)))
|
||||
:on-press-in #(reset! pressed? true)
|
||||
:on-press-out #(reset! pressed? false)
|
||||
:style (style/container background-color)}
|
||||
|
||||
@@ -17,13 +17,15 @@
|
||||
|
||||
(defn- view-internal
|
||||
[]
|
||||
(fn [{:keys [disabled? theme blur? left-action delete-key? on-press]}]
|
||||
(fn [{:keys [disabled? theme blur? left-action delete-key? on-press on-delete]
|
||||
:or {left-action :none}}]
|
||||
[rn/view
|
||||
{:style style/container}
|
||||
(for [row-index (range 1 4)]
|
||||
^{:key row-index}
|
||||
[rn/view {:style style/row-container}
|
||||
(for [column-index (range 1 4)]
|
||||
^{:key (str row-index column-index)}
|
||||
[keyboard-item
|
||||
{:item (+ (* (dec row-index) 3) column-index)
|
||||
:type :digit
|
||||
@@ -61,7 +63,7 @@
|
||||
{:item :i/delete
|
||||
:type :key
|
||||
:disabled? disabled?
|
||||
:on-press on-press
|
||||
:on-press on-delete
|
||||
:blur? blur?
|
||||
:theme theme}]
|
||||
[keyboard-item])]]))
|
||||
|
||||
@@ -1,32 +1,39 @@
|
||||
(ns quo.components.wallet.token-input.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.components.buttons.button.view :as button]
|
||||
[quo.components.dividers.divider-line.view :as divider-line]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.network-tags.view :as network-tag]
|
||||
[quo.components.wallet.token-input.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.common :as common]
|
||||
[quo.foundations.resources :as resources]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
[clojure.string :as string]
|
||||
[quo.components.buttons.button.view :as button]
|
||||
[quo.components.dividers.divider-line.view :as divider-line]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.network-tags.view :as network-tag]
|
||||
[quo.components.wallet.token-input.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.common :as common]
|
||||
[quo.foundations.resources :as resources]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn calc-value
|
||||
[crypto? currency token value conversion]
|
||||
(if crypto?
|
||||
(str (get common/currency-label currency) (.toFixed (* value conversion) 2))
|
||||
(str (.toFixed (/ value conversion) 2) " " (string/upper-case (clj->js token)))))
|
||||
(let [num-value (if (string? value) (parse-double (or value "0")) value)]
|
||||
(if crypto?
|
||||
(str (get common/currency-label currency) (.toFixed (* num-value conversion) 2))
|
||||
(str (.toFixed (/ num-value conversion) 2) " " (string/upper-case (or (clj->js token) ""))))))
|
||||
|
||||
(defn- view-internal
|
||||
[]
|
||||
(let [width (:width (rn/get-window))
|
||||
value (reagent/atom 0)
|
||||
value (reagent/atom nil)
|
||||
crypto? (reagent/atom true)
|
||||
input-ref (atom nil)]
|
||||
(fn [{:keys [theme token currency conversion networks title customization-color]}]
|
||||
[rn/view {:style (style/main-container width)}
|
||||
(fn [{:keys [theme token currency conversion networks title customization-color
|
||||
on-swap container-style show-keyboard?]
|
||||
:or {show-keyboard? true}
|
||||
external-value :value}]
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(style/main-container width)
|
||||
container-style)}
|
||||
[rn/view {:style style/amount-container}
|
||||
[rn/pressable
|
||||
{:on-press #(when @input-ref (.focus ^js @input-ref))
|
||||
@@ -37,30 +44,38 @@
|
||||
{:style style/token
|
||||
:source (resources/get-token token)}]
|
||||
[rn/text-input
|
||||
{:ref #(reset! input-ref %)
|
||||
:placeholder "0"
|
||||
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)
|
||||
:keyboard-type :numeric
|
||||
:max-length 12
|
||||
:default-value @value
|
||||
:on-change-text #(reset! value %)
|
||||
:style (style/text-input theme)
|
||||
:selection-color customization-color}]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :semi-bold
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:margin-right 8
|
||||
:padding-bottom 2}}
|
||||
(string/upper-case (clj->js (if @crypto? token currency)))]]
|
||||
[button/button
|
||||
{:icon true
|
||||
:icon-only? true
|
||||
:size 32
|
||||
:on-press #(swap! crypto? not)
|
||||
:type :outline
|
||||
:accessibility-label :reorder}
|
||||
:i/reorder]]
|
||||
{:ref #(do (reset! input-ref %)
|
||||
(when %
|
||||
(.focus ^js %)))
|
||||
:placeholder "0"
|
||||
:placeholder-text-color (colors/theme-colors colors/neutral-40
|
||||
colors/neutral-50
|
||||
theme)
|
||||
:default-value (or external-value @value)
|
||||
:keyboard-type :numeric
|
||||
:max-length 12
|
||||
:on-change-text #(reset! value %)
|
||||
:style (style/text-input theme)
|
||||
:selection-color customization-color
|
||||
:show-soft-input-on-focus show-keyboard?}]]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :semi-bold
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:margin-right 8
|
||||
:padding-bottom 2}}
|
||||
(string/upper-case (or (clj->js (if @crypto? token currency)) ""))]]
|
||||
[button/button
|
||||
{:icon true
|
||||
:icon-only? true
|
||||
:size 32
|
||||
:on-press (fn []
|
||||
(swap! crypto? not)
|
||||
(when on-swap
|
||||
(on-swap @crypto?)))
|
||||
:type :outline
|
||||
:accessibility-label :reorder}
|
||||
:i/reorder]
|
||||
[divider-line/view {:container-style {:margin-vertical 8}}]
|
||||
[rn/view {:style style/data-container}
|
||||
[network-tag/view {:networks networks :title title}]
|
||||
@@ -68,6 +83,6 @@
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||
(calc-value @crypto? currency token @value conversion)]]])))
|
||||
(calc-value @crypto? currency token (or external-value @value) conversion)]]])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -7,6 +7,15 @@
|
||||
:keycard-watermark (js/require "../resources/images/ui2/keycard-watermark.png")
|
||||
:bored-ape (js/require "../resources/images/mock2/bored-ape.png")})
|
||||
|
||||
(def ui-themed
|
||||
{:no-funds
|
||||
{:light (js/require "../resources/images/ui2/no-funds-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-funds-dark.png")}})
|
||||
|
||||
(defn get-themed-image
|
||||
[k theme]
|
||||
(get-in ui-themed [k theme]))
|
||||
|
||||
(defn get-image
|
||||
[k]
|
||||
(get ui k))
|
||||
|
||||
@@ -79,7 +79,19 @@
|
||||
:dark (js/require "../resources/images/ui2/no-contacts-to-invite-dark.png")}
|
||||
:no-notifications
|
||||
{:light (js/require "../resources/images/ui2/no-notifications-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-notifications-dark.png")}})
|
||||
:dark (js/require "../resources/images/ui2/no-notifications-dark.png")}
|
||||
:no-activity
|
||||
{:light (js/require "../resources/images/ui2/no-activity-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-activity-dark.png")}
|
||||
:no-collectibles
|
||||
{:light (js/require "../resources/images/ui2/no-collectibles-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-collectibles-dark.png")}
|
||||
:no-dapps
|
||||
{:light (js/require "../resources/images/ui2/no-dapps-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-dapps-dark.png")}
|
||||
:no-permissions
|
||||
{:light (js/require "../resources/images/ui2/no-permissions-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-permissions-dark.png")}})
|
||||
|
||||
(def mock-images
|
||||
{:bored-ape (js/require "../resources/images/mock2/bored-ape.png")
|
||||
|
||||
@@ -112,7 +112,6 @@
|
||||
:collapsed? collapsed?
|
||||
:page-nav-props page-nav-props
|
||||
:overlay-shown? overlay-shown?}]
|
||||
|
||||
[rn/scroll-view
|
||||
{:content-container-style {:flex-grow 1}
|
||||
:content-inset-adjustment-behavior :never
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
(ns status-im2.common.top-bar.style
|
||||
(:require [quo.foundations.colors :as colors]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
|
||||
(defonce ^:const cover-height 168)
|
||||
(defonce ^:const overscroll-cover-height 2000)
|
||||
(defonce ^:const header-avatar-top-offset -36)
|
||||
|
||||
(defn header-container
|
||||
[show? theme]
|
||||
{:display (if show? :flex :none)
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-100 theme)
|
||||
:top (- overscroll-cover-height)
|
||||
:margin-bottom (- overscroll-cover-height)})
|
||||
|
||||
(defn header-cover
|
||||
[cover-bg-color theme]
|
||||
{:flex 1
|
||||
:height (+ overscroll-cover-height cover-height)
|
||||
:background-color (colors/theme-colors
|
||||
(colors/custom-color cover-bg-color 50 20)
|
||||
(colors/custom-color cover-bg-color 50 40)
|
||||
theme)})
|
||||
|
||||
(defn header-bottom-part
|
||||
[animation theme]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:border-top-right-radius animation
|
||||
:border-top-left-radius animation}
|
||||
{:top -16
|
||||
:margin-bottom -16
|
||||
:padding-bottom 24
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)}))
|
||||
|
||||
(def header-avatar
|
||||
{:top header-avatar-top-offset
|
||||
:margin-horizontal 20
|
||||
:margin-bottom header-avatar-top-offset})
|
||||
|
||||
(def header-description-text
|
||||
{:margin-top 8})
|
||||
@@ -1,57 +0,0 @@
|
||||
(ns status-im2.common.top-bar.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im2.common.top-bar.style :as style]))
|
||||
|
||||
(def header-extrapolation-option
|
||||
{:extrapolateLeft "clamp"
|
||||
:extrapolateRight "clamp"})
|
||||
|
||||
(defn- add-inverted-y-android
|
||||
[style]
|
||||
(cond-> style
|
||||
platform/android?
|
||||
(assoc :scale-y -1)))
|
||||
|
||||
;; TODO(alwx): status-im2.contexts.chat.messages.list.view/list-footer should be abstracted
|
||||
(defn f-abstract-list-header
|
||||
[{:keys [inverted-y-on-android?
|
||||
show?
|
||||
theme
|
||||
cover-bg-color
|
||||
scroll-y
|
||||
on-layout
|
||||
avatar-component
|
||||
title-component
|
||||
description
|
||||
actions-component
|
||||
loading-component]}]
|
||||
(let [border-animation (reanimated/interpolate scroll-y
|
||||
[30 125]
|
||||
[14 0]
|
||||
header-extrapolation-option)]
|
||||
[rn/view (cond-> {:flex 1}
|
||||
inverted-y-on-android?
|
||||
(add-inverted-y-android))
|
||||
[rn/view {:style (style/header-container show? theme)
|
||||
:on-layout on-layout}
|
||||
[rn/view {:style (style/header-cover cover-bg-color theme)}]
|
||||
[reanimated/view {:style (style/header-bottom-part border-animation theme)}
|
||||
[rn/view {:style style/header-avatar}
|
||||
[rn/view {:style {:align-items :flex-start}}
|
||||
[avatar-component]]
|
||||
[title-component]
|
||||
(when description
|
||||
[quo/text {:style style/header-description-text}
|
||||
description])
|
||||
(when actions-component
|
||||
[actions-component])]]]
|
||||
(when loading-component
|
||||
[loading-component])]))
|
||||
|
||||
(defn abstract-list-header
|
||||
[props]
|
||||
[:f> f-abstract-list-header props])
|
||||
@@ -18,6 +18,37 @@
|
||||
(def list-container
|
||||
{:padding-vertical 16})
|
||||
|
||||
(defn header-container
|
||||
[show? theme]
|
||||
{:display (if show? :flex :none)
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-100 theme)
|
||||
:top (- overscroll-cover-height)
|
||||
:margin-bottom (- overscroll-cover-height)})
|
||||
|
||||
(defn header-cover
|
||||
[cover-bg-color theme]
|
||||
{:flex 1
|
||||
:height (+ overscroll-cover-height cover-height)
|
||||
:background-color (colors/theme-colors
|
||||
(colors/custom-color cover-bg-color 50 20)
|
||||
(colors/custom-color cover-bg-color 50 40)
|
||||
theme)})
|
||||
|
||||
(defn header-bottom-part
|
||||
[animation theme]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:border-top-right-radius animation
|
||||
:border-top-left-radius animation}
|
||||
{:top -16
|
||||
:margin-bottom -16
|
||||
:padding-bottom 24
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)}))
|
||||
|
||||
(def header-avatar
|
||||
{:top header-avatar-top-offset
|
||||
:margin-horizontal 20
|
||||
:margin-bottom header-avatar-top-offset})
|
||||
|
||||
(defn header-image
|
||||
[scale-animation top-margin-animation side-margin-animation]
|
||||
(reanimated/apply-animations-to-style
|
||||
@@ -26,3 +57,6 @@
|
||||
:margin-left side-margin-animation
|
||||
:margin-bottom side-margin-animation}
|
||||
{:align-items :flex-start}))
|
||||
|
||||
(def bio
|
||||
{:margin-top 8})
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im.ui.screens.chat.group :as chat.group]
|
||||
[status-im.ui.screens.chat.message.gap :as message.gap]
|
||||
[status-im2.common.top-bar.view :as top-bar]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.chat.composer.constants :as composer.constants]
|
||||
[status-im2.contexts.chat.messages.content.view :as message]
|
||||
@@ -41,14 +40,14 @@
|
||||
[]
|
||||
(some-> ^js @messages-list-ref
|
||||
(.scrollToOffset #js
|
||||
{:animated true})))
|
||||
{:animated true})))
|
||||
|
||||
(defn on-scroll
|
||||
[evt show-floating-scroll-down-button?]
|
||||
(let [y (oops/oget evt "nativeEvent.contentOffset.y")
|
||||
layout-height (oops/oget evt "nativeEvent.layoutMeasurement.height")
|
||||
threshold-height (* (/ layout-height 100)
|
||||
threshold-percentage-to-show-floating-scroll-down-button)
|
||||
(let [y (oops/oget evt "nativeEvent.contentOffset.y")
|
||||
layout-height (oops/oget evt "nativeEvent.layoutMeasurement.height")
|
||||
threshold-height (* (/ layout-height 100)
|
||||
threshold-percentage-to-show-floating-scroll-down-button)
|
||||
reached-threshold? (> y threshold-height)]
|
||||
(when (not= reached-threshold? @show-floating-scroll-down-button?)
|
||||
(rn/configure-next (:ease-in-ease-out rn/layout-animation-presets))
|
||||
@@ -58,16 +57,16 @@
|
||||
[e]
|
||||
(when @messages-list-ref
|
||||
(reset! state/first-not-visible-item
|
||||
(when-let [last-visible-element (aget (oops/oget e "viewableItems")
|
||||
(dec (oops/oget e "viewableItems.length")))]
|
||||
(let [index (oops/oget last-visible-element "index")
|
||||
;; Get first not visible element, if it's a datemark/gap
|
||||
;; we might add messages on receiving as they do not have
|
||||
;; a clock value, but usually it will be a message
|
||||
first-not-visible (aget (oops/oget @messages-list-ref "props.data") (inc index))]
|
||||
(when (and first-not-visible
|
||||
(= :message (:type first-not-visible)))
|
||||
first-not-visible))))))
|
||||
(when-let [last-visible-element (aget (oops/oget e "viewableItems")
|
||||
(dec (oops/oget e "viewableItems.length")))]
|
||||
(let [index (oops/oget last-visible-element "index")
|
||||
;; Get first not visible element, if it's a datemark/gap
|
||||
;; we might add messages on receiving as they do not have
|
||||
;; a clock value, but usually it will be a message
|
||||
first-not-visible (aget (oops/oget @messages-list-ref "props.data") (inc index))]
|
||||
(when (and first-not-visible
|
||||
(= :message (:type first-not-visible)))
|
||||
first-not-visible))))))
|
||||
|
||||
(defn list-on-end-reached
|
||||
[scroll-y on-end-reached?]
|
||||
@@ -95,9 +94,9 @@
|
||||
{:no-color true
|
||||
:size 20
|
||||
:color (colors/theme-colors
|
||||
(colors/custom-color :success 50)
|
||||
(colors/custom-color :success 60)
|
||||
theme)}]
|
||||
(colors/custom-color :success 50)
|
||||
(colors/custom-color :success 60)
|
||||
theme)}]
|
||||
(when added?
|
||||
[quo/icon :i/contact
|
||||
{:no-color true
|
||||
@@ -116,17 +115,17 @@
|
||||
|
||||
(defn loading-view
|
||||
[chat-id messages-view-height messages-view-header-height]
|
||||
(let [loading-messages? (rf/sub [:chats/loading-messages? chat-id])
|
||||
all-loaded? (rf/sub [:chats/all-loaded? chat-id])
|
||||
messages (rf/sub [:chats/raw-chat-messages-stream chat-id])
|
||||
(let [loading-messages? (rf/sub [:chats/loading-messages? chat-id])
|
||||
all-loaded? (rf/sub [:chats/all-loaded? chat-id])
|
||||
messages (rf/sub [:chats/raw-chat-messages-stream chat-id])
|
||||
loading-first-page? (= (count messages) 0)
|
||||
top-spacing (if loading-first-page? 0 navigation.style/navigation-bar-height)
|
||||
parent-height (if loading-first-page?
|
||||
(- @messages-view-height
|
||||
@messages-view-header-height
|
||||
composer.constants/composer-default-height
|
||||
loading-indicator-extra-spacing)
|
||||
loading-indicator-page-loading-height)]
|
||||
top-spacing (if loading-first-page? 0 navigation.style/navigation-bar-height)
|
||||
parent-height (if loading-first-page?
|
||||
(- @messages-view-height
|
||||
@messages-view-header-height
|
||||
composer.constants/composer-default-height
|
||||
loading-indicator-extra-spacing)
|
||||
loading-indicator-page-loading-height)]
|
||||
(when (or loading-messages? (not all-loaded?))
|
||||
[rn/view {:padding-top top-spacing}
|
||||
;; Only use animated loading skeleton for ios
|
||||
@@ -147,14 +146,14 @@
|
||||
|
||||
(defn f-list-footer-avatar
|
||||
[{:keys [scroll-y display-name online? profile-picture]}]
|
||||
(let [image-scale-animation (reanimated/interpolate scroll-y
|
||||
scroll-animation-input-range
|
||||
[1 0.5]
|
||||
header-extrapolation-option)
|
||||
image-top-margin-animation (reanimated/interpolate scroll-y
|
||||
scroll-animation-input-range
|
||||
[0 40]
|
||||
header-extrapolation-option)
|
||||
(let [image-scale-animation (reanimated/interpolate scroll-y
|
||||
scroll-animation-input-range
|
||||
[1 0.5]
|
||||
header-extrapolation-option)
|
||||
image-top-margin-animation (reanimated/interpolate scroll-y
|
||||
scroll-animation-input-range
|
||||
[0 40]
|
||||
header-extrapolation-option)
|
||||
image-side-margin-animation (reanimated/interpolate scroll-y
|
||||
scroll-animation-input-range
|
||||
[0 -20]
|
||||
@@ -177,13 +176,13 @@
|
||||
(defn- add-inverted-y-android
|
||||
[style]
|
||||
(cond-> style
|
||||
platform/android?
|
||||
(assoc :scale-y -1)))
|
||||
platform/android?
|
||||
(assoc :scale-y -1)))
|
||||
|
||||
(defn actions
|
||||
[chat-id cover-bg-color]
|
||||
(let [latest-pin-text (rf/sub [:chats/last-pinned-message-text chat-id])
|
||||
pins-count (rf/sub [:chats/pin-messages-count chat-id])]
|
||||
pins-count (rf/sub [:chats/pin-messages-count chat-id])]
|
||||
[quo/channel-actions
|
||||
{:style {:margin-top 16}
|
||||
:actions [{:accessibility-label :action-button-pinned
|
||||
@@ -202,46 +201,53 @@
|
||||
messages-view-header-height big-name-visible?]}]
|
||||
(let [{:keys [chat-id chat-name emoji chat-type
|
||||
group-chat]} chat
|
||||
all-loaded? (rf/sub [:chats/all-loaded? chat-id])
|
||||
display-name (cond
|
||||
(= chat-type constants/one-to-one-chat-type)
|
||||
(first (rf/sub [:contacts/contact-two-names-by-identity chat-id]))
|
||||
(= chat-type constants/community-chat-type)
|
||||
(str (when emoji (str emoji " ")) "# " chat-name)
|
||||
:else (str emoji chat-name))
|
||||
{:keys [bio]} (rf/sub [:contacts/contact-by-identity chat-id])
|
||||
online? (rf/sub [:visibility-status-updates/online? chat-id])
|
||||
contact (when-not group-chat
|
||||
(rf/sub [:contacts/contact-by-address chat-id]))
|
||||
photo-path (rf/sub [:chats/photo-path chat-id])]
|
||||
[top-bar/abstract-list-header
|
||||
{:inverted-y-on-android? true
|
||||
:show? all-loaded?
|
||||
:theme theme
|
||||
:cover-bg-color cover-bg-color
|
||||
:scroll-y scroll-y
|
||||
:on-layout on-layout
|
||||
:avatar-component (fn [] (when-not group-chat
|
||||
[list-footer-avatar
|
||||
{:scroll-y scroll-y
|
||||
:display-name display-name
|
||||
:online? online?
|
||||
:profile-picture photo-path}]))
|
||||
:title-component (fn [] [rnio/view
|
||||
{:on-change (fn [view-visible?]
|
||||
(reset! big-name-visible? view-visible?))
|
||||
:style {:flex-direction :row
|
||||
:margin-top (if group-chat 54 12)}}
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-1
|
||||
:style {:flex-shrink 1}
|
||||
:number-of-lines 1}
|
||||
display-name]
|
||||
[contact-icon contact theme]])
|
||||
:description bio
|
||||
:actions-component (fn [] [actions chat-id cover-bg-color])
|
||||
:loading-component (fn [] [loading-view chat-id messages-view-height messages-view-header-height])}]))
|
||||
all-loaded? (rf/sub [:chats/all-loaded? chat-id])
|
||||
display-name (cond
|
||||
(= chat-type constants/one-to-one-chat-type)
|
||||
(first (rf/sub [:contacts/contact-two-names-by-identity chat-id]))
|
||||
(= chat-type constants/community-chat-type)
|
||||
(str (when emoji (str emoji " ")) "# " chat-name)
|
||||
:else (str emoji chat-name))
|
||||
{:keys [bio]} (rf/sub [:contacts/contact-by-identity chat-id])
|
||||
online? (rf/sub [:visibility-status-updates/online? chat-id])
|
||||
contact (when-not group-chat
|
||||
(rf/sub [:contacts/contact-by-address chat-id]))
|
||||
photo-path (rf/sub [:chats/photo-path chat-id])
|
||||
border-animation (reanimated/interpolate scroll-y
|
||||
[30 125]
|
||||
[14 0]
|
||||
header-extrapolation-option)]
|
||||
[rn/view (add-inverted-y-android {:flex 1})
|
||||
[rn/view
|
||||
{:style (style/header-container all-loaded? theme)
|
||||
:on-layout on-layout}
|
||||
[rn/view {:style (style/header-cover cover-bg-color theme)}]
|
||||
[reanimated/view {:style (style/header-bottom-part border-animation theme)}
|
||||
[rn/view {:style style/header-avatar}
|
||||
[rn/view {:style {:align-items :flex-start}}
|
||||
(when-not group-chat
|
||||
[list-footer-avatar
|
||||
{:scroll-y scroll-y
|
||||
:display-name display-name
|
||||
:online? online?
|
||||
:profile-picture photo-path}])]
|
||||
[rnio/view
|
||||
{:on-change (fn [view-visible?]
|
||||
(reset! big-name-visible? view-visible?))
|
||||
:style {:flex-direction :row
|
||||
:margin-top (if group-chat 54 12)}}
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-1
|
||||
:style {:flex-shrink 1}
|
||||
:number-of-lines 1}
|
||||
display-name]
|
||||
[contact-icon contact theme]]
|
||||
(when bio
|
||||
[quo/text {:style style/bio}
|
||||
bio])
|
||||
[actions chat-id cover-bg-color]]]]
|
||||
[loading-view chat-id messages-view-height messages-view-header-height]]))
|
||||
|
||||
(defn list-footer
|
||||
[props]
|
||||
@@ -251,11 +257,10 @@
|
||||
[{:keys [chat-id invitation-admin]}]
|
||||
[rn/view
|
||||
[chat.group/group-chat-footer chat-id invitation-admin]])
|
||||
|
||||
(defn footer-on-layout
|
||||
[e messages-view-header-height]
|
||||
(let [height (oops/oget e "nativeEvent.layout.height")
|
||||
y (oops/oget e "nativeEvent.layout.y")]
|
||||
y (oops/oget e "nativeEvent.layout.y")]
|
||||
(reset! messages-view-header-height (+ height y))))
|
||||
|
||||
(defn render-fn
|
||||
@@ -264,7 +269,7 @@
|
||||
(when (not= content-type constants/content-type-contact-request)
|
||||
[rn/view
|
||||
(add-inverted-y-android
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-95 theme)})
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-95 theme)})
|
||||
(cond
|
||||
(= type :datemark)
|
||||
[quo/divider-date value]
|
||||
@@ -277,9 +282,9 @@
|
||||
|
||||
(defn scroll-handler
|
||||
[event scroll-y animate-topbar-opacity? on-end-reached? animate-topbar-name?]
|
||||
(let [content-size-y (- (oops/oget event "nativeEvent.contentSize.height")
|
||||
(oops/oget event "nativeEvent.layoutMeasurement.height"))
|
||||
current-y (oops/oget event "nativeEvent.contentOffset.y")
|
||||
(let [content-size-y (- (oops/oget event "nativeEvent.contentSize.height")
|
||||
(oops/oget event "nativeEvent.layoutMeasurement.height"))
|
||||
current-y (oops/oget event "nativeEvent.contentOffset.y")
|
||||
scroll-distance (- content-size-y current-y)]
|
||||
(when (and @on-end-reached? (pos? scroll-distance))
|
||||
(reset! on-end-reached? false))
|
||||
@@ -301,13 +306,13 @@
|
||||
(reset! animate-topbar-opacity? true)
|
||||
(reset! animate-topbar-opacity? false)))
|
||||
[composer-active? @on-end-reached? @animate-topbar-opacity?])
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
{window-height :height} (rn/get-window)
|
||||
{:keys [keyboard-height]} (hooks/use-keyboard)
|
||||
context (rf/sub [:chats/current-chat-message-list-view-context])
|
||||
messages (rf/sub [:chats/raw-chat-messages-stream (:chat-id chat)])
|
||||
recording? (rf/sub [:chats/recording?])
|
||||
all-loaded? (rf/sub [:chats/all-loaded? (:chat-id chat)])
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
{window-height :height} (rn/get-window)
|
||||
{:keys [keyboard-height]} (hooks/use-keyboard)
|
||||
context (rf/sub [:chats/current-chat-message-list-view-context])
|
||||
messages (rf/sub [:chats/raw-chat-messages-stream (:chat-id chat)])
|
||||
recording? (rf/sub [:chats/recording?])
|
||||
all-loaded? (rf/sub [:chats/all-loaded? (:chat-id chat)])
|
||||
{:keys [show-floating-scroll-down-button?
|
||||
messages-view-height
|
||||
messages-view-header-height]} inner-state-atoms]
|
||||
@@ -317,20 +322,18 @@
|
||||
:key-fn list-key-fn
|
||||
:ref list-ref
|
||||
:bounces false
|
||||
;; TODO(alwx): list-header indicates offsets
|
||||
:header [:<>
|
||||
[list-header insets (:able-to-send-message? context) theme]
|
||||
(when (= (:chat-type chat) constants/private-group-chat-type)
|
||||
[list-group-chat-header chat])]
|
||||
;; TODO(alwx): list-footer is basically a header, yes
|
||||
:footer [list-footer
|
||||
{:theme theme
|
||||
:chat chat
|
||||
:scroll-y scroll-y
|
||||
:cover-bg-color cover-bg-color
|
||||
:on-layout #(footer-on-layout
|
||||
%
|
||||
messages-view-header-height)
|
||||
%
|
||||
messages-view-header-height)
|
||||
:messages-view-header-height messages-view-header-height
|
||||
:messages-view-height messages-view-height
|
||||
:big-name-visible? big-name-visible?}]
|
||||
@@ -343,26 +346,26 @@
|
||||
:on-viewable-items-changed on-viewable-items-changed
|
||||
:on-content-size-change (fn [_ y]
|
||||
(if (or
|
||||
(< minimum-scroll-y-topbar-overlaying-avatar
|
||||
(reanimated/get-shared-value scroll-y))
|
||||
(< topbar-visible-scroll-y-value
|
||||
(reanimated/get-shared-value scroll-y)))
|
||||
(< minimum-scroll-y-topbar-overlaying-avatar
|
||||
(reanimated/get-shared-value scroll-y))
|
||||
(< topbar-visible-scroll-y-value
|
||||
(reanimated/get-shared-value scroll-y)))
|
||||
(reset! animate-topbar-opacity? true)
|
||||
(reset! animate-topbar-opacity? false))
|
||||
(when-not (or
|
||||
(not @big-name-visible?)
|
||||
(= :initial-render @big-name-visible?)
|
||||
(pos? (reanimated/get-shared-value
|
||||
scroll-y)))
|
||||
(not @big-name-visible?)
|
||||
(= :initial-render @big-name-visible?)
|
||||
(pos? (reanimated/get-shared-value
|
||||
scroll-y)))
|
||||
(reset! on-end-reached? false))
|
||||
;; NOTE(alwx): here we set the initial value of
|
||||
;; `scroll-y` which is needed because by default the
|
||||
;; chat is scrolled to the bottom and no initial
|
||||
;; `on-scroll` event is getting triggered
|
||||
(let [scroll-y-shared (reanimated/get-shared-value
|
||||
scroll-y)
|
||||
(let [scroll-y-shared (reanimated/get-shared-value
|
||||
scroll-y)
|
||||
content-height-shared (reanimated/get-shared-value
|
||||
content-height)]
|
||||
content-height)]
|
||||
(when (or (= scroll-y-shared 0)
|
||||
(> (Math/abs (- content-height-shared y))
|
||||
min-message-height))
|
||||
@@ -393,19 +396,19 @@
|
||||
animate-topbar-name?)
|
||||
(on-scroll event show-floating-scroll-down-button?))
|
||||
:style (add-inverted-y-android
|
||||
{:background-color (if all-loaded?
|
||||
(colors/theme-colors
|
||||
(colors/custom-color cover-bg-color
|
||||
50
|
||||
20)
|
||||
(colors/custom-color cover-bg-color
|
||||
50
|
||||
40)
|
||||
theme)
|
||||
(colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-95
|
||||
theme))})
|
||||
{:background-color (if all-loaded?
|
||||
(colors/theme-colors
|
||||
(colors/custom-color cover-bg-color
|
||||
50
|
||||
20)
|
||||
(colors/custom-color cover-bg-color
|
||||
50
|
||||
40)
|
||||
theme)
|
||||
(colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-95
|
||||
theme))})
|
||||
;;TODO(rasom) https://github.com/facebook/react-native/issues/30034
|
||||
:inverted (when platform/ios? true)
|
||||
:on-layout (fn [e]
|
||||
@@ -427,9 +430,9 @@
|
||||
(defn message-list-content-view
|
||||
[props]
|
||||
(let [chat-screen-loaded? (rf/sub [:shell/chat-screen-loaded?])
|
||||
window-height (:height (rn/get-window))
|
||||
content-height (- window-height composer.constants/composer-default-height)
|
||||
top-spacing (when (not chat-screen-loaded?) navigation.style/navigation-bar-height)]
|
||||
window-height (:height (rn/get-window))
|
||||
content-height (- window-height composer.constants/composer-default-height)
|
||||
top-spacing (when (not chat-screen-loaded?) navigation.style/navigation-bar-height)]
|
||||
(if chat-screen-loaded?
|
||||
[:f> f-messages-list-content props]
|
||||
[rn/view {:style {:padding-top top-spacing :flex 1}}
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
:on-end-reached? on-end-reached?
|
||||
:messages-list-on-layout-finished? messages-list-on-layout-finished?}]
|
||||
|
||||
;; TODO(alwx): this part is basically the top bar itself, shown only when scrolled
|
||||
[messages.navigation/navigation-view
|
||||
{:scroll-y scroll-y
|
||||
:animate-topbar-name? animate-topbar-name?
|
||||
|
||||
@@ -5,13 +5,11 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.home.actions.view :as actions]
|
||||
[status-im2.common.password-authentication.view :as password-authentication]
|
||||
[status-im2.common.scroll-page.style :as scroll-page.style]
|
||||
[status-im2.common.scroll-page.view :as scroll-page]
|
||||
[status-im2.common.top-bar.view :as top-bar]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.communities.actions.chat.view :as chat-actions]
|
||||
[status-im2.contexts.communities.actions.community-options.view :as options]
|
||||
@@ -39,8 +37,8 @@
|
||||
(defn add-category-height
|
||||
[categories-heights category height]
|
||||
(swap! categories-heights
|
||||
(fn [heights]
|
||||
(assoc heights category height))))
|
||||
(fn [heights]
|
||||
(assoc heights category height))))
|
||||
|
||||
(defn collapse-category
|
||||
[community-id category-id collapsed?]
|
||||
@@ -53,22 +51,22 @@
|
||||
(defn- channel-chat-item
|
||||
[community-id community-color
|
||||
{:keys [name emoji muted? id mentions-count unread-messages? on-press locked?] :as chat}]
|
||||
(let [sheet-content [actions/chat-actions
|
||||
(assoc chat
|
||||
:chat-type constants/community-chat-type
|
||||
:chat-id (str community-id id))
|
||||
false]
|
||||
notification (cond
|
||||
muted? :mute
|
||||
(> mentions-count 0) :mention
|
||||
unread-messages? :notification
|
||||
:else nil)
|
||||
channel-options {:name name
|
||||
:emoji emoji
|
||||
:customization-color community-color
|
||||
:mentions-count mentions-count
|
||||
:locked? locked?
|
||||
:notification notification}
|
||||
(let [sheet-content [actions/chat-actions
|
||||
(assoc chat
|
||||
:chat-type constants/community-chat-type
|
||||
:chat-id (str community-id id))
|
||||
false]
|
||||
notification (cond
|
||||
muted? :mute
|
||||
(> mentions-count 0) :mention
|
||||
unread-messages? :notification
|
||||
:else nil)
|
||||
channel-options {:name name
|
||||
:emoji emoji
|
||||
:customization-color community-color
|
||||
:mentions-count mentions-count
|
||||
:locked? locked?
|
||||
:notification notification}
|
||||
channel-sheet-data {:selected-item (fn [] [quo/channel channel-options])
|
||||
:content (fn [] sheet-content)}]
|
||||
[rn/view {:key id}
|
||||
@@ -82,8 +80,8 @@
|
||||
channels-list]
|
||||
[rn/view
|
||||
{:on-layout #(on-first-channel-height-changed
|
||||
(+ 38 (int (Math/ceil (layout-y %))))
|
||||
(into #{} (map (comp :name second) channels-list)))
|
||||
(+ 38 (int (Math/ceil (layout-y %))))
|
||||
(into #{} (map (comp :name second) channels-list)))
|
||||
:style {:margin-top 8 :flex 1}}
|
||||
(for [[category-id {:keys [chats name collapsed?]}] channels-list]
|
||||
[rn/view
|
||||
@@ -106,9 +104,9 @@
|
||||
(defn get-access-type
|
||||
[access]
|
||||
(condp = access
|
||||
constants/community-no-membership-access :open
|
||||
constants/community-no-membership-access :open
|
||||
constants/community-invitation-only-access :invite-only
|
||||
constants/community-on-request-access :request-access
|
||||
constants/community-on-request-access :request-access
|
||||
:unknown-access))
|
||||
|
||||
(defn join-gated-community
|
||||
@@ -124,15 +122,15 @@
|
||||
[rn/touchable-without-feedback
|
||||
{:on-press
|
||||
#(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[quo/documentation-drawers
|
||||
{:title (i18n/label :t/token-gated-communities)
|
||||
:show-button? true
|
||||
:button-label (i18n/label :t/read-more)
|
||||
:button-icon :info}
|
||||
[quo/text (i18n/label :t/token-gated-communities-info)]])}])}
|
||||
[:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[quo/documentation-drawers
|
||||
{:title (i18n/label :t/token-gated-communities)
|
||||
:show-button? true
|
||||
:button-label (i18n/label :t/read-more)
|
||||
:button-icon :info}
|
||||
[quo/text (i18n/label :t/token-gated-communities-info)]])}])}
|
||||
[rn/view
|
||||
[quo/icon :i/info {:no-color true}]]])
|
||||
|
||||
@@ -175,9 +173,9 @@
|
||||
(defn join-community
|
||||
[{:keys [joined color permissions token-permissions] :as community}
|
||||
pending?]
|
||||
(let [access-type (get-access-type (:access permissions))
|
||||
(let [access-type (get-access-type (:access permissions))
|
||||
unknown-access? (= access-type :unknown-access)
|
||||
invite-only? (= access-type :invite-only)]
|
||||
invite-only? (= access-type :invite-only)]
|
||||
[:<>
|
||||
(when-not (or joined pending? invite-only? unknown-access?)
|
||||
(if (seq token-permissions)
|
||||
@@ -213,18 +211,18 @@
|
||||
:or {locked? false}
|
||||
:as chat}]
|
||||
(merge
|
||||
chat
|
||||
(when (and (not locked?) id)
|
||||
{:on-press (when joined
|
||||
(fn []
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(debounce/dispatch-and-chill [:chat/navigate-to-chat (str community-id id)]
|
||||
1000)))
|
||||
:on-long-press #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[chat-actions/actions chat false])}])
|
||||
:community-id community-id})))
|
||||
chat
|
||||
(when (and (not locked?) id)
|
||||
{:on-press (when joined
|
||||
(fn []
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(debounce/dispatch-and-chill [:chat/navigate-to-chat (str community-id id)]
|
||||
1000)))
|
||||
:on-long-press #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[chat-actions/actions chat false])}])
|
||||
:community-id community-id})))
|
||||
|
||||
(defn add-handlers-to-chats
|
||||
[community-id joined chats]
|
||||
@@ -248,10 +246,10 @@
|
||||
scroll-page.style/picture-border-width
|
||||
12))
|
||||
:margin-bottom 12}
|
||||
:avatar logo
|
||||
:title title
|
||||
:description description
|
||||
:title-accessibility-label :community-title
|
||||
:avatar logo
|
||||
:title title
|
||||
:description description
|
||||
:title-accessibility-label :community-title
|
||||
:description-accessibility-label :community-description}])
|
||||
|
||||
(defn community-content
|
||||
@@ -302,8 +300,8 @@
|
||||
[{:icon-name :i/options
|
||||
:accessibility-label :community-options-for-community
|
||||
:on-press #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [options/community-options-bottom-sheet id])}])}])
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [options/community-options-bottom-sheet id])}])}])
|
||||
|
||||
(defn pick-first-category-by-height
|
||||
[scroll-height first-channel-height categories-heights]
|
||||
@@ -315,18 +313,18 @@
|
||||
|
||||
(defn community-scroll-page
|
||||
[{:keys [joined]}]
|
||||
(let [scroll-height (reagent/atom 0)
|
||||
categories-heights (reagent/atom {})
|
||||
(let [scroll-height (reagent/atom 0)
|
||||
categories-heights (reagent/atom {})
|
||||
first-channel-height (reagent/atom 0)
|
||||
;; We track the initial value of joined
|
||||
;; as we open the page to avoid switching
|
||||
;; from not collapsed to collapsed if the
|
||||
;; user is on this page
|
||||
initial-joined? joined]
|
||||
initial-joined? joined]
|
||||
(fn [{:keys [id name images] :as community} pending?]
|
||||
(let [cover {:uri (get-in images [:banner :uri])}
|
||||
logo {:uri (get-in images [:thumbnail :uri])}
|
||||
collapsed? (and initial-joined? (:joined community))
|
||||
(let [cover {:uri (get-in images [:banner :uri])}
|
||||
logo {:uri (get-in images [:thumbnail :uri])}
|
||||
collapsed? (and initial-joined? (:joined community))
|
||||
overlay-shown? (boolean (:sheets (rf/sub [:bottom-sheet])))]
|
||||
[scroll-page/scroll-page
|
||||
{:cover-image cover
|
||||
@@ -345,14 +343,14 @@
|
||||
:sticky-header [sticky-category-header
|
||||
{:enabled (> @scroll-height @first-channel-height)
|
||||
:label (pick-first-category-by-height
|
||||
@scroll-height
|
||||
@first-channel-height
|
||||
@categories-heights)}]}
|
||||
@scroll-height
|
||||
@first-channel-height
|
||||
@categories-heights)}]}
|
||||
[community-content
|
||||
community
|
||||
pending?
|
||||
{:on-category-layout (partial add-category-height categories-heights)
|
||||
:collapsed? collapsed?
|
||||
{:on-category-layout (partial add-category-height categories-heights)
|
||||
:collapsed? collapsed?
|
||||
:on-first-channel-height-changed
|
||||
;; Here we set the height of the component and we filter out the categories, as some
|
||||
;; might have been removed.
|
||||
@@ -364,12 +362,12 @@
|
||||
[id]
|
||||
(let [{:keys [id]
|
||||
:as community} (rf/sub [:communities/community id])
|
||||
pending? (rf/sub [:communities/my-pending-request-to-join id])]
|
||||
pending? (rf/sub [:communities/my-pending-request-to-join id])]
|
||||
[community-scroll-page community pending?]))
|
||||
|
||||
(defn overview
|
||||
[id]
|
||||
(let [id (or id (rf/sub [:get-screen-params :community-overview]))
|
||||
(let [id (or id (rf/sub [:get-screen-params :community-overview]))
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[rn/view {:style style/community-overview-container}
|
||||
[community-card-page-view id]
|
||||
@@ -379,54 +377,3 @@
|
||||
:label (i18n/label :t/jump-to)}}
|
||||
{:position :absolute
|
||||
:bottom 34}]]))
|
||||
|
||||
(defn list-header [{:keys [scroll-y theme]}]
|
||||
[top-bar/abstract-list-header
|
||||
{:inverted-y-on-android? false
|
||||
:show? true
|
||||
:theme theme
|
||||
:cover-bg-color :red
|
||||
:scroll-y scroll-y
|
||||
:on-layout (fn []
|
||||
)
|
||||
:avatar-component (fn []
|
||||
)
|
||||
:title-component (fn []
|
||||
)
|
||||
:description "test"
|
||||
:actions-component (fn []
|
||||
)
|
||||
:loading-component (fn []
|
||||
)
|
||||
}])
|
||||
|
||||
(defn overview-content-view [{:keys [id community customization-color chats-by-category
|
||||
scroll-y content-height]}]
|
||||
(let [categories-heights (reagent/atom {})
|
||||
first-channel-height (reagent/atom 0)]
|
||||
[rn/scroll-view
|
||||
[channel-list-component
|
||||
{:on-category-layout (partial add-category-height categories-heights)
|
||||
:community-id id
|
||||
:community-color (:color community)
|
||||
:on-first-channel-height-changed (fn [height categories]
|
||||
(swap! categories-heights select-keys categories)
|
||||
(reset! first-channel-height height))}
|
||||
(add-handlers-to-categorized-chats id chats-by-category (:joined community))]]))
|
||||
|
||||
(defn overview-old
|
||||
[id]
|
||||
(let [scroll-y (reanimated/use-shared-value 0)
|
||||
content-height (reanimated/use-shared-value 0)
|
||||
id (or id (rf/sub [:get-screen-params :community-overview]))
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
community (rf/sub [:communities/community id])
|
||||
chats-by-category (rf/sub [:communities/categorized-channels id])]
|
||||
[rn/view {:style style/community-overview-container}
|
||||
[overview-content-view
|
||||
{:id id
|
||||
:customization-color customization-color
|
||||
:community community
|
||||
:chats-by-category chats-by-category
|
||||
:scroll-y scroll-y
|
||||
:content-height content-height}]]))
|
||||
@@ -3,11 +3,10 @@
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.wallet.account.tabs.dapps.style :as style]
|
||||
[status-im2.contexts.wallet.common.empty-tab.view :as empty-tab]
|
||||
[status-im2.contexts.wallet.common.temp :as temp]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn dapp-options
|
||||
[]
|
||||
@@ -23,13 +22,12 @@
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [theme]}]
|
||||
(let [dapps-list (temp/dapps-list {:on-press-icon #(rf/dispatch [:show-bottom-sheet
|
||||
{:content dapp-options}])})]
|
||||
(let [dapps-list []]
|
||||
(if (empty? dapps-list)
|
||||
[empty-tab/view
|
||||
{:title (i18n/label :t/no-dapps)
|
||||
:description (i18n/label :t/no-collectibles-description)
|
||||
:placeholder? true}]
|
||||
{:title (i18n/label :t/no-dapps)
|
||||
:description (i18n/label :t/no-dapps-description)
|
||||
:image (resources/get-themed-image :no-dapps theme)}]
|
||||
[rn/view {:style style/dapps-container}
|
||||
[rn/flat-list
|
||||
{:data dapps-list
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
(ns status-im2.contexts.wallet.account.tabs.view
|
||||
(:require
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.wallet.account.tabs.about.view :as about]
|
||||
[status-im2.contexts.wallet.account.tabs.dapps.view :as dapps]
|
||||
[status-im2.contexts.wallet.common.activity-tab.view :as activity]
|
||||
@@ -10,8 +12,8 @@
|
||||
[status-im2.contexts.wallet.common.token-value.view :as token-value]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn view
|
||||
[{:keys [selected-tab]}]
|
||||
(defn- view-internal
|
||||
[{:keys [selected-tab theme]}]
|
||||
(case selected-tab
|
||||
:assets [rn/flat-list
|
||||
{:render-fn token-value/view
|
||||
@@ -20,8 +22,13 @@
|
||||
:collectibles [collectibles/view]
|
||||
:activity [activity/view]
|
||||
:permissions [empty-tab/view
|
||||
{:title (i18n/label :t/no-permissions)
|
||||
:description (i18n/label :t/no-collectibles-description)
|
||||
:placeholder? true}]
|
||||
{:title (i18n/label :t/no-permissions)
|
||||
:description (i18n/label :t/no-collectibles-description)
|
||||
:image (resources/get-image
|
||||
(quo.theme/theme-value :no-permissions-light
|
||||
:no-permissions-dark
|
||||
theme))}]
|
||||
:dapps [dapps/view]
|
||||
[about/view]))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
[{:id :assets :label (i18n/label :t/assets) :accessibility-label :assets-tab}
|
||||
{:id :collectibles :label (i18n/label :t/collectibles) :accessibility-label :collectibles-tab}
|
||||
{:id :activity :label (i18n/label :t/activity) :accessibility-label :activity-tab}
|
||||
{:id :permissions :label (i18n/label :t/permissions) :accessibility-label :permissions}
|
||||
{:id :dapps :label (i18n/label :t/dapps) :accessibility-label :dapps}
|
||||
{:id :about :label (i18n/label :t/about) :accessibility-label :about}])
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
(ns status-im2.contexts.wallet.common.activity-tab.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.wallet.common.empty-tab.view :as empty-tab]
|
||||
[status-im2.contexts.wallet.common.temp :as temp]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn activity-item
|
||||
@@ -14,15 +15,17 @@
|
||||
(merge {:on-press #(js/alert "Item pressed")}
|
||||
item)]])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [activity-list temp/activity-list]
|
||||
(defn- view-internal
|
||||
[{:keys [theme]}]
|
||||
(let [activity-list []]
|
||||
(if (empty? activity-list)
|
||||
[empty-tab/view
|
||||
{:title (i18n/label :t/no-activity)
|
||||
:description (i18n/label :t/empty-tab-description)
|
||||
:placeholder? true}]
|
||||
{:title (i18n/label :t/no-activity)
|
||||
:description (i18n/label :t/empty-tab-description)
|
||||
:image (resources/get-themed-image :no-activity theme)}]
|
||||
[rn/flat-list
|
||||
{:data activity-list
|
||||
:style {:flex 1}
|
||||
:render-fn activity-item}])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
(ns status-im2.contexts.wallet.common.collectibles-tab.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.wallet.common.empty-tab.view :as empty-tab]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(defn- view-internal
|
||||
[{:keys [theme]}]
|
||||
(let [collectible-list (rf/sub [:wallet/collectibles])]
|
||||
(if (empty? collectible-list)
|
||||
[empty-tab/view
|
||||
{:title (i18n/label :t/no-collectibles)
|
||||
:description (i18n/label :t/no-collectibles-description)
|
||||
:placeholder? true}]
|
||||
{:title (i18n/label :t/no-collectibles)
|
||||
:description (i18n/label :t/no-collectibles-description)
|
||||
:image (resources/get-themed-image :no-collectibles theme)}]
|
||||
[rn/flat-list
|
||||
{:data collectible-list
|
||||
:style {:flex 1}
|
||||
@@ -25,3 +27,5 @@
|
||||
:on-press #(rf/dispatch
|
||||
[:navigate-to
|
||||
:wallet-collectible])}])}])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
[quo/button {:on-press #(rf/dispatch [:navigate-to :wallet-create-account])}
|
||||
"Create Account"]
|
||||
[quo/button {:on-press #(rf/dispatch [:navigate-to :wallet-saved-addresses])}
|
||||
"Saved Addresses"]])
|
||||
"Saved Addresses"]
|
||||
[quo/button {:on-press #(rf/dispatch [:navigate-to :wallet-send-input-amount])}
|
||||
"Send: input amount"]])
|
||||
|
||||
(defn wallet-overview-state
|
||||
[networks]
|
||||
|
||||
@@ -53,10 +53,7 @@
|
||||
[common.top-nav/view]
|
||||
[rn/view {:style style/overview-container}
|
||||
[quo/wallet-overview (temp/wallet-overview-state networks)]]
|
||||
[rn/pressable
|
||||
{:on-long-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content temp/wallet-temporary-navigation}])}
|
||||
[quo/wallet-graph {:time-frame :empty}]]
|
||||
[quo/wallet-graph {:time-frame :empty}]
|
||||
[rn/flat-list
|
||||
{:style style/accounts-list
|
||||
:content-container-style style/accounts-list-container
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
(ns status-im2.contexts.wallet.send.input-amount.style)
|
||||
|
||||
(def screen
|
||||
{:flex 1})
|
||||
|
||||
(def input-container
|
||||
{:padding-top 12
|
||||
:padding-bottom 0})
|
||||
@@ -0,0 +1,93 @@
|
||||
(ns status-im2.contexts.wallet.send.input-amount.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.wallet.send.input-amount.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- make-limit-label
|
||||
[{:keys [amount currency]}]
|
||||
(str amount " " (string/upper-case (name currency))))
|
||||
|
||||
(defn- make-new-input
|
||||
[current v]
|
||||
(let [dot "."
|
||||
max-length 12
|
||||
length-owerflow? (>= (count current) max-length)
|
||||
ignore-extra-dot? (and (= v dot) (string/includes? current dot))
|
||||
ignore-value? (or
|
||||
ignore-extra-dot?
|
||||
length-owerflow?)]
|
||||
(if ignore-value?
|
||||
current
|
||||
(str current v))))
|
||||
|
||||
(defn- view-internal
|
||||
[_]
|
||||
(let [token :eth
|
||||
{:keys [currency]} (rf/sub [:profile/profile])
|
||||
networks (rf/sub [:wallet/network-details])
|
||||
conversion-rate 10
|
||||
limit-crypto 286.32
|
||||
limit-fiat (* limit-crypto conversion-rate)
|
||||
input-value (reagent/atom "")
|
||||
current-limit (reagent/atom {:amount limit-crypto
|
||||
:currency token})
|
||||
handle-swap (fn [crypto?]
|
||||
(let [num-value (parse-double @input-value)]
|
||||
(reset! current-limit (if crypto?
|
||||
{:amount limit-crypto
|
||||
:currency token}
|
||||
{:amount limit-fiat
|
||||
:currency currency}))
|
||||
(when (> num-value (:amount @current-limit))
|
||||
(reset! input-value ""))))
|
||||
handle-keyboard-press (fn [v]
|
||||
(let [current-value @input-value
|
||||
new-value (make-new-input current-value v)
|
||||
num-value (parse-double new-value)]
|
||||
(when (<= num-value (:amount @current-limit))
|
||||
(reset! input-value new-value))))
|
||||
handle-delete (fn [_]
|
||||
(swap! input-value #(subs % 0 (dec (count %)))))]
|
||||
(fn [{:keys [on-confirm]
|
||||
:or {on-confirm #(js/alert "Confirmed")}}]
|
||||
(let [limit-label (make-limit-label @current-limit)]
|
||||
[rn/view
|
||||
{:style style/screen}
|
||||
[quo/page-nav
|
||||
{:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:right-side :account-switcher
|
||||
:account-switcher {:customization-color :yellow
|
||||
:emoji "🎮"
|
||||
:on-press #(js/alert "Switch account")}}]
|
||||
[quo/token-input
|
||||
{:container-style style/input-container
|
||||
:token token
|
||||
:currency currency
|
||||
:networks networks
|
||||
:title (i18n/label :t/send-limit {:limit limit-label})
|
||||
:conversion conversion-rate
|
||||
:show-keyboard? false
|
||||
:value @input-value
|
||||
:on-swap handle-swap}]
|
||||
;; Network routing content to be added
|
||||
[rn/scroll-view]
|
||||
[quo/bottom-actions
|
||||
{:actions :1-action
|
||||
:button-one-label (i18n/label :t/confirm)
|
||||
:button-one-props {:disabled? (empty? @input-value)
|
||||
:on-press on-confirm}}]
|
||||
[quo/numbered-keyboard
|
||||
{:left-action :dot
|
||||
:delete-key? true
|
||||
:on-press handle-keyboard-press
|
||||
:on-delete handle-delete}]]))))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -49,6 +49,7 @@
|
||||
[status-im2.contexts.wallet.edit-account.view :as wallet-edit-account]
|
||||
[status-im2.contexts.wallet.saved-addresses.view :as wallet-saved-addresses]
|
||||
[status-im2.contexts.wallet.scan-account.view :as scan-address]
|
||||
[status-im2.contexts.wallet.send.input-amount.view :as wallet-send-input-amount]
|
||||
[status-im2.contexts.wallet.send.select-address.view :as wallet-select-address]
|
||||
[status-im2.navigation.options :as options]
|
||||
[status-im2.navigation.transitions :as transitions]))
|
||||
@@ -287,6 +288,11 @@
|
||||
{:name :wallet-saved-addresses
|
||||
:component wallet-saved-addresses/view}
|
||||
|
||||
{:name :wallet-send-input-amount
|
||||
:options {:modalPresentationStyle :overCurrentContext
|
||||
:insets {:top? true}}
|
||||
:component wallet-send-input-amount/view}
|
||||
|
||||
{:name :wallet-select-address
|
||||
:options {:modalPresentationStyle :overCurrentContext}
|
||||
:component wallet-select-address/view}
|
||||
|
||||
@@ -2389,5 +2389,8 @@
|
||||
"address-placeholder": "0x123abc... or bob.eth",
|
||||
"invalid-address": "It’s not Ethereum address or ENS name",
|
||||
"address-already-in-use": "Address already being used",
|
||||
"address-copied": "Address copied"
|
||||
"address-copied": "Address copied",
|
||||
"no-dapps-description": "We want dApps!",
|
||||
"send-limit": "Max: {{limit}}"
|
||||
}
|
||||
|
||||
|
||||