Skip to content

Commit 2e21954

Browse files
ieowgrvgoel81
andcommitted
chore(runway): cherry-pick fix: start animate when rive onPlay ( ready ) cp-7.60.0 (#22982)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> * fix: race condition in rive animations when animation fail to start. * Jira: https://consensyssoftware.atlassian.net/browse/SL-332 * Issue: #23048 In some device on edge cases, sometime the MetaMask riv logo does not appear during the onboarding screen animation. This is due to race conditions between state triggers and the rive onPlay state. This PR wait for onPlay state before fire the inputState ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: #23048 * race condition in rive animations when animation fail to start. ## **Manual testing steps** ```gherkin Feature: onboarding Scenario: user open the app after install Given user open the app after install Then user should see the Metamask riv logo ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/834c82d8-9fbf-4c96-943d-1ea067115401 ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/c4bca6d3-3bec-4be8-a68a-882770676ac4 ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Delay animation triggers until Rive reports onPlay, fixing race conditions that caused onboarding/fox animations to not start. > > - **UI** > - `FoxAnimation`: add `isPlaying` state and `onPlay` handler; trigger `fireState('FoxRaiseUp', ...)` only after play starts; remove `autoplay` usage. > - `OnboardingAnimation`: gate `startRiveAnimation` on `isPlaying`; add `onPlay` to set ready state; remove `autoplay` usage. > - **Testing/Mocks** > - Update `app/__mocks__/rive-react-native.tsx` to accept `onPlay` and invoke it on mount for tests. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b36851c. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Gaurav Goel <grvgoel19@gmail.com>
1 parent 099048d commit 2e21954

File tree

3 files changed

+34
-10
lines changed

3 files changed

+34
-10
lines changed

app/__mocks__/rive-react-native.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { forwardRef, useImperativeHandle } from 'react';
1+
import React, { forwardRef, useImperativeHandle, useEffect } from 'react';
22
import { View, ViewProps } from 'react-native';
33

44
export interface RiveRef {
@@ -27,6 +27,7 @@ type MockRiveProps = ViewProps & {
2727
alignment?: string;
2828
autoplay?: boolean;
2929
stateMachineName?: string;
30+
onPlay?: () => void;
3031
};
3132

3233
const DEFAULT_TEST_ID = 'mock-rive-animation';
@@ -48,12 +49,19 @@ const updateLastMockedMethods = (methods: RiveRef) => {
4849
};
4950

5051
const RiveMock = forwardRef<RiveRef, MockRiveProps>(
51-
({ testID = DEFAULT_TEST_ID, mockedMethods, ...viewProps }, ref) => {
52+
({ testID = DEFAULT_TEST_ID, mockedMethods, onPlay, ...viewProps }, ref) => {
5253
const methods = createMockedMethods(mockedMethods);
5354
updateLastMockedMethods(methods);
5455

5556
useImperativeHandle(ref, () => methods, [methods]);
5657

58+
useEffect(() => {
59+
if (onPlay) {
60+
onPlay();
61+
}
62+
// eslint-disable-next-line react-hooks/exhaustive-deps
63+
}, []);
64+
5765
return <View testID={testID} {...viewProps} />;
5866
},
5967
);

app/components/UI/FoxAnimation/FoxAnimation.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useCallback, useEffect, useRef } from 'react';
1+
import React, { useCallback, useEffect, useRef, useState } from 'react';
22
import { StyleSheet, Platform, View } from 'react-native';
33
import Rive, { Alignment, Fit, RiveRef } from 'rive-react-native';
44
import { useSafeAreaInsets, EdgeInsets } from 'react-native-safe-area-context';
@@ -77,6 +77,8 @@ const FoxAnimation = ({
7777
const insets = useSafeAreaInsets();
7878
const styles = createStyles(hasFooter, insets);
7979

80+
const [isPlaying, setIsPlaying] = useState(false);
81+
8082
const showFoxAnimation = useCallback(async () => {
8183
if (foxRef.current && trigger) {
8284
try {
@@ -88,8 +90,10 @@ const FoxAnimation = ({
8890
}, [foxRef, trigger]);
8991

9092
useEffect(() => {
91-
showFoxAnimation();
92-
}, [showFoxAnimation]);
93+
if (isPlaying) {
94+
showFoxAnimation();
95+
}
96+
}, [showFoxAnimation, isPlaying]);
9397

9498
return (
9599
<View style={[styles.foxAnimationWrapper]}>
@@ -99,9 +103,11 @@ const FoxAnimation = ({
99103
source={FoxAnimationRive}
100104
fit={Fit.Contain}
101105
alignment={Alignment.Center}
102-
autoplay={false}
103106
stateMachineName="FoxRaiseUp"
104107
testID="fox-animation"
108+
onPlay={() => {
109+
setIsPlaying(true);
110+
}}
105111
/>
106112
</View>
107113
);

app/components/UI/OnboardingAnimation/OnboardingAnimation.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
1+
import React, {
2+
useCallback,
3+
useEffect,
4+
useMemo,
5+
useRef,
6+
useState,
7+
} from 'react';
28
import { View, Animated, Easing, StyleSheet } from 'react-native';
39
import Rive, { Fit, Alignment, RiveRef } from 'rive-react-native';
410

@@ -67,6 +73,8 @@ const OnboardingAnimation = ({
6773
const { themeAppearance } = useAppThemeFromContext();
6874
const styles = createStyles();
6975

76+
const [isPlaying, setIsPlaying] = useState(false);
77+
7078
const moveLogoUp = useCallback(() => {
7179
Animated.parallel([
7280
Animated.timing(logoPosition, {
@@ -118,10 +126,10 @@ const OnboardingAnimation = ({
118126
]);
119127

120128
useEffect(() => {
121-
if (startOnboardingAnimation) {
129+
if (startOnboardingAnimation && isPlaying) {
122130
startRiveAnimation();
123131
}
124-
}, [startOnboardingAnimation, startRiveAnimation]);
132+
}, [startRiveAnimation, startOnboardingAnimation, isPlaying]);
125133

126134
return (
127135
<>
@@ -141,9 +149,11 @@ const OnboardingAnimation = ({
141149
source={MetaMaskWordmarkAnimation}
142150
fit={Fit.Contain}
143151
alignment={Alignment.Center}
144-
autoplay={false}
145152
stateMachineName="WordmarkBuildUp"
146153
testID="metamask-wordmark-animation"
154+
onPlay={() => {
155+
setIsPlaying(true);
156+
}}
147157
/>
148158
</Animated.View>
149159
</View>

0 commit comments

Comments
 (0)