mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-23 06:40:50 +01:00
Update context menu
This commit is contained in:
parent
1461f43a6d
commit
1c6f7fec1c
@ -89,9 +89,6 @@ export const AvatarInfoWidgetView: FC<{}> = props =>
|
||||
case AvatarInfoRentableBot.RENTABLE_BOT: {
|
||||
return <AvatarInfoWidgetRentableBotView avatarInfo={ (avatarInfo as AvatarInfoRentableBot) } close={ () => setAvatarInfo(null) } />
|
||||
}
|
||||
case AvatarInfoFurni.FURNI: {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,81 +16,67 @@ interface ContextMenuViewProps extends BaseProps<HTMLDivElement>
|
||||
|
||||
const LOCATION_STACK_SIZE: number = 25;
|
||||
const BUBBLE_DROP_SPEED: number = 3;
|
||||
const fadeDelay = 3000;
|
||||
const fadeLength = 75;
|
||||
const FADE_DELAY = 5000;
|
||||
const FADE_LENGTH = 75;
|
||||
const SPACE_AROUND_EDGES = 10;
|
||||
|
||||
let COLLAPSED = false;
|
||||
let FIXED_STACK: FixedSizeStack = null;
|
||||
let MAX_STACK = -1000000;
|
||||
let FADE_TIME = 1;
|
||||
|
||||
export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
||||
{
|
||||
const { objectId = -1, category = -1, userType = -1, fades = false, close = null, position = 'absolute', classNames = [], style = {}, children = null, collapsable = false, ...rest } = props;
|
||||
const [ pos, setPos ] = useState<{ x: number, y: number }>({ x: null, y: null });
|
||||
const [ deltaYStack, setDeltaYStack ] = useState<FixedSizeStack>(null);
|
||||
const [ currentDeltaY, setCurrentDeltaY ] = useState(-1000000);
|
||||
const [ opacity, setOpacity ] = useState(1);
|
||||
const [ isFading, setIsFading ] = useState(false);
|
||||
const [ fadeTime, setFadeTime ] = useState(0);
|
||||
const [ isCollapsed, setIsCollapsed ] = useState(COLLAPSED);
|
||||
const elementRef = useRef<HTMLDivElement>();
|
||||
|
||||
const getOffset = useCallback((bounds: NitroRectangle) =>
|
||||
{
|
||||
let height = -(elementRef.current.offsetHeight);
|
||||
|
||||
if((userType > -1) && ((userType === RoomObjectType.USER) || (userType === RoomObjectType.BOT) || (userType === RoomObjectType.RENTABLE_BOT)))
|
||||
{
|
||||
height = (height + ((bounds.height > 50) ? 15 : 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
height = (height - 14);
|
||||
}
|
||||
|
||||
return height;
|
||||
}, [ userType ]);
|
||||
|
||||
const updateFade = useCallback((time: number) =>
|
||||
{
|
||||
let newFadeTime = time;
|
||||
let newOpacity = 1;
|
||||
if(!isFading) return;
|
||||
|
||||
if(isFading)
|
||||
FADE_TIME += time;
|
||||
|
||||
let newOpacity = ((1 - (FADE_TIME / FADE_LENGTH)) * 1);
|
||||
|
||||
if(newOpacity <= 0)
|
||||
{
|
||||
setFadeTime(prevValue =>
|
||||
{
|
||||
newFadeTime += prevValue;
|
||||
close();
|
||||
|
||||
return newFadeTime;
|
||||
});
|
||||
|
||||
newOpacity = ((1 - (newFadeTime / fadeLength)) * 1);
|
||||
|
||||
if(newOpacity <= 0)
|
||||
{
|
||||
close();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
setOpacity(newOpacity);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
console.log(newOpacity);
|
||||
|
||||
setOpacity(newOpacity);
|
||||
}, [ isFading, close ]);
|
||||
|
||||
const updatePosition = useCallback((bounds: NitroRectangle, location: NitroPoint) =>
|
||||
{
|
||||
if(!bounds || !location || !deltaYStack) return;
|
||||
if(!bounds || !location || !FIXED_STACK) return;
|
||||
|
||||
const offset = getOffset(bounds);
|
||||
let offset = -(elementRef.current.offsetHeight);
|
||||
|
||||
deltaYStack.addValue((location.y - bounds.top));
|
||||
if((userType > -1) && ((userType === RoomObjectType.USER) || (userType === RoomObjectType.BOT) || (userType === RoomObjectType.RENTABLE_BOT)))
|
||||
{
|
||||
offset = (offset + ((bounds.height > 50) ? 15 : 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = (offset - 14);
|
||||
}
|
||||
|
||||
let maxStack = deltaYStack.getMax();
|
||||
FIXED_STACK.addValue((location.y - bounds.top));
|
||||
|
||||
let maxStack = FIXED_STACK.getMax();
|
||||
|
||||
if(maxStack < (MAX_STACK - BUBBLE_DROP_SPEED)) maxStack = (MAX_STACK - BUBBLE_DROP_SPEED);
|
||||
|
||||
MAX_STACK = maxStack;
|
||||
|
||||
if(maxStack < (currentDeltaY - BUBBLE_DROP_SPEED)) maxStack = (currentDeltaY - BUBBLE_DROP_SPEED);
|
||||
|
||||
const deltaY = (location.y - maxStack);
|
||||
|
||||
let x = ~~(location.x - (elementRef.current.offsetWidth / 2));
|
||||
@ -105,19 +91,8 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
||||
if(y < SPACE_AROUND_EDGES) y = SPACE_AROUND_EDGES;
|
||||
else if(y > maxTop) y = maxTop;
|
||||
|
||||
setCurrentDeltaY(maxStack);
|
||||
setPos({ x, y });
|
||||
}, [ deltaYStack, currentDeltaY, getOffset ]);
|
||||
|
||||
const update = useCallback((time: number) =>
|
||||
{
|
||||
if(!elementRef.current || !updateFade(time)) return;
|
||||
|
||||
const bounds = GetRoomObjectBounds(GetRoomSession().roomId, objectId, category);
|
||||
const location = GetRoomObjectScreenLocation(GetRoomSession().roomId, objectId, category);
|
||||
|
||||
updatePosition(bounds, location);
|
||||
}, [ objectId, category, updateFade, updatePosition ]);
|
||||
}, [ userType ]);
|
||||
|
||||
const getClassNames = useMemo(() =>
|
||||
{
|
||||
@ -147,38 +122,51 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setDeltaYStack(new FixedSizeStack(LOCATION_STACK_SIZE));
|
||||
setCurrentDeltaY(-1000000);
|
||||
}, []);
|
||||
if(!elementRef.current) return;
|
||||
|
||||
const update = (time: number) =>
|
||||
{
|
||||
if(!elementRef.current) return;
|
||||
|
||||
updateFade(time);
|
||||
|
||||
const bounds = GetRoomObjectBounds(GetRoomSession().roomId, objectId, category);
|
||||
const location = GetRoomObjectScreenLocation(GetRoomSession().roomId, objectId, category);
|
||||
|
||||
updatePosition(bounds, location);
|
||||
}
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
GetTicker().add(update);
|
||||
|
||||
return () =>
|
||||
{
|
||||
GetTicker().remove(update);
|
||||
}
|
||||
}, [ update ]);
|
||||
}, [ objectId, category, updateFade, updatePosition ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!fades) return;
|
||||
|
||||
const timeout = setTimeout(() => setIsFading(true), fadeDelay);
|
||||
const timeout = setTimeout(() => setIsFading(true), FADE_DELAY);
|
||||
|
||||
return () => clearTimeout(timeout);
|
||||
}, [ fades ]);
|
||||
|
||||
const toggleCollapse = () =>
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
COLLAPSED = !COLLAPSED;
|
||||
setIsCollapsed(COLLAPSED);
|
||||
setOpacity(0);
|
||||
}
|
||||
COLLAPSED = isCollapsed;
|
||||
}, [ isCollapsed ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
FIXED_STACK = new FixedSizeStack(LOCATION_STACK_SIZE);
|
||||
MAX_STACK = -1000000;
|
||||
FADE_TIME = 1;
|
||||
}, []);
|
||||
|
||||
return <Base innerRef={ elementRef } position={ position } classNames={ getClassNames } style={ getStyle } { ...rest }>
|
||||
{ !(collapsable && COLLAPSED) && children }
|
||||
{ collapsable && <ContextMenuCaretView onClick={ () => toggleCollapse() } collapsed={ isCollapsed } /> }
|
||||
{ collapsable && <ContextMenuCaretView onClick={ () => setIsCollapsed(!isCollapsed) } collapsed={ isCollapsed } /> }
|
||||
</Base>;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user