2026-03-29 17:44:41 +02:00
|
|
|
const { setIcon } = require("obsidian");
|
|
|
|
|
const { findGroupByTitle } = require("./settings-ui");
|
|
|
|
|
const { isIgnisPlugin } = require("../plugin-registry");
|
|
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
// Tracks which plugin IDs have nav items we created.
|
|
|
|
|
const ownedPluginIds = new Set();
|
2026-03-29 17:44:41 +02:00
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
function addPluginNavItem(pluginId, setting, corePluginsItems, ignisNavEls) {
|
2026-03-29 17:44:41 +02:00
|
|
|
const tab = setting.pluginTabs.find((t) => t.id === pluginId);
|
|
|
|
|
|
|
|
|
|
if (!tab) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
if (ownedPluginIds.has(pluginId)) {
|
2026-03-29 17:44:41 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const nav = document.createElement("div");
|
|
|
|
|
nav.className = "vertical-tab-nav-item tappable";
|
|
|
|
|
|
|
|
|
|
if (tab.icon) {
|
|
|
|
|
const iconEl = document.createElement("div");
|
|
|
|
|
iconEl.className = "vertical-tab-nav-item-icon";
|
|
|
|
|
setIcon(iconEl, tab.icon);
|
|
|
|
|
nav.appendChild(iconEl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const title = document.createElement("div");
|
|
|
|
|
title.className = "vertical-tab-nav-item-title";
|
|
|
|
|
title.textContent = tab.name;
|
|
|
|
|
nav.appendChild(title);
|
|
|
|
|
|
|
|
|
|
const chevron = document.createElement("div");
|
|
|
|
|
chevron.className = "vertical-tab-nav-item-chevron";
|
|
|
|
|
nav.appendChild(chevron);
|
|
|
|
|
|
|
|
|
|
nav.addEventListener("click", () => {
|
|
|
|
|
setting.openTab(tab);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
corePluginsItems.appendChild(nav);
|
2026-03-30 21:05:47 +02:00
|
|
|
ownedPluginIds.add(pluginId);
|
|
|
|
|
ignisNavEls.set(pluginId, nav);
|
2026-03-29 17:44:41 +02:00
|
|
|
}
|
|
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
function removePluginNavItem(pluginId, ignisNavEls) {
|
|
|
|
|
const nav = ignisNavEls.get(pluginId);
|
2026-03-29 17:44:41 +02:00
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
if (nav && ownedPluginIds.has(pluginId)) {
|
2026-03-29 17:44:41 +02:00
|
|
|
nav.remove();
|
2026-03-30 21:05:47 +02:00
|
|
|
ownedPluginIds.delete(pluginId);
|
|
|
|
|
ignisNavEls.delete(pluginId);
|
2026-03-29 17:44:41 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function hideIgnisFromCommunityPlugins(setting) {
|
|
|
|
|
const cpTab = setting.settingTabs.find((t) => t.id === "community-plugins");
|
|
|
|
|
|
|
|
|
|
if (!cpTab || cpTab._ignisPatched) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const origRender = cpTab.renderInstalledPlugin;
|
|
|
|
|
|
|
|
|
|
cpTab.renderInstalledPlugin = function (manifest, ...rest) {
|
|
|
|
|
if (isIgnisPlugin(manifest.id)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return origRender.call(this, manifest, ...rest);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
cpTab._ignisPatched = true;
|
|
|
|
|
cpTab._origRenderInstalledPlugin = origRender;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function restoreCommunityPlugins(setting) {
|
|
|
|
|
const cpTab = setting.settingTabs.find(
|
|
|
|
|
(t) => t.id === "community-plugins",
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (cpTab?._origRenderInstalledPlugin) {
|
|
|
|
|
cpTab.renderInstalledPlugin = cpTab._origRenderInstalledPlugin;
|
|
|
|
|
delete cpTab._origRenderInstalledPlugin;
|
|
|
|
|
delete cpTab._ignisPatched;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function hideIgnisNavFromCommunityGroup(setting) {
|
|
|
|
|
const communityGroup = findGroupByTitle(
|
|
|
|
|
setting.tabHeadersEl,
|
|
|
|
|
"Community plugins",
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!communityGroup) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const items = communityGroup.querySelector(".vertical-tab-header-group-items");
|
|
|
|
|
|
|
|
|
|
if (!items) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const tab of setting.pluginTabs) {
|
|
|
|
|
if (isIgnisPlugin(tab.id) && tab.navEl?.parentElement === items) {
|
|
|
|
|
tab.navEl.style.display = "none";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const hasVisible = Array.from(items.children).some(
|
|
|
|
|
(el) => el.style.display !== "none",
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
communityGroup.style.display = hasVisible ? "" : "none";
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
function hideCorePluginsGroupIfEmpty(ignisNavEls) {
|
|
|
|
|
let hasConnected = false;
|
2026-03-29 17:44:41 +02:00
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
for (const id of ownedPluginIds) {
|
|
|
|
|
const nav = ignisNavEls.get(id);
|
2026-03-29 17:44:41 +02:00
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
if (nav?.isConnected) {
|
|
|
|
|
hasConnected = true;
|
|
|
|
|
break;
|
2026-03-29 17:44:41 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const groups = document.querySelectorAll(".vertical-tab-header-group");
|
|
|
|
|
|
|
|
|
|
for (const g of groups) {
|
|
|
|
|
const title = g.querySelector(".vertical-tab-header-group-title");
|
|
|
|
|
|
|
|
|
|
if (title?.textContent === "Ignis Core Plugins") {
|
2026-03-30 21:05:47 +02:00
|
|
|
g.style.display = hasConnected ? "" : "none";
|
2026-03-29 17:44:41 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
function setupPluginTabs(setting, corePluginsItems, ignisNavEls) {
|
2026-03-29 17:44:41 +02:00
|
|
|
for (const tab of setting.pluginTabs) {
|
|
|
|
|
if (isIgnisPlugin(tab.id) && tab.id !== "ignis-bridge") {
|
2026-03-30 21:05:47 +02:00
|
|
|
addPluginNavItem(tab.id, setting, corePluginsItems, ignisNavEls);
|
2026-03-29 17:44:41 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hideIgnisNavFromCommunityGroup(setting);
|
2026-03-30 21:05:47 +02:00
|
|
|
hideCorePluginsGroupIfEmpty(ignisNavEls);
|
2026-03-29 17:44:41 +02:00
|
|
|
|
|
|
|
|
const communityGroup = findGroupByTitle(
|
|
|
|
|
setting.tabHeadersEl,
|
|
|
|
|
"Community plugins",
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (communityGroup) {
|
|
|
|
|
const observer = new MutationObserver(() => {
|
|
|
|
|
for (const tab of setting.pluginTabs) {
|
|
|
|
|
if (isIgnisPlugin(tab.id) && tab.id !== "ignis-bridge") {
|
2026-03-30 21:05:47 +02:00
|
|
|
addPluginNavItem(tab.id, setting, corePluginsItems, ignisNavEls);
|
2026-03-29 17:44:41 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hideIgnisNavFromCommunityGroup(setting);
|
2026-03-30 21:05:47 +02:00
|
|
|
hideCorePluginsGroupIfEmpty(ignisNavEls);
|
2026-03-29 17:44:41 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
observer.observe(communityGroup, { childList: true, subtree: true });
|
|
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
const modalEl = setting.tabHeadersEl.closest(".modal");
|
2026-03-29 17:44:41 +02:00
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
if (modalEl && modalEl.parentElement) {
|
|
|
|
|
const cleanupObserver = new MutationObserver(() => {
|
|
|
|
|
if (!setting.tabHeadersEl.isConnected) {
|
|
|
|
|
observer.disconnect();
|
|
|
|
|
cleanupObserver.disconnect();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
cleanupObserver.observe(modalEl.parentElement, {
|
|
|
|
|
childList: true,
|
|
|
|
|
});
|
|
|
|
|
}
|
2026-03-29 17:44:41 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
function reconcilePluginTabs(setting, ignisNavEls) {
|
2026-03-29 17:44:41 +02:00
|
|
|
const corePluginsGroup = findGroupByTitle(
|
|
|
|
|
setting.tabHeadersEl,
|
|
|
|
|
"Ignis Core Plugins",
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!corePluginsGroup) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const corePluginsItems = corePluginsGroup.querySelector(
|
|
|
|
|
".vertical-tab-header-group-items",
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!corePluginsItems) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const activeIds = new Set(
|
|
|
|
|
setting.pluginTabs
|
|
|
|
|
.filter((t) => isIgnisPlugin(t.id) && t.id !== "ignis-bridge")
|
|
|
|
|
.map((t) => t.id),
|
|
|
|
|
);
|
|
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
for (const id of ownedPluginIds) {
|
2026-03-29 17:44:41 +02:00
|
|
|
if (!activeIds.has(id)) {
|
2026-03-30 21:05:47 +02:00
|
|
|
removePluginNavItem(id, ignisNavEls);
|
2026-03-29 17:44:41 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const id of activeIds) {
|
2026-03-30 21:05:47 +02:00
|
|
|
addPluginNavItem(id, setting, corePluginsItems, ignisNavEls);
|
2026-03-29 17:44:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hideIgnisNavFromCommunityGroup(setting);
|
2026-03-30 21:05:47 +02:00
|
|
|
hideCorePluginsGroupIfEmpty(ignisNavEls);
|
2026-03-29 17:44:41 +02:00
|
|
|
}
|
|
|
|
|
|
2026-03-30 21:05:47 +02:00
|
|
|
function clearOwnedPluginIds() {
|
|
|
|
|
ownedPluginIds.clear();
|
2026-03-29 17:44:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
|
setupPluginTabs,
|
|
|
|
|
reconcilePluginTabs,
|
|
|
|
|
hideIgnisFromCommunityPlugins,
|
|
|
|
|
restoreCommunityPlugins,
|
2026-03-30 21:05:47 +02:00
|
|
|
clearOwnedPluginIds,
|
2026-03-29 17:44:41 +02:00
|
|
|
};
|