P3: transfer engine with queue, progress, cancel + transfer bar UI

- TransferEngine: FIFO queue, provider-generic stream pipeline (covers all four
  panel combos), throttled transferUpdate push, cancel via stream destroy,
  self-copy guards, failSession hook for dead SSH sessions
- TransfersService + TransferBar: per-job rows, progress bars, cancel/dismiss,
  auto-dismiss completed, dst panel refresh
- F5 + Copy button wired to active-panel selection
- verified: 30MB nested tree copy (UTF-8 names, empty dirs), self-copy rejection,
  mid-transfer cancel leaving partial file

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jokin
2026-07-11 13:46:34 +02:00
co-authored by Claude Fable 5
parent b907e0a4ce
commit 88af44acfc
9 changed files with 455 additions and 7 deletions
+4 -1
View File
@@ -9,10 +9,12 @@ import { FileActionsService } from './file-actions.service';
import { FilePanel } from './file-panel/file-panel';
import { RpcService } from './rpc.service';
import { ToastService } from './toast.service';
import { TransferBar } from './transfer-bar/transfer-bar';
import { TransfersService } from './transfers.service';
@Component({
selector: 'app-root',
imports: [NgIcon, FilePanel, PromptDialog, ConfirmDialog, ChmodDialog],
imports: [NgIcon, FilePanel, PromptDialog, ConfirmDialog, ChmodDialog, TransferBar],
templateUrl: './app.html',
})
export class App {
@@ -21,6 +23,7 @@ export class App {
readonly toast = inject(ToastService);
readonly dialogs = inject(DialogsService);
readonly actions = inject(FileActionsService);
readonly transfers = inject(TransfersService);
constructor() {
document.title = BRANDING.appName;