{
+ showImageModal(
+ data,
+ true,
+ isMobileScreen
+ ? { width: "100%", height: "fit-content" }
+ : { maxWidth: "100%", maxHeight: "100%" },
+ isMobileScreen
+ ? { width: "100%", height: "fit-content" }
+ : { width: "100%", height: "100%" },
+ );
+ }}
+ isMobileScreen={isMobileScreen}
+ />
) : item.status === "error" ? (
@@ -286,7 +249,7 @@ export function Sd() {
created_at: new Date().toLocaleString(),
img_data: "",
};
- sdStore.sendTask(reqData, sdListDb);
+ sdStore.sendTask(reqData, fileDb);
}}
/>
{
if (await showConfirm(Locale.Sd.Danger.Delete)) {
// remove img_data + remove item in list
- sdListDb.deleteRecord(item.id).then(
+ fileDb.deleteRecord(item.id).then(
() => {
sdStore.draw = sdImages.filter(
(i: any) => i.id !== item.id,
diff --git a/app/components/ui-lib.tsx b/app/components/ui-lib.tsx
index 27555105a..a859b9695 100644
--- a/app/components/ui-lib.tsx
+++ b/app/components/ui-lib.tsx
@@ -19,6 +19,7 @@ import React, {
MouseEvent,
useEffect,
useState,
+ useMemo,
} from "react";
import { IconButton } from "./button";
@@ -510,3 +511,29 @@ export function Selector(props: {
);
}
+
+export function IndexDBImage({ src, alt, onClick, db, className }) {
+ const [data, setData] = useState(src);
+ const imgId = useMemo(
+ () => src.replace("indexeddb://", "").split("@").pop(),
+ [src],
+ );
+ useEffect(() => {
+ db.getByID(imgId)
+ .then(({ data }) => {
+ setData(`data:image/png;base64,${data}`);
+ })
+ .catch((e) => {
+ setData(src);
+ });
+ }, [src, imgId]);
+
+ return (
+ onClick(data, e)}
+ />
+ );
+}
diff --git a/app/constant.ts b/app/constant.ts
index 201843e90..509b90ee0 100644
--- a/app/constant.ts
+++ b/app/constant.ts
@@ -55,6 +55,7 @@ export enum FileName {
}
export enum StoreKey {
+ File = "chat-next-web-file",
Chat = "chat-next-web-store",
Access = "access-control",
Config = "app-config",
diff --git a/app/store/sd.ts b/app/store/sd.ts
index 7218926df..77b20d001 100644
--- a/app/store/sd.ts
+++ b/app/store/sd.ts
@@ -1,33 +1,9 @@
-import { initDB } from "react-indexed-db-hook";
import { StabilityPath, StoreKey } from "@/app/constant";
import { showToast } from "@/app/components/ui-lib";
import { getHeaders } from "@/app/client/api";
import { createPersistStore } from "@/app/utils/store";
import { nanoid } from "nanoid";
-export const SdDbConfig = {
- name: "@chatgpt-next-web/sd",
- version: 1,
- objectStoresMeta: [
- {
- store: StoreKey.SdList,
- storeConfig: { keyPath: "id", autoIncrement: true },
- storeSchema: [
- { name: "data", keypath: "data", options: { unique: false } },
- {
- name: "created_at",
- keypath: "created_at",
- options: { unique: false },
- },
- ],
- },
- ],
-};
-
-export function SdDbInit() {
- initDB(SdDbConfig);
-}
-
export const useSdStore = createPersistStore<
{
currentId: number;
@@ -96,7 +72,7 @@ export const useSdStore = createPersistStore<
this.updateDraw({
...data,
status: "success",
- img_data: `indexeddb://${StoreKey.SdList}@${data.id}`,
+ img_data: `indexeddb://${StoreKey.File}@${data.id}`,
});
} else {
this.updateDraw({
diff --git a/app/utils/file.tsx b/app/utils/file.tsx
new file mode 100644
index 000000000..0e77840e4
--- /dev/null
+++ b/app/utils/file.tsx
@@ -0,0 +1,31 @@
+"use client";
+import { initDB } from "react-indexed-db-hook";
+import { StoreKey } from "@/app/constant";
+import { useIndexedDB } from "react-indexed-db-hook";
+
+export const FileDbConfig = {
+ name: "@chatgpt-next-web/file",
+ version: 1,
+ objectStoresMeta: [
+ {
+ store: StoreKey.File,
+ storeConfig: { keyPath: "id", autoIncrement: true },
+ storeSchema: [
+ { name: "data", keypath: "data", options: { unique: false } },
+ {
+ name: "created_at",
+ keypath: "created_at",
+ options: { unique: false },
+ },
+ ],
+ },
+ ],
+};
+
+export function FileDbInit() {
+ initDB(FileDbConfig);
+}
+
+export function useFileDB() {
+ return useIndexedDB(StoreKey.File);
+}