diff --git a/src/components/calendar.tsx b/src/components/calendar.tsx index 8dae954..5b1eb2f 100644 --- a/src/components/calendar.tsx +++ b/src/components/calendar.tsx @@ -2,26 +2,18 @@ import React, { useEffect, useState } from 'react'; import Calendar, { CalendarTileProperties } from 'react-calendar'; import { RxDotFilled } from 'react-icons/rx'; import OZCalendarPlugin from '../main'; -import useForceUpdate from '../hooks/forceUpdate'; import NoteListComponent from './noteList'; import dayjs from 'dayjs'; +import useForceUpdate from 'hooks/forceUpdate'; export default function MyCalendar(params: { plugin: OZCalendarPlugin }) { const { plugin } = params; - const forceUpdate = useForceUpdate(); const [selectedDay, setSelectedDay] = useState(new Date()); - const [selectedDayNotes, setSelectedDayNotes] = useState([]); const [activeStartDate, setActiveStartDate] = useState(new Date()); + const { forceValue, forceUpdate } = useForceUpdate(); useEffect(() => setActiveStartDate(selectedDay), [selectedDay]); - useEffect(() => { - const selectedDayIso = dayjs(selectedDay).format('YYYY-MM-DD'); - const notes = - selectedDayIso in plugin.OZCALENDARDAYS_STATE ? plugin.OZCALENDARDAYS_STATE[selectedDayIso] : []; - setSelectedDayNotes(notes); - }, [selectedDay, plugin.OZCALENDARDAYS_STATE]); - useEffect(() => { window.addEventListener(plugin.EVENT_TYPES.forceUpdate, forceUpdate); return () => { @@ -29,12 +21,9 @@ export default function MyCalendar(params: { plugin: OZCalendarPlugin }) { }; }, []); - useEffect(() => forceUpdate(), [plugin.OZCALENDARDAYS_STATE]); - const customTileContent = ({ date, view }: CalendarTileProperties) => { if (view === 'month') { const dateString = dayjs(date).format('YYYY-MM-DD'); - let dotsCount = dateString in plugin.OZCALENDARDAYS_STATE ? plugin.OZCALENDARDAYS_STATE[dateString].length : 0; return ( @@ -78,8 +67,8 @@ export default function MyCalendar(params: { plugin: OZCalendarPlugin }) { selectedDay={selectedDay} setSelectedDay={setSelectedDay} setActiveStartDate={setActiveStartDate} - selectedDayNotes={selectedDayNotes} plugin={plugin} + forceValue={forceValue} /> diff --git a/src/components/noteList.tsx b/src/components/noteList.tsx index 49ca32e..726f645 100644 --- a/src/components/noteList.tsx +++ b/src/components/noteList.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo, useState } from 'react'; import { BsArrowRight, BsArrowLeft } from 'react-icons/bs'; import { HiOutlineDocumentText } from 'react-icons/hi'; import { RiPhoneFindLine } from 'react-icons/ri'; @@ -11,12 +11,12 @@ interface NoteListComponentParams { selectedDay: Date; setSelectedDay: (selectedDay: Date) => void; setActiveStartDate: (newActiveStartDate: Date) => void; - selectedDayNotes: string[]; plugin: OZCalendarPlugin; + forceValue: number; } export default function NoteListComponent(params: NoteListComponentParams) { - const { selectedDayNotes, setSelectedDay, selectedDay, plugin, setActiveStartDate } = params; + const { setSelectedDay, selectedDay, plugin, setActiveStartDate, forceValue } = params; const setNewSelectedDay = (nrChange: number) => { let newDate = dayjs(selectedDay).add(nrChange, 'day'); @@ -45,6 +45,11 @@ export default function NoteListComponent(params: NoteListComponentParams) { } }; + const selectedDayNotes = useMemo(() => { + const selectedDayIso = dayjs(selectedDay).format('YYYY-MM-DD'); + return selectedDayIso in plugin.OZCALENDARDAYS_STATE ? plugin.OZCALENDARDAYS_STATE[selectedDayIso] : []; + }, [selectedDay, forceValue]); + return ( <>
diff --git a/src/hooks/forceUpdate.tsx b/src/hooks/forceUpdate.tsx index 18c8731..7a20724 100644 --- a/src/hooks/forceUpdate.tsx +++ b/src/hooks/forceUpdate.tsx @@ -2,5 +2,8 @@ import React, { useState } from 'react'; export default function useForceUpdate() { const [value, setValue] = useState(0); - return () => setValue((value) => value + 1); + return { + forceValue: value, + forceUpdate: () => setValue((value) => value + 1), + }; } diff --git a/src/main.ts b/src/main.ts index 2e77d33..81b7bba 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import { CachedMetadata, Plugin, TFile, addIcon } from 'obsidian'; +import { CachedMetadata, Plugin, TAbstractFile, TFile, addIcon } from 'obsidian'; import { OZCalendarView, VIEW_TYPE } from './view'; import dayjs from 'dayjs'; import { OZCalendarDaysMap } from './types'; @@ -31,27 +31,21 @@ export default class OZCalendarPlugin extends Plugin { }); this.app.metadataCache.on('changed', this.handleCacheChange); - this.app.vault.on('rename', (file, oldPath) => { - if (file instanceof TFile && file.extension === 'md') { - this.removeFilePathFromState(oldPath); - this.scanTFileDate(file); - } - }); + this.app.vault.on('rename', this.handleRename); + this.app.vault.on('delete', this.handleDelete); } - scanTFileDate = (file: TFile) => { - let cache = this.app.metadataCache.getCache(file.path); - if (cache && cache.frontmatter) { - let fm = cache.frontmatter; - for (let k of Object.keys(cache.frontmatter)) { - if (k === this.settings.yamlKey) { - let fmValue = fm[k]; - let parsedDayISOString = dayjs(fmValue, this.settings.dateFormat).format('YYYY-MM-DD'); - this.addFilePathToState(parsedDayISOString, file.path); - } - } - } - }; + onunload() {} + + async loadSettings() { + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + } + + async saveSettings() { + await this.saveData(this.settings); + } + + /* ------------ HANDLE VAULT CHANGES - HELPERS ------------ */ addFilePathToState = (date: string, filePath: string) => { let newStateMap = this.OZCALENDARDAYS_STATE; @@ -64,25 +58,45 @@ export default class OZCalendarPlugin extends Plugin { this.OZCALENDARDAYS_STATE = newStateMap; }; - removeFilePathFromState = (filePath: string) => { + removeFilePathFromState = (filePath: string): boolean => { + let changeFlag = false; let newStateMap = this.OZCALENDARDAYS_STATE; for (let k of Object.keys(newStateMap)) { if (newStateMap[k].contains(filePath)) { newStateMap[k] = newStateMap[k].filter((p) => p !== filePath); + changeFlag = true; } } this.OZCALENDARDAYS_STATE = newStateMap; + return changeFlag; }; - onunload() {} + scanTFileDate = (file: TFile): boolean => { + let cache = this.app.metadataCache.getCache(file.path); + let changeFlag = false; + if (cache && cache.frontmatter) { + let fm = cache.frontmatter; + for (let k of Object.keys(cache.frontmatter)) { + if (k === this.settings.yamlKey) { + let fmValue = fm[k]; + let parsedDayISOString = dayjs(fmValue, this.settings.dateFormat).format('YYYY-MM-DD'); + this.addFilePathToState(parsedDayISOString, file.path); + changeFlag = true; + } + } + } + return changeFlag; + }; - async loadSettings() { - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); - } + calendarForceUpdate = () => { + window.dispatchEvent( + new CustomEvent(this.EVENT_TYPES.forceUpdate, { + detail: {}, + }) + ); + }; - async saveSettings() { - await this.saveData(this.settings); - } + /* ------------ HANDLE VAULT CHANGES - LISTENER FUNCTIONS ------------ */ handleCacheChange = (file: TFile, data: string, cache: CachedMetadata) => { this.removeFilePathFromState(file.path); @@ -107,6 +121,21 @@ export default class OZCalendarPlugin extends Plugin { this.calendarForceUpdate(); }; + handleRename = (file: TFile, oldPath: string) => { + if (file instanceof TFile && file.extension === 'md') { + let changeFlag = this.removeFilePathFromState(oldPath); + let changeFlag2 = this.scanTFileDate(file); + if (changeFlag || changeFlag2) this.calendarForceUpdate(); + } + }; + + handleDelete = (file: TAbstractFile) => { + let changeFlag = this.removeFilePathFromState(file.path); + if (changeFlag) this.calendarForceUpdate(); + }; + + /* ------------ OTHER FUNCTIONS ------------ */ + openOZCalendarLeaf = async (params: { showAfterAttach: boolean }) => { const { showAfterAttach } = params; let leafs = this.app.workspace.getLeavesOfType(VIEW_TYPE); @@ -121,14 +150,6 @@ export default class OZCalendarPlugin extends Plugin { } }; - calendarForceUpdate = () => { - window.dispatchEvent( - new CustomEvent(this.EVENT_TYPES.forceUpdate, { - detail: {}, - }) - ); - }; - reloadPlugin = () => { // @ts-ignore this.app.plugins.disablePlugin('oz-calendar');