refactor: logic and ui

This commit is contained in:
Aleix 2025-05-21 15:37:23 +02:00
parent 33935c2d77
commit 2cdd2e8808
2 changed files with 94 additions and 72 deletions

View file

@ -1,11 +1,11 @@
import { App, Menu, TFile } from 'obsidian';
import { NoteStatusSettings } from '../../models/types';
import { ExplorerIntegration } from '../explorer/explorer-integration';
import { NoteStatusSettings } from 'models/types';
import { StatusService } from 'services/status-service';
import { StatusContextMenu } from './status-context-menu';
import { ExplorerIntegration } from 'integrations/explorer/explorer-integration';
import { StatusContextMenu } from 'integrations/context-menu/status-context-menu';
/**
* Gestiona menús contextuales del explorador de archivos
* Gestiona la integración de menús contextuales con el explorador de archivos
*/
export class FileContextMenuIntegration {
private app: App;
@ -36,15 +36,17 @@ export class FileContextMenuIntegration {
}
/**
* Registra los elementos del menú de archivo
* Registra los eventos del menú contextual de archivos
*/
public registerFileContextMenuEvents(): void {
// Evento para archivo único
this.app.workspace.on('file-menu', (menu, file, source) => {
if (source === 'file-explorer-context-menu' && file instanceof TFile && file.extension === 'md') {
this.addStatusChangeMenu(menu, file);
}
});
// Evento para múltiples archivos
this.app.workspace.on('files-menu', (menu, files) => {
const mdFiles = files.filter(file =>
file instanceof TFile && file.extension === 'md'
@ -57,45 +59,25 @@ export class FileContextMenuIntegration {
}
/**
* Añade opción de cambio de estado al menú de archivo
* Añade opción de cambio de estado al menú contextual de un archivo
*/
private addStatusChangeMenu(menu: Menu, file: TFile): void {
menu.addItem(item =>
item
.setTitle('Change status')
.setIcon('tag')
.onClick(() => {
const selectedFiles = this.explorerIntegration.getSelectedFiles();
if (selectedFiles.length > 1) {
this.showStatusChangeModal(selectedFiles);
} else {
this.showStatusChangeModal([file]);
}
})
);
this.statusContextMenu.addStatusMenuItemToSingleFile(menu, file, (file) => {
const selectedFiles = this.explorerIntegration.getSelectedFiles();
if (selectedFiles.length > 1) {
this.statusContextMenu.showForFiles(selectedFiles);
} else {
this.statusContextMenu.showForFiles([file]);
}
});
}
/**
* Añade opción de cambio de estado para múltiples archivos
*/
private addBatchStatusChangeMenu(menu: Menu, files: TFile[]): void {
menu.addItem(item =>
item
.setTitle('Change status')
.setIcon('tag')
.onClick(() => {
this.showStatusChangeModal(files);
})
);
}
/**
* Muestra el modal para cambiar estado
*/
private showStatusChangeModal(files: TFile[]): void {
// Implementación que mostraría un modal para seleccionar estado
// En la práctica, esta función delegaría en un servicio de UI
console.log(`Cambiar estado para ${files.length} archivos`);
this.statusContextMenu.showForFiles(files)
this.statusContextMenu.addStatusMenuItemToBatch(menu, files, (files) => {
this.statusContextMenu.showForFiles(files);
});
}
}

View file

@ -1,18 +1,18 @@
import { App, Menu, TFile } from 'obsidian';
import { NoteStatusSettings } from '../../models/types';
import { StatusService } from '../../services/status-service';
import { NoteStatusSettings } from 'models/types';
import { StatusService } from 'services/status-service';
import { StatusDropdown } from 'components/status-dropdown';
import { ExplorerIntegration } from 'integrations/explorer';
import { ExplorerIntegration } from 'integrations/explorer/explorer-integration';
/**
* Handles context menu interactions for status changes
* Gestiona los menús contextuales para cambios de estado
*/
export class StatusContextMenu {
private statusDropdown: StatusDropdown;
private app: App;
private settings: NoteStatusSettings;
private statusService: StatusService;
private statusDropdown: StatusDropdown;
private explorerIntegration: ExplorerIntegration;
public app: App;
constructor(
app: App,
@ -29,14 +29,40 @@ export class StatusContextMenu {
}
/**
* Updates settings reference
* Actualiza la configuración
*/
public updateSettings(settings: NoteStatusSettings): void {
this.settings = settings;
}
/**
* Shows the context menu for changing status of one or more files
* Añade ítem de menú para cambiar estado de un archivo
*/
public addStatusMenuItemToSingleFile(menu: Menu, file: TFile, onClick: (file: TFile) => void): void {
menu.addItem(item =>
item
.setTitle('Change status')
.setIcon('tag')
.onClick(() => onClick(file))
);
}
/**
* Añade ítem de menú para cambiar estado de múltiples archivos
*/
public addStatusMenuItemToBatch(menu: Menu, files: TFile[], onClick: (files: TFile[]) => void): void {
menu.addItem(item =>
item
.setTitle('Change status')
.setIcon('tag')
.onClick(() => onClick(files))
);
}
/**
* Muestra el menú contextual para cambiar estado de uno o más archivos
* @param files Archivos a los que cambiar el estado
* @param position Posición opcional para mostrar el menú
*/
public showForFiles(files: TFile[], position?: { x: number; y: number }): void {
if (files.length === 0) return;
@ -44,38 +70,16 @@ export class StatusContextMenu {
if (files.length === 1) {
this.showForSingleFile(files[0], position);
} else {
const menu = new Menu();
menu.addItem((item) => {
item.setTitle(`Update ${files.length} files`)
.setDisabled(true);
return item;
});
menu.addItem((item) =>
item
.setTitle('Manage statuses...')
.setIcon('tag')
.onClick(() => {
this.statusDropdown.openStatusDropdown({
position,
files
});
})
);
if (position) {
menu.showAtPosition(position);
} else {
menu.showAtMouseEvent(new MouseEvent('contextmenu'));
}
this.showForMultipleFiles(files, position);
}
}
/**
* Shows a context menu for a single file
* Muestra el menú contextual para un solo archivo
* @param file Archivo al que cambiar el estado
* @param position Posición opcional para mostrar el menú
*/
public showForSingleFile(file: TFile, position?: { x: number; y: number }): void {
private showForSingleFile(file: TFile, position?: { x: number; y: number }): void {
if (!(file instanceof TFile) || file.extension !== 'md') return;
this.statusDropdown.openStatusDropdown({
@ -83,4 +87,40 @@ export class StatusContextMenu {
files: [file]
});
}
/**
* Muestra el menú contextual para múltiples archivos
* @param files Archivos a los que cambiar el estado
* @param position Posición opcional para mostrar el menú
*/
private showForMultipleFiles(files: TFile[], position?: { x: number; y: number }): void {
const menu = new Menu();
// Elemento de información (deshabilitado)
menu.addItem((item) => {
item.setTitle(`Update ${files.length} files`)
.setDisabled(true);
return item;
});
// Opción para gestionar estados
menu.addItem((item) =>
item
.setTitle('Manage statuses...')
.setIcon('tag')
.onClick(() => {
this.statusDropdown.openStatusDropdown({
position,
files
});
})
);
// Mostrar el menú en la posición adecuada
if (position) {
menu.showAtPosition(position);
} else {
menu.showAtMouseEvent(new MouseEvent('contextmenu'));
}
}
}