fix(DeviceDetailOverlay): notify parent on browsing state changes and improve portal usage in DeviceCard
This commit is contained in:
parent
3088f1801c
commit
7c25680091
|
|
@ -1,4 +1,5 @@
|
|||
import { useEffect, useRef, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { SettingsInput } from './ui/settings-input';
|
||||
import { X, Printer, HardDrive, Network, Box, FolderOpen, MoreVertical, RotateCcw } from 'lucide-react';
|
||||
import { motion, AnimatePresence } from 'motion/react';
|
||||
|
|
@ -48,13 +49,19 @@ interface DeviceCardProps {
|
|||
config: any;
|
||||
setConfig: (c: any) => void;
|
||||
isActive: boolean;
|
||||
onBrowsingChange?: (browsing: boolean) => void;
|
||||
}
|
||||
|
||||
function DeviceCard({ device, config, setConfig, isActive }: DeviceCardProps) {
|
||||
function DeviceCard({ device, config, setConfig, isActive, onBrowsingChange }: DeviceCardProps) {
|
||||
const [browsingField, setBrowsingField] = useState<'url' | 'base_url' | 'cache' | null>(null);
|
||||
const [mediaSetFiles, setMediaSetFiles] = useState<MediaSetEntry[] | null>(null);
|
||||
const detectTokenRef = useRef(0);
|
||||
|
||||
// Notify parent when browser opens/closes so it can lock slide scroll.
|
||||
useEffect(() => {
|
||||
onBrowsingChange?.(browsingField !== null);
|
||||
}, [browsingField, onBrowsingChange]);
|
||||
|
||||
// Close any open browser when swiped away.
|
||||
useEffect(() => {
|
||||
if (!isActive) setBrowsingField(null);
|
||||
|
|
@ -332,7 +339,7 @@ function DeviceCard({ device, config, setConfig, isActive }: DeviceCardProps) {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{browsingField && (
|
||||
{browsingField && createPortal(
|
||||
<MediaBrowser
|
||||
currentPath={
|
||||
browsingField === 'cache' ? (deviceData.cache || '/') :
|
||||
|
|
@ -348,7 +355,8 @@ function DeviceCard({ device, config, setConfig, isActive }: DeviceCardProps) {
|
|||
setBrowsingField(null);
|
||||
}}
|
||||
onClose={() => setBrowsingField(null)}
|
||||
/>
|
||||
/>,
|
||||
document.body
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
@ -366,6 +374,7 @@ export default function DeviceDetailOverlay({
|
|||
}: DeviceDetailOverlayProps) {
|
||||
const [activeIndex, setActiveIndex] = useState(initialIndex);
|
||||
const [showCommandMenu, setShowCommandMenu] = useState(false);
|
||||
const [isBrowsing, setIsBrowsing] = useState(false);
|
||||
const swiperRef = useRef<SwiperType | null>(null);
|
||||
|
||||
const activeDevice = devices[activeIndex] ?? devices[0];
|
||||
|
|
@ -461,12 +470,13 @@ export default function DeviceDetailOverlay({
|
|||
style={{ height: '100%' }}
|
||||
>
|
||||
{devices.map((device, i) => (
|
||||
<SwiperSlide key={device.id} style={{ overflowY: 'auto', height: '100%' }}>
|
||||
<SwiperSlide key={device.id} style={{ overflowY: isBrowsing && i === activeIndex ? 'hidden' : 'auto', height: '100%' }}>
|
||||
<DeviceCard
|
||||
device={device}
|
||||
config={config}
|
||||
setConfig={setConfig}
|
||||
isActive={i === activeIndex}
|
||||
onBrowsingChange={i === activeIndex ? setIsBrowsing : undefined}
|
||||
/>
|
||||
</SwiperSlide>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ export default function MediaBrowser({ currentPath, onSelect, onClose }: MediaBr
|
|||
const pathParts = (path ?? '').split('/').filter(Boolean);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="fixed inset-0 bg-black/50 z-50 flex items-end" onClick={onClose}>
|
||||
<div className="bg-white w-full max-h-[80vh] rounded-t-xl flex flex-col" onClick={e => e.stopPropagation()}>
|
||||
<div className="sticky top-0 bg-white border-b border-neutral-200 p-4">
|
||||
|
|
@ -219,6 +220,8 @@ export default function MediaBrowser({ currentPath, onSelect, onClose }: MediaBr
|
|||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<ConfirmDialog
|
||||
open={confirm !== null}
|
||||
{...(confirm ?? { title: '', onConfirm: () => {} })}
|
||||
|
|
@ -254,6 +257,6 @@ export default function MediaBrowser({ currentPath, onSelect, onClose }: MediaBr
|
|||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user