Skip to content

Commit 79ea3c8

Browse files
authored
Media Embed Parsing And Links Fixes (#278)
#278 * media embed parsing fixed, snippets setting array in list fixes * Open node path fixed from highlight, remove tag in highlight * Multiple calls on clicking Add Tag in Shortener fixed * Changeset added
1 parent b147d0a commit 79ea3c8

File tree

18 files changed

+142
-121
lines changed

18 files changed

+142
-121
lines changed

.changeset/curvy-months-provide.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'mexit': patch
3+
'mexit-webapp': patch
4+
---
5+
6+
Bulk snippets, Media embed URL fixed

apps/extension/src/Components/Sidebar/ContextInfoBar.tsx

+2-21
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,8 @@
1-
import React, { useEffect, useMemo, useRef, useState } from 'react'
1+
import React, { useMemo } from 'react'
22

3-
import edit2Line from '@iconify/icons-ri/edit-2-line'
4-
import linkM from '@iconify/icons-ri/link-m'
5-
import searchLine from '@iconify/icons-ri/search-line'
6-
import { Icon } from '@iconify/react'
7-
import fuzzysort from 'fuzzysort'
8-
import { debounce, reduce } from 'lodash'
9-
10-
import { Infobox } from '@workduck-io/mex-components'
11-
12-
import { mog, SingleHighlight, SourceHighlights } from '@mexit/core'
13-
import {
14-
SnippetCards,
15-
SidebarListFilterWrapper,
16-
SidebarListFilter,
17-
Input,
18-
SnippetSidebarHelp,
19-
HighlightSidebarHelp,
20-
CenteredFlex
21-
} from '@mexit/shared'
3+
import { SnippetCards, CenteredFlex } from '@mexit/shared'
224

235
import { useHighlightStore } from '../../Stores/useHighlightStore'
24-
import { getElementById } from '../../contentScript'
256
import { GenericCard } from './GenericCard'
267
import { HighlightGroups } from './HighlightGroup'
278
import { ShortenerComponent } from './ShortenerComponent'

apps/extension/src/Components/Sidebar/HighlightGroup.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export const HighlightGroups = ({ highlights }: { highlights: SourceHighlights }
5656
const { getPathFromNodeid } = useLinks()
5757

5858
const openNote = (nodeid: string) => {
59-
window.open(`${MEXIT_FRONTEND_URL_BASE}/node/${nodeid}`, '_blank')
59+
window.open(`${MEXIT_FRONTEND_URL_BASE}/editor/${nodeid}`, '_blank')
6060
}
6161

6262
return (

apps/extension/src/Components/Sidebar/ShortenerComponent.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export const ShortenerComponent = () => {
121121
<TagsLabel
122122
tags={tags}
123123
onClick={() => console.log('clicked on tags')}
124-
onDelete={(val: string) => console.log('link delete', val)}
124+
onDelete={(val: string) => onRemoveTag(val)}
125125
/>
126126
</ShortenerWrapper>
127127
)

apps/extension/src/Editor/plugins/index.tsx

+5-28
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,13 @@ import {
4040
ELEMENT_H5,
4141
ELEMENT_H6,
4242
ELEMENT_PARAGRAPH,
43-
createTablePlugin,
44-
parseIframeUrl,
45-
parseTwitterUrl,
46-
MediaEmbedTweet,
47-
parseVideoUrl,
48-
MediaEmbedVideo
43+
createTablePlugin
4944
} from '@udecode/plate'
5045

46+
import { useAuth } from '@workduck-io/dwindle'
47+
5148
import { ELEMENT_EXCALIDRAW } from '@mexit/core'
52-
import { MediaIFrame, parseRestMediaUrls, TableWrapper, useUploadToCDN } from '@mexit/shared'
49+
import { TableWrapper, useUploadToCDN } from '@mexit/shared'
5350

5451
import { createQuickLinkPlugin } from './QuickLink'
5552
import { createBlockModifierPlugin } from './createBlockModifierPlugin'
@@ -64,7 +61,6 @@ import {
6461
optionsSelectOnBackspacePlugin,
6562
optionsSoftBreakPlugin
6663
} from './options'
67-
import { useAuth } from '@workduck-io/dwindle'
6864

6965
export type PluginOptionType = {
7066
exclude: {
@@ -157,26 +153,7 @@ export const generatePlugins = (options: PluginOptionType) => {
157153
// createDeserializeMDPlugin(),
158154

159155
// Media and link embed
160-
createMediaEmbedPlugin({
161-
options: {
162-
transformUrl: parseIframeUrl,
163-
rules: [
164-
// {
165-
// parser: parseTwitterUrl,
166-
// component: MediaEmbedTweet
167-
// },
168-
{
169-
parser: parseVideoUrl,
170-
component: MediaEmbedVideo
171-
},
172-
{
173-
parser: parseRestMediaUrls,
174-
component: MediaIFrame
175-
}
176-
]
177-
}
178-
}),
179-
156+
createMediaEmbedPlugin(),
180157
// Custom Plugins
181158
// createBlurSelectionPlugin() ,
182159

apps/webapp/src/Actions/Components/Shortener.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export const Shortener = () => {
143143
<Label>Add an Alias</Label>
144144
<Input placeholder="Shorcut" value={short} onChange={(event) => setShort(getValidTitle(event.target.value))} />
145145
</InputRow>
146-
<LoadingButton loading={isLoading} onClick={onShortenLinkSubmit} type="submit">
146+
<LoadingButton id="mex-save-shortened-url" loading={isLoading} type="submit">
147147
Save
148148
</LoadingButton>
149149
</Form>

apps/webapp/src/Components/CreateTodoModal/TaskEditor/plugins.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import {
2020
createPlugins,
2121
createSingleLinePlugin,
2222
parseIframeUrl,
23-
parseTwitterUrl,
2423
MediaEmbedVideo,
2524
parseVideoUrl,
2625
MediaEmbedTweet
@@ -46,6 +45,7 @@ import { createMentionPlugin } from '../../../Editor/Plugins/createMentionsPlugi
4645
import { createTagPlugin } from '../../../Editor/Plugins/createTagPlugin'
4746
import { createTodoPlugin } from '../../../Editor/Plugins/createTodoPlugin'
4847
import { optionsCreateNodeIdPlugin, optionsSelectOnBackspacePlugin } from '../../../Editor/Plugins/options'
48+
import { parseTwitterUrl } from '../../../Editor/Plugins/parseTwitterUrl'
4949
import Todo from '../../Todo'
5050

5151
const generateTodoPlugins = (uploadImage?: UploadImageFn) => {

apps/webapp/src/Components/Sidebar/SnippetList.tsx

+4-10
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,7 @@ const SnippetList = () => {
2525

2626
const sortedSnippets = React.useMemo(() => {
2727
return snippets
28-
.sort((a, b) => {
29-
if (a.title < b.title) {
30-
return -1
31-
}
32-
if (a.title > b.title) {
33-
return 1
34-
}
35-
return 0
36-
})
28+
.sort((a, b) => (a.title < b.title ? 1 : -1))
3729
.map((snippet) => ({
3830
id: snippet.id,
3931
label: snippet.title,
@@ -42,9 +34,11 @@ const SnippetList = () => {
4234
}))
4335
}, [snippets])
4436

37+
mog('Snippets', { sortedSnippets, snippets })
38+
4539
return (
4640
<SidebarWrapper>
47-
<SidebarHeaderLite title="Snippets" icon={quillPenLine} />
41+
<SidebarHeaderLite title={`Snippets (${snippets.length})`} icon={quillPenLine} />
4842
<SidebarList
4943
items={sortedSnippets}
5044
onClick={onOpenSnippet}

apps/webapp/src/Editor/Components/Combobox/index.tsx

+19-19
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
import React, { useCallback, useEffect, useState } from 'react'
22

3+
import { shift, offset, flip } from '@floating-ui/react-dom-interactions'
34
import { Icon } from '@iconify/react'
45
import useMergedRef from '@react-hook/merged-ref'
5-
import { getPlateEditorRef, getRangeBoundingClientRect, PortalBody, useEditorState, usePlateEditorRef, useVirtualFloating } from '@udecode/plate'
6+
import {
7+
getPlateEditorRef,
8+
getRangeBoundingClientRect,
9+
PortalBody,
10+
useEditorState,
11+
usePlateEditorRef,
12+
useVirtualFloating
13+
} from '@udecode/plate'
614
import { useTheme } from 'styled-components'
715

8-
import { shift, offset, flip } from '@floating-ui/react-dom-interactions'
916
import { DisplayShortcut } from '@workduck-io/mex-components'
1017

11-
import { mog, NodeEditorContent } from '@mexit/core'
18+
import { mog, NodeEditorContent } from '@mexit/core'
1219
import { ComboboxItem, ComboboxItemTitle, MexIcon, PreviewMeta } from '@mexit/shared'
1320
import {
1421
ActionTitle,
@@ -107,7 +114,6 @@ export const Combobox = ({ onSelectItem, onRenderItem, isSlash, portalElement }:
107114
const editor = usePlateEditorRef()
108115
const theme = useTheme()
109116

110-
111117
const menuProps = combobox ? combobox.getMenuProps({}, { suppressRefError: true }) : { ref: null }
112118

113119
const comboProps = (item, index) => {
@@ -141,7 +147,7 @@ export const Combobox = ({ onSelectItem, onRenderItem, isSlash, portalElement }:
141147
useEffect(() => {
142148
return () => closeMenu()
143149
}, [])
144-
150+
145151
useEffect(() => {
146152
const comboItem = items[itemIndex]
147153

@@ -179,13 +185,9 @@ export const Combobox = ({ onSelectItem, onRenderItem, isSlash, portalElement }:
179185
}
180186
}, [itemIndex, items, activeBlock, isOpen, search])
181187

182-
const getBoundingClientRect = useCallback(
183-
() => {
184-
185-
return getRangeBoundingClientRect(editor, targetRange)
186-
187-
}, [editor, targetRange]
188-
)
188+
const getBoundingClientRect = useCallback(() => {
189+
return getRangeBoundingClientRect(editor, targetRange)
190+
}, [editor, targetRange])
189191

190192
// Update popper position
191193
const { style, floating } = useVirtualFloating({
@@ -201,9 +203,8 @@ const getBoundingClientRect = useCallback(
201203

202204
return (
203205
<PortalBody>
204-
{isOpen && (
205-
206-
<ComboboxRoot {...menuProps} ref={floating} style={style} isOpen={isOpen}>
206+
{isOpen && (
207+
<ComboboxRoot {...menuProps} ref={floating} style={style} isOpen={isOpen}>
207208
<>
208209
{!isBlockTriggered && (
209210
<div id="List" style={{ flex: 1 }}>
@@ -290,17 +291,16 @@ const getBoundingClientRect = useCallback(
290291
readOnly
291292
draftView
292293
editorId={
293-
isBlockTriggered && activeBlock ? activeBlock.blockId : `${items[itemIndex]?.key}_Preview_Block`
294+
isBlockTriggered && activeBlock ? activeBlock?.blockId : `${items[itemIndex]?.key}_Preview_Block`
294295
}
295296
/>
296297
</section>
297298
{preview && <PreviewMeta meta={metaData} />}
298299
</ComboSeperator>
299300
)}
300301
</>
301-
</ComboboxRoot>
302-
)}
303-
302+
</ComboboxRoot>
303+
)}
304304
</PortalBody>
305305
)
306306
}

apps/webapp/src/Editor/Hooks/useComboboxOnKeyDown.ts

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { ComboConfigData, ComboSearchType } from '../Types/MultiCombobox'
1313
import { getNextWrappingIndex } from '../Utils/getNextWrappingIndex'
1414
import { getNodeIdFromEditor } from '../Utils/helper'
1515
import { CreateNewPrefix, SnippetCommandPrefix } from '../constants'
16-
import { useMexEditorStore } from './useMexEditorStore'
1716

1817
const pure = (id: string) => {
1918
let newId = id

apps/webapp/src/Editor/Plugins/index.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -42,28 +42,29 @@ import {
4242
ELEMENT_PARAGRAPH,
4343
createTablePlugin,
4444
parseIframeUrl,
45-
parseTwitterUrl,
4645
parseVideoUrl,
4746
MediaEmbedTweet,
4847
MediaEmbedVideo
4948
} from '@udecode/plate'
5049

50+
import { useAuth } from '@workduck-io/dwindle'
51+
5152
import { ELEMENT_EXCALIDRAW } from '@mexit/core'
5253
import { TableWrapper, parseRestMediaUrls, MediaIFrame, useUploadToCDN } from '@mexit/shared'
5354

5455
import { withStyledDraggables } from '../Actions/withDraggables'
5556
import { withStyledPlaceHolders } from '../Actions/withPlaceholder'
5657
import { withBlockOptions } from '../Components/Blocks'
58+
import { PlateFloatingLink } from '../Components/FloatingLink'
5759
import { createBlockModifierPlugin } from './createBlockModifierPlugin'
5860
import { createBlurSelectionPlugin } from './createBlurSelection'
5961
import { createHighlightTextPlugin } from './createHighlightTextPlugin'
6062
import { createILinkPlugin } from './createILinkPlugin'
6163
import { createInlineBlockPlugin } from './createInlineBlockPlugin'
6264
import { createMentionPlugin } from './createMentionsPlugin'
6365
import { createTagPlugin } from './createTagPlugin'
64-
import { createTodoPlugin } from './createTodoPlugin'
6566
import { createTaskViewLinkPlugin } from './createTaskViewLinkPlugin'
66-
67+
import { createTodoPlugin } from './createTodoPlugin'
6768
import {
6869
optionsAutoFormatRule,
6970
optionsCreateNodeIdPlugin,
@@ -72,8 +73,7 @@ import {
7273
optionsSelectOnBackspacePlugin,
7374
optionsSoftBreakPlugin
7475
} from './options'
75-
import { PlateFloatingLink } from '../Components/FloatingLink'
76-
import { useAuth } from '@workduck-io/dwindle'
76+
import { parseTwitterUrl } from './parseTwitterUrl'
7777

7878
export type PluginOptionType = {
7979
exclude?: {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { MediaPlugin } from '@udecode/plate'
2+
import { getPluginOptions, PlateEditor, RenderFunction, Value } from '@udecode/plate-core'
3+
4+
import { mog } from '@mexit/core'
5+
6+
const twitterRegex = /^https?:\/\/twitter\.com\/(?:#!\/)?(\w+)\/status(es)?\/(?<id>\d+)/
7+
8+
export const parseTwitterUrl = (url: string): EmbedUrlData | undefined => {
9+
mog('URL IS', { url })
10+
if (url?.match(twitterRegex)) {
11+
return {
12+
provider: 'twitter',
13+
id: twitterRegex.exec(url)?.groups?.id,
14+
url
15+
}
16+
}
17+
}
18+
19+
export type EmbedUrlData = {
20+
url?: string
21+
provider?: string
22+
id?: string
23+
component?: RenderFunction<EmbedUrlData>
24+
}
25+
26+
export const parseMediaUrl = <V extends Value>(
27+
editor: PlateEditor<V>,
28+
{
29+
pluginKey,
30+
url
31+
}: {
32+
pluginKey: string
33+
url: string
34+
}
35+
): EmbedUrlData => {
36+
const { rules } = getPluginOptions<MediaPlugin, V>(editor, pluginKey)
37+
if (!rules) return { url }
38+
39+
for (const { parser, component } of rules) {
40+
const parsed = parser(url)
41+
if (parsed) {
42+
return { ...parsed, component }
43+
}
44+
}
45+
46+
return { url }
47+
}

apps/webapp/src/Hooks/useUpdater.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,8 @@ export const useUpdater = () => {
3232
updateLinksFromContent(noteId, content)
3333
updateTagsFromContent(noteId, content)
3434
const todos = getTodosFromContent(content)
35-
mog('CONTENT FOR TODOS', { todos })
35+
mog(`[${noteId}]: Updating from Contnet`, { todos })
3636
updateNodeTodos(noteId, todos)
37-
3837
updateDocument('node', noteId, content)
3938
}
4039
}

apps/webapp/src/Stores/useTodoStore.ts

+2
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,9 @@ const useTodoStore = create<TodoStoreType>(
151151
}
152152

153153
const nTodo = todos[nodeid] ?? []
154+
mog('NUN TOODS', { nTodo })
154155
const nodeTodos = todosContent.map((content) => {
156+
mog('found todo', { content })
155157
const todo = nTodo.find((todo) => todo.id === content.id && nodeid === todo.nodeid)
156158
const tags = getTagsFromContent([content])
157159
const mentions = getMentionsFromContent([content])

0 commit comments

Comments
 (0)