Skip to content

Commit

Permalink
refactor(example): separating components from the app file
Browse files Browse the repository at this point in the history
  • Loading branch information
mateoguzmana committed Oct 6, 2024
1 parent 3dda804 commit 8fdbf79
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 81 deletions.
104 changes: 23 additions & 81 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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;
Expand All @@ -42,18 +29,25 @@ export default function App() {
useState<FileOperationResultExtended>();
const [progress, setProgress] = useState<number | undefined>();

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();
Expand All @@ -70,6 +64,8 @@ export default function App() {
};

const executeCompressFileUsingImageLibrary = async () => {
onReset();

try {
const options: ImageLibraryOptions = {
mediaType: 'photo',
Expand Down Expand Up @@ -108,6 +104,8 @@ export default function App() {
};

const executeCompressFileUsingDocumentPicker = async () => {
onReset();

const [file] = await pick({ copyTo: 'cachesDirectory' });

if (!file || !file.fileCopyUri) return;
Expand All @@ -134,6 +132,8 @@ export default function App() {
};

const executeDecompressFile = async () => {
onReset();

const [file] = await pick({ copyTo: 'cachesDirectory' });

if (!file || !file.fileCopyUri) return;
Expand All @@ -159,8 +159,6 @@ export default function App() {
}
};

console.log('re-render');

return (
<View style={styles.container}>
{versionNumber && (
Expand All @@ -174,14 +172,12 @@ export default function App() {
{fileOperationResult && (
<View style={styles.subContainer}>
{Object.entries(fileOperationResult).map(([key, value]) => (
<Text key={key} style={styles.label}>
{key}: {formatString(value.toString())}
</Text>
<PropertyLabel title={key} value={value} key={key} />
))}
</View>
)}

{progress && <ProgressBar progress={progress} />}
{progress ? <ProgressBar progress={progress} /> : null}

<View style={styles.separator} />

Expand Down Expand Up @@ -210,46 +206,6 @@ export default function App() {
);
}

interface ButtonProps {
title: string;
onPress(): void;
}

function OptionButton({ title, onPress }: ButtonProps) {
return (
<TouchableOpacity onPress={onPress} style={styles.button}>
<Text style={styles.buttonText}>{title}</Text>
</TouchableOpacity>
);
}

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 (
<View style={styles.container}>
<Animated.View style={[styles.progressBar, { width: animatedWidth }]} />
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
Expand All @@ -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)',
},
});
26 changes: 26 additions & 0 deletions example/src/components/OptionButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { StyleSheet, Text, TouchableOpacity } from 'react-native';

interface OptionButtonProps {
title: string;
onPress(): void;
}

export function OptionButton({ title, onPress }: OptionButtonProps) {
return (
<TouchableOpacity onPress={onPress} style={styles.button}>
<Text style={styles.buttonText}>{title}</Text>
</TouchableOpacity>
);
}

const styles = StyleSheet.create({
button: {
backgroundColor: 'transparent',
color: '#2196F3',
margin: 4,
},
buttonText: {
color: '#2196F3',
padding: 10,
},
});
47 changes: 47 additions & 0 deletions example/src/components/ProgressBar.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<View style={styles.progressBarContainer}>
<Animated.View style={[styles.progressBar, { width: animatedWidth }]} />
<Text style={styles.progressBarText}>{progress}%</Text>
</View>
);
}

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',
},
});
32 changes: 32 additions & 0 deletions example/src/components/PropertyLabel.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Text style={styles.label}>
{title}: {formatString(value.toString())}
</Text>
);
}

const styles = StyleSheet.create({
label: {
fontSize: 12,
color: '#333',
padding: 10,
},
});

0 comments on commit 8fdbf79

Please sign in to comment.