Fix #3013 Swipe chat based deletion
Signed-off-by: Julien Eluard <julien.eluard@gmail.com>
This commit is contained in:
parent
3a33e04410
commit
502a28ec7a
|
@ -16,4 +16,8 @@
|
|||
|
||||
(defn save
|
||||
[{:keys [browser-id] :as browser}]
|
||||
(data-store/save browser (exists? browser-id)))
|
||||
(data-store/save browser (exists? browser-id)))
|
||||
|
||||
(defn delete
|
||||
[browser-id]
|
||||
(data-store/delete browser-id))
|
|
@ -14,6 +14,11 @@
|
|||
[browser update?]
|
||||
(realm/save @realm/account-realm :browser browser update?))
|
||||
|
||||
(defn delete
|
||||
[browser-id]
|
||||
(when-let [browser (realm/get-one-by-field @realm/account-realm :browser :browser-id browser-id)]
|
||||
(realm/delete @realm/account-realm browser)))
|
||||
|
||||
(defn exists?
|
||||
[browser-id]
|
||||
(realm/exists? @realm/account-realm :browser {:browser-id browser-id}))
|
||||
|
|
|
@ -35,9 +35,6 @@
|
|||
(defn stop-animation [anim-value]
|
||||
(.stopAnimation anim-value))
|
||||
|
||||
(defn value [anim-value]
|
||||
(.-value anim-value))
|
||||
|
||||
(defn set-value [anim-value value]
|
||||
(.setValue anim-value value))
|
||||
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
(fn [browser]
|
||||
(browser-store/save browser)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:remove-browser
|
||||
(fn [browser-id]
|
||||
(browser-store/delete browser-id)))
|
||||
|
||||
(defn match-url [url]
|
||||
(str (when (and url (not (re-find #"^[a-zA-Z-_]+:/" url))) "http://") url))
|
||||
|
||||
|
@ -75,3 +80,10 @@
|
|||
[re-frame/trim-v]
|
||||
(fn [{:keys [db now] :as cofx} [options]]
|
||||
{:db (update db :browser/options merge options)}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:remove-browser
|
||||
[re-frame/trim-v]
|
||||
(fn [{:keys [db]} [browser-id]]
|
||||
{:db (update-in db [:browser/browsers] dissoc browser-id)
|
||||
:remove-browser browser-id}))
|
||||
|
|
|
@ -403,3 +403,9 @@
|
|||
:request-permissions
|
||||
(fn [_ [_ permissions then else]]
|
||||
{::request-permissions-fx [permissions then else]}))
|
||||
|
||||
(handlers/register-handler-db
|
||||
:set-swipe-position
|
||||
[re-frame/trim-v]
|
||||
(fn [db [item-id value]]
|
||||
(assoc-in db [:chat-animations item-id :delete-swiped] value)))
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
(ns status-im.ui.screens.home.animations.responder
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.components.animation :as animation]))
|
||||
|
||||
(defn get-updated-value [gesture end-offset-x swiped?]
|
||||
(let [base-value (if swiped? end-offset-x 0)]
|
||||
(- base-value (.-dx gesture))))
|
||||
|
||||
(defn on-start [_ gesture]
|
||||
(> (js/Math.abs (.-dx gesture)) 10))
|
||||
|
||||
(defn on-move [animated-offset-x end-offset-x swiped?]
|
||||
(fn [_ gesture]
|
||||
(let [to-value (get-updated-value gesture end-offset-x swiped?)]
|
||||
(animation/start (animation/spring animated-offset-x {:toValue to-value})))))
|
||||
|
||||
(defn on-release [animated-offset-x end-offset-x chat-id swiped?]
|
||||
(fn [_ gesture]
|
||||
(let [updated-value (get-updated-value gesture end-offset-x swiped?)
|
||||
should-open? (> updated-value (/ end-offset-x 2))
|
||||
to-value (if should-open? end-offset-x 0)]
|
||||
(re-frame/dispatch [:set-swipe-position chat-id should-open?])
|
||||
(animation/start (animation/spring animated-offset-x {:toValue to-value})))))
|
||||
|
||||
(defn swipe-pan-responder [animated-offset-x end-offset-x chat-id swiped?]
|
||||
(.create react/pan-responder
|
||||
(clj->js {:onMoveShouldSetPanResponder on-start
|
||||
:onPanResponderMove (on-move animated-offset-x end-offset-x swiped?)
|
||||
:onPanResponderRelease (on-release animated-offset-x end-offset-x chat-id swiped?)
|
||||
:onPanResponderTerminate (on-release animated-offset-x end-offset-x chat-id swiped?)})))
|
||||
|
||||
|
||||
(defn pan-handlers [pan-responder]
|
||||
(js->clj (.-panHandlers pan-responder)))
|
|
@ -3,6 +3,8 @@
|
|||
(:require [status-im.ui.components.styles :as component.styles]
|
||||
[status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def delete-button-width 100)
|
||||
|
||||
(defn toolbar []
|
||||
{:background-color colors/white})
|
||||
|
||||
|
@ -202,4 +204,18 @@
|
|||
(def toolbar-logo
|
||||
{:size 42
|
||||
:icon-size 17
|
||||
:shadow? false})
|
||||
:shadow? false})
|
||||
|
||||
(def delete-icon-highlight
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:right -800
|
||||
:width 800
|
||||
:background-color colors/red-light})
|
||||
|
||||
(def delete-icon-container
|
||||
{:flex 1
|
||||
:width delete-button-width
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
[status-im.ui.components.sync-state.offline :refer [offline-view]]
|
||||
[status-im.ui.screens.home.views.inner-item :as inner-item]
|
||||
[status-im.ui.screens.home.styles :as styles]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.animation :as animation]
|
||||
[status-im.ui.screens.home.animations.responder :as responder]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
|
@ -31,14 +34,24 @@
|
|||
:accessibility-label :plus-button
|
||||
:on-press #(re-frame/dispatch [:navigate-to :new])}])
|
||||
|
||||
(defn- home-list-item [[home-item-id home-item]]
|
||||
(if (:chat-id home-item)
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to-chat home-item-id])}
|
||||
[react/view
|
||||
[inner-item/home-list-chat-item-inner-view home-item]]]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:open-browser home-item])}
|
||||
[react/view
|
||||
[inner-item/home-list-browser-item-inner-view home-item]]]))
|
||||
(views/defview home-list-deletable [[home-item-id home-item]]
|
||||
(views/letsubs [swiped? [:delete-swipe-position home-item-id]]
|
||||
(let [delete-action (if (:chat-id home-item) :remove-chat :remove-browser)
|
||||
inner-item-view (if (:chat-id home-item)
|
||||
inner-item/home-list-chat-item-inner-view
|
||||
inner-item/home-list-browser-item-inner-view)
|
||||
offset-x (animation/create-value (if swiped? styles/delete-button-width 0))
|
||||
swipe-pan-responder (responder/swipe-pan-responder offset-x styles/delete-button-width home-item-id swiped?)
|
||||
swipe-pan-handler (responder/pan-handlers swipe-pan-responder)]
|
||||
[react/view swipe-pan-handler
|
||||
[react/animated-view {:style {:flex 1 :right offset-x}}
|
||||
[inner-item-view home-item]
|
||||
[react/touchable-highlight {:style styles/delete-icon-highlight
|
||||
:on-press #(do
|
||||
(re-frame/dispatch [:set-swipe-position home-item-id false])
|
||||
(re-frame/dispatch [delete-action home-item-id]))}
|
||||
[react/view {:style styles/delete-icon-container}
|
||||
[vector-icons/icon :icons/delete {:color colors/red}]]]]])))
|
||||
|
||||
;;do not remove view-id and will-update or will-unmount handlers, this is how it works
|
||||
(views/defview welcome [view-id]
|
||||
|
@ -70,7 +83,7 @@
|
|||
:else
|
||||
[list/flat-list {:data home-items
|
||||
:render-fn (fn [[home-item-id :as home-item]]
|
||||
^{:key home-item-id} [home-list-item home-item])}])
|
||||
^{:key home-item-id} [home-list-deletable home-item])}])
|
||||
(when platform/android?
|
||||
[home-action-button])
|
||||
[offline-view]]))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
(ns status-im.ui.screens.home.views.inner-item
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [clojure.string :as str]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[clojure.string :as str]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.screens.home.styles :as styles]
|
||||
[status-im.ui.components.styles :as component.styles]
|
||||
[status-im.utils.core :as utils]
|
||||
|
@ -11,6 +11,7 @@
|
|||
[status-im.utils.datetime :as time]
|
||||
[status-im.utils.gfycat.core :as gfycat]
|
||||
[status-im.constants :as const]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]))
|
||||
|
||||
(defn message-content-text [{:keys [content] :as message}]
|
||||
|
@ -87,38 +88,41 @@
|
|||
public-key unremovable? :as chat]}]
|
||||
(letsubs [last-message [:get-last-message chat-id]]
|
||||
(let [name (or (i18n/get-contact-translated chat-id :name name)
|
||||
(gfycat/generate-gfy public-key))]
|
||||
[react/view styles/chat-container
|
||||
[react/view styles/chat-icon-container
|
||||
[chat-icon.screen/chat-icon-view-chat-list chat-id group-chat name color online]]
|
||||
[react/view styles/chat-info-container
|
||||
[react/view styles/item-upper-container
|
||||
[chat-list-item-name name group-chat public? public-key]
|
||||
(when last-message
|
||||
[react/view styles/message-status-container
|
||||
[message-status chat last-message]
|
||||
[message-timestamp last-message]])]
|
||||
[react/view styles/item-lower-container
|
||||
[message-content-text last-message]
|
||||
[unviewed-indicator chat-id]]]])))
|
||||
(gfycat/generate-gfy public-key))]
|
||||
[react/view
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to-chat chat-id])}
|
||||
[react/view styles/chat-container
|
||||
[react/view styles/chat-icon-container
|
||||
[chat-icon.screen/chat-icon-view-chat-list chat-id group-chat name color online]]
|
||||
[react/view styles/chat-info-container
|
||||
[react/view styles/item-upper-container
|
||||
[chat-list-item-name name group-chat public? public-key]
|
||||
(when last-message
|
||||
[react/view styles/message-status-container
|
||||
[message-status chat last-message]
|
||||
[message-timestamp last-message]])]
|
||||
[react/view styles/item-lower-container
|
||||
[message-content-text last-message]
|
||||
[unviewed-indicator chat-id]]]]]])))
|
||||
|
||||
(defview home-list-browser-item-inner-view [{:keys [browser-id name url dapp? contact] :as browser}]
|
||||
(letsubs [contact' [:contact-by-identity contact]]
|
||||
[react/view styles/chat-container
|
||||
[react/view styles/chat-icon-container
|
||||
(if contact'
|
||||
[chat-icon.screen/dapp-icon-browser contact' 36]
|
||||
[react/view styles/browser-icon-container
|
||||
[vector-icons/icon :icons/discover {:color component.styles/color-light-gray6}]])]
|
||||
[react/view styles/chat-info-container
|
||||
[react/view styles/item-upper-container
|
||||
[react/view styles/name-view
|
||||
[react/view {:flex-shrink 1}
|
||||
[react/text {:style styles/name-text
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:open-browser browser])}
|
||||
[react/view styles/chat-container
|
||||
[react/view styles/chat-icon-container
|
||||
(if contact'
|
||||
[chat-icon.screen/dapp-icon-browser contact' 36]
|
||||
[react/view styles/browser-icon-container
|
||||
[vector-icons/icon :icons/discover {:color component.styles/color-light-gray6}]])]
|
||||
[react/view styles/chat-info-container
|
||||
[react/view styles/item-upper-container
|
||||
[react/view styles/name-view
|
||||
[react/view {:flex-shrink 1}
|
||||
[react/text {:style styles/name-text
|
||||
:number-of-lines 1}
|
||||
name]]]]
|
||||
[react/view styles/item-lower-container
|
||||
[react/view styles/last-message-container
|
||||
[react/text {:style styles/last-message-text
|
||||
:number-of-lines 1}
|
||||
name]]]]
|
||||
[react/view styles/item-lower-container
|
||||
[react/view styles/last-message-container
|
||||
[react/text {:style styles/last-message-text
|
||||
:number-of-lines 1}
|
||||
(or url (i18n/label :t/dapp))]]]]]))
|
||||
(or url (i18n/label :t/dapp))]]]]]]))
|
||||
|
|
|
@ -50,4 +50,9 @@
|
|||
|
||||
(reg-sub :can-navigate-back?
|
||||
(fn [db]
|
||||
(> (count (:navigation-stack db)) 1)))
|
||||
(> (count (:navigation-stack db)) 1)))
|
||||
|
||||
(reg-sub :delete-swipe-position
|
||||
(fn [db [_ item-id]]
|
||||
(let [item-animation (get-in db [:chat-animations item-id])]
|
||||
(if (some? item-animation) (:delete-swiped item-animation) nil))))
|
||||
|
|
Loading…
Reference in New Issue