From 8fdbf79170657580f91113e90c767ed96ea8d0c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Guzm=C3=A1n?= Date: Sun, 6 Oct 2024 18:02:33 +0200 Subject: [PATCH] refactor(example): separating components from the app file --- example/src/App.tsx | 104 +++++------------------ example/src/components/OptionButton.tsx | 26 ++++++ example/src/components/ProgressBar.tsx | 47 ++++++++++ example/src/components/PropertyLabel.tsx | 32 +++++++ 4 files changed, 128 insertions(+), 81 deletions(-) create mode 100644 example/src/components/OptionButton.tsx create mode 100644 example/src/components/ProgressBar.tsx create mode 100644 example/src/components/PropertyLabel.tsx diff --git a/example/src/App.tsx b/example/src/App.tsx index 9d604f5..a8e27cf 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,11 +1,5 @@ -import { useEffect, useRef, useState } from 'react'; -import { - StyleSheet, - View, - Text, - TouchableOpacity, - Animated, -} from 'react-native'; +import { useState } from 'react'; +import { StyleSheet, View, Text } from 'react-native'; import { compressFile, decompressFile, @@ -18,16 +12,9 @@ import { type ImageLibraryOptions, } from 'react-native-image-picker'; import { pick } from 'react-native-document-picker'; - -const MAX_STRING_LENGTH = 50; - -const formatString = (value: string) => { - return value.length > MAX_STRING_LENGTH - ? value.slice(0, MAX_STRING_LENGTH) + - '...' + - value.slice(-MAX_STRING_LENGTH) - : value; -}; +import { ProgressBar } from './components/ProgressBar'; +import { OptionButton } from './components/OptionButton'; +import { PropertyLabel } from './components/PropertyLabel'; interface FileOperationResultExtended extends FileOperationResult { sourcePath: string; @@ -42,18 +29,25 @@ export default function App() { useState(); const [progress, setProgress] = useState(); + const onReset = () => { + setProgress(undefined); + setFileOperationResult(undefined); + }; + /** * Example of a callback function that is called with the progress of the operation. * @param processedSize * @param totalSize */ - function onProgress(processedSize: number, totalSize: number) { + const onProgress = (processedSize: number, totalSize: number) => { const _progress = Math.round((processedSize / totalSize) * 100); - if (_progress % 50 === 0) { + // doing it in intervals of 10% to avoid unnecessary re-renders. + // it would be more efficient to have this progress in a ref and using reanimated to animate the progress + if (_progress % 10 === 0) { setProgress(_progress); } - } + }; const executeGetLz4VersionNumber = async () => { const _versionNumber = await getLz4VersionNumber(); @@ -70,6 +64,8 @@ export default function App() { }; const executeCompressFileUsingImageLibrary = async () => { + onReset(); + try { const options: ImageLibraryOptions = { mediaType: 'photo', @@ -108,6 +104,8 @@ export default function App() { }; const executeCompressFileUsingDocumentPicker = async () => { + onReset(); + const [file] = await pick({ copyTo: 'cachesDirectory' }); if (!file || !file.fileCopyUri) return; @@ -134,6 +132,8 @@ export default function App() { }; const executeDecompressFile = async () => { + onReset(); + const [file] = await pick({ copyTo: 'cachesDirectory' }); if (!file || !file.fileCopyUri) return; @@ -159,8 +159,6 @@ export default function App() { } }; - console.log('re-render'); - return ( {versionNumber && ( @@ -174,14 +172,12 @@ export default function App() { {fileOperationResult && ( {Object.entries(fileOperationResult).map(([key, value]) => ( - - {key}: {formatString(value.toString())} - + ))} )} - {progress && } + {progress ? : null} @@ -210,46 +206,6 @@ export default function App() { ); } -interface ButtonProps { - title: string; - onPress(): void; -} - -function OptionButton({ title, onPress }: ButtonProps) { - return ( - - {title} - - ); -} - -interface ProgressBarProps { - progress: number; -} - -function ProgressBar({ progress }: ProgressBarProps) { - const progressAnim = useRef(new Animated.Value(0)).current; - - useEffect(() => { - Animated.timing(progressAnim, { - toValue: progress, // final value for the progress - duration: 500, // animation duration in ms - useNativeDriver: false, // native driver should be false for width animation - }).start(); - }, [progress, progressAnim]); - - const animatedWidth = progressAnim.interpolate({ - inputRange: [0, 100], - outputRange: ['0%', '100%'], // percentage for width based on progress - }); - - return ( - - - - ); -} - const styles = StyleSheet.create({ container: { flex: 1, @@ -265,24 +221,10 @@ const styles = StyleSheet.create({ color: '#333', padding: 10, }, - button: { - backgroundColor: 'transparent', - color: '#2196F3', - margin: 4, - }, - buttonText: { - color: '#2196F3', - padding: 10, - }, separator: { marginVertical: 10, height: 1, width: '100%', backgroundColor: 'rgba(0, 0, 0, 0.1)', }, - progressBar: { - height: 10, - width: '100%', - backgroundColor: 'rgba(0, 0, 0, 0.1)', - }, }); diff --git a/example/src/components/OptionButton.tsx b/example/src/components/OptionButton.tsx new file mode 100644 index 0000000..40b4b19 --- /dev/null +++ b/example/src/components/OptionButton.tsx @@ -0,0 +1,26 @@ +import { StyleSheet, Text, TouchableOpacity } from 'react-native'; + +interface OptionButtonProps { + title: string; + onPress(): void; +} + +export function OptionButton({ title, onPress }: OptionButtonProps) { + return ( + + {title} + + ); +} + +const styles = StyleSheet.create({ + button: { + backgroundColor: 'transparent', + color: '#2196F3', + margin: 4, + }, + buttonText: { + color: '#2196F3', + padding: 10, + }, +}); diff --git a/example/src/components/ProgressBar.tsx b/example/src/components/ProgressBar.tsx new file mode 100644 index 0000000..fc8b289 --- /dev/null +++ b/example/src/components/ProgressBar.tsx @@ -0,0 +1,47 @@ +import { useEffect, useRef } from 'react'; +import { StyleSheet, View, Text, Animated } from 'react-native'; + +interface ProgressBarProps { + progress: number; +} + +export function ProgressBar({ progress }: ProgressBarProps) { + const progressAnim = useRef(new Animated.Value(0)).current; + + useEffect(() => { + Animated.timing(progressAnim, { + toValue: progress, + duration: 500, + useNativeDriver: false, + }).start(); + }, [progress, progressAnim]); + + const animatedWidth = progressAnim.interpolate({ + inputRange: [0, 100], + outputRange: ['0%', '100%'], + }); + + return ( + + + {progress}% + + ); +} + +const styles = StyleSheet.create({ + progressBarContainer: { + marginHorizontal: 10, + }, + progressBar: { + height: 10, + width: '100%', + backgroundColor: 'rgba(5, 171, 55, 0.555)', + alignSelf: 'center', + borderRadius: 10, + }, + progressBarText: { + color: '#333', + textAlign: 'center', + }, +}); diff --git a/example/src/components/PropertyLabel.tsx b/example/src/components/PropertyLabel.tsx new file mode 100644 index 0000000..332c103 --- /dev/null +++ b/example/src/components/PropertyLabel.tsx @@ -0,0 +1,32 @@ +import { StyleSheet, Text } from 'react-native'; + +const MAX_STRING_LENGTH = 50; + +const formatString = (value: string) => { + return value.length > MAX_STRING_LENGTH + ? value.slice(0, MAX_STRING_LENGTH) + + '...' + + value.slice(-MAX_STRING_LENGTH) + : value; +}; + +interface PropertyLabelProps { + title: string; + value: string | number; +} + +export function PropertyLabel({ title, value }: PropertyLabelProps) { + return ( + + {title}: {formatString(value.toString())} + + ); +} + +const styles = StyleSheet.create({ + label: { + fontSize: 12, + color: '#333', + padding: 10, + }, +});