Skip to content

Commit

Permalink
wip set api
Browse files Browse the repository at this point in the history
  • Loading branch information
kiloking committed Jan 10, 2024
1 parent b4a73db commit 9560d81
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 97 deletions.
3 changes: 2 additions & 1 deletion src/Layouts/CameraLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function CameraLayout() {
<div
className='min-h-[100vh] h-screen md:h-auto relative text-white bg-no-repeat bg-cover bg-center z-10'
style={{
backgroundImage: `url('https://r2.web.moonshine.tw/msweb/backto80s_ai/bg01.png')`,
backgroundImage: `url('https://r2.web.moonshine.tw/opt/lg/msweb/backto80s_ai/bg01.png')`,
}}
>
{location.pathname === '/camera' &&
Expand Down Expand Up @@ -117,6 +117,7 @@ function CameraLayout() {
const offsetY = (position.y + index) / (index+2);
return(
<div
key={'ic0'+index}
onMouseMove={(e) => handleMouseMove(e)}
className={`absolute`}
style={{
Expand Down
2 changes: 1 addition & 1 deletion src/Layouts/RenderLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function RenderLayout() {
<div
className='min-h-[100vh] relative bg-black text-white bg-no-repeat bg-center bg-cover '
style={{
backgroundImage: `url('https://r2.web.moonshine.tw/msweb/backto80s_ai/bg01.png')`,
backgroundImage: `url('https://r2.web.moonshine.tw/opt/lg/msweb/backto80s_ai/bg01.png')`,
}}
>

Expand Down
189 changes: 103 additions & 86 deletions src/Page/Camera/ModelSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,37 @@ const bannerData = [

]


const apiUrl = 'https://faceswap.rd-02f.workers.dev/'
function ModelSelect() {
const storedUsername = getUsernameFromCookie();
const [isMobile, setIsMobile] = useState(window.innerWidth < 768);
const [sourceImage ,setSourceImage ] = useState(null)
const [taskStatus, setTaskStatus] = useState(Array(4).fill('Waiting')); // 任務初始狀態為 'Waiting'
const [taskStatus, setTaskStatus] = useState([
{
status: 'ok',
id: null,
img: 'https://r2.web.moonshine.tw/msweb/backto80s_ai/template_80s/49.jpg',
finished: 1,
},
{
status: 'ok',
id: null,
img: 'https://r2.web.moonshine.tw/msweb/backto80s_ai/template_80s/50.jpg',
finished: 1,
},
{
status: 'Waiting for Result...',
id: null,
img: 'https://r2.web.moonshine.tw/msweb/backto80s_ai/template_80s/49.jpg',
finished: 0,
} ,
{
status: 'Waiting for Result...',
id: null,
img: 'https://r2.web.moonshine.tw/msweb/backto80s_ai/template_80s/49.jpg',
finished: 0,
}
]); // 任務初始狀態為 'Waiting'
const handleResize = () => {
setIsMobile(window.innerWidth < 768);
};
Expand Down Expand Up @@ -124,96 +149,88 @@ function ModelSelect() {
}catch{

}


// const formData = new FormData();
// formData.append('source_image', compressFiles);
// formData.append("command_type", currentId);

// fetch('https://faceswap.rd-02f.workers.dev/images', {
// method: 'POST',
// body: formData,
// redirect: 'follow'
// })
// .then(response => {
// console.log(response)
// if(response.ok){

// return response.json()
// }else{
// setMsg('Error:please upload the image again.')
// }

// })
// .then(responseData => {
// // console.log(responseData)
// if(responseData.message){
// setMsg('Error:please upload the image again.')
// return
// }
// setRenderedData(responseData)
// setIsRender(true)
// setMsg(null)

// setTimeout(async() => {
// setMsg('Please wait for the result')
// await getResulImage(responseData.id,compressFiles)
// }, 500);


// })
// .catch(error => {
// console.error(error);
// });


}
//TODO 從上面執行
const uploadAndAwaitResult = async (imageUrls,compressFiles)=>{
for (let i = 0; i < imageUrls.length; i++) {
const imageUrl = imageUrls[i];

setTaskStatus((prevStatus) => {
const newStatus = [...prevStatus];
newStatus[i] = 'Uploading...';
return newStatus;
});
const statusList = imageUrls.map((imageUrl) => ({
status: 'Uploading...',
id: null,
img: '',
finished: 0,
}));
const uploadPromises = imageUrls.map((imageUrl,index) => {
return new Promise(async (resolve, reject) => {
try {
// 上传图像的逻辑
const formData = new FormData();
formData.append('source_image', beforeImage);
formData.append('img_url', imageUrl);

const response = await fetch(apiUrl+'face_swap', {
method: 'POST',
body: formData,
redirect: 'follow',
});

if (!response.ok) {
setMsg('Error:please upload the image again.')
reject(new Error('Image upload failed.'));
return;
}

const responseData = await response.json();
console.log(responseData);

if (responseData.message) {
setMsg('Error:please upload the image again.')
reject(new Error('Image upload failed.'));
return;
}

const formData = new FormData();
formData.append('source_image', beforeImage);
formData.append('command_type', imageUrl);

const response = await fetch('https://faceswap.rd-02f.workers.dev/images', {
method: 'POST',
body: formData,
redirect: 'follow',

// 上传成功,等待结果
await new Promise((innerResolve) => setTimeout(innerResolve, 300));

statusList[index].status = 'Image uploaded, Waiting for result...';
statusList[index].id = responseData.id;

resolve(responseData);
} catch (error) {
setMsg('Error: Image upload failed.');
reject(error);
}
});

if (!response.ok) {
setMsg('Error:please upload the image again.')
throw new Error('Image upload failed.');
}
});




const responseData = await response.json();
console.log(responseData);

if(responseData.message){
setMsg('Error:please upload the image again.')
return
try {
const results = await Promise.all(uploadPromises);
console.log('All uploads completed:', results);
// 在这里处理所有上传任务完成后的逻辑

for (let i = 0; i < results.length; i++) {
const result = results[i];
const status = statusList[i];

if (result && result.id) {
// 调用 getResulImage,注意传入对应的 id 和 sourceImg
const resultImage = await getResulImage(result.id, compressFiles);

// 更新对应任务的状态
status.finished = 1;
status.img = resultImage; // 假设 resultImage 是返回的结果图片URL
status.status = 'Result received';
}
}

setTaskStatus(statusList);

await new Promise((resolve) => setTimeout(resolve, 300));
} catch (error) {
console.error('Upload error:', error);
// 在这里处理上传过程中的错误
}

setTaskStatus((prevStatus) => {
return prevStatus.map((status, index) =>
index === i ? 'Image uploaded, Waiting for result...' : status
);
});

}
}

let source;
Expand All @@ -225,7 +242,7 @@ function ModelSelect() {
}

// let reid = id
await fetch('https://faceswap.rd-02f.workers.dev/images/'+id, {
await fetch(apiUrl+id, {
method: 'GET',
})
.then(response => response.json())
Expand Down Expand Up @@ -266,7 +283,7 @@ function ModelSelect() {
formData.append("username", storedUsername ? storedUsername : ' ');
formData.append("command_type", currentId);

await fetch('https://faceswap.rd-02f.workers.dev/swap_data', {
await fetch(apiUrl+'swap_data', {
method: 'POST',
body: formData,
redirect: 'follow'
Expand Down Expand Up @@ -342,7 +359,7 @@ function ModelSelect() {
<div key={'tf'+index} className=' cursor-pointer '>
<div className=' relative '>
<div
className={currentId === item.id && ' -translate-y-12 ' + ' relative w-full transition-all duration-1000' }
className={currentId === item.id ? ' -translate-y-12 ' : ' ' + ' relative w-full transition-all duration-1000' }
onClick={()=>{
handleImageClick(index)
setCurrentId(String(index+1))
Expand Down Expand Up @@ -408,7 +425,7 @@ function ModelSelect() {
initial={{ opacity: 0,y:10 }}
animate={{ opacity: 1,y:0}}
exit={{ opacity: 0,y:10}}
className='text-[#FF0050] text-3xl font-extrabold mt-8 drop-shadow-[0_0.8px_0.1px_rgba(0,0,0,0.8)]'>{msg}</motion.div>
className='text-[#FF0050] text-2xl font-extrabold mt-8 drop-shadow-[0_0.8px_0.1px_rgba(0,0,0,0.8)]'>{msg}</motion.div>
)}
{
msg && msg.includes('錯誤') &&
Expand All @@ -429,7 +446,7 @@ function ModelSelect() {



<Result open={showRender} handleOpen={handleOpen} renderedResult={renderedResult} username={storedUsername}/>
<Result open={!showRender} handleOpen={handleOpen} renderedResult={renderedResult} username={storedUsername} taskStatus={taskStatus}/>

</div>
)
Expand Down
54 changes: 46 additions & 8 deletions src/Page/Camera/Result.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
Spinner,
IconButton
} from "@material-tailwind/react";
import QRCode from "react-qr-code";
function Result({open ,handleOpen,renderedResult,username}) {
import { motion, AnimatePresence } from "framer-motion";
function Result({open ,handleOpen,renderedResult,username,taskStatus}) {

const downloadImage = (imgurl) => {
const imageUrl = imgurl
Expand Down Expand Up @@ -65,15 +65,53 @@ function Result({open ,handleOpen,renderedResult,username}) {
<DialogBody className='p-0 m-0'>
<div className='flex flex-col md:flex-col justify-center items-center gap-0 '>

{Object.keys(renderedResult).length > 0 && (
{Object.keys(taskStatus).length > 0 && (
<div className='w-[75%] relative my-10'>
<Suspense fallback={<Spinner/>}>
<div className='md:hidden text-center mb-2 text-[#FF0050] font-cachet font-bold'>Press and hold to save photo↓</div>
<div className='grid grid-cols-2 md:grid-cols-4 gap-8'>
<img src={renderedResult.generations[0].img} alt="" className=' rounded-3xl '/>
<img src={renderedResult.generations[0].img} alt="" className=' rounded-3xl '/>
<img src={renderedResult.generations[0].img} alt="" className=' rounded-3xl '/>
<img src={renderedResult.generations[0].img} alt="" className=' rounded-3xl '/>
<div className='w-full md:w-[80%] mx-auto relative mt-5 md:mt-0 grid gap-4 grid-cols-2 md:grid-cols-4 px-5'>
{Object.keys(taskStatus).length > 0 ?

taskStatus.map((item,index)=>{
if(item.finished === 0){
return(
<div className='flex flex-col justify-center items-center '>
<div className='w-full h-full relative overflow-hidden rounded-xl '>
<div className='w-full h-full bg-gray-100 z-0 '></div>
<div
className=" z-10 absolute top-0 left-0 w-full h-full bg-gradient-to-r from-transparent via-gray-300 to-transparent -translate-x-full animate-[shimmer_2s_infinite]"
>
</div>
</div>
<motion.div
initial={{ opacity: 0,y:10 }}
animate={{ opacity: 1,y:0}}
exit={{ opacity: 0,y:10}}
>
{item.status}
</motion.div>
</div>
)
}else{
return(
<div className='flex flex-col justify-center items-center '>
<img src={item.img} alt="" className='rounded-xl ' />
<motion.div
initial={{ opacity: 0,y:10 }}
animate={{ opacity: 1,y:0}}
exit={{ opacity: 0,y:10}}
>
{item.status}
</motion.div>

</div>
)
}

})
:
<div>no result or fail </div>
}
</div>


Expand Down
7 changes: 6 additions & 1 deletion tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ module.exports = withMT({
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
}
},
shimmer: {
"100%": {
transform: "translateX(100%)",
},
},
},
fontFamily: {
'roboto': ['Roboto', 'sans-serif'],
Expand Down

0 comments on commit 9560d81

Please sign in to comment.