初始化
This commit is contained in:
150
frontend/static/js/notes.js
Normal file
150
frontend/static/js/notes.js
Normal file
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* 笔记页面交互逻辑
|
||||
*/
|
||||
var currentNoteId = null;
|
||||
var saveTimer = null;
|
||||
var viewMode = "edit";
|
||||
|
||||
function setViewMode(mode) {
|
||||
viewMode = mode;
|
||||
var editPane = document.querySelector("#editPane");
|
||||
var previewPane = document.querySelector("#previewPane");
|
||||
document.querySelectorAll(".toggle-group button").forEach(function(b) {
|
||||
b.classList.toggle("active", b.dataset.mode === mode);
|
||||
});
|
||||
editPane.classList.remove("hidden");
|
||||
previewPane.classList.remove("hidden");
|
||||
if (mode === "edit") { previewPane.classList.add("hidden"); }
|
||||
else if (mode === "preview") { editPane.classList.add("hidden"); }
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
function createNote() {
|
||||
var folderId = getActiveFolderId();
|
||||
fetch("/api/notes", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ title: "无标题笔记", content: "", folder_id: folderId }),
|
||||
}).then(function(r) { return r.json(); })
|
||||
.then(function(note) { loadNote(note.id); refreshFolderNotes(); });
|
||||
}
|
||||
|
||||
function loadNote(noteId) {
|
||||
fetch("/api/notes/" + noteId)
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(note) {
|
||||
currentNoteId = note.id;
|
||||
document.querySelector("#currentNoteId").value = note.id;
|
||||
document.querySelector("#noteTitle").value = note.title;
|
||||
initEditor(note.content || "");
|
||||
document.querySelectorAll(".note-list-item").forEach(function(el) {
|
||||
el.classList.toggle("active", parseInt(el.dataset.noteId) === note.id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function scheduleSave() {
|
||||
var s = document.querySelector("#saveStatus");
|
||||
if (s) { s.textContent = "保存中…"; s.style.color = "#F5A623"; }
|
||||
clearTimeout(saveTimer);
|
||||
saveTimer = setTimeout(saveNote, 800);
|
||||
}
|
||||
|
||||
function saveNote() {
|
||||
if (!currentNoteId) return;
|
||||
var title = document.querySelector("#noteTitle").value;
|
||||
var content = editor ? editor.getHTML() : "";
|
||||
fetch("/api/notes/" + currentNoteId, {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ title: title, content: content }),
|
||||
}).then(function(r) {
|
||||
if (r.ok) { var s = document.querySelector("#saveStatus"); if (s) { s.textContent = "已保存"; s.style.color = ""; } }
|
||||
});
|
||||
}
|
||||
|
||||
function filterByFolder(folderId, el) {
|
||||
document.querySelectorAll(".folder-item").forEach(function(f) { f.classList.remove("active"); });
|
||||
el.classList.add("active");
|
||||
fetch("/api/notes?folder_id=" + folderId)
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(notes) { renderNoteList(notes); });
|
||||
}
|
||||
|
||||
function renderNoteList(notes) {
|
||||
var listDiv = document.querySelector("#folderNoteList");
|
||||
if (!listDiv) return;
|
||||
listDiv.classList.remove("hidden");
|
||||
|
||||
var html = '<div style="padding:4px 0; cursor:pointer; color:var(--brand); font-size:11px;" onclick="showFolderList()">← 返回文件夹</div>';
|
||||
if (!notes.length) {
|
||||
html += '<div style="color:#ccc; padding:8px; text-align:center; font-size:12px;">暂无笔记</div>';
|
||||
} else {
|
||||
notes.forEach(function(note) {
|
||||
var title = note.title || "无标题";
|
||||
var date = (note.updated_at || "").substr(0, 10);
|
||||
html += '<div class="note-list-item" data-note-id="' + note.id + '" onclick="loadNote(' + note.id + ')">' +
|
||||
'<span class="note-title-s">' + escapeHtml(title) + '</span>' +
|
||||
'<span class="note-date">' + date + '</span></div>';
|
||||
});
|
||||
}
|
||||
listDiv.innerHTML = html;
|
||||
}
|
||||
|
||||
function showFolderList() {
|
||||
var listDiv = document.querySelector("#folderNoteList");
|
||||
if (listDiv) listDiv.classList.add("hidden");
|
||||
}
|
||||
|
||||
function getActiveFolderId() {
|
||||
var active = document.querySelector(".folder-item.active");
|
||||
return active ? parseInt(active.dataset.folderId) : null;
|
||||
}
|
||||
|
||||
function refreshFolderNotes() {
|
||||
var af = document.querySelector(".folder-item.active");
|
||||
if (af) filterByFolder(parseInt(af.dataset.folderId), af);
|
||||
}
|
||||
|
||||
function addFolder() {
|
||||
var name = prompt("输入新文件夹名称:");
|
||||
if (!name) return;
|
||||
fetch("/api/folders", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: name, type: "note" }) })
|
||||
.then(function() { window.location.reload(); });
|
||||
}
|
||||
|
||||
function toggleFolderMenu(btn) {
|
||||
document.querySelectorAll(".folder-menu").forEach(function(m) { if (m !== btn.nextElementSibling) m.classList.add("hidden"); });
|
||||
var menu = btn.nextElementSibling;
|
||||
if (menu) menu.classList.toggle("hidden");
|
||||
setTimeout(function() {
|
||||
document.addEventListener("click", function close() { if (menu) menu.classList.add("hidden"); document.removeEventListener("click", close); }, { once: true });
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function renameFolder(folderId) {
|
||||
var name = prompt("新名称:"); if (!name) return;
|
||||
fetch("/api/folders/" + folderId, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: name }) })
|
||||
.then(function() { window.location.reload(); });
|
||||
}
|
||||
|
||||
function deleteFolder(folderId) {
|
||||
if (!confirm("确定删除此文件夹?内容将移至「未分类」")) return;
|
||||
fetch("/api/folders/" + folderId, { method: "DELETE" }).then(function() { window.location.reload(); });
|
||||
}
|
||||
|
||||
function deleteCurrentNote() {
|
||||
if (!currentNoteId || !confirm("确定删除?")) return;
|
||||
fetch("/api/notes/" + currentNoteId, { method: "DELETE" }).then(function() { window.location.reload(); });
|
||||
}
|
||||
|
||||
function filterByTag(tagId, el) { el.classList.toggle("active"); }
|
||||
function addTag() { var n = prompt("标签名:"); if (n) window.location.reload(); }
|
||||
|
||||
function escapeHtml(s) { return s ? s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""") : ""; }
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
document.querySelector("#noteTitle").addEventListener("input", scheduleSave);
|
||||
var firstId = document.querySelector("#firstNoteId");
|
||||
if (firstId && firstId.value) loadNote(parseInt(firstId.value)); else createNote();
|
||||
});
|
||||
Reference in New Issue
Block a user