Right-click context menus on file panels
Native menus (electrobun ContextMenu) on rows and empty panel space. Rows: Open (dirs navigate; local files open with the default app via Utils.openPath), Edit, Copy to Other Panel, Rename, Permissions, Copy Path (works for remote paths too), Reveal in Finder (local, Utils.showItemInFolder), Move to Trash (local, Utils.moveToTrash — tooltip notes Finder Restore doesn't apply) and Delete. Empty space / '..': New Folder, New File, Refresh, Reveal in Finder. Right-click parks the cursor on the row (keeping the selection when clicking inside it). Local shell actions run bun-side directly; everything else routes through the existing menuAction channel back to the stored click target. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,7 @@ import { StatusBar } from './status-bar/status-bar';
|
||||
import { TabBar } from './tab-bar/tab-bar';
|
||||
import { ToastService } from './toast.service';
|
||||
import { TransferBar } from './transfer-bar/transfer-bar';
|
||||
import { TransfersService } from './transfers.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -43,6 +44,7 @@ export class App {
|
||||
readonly panels = inject(PanelsService);
|
||||
readonly actions = inject(FileActionsService);
|
||||
readonly connections = inject(ConnectionsService);
|
||||
private readonly transfers = inject(TransfersService);
|
||||
|
||||
constructor() {
|
||||
document.title = BRANDING.appName;
|
||||
@@ -69,6 +71,10 @@ export class App {
|
||||
|
||||
/** Native application-menu actions forwarded from the bun process. */
|
||||
private handleMenuAction(action: string): void {
|
||||
if (action.startsWith('ctx-')) {
|
||||
this.handleContextAction(action);
|
||||
return;
|
||||
}
|
||||
if (action.startsWith('connect:')) {
|
||||
const id = action.slice('connect:'.length);
|
||||
const connection = this.connections.connections().find((c) => c.id === id);
|
||||
@@ -117,6 +123,45 @@ export class App {
|
||||
}
|
||||
}
|
||||
|
||||
/** Context-menu actions apply to the row/panel remembered at right-click time. */
|
||||
private handleContextAction(action: string): void {
|
||||
const target = this.actions.menuTarget;
|
||||
if (!target) return;
|
||||
const { panel, side, entry } = target;
|
||||
switch (action) {
|
||||
case 'ctx-open':
|
||||
if (entry) panel.open(entry);
|
||||
break;
|
||||
case 'ctx-edit':
|
||||
void this.actions.edit(panel);
|
||||
break;
|
||||
case 'ctx-copy':
|
||||
void this.transfers.copyToOtherPanel(side);
|
||||
break;
|
||||
case 'ctx-rename':
|
||||
this.actions.rename(panel);
|
||||
break;
|
||||
case 'ctx-chmod':
|
||||
this.actions.chmod(panel);
|
||||
break;
|
||||
case 'ctx-delete':
|
||||
this.actions.delete(panel);
|
||||
break;
|
||||
case 'ctx-trash':
|
||||
if (entry) void this.actions.trash(panel, entry);
|
||||
break;
|
||||
case 'ctx-new-folder':
|
||||
this.actions.mkdir(panel);
|
||||
break;
|
||||
case 'ctx-new-file':
|
||||
this.actions.createFile(panel);
|
||||
break;
|
||||
case 'ctx-refresh':
|
||||
void panel.refresh();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
toastIcon(kind: 'error' | 'info' | 'success'): string {
|
||||
if (kind === 'error') return 'mynaXCircle';
|
||||
if (kind === 'success') return 'mynaCheckCircle';
|
||||
|
||||
Reference in New Issue
Block a user