diff --git a/manifest.json b/manifest.json index 5606e54..64e20a7 100755 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "manifest_version": 3, - "version": "1.2.4", + "version": "1.2.5", "name": "PlaceNoter", "description": "Turns browser's home page to a Note-Taking-App.", "offline_enabled": true, diff --git a/package-lock.json b/package-lock.json index c6d9302..f33d909 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "placenoter", - "version": "1.2.4", + "version": "1.2.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "placenoter", - "version": "1.2.4", + "version": "1.2.5", "license": "MIT", "dependencies": { "@dnd-kit/core": "^6.0.3", diff --git a/package.json b/package.json index 5d0ca99..1742642 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "placenoter", - "version": "1.2.4", + "version": "1.2.5", "description": "New tab replaced by note taking app.", "license": "MIT", "repository": { diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 0433556..f69e9bd 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -133,6 +133,8 @@ const Sidebar = () => { // Adding note to `binNotes` // TODO: don't need so much vars/consts setBinNotes(JSON.parse(JSON.stringify([note, ...binNotes]))) + + if (id === activeNote?.id) setActiveNote(undefined) } const initiateMoveToBin = (e: any, note: Note) => { diff --git a/src/components/editor/Menubar.tsx b/src/components/editor/Menubar.tsx index 5dc212d..bc00d71 100644 --- a/src/components/editor/Menubar.tsx +++ b/src/components/editor/Menubar.tsx @@ -6,7 +6,7 @@ import { Button, Input, Tooltip, Text } from '@nextui-org/react'; import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { debounce } from 'lodash'; import { RiSearch2Line, RiArrowDownSLine } from 'react-icons/ri' -import { MdSpellcheck } from 'react-icons/md' +import { MdEdit, MdPreview, MdSpellcheck } from 'react-icons/md' import { useLocalStorage } from 'react-use'; import { stopPrevent } from '../../utils' @@ -159,9 +159,17 @@ type MenubarProps = { editor: Editor, isLocalSearchVisible: boolean, onSearchTooltipClose: () => any + isPreview: boolean, + toggleIsPreview: () => any } -const Menubar = ({ editor, isLocalSearchVisible, onSearchTooltipClose }: MenubarProps) => { +const Menubar = ({ + editor, + isLocalSearchVisible, + onSearchTooltipClose, + isPreview, + toggleIsPreview, +}: MenubarProps) => { if (!editor) return null const activeNote = useRecoilValue(activeNoteState) @@ -362,6 +370,22 @@ const Menubar = ({ editor, isLocalSearchVisible, onSearchTooltipClose }: Menubar + + + + {LinkModal({ visible: linkModalVisible, onClose: closeLinkModalAndUpdateLink })} {BubbleMenu({ editor, debouncedCalculateIsActiveStates, isActiveStates, openLinkModal })} diff --git a/src/components/editor/Tiptap.scss b/src/components/editor/Tiptap.scss index 55a74b5..b06e7c0 100644 --- a/src/components/editor/Tiptap.scss +++ b/src/components/editor/Tiptap.scss @@ -33,6 +33,12 @@ pointer-events: none; } + h1, + h2, + h3 { + margin: 0; + } + ul, ol { padding: 0 1rem; diff --git a/src/components/editor/Tiptap.tsx b/src/components/editor/Tiptap.tsx index 3f2ae96..dc1be32 100644 --- a/src/components/editor/Tiptap.tsx +++ b/src/components/editor/Tiptap.tsx @@ -18,7 +18,7 @@ import TableRow from '@tiptap/extension-table-row'; import './Tiptap.scss' import Menubar from './Menubar' -import { suggestions, Commands, SearchAndReplace, SmilieReplacer } from './extensions' +import { suggestions, Commands, SearchAndReplace, SmilieReplacer, Doc, DBlock, NodeMover } from './extensions' import { CodeBlockLowLight } from './extensions/CodeBlockLowLight'; import { useRecoilValue, useSetRecoilState } from 'recoil'; import { currentLinkUrlState, linkModalState, spellCheckState } from '../../Store'; @@ -36,6 +36,8 @@ const Tiptap = ({ onUpdate, content, isNoteInBin }: TiptapProps) => { const [isLocalSearchVisible, setIsLocalSearchVisible] = useState(false) + const [isPreview, setIsPreview] = useState(false) + const spellcheckRecoilState = useRecoilValue(spellCheckState) const focusSearchInput = async (): Promise => { @@ -56,7 +58,17 @@ const Tiptap = ({ onUpdate, content, isNoteInBin }: TiptapProps) => { const editor = useEditor({ extensions: [ - StarterKit.configure({ codeBlock: false }), + Doc, + StarterKit.configure({ + codeBlock: false, + document: false, + dropcursor: { + color: 'skyblue', + width: 2 + } + }), + DBlock, + NodeMover, Placeholder.configure({ placeholder: "Type '/' for commands…" }), @@ -126,6 +138,17 @@ const Tiptap = ({ onUpdate, content, isNoteInBin }: TiptapProps) => { }) }, [spellcheckRecoilState]) + useEffect(() => { + editor?.setEditable(!isPreview) + }, [isPreview]) + + const [editorContentKey, setEditorContentKey] = useState(`${Math.random()}`) + + const toggleIsPreview = () => { + setIsPreview(!isPreview) + setEditorContentKey(`${Math.random()}`) + } + return ( <> { @@ -134,11 +157,18 @@ const Tiptap = ({ onUpdate, content, isNoteInBin }: TiptapProps) => { editor={editor} isLocalSearchVisible={isLocalSearchVisible} onSearchTooltipClose={() => setIsLocalSearchVisible(false)} + isPreview={isPreview} + toggleIsPreview={toggleIsPreview} /> ) } - + diff --git a/src/components/editor/extensions/dBlock/DBlockNodeView.tsx b/src/components/editor/extensions/dBlock/DBlockNodeView.tsx new file mode 100644 index 0000000..24f8327 --- /dev/null +++ b/src/components/editor/extensions/dBlock/DBlockNodeView.tsx @@ -0,0 +1,111 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ + +import { Button, Tooltip, styled } from '@nextui-org/react'; +import { NodeViewContent, NodeViewProps, NodeViewWrapper } from "@tiptap/react"; +import React, { useMemo } from "react"; +import { BiPlus } from 'react-icons/bi'; +import { MdClose, MdDragIndicator } from 'react-icons/md'; +import { RiArrowDownLine, RiArrowUpLine } from 'react-icons/ri'; + +import './DBlockStyle.scss' + +const LeftSection = styled('section', { + display: 'flex', + gap: '4px', + alignItems: 'center' +}) + +const MoveButtonsContainer = styled('div', { + display: 'flex', + justifyContent: 'space-between' +}) + +export const DBlockNodeView: React.FC = ({ + node, + getPos, + editor, + deleteNode +}) => { + const isTable = useMemo(() => { + const { content } = node.content as any; + + return content[0].type.name === "table"; + }, [node.content]); + + const createNodeAfter = () => { + const pos = getPos() + node.nodeSize; + + editor + .chain() + .insertContentAt(pos, { + type: "dBlock", + content: [ + { + type: "paragraph", + }, + ], + }) + .focus(pos + 2) + .run(); + }; + + const onDeleteClicked = () => { + deleteNode() + + setTimeout(() => editor.commands.focus()) + } + + const moveNode = (dir: 'up' | 'down') => { + const { from, to } = editor.state.selection + const [nodeFrom, nodeTo] = [getPos(), getPos() + node.nodeSize] + + if (!(nodeFrom <= from && to <= nodeTo)) editor.commands.focus(getPos() + 2) + + setTimeout(() => editor.chain().moveNode(dir).focus().run()) + } + + return ( + + { + editor.isEditable && ( + + + + +