upd: upload gambar

Deskripsi:
- coba upload gambar
- nb: blm selesai

No Issues
This commit is contained in:
amel
2025-05-15 17:16:42 +08:00
parent 9b05c6220c
commit c92c4771ad
5 changed files with 140 additions and 20 deletions

3
.gitignore vendored
View File

@@ -36,3 +36,6 @@ yarn-error.*
*.tsbuildinfo *.tsbuildinfo
app-example app-example
x.ts
x.sh

View File

@@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<queries> <queries>
<intent> <intent>
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW"/>

View File

@@ -11,6 +11,13 @@ import { router, Stack } from "expo-router";
import { useState } from "react"; import { useState } from "react";
import { Image, Platform, Pressable, SafeAreaView, ScrollView, Text, View } from "react-native"; import { Image, Platform, Pressable, SafeAreaView, ScrollView, Text, View } from "react-native";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
import * as FileSystem from 'expo-file-system';
import axios from "axios";
import ReactNativeBlobUtil from 'react-native-blob-util';
import FormData from 'form-data';
const debug = true
export default function CreateBanner() { export default function CreateBanner() {
const { decryptToken, token } = useAuthSession() const { decryptToken, token } = useAuthSession()
@@ -20,39 +27,80 @@ export default function CreateBanner() {
const [title, setTitle] = useState('') const [title, setTitle] = useState('')
const pickImageAsync = async () => { const pickImageAsync = async () => {
kirim()
return
let result = await ImagePicker.launchImageLibraryAsync({ let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ['images'], mediaTypes: ['images'],
allowsEditing: false, allowsEditing: false,
quality: 1, quality: 1,
}); });
const formData = new FormData()
formData.append('file', result.assets![0].uri)
if (debug) console.log("[mengirim gambar]")
const res = await fetch("http://10.0.2.2:3000/api/v2/test", {
method: "POST",
body: formData,
});
console.log("[res]", await res.json())
if (debug) console.log("[pickImageAsync]")
if (!result.canceled) { if (!result.canceled) {
setSelectedImage(result.assets[0].uri); if (result.assets?.[0].uri) {
setImgForm(result.assets[0]) // setSelectedImage(result.assets[0].uri);
// setImgForm(result.assets[0])
const formData = new FormData()
formData.append('file', result.assets[0].uri)
if (debug) console.log("[mengirim gambar]")
const res = await fetch("http://10.0.2.2:3000/api/v2/test", {
method: "POST",
body: formData,
});
console.log("[res]", await res.json())
} else { } else {
if (debug) console.log("[pickImageAsync]", 'Tidak ada gambar yang dipilih');
alert('Tidak ada gambar yang dipilih'); alert('Tidak ada gambar yang dipilih');
} }
console.log("[imgForm]", imgForm)
} else {
if (debug) console.log("[pickImageAsync]", 'Tidak ada gambar yang dipilih');
alert('Tidak ada gambar yang dipilih');
}
}; };
console.log(imgForm)
const handleCreateEntity = async () => { const handleCreateEntity = async () => {
const hasil = await decryptToken(String(token?.current)) // const hasil = await decryptToken(String(token?.current))
const fd = new FormData() // const fd = new FormData()
fd.append("file", JSON.stringify({
uri: imgForm.uri,
type: imgForm.mimeType, // fd.append("file", JSON.stringify({
name: imgForm.fileName, // uri: imgForm.uri,
size: imgForm.fileSize, // type: imgForm.mimeType,
})) // name: imgForm.fileName,
fd.append("data", JSON.stringify( // size: imgForm.fileSize,
{ // }))
title: title, // fd.append("data", JSON.stringify(
user: hasil // {
} // title: title,
)) // user: hasil
const createdEntity = await apiCreateBanner(fd); // }
// console.log('cliene',createdEntity) // ))
// const createdEntity = await apiCreateBanner(fd);
// console.log("[createdEntity]", createdEntity)
// dispatch(addEntity(createdEntity)); // dispatch(addEntity(createdEntity));
}; };
@@ -90,3 +138,65 @@ export default function CreateBanner() {
</SafeAreaView> </SafeAreaView>
) )
} }
const requestPermission = async () => {
if (Platform.OS !== 'web') {
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== 'granted') {
alert('Maaf, kami membutuhkan izin untuk mengakses galeri!');
return false;
}
return true;
}
return true;
};
async function kirim() {
const hasPermission = await requestPermission();
if (!hasPermission) {
return;
}
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
aspect: [4, 3],
quality: 0.8,
});
if (!result.canceled) {
const uri = result.assets[0].uri;
console.log("Selected image URI:", uri);
try {
const base64Data = await ReactNativeBlobUtil.fs.readFile(uri, 'base64');
// Convert base64 to Blob
const blob = new Blob([base64Data], { type: 'image/jpeg' });
const formData = new FormData();
formData.append('file', blob);
formData.append('name', 'bg.png');
console.log("Sending FormData with file URI...");
// Kirim request tanpa header Content-Type
const response = await fetch("http://10.0.2.2:3000/api/v2/test", {
method: 'POST',
body: formData as any,
});
// console.log("Response status:", response.status);
} catch (error: any) {
console.error('Error uploading image:', error);
return null;
}
}
return null;
}

BIN
bun.lockb

Binary file not shown.

View File

@@ -20,6 +20,7 @@
"@react-navigation/bottom-tabs": "^7.2.0", "@react-navigation/bottom-tabs": "^7.2.0",
"@react-navigation/native": "^7.0.14", "@react-navigation/native": "^7.0.14",
"@reduxjs/toolkit": "^2.7.0", "@reduxjs/toolkit": "^2.7.0",
"@types/formidable": "^3.4.5",
"axios": "^1.8.4", "axios": "^1.8.4",
"crypto-es": "^2.1.0", "crypto-es": "^2.1.0",
"crypto-js": "^3.1.9-1", "crypto-js": "^3.1.9-1",
@@ -28,6 +29,7 @@
"expo-blur": "~14.0.3", "expo-blur": "~14.0.3",
"expo-constants": "~17.0.7", "expo-constants": "~17.0.7",
"expo-document-picker": "^13.0.3", "expo-document-picker": "^13.0.3",
"expo-file-system": "~18.0.12",
"expo-font": "~13.0.4", "expo-font": "~13.0.4",
"expo-haptics": "~14.0.1", "expo-haptics": "~14.0.1",
"expo-image-picker": "~16.0.6", "expo-image-picker": "~16.0.6",
@@ -40,10 +42,13 @@
"expo-symbols": "~0.2.2", "expo-symbols": "~0.2.2",
"expo-system-ui": "~4.0.8", "expo-system-ui": "~4.0.8",
"expo-web-browser": "~14.0.2", "expo-web-browser": "~14.0.2",
"form-data": "^4.0.2",
"formidable": "^3.5.4",
"moment": "^2.30.1", "moment": "^2.30.1",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-native": "0.76.7", "react-native": "0.76.7",
"react-native-blob-util": "^0.21.2",
"react-native-confirmation-code-field": "^7.4.0", "react-native-confirmation-code-field": "^7.4.0",
"react-native-fs": "^2.20.0", "react-native-fs": "^2.20.0",
"react-native-gesture-handler": "~2.20.2", "react-native-gesture-handler": "~2.20.2",
@@ -51,6 +56,7 @@
"react-native-modal": "^14.0.0-rc.1", "react-native-modal": "^14.0.0-rc.1",
"react-native-reanimated": "~3.16.1", "react-native-reanimated": "~3.16.1",
"react-native-reanimated-carousel": "^4.0.2", "react-native-reanimated-carousel": "^4.0.2",
"react-native-render-html": "^6.3.4",
"react-native-safe-area-context": "4.12.0", "react-native-safe-area-context": "4.12.0",
"react-native-screens": "~4.4.0", "react-native-screens": "~4.4.0",
"react-native-svg": "15.8.0", "react-native-svg": "15.8.0",