Merge remote-tracking branch 'gitlab/dev' into drafts

This commit is contained in:
bniwredyc 2023-05-04 19:42:39 +02:00
commit 378fc65955
10 changed files with 43 additions and 24 deletions

View File

@ -39,6 +39,7 @@ import { TextBubbleMenu } from './TextBubbleMenu'
import { ImageBubbleMenu } from './ImageBubbleMenu' import { ImageBubbleMenu } from './ImageBubbleMenu'
import { EditorFloatingMenu } from './EditorFloatingMenu' import { EditorFloatingMenu } from './EditorFloatingMenu'
import { useEditorContext } from '../../context/editor' import { useEditorContext } from '../../context/editor'
import { isTextSelection } from '@tiptap/core'
type EditorProps = { type EditorProps = {
shoutId: number shoutId: number
@ -147,17 +148,21 @@ export const Editor = (props: EditorProps) => {
CharacterCount, CharacterCount,
BubbleMenu.configure({ BubbleMenu.configure({
pluginKey: 'textBubbleMenu', pluginKey: 'textBubbleMenu',
element: textBubbleMenuRef.current element: textBubbleMenuRef.current,
// shouldShow: ({ editor: e, view, state, oldState, from, to }) => { shouldShow: ({ editor: e, view, state, oldState, from, to }) => {
// console.log('!!! e:', view) const { doc, selection } = state
// return !e.isActive('image') const { empty } = selection
// }
const isEmptyTextBlock = doc.textBetween(from, to).length === 0 && isTextSelection(selection)
return !(!view.hasFocus() || empty || isEmptyTextBlock || e.isActive('image'))
}
}), }),
BubbleMenu.configure({ BubbleMenu.configure({
pluginKey: 'imageBubbleMenu', pluginKey: 'imageBubbleMenu',
element: imageBubbleMenuRef.current, element: imageBubbleMenuRef.current,
shouldShow: ({ editor: e, view, state, oldState, from, to }) => { shouldShow: ({ editor: e, view, state, oldState, from, to }) => {
return e.isFocused && e.isActive('image') return view.hasFocus() && e.isActive('image')
} }
}), }),
FloatingMenu.configure({ FloatingMenu.configure({

View File

@ -15,9 +15,9 @@
.menuHolder { .menuHolder {
background: #fff; background: #fff;
left: calc(100% + 1rem); left: 40px;
position: absolute; position: absolute;
top: -0.8rem; top: -0.4rem;
min-width: 64vw; min-width: 64vw;
} }
} }

View File

@ -32,7 +32,7 @@ const validateEmbed = async (value) => {
export const EditorFloatingMenu = (props: FloatingMenuProps) => { export const EditorFloatingMenu = (props: FloatingMenuProps) => {
const { t } = useLocalize() const { t } = useLocalize()
const [selectedMenuItem, setSelectedMenuItem] = createSignal<MenuItem | null>(null) const [selectedMenuItem, setSelectedMenuItem] = createSignal<MenuItem | undefined>()
const [menuOpen, setMenuOpen] = createSignal<boolean>(false) const [menuOpen, setMenuOpen] = createSignal<boolean>(false)
const handleEmbedFormSubmit = async (value: string) => { const handleEmbedFormSubmit = async (value: string) => {
// TODO: add support instagram embed (blockquote) // TODO: add support instagram embed (blockquote)
@ -53,14 +53,19 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => {
} }
}) })
const closeUploadModalHandler = () => { const closeUploadModalHandler = () => {
setSelectedMenuItem(null) setSelectedMenuItem()
setMenuOpen(false) setMenuOpen(false)
} }
return ( return (
<> <>
<div ref={props.ref} class={styles.editorFloatingMenu}> <div ref={props.ref} class={styles.editorFloatingMenu}>
<button type="button" onClick={() => setMenuOpen(!menuOpen())}> <button
type="button"
onClick={() => {
setMenuOpen(!menuOpen())
}}
>
<Icon name="editor-plus" /> <Icon name="editor-plus" />
</button> </button>
<Show when={menuOpen()}> <Show when={menuOpen()}>
@ -73,7 +78,7 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => {
placeholder={t('Paste Embed code')} placeholder={t('Paste Embed code')}
showInput={true} showInput={true}
onClose={closeUploadModalHandler} onClose={closeUploadModalHandler}
onClear={() => setSelectedMenuItem(null)} onClear={() => setSelectedMenuItem()}
validate={validateEmbed} validate={validateEmbed}
onSubmit={handleEmbedFormSubmit} onSubmit={handleEmbedFormSubmit}
errorMessage={t('Error')} errorMessage={t('Error')}
@ -83,7 +88,7 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => {
</Show> </Show>
</div> </div>
<Modal variant="narrow" name="uploadImage" onClose={closeUploadModalHandler}> <Modal variant="narrow" name="uploadImage" onClose={closeUploadModalHandler}>
<UploadModalContent closeCallback={() => setSelectedMenuItem(null)} editor={props.editor} /> <UploadModalContent closeCallback={() => setSelectedMenuItem()} editor={props.editor} />
</Modal> </Modal>
</> </>
) )

View File

@ -2,6 +2,7 @@ import styles from './Menu.module.scss'
import { Icon } from '../../../_shared/Icon' import { Icon } from '../../../_shared/Icon'
export type MenuItem = 'image' | 'embed' | 'horizontal-rule' export type MenuItem = 'image' | 'embed' | 'horizontal-rule'
type Props = { type Props = {
selectedItem: (value: string) => void selectedItem: (value: string) => void
} }

View File

@ -11,6 +11,7 @@ import { useLocalize } from '../../../context/localize'
import { Editor } from '@tiptap/core' import { Editor } from '@tiptap/core'
import { Loading } from '../../_shared/Loading' import { Loading } from '../../_shared/Loading'
import { verifyImg } from '../../../utils/verifyImg' import { verifyImg } from '../../../utils/verifyImg'
import { imageProxy } from '../../../utils/imageProxy'
type Props = { type Props = {
editor: Editor editor: Editor
@ -29,7 +30,7 @@ export const UploadModalContent = (props: Props) => {
.chain() .chain()
.focus() .focus()
.extendMarkRange('link') .extendMarkRange('link')
.setImage({ src: `https://new.discours.io/api/image?url=${src}` }) .setImage({ src: imageProxy(src) })
.run() .run()
hideModal() hideModal()
} }
@ -43,6 +44,7 @@ export const UploadModalContent = (props: Props) => {
setIsUploading(true) setIsUploading(true)
const fileUrl = await handleFileUpload(file) const fileUrl = await handleFileUpload(file)
setIsUploading(false) setIsUploading(false)
props.closeCallback()
renderImage(fileUrl) renderImage(fileUrl)
} catch (error) { } catch (error) {
console.error('[upload image] error', error) console.error('[upload image] error', error)

View File

@ -1,4 +1,4 @@
import { createSignal, For } from 'solid-js' import { For } from 'solid-js'
import type { Author } from '../../../graphql/types.gen' import type { Author } from '../../../graphql/types.gen'
import { useAuthorsStore } from '../../../stores/zine/authors' import { useAuthorsStore } from '../../../stores/zine/authors'
import { Icon } from '../../_shared/Icon' import { Icon } from '../../_shared/Icon'
@ -29,10 +29,6 @@ export const Sidebar = (props: FeedSidebarProps) => {
const { articlesByTopic } = useArticlesStore() const { articlesByTopic } = useArticlesStore()
const { topicEntities } = useTopicsStore() const { topicEntities } = useTopicsStore()
createSignal(() => {
console.log('!!! topicEntities:', topicEntities())
})
const checkTopicIsSeen = (topicSlug: string) => { const checkTopicIsSeen = (topicSlug: string) => {
return articlesByTopic()[topicSlug]?.every((article) => Boolean(seen()[article.slug])) return articlesByTopic()[topicSlug]?.every((article) => Boolean(seen()[article.slug]))
} }

View File

@ -484,11 +484,15 @@
width: 100%; width: 100%;
} }
} }
.icon {
display: inline-flex;
align-items: center;
justify-content: center;
img { img {
height: 20px; height: 20px;
vertical-align: middle; width: auto;
width: auto; }
} }
.textLabel { .textLabel {

View File

@ -5,6 +5,7 @@
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: block;
} }
} }

View File

@ -1,8 +1,9 @@
import { splitProps } from 'solid-js' import { splitProps } from 'solid-js'
import type { JSX } from 'solid-js' import type { JSX } from 'solid-js'
import { imageProxy } from '../../../utils/imageProxy'
export const Image = (props: JSX.ImgHTMLAttributes<HTMLImageElement>) => { export const Image = (props: JSX.ImgHTMLAttributes<HTMLImageElement>) => {
const [local, others] = splitProps(props, ['src']) const [local, others] = splitProps(props, ['src'])
return <img src={`/api/image?url=${encodeURI(local.src)}`} {...others} /> return <img src={imageProxy(local.src)} {...others} />
} }

4
src/utils/imageProxy.ts Normal file
View File

@ -0,0 +1,4 @@
import { isDev } from './config'
export const imageProxy = (url: string) => {
return `${isDev ? 'https://new.discours.io' : ''}/api/image?url=${encodeURI(url)}`
}