You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<div style="text-align:center;margin-top:14px;color:var(--muted);font-size:0.85rem;">Notes live in your browser (localStorage). No account needed.</div>
function nowISO(){return new Date().toISOString()}
84
+
function load(){try{const raw=localStorage.getItem(STORAGE_KEY);const parsed=raw?JSON.parse(raw):[];notes=Array.isArray(parsed)?parsed:[]}catch(e){notes=[]}}
85
+
function saveAll(){try{localStorage.setItem(STORAGE_KEY,JSON.stringify(notes))}catch(e){console.error('save failed',e)}}
86
+
function stripHtml(html){const d=document.createElement('div');d.innerHTML=html||'';return d.textContent||d.innerText||''}
87
+
function snippet(html){const txt=stripHtml(html).trim();return txt.length>120?txt.slice(0,120)+'...':(txt||'(empty)')}
88
+
function renderNotesList(filter){if(!notesListEl) return;notesListEl.innerHTML='';const f=String(filter||'').toLowerCase();const sorted=notes.slice().sort((a,b)=>new Date(b.updated_at||b.created_at)-new Date(a.updated_at||a.created_at));const filtered=sorted.filter(n=>((n.title||'').toLowerCase().includes(f))||((stripHtml(n.content)||'').toLowerCase().includes(f)));if(filtered.length===0){notesListEl.innerHTML='<div class="small" style="padding:8px;color:var(--muted)">No saved notes yet</div>';return}for(const n of filtered){const card=document.createElement('div');card.className='note-card';if(n.id===activeId) card.className+=' active-note';card.dataset.id=n.id;const t=document.createElement('div');t.className='note-title';t.innerText=n.title||'Untitled';const s=document.createElement('div');s.className='note-snippet';s.innerText=snippet(n.content);const meta=document.createElement('div');meta.className='small';meta.innerText=new Date(n.updated_at||n.created_at).toLocaleString();card.appendChild(t);card.appendChild(s);card.appendChild(meta);card.addEventListener('click',()=>openNote(n.id));notesListEl.appendChild(card)}}
89
+
function highlightActive(){const cards=document.querySelectorAll('.note-card');cards.forEach(c=>{c.style.outline=(c.dataset.id===activeId)?'2px solid rgba(124,58,237,0.18)':'none'})}
90
+
function createNoteWithContent(title,content){const id='n_'+Math.random().toString(36).slice(2,9);const now=nowISO();const n={id,title:title||'',content:content||'',created_at:now,updated_at:now};notes.push(n);saveAll();renderNotesList(searchEl?searchEl.value.toLowerCase():'');openNote(id);return n}
91
+
function newNote(){createNoteWithContent('','');if(titleEl) titleEl.focus()}
92
+
function openNote(id){const n=notes.find(x=>x.id===id);if(!n) return;activeId=id;if(titleEl) titleEl.value=n.title||'';if(editorEl) editorEl.innerHTML=n.content||'';highlightActive()}
93
+
function saveNote(){const title=(titleEl&&titleEl.value!==undefined)?titleEl.value.trim():'';const content=(editorEl&&editorEl.innerHTML!==undefined)?editorEl.innerHTML:'';if(!activeId){const created=createNoteWithContent(title,content);created.title=title;created.content=content;created.updated_at=nowISO();saveAll();renderNotesList(searchEl?searchEl.value.toLowerCase():'');activeId=created.id;flash('Saved');return}const n=notes.find(x=>x.id===activeId);if(!n){const created=createNoteWithContent(title,content);created.updated_at=nowISO();saveAll();renderNotesList(searchEl?searchEl.value.toLowerCase():'');activeId=created.id;flash('Saved');return}n.title=title;n.content=content;n.updated_at=nowISO();saveAll();renderNotesList(searchEl?searchEl.value.toLowerCase():'');flash('Saved')}
94
+
function deleteNote(){if(!activeId) return;const ok=confirm('Delete this note?');if(!ok) return;notes=notes.filter(x=>x.id!==activeId);saveAll();activeId=null;if(titleEl) titleEl.value='';if(editorEl) editorEl.innerHTML='';renderNotesList(searchEl?searchEl.value.toLowerCase():'');flash('Deleted')}
95
+
function flash(msg){const el=document.createElement('div');el.innerText=msg;el.style.position='fixed';el.style.right='18px';el.style.bottom='18px';el.style.padding='10px 12px';el.style.borderRadius='8px';el.style.background='rgba(0,0,0,0.6)';el.style.color='white';el.style.zIndex='9999';document.body.appendChild(el);setTimeout(()=>{el.style.transition='opacity 300ms';el.style.opacity='0'},1200);setTimeout(()=>el.remove(),1600)}
96
+
function format(cmd,val){try{document.execCommand(cmd,false,val)}catch(e){console.warn('format failed',e)}if(editorEl) editorEl.focus()}
97
+
function insertLink(){const url=prompt('Enter a URL (include https://)');if(!url) return;format('createLink',url)}
0 commit comments