Fix #3013 Swipe chat based deletion

Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
Hanwen Cheng 2018-02-20 22:54:11 +08:00 committed by Andrey Shovkoplyas
parent 0a17d75ff4
commit f4f1ab4e2f
No known key found for this signature in database
GPG Key ID: EAAB7C8622D860A4
13 changed files with 148 additions and 46 deletions

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path fill="" d="M7.00001034,5 C7.004297,3.34182361 8.34093668,2 10,2 L14,2 C15.6555111,2 16.9973018,3.34290405 16.9999959,5 L18.5454545,5 C19.9047426,5 21,6.12948418 21,7.5 C21,8.87051582 19.9047426,10 18.5454545,10 L5.45454545,10 C4.09525738,10 3,8.87051582 3,7.5 C3,6.12948418 4.09525738,5 5.45454545,5 L7.0000096,5 Z M14.9999879,5 C14.9973085,4.44655807 14.5500233,4 14,4 L10,4 C9.44811686,4 9.00424986,4.44383154 9.00003034,5 L14.9999888,5 Z M12,13.5857864 L13.2928932,12.2928932 C13.6834175,11.9023689 14.3165825,11.9023689 14.7071068,12.2928932 C15.0976311,12.6834175 15.0976311,13.3165825 14.7071068,13.7071068 L13.4142136,15 L14.7071068,16.2928932 C15.0976311,16.6834175 15.0976311,17.3165825 14.7071068,17.7071068 C14.3165825,18.0976311 13.6834175,18.0976311 13.2928932,17.7071068 L12,16.4142136 L10.7071068,17.7071068 C10.3165825,18.0976311 9.68341751,18.0976311 9.29289322,17.7071068 C8.90236893,17.3165825 8.90236893,16.6834175 9.29289322,16.2928932 L10.5857864,15 L9.29289322,13.7071068 C8.90236893,13.3165825 8.90236893,12.6834175 9.29289322,12.2928932 C9.68341751,11.9023689 10.3165825,11.9023689 10.7071068,12.2928932 L12,13.5857864 Z M17,12 C17,11.4477153 17.4477153,11 18,11 C18.5522847,11 19,11.4477153 19,12 L19,19.998 C19,21.604 17.953,23 16.4985,23 L7.5,23 C6.047,23 5,21.604 5,20 L5,12 C5,11.4477153 5.44771525,11 6,11 C6.55228475,11 7,11.4477153 7,12 L7,20 C7,20.604 7.297,21 7.5,21 L16.4985,21 C16.703,21 17,20.604 17,19.998 L17,12 Z M18.5454545,8 C18.7861665,8 19,7.77948418 19,7.5 C19,7.22051582 18.7861665,7 18.5454545,7 L5.45454545,7 C5.21383352,7 5,7.22051582 5,7.5 C5,7.77948418 5.21383352,8 5.45454545,8 L18.5454545,8 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -17,3 +17,7 @@
(defn save (defn save
[{:keys [browser-id] :as browser}] [{: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 (exists? browser-id)))

View File

@ -14,6 +14,11 @@
[browser update?] [browser update?]
(realm/save @realm/account-realm :browser browser update?)) (realm/save @realm/account-realm :browser browser update?))
(defn delete
[browser-id]
(when-let [browser (realm/get-one-by-field-clj @realm/account-realm :browser :browser-id browser-id)]
(realm/delete @realm/account-realm browser)))
(defn exists? (defn exists?
[browser-id] [browser-id]
(realm/exists? @realm/account-realm :browser {:browser-id browser-id})) (realm/exists? @realm/account-realm :browser {:browser-id browser-id}))

View File

@ -35,9 +35,6 @@
(defn stop-animation [anim-value] (defn stop-animation [anim-value]
(.stopAnimation anim-value)) (.stopAnimation anim-value))
(defn value [anim-value]
(.-value anim-value))
(defn set-value [anim-value value] (defn set-value [anim-value value]
(.setValue anim-value value)) (.setValue anim-value value))

View File

