Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MexIt] Snippets, Tags and Search fixes #99

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions apps/webapp/src/Actions/Components/Tags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,12 @@ export const Tags: React.FC<TagsProps> = ({ userTags, addNewTag, removeTag }: Ta
const { key } = e
const trimmedInput = input.trim()
const tagTexts = new Array<string>()
userTags.forEach((tag) => tagTexts.push(tag.text))
userTags.forEach((tag) => tagTexts.push(tag.value))

if (key === 'Enter' && trimmedInput.length && !tagTexts.includes(trimmedInput)) {
e.preventDefault()
const t: Tag = {
id: `TAG_${nanoid()}`,
text: trimmedInput
value: trimmedInput
}
addNewTag(t)
setInput('')
Expand All @@ -64,7 +63,7 @@ export const Tags: React.FC<TagsProps> = ({ userTags, addNewTag, removeTag }: Ta
const poppedTag = tagsCopy.pop()
e.preventDefault()
removeTag(poppedTag)
setInput(poppedTag.text)
setInput(poppedTag.value)
}

setIsKeyReleased(false)
Expand All @@ -89,8 +88,8 @@ export const Tags: React.FC<TagsProps> = ({ userTags, addNewTag, removeTag }: Ta
{/* TODO: recommend and show recent used tags */}
<TagsContainer>
{userTags.map((tag) => (
<Tagg key={tag.id} className="tag">
{tag.text}
<Tagg key={tag.value} className="tag">
{tag.value}
<button onClick={() => removeTag(tag)}>x</button>
</Tagg>
))}
Expand Down
11 changes: 9 additions & 2 deletions apps/webapp/src/Components/Editor/ContentEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const ContentEditor = () => {
const isBlockMode = useBlockStore((store) => store.isBlockMode)
const { setShowLoader } = useLayoutStore()

const { addOrUpdateValBuffer, getBufferVal } = useEditorBuffer()
const { addOrUpdateValBuffer, saveAndClearBuffer, getBufferVal } = useEditorBuffer()
const { node, fsContent } = useEditorStore(
(state) => ({ nodeid: state.node.nodeid, node: state.node, fsContent: state.content }),
shallow
Expand Down Expand Up @@ -95,6 +95,10 @@ const ContentEditor = () => {
}
}, [])

useEffect(() => {
return () => saveAndClearBuffer()
}, [])

return (
<StyledEditor showGraph={false} className="mex_editor">
<Toolbar />
Expand All @@ -107,7 +111,10 @@ const ContentEditor = () => {
readOnly={readOnly}
nodeUID={nodeId}
nodePath={node.path}
content={fsContent?.content ?? defaultContent.content}
onAutoSave={(val) => {
saveAndClearBuffer()
}}
content={fsContent?.content?.length ? fsContent?.content : defaultContent.content}
onChange={onChangeSave}
/>
</EditorWrapper>
Expand Down
27 changes: 21 additions & 6 deletions apps/webapp/src/Components/Editor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { LinkElement, MediaEmbedElement, TableWrapper } from '@mexit/shared'

import TagWrapper from './TagWrapper'
import BallonMarkToolbarButtons from './BalloonToolbar/EditorBalloonToolbar'
import { ELEMENT_ILINK, ELEMENT_INLINE_BLOCK, ELEMENT_TAG, ELEMENT_TODO_LI } from '@mexit/core'
import { ELEMENT_ILINK, ELEMENT_INLINE_BLOCK, ELEMENT_TAG, ELEMENT_TODO_LI, NodeEditorContent } from '@mexit/core'
import Todo from '../Todo'
import { useEditorChange } from '@mexit/shared'
import { EditorStyles } from '@mexit/shared'
Expand Down Expand Up @@ -38,9 +38,10 @@ interface EditorProps {
readOnly?: boolean
onChange?: any // eslint-disable-line @typescript-eslint/no-explicit-any
autoFocus?: boolean
onAutoSave?: (content: NodeEditorContent) => void
}

const Editor: React.FC<EditorProps> = ({ nodeUID, nodePath, content, readOnly, onChange, autoFocus }) => {
const Editor: React.FC<EditorProps> = ({ nodeUID, nodePath, content, readOnly, onChange, autoFocus, onAutoSave }) => {
const tags = useDataStore((store) => store.tags)
const addTag = useDataStore((store) => store.addTag)
const ilinks = useDataStore((store) => store.ilinks)
Expand Down Expand Up @@ -152,7 +153,7 @@ const Editor: React.FC<EditorProps> = ({ nodeUID, nodePath, content, readOnly, o
tag: {
cbKey: ComboboxKey.TAG,
trigger: '#',
data: tags.map((t) => ({ ...t, value: t.text })),
data: tags.map((t) => ({ ...t, text: t.value })),
icon: 'ri:hashtag'
},
slash_command: {
Expand All @@ -179,10 +180,24 @@ const Editor: React.FC<EditorProps> = ({ nodeUID, nodePath, content, readOnly, o
withBalloonToolbar: true
}

const debounced = useDebouncedCallback((value) => {
const onDelayPerform = useDebouncedCallback((value) => {
const f = !readOnly && typeof onChange === 'function' ? onChange : () => undefined
f(value)
}, 1000)
}, 400)

const saveAfterDelay = useDebouncedCallback(
typeof onAutoSave === 'function' ? onAutoSave : () => undefined,
30 * 1000 // After 30 seconds
)

const onChangeContent = (val: NodeEditorContent) => {
onDelayPerform(val)

if (onAutoSave) {
saveAfterDelay.cancel()
saveAfterDelay(val)
}
}

const comboboxConfig: ComboboxConfig = {
onChangeConfig: comboOnChangeConfig,
Expand All @@ -199,7 +214,7 @@ const Editor: React.FC<EditorProps> = ({ nodeUID, nodePath, content, readOnly, o
}}
BalloonMarkToolbarButtons={<BallonMarkToolbarButtons />}
// debug
onChange={debounced}
onChange={onChangeContent}
options={editorOptions}
editorId={nodeUID}
value={content}
Expand Down
10 changes: 5 additions & 5 deletions apps/webapp/src/Components/Editor/SnippetEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import tinykeys from 'tinykeys'
import { useSnippetBuffer, useSnippetBufferStore } from '../../Hooks/useEditorBuffer'
import { useRouting, ROUTE_PATHS, NavigationType } from '../../Hooks/useRouting'
import { SnippetSaverButton } from '../Saver'
import { useApi } from '../../Hooks/useApi'
import { useSnippetStore } from '../../Stores/useSnippetStore'

type Inputs = {
Expand All @@ -24,7 +23,6 @@ const SnippetEditor = () => {
const snippet = useSnippetStore((store) => store.editor.snippet)
const { goTo } = useRouting()

const api = useApi()
const {
register,
formState: { errors }
Expand Down Expand Up @@ -69,7 +67,6 @@ const SnippetEditor = () => {
mog('onChangeSave', { val })
if (val) {
addOrUpdateValBuffer(snippet.id, val)
api.saveSnippetAPI(snippet.id, snippet.title, val)
}
}

Expand Down Expand Up @@ -104,6 +101,7 @@ const SnippetEditor = () => {
})

return () => {
saveSnippet()
unsubscribe()
}
}, [])
Expand All @@ -115,12 +113,13 @@ const SnippetEditor = () => {
// const snippet = useSnippetStore.getState().sn
}

const returnToSnippets = () => {
const saveSnippet = () => {
saveAndClearBuffer()
// updater()
goTo(ROUTE_PATHS.snippets, NavigationType.push)
}

const returnToSnippets = () => goTo(ROUTE_PATHS.snippets, NavigationType.push)

const defaultValue = snippet && snippet.title !== DRAFT_NODE ? snippet.title : ''

const onDelay = debounce((value) => onChangeTitle(value), 250)
Expand Down Expand Up @@ -161,6 +160,7 @@ const SnippetEditor = () => {
/> */}
<SnippetSaverButton
getSnippetExtras={getSnippetExtras}
noButton
callbackAfterSave={callbackAfterSave}
title="Save Snippet"
/>
Expand Down
15 changes: 13 additions & 2 deletions apps/webapp/src/Components/Editor/Toolbar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import focusLine from '@iconify/icons-ri/focus-line'
import { useSingleton } from '@tippyjs/react'
import shareLine from '@iconify/icons-ri/share-line'

import { Loading, ToolbarTooltip, IconButton } from '@mexit/shared'

Expand All @@ -19,18 +20,28 @@ const Toolbar = () => {
const nodeid = useEditorStore((state) => state.node.nodeid)
const [source, target] = useSingleton()
const shortcuts = useHelpStore((store) => store.shortcuts)
const showShareOptions = useLayoutStore((store) => store.showShareOptions)
const toggleShareOptions = useLayoutStore((store) => store.toggleShareOptions)

return (
<NodeInfo {...getFocusProps(focusMode)}>
<NodeRenameOnlyTitle />
{fetchingContent && <Loading dots={3} />}
<InfoTools>
<ToolbarTooltip singleton={source} />
<ToolbarTooltip singleton={target} content="Bookmark">
<IconButton
singleton={target}
size={24}
icon={shareLine}
title="Share"
highlight={showShareOptions}
onClick={toggleShareOptions}
/>
{/* <ToolbarTooltip singleton={target} content="Bookmark">
<span tabIndex={0}>
<BookmarkButton nodeid={nodeid} />
</span>
</ToolbarTooltip>
</ToolbarTooltip> */}
<IconButton
singleton={target}
size={24}
Expand Down
18 changes: 15 additions & 3 deletions apps/webapp/src/Components/EditorInfobar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import React from 'react'
import Metadata from './Metadata'
import { animated, useSpring } from 'react-spring'
import styled from 'styled-components'
import { useLayoutStore } from '../../Stores/useLayoutStore'

import ShareOptions from './ShareOptions'

const StyledEditorInfo = styled(animated.div)``

const EditorInfoBar = () => {
const showShareOptions = useLayoutStore((store) => store.showShareOptions)

const transition = useSpring({
opacity: showShareOptions ? 1 : 0,
height: showShareOptions ? '4rem' : '0rem',
y: showShareOptions ? 0 : 5
})

return (
<>
<StyledEditorInfo style={transition}>
<ShareOptions />
</>
</StyledEditorInfo>
)
}

Expand Down
9 changes: 8 additions & 1 deletion apps/webapp/src/Components/Saver.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,12 @@ interface SnippetSaverButtonProps extends SaverButtonProps {
getSnippetExtras: () => SnippetExtras
}

export const SnippetSaverButton = ({ callbackAfterSave, title, getSnippetExtras }: SnippetSaverButtonProps) => {
export const SnippetSaverButton = ({
callbackAfterSave,
title,
getSnippetExtras,
noButton
}: SnippetSaverButtonProps) => {
const { onSave: onSaveFs } = useSnippetSaver()
const shortcuts = useHelpStore((state) => state.shortcuts)
const { trackEvent } = useAnalytics()
Expand All @@ -229,6 +234,8 @@ export const SnippetSaverButton = ({ callbackAfterSave, title, getSnippetExtras
}
})

if (noButton) return <></>

return (
<IconButton
size={24}
Expand Down
11 changes: 9 additions & 2 deletions apps/webapp/src/Data/links.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import searchLine from '@iconify/icons-ri/search-line'
import { ROUTE_PATHS } from '../Hooks/useRouting'
import { useHelpStore } from '../Stores/useHelpStore'
import { NavLinkData } from '../Types/Nav'
import { useLinks } from '../Hooks/useLinks'
import { getNodeidFromPathAndLinks, useLinks } from '../Hooks/useLinks'
import { useDataStore } from '../Stores/useDataStore'
import { useEditorStore } from '../Stores/useEditorStore'
import { useReminderStore } from '../Stores/useReminderStore'
Expand All @@ -27,12 +27,19 @@ export const GetIcon = (icon: any): React.ReactNode => <Icon icon={icon} />
const useNavlinks = () => {
const shortcuts = useHelpStore((store) => store.shortcuts)
const nodeid = useEditorStore((store) => store.node.nodeid)
const baseNodeId = useDataStore((store) => store.baseNodeId)

const reminders = useReminderStore((store) => store.reminders)
const ilinks = useDataStore((store) => store.ilinks)
const archive = useDataStore((store) => store.archive)
const tasks = useTodoStore((store) => store.todos)
const { getLinkCount } = useLinks()

const noteId = useMemo(() => {
const currentNotId = nodeid === '__null__' ? getNodeidFromPathAndLinks(ilinks, baseNodeId) : nodeid
return currentNotId
}, [nodeid, ilinks])

const count = useMemo(() => getLinkCount(), [reminders, ilinks, archive, tasks])

const getLinks = () => {
Expand All @@ -51,7 +58,7 @@ const useNavlinks = () => {
// },
{
title: 'Notes',
path: `${ROUTE_PATHS.node}/${nodeid}`,
path: `${ROUTE_PATHS.node}/${noteId}`,
shortcut: shortcuts.showEditor.keystrokes,
icon: GetIcon(fileDocument),
count: count.notes
Expand Down
13 changes: 8 additions & 5 deletions apps/webapp/src/Editor/Actions/withDraggables.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { RelativeTime } from '@mexit/shared'
import useBlockStore from '../../Stores/useBlockStore'
import { ProfileImage } from '../../Components/User/ProfileImage'
import { useEditorStore } from '../../Stores/useEditorStore'
import { IS_DEV } from '@mexit/core'

const StyledTip = styled.div`
display: flex;
Expand Down Expand Up @@ -167,11 +168,13 @@ export const DraggerContent = ({ element }: any) => {
<>
<div>Drag to move</div>
<div>Click to select</div>
<div>
<span>
<i>{element && element.id}</i> - {element && element.type}
</span>
</div>
{IS_DEV && (
<div>
<span>
<i>{element && element.id}</i> - {element && element.type}
</span>
</div>
)}
</>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useCallback } from 'react'
import { OnChange, usePlateEditorRef } from '@udecode/plate'

import { getTimeInText, isReservedOrClash, toLocaleString, withoutContinuousDelimiter } from '@mexit/core'
import { getTimeInText, isReservedOrClash, mog, toLocaleString, withoutContinuousDelimiter } from '@mexit/core'

import { useLinks } from '../../../Hooks/useLinks'
import { useRouting } from '../../../Hooks/useRouting'
Expand Down Expand Up @@ -71,14 +71,17 @@ const useMultiComboboxOnChange = (editorId: string, keys: Record<string, Combobo
const data = ct.data

if (!data) return false

const textAfterTrigger = search.textAfterTrigger

if (params.snippetid && textAfterTrigger?.startsWith('.')) return

const { isChild, key: pathKey } = withoutContinuousDelimiter(textAfterTrigger)
const searchTerm = isChild ? `${getPathFromNodeid(editorId)}${pathKey}` : pathKey

const searchItems = fuzzySearch(data, searchTerm, (item) => item.text)
mog('data', { data })

const searchItems = fuzzySearch(data, searchTerm || '', (item) => item?.text || '')

const { isExtended, extendedCommands } = getCommandExtended(search.textAfterTrigger, keys)

Expand Down
Loading