From 3db98ac6cb0e65e2e7ad02870df881be0fb6dca4 Mon Sep 17 00:00:00 2001
From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com>
Date: Tue, 5 Sep 2023 08:49:19 +0300
Subject: [PATCH] Footnote fixpack (#208)
* Footnote hotfixies
---
src/components/Article/Article.module.scss | 18 ++++++++++---
src/components/Article/FullArticle.tsx | 7 ++++-
src/components/Editor/Editor.tsx | 14 ++++++++--
src/components/Editor/Prosemirror.scss | 3 +++
.../Editor/SimplifiedEditor.module.scss | 5 ++++
src/components/Editor/SimplifiedEditor.tsx | 7 ++++-
.../TextBubbleMenu/TextBubbleMenu.module.scss | 2 ++
.../Editor/TextBubbleMenu/TextBubbleMenu.tsx | 26 ++++++++++++++-----
src/components/Editor/extensions/Footnote.ts | 9 +------
9 files changed, 69 insertions(+), 22 deletions(-)
diff --git a/src/components/Article/Article.module.scss b/src/components/Article/Article.module.scss
index d5287d23..7916cc50 100644
--- a/src/components/Article/Article.module.scss
+++ b/src/components/Article/Article.module.scss
@@ -562,10 +562,22 @@ a[data-toggle='tooltip'] {
max-width: 400px;
box-sizing: border-box;
background: var(--black-500);
- color: var(--default-color-invert);
- p:last-child {
- margin: 0;
+ .tooltipContent {
+ max-height: 300px;
+ overflow: auto;
+
+ & * {
+ color: var(--default-color-invert);
+ }
+
+ a {
+ text-decoration: underline;
+ }
+
+ p:last-child {
+ margin: 0;
+ }
}
&::after {
diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx
index 473d2efa..f9d45e29 100644
--- a/src/components/Article/FullArticle.tsx
+++ b/src/components/Article/FullArticle.tsx
@@ -138,7 +138,12 @@ export const FullArticle = (props: Props) => {
tooltipElements.forEach((element) => {
const tooltip = document.createElement('div')
tooltip.classList.add(styles.tooltip)
- tooltip.innerHTML = element.dataset.originalTitle || element.dataset.value
+ const tooltipContent = document.createElement('div')
+ tooltipContent.classList.add(styles.tooltipContent)
+ tooltipContent.innerHTML = element.dataset.originalTitle || element.dataset.value
+
+ tooltip.appendChild(tooltipContent)
+
document.body.appendChild(tooltip)
if (element.tagName === 'a') {
element.setAttribute('href', 'javascript: void(0);')
diff --git a/src/components/Editor/Editor.tsx b/src/components/Editor/Editor.tsx
index 6b71be56..1118bdab 100644
--- a/src/components/Editor/Editor.tsx
+++ b/src/components/Editor/Editor.tsx
@@ -1,4 +1,4 @@
-import { createEffect, createSignal, Show } from 'solid-js'
+import { createEffect, createSignal, onCleanup, Show } from 'solid-js'
import { createTiptapEditor, useEditorHTML } from 'solid-tiptap'
import uniqolor from 'uniqolor'
import * as Y from 'yjs'
@@ -63,6 +63,7 @@ export const Editor = (props: Props) => {
const { user } = useSession()
const [isCommonMarkup, setIsCommonMarkup] = createSignal(false)
+ const [shouldShowTextBubbleMenu, setShouldShowTextBubbleMenu] = createSignal(false)
const docName = `shout-${props.shoutId}`
@@ -185,7 +186,11 @@ export const Editor = (props: Props) => {
const { empty } = selection
const isEmptyTextBlock = doc.textBetween(from, to).length === 0 && isTextSelection(selection)
setIsCommonMarkup(e.isActive('figcaption'))
- return view.hasFocus() && !empty && !isEmptyTextBlock && !e.isActive('image')
+ const result =
+ (view.hasFocus() && !empty && !isEmptyTextBlock && !e.isActive('image')) ||
+ e.isActive('footnote')
+ setShouldShowTextBubbleMenu(result)
+ return result
},
tippyOptions: {
sticky: true
@@ -246,6 +251,10 @@ export const Editor = (props: Props) => {
}
})
+ onCleanup(() => {
+ editor().destroy()
+ })
+
return (
<>
@@ -256,6 +265,7 @@ export const Editor = (props: Props) => {
(textBubbleMenuRef.current = el)}
diff --git a/src/components/Editor/Prosemirror.scss b/src/components/Editor/Prosemirror.scss
index e9ab8c8e..91367d48 100644
--- a/src/components/Editor/Prosemirror.scss
+++ b/src/components/Editor/Prosemirror.scss
@@ -263,6 +263,9 @@ footnote {
display: inline-flex;
position: relative;
cursor: pointer;
+ width: 0.8rem;
+ height: 1em;
+
&:before {
content: '';
position: absolute;
diff --git a/src/components/Editor/SimplifiedEditor.module.scss b/src/components/Editor/SimplifiedEditor.module.scss
index 7f774dc9..81312dc0 100644
--- a/src/components/Editor/SimplifiedEditor.module.scss
+++ b/src/components/Editor/SimplifiedEditor.module.scss
@@ -55,6 +55,11 @@
bottom: -1rem;
transition: 0.3s ease-in-out;
+ &.alwaysVisible {
+ opacity: unset;
+ bottom: unset;
+ }
+
.actions {
display: flex;
align-items: center;
diff --git a/src/components/Editor/SimplifiedEditor.tsx b/src/components/Editor/SimplifiedEditor.tsx
index f8fd3939..b5576994 100644
--- a/src/components/Editor/SimplifiedEditor.tsx
+++ b/src/components/Editor/SimplifiedEditor.tsx
@@ -52,9 +52,11 @@ type Props = {
submitByEnter?: boolean
submitByShiftEnter?: boolean
onlyBubbleControls?: boolean
+ controlsAlwaysVisible?: boolean
}
export const MAX_DESCRIPTION_LIMIT = 400
+
const SimplifiedEditor = (props: Props) => {
const { t } = useLocalize()
const [counter, setCounter] = createSignal()
@@ -217,6 +219,7 @@ const SimplifiedEditor = (props: Props) => {
})
onCleanup(() => {
+ editor().destroy()
window.removeEventListener('keydown', handleKeyDown)
})
@@ -233,6 +236,7 @@ const SimplifiedEditor = (props: Props) => {
setCounter(editor().storage.characterCount.characters())
}
})
+
return (
(wrapperEditorElRef.current = el)}
@@ -252,7 +256,7 @@ const SimplifiedEditor = (props: Props) => {
(editorElRef.current = el)} />
-
+
{(triggerRef: (el) => void) => (
@@ -350,6 +354,7 @@ const SimplifiedEditor = (props: Props) => {
(textBubbleMenuRef.current = el)}
diff --git a/src/components/Editor/TextBubbleMenu/TextBubbleMenu.module.scss b/src/components/Editor/TextBubbleMenu/TextBubbleMenu.module.scss
index 9f022771..e6b15233 100644
--- a/src/components/Editor/TextBubbleMenu/TextBubbleMenu.module.scss
+++ b/src/components/Editor/TextBubbleMenu/TextBubbleMenu.module.scss
@@ -1,6 +1,8 @@
.TextBubbleMenu {
background: var(--editor-bubble-menu-background);
box-shadow: 0 4px 10px rgba(#000, 0.25);
+ max-height: 300px;
+ overflow: auto;
&.growWidth {
min-width: 460px;
diff --git a/src/components/Editor/TextBubbleMenu/TextBubbleMenu.tsx b/src/components/Editor/TextBubbleMenu/TextBubbleMenu.tsx
index 65b91f4a..c384fc0a 100644
--- a/src/components/Editor/TextBubbleMenu/TextBubbleMenu.tsx
+++ b/src/components/Editor/TextBubbleMenu/TextBubbleMenu.tsx
@@ -8,13 +8,12 @@ import { useLocalize } from '../../../context/localize'
import { Popover } from '../../_shared/Popover'
import { InsertLinkForm } from '../InsertLinkForm'
import SimplifiedEditor from '../SimplifiedEditor'
-import { Button } from '../../_shared/Button'
-import { showModal } from '../../../stores/ui'
type BubbleMenuProps = {
editor: Editor
isCommonMarkup: boolean
ref: (el: HTMLDivElement) => void
+ shouldShow: boolean
}
export const TextBubbleMenu = (props: BubbleMenuProps) => {
@@ -32,6 +31,13 @@ export const TextBubbleMenu = (props: BubbleMenuProps) => {
const [footnoteEditorOpen, setFootnoteEditorOpen] = createSignal(false)
const [footNote, setFootNote] = createSignal()
+ createEffect(() => {
+ if (!props.shouldShow) {
+ setFootNote()
+ setFootnoteEditorOpen(false)
+ }
+ })
+
const isBold = isActive('bold')
const isItalic = isActive('italic')
const isH1 = isActive('heading', { level: 2 })
@@ -65,9 +71,15 @@ export const TextBubbleMenu = (props: BubbleMenuProps) => {
}
}
- const currentFootnoteValue = createEditorTransaction(
+ const updateCurrentFootnoteValue = createEditorTransaction(
() => props.editor,
- (ed) => (ed && ed.getAttributes('footnote').value) || ''
+ (ed) => {
+ if (!isFootnote()) {
+ return
+ }
+ const value = ed.getAttributes('footnote').value
+ setFootNote(value)
+ }
)
const handleAddFootnote = (footnote) => {
@@ -81,7 +93,7 @@ export const TextBubbleMenu = (props: BubbleMenuProps) => {
}
const handleOpenFootnoteEditor = () => {
- setFootNote(currentFootnoteValue())
+ updateCurrentFootnoteValue()
setFootnoteEditorOpen(true)
}
@@ -100,13 +112,13 @@ export const TextBubbleMenu = (props: BubbleMenuProps) => {
setLinkEditorOpen(false)} />
-