Gesture section list (#15727)

* feat: gesture section list
This commit is contained in:
Omar Basem 2023-04-25 15:20:52 +04:00 committed by GitHub
parent 1e4a49fafe
commit 2fe4956f4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 75 additions and 52 deletions

View File

@ -76,3 +76,22 @@
[gesture-flat-list (rn-flat-list/base-list-props props)]) [gesture-flat-list (rn-flat-list/base-list-props props)])
(def scroll-view (reagent/adapt-react-class ScrollView)) (def scroll-view (reagent/adapt-react-class ScrollView))
;;; Custom gesture section-list
(defn- flatten-sections
[sections]
(mapcat (fn [{:keys [title data]}]
(into [{:title title :header? true}] data))
sections))
(defn section-list
[{:keys [sections render-section-header-fn render-fn] :as props}]
(let [data (flatten-sections sections)]
[flat-list
(merge props
{:data data
:render-fn (fn [item]
(if (:header? item)
(render-section-header-fn item)
(render-fn item)))})]))

View File

@ -3,6 +3,7 @@
[quo2.core :as quo2] [quo2.core :as quo2]
[quo2.foundations.colors :as quo2.colors] [quo2.foundations.colors :as quo2.colors]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[react-native.gesture :as gesture]
[status-im2.constants :as constants] [status-im2.constants :as constants]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[react-native.core :as rn] [react-native.core :as rn]
@ -58,7 +59,7 @@
item]))) item])))
(defn contact-selection-list (defn contact-selection-list
[] [{:keys [scroll-enabled on-scroll]}]
[:f> [:f>
(fn [] (fn []
(let [contacts (rf/sub [:contacts/sorted-and-grouped-by-first-letter]) (let [contacts (rf/sub [:contacts/sorted-and-grouped-by-first-letter])
@ -97,13 +98,15 @@
{:style {:flex 1}} {:style {:flex 1}}
(if no-contacts? (if no-contacts?
[no-contacts-view] [no-contacts-view]
[rn/section-list [gesture/section-list
{:key-fn :title {:key-fn :title
:sticky-section-headers-enabled false :sticky-section-headers-enabled false
:sections (rf/sub [:contacts/filtered-active-sections]) :sections (rf/sub [:contacts/filtered-active-sections])
:render-section-header-fn contact-list/contacts-section-header :render-section-header-fn contact-list/contacts-section-header
:content-container-style {:padding-bottom 70} :content-container-style {:padding-bottom 70}
:render-fn contact-item-render}])] :render-fn contact-item-render
:scroll-enabled @scroll-enabled
:on-scroll on-scroll}])]
(when contacts-selected? (when contacts-selected?
[button/button [button/button
{:type :primary {:type :primary

View File

@ -70,14 +70,13 @@
:padding-top padding-top}} :padding-top padding-top}}
(when-not skip-background? (when-not skip-background?
[reanimated/view {:style (style/background opacity)}]) [reanimated/view {:style (style/background opacity)}])
[gesture/gesture-detector
[reanimated/view {:style (style/main-view translate-y)} {:gesture (drag-gesture translate-y opacity scroll-enabled curr-scroll)}
[gesture/gesture-detector [reanimated/view {:style (style/main-view translate-y)}
{:gesture (drag-gesture translate-y opacity scroll-enabled curr-scroll)}
[rn/view {:style style/handle-container} [rn/view {:style style/handle-container}
[rn/view {:style (style/handle)}]]] [rn/view {:style (style/handle)}]]
[content [content
{:insets insets {:insets insets
:close close :close close
:scroll-enabled @scroll-enabled :scroll-enabled scroll-enabled
:on-scroll #(on-scroll % curr-scroll)}]]])))]) :on-scroll #(on-scroll % curr-scroll)}]]]])))])

View File

@ -40,12 +40,12 @@
:size 32} :i/reaction]]) :size 32} :i/reaction]])
(defn image-button (defn image-button
[bottom-inset] [insets]
[quo/button [quo/button
{:on-press (fn [] {:on-press (fn []
(permissions/request-permissions (permissions/request-permissions
{:permissions [:read-external-storage :write-external-storage] {:permissions [:read-external-storage :write-external-storage]
:on-allowed #(rf/dispatch [:open-modal :photo-selector {:bottom-inset bottom-inset}]) :on-allowed #(rf/dispatch [:open-modal :photo-selector {:insets insets}])
:on-denied (fn [] :on-denied (fn []
(background-timer/set-timeout (background-timer/set-timeout
#(utils-old/show-popup (i18n/label :t/error) #(utils-old/show-popup (i18n/label :t/error)
@ -118,7 +118,7 @@
(when (and (not @input/recording-audio?) (when (and (not @input/recording-audio?)
(nil? (get @input/reviewing-audio-filepath chat-id))) (nil? (get @input/reviewing-audio-filepath chat-id)))
[:<> [:<>
[image-button bottom-inset] [image-button {:bottom bottom-inset}]
[rn/view {:width 12}] [rn/view {:width 12}]
[reactions-button] [reactions-button]
[rn/view {:flex 1}] [rn/view {:flex 1}]

View File

@ -2,6 +2,7 @@
(:require (:require
[quo2.core :as quo] [quo2.core :as quo]
[react-native.core :as rn] [react-native.core :as rn]
[react-native.gesture :as gesture]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf] [utils.re-frame :as rf]
[quo2.foundations.colors :as colors] [quo2.foundations.colors :as colors]
@ -50,7 +51,7 @@
(str (:title item) index)) (str (:title item) index))
(defn album-selector (defn album-selector
[] [{:keys [scroll-enabled on-scroll]}]
[:f> [:f>
(fn [] (fn []
(let [albums (rf/sub [:camera-roll/albums]) (let [albums (rf/sub [:camera-roll/albums])
@ -60,8 +61,8 @@
(rf/dispatch [:chat.ui/camera-roll-get-albums]) (rf/dispatch [:chat.ui/camera-roll-get-albums])
js/undefined)) js/undefined))
[rn/view {:style {:padding-top 20}} [rn/view {:style {:padding-top 20}}
[album-title false selected-album] [album-title false]
[rn/section-list [gesture/section-list
{:data albums {:data albums
:render-fn album :render-fn album
:render-data selected-album :render-data selected-album
@ -70,4 +71,6 @@
:render-section-header-fn section-header :render-section-header-fn section-header
:style {:margin-top 12} :style {:margin-top 12}
:content-container-style {:padding-bottom 40} :content-container-style {:padding-bottom 40}
:key-fn key-fn}]]))]) :key-fn key-fn
:scroll-enabled @scroll-enabled
:on-scroll on-scroll}]]))])

View File

@ -80,41 +80,41 @@
(inc (utils/first-index #(= (:uri item) (:uri %)) @selected))])]) (inc (utils/first-index #(= (:uri item) (:uri %)) @selected))])])
(defn album-title (defn album-title
[photos? selected-album] [photos? selected temporary-selected insets]
(fn [] (fn []
[rn/touchable-opacity (let [selected-album (or (rf/sub [:camera-roll/selected-album]) (i18n/label :t/recent))]
{:style (style/title-container) [rn/touchable-opacity
:active-opacity 1 {:style (style/title-container)
:accessibility-label :album-title :active-opacity 1
:on-press (fn [] :accessibility-label :album-title
;; TODO: album-selector issue: :on-press (fn []
;; https://github.com/status-im/status-mobile/issues/15398 ;; TODO: album-selector issue:
(js/alert "currently disabled"))} ;; https://github.com/status-im/status-mobile/issues/15398
;(if photos? (if photos?
; (do (do
; (reset! temporary-selected @selected) (reset! temporary-selected @selected)
; (rf/dispatch [:open-modal :album-selector {:insets insets}])) (rf/dispatch [:open-modal :album-selector {:insets insets}]))
; (rf/dispatch [:navigate-back])) (rf/dispatch [:navigate-back])))}
[quo/text
{:weight :medium [quo/text
:ellipsize-mode :tail {:weight :medium
:number-of-lines 1 :ellipsize-mode :tail
:style {:max-width 150}} :number-of-lines 1
selected-album] :style {:max-width 150}}
[rn/view {:style (style/chevron-container)} selected-album]
[quo/icon (if photos? :i/chevron-down :i/chevron-up) [rn/view {:style (style/chevron-container)}
{:color (colors/theme-colors colors/neutral-100 colors/white)}]]])) [quo/icon (if photos? :i/chevron-down :i/chevron-up)
{:color (colors/theme-colors colors/neutral-100 colors/white)}]]])))
(defn photo-selector (defn photo-selector
[{:keys [scroll-enabled on-scroll]}] [{:keys [scroll-enabled on-scroll]}]
[:f> [:f>
(let [{:keys [insets]} (rf/sub [:get-screen-params]) ; TODO: (let [temporary-selected (reagent/atom [])
; https://github.com/status-im/status-mobile/issues/15535 {:keys [insets]} (rf/sub [:get-screen-params])] ; used when switching albums
temporary-selected (reagent/atom [])] ; used when switching albums
(fn [] (fn []
(let [selected (reagent/atom []) ; currently selected (let [selected (reagent/atom []) ; currently selected
selected-images (rf/sub [:chats/sending-image]) ; already selected and dispatched selected-images (rf/sub [:chats/sending-image])
selected-album (or (rf/sub [:camera-roll/selected-album]) (i18n/label :t/recent))] selected-album (or (rf/sub [:camera-roll/selected-album]) (i18n/label :t/recent))]
(rn/use-effect (rn/use-effect
(fn [] (fn []
@ -130,10 +130,10 @@
end-cursor (rf/sub [:camera-roll/end-cursor]) end-cursor (rf/sub [:camera-roll/end-cursor])
loading? (rf/sub [:camera-roll/loading-more]) loading? (rf/sub [:camera-roll/loading-more])
has-next-page? (rf/sub [:camera-roll/has-next-page])] has-next-page? (rf/sub [:camera-roll/has-next-page])]
[:<> [rn/view {:style {:flex 1}}
[rn/view [rn/view
{:style style/buttons-container} {:style style/buttons-container}
[album-title true selected-album selected temporary-selected] [album-title true selected temporary-selected insets]
[clear-button selected]] [clear-button selected]]
[gesture/flat-list [gesture/flat-list
{:key-fn identity {:key-fn identity
@ -145,7 +145,7 @@
:padding-bottom (+ (:bottom insets) 100) :padding-bottom (+ (:bottom insets) 100)
:padding-top 64} :padding-top 64}
:on-scroll on-scroll :on-scroll on-scroll
:scroll-enabled scroll-enabled :scroll-enabled @scroll-enabled
:on-end-reached #(rf/dispatch [:camera-roll/on-end-reached end-cursor :on-end-reached #(rf/dispatch [:camera-roll/on-end-reached end-cursor
selected-album loading? selected-album loading?
has-next-page?])}] has-next-page?])}]

View File

@ -1,6 +1,5 @@
(ns status-im2.navigation.screens (ns status-im2.navigation.screens
(:require (:require
[react-native.platform :as platform]
[status-im2.config :as config] [status-im2.config :as config]
[status-im2.contexts.activity-center.view :as activity-center] [status-im2.contexts.activity-center.view :as activity-center]
[status-im2.contexts.add-new-contact.views :as add-new-contact] [status-im2.contexts.add-new-contact.views :as add-new-contact]
@ -67,7 +66,7 @@
:component photo-selector/photo-selector} :component photo-selector/photo-selector}
{:name :album-selector {:name :album-selector
:options {:modalPresentationStyle (if platform/ios? :overCurrentContext :none)} :options {:sheet? true}
:component album-selector/album-selector} :component album-selector/album-selector}
{:name :new-contact {:name :new-contact