|
@@ -173,6 +173,7 @@ import { BulkPrinterToolbar, type PrinterState } from '../components/BulkPrinter
|
|
|
import { FileManagerModal } from '../components/FileManagerModal';
|
|
import { FileManagerModal } from '../components/FileManagerModal';
|
|
|
import { EmbeddedCameraViewer } from '../components/EmbeddedCameraViewer';
|
|
import { EmbeddedCameraViewer } from '../components/EmbeddedCameraViewer';
|
|
|
import { CameraWall } from '../components/CameraWall';
|
|
import { CameraWall } from '../components/CameraWall';
|
|
|
|
|
+import { DEFAULT_CAM_WALL_TILE_SIZE } from '../components/camWallTileSize';
|
|
|
import { ContextMenu, type ContextMenuItem } from '../components/ContextMenu';
|
|
import { ContextMenu, type ContextMenuItem } from '../components/ContextMenu';
|
|
|
import { MQTTDebugModal } from '../components/MQTTDebugModal';
|
|
import { MQTTDebugModal } from '../components/MQTTDebugModal';
|
|
|
import { HMSErrorModal, filterKnownHMSErrors, isSevereHMSError } from '../components/HMSErrorModal';
|
|
import { HMSErrorModal, filterKnownHMSErrors, isSevereHMSError } from '../components/HMSErrorModal';
|
|
@@ -8878,6 +8879,12 @@ export function PrintersPage() {
|
|
|
// 'full' adds progress, layer, and time-left on printing/paused tiles.
|
|
// 'full' adds progress, layer, and time-left on printing/paused tiles.
|
|
|
// Defaulting to 'full' because the cards already show this info — users who
|
|
// Defaulting to 'full' because the cards already show this info — users who
|
|
|
// pick cam-wall view still want to glance the same details without flipping.
|
|
// pick cam-wall view still want to glance the same details without flipping.
|
|
|
|
|
+ // Kept apart from the card size: S on the cards also means the compact
|
|
|
|
|
+ // layout, and a wall of 2 cameras wants big tiles next to small cards (#2735).
|
|
|
|
|
+ const [camWallTileSize, setCamWallTileSize] = useState<number>(() => {
|
|
|
|
|
+ const saved = parseInt(localStorage.getItem('camWallTileSize') || '', 10);
|
|
|
|
|
+ return saved >= 1 && saved <= 4 ? saved : DEFAULT_CAM_WALL_TILE_SIZE;
|
|
|
|
|
+ });
|
|
|
const [camWallStatusMode, setCamWallStatusMode] = useState<'off' | 'compact' | 'full'>(() => {
|
|
const [camWallStatusMode, setCamWallStatusMode] = useState<'off' | 'compact' | 'full'>(() => {
|
|
|
const saved = localStorage.getItem('camWallStatusMode');
|
|
const saved = localStorage.getItem('camWallStatusMode');
|
|
|
return saved === 'off' || saved === 'compact' || saved === 'full' ? saved : 'full';
|
|
return saved === 'off' || saved === 'compact' || saved === 'full' ? saved : 'full';
|
|
@@ -9733,14 +9740,19 @@ export function PrintersPage() {
|
|
|
)}
|
|
)}
|
|
|
|
|
|
|
|
{/* Card size selector */}
|
|
{/* Card size selector */}
|
|
|
- <div className={`flex h-8 items-center bg-bambu-dark rounded-lg border border-bambu-dark-tertiary ${pageView === 'camwall' ? 'opacity-40 pointer-events-none' : ''} ${inMenu ? 'w-full' : ''}`}>
|
|
|
|
|
|
|
+ <div className={`flex h-8 items-center bg-bambu-dark rounded-lg border border-bambu-dark-tertiary ${inMenu ? 'w-full' : ''}`}>
|
|
|
{cardSizeLabels.map((label, index) => {
|
|
{cardSizeLabels.map((label, index) => {
|
|
|
const size = index + 1;
|
|
const size = index + 1;
|
|
|
- const isSelected = cardSize === size;
|
|
|
|
|
|
|
+ const isSelected = (pageView === 'camwall' ? camWallTileSize : cardSize) === size;
|
|
|
return (
|
|
return (
|
|
|
<button
|
|
<button
|
|
|
key={label}
|
|
key={label}
|
|
|
onClick={() => {
|
|
onClick={() => {
|
|
|
|
|
+ if (pageView === 'camwall') {
|
|
|
|
|
+ setCamWallTileSize(size);
|
|
|
|
|
+ localStorage.setItem('camWallTileSize', String(size));
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
setCompactDrilldownPrinterId(null);
|
|
setCompactDrilldownPrinterId(null);
|
|
|
setCardSize(size);
|
|
setCardSize(size);
|
|
|
localStorage.setItem('printerCardSize', String(size));
|
|
localStorage.setItem('printerCardSize', String(size));
|
|
@@ -9754,7 +9766,7 @@ export function PrintersPage() {
|
|
|
? 'bg-bambu-green text-white'
|
|
? 'bg-bambu-green text-white'
|
|
|
: 'text-white hover:bg-bambu-dark-tertiary'
|
|
: 'text-white hover:bg-bambu-dark-tertiary'
|
|
|
}`}
|
|
}`}
|
|
|
- title={label === 'S' ? t('printers.cardSize.small') : label === 'M' ? t('printers.cardSize.medium') : label === 'L' ? t('printers.cardSize.large') : t('printers.cardSize.extraLarge')}
|
|
|
|
|
|
|
+ title={t(`printers.${pageView === 'camwall' ? 'camWall.tileSize' : 'cardSize'}.${['small', 'medium', 'large', 'extraLarge'][index]}`)}
|
|
|
>
|
|
>
|
|
|
{label}
|
|
{label}
|
|
|
</button>
|
|
</button>
|
|
@@ -9942,6 +9954,7 @@ export function PrintersPage() {
|
|
|
printers={sortedPrinters}
|
|
printers={sortedPrinters}
|
|
|
maxLive={camWallMaxLive}
|
|
maxLive={camWallMaxLive}
|
|
|
snapshotIntervalSec={camWallSnapshotSec}
|
|
snapshotIntervalSec={camWallSnapshotSec}
|
|
|
|
|
+ tileSize={camWallTileSize}
|
|
|
onTileClick={(id, name) => {
|
|
onTileClick={(id, name) => {
|
|
|
// A wall tile has no room for a split button, so it follows the
|
|
// A wall tile has no room for a split button, so it follows the
|
|
|
// mode the card buttons last chose.
|
|
// mode the card buttons last chose.
|