This commit is contained in:
@@ -15,9 +15,15 @@ const sourceText = ref(''); // Original markdown source, used for editing
|
||||
const displayText = ref(''); // Compiled HTML from markdown
|
||||
|
||||
const editingMode = ref(false);
|
||||
const editableTitle = ref(null);
|
||||
const title = ref(props.title);
|
||||
const displayTitle = ref('');
|
||||
const isDirty = ref(false);
|
||||
const showClose = ref(false);
|
||||
|
||||
let savedState = { text: '', title: '' };
|
||||
|
||||
function markDirty() {
|
||||
isDirty.value = sourceText.value !== savedState.text || title.value !== savedState.title;
|
||||
}
|
||||
|
||||
function closeNote(){
|
||||
emitter.emit('delete-note', props.noteKey);
|
||||
@@ -48,20 +54,29 @@ function update(){
|
||||
}, 0);
|
||||
}
|
||||
|
||||
watch(sourceText, (newText) => {
|
||||
// update();
|
||||
});
|
||||
watch(sourceText, markDirty);
|
||||
|
||||
watch(title, markDirty);
|
||||
|
||||
onMounted(() => {
|
||||
sourceText.value = props.text;
|
||||
title.value = props.title;
|
||||
displayTitle.value = props.title;
|
||||
|
||||
savedState = { text: props.text, title: props.title };
|
||||
emitter.on('title-updated', handleTitleUpdate);
|
||||
// window.addEventListener('keydown', handleKeydown);
|
||||
setTimeout(() => setupCallout(), 0);
|
||||
update();
|
||||
});
|
||||
|
||||
function handleTitleUpdate(data) {
|
||||
if (data.key !== props.noteKey) return;
|
||||
title.value = data.title;
|
||||
savedState.title = data.title;
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
emitter.off('title-updated', handleTitleUpdate);
|
||||
// window.removeEventListener('keydown', handleKeydown);
|
||||
});
|
||||
|
||||
@@ -92,12 +107,11 @@ function SaveNote(){
|
||||
title: title.value,
|
||||
}).then((response) => {
|
||||
if(response.data.status !== 'ok'){
|
||||
// Handle error (e.g., show a notification)
|
||||
return;
|
||||
}
|
||||
// DisplayToast('green', "Note saved successfully.", 500);
|
||||
savedState = { text: sourceText.value, title: title.value };
|
||||
isDirty.value = false;
|
||||
}).catch((error) => {
|
||||
// Handle error (e.g., show a notification)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -147,16 +161,18 @@ function setupCallout() {
|
||||
}
|
||||
|
||||
|
||||
const editTitle = (e) => {
|
||||
title.value = e.target.innerText;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="note" @keydown="handleKeydown" tabindex="0">
|
||||
<div class="note-stunt">
|
||||
<div class="close-button" v-on:click="closeNote">
|
||||
<div class="unsaved-wrapper" v-if="isDirty">
|
||||
<div class="unsaved-dot"></div>
|
||||
<div class="close-button close-hidden" v-on:click="closeNote">
|
||||
<img class="icon" src="/icons/Pixelarticons/white/close.svg" alt="My Happy SVG"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="close-button" v-else v-on:click="closeNote">
|
||||
<img class="icon" src="/icons/Pixelarticons/white/close.svg" alt="My Happy SVG"/>
|
||||
</div>
|
||||
<span>{{ title }}</span>
|
||||
@@ -164,7 +180,7 @@ const editTitle = (e) => {
|
||||
<div class="note-content-container">
|
||||
<textarea v-model="sourceText" class="full-editor" v-if="editingMode"></textarea>
|
||||
<div v-else class="note-content" ref="noteContent">
|
||||
<h1 contenteditable="true" ref="editableTitle" @input="editTitle">{{ displayTitle }}</h1>
|
||||
<h1>{{ title }}</h1>
|
||||
<div ref="noteContent" v-html="displayText"></div>
|
||||
</div>
|
||||
|
||||
@@ -184,6 +200,46 @@ const editTitle = (e) => {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.unsaved-wrapper {
|
||||
position: relative;
|
||||
margin-bottom: 5px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.unsaved-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background-color: #ffffff;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.close-hidden {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-bottom: 0;
|
||||
transition: opacity 0.15s ease, visibility 0.15s ease;
|
||||
}
|
||||
|
||||
.unsaved-wrapper:hover .close-hidden {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.unsaved-wrapper:hover .unsaved-dot {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.full-editor {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
@@ -48,11 +48,20 @@ function handleDeleteNote(key) {
|
||||
onMounted(() => {
|
||||
emitter.on("push-note", handlePushNote);
|
||||
emitter.on("delete-note", handleDeleteNote);
|
||||
emitter.on("title-updated", handleTitleUpdated);
|
||||
});
|
||||
|
||||
function handleTitleUpdated(data) {
|
||||
const note = noteData.value.find(n => n.key === data.key);
|
||||
if (note) {
|
||||
note.title = data.title;
|
||||
}
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
emitter.off("push-note", handlePushNote);
|
||||
emitter.off("delete-note", handleDeleteNote);
|
||||
emitter.off("title-updated", handleTitleUpdated);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user