Improve home animations (#15247)
This commit is contained in:
parent
4810e1d7bf
commit
0fe6fea7e4
|
@ -0,0 +1,7 @@
|
|||
import {useAnimatedScrollHandler} from "react-native-reanimated";
|
||||
|
||||
export function useAnimatedScrollHandlerWorklet(scrollY) {
|
||||
return useAnimatedScrollHandler((event) => {
|
||||
scrollY.value = event.contentOffset.y;
|
||||
})
|
||||
}
|
|
@ -355,11 +355,6 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
|
|||
(def worklet-factory
|
||||
#js {:applyAnimationsToStyle (fn [])})
|
||||
|
||||
(def shell-worklets #js {})
|
||||
|
||||
(def bottom-sheet #js {})
|
||||
(def record-audio-worklets #js {})
|
||||
|
||||
;; Update i18n_resources.cljs
|
||||
(defn mock
|
||||
[module]
|
||||
|
@ -407,10 +402,11 @@ 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
|
||||
"../src/js/worklet_factory.js" worklet-factory
|
||||
"../src/js/shell_worklets.js" shell-worklets
|
||||
"../src/js/bottom_sheet.js" bottom-sheet
|
||||
"../src/js/record_audio_worklets.js" record-audio-worklets
|
||||
"../src/js/worklets/core.js" worklet-factory
|
||||
"../src/js/worklets/shell.js" #js {}
|
||||
"../src/js/worklets/bottom_sheet.js" #js {}
|
||||
"../src/js/worklets/record_audio.js" #js {}
|
||||
"../src/js/worklets/scroll_view.js" #js {}
|
||||
"./fleets.js" default-fleets
|
||||
"@walletconnect/client" wallet-connect-client
|
||||
"../translations/ar.json" (js/JSON.parse (slurp "./translations/ar.json"))
|
||||
|
|
|
@ -78,42 +78,42 @@
|
|||
[props
|
||||
{:keys [name
|
||||
muted?
|
||||
unread-messages?
|
||||
unread-mentions-count
|
||||
unviewed-messages-count
|
||||
unviewed-mentions-count
|
||||
status
|
||||
community-icon
|
||||
images
|
||||
tokens
|
||||
locked?]}]
|
||||
locked?
|
||||
style]}]
|
||||
[rn/touchable-highlight
|
||||
(merge {:underlay-color (colors/theme-colors
|
||||
colors/neutral-5
|
||||
colors/neutral-95)
|
||||
:style {:border-radius 12}}
|
||||
props)
|
||||
[rn/view {:flex 1}
|
||||
[rn/view (style/membership-info-container)
|
||||
[community-icon/community-icon
|
||||
{:images community-icon} 32]
|
||||
[rn/view
|
||||
{:flex 1
|
||||
:margin-left 12
|
||||
:justify-content :center}
|
||||
[text/text
|
||||
{:accessibility-label :chat-name-text
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :tail
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1}
|
||||
name]]
|
||||
[rn/view (merge (style/membership-info-container) style)
|
||||
[community-icon/community-icon
|
||||
{:images images} 32]
|
||||
[rn/view
|
||||
{:flex 1
|
||||
:margin-left 12
|
||||
:justify-content :center}
|
||||
[text/text
|
||||
{:accessibility-label :chat-name-text
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :tail
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1}
|
||||
name]]
|
||||
|
||||
[rn/view
|
||||
{:justify-content :center
|
||||
:margin-right 16}
|
||||
(if (= status :gated)
|
||||
[community-view/permission-tag-container
|
||||
{:locked? locked?
|
||||
:tokens tokens}]
|
||||
[notification-view
|
||||
{:muted? muted?
|
||||
:unread-mentions-count unread-mentions-count
|
||||
:unread-messages? unread-messages?}])]]]])
|
||||
[rn/view
|
||||
{:justify-content :center
|
||||
:margin-right 16}
|
||||
(if (= status :gated)
|
||||
[community-view/permission-tag-container
|
||||
{:locked? locked?
|
||||
:tokens tokens}]
|
||||
[notification-view
|
||||
{:muted? muted?
|
||||
:unread-mentions-count unviewed-mentions-count
|
||||
:unread-messages? (pos? unviewed-messages-count)}])]]])
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
colors/neutral-90)}
|
||||
{:flex-direction :row
|
||||
:margin-horizontal 20
|
||||
:margin-vertical 8
|
||||
:height 56
|
||||
:padding-right 12})
|
||||
[card-title-and-description title description]
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
:shadow-radius radius
|
||||
:shadow-opacity 1
|
||||
:shadow-color colors/shadow
|
||||
:elevation 1
|
||||
:border-radius radius
|
||||
:justify-content :space-between
|
||||
:elevation 2
|
||||
:background-color (colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-90)})
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
[taoensso.timbre :as log]
|
||||
[cljs-bean.core :as bean]
|
||||
[reagent.core :as reagent]
|
||||
[quo2.components.record-audio.record-audio.helpers :as helpers]))
|
||||
[quo2.components.record-audio.record-audio.helpers :as helpers]
|
||||
[utils.worklets.record-audio :as worklets.record-audio]))
|
||||
|
||||
(def ^:private scale-to-each 1.8)
|
||||
(def ^:private scale-to-total 2.6)
|
||||
|
@ -18,14 +19,6 @@
|
|||
(def ^:private signal-anim-duration 3900)
|
||||
(def ^:private signal-anim-duration-2 1950)
|
||||
|
||||
(def ^:private record-audio-worklets (js/require "../src/js/record_audio_worklets.js"))
|
||||
|
||||
(defn- ring-scale
|
||||
[scale substract]
|
||||
(.ringScale ^js record-audio-worklets
|
||||
scale
|
||||
substract))
|
||||
|
||||
(def ^:private animated-ring
|
||||
(reagent/adapt-react-class
|
||||
(rn/memo
|
||||
|
@ -45,7 +38,9 @@
|
|||
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))]
|
||||
(let [ring-scale (worklets.record-audio/ring-scale scale
|
||||
(* scale-padding
|
||||
index))]
|
||||
{:scale ring-scale
|
||||
:opacity (reanimated/interpolate ring-scale
|
||||
[1 scale-to-each]
|
||||
|
|
|
@ -98,6 +98,10 @@
|
|||
|
||||
(def use-ref react/useRef)
|
||||
|
||||
(defn current-ref
|
||||
[ref]
|
||||
(oops/oget ref "current"))
|
||||
|
||||
(defn use-effect
|
||||
([effect-fn]
|
||||
(use-effect effect-fn []))
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
LinearTransition)]
|
||||
[reagent.core :as reagent]
|
||||
[react-native.flat-list :as rn-flat-list]
|
||||
[utils.collection]))
|
||||
[utils.collection]
|
||||
[utils.worklets.core :as worklets.core]))
|
||||
|
||||
;; Animations
|
||||
(def slide-in-up-animation SlideInUp)
|
||||
|
@ -29,14 +30,14 @@
|
|||
(def create-animated-component (comp reagent/adapt-react-class (.-createAnimatedComponent reanimated)))
|
||||
|
||||
(def view (reagent/adapt-react-class (.-View reanimated)))
|
||||
(def scroll-view (reagent/adapt-react-class (.-ScrollView reanimated)))
|
||||
(def image (reagent/adapt-react-class (.-Image reanimated)))
|
||||
(def reanimated-flat-list (reagent/adapt-react-class (.-FlatList ^js rn)))
|
||||
(def reanimated-flat-list (create-animated-component (.-FlatList ^js rn)))
|
||||
(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)))
|
||||
|
@ -77,24 +78,20 @@
|
|||
(when (and anim (some? val))
|
||||
(set! (.-value anim) val)))
|
||||
|
||||
;; Worklets
|
||||
(def worklet-factory (js/require "../src/js/worklet_factory.js"))
|
||||
|
||||
(defn interpolate
|
||||
([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
|
||||
shared-value
|
||||
(clj->js input-range)
|
||||
(clj->js output-range)
|
||||
(clj->js extrapolation))))
|
||||
(worklets.core/interpolate-value
|
||||
shared-value
|
||||
(clj->js input-range)
|
||||
(clj->js output-range)
|
||||
(clj->js extrapolation))))
|
||||
|
||||
;;;; Component Animations
|
||||
(defn apply-animations-to-style
|
||||
[animations style]
|
||||
(use-animated-style
|
||||
(.applyAnimationsToStyle ^js worklet-factory (clj->js animations) (clj->js style))))
|
||||
(worklets.core/apply-animations-to-style (clj->js animations) (clj->js style))))
|
||||
|
||||
;; Animators
|
||||
(defn animate-shared-value-with-timing
|
||||
|
|
|
@ -10,9 +10,8 @@
|
|||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(def bottom-sheet-js (js/require "../src/js/bottom_sheet.js"))
|
||||
[reagent.core :as reagent]
|
||||
[utils.worklets.bottom-sheet :as worklets.bottom-sheet]))
|
||||
|
||||
(def animation-delay 450)
|
||||
|
||||
|
@ -129,9 +128,9 @@
|
|||
bg-height (max (min @content-height bg-height-expanded) 109)
|
||||
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)
|
||||
translate-y (worklets.bottom-sheet/use-translate-y window-height bottom-sheet-dy pan-y)
|
||||
bg-opacity
|
||||
(.useBackgroundOpacity ^js bottom-sheet-js translate-y bg-height window-height)
|
||||
(worklets.bottom-sheet/use-background-opacity translate-y bg-height window-height)
|
||||
on-content-layout (fn [evt]
|
||||
(let [height (oget evt "nativeEvent" "layout" "height")]
|
||||
(reset! content-height height)))
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
:style override-style
|
||||
:avatar user-avatar}
|
||||
"
|
||||
[{:keys [type style avatar hide-search]}]
|
||||
[{:keys [type style avatar search?] :or {type :default}}]
|
||||
(let [button-common-props (get-button-common-props type)
|
||||
notif-count (rf/sub [:activity-center/unread-count])
|
||||
new-notifications? (pos? notif-count)
|
||||
|
@ -71,7 +71,7 @@
|
|||
:right 20
|
||||
:top 12
|
||||
:flex-direction :row}}
|
||||
(when-not hide-search
|
||||
(when search?
|
||||
[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]
|
||||
|
|
|
@ -11,9 +11,7 @@
|
|||
|
||||
(defn icon-color
|
||||
[]
|
||||
(colors/theme-colors
|
||||
colors/white-opa-40
|
||||
colors/neutral-80-opa-40))
|
||||
(colors/theme-colors colors/white-opa-40 colors/neutral-80-opa-40))
|
||||
|
||||
(def negative-scroll-position-0 (if platform/ios? -44 0))
|
||||
(def scroll-position-0 (if platform/ios? 44 0))
|
||||
|
@ -27,15 +25,7 @@
|
|||
(min maximum)))
|
||||
|
||||
(defn scroll-page-header
|
||||
[scroll-height
|
||||
height
|
||||
name
|
||||
page-nav
|
||||
logo
|
||||
sticky-header
|
||||
top-nav
|
||||
title-colum
|
||||
navigate-back?]
|
||||
[scroll-height height name page-nav logo 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 (reanimated/use-shared-value scroll-height)
|
||||
|
@ -120,19 +110,10 @@
|
|||
(defn scroll-page
|
||||
[_ _ _]
|
||||
(let [scroll-height (reagent/atom negative-scroll-position-0)]
|
||||
(fn
|
||||
[{:keys [cover-image
|
||||
logo
|
||||
page-nav-right-section-buttons
|
||||
name
|
||||
on-scroll
|
||||
height
|
||||
top-nav
|
||||
title-colum
|
||||
background-color
|
||||
navigate-back?]}
|
||||
sticky-header
|
||||
children]
|
||||
(fn [{:keys [name cover-image logo page-nav-right-section-buttons on-scroll
|
||||
height top-nav title-colum background-color navigate-back?]}
|
||||
sticky-header
|
||||
children]
|
||||
[:<>
|
||||
[:f> scroll-page-header @scroll-height height name page-nav-right-section-buttons
|
||||
logo sticky-header top-nav title-colum navigate-back?]
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
(ns status-im2.common.sticky-scroll-view.view
|
||||
(:require [react-native.reanimated :as reanimated]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[utils.worklets.scroll-view :as worklets.scroll-view]
|
||||
[quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn sticky-item
|
||||
[{:keys [height translation-y background-color]} content]
|
||||
[:f>
|
||||
(fn []
|
||||
[rn/view (merge {:height height} (when platform/ios? {:z-index 1}))
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:transform [{:translateY translation-y}]}
|
||||
{:position :absolute
|
||||
:z-index (when platform/android? 1)
|
||||
:top 0
|
||||
:left 0
|
||||
:right 0
|
||||
:height height
|
||||
:background-color background-color})}
|
||||
content]])])
|
||||
|
||||
(defn scroll-view
|
||||
[{:keys [ref scroll-y blur]} & content]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [scroll-handler (worklets.scroll-view/use-animated-scroll-handler scroll-y)
|
||||
opacity (when blur
|
||||
(reanimated/interpolate scroll-y
|
||||
[0 (:delta blur)]
|
||||
[0 1]
|
||||
{:extrapolateLeft "clamp"
|
||||
:extrapolateRight "extend"}))]
|
||||
(into [reanimated/scroll-view
|
||||
{:ref ref
|
||||
:scroll-event-throttle 1
|
||||
:shows-vertical-scroll-indicator false
|
||||
:contentInsetAdjustmentBehavior :never
|
||||
:on-scroll scroll-handler}]
|
||||
(concat
|
||||
(when blur
|
||||
;bug on Android
|
||||
;https://github.com/Kureev/react-native-blur/issues/520}
|
||||
[[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:transform [{:translateY scroll-y}]
|
||||
:opacity opacity}
|
||||
{:overflow (if platform/ios? :visible :hidden)
|
||||
:position :absolute
|
||||
:z-index 1
|
||||
:top 0
|
||||
:height (:height blur)
|
||||
:right 0
|
||||
:left 0})}
|
||||
[reanimated/blur-view
|
||||
{:blur-amount 10
|
||||
:blur-type (if (colors/dark?) :dark :xlight)
|
||||
:style {:position :absolute
|
||||
:top 0
|
||||
:height (:height blur)
|
||||
:right 0
|
||||
:left 0}}]]])
|
||||
content))))])
|
||||
|
||||
(defn flat-list
|
||||
[{:keys [scroll-y blur header render-fn data]}]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [scroll-handler (worklets.scroll-view/use-animated-scroll-handler scroll-y)
|
||||
opacity (when blur
|
||||
(reanimated/interpolate scroll-y
|
||||
[0 (:delta blur)]
|
||||
[0 1]
|
||||
{:extrapolateLeft "clamp"
|
||||
:extrapolateRight "extend"}))]
|
||||
[reanimated/flat-list
|
||||
{:scroll-event-throttle 1
|
||||
:shows-vertical-scroll-indicator false
|
||||
:contentInsetAdjustmentBehavior :never
|
||||
:data data
|
||||
:render-fn render-fn
|
||||
:header (if blur
|
||||
[:<>
|
||||
[reanimated/blur-view
|
||||
{:blur-amount 10
|
||||
:blur-type :xlight
|
||||
:style (reanimated/apply-animations-to-style
|
||||
{:transform [{:translateY scroll-y}]
|
||||
:opacity opacity}
|
||||
{:z-index 1
|
||||
:position :absolute
|
||||
:top 0
|
||||
:height (:height blur)
|
||||
:right 0
|
||||
:left 0})}]
|
||||
header]
|
||||
header)
|
||||
:on-scroll scroll-handler}]))])
|
|
@ -0,0 +1,24 @@
|
|||
(ns status-im2.contexts.chat.home.style
|
||||
(:require [react-native.platform :as platform]))
|
||||
|
||||
(def tabs
|
||||
{:padding-horizontal 20
|
||||
:padding-top 16
|
||||
:padding-bottom 12})
|
||||
|
||||
(def blur
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:right 0
|
||||
:left 0
|
||||
:bottom 0})
|
||||
|
||||
(defn blur-container
|
||||
[top]
|
||||
{:overflow (if platform/ios? :visible :hidden)
|
||||
:position :absolute
|
||||
:z-index 1
|
||||
:top 0
|
||||
:right 0
|
||||
:left 0
|
||||
:padding-top top})
|
|
@ -10,11 +10,16 @@
|
|||
[status-im2.contexts.chat.home.contact-request.view :as contact-request]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.common.contact-list-item.view :as contact-list-item]
|
||||
[status-im2.common.home.actions.view :as actions]))
|
||||
[status-im2.common.home.actions.view :as actions]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.blur :as blur]
|
||||
[status-im2.contexts.chat.home.style :as style]
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(defn get-item-layout
|
||||
[_ index]
|
||||
#js {:length 64 :offset (* 64 index) :index index})
|
||||
#js {:length 56 :offset (* 56 index) :index index})
|
||||
|
||||
(defn filter-items-by-tab
|
||||
[tab items]
|
||||
|
@ -30,20 +35,21 @@
|
|||
[quo/text (i18n/label :t/blank-messages-text)]])
|
||||
|
||||
(defn chats
|
||||
[selected-tab]
|
||||
[selected-tab top]
|
||||
(let [{:keys [items search-filter]} (rf/sub [:home-items])
|
||||
items (filter-items-by-tab selected-tab items)]
|
||||
(if (and (empty? items)
|
||||
(empty? search-filter))
|
||||
[welcome-blank-chats]
|
||||
[rn/flat-list
|
||||
{:key-fn #(or (:chat-id %) (:public-key %) (:id %))
|
||||
:get-item-layout get-item-layout
|
||||
:on-end-reached #(re-frame/dispatch [:chat/show-more-chats])
|
||||
:keyboard-should-persist-taps :always
|
||||
:data items
|
||||
:render-fn chat-list-item/chat-list-item
|
||||
:content-container-style {:padding-bottom 30}}])))
|
||||
{:key-fn #(or (:chat-id %) (:public-key %) (:id %))
|
||||
:content-inset-adjustment-behavior :never
|
||||
:header [rn/view {:height (+ 245 top)}]
|
||||
:get-item-layout get-item-layout
|
||||
:on-end-reached #(re-frame/dispatch [:chat/show-more-chats])
|
||||
:keyboard-should-persist-taps :always
|
||||
:data items
|
||||
:render-fn chat-list-item/chat-list-item}])))
|
||||
|
||||
(defn welcome-blank-contacts
|
||||
[]
|
||||
|
@ -65,63 +71,63 @@
|
|||
:on-press show-profile-actions}})
|
||||
item]))
|
||||
|
||||
(defn contacts-section-list
|
||||
[sections]
|
||||
[rn/section-list
|
||||
{:key-fn :title
|
||||
:sticky-section-headers-enabled false
|
||||
:sections sections
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:content-container-style {:padding-bottom 20}
|
||||
:render-fn contact-item-render}])
|
||||
|
||||
(defn contacts
|
||||
[pending-contact-requests]
|
||||
[pending-contact-requests top]
|
||||
(let [items (rf/sub [:contacts/active-sections])]
|
||||
(if (and (empty? items) (empty? pending-contact-requests))
|
||||
[welcome-blank-contacts]
|
||||
[:<>
|
||||
(when (seq pending-contact-requests)
|
||||
[contact-request/contact-requests pending-contact-requests])
|
||||
(when (seq items)
|
||||
[contacts-section-list items])])))
|
||||
[rn/section-list
|
||||
{:key-fn :public-key
|
||||
:get-item-layout get-item-layout
|
||||
:content-inset-adjustment-behavior :never
|
||||
:header [:<>
|
||||
[rn/view {:height (+ 245 top)}]
|
||||
(when (seq pending-contact-requests)
|
||||
[contact-request/contact-requests
|
||||
pending-contact-requests])]
|
||||
:sections items
|
||||
:sticky-section-headers-enabled false
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:render-fn contact-item-render}])))
|
||||
|
||||
(defn tabs
|
||||
(defn get-tabs-data
|
||||
[dot?]
|
||||
[{:id :recent :label (i18n/label :t/recent) :accessibility-label :tab-recent}
|
||||
{:id :groups :label (i18n/label :t/groups) :accessibility-label :tab-groups}
|
||||
{:id :contacts
|
||||
:label (i18n/label :t/contacts)
|
||||
:accessibility-label :tab-contacts
|
||||
:notification-dot? dot?}])
|
||||
|
||||
(defn home
|
||||
[]
|
||||
(let [selected-tab (reagent/atom :recent)]
|
||||
(fn []
|
||||
(let [pending-contact-requests (rf/sub [:activity-center/pending-contact-requests])]
|
||||
[:<>
|
||||
[quo/discover-card
|
||||
{:title (i18n/label :t/invite-friends-to-status)
|
||||
:description (i18n/label :t/share-invite-link)}]
|
||||
[quo/tabs
|
||||
{:style {:margin-left 20
|
||||
:margin-bottom 20
|
||||
:margin-top 24}
|
||||
:size 32
|
||||
:on-change #(reset! selected-tab %)
|
||||
:default-active @selected-tab
|
||||
:data [{:id :recent
|
||||
:label (i18n/label :t/recent)
|
||||
:accessibility-label :tab-recent}
|
||||
{:id :groups
|
||||
:label (i18n/label :t/groups)
|
||||
:accessibility-label :tab-groups}
|
||||
{:id :contacts
|
||||
:label (i18n/label :t/contacts)
|
||||
:accessibility-label :tab-contacts
|
||||
:notification-dot? (pos? (count pending-contact-requests))}]}]
|
||||
(if (= @selected-tab :contacts)
|
||||
[contacts pending-contact-requests]
|
||||
[chats @selected-tab])]))))
|
||||
|
||||
(defn home
|
||||
[]
|
||||
[:<>
|
||||
[common.home/top-nav {:type :default :hide-search true}]
|
||||
[common.home/title-column
|
||||
{:label (i18n/label :t/messages)
|
||||
:handler #(rf/dispatch [:bottom-sheet/show-sheet :new-chat-bottom-sheet {}])
|
||||
:accessibility-label :new-chat-button}]
|
||||
[tabs]])
|
||||
[safe-area/consumer
|
||||
(fn [{:keys [top]}]
|
||||
[:<>
|
||||
(if (= @selected-tab :contacts)
|
||||
[contacts pending-contact-requests top]
|
||||
[chats @selected-tab top])
|
||||
[rn/view
|
||||
{:style (style/blur-container top)}
|
||||
[blur/view
|
||||
{:blur-amount (if platform/ios? 20 10)
|
||||
:blur-type (if (colors/dark?) :dark (if platform/ios? :light :xlight))
|
||||
:style style/blur}]
|
||||
[common.home/top-nav]
|
||||
[common.home/title-column
|
||||
{:label (i18n/label :t/messages)
|
||||
:handler #(rf/dispatch [:bottom-sheet/show-sheet :new-chat-bottom-sheet
|
||||
{}])
|
||||
:accessibility-label :new-chat-button}]
|
||||
[quo/discover-card
|
||||
{:title (i18n/label :t/invite-friends-to-status)
|
||||
:description (i18n/label :t/share-invite-link)}]
|
||||
[quo/tabs
|
||||
{:style style/tabs
|
||||
:size 32
|
||||
:on-change #(reset! selected-tab %)
|
||||
:default-active @selected-tab
|
||||
:data (get-tabs-data (pos? (count pending-contact-requests)))}]]])]))))
|
||||
|
|
|
@ -153,31 +153,24 @@
|
|||
(get mock-community-item-data :data))])]))
|
||||
(if communities communities communities-ids))])
|
||||
|
||||
|
||||
(defn communities-lists
|
||||
[selected-tab view-type]
|
||||
(let [ids-by-user-involvement (rf/sub [:communities/community-ids-by-user-involvement])
|
||||
all-communities (rf/sub [:communities/sorted-communities])
|
||||
tab @selected-tab]
|
||||
[rn/view {:style {:flex 1}}
|
||||
(case tab
|
||||
:all
|
||||
(other-communities-list {:communities all-communities
|
||||
:view-type view-type})
|
||||
[rn/view {:style {:flex 1}}
|
||||
(case @selected-tab
|
||||
:all
|
||||
(other-communities-list {:communities (rf/sub [:communities/sorted-communities])
|
||||
:view-type view-type})
|
||||
|
||||
:open
|
||||
(other-communities-list {:communities-ids (:open ids-by-user-involvement)
|
||||
:view-type view-type})
|
||||
:open
|
||||
[:<>]
|
||||
|
||||
:gated
|
||||
(other-communities-list {:communities-ids (:gated ids-by-user-involvement)
|
||||
:view-type view-type})
|
||||
|
||||
[quo/information-box
|
||||
{:type :error
|
||||
:icon :i/info}
|
||||
(i18n/label :t/error)])]))
|
||||
:gated
|
||||
[:<>]
|
||||
|
||||
[quo/information-box
|
||||
{:type :error
|
||||
:icon :i/info}
|
||||
(i18n/label :t/error)])])
|
||||
|
||||
(defn render-communities
|
||||
[selected-tab
|
||||
|
|
|
@ -1,38 +1,25 @@
|
|||
(ns status-im2.contexts.communities.home.style
|
||||
(:require [react-native.platform :as platform]))
|
||||
|
||||
(defn community-segments
|
||||
[padding-top]
|
||||
{:padding-bottom 12
|
||||
:padding-top padding-top
|
||||
:padding-horizontal 20
|
||||
:background-color :transparent})
|
||||
(def tabs
|
||||
{:padding-horizontal 20
|
||||
:padding-top 16
|
||||
:padding-bottom 12})
|
||||
|
||||
(def communities-header-style
|
||||
{:padding-vertical 8
|
||||
:margin-top (if platform/ios? 208 112)})
|
||||
(def blur
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:right 0
|
||||
:left 0
|
||||
:bottom 0})
|
||||
|
||||
(def render-segments-container
|
||||
{:flex 1
|
||||
:padding-horizontal 20
|
||||
:padding-vertical 12})
|
||||
(defn blur-container
|
||||
[top]
|
||||
{:overflow (if platform/ios? :visible :hidden)
|
||||
:position :absolute
|
||||
:z-index 1
|
||||
:top 0
|
||||
:right 0
|
||||
:left 0
|
||||
:padding-top top})
|
||||
|
||||
(defn home-communities-container
|
||||
[background-color]
|
||||
{:flex 1
|
||||
:background-color background-color
|
||||
:position :absolute
|
||||
:top (if platform/ios? -44 0)
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0})
|
||||
|
||||
(def blur-tabs-header
|
||||
{:flex 1
|
||||
:position :absolute
|
||||
:top (if platform/ios? 156 112)
|
||||
:height 52
|
||||
:left 0
|
||||
:right 0
|
||||
:justify-content :center
|
||||
:background-color :transparent})
|
||||
|
|
|
@ -1,136 +1,74 @@
|
|||
(ns status-im2.contexts.communities.home.view
|
||||
(:require [utils.i18n :as i18n]
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[reagent.core :as reagent]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.home.view :as common.home]
|
||||
[status-im2.common.scroll-page.view :as scroll-page]
|
||||
[status-im2.contexts.communities.menus.community-options.view :as options]
|
||||
[utils.re-frame :as rf]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[react-native.blur :as blur]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[status-im2.contexts.communities.home.style :as style]
|
||||
[utils.re-frame :as rf]))
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(defn community-segments
|
||||
[selected-tab padding-top]
|
||||
[rn/view
|
||||
{:style (style/community-segments padding-top)}
|
||||
[quo/tabs
|
||||
{:size 32
|
||||
:on-change #(reset! selected-tab %)
|
||||
:default-active :joined
|
||||
:data [{:id :joined :label (i18n/label :chats/joined) :accessibility-label :joined-tab}
|
||||
{:id :pending :label (i18n/label :t/pending) :accessibility-label :pending-tab}
|
||||
{:id :opened :label (i18n/label :t/opened) :accessibility-label :opened-tab}]}]])
|
||||
(defn item-render
|
||||
[{:keys [id] :as item}]
|
||||
(let [unviewed-counts (rf/sub [:communities/unviewed-counts id])
|
||||
item (merge item unviewed-counts)]
|
||||
[quo/communities-membership-list-item
|
||||
{:style {:padding-horizontal 18}
|
||||
:on-press #(rf/dispatch [:navigate-to-nav2 :community-overview id])
|
||||
:on-long-press #(rf/dispatch
|
||||
[:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
[options/community-options-bottom-sheet id])
|
||||
:selected-item (fn []
|
||||
[quo/communities-membership-list-item {} item])}])}
|
||||
item]))
|
||||
|
||||
(defn communities-list
|
||||
[communities-ids]
|
||||
[rn/view
|
||||
(map-indexed
|
||||
(fn [index id]
|
||||
(let [community (rf/sub [:communities/home-item id])]
|
||||
^{:key index}
|
||||
[quo/communities-membership-list-item
|
||||
{:on-press #(rf/dispatch [:navigate-to-nav2 :community-overview id])
|
||||
:on-long-press #(rf/dispatch
|
||||
[:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
[options/community-options-bottom-sheet id])
|
||||
:selected-item (fn []
|
||||
[quo/communities-membership-list-item {} community])}])}
|
||||
community]))
|
||||
communities-ids)])
|
||||
|
||||
|
||||
(defn render-communities-segments
|
||||
[selected-tab]
|
||||
(let [ids-by-user-involvement (rf/sub [:communities/community-ids-by-user-involvement])
|
||||
tab @selected-tab]
|
||||
[rn/view
|
||||
{:style style/render-segments-container}
|
||||
(case tab
|
||||
:joined
|
||||
[communities-list (:joined ids-by-user-involvement)]
|
||||
|
||||
:pending
|
||||
[communities-list (:pending ids-by-user-involvement)]
|
||||
|
||||
:opened
|
||||
[communities-list (:opened ids-by-user-involvement)]
|
||||
|
||||
[quo/information-box
|
||||
{:type :error
|
||||
:icon :i/info}
|
||||
(i18n/label :t/error)])]))
|
||||
|
||||
(defn communities-header
|
||||
[selected-tab padding-top]
|
||||
[:<>
|
||||
[rn/view
|
||||
{:style style/communities-header-style}
|
||||
[quo/discover-card
|
||||
{:on-press #(rf/dispatch [:navigate-to :discover-communities])
|
||||
:title (i18n/label :t/discover)
|
||||
:description (i18n/label :t/whats-trending)
|
||||
:accessibility-label :communities-home-discover-card}]]
|
||||
[community-segments selected-tab padding-top]])
|
||||
|
||||
(defn home-page-comunity-lists
|
||||
[{:keys [selected-tab padding-top]}]
|
||||
[rn/view {:style {:flex 1}}
|
||||
[communities-header selected-tab padding-top]
|
||||
[render-communities-segments selected-tab]])
|
||||
|
||||
(defn home-sticky-header
|
||||
[{:keys [selected-tab scroll-height padding-top]}]
|
||||
(when (> @scroll-height 80)
|
||||
[rn/view
|
||||
{:style style/blur-tabs-header}
|
||||
[community-segments selected-tab padding-top]]))
|
||||
|
||||
(defn home-nav
|
||||
[]
|
||||
[common.home/top-nav
|
||||
{:type :default
|
||||
:hide-search true
|
||||
:style {:background-color :transparent}}])
|
||||
|
||||
(defn title-column
|
||||
[]
|
||||
[common.home/title-column
|
||||
{:label (i18n/label :t/communities)
|
||||
:handler #(rf/dispatch [:bottom-sheet/show-sheet :add-new {}])
|
||||
:accessibility-label :new-chat-button}])
|
||||
|
||||
(defn communities-screen-content
|
||||
[]
|
||||
(let [scroll-height (reagent/atom 0)
|
||||
selected-tab (reagent/atom :joined)]
|
||||
(fn []
|
||||
[scroll-page/scroll-page
|
||||
{:name (i18n/label :t/communities)
|
||||
:on-scroll #(reset! scroll-height %)
|
||||
:top-nav [home-nav]
|
||||
:title-colum [title-column]
|
||||
:background-color (colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-95)
|
||||
:navigate-back? :false
|
||||
:height (if (> @scroll-height 80)
|
||||
208
|
||||
156)}
|
||||
[home-sticky-header
|
||||
{:selected-tab selected-tab
|
||||
:scroll-height scroll-height
|
||||
:padding-top 8}]
|
||||
[home-page-comunity-lists
|
||||
{:selected-tab selected-tab
|
||||
:padding-top 16
|
||||
:height 60}]])))
|
||||
(def tabs-data
|
||||
[{:id :joined :label (i18n/label :chats/joined) :accessibility-label :joined-tab}
|
||||
{:id :pending :label (i18n/label :t/pending) :accessibility-label :pending-tab}
|
||||
{:id :opened :label (i18n/label :t/opened) :accessibility-label :opened-tab}])
|
||||
|
||||
(defn home
|
||||
[]
|
||||
[rn/view
|
||||
{:style (style/home-communities-container (colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-95))}
|
||||
[communities-screen-content]])
|
||||
(let [selected-tab (reagent/atom :joined)]
|
||||
(fn []
|
||||
(let [{:keys [joined pending opened]} (rf/sub [:communities/grouped-by-status])
|
||||
selected-items (case @selected-tab
|
||||
:joined joined
|
||||
:pending pending
|
||||
:opened opened)]
|
||||
[safe-area/consumer
|
||||
(fn [{:keys [top]}]
|
||||
[:<>
|
||||
[rn/flat-list
|
||||
{:key-fn :id
|
||||
:content-inset-adjustment-behavior :never
|
||||
:header [rn/view {:height (+ 245 top)}]
|
||||
:render-fn item-render
|
||||
:data selected-items}]
|
||||
[rn/view
|
||||
{:style (style/blur-container top)}
|
||||
[blur/view
|
||||
{:blur-amount (if platform/ios? 20 10)
|
||||
:blur-type (if (colors/dark?) :dark (if platform/ios? :light :xlight))
|
||||
:style style/blur}]
|
||||
[common.home/top-nav]
|
||||
[common.home/title-column
|
||||
{:label (i18n/label :t/communities)
|
||||
:handler #(rf/dispatch [:bottom-sheet/show-sheet :add-new {}])
|
||||
:accessibility-label :new-chat-button}]
|
||||
[quo/discover-card
|
||||
{:on-press #(rf/dispatch [:navigate-to :discover-communities])
|
||||
:title (i18n/label :t/discover)
|
||||
:description (i18n/label :t/whats-trending)
|
||||
:accessibility-label :communities-home-discover-card}]
|
||||
[quo/tabs
|
||||
{:size 32
|
||||
:style style/tabs
|
||||
:on-change #(reset! selected-tab %)
|
||||
:default-active @selected-tab
|
||||
:data tabs-data}]]])]))))
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
[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]))
|
||||
[status-im2.contexts.shell.constants :as shell.constants]
|
||||
[utils.worklets.shell :as worklets.shell]))
|
||||
|
||||
;; Atoms
|
||||
(def selected-stack-id (atom nil))
|
||||
|
@ -66,8 +67,6 @@
|
|||
:top (+ top-empty-space (shell.constants/bottom-tabs-container-height))
|
||||
:scale minimize-scale}))
|
||||
|
||||
(def shell-worklets (js/require "../src/js/shell_worklets.js"))
|
||||
|
||||
;; Shared Values
|
||||
(defn calculate-shared-values
|
||||
[]
|
||||
|
@ -87,18 +86,11 @@
|
|||
(assoc
|
||||
acc
|
||||
stack-opacity-keyword
|
||||
(.stackOpacity
|
||||
^js shell-worklets
|
||||
(name id)
|
||||
selected-stack-id-sv)
|
||||
(worklets.shell/stack-opacity (name id) selected-stack-id-sv)
|
||||
stack-pointer-keyword
|
||||
(.stackPointer
|
||||
^js shell-worklets
|
||||
(name id)
|
||||
selected-stack-id-sv)
|
||||
(worklets.shell/stack-pointer (name id) selected-stack-id-sv)
|
||||
tabs-icon-color-keyword
|
||||
(.bottomTabIconColor
|
||||
^js shell-worklets
|
||||
(worklets.shell/bottom-tab-icon-color
|
||||
(name id)
|
||||
selected-stack-id-sv
|
||||
home-stack-state-sv
|
||||
|
@ -110,28 +102,19 @@
|
|||
:pass-through? pass-through-sv
|
||||
:home-stack-state home-stack-state-sv
|
||||
:animate-home-stack-left animate-home-stack-left
|
||||
:home-stack-left (.homeStackLeft
|
||||
^js shell-worklets
|
||||
:home-stack-left (worklets.shell/home-stack-left
|
||||
selected-stack-id-sv
|
||||
animate-home-stack-left
|
||||
home-stack-state-sv
|
||||
(clj->js (:left home-stack-position)))
|
||||
:home-stack-top (.homeStackTop
|
||||
^js shell-worklets
|
||||
:home-stack-top (worklets.shell/home-stack-top
|
||||
home-stack-state-sv
|
||||
(:top home-stack-position))
|
||||
:home-stack-opacity (.homeStackOpacity
|
||||
^js shell-worklets
|
||||
home-stack-state-sv)
|
||||
:home-stack-pointer (.homeStackPointer
|
||||
^js shell-worklets
|
||||
home-stack-state-sv)
|
||||
:home-stack-scale (.homeStackScale
|
||||
^js shell-worklets
|
||||
home-stack-state-sv
|
||||
(:scale home-stack-position))
|
||||
:bottom-tabs-height (.bottomTabsHeight
|
||||
^js shell-worklets
|
||||
:home-stack-opacity (worklets.shell/home-stack-opacity home-stack-state-sv)
|
||||
:home-stack-pointer (worklets.shell/home-stack-pointer home-stack-state-sv)
|
||||
:home-stack-scale (worklets.shell/home-stack-scale home-stack-state-sv
|
||||
(:scale home-stack-position))
|
||||
:bottom-tabs-height (worklets.shell/bottom-tabs-height
|
||||
home-stack-state-sv
|
||||
(shell.constants/bottom-tabs-container-height)
|
||||
(shell.constants/bottom-tabs-extended-container-height))}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
(ns status-im2.contexts.shell.home-stack
|
||||
(:require [react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.safe-area :as safe-area]
|
||||
(:require [react-native.reanimated :as reanimated]
|
||||
[status-im.ui.screens.wallet.accounts.views :as wallet.accounts]
|
||||
[status-im2.contexts.chat.home.view :as chat] ;; TODO move to status-im2
|
||||
[status-im2.contexts.chat.home.view :as chat]
|
||||
[status-im2.contexts.communities.home.view :as communities]
|
||||
[status-im2.contexts.shell.animation :as animation]
|
||||
[status-im2.contexts.shell.constants :as shell.constants]
|
||||
|
@ -43,22 +41,19 @@
|
|||
|
||||
(defn home-stack
|
||||
[]
|
||||
[safe-area/consumer
|
||||
(fn [insets]
|
||||
[:f>
|
||||
(fn []
|
||||
(let [shared-values @animation/shared-values-atom
|
||||
home-stack-original-style (styles/home-stack @animation/screen-height)
|
||||
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)]
|
||||
[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]
|
||||
[stack-view :browser-stack shared-values]
|
||||
[stack-view :wallet-stack shared-values]]]))])])
|
||||
[:f>
|
||||
(fn []
|
||||
(let [shared-values @animation/shared-values-atom
|
||||
home-stack-original-style (styles/home-stack @animation/screen-height)
|
||||
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)]
|
||||
[reanimated/view {:style home-stack-animated-style}
|
||||
[stack-view :communities-stack shared-values]
|
||||
[stack-view :chats-stack shared-values]
|
||||
[stack-view :browser-stack shared-values]
|
||||
[stack-view :wallet-stack shared-values]]))])
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
height (or screen-height height)]
|
||||
{:border-bottom-left-radius 20
|
||||
:border-bottom-right-radius 20
|
||||
:background-color (colors/theme-colors colors/neutral-5 colors/neutral-95)
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95)
|
||||
:overflow :hidden
|
||||
:position :absolute
|
||||
:width width
|
||||
|
|
|
@ -109,10 +109,9 @@
|
|||
[jump-to-list switcher-cards shell-margin]
|
||||
[top-nav-blur-overlay (:top insets)]
|
||||
[common.home/top-nav
|
||||
{:type :shell
|
||||
:hide-search true
|
||||
:style {:margin-top (:top insets)
|
||||
:z-index 2}}]])]))
|
||||
{:type :shell
|
||||
:style {:margin-top (:top insets)
|
||||
:z-index 2}}]])]))
|
||||
|
||||
(defn on-layout
|
||||
[evt]
|
||||
|
|
|
@ -121,21 +121,16 @@
|
|||
(map :id communities)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/community-ids-by-user-involvement
|
||||
:communities/grouped-by-status
|
||||
:<- [:communities/communities]
|
||||
;; Return communities splitted by level of user participation. Some communities user
|
||||
;; already joined, to some of them join request sent and others were opened one day
|
||||
;; and their data remained in app-db.
|
||||
;; Result map has form: {:joined [id1, id2] :pending [id3, id5] :opened [id4]}"
|
||||
(fn [communities]
|
||||
(reduce (fn [acc community]
|
||||
(let [joined? (:joined community)
|
||||
requested? (pos? (:requested-to-join-at community))
|
||||
id (:id community)]
|
||||
requested? (pos? (:requested-to-join-at community))] ;; this looks suspicious
|
||||
(cond
|
||||
joined? (update acc :joined conj id)
|
||||
requested? (update acc :pending conj id)
|
||||
:else (update acc :opened conj id))))
|
||||
joined? (update acc :joined conj community)
|
||||
requested? (update acc :pending conj community)
|
||||
:else (update acc :opened conj community))))
|
||||
{:joined [] :pending [] :opened []}
|
||||
communities)))
|
||||
|
||||
|
|
|
@ -81,42 +81,6 @@
|
|||
:unviewed-mentions-count 0}
|
||||
(rf/sub [sub-name community-id])))))
|
||||
|
||||
(h/deftest-sub :communities/community-ids-by-user-involvement
|
||||
[sub-name]
|
||||
(testing "Empty communities list"
|
||||
(swap! rf-db/app-db assoc
|
||||
:communities
|
||||
{})
|
||||
(is (= {:joined [] :pending [] :opened []}
|
||||
(rf/sub [sub-name]))))
|
||||
(testing "Only opened communities"
|
||||
(swap! rf-db/app-db assoc
|
||||
:communities/enabled? true
|
||||
:communities
|
||||
{"0x1" {:id "0x1" :name "civilized monkeys"}
|
||||
"0x2" {:id "0x2" :name "Civilized rats"}
|
||||
"0x3" {:id "0x3" :name "Civilized dolphins"}})
|
||||
(is (= {:joined [] :pending [] :opened ["0x1" "0x2" "0x3"]}
|
||||
(rf/sub [sub-name]))))
|
||||
(testing "One joined community and two opened ones"
|
||||
(swap! rf-db/app-db assoc
|
||||
:communities/enabled? true
|
||||
:communities
|
||||
{"0x1" {:id "0x1" :name "civilized monkeys" :joined true}
|
||||
"0x2" {:id "0x2" :name "Civilized rats"}
|
||||
"0x3" {:id "0x3" :name "Civilized dolphins"}})
|
||||
(is (= {:joined ["0x1"] :pending [] :opened ["0x2" "0x3"]}
|
||||
(rf/sub [sub-name]))))
|
||||
(testing "One joined community, one open and one pending"
|
||||
(swap! rf-db/app-db assoc
|
||||
:communities/enabled? true
|
||||
:communities
|
||||
{"0x1" {:id "0x1" :name "civilized monkeys" :joined true}
|
||||
"0x2" {:id "0x2" :name "Civilized rats" :requested-to-join-at 1000}
|
||||
"0x3" {:id "0x3" :name "Civilized dolphins"}})
|
||||
(is (= {:joined ["0x1"] :pending ["0x2"] :opened ["0x3"]}
|
||||
(rf/sub [sub-name])))))
|
||||
|
||||
(h/deftest-sub :communities/sorted-communities
|
||||
[sub-name]
|
||||
(testing "Empty communities list"
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
(ns utils.worklets.bottom-sheet)
|
||||
|
||||
(def bottom-sheet-js (js/require "../src/js/worklets/bottom_sheet.js"))
|
||||
|
||||
(defn use-translate-y
|
||||
[window-height bottom-sheet-dy pan-y]
|
||||
(.useTranslateY ^js bottom-sheet-js window-height bottom-sheet-dy pan-y))
|
||||
|
||||
(defn use-background-opacity
|
||||
[translate-y bg-height window-height]
|
||||
(.useBackgroundOpacity ^js bottom-sheet-js translate-y bg-height window-height))
|
|
@ -0,0 +1,18 @@
|
|||
(ns utils.worklets.core)
|
||||
|
||||
(def core-js (js/require "../src/js/worklets/core.js"))
|
||||
|
||||
(defn interpolate-value
|
||||
[shared-value
|
||||
input-range
|
||||
output-range
|
||||
extrapolation]
|
||||
(.interpolateValue ^js core-js
|
||||
shared-value
|
||||
(clj->js input-range)
|
||||
(clj->js output-range)
|
||||
(clj->js extrapolation)))
|
||||
|
||||
(defn apply-animations-to-style
|
||||
[animations style]
|
||||
(.applyAnimationsToStyle ^js core-js (clj->js animations) (clj->js style)))
|
|
@ -0,0 +1,7 @@
|
|||
(ns utils.worklets.record-audio)
|
||||
|
||||
(def ^:private record-audio-worklets (js/require "../src/js/worklets/record_audio.js"))
|
||||
|
||||
(defn ring-scale
|
||||
[scale substract]
|
||||
(.ringScale ^js record-audio-worklets scale substract))
|
|
@ -0,0 +1,7 @@
|
|||
(ns utils.worklets.scroll-view)
|
||||
|
||||
(def scroll-worklet-js (js/require "../src/js/worklets/scroll_view.js"))
|
||||
|
||||
(defn use-animated-scroll-handler
|
||||
[scroll-y]
|
||||
(.useAnimatedScrollHandlerWorklet ^js scroll-worklet-js scroll-y))
|
|
@ -0,0 +1,52 @@
|
|||
(ns utils.worklets.shell)
|
||||
|
||||
(def shell-worklets (js/require "../src/js/worklets/shell.js"))
|
||||
|
||||
(defn stack-opacity
|
||||
[id selected-stack-id]
|
||||
(.stackOpacity ^js shell-worklets id selected-stack-id))
|
||||
|
||||
(defn stack-pointer
|
||||
[id selected-stack-id]
|
||||
(.stackPointer ^js shell-worklets id selected-stack-id))
|
||||
|
||||
(defn bottom-tabs-height
|
||||
[home-stack-state-sv container-height extended-container-height]
|
||||
(.bottomTabsHeight ^js shell-worklets home-stack-state-sv container-height extended-container-height))
|
||||
|
||||
(defn bottom-tab-icon-color
|
||||
[id selected-stack-id-sv home-stack-state-sv pass-through-sv selected-tab-color default-color
|
||||
pass-through-color]
|
||||
(.bottomTabIconColor ^js shell-worklets
|
||||
id
|
||||
selected-stack-id-sv
|
||||
home-stack-state-sv
|
||||
pass-through-sv
|
||||
selected-tab-color
|
||||
default-color
|
||||
pass-through-color))
|
||||
|
||||
(defn home-stack-opacity
|
||||
[home-stack-state-sv]
|
||||
(.homeStackOpacity ^js shell-worklets home-stack-state-sv))
|
||||
|
||||
(defn home-stack-pointer
|
||||
[home-stack-state-sv]
|
||||
(.homeStackPointer ^js shell-worklets home-stack-state-sv))
|
||||
|
||||
(defn home-stack-scale
|
||||
[home-stack-state-sv scale]
|
||||
(.homeStackScale ^js shell-worklets home-stack-state-sv scale))
|
||||
|
||||
(defn home-stack-left
|
||||
[selected-stack-id-sv animate-home-stack-left home-stack-state-sv left-home-stack-position]
|
||||
(.homeStackLeft
|
||||
^js shell-worklets
|
||||
selected-stack-id-sv
|
||||
animate-home-stack-left
|
||||
home-stack-state-sv
|
||||
left-home-stack-position))
|
||||
|
||||
(defn home-stack-top
|
||||
[home-stack-state-sv top-home-stack-position]
|
||||
(.homeStackTop ^js shell-worklets home-stack-state-sv top-home-stack-position))
|
Loading…
Reference in New Issue