Skip to content
This repository has been archived by the owner on Mar 5, 2024. It is now read-only.

Commit

Permalink
feat: add button copy image
Browse files Browse the repository at this point in the history
  • Loading branch information
watchakorn-18k committed Dec 19, 2023
1 parent 4b22652 commit 73d3558
Show file tree
Hide file tree
Showing 11 changed files with 525 additions and 328 deletions.
446 changes: 300 additions & 146 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"@tabler/icons-react": "^2.20.0",
"@types/node": "^20.2.3",
"axios": "^1.4.0",
"daisyui": "^2.51.6",
"copy-image-clipboard": "^2.1.2",
"file-saver": "^2.0.5",
"i18next": "^22.5.0",
"react": "^18.2.0",
Expand All @@ -31,6 +31,7 @@
"@typescript-eslint/parser": "^5.57.1",
"@vitejs/plugin-react": "^4.0.0",
"autoprefixer": "^10.4.14",
"daisyui": "^4.4.20",
"eslint": "^8.38.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.3.4",
Expand Down
19 changes: 13 additions & 6 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
<p align="center"><img src="https://cdn.discordapp.com/attachments/585069498986397707/1111517852009238628/image.png"></p>
<h1 align="center">Genarate Image From Text <img alt="GitHub release" src="https://img.shields.io/badge/release-v1.1.4-blue"> </h1>



<strong align="center">🖼️ Generate Inage With Text with EdgeGPT reverse engineering</strong>

<h6>Try FREE!!</h6>
<br>
<p align="center"><a href="https://github.com/watchakorn-18k/generate_image_web/actions"><img src="https://img.shields.io/badge/github%20actions-%232671E5.svg?style=for-the-badge&logo=githubactions&logoColor=white"></a> <a href="#Install"><img src="https://img.shields.io/badge/vite-%23646CFF.svg?style=for-the-badge&logo=vite&logoColor=white"></a> <a href="https://fast-apiimggen--etwg34dassad211.repl.co"><img src="https://img.shields.io/badge/Replit-DD1200?style=for-the-badge&logo=Replit&logoColor=white"></a> <a href="https://fast-apiimggen--etwg34dassad211.repl.co/docs"><img src="https://img.shields.io/badge/FastAPI-005571?style=for-the-badge&logo=fastapi"></a> <a href="https://fast-apiimggen--etwg34dassad211.repl.co/docs"><img src="https://img.shields.io/badge/FastAPI-005571?style=for-the-badge&logo=fastapi"></a> <a href="https://www.figma.com/file/8FsDo7EAE4UQOVejh7VJeS/Untitled?type=design&t=cmZltZSNfiqrWjFc-0"><img src="https://img.shields.io/badge/figma-%23F24E1E.svg?style=for-the-badge&logo=figma&logoColor=white"></a></p>
Expand All @@ -19,22 +18,26 @@
<br>

# Generate Image From Text

