Begin new card

This commit is contained in:
Bill 2024-04-11 22:57:44 -04:00
parent 5469c9df36
commit a6a15b0771
5 changed files with 186 additions and 14 deletions

View File

@ -1,7 +1,6 @@
import { MouseEventType, TouchEventType } from '@nitrots/nitro-renderer';
import { CSSProperties, FC, Key, MouseEvent as ReactMouseEvent, ReactNode, TouchEvent as ReactTouchEvent, useCallback, useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { Base } from '..';
import { GetLocalStorage, SetLocalStorage, WindowSaveOptions } from '../../api';
import { DraggableWindowPosition } from './DraggableWindowPosition';
@ -263,8 +262,8 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
return (
createPortal(
<Base className="draggable-window" innerRef={ elementRef } position="absolute" style={ dragStyle } onMouseDownCapture={ onMouseDown } onTouchStartCapture={ onTouchStart }>
<div ref={ elementRef } className="absolute draggable-window" style={ dragStyle } onMouseDownCapture={ onMouseDown } onTouchStartCapture={ onTouchStart }>
{ children }
</Base>, document.getElementById('draggable-windows-container'))
</div>, document.getElementById('draggable-windows-container'))
);
}

View File

@ -1,8 +1,9 @@
import { NitroCard, NitroCardTabs } from '@layout/NitroCard';
import { AddLinkEventTracker, ConvertGlobalRoomIdMessageComposer, HabboWebTools, ILinkEventTracker, LegacyExternalInterface, NavigatorInitComposer, NavigatorSearchComposer, RemoveLinkEventTracker, RoomSessionEvent } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useRef, useState } from 'react';
import { FaPlus } from 'react-icons/fa';
import { LocalizeText, SendMessageComposer, TryVisitRoom } from '../../api';
import { Column, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
import { Column, NitroCardTabsItemView } from '../../common';
import { useNavigator, useNitroEvent } from '../../hooks';
import { NavigatorDoorStateView } from './views/NavigatorDoorStateView';
import { NavigatorRoomCreatorView } from './views/NavigatorRoomCreatorView';
@ -196,24 +197,28 @@ export const NavigatorView: FC<{}> = props =>
return (
<>
{ isVisible &&
<NitroCardView className="nitro-navigator" uniqueKey="navigator">
<NitroCardHeaderView headerText={ LocalizeText(isCreatorOpen ? 'navigator.createroom.title' : 'navigator.title') } onCloseClick={ event => setIsVisible(false) } />
<NitroCardTabsView>
<NitroCard.Main
className="w-navigator h-navigator"
uniqueKey="navigator">
<NitroCard.Header
headerText={ LocalizeText(isCreatorOpen ? 'navigator.createroom.title' : 'navigator.title') }
onCloseClick={ event => setIsVisible(false) } />
<NitroCardTabs.Main>
{ topLevelContexts && (topLevelContexts.length > 0) && topLevelContexts.map((context, index) =>
{
return (
<NitroCardTabsItemView key={ index } isActive={ ((topLevelContext === context) && !isCreatorOpen) } onClick={ event => sendSearch('', context.code) }>
<NitroCardTabs.Item key={ index } isActive={ ((topLevelContext === context) && !isCreatorOpen) } onClick={ event => sendSearch('', context.code) }>
{ LocalizeText(('navigator.toplevelview.' + context.code)) }
</NitroCardTabsItemView>
</NitroCardTabs.Item>
);
}) }
<NitroCardTabsItemView isActive={ isCreatorOpen } onClick={ event => setCreatorOpen(true) }>
<FaPlus className="fa-icon" />
</NitroCardTabsItemView>
</NitroCardTabsView>
<NitroCardContentView position="relative">
</NitroCardTabs.Main>
<NitroCard.Content>
{ isLoading &&
<div className="position-absolute size-full top-0 start-0 z-index-1 bg-muted opacity-0-5" /> }
<div className="top-0 position-absolute size-full start-0 z-index-1 bg-muted opacity-0-5" /> }
{ !isCreatorOpen &&
<>
<NavigatorSearchView sendSearch={ sendSearch } />
@ -222,8 +227,8 @@ export const NavigatorView: FC<{}> = props =>
</Column>
</> }
{ isCreatorOpen && <NavigatorRoomCreatorView /> }
</NitroCardContentView>
</NitroCardView> }
</NitroCard.Content>
</NitroCard.Main> }
<NavigatorDoorStateView />
{ isRoomInfoOpen && <NavigatorRoomInfoView onCloseClick={ () => setRoomInfoOpen(false) } /> }
{ isRoomLinkOpen && <NavigatorRoomLinkView onCloseClick={ () => setRoomLinkOpen(false) } /> }

133
src/layout/NitroCard.tsx Normal file
View File

@ -0,0 +1,133 @@
import { DetailedHTMLProps, forwardRef, HTMLAttributes, MouseEvent, PropsWithChildren } from 'react';
import { FaTimes } from 'react-icons/fa';
import { classNames, DraggableWindow, DraggableWindowPosition, DraggableWindowProps } from '../common';
import { NitroItemCountBadge } from './NitroItemCountBadge';
const classes = {
base: 'flex flex-col rounded shadow',
themes: {
'primary': 'border'
}
}
const NitroCardMain = forwardRef<HTMLDivElement, PropsWithChildren<{
theme?: 'primary';
} & DraggableWindowProps> & DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>>((props, ref) =>
{
const { theme = 'primary', uniqueKey = null, handleSelector = '.drag-handler', windowPosition = DraggableWindowPosition.CENTER, disableDrag = false, className = null, ...rest } = props;
return (
<DraggableWindow disableDrag={ disableDrag } handleSelector={ handleSelector } uniqueKey={ uniqueKey } windowPosition={ windowPosition }>
<div
ref={ ref }
className={ classNames(
classes.base,
classes.themes[theme],
className
) }
{ ...rest } />
</DraggableWindow>
);
});
NitroCardMain.displayName = 'NitroCardMain';
const NitroCardHeader = forwardRef<HTMLDivElement, {
headerText: string;
onCloseClick?: (event: MouseEvent) => void;
} & DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>>((props, ref) =>
{
const { headerText = '', onCloseClick = null, className = null, ...rest } = props;
const onMouseDown = (event: MouseEvent<HTMLDivElement>) =>
{
event.stopPropagation();
event.nativeEvent.stopImmediatePropagation();
}
return (
<div ref={ ref } className={ classNames('relative flex items-center justify-center flex-column drag-handler', className) }>
<div className="flex items-center justify-center w-full">
<span>{ headerText }</span>
<div className="absolute flex items-center justify-center right-2" onClick={ onCloseClick } onMouseDownCapture={ onMouseDown }>
<FaTimes className="fa-icon w-[12px] h-[12px]" />
</div>
</div>
</div>
)
});
NitroCardHeader.displayName = 'NitroCardHeader';
const NitroCardContent = forwardRef<HTMLDivElement, DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>>((props, ref) =>
{
const { className = null, ...rest } = props;
return (
<div
ref={ ref }
className={ classNames(
'overflow-auto',
className
) }
{ ...rest } />
);
});
NitroCardContent.displayName = 'NitroCardContent';
const NitroCardTabsMain = forwardRef<HTMLDivElement, {
} & DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>>((props, ref) =>
{
const { className = null, ...rest } = props;
return (
<div
ref={ ref }
className={ classNames(
'justify-center gap-1 flex',
className)
}
{ ...rest } />
)
});
NitroCardTabsMain.displayName = 'NitroCardTabsMain';
const NitroCardTabsItem = forwardRef<HTMLDivElement, {
isActive?: boolean;
count?: number;
} & DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>>((props, ref) =>
{
const { isActive = false, count = 0, className = null, children = null, ...rest } = props;
return (
<div
ref={ ref }
className={ classNames(
'overflow-hidden relative cursor-pointer rounded-t-lg flex',
isActive && 'active',
className)
}
{ ...rest }>
<div className="flex items-center justify-center shrink-0">
{ children }
</div>
{ (count > 0) &&
<NitroItemCountBadge count={ count } /> }
</div>
)
});
NitroCardTabsItem.displayName = 'NitroCardTabsItem';
export const NitroCard = {
Main: NitroCardMain,
Header: NitroCardHeader,
Content: NitroCardContent
};
export const NitroCardTabs = {
Main: NitroCardTabsMain,
Item: NitroCardTabsItem
};

View File

@ -0,0 +1,33 @@
import { DetailedHTMLProps, forwardRef, HTMLAttributes, PropsWithChildren } from 'react';
import { classNames } from '../common';
const classes = {
base: 'top-2 right-2 py-0.5 px-[3px] z-[1] rounded border',
themes: {
'primary': 'border-black bg-red-700'
}
}
export const NitroItemCountBadge = forwardRef<HTMLDivElement, PropsWithChildren<{
theme?: 'primary';
count: number;
}> & DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>>((props, ref) =>
{
const { theme = 'primary', count = 0, className = null, children = null, ...rest } = props;
return (
<div
ref={ ref }
className={ classNames(
classes.base,
classes.themes[theme],
className
) }
{ ...rest }>
{ count }
{ children }
</div>
);
});
NitroItemCountBadge.displayName = 'NitroItemCountBadge';

2
src/layout/index.ts Normal file
View File

@ -0,0 +1,2 @@
export * from './NitroCard';
export * from './NitroItemCountBadge';