Skip to content

Commit

Permalink
Merge pull request #5 from sereneinserenade/new-note-previews
Browse files Browse the repository at this point in the history
[feat] Revamped the NotePreviews in Sidebar
  • Loading branch information
sereneinserenade committed May 28, 2022
2 parents 3ba0c9f + dfeac9f commit ddaba6e
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 165 deletions.
6 changes: 3 additions & 3 deletions src/pages/Newtab/Newtab.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -18,8 +18,8 @@ const Newtab = () => {
type: 'dark',
theme: {
colors: {
primary: '#3D9CF7',
link: '#3D9CF7',
// primary: '#3D9CF7',
// link: '#3D9CF7',
}
}
})
Expand Down
20 changes: 0 additions & 20 deletions src/pages/Newtab/components/MainTop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,6 @@ const MainTop = () => {

const onSidebarControlButtonClicked = (): void => setSidebarActive(!sidebarActive)

const changeTitle = (e: React.FormEvent<FormElement>) => {
const obj: Partial<Note> = { title: (e.target as any).value }

setActiveNote({ ...activeNote, ...obj } as Note)
}

const deleteActiveNote = () => {
const localNotes: Note[] = JSON.parse(JSON.stringify(notes))

Expand Down Expand Up @@ -161,20 +155,6 @@ const MainTop = () => {
</Tooltip>
</section>

<section className='middle-controls' aria-label='middle-controls-section'>
{
activeNote && binNotes.findIndex(n => n.id === activeNote.id) === -1 &&
<Input
underlined
placeholder="Title..."
onInput={(e) => updateTitle(e)}
value={`${activeNote?.title}`}
className="title-input"
onBlur={refreshNote} // TODO: make this logic better
/>
}
</section>

<section className='right-controls flex' aria-label='right-controls-section'>
{
// TODO: Give option to share in cloud storage
Expand Down
101 changes: 24 additions & 77 deletions src/pages/Newtab/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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) => (<input
placeholder='Add Title...'
className='title-editor-input'
onClick={e => 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'
Expand Down Expand Up @@ -202,47 +197,18 @@ const Sidebar = () => {
{
localBinNotes.map((note: Note) => {
return (
<article
<NotePreview
activeNote={activeNote}
initiateMoveToBin={initiateMoveToBin}
isBin={true}
note={note}
onClick={() => changeActiveNoteTo(note)}
returnFormattedDateString={returnFormattedDateString}
setNoteTitle={setNoteTitle}
key={note.id}
className={`sidebar-note ${note.id === activeNote?.id ? 'active' : ''}`}
>
<section className='title-and-action-center flex' aria-label='title-and-action-center'>
{GetNoteTitle(note, true)}
<Tooltip
placement='top'
content={'Recycle'}
>
<Button
color="primary"
auto
ghost
size='sm'
onClick={(e) => initiateRecycleNote(e, note)}
icon={<RiRecycleLine />}
/>
</Tooltip>
<Tooltip
placement='right'
content={'Delete Permanently'}
>
<Button
color="error"
auto
ghost
size='sm'
onClick={(e) => initiateDeletePermanently(e, note)}
icon={<FiTrash2 />}
/>
</Tooltip>
</section>
{
note.textContent.trim().length
? <Text> {note.textContent.length >= 40 ? note.textContent.substring(0, 40).trim() + '...' : note.textContent} </Text>
: <Text color="gray"> {'No content...'} </Text>
}
<Text size={12}> {returnFormattedDateString(new Date(note.timestamp))} </Text>
</article>
initiateRecycleNote={initiateRecycleNote}
initiateDeletePermanently={initiateDeletePermanently}
/>
)
})
}
Expand All @@ -268,35 +234,16 @@ const Sidebar = () => {

return (
!!localNotes.length
? (localNotes.map((note: Note) => (<article
? (localNotes.map((note: Note) => (<NotePreview
activeNote={activeNote}
initiateMoveToBin={initiateMoveToBin}
isBin={false}
note={note}
onClick={() => changeActiveNoteTo(note)}
returnFormattedDateString={returnFormattedDateString}
setNoteTitle={setNoteTitle}
key={note.id}
className={`sidebar-note ${note.id === activeNote?.id ? 'active' : ''}`}
>
<section className='title-and-action-center flex' aria-label='title-and-action-center'>
{GetNoteTitle(note)}
<Tooltip
placement='right'
content={'Move to Bin'}
>
<Button
color="error"
auto
ghost
size='sm'
onClick={(e) => initiateMoveToBin(e, note)}
icon={<FiTrash2 />}
/>
</Tooltip>
</section>
{
note.textContent.trim().length
? <Text> {note.textContent.length >= 40 ? note.textContent.substring(0, 40).trim() + '...' : note.textContent} </Text>
: <Text color="gray"> {'No content...'} </Text>
}
<Text size={12}> {returnFormattedDateString(new Date(note.timestamp))} </Text>
</article>
)))
/>)))
: (
<Text css={{
fontWeight: 400,
Expand Down
56 changes: 1 addition & 55 deletions src/pages/Newtab/components/css/Sidebar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,45 +24,8 @@
max-height: 92vh;
overflow-y: auto;

.sidebar-note {
padding: 8px;
cursor: pointer;
border-bottom: 1px solid rgba($color: #000000, $alpha: 0.15);
transition: border 0.2s ease-in-out;

&:hover {
background: rgba($color: #000000, $alpha: 0.05);
transition: border 0.2s ease-in-out;
}

&.active {
transition: border 0.2s ease-in-out;
border-left: 6px solid black;
background: rgba($color: #000000, $alpha: 0.05);
}

.title-and-action-center {
justify-content: space-between;

.title-editor-input {
background: none;
border: none;
outline: none;
padding: none;

font-size: 1.2em;
}
}
}

.bin-top-section {
width: 90%;
}

.bin-section {
.sidebar-note:first-of-type {
border-top: 1px solid rgba($color: #000000, $alpha: 0.15);
}
border-bottom: 1px solid var(--nextui-colors-text);
}
}

Expand All @@ -81,23 +44,6 @@
.dark-theme {
.sidebar {
border-right: 1px solid gray;

.sidebar-notes-list {
.sidebar-note {
border-bottom: 1px solid gray;

&.active {
border-left: 6px solid gray;
background: rgba($color: gray, $alpha: 0.25);
}
}

.bin-section {
.sidebar-note:first-of-type {
border-top: 1px solid gray;
}
}
}
}
}

Expand Down
Empty file.
10 changes: 0 additions & 10 deletions src/pages/Newtab/components/note/Note.tsx

This file was deleted.

124 changes: 124 additions & 0 deletions src/pages/Newtab/components/note/NotePreview.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<span className='title-editor-container flex'>
{
!isInBin
&& (
<span className='control-buttons'>
{isEditable
? <Tooltip placement='topStart' content={<Text> Save Title <kbd>Enter</kbd></Text>}><FiCheck onClick={(e) => stopPrevent(e) && onInput()} /> </Tooltip>
: <Tooltip placement='topStart' content={'Edit Title'}><FiEdit2 onClick={(e) => stopPrevent(e) && onEditStart()} /> </Tooltip>
}
</span>
)
}

<input
placeholder='Add Title...'
className='title-editor-input'
onClick={e => e.stopPropagation()}
value={name}
onInput={e => setName((e.target as any).value)}
disabled={!isEditable}
onKeyPress={(e) => e.code === 'Enter' && onInput()}
ref={inputRef}
/>
</span>
)
}

export const NotePreview: React.FC<NotePreviewProps> = ({
onClick,
note,
activeNote,
initiateMoveToBin,
returnFormattedDateString,
setNoteTitle,
isBin,
initiateRecycleNote,
initiateDeletePermanently
}) => {
return (
<article
onClick={() => onClick(note)}
key={note.id + 'internal'}
className={`sidebar-note flex flex-row justify-between align-center ${note.id === activeNote?.id ? 'active' : ''}`}
>
<section className='title-and-action-center flex' aria-label='title-and-action-center'>
{GetNoteTitle(note, isBin, setNoteTitle)}
<Text size={12}> {returnFormattedDateString(new Date(note.timestamp))} </Text>
</section>

{
isBin && (
<Tooltip
placement='top'
content={'Recycle'}>
<Button
color="primary"
auto
ghost
size='sm'
onClick={(e) => initiateRecycleNote?.(e, note)}
icon={<RiRecycleLine />}
/>
</Tooltip>
)
}

<Tooltip
placement='right'
content={'Move to Bin'}
>
<Button
color="error"
auto
ghost
size='sm'
onClick={(e) => isBin ? initiateDeletePermanently?.(e, note) : initiateMoveToBin(e, note)}
icon={<FiTrash2 />}
/>
</Tooltip>
</article>
)
}
Loading

0 comments on commit ddaba6e

Please sign in to comment.