Skip to content

Commit a39dd8c

Browse files
committed
feat(extension): note management / form
1 parent fafb24f commit a39dd8c

File tree

9 files changed

+80
-8
lines changed

9 files changed

+80
-8
lines changed

clients/extension/action/app.tsx

+15
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ import { ActionContainer } from '../components/action-container'
44
import { sendMessage } from '../utilities/send-message'
55

66
import type { ExtItem, ExtMessage } from '../types'
7+
import type { NoteEdge } from '@common/types/pocket'
78

89
export function App() {
910
const [isOpen, setIsOpen] = useState(false)
1011
const [saveStatus, setSaveStatus] = useState('saving')
1112
const [noteStatus, setNoteStatus] = useState<string | undefined>(undefined)
1213
const [errorMessage, setErrorMessage] = useState<string | undefined>(undefined)
1314
const [item, setItem] = useState<ExtItem | undefined>(undefined)
15+
const [notes, setNotes] = useState<NoteEdge[] | []>([])
1416

1517
/* Setup Listeners and show popup
1618
–––––––––––––––––––––––––––––––––––––––––––––––––– */
@@ -39,6 +41,7 @@ export function App() {
3941
case EXT_ACTIONS.SAVE_TO_POCKET_SUCCESS: {
4042
const item = message?.item as ExtItem
4143
setItem(item)
44+
setNotes(item.savedItem.notes.edges)
4245
setNoteStatus(undefined)
4346
setSaveStatus('saved')
4447
return
@@ -58,6 +61,17 @@ export function App() {
5861
return
5962
}
6063

64+
case EXT_ACTIONS.DELETE_NOTE_SUCCESS: {
65+
const { noteId } = message
66+
if (noteId) {
67+
setNoteStatus(undefined)
68+
setNotes((notes) => {
69+
return notes.filter((note) => note?.node?.id !== noteId)
70+
})
71+
}
72+
return
73+
}
74+
6175
case EXT_ACTIONS.REMOVE_ITEM_REQUEST: {
6276
setSaveStatus('removing')
6377
return
@@ -118,6 +132,7 @@ export function App() {
118132
errorMessage={errorMessage}
119133
saveStatus={saveStatus}
120134
noteStatus={noteStatus}
135+
notes={notes}
121136
setNoteStatus={setNoteStatus}
122137
isOpen={isOpen}
123138
item={item}

clients/extension/background/index.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ async function messageHandler(message: ExtMessage, sender: chrome.runtime.Messag
5151
const tab = senderTab ?? activeTab[0]
5252
const tabId = tab?.id
5353

54-
console.log({ message })
55-
5654
switch (action) {
5755
case EXT_ACTIONS.BROWSER_ACTION: {
5856
// No tab was sent
@@ -82,7 +80,7 @@ async function messageHandler(message: ExtMessage, sender: chrome.runtime.Messag
8280

8381
case EXT_ACTIONS.ADD_NOTE_REQUEST: {
8482
const { noteData } = message
85-
if (noteData && tab?.url) await saveNote(noteData, tab.url)
83+
if (noteData) await saveNote(noteData, tab?.url)
8684
return true
8785
}
8886

@@ -167,6 +165,8 @@ async function save(saveData: ExtSave) {
167165

168166
async function saveNote(noteData: ExtNote, source?: string) {
169167
try {
168+
if (!source) throw new Error('Error attaching note!')
169+
170170
// Let's add our note
171171
const item = await addNote({ ...noteData, source })
172172

@@ -182,6 +182,8 @@ async function saveNote(noteData: ExtNote, source?: string) {
182182

183183
async function deleteNote(noteId: string) {
184184
try {
185+
if (!noteId) throw new Error('Error finding noteId')
186+
185187
await removeNote(noteId)
186188
// send a message so the popup can display the preview
187189
sendMessage({ action: EXT_ACTIONS.DELETE_NOTE_SUCCESS, noteId })

clients/extension/components/action-container/index.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,23 @@ import { SavedScreen } from '../saved'
77

88
// Types
99
import type { ExtItem } from '../../types'
10+
import type { NoteEdge } from '@common/types/pocket'
1011
import type { Dispatch, SetStateAction } from 'react'
1112

1213
export function ActionContainer({
1314
isOpen = false,
1415
errorMessage,
1516
noteStatus,
1617
setNoteStatus,
18+
notes,
1719
item
1820
}: {
1921
isOpen: boolean
2022
errorMessage?: string
2123
saveStatus?: string
2224
noteStatus?: string
2325
item?: ExtItem
26+
notes: NoteEdge[] | []
2427
setNoteStatus: Dispatch<SetStateAction<string | undefined>>
2528
actionLogOut: () => void
2629
actionUnSave: () => void
@@ -29,7 +32,6 @@ export function ActionContainer({
2932
const [errorText, setErrorText] = useState<string | undefined>(errorMessage)
3033

3134
const preview = item?.preview
32-
const notes = item?.savedItem?.notes
3335
const tags = item?.savedItem?.tags
3436
const suggestedTags = item?.savedItem?.suggestedTags
3537

@@ -41,7 +43,7 @@ export function ActionContainer({
4143
{showNotes ? (
4244
<Notes
4345
noteStatus={noteStatus}
44-
notes={notes?.edges}
46+
notes={notes}
4547
setShowNotes={setShowNotes}
4648
setNoteStatus={setNoteStatus}
4749
setErrorText={setErrorText}

clients/extension/components/notes-add/index.tsx

+12-1
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import type { Dispatch, SetStateAction } from 'react'
66

77
export function NotesAdd({
88
textRef,
9+
titleRef,
910
noteStatus,
1011
setErrorText
1112
}: {
13+
titleRef?: RefObject<HTMLInputElement | null>
1214
textRef?: RefObject<HTMLTextAreaElement | null>
1315
noteStatus?: string
1416
setErrorText: Dispatch<SetStateAction<string | undefined>>
@@ -20,7 +22,16 @@ export function NotesAdd({
2022
{noteStatus ? (
2123
<ActionLoader />
2224
) : (
23-
<textarea onFocus={resetError} name="note" id="note" ref={textRef}></textarea>
25+
<>
26+
<input
27+
type="text"
28+
ref={titleRef}
29+
name="noteTitle"
30+
id="noteTitle"
31+
placeholder="Title (optional)"
32+
/>
33+
<textarea onFocus={resetError} name="note" id="note" ref={textRef}></textarea>
34+
</>
2435
)}
2536
</div>
2637
)
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
.container {
22
padding: 1rem;
3+
input,
4+
textarea {
5+
background-color: var(--color-canvas-darker);
6+
}
7+
input[type='text'] {
8+
margin-bottom: 0.5rem;
9+
}
310
}

clients/extension/components/notes-list/index.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ function Note({
4040
const node = note?.node
4141
const noteId = node?.id
4242
const title = node?.title
43+
const date = new Date(node?.createdAt as string)
44+
const dateString = date.toLocaleString(undefined, {
45+
year: 'numeric',
46+
month: 'short',
47+
day: 'numeric'
48+
})
4349
const contentPreview = node?.contentPreview as string
4450

4551
const handleDeleteClick = () => {
@@ -57,6 +63,7 @@ function Note({
5763
<div className={`${style.container} ${confirmDelete && style.active}`} ref={noteRef}>
5864
<div className={style.note}>
5965
{title ? <h3>{title}</h3> : null}
66+
<div className={style.date}>{dateString}</div>
6067
<ReactMarkdown allowedElements={['div']} unwrapDisallowed={true}>
6168
{contentPreview}
6269
</ReactMarkdown>

clients/extension/components/notes-list/style.module.css

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
border-bottom: none;
1919
}
2020
.actions {
21+
display: flex;
22+
align-items: center;
2123
visibility: hidden;
2224
color: var(--color-text-secondary);
2325
button {
@@ -78,3 +80,10 @@
7880
width: 100%;
7981
}
8082
}
83+
84+
.date {
85+
font-size: 0.75rem;
86+
font-style: italic;
87+
padding: 0 0 0.5rem 0;
88+
color: var(--color-text-secondary);
89+
}

clients/extension/components/notes/index.tsx

+18-2
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,32 @@ export function Notes({
2424
setShowNotes: Dispatch<SetStateAction<boolean>>
2525
}) {
2626
const textRef = useRef<HTMLTextAreaElement | null>(null)
27+
const titleRef = useRef<HTMLInputElement | null>(null)
2728

2829
const handleAddNote = () => {
2930
// Get the value of our textarea
3031
if (!textRef.current) return
3132
const docMarkdown = textRef.current.value.trim()
3233

34+
// Let's sort out the optional title
35+
const title = titleRef.current ? titleRef.current.value.trim() : false
36+
3337
// Let's not add empty notes
3438
if (!docMarkdown?.length) {
3539
textRef.current.value = '' // gets rid of space only values
3640
return setErrorText('Text is require to create a note')
3741
}
3842

43+
// Need to reset the input fields
44+
if (titleRef.current) titleRef.current.value = ''
3945
textRef.current.value = ''
46+
47+
// Let's
4048
setNoteStatus('saving note')
41-
void sendMessage({ action: EXT_ACTIONS.ADD_NOTE_REQUEST, noteData: { docMarkdown } })
49+
void sendMessage({
50+
action: EXT_ACTIONS.ADD_NOTE_REQUEST,
51+
noteData: { docMarkdown, ...(title && { title }) }
52+
})
4253
}
4354

4455
const handleNoteDelete = (id: string) => {
@@ -50,7 +61,12 @@ export function Notes({
5061
<div>
5162
<div className={style.container}>
5263
<NotesList notes={notes} handleNoteDelete={handleNoteDelete} />
53-
<NotesAdd noteStatus={noteStatus} textRef={textRef} setErrorText={setErrorText} />
64+
<NotesAdd
65+
noteStatus={noteStatus}
66+
textRef={textRef}
67+
titleRef={titleRef}
68+
setErrorText={setErrorText}
69+
/>
5470
</div>
5571
<NotesFooter
5672
noteStatus={noteStatus}

clients/extension/public/styles/global.css

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
--color-canvas: #ffffff;
2323
--color-canvas-active: hsl(0, 0%, 90%);
24+
--color-canvas-darker: hsl(0, 0%, 95%);
2425
--color-loader: #42414d;
2526
--color-text-primary: #15141a;
2627
--color-text-secondary: #333;
@@ -38,6 +39,7 @@
3839
@media (prefers-color-scheme: dark) {
3940
--color-canvas: #42414d;
4041
--color-canvas-active: hsl(245, 8%, 38%);
42+
--color-canvas-darker: hsl(245, 8%, 24%);
4143
--color-loader: #15141a;
4244
--color-text-primary: #fbfbfe;
4345
--color-text-secondary: var(--color-grey85);
@@ -57,6 +59,7 @@
5759
.colormode-light {
5860
--color-canvas: #ffffff;
5961
--color-canvas-active: hsl(0, 0%, 90%);
62+
--color-canvas-darker: hsl(0, 0%, 95%);
6063
--color-loader: #42414d;
6164
--color-text-primary: #15141a;
6265
--color-text-secondary: #333;

0 commit comments

Comments
 (0)