From e4d64f365631410dc2dee0b8c7efcd2ab4aa30a5 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Thu, 27 Jul 2023 16:00:31 +0800 Subject: [PATCH] Added avatar uploading --- app.json | 10 ++++-- package-lock.json | 28 ++++++++++++++++ package.json | 3 ++ src/components/Api/Api.tsx | 5 +-- src/interfaces/Interfaces.tsx | 6 ++++ src/routes/UserInfoPage/UserInfoPage.tsx | 42 +++++++++++++++++++----- src/styles.tsx | 2 ++ 7 files changed, 84 insertions(+), 12 deletions(-) diff --git a/app.json b/app.json index 893a6ba..2456397 100644 --- a/app.json +++ b/app.json @@ -42,9 +42,15 @@ [ "expo-location", { - "locationAlwaysAndWhenInUsePermission": "Allow Stud-E to use your location." + "locationAlwaysAndWhenInUsePermission": "Allow StudE to use your location." } - ] + ], + [ + "expo-image-picker", + { + "photosPermission": "Allow StudE to take and send photos for sharing in-app" + } + ] ], "extra": { "eas": { diff --git a/package-lock.json b/package-lock.json index 2c02127..14006b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,8 @@ "@tanstack/react-query": "^4.29.25", "axios": "^1.4.0", "expo": "~48.0.18", + "expo-file-system": "~15.2.2", + "expo-image-picker": "~14.1.1", "expo-intent-launcher": "~10.5.2", "expo-linking": "~4.0.1", "expo-location": "~15.1.1", @@ -41,6 +43,7 @@ "devDependencies": { "@babel/core": "^7.20.0", "@types/react": "~18.0.14", + "@types/react-native-fetch-blob": "^0.10.7", "typescript": "^4.9.4" } }, @@ -5311,6 +5314,12 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-native-fetch-blob": { + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@types/react-native-fetch-blob/-/react-native-fetch-blob-0.10.7.tgz", + "integrity": "sha512-9UTvmUvArimShiENeR3xnRO71NcZjpTi7AcFAIbhdTIfqQOO2OK/I/DpUPXcZF/erffLxOoRkoXrZOxyBBWKRQ==", + "dev": true + }, "node_modules/@types/scheduler": { "version": "0.16.3", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", @@ -7458,6 +7467,25 @@ "expo": "*" } }, + "node_modules/expo-image-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-4.1.1.tgz", + "integrity": "sha512-ciEHVokU0f6w0eTxdRxLCio6tskMsjxWIoV92+/ZD37qePUJYMfEphPhu1sruyvMBNR8/j5iyOvPFVGTfO8oxA==", + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-image-picker": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-14.1.1.tgz", + "integrity": "sha512-SvWtnkLW7jp5Ntvk3lVcRQmhFYja8psmiR7O6P/+7S6f4llt3vaFwb4I3+pUXqJxxpi7BHc2+95qOLf0SFOIag==", + "dependencies": { + "expo-image-loader": "~4.1.0" + }, + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-intent-launcher": { "version": "10.5.2", "resolved": "https://registry.npmjs.org/expo-intent-launcher/-/expo-intent-launcher-10.5.2.tgz", diff --git a/package.json b/package.json index 5d4609b..5af9ec0 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,8 @@ "@tanstack/react-query": "^4.29.25", "axios": "^1.4.0", "expo": "~48.0.18", + "expo-file-system": "~15.2.2", + "expo-image-picker": "~14.1.1", "expo-intent-launcher": "~10.5.2", "expo-linking": "~4.0.1", "expo-location": "~15.1.1", @@ -42,6 +44,7 @@ "devDependencies": { "@babel/core": "^7.20.0", "@types/react": "~18.0.14", + "@types/react-native-fetch-blob": "^0.10.7", "typescript": "^4.9.4" }, "private": true diff --git a/src/components/Api/Api.tsx b/src/components/Api/Api.tsx index 45701b9..0f4e758 100644 --- a/src/components/Api/Api.tsx +++ b/src/components/Api/Api.tsx @@ -17,7 +17,7 @@ if (__DEV__) { } // Switch this on if you wanna run production URLs while in development -let use_production = true; +let use_production = false; if (use_production) { backendURL = "https://stude.keannu1.duckdns.org"; backendURLWebsocket = "ws://stude.keannu1.duckdns.org"; @@ -142,6 +142,7 @@ export async function UserInfo() { } export async function PatchUserInfo(info: PatchStudentData) { + console.log("API", JSON.stringify(info)); const config = await GetConfig(); return instance .patch("/api/v1/accounts/users/me/", info, config) @@ -153,7 +154,7 @@ export async function PatchUserInfo(info: PatchStudentData) { let error_message = ""; if (error.response) error_message = error.response.data; else error_message = "Unable to reach servers"; - // console.log(error_message); + console.log(error_message); return [false, error_message]; }); } diff --git a/src/interfaces/Interfaces.tsx b/src/interfaces/Interfaces.tsx index 7c83a9b..40b0348 100644 --- a/src/interfaces/Interfaces.tsx +++ b/src/interfaces/Interfaces.tsx @@ -96,6 +96,11 @@ export interface Subject { export type Subjects = Array; export type SubjectParams = [boolean, Subjects]; +export type avatar = { + uri: string; + type: string; + name: string; +}; // For dropdown menu export interface OnboardingParams { @@ -112,6 +117,7 @@ export interface PatchStudentData { subjects?: any[] | null; // To-do, replace 'any' with your actual type year_level?: string | null; irregular?: boolean | null; + avatar?: string | null; } export interface StudentData { diff --git a/src/routes/UserInfoPage/UserInfoPage.tsx b/src/routes/UserInfoPage/UserInfoPage.tsx index 3ef6a8a..0453bd6 100644 --- a/src/routes/UserInfoPage/UserInfoPage.tsx +++ b/src/routes/UserInfoPage/UserInfoPage.tsx @@ -6,6 +6,7 @@ import { TextInput, NativeSyntheticEvent, TextInputChangeEventData, + Pressable, } from "react-native"; import { useState } from "react"; import { @@ -32,13 +33,14 @@ import { } from "../../components/Api/Api"; import { colors } from "../../styles"; import DropDownPicker from "react-native-dropdown-picker"; -import { ValueType } from "react-native-dropdown-picker"; import AnimatedContainerNoScroll from "../../components/AnimatedContainer/AnimatedContainerNoScroll"; import BouncyCheckbox from "react-native-bouncy-checkbox"; import { useSelector } from "react-redux"; import { RootState } from "../../features/redux/Store/Store"; import { useDispatch } from "react-redux"; import { setUser as setUserinState } from "../../features/redux/slices/UserSlice/UserSlice"; +import * as ImagePicker from "expo-image-picker"; +import * as FileSystem from "expo-file-system"; export default function UserInfoPage() { const logged_in_user = useSelector((state: RootState) => state.user.user); @@ -71,9 +73,9 @@ export default function UserInfoPage() { year_level: data[1].year_level, semester: data[1].semester, course: data[1].course, - avatar: data[1].avatar, student_id_number: data[1].student_id_number, irregular: data[1].irregular, + avatar: data[1].avatar, }); setSelectedCourse(data[1].course); setSelectedSemester(data[1].semester); @@ -157,15 +159,39 @@ export default function UserInfoPage() { }); // Profile photo + const pickImage = async () => { + // No permissions request is necessary for launching the image library + let result = await ImagePicker.launchImageLibraryAsync({ + mediaTypes: ImagePicker.MediaTypeOptions.All, + allowsEditing: true, + aspect: [4, 3], + quality: 1, + }); + if (!result.canceled) { + const encodedImage = await FileSystem.readAsStringAsync( + result.assets[0].uri, + { encoding: "base64" } + ); + mutation.mutate({ + avatar: encodedImage, + }); + } + }; function Avatar() { if (user.avatar) { - return ; + return ( + + + + ); } else { return ( - + + + ); } } @@ -350,7 +376,7 @@ export default function UserInfoPage() { Irregular