stfrigerio_sqliteDB/src/codeblocks/dateHeader/DateNavigator.ts

85 lines
3.4 KiB
TypeScript
Raw Normal View History

2025-04-05 14:50:18 +00:00
import { App } from "obsidian";
import { PluginState } from "src/pluginState";
import { DateNavigatorOptions, DateNavigatorDOMElements, NavigationPeriod } from "./dateNavigator.types";
import { createPrevHandler, createNextHandler, createOpenModalHandler } from "./eventHandlers/dateNavigationHandlers";
import { buildDateNavigatorDOM, updateDateNavigatorDisplay } from "./dom/buildDateNavigatorDOM";
import { DATE_CHANGED_EVENT_NAME } from "../../pluginState";
import { createPeriodChangeHandler } from "./eventHandlers/periodChangeHandler";
2025-04-05 14:50:18 +00:00
/**
* Creates and manages the interactive Date Navigator header.
* Uses pluginState to get/set the current date.
* Updates its display when the date changes.
*/
export class DateNavigator {
private app: App;
private pluginState: PluginState;
private containerEl: HTMLElement;
private configPeriod: NavigationPeriod;
2025-04-05 14:50:18 +00:00
private elements: DateNavigatorDOMElements | null = null;
private isListening: boolean = false;
2025-04-05 14:50:18 +00:00
constructor(options: DateNavigatorOptions) {
this.app = options.app;
this.pluginState = options.pluginState;
this.containerEl = options.containerEl;
this.configPeriod = options.period ?? 'day';
2025-04-05 14:50:18 +00:00
if (!this.app || !this.pluginState || !this.containerEl) {
throw new Error("DateNavigator missing required options (app, pluginState, containerEl).");
}
//? Set the global state's period to match this instance *on initialization*.
//? This means the last rendered navigator sets the global period.
if (this.pluginState.currentPeriod !== this.configPeriod) {
//? Note: This immediately changes global state and triggers event/recalc
this.pluginState.currentPeriod = this.configPeriod;
}
//? Now build the UI using the synchronized (or initially matching) state
2025-04-05 14:50:18 +00:00
this._buildUI();
this._setupStateListener();
2025-04-05 14:50:18 +00:00
}
/** Builds the initial UI */
private _buildUI(): void {
const currentGlobalPeriod = this.pluginState.currentPeriod;
const currentSelectedDate = this.pluginState.selectedDate;
2025-04-05 14:50:18 +00:00
//~ Create bound handlers first
const handlers = {
handlePrev: createPrevHandler(this.pluginState, this.app),
handleNext: createNextHandler(this.pluginState, this.app),
handleOpenModal: createOpenModalHandler(this.pluginState, this.app),
handlePeriodChange: createPeriodChangeHandler(this.pluginState),
2025-04-05 14:50:18 +00:00
};
//~ Build DOM and store element references
this.elements = buildDateNavigatorDOM(
this.containerEl,
currentSelectedDate,
currentGlobalPeriod,
handlers
);
2025-04-05 14:50:18 +00:00
}
/** Updates the displayed date. Bound method for callbacks. */
private _updateDisplay = (): void => {
const currentIsoDate = this.pluginState.selectedDate;
const currentPeriod = this.pluginState.currentPeriod;
updateDateNavigatorDisplay(this.elements, currentIsoDate, currentPeriod);
2025-04-05 14:50:18 +00:00
};
/** Listen for the custom date change event from pluginState */
private _setupStateListener(): void {
if (this.isListening) return;
document.addEventListener(DATE_CHANGED_EVENT_NAME, this._updateDisplay);
this.isListening = true;
}
2025-04-05 14:50:18 +00:00
/** Cleans up the component (e.g., remove listeners, clear container) */
public destroy(): void {
this.containerEl.empty();
this.elements = null;
}
}