upd: announcement dan upload gambar

Deskripsi
- fix html tag pada pengumuman
- testing upload gambar = blm selesai

No Issues
This commit is contained in:
amel
2025-05-16 10:12:50 +08:00
parent c92c4771ad
commit cb8df3469e
6 changed files with 50 additions and 53 deletions

View File

@@ -6,7 +6,8 @@ import { useAuthSession } from "@/providers/AuthProvider";
import { AntDesign, Entypo, MaterialIcons } from "@expo/vector-icons";
import { router, Stack, useLocalSearchParams } from "expo-router";
import { useEffect, useState } from "react";
import { SafeAreaView, ScrollView, Text, View } from "react-native";
import { Dimensions, SafeAreaView, ScrollView, Text, View } from "react-native";
import RenderHTML from 'react-native-render-html';
import { useSelector } from "react-redux";
type Props = {
@@ -18,10 +19,11 @@ type Props = {
export default function DetailAnnouncement() {
const { id } = useLocalSearchParams<{ id: string }>();
const { token, decryptToken } = useAuthSession()
const [data, setData] = useState<Props>()
const [data, setData] = useState<Props>({ id: '', title: '', desc: '' })
const [dataMember, setDataMember] = useState<any>({})
const update = useSelector((state: any) => state.announcementUpdate)
const entityUser = useSelector((state: any) => state.user)
const contentWidth = Dimensions.get('window').width
async function handleLoad() {
try {
@@ -55,9 +57,11 @@ export default function DetailAnnouncement() {
<MaterialIcons name="campaign" size={30} color="black" style={Styles.mr05} />
<Text style={[Styles.textDefaultSemiBold]}>{data?.title}</Text>
</View>
<View style={[Styles.rowItemsCenter, Styles.mt10]}>
<AntDesign name="profile" size={30} color="black" style={Styles.mr05} />
<Text style={[Styles.textDefault]}>{data?.desc}</Text>
<View style={[Styles.mt10]}>
<RenderHTML
contentWidth={contentWidth}
source={{ html: data?.desc }}
/>
</View>
</View>
<View style={[Styles.wrapPaper, Styles.mv15]}>
@@ -71,7 +75,7 @@ export default function DetailAnnouncement() {
return (
<View key={x} style={[Styles.rowItemsCenter]}>
<Entypo name="dot-single" size={24} color="black" />
<Text style={[Styles.textDefault]}>{item.division}</Text>
<Text style={[Styles.textDefault]} numberOfLines={1} ellipsizeMode='tail'>{item.division}</Text>
</View>
)
})

View File

@@ -70,7 +70,7 @@ export default function Announcement() {
</View>
}
title={item.title}
desc={item.desc}
desc={item.desc.replace(/<[^>]*>?/gm, '')}
rightTopInfo={item.createdAt}
/>
)

View File

@@ -14,7 +14,7 @@ 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';
import { launchImageLibrary } from "react-native-image-picker";
const debug = true
@@ -151,52 +151,46 @@ const requestPermission = async () => {
return true;
};
const base64ToBlob = (base64: string, mimeType: string) => {
const byteString = atob(base64);
const arrayBuffer = new ArrayBuffer(byteString.length);
const int8Array = new Uint8Array(arrayBuffer);
for (let i = 0; i < byteString.length; i++) {
int8Array[i] = byteString.charCodeAt(i);
}
return new Blob([int8Array], { type: mimeType });
};
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,
console.log("clicked");
const result = await launchImageLibrary({
mediaType: "photo",
quality: 1,
includeBase64: true,
});
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;
}
if (!result.assets || result.assets.length === 0) {
console.log("No image selected");
return;
}
return null;
const base64 = result.assets[0].base64!;
const mimeType = result.assets[0].type!; // e.g., 'image/jpeg'
const blob = base64ToBlob(base64, mimeType);
const formData = new FormData();
formData.append("file", blob);
formData.append("name", "bip.png");
const res = await fetch("http://10.0.2.2:3000/api/v2/test", {
method: "POST",
body: formData,
});
console.log(await res.text());
}