diff --git a/src/pages/Newtab/Newtab.tsx b/src/pages/Newtab/Newtab.tsx index 4a2dec7..69c6f16 100644 --- a/src/pages/Newtab/Newtab.tsx +++ b/src/pages/Newtab/Newtab.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState } from 'react'; import { createTheme, NextUIProvider, getDocumentTheme } from '@nextui-org/react'; -import { RecoilRoot, useRecoilState } from 'recoil'; +import { RecoilRoot } from 'recoil'; import 'tippy.js/animations/shift-toward-subtle.css'; @@ -18,8 +18,8 @@ const Newtab = () => { type: 'dark', theme: { colors: { - primary: '#3D9CF7', - link: '#3D9CF7', + // primary: '#3D9CF7', + // link: '#3D9CF7', } } }) diff --git a/src/pages/Newtab/components/MainTop.tsx b/src/pages/Newtab/components/MainTop.tsx index d549780..3a7fd84 100644 --- a/src/pages/Newtab/components/MainTop.tsx +++ b/src/pages/Newtab/components/MainTop.tsx @@ -58,12 +58,6 @@ const MainTop = () => { const onSidebarControlButtonClicked = (): void => setSidebarActive(!sidebarActive) - const changeTitle = (e: React.FormEvent) => { - const obj: Partial = { title: (e.target as any).value } - - setActiveNote({ ...activeNote, ...obj } as Note) - } - const deleteActiveNote = () => { const localNotes: Note[] = JSON.parse(JSON.stringify(notes)) @@ -161,20 +155,6 @@ const MainTop = () => { -
- { - activeNote && binNotes.findIndex(n => n.id === activeNote.id) === -1 && - updateTitle(e)} - value={`${activeNote?.title}`} - className="title-input" - onBlur={refreshNote} // TODO: make this logic better - /> - } -
-
{ // TODO: Give option to share in cloud storage diff --git a/src/pages/Newtab/components/Sidebar.tsx b/src/pages/Newtab/components/Sidebar.tsx index 174da1c..4c68ce3 100644 --- a/src/pages/Newtab/components/Sidebar.tsx +++ b/src/pages/Newtab/components/Sidebar.tsx @@ -11,6 +11,7 @@ import './css/Sidebar.scss' import { FiTrash2 } from 'react-icons/fi'; import { RiArrowLeftSLine, RiDeleteBin2Line, RiRecycleLine } from 'react-icons/ri'; import { useLocalStorage } from 'react-use'; +import { NotePreview } from './note/NotePreview'; const { storage } = chrome @@ -90,18 +91,12 @@ const Sidebar = () => { if (isInBin) setBinNotes(localNotes) else setNotes(localNotes) - if (note.id === activeNote?.id) setActiveNote(JSON.parse(JSON.stringify(newNote))) - } - - const GetNoteTitle = (note: Note, isInBin: boolean = false) => ( e.stopPropagation()} - value={note.title} - onInput={e => setNoteTitle(note, (e as any).target.value, isInBin)} - disabled={isInBin} - />) + if (note.id === activeNote?.id) { + setActiveNote(undefined) + setTimeout(() => setActiveNote(JSON.parse(JSON.stringify(newNote)))) + } + } const deleteNote = (id: string, source: 'normal' | 'bin' = 'normal') => { const isBin = source === 'bin' @@ -202,47 +197,18 @@ const Sidebar = () => { { localBinNotes.map((note: Note) => { return ( -
changeActiveNoteTo(note)} + returnFormattedDateString={returnFormattedDateString} + setNoteTitle={setNoteTitle} key={note.id} - className={`sidebar-note ${note.id === activeNote?.id ? 'active' : ''}`} - > -
- {GetNoteTitle(note, true)} - -
- { - note.textContent.trim().length - ? {note.textContent.length >= 40 ? note.textContent.substring(0, 40).trim() + '...' : note.textContent} - : {'No content...'} - } - {returnFormattedDateString(new Date(note.timestamp))} -
+ initiateRecycleNote={initiateRecycleNote} + initiateDeletePermanently={initiateDeletePermanently} + /> ) }) } @@ -268,35 +234,16 @@ const Sidebar = () => { return ( !!localNotes.length - ? (localNotes.map((note: Note) => (
( changeActiveNoteTo(note)} + returnFormattedDateString={returnFormattedDateString} + setNoteTitle={setNoteTitle} key={note.id} - className={`sidebar-note ${note.id === activeNote?.id ? 'active' : ''}`} - > -
- {GetNoteTitle(note)} - -
- { - note.textContent.trim().length - ? {note.textContent.length >= 40 ? note.textContent.substring(0, 40).trim() + '...' : note.textContent} - : {'No content...'} - } - {returnFormattedDateString(new Date(note.timestamp))} -
- ))) + />))) : ( { - return ( - <> - - ) -} - -export default Note diff --git a/src/pages/Newtab/components/note/NotePreview.tsx b/src/pages/Newtab/components/note/NotePreview.tsx new file mode 100644 index 0000000..e6e7b2b --- /dev/null +++ b/src/pages/Newtab/components/note/NotePreview.tsx @@ -0,0 +1,124 @@ +import React, { useCallback, useRef, useState } from 'react'; +import { Button, Tooltip, Text } from '@nextui-org/react'; + +import { Note } from '../../types'; + +import './styles/NotePreview.scss' +import { FiCheck, FiEdit2, FiTrash2 } from 'react-icons/fi'; +import { stopPrevent } from '../../utils'; +import { RiRecycleLine } from 'react-icons/ri'; + +interface NotePreviewProps { + onClick: Function, + note: Note, + activeNote: Note | undefined, + initiateMoveToBin: Function, + returnFormattedDateString: Function + setNoteTitle: Function + isBin: boolean + + initiateRecycleNote?: Function + initiateDeletePermanently?: Function +} + +const GetNoteTitle = (note: Note, isInBin = false, setNoteTitle: Function) => { + const [isEditable, setIsEditable] = useState(false) + + const [name, setName] = useState(`${note.title}`) + + const inputRef = useRef(null) + + const onInput = useCallback(() => { + setNoteTitle(note, name, isInBin) + setIsEditable(false) + }, [name, note, isInBin]) + + const onEditStart = useCallback(() => { + setIsEditable(true); + + setTimeout(() => (inputRef.current as unknown as HTMLInputElement).focus()) + }, []) + + return ( + + { + !isInBin + && ( + + {isEditable + ? Save Title Enter}> stopPrevent(e) && onInput()} /> + : stopPrevent(e) && onEditStart()} /> + } + + ) + } + + e.stopPropagation()} + value={name} + onInput={e => setName((e.target as any).value)} + disabled={!isEditable} + onKeyPress={(e) => e.code === 'Enter' && onInput()} + ref={inputRef} + /> + + ) +} + +export const NotePreview: React.FC = ({ + onClick, + note, + activeNote, + initiateMoveToBin, + returnFormattedDateString, + setNoteTitle, + isBin, + initiateRecycleNote, + initiateDeletePermanently +}) => { + return ( +
onClick(note)} + key={note.id + 'internal'} + className={`sidebar-note flex flex-row justify-between align-center ${note.id === activeNote?.id ? 'active' : ''}`} + > +
+ {GetNoteTitle(note, isBin, setNoteTitle)} + {returnFormattedDateString(new Date(note.timestamp))} +
+ + { + isBin && ( + +
+ ) +} diff --git a/src/pages/Newtab/components/note/styles/NotePreview.scss b/src/pages/Newtab/components/note/styles/NotePreview.scss new file mode 100644 index 0000000..47dccd6 --- /dev/null +++ b/src/pages/Newtab/components/note/styles/NotePreview.scss @@ -0,0 +1,56 @@ +.sidebar-note { + padding: 10px; + cursor: pointer; + border-radius: var(--nextui-radii-md); + margin: 8px; + transition: all 0.2s ease-in-out; + + &:hover { + transition: none; + background-color: var(--nextui-colors-primaryLight); + + .control-buttons { + max-width: 50px !important; + } + } + + &.active { + transition: all 0.2s ease-in-out; + background-color: var(--nextui-colors-primaryLightHover); + } + + .title-and-action-center { + justify-content: space-between; + flex-direction: column; + + .title-editor-container { + .title-editor-input { + background: none; + outline: none; + padding: none; + font-size: 1.2em; + border: none; + border-bottom: 1px dashed var(--nextui-colors-text); + cursor: text; + + &:disabled { + border: none; + cursor: pointer; + } + + &::selection { + background-color: var(--nextui-colors-purple400); + } + } + + .control-buttons { + margin-right: 2px; + transform: translateY(8px); + overflow: hidden; + display: inline-flex; + transition: all 0.2s ease-in-out; + max-width: 0; + } + } + } +}