mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-20 15:36:18 +00:00
Merge pull request #116 from duckietm/Dev
🆙 Small fix for the badge selector in the infostand view
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
import { createPortal } from 'react-dom';
|
||||||
import { FaPlus } from 'react-icons/fa';
|
import { FaPlus } from 'react-icons/fa';
|
||||||
import { GetConfigurationValue, LocalizeText } from '../../../../../api';
|
import { GetConfigurationValue, LocalizeText } from '../../../../../api';
|
||||||
import { LayoutBadgeImageView } from '../../../../../common';
|
import { LayoutBadgeImageView } from '../../../../../common';
|
||||||
@@ -15,7 +16,8 @@ const BadgeMiniPicker: FC<{
|
|||||||
onSelect: (badgeCode: string) => void;
|
onSelect: (badgeCode: string) => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
activeBadgeCodes: (string | null)[];
|
activeBadgeCodes: (string | null)[];
|
||||||
}> = ({ onSelect, onClose, activeBadgeCodes }) =>
|
position: { top: number; left: number };
|
||||||
|
}> = ({ onSelect, onClose, activeBadgeCodes, position }) =>
|
||||||
{
|
{
|
||||||
const { badgeCodes = [], requestBadges = null } = useInventoryBadges();
|
const { badgeCodes = [], requestBadges = null } = useInventoryBadges();
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
@@ -43,10 +45,11 @@ const BadgeMiniPicker: FC<{
|
|||||||
return () => document.removeEventListener('mousedown', handleClickOutside);
|
return () => document.removeEventListener('mousedown', handleClickOutside);
|
||||||
}, [ onClose ]);
|
}, [ onClose ]);
|
||||||
|
|
||||||
return (
|
return createPortal(
|
||||||
<div
|
<div
|
||||||
ref={ ref }
|
ref={ ref }
|
||||||
className="absolute right-[calc(100%+8px)] top-0 z-50 bg-[rgba(28,28,32,0.97)] border border-white/20 rounded-md p-2 shadow-lg min-w-[160px]"
|
className="fixed z-[9999] bg-[rgba(28,28,32,0.97)] border border-white/20 rounded-md p-2 shadow-lg min-w-[160px]"
|
||||||
|
style={ { top: position.top, left: position.left } }
|
||||||
onClick={ e => e.stopPropagation() }>
|
onClick={ e => e.stopPropagation() }>
|
||||||
<input
|
<input
|
||||||
autoFocus
|
autoFocus
|
||||||
@@ -73,7 +76,8 @@ const BadgeMiniPicker: FC<{
|
|||||||
) }
|
) }
|
||||||
</div>
|
</div>
|
||||||
) }
|
) }
|
||||||
</div>
|
</div>,
|
||||||
|
document.body
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -83,7 +87,9 @@ export const InfoStandBadgeSlotView: FC<InfoStandBadgeSlotProps> = ({ slotIndex,
|
|||||||
const [ isDragOver, setIsDragOver ] = useState(false);
|
const [ isDragOver, setIsDragOver ] = useState(false);
|
||||||
const [ isDragging, setIsDragging ] = useState(false);
|
const [ isDragging, setIsDragging ] = useState(false);
|
||||||
const [ justDropped, setJustDropped ] = useState(false);
|
const [ justDropped, setJustDropped ] = useState(false);
|
||||||
const [ showPicker, setShowPicker ] = useState(false);
|
const [ pickerPosition, setPickerPosition ] = useState<{ top: number; left: number } | null>(null);
|
||||||
|
const slotRef = useRef<HTMLDivElement>(null);
|
||||||
|
const showPicker = pickerPosition !== null;
|
||||||
|
|
||||||
const hookInitialized = activeBadgeCodes.length > 0;
|
const hookInitialized = activeBadgeCodes.length > 0;
|
||||||
|
|
||||||
@@ -152,9 +158,17 @@ export const InfoStandBadgeSlotView: FC<InfoStandBadgeSlotProps> = ({ slotIndex,
|
|||||||
|
|
||||||
const handleSlotClick = useCallback(() =>
|
const handleSlotClick = useCallback(() =>
|
||||||
{
|
{
|
||||||
if(!isOwnUser || badgeCode) return;
|
if(!isOwnUser || badgeCode || !slotRef.current) return;
|
||||||
|
|
||||||
setShowPicker(true);
|
const rect = slotRef.current.getBoundingClientRect();
|
||||||
|
const pickerWidth = 180;
|
||||||
|
const gap = 8;
|
||||||
|
let left = rect.right + gap;
|
||||||
|
|
||||||
|
if((left + pickerWidth) > (window.innerWidth - gap)) left = rect.left - pickerWidth - gap;
|
||||||
|
if(left < gap) left = gap;
|
||||||
|
|
||||||
|
setPickerPosition({ top: rect.top, left });
|
||||||
}, [ isOwnUser, badgeCode ]);
|
}, [ isOwnUser, badgeCode ]);
|
||||||
|
|
||||||
const handleDoubleClick = useCallback(() =>
|
const handleDoubleClick = useCallback(() =>
|
||||||
@@ -167,12 +181,13 @@ export const InfoStandBadgeSlotView: FC<InfoStandBadgeSlotProps> = ({ slotIndex,
|
|||||||
const handlePickerSelect = useCallback((code: string) =>
|
const handlePickerSelect = useCallback((code: string) =>
|
||||||
{
|
{
|
||||||
setBadgeAtSlot(code, slotIndex);
|
setBadgeAtSlot(code, slotIndex);
|
||||||
setShowPicker(false);
|
setPickerPosition(null);
|
||||||
}, [ setBadgeAtSlot, slotIndex ]);
|
}, [ setBadgeAtSlot, slotIndex ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div
|
<div
|
||||||
|
ref={ slotRef }
|
||||||
className={ `flex items-center justify-center relative w-[40px] h-[40px] bg-no-repeat bg-center transition-all duration-150
|
className={ `flex items-center justify-center relative w-[40px] h-[40px] bg-no-repeat bg-center transition-all duration-150
|
||||||
${ isOwnUser && badgeCode ? 'cursor-grab active:cursor-grabbing' : '' }
|
${ isOwnUser && badgeCode ? 'cursor-grab active:cursor-grabbing' : '' }
|
||||||
${ isOwnUser && !badgeCode ? 'cursor-pointer' : '' }
|
${ isOwnUser && !badgeCode ? 'cursor-pointer' : '' }
|
||||||
@@ -196,8 +211,9 @@ export const InfoStandBadgeSlotView: FC<InfoStandBadgeSlotProps> = ({ slotIndex,
|
|||||||
{ showPicker && (
|
{ showPicker && (
|
||||||
<BadgeMiniPicker
|
<BadgeMiniPicker
|
||||||
activeBadgeCodes={ activeBadgeCodes }
|
activeBadgeCodes={ activeBadgeCodes }
|
||||||
onClose={ () => setShowPicker(false) }
|
onClose={ () => setPickerPosition(null) }
|
||||||
onSelect={ handlePickerSelect }
|
onSelect={ handlePickerSelect }
|
||||||
|
position={ pickerPosition }
|
||||||
/>
|
/>
|
||||||
) }
|
) }
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user