256 lines
7.3 KiB
JavaScript
Executable File
256 lines
7.3 KiB
JavaScript
Executable File
// stores/notionStore.js
|
|
import { defineStore } from "pinia";
|
|
|
|
export const useNotionStore = defineStore("notion", {
|
|
state: () => ({
|
|
blocks: [],
|
|
selectedBlockId: null,
|
|
draggedBlockId: null,
|
|
}),
|
|
|
|
getters: {
|
|
getBlockById: (state) => (id) => {
|
|
return state.blocks.find((block) => block.id === id);
|
|
},
|
|
|
|
getChildBlocks: (state) => (parentId) => {
|
|
return state.blocks.filter((block) => block.parentId === parentId);
|
|
},
|
|
|
|
selectedBlock: (state) => {
|
|
return state.blocks.find((block) => block.id === state.selectedBlockId);
|
|
},
|
|
|
|
// بلوکهای سطح بالا (بدون والد)
|
|
topLevelBlocks: (state) => {
|
|
return state.blocks.filter((block) => !block.parentId);
|
|
},
|
|
},
|
|
|
|
actions: {
|
|
// ایجاد ID یکتا
|
|
generateId() {
|
|
return (
|
|
"block_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9)
|
|
);
|
|
},
|
|
|
|
// ایجاد بلوک جدید
|
|
addBlock({
|
|
type = "paragraph",
|
|
content = "",
|
|
parentId = null,
|
|
position = null,
|
|
}) {
|
|
const newBlock = {
|
|
id: this.generateId(),
|
|
type,
|
|
content,
|
|
parentId,
|
|
children: [],
|
|
properties: {},
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
collapsed: false,
|
|
aiProcessing: false,
|
|
color: "default",
|
|
};
|
|
|
|
// اضافه کردن بلوک در موقعیت مشخص
|
|
if (position !== null && position >= 0 && position < this.blocks.length) {
|
|
this.blocks.splice(position, 0, newBlock);
|
|
} else {
|
|
this.blocks.push(newBlock);
|
|
}
|
|
|
|
// اگر والد دارد، به لیست فرزندانش اضافه شود
|
|
if (parentId) {
|
|
const parent = this.getBlockById(parentId);
|
|
if (parent) {
|
|
parent.children.push(newBlock.id);
|
|
}
|
|
}
|
|
|
|
this.selectedBlockId = newBlock.id;
|
|
this.saveToLocalStorage();
|
|
return newBlock;
|
|
},
|
|
|
|
// بهروزرسانی بلوک
|
|
updateBlock(blockId, updates) {
|
|
const index = this.blocks.findIndex((block) => block.id === blockId);
|
|
if (index !== -1) {
|
|
this.blocks[index] = {
|
|
...this.blocks[index],
|
|
...updates,
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
this.saveToLocalStorage();
|
|
}
|
|
},
|
|
|
|
// حذف بلوک
|
|
deleteBlock(blockId) {
|
|
const block = this.getBlockById(blockId);
|
|
|
|
// حذف فرزندان بلوک
|
|
if (block && block.children && block.children.length > 0) {
|
|
block.children.forEach((childId) => this.deleteBlock(childId));
|
|
}
|
|
|
|
// حذف از لیست فرزندان والد
|
|
if (block && block.parentId) {
|
|
const parent = this.getBlockById(block.parentId);
|
|
if (parent) {
|
|
parent.children = parent.children.filter((id) => id !== blockId);
|
|
}
|
|
}
|
|
|
|
// حذف بلوک اصلی
|
|
this.blocks = this.blocks.filter((block) => block.id !== blockId);
|
|
this.saveToLocalStorage();
|
|
},
|
|
|
|
// انتخاب بلوک
|
|
selectBlock(blockId) {
|
|
this.selectedBlockId = blockId;
|
|
},
|
|
|
|
// جابجایی بلوک
|
|
moveBlock(blockId, newParentId = null, newIndex = null) {
|
|
const block = this.getBlockById(blockId);
|
|
if (!block) return;
|
|
|
|
// حذف از والد قبلی
|
|
if (block.parentId) {
|
|
const oldParent = this.getBlockById(block.parentId);
|
|
if (oldParent) {
|
|
oldParent.children = oldParent.children.filter(
|
|
(id) => id !== blockId
|
|
);
|
|
}
|
|
}
|
|
|
|
// آپدیت والد جدید
|
|
block.parentId = newParentId;
|
|
|
|
// اضافه به لیست فرزندان والد جدید
|
|
if (newParentId) {
|
|
const newParent = this.getBlockById(newParentId);
|
|
if (newParent) {
|
|
if (newIndex !== null) {
|
|
newParent.children.splice(newIndex, 0, blockId);
|
|
} else {
|
|
newParent.children.push(blockId);
|
|
}
|
|
}
|
|
}
|
|
|
|
// جابجایی در آرایه اصلی اگر index مشخص شده
|
|
if (newIndex !== null) {
|
|
const currentIndex = this.blocks.findIndex((b) => b.id === blockId);
|
|
if (currentIndex !== -1) {
|
|
const [block] = this.blocks.splice(currentIndex, 1);
|
|
this.blocks.splice(newIndex, 0, block);
|
|
}
|
|
}
|
|
|
|
this.saveToLocalStorage();
|
|
},
|
|
|
|
// ذخیره در localStorage
|
|
saveToLocalStorage() {
|
|
if (typeof window !== "undefined") {
|
|
localStorage.setItem(
|
|
"notion-blocks",
|
|
JSON.stringify({
|
|
blocks: this.blocks,
|
|
version: "1.0.0",
|
|
lastSaved: new Date().toISOString(),
|
|
})
|
|
);
|
|
}
|
|
},
|
|
|
|
// بارگذاری از localStorage
|
|
loadFromLocalStorage() {
|
|
if (typeof window !== "undefined") {
|
|
const saved = localStorage.getItem("notion-blocks");
|
|
if (saved) {
|
|
const data = JSON.parse(saved);
|
|
this.blocks = data.blocks || [];
|
|
} else {
|
|
// ایجاد بلوکهای پیشفرض
|
|
this.initializeDefaultBlocks();
|
|
}
|
|
}
|
|
},
|
|
|
|
// بلوکهای پیشفرض
|
|
initializeDefaultBlocks() {
|
|
this.blocks = [
|
|
{
|
|
id: this.generateId(),
|
|
type: "heading1",
|
|
content: "خوش آمدید به نوشن فارسی! 🎉",
|
|
parentId: null,
|
|
children: [],
|
|
properties: {},
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
collapsed: false,
|
|
color: "default",
|
|
},
|
|
{
|
|
id: this.generateId(),
|
|
type: "paragraph",
|
|
content:
|
|
"روی هر بلوک کلیک کنید یا علامت + را بزنید. برای منوی بیشتر راست کلیک کنید.",
|
|
parentId: null,
|
|
children: [],
|
|
properties: {},
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
collapsed: false,
|
|
color: "default",
|
|
},
|
|
{
|
|
id: this.generateId(),
|
|
type: "todo",
|
|
content: "اولین کار را انجام دهید",
|
|
parentId: null,
|
|
children: [],
|
|
properties: { checked: false },
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
collapsed: false,
|
|
color: "default",
|
|
},
|
|
];
|
|
},
|
|
|
|
// پیدا کردن موقعیت بلوک
|
|
findBlockPosition(blockId) {
|
|
return this.blocks.findIndex((block) => block.id === blockId);
|
|
},
|
|
|
|
// پیدا کردن بلوک بعدی
|
|
findNextBlock(blockId) {
|
|
const index = this.findBlockPosition(blockId);
|
|
if (index < this.blocks.length - 1) {
|
|
return this.blocks[index + 1];
|
|
}
|
|
return null;
|
|
},
|
|
|
|
// پیدا کردن بلوک قبلی
|
|
findPreviousBlock(blockId) {
|
|
const index = this.findBlockPosition(blockId);
|
|
if (index > 0) {
|
|
return this.blocks[index - 1];
|
|
}
|
|
return null;
|
|
},
|
|
},
|
|
});
|