Skip to content

Commit

Permalink
Merge pull request #35232 from software-mansion-labs/clamp-improve
Browse files Browse the repository at this point in the history
Pare back the parallax animation on empty chats
  • Loading branch information
roryabraham authored Feb 5, 2024
2 parents 51f0a00 + ee64a29 commit 54c438d
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 30 deletions.
4 changes: 3 additions & 1 deletion src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ const CONST = {
IN: 'in',
OUT: 'out',
},
// Multiplier for gyroscope animation in order to make it a bit more subtle
ANIMATION_GYROSCOPE_VALUE: 0.4,
BACKGROUND_IMAGE_TRANSITION_DURATION: 1000,
ARROW_HIDE_DELAY: 3000,

Expand Down Expand Up @@ -150,7 +152,7 @@ const CONST = {
CONTAINER_MINHEIGHT: 500,
VIEW_HEIGHT: 275,
},
MONEY_REPORT: {
MONEY_OR_TASK_REPORT: {
SMALL_SCREEN: {
IMAGE_HEIGHT: 300,
CONTAINER_MINHEIGHT: 280,
Expand Down
14 changes: 1 addition & 13 deletions src/libs/NumberUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,6 @@ function generateHexadecimalValue(num: number): string {
return result.join('').toUpperCase();
}

/**
* Clamp a number in a range.
* This is a worklet so it should be used only from UI thread.
* @returns clamped value between min and max
*/
function clampWorklet(num: number, min: number, max: number): number {
'worklet';

return Math.min(Math.max(num, min), max);
}

/**
* Generates a random integer between a and b
* It's and equivalent of _.random(a, b)
Expand All @@ -81,4 +69,4 @@ function parseFloatAnyLocale(value: string): number {
return parseFloat(value ? value.replace(',', '.') : value);
}

export {rand64, generateHexadecimalValue, generateRandomInt, clampWorklet, parseFloatAnyLocale};
export {rand64, generateHexadecimalValue, generateRandomInt, parseFloatAnyLocale};
12 changes: 6 additions & 6 deletions src/pages/home/report/AnimatedEmptyStateBackground.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React from 'react';
import Animated, {SensorType, useAnimatedSensor, useAnimatedStyle, useSharedValue, withSpring} from 'react-native-reanimated';
import Animated, {clamp, SensorType, useAnimatedSensor, useAnimatedStyle, useReducedMotion, useSharedValue, withSpring} from 'react-native-reanimated';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeIllustrations from '@hooks/useThemeIllustrations';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as NumberUtils from '@libs/NumberUtils';
import variables from '@styles/variables';
import CONST from '@src/CONST';

Expand All @@ -22,10 +21,11 @@ function AnimatedEmptyStateBackground() {
const animatedSensor = useAnimatedSensor(SensorType.GYROSCOPE);
const xOffset = useSharedValue(0);
const yOffset = useSharedValue(0);
const isReducedMotionEnabled = useReducedMotion();

// Apply data to create style object
const animatedStyles = useAnimatedStyle(() => {
if (!isSmallScreenWidth) {
if (!isSmallScreenWidth || isReducedMotionEnabled) {
return {};
}
/*
Expand All @@ -34,12 +34,12 @@ function AnimatedEmptyStateBackground() {
*/
const {x, y} = animatedSensor.sensor.value;
// The x vs y here seems wrong but is the way to make it feel right to the user
xOffset.value = NumberUtils.clampWorklet(xOffset.value + y, -IMAGE_OFFSET_X, IMAGE_OFFSET_X);
yOffset.value = NumberUtils.clampWorklet(yOffset.value - x, -IMAGE_OFFSET_Y, IMAGE_OFFSET_Y);
xOffset.value = clamp(xOffset.value + y * CONST.ANIMATION_GYROSCOPE_VALUE, -IMAGE_OFFSET_X, IMAGE_OFFSET_X);
yOffset.value = clamp(yOffset.value - x * CONST.ANIMATION_GYROSCOPE_VALUE, -IMAGE_OFFSET_Y, IMAGE_OFFSET_Y);
return {
transform: [{translateX: withSpring(-IMAGE_OFFSET_X - xOffset.value)}, {translateY: withSpring(yOffset.value)}],
};
}, []);
}, [isReducedMotionEnabled]);

return (
<Animated.Image
Expand Down
8 changes: 4 additions & 4 deletions src/pages/home/report/ReportActionItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ function ReportActionItem(props) {
if (ReportUtils.isTaskReport(props.report)) {
if (ReportUtils.isCanceledTaskReport(props.report, parentReportAction)) {
return (
<>
<View style={[StyleUtils.getReportWelcomeContainerStyle(props.isSmallScreenWidth, true)]}>
<AnimatedEmptyStateBackground />
<View style={[StyleUtils.getReportWelcomeTopMarginStyle(props.isSmallScreenWidth)]}>
<ReportActionItemSingle
Expand All @@ -639,19 +639,19 @@ function ReportActionItem(props) {
</ReportActionItemSingle>
<View style={styles.reportHorizontalRule} />
</View>
</>
</View>
);
}
return (
<>
<View style={[StyleUtils.getReportWelcomeContainerStyle(props.isSmallScreenWidth, true)]}>
<AnimatedEmptyStateBackground />
<View style={[StyleUtils.getReportWelcomeTopMarginStyle(props.isSmallScreenWidth)]}>
<TaskView
report={props.report}
shouldShowHorizontalRule={!props.shouldHideThreadDividerLine}
/>
</View>
</>
</View>
);
}
if (ReportUtils.isExpenseReport(props.report) || ReportUtils.isIOUReport(props.report)) {
Expand Down
12 changes: 6 additions & 6 deletions src/styles/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -699,8 +699,8 @@ function getHorizontalStackedOverlayAvatarStyle(oneAvatarSize: AvatarSize, oneAv
/**
* Gets the correct size for the empty state background image based on screen dimensions
*/
function getReportWelcomeBackgroundImageStyle(isSmallScreenWidth: boolean, isMoneyReport = false): ImageStyle {
const emptyStateBackground = isMoneyReport ? CONST.EMPTY_STATE_BACKGROUND.MONEY_REPORT : CONST.EMPTY_STATE_BACKGROUND;
function getReportWelcomeBackgroundImageStyle(isSmallScreenWidth: boolean, isMoneyOrTaskReport = false): ImageStyle {
const emptyStateBackground = isMoneyOrTaskReport ? CONST.EMPTY_STATE_BACKGROUND.MONEY_OR_TASK_REPORT : CONST.EMPTY_STATE_BACKGROUND;

if (isSmallScreenWidth) {
return {
Expand All @@ -720,8 +720,8 @@ function getReportWelcomeBackgroundImageStyle(isSmallScreenWidth: boolean, isMon
/**
* Gets the correct top margin size for the chat welcome message based on screen dimensions
*/
function getReportWelcomeTopMarginStyle(isSmallScreenWidth: boolean, isMoneyReport = false): ViewStyle {
const emptyStateBackground = isMoneyReport ? CONST.EMPTY_STATE_BACKGROUND.MONEY_REPORT : CONST.EMPTY_STATE_BACKGROUND;
function getReportWelcomeTopMarginStyle(isSmallScreenWidth: boolean, isMoneyOrTaskReport = false): ViewStyle {
const emptyStateBackground = isMoneyOrTaskReport ? CONST.EMPTY_STATE_BACKGROUND.MONEY_OR_TASK_REPORT : CONST.EMPTY_STATE_BACKGROUND;
if (isSmallScreenWidth) {
return {
marginTop: emptyStateBackground.SMALL_SCREEN.VIEW_HEIGHT,
Expand Down Expand Up @@ -754,8 +754,8 @@ function getLineHeightStyle(lineHeight: number): TextStyle {
/**
* Gets the correct size for the empty state container based on screen dimensions
*/
function getReportWelcomeContainerStyle(isSmallScreenWidth: boolean, isMoneyReport = false): ViewStyle {
const emptyStateBackground = isMoneyReport ? CONST.EMPTY_STATE_BACKGROUND.MONEY_REPORT : CONST.EMPTY_STATE_BACKGROUND;
function getReportWelcomeContainerStyle(isSmallScreenWidth: boolean, isMoneyOrTaskReport = false): ViewStyle {
const emptyStateBackground = isMoneyOrTaskReport ? CONST.EMPTY_STATE_BACKGROUND.MONEY_OR_TASK_REPORT : CONST.EMPTY_STATE_BACKGROUND;
if (isSmallScreenWidth) {
return {
minHeight: emptyStateBackground.SMALL_SCREEN.CONTAINER_MINHEIGHT,
Expand Down
1 change: 1 addition & 0 deletions tests/ui/UnreadIndicatorsTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jest.mock('react-native/Libraries/LogBox/LogBox', () => ({
jest.mock('react-native-reanimated', () => ({
...jest.requireActual('react-native-reanimated/mock'),
createAnimatedPropAdapter: jest.fn,
useReducedMotion: jest.fn,
}));

/**
Expand Down

0 comments on commit 54c438d

Please sign in to comment.