Update context menu

This commit is contained in:
Bill 2022-07-24 23:08:56 -04:00
parent 1461f43a6d
commit 1c6f7fec1c
2 changed files with 61 additions and 76 deletions

View File

@ -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;
}
}
}

View File

@ -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>;
}