fix: properly display macro command icons in UI

This commit is contained in:
Lyqed 2024-12-20 11:02:20 +02:00
parent 265e780565
commit c81b0204c3
7 changed files with 137 additions and 116 deletions

7
.eslintrc.json Executable file
View file

@ -0,0 +1,7 @@
{
"rules": {
"@typescript-eslint/no-unused-vars": ["error", {
"varsIgnorePattern": "^h$"
}]
}
}

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "cmdr",
"version": "0.4.9",
"version": "0.5.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "cmdr",
"version": "0.4.9",
"version": "0.5.2",
"dependencies": {
"array-move": "^4.0.0",
"canvas-confetti": "^1.6.0",

View file

@ -4,7 +4,7 @@ import builtins from "builtin-modules";
import alias from "esbuild-plugin-alias";
import { sassPlugin } from "esbuild-sass-plugin";
import { createRequire } from "module";
import { renameSync, copyFileSync, appendFileSync } from "fs";
import { appendFileSync } from "fs";
const require = createRequire(import.meta.url);
const banner = `/*
@ -85,35 +85,7 @@ esbuild
}
});
},
},
{
name: "Move output",
setup(build) {
build.onEnd(() => {
setTimeout(
() => {
try {
copyFileSync(
"styles.css",
"../../vault/.obsidian/plugins/cmdr/styles.css"
);
copyFileSync(
"main.js",
"../../vault/.obsidian/plugins/cmdr/main.js"
);
copyFileSync(
"manifest.json",
"../../vault/.obsidian/plugins/cmdr/manifest.json"
);
} catch (error) {
console.error(error);
}
},
prod ? 5000 : 500
);
});
},
},
}
],
})
.catch(() => process.exit(1));

View file

@ -173,7 +173,7 @@ export default class CommanderPlugin extends Plugin {
this.getCommands().forEach((c) => {
if (
this.settings.advancedToolbar.mappedIcons.find(
(m) => m.commandID === c.id
(m) => m.commandID === `cmdr:${c.id}`
)
) {
commands.push(c);

View file

@ -1,4 +1,75 @@
import { h } from "preact";
import { App, Command, Plugin, PluginManifest } from "obsidian";
import { JSX } from "preact";
/* eslint-disable no-unused-vars */
declare module "obsidian" {
interface MenuItem {
dom: HTMLElement;
}
interface App {
commands: {
commands: {
[id: string]: Command;
};
executeCommandById: (id: string) => void;
};
plugins: {
manifests: {
[id: string]: PluginManifest;
};
};
statusBar: {
containerEl: HTMLElement;
};
appId: string;
isMobile: boolean;
setting: {
closeActiveTab: () => void;
openTabById: (id: string) => void;
activeTab: {
containerEl: HTMLElement;
};
};
}
interface WorkspaceRibbon {
orderedRibbonActions: {
icon: string;
title: string;
callback: () => void;
}[];
collapseButtonEl: HTMLElement;
ribbonItemsEl: HTMLElement;
addRibbonItemButton: (
icon: string,
name: string,
callback: (event: MouseEvent) => void
) => void;
makeRibbonItemButton: (
icon: string,
name: string,
callback: (event: MouseEvent) => void
) => HTMLElement;
}
interface WorkspaceLeaf {
containerEl: HTMLElement;
}
}
export interface CommanderPlugin extends Plugin {
app: App;
settings: CommanderSettings;
addCommand: (command: {
id: string;
name: string;
callback: () => void;
icon?: string;
}) => Command;
saveSettings: () => Promise<void>;
executeMacro: (id: number) => void;
}
export enum Action {
COMMAND,
@ -57,7 +128,7 @@ export interface AdvancedToolbarSettings {
export interface Tab {
name: string;
tab: h.JSX.Element;
tab: JSX.Element;
}
export type Mode = "desktop" | "any" | "mobile" | string;
@ -69,60 +140,3 @@ export interface CommandIconPair {
mode: Mode;
color?: string;
}
/* eslint-disable no-unused-vars */
declare module "obsidian" {
interface MenuItem {
dom: HTMLElement;
}
interface App {
commands: {
commands: {
[id: string]: Command;
};
executeCommandById: (id: string) => void;
};
plugins: {
manifests: {
[id: string]: PluginManifest;
};
};
statusBar: {
containerEl: HTMLElement;
};
appId: string;
isMobile: boolean;
setting: {
closeActiveTab: () => void;
openTabById: (id: string) => void;
activeTab: {
containerEl: HTMLElement;
};
};
}
interface WorkspaceRibbon {
orderedRibbonActions: {
icon: string;
title: string;
callback: () => void;
}[];
collapseButtonEl: HTMLElement;
ribbonItemsEl: HTMLElement;
addRibbonItemButton: (
icon: string,
name: string,
callback: (event: MouseEvent) => void
) => void;
makeRibbonItemButton: (
icon: string,
name: string,
callback: (event: MouseEvent) => void
) => HTMLElement;
}
interface WorkspaceLeaf {
containerEl: HTMLElement;
}
}

View file

@ -8,7 +8,9 @@ import AddCommandModal from "./ui/addCommandModal";
import ChooseIconModal from "./ui/chooseIconModal";
import { Command, Platform, setIcon } from "obsidian";
import ChooseCustomNameModal from "./ui/chooseCustomNameModal";
import { ComponentProps, h } from "preact";
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { ComponentProps, h, JSX } from "preact";
/** @jsx h */
import { useRef, useLayoutEffect } from "preact/hooks";
import confetti from "canvas-confetti";
@ -55,7 +57,7 @@ export function ObsidianIcon({
icon,
size,
...props
}: ObsidianIconProps): h.JSX.Element {
}: ObsidianIconProps): JSX.Element {
const iconEl = useRef<HTMLDivElement>(null);
useLayoutEffect(() => {
@ -88,19 +90,17 @@ export function updateHiderStylesheet(settings: CommanderSettings): void {
document.head.querySelector("style#cmdr")?.remove();
if (style) {
document.head.appendChild(
createEl("style", {
attr: { id: "cmdr" },
text: style,
type: "text/css",
})
);
const styleEl = document.createElement("style");
styleEl.id = "cmdr";
styleEl.type = "text/css";
styleEl.textContent = style;
document.head.appendChild(styleEl);
}
}
export async function showConfetti({ target }: MouseEvent): Promise<void> {
const myCanvas = activeDocument.createElement("canvas");
activeDocument.body.appendChild(myCanvas);
const myCanvas = document.createElement("canvas");
document.body.appendChild(myCanvas);
myCanvas.style.position = "fixed";
myCanvas.style.width = "100vw";
myCanvas.style.height = "100vh";
@ -126,8 +126,8 @@ export async function showConfetti({ target }: MouseEvent): Promise<void> {
ticks: 250,
origin: {
//Center of the target component using values from 0 to 1
x: (pos.x + pos.width / 2) / activeWindow.innerWidth,
y: (pos.y + pos.height / 2) / activeWindow.innerHeight,
x: (pos.x + pos.width / 2) / window.innerWidth,
y: (pos.y + pos.height / 2) / window.innerHeight,
},
});
@ -135,7 +135,7 @@ export async function showConfetti({ target }: MouseEvent): Promise<void> {
}
export function updateSpacing(spacing: number): void {
activeDocument.body.style.setProperty("--cmdr-spacing", `${spacing}px`);
document.body.style.setProperty("--cmdr-spacing", `${spacing}px`);
}
export function updateMacroCommands(plugin: CommanderPlugin): void {
@ -144,22 +144,44 @@ export function updateMacroCommands(plugin: CommanderPlugin): void {
);
for (const command of oldCommands) {
//@ts-ignore
app.commands.removeCommand(command);
plugin.app.commands.removeCommand(command);
}
const macros = plugin.settings.macros;
for (const [idx, macro] of Object.entries(macros)) {
for (const [idx, macro] of macros.entries()) {
const commandId = `macro-${idx}`;
// Create the command with direct icon assignment
plugin.addCommand({
id: `macro-${idx}`,
id: commandId,
name: macro.name,
icon: macro.icon, // Set icon directly on the command
callback: () => {
plugin.executeMacro(parseInt(idx));
plugin.executeMacro(Number(idx));
},
});
// Also maintain icon mapping for mobile toolbar compatibility
if (macro.icon) {
const existingMapping = plugin.settings.advancedToolbar.mappedIcons.find(
m => m.commandID === `cmdr:${commandId}`
);
if (existingMapping) {
existingMapping.iconID = macro.icon;
} else {
plugin.settings.advancedToolbar.mappedIcons.push({
commandID: `cmdr:${commandId}`,
iconID: macro.icon
});
}
}
}
// Save the updated settings
void plugin.saveSettings();
}
export function updateStyles(settings: AdvancedToolbarSettings) {
export function updateStyles(settings: AdvancedToolbarSettings): void {
const { classList: c, style: s } = document.body;
s.setProperty("--at-button-height", (settings.rowHeight ?? 48) + "px");
s.setProperty("--at-button-width", (settings.buttonWidth ?? 48) + "px");
@ -172,7 +194,7 @@ export function updateStyles(settings: AdvancedToolbarSettings) {
c.toggle("AT-no-toolbar", settings.rowCount === 0);
}
export function removeStyles() {
export function removeStyles(): void {
const { classList: c, style: s } = document.body;
s.removeProperty("--at-button-height");
s.removeProperty("--at-button-width");
@ -189,13 +211,14 @@ export function removeStyles() {
export function injectIcons(
settings: AdvancedToolbarSettings,
plugin: CommanderPlugin
) {
): void {
settings.mappedIcons.forEach((mapped) => {
const command = plugin.app.commands.commands[mapped.commandID];
const commandId = mapped.commandID.replace('cmdr:', '');
const command = plugin.app.commands.commands[commandId];
if (command) {
command.icon = mapped.iconID;
} else {
settings.mappedIcons.remove(mapped);
settings.mappedIcons = settings.mappedIcons.filter(m => m !== mapped);
}
});
}

View file

@ -11,7 +11,12 @@
"importHelpers": true,
"isolatedModules": true,
"strictNullChecks": true,
"lib": ["DOM", "ES5", "ES6", "ES7", "DOM.Iterable"],
"lib": ["DOM", "ES5", "ES6", "ES7", "DOM.Iterable", "ESNext"],
"types": ["node"],
"paths": {
"obsidian": ["node_modules/obsidian/obsidian.d.ts"],
"preact": ["node_modules/preact/dist/preact.d.ts"]
},
"jsx": "react",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment",