mirror of
https://github.com/devonthesofa/obsidian-note-status.git
synced 2026-07-22 12:30:24 +00:00
refactor: add components folder with statusBar
This commit is contained in:
parent
1cae811a91
commit
b6db59c593
5 changed files with 221 additions and 177 deletions
107
components/statusBar/status-bar-controller.ts
Normal file
107
components/statusBar/status-bar-controller.ts
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import { NoteStatusSettings } from '../../models/types';
|
||||
import { StatusService } from '../../services/status-service';
|
||||
import { StatusBarView } from './status-bar-view';
|
||||
|
||||
/**
|
||||
* Controller for the status bar
|
||||
*/
|
||||
export class StatusBarController {
|
||||
private view: StatusBarView;
|
||||
private settings: NoteStatusSettings;
|
||||
private statusService: StatusService;
|
||||
private currentStatuses: string[] = ['unknown'];
|
||||
|
||||
constructor(statusBarEl: HTMLElement, settings: NoteStatusSettings, statusService: StatusService) {
|
||||
this.view = new StatusBarView(statusBarEl);
|
||||
this.settings = settings;
|
||||
this.statusService = statusService;
|
||||
|
||||
// Register right-click handler for force refresh
|
||||
this.setupContextMenu(statusBarEl);
|
||||
|
||||
this.update(['unknown']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up right-click context menu for force refresh
|
||||
*/
|
||||
private setupContextMenu(element: HTMLElement): void {
|
||||
element.addEventListener('contextmenu', (e) => {
|
||||
e.preventDefault();
|
||||
window.dispatchEvent(new CustomEvent('note-status:force-refresh'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the status bar with new statuses
|
||||
*/
|
||||
public update(statuses: string[]): void {
|
||||
this.currentStatuses = statuses;
|
||||
this.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the status bar
|
||||
*/
|
||||
private render(): void {
|
||||
this.view.reset();
|
||||
|
||||
if (!this.settings.showStatusBar) {
|
||||
this.view.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.settings.useMultipleStatuses) {
|
||||
this.renderStatuses([this.currentStatuses[0]]);
|
||||
} else {
|
||||
this.renderStatuses(this.currentStatuses);
|
||||
}
|
||||
|
||||
this.handleAutoHide();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render statuses - handles both single and multiple status cases
|
||||
*/
|
||||
private renderStatuses(statuses: string[]): void {
|
||||
const statusDetails = statuses.map(status => {
|
||||
const statusObj = this.statusService.getAllStatuses().find(s => s.name === status);
|
||||
return {
|
||||
name: status,
|
||||
icon: this.statusService.getStatusIcon(status),
|
||||
tooltipText: statusObj?.description ? `${status} - ${statusObj.description}` : status
|
||||
};
|
||||
});
|
||||
|
||||
this.view.renderStatuses(statusDetails);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle auto-hide behavior
|
||||
*/
|
||||
private handleAutoHide(): void {
|
||||
const onlyUnknown = this.currentStatuses.length === 1 &&
|
||||
this.currentStatuses[0] === 'unknown';
|
||||
|
||||
if (this.settings.autoHideStatusBar && onlyUnknown) {
|
||||
this.view.hide();
|
||||
} else {
|
||||
this.view.show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update settings reference
|
||||
*/
|
||||
public updateSettings(settings: NoteStatusSettings): void {
|
||||
this.settings = settings;
|
||||
this.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up when plugin is unloaded
|
||||
*/
|
||||
public unload(): void {
|
||||
this.view.destroy();
|
||||
}
|
||||
}
|
||||
107
components/statusBar/status-bar-view.ts
Normal file
107
components/statusBar/status-bar-view.ts
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import { setTooltip } from 'obsidian';
|
||||
|
||||
/**
|
||||
* Renders the status bar UI
|
||||
*/
|
||||
export class StatusBarView {
|
||||
private element: HTMLElement;
|
||||
|
||||
constructor(element: HTMLElement) {
|
||||
this.element = element;
|
||||
this.element.addClass('note-status-bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the element and resets CSS classes
|
||||
*/
|
||||
reset(): void {
|
||||
this.element.empty();
|
||||
this.element.removeClass('left', 'hidden', 'auto-hide', 'visible');
|
||||
this.element.addClass('note-status-bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the status bar
|
||||
*/
|
||||
hide(): void {
|
||||
this.element.addClass('hidden');
|
||||
this.element.removeClass('visible');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the status bar
|
||||
*/
|
||||
show(): void {
|
||||
this.element.removeClass('hidden');
|
||||
this.element.addClass('visible');
|
||||
}
|
||||
|
||||
|
||||
renderStatuses(statuses: Array<{name: string, icon: string, tooltipText: string}>): void {
|
||||
if (statuses.length === 1) {
|
||||
this.renderSingleStatus(statuses[0].name, statuses[0].icon, statuses[0].tooltipText);
|
||||
} else {
|
||||
this.renderMultipleStatuses(statuses);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a single status
|
||||
*/
|
||||
private renderSingleStatus(status: string, icon: string, tooltipText: string): void {
|
||||
const statusText = this.element.createEl('span', {
|
||||
text: `Status: ${status}`,
|
||||
cls: `note-status-${status}`
|
||||
});
|
||||
setTooltip(statusText, tooltipText);
|
||||
|
||||
const statusIcon = this.element.createEl('span', {
|
||||
text: icon,
|
||||
cls: `note-status-icon status-${status}`
|
||||
});
|
||||
setTooltip(statusIcon, tooltipText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render multiple statuses
|
||||
*/
|
||||
private renderMultipleStatuses(statuses: Array<{name: string, icon: string, tooltipText: string}>): void {
|
||||
this.element.createEl('span', {
|
||||
text: 'Statuses: ',
|
||||
cls: 'note-status-label'
|
||||
});
|
||||
|
||||
const badgesContainer = this.element.createEl('span', {
|
||||
cls: 'note-status-badges'
|
||||
});
|
||||
|
||||
statuses.forEach(status => this.createStatusBadge(badgesContainer, status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a status badge for multiple status display
|
||||
*/
|
||||
private createStatusBadge(container: HTMLElement, status: {name: string, icon: string, tooltipText: string}): void {
|
||||
const badge = container.createEl('span', {
|
||||
cls: `note-status-badge status-${status.name}`
|
||||
});
|
||||
setTooltip(badge, status.tooltipText);
|
||||
|
||||
badge.createEl('span', {
|
||||
text: status.icon,
|
||||
cls: 'note-status-badge-icon'
|
||||
});
|
||||
|
||||
badge.createEl('span', {
|
||||
text: status.name,
|
||||
cls: 'note-status-badge-text'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the element
|
||||
*/
|
||||
destroy(): void {
|
||||
this.element.empty();
|
||||
}
|
||||
}
|
||||
6
main.ts
6
main.ts
|
|
@ -12,7 +12,6 @@ import { StatusService } from './services/status-service';
|
|||
import { StyleService } from './services/style-service';
|
||||
|
||||
// UI Components
|
||||
import { StatusBar } from './ui/components/status-bar';
|
||||
import { StatusDropdown } from './ui/components/status-dropdown';
|
||||
import { StatusPaneView } from './ui/components/status-pane-view';
|
||||
import { ExplorerIntegration } from './ui/integrations/explorer-integration';
|
||||
|
|
@ -20,6 +19,7 @@ import { StatusContextMenu } from './ui/menus/status-context-menu';
|
|||
|
||||
// Settings
|
||||
import { NoteStatusSettingTab } from './settings/settings-tab';
|
||||
import { StatusBarController } from 'components/statusBar/status-bar-controller';
|
||||
|
||||
/**
|
||||
* Main plugin class for Note Status functionality
|
||||
|
|
@ -28,7 +28,7 @@ export default class NoteStatus extends Plugin {
|
|||
settings: NoteStatusSettings;
|
||||
statusService: StatusService;
|
||||
styleService: StyleService;
|
||||
statusBar: StatusBar;
|
||||
statusBar: StatusBarController;
|
||||
statusDropdown: StatusDropdown;
|
||||
explorerIntegration: ExplorerIntegration;
|
||||
statusContextMenu: StatusContextMenu;
|
||||
|
|
@ -105,7 +105,7 @@ export default class NoteStatus extends Plugin {
|
|||
*/
|
||||
private initializeUI(): void {
|
||||
// Init basic UI components
|
||||
this.statusBar = new StatusBar(this.addStatusBarItem(), this.settings, this.statusService);
|
||||
this.statusBar = new StatusBarController(this.addStatusBarItem(), this.settings, this.statusService);
|
||||
this.statusDropdown = new StatusDropdown(this.app, this.settings, this.statusService);
|
||||
|
||||
// Initialize explorer integration with a slight delay to ensure UI elements are ready
|
||||
|
|
|
|||
|
|
@ -383,11 +383,10 @@ export class StatusService {
|
|||
// General UI refresh
|
||||
window.dispatchEvent(new CustomEvent('note-status:refresh-ui'));
|
||||
|
||||
// If it's the active file, ensure status bar and toolbar are updated
|
||||
const activeFile = this.app.workspace.getActiveFile();
|
||||
if (activeFile && files.some(f => f.path === activeFile.path)) {
|
||||
const statuses = this.getFileStatuses(activeFile);
|
||||
this.notifyStatusChanged(statuses, activeFile)
|
||||
// Notify status changes for each modified file
|
||||
for (const file of files) {
|
||||
const statuses = this.getFileStatuses(file);
|
||||
this.notifyStatusChanged(statuses, file);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,169 +0,0 @@
|
|||
import { setTooltip } from 'obsidian';
|
||||
import { NoteStatusSettings } from '../../models/types';
|
||||
import { StatusService } from '../../services/status-service';
|
||||
|
||||
/**
|
||||
* Handles the status bar functionality
|
||||
*/
|
||||
export class StatusBar {
|
||||
private statusBarEl: HTMLElement;
|
||||
private settings: NoteStatusSettings;
|
||||
private statusService: StatusService;
|
||||
private currentStatuses: string[] = ['unknown'];
|
||||
|
||||
constructor(statusBarEl: HTMLElement, settings: NoteStatusSettings, statusService: StatusService) {
|
||||
this.statusBarEl = statusBarEl;
|
||||
this.settings = settings;
|
||||
this.statusService = statusService;
|
||||
|
||||
this.statusBarEl.addClass('note-status-bar');
|
||||
this.setupContextMenu();
|
||||
this.update(['unknown']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up right-click context menu for force refresh
|
||||
*/
|
||||
private setupContextMenu(): void {
|
||||
this.statusBarEl.addEventListener('contextmenu', (e) => {
|
||||
e.preventDefault();
|
||||
window.dispatchEvent(new CustomEvent('note-status:force-refresh'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the status bar with new statuses
|
||||
*/
|
||||
public update(statuses: string[]): void {
|
||||
this.currentStatuses = statuses;
|
||||
this.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the status bar based on current settings and statuses
|
||||
*/
|
||||
public render(): void {
|
||||
this.statusBarEl.empty();
|
||||
this.resetClasses();
|
||||
|
||||
if (!this.settings.showStatusBar) {
|
||||
this.statusBarEl.addClass('hidden');
|
||||
return;
|
||||
}
|
||||
|
||||
// Select display mode based on number of statuses and settings
|
||||
if (this.currentStatuses.length === 1 || !this.settings.useMultipleStatuses) {
|
||||
this.renderSingleStatus();
|
||||
} else {
|
||||
this.renderMultipleStatuses();
|
||||
}
|
||||
|
||||
this.handleAutoHide();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset CSS classes to their default state
|
||||
*/
|
||||
private resetClasses(): void {
|
||||
this.statusBarEl.removeClass('left', 'hidden', 'auto-hide', 'visible');
|
||||
this.statusBarEl.addClass('note-status-bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a single status display
|
||||
*/
|
||||
private renderSingleStatus(): void {
|
||||
const primaryStatus = this.currentStatuses[0];
|
||||
const statusObj = this.statusService.getAllStatuses().find(s => s.name === primaryStatus);
|
||||
const tooltipText = statusObj?.description
|
||||
? `${primaryStatus} - ${statusObj.description}`
|
||||
: primaryStatus;
|
||||
|
||||
// Create status text
|
||||
const statusText = this.statusBarEl.createEl('span', {
|
||||
text: `Status: ${primaryStatus}`,
|
||||
cls: `note-status-${primaryStatus}`
|
||||
});
|
||||
setTooltip(statusText, tooltipText);
|
||||
|
||||
// Create status icon
|
||||
const statusIcon = this.statusBarEl.createEl('span', {
|
||||
text: this.statusService.getStatusIcon(primaryStatus),
|
||||
cls: `note-status-icon status-${primaryStatus}`
|
||||
});
|
||||
setTooltip(statusIcon, tooltipText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render multiple statuses display
|
||||
*/
|
||||
private renderMultipleStatuses(): void {
|
||||
this.statusBarEl.createEl('span', {
|
||||
text: 'Statuses: ',
|
||||
cls: 'note-status-label'
|
||||
});
|
||||
|
||||
const badgesContainer = this.statusBarEl.createEl('span', {
|
||||
cls: 'note-status-badges'
|
||||
});
|
||||
|
||||
this.currentStatuses.forEach(status =>
|
||||
this.createStatusBadge(badgesContainer, status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a status badge for multiple status display
|
||||
*/
|
||||
private createStatusBadge(container: HTMLElement, status: string): void {
|
||||
const statusObj = this.statusService.getAllStatuses().find(s => s.name === status);
|
||||
const tooltipText = statusObj?.description
|
||||
? `${status} - ${statusObj.description}`
|
||||
: status;
|
||||
|
||||
const badge = container.createEl('span', {
|
||||
cls: `note-status-badge status-${status}`
|
||||
});
|
||||
setTooltip(badge, tooltipText);
|
||||
|
||||
badge.createEl('span', {
|
||||
text: this.statusService.getStatusIcon(status),
|
||||
cls: 'note-status-badge-icon'
|
||||
});
|
||||
|
||||
badge.createEl('span', {
|
||||
text: status,
|
||||
cls: 'note-status-badge-text'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle auto-hide behavior
|
||||
*/
|
||||
private handleAutoHide(): void {
|
||||
const onlyUnknown = this.currentStatuses.length === 1 &&
|
||||
this.currentStatuses[0] === 'unknown';
|
||||
|
||||
if (this.settings.autoHideStatusBar && onlyUnknown) {
|
||||
this.statusBarEl.addClass('hidden');
|
||||
this.statusBarEl.removeClass('visible');
|
||||
} else {
|
||||
this.statusBarEl.removeClass('hidden');
|
||||
this.statusBarEl.addClass('visible');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update settings reference
|
||||
*/
|
||||
public updateSettings(settings: NoteStatusSettings): void {
|
||||
this.settings = settings;
|
||||
this.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up when plugin is unloaded
|
||||
*/
|
||||
public unload(): void {
|
||||
this.statusBarEl.empty();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue