From b991570285e1ba58dd36db9cbf9fac6bb51635bc Mon Sep 17 00:00:00 2001 From: Thomas Peterson Date: Mon, 1 Dec 2025 11:23:20 +0100 Subject: [PATCH] Backup --- examples/ServerManager/UI/SftpManagerTab.php | 118 +++++++++++++++---- src/Ui/Widget/FileBrowser.php | 17 +-- src/Ui/Widget/Table.php | 12 -- 3 files changed, 101 insertions(+), 46 deletions(-) diff --git a/examples/ServerManager/UI/SftpManagerTab.php b/examples/ServerManager/UI/SftpManagerTab.php index 261629a..0c0d3df 100644 --- a/examples/ServerManager/UI/SftpManagerTab.php +++ b/examples/ServerManager/UI/SftpManagerTab.php @@ -36,12 +36,17 @@ class SftpManagerTab private float $lastRemoteClickTime = 0.0; private ProgressBar $transferProgressBar; private Label $transferInfoLabel; + private Label $transferBytesLabel; private array $pendingUploadQueue = []; private int $totalUploadFiles = 0; private int $completedUploadFiles = 0; + private int $totalUploadBytes = 0; + private int $completedUploadBytes = 0; private array $pendingDownloadQueue = []; private int $totalDownloadFiles = 0; private int $completedDownloadFiles = 0; + private int $totalDownloadBytes = 0; + private int $completedDownloadBytes = 0; public function __construct( string &$apiKey, @@ -112,9 +117,11 @@ class SftpManagerTab // Transfer-Info + ProgressBar $this->transferInfoLabel = new Label('Kein Transfer aktiv', 'text-xs text-gray-600 mt-2'); + $this->transferBytesLabel = new Label('', 'text-xs text-gray-600'); $this->transferProgressBar = new ProgressBar('mt-1'); $this->transferProgressBar->setValue(0.0); $transferContainer->addComponent($this->transferInfoLabel); + $transferContainer->addComponent($this->transferBytesLabel); $transferContainer->addComponent($this->transferProgressBar); $this->tab->addComponent($localBrowserContainer); @@ -807,26 +814,30 @@ class SftpManagerTab $remoteDir = '/'; } - // Upload-Größe vorab bestimmen - $stats = $this->calculateLocalUploadStats($localPath, $localRow); - $totalBytes = $stats['bytes']; - $fileCount = $stats['files']; - $dirCount = $stats['dirs']; + // Upload-Queue inkl. Byte-Größen vorbereiten + $this->pendingUploadQueue = $this->buildUploadQueue($localPath, $localRow, $remoteDir); + $this->totalUploadFiles = count($this->pendingUploadQueue); + $this->completedUploadFiles = 0; + $this->totalUploadBytes = 0; + $this->completedUploadBytes = 0; + + foreach ($this->pendingUploadQueue as $item) { + $this->totalUploadBytes += (int) ($item['size'] ?? 0); + } $this->transferProgressBar->setValue(0.0); $this->transferInfoLabel->setText( sprintf( - 'Upload: %d Dateien, %d Ordner (%.2f MB)', - $fileCount, - $dirCount, - $totalBytes > 0 ? ($totalBytes / (1024 * 1024)) : 0, + 'Upload: %d Dateien', + $this->totalUploadFiles, + ), + ); + $this->transferBytesLabel->setText( + sprintf( + '0.00 / %.2f MB', + $this->totalUploadBytes > 0 ? ($this->totalUploadBytes / (1024 * 1024)) : 0, ), ); - - // Upload-Queue für virtuelle ProgressBar vorbereiten - $this->pendingUploadQueue = $this->buildUploadQueue($localPath, $localRow, $remoteDir); - $this->totalUploadFiles = count($this->pendingUploadQueue); - $this->completedUploadFiles = 0; if ($this->totalUploadFiles <= 0) { $this->transferProgressBar->setValue(1.0); @@ -904,6 +915,7 @@ class SftpManagerTab $queue[] = [ 'local' => $localPath, 'remote' => $remoteBase . '/' . basename($localPath), + 'size' => is_file($localPath) ? (int) @filesize($localPath) : 0, ]; return $queue; } @@ -941,6 +953,7 @@ class SftpManagerTab $queue[] = [ 'local' => $localChild, 'remote' => $remoteChild, + 'size' => is_file($localChild) ? (int) @filesize($localChild) : 0, ]; } } @@ -973,6 +986,7 @@ class SftpManagerTab $item = array_shift($this->pendingUploadQueue); $localPath = $item['local']; $remotePath = $item['remote']; + $fileSize = (int) ($item['size'] ?? 0); $selectedServerRef = &$serverListTab->selectedServer; $sftpTab = $this; @@ -1020,7 +1034,7 @@ class SftpManagerTab return ['error' => $e->getMessage()]; } }, - function ($result) use ($sftpTab, &$currentPrivateKeyPath, $serverListTab, $statusLabel) { + function ($result) use ($sftpTab, &$currentPrivateKeyPath, $serverListTab, $statusLabel, $fileSize) { if (isset($result['error'])) { $sftpTab->transferInfoLabel->setText('Upload fehlgeschlagen: ' . $result['error']); $statusLabel->setText('Fehler beim Hochladen: ' . $result['error']); @@ -1029,9 +1043,17 @@ class SftpManagerTab if (isset($result['success'])) { $sftpTab->completedUploadFiles++; - $progress = $sftpTab->totalUploadFiles > 0 - ? ($sftpTab->completedUploadFiles / $sftpTab->totalUploadFiles) - : 1.0; + $sftpTab->completedUploadBytes += $fileSize; + + $progress = 0.0; + if ($sftpTab->totalUploadBytes > 0) { + $progress = $sftpTab->completedUploadBytes / $sftpTab->totalUploadBytes; + } elseif ($sftpTab->totalUploadFiles > 0) { + $progress = $sftpTab->completedUploadFiles / $sftpTab->totalUploadFiles; + } else { + $progress = 1.0; + } + $sftpTab->transferProgressBar->setValue($progress); $sftpTab->transferInfoLabel->setText( sprintf( @@ -1040,6 +1062,17 @@ class SftpManagerTab $sftpTab->totalUploadFiles, ), ); + $sftpTab->transferBytesLabel->setText( + sprintf( + '%.2f / %.2f MB', + $sftpTab->completedUploadBytes > 0 + ? ($sftpTab->completedUploadBytes / (1024 * 1024)) + : 0, + $sftpTab->totalUploadBytes > 0 + ? ($sftpTab->totalUploadBytes / (1024 * 1024)) + : 0, + ), + ); // Nächste Datei starten $sftpTab->startNextUploadTask($currentPrivateKeyPath, $serverListTab, $statusLabel); @@ -1081,6 +1114,7 @@ class SftpManagerTab $item = array_shift($this->pendingDownloadQueue); $remotePath = $item['remote']; $localPath = $item['local']; + $fileSize = (int) ($item['size'] ?? 0); $selectedServerRef = &$serverListTab->selectedServer; $sftpTab = $this; @@ -1119,7 +1153,7 @@ class SftpManagerTab return ['error' => $e->getMessage()]; } }, - function ($result) use ($sftpTab, &$currentPrivateKeyPath, $serverListTab, $statusLabel, $localRootDir) { + function ($result) use ($sftpTab, &$currentPrivateKeyPath, $serverListTab, $statusLabel, $localRootDir, $fileSize) { if (isset($result['error'])) { $sftpTab->transferInfoLabel->setText('Download fehlgeschlagen: ' . $result['error']); $statusLabel->setText('Fehler beim Herunterladen: ' . $result['error']); @@ -1128,9 +1162,17 @@ class SftpManagerTab if (isset($result['success'])) { $sftpTab->completedDownloadFiles++; - $progress = $sftpTab->totalDownloadFiles > 0 - ? ($sftpTab->completedDownloadFiles / $sftpTab->totalDownloadFiles) - : 1.0; + $sftpTab->completedDownloadBytes += $fileSize; + + $progress = 0.0; + if ($sftpTab->totalDownloadBytes > 0) { + $progress = $sftpTab->completedDownloadBytes / $sftpTab->totalDownloadBytes; + } elseif ($sftpTab->totalDownloadFiles > 0) { + $progress = $sftpTab->completedDownloadFiles / $sftpTab->totalDownloadFiles; + } else { + $progress = 1.0; + } + $sftpTab->transferProgressBar->setValue($progress); $sftpTab->transferInfoLabel->setText( sprintf( @@ -1139,6 +1181,17 @@ class SftpManagerTab $sftpTab->totalDownloadFiles, ), ); + $sftpTab->transferBytesLabel->setText( + sprintf( + '%.2f / %.2f MB', + $sftpTab->completedDownloadBytes > 0 + ? ($sftpTab->completedDownloadBytes / (1024 * 1024)) + : 0, + $sftpTab->totalDownloadBytes > 0 + ? ($sftpTab->totalDownloadBytes / (1024 * 1024)) + : 0, + ), + ); // Nächste Datei herunterladen $sftpTab->startNextDownloadTask($currentPrivateKeyPath, $serverListTab, $statusLabel, $localRootDir); @@ -1219,19 +1272,24 @@ class SftpManagerTab $queue = []; $files = 0; $dirs = 0; + $totalBytes = 0; $isDir = (bool) ($remoteRow['isDir'] ?? false); if (!$isDir) { + $stat = $sftp->stat($remotePath); + $size = (int) ($stat['size'] ?? 0); $queue[] = [ 'remote' => $remotePath, 'local' => rtrim($localDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . basename($remotePath), + 'size' => $size, ]; $files = 1; + $totalBytes = $size; } else { $rootLocal = rtrim($localDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . basename($remotePath); $collect = null; - $collect = function (string $srcDir, string $dstDir) use (&$collect, $sftp, &$queue, &$files, &$dirs) { + $collect = function (string $srcDir, string $dstDir) use (&$collect, $sftp, &$queue, &$files, &$dirs, &$totalBytes) { $dirs++; $entries = $sftp->nlist($srcDir); @@ -1253,11 +1311,14 @@ class SftpManagerTab if ($isDirChild) { $collect($remoteChild, $localChild); } else { + $size = (int) ($stat['size'] ?? 0); $queue[] = [ 'remote' => $remoteChild, 'local' => $localChild, + 'size' => $size, ]; $files++; + $totalBytes += $size; } } }; @@ -1271,6 +1332,7 @@ class SftpManagerTab 'files' => $files, 'dirs' => $dirs, 'localDir' => $localDir, + 'totalBytes' => $totalBytes, ]; } catch (\Exception $e) { return ['error' => $e->getMessage()]; @@ -1292,14 +1354,18 @@ class SftpManagerTab $queue = $result['queue'] ?? []; $files = (int) ($result['files'] ?? 0); $dirs = (int) ($result['dirs'] ?? 0); + $totalBytes = (int) ($result['totalBytes'] ?? 0); $sftpTab->pendingDownloadQueue = $queue; $sftpTab->totalDownloadFiles = count($queue); $sftpTab->completedDownloadFiles = 0; + $sftpTab->totalDownloadBytes = $totalBytes; + $sftpTab->completedDownloadBytes = 0; if ($sftpTab->totalDownloadFiles <= 0) { $sftpTab->transferProgressBar->setValue(1.0); $sftpTab->transferInfoLabel->setText('Keine Dateien zum Herunterladen'); + $sftpTab->transferBytesLabel->setText(''); return; } @@ -1311,6 +1377,12 @@ class SftpManagerTab $dirs, ), ); + $sftpTab->transferBytesLabel->setText( + sprintf( + '0.00 / %.2f MB', + $totalBytes > 0 ? ($totalBytes / (1024 * 1024)) : 0, + ), + ); $localDir = $result['localDir'] ?? ''; $sftpTab->startNextDownloadTask($currentPrivateKeyPath, $serverListTab, $statusLabel, $localDir); diff --git a/src/Ui/Widget/FileBrowser.php b/src/Ui/Widget/FileBrowser.php index 61e2c6b..7f5297b 100644 --- a/src/Ui/Widget/FileBrowser.php +++ b/src/Ui/Widget/FileBrowser.php @@ -13,7 +13,7 @@ class FileBrowser extends Container private $onRenameFile = null; private $onDeleteFile = null; private bool $isRemote = false; - private ?string $lastClickPath = null; + private null|string $lastClickPath = null; private float $lastClickTime = 0.0; public function __construct(string $initialPath = '.', bool $isRemote = false, string $style = '') @@ -136,10 +136,7 @@ class FileBrowser extends Container $now = microtime(true); $doubleClickThreshold = 0.4; // Sekunden - if ( - $fileBrowser->lastClickPath !== $path || - ($now - $fileBrowser->lastClickTime) > $doubleClickThreshold - ) { + if ($fileBrowser->lastClickPath !== $path || ($now - $fileBrowser->lastClickTime) > $doubleClickThreshold) { // Erster Klick: nur merken $fileBrowser->lastClickPath = $path; $fileBrowser->lastClickTime = $now; @@ -288,16 +285,14 @@ class FileBrowser extends Container public function renderActionsCell(array $rowData, int $rowIndex): Container { // Match the cell style from Table (100px width for icon buttons) - $container = new Container( - 'w-25 py-1 border-r border-gray-300 flex flex-row items-center justify-center gap-1', - ); + $container = new Container('w-25 border-r border-gray-300 flex flex-row items-center justify-center gap-1'); // Only show action buttons for files (not directories) if (!($rowData['isDir'] ?? false) && !empty($rowData['path'])) { $fileBrowser = $this; // Edit button - $editButton = new Button('', 'p-1 text-blue-500 hover:text-blue-600 flex items-center justify-center'); + $editButton = new Button('', 'text-blue-500 hover:text-blue-600 flex items-center justify-center'); $editIcon = new Icon(\PHPNative\Tailwind\Data\Icon::edit, 16, 'text-blue-500'); $editButton->setIcon($editIcon); $editButton->setOnClick(function () use ($fileBrowser, $rowData) { @@ -308,7 +303,7 @@ class FileBrowser extends Container $container->addComponent($editButton); // Rename button - $renameButton = new Button('', 'p-1 text-amber-500 hover:text-amber-600 flex items-center justify-center'); + $renameButton = new Button('', 'text-amber-500 hover:text-amber-600 flex items-center justify-center'); $renameIcon = new Icon(\PHPNative\Tailwind\Data\Icon::pen, 16, 'text-amber-500'); $renameButton->setIcon($renameIcon); $renameButton->setOnClick(function () use ($fileBrowser, $rowData) { @@ -319,7 +314,7 @@ class FileBrowser extends Container $container->addComponent($renameButton); // Delete button - $deleteButton = new Button('', 'p-1 text-red-500 hover:text-red-600 flex items-center justify-center'); + $deleteButton = new Button('', 'text-red-500 hover:text-red-600 flex items-center justify-center'); $deleteIcon = new Icon(\PHPNative\Tailwind\Data\Icon::trash, 16, 'text-red-500'); $deleteButton->setIcon($deleteIcon); $deleteButton->setOnClick(function () use ($fileBrowser, $rowData) { diff --git a/src/Ui/Widget/Table.php b/src/Ui/Widget/Table.php index 86f6db5..52db974 100644 --- a/src/Ui/Widget/Table.php +++ b/src/Ui/Widget/Table.php @@ -91,18 +91,6 @@ class Table extends Container if ($preserveScroll && $scrollPosition !== null) { $this->bodyContainer->setScrollPosition($scrollPosition['x'], $scrollPosition['y']); } - - // Debug-Ausgabe: Größe des Tabellen-Body und Viewport - $bodySize = $this->bodyContainer->getContentSize(); - $bodyViewport = $this->bodyContainer->getContentViewport(); - error_log( - sprintf( - 'Table body debug: rows=%d, contentHeight=%d, viewportHeight=%d', - count($data), - (int) ($bodySize['height'] ?? 0), - (int) $bodyViewport->height, - ), - ); } /**