mirror of
https://github.com/coaidev/coai.git
synced 2025-05-19 21:10:18 +09:00
feat: support base64 image in frontend
This commit is contained in:
parent
6e54c6444f
commit
4cd5c422c0
@ -1,5 +1,5 @@
|
|||||||
import { Download, Eye, File } from "lucide-react";
|
import { Download, Eye, File } from "lucide-react";
|
||||||
import { saveAsFile, saveBlobAsFile } from "@/utils/dom.ts";
|
import { saveAsFile, saveBlobAsFile, saveImageAsFile } from "@/utils/dom.ts";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { Button } from "@/components/ui/button.tsx";
|
import { Button } from "@/components/ui/button.tsx";
|
||||||
import FileViewer from "@/components/FileViewer.tsx";
|
import FileViewer from "@/components/FileViewer.tsx";
|
||||||
@ -15,11 +15,16 @@ import FileViewer from "@/components/FileViewer.tsx";
|
|||||||
export function parseFile(data: string, acceptDownload?: boolean) {
|
export function parseFile(data: string, acceptDownload?: boolean) {
|
||||||
const filename = data.split("\n")[0].replace("[[", "").replace("]]", "");
|
const filename = data.split("\n")[0].replace("[[", "").replace("]]", "");
|
||||||
const content = data.replace(`[[${filename}]]\n`, "");
|
const content = data.replace(`[[${filename}]]\n`, "");
|
||||||
|
|
||||||
const image = useMemo(() => {
|
const image = useMemo(() => {
|
||||||
// get image url from content (like: https://i.imgur.com/xxxxx.png)
|
// get image url from content (like: https://i.imgur.com/xxxxx.png)
|
||||||
const match = content
|
const match = content.match(/(https?:\/\/.*\.(?:png|jpg|jpeg|gif))/);
|
||||||
.toLowerCase()
|
return match ? match[0] : "";
|
||||||
.match(/(https?:\/\/.*\.(?:png|jpg|jpeg|gif))/);
|
}, [filename, content]);
|
||||||
|
|
||||||
|
const b64image = useMemo(() => {
|
||||||
|
// get base64 image from content (like: data:image/png;base64,xxxxx)
|
||||||
|
const match = content.match(/(data:image\/.*;base64,.*=)/);
|
||||||
return match ? match[0] : "";
|
return match ? match[0] : "";
|
||||||
}, [filename, content]);
|
}, [filename, content]);
|
||||||
|
|
||||||
@ -38,12 +43,16 @@ export function parseFile(data: string, acceptDownload?: boolean) {
|
|||||||
<File className={`mr-1`} />
|
<File className={`mr-1`} />
|
||||||
<span className={`name`}>{filename}</span>
|
<span className={`name`}>{filename}</span>
|
||||||
<div className={`grow`} />
|
<div className={`grow`} />
|
||||||
{image ? (
|
{image || b64image ? (
|
||||||
<Button
|
<Button
|
||||||
variant={`ghost`}
|
variant={`ghost`}
|
||||||
size={`icon`}
|
size={`icon`}
|
||||||
className={`download-action p-0 h-4 w-4`}
|
className={`download-action p-0 h-4 w-4`}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
|
if (b64image) {
|
||||||
|
saveImageAsFile(filename, b64image);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const res = await fetch(image);
|
const res = await fetch(image);
|
||||||
saveBlobAsFile(filename, await res.blob());
|
saveBlobAsFile(filename, await res.blob());
|
||||||
}}
|
}}
|
||||||
@ -57,6 +66,7 @@ export function parseFile(data: string, acceptDownload?: boolean) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{image && <img src={image} className={`file-image`} alt={""} />}
|
{image && <img src={image} className={`file-image`} alt={""} />}
|
||||||
|
{b64image && <img src={b64image} className={`file-image`} alt={""} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,9 @@ func RegisterStaticRoute(engine *gin.Engine) {
|
|||||||
// static files are in ~/app/dist
|
// static files are in ~/app/dist
|
||||||
|
|
||||||
if !viper.GetBool("serve_static") {
|
if !viper.GetBool("serve_static") {
|
||||||
|
engine.NoRoute(func(c *gin.Context) {
|
||||||
|
c.JSON(404, gin.H{"status": false, "message": "not found or method not allowed"})
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user