diff --git a/App.js b/App.js
index 09f879b..b1ae993 100644
--- a/App.js
+++ b/App.js
@@ -1,10 +1,69 @@
import { StatusBar } from 'expo-status-bar';
-import { StyleSheet, Text, View } from 'react-native';
+import { StyleSheet, Text, View, Image } from 'react-native';
+import { useState } from 'react';
+import * as ImagePicker from 'expo-image-picker';
+
+import ImageViewer from './components/ImageViewer';
+import Button from './components/Button';
+import CircleButton from './components/CircleButton';
+import IconButton from './components/IconButton';
+import Picker from './components/Picker';
+
+const backgroundImage = require('./assets/images/background-image.png')
export default function App() {
+ const [selectedImage, setSelectedImage] = useState(null);
+ const [showAppOptions, setShowAppOptions] = useState(false);
+ const [isModalVisible, setIsModalVisible] = useState(false);
+
+ const pickImageAsync = async () => {
+ let result = await ImagePicker.launchImageLibraryAsync({
+ allowsEditing: true,
+ quality: 1,
+ });
+
+ if (!result.canceled) {
+ setSelectedImage(result.assets[0].uri);
+ setShowAppOptions(true);
+ } else {
+ alert('You did not select any image.');
+ }
+ };
+ const onReset = () => {
+ setShowAppOptions(false);
+ };
+ const onAddSticker = () => {
+ setIsModalVisible(true);
+ };
+ const onModalClose = () => {
+ setIsModalVisible(false);
+ };
+ const onSaveImageAsync = async () => {
+ // we will implement this later
+ };
+
return (
- Open up App.js to start working on your app!
+
+
+
+ {showAppOptions ? (
+
+
+
+
+
+
+
+ ) : (
+
+
+
+ )}
+
+ {/* A list of emoji component will go here */}
+
);
@@ -13,8 +72,25 @@ export default function App() {
const styles = StyleSheet.create({
container: {
flex: 1,
- backgroundColor: '#fff',
+ backgroundColor: '#e9ffdb',
alignItems: 'center',
- justifyContent: 'center',
+ justifyContent: 'center'
},
+ imageContainer: {
+ flex: 1,
+ paddingTop: 59
+ },
+ buttonContainer: {
+ flex: 1 / 3,
+ alignItems: 'center',
+ rowGap: 10
+ },
+ optionsContainer: {
+ position: 'absolute',
+ bottom: 80,
+ },
+ optionsRow: {
+ alignItems: 'center',
+ flexDirection: 'row',
+ }
});
diff --git a/components/Button.js b/components/Button.js
new file mode 100644
index 0000000..9183835
--- /dev/null
+++ b/components/Button.js
@@ -0,0 +1,48 @@
+import { StyleSheet, View, Pressable, Text } from 'react-native';
+import FontAwesome from "@expo/vector-icons/FontAwesome";
+
+export default function Button({ label, override, onPress }) {
+ if (override) {
+ return (
+
+
+
+ {label}
+
+
+ );
+ } else {
+ return (
+
+
+ {label}
+
+
+ );
+ }
+}
+
+const styles = StyleSheet.create({
+ buttonContainer: {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ width: 320,
+ height: 68,
+ marginHorizontal: 20,
+ alignItems: 'center',
+ justifyContent: 'center',
+ padding: 3,
+ backgroundColor: '#E3F988',
+ borderRadius: 80
+ },
+ buttonIcon: {
+ position: 'absolute',
+ marginLeft: -30
+ }
+});
\ No newline at end of file
diff --git a/components/CircleButton.js b/components/CircleButton.js
new file mode 100644
index 0000000..d4a899f
--- /dev/null
+++ b/components/CircleButton.js
@@ -0,0 +1,31 @@
+import { View, Pressable, StyleSheet } from 'react-native';
+import MaterialIcons from '@expo/vector-icons/MaterialIcons';
+
+export default function CircleButton({ onPress }) {
+ return (
+
+
+
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ circleButtonContainer: {
+ width: 84,
+ height: 84,
+ marginHorizontal: 60,
+ borderWidth: 4,
+ borderColor: '#ffd33d',
+ borderRadius: 42,
+ padding: 3,
+ },
+ circleButton: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ borderRadius: 42,
+ backgroundColor: '#fff',
+ },
+});
diff --git a/components/IconButton.js b/components/IconButton.js
new file mode 100644
index 0000000..ddb7a37
--- /dev/null
+++ b/components/IconButton.js
@@ -0,0 +1,22 @@
+import { Pressable, StyleSheet, Text } from 'react-native';
+import MaterialIcons from '@expo/vector-icons/MaterialIcons';
+
+export default function IconButton({ icon, label, onPress }) {
+ return (
+
+
+ {label}
+
+ );
+}
+
+const styles = StyleSheet.create({
+ iconButton: {
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ iconButtonLabel: {
+ color: '#000',
+ marginTop: 12,
+ },
+});
diff --git a/components/ImageViewer.js b/components/ImageViewer.js
new file mode 100644
index 0000000..dc34a98
--- /dev/null
+++ b/components/ImageViewer.js
@@ -0,0 +1,17 @@
+import { StatusBar } from 'expo-status-bar';
+import { StyleSheet, Text, View, Image } from 'react-native';
+
+export default function ImageViewer({placeholderImageSource,selectedImage}){
+ const imageSource = selectedImage ? { uri: selectedImage } : placeholderImageSource;
+ return (
+
+ );
+}
+
+const styles = StyleSheet.create({
+ image:{
+ width:350,
+ height:450,
+ borderRadius:80
+ }
+})
\ No newline at end of file
diff --git a/components/Picker.js b/components/Picker.js
new file mode 100644
index 0000000..b60dbac
--- /dev/null
+++ b/components/Picker.js
@@ -0,0 +1,44 @@
+import { Modal, View, Text, Pressable, StyleSheet } from 'react-native';
+import MaterialIcons from '@expo/vector-icons/MaterialIcons';
+
+export default function Picker({ isVisible, children, onClose }) {
+ return (
+
+
+
+ Choose a sticker
+
+
+
+
+ {children}
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ modalContent: {
+ height: '25%',
+ width: '100%',
+ backgroundColor: '#25292e',
+ borderTopRightRadius: 18,
+ borderTopLeftRadius: 18,
+ position: 'absolute',
+ bottom: 0,
+ },
+ titleContainer: {
+ height: '16%',
+ backgroundColor: '#464C55',
+ borderTopRightRadius: 10,
+ borderTopLeftRadius: 10,
+ paddingHorizontal: 20,
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ },
+ title: {
+ color: '#000',
+ fontSize: 16,
+ },
+});
diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 0000000..aea4cbe
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "target": "ES6",
+ "module": "commonjs",
+ "allowSyntheticDefaultImports": true
+ },
+ "exclude": [
+ "node_modules"
+ ]
+}
diff --git a/package-lock.json b/package-lock.json
index 69e8a0c..7f372a2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,9 @@
"version": "1.0.0",
"dependencies": {
"@expo/metro-runtime": "~3.2.1",
+ "@expo/vector-icons": "^14.0.2",
"expo": "~51.0.22",
+ "expo-image-picker": "~15.0.7",
"expo-status-bar": "~1.12.1",
"react": "18.2.0",
"react-dom": "18.2.0",
@@ -7796,6 +7798,25 @@
"expo": "*"
}
},
+ "node_modules/expo-image-loader": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-4.7.0.tgz",
+ "integrity": "sha512-cx+MxxsAMGl9AiWnQUzrkJMJH4eNOGlu7XkLGnAXSJrRoIiciGaKqzeaD326IyCTV+Z1fXvIliSgNW+DscvD8g==",
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
+ "node_modules/expo-image-picker": {
+ "version": "15.0.7",
+ "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-15.0.7.tgz",
+ "integrity": "sha512-u8qiPZNfDb+ap6PJ8pq2iTO7JKX+ikAUQ0K0c7gXGliKLxoXgDdDmXxz9/6QdICTshJBJlBvI0MwY5NWu7A/uw==",
+ "dependencies": {
+ "expo-image-loader": "~4.7.0"
+ },
+ "peerDependencies": {
+ "expo": "*"
+ }
+ },
"node_modules/expo-keep-awake": {
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-13.0.2.tgz",
diff --git a/package.json b/package.json
index d8ef586..ae6456f 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,9 @@
"react-native": "0.74.3",
"react-dom": "18.2.0",
"react-native-web": "~0.19.10",
- "@expo/metro-runtime": "~3.2.1"
+ "@expo/metro-runtime": "~3.2.1",
+ "@expo/vector-icons": "^14.0.2",
+ "expo-image-picker": "~15.0.7"
},
"devDependencies": {
"@babel/core": "^7.20.0"