web: use database updated event to add editor reactivity

This commit is contained in:
Abdullah Atta
2024-03-14 10:01:34 +05:00
parent a86565a8ec
commit 0cfd607806
3 changed files with 57 additions and 42 deletions

View File

@@ -109,12 +109,13 @@ type EditorPropertiesProps = {
session: DefaultEditorSession | ReadonlyEditorSession | DeletedEditorSession;
};
function EditorProperties(props: EditorPropertiesProps) {
const { session } = props;
const toggleProperties = useEditorStore((store) => store.toggleProperties);
const isFocusMode = useAppStore((store) => store.isFocusMode);
if (isFocusMode) return null;
const session = useEditorStore((store) =>
store.getSession(props.session.id, [props.session.type])
);
console.log(session);
if (isFocusMode || !session) return null;
return (
<AnimatedFlex
animate={{

View File

@@ -251,7 +251,7 @@ class EditorStore extends BaseStore<EditorStore> {
else if (item.type === "note") {
updateSession(
session.id,
["default", "readonly", "deleted", "locked"],
[session.type],
(session) => (session.note = item)
);
}
@@ -263,7 +263,8 @@ class EditorStore extends BaseStore<EditorStore> {
db.eventManager.subscribe(
EVENTS.databaseUpdated,
(event: DatabaseUpdatedEvent) => {
const { sessions, openSession, closeSessions } = this.get();
const { sessions, openSession, closeSessions, updateSession } =
this.get();
const clearIds: string[] = [];
if (event.collection === "notes") {
// when a note is permanently deleted from trash
@@ -279,15 +280,15 @@ class EditorStore extends BaseStore<EditorStore> {
} else if (event.type === "update") {
for (const session of sessions) {
if (
!event.ids.includes(session.id) &&
!("note" in session && event.ids.includes(session.note.id))
session.type === "new" ||
(!event.ids.includes(session.id) &&
!event.ids.includes(session.note.id))
)
continue;
if (
// when a note's readonly property is toggled
(session.type === "readonly") !==
!!(event.item as Note).readonly ||
(session.type === "readonly") !== !!event.item.readonly ||
// when a note is restored from trash
(session.type === "deleted") === (event.item.type !== "trash")
) {
@@ -298,6 +299,18 @@ class EditorStore extends BaseStore<EditorStore> {
(event.item.type === "trash")
)
clearIds.push(session.id);
else {
updateSession(session.id, [session.type], (session) => {
session.note.pinned =
event.item.pinned ?? session.note.pinned;
session.note.localOnly =
event.item.localOnly ?? session.note.localOnly;
session.note.favorite =
event.item.favorite ?? session.note.favorite;
session.note.dateEdited =
event.item.dateEdited ?? session.note.dateEdited;
});
}
}
}
} else if (event.collection === "content") {
@@ -310,12 +323,40 @@ class EditorStore extends BaseStore<EditorStore> {
if (
// when a note is locked or unlocked
(session.type === "locked") !==
!!(event.item as ContentItem).locked
!!event.item.locked
) {
openSession(session.id, { force: true, silent: true });
}
}
}
} else if (event.collection === "relations") {
if (
event.type === "upsert" &&
event.item.toId &&
event.item.fromId &&
event.item.fromType === "color" &&
event.item.toType === "note"
) {
updateSession(event.item.toId, undefined, {
color: event.item.fromId
});
} else if (
event.type === "unlink" &&
event.reference.type === "color" &&
event.types.includes("note")
) {
for (const session of sessions) {
if (!("color" in session) || !session.color) continue;
const hasSameColor =
"id" in event.reference
? session.color === event.reference.id
: event.reference.ids.includes(session.color);
if (!hasSameColor) continue;
updateSession(session.id, undefined, {
color: undefined
});
}
}
}
if (clearIds.length > 0) closeSessions(...clearIds);
}
@@ -354,16 +395,16 @@ class EditorStore extends BaseStore<EditorStore> {
refresh = async () => {};
updateSession = <T extends SessionType[]>(
updateSession = <T extends SessionType[] = SessionType[]>(
id: string,
types: T,
types: T | undefined,
partial:
| Partial<SessionTypeMap[T[number]]>
| ((session: SessionTypeMap[T[number]]) => void)
) => {
this.set((state) => {
const index = state.sessions.findIndex(
(s) => s.id === id && types.includes(s.type)
(s) => s.id === id && (!types || types.includes(s.type))
);
if (index === -1) return;
const session = state.sessions[index] as SessionTypeMap[T[number]];

View File

@@ -19,9 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { db } from "../common/db";
import createStore from "../common/store";
import { useEditorStore } from "./editor-store";
import { store as appStore } from "./app-store";
import { store as selectionStore } from "./selection-store";
import Vault from "../common/vault";
import BaseStore from ".";
import Config from "../utils/config";
@@ -71,30 +69,22 @@ class NoteStore extends BaseStore<NoteStore> {
};
delete = async (...ids: string[]) => {
const { closeSessions, getActiveSession } = useEditorStore.getState();
const session = getActiveSession();
if (session && session.id && ids.indexOf(session.id) > -1)
closeSessions(session.id);
await db.notes.moveToTrash(...ids);
await this.refresh();
};
pin = async (state: boolean, ...ids: string[]) => {
await db.notes.pin(state, ...ids);
this.syncNoteWithEditor(ids, "pinned", state);
await this.refresh();
};
favorite = async (state: boolean, ...ids: string[]) => {
await db.notes.favorite(state, ...ids);
this.syncNoteWithEditor(ids, "favorite", state);
await this.refresh();
};
unlock = async (id: string) => {
return await Vault.unlockNote(id).then(async (res) => {
if (useEditorStore.getState().getActiveSession()?.id === id)
await useEditorStore.getState().openSession(id);
await this.refresh();
return res;
});
@@ -103,13 +93,10 @@ class NoteStore extends BaseStore<NoteStore> {
lock = async (id: string) => {
if (!(await Vault.lockNote(id))) return false;
await this.refresh();
if (useEditorStore.getState().getActiveSession()?.id === id)
await useEditorStore.getState().openSession(id, { force: true });
};
readonly = async (state: boolean, ...ids: string[]) => {
await db.notes.readonly(state, ...ids);
this.syncNoteWithEditor(ids, "readonly", state);
await this.refresh();
};
@@ -120,12 +107,11 @@ class NoteStore extends BaseStore<NoteStore> {
localOnly = async (state: boolean, ...ids: string[]) => {
await db.notes.localOnly(state, ...ids);
this.syncNoteWithEditor(ids, "localOnly", state);
await this.refresh();
};
setColor = async (colorId: string, isChecked: boolean, ...ids: string[]) => {
await db.relations.to({ type: "note", ids }, "color").unlink();
await db.relations.from({ type: "color", id: colorId }, "note").unlink();
if (!isChecked) {
for (const id of ids) {
await db.relations.add(
@@ -135,21 +121,8 @@ class NoteStore extends BaseStore<NoteStore> {
}
}
await appStore.refreshNavItems();
this.syncNoteWithEditor(ids, "color", colorId);
await this.refresh();
};
private syncNoteWithEditor = (
noteIds: string[],
action: "favorite" | "pinned" | "readonly" | "localOnly" | "color",
value: boolean | string
) => {
const { getActiveSession, toggle } = useEditorStore.getState();
const session = getActiveSession();
if (!session || !session.id || !noteIds.includes(session.id)) return false;
toggle(session.id, action, value);
return true;
};
}
const [useStore, store] = createStore<NoteStore>(