diff --git a/src/layout/card/NitroCardView.scss b/src/layout/card/NitroCardView.scss index 9f11cdef..b604cd44 100644 --- a/src/layout/card/NitroCardView.scss +++ b/src/layout/card/NitroCardView.scss @@ -13,6 +13,7 @@ $nitro-card-tabs-height: 33px; width: 100%; height: 100%; pointer-events: none; + overflow: hidden; .theme-primary { border: $border-width solid $border-color; @@ -25,7 +26,7 @@ $nitro-card-tabs-height: 33px; left: 0 !important; width: 100%; height: 100%; - transform: none !important; + //transform: none !important; overflow: hidden; } @@ -39,6 +40,29 @@ $nitro-card-tabs-height: 33px; // } } } + + @include media-breakpoint-down(sm) { + + .draggable-window { + top: 0 !important; + left: 0 !important; + width: 100%; + height: 100%; + //transform: none !important; + overflow: hidden; + } + + .nitro-card { + width: 100%; + max-width: 100%; + max-height: calc(100% - #{$toolbar-height}); + margin: 0; + + &.rounded { + border-radius: 0 !important; + } + } + } } @import './accordion/NitroCardAccordionView'; diff --git a/src/layout/common/NitroLayoutSpacing.type.ts b/src/layout/common/NitroLayoutSpacing.type.ts index 96e53311..4f2bd26a 100644 --- a/src/layout/common/NitroLayoutSpacing.type.ts +++ b/src/layout/common/NitroLayoutSpacing.type.ts @@ -1 +1 @@ -export type NitroLayoutSpacing = 1 | 2 | 3 | 4 | 5; +export type NitroLayoutSpacing = 0 | 1 | 2 | 3 | 4 | 5; diff --git a/src/layout/draggable-window/DraggableWindow.tsx b/src/layout/draggable-window/DraggableWindow.tsx index a5cab370..d9d1fb03 100644 --- a/src/layout/draggable-window/DraggableWindow.tsx +++ b/src/layout/draggable-window/DraggableWindow.tsx @@ -1,5 +1,5 @@ -import { MouseEventType } from '@nitrots/nitro-renderer'; -import { FC, Key, MouseEvent as ReactMouseEvent, useCallback, useEffect, useRef, useState } from 'react'; +import { MouseEventType, TouchEventType } from '@nitrots/nitro-renderer'; +import { FC, Key, MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent, useCallback, useEffect, useRef, useState } from 'react'; import { DraggableWindowPosition, DraggableWindowProps } from './DraggableWindow.types'; const CURRENT_WINDOWS: HTMLElement[] = []; @@ -29,7 +29,7 @@ export const DraggableWindow: FC = props => } }, []); - const onMouseDown = useCallback((event: ReactMouseEvent) => + const moveCurrentWindow = useCallback(() => { const index = CURRENT_WINDOWS.indexOf(elementRef.current); @@ -50,18 +50,47 @@ export const DraggableWindow: FC = props => bringToTop(); }, [ bringToTop ]); - const onDragMouseDown = useCallback((event: MouseEvent) => + const onMouseDown = useCallback((event: ReactMouseEvent) => { - setStart({ x: event.clientX, y: event.clientY }); + moveCurrentWindow(); + }, [ moveCurrentWindow ]); + + const onTouchStart = useCallback((event: ReactTouchEvent) => + { + moveCurrentWindow(); + }, [ moveCurrentWindow ]); + + const startDragging = useCallback((startX: number, startY: number) => + { + setStart({ x: startX, y: startY }); setIsDragging(true); }, []); + const onDragMouseDown = useCallback((event: MouseEvent) => + { + startDragging(event.clientX, event.clientY); + }, [ startDragging ]); + + const onTouchDown = useCallback((event: TouchEvent) => + { + const touch = event.touches[0]; + + startDragging(touch.clientX, touch.clientY); + }, [ startDragging ]); + const onDragMouseMove = useCallback((event: MouseEvent) => { setDelta({ x: (event.clientX - start.x), y: (event.clientY - start.y) }); }, [ start ]); - const onDragMouseUp = useCallback((event: MouseEvent) => + const onDragTouchMove = useCallback((event: TouchEvent) => + { + const touch = event.touches[0]; + + setDelta({ x: (touch.clientX - start.x), y: (touch.clientY - start.y) }); + }, [ start ]); + + const completeDrag = useCallback(() => { if(!elementRef.current || !dragHandler) return; @@ -98,6 +127,16 @@ export const DraggableWindow: FC = props => if(uniqueKey !== null) POS_MEMORY.set(uniqueKey, { x: offsetX, y: offsetY }); }, [ dragHandler, delta, offset, uniqueKey ]); + const onDragMouseUp = useCallback((event: MouseEvent) => + { + completeDrag(); + }, [ completeDrag ]); + + const onDragTouchUp = useCallback((event: TouchEvent) => + { + completeDrag(); + }, [ completeDrag ]); + useEffect(() => { const element = (elementRef.current as HTMLElement); @@ -169,29 +208,35 @@ export const DraggableWindow: FC = props => if(!dragHandler) return; dragHandler.addEventListener(MouseEventType.MOUSE_DOWN, onDragMouseDown); + dragHandler.addEventListener(TouchEventType.TOUCH_START, onTouchDown); return () => { dragHandler.removeEventListener(MouseEventType.MOUSE_DOWN, onDragMouseDown); + dragHandler.removeEventListener(TouchEventType.TOUCH_START, onTouchDown); } - }, [ dragHandler, onDragMouseDown ]); + }, [ dragHandler, onDragMouseDown, onTouchDown ]); useEffect(() => { if(!isDragging) return; document.addEventListener(MouseEventType.MOUSE_UP, onDragMouseUp); + document.addEventListener(TouchEventType.TOUCH_END, onDragTouchUp); document.addEventListener(MouseEventType.MOUSE_MOVE, onDragMouseMove); + document.addEventListener(TouchEventType.TOUCH_MOVE, onDragTouchMove); return () => { document.removeEventListener(MouseEventType.MOUSE_UP, onDragMouseUp); + document.removeEventListener(TouchEventType.TOUCH_END, onDragTouchUp); document.removeEventListener(MouseEventType.MOUSE_MOVE, onDragMouseMove); + document.removeEventListener(TouchEventType.TOUCH_MOVE, onDragTouchMove); } - }, [ isDragging, onDragMouseUp, onDragMouseMove ]); + }, [ isDragging, onDragMouseUp, onDragMouseMove, onDragTouchUp, onDragTouchMove ]); return ( -
+
{ children }
); diff --git a/src/layout/notification-bubble/NotificationBubbleView.tsx b/src/layout/notification-bubble/NotificationBubbleView.tsx index 49a45b9f..5c91505d 100644 --- a/src/layout/notification-bubble/NotificationBubbleView.tsx +++ b/src/layout/notification-bubble/NotificationBubbleView.tsx @@ -1,28 +1,46 @@ -import { FC, useEffect, useState } from 'react'; +import { FC, useEffect, useMemo, useState } from 'react'; +import { NitroLayoutBase } from '../base'; +import { TransitionAnimation, TransitionAnimationTypes } from '../transitions'; import { NotificationBubbleViewProps } from './NotificationBubbleView.types'; export const NotificationBubbleView: FC = props => { - const { fadesOut = false, close = null, className = '', children = null, ...rest } = props; - const [ isFading, setIsFading ] = useState(false); + const { fadesOut = true, timeoutMs = 8000, close = null, className = '', ...rest } = props; + const [ isVisible, setIsVisible ] = useState(false); + + const getClassName = useMemo(() => + { + let newClassName = 'nitro-notification-bubble rounded'; + + if(className && className.length) newClassName += ` ${ className }`; + + return newClassName; + }, [ className ]); + + useEffect(() => + { + setIsVisible(true); + + return () => setIsVisible(false); + }, []); useEffect(() => { if(!fadesOut) return; const timeout = setTimeout(() => - { - setIsFading(true); + { + setIsVisible(false); - setTimeout(() => close()); - }, 8000); + setTimeout(() => close(), 300); + }, timeoutMs); return () => clearTimeout(timeout); - }, [ fadesOut, close ]); + }, [ fadesOut, timeoutMs, close ]); return ( -
- { children } -
- ) + + + + ); } diff --git a/src/layout/notification-bubble/NotificationBubbleView.types.ts b/src/layout/notification-bubble/NotificationBubbleView.types.ts index 1fac4e46..5c160b4e 100644 --- a/src/layout/notification-bubble/NotificationBubbleView.types.ts +++ b/src/layout/notification-bubble/NotificationBubbleView.types.ts @@ -1,7 +1,8 @@ -import { DetailsHTMLAttributes } from 'react'; +import { NitroLayoutBaseProps } from '../base'; -export interface NotificationBubbleViewProps extends DetailsHTMLAttributes +export interface NotificationBubbleViewProps extends NitroLayoutBaseProps { fadesOut?: boolean; + timeoutMs?: number; close: () => void; } diff --git a/src/layout/trophy/NitroLayoutTrophyView.scss b/src/layout/trophy/NitroLayoutTrophyView.scss index edcc05f8..795169b4 100644 --- a/src/layout/trophy/NitroLayoutTrophyView.scss +++ b/src/layout/trophy/NitroLayoutTrophyView.scss @@ -3,6 +3,7 @@ width: 340px; height: 173px; color: black; + pointer-events: all; background-position: 0px 0px; background-image: url('../../assets/images/room-widgets/trophy-widget/trophy-spritesheet.png');