edit existing note, editor state
This commit is contained in:
parent
a5e6806aca
commit
c4de94d395
|
@ -23,26 +23,29 @@
|
|||
<div class="menu" id="contextMenu">
|
||||
<button id="deleteButton">Delete</button>
|
||||
</div>
|
||||
<h1>Snotes Deck</h1>
|
||||
<h1>Maid Notes</h1>
|
||||
|
||||
<div id="button-row">
|
||||
<button class="row" id="show-notes-button">Refresh Notes</button>
|
||||
<button type="submit" id="save-button">Save</button>
|
||||
<button class="row" id="new-button">New</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="sidebar">
|
||||
<div class="note-sidebar-container" id="note-sidebar-container">
|
||||
<!--
|
||||
<!-- This is how the generated notes will look like:
|
||||
<div class="sidebar-note rightclick-element">
|
||||
<span class="sidebar-note-id">1</span>
|
||||
<span class="sidebar-note-content">Lorem ipsum dolor sit amet...</span>
|
||||
<span class="sidebar-note-tag">Tag</span>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="editor">
|
||||
<input id="create-tag" placeholder="Tag..." />
|
||||
<textarea id="create-input" placeholder="Note..."></textarea>
|
||||
<textarea id="create-input" placeholder="Type your note here..."></textarea>
|
||||
<p id="create-msg"></p>
|
||||
|
||||
<p style="white-space: pre-line" id="notes-list"></p>
|
||||
|
|
|
@ -124,6 +124,18 @@ pub fn delete_specific_note(id: i32) -> Result<(), String> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn edit_specific_note(id: i32, tag: &str, content: &str) -> Result<(), String> {
|
||||
let home = home_dir().unwrap().join(".snotes.db");
|
||||
let connection = Connection::open(home).map_err(|e| format!("Database Error: {}", e))?;
|
||||
|
||||
let query = "UPDATE notes SET tag = ?1, content = ?2 WHERE nid = ?3";
|
||||
match connection.execute(query, [&tag, &content, &id.to_string().as_str()]) {
|
||||
Ok(1) => Ok(()), // 1 row affected means the note was updated successfully
|
||||
Ok(_) => Err("No note with the provided ID found.".to_string()),
|
||||
Err(e) => Err(format!("Edit Error: {}", e)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -9,9 +9,10 @@ fn greet(name: &str) -> String {
|
|||
format!("Hello, {}! You've been greeted from Rust!", name)
|
||||
}
|
||||
|
||||
/// get ALL notes in the Database. If you don't want this, set show_notes(false)
|
||||
#[tauri::command]
|
||||
fn get_notes_list() -> String {
|
||||
let notes = show_notes(false, "").unwrap();
|
||||
let notes = show_notes(true, "").unwrap();
|
||||
notes.to_string()
|
||||
}
|
||||
|
||||
|
@ -30,9 +31,22 @@ fn delete_specific_note(id: u32) -> bool {
|
|||
libsnotes::delete_specific_note(id.try_into().unwrap()).is_ok()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn update_specific_note(id: u32, content: &str, tag: &str) -> bool {
|
||||
println!("update specific note");
|
||||
|
||||
libsnotes::edit_specific_note(id.try_into().unwrap(), tag, content).is_ok()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
.invoke_handler(tauri::generate_handler![greet, get_notes_list, create_note, delete_specific_note])
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
greet,
|
||||
get_notes_list,
|
||||
create_note,
|
||||
delete_specific_note,
|
||||
update_specific_note
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
},
|
||||
"package": {
|
||||
"productName": "snotes-deck",
|
||||
"version": "0.0.2"
|
||||
"version": "0.0.3"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
|
|
91
src/main.ts
91
src/main.ts
|
@ -11,19 +11,54 @@ let noteSidebarContainerEl: HTMLDivElement | null;
|
|||
|
||||
let noteArray: Note[] = []
|
||||
|
||||
// create
|
||||
async function createNote() {
|
||||
console.log("reached ssssjs")
|
||||
/** ID of current note, if we're editing an existing note */
|
||||
let currentNoteId: number | null = null;
|
||||
|
||||
|
||||
enum EditorState {
|
||||
NEW,
|
||||
EDITING
|
||||
}
|
||||
|
||||
/** Editor always initializes in the NEW state */
|
||||
let editorState = EditorState.NEW
|
||||
|
||||
/**
|
||||
* Saves the note.
|
||||
* Or updates an existing note depending on editor state
|
||||
*/
|
||||
async function saveNote() {
|
||||
if (createNoteContentEl && createNoteTagEl) {
|
||||
console.log("reached js")
|
||||
await invoke("create_note", {
|
||||
content: createNoteContentEl.value,
|
||||
tag: createNoteTagEl.value
|
||||
});
|
||||
switch (editorState) {
|
||||
case EditorState.NEW:
|
||||
console.log("creating new note..")
|
||||
await invoke("create_note", {
|
||||
content: createNoteContentEl.value,
|
||||
tag: createNoteTagEl.value
|
||||
});
|
||||
clearEditor();
|
||||
break;
|
||||
case EditorState.EDITING:
|
||||
console.log("updating existing note..")
|
||||
if (currentNoteId !== null) {
|
||||
await invoke("update_specific_note", {
|
||||
id: currentNoteId,
|
||||
content: createNoteContentEl.value,
|
||||
tag: createNoteTagEl.value
|
||||
});
|
||||
clearEditor();
|
||||
} else {
|
||||
console.error("No note is currently being edited");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// read
|
||||
/**
|
||||
* Retrieve Notes from DB and fill the sidebar with them
|
||||
*/
|
||||
async function showNotes() {
|
||||
if (notesMsgEl) {
|
||||
const array: Array<any> = await retrieveNotes();
|
||||
|
@ -56,9 +91,14 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
showNotes();
|
||||
document.querySelector("#save-button")?.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
createNote();
|
||||
saveNote();
|
||||
showNotes();
|
||||
});
|
||||
document.querySelector("#new-button")?.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
clearEditor();
|
||||
showNotes();
|
||||
})
|
||||
document.querySelector("#show-notes-button")?.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
showNotes();
|
||||
|
@ -94,14 +134,13 @@ function refreshContextMenuElements() {
|
|||
let posY = mouseY + menuHeight > viewportHeight ? mouseY - menuHeight : mouseY;
|
||||
|
||||
|
||||
contextMenu.style.display = 'block'; // Show the custom context menu
|
||||
contextMenu.style.display = 'block';
|
||||
contextMenu.style.left = `${posX}px`;
|
||||
contextMenu.style.top = `${posY}px`;
|
||||
|
||||
const noteIdElement = element.querySelector('.sidebar-note-id');
|
||||
if (noteIdElement) {
|
||||
const noteIdStr = noteIdElement.textContent;
|
||||
//console.log('Right-clicked note id:', noteId);
|
||||
if (noteIdStr) {
|
||||
const noteId: Number = parseInt(noteIdStr);
|
||||
showNoteSidebarContextMenu(noteId);
|
||||
|
@ -177,8 +216,7 @@ function handleSidebarNoteClick(id: Number): any {
|
|||
});
|
||||
|
||||
if (n) {
|
||||
createNoteContentEl.value = n.content as string;
|
||||
createNoteTagEl.value = n.tag as string;
|
||||
openNote(n);
|
||||
} else {
|
||||
// don't destory currently editing note if this fails
|
||||
console.error("Error fetching note");
|
||||
|
@ -211,3 +249,28 @@ function showNoteSidebarContextMenu(noteId: Number) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When a note is opened, the editor will switch to the EDITING state and get filled with
|
||||
* Note content
|
||||
*/
|
||||
function openNote(note: Note) {
|
||||
if (createNoteContentEl && createNoteTagEl) {
|
||||
createNoteContentEl.value = note.content as string;
|
||||
createNoteTagEl.value = note.tag as string;
|
||||
currentNoteId = note.id as number;
|
||||
// switch state
|
||||
editorState = EditorState.EDITING;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When new note is clicked, clear the editor content and switch Editor state
|
||||
*/
|
||||
function clearEditor() {
|
||||
if (createNoteContentEl && createNoteTagEl) {
|
||||
createNoteContentEl.value = "";
|
||||
createNoteTagEl.value = "";
|
||||
currentNoteId = null;
|
||||
editorState = EditorState.NEW;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
}
|
||||
|
||||
.editor {
|
||||
background-color: #24c8db;
|
||||
background-color: #41005a;
|
||||
margin-left: 1em;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -109,6 +109,10 @@ button:active {
|
|||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
||||
|
||||
resize: none;
|
||||
|
||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
||||
background-color: #252525;
|
||||
color: #f0f0f0
|
||||
}
|
||||
|
||||
#create-input:focus {
|
||||
|
@ -140,6 +144,11 @@ button {
|
|||
padding: 20px;
|
||||
}
|
||||
|
||||
.note-sidebar-container {
|
||||
max-height: 100%;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.sidebar-note {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -192,4 +201,28 @@ button {
|
|||
|
||||
.menu button:hover {
|
||||
background-color: #770079;
|
||||
}
|
||||
|
||||
/* MISC */
|
||||
|
||||
/* Fancier Scrollbar */
|
||||
|
||||
/* Hide scrollbar track */
|
||||
::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar:hover {
|
||||
visibility: visible;
|
||||
/* Show the scrollbar when hovered */
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #888;
|
||||
}
|
||||
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #555;
|
||||
}
|
Loading…
Reference in New Issue