andrii256_ops_obsidian_smar.../main.ts

264 lines
7 KiB
TypeScript
Raw Permalink Normal View History

// Import the SunCalc library to calculate sun position and light phases
import SunCalc from "suncalc"; // Documentation: https://www.npmjs.com/package/suncalc
2025-03-27 19:51:46 +00:00
import { App, Plugin, PluginSettingTab, Setting, debounce } from "obsidian";
2022-04-15 18:13:31 +00:00
/**
* SDNS: Smart DayNight Switcher
*/
2025-03-12 00:49:29 +00:00
interface SDNSPluginSettings {
2025-03-11 22:18:10 +00:00
latitude: string;
longitude: string;
}
const DEFAULT_SETTINGS: SDNSPluginSettings = {
2025-03-11 22:18:10 +00:00
latitude: "51.507351",
longitude: "-0.127758",
2025-03-11 21:07:44 +00:00
};
2022-04-15 18:13:31 +00:00
export default class SDNSPlugin extends Plugin {
2025-03-11 21:07:44 +00:00
private timeout: ReturnType<typeof setTimeout> | null;
settings: SDNSPluginSettings;
defaultColorScheme: "dark" | "light";
2022-04-15 18:13:31 +00:00
async onload() {
2025-03-11 22:18:10 +00:00
await this.loadSettings();
this.addSettingTab(new SDNSPluginSettingTab(this.app, this));
2025-03-11 22:18:10 +00:00
this.saveDefaultColorScheme();
this.checkAndSwitchColorScheme();
2022-04-15 18:13:31 +00:00
}
onunload() {
2025-03-11 21:07:44 +00:00
if (this.timeout !== null) {
clearTimeout(this.timeout);
this.timeout = null;
}
2025-03-11 23:18:04 +00:00
this.setColorScheme(this.defaultColorScheme);
2022-04-15 18:13:31 +00:00
}
2025-03-11 22:18:10 +00:00
async loadSettings() {
this.settings = Object.assign(
{},
DEFAULT_SETTINGS,
await this.loadData()
);
}
async saveSettings() {
await this.saveData(this.settings);
this.checkAndSwitchColorScheme();
2025-03-11 22:18:10 +00:00
}
checkAndSwitchColorScheme() {
2025-03-11 21:07:44 +00:00
const now = Date.now();
2025-03-11 22:18:10 +00:00
2025-03-12 21:02:31 +00:00
const { dawn, sunsetStart: dusk } = SunCalc.getTimes(
2025-03-11 22:18:10 +00:00
new Date(),
+this.settings.latitude,
+this.settings.longitude
);
2025-03-11 21:07:44 +00:00
const tomorrowDawn = SunCalc.getTimes(
new Date(now + 24 * 60 * 60 * 1000),
2025-03-11 22:18:10 +00:00
+this.settings.latitude,
+this.settings.longitude
2025-03-11 21:07:44 +00:00
).dawn;
const times = {
dawn: dawn.getTime(),
dusk: dusk.getTime(),
tomorrowDawn: tomorrowDawn.getTime(),
};
let checkDelay: number;
if (now < dawn) {
this.setColorScheme("dark");
2025-03-11 21:07:44 +00:00
checkDelay = times.dawn - now;
} else if (now >= dawn && now < dusk) {
this.setColorScheme("light");
2025-03-11 21:07:44 +00:00
checkDelay = times.dusk - now;
} else {
this.setColorScheme("dark");
2025-03-11 21:07:44 +00:00
checkDelay = times.tomorrowDawn - now;
}
2025-03-11 22:18:10 +00:00
if (this.timeout) {
clearTimeout(this.timeout);
}
2025-03-11 21:07:44 +00:00
this.timeout = setTimeout(
this.checkAndSwitchColorScheme.bind(this),
2025-03-11 21:07:44 +00:00
checkDelay
);
2022-04-15 18:13:31 +00:00
}
setColorScheme(targetColorScheme: "dark" | "light") {
switch (targetColorScheme) {
2025-03-11 21:07:44 +00:00
case "dark":
document.body.classList.remove("theme-light");
document.body.classList.add("theme-dark");
break;
case "light":
document.body.classList.remove("theme-dark");
document.body.classList.add("theme-light");
break;
}
this.app.workspace.trigger("css-change");
2022-04-15 18:13:31 +00:00
}
2025-03-11 23:18:04 +00:00
saveDefaultColorScheme() {
const getColorScheme = () =>
2025-03-11 23:18:04 +00:00
document.body.classList.contains("theme-dark") ? "dark" : "light";
this.defaultColorScheme = getColorScheme();
2025-03-11 23:18:04 +00:00
}
2022-04-15 18:13:31 +00:00
}
2025-03-11 22:18:10 +00:00
class SDNSPluginSettingTab extends PluginSettingTab {
plugin: SDNSPlugin;
2025-03-11 22:18:10 +00:00
constructor(app: App, plugin: SDNSPlugin) {
2025-03-11 22:18:10 +00:00
super(app, plugin);
this.plugin = plugin;
}
display(): void {
const { containerEl } = this;
containerEl.empty();
containerEl.createEl("p", {
text: "Please enter the latitude and longitude of your approximate location (coords of any city within ±200 km)",
});
2025-03-11 22:18:10 +00:00
new Setting(containerEl)
.setName("Latitude")
.setDesc(
"Please enter the latitude of your approximate location (within ±200 km)"
)
.addText((text) =>
text
.setPlaceholder("Latitude")
.setValue(this.plugin.settings.latitude)
.onChange(
debounce(async (value) => {
this.plugin.settings.latitude = value;
await this.plugin.saveSettings();
2025-03-12 00:53:36 +00:00
}, 300)
2025-03-11 22:18:10 +00:00
)
);
new Setting(containerEl)
.setName("Longitude")
.setDesc(
"Please enter the longitude of your approximate location (within ±200 km)"
)
.addText((text) =>
text
.setPlaceholder("Longitude")
.setValue(this.plugin.settings.longitude)
2025-03-12 00:53:36 +00:00
.onChange(
debounce(async (value) => {
this.plugin.settings.longitude = value;
await this.plugin.saveSettings();
}, 300)
)
2025-03-11 22:18:10 +00:00
);
const addAdditionalDescription = () => {
const additionalDescription = containerEl.createEl("p");
additionalDescription.createEl("small", {
text: "To easily find your latitude and longitude, you can use any simple online service, such as ",
});
additionalDescription.createEl("small").createEl("a", {
href: "https://www.latlong.net/",
text: "latlong.net",
});
additionalDescription.createEl("small", { text: ", " });
additionalDescription.createEl("small").createEl("a", {
href: "https://www.gps-coordinates.net/",
text: "gps-coordinates.net",
});
additionalDescription.createEl("small", {
text: ", or any other similar tools available on the web.",
});
additionalDescription.createEl("br");
additionalDescription.createEl("br");
additionalDescription.createEl("small", {
text: "* Obsidian does not provide developers with access to geolocation, so this plugin cannot automatically determine your coordinates.",
});
additionalDescription.createEl("br");
additionalDescription.createEl("small", { text: "However, " });
additionalDescription.createEl("small").createEl("strong", {
text: "to accurately calculate sunrise and sunset times in your location",
});
additionalDescription.createEl("small", {
text: ", the formula needs an approximate location (within ±200 km) of where you are.",
});
};
addAdditionalDescription();
const addSchedule = () => {
const dynamicContent = containerEl.createEl("div");
const scheduleHeader = dynamicContent.createEl("h4", {
text: "Schedule:",
});
scheduleHeader.setCssStyles({
borderTop: "1px solid var(--background-modifier-border)",
margin: "1em auto 1em",
paddingTop: "1em",
});
const table = dynamicContent.createEl("table", {
attr: { style: "width: 100%; text-align: center;" },
});
const tbody = table.createEl("tbody");
const headerRow = tbody.createEl("tr");
headerRow.createEl("th", { text: "Date" });
const dawnTh = headerRow.createEl("th");
dawnTh.createEl("span", { text: "Dawn" });
dawnTh.createEl("br");
dawnTh.createEl("small", { text: "(Light mode will be enabled)" });
const duskTh = headerRow.createEl("th");
duskTh.createEl("span", { text: "Dusk" });
duskTh.createEl("br");
duskTh.createEl("small", { text: "(Dark mode will be enabled)" });
const date = new Date();
for (let i = 0; i <= 30; i++) {
const { dawn, sunsetStart: dusk } = SunCalc.getTimes(
date,
+this.plugin.settings.latitude,
+this.plugin.settings.longitude
);
const dateStr = `${date.getDate()} ${date.toLocaleString(
"en-US",
{
month: "short",
}
)} ${date.getFullYear()}`;
const dawnStr = `${String(dawn.getHours()).padStart(
2,
"0"
)}:${String(dawn.getMinutes()).padStart(2, "0")}`;
const duskStr = `${String(dusk.getHours()).padStart(
2,
"0"
)}:${String(dusk.getMinutes()).padStart(2, "0")}`;
const row = tbody.createEl("tr");
row.createEl("td", { text: dateStr });
row.createEl("td", { text: dawnStr });
row.createEl("td", { text: duskStr });
date.setDate(date.getDate() + 1);
}
};
addSchedule();
2025-03-11 22:18:10 +00:00
}
}