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

@ -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 (exists? browser-id)))

View File

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

View File

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

View File

@ -11,4 +11,5 @@
(def gray-lighter "#eef2f5") ;; Used as a background or shadow
(def blue "#4360df") ;; Used as main wallet color
(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)

View File

@ -47,6 +47,7 @@
:icons/browse (slurp/slurp-svg "./resources/icons/browse.svg")
:icons/close (slurp/slurp-svg "./resources/icons/close.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-vertical (slurp/slurp-svg "./resources/icons/dots_vertical.svg")
:icons/exclamation_mark (slurp/slurp-svg "./resources/icons/exclamation_mark.svg")

View File

@ -25,6 +25,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))
@ -77,3 +82,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}))

View File

@ -404,3 +404,10 @@
: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]]
(-> 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]
[status-im.ui.components.colors :as colors]))
(def delete-button-width 100)
(defn toolbar []
{:background-color colors/white})
@ -155,3 +157,17 @@
:width 14
:height 9
: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.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]))
(defn- toolbar []
@ -29,14 +32,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]]]))
(defn- 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-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 {: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/letsubs [home-items [:home-items]]
@ -44,7 +57,7 @@
[toolbar]
[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]]))

View File

@ -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,40 @@
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/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))]]]]]]))

View File

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