fix bun
This commit is contained in:
parent
02727d17fd
commit
e9b306e9a2
|
|
@ -0,0 +1,72 @@
|
||||||
|
import { apiContext } from "service-srv";
|
||||||
|
import argon from "@node-rs/argon2";
|
||||||
|
import { session } from "utils/session";
|
||||||
|
|
||||||
|
export const _ = {
|
||||||
|
url: "/_login",
|
||||||
|
async api(username: string, password: string) {
|
||||||
|
const { res, req } = apiContext(this);
|
||||||
|
|
||||||
|
const current = session.get(req);
|
||||||
|
|
||||||
|
if (!current) {
|
||||||
|
const user = await db.user.findFirst({
|
||||||
|
where: { OR: [{ username }, { phone: username }] },
|
||||||
|
include: {
|
||||||
|
org_user: {
|
||||||
|
select: {
|
||||||
|
org: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
org: {
|
||||||
|
select: { id: true, name: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (user && user.org_user) {
|
||||||
|
user.org = user.org_user.map((e) => e.org);
|
||||||
|
delete (user as any).org_user;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!!user && (await argon.verify(user.password, password))) {
|
||||||
|
//@ts-ignore
|
||||||
|
delete user.password;
|
||||||
|
const sdata = await session.new({ user });
|
||||||
|
|
||||||
|
let setDefaultCookie = true;
|
||||||
|
const origin = req.headers.get("origin");
|
||||||
|
if (origin) {
|
||||||
|
const url = new URL(origin);
|
||||||
|
if (url.hostname === "localhost") {
|
||||||
|
setDefaultCookie = false;
|
||||||
|
res.setHeader("set-cookie", `${session.cookieKey}=${sdata.id};`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setDefaultCookie) {
|
||||||
|
res.setHeader(
|
||||||
|
"set-cookie",
|
||||||
|
`${session.cookieKey}=${sdata.id}; SameSite=None; Secure; HttpOnly`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return { status: "ok", session: sdata };
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e, user, password);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return { status: "ok", session: current };
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: "failed",
|
||||||
|
reason: "Invalid username / password",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -1,9 +1,37 @@
|
||||||
import { apiContext } from "service-srv";
|
import { apiContext } from "service-srv";
|
||||||
|
import { session } from "utils/session";
|
||||||
|
import { user } from "dbgen";
|
||||||
|
|
||||||
export const _ = {
|
export const _ = {
|
||||||
url: "/session)}",
|
url: "/session",
|
||||||
async api() {
|
async api() {
|
||||||
const { req, res } = apiContext(this);
|
const { req, res } = apiContext(this);
|
||||||
return "This is session.ts";
|
const sdata = session.get<{
|
||||||
|
user: user & {
|
||||||
|
org: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
}>(req);
|
||||||
|
if (sdata) {
|
||||||
|
let setDefaultCookie = true;
|
||||||
|
const origin = req.headers.get("origin");
|
||||||
|
if (origin) {
|
||||||
|
const url = new URL(origin);
|
||||||
|
if (url.hostname === "localhost") {
|
||||||
|
setDefaultCookie = false;
|
||||||
|
res.setHeader("set-cookie", `${session.cookieKey}=${sdata.id};`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (setDefaultCookie) {
|
||||||
|
res.setHeader(
|
||||||
|
"set-cookie",
|
||||||
|
`${session.cookieKey}=${sdata.id}; SameSite=None; Secure; HttpOnly`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sdata;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,31 @@
|
||||||
|
declare module "api/auth/login" {
|
||||||
|
export const _: {
|
||||||
|
url: string;
|
||||||
|
api(username: string, password: string): Promise<{
|
||||||
|
status: string;
|
||||||
|
session: any;
|
||||||
|
reason?: undefined;
|
||||||
|
} | {
|
||||||
|
status: string;
|
||||||
|
reason: string;
|
||||||
|
session?: undefined;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
}
|
||||||
declare module "api/session" {
|
declare module "api/session" {
|
||||||
export const _: {
|
export const _: {
|
||||||
url: string;
|
url: string;
|
||||||
api(): Promise<string>;
|
api(): Promise<any>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
declare module "exports" {
|
declare module "exports" {
|
||||||
|
export const login: {
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
path: string;
|
||||||
|
args: string[];
|
||||||
|
handler: Promise<typeof import("api/auth/login")>;
|
||||||
|
};
|
||||||
export const session: {
|
export const session: {
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,13 @@
|
||||||
|
export const login = {
|
||||||
|
name: "login",
|
||||||
|
url: "/_login",
|
||||||
|
path: "app/srv/api/auth/login.ts",
|
||||||
|
args: ["username","password"],
|
||||||
|
handler: import("./api/auth/login")
|
||||||
|
}
|
||||||
export const session = {
|
export const session = {
|
||||||
name: "session",
|
name: "session",
|
||||||
url: "/session)}",
|
url: "/session",
|
||||||
path: "app/srv/api/session.ts",
|
path: "app/srv/api/session.ts",
|
||||||
args: [],
|
args: [],
|
||||||
handler: import("./api/session")
|
handler: import("./api/session")
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { useLocal } from "web-utils";
|
import { useLocal } from "web-utils";
|
||||||
import { FieldColor } from "../ui/FieldColor";
|
import { FieldColor } from "../ui/FieldColor";
|
||||||
import { FieldImg } from "../ui/FieldImg";
|
|
||||||
import { dropdownProp } from "../ui/style";
|
import { dropdownProp } from "../ui/style";
|
||||||
import { Button } from "../ui/Button";
|
import { Button } from "../ui/Button";
|
||||||
import { FNBackground } from "../../../../../utils/types/meta-fn";
|
import { FNBackground } from "../../../../../utils/types/meta-fn";
|
||||||
|
|
@ -53,81 +52,6 @@ export const PanelBackground: FC<{
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip asChild content={"Background Image"}>
|
|
||||||
<div
|
|
||||||
className={cx(
|
|
||||||
"bg-white p-[2px] border flex flex-1 border-gray-300",
|
|
||||||
css`
|
|
||||||
> * {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<FieldImg
|
|
||||||
value={bg.url}
|
|
||||||
update={async (url) => {
|
|
||||||
update("bg", { ...bg, url });
|
|
||||||
|
|
||||||
if (
|
|
||||||
value.type === "item" &&
|
|
||||||
(!value.dim ||
|
|
||||||
(value.dim && (!value.dim.w || value.dim.w === "fit")))
|
|
||||||
) {
|
|
||||||
const img = await getImgMeta(`${siteApiUrl}${url}`);
|
|
||||||
(update as any)("dim", {
|
|
||||||
w: Math.min(500, img?.width || 100),
|
|
||||||
h: Math.min(500, img?.height || 100),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
{bg.url ? (
|
|
||||||
<>
|
|
||||||
<Tooltip asChild content={"Unlink Image"}>
|
|
||||||
<div className={"flex flex-row bg-white"}>
|
|
||||||
<Button
|
|
||||||
className={cx(
|
|
||||||
"flex-1 flex-grow",
|
|
||||||
css`
|
|
||||||
height: 30px;
|
|
||||||
width: 20px;
|
|
||||||
max-width: 20px;
|
|
||||||
padding: 0px !important;
|
|
||||||
min-width: 0px !important;
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
onClick={(e) => {
|
|
||||||
update("bg", { ...bg, url: "" });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="w-[10px] flex items-center justify-center">
|
|
||||||
<>
|
|
||||||
<div className="text-lg text-gray-700">
|
|
||||||
<svg
|
|
||||||
width="15"
|
|
||||||
height="15"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M16.949 14.121L19.071 12a5.008 5.008 0 0 0 0-7.071a5.006 5.006 0 0 0-7.071 0l-.707.707l1.414 1.414l.707-.707a3.007 3.007 0 0 1 4.243 0a3.005 3.005 0 0 1 0 4.243l-2.122 2.121a2.723 2.723 0 0 1-.844.57L13.414 12l1.414-1.414l-.707-.707a4.965 4.965 0 0 0-3.535-1.465c-.235 0-.464.032-.691.066L3.707 2.293L2.293 3.707l18 18l1.414-1.414l-5.536-5.536c.277-.184.538-.396.778-.636zm-6.363 3.536a3.007 3.007 0 0 1-4.243 0a3.005 3.005 0 0 1 0-4.243l1.476-1.475l-1.414-1.414L4.929 12a5.008 5.008 0 0 0 0 7.071a4.983 4.983 0 0 0 3.535 1.462A4.982 4.982 0 0 0 12 19.071l.707-.707l-1.414-1.414l-.707.707z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-stretch space-x-2">
|
<div className="flex items-stretch space-x-2">
|
||||||
|
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
import { FC, useEffect } from "react";
|
|
||||||
import { useLocal } from "web-utils";
|
|
||||||
import { FilePicker } from "./FilePicker";
|
|
||||||
import { Button } from "./Button";
|
|
||||||
import { FileImageGallery } from "./FileImageGallery";
|
|
||||||
|
|
||||||
export const FieldImg: FC<{
|
|
||||||
value?: string;
|
|
||||||
update: (value: string) => void;
|
|
||||||
}> = ({ value, update }) => {
|
|
||||||
const local = useLocal({ val: "", open: false });
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
local.val = value || "";
|
|
||||||
local.render();
|
|
||||||
}, [value]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Button
|
|
||||||
className="btn-hover h-[22px]"
|
|
||||||
appearance="subtle"
|
|
||||||
onClick={() => {
|
|
||||||
local.open = true;
|
|
||||||
local.render();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Image
|
|
||||||
</Button>
|
|
||||||
{local.open && (
|
|
||||||
<FileImageGallery
|
|
||||||
value={value}
|
|
||||||
update={update}
|
|
||||||
meta={local}
|
|
||||||
onClose={() => {
|
|
||||||
local.open = false;
|
|
||||||
local.render();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1,421 +0,0 @@
|
||||||
import { FC } from "react";
|
|
||||||
import { fetchSendApi } from "web-utils/src/web/iframe-cors";
|
|
||||||
import { useGlobal, useLocal } from "web-utils";
|
|
||||||
import { Gallery } from "./Gallery";
|
|
||||||
import { Loading } from "../../../../../utils/ui/loading";
|
|
||||||
import { ToolbarBox } from "../../../../../utils/ui/box";
|
|
||||||
import { EditorGlobal } from "../../../logic/global";
|
|
||||||
export const FileImageGallery: FC<{
|
|
||||||
value?: string;
|
|
||||||
update: (src: string) => void;
|
|
||||||
onClose: () => void;
|
|
||||||
accept?: string;
|
|
||||||
type?: string;
|
|
||||||
meta?: any;
|
|
||||||
}> = ({
|
|
||||||
meta,
|
|
||||||
onClose,
|
|
||||||
update,
|
|
||||||
value,
|
|
||||||
accept = "video/mp4, image/jpeg, image/png, image/jpg, image/x-icon, image/vnd.microsoft.icon",
|
|
||||||
type = "image",
|
|
||||||
}) => {
|
|
||||||
const p = useGlobal(EditorGlobal, "EDITOR");
|
|
||||||
const local = useLocal(
|
|
||||||
{
|
|
||||||
value: value || "",
|
|
||||||
load: true,
|
|
||||||
mode: "upload",
|
|
||||||
preview: false as boolean,
|
|
||||||
previewUrl: "" as string,
|
|
||||||
isUpload: false as boolean,
|
|
||||||
selectUrl: "" as string,
|
|
||||||
},
|
|
||||||
async () => {
|
|
||||||
local.mode = "gallery";
|
|
||||||
if (local.previewUrl) {
|
|
||||||
local.selectUrl = local.previewUrl;
|
|
||||||
}
|
|
||||||
local.render();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const onUpload: React.ChangeEventHandler<HTMLInputElement> = async function (
|
|
||||||
e
|
|
||||||
) {
|
|
||||||
local.isUpload = true;
|
|
||||||
local.render();
|
|
||||||
const files = e.currentTarget.files;
|
|
||||||
if (files && p.page) {
|
|
||||||
const res: string[] = await fetchSendApi(
|
|
||||||
`${siteApiUrl}/_upload/${p.page.id}`,
|
|
||||||
files[0]
|
|
||||||
);
|
|
||||||
local.previewUrl = res[0];
|
|
||||||
local.preview = true;
|
|
||||||
local.selectUrl = local.previewUrl;
|
|
||||||
local.render();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div
|
|
||||||
className="fixed inset-0 bg-black bg-opacity-10 cursor-pointer"
|
|
||||||
onClick={() => {
|
|
||||||
meta.open = false;
|
|
||||||
meta.render();
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
<div className="fixed inset-[50px] bg-white shadow-2xl z-50 ">
|
|
||||||
{false ? (
|
|
||||||
<div className="flex w-full h-full items-center justify-center">
|
|
||||||
<Loading note="img-gallery" backdrop={false} />
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div
|
|
||||||
className={cx(
|
|
||||||
"relative w-full h-full flex flex-col items-stretch",
|
|
||||||
css`
|
|
||||||
contain: content;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
> ul {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropping {
|
|
||||||
background: #efefff;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div className="w-full flex flex-row">
|
|
||||||
<div
|
|
||||||
className={cx(
|
|
||||||
"toolbar",
|
|
||||||
"flex flex-row flex-grow px-2 justify-center items-center"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={cx(
|
|
||||||
"toolbar-right",
|
|
||||||
"flex mr-2 ",
|
|
||||||
css`
|
|
||||||
align-items: center !important;
|
|
||||||
border-bottom: 0px !important;
|
|
||||||
height: auto !important;
|
|
||||||
|
|
||||||
.toolbar-box {
|
|
||||||
height: 22px;
|
|
||||||
// margin: 0px !important;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<ToolbarBox
|
|
||||||
items={[
|
|
||||||
{
|
|
||||||
onClick() {
|
|
||||||
local.mode = "upload";
|
|
||||||
local.render();
|
|
||||||
},
|
|
||||||
className: cx(
|
|
||||||
local.mode === "upload" &&
|
|
||||||
"border-b-2 border-blue-500 bg-blue-50"
|
|
||||||
),
|
|
||||||
content: (
|
|
||||||
<>
|
|
||||||
<div className="flex flex-row items-center justify-center space-x-2">
|
|
||||||
<div className="text-lg text-gray-700">
|
|
||||||
<svg
|
|
||||||
width="15"
|
|
||||||
height="15"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="m19.21 12.04l-1.53-.11l-.3-1.5A5.484 5.484 0 0 0 12 6C9.94 6 8.08 7.14 7.12 8.96l-.5.95l-1.07.11A3.99 3.99 0 0 0 2 14c0 2.21 1.79 4 4 4h13c1.65 0 3-1.35 3-3c0-1.55-1.22-2.86-2.79-2.96zm-5.76.96v3h-2.91v-3H8l4-4l4 4h-2.55z"
|
|
||||||
opacity=".3"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M19.35 10.04A7.49 7.49 0 0 0 12 4C9.11 4 6.6 5.64 5.35 8.04A5.994 5.994 0 0 0 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5c0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4c0-2.05 1.53-3.76 3.56-3.97l1.07-.11l.5-.95A5.469 5.469 0 0 1 12 6c2.62 0 4.88 1.86 5.39 4.43l.3 1.5l1.53.11A2.98 2.98 0 0 1 22 15c0 1.65-1.35 3-3 3zM8 13h2.55v3h2.9v-3H16l-4-4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span>Upload File</span>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
onClick() {
|
|
||||||
local.mode = "gallery";
|
|
||||||
local.render();
|
|
||||||
},
|
|
||||||
className: cx(
|
|
||||||
local.mode === "gallery" &&
|
|
||||||
"border-b-2 border-blue-500 bg-blue-50"
|
|
||||||
),
|
|
||||||
content: (
|
|
||||||
<>
|
|
||||||
<div className="flex flex-row items-center justify-center space-x-2">
|
|
||||||
<div className="text-lg text-gray-700">
|
|
||||||
<svg
|
|
||||||
width="15"
|
|
||||||
height="15"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<g fill="currentColor">
|
|
||||||
<path d="M18.512 10.077c0 .738-.625 1.337-1.396 1.337c-.77 0-1.395-.599-1.395-1.337c0-.739.625-1.338 1.395-1.338s1.396.599 1.396 1.338Z" />
|
|
||||||
<path
|
|
||||||
fillRule="evenodd"
|
|
||||||
d="M18.036 5.532c-1.06-.137-2.414-.137-4.123-.136h-3.826c-1.71 0-3.064 0-4.123.136c-1.09.14-1.974.437-2.67 1.104S2.29 8.149 2.142 9.195C2 10.21 2 11.508 2 13.147v.1c0 1.64 0 2.937.142 3.953c.147 1.046.456 1.892 1.152 2.559c.696.667 1.58.963 2.67 1.104c1.06.136 2.414.136 4.123.136h3.826c1.71 0 3.064 0 4.123-.136c1.09-.14 1.974-.437 2.67-1.104s1.005-1.514 1.152-2.559C22 16.184 22 14.886 22 13.248v-.1c0-1.64 0-2.937-.142-3.953c-.147-1.046-.456-1.892-1.152-2.559c-.696-.667-1.58-.963-2.67-1.104ZM6.15 6.858c-.936.12-1.475.346-1.87.724c-.393.377-.629.894-.755 1.791c-.1.72-.123 1.619-.128 2.795l.47-.395c1.125-.942 2.819-.888 3.875.124l3.99 3.825a1.2 1.2 0 0 0 1.491.124l.278-.187a3.606 3.606 0 0 1 4.34.25l2.407 2.077c.098-.264.173-.579.227-.964c.128-.916.13-2.124.13-3.824c0-1.7-.002-2.909-.13-3.825c-.126-.897-.362-1.414-.756-1.791c-.393-.378-.933-.604-1.869-.724c-.956-.124-2.216-.125-3.99-.125h-3.72c-1.774 0-3.034.001-3.99.125Z"
|
|
||||||
clipRule="evenodd"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M17.087 2.61c-.86-.11-1.955-.11-3.32-.11h-3.09c-1.364 0-2.459 0-3.318.11c-.89.115-1.633.358-2.222.92a2.9 2.9 0 0 0-.724 1.12c.504-.23 1.074-.366 1.714-.45c1.085-.14 2.47-.14 4.22-.14h3.915c1.749 0 3.134 0 4.219.14c.559.073 1.064.186 1.52.366a2.875 2.875 0 0 0-.693-1.035c-.589-.563-1.331-.806-2.221-.92Z"
|
|
||||||
opacity=".5"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<span>Gallery</span>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* <ResponsiveToggle /> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex-grow flex flex-col">
|
|
||||||
{local.mode === "gallery" ? (
|
|
||||||
<>
|
|
||||||
<Gallery value={value} update={update} meta={local} />
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<div className="flex flex-row items-center relative px-2 py-4 space-x-4 justify-center flex-1">
|
|
||||||
<div className="relative flex flex-row p-2 cursor-pointer bg-blue-500 text-white">
|
|
||||||
<span>Upload Image</span>
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
name="file"
|
|
||||||
className={cx(
|
|
||||||
"absolute inset-0 opacity-0 cursor-pointer w-full h-full"
|
|
||||||
)}
|
|
||||||
accept={accept}
|
|
||||||
onChange={onUpload}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-row flex-grow items-center justify-center px-2 py-4 space-x-4">
|
|
||||||
{local.preview ? (
|
|
||||||
<>
|
|
||||||
<div
|
|
||||||
className={cx(
|
|
||||||
"border-2 rounded mx-2 flex flex-row flex-grow h-full items-center justify-center px-2 py-4 space-x-4",
|
|
||||||
css`
|
|
||||||
background-image: linear-gradient(
|
|
||||||
45deg,
|
|
||||||
#d1d1d1 25%,
|
|
||||||
transparent 25%
|
|
||||||
),
|
|
||||||
linear-gradient(
|
|
||||||
-45deg,
|
|
||||||
#d1d1d1 25%,
|
|
||||||
transparent 25%
|
|
||||||
),
|
|
||||||
linear-gradient(
|
|
||||||
45deg,
|
|
||||||
transparent 75%,
|
|
||||||
#d1d1d1 75%
|
|
||||||
),
|
|
||||||
linear-gradient(
|
|
||||||
-45deg,
|
|
||||||
transparent 75%,
|
|
||||||
#d1d1d1 75%
|
|
||||||
);
|
|
||||||
background-size: 20px 20px;
|
|
||||||
background-position: 0 0, 0 10px, 10px -10px,
|
|
||||||
-10px 0px;
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href={`${siteApiUrl}${local.previewUrl}`}
|
|
||||||
className={cx(
|
|
||||||
"bg-no-repeat bg-contain bg-center rounded mx-2 flex flex-row flex-grow h-full items-center justify-center px-2 py-4 space-x-4",
|
|
||||||
css`
|
|
||||||
background-image: url("${siteApiUrl}${local.previewUrl}");
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
></a>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
{local.isUpload ? (
|
|
||||||
<>
|
|
||||||
<div
|
|
||||||
className={cx(
|
|
||||||
"border-2 rounded mx-2 flex flex-row flex-grow h-full items-center justify-center px-2 py-4 space-x-4"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div className="flex flex-col space-y-2">
|
|
||||||
<div className="text-lg text-gray-700">
|
|
||||||
<svg
|
|
||||||
width="150"
|
|
||||||
height="150"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<mask id="lineMdCloudUploadOutlineLoop0">
|
|
||||||
<g fill="#fff">
|
|
||||||
<circle cx="12" cy="10" r="6" />
|
|
||||||
<rect
|
|
||||||
width="9"
|
|
||||||
height="8"
|
|
||||||
x="8"
|
|
||||||
y="12"
|
|
||||||
/>
|
|
||||||
<rect
|
|
||||||
width="17"
|
|
||||||
height="12"
|
|
||||||
x="1"
|
|
||||||
y="8"
|
|
||||||
rx="6"
|
|
||||||
>
|
|
||||||
<animate
|
|
||||||
attributeName="x"
|
|
||||||
dur="24s"
|
|
||||||
repeatCount="indefinite"
|
|
||||||
values="1;0;1;2;1"
|
|
||||||
/>
|
|
||||||
</rect>
|
|
||||||
<rect
|
|
||||||
width="17"
|
|
||||||
height="10"
|
|
||||||
x="6"
|
|
||||||
y="10"
|
|
||||||
rx="5"
|
|
||||||
>
|
|
||||||
<animate
|
|
||||||
attributeName="x"
|
|
||||||
dur="15s"
|
|
||||||
repeatCount="indefinite"
|
|
||||||
values="6;5;6;7;6"
|
|
||||||
/>
|
|
||||||
</rect>
|
|
||||||
</g>
|
|
||||||
<circle cx="12" cy="10" r="4" />
|
|
||||||
<rect width="8" height="8" x="8" y="10" />
|
|
||||||
<rect
|
|
||||||
width="11"
|
|
||||||
height="8"
|
|
||||||
x="3"
|
|
||||||
y="10"
|
|
||||||
rx="4"
|
|
||||||
>
|
|
||||||
<animate
|
|
||||||
attributeName="x"
|
|
||||||
dur="24s"
|
|
||||||
repeatCount="indefinite"
|
|
||||||
values="3;2;3;4;3"
|
|
||||||
/>
|
|
||||||
</rect>
|
|
||||||
<rect
|
|
||||||
width="13"
|
|
||||||
height="6"
|
|
||||||
x="8"
|
|
||||||
y="12"
|
|
||||||
rx="3"
|
|
||||||
>
|
|
||||||
<animate
|
|
||||||
attributeName="x"
|
|
||||||
dur="15s"
|
|
||||||
repeatCount="indefinite"
|
|
||||||
values="8;7;8;9;8"
|
|
||||||
/>
|
|
||||||
</rect>
|
|
||||||
<g fill="#fff">
|
|
||||||
<rect
|
|
||||||
width="3"
|
|
||||||
height="4"
|
|
||||||
x="10.5"
|
|
||||||
y="12"
|
|
||||||
/>
|
|
||||||
<path d="M12 9L16 13H8L12 9Z">
|
|
||||||
<animateMotion
|
|
||||||
calcMode="linear"
|
|
||||||
dur="1.5s"
|
|
||||||
keyPoints="0;0.25;0.5;0.75;1"
|
|
||||||
keyTimes="0;0.1;0.5;0.8;1"
|
|
||||||
path="M0 0v-1v2z"
|
|
||||||
repeatCount="indefinite"
|
|
||||||
/>
|
|
||||||
</path>
|
|
||||||
</g>
|
|
||||||
</mask>
|
|
||||||
<rect
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
fill="currentColor"
|
|
||||||
mask="url(#lineMdCloudUploadOutlineLoop0)"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-row space-x-2 items-center justify-center text-xl">
|
|
||||||
<span className="flex flex-row space-x-2">
|
|
||||||
Uploading...
|
|
||||||
</span>
|
|
||||||
{/* <span className="flex flex-row space-x-2 font-medium">
|
|
||||||
10%
|
|
||||||
</span> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{local.selectUrl && (
|
|
||||||
<div className="border-t-2 flex flex-row items-center justify-end p-4">
|
|
||||||
<div
|
|
||||||
onClick={() => {
|
|
||||||
// FieldImg;
|
|
||||||
update(local.selectUrl);
|
|
||||||
meta.open = false;
|
|
||||||
meta.render();
|
|
||||||
}}
|
|
||||||
className="relative flex flex-row p-2 cursor-pointer bg-blue-500 text-white font-medium px-6"
|
|
||||||
>
|
|
||||||
<span>Choose Image</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
import { FC, useTransition } from "react";
|
|
||||||
import { fetchSendApi } from "web-utils/src/web/iframe-cors";
|
|
||||||
import { useLocal } from "web-utils";
|
|
||||||
import { Button } from "./Button";
|
|
||||||
export const FilePicker: FC<{
|
|
||||||
value?: string;
|
|
||||||
update: (src: string) => void;
|
|
||||||
onClose: () => void;
|
|
||||||
accept?: string;
|
|
||||||
type?: string;
|
|
||||||
}> = ({
|
|
||||||
onClose,
|
|
||||||
update,
|
|
||||||
value,
|
|
||||||
accept = "video/mp4, image/jpeg, image/png, image/jpg, image/x-icon, image/vnd.microsoft.icon",
|
|
||||||
type = "image",
|
|
||||||
}) => {
|
|
||||||
const local = useLocal({
|
|
||||||
value: value || "",
|
|
||||||
load: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const [_, tx] = useTransition();
|
|
||||||
const onUpload: React.ChangeEventHandler<HTMLInputElement> = async function (
|
|
||||||
e
|
|
||||||
) {
|
|
||||||
const files = e.currentTarget.files;
|
|
||||||
if (files) {
|
|
||||||
// const res: string[] = (await fetchSendApi(
|
|
||||||
// `${siteApiUrl}/_upload${site ? `/${site.id}` : ""}`,
|
|
||||||
// files[0]
|
|
||||||
// )) as any;
|
|
||||||
// if (res) {
|
|
||||||
// const val = res[0];
|
|
||||||
// local.value = val;
|
|
||||||
// local.render();
|
|
||||||
// update(val);
|
|
||||||
// }
|
|
||||||
// onClose();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="flex flex-col items-stretch space-y-2 flex-1">
|
|
||||||
<div className="flex-1 flex flex-col relative">
|
|
||||||
<div className="absolute inset-0 flex overflow-hidden pointer-events-none items-center text-center justify-center">
|
|
||||||
{local.load && local.value && (
|
|
||||||
<div className={cx("self-center")}>Loading</div>
|
|
||||||
)}
|
|
||||||
{!!local.value ? (
|
|
||||||
<>
|
|
||||||
{type === "image" && (
|
|
||||||
<img
|
|
||||||
src={
|
|
||||||
local.value.startsWith("http")
|
|
||||||
? local.value
|
|
||||||
: `${siteApiUrl}${local.value}?w=500&h=500&fit=contain`
|
|
||||||
}
|
|
||||||
className={cx(
|
|
||||||
css`
|
|
||||||
visibility: "visible";
|
|
||||||
max-height: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
`,
|
|
||||||
"self-center"
|
|
||||||
)}
|
|
||||||
onLoad={() => {
|
|
||||||
local.load = false;
|
|
||||||
local.render();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{type === "pdf" && (
|
|
||||||
<div className=" text-9xl text-green-600 pb-8">
|
|
||||||
<PdfDocument />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<div className="flex flex-col items-center">
|
|
||||||
<span>Please Upload Image</span>
|
|
||||||
<i className="italic"> — or —</i>
|
|
||||||
<span>Fill Image URL</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
name="file"
|
|
||||||
className={cx("absolute inset-0 opacity-0")}
|
|
||||||
accept={accept}
|
|
||||||
onChange={onUpload}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
value={local.value}
|
|
||||||
spellCheck={false}
|
|
||||||
placeholder="Image URL"
|
|
||||||
onChange={(e) => {
|
|
||||||
local.value = e.currentTarget.value;
|
|
||||||
local.render();
|
|
||||||
|
|
||||||
tx(() => {
|
|
||||||
update(local.value);
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div className="flex justify-between">
|
|
||||||
<input type="file" name="file" accept={accept} onChange={onUpload} />
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
local.value = "";
|
|
||||||
local.render();
|
|
||||||
|
|
||||||
tx(() => {
|
|
||||||
update(local.value);
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Clear
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const PdfDocument = () => (
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="11"
|
|
||||||
height="11"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 100 125"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
<path
|
|
||||||
fill="#000"
|
|
||||||
fillRule="evenodd"
|
|
||||||
d="M58.993 32A2.992 2.992 0 0156 29.007V4H19.666A3.665 3.665 0 0016 7.668v82.664A3.674 3.674 0 0019.68 94h60.64A3.683 3.683 0 0084 90.322V32H58.993zm6.919 35.403c-.544.274-1.36.549-2.448.549-2.176 0-5.44-.549-8.16-1.92-4.624.549-8.16 1.097-10.88 2.194-.272 0-.272 0-.544.274-3.264 5.758-5.984 8.5-8.16 8.5-.544 0-.816 0-1.088-.274l-1.36-.823v-.274C33 75.081 33 74.806 33 74.259c.272-1.372 1.904-3.84 5.168-5.759.544-.274 1.36-.823 2.448-1.371.816-1.37 1.632-3.016 2.72-4.935 1.36-2.742 2.176-5.484 2.992-7.952-1.088-3.29-1.632-5.21-.544-9.048C46.056 44.097 46.872 43 47.96 43h.544c.544 0 1.088.274 1.632.548 1.904 1.92 1.088 6.307 0 9.871v.275c1.088 3.016 2.72 5.483 4.352 7.129.816.548 1.36 1.096 2.448 1.645 1.36 0 2.448-.274 3.536-.274 3.264 0 5.44.548 6.256 1.919.272.548.272 1.097.272 1.645-.272.274-.544 1.097-1.088 1.645zM48.232 56.71c-.544 1.919-1.632 4.113-2.72 6.58-.544 1.097-1.088 1.92-1.632 3.016h.544c3.536-1.37 6.8-2.193 8.976-2.467-.544-.274-.816-.549-1.088-.823-1.36-1.645-2.992-3.839-4.08-6.306zm16.592 8.5c-.272-.275-1.36-1.097-5.168-1.097h-.544v.274c1.904.823 3.808 1.371 5.168 1.371H65.096v-.274s-.272 0-.272-.274zM39.8 69.323c-.544.274-1.088.548-1.36.822-1.904 1.645-3.264 3.565-3.536 4.387 1.632-.274 3.264-1.92 4.896-5.21zm8.16-18.92c.272-1.097.544-1.645.544-2.468v-.548c.272-1.37.272-2.468 0-2.742v-.274l-.272-.274s0 .274-.272.274c-.544 1.645-.544 3.564 0 6.032zM84 28H62.005A2.005 2.005 0 0160 25.995V4l24 24z"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
|
|
@ -1,268 +0,0 @@
|
||||||
import { format } from "date-fns";
|
|
||||||
import get from "lodash.get";
|
|
||||||
import { FC, useTransition } from "react";
|
|
||||||
import { fetchSendApi } from "web-utils/src/web/iframe-cors";
|
|
||||||
import { useGlobal, useLocal } from "web-utils";
|
|
||||||
import { Loading } from "../../../../../utils/ui/loading";
|
|
||||||
import { EditorGlobal } from "../../../logic/global";
|
|
||||||
export const Gallery: FC<{
|
|
||||||
value?: string;
|
|
||||||
update: (src: string) => void;
|
|
||||||
onClose?: () => void;
|
|
||||||
accept?: string;
|
|
||||||
type?: string;
|
|
||||||
meta?: any;
|
|
||||||
}> = ({
|
|
||||||
meta,
|
|
||||||
onClose,
|
|
||||||
update,
|
|
||||||
value,
|
|
||||||
accept = "video/mp4, image/jpeg, image/png, image/jpg, image/x-icon, image/vnd.microsoft.icon",
|
|
||||||
type = "image",
|
|
||||||
}) => {
|
|
||||||
const p = useGlobal(EditorGlobal, "EDITOR");
|
|
||||||
const local = useLocal(
|
|
||||||
{
|
|
||||||
value: value || "",
|
|
||||||
load: true,
|
|
||||||
mode: "upload",
|
|
||||||
list: [] as Array<any>,
|
|
||||||
ready: false,
|
|
||||||
isPreview: false,
|
|
||||||
hover: null as any,
|
|
||||||
preview: {
|
|
||||||
url: "" as string,
|
|
||||||
dimension: {
|
|
||||||
width: 0 as number,
|
|
||||||
height: 0 as number,
|
|
||||||
},
|
|
||||||
details: null as any,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
async () => {
|
|
||||||
local.isPreview = false;
|
|
||||||
local.ready = false;
|
|
||||||
local.render();
|
|
||||||
if (p.page) {
|
|
||||||
let res = (await fetchSendApi(
|
|
||||||
`${siteApiUrl}/get-gallery/${p.page.id}`,
|
|
||||||
{}
|
|
||||||
)) as any;
|
|
||||||
local.list = res.data;
|
|
||||||
}
|
|
||||||
local.ready = true;
|
|
||||||
local.render();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const [_, tx] = useTransition();
|
|
||||||
const getSize = (size: number) => {
|
|
||||||
let hz = "";
|
|
||||||
if (size < 1024) hz = size + " B";
|
|
||||||
else if (size < 1024 * 1024) hz = (size / 1024).toFixed(2) + " KB";
|
|
||||||
else if (size < 1024 * 1024 * 1024)
|
|
||||||
hz = (size / 1024 / 1024).toFixed(2) + " MB";
|
|
||||||
else hz = (size / 1024 / 1024 / 1024).toFixed(2) + " GB";
|
|
||||||
return hz;
|
|
||||||
};
|
|
||||||
const loadImage: any = (imageSrc: any) =>
|
|
||||||
new Promise((resolve) => {
|
|
||||||
const image = new Image();
|
|
||||||
image.onload = () => {
|
|
||||||
const height = image.height;
|
|
||||||
const width = image.width;
|
|
||||||
resolve({ image, width, height });
|
|
||||||
};
|
|
||||||
image.src = imageSrc;
|
|
||||||
});
|
|
||||||
const onUpload: React.ChangeEventHandler<HTMLInputElement> = async function (
|
|
||||||
e
|
|
||||||
) {
|
|
||||||
const files = e.currentTarget.files;
|
|
||||||
if (files) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{local.ready ? (
|
|
||||||
<>
|
|
||||||
<div className="flex flex-row flex-grow w-full">
|
|
||||||
<div className="flex flex-row flex-grow">
|
|
||||||
<div className="flex-row flex p-2 relative flex-grow overflow-auto">
|
|
||||||
<div
|
|
||||||
className={cx(
|
|
||||||
"flex items-start flex-wrap pl-[10px] absolute w-full h-full top-0 left-0"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
{local.list.length ? (
|
|
||||||
<>
|
|
||||||
{local.list.map((e, idx) => {
|
|
||||||
const bgurl = `${siteApiUrl}${get(e, "url")}`;
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={e.url}
|
|
||||||
className={cx(
|
|
||||||
"relative flex flex-col items-start w-[200px] h-[100px] p-2 text-sm cursor-pointer hover:bg-blue-100 ml-1 mb-1",
|
|
||||||
"justify-between transition-all",
|
|
||||||
"hover:border-blue-500",
|
|
||||||
"bg-no-repeat bg-cover bg-center",
|
|
||||||
local.preview.url ===
|
|
||||||
`${siteApiUrl}${get(e, "url")}`
|
|
||||||
? "border-4 border-blue-500 shadow-xl"
|
|
||||||
: "border",
|
|
||||||
css`
|
|
||||||
background-image: url("${bgurl}");
|
|
||||||
.edit {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.edit {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
onClick={async () => {
|
|
||||||
const { width, height } = await loadImage(
|
|
||||||
`${siteApiUrl}${get(e, "url")}`
|
|
||||||
);
|
|
||||||
local.preview = {
|
|
||||||
url: `${siteApiUrl}${get(e, "url")}`,
|
|
||||||
dimension: {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
},
|
|
||||||
details: e,
|
|
||||||
};
|
|
||||||
local.isPreview = true;
|
|
||||||
meta.selectUrl = `${siteApiUrl}${get(e, "url")}`;
|
|
||||||
meta.render();
|
|
||||||
}}
|
|
||||||
onMouseEnter={() => {
|
|
||||||
local.hover = `${siteApiUrl}${get(e, "url")}`;
|
|
||||||
local.render();
|
|
||||||
}}
|
|
||||||
onMouseLeave={() => {
|
|
||||||
local.hover = null;
|
|
||||||
local.render();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="flex flex-row flex-grow items-end justify-end">
|
|
||||||
{local.hover ===
|
|
||||||
`${siteApiUrl}${get(e, "url")}` ? (
|
|
||||||
<>
|
|
||||||
{" "}
|
|
||||||
<div
|
|
||||||
onClick={async (ev) => {
|
|
||||||
ev.preventDefault();
|
|
||||||
ev.stopPropagation();
|
|
||||||
await fetchSendApi(
|
|
||||||
`${siteApiUrl}/_delete`,
|
|
||||||
{
|
|
||||||
path: get(e, "path"),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
let list = local.list.filter(
|
|
||||||
(x) => get(x, "path") !== get(e, "path")
|
|
||||||
);
|
|
||||||
local.list = list;
|
|
||||||
local.render();
|
|
||||||
}}
|
|
||||||
className="relative flex flex-row p-2 cursor-pointer bg-red-500 rounded font-medium"
|
|
||||||
>
|
|
||||||
<div className="text-lg text-gray-700">
|
|
||||||
<svg
|
|
||||||
width="15"
|
|
||||||
height="15"
|
|
||||||
viewBox="0 0 28 28"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M11.5 6h5a2.5 2.5 0 0 0-5 0ZM10 6a4 4 0 0 1 8 0h6.25a.75.75 0 0 1 0 1.5h-1.31l-1.217 14.603A4.25 4.25 0 0 1 17.488 26h-6.976a4.25 4.25 0 0 1-4.235-3.897L5.06 7.5H3.75a.75.75 0 0 1 0-1.5H10ZM7.772 21.978a2.75 2.75 0 0 0 2.74 2.522h6.976a2.75 2.75 0 0 0 2.74-2.522L21.436 7.5H6.565l1.207 14.478ZM11.75 11a.75.75 0 0 1 .75.75v8.5a.75.75 0 0 1-1.5 0v-8.5a.75.75 0 0 1 .75-.75Zm5.25.75a.75.75 0 0 0-1.5 0v8.5a.75.75 0 0 0 1.5 0v-8.5Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>No Image</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{local.isPreview ? (
|
|
||||||
<>
|
|
||||||
<div className="border-l-2 w-1/4 flex flex-col">
|
|
||||||
<a
|
|
||||||
href={`${local.preview.url}`}
|
|
||||||
className={cx(
|
|
||||||
"border-2 rounded m-2 flex flex-row items-center justify-center space-x-4 h-[200px]",
|
|
||||||
css`
|
|
||||||
background-image: linear-gradient(
|
|
||||||
45deg,
|
|
||||||
#d1d1d1 25%,
|
|
||||||
transparent 25%
|
|
||||||
),
|
|
||||||
linear-gradient(-45deg, #d1d1d1 25%, transparent 25%),
|
|
||||||
linear-gradient(45deg, transparent 75%, #d1d1d1 75%),
|
|
||||||
linear-gradient(-45deg, transparent 75%, #d1d1d1 75%);
|
|
||||||
background-size: 20px 20px;
|
|
||||||
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={cx(
|
|
||||||
"bg-no-repeat bg-contain bg-center rounded flex flex-row flex-grow h-full items-center justify-center space-x-4",
|
|
||||||
css`
|
|
||||||
background-image: url("${local.preview.url}");
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
></div>
|
|
||||||
</a>
|
|
||||||
<p className="text-sm px-2">
|
|
||||||
Dimension:{" "}
|
|
||||||
<span>{`${local.preview.dimension.width} x ${local.preview.dimension.height}`}</span>{" "}
|
|
||||||
</p>
|
|
||||||
<p className="text-sm px-2">
|
|
||||||
File Size:{" "}
|
|
||||||
<span>{getSize(local.preview.details.size)}</span>
|
|
||||||
</p>
|
|
||||||
<p className="text-sm px-2">
|
|
||||||
Last Modified:{" "}
|
|
||||||
<span>
|
|
||||||
{format(
|
|
||||||
new Date(local.preview.details.detail.mtime),
|
|
||||||
"d MMMM yyyy"
|
|
||||||
)}
|
|
||||||
</span>{" "}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<div className="flex w-full h-full items-center justify-center">
|
|
||||||
<Loading note="gallery" backdrop={false} />
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -19,5 +19,5 @@
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "^5.0.0"
|
"typescript": "^5.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {}
|
"dependencies": { "@node-rs/argon2": "^1.5.2" }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -165,34 +165,25 @@ export const createFrameCors = async (url: string, win?: any) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchSendApi = async (
|
export const fetchSendApi = async (
|
||||||
_url: string,
|
rawUrl: string,
|
||||||
params: any,
|
params: any,
|
||||||
parentWindow?: any
|
parentWindow?: any
|
||||||
) => {
|
) => {
|
||||||
let w: any = typeof window === "object" ? window : globalThis;
|
let w: any = typeof window === "object" ? window : globalThis;
|
||||||
|
|
||||||
const win = parentWindow || w;
|
const win = parentWindow || w;
|
||||||
let url = _url;
|
const url = new URL(rawUrl);
|
||||||
let frm: Awaited<ReturnType<typeof createFrameCors>>;
|
let frm: Awaited<ReturnType<typeof createFrameCors>>;
|
||||||
|
|
||||||
|
const base = `${url.protocol}//${url.host}`;
|
||||||
|
|
||||||
if (!win.frmapi) {
|
if (!win.frmapi) {
|
||||||
win.frmapi = {};
|
win.frmapi = {};
|
||||||
|
win.frmapi[base] = await createFrameCors(base, win);
|
||||||
win.frmapi[w.serverurl] = await createFrameCors(w.serverurl, win);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
frm = win.frmapi[w.serverurl];
|
frm = win.frmapi[base];
|
||||||
|
|
||||||
if (url.startsWith("http")) {
|
|
||||||
const purl = new URL(url);
|
|
||||||
if (!win.frmapi[purl.host]) {
|
|
||||||
win.frmapi[purl.host] = await createFrameCors(
|
|
||||||
`${purl.protocol}//${purl.host}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
frm = win.frmapi[purl.host];
|
|
||||||
url = url.substring(`${purl.protocol}//${purl.host}`.length);
|
|
||||||
}
|
|
||||||
if (!win.apiHeaders) {
|
if (!win.apiHeaders) {
|
||||||
win.apiHeaders = {};
|
win.apiHeaders = {};
|
||||||
}
|
}
|
||||||
|
|
@ -204,5 +195,5 @@ export const fetchSendApi = async (
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return await frm.send(url, params, win.apiHeaders);
|
return await frm.send(url.pathname, params, win.apiHeaders);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue