Skip to content

Commit d0ce935

Browse files
authored
Update example (#7)
* Remove useMemo * Add reanimated * Fix babel config for reanimated * Update ProgressBar to use reanimated * Fix calc in ProgressBar * Clean up example * Bump package * Nit
1 parent e38fc2b commit d0ce935

File tree

8 files changed

+120
-67
lines changed

8 files changed

+120
-67
lines changed

example/babel.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ module.exports = {
1313
},
1414
},
1515
],
16+
'react-native-reanimated/plugin',
1617
],
1718
};

example/ios/Podfile.lock

+31
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,33 @@ PODS:
385385
- SDWebImageWebPCoder (~> 0.8.4)
386386
- RNReactNativeHapticFeedback (1.14.0):
387387
- React-Core
388+
- RNReanimated (2.13.0):
389+
- DoubleConversion
390+
- FBLazyVector
391+
- FBReactNativeSpec
392+
- glog
393+
- RCT-Folly
394+
- RCTRequired
395+
- RCTTypeSafety
396+
- React-callinvoker
397+
- React-Core
398+
- React-Core/DevSupport
399+
- React-Core/RCTWebSocket
400+
- React-CoreModules
401+
- React-cxxreact
402+
- React-jsi
403+
- React-jsiexecutor
404+
- React-jsinspector
405+
- React-RCTActionSheet
406+
- React-RCTAnimation
407+
- React-RCTBlob
408+
- React-RCTImage
409+
- React-RCTLinking
410+
- React-RCTNetwork
411+
- React-RCTSettings
412+
- React-RCTText
413+
- ReactCommon/turbomodule/core
414+
- Yoga
388415
- SDWebImage (5.11.1):
389416
- SDWebImage/Core (= 5.11.1)
390417
- SDWebImage/Core (5.11.1)
@@ -458,6 +485,7 @@ DEPENDENCIES:
458485
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
459486
- RNFastImage (from `../node_modules/react-native-fast-image`)
460487
- RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`)
488+
- RNReanimated (from `../node_modules/react-native-reanimated`)
461489
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
462490

463491
SPEC REPOS:
@@ -554,6 +582,8 @@ EXTERNAL SOURCES:
554582
:path: "../node_modules/react-native-fast-image"
555583
RNReactNativeHapticFeedback:
556584
:path: "../node_modules/react-native-haptic-feedback"
585+
RNReanimated:
586+
:path: "../node_modules/react-native-reanimated"
557587
Yoga:
558588
:path: "../node_modules/react-native/ReactCommon/yoga"
559589

@@ -608,6 +638,7 @@ SPEC CHECKSUMS:
608638
ReactCommon: 01064177e66d652192c661de899b1076da962fd9
609639
RNFastImage: 5c9c9fed9c076e521b3f509fe79e790418a544e8
610640
RNReactNativeHapticFeedback: 1e3efeca9628ff9876ee7cdd9edec1b336913f8c
641+
RNReanimated: ce445c233a6ff5600223484a88ad5704945d972a
611642
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
612643
SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d
613644
SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608

example/ios/UseFileUploadExample.xcodeproj/project.pbxproj

-18
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
1313
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
1414
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
15-
244AD18F2908A8C00093BC55 /* hermes.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 244AD18D2908A8B20093BC55 /* hermes.xcframework */; };
16-
244AD1902908A8C00093BC55 /* hermes.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 244AD18D2908A8B20093BC55 /* hermes.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
1715
7699B88040F8A987B510C191 /* libPods-UseFileUploadExample-UseFileUploadExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-UseFileUploadExample-UseFileUploadExampleTests.a */; };
1816
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
1917
/* End PBXBuildFile section */
@@ -28,20 +26,6 @@
2826
};
2927
/* End PBXContainerItemProxy section */
3028

31-
/* Begin PBXCopyFilesBuildPhase section */
32-
244AD1912908A8C00093BC55 /* Embed Frameworks */ = {
33-
isa = PBXCopyFilesBuildPhase;
34-
buildActionMask = 2147483647;
35-
dstPath = "";
36-
dstSubfolderSpec = 10;
37-
files = (
38-
244AD1902908A8C00093BC55 /* hermes.xcframework in Embed Frameworks */,
39-
);
40-
name = "Embed Frameworks";
41-
runOnlyForDeploymentPostprocessing = 0;
42-
};
43-
/* End PBXCopyFilesBuildPhase section */
44-
4529
/* Begin PBXFileReference section */
4630
00E356EE1AD99517003FC87E /* UseFileUploadExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UseFileUploadExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
4731
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -77,7 +61,6 @@
7761
buildActionMask = 2147483647;
7862
files = (
7963
0C80B921A6F3F58F76C31292 /* libPods-UseFileUploadExample.a in Frameworks */,
80-
244AD18F2908A8C00093BC55 /* hermes.xcframework in Frameworks */,
8164
);
8265
runOnlyForDeploymentPostprocessing = 0;
8366
};
@@ -203,7 +186,6 @@
203186
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
204187
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */,
205188
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */,
206-
244AD1912908A8C00093BC55 /* Embed Frameworks */,
207189
);
208190
buildRules = (
209191
);

example/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"react-native-fast-image": "8.6.3",
1616
"react-native-haptic-feedback": "1.14.0",
1717
"react-native-image-picker": "4.10.0",
18+
"react-native-reanimated": "2.13.0",
1819
"react-native-sortable-grid": "https://github.com/rossmartin/react-native-sortable-grid.git#b5c911c263b8c230c4973af00986724bcb234929"
1920
},
2021
"devDependencies": {

example/src/App.tsx

+18-28
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef, useMemo, useState } from 'react';
1+
import React, { useRef, useState } from 'react';
22
import {
33
ActivityIndicator,
44
Animated,
@@ -29,8 +29,7 @@ const hapticFeedbackOptions: HapticOptions = {
2929
interface Item extends UploadItem {
3030
progress?: number;
3131
failed?: boolean; // true on timeout or error
32-
completedAt?: number; // when request is done
33-
startedAt?: number; // when request starts
32+
completed?: boolean;
3433
}
3534

3635
export default function App() {
@@ -42,15 +41,15 @@ export default function App() {
4241
field: 'file',
4342
// optional below
4443
method: 'POST',
45-
timeout: 60000, // you can set this lower to cause timeouts to happen
44+
timeout: 60 * 1000, // you can set this lower to cause timeouts to happen
4645
onProgress,
4746
onDone: ({ item }) => {
4847
updateItem({
4948
item,
5049
keysAndValues: [
5150
{
52-
key: 'completedAt',
53-
value: new Date().getTime(),
51+
key: 'completed',
52+
value: true,
5453
},
5554
],
5655
});
@@ -75,15 +74,12 @@ export default function App() {
7574
},
7675
});
7776

78-
const isUploading = useMemo(() => {
79-
return data.some((item) => {
80-
return (
81-
typeof item.progress === 'number' &&
82-
item.progress > 0 &&
83-
item.progress < 100
84-
);
85-
});
86-
}, [data]);
77+
const isUploading = data.some(
78+
(item) =>
79+
typeof item.progress === 'number' &&
80+
item.progress > 0 &&
81+
item.progress < 100
82+
);
8783

8884
const updateItem = <K extends keyof Item>({
8985
item,
@@ -106,7 +102,7 @@ export default function App() {
106102
});
107103
};
108104

109-
async function onProgress({ item, event }: OnProgressData<Item>) {
105+
function onProgress({ item, event }: OnProgressData<Item>) {
110106
const progress = event?.loaded
111107
? Math.round((event.loaded / event.total) * 100)
112108
: 0;
@@ -133,7 +129,6 @@ export default function App() {
133129
setData((prevState) => [...prevState, ...items]);
134130
};
135131

136-
// :~)
137132
const putItOnTheLine = async (_data: Item[]) => {
138133
const promises = _data
139134
.filter((item) => typeof item.progress !== 'number') // leave out any in progress or completed
@@ -143,13 +138,12 @@ export default function App() {
143138
console.log('result: ', result);
144139
};
145140

146-
const onPressUpload = async () => {
141+
const onPressUpload = () => {
147142
// allow uploading any that previously failed
148143
setData((prevState) => {
149144
const newState = [...prevState].map((item) => ({
150145
...item,
151146
failed: false,
152-
startedAt: new Date().getTime(),
153147
}));
154148

155149
putItOnTheLine(newState);
@@ -172,26 +166,23 @@ export default function App() {
172166
abortUpload(item.uri);
173167
};
174168

175-
const onPressRetry = (item: Item) => async () => {
169+
const onPressRetry = (item: Item) => () => {
176170
updateItem({
177171
item,
178172
keysAndValues: [
179173
{
180174
key: 'failed',
181175
value: false,
182176
},
183-
{
184-
key: 'startedAt',
185-
value: new Date().getTime(),
186-
},
187177
],
188178
});
189-
startUpload({ ...item, startedAt: new Date().getTime() }).catch(() => {});
179+
startUpload({ ...item, failed: false }).catch(() => {});
190180
};
191181

192182
const onDragStart = () => {
193183
ReactNativeHapticFeedback.trigger('impactMedium', hapticFeedbackOptions);
194184
dragStartAnimatedValue.current.setValue(1);
185+
// unable to set useNativeDriver true because of a limitation in react-native-sortable-grid
195186
Animated.loop(
196187
Animated.sequence([
197188
Animated.timing(dragStartAnimatedValue.current, {
@@ -210,6 +201,7 @@ export default function App() {
210201

211202
const onDragRelease = (_itemOrder: ItemOrder) => {
212203
//console.log('onDragRelease, itemOrder: ', _itemOrder);
204+
// you can see where this can go :~)
213205
};
214206

215207
const getDragStartAnimation = () => {
@@ -245,9 +237,7 @@ export default function App() {
245237
<Text style={styles.iconText}>&#x21bb;</Text>
246238
</Pressable>
247239
) : null}
248-
{item.completedAt ? (
249-
<Text style={styles.iconText}>&#10003;</Text>
250-
) : null}
240+
{item.completed ? <Text style={styles.iconText}>&#10003;</Text> : null}
251241
<Pressable style={styles.deleteIcon} onPress={onPressDeleteItem(item)}>
252242
<Text style={styles.deleteIconText}>&#x2717;</Text>
253243
</Pressable>

example/src/components/ProgressBar.tsx

+27-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
import React, { useRef, useEffect } from 'react';
2-
import { Animated, StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
1+
import React, { useState } from 'react';
2+
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
3+
import Animated, {
4+
useAnimatedStyle,
5+
withSpring,
6+
} from 'react-native-reanimated';
37

48
type Props = {
59
value: number;
@@ -12,37 +16,41 @@ export default function ProgressBar({
1216
style,
1317
progressColor = '#3880ff',
1418
}: Props) {
15-
const valueAnimated = useRef(new Animated.Value(0)).current;
16-
const width = valueAnimated.interpolate({
17-
inputRange: [0, 100],
18-
outputRange: ['0%', '100%'],
19-
extrapolate: 'clamp',
20-
});
19+
const [layoutWidth, setLayoutWidth] = useState<number>();
20+
const animatedStyle = useAnimatedStyle(() => {
21+
if (!layoutWidth) {
22+
return { width: 0 };
23+
}
2124

22-
useEffect(() => {
23-
Animated.timing(valueAnimated, {
24-
toValue: value,
25-
duration: 500,
26-
useNativeDriver: false,
27-
}).start();
28-
}, [value, valueAnimated]);
25+
// subtract 2 to account for border
26+
const widthValue = (value / 100) * layoutWidth - 2;
27+
return {
28+
width: withSpring(widthValue, {
29+
overshootClamping: true,
30+
stiffness: 75,
31+
}),
32+
};
33+
}, [layoutWidth, value]);
2934

3035
return (
31-
<View style={[styles.progressBar, style]}>
36+
<View
37+
style={[styles.container, style]}
38+
onLayout={(event) => setLayoutWidth(event.nativeEvent.layout.width)}
39+
>
3240
<Animated.View
3341
style={[
3442
StyleSheet.absoluteFill,
35-
{ backgroundColor: progressColor, width },
43+
animatedStyle,
44+
{ backgroundColor: progressColor },
3645
]}
3746
/>
3847
</View>
3948
);
4049
}
4150

4251
const styles = StyleSheet.create({
43-
progressBar: {
52+
container: {
4453
height: 10,
45-
width: '100%',
4654
backgroundColor: '#fff',
4755
borderColor: '#708090',
4856
borderWidth: 1,

0 commit comments

Comments
 (0)