diff --git a/public/icons/editor-horizontal-rule.svg b/public/icons/editor-horizontal-rule.svg new file mode 100644 index 00000000..3349d421 --- /dev/null +++ b/public/icons/editor-horizontal-rule.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/components/Editor/Editor.tsx b/src/components/Editor/Editor.tsx index 23e012ae..7663c803 100644 --- a/src/components/Editor/Editor.tsx +++ b/src/components/Editor/Editor.tsx @@ -151,11 +151,7 @@ export const Editor = (props: EditorProps) => { const isEmptyTextBlock = doc.textBetween(from, to).length === 0 && isTextSelection(selection) - if (!view.hasFocus() || empty || isEmptyTextBlock || e.isActive('image')) { - return false - } - - return true + return !(!view.hasFocus() || empty || isEmptyTextBlock || e.isActive('image')) } }), BubbleMenu.configure({ diff --git a/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.module.scss b/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.module.scss index e6078156..83d6bdbd 100644 --- a/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.module.scss +++ b/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.module.scss @@ -12,10 +12,10 @@ opacity: 1; } } + .menuHolder { background: #fff; left: calc(100% + 1rem); - box-shadow: 0 4px 10px rgba(#000, 0.25); position: absolute; top: -0.8rem; min-width: 64vw; diff --git a/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx b/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx index 23f916b9..30d91a07 100644 --- a/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx +++ b/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx @@ -7,6 +7,7 @@ import HTMLParser from 'html-to-json-parser' import { useLocalize } from '../../../context/localize' import { Modal } from '../../Nav/Modal' import { Menu } from './Menu' +import type { MenuItem } from './Menu/Menu' import { showModal } from '../../../stores/ui' import { UploadModalContent } from '../UploadModal' @@ -31,7 +32,7 @@ const validateEmbed = async (value) => { export const EditorFloatingMenu = (props: FloatingMenuProps) => { const { t } = useLocalize() - const [selectedMenuItem, setSelectedMenuItem] = createSignal(null) + const [selectedMenuItem, setSelectedMenuItem] = createSignal(null) const [menuOpen, setMenuOpen] = createSignal(false) const handleEmbedFormSubmit = async (value: string) => { // TODO: add support instagram embed (blockquote) @@ -40,8 +41,15 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => { } createEffect(() => { - if (selectedMenuItem() === 'image') { - showModal('uploadImage') + switch (selectedMenuItem()) { + case 'image': { + showModal('uploadImage') + return + } + case 'horizontal-rule': { + props.editor.chain().focus().setHorizontalRule().run() + return + } } }) const closeUploadModalHandler = () => { @@ -58,7 +66,7 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => {
- setSelectedMenuItem(value)} /> + setSelectedMenuItem(value)} /> void } export const Menu = (props: Props) => { + const setSelectedMenuItem = (value: MenuItem) => { + props.selectedItem(value) + } + return (
- - +
) } diff --git a/src/components/Editor/Prosemirror.scss b/src/components/Editor/Prosemirror.scss index 28885985..535d96f4 100644 --- a/src/components/Editor/Prosemirror.scss +++ b/src/components/Editor/Prosemirror.scss @@ -68,3 +68,7 @@ display: block; width: unset !important; } + +.horizontalRule { + border-top: 2px solid #000; +} diff --git a/src/components/Editor/UploadModal/UploadModalContent.tsx b/src/components/Editor/UploadModal/UploadModalContent.tsx index 7abd8424..004de8aa 100644 --- a/src/components/Editor/UploadModal/UploadModalContent.tsx +++ b/src/components/Editor/UploadModal/UploadModalContent.tsx @@ -11,6 +11,7 @@ import { useLocalize } from '../../../context/localize' import { Editor } from '@tiptap/core' import { Loading } from '../../_shared/Loading' import { verifyImg } from '../../../utils/verifyImg' +import { imageProxy } from '../../../utils/imageProxy' type Props = { editor: Editor @@ -29,7 +30,7 @@ export const UploadModalContent = (props: Props) => { .chain() .focus() .extendMarkRange('link') - .setImage({ src: `/api/image?url=${src}` }) + .setImage({ src: imageProxy(src) }) .run() hideModal() } diff --git a/src/components/_shared/Image/Image.tsx b/src/components/_shared/Image/Image.tsx index a4a6f88b..fa957458 100644 --- a/src/components/_shared/Image/Image.tsx +++ b/src/components/_shared/Image/Image.tsx @@ -1,8 +1,9 @@ import { splitProps } from 'solid-js' import type { JSX } from 'solid-js' +import { imageProxy } from '../../../utils/imageProxy' export const Image = (props: JSX.ImgHTMLAttributes) => { const [local, others] = splitProps(props, ['src']) - return + return } diff --git a/src/styles/app.scss b/src/styles/app.scss index 9a22667e..ee5b68f0 100644 --- a/src/styles/app.scss +++ b/src/styles/app.scss @@ -677,7 +677,7 @@ figcaption { .main-content { flex: 1 100%; - min-height: 300px; + min-height: 90vh; padding-top: 120px; position: relative; } diff --git a/src/utils/imageProxy.ts b/src/utils/imageProxy.ts new file mode 100644 index 00000000..3e069019 --- /dev/null +++ b/src/utils/imageProxy.ts @@ -0,0 +1,4 @@ +import { isDev } from './config' +export const imageProxy = (url: string) => { + return `${isDev ? 'https://new.discours.io' : ''}/api/image?url=${encodeURI(url)}` +}