alinea
Version:
Headless git-based CMS
224 lines (220 loc) • 8.05 kB
JavaScript
import {
dist_default
} from "../../../chunks/chunk-A5O3N2GS.js";
import {
useAtomValue
} from "../../../chunks/chunk-TOJF2G3X.js";
import "../../../chunks/chunk-WJ67RR7S.js";
import {
v
} from "../../../chunks/chunk-76QF5YTJ.js";
import {
prettyBytes
} from "../../../chunks/chunk-HRTN3UQ6.js";
import "../../../chunks/chunk-NZLE2WMY.js";
// src/dashboard/view/media/FileEntry.tsx
import { Config } from "alinea/core/Config";
import { isImage } from "alinea/core/media/IsImage";
import { MEDIA_LOCATION } from "alinea/core/media/MediaLocation";
import { outcome } from "alinea/core/Outcome";
import { Typo } from "alinea/ui";
import { Lift } from "alinea/ui/Lift";
import { Main } from "alinea/ui/Main";
import { Property } from "alinea/ui/Property";
import { useState } from "react";
import { FormProvider } from "../../atoms/FormAtoms.js";
import { InputField } from "../../editor/InputForm.js";
import { useField } from "../../editor/UseField.js";
import { useConfig } from "../../hook/UseConfig.js";
import { useNav } from "../../hook/UseNav.js";
import { EntryHeader } from "../entry/EntryHeader.js";
import { EntryTitle } from "../entry/EntryTitle.js";
// src/dashboard/view/media/FileEntry.module.scss
var FileEntry_module_default = {
"root": "alinea-FileEntry",
"image": "alinea-FileEntry-image",
"image-wrapper": "alinea-FileEntry-image-wrapper",
"imageWrapper": "alinea-FileEntry-image-wrapper",
"image-preview": "alinea-FileEntry-image-preview",
"imagePreview": "alinea-FileEntry-image-preview",
"image-preview-focus": "alinea-FileEntry-image-preview-focus",
"imagePreviewFocus": "alinea-FileEntry-image-preview-focus",
"image-preview-img": "alinea-FileEntry-image-preview-img",
"imagePreviewImg": "alinea-FileEntry-image-preview-img",
"image-content": "alinea-FileEntry-image-content",
"imageContent": "alinea-FileEntry-image-content",
"image-content-url": "alinea-FileEntry-image-content-url",
"imageContentUrl": "alinea-FileEntry-image-content-url"
};
// src/dashboard/view/media/FileEntry.tsx
import { jsx, jsxs } from "react/jsx-runtime";
var styles = dist_default(FileEntry_module_default);
function ImageView({ type, editor }) {
const config = useConfig();
const image = editor.activeVersion;
const { value: focus = { x: 0.5, y: 0.5 }, mutator: setFocus } = useField(
type.focus
);
const [hover, setHover] = useState({});
const { x: focusX = focus.x, y: focusY = focus.y } = hover;
const location = image.data.location;
const [liveUrl] = outcome(
() => new URL(location, Config.baseUrl(config) ?? window.location.href)
);
return /* @__PURE__ */ jsxs(Lift, { className: styles.image(), children: [
/* @__PURE__ */ jsx(
"div",
{
className: styles.image.wrapper(),
style: {
backgroundImage: image.data.averageColor && `linear-gradient(45deg, ${v(
image.data.averageColor,
0.6
)} 0%, ${v(image.data.averageColor, 0.8)} 100%)`
},
children: /* @__PURE__ */ jsxs(
"div",
{
className: styles.image.preview(),
onMouseMove: (event) => {
const rect = event.currentTarget.getBoundingClientRect();
const x = (event.clientX - rect.left) / rect.width;
const y = (event.clientY - rect.top) / rect.height;
setHover({ x, y });
},
onMouseOut: () => setHover({}),
onBlur: () => setHover({}),
onClick: (event) => {
event.preventDefault();
const rect = event.currentTarget.getBoundingClientRect();
const x = (event.clientX - rect.left) / rect.width;
const y = (event.clientY - rect.top) / rect.height;
setFocus({ x, y });
},
children: [
/* @__PURE__ */ jsx(
"img",
{
className: styles.image.preview.img(),
src: image.data.preview,
alt: "Preview of media file"
}
),
/* @__PURE__ */ jsx(
"span",
{
className: styles.image.preview.focus(),
style: {
left: `${focus.x * 100}%`,
top: `${focus.y * 100}%`
}
}
)
]
}
)
}
),
/* @__PURE__ */ jsxs("div", { className: styles.image.content(), children: [
/* @__PURE__ */ jsx(InputField, { field: type.title }),
/* @__PURE__ */ jsx(Property, { label: "Extension", children: image.data.extension }),
/* @__PURE__ */ jsx(Property, { label: "File size", children: prettyBytes(image.data.size) }),
/* @__PURE__ */ jsxs(Property, { label: "Dimensions", children: [
image.data.width,
" x ",
image.data.height,
" pixels"
] }),
/* @__PURE__ */ jsx(Property, { label: "URL", children: /* @__PURE__ */ jsx(
"a",
{
href: liveUrl ? String(liveUrl) : location,
target: "_blank",
title: location,
className: styles.image.content.url(),
children: /* @__PURE__ */ jsx(Typo.Monospace, { children: location })
}
) }),
/* @__PURE__ */ jsxs(
Property,
{
label: "Focus point",
help: "Click on the image to change the focus point",
children: [
"(",
focusX.toFixed(2),
", ",
focusY.toFixed(2),
")"
]
}
)
] })
] });
}
function IcTwotonePinDrop() {
return /* @__PURE__ */ jsxs(
"svg",
{
width: "1em",
height: "1em",
viewBox: "0 0 24 16",
style: { display: "block" },
children: [
/* @__PURE__ */ jsx(
"path",
{
fill: "var(--alinea-background)",
d: "M12 3C9.19 3 6 5.11 6 9.13c0 2.68 2 5.49 6 8.44c4-2.95 6-5.77 6-8.44C18 5.11 14.81 3 12 3z"
}
),
/* @__PURE__ */ jsx(
"path",
{
fill: "var(--alinea-foreground)",
d: "M12 4c1.93 0 5 1.4 5 5.15c0 2.16-1.72 4.67-5 7.32c-3.28-2.65-5-5.17-5-7.32C7 5.4 10.07 4 12 4m0-2C8.73 2 5 4.46 5 9.15c0 3.12 2.33 6.41 7 9.85c4.67-3.44 7-6.73 7-9.85C19 4.46 15.27 2 12 2z"
}
),
/* @__PURE__ */ jsx(
"path",
{
fill: "var(--alinea-foreground)",
d: "M12 7c-1.1 0-2 .9-2 2s.9 2 2 2s2-.9 2-2s-.9-2-2-2z"
}
)
]
}
);
}
function FileView({ type, editor }) {
const file = editor.activeVersion;
return /* @__PURE__ */ jsxs(Lift, { children: [
/* @__PURE__ */ jsx(InputField, { field: type.title }),
/* @__PURE__ */ jsx(Property, { label: "Extension", children: file.data.extension }),
/* @__PURE__ */ jsx(Property, { label: "File size", children: prettyBytes(file.data.size) }),
/* @__PURE__ */ jsx(Property, { label: "URL", children: /* @__PURE__ */ jsx(Typo.Monospace, { children: MEDIA_LOCATION in file.data ? file.data[MEDIA_LOCATION] : file.data.location }) })
] });
}
function FileEntry(props) {
const nav = useNav();
const { editor } = props;
const form = useAtomValue(editor.form);
return /* @__PURE__ */ jsxs(Main, { className: styles.root(), children: [
/* @__PURE__ */ jsx(EntryHeader, { editor }),
/* @__PURE__ */ jsx(
EntryTitle,
{
editor,
backLink: editor.activeVersion.parentId ? nav.entry({
id: editor.activeVersion.parentId,
workspace: editor.activeVersion.workspace
}) : nav.entry({ id: void 0 })
}
),
/* @__PURE__ */ jsx(FormProvider, { form, children: /* @__PURE__ */ jsx(Main.Container, { children: isImage(editor.activeVersion.data.extension) ? /* @__PURE__ */ jsx(ImageView, { ...props }) : /* @__PURE__ */ jsx(FileView, { ...props }) }) })
] });
}
export {
FileEntry,
IcTwotonePinDrop
};