mirror of
https://github.com/devonthesofa/obsidian-note-status.git
synced 2026-07-22 12:30:24 +00:00
feat: add settings to customize the status bar when unknown status; custom unknown icon
This commit is contained in:
parent
75ebd05d15
commit
feaf3fc448
7 changed files with 165 additions and 7 deletions
|
|
@ -6,10 +6,20 @@ type Props = {
|
|||
onMouseEnter: (statuses: GroupedStatuses) => void;
|
||||
onMouseLeave: (statuses: GroupedStatuses) => void;
|
||||
hideUnknownStatus?: boolean;
|
||||
unknownStatusConfig?: {
|
||||
icon: string;
|
||||
color: string;
|
||||
};
|
||||
};
|
||||
|
||||
export const FileExplorerIcon: FC<Props> = memo(
|
||||
({ statuses, onMouseLeave, onMouseEnter, hideUnknownStatus }) => {
|
||||
({
|
||||
statuses,
|
||||
onMouseLeave,
|
||||
onMouseEnter,
|
||||
hideUnknownStatus,
|
||||
unknownStatusConfig,
|
||||
}) => {
|
||||
const statusEntries = Object.entries(statuses);
|
||||
const totalStatuses = statusEntries.reduce(
|
||||
(acc, [, list]) => acc + list.length,
|
||||
|
|
@ -20,7 +30,10 @@ export const FileExplorerIcon: FC<Props> = memo(
|
|||
// If hideUnknownStatus is enabled, don't show anything for files without status
|
||||
if (hideUnknownStatus) return null;
|
||||
|
||||
// Show "no status" icon
|
||||
// Use config passed from integration, with fallbacks
|
||||
const icon = unknownStatusConfig?.icon || "❓";
|
||||
const color = unknownStatusConfig?.color || "#8b949e";
|
||||
|
||||
return (
|
||||
<div className="status-wrapper">
|
||||
<div
|
||||
|
|
@ -29,11 +42,11 @@ export const FileExplorerIcon: FC<Props> = memo(
|
|||
onMouseLeave={() => onMouseLeave({})}
|
||||
style={
|
||||
{
|
||||
"--primary-color": "var(--text-muted)",
|
||||
"--primary-color": color,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
>
|
||||
<span className="status-icon">❓</span>
|
||||
<span className="status-icon">{icon}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,18 @@ export const UISettings: React.FC<Props> = ({ settings, onChange }) => {
|
|||
onChange(key, e.target.checked);
|
||||
};
|
||||
|
||||
const handleInputChange =
|
||||
(key: keyof PluginSettings) =>
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange(key, e.target.value);
|
||||
};
|
||||
|
||||
const handleTextInputChange =
|
||||
(key: keyof PluginSettings) =>
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange(key, e.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="ui-settings">
|
||||
<h3>User interface</h3>
|
||||
|
|
@ -90,6 +102,67 @@ export const UISettings: React.FC<Props> = ({ settings, onChange }) => {
|
|||
onChange={handleChange("excludeUnknownStatus")}
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<h4>Unknown Status Customization</h4>
|
||||
|
||||
<SettingItem
|
||||
name="Unknown status icon"
|
||||
description="Custom icon to display for files with unknown status"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value={settings.unknownStatusIcon || "❓"}
|
||||
onChange={handleInputChange("unknownStatusIcon")}
|
||||
style={{ width: "60px", textAlign: "center" }}
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<SettingItem
|
||||
name="Unknown status color"
|
||||
description="Custom hex color for unknown status (e.g., #8b949e)"
|
||||
>
|
||||
<input
|
||||
type="color"
|
||||
value={settings.unknownStatusColor || "#8b949e"}
|
||||
onChange={handleInputChange("unknownStatusColor")}
|
||||
style={{ width: "50px", height: "30px" }}
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<SettingItem
|
||||
name="Status bar 'no status' text"
|
||||
description="Custom text to display in status bar when there is no status"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value={settings.statusBarNoStatusText}
|
||||
onChange={handleTextInputChange("statusBarNoStatusText")}
|
||||
style={{ width: "150px" }}
|
||||
placeholder="No status"
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<SettingItem
|
||||
name="Show icon in status bar for 'no status'"
|
||||
description="Display the unknown status icon alongside the text in the status bar"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={settings.statusBarShowNoStatusIcon || false}
|
||||
onChange={handleChange("statusBarShowNoStatusIcon")}
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<SettingItem
|
||||
name="Show text in status bar for 'no status'"
|
||||
description="Display the custom text in the status bar when there is no status"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={settings.statusBarShowNoStatusText ?? true}
|
||||
onChange={handleChange("statusBarShowNoStatusText")}
|
||||
/>
|
||||
</SettingItem>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,25 +11,53 @@ export type Props = {
|
|||
templates?: { [key: string]: { description: string } };
|
||||
hideIfNotStatuses?: boolean;
|
||||
onStatusClick: StatusBarContextProps["onStatusClick"];
|
||||
noStatusConfig?: {
|
||||
text: string;
|
||||
showIcon: boolean;
|
||||
showText: boolean;
|
||||
icon: string;
|
||||
color: string;
|
||||
};
|
||||
};
|
||||
|
||||
export const StatusBar: FC<Props> = ({
|
||||
statuses,
|
||||
hideIfNotStatuses,
|
||||
onStatusClick,
|
||||
noStatusConfig,
|
||||
}) => {
|
||||
const statusEntries = Object.entries(statuses);
|
||||
const hasStatuses = statusEntries.flatMap((s) => s[1]).length > 0;
|
||||
|
||||
if (!hasStatuses) {
|
||||
if (hideIfNotStatuses) return null;
|
||||
|
||||
if (
|
||||
!noStatusConfig ||
|
||||
(!noStatusConfig.showIcon && !noStatusConfig.showText)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<span
|
||||
className="status-bar-item mod-clickable"
|
||||
onClick={() => onStatusClick({ name: "", icon: "" })}
|
||||
style={{ cursor: "pointer" }}
|
||||
style={{
|
||||
cursor: "pointer",
|
||||
color: noStatusConfig.color,
|
||||
}}
|
||||
>
|
||||
No status
|
||||
{noStatusConfig.showIcon && (
|
||||
<span
|
||||
style={{
|
||||
marginRight: noStatusConfig.showText ? "4px" : "0",
|
||||
}}
|
||||
>
|
||||
{noStatusConfig.icon}
|
||||
</span>
|
||||
)}
|
||||
{noStatusConfig.showText && noStatusConfig.text}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,4 +22,10 @@ export const DEFAULT_PLUGIN_SETTINGS: PluginSettings = {
|
|||
strictStatuses: false, // Default to show all statuses from frontmatter
|
||||
excludeUnknownStatus: true, // Default to exclude unknown status files for better performance
|
||||
quickStatusCommands: ["active", "completed"], // Add default quick commands
|
||||
// Unknown status customization
|
||||
unknownStatusIcon: "❓",
|
||||
unknownStatusColor: "#8b949e",
|
||||
statusBarNoStatusText: "No status",
|
||||
statusBarShowNoStatusIcon: false,
|
||||
statusBarShowNoStatusText: true,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -55,7 +55,9 @@ export class FileExplorerIntegration implements IElementProcessor {
|
|||
key === "useMultipleStatuses" ||
|
||||
key === "tagPrefix" ||
|
||||
key === "strictStatuses" ||
|
||||
key === "fileExplorerIconPosition"
|
||||
key === "fileExplorerIconPosition" ||
|
||||
key === "unknownStatusIcon" ||
|
||||
key === "unknownStatusColor"
|
||||
) {
|
||||
this.destroy();
|
||||
this.integrate().catch((r) => console.error(r));
|
||||
|
|
@ -108,6 +110,14 @@ export class FileExplorerIntegration implements IElementProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
private getUnknownStatusConfig() {
|
||||
const settings = settingsService.settings;
|
||||
return {
|
||||
icon: settings.unknownStatusIcon || "❓",
|
||||
color: settings.unknownStatusColor || "#8b949e",
|
||||
};
|
||||
}
|
||||
|
||||
render(element: Element, statuses: GroupedStatuses): void {
|
||||
// Remove existing icon
|
||||
const existingIcon = element.querySelector(`.${this.ICON_CLASS}`);
|
||||
|
|
@ -136,6 +146,7 @@ export class FileExplorerIntegration implements IElementProcessor {
|
|||
hideUnknownStatus={
|
||||
settingsService.settings.hideUnknownStatusInExplorer
|
||||
}
|
||||
unknownStatusConfig={this.getUnknownStatusConfig()}
|
||||
/>,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,15 @@ export class StatusBarIntegration {
|
|||
if (key === "customStatuses") {
|
||||
this.handleActiveFileChange().catch(console.error); // INFO: Force a re-read of the statuses and render
|
||||
}
|
||||
if (
|
||||
key === "unknownStatusIcon" ||
|
||||
key === "unknownStatusColor" ||
|
||||
key === "statusBarNoStatusText" ||
|
||||
key === "statusBarShowNoStatusIcon" ||
|
||||
key === "statusBarShowNoStatusText"
|
||||
) {
|
||||
this.render(); // INFO: Force a render for unknown status customization
|
||||
}
|
||||
},
|
||||
"statusBarIntegrationSubscription2",
|
||||
);
|
||||
|
|
@ -108,6 +117,17 @@ export class StatusBarIntegration {
|
|||
});
|
||||
}
|
||||
|
||||
private getNoStatusConfig() {
|
||||
const settings = settingsService.settings;
|
||||
return {
|
||||
text: settings.statusBarNoStatusText || "No status",
|
||||
showIcon: settings.statusBarShowNoStatusIcon || false,
|
||||
showText: settings.statusBarShowNoStatusText ?? true,
|
||||
icon: settings.unknownStatusIcon || "❓",
|
||||
color: settings.unknownStatusColor || "#8b949e",
|
||||
};
|
||||
}
|
||||
|
||||
private render() {
|
||||
if (!this.root) {
|
||||
this.root = createRoot(this.statusBarContainer);
|
||||
|
|
@ -129,6 +149,7 @@ export class StatusBarIntegration {
|
|||
settingsService.settings.autoHideStatusBar
|
||||
}
|
||||
onStatusClick={() => this.openStatusModal()}
|
||||
noStatusConfig={this.getNoStatusConfig()}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,5 +25,11 @@ export type PluginSettings = {
|
|||
strictStatuses: boolean; // Whether to only show known statuses
|
||||
excludeUnknownStatus: boolean; // Whether to exclude files with unknown status from the status pane
|
||||
quickStatusCommands: string[];
|
||||
// Unknown status customization
|
||||
unknownStatusIcon: string; // Custom icon for unknown status
|
||||
unknownStatusColor: string; // Custom hex color for unknown status
|
||||
statusBarNoStatusText: string; // Custom text for status bar when no status
|
||||
statusBarShowNoStatusIcon: boolean; // Whether to show icon in status bar for no status
|
||||
statusBarShowNoStatusText: boolean; // Whether to show text in status bar for no status
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue