From 54f7c298b70cd8a725dc2d8f74a95915056773b1 Mon Sep 17 00:00:00 2001
From: Michael Kirk <michael.code@endoftheworl.de>
Date: Tue, 2 Jan 2018 17:29:38 -0600
Subject: [PATCH] Only initiate "show details" pan gesture when swiping back

// FREEBIE
---
 .../ConversationView/Cells/OWSMessageCell.m   |  2 +-
 .../DirectionalPanGestureRecognizer.swift     | 44 ++++++++++++++++---
 2 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m
index 4bb8f4c12..d06523d3d 100644
--- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m
+++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m
@@ -283,7 +283,7 @@ const CGFloat OWSMessageCellCornerRadius = 17;
     [self.textBubbleImageView addGestureRecognizer:textLongPress];
 
     PanDirectionGestureRecognizer *panGesture =
-        [[PanDirectionGestureRecognizer alloc] initWithDirection:PanDirectionHorizontal
+        [[PanDirectionGestureRecognizer alloc] initWithDirection:PanDirectionForward
                                                           target:self
                                                           action:@selector(handlePanGesture:)];
     [self addGestureRecognizer:panGesture];
diff --git a/Signal/src/views/DirectionalPanGestureRecognizer.swift b/Signal/src/views/DirectionalPanGestureRecognizer.swift
index 696a30a87..8e4b3b59d 100644
--- a/Signal/src/views/DirectionalPanGestureRecognizer.swift
+++ b/Signal/src/views/DirectionalPanGestureRecognizer.swift
@@ -1,13 +1,12 @@
 //
-//  Copyright (c) 2017 Open Whisper Systems. All rights reserved.
+//  Copyright (c) 2018 Open Whisper Systems. All rights reserved.
 //
 
 import UIKit.UIGestureRecognizerSubclass
 
 @objc
 enum PanDirection: Int {
-    case vertical
-    case horizontal
+    case forward, backward, up, down, any
 }
 
 @objc
@@ -17,19 +16,50 @@ class PanDirectionGestureRecognizer: UIPanGestureRecognizer {
 
     init(direction: PanDirection, target: AnyObject, action: Selector) {
         self.direction = direction
+
         super.init(target: target, action: action)
     }
 
     override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
+        // Only start gesture if it's initially in the specified direction.
+        if state == .possible {
+            guard let touch = touches.first else {
+                return
+            }
+
+            let previousLocation = touch.previousLocation(in: view)
+            let location = touch.location(in: view)
+            let deltaY = previousLocation.y - location.y
+            let deltaX = previousLocation.x - location.x
+
+            switch direction {
+            case .down where deltaY < 0:
+                return
+            case .up where deltaY > 0:
+                return
+            case .forward where deltaX < 0:
+                return
+            case .backward where deltaX > 0:
+                return
+            default:
+                break
+            }
+        }
+
+        // Gesture was already started, or in the correct direction.
         super.touchesMoved(touches, with: event)
 
         if state == .began {
             let vel = velocity(in: view)
             switch direction {
-            case .horizontal where fabs(vel.y) > fabs(vel.x):
-                state = .cancelled
-            case .vertical where fabs(vel.x) > fabs(vel.y):
-                state = .cancelled
+            case .forward, .backward:
+                if fabs(vel.y) > fabs(vel.x) {
+                    state = .cancelled
+                }
+            case .up, .down:
+                if fabs(vel.x) > fabs(vel.y) {
+                    state = .cancelled
+                }
             default:
                 break
             }