diff --git a/src/status_im/components/main_tabs.cljs b/src/status_im/components/main_tabs.cljs index 16fb5b074d..01551e75da 100644 --- a/src/status_im/components/main_tabs.cljs +++ b/src/status_im/components/main_tabs.cljs @@ -1,11 +1,16 @@ (ns status-im.components.main-tabs - (:require-macros [status-im.utils.views :refer [defview]]) + (:require-macros [reagent.ratom :refer [reaction]] + [status-im.utils.views :refer [defview]]) (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] + [reagent.core :as r] [status-im.components.react :refer [view + animated-view text-input text image - touchable-highlight]] + touchable-highlight + get-dimensions]] + [status-im.components.animation :as anim] [status-im.chats-list.screen :refer [chats-list]] [status-im.discovery.screen :refer [discovery]] [status-im.contacts.screen :refer [contact-list]] @@ -14,33 +19,91 @@ [status-im.components.styles :as common-st] [status-im.i18n :refer [label]])) +(def window-width (:width (get-dimensions "window"))) + (def tab-list [{:view-id :chat-list :title (label :t/chats) :screen chats-list - :icon :icon_tab_chats} + :icon :icon_tab_chats + :index 0} {:view-id :discovery :title (label :t/discovery) :screen discovery - :icon :icon_tab_discovery} + :icon :icon_tab_discovery + :index 1} {:view-id :contact-list :title (label :t/contacts) :screen contact-list - :icon :icon_tab_contacts}]) + :icon :icon_tab_contacts + :index 2}]) -(defn show-view? [current-view view-id] - (let [key-map {:key view-id}] - (if (= current-view view-id) - (merge st/show-tab key-map) - (merge st/hide-tab key-map)))) +(defn animation-logic [{:keys [offsets val tab-id to-tab-id]}] + (fn [_] + (when-let [offsets @offsets] + (let [from-value (:from offsets) + to-value (:to offsets) + to-tab-id @to-tab-id] + (anim/set-value val from-value) + (when to-value + (anim/start + (anim/timing val {:toValue to-value + :duration 300}) + (when (= tab-id to-tab-id) + (fn [arg] + (when (.-finished arg) + (dispatch [:on-navigated-to-tab])))))))))) -(defn tab-view [current-view {:keys [view-id screen]}] - [view (show-view? current-view view-id) +(defn get-tab-index-by-id [id] + (:index (first (filter #(= id (:view-id %)) tab-list)))) + +(defn get-offsets [tab-id from-id to-id] + (let [tab (get-tab-index-by-id tab-id) + from (get-tab-index-by-id from-id) + to (get-tab-index-by-id to-id)] + (if (or (= tab from) (= tab to)) + (cond + (or (nil? from) (= from to)) {:from 0} + (< from to) (if (= tab to) + {:from window-width, :to 0} + {:from 0, :to (- window-width)}) + (< to from) (if (= tab to) + {:from (- window-width), :to 0} + {:from 0, :to window-width})) + {:from (- window-width)}))) + +(defn tab-view-container [tab-id content] + (let [cur-tab-id (subscribe [:get :view-id]) + prev-tab-id (subscribe [:get :prev-tab-view-id]) + offsets (reaction (get-offsets tab-id @prev-tab-id @cur-tab-id)) + anim-value (anim/create-value (- window-width)) + context {:offsets offsets + :val anim-value + :tab-id tab-id + :to-tab-id cur-tab-id} + on-update (animation-logic context)] + (r/create-class + {:component-did-mount + on-update + :component-did-update + on-update + :reagent-render + (fn [tab-id content] + @offsets + [animated-view {:style (st/tab-view-container anim-value)} + content])}))) + +(defn tab-view [{:keys [view-id screen]}] + ^{:key view-id} + [tab-view-container view-id [screen]]) (defview main-tabs [] - [view-id [:get :view-id]] - [view common-st/flex - (doall (map #(tab-view view-id %1) tab-list)) - [tabs {:selected-view-id view-id - :tab-list tab-list}]]) + [view-id [:get :view-id] + tab-animation? [:get :prev-tab-view-id]] + [view {:style common-st/flex} + [view {:style common-st/flex + :pointerEvents (if tab-animation? :none :auto)} + (doall (map #(tab-view %) tab-list))] + [tabs {:selected-view-id view-id + :tab-list tab-list}]]) diff --git a/src/status_im/components/styles.cljs b/src/status_im/components/styles.cljs index 5aa0bf675d..13da04b19f 100644 --- a/src/status_im/components/styles.cljs +++ b/src/status_im/components/styles.cljs @@ -29,4 +29,4 @@ (def default-chat-color color-purple) (def flex - {:style {:flex 1}}) + {:flex 1}) diff --git a/src/status_im/components/tabs/styles.cljs b/src/status_im/components/tabs/styles.cljs index f3571cf3c8..45af60e439 100644 --- a/src/status_im/components/tabs/styles.cljs +++ b/src/status_im/components/tabs/styles.cljs @@ -54,17 +54,11 @@ :justifyContent :center :alignItems :center}) -(def show-tab - {:flex 1 - :pointerEvents :auto - :position :absolute - :top 0 - :left 0 - :right 0 - :bottom tab-height}) - -(def hide-tab - {:opacity 0 - :pointerEvents :none - :overflow :hidden}) - +(defn tab-view-container [offset-x] + {:flex 1 + :position :absolute + :top 0 + :left 0 + :right 0 + :bottom tab-height + :transform [{:translateX offset-x}]}) diff --git a/src/status_im/components/tabs/tab.cljs b/src/status_im/components/tabs/tab.cljs index e2f56af6b5..9ee44dcc44 100644 --- a/src/status_im/components/tabs/tab.cljs +++ b/src/status_im/components/tabs/tab.cljs @@ -10,9 +10,9 @@ [status-im.components.tabs.styles :as st])) (defview tab [{:keys [view-id title icon selected-view-id]}] - [touchable-highlight {:style st/tab - :onPress #(dispatch [:navigate-to - view-id])} + [touchable-highlight {:style st/tab + :disabled (= view-id selected-view-id) + :onPress #(dispatch [:navigate-to-tab view-id])} [view {:style st/tab-container} [image {:source {:uri icon} :style st/tab-icon}] diff --git a/src/status_im/navigation/handlers.cljs b/src/status_im/navigation/handlers.cljs index ac5bd9ec12..aa9c1eee32 100644 --- a/src/status_im/navigation/handlers.cljs +++ b/src/status_im/navigation/handlers.cljs @@ -43,6 +43,18 @@ (assoc :view-id view-id) (assoc :navigation-stack navigation-stack')))))) +(register-handler :navigate-to-tab + (enrich preload-data!) + (fn [db [_ view-id]] + (-> db + (assoc :prev-tab-view-id (:view-id db)) + (replace-view view-id)))) + +(register-handler :on-navigated-to-tab + (enrich preload-data!) + (fn [db [_]] + (assoc db :prev-tab-view-id nil))) + (register-handler :show-group-new (debug (fn [db _]