> 🖼️ Generate Inage With Text with EdgeGPT reverse engineering
<br>
> <br>
![](https://media.discordapp.net/attachments/585069498986397707/1111521783191973939/screenshot-1685077818060.jpeg)

# API

```
https://fast-apiimggen--etwg34dassad211.repl.co
```

# Install

```
npm create vite@latest
```

# Start

```
git clone https://github.com/watchakorn-18k/generate_image_web
cd generate_image_web
Expand All @@ -43,16 +46,19 @@ npm start
```

# Run

```
npm run dev
```

# Build

```
npm run build
```

## Contribute

1. Ensure you have installed `node` and `yarn`
2. Go to `desktop-app` folder
3. Run `yarn` to install dependencies
Expand All @@ -62,7 +68,6 @@ npm run build

<p align="center">


<img src="https://cdn.discordapp.com/attachments/585069498986397707/1111521782885793893/screenshot-1685077634582.jpeg" />

<img src="https://media.discordapp.net/attachments/585069498986397707/1111521783191973939/screenshot-1685077818060.jpeg" />
Expand All @@ -73,8 +78,10 @@ npm run build

</p>


# Changelog

- v1.1.8 add button copy image
- v1.1.7 Fix bug can't access image
- v1.1.6 Fix bug api and manage error front end and back end
- v1.1.5 Check bad words in prompt
- v1.1.4 Fix UI responsive layout tablet
Expand All @@ -91,4 +98,4 @@ npm run build
- v1.0.3 Add Icon Footer
- v1.0.2 Add sessionStorage for switch language when refresh can change language follow your select
- v1.0.1 Add Alert to Generate Image and Add event Enter <p align="center"><img src="https://cdn.discordapp.com/attachments/585069498986397707/1111121577174650920/image.png" /></p>
- v1.0.0 Release generate image from text
- v1.0.0 Release generate image from text
70 changes: 39 additions & 31 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,45 @@ import TextPrompt from "./components/TextPrompt/TextPrompt.tsx";
import CardImage from "./components/CardImage/CardImage.tsx";
import Footer from "./components/Footer/Footer.tsx";
import Navbar from "./components/Navbar/Navbar.tsx";
import { useTranslation } from 'react-i18next';
import { Progress,Spinner } from "@material-tailwind/react";

import { useTranslation } from "react-i18next";
import { Progress, Spinner } from "@material-tailwind/react";

export default function App() {
const { t } = useTranslation();
const [data, setData] = useState({ status_gen: false, images: [], prompt_text: "","thumbnail": [],status_erro:false });
const [data, setData] = useState({
status_gen: false,
images: [],
prompt_text: "",
thumbnail: [],
status_erro: false,
});
const [value, setValue] = useState(0);
const [isRunning, setIsRunning] = useState(true);
const choices = [image_logo, image_logo_1, image_logo_2];
const [randomChoice] = useState(choices[Math.floor(Math.random() * choices.length)]);
const [randomChoice] = useState(
choices[Math.floor(Math.random() * choices.length)]
);

const handleContextMenu = (e: React.MouseEvent<HTMLDivElement>) => {
e.preventDefault();
}
};



useEffect(() => {
const fetchData = async () => {
try {
const result = await axios.get(
import.meta.env.VITE_URL_API
);
const result = await axios.get(import.meta.env.VITE_URL_API);
setData(result.data);
console.log(result.data);


if (result.data.status_gen === true) {
setIsRunning(false);
}
else {
} else {
setIsRunning(true);
}
} catch (error) {
console.log(error);
setIsRunning(true);
}
};



fetchData();

const interval = setInterval(() => {
Expand All @@ -71,32 +69,42 @@ export default function App() {
return () => clearInterval(intervalId);
}, [isRunning]);


return (

<div className="flex flex-col min-h-screen justify-between" onContextMenu={handleContextMenu}>
<div
className="flex flex-col min-h-screen justify-between"
onContextMenu={handleContextMenu}
>
<Navbar />
<div className="container mx-auto px-5 flex flex-col justify-between">
<div className="grid grid-cols-1 gap-2">

<ImageShow src_image={randomChoice} />

<TextPrompt status_gen={data.status_gen} status_erro={data.status_erro} />

<TextPrompt
status_gen={data.status_gen}
status_erro={data.status_erro}
/>
{data.status_gen === false ? (
<div className="grid grid-cols-1 gap-2 place-items-center p-10 md:p-32">

<Spinner className="h-10 w-10 md:h-20 md:w-20 mr-3" />
<p className="text-center text-xl animate-pulse">{t('loading')}</p>
<Progress value={value} className="w-60 md:w-1/2 " variant="gradient" />
<p className="text-center text-xl animate-pulse">
{t("loading")}
</p>
<Progress
value={value}
className="w-60 md:w-1/2 "
variant="gradient"
/>
</div>
) : (
<CardImage text={data.prompt_text} urls={data.images} thumbnails={data.thumbnail}/>

<CardImage
text={data.prompt_text}
urls={data.images}
thumbnails={data.thumbnail}
/>
)}
</div>

</div>

<Footer />
</div>
);
Expand Down
43 changes: 34 additions & 9 deletions src/components/CardImage/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import {
IconBrandMeta,
IconBrandTwitter,
IconBrandLinkedin,
IconCopy,
} from "@tabler/icons-react";
import { Tooltip } from "@material-tailwind/react";
import FileSaver from "file-saver";
import "./CardImage.css";
import { useTranslation } from "react-i18next";
import { copyImageToClipboard } from "copy-image-clipboard";

type Props = {
url: string;
Expand All @@ -23,29 +25,52 @@ export default function Card({ url, text, index, thumbnail }: Props) {
fetch(url)
.then((res) => res.blob())
.then((blob) => {
FileSaver.saveAs(blob, `${index}_${thumbnail.slice(58,-5)}-wk18k.jpeg`);
FileSaver.saveAs(
blob,
`${index}_${thumbnail.slice(58, -5)}-wk18k.jpeg`
);
})
.catch((err) => console.error(err));
};

const handleCopyImage = async () => {
try {
copyImageToClipboard(url)
.then(() => {
console.log("Image Copied");
})
.catch((e) => {
console.log("Error: ", e.message);
});
} catch (err) {
console.error("Failed to copy: ", err);
}
};

return (
<div className="py-1 lg:py-5">
<div className="indicator">
<span className="indicator-item badge badge-secondary">#{index}</span>
<span className="indicator-item p-3 rounded-full badge badge-warning">
#{index}
</span>
<div className="card card-compact w-80 md:w-96 bg-base-100 shadow-xl">

<figure>
<img
src={`${thumbnail}?v=${index}`}
className="w-full h-80 object-cover image-card"
/>
</figure>
<figure>
<img
src={`${thumbnail}?v=${index}`}
className="w-full h-80 object-cover image-card"
/>
</figure>
<div className="card-body">
<h2 className="card-title">
{t("scenario")} {index}
</h2>
<p className="text">{text}</p>
<div className="card-actions justify-end">
<Tooltip className="text" content={t("tool-tip-copy")}>
<button className="btn-text" onClick={handleCopyImage}>
<IconCopy />
</button>
</Tooltip>
<Tooltip className="text" content={t("tool-tip-download")}>
<button className="btn-text" onClick={handleDownload}>
<IconDownload />
Expand Down
25 changes: 16 additions & 9 deletions src/components/CardImage/CardImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@ type Props = {
text: string;
};

export default function CardImage({ urls,text,thumbnails}: Props) {
const CardElements = urls.map((url: string,index: number) => (
<Card key={index} url={url} text={text} thumbnail={thumbnails[index]} index={index+1} />
));
export default function CardImage({ urls, text, thumbnails }: Props) {
const CardElements = urls.map((url: string, index: number) => {
return index != 4 ? (
<Card
key={index}
url={url}
text={text}
thumbnail={thumbnails[index]}
index={index + 1}
/>
) : null;
});
return (
<div className="flex justify-center">
<div className="grid grid-cols-1 md:grid-cols-1 xl:grid-cols-2 gap-2 :gap-5 lg:gap-5">
{CardElements}

</div>
<div className="flex justify-center">
<div className="grid grid-cols-1 m-4 md:grid-cols-1 xl:grid-cols-2 gap-6 lg:gap-5">
{CardElements}
</div>
</div>
);
}
12 changes: 6 additions & 6 deletions src/components/TextPrompt/TextPrompt.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@
border: none;
border-radius: 100% !important;
top: -0.75rem !important;
background: linear-gradient(80deg, #61D9E8, transparent) #4ABBC9 !important;
background: linear-gradient(80deg, #0e1d8d, transparent) #004cff !important;
transition: background-color 1s;
}

.btn-search:hover{
.btn-search:hover {
background-color: #2e63f3 !important;
}

.btn-disable{
.btn-disable {
background: linear-gradient(80deg, #a3a3a394, transparent) #a3a3a394 !important;
background-color: #a3a3a3 !important;
color: #e6e6e6 !important;
}

@media screen and (max-width: 640px) {
.mobile-top{
.mobile-top {
top: -0.30rem !important;
}
}

}
Loading

0 comments on commit 73d3558

Please sign in to comment.