Skip to content

Commit c81b020

Browse files
committed
fix: properly display macro command icons in UI
1 parent 265e780 commit c81b020

File tree

7 files changed

+137
-116
lines changed

7 files changed

+137
-116
lines changed

.eslintrc.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"rules": {
3+
"@typescript-eslint/no-unused-vars": ["error", {
4+
"varsIgnorePattern": "^h$"
5+
}]
6+
}
7+
}

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/esbuild.config.mjs

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import builtins from "builtin-modules";
44
import alias from "esbuild-plugin-alias";
55
import { sassPlugin } from "esbuild-sass-plugin";
66
import { createRequire } from "module";
7-
import { renameSync, copyFileSync, appendFileSync } from "fs";
7+
import { appendFileSync } from "fs";
88
const require = createRequire(import.meta.url);
99

1010
const banner = `/*
@@ -85,35 +85,7 @@ esbuild
8585
}
8686
});
8787
},
88-
},
89-
{
90-
name: "Move output",
91-
setup(build) {
92-
build.onEnd(() => {
93-
setTimeout(
94-
() => {
95-
try {
96-
copyFileSync(
97-
"styles.css",
98-
"../../vault/.obsidian/plugins/cmdr/styles.css"
99-
);
100-
copyFileSync(
101-
"main.js",
102-
"../../vault/.obsidian/plugins/cmdr/main.js"
103-
);
104-
copyFileSync(
105-
"manifest.json",
106-
"../../vault/.obsidian/plugins/cmdr/manifest.json"
107-
);
108-
} catch (error) {
109-
console.error(error);
110-
}
111-
},
112-
prod ? 5000 : 500
113-
);
114-
});
115-
},
116-
},
88+
}
11789
],
11890
})
11991
.catch(() => process.exit(1));

src/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ export default class CommanderPlugin extends Plugin {
173173
this.getCommands().forEach((c) => {
174174
if (
175175
this.settings.advancedToolbar.mappedIcons.find(
176-
(m) => m.commandID === c.id
176+
(m) => m.commandID === `cmdr:${c.id}`
177177
)
178178
) {
179179
commands.push(c);

src/types.ts

Lines changed: 73 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,75 @@
1-
import { h } from "preact";
1+
import { App, Command, Plugin, PluginManifest } from "obsidian";
2+
import { JSX } from "preact";
3+
4+
/* eslint-disable no-unused-vars */
5+
declare module "obsidian" {
6+
interface MenuItem {
7+
dom: HTMLElement;
8+
}
9+
10+
interface App {
11+
commands: {
12+
commands: {
13+
[id: string]: Command;
14+
};
15+
executeCommandById: (id: string) => void;
16+
};
17+
plugins: {
18+
manifests: {
19+
[id: string]: PluginManifest;
20+
};
21+
};
22+
statusBar: {
23+
containerEl: HTMLElement;
24+
};
25+
appId: string;
26+
isMobile: boolean;
27+
setting: {
28+
closeActiveTab: () => void;
29+
openTabById: (id: string) => void;
30+
activeTab: {
31+
containerEl: HTMLElement;
32+
};
33+
};
34+
}
35+
36+
interface WorkspaceRibbon {
37+
orderedRibbonActions: {
38+
icon: string;
39+
title: string;
40+
callback: () => void;
41+
}[];
42+
collapseButtonEl: HTMLElement;
43+
ribbonItemsEl: HTMLElement;
44+
addRibbonItemButton: (
45+
icon: string,
46+
name: string,
47+
callback: (event: MouseEvent) => void
48+
) => void;
49+
makeRibbonItemButton: (
50+
icon: string,
51+
name: string,
52+
callback: (event: MouseEvent) => void
53+
) => HTMLElement;
54+
}
55+
56+
interface WorkspaceLeaf {
57+
containerEl: HTMLElement;
58+
}
59+
}
60+
61+
export interface CommanderPlugin extends Plugin {
62+
app: App;
63+
settings: CommanderSettings;
64+
addCommand: (command: {
65+
id: string;
66+
name: string;
67+
callback: () => void;
68+
icon?: string;
69+
}) => Command;
70+
saveSettings: () => Promise<void>;
71+
executeMacro: (id: number) => void;
72+
}
273

374
export enum Action {
475
COMMAND,
@@ -57,7 +128,7 @@ export interface AdvancedToolbarSettings {
57128

58129
export interface Tab {
59130
name: string;
60-
tab: h.JSX.Element;
131+
tab: JSX.Element;
61132
}
62133

63134
export type Mode = "desktop" | "any" | "mobile" | string;
@@ -69,60 +140,3 @@ export interface CommandIconPair {
69140
mode: Mode;
70141
color?: string;
71142
}
72-
73-
/* eslint-disable no-unused-vars */
74-
declare module "obsidian" {
75-
interface MenuItem {
76-
dom: HTMLElement;
77-
}
78-
79-
interface App {
80-
commands: {
81-
commands: {
82-
[id: string]: Command;
83-
};
84-
executeCommandById: (id: string) => void;
85-
};
86-
plugins: {
87-
manifests: {
88-
[id: string]: PluginManifest;
89-
};
90-
};
91-
statusBar: {
92-
containerEl: HTMLElement;
93-
};
94-
appId: string;
95-
isMobile: boolean;
96-
setting: {
97-
closeActiveTab: () => void;
98-
openTabById: (id: string) => void;
99-
activeTab: {
100-
containerEl: HTMLElement;
101-
};
102-
};
103-
}
104-
105-
interface WorkspaceRibbon {
106-
orderedRibbonActions: {
107-
icon: string;
108-
title: string;
109-
callback: () => void;
110-
}[];
111-
collapseButtonEl: HTMLElement;
112-
ribbonItemsEl: HTMLElement;
113-
addRibbonItemButton: (
114-
icon: string,
115-
name: string,
116-
callback: (event: MouseEvent) => void
117-
) => void;
118-
makeRibbonItemButton: (
119-
icon: string,
120-
name: string,
121-
callback: (event: MouseEvent) => void
122-
) => HTMLElement;
123-
}
124-
125-
interface WorkspaceLeaf {
126-
containerEl: HTMLElement;
127-
}
128-
}

src/util.tsx

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import AddCommandModal from "./ui/addCommandModal";
88
import ChooseIconModal from "./ui/chooseIconModal";
99
import { Command, Platform, setIcon } from "obsidian";
1010
import ChooseCustomNameModal from "./ui/chooseCustomNameModal";
11-
import { ComponentProps, h } from "preact";
11+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
12+
import { ComponentProps, h, JSX } from "preact";
13+
/** @jsx h */
1214
import { useRef, useLayoutEffect } from "preact/hooks";
1315
import confetti from "canvas-confetti";
1416

@@ -55,7 +57,7 @@ export function ObsidianIcon({
5557
icon,
5658
size,
5759
...props
58-
}: ObsidianIconProps): h.JSX.Element {
60+
}: ObsidianIconProps): JSX.Element {
5961
const iconEl = useRef<HTMLDivElement>(null);
6062

6163
useLayoutEffect(() => {
@@ -88,19 +90,17 @@ export function updateHiderStylesheet(settings: CommanderSettings): void {
8890
document.head.querySelector("style#cmdr")?.remove();
8991

9092
if (style) {
91-
document.head.appendChild(
92-
createEl("style", {
93-
attr: { id: "cmdr" },
94-
text: style,
95-
type: "text/css",
96-
})
97-
);
93+
const styleEl = document.createElement("style");
94+
styleEl.id = "cmdr";
95+
styleEl.type = "text/css";
96+
styleEl.textContent = style;
97+
document.head.appendChild(styleEl);
9898
}
9999
}
100100

101101
export async function showConfetti({ target }: MouseEvent): Promise<void> {
102-
const myCanvas = activeDocument.createElement("canvas");
103-
activeDocument.body.appendChild(myCanvas);
102+
const myCanvas = document.createElement("canvas");
103+
document.body.appendChild(myCanvas);
104104
myCanvas.style.position = "fixed";
105105
myCanvas.style.width = "100vw";
106106
myCanvas.style.height = "100vh";
@@ -126,16 +126,16 @@ export async function showConfetti({ target }: MouseEvent): Promise<void> {
126126
ticks: 250,
127127
origin: {
128128
//Center of the target component using values from 0 to 1
129-
x: (pos.x + pos.width / 2) / activeWindow.innerWidth,
130-
y: (pos.y + pos.height / 2) / activeWindow.innerHeight,
129+
x: (pos.x + pos.width / 2) / window.innerWidth,
130+
y: (pos.y + pos.height / 2) / window.innerHeight,
131131
},
132132
});
133133

134134
myCanvas.remove();
135135
}
136136

137137
export function updateSpacing(spacing: number): void {
138-
activeDocument.body.style.setProperty("--cmdr-spacing", `${spacing}px`);
138+
document.body.style.setProperty("--cmdr-spacing", `${spacing}px`);
139139
}
140140

141141
export function updateMacroCommands(plugin: CommanderPlugin): void {
@@ -144,22 +144,44 @@ export function updateMacroCommands(plugin: CommanderPlugin): void {
144144
);
145145
for (const command of oldCommands) {
146146
//@ts-ignore
147-
app.commands.removeCommand(command);
147+
plugin.app.commands.removeCommand(command);
148148
}
149149

150150
const macros = plugin.settings.macros;
151-
for (const [idx, macro] of Object.entries(macros)) {
151+
for (const [idx, macro] of macros.entries()) {
152+
const commandId = `macro-${idx}`;
153+
154+
// Create the command with direct icon assignment
152155
plugin.addCommand({
153-
id: `macro-${idx}`,
156+
id: commandId,
154157
name: macro.name,
158+
icon: macro.icon, // Set icon directly on the command
155159
callback: () => {
156-
plugin.executeMacro(parseInt(idx));
160+
plugin.executeMacro(Number(idx));
157161
},
158162
});
163+
164+
// Also maintain icon mapping for mobile toolbar compatibility
165+
if (macro.icon) {
166+
const existingMapping = plugin.settings.advancedToolbar.mappedIcons.find(
167+
m => m.commandID === `cmdr:${commandId}`
168+
);
169+
if (existingMapping) {
170+
existingMapping.iconID = macro.icon;
171+
} else {
172+
plugin.settings.advancedToolbar.mappedIcons.push({
173+
commandID: `cmdr:${commandId}`,
174+
iconID: macro.icon
175+
});
176+
}
177+
}
159178
}
179+
180+
// Save the updated settings
181+
void plugin.saveSettings();
160182
}
161183

162-
export function updateStyles(settings: AdvancedToolbarSettings) {
184+
export function updateStyles(settings: AdvancedToolbarSettings): void {
163185
const { classList: c, style: s } = document.body;
164186
s.setProperty("--at-button-height", (settings.rowHeight ?? 48) + "px");
165187
s.setProperty("--at-button-width", (settings.buttonWidth ?? 48) + "px");
@@ -172,7 +194,7 @@ export function updateStyles(settings: AdvancedToolbarSettings) {
172194
c.toggle("AT-no-toolbar", settings.rowCount === 0);
173195
}
174196

175-
export function removeStyles() {
197+
export function removeStyles(): void {
176198
const { classList: c, style: s } = document.body;
177199
s.removeProperty("--at-button-height");
178200
s.removeProperty("--at-button-width");
@@ -189,13 +211,14 @@ export function removeStyles() {
189211
export function injectIcons(
190212
settings: AdvancedToolbarSettings,
191213
plugin: CommanderPlugin
192-
) {
214+
): void {
193215
settings.mappedIcons.forEach((mapped) => {
194-
const command = plugin.app.commands.commands[mapped.commandID];
216+
const commandId = mapped.commandID.replace('cmdr:', '');
217+
const command = plugin.app.commands.commands[commandId];
195218
if (command) {
196219
command.icon = mapped.iconID;
197220
} else {
198-
settings.mappedIcons.remove(mapped);
221+
settings.mappedIcons = settings.mappedIcons.filter(m => m !== mapped);
199222
}
200223
});
201224
}

tsconfig.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@
1111
"importHelpers": true,
1212
"isolatedModules": true,
1313
"strictNullChecks": true,
14-
"lib": ["DOM", "ES5", "ES6", "ES7", "DOM.Iterable"],
14+
"lib": ["DOM", "ES5", "ES6", "ES7", "DOM.Iterable", "ESNext"],
15+
"types": ["node"],
16+
"paths": {
17+
"obsidian": ["node_modules/obsidian/obsidian.d.ts"],
18+
"preact": ["node_modules/preact/dist/preact.d.ts"]
19+
},
1520
"jsx": "react",
1621
"jsxFactory": "h",
1722
"jsxFragmentFactory": "Fragment",

0 commit comments

Comments
 (0)