mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 13:37:11 +00:00
Fix various flakey tests.
This commit is contained in:
parent
d2d3b28dc7
commit
4996137006
@ -31,42 +31,7 @@ struct SwipeRightAction<Label: View>: ViewModifier {
|
||||
content
|
||||
.offset(x: xOffset, y: 0.0)
|
||||
.animation(.interactiveSpring().speed(0.5), value: xOffset)
|
||||
.gesture(DragGesture()
|
||||
.updating($dragGestureActive) { _, state, _ in
|
||||
// Available actions should be computed on the fly so we use a gesture state change
|
||||
// to ask whether the move should be started or not.
|
||||
state = true
|
||||
}
|
||||
.onChanged { value in
|
||||
guard canStartAction else {
|
||||
return
|
||||
}
|
||||
|
||||
// We want to add a spring like behavior to the drag in which the view
|
||||
// moves slower the more it's dragged. We use a circular easing function
|
||||
// to generate those values up to the `swipeThreshold`
|
||||
// The final translation will be between 0 and `swipeThreshold` with the action being enabled from
|
||||
// `actionThreshold` onwards
|
||||
let screenWidthNormalisedTranslation = max(0.0, min(value.translation.width, swipeThreshold)) / swipeThreshold
|
||||
let easedTranslation = circularEaseOut(screenWidthNormalisedTranslation)
|
||||
xOffset = easedTranslation * xOffsetThreshold
|
||||
|
||||
if xOffset > actionThreshold {
|
||||
if !hasReachedActionThreshold {
|
||||
feedbackGenerator.impactOccurred()
|
||||
hasReachedActionThreshold = true
|
||||
}
|
||||
} else {
|
||||
hasReachedActionThreshold = false
|
||||
}
|
||||
}
|
||||
.onEnded { _ in
|
||||
if xOffset > actionThreshold {
|
||||
action()
|
||||
}
|
||||
|
||||
xOffset = 0.0
|
||||
})
|
||||
.simultaneousGesture(gesture)
|
||||
.onChange(of: dragGestureActive) { value in
|
||||
if value == true {
|
||||
if shouldStartAction() {
|
||||
@ -86,6 +51,55 @@ struct SwipeRightAction<Label: View>: ViewModifier {
|
||||
}
|
||||
}
|
||||
|
||||
private var gesture: some Gesture {
|
||||
DragGesture()
|
||||
.updating($dragGestureActive) { _, state, _ in
|
||||
// Available actions should be computed on the fly so we use a gesture state change
|
||||
// to ask whether the move should be started or not.
|
||||
state = true
|
||||
}
|
||||
.onChanged { value in
|
||||
guard canStartAction, value.translation.width > value.translation.height else {
|
||||
return
|
||||
}
|
||||
|
||||
// Due to https://forums.developer.apple.com/forums/thread/760035 we had to make
|
||||
// the drag a simultaneous gesture otherwise it was impossible to scroll the timeline.
|
||||
// Therefore we need to prevent the animation to run if the user is to scrolling vertically.
|
||||
// It would be nice if we could somehow abort the gesture in this case.
|
||||
let width: CGFloat = if value.translation.width > abs(value.translation.height) {
|
||||
value.translation.width
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
|
||||
// We want to add a spring like behaviour to the drag in which the view
|
||||
// moves slower the more it's dragged. We use a circular easing function
|
||||
// to generate those values up to the `swipeThreshold`
|
||||
// The final translation will be between 0 and `swipeThreshold` with the action being enabled from
|
||||
// `actionThreshold` onwards
|
||||
let screenWidthNormalisedTranslation = max(0.0, min(width, swipeThreshold)) / swipeThreshold
|
||||
let easedTranslation = circularEaseOut(screenWidthNormalisedTranslation)
|
||||
xOffset = easedTranslation * xOffsetThreshold
|
||||
|
||||
if xOffset > actionThreshold {
|
||||
if !hasReachedActionThreshold {
|
||||
feedbackGenerator.impactOccurred()
|
||||
hasReachedActionThreshold = true
|
||||
}
|
||||
} else {
|
||||
hasReachedActionThreshold = false
|
||||
}
|
||||
}
|
||||
.onEnded { _ in
|
||||
if xOffset > actionThreshold {
|
||||
action()
|
||||
}
|
||||
|
||||
xOffset = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to compute the horizontal translation amount.
|
||||
/// The more it's dragged the less it moves on a circular ease out curve
|
||||
private func circularEaseOut(_ value: Double) -> Double {
|
||||
|
@ -379,6 +379,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
return
|
||||
}
|
||||
await self?.updatePinnedEventIDs()
|
||||
await self?.updatePermissions()
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
BIN
UITests/Sources/__Snapshots__/Application/roomLayoutBottom-0-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/roomLayoutBottom-0-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/roomLayoutBottom-1-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/roomLayoutBottom-1-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/roomLayoutHighlight-0-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/roomLayoutHighlight-0-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/roomLayoutTop-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/roomLayoutTop-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/roomPlainNoAvatar-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/roomPlainNoAvatar-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/roomSmallTimeline-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/roomSmallTimeline-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/roomSmallTimelineLargePagination-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/roomSmallTimelineLargePagination-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/roomSmallTimelineWithReadReceipts-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/roomSmallTimelineWithReadReceipts-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/roomWithDisclosedPolls-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/roomWithDisclosedPolls-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/roomWithOutgoingPolls-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/roomWithOutgoingPolls-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/roomWithUndisclosedPolls-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/roomWithUndisclosedPolls-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/userSessionScreen-1-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/userSessionScreen-1-iPhone-16-en-GB.UI.png
(Stored with Git LFS)
Binary file not shown.
@ -380,10 +380,13 @@ class TimelineViewModelTests: XCTestCase {
|
||||
|
||||
func testPinnedEvents() async throws {
|
||||
ServiceLocator.shared.settings.pinningEnabled = true
|
||||
|
||||
// Note: We need to start the test with a non-default value so we know the view model has finished the Task.
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(name: "",
|
||||
pinnedEventIDs: .init(["test1"])))
|
||||
let actionsSubject = PassthroughSubject<JoinedRoomProxyAction, Never>()
|
||||
roomProxyMock.underlyingActionsPublisher = actionsSubject.eraseToAnyPublisher()
|
||||
|
||||
let viewModel = TimelineViewModel(roomProxy: roomProxyMock,
|
||||
timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
@ -409,9 +412,12 @@ class TimelineViewModelTests: XCTestCase {
|
||||
|
||||
func testCanUserPinEvents() async throws {
|
||||
ServiceLocator.shared.settings.pinningEnabled = true
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(name: "", canUserPin: false))
|
||||
|
||||
// Note: We need to start the test with the non-default value so we know the view model has finished the Task.
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(name: "", canUserPin: true))
|
||||
let actionsSubject = PassthroughSubject<JoinedRoomProxyAction, Never>()
|
||||
roomProxyMock.underlyingActionsPublisher = actionsSubject.eraseToAnyPublisher()
|
||||
|
||||
let viewModel = TimelineViewModel(roomProxy: roomProxyMock,
|
||||
timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
@ -423,13 +429,13 @@ class TimelineViewModelTests: XCTestCase {
|
||||
analyticsService: ServiceLocator.shared.analytics)
|
||||
|
||||
var deferred = deferFulfillment(viewModel.context.$viewState) { value in
|
||||
!value.canCurrentUserPin
|
||||
value.canCurrentUserPin
|
||||
}
|
||||
try await deferred.fulfill()
|
||||
|
||||
roomProxyMock.canUserPinOrUnpinUserIDReturnValue = .success(true)
|
||||
roomProxyMock.canUserPinOrUnpinUserIDReturnValue = .success(false)
|
||||
deferred = deferFulfillment(viewModel.context.$viewState) { value in
|
||||
value.canCurrentUserPin
|
||||
!value.canCurrentUserPin
|
||||
}
|
||||
actionsSubject.send(.roomInfoUpdate)
|
||||
try await deferred.fulfill()
|
||||
|
Loading…
x
Reference in New Issue
Block a user