mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-08-29 10:09:26 +02:00
editor: allow any width/height value in EmbedSizeOptions when inserting embed (#9925)
* editor: allow any width/height value in EmbedSizeOptions when inserting embeds * editor: only accept valid url as value * editor: allow embeding normal website urls * editor: check url if embedSource=url * editor: use defaultValue prop for width/height
This commit is contained in:
@@ -17,17 +17,17 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Flex, Text } from "@theme-ui/components";
|
||||
import { useCallback, useState } from "react";
|
||||
import { Popup } from "../components/popup.js";
|
||||
import { Input, Textarea } from "@theme-ui/components";
|
||||
import { Embed, EmbedSizeOptions } from "../../extensions/embed/index.js";
|
||||
import { convertUrlToEmbedUrl } from "@social-embed/lib";
|
||||
import { InlineInput } from "../../components/inline-input/index.js";
|
||||
import { Tabs, Tab } from "../../components/tabs/index.js";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { convertUrlToEmbedUrl, isValidUrl } from "@social-embed/lib";
|
||||
import { Flex, Input, Text, Textarea } from "@theme-ui/components";
|
||||
import { useCallback, useState } from "react";
|
||||
import { InlineInput } from "../../components/inline-input/index.js";
|
||||
import { Tab, Tabs } from "../../components/tabs/index.js";
|
||||
import { Embed, EmbedSizeOptions } from "../../extensions/embed/index.js";
|
||||
import { Popup } from "../components/popup.js";
|
||||
|
||||
type EmbedSource = "url" | "code";
|
||||
|
||||
export type EmbedPopupProps = {
|
||||
onClose: (embed?: Embed) => void;
|
||||
title: string;
|
||||
@@ -38,33 +38,30 @@ export type EmbedPopupProps = {
|
||||
|
||||
export function EmbedPopup(props: EmbedPopupProps) {
|
||||
const { onClose, onSizeChanged, title, embed } = props;
|
||||
const [width, setWidth] = useState(embed?.width || 300);
|
||||
const [height, setHeight] = useState(embed?.height || 150);
|
||||
const [src, setSrc] = useState(embed?.src || "");
|
||||
const [embedSource, setEmbedSource] = useState<EmbedSource>("url");
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [size, setSize] = useState<EmbedSizeOptions>({
|
||||
width: embed?.width || 300,
|
||||
height: embed?.height || 150
|
||||
});
|
||||
|
||||
const onSizeChange = useCallback(
|
||||
(newWidth?: number, newHeight?: number) => {
|
||||
const size: EmbedSizeOptions = newWidth
|
||||
? {
|
||||
width: newWidth,
|
||||
height: newWidth * (height / width)
|
||||
}
|
||||
: newHeight
|
||||
? {
|
||||
width: newHeight * (width / height),
|
||||
height: newHeight
|
||||
}
|
||||
: {
|
||||
width: 0,
|
||||
height: 0
|
||||
};
|
||||
setWidth(size.width);
|
||||
setHeight(size.height);
|
||||
if (onSizeChanged) onSizeChanged(size);
|
||||
const hasNewWidth = Number.isFinite(newWidth);
|
||||
const hasNewHeight = Number.isFinite(newHeight);
|
||||
|
||||
if (!hasNewWidth && !hasNewHeight) return;
|
||||
setSize((size) => {
|
||||
const newSize = {
|
||||
width: hasNewWidth ? ((newWidth || 0) as number) : size.width,
|
||||
height: hasNewHeight ? ((newHeight || 0) as number) : size.height
|
||||
};
|
||||
if (onSizeChanged) onSizeChanged(newSize);
|
||||
return newSize;
|
||||
});
|
||||
},
|
||||
[height, width, onSizeChanged]
|
||||
[onSizeChanged]
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -77,8 +74,9 @@ export function EmbedPopup(props: EmbedPopupProps) {
|
||||
onClick: () => {
|
||||
setError(null);
|
||||
let _src = src;
|
||||
let _width = width;
|
||||
let _height = height;
|
||||
let _width = size.width;
|
||||
let _height = size.height;
|
||||
|
||||
if (embedSource === "code") {
|
||||
const document = new DOMParser().parseFromString(src, "text/html");
|
||||
if (document.getElementsByTagName("iframe").length <= 0)
|
||||
@@ -100,8 +98,19 @@ export function EmbedPopup(props: EmbedPopupProps) {
|
||||
if (heightValue && !isNaN(parseInt(heightValue)))
|
||||
_height = parseInt(heightValue);
|
||||
}
|
||||
|
||||
if (embedSource === "url" && !isValidUrl(src)) {
|
||||
return setError("Please provide a valid url.");
|
||||
}
|
||||
|
||||
const convertedUrl = convertUrlToEmbedUrl(_src);
|
||||
|
||||
if (convertedUrl) _src = convertedUrl;
|
||||
|
||||
if (!_src && embedSource === "url") {
|
||||
return setError("Please provide a valid embed url.");
|
||||
}
|
||||
|
||||
if (_src.startsWith("javascript:")) {
|
||||
return setError("Embedding javascript code is not supported.");
|
||||
}
|
||||
@@ -147,7 +156,7 @@ export function EmbedPopup(props: EmbedPopupProps) {
|
||||
label="width"
|
||||
type="number"
|
||||
placeholder={strings.width()}
|
||||
value={width}
|
||||
defaultValue={size.width}
|
||||
sx={{
|
||||
mr: 1,
|
||||
fontSize: "body"
|
||||
@@ -158,7 +167,7 @@ export function EmbedPopup(props: EmbedPopupProps) {
|
||||
label="height"
|
||||
type="number"
|
||||
placeholder={strings.height()}
|
||||
value={height}
|
||||
defaultValue={size.height}
|
||||
sx={{ fontSize: "body" }}
|
||||
onChange={(e) =>
|
||||
onSizeChange(undefined, e.target.valueAsNumber)
|
||||
|
||||
Reference in New Issue
Block a user