mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
aabf656d89
Updated the config message generation for GRDB Migrated more preferences into GRDB Added paging to the MediaTileViewController and sorted out the various animations/transitions Fixed an issue where the 'recipientState' for the 'baseQuery' on the ConversationCell.ViewModel wasn't grouping correctly Fixed an issue where the MediaZoomAnimationController could fail if the contextual info wasn't available Fixed an issue where the MediaZoomAnimationController bounce looked odd when returning to the detail screen from the tile screen Fixed an issue where the MediaZoomAnimationController didn't work for videos Fixed a bug where the YDB to GRDB migration wasn't properly handling video files Fixed a number of minor UI bugs with the GalleryRailView Deleted a bunch of legacy code
126 lines
4.5 KiB
Swift
126 lines
4.5 KiB
Swift
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
|
|
|
import UIKit
|
|
|
|
// MARK: - InteractivelyDismissableViewController
|
|
|
|
protocol InteractivelyDismissableViewController: UIViewController {
|
|
func performInteractiveDismissal(animated: Bool)
|
|
}
|
|
|
|
// MARK: - InteractiveDismissDelegate
|
|
|
|
protocol InteractiveDismissDelegate: AnyObject {
|
|
func interactiveDismissUpdate(_ interactiveDismiss: UIPercentDrivenInteractiveTransition, didChangeTouchOffset offset: CGPoint)
|
|
func interactiveDismissDidFinish(_ interactiveDismiss: UIPercentDrivenInteractiveTransition)
|
|
}
|
|
|
|
// MARK: - MediaInteractiveDismiss
|
|
|
|
class MediaInteractiveDismiss: UIPercentDrivenInteractiveTransition {
|
|
var interactionInProgress = false
|
|
|
|
weak var interactiveDismissDelegate: InteractiveDismissDelegate?
|
|
private weak var targetViewController: InteractivelyDismissableViewController?
|
|
|
|
init(targetViewController: InteractivelyDismissableViewController) {
|
|
super.init()
|
|
|
|
self.targetViewController = targetViewController
|
|
}
|
|
|
|
public func addGestureRecognizer(to view: UIView) {
|
|
let gesture: DirectionalPanGestureRecognizer = DirectionalPanGestureRecognizer(direction: .vertical, target: self, action: #selector(handleGesture(_:)))
|
|
|
|
// Allow panning with trackpad
|
|
if #available(iOS 13.4, *) { gesture.allowedScrollTypesMask = .continuous }
|
|
|
|
view.addGestureRecognizer(gesture)
|
|
}
|
|
|
|
// MARK: - Private
|
|
|
|
private var fastEnoughToCompleteTransition = false
|
|
private var farEnoughToCompleteTransition = false
|
|
private var lastProgress: CGFloat = 0
|
|
private var lastIncreasedProgress: CGFloat = 0
|
|
|
|
private var shouldCompleteTransition: Bool {
|
|
if farEnoughToCompleteTransition { return true }
|
|
if fastEnoughToCompleteTransition { return true }
|
|
|
|
return false
|
|
}
|
|
|
|
@objc private func handleGesture(_ gestureRecognizer: UIScreenEdgePanGestureRecognizer) {
|
|
guard let coordinateSpace = gestureRecognizer.view?.superview else { return }
|
|
|
|
if case .began = gestureRecognizer.state {
|
|
gestureRecognizer.setTranslation(.zero, in: coordinateSpace)
|
|
}
|
|
|
|
let totalDistance: CGFloat = 100
|
|
let velocityThreshold: CGFloat = 500
|
|
|
|
switch gestureRecognizer.state {
|
|
case .began:
|
|
interactionInProgress = true
|
|
targetViewController?.performInteractiveDismissal(animated: true)
|
|
|
|
case .changed:
|
|
let velocity = abs(gestureRecognizer.velocity(in: coordinateSpace).y)
|
|
if velocity > velocityThreshold {
|
|
fastEnoughToCompleteTransition = true
|
|
}
|
|
|
|
let offset = gestureRecognizer.translation(in: coordinateSpace)
|
|
let progress = abs(offset.y) / totalDistance
|
|
|
|
// `farEnoughToCompleteTransition` is cancelable if the user reverses direction
|
|
farEnoughToCompleteTransition = (progress >= 0.5)
|
|
|
|
// If the user has reverted enough progress then we want to reset the velocity
|
|
// flag (don't want the user to start quickly, slowly drag it back end end up
|
|
// dismissing the screen)
|
|
if (lastIncreasedProgress - progress) > 0.2 || progress < 0.05 {
|
|
fastEnoughToCompleteTransition = false
|
|
}
|
|
|
|
update(progress)
|
|
|
|
lastIncreasedProgress = (progress > lastProgress ? progress : lastIncreasedProgress)
|
|
lastProgress = progress
|
|
|
|
interactiveDismissDelegate?.interactiveDismissUpdate(self, didChangeTouchOffset: offset)
|
|
|
|
case .cancelled:
|
|
interactiveDismissDelegate?.interactiveDismissDidFinish(self)
|
|
cancel()
|
|
|
|
interactionInProgress = false
|
|
farEnoughToCompleteTransition = false
|
|
fastEnoughToCompleteTransition = false
|
|
lastIncreasedProgress = 0
|
|
lastProgress = 0
|
|
|
|
case .ended:
|
|
if shouldCompleteTransition {
|
|
finish()
|
|
}
|
|
else {
|
|
cancel()
|
|
}
|
|
|
|
interactiveDismissDelegate?.interactiveDismissDidFinish(self)
|
|
|
|
interactionInProgress = false
|
|
farEnoughToCompleteTransition = false
|
|
fastEnoughToCompleteTransition = false
|
|
lastIncreasedProgress = 0
|
|
lastProgress = 0
|
|
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
}
|