mirror of
https://github.com/jsmorabito/obsidian-commander.git
synced 2026-07-22 06:40:31 +00:00
The previous fix (61f15f0) restored this.forceUpdate() based on
tracing through preact's diff/component internals, which showed
function components are invoked as c.render(...) - a method call
that should bind `this` to a real Component instance with a working
forceUpdate(). That trace was confirmed against the library source,
but you tested it and the settings list still didn't update in place
after adding a command, so something in that chain isn't panning out
in practice (possibly the setTimeout-based render scheduling, possibly
something else) - not worth continuing to debug blind.
Replacing it with the standard, unambiguous approach: a useState
counter bumped to force a re-render, the documented Preact/React
idiom that doesn't depend on any internal `this` plumbing. Applied to
CommandViewer, MacroViewer, and MobileModifyComponent everywhere they
previously called this.forceUpdate().
Please rebuild and re-test: add/remove/reorder/rename/recolor a
command from the settings list without switching tabs, same for
macros, and the mobile icon-picker modal.
89 lines
2.3 KiB
TypeScript
89 lines
2.3 KiB
TypeScript
import { h } from "preact";
|
|
import { useEffect, useState } from "preact/hooks";
|
|
import t from "src/l10n";
|
|
import { ObsidianIcon } from "src/util";
|
|
import MobileModifyModal from "../mobileModifyModal";
|
|
import { ColorPicker } from "./ColorPicker";
|
|
import CommanderPlugin from "src/main";
|
|
|
|
export default function MobileModifyComponent({
|
|
plugin,
|
|
modal: controller,
|
|
}: {
|
|
plugin: CommanderPlugin;
|
|
modal: MobileModifyModal;
|
|
}): h.JSX.Element {
|
|
const [, setUpdateTick] = useState(0);
|
|
|
|
useEffect(() => {
|
|
const update = (): void => {
|
|
setUpdateTick((tick) => tick + 1);
|
|
};
|
|
addEventListener("cmdr-icon-changed", update);
|
|
return (): void => removeEventListener("cmdr-icon-changed", update);
|
|
}, []);
|
|
|
|
return (
|
|
<div className="cmdr-mobile-modify-grid">
|
|
<div
|
|
className="cmdr-mobile-modify-option"
|
|
onClick={controller.handleNewIcon}
|
|
>
|
|
<span>{t("Icon")}</span>
|
|
<span className="cmdr-flex cmdr-gap-1">
|
|
<ObsidianIcon
|
|
icon={controller.pair.icon}
|
|
size={20}
|
|
className="clickable-icon"
|
|
style={{ marginRight: "0px" }}
|
|
/>
|
|
<ColorPicker
|
|
initialColor={controller.pair.color ?? "#000"}
|
|
onChange={controller.handleColorChange}
|
|
/>
|
|
</span>
|
|
</div>
|
|
<div className="cmdr-mobile-modify-option">
|
|
<span>{t("Name")}</span>
|
|
<input
|
|
onBlur={({ currentTarget }): void =>
|
|
controller.handleRename(currentTarget.value)
|
|
}
|
|
type="text"
|
|
placeholder={t("Custom Name")}
|
|
value={controller.pair.name}
|
|
/>
|
|
</div>
|
|
<div className="cmdr-mobile-modify-option">
|
|
<select
|
|
className="dropdown"
|
|
value={controller.pair.mode}
|
|
onChange={({ currentTarget }): void =>
|
|
controller.handleModeChange(currentTarget.value)
|
|
}
|
|
>
|
|
<option value="any">
|
|
{t("Add command to all devices")}
|
|
</option>
|
|
<option value="mobile">
|
|
{t("Add command only to mobile devices")}
|
|
</option>
|
|
<option value="desktop">
|
|
{t("Add command only to desktop devices")}
|
|
</option>
|
|
<option value={plugin.app.appId}>
|
|
{t("Add command only to this device")}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
<div className="modal-button-container">
|
|
<button
|
|
className="mod-cta"
|
|
onClick={(): void => controller.close()}
|
|
>
|
|
{t("Done")}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|