@ -11,4 +11,5 @@
(def gray-lighter "#eef2f5") ;; Used as a background or shadow (def gray-lighter "#eef2f5") ;; Used as a background or shadow
(def blue "#4360df") ;; Used as main wallet color (def blue "#4360df") ;; Used as main wallet color
(def red "#ff2d55") ;; Used to highlight errors or "dangerous" actions (def red "#ff2d55") ;; Used to highlight errors or "dangerous" actions
(def light-red "#ffe6e6") ;; Used as a background for delete icon
(def text-light-gray "#212121") ;; Used for labels (home items) (def text-light-gray "#212121") ;; Used for labels (home items)

View File

@ -47,6 +47,7 @@
:icons/browse (slurp/slurp-svg "./resources/icons/browse.svg") :icons/browse (slurp/slurp-svg "./resources/icons/browse.svg")
:icons/close (slurp/slurp-svg "./resources/icons/close.svg") :icons/close (slurp/slurp-svg "./resources/icons/close.svg")
:icons/copy-from (slurp/slurp-svg "./resources/icons/copy_from.svg") :icons/copy-from (slurp/slurp-svg "./resources/icons/copy_from.svg")
:icons/delete (slurp/slurp-svg "./resources/icons/delete.svg")
:icons/dots-horizontal (slurp/slurp-svg "./resources/icons/dots_horizontal.svg") :icons/dots-horizontal (slurp/slurp-svg "./resources/icons/dots_horizontal.svg")
:icons/dots-vertical (slurp/slurp-svg "./resources/icons/dots_vertical.svg") :icons/dots-vertical (slurp/slurp-svg "./resources/icons/dots_vertical.svg")
:icons/exclamation_mark (slurp/slurp-svg "./resources/icons/exclamation_mark.svg") :icons/exclamation_mark (slurp/slurp-svg "./resources/icons/exclamation_mark.svg")

View File

@ -25,6 +25,11 @@
(fn [browser] (fn [browser]
(browser-store/save browser))) (browser-store/save browser)))
(re-frame/reg-fx
:remove-browser
(fn [browser-id]
(browser-store/delete browser-id)))
(defn match-url [url] (defn match-url [url]
(str (when (and url (not (re-find #"^[a-zA-Z-_]+:/" url))) "http://") url)) (str (when (and url (not (re-find #"^[a-zA-Z-_]+:/" url))) "http://") url))
@ -77,3 +82,10 @@
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db now] :as cofx} [options]] (fn [{:keys [db now] :as cofx} [options]]
{:db (update db :browser/options merge 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}))

View File

@ -404,3 +404,10 @@
:request-permissions :request-permissions
(fn [_ [_ permissions then else]] (fn [_ [_ permissions then else]]
{::request-permissions-fx [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]]
(-> db
(assoc-in [:chat-animations item-id :delete-swiped] value))))

View File

@ -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)))

View File

@ -3,6 +3,8 @@
(:require [status-im.ui.components.styles :as component.styles] (:require [status-im.ui.components.styles :as component.styles]
[status-im.ui.components.colors :as colors])) [status-im.ui.components.colors :as colors]))
(def delete-button-width 100)
(defn toolbar [] (defn toolbar []
{:background-color colors/white}) {:background-color colors/white})
@ -155,3 +157,17 @@
:width 14 :width 14
:height 9 :height 9
:tint-color :white}) :tint-color :white})
(def delete-icon-highlight
{:position :absolute
:top 0
:bottom 0
:right -800
:width 800
:background-color colors/light-red})
(def delete-icon-container
{:flex 1
:width delete-button-width
:justify-content :center
:align-items :center})

View File

@ -12,6 +12,9 @@
[status-im.ui.components.sync-state.offline :refer [offline-view]] [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.views.inner-item :as inner-item]
[status-im.ui.screens.home.styles :as styles] [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.utils.platform :as platform]))
(defn- toolbar [] (defn- toolbar []
@ -29,14 +32,24 @@
:accessibility-label :plus-button :accessibility-label :plus-button
:on-press #(re-frame/dispatch [:navigate-to :new])}]) :on-press #(re-frame/dispatch [:navigate-to :new])}])
(defn- home-list-item [[home-item-id home-item]] (defn- home-list-deletable [[home-item-id home-item]]
(if (:chat-id home-item) (views/letsubs [swiped? [:delete-swipe-position home-item-id]]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to-chat home-item-id])} (let [delete-action (if (:chat-id home-item) :remove-chat :remove-browser)
[react/view inner-view (if (:chat-id home-item)
[inner-item/home-list-chat-item-inner-view home-item]]] inner-item/home-list-chat-item-inner-view
[react/touchable-highlight {:on-press #(re-frame/dispatch [:open-browser home-item])} inner-item/home-list-browser-item-inner-view)
[react/view offset-x (animation/create-value (if swiped? styles/delete-button-width 0))
[inner-item/home-list-browser-item-inner-view home-item]]])) 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 {:right offset-x}}
[inner-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}]]]]])))
(views/defview home [] (views/defview home []
(views/letsubs [home-items [:home-items]] (views/letsubs [home-items [:home-items]]
@ -44,7 +57,7 @@
[toolbar] [toolbar]
[list/flat-list {:data home-items [list/flat-list {:data home-items
:render-fn (fn [[home-item-id :as home-item]] :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? (when platform/android?
[home-action-button]) [home-action-button])
[offline-view]])) [offline-view]]))

View File

@ -1,8 +1,8 @@
(ns status-im.ui.screens.home.views.inner-item (ns status-im.ui.screens.home.views.inner-item
(:require-macros [status-im.utils.views :refer [defview letsubs]]) (: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.react :as react]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.screens.home.styles :as styles] [status-im.ui.screens.home.styles :as styles]
[status-im.ui.components.styles :as component.styles] [status-im.ui.components.styles :as component.styles]
[status-im.utils.core :as utils] [status-im.utils.core :as utils]
@ -11,6 +11,7 @@
[status-im.utils.datetime :as time] [status-im.utils.datetime :as time]
[status-im.utils.gfycat.core :as gfycat] [status-im.utils.gfycat.core :as gfycat]
[status-im.constants :as const] [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])) [status-im.ui.components.chat-icon.screen :as chat-icon.screen]))
(defn message-content-text [{:keys [content] :as message}] (defn message-content-text [{:keys [content] :as message}]
@ -88,6 +89,7 @@
(letsubs [last-message [:get-last-message chat-id]] (letsubs [last-message [:get-last-message chat-id]]
(let [name (or (i18n/get-contact-translated chat-id :name name) (let [name (or (i18n/get-contact-translated chat-id :name name)
(gfycat/generate-gfy public-key))] (gfycat/generate-gfy public-key))]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to-chat chat-id])}
[react/view styles/chat-container [react/view styles/chat-container
[react/view styles/chat-icon-container [react/view styles/chat-icon-container
[chat-icon.screen/chat-icon-view-chat-list chat-id group-chat name color online]] [chat-icon.screen/chat-icon-view-chat-list chat-id group-chat name color online]]
@ -100,10 +102,11 @@
[message-timestamp last-message]])] [message-timestamp last-message]])]
[react/view styles/item-lower-container [react/view styles/item-lower-container
[message-content-text last-message] [message-content-text last-message]
[unviewed-indicator chat-id]]]]))) [unviewed-indicator chat-id]]]]])))
(defview home-list-browser-item-inner-view [{:keys [browser-id name url dapp? contact] :as browser}] (defview home-list-browser-item-inner-view [{:keys [browser-id name url dapp? contact] :as browser}]
(letsubs [contact' [:contact-by-identity contact]] (letsubs [contact' [:contact-by-identity contact]]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:open-browser browser])}
[react/view styles/chat-container [react/view styles/chat-container
[react/view styles/chat-icon-container [react/view styles/chat-icon-container
(if contact' (if contact'
@ -121,4 +124,4 @@
[react/view styles/last-message-container [react/view styles/last-message-container
[react/text {:style styles/last-message-text [react/text {:style styles/last-message-text
:number-of-lines 1} :number-of-lines 1}
(or url (i18n/label :t/dapp))]]]]])) (or url (i18n/label :t/dapp))]]]]]]))

View File

@ -55,3 +55,8 @@
(reg-sub :get-screen-params (reg-sub :get-screen-params
(fn [db [_ view-id]] (fn [db [_ view-id]]
(get-in db [:navigation/screen-params (or view-id (:view-id db))]))) (get-in db [:navigation/screen-params (or view-id (:view-id db))])))
(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))))