diff --git a/src/constants.ts b/src/constants.ts index 7c28701..2869810 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,3 +1,5 @@ +export const CALENDAR_VIEW_TYPE = "journal-calendar"; + export const FRONTMATTER_DATE_FORMAT = "YYYY-MM-DD"; export const FRONTMATTER_ID_KEY = "journal"; export const FRONTMATTER_START_DATE_KEY = "journal-start-date"; diff --git a/src/journals/journals-index.ts b/src/journals/journals-index.ts index 3462efe..9d85128 100644 --- a/src/journals/journals-index.ts +++ b/src/journals/journals-index.ts @@ -20,7 +20,11 @@ export class JournalsIndex extends Component { this.#setupListeners(); } - getPathComputed(path: string) { + getForPath(path: string): JournalMetadata | null { + return this.#pathIndex.value.get(path) ?? null; + } + + getForPathComputed(path: string) { let cmp = this.#pathComputeds.get(path); if (cmp) return cmp; cmp = computed(() => this.#pathIndex.value.get(path) ?? null); diff --git a/src/main.ts b/src/main.ts index eaf8d4f..2c4115f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,5 @@ -import { type App, Plugin } from "obsidian"; -import { calendarSettings$, journals$, pluginSettings$ } from "./stores/settings.store"; +import { type App, Notice, Plugin } from "obsidian"; +import { calendarSettings$, calendarViewSettings$, journals$, pluginSettings$ } from "./stores/settings.store"; import { watch, type WatchStopHandle } from "vue"; import { debounce } from "perfect-debounce"; import { initCalendarCustomization, updateLocale } from "./calendar"; @@ -10,6 +10,7 @@ import type { JournalSettings } from "./types/settings.types"; import { defaultJournalSettings } from "./defaults"; import { prepareJournalDefaultsBasedOnType } from "./journals/journal-defaults"; import { JournalsIndex } from "./journals/journals-index"; +import { CALENDAR_VIEW_TYPE } from "./constants"; export default class JournalPlugin extends Plugin { #stopHandles: WatchStopHandle[] = []; @@ -37,6 +38,20 @@ export default class JournalPlugin extends Plugin { delete pluginSettings$.value.journals[id]; } + placeCalendarView(moving = false) { + if (this.app.workspace.getLeavesOfType(CALENDAR_VIEW_TYPE).length > 0) { + if (!moving) return; + this.app.workspace.getLeavesOfType(CALENDAR_VIEW_TYPE).forEach((leaf) => { + leaf.detach(); + }); + } + if (calendarViewSettings$.value.leaf === "left") { + this.app.workspace.getLeftLeaf(false)?.setViewState({ type: CALENDAR_VIEW_TYPE }); + } else { + this.app.workspace.getRightLeaf(false)?.setViewState({ type: CALENDAR_VIEW_TYPE }); + } + } + async onload(): Promise { app$.value = this.app; plugin$.value = this; @@ -50,6 +65,8 @@ export default class JournalPlugin extends Plugin { this.addChild(this.#index); this.index.reindex(); + this.#configureCommands(); + this.addSettingTab(new JournalSettingTab(this.app, this)); } onunload(): void { @@ -98,4 +115,80 @@ export default class JournalPlugin extends Plugin { }), ); } + + #configureCommands(): void { + this.addCommand({ + id: "open-next", + name: "Open next note", + editorCallback: async (editor, ctx) => { + const file = ctx.file; + if (!file) return; + const metadata = this.#index.getForPath(file.path); + if (!metadata) { + new Notice("This note is not connected to any journal."); + return; + } + const journal = this.#journals.get(metadata.id); + if (!journal) { + new Notice("Unknown journal id."); + return; + } + const nextNote = await journal.next(metadata, true); + if (!nextNote) { + new Notice("There is no next note after this one."); + return; + } + await journal.open(nextNote); + }, + }); + this.addCommand({ + id: "open-prev", + name: "Open previous note", + editorCallback: async (editor, ctx) => { + const file = ctx.file; + if (!file) return; + const metadata = this.#index.getForPath(file.path); + if (!metadata) { + new Notice("This note is not connected to any journal."); + return; + } + const journal = this.#journals.get(metadata.id); + if (!journal) { + new Notice("Unknown journal id."); + return; + } + const prevNote = await journal.previous(metadata, true); + if (!prevNote) { + new Notice("There is no previous note before this one."); + return; + } + await journal.open(prevNote); + }, + }); + + this.addCommand({ + id: "connect-note", + name: "Connect note to a journal", + editorCallback: async (editor, ctx) => { + const file = ctx.file; + if (file) { + // TODO + // new ConnectNoteModal(this.app, this, file).open(); + } + }, + }); + + this.addCommand({ + id: "open-calendar", + name: "Open calendar", + callback: () => { + let [leaf] = this.app.workspace.getLeavesOfType(CALENDAR_VIEW_TYPE); + if (!leaf) { + this.placeCalendarView(); + leaf = this.app.workspace.getLeavesOfType(CALENDAR_VIEW_TYPE)[0]; + } + this.app.workspace.revealLeaf(leaf); + }, + }); + } }