Layout updates

This commit is contained in:
Bill 2021-09-22 15:01:56 -04:00
parent 6a28213896
commit 34ab1e6fd3
29 changed files with 183 additions and 189 deletions

View File

@ -17,6 +17,21 @@ $grid-active-border-color: $white;
$toolbar-height: 55px;
$achievement-width: 650px;
$achievement-height: 400px;
$avatar-editor-width: 620px;
$avatar-editor-height: 374px;
$catalog-width: 620px;
$catalog-height: 400px;
$inventory-width: 485px;
$inventory-height: 315px;
$navigator-width: 400px;
$navigator-height: 420px;
.nitro-app {
width: 100%;
height: 100%;

View File

@ -85,6 +85,7 @@ $ghost: #c8cad0 !default;
$gray-chateau: #a3a7b1 !default;
$gable-green: #1C323F !default;
$william: #3d5f6e !default;
$bluewood: #304059 !default;
$success: $green !default;
$info: $cyan !default;
$warning: $yellow !default;
@ -385,7 +386,7 @@ $enable-transitions: true !default;
$enable-reduced-motion: true !default;
$enable-smooth-scroll: true !default;
$enable-grid-classes: true !default;
$enable-cssgrid: false !default;
$enable-cssgrid: true !default;
$enable-button-pointers: true !default;
$enable-rfs: true !default;
$enable-validation-icons: true !default;

View File

@ -10,6 +10,14 @@
transform: scale(1) translateZ(0);
}
.scale-1-25 {
transform: scale(1.25) translateZ(0);
}
.scale-1-50 {
transform: scale(1.50) translateZ(0);
}
.scale-2 {
transform: scale(2) translateZ(0);
}

View File

@ -3,6 +3,7 @@ $nitro-card-tabs-height: 33px;
.nitro-card {
pointer-events: all;
resize: both;
@import './accordion/NitroCardAccordionView';
@import './content/NitroCardContentView';

View File

@ -10,6 +10,5 @@
height: 100% !important;
min-height: auto !important;
max-height: 100% !important;
resize: none !important;
}
}

View File

@ -8,7 +8,7 @@ export const NitroCardContentView: FC<NitroCardContentViewProps> = props =>
const { simple = false } = useNitroCardContext();
return (
<div className={ `container-fluid bg-light content-area ${ (simple ? 'simple' : '') } ${ className || '' }` } { ...rest }>
<div className={ `container-fluid bg-light content-area d-flex flex-column overflow-hidden ${ (simple ? 'simple' : '') } ${ className || '' }` } { ...rest }>
{ children }
</div>
);

View File

@ -66,6 +66,6 @@
}
}
}
@import './item/NitroCardGridItemView.scss';
}
@import './item/NitroCardGridItemView.scss';

View File

@ -1,18 +1,31 @@
import { FC } from 'react';
import { NitroCardGridContextProvider } from './context/NitroCardGridContext';
import { NitroCardGridThemes, NitroCardGridViewProps } from './NitroCardGridView.types';
import { FC, useMemo } from 'react';
import { NitroCardGridViewProps } from './NitroCardGridView.types';
export const NitroCardGridView: FC<NitroCardGridViewProps> = props =>
{
const { columns = 5, theme = NitroCardGridThemes.THEME_DEFAULT, className = '', children = null, ...rest } = props;
const { columns = 5, className = '', style = null, children = null, ...rest } = props;
const getClassName = useMemo(() =>
{
let newClassName = 'grid gap-2 overflow-auto';
if(className && className.length) newClassName += ' ' + className;
return newClassName;
}, [ className ]);
const getStyle = useMemo(() =>
{
const newStyle = { ...style };
newStyle['--bs-columns'] = columns.toString();
return newStyle;
}, [ style, columns ]);
return (
<NitroCardGridContextProvider value={ { theme } }>
<div className={ `h-100 overflow-hidden nitro-card-grid ${ theme } ${ className || '' }` } { ...rest }>
<div className={ `row row-cols-${ columns } align-content-start g-0 w-100 h-100 overflow-auto` }>
{ children }
</div>
</div>
</NitroCardGridContextProvider>
<div className={ getClassName } style={ getStyle } { ...rest }>
{ children }
</div>
);
}

View File

@ -3,11 +3,4 @@ import { DetailsHTMLAttributes } from 'react';
export interface NitroCardGridViewProps extends DetailsHTMLAttributes<HTMLDivElement>
{
columns?: number;
theme?: string;
}
export class NitroCardGridThemes
{
public static THEME_DEFAULT: string = 'theme-default';
public static THEME_SHADOWED: string = 'theme-shadowed';
}

View File

@ -1,13 +0,0 @@
import { createContext, FC, useContext } from 'react';
import { INitroCardGridContext, NitroCardGridContextProps } from './NitroCardGridContext.types';
const NitroCardGridContext = createContext<INitroCardGridContext>({
theme: null
});
export const NitroCardGridContextProvider: FC<NitroCardGridContextProps> = props =>
{
return <NitroCardGridContext.Provider value={ props.value }>{ props.children }</NitroCardGridContext.Provider>
}
export const useNitroCardGridContext = () => useContext(NitroCardGridContext);

View File

@ -1,11 +0,0 @@
import { ProviderProps } from 'react';
export interface INitroCardGridContext
{
theme: string;
}
export interface NitroCardGridContextProps extends ProviderProps<INitroCardGridContext>
{
}

View File

@ -1,2 +0,0 @@
export * from './NitroCardGridContext';
export * from './NitroCardGridContext.types';

View File

@ -1,4 +1,3 @@
export * from './context';
export * from './item';
export * from './NitroCardGridView';
export * from './NitroCardGridView.types';

View File

@ -1,86 +1,48 @@
.grid-item-container {
.grid-item {
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 50px;
max-height: 50px;
width: 100%;
background-position: center;
background-repeat: no-repeat;
border-radius: $border-radius;
border-color: $grid-border-color !important;
background-color: $grid-bg-color;
border: nth(map-values($border-widths), 2) solid;
.grid-item {
display: flex;
justify-content: center;
align-items: center;
position: relative;
width: 100%;
height: 100%;
background-position: center;
background-repeat: no-repeat;
overflow: hidden;
&.active {
border-color: $grid-active-border-color !important;
background-color: $grid-active-bg-color !important;
}
&.theme-default {
border-radius: $border-radius;
border-color: $grid-border-color !important;
background-color: $grid-bg-color;
border: nth(map-values($border-widths), 2) solid;
}
&.unseen {
background-color: rgba($success, 0.4);
}
&.theme-shadowed {
border-radius: $border-radius;
background-color: $light;
.badge {
top: 2px;
right: 2px;
font-size: 8px;
}
&::after {
position: absolute;
content: '';
top: 0;
bottom: 0;
left: 0;
right: 0;
border-radius: $border-radius;
border-bottom: 2px solid white;
border-right: 2px solid white;
box-shadow: -2px -2px rgba(0, 0, 0, .4), inset 3px 3px rgba(0, 0, 0, .2);
}
.avatar-image {
background-position-y: 10px;
}
&.active {
border: nth(map-values($border-widths), 2) solid;
border-color: $oslo-gray !important;
background-color: #F5F5F5;
.trade-button {
position: absolute;
bottom: 2px;
right: 2px;
font-size: 5px;
padding: 3px;
min-height: unset;
&:after {
content: unset;
}
}
}
&.active {
border-color: $grid-active-border-color !important;
background-color: $grid-active-bg-color !important;
}
&.unseen {
background-color: rgba($success, 0.4);
}
.badge {
top: 2px;
right: 2px;
font-size: 8px;
}
.avatar-image {
background-position: center;
background-repeat: no-repeat;
background-position-y: 12px !important;
}
.trade-button {
position: absolute;
bottom: 2px;
right: 2px;
font-size: 5px;
padding: 3px;
min-height: unset;
&.left {
right: unset;
left: 2px;
}
&.left {
right: unset;
left: 2px;
}
}
}

View File

@ -1,27 +1,48 @@
import { FC } from 'react';
import { FC, useMemo } from 'react';
import { LimitedEditionStyledNumberView } from '../../../../views/shared/limited-edition/styled-number/LimitedEditionStyledNumberView';
import { useNitroCardGridContext } from '../context';
import { NitroCardGridThemes } from '../NitroCardGridView.types';
import { NitroCardGridItemViewProps } from './NitroCardGridItemView.types';
export const NitroCardGridItemView: FC<NitroCardGridItemViewProps> = props =>
{
const { itemImage = undefined, itemColor = undefined, itemActive = false, itemCount = 1, itemUnique = false, itemUniqueNumber = 0, itemUnseen = false, columns = undefined, className = '', style = {}, children = null, ...rest } = props;
const { theme = NitroCardGridThemes.THEME_DEFAULT } = useNitroCardGridContext();
const { itemImage = undefined, itemColor = undefined, itemActive = false, itemCount = 1, itemUniqueNumber = 0, itemUnseen = false, className = '', style = {}, children = null, ...rest } = props;
const imageUrl = `url(${ itemImage })`;
const getClassName = useMemo(() =>
{
let newClassName = 'grid-item cursor-pointer overflow-hidden';
if(itemActive) newClassName += ' active';
if(itemUniqueNumber > 0) newClassName += ' unique-item';
if(itemUnseen) newClassName += ' unseen';
if(itemImage === null) newClassName += ' icon loading-icon';
if(className && className.length) newClassName += ' ' + className;
return newClassName;
}, [ className, itemActive, itemUniqueNumber, itemUnseen, itemImage ]);
const getStyle = useMemo(() =>
{
const newStyle = { ...style };
if(itemImage) newStyle.backgroundImage = `url(${ itemImage })`;
if(itemColor) newStyle.backgroundColor = itemColor;
return newStyle;
}, [ style, itemImage, itemColor ]);
return (
<div className={ `${ columns === undefined ? 'col' : ('col-' + columns) } pb-1 grid-item-container` }>
<div className={ `grid-item ${ theme } cursor-pointer${ itemActive ? ' active' : '' }${ itemUnique ? ' unique-item' : '' }${ itemUnseen ? ' unseen' : ''}${ (itemImage === null ? ' icon loading-icon': '')} ${ className || '' }` } style={ itemImage ? { ...style, backgroundImage: imageUrl } : (itemColor ? { ...style, backgroundColor: itemColor } : style) } { ...rest }>
{ (itemCount > 1) &&
<span className="position-absolute badge border bg-danger px-1 rounded-circle">{ itemCount }</span> }
{ itemUnique &&
<div className="position-absolute unique-item-counter">
<LimitedEditionStyledNumberView value={ itemUniqueNumber } />
</div> }
{ children }
</div>
<div className={ getClassName } style={ getStyle } { ...rest }>
{ (itemCount > 1) &&
<span className="position-absolute badge border bg-danger px-1 rounded-circle">{ itemCount }</span> }
{ (itemUniqueNumber > 0) &&
<div className="position-absolute unique-item-counter">
<LimitedEditionStyledNumberView value={ itemUniqueNumber } />
</div> }
{ children }
</div>
);
}

View File

@ -6,8 +6,6 @@ export interface NitroCardGridItemViewProps extends DetailsHTMLAttributes<HTMLDi
itemColor?: string;
itemActive?: boolean;
itemCount?: number;
itemUnique?: boolean;
itemUniqueNumber?: number;
itemUnseen?: boolean;
columns?: number;
}

View File

@ -1,10 +1,6 @@
.nitro-achievements {
width: 650px;
.content-area {
min-height: 376px;
height: 376px;
}
width: $achievement-width;
height: $achievement-height;
.score {
border-color: $grid-border-color !important;

View File

@ -1,10 +1,6 @@
.nitro-avatar-editor {
width: 620px;
.content-area {
min-height: 300px;
height: 300px;
}
width: $avatar-editor-width;
height: $avatar-editor-height;
.category-item {
height: 40px;
@ -82,6 +78,37 @@
.wardrobe-grid {
.grid-item {
height: 140px;
max-height: 140px;
background-color: $ghost;
&:after {
position: absolute;
content: '';
top: 75%;
bottom: 0;
left: 0;
right: 0;
border-radius: 50%;
background-color: $gray-chateau;
box-shadow: 0 0 8px 2px rgba($white,.6);
transform: scale(2);
}
.avatar-image {
position: absolute;
bottom: 0;
background-position-y: -23px !important;
z-index: 4;
}
.figure-button-container {
background-color: $gray-chateau;
z-index: 3;
}
}
.grid-item-container {
height: 142px !important;
max-height: 142px !important;

View File

@ -1,6 +1,5 @@
import { FC, useCallback } from 'react';
import { NitroCardGridView } from '../../../../layout/card/grid/NitroCardGridView';
import { NitroCardGridThemes } from '../../../../layout/card/grid/NitroCardGridView.types';
import { AvatarEditorGridPartItem } from '../../common/AvatarEditorGridPartItem';
import { AvatarEditorFigureSetItemView } from '../figure-set-item/AvatarEditorFigureSetItemView';
import { AvatarEditorFigureSetViewProps } from './AvatarEditorFigureSetView.types';
@ -23,7 +22,7 @@ export const AvatarEditorFigureSetView: FC<AvatarEditorFigureSetViewProps> = pro
}, [ model, category, setMaxPaletteCount ]);
return (
<NitroCardGridView columns={ 3 } theme={ NitroCardGridThemes.THEME_SHADOWED }>
<NitroCardGridView columns={ 3 }>
{ (category.parts.length > 0) && category.parts.map((item, index) =>
{
return <AvatarEditorFigureSetItemView key={ index } partItem={ item } onClick={ selectPart } />;

View File

@ -71,7 +71,7 @@ export const AvatarEditorModelView: FC<AvatarEditorModelViewProps> = props =>
<div className="col-5 d-flex flex-column h-100">
<AvatarEditorFigureSetView model={ model } category={ activeCategory } setMaxPaletteCount={ setMaxPaletteCount } />
</div>
<div className="col-5 d-flex flex-column h-100">
<div className="col-5 d-flex flex-column h-100 gap-2">
{ (maxPaletteCount >= 1) &&
<AvatarEditorPaletteSetView model={ model } category={ activeCategory } paletteSet={ activeCategory.getPalette(0) } paletteIndex={ 0 } /> }
{ (maxPaletteCount === 2) &&

View File

@ -1,6 +1,5 @@
import { FC, useCallback } from 'react';
import { NitroCardGridView } from '../../../../layout/card/grid/NitroCardGridView';
import { NitroCardGridThemes } from '../../../../layout/card/grid/NitroCardGridView.types';
import { AvatarEditorGridColorItem } from '../../common/AvatarEditorGridColorItem';
import { AvatarEditorPaletteSetItem } from '../palette-set-item/AvatarEditorPaletteSetItem';
import { AvatarEditorPaletteSetViewProps } from './AvatarEditorPaletteSetView.types';
@ -19,7 +18,7 @@ export const AvatarEditorPaletteSetView: FC<AvatarEditorPaletteSetViewProps> = p
}, [ model, category, paletteSet, paletteIndex ]);
return (
<NitroCardGridView columns={ 4 } theme={ NitroCardGridThemes.THEME_SHADOWED } { ...rest }>
<NitroCardGridView columns={ 4 } { ...rest }>
{ (paletteSet.length > 0) && paletteSet.map((item, index) =>
{
return <AvatarEditorPaletteSetItem key={ index } colorItem={ item } onClick={ event => selectColor(item) } />;

View File

@ -5,7 +5,6 @@ import { GetAvatarRenderManager, GetSessionDataManager } from '../../../../api';
import { SendMessageHook } from '../../../../hooks';
import { NitroCardGridItemView } from '../../../../layout/card/grid/item/NitroCardGridItemView';
import { NitroCardGridView } from '../../../../layout/card/grid/NitroCardGridView';
import { NitroCardGridThemes } from '../../../../layout/card/grid/NitroCardGridView.types';
import { AvatarImageView } from '../../../shared/avatar-image/AvatarImageView';
import { CurrencyIcon } from '../../../shared/currency-icon/CurrencyIcon';
import { AvatarEditorWardrobeViewProps } from './AvatarEditorWardrobeView.types';
@ -68,7 +67,7 @@ export const AvatarEditorWardrobeView: FC<AvatarEditorWardrobeViewProps> = props
return (
<div className="row h-100">
<div className="col-12 d-flex h-100">
<NitroCardGridView className="wardrobe-grid" columns={ 5 } theme={ NitroCardGridThemes.THEME_DEFAULT }>
<NitroCardGridView className="wardrobe-grid" columns={ 5 }>
{ figures }
</NitroCardGridView>
</div>

View File

@ -1,11 +1,6 @@
.nitro-catalog {
width: 620px;
.content-area {
min-height: 350px;
height: 350px;
resize: vertical;
}
width: $catalog-width;
height: $catalog-height;
font[size="16"] {
font-size: 20px;

View File

@ -1,11 +1,6 @@
.nitro-inventory {
width: 475px;
.content-area {
min-height: 240px;
height: 240px;
resize: vertical;
}
width: $inventory-width;
height: $inventory-height;
.empty-image {
background: url('../../assets/images/inventory/empty.png');

View File

@ -46,5 +46,5 @@ export const InventoryFurnitureItemView: FC<InventoryFurnitureItemViewProps> = p
const count = groupItem.getUnlockedCount();
return <NitroCardGridItemView className={ !count ? 'opacity-0-5 ' : '' } itemImage={ groupItem.iconUrl } itemCount={ count } itemActive={ isActive } itemUnique={ groupItem.stuffData.isUnique } itemUniqueNumber={ groupItem.stuffData.uniqueNumber } itemUnseen={ groupItem.hasUnseenItems } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent } />;
return <NitroCardGridItemView className={ !count ? 'opacity-0-5 ' : '' } itemImage={ groupItem.iconUrl } itemCount={ count } itemActive={ isActive } itemUniqueNumber={ groupItem.stuffData.uniqueNumber } itemUnseen={ groupItem.hasUnseenItems } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent } />;
}

View File

@ -233,7 +233,7 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
const count = item.getUnlockedCount();
return (
<NitroCardGridItemView key={ index } className={ !count ? 'opacity-0-5 ' : '' } itemImage={ item.iconUrl } itemCount={ count } itemActive={ (groupItem === item) } itemUnique={ item.stuffData.isUnique } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => (count && setGroupItem(item)) }>
<NitroCardGridItemView key={ index } className={ !count ? 'opacity-0-5 ' : '' } itemImage={ item.iconUrl } itemCount={ count } itemActive={ (groupItem === item) } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => (count && setGroupItem(item)) }>
{ ((count > 0) && (groupItem === item)) &&
<button className="btn btn-success btn-sm trade-button" onClick={ event => attemptItemOffer(1) }>
<i className="fas fa-chevron-right" />
@ -255,7 +255,7 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
if(!item) return <NitroCardGridItemView key={ i } />;
return (
<NitroCardGridItemView key={ i } itemActive={ (ownGroupItem === item) } itemImage={ item.iconUrl } itemCount={ item.getTotalCount() } itemUnique={ item.stuffData.isUnique } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => setOwnGroupItem(item) }>
<NitroCardGridItemView key={ i } itemActive={ (ownGroupItem === item) } itemImage={ item.iconUrl } itemCount={ item.getTotalCount() } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => setOwnGroupItem(item) }>
{ (ownGroupItem === item) &&
<button className="btn btn-danger btn-sm trade-button left" onClick={ event => removeItem(item) }>
<i className="fas fa-chevron-left" />
@ -275,7 +275,7 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
if(!item) return <NitroCardGridItemView key={ i } />;
return <NitroCardGridItemView key={ i } itemActive={ (otherGroupItem === item) } itemImage={ item.iconUrl } itemCount={ item.getTotalCount() } itemUnique={ item.stuffData.isUnique } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => setOtherGroupItem(item) } />;
return <NitroCardGridItemView key={ i } itemActive={ (otherGroupItem === item) } itemImage={ item.iconUrl } itemCount={ item.getTotalCount() } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => setOtherGroupItem(item) } />;
}) }
<div className="col-12 badge bg-muted w-100">{ otherGroupItem ? otherGroupItem.name : LocalizeText('catalog_selectproduct') }</div>
</NitroCardGridView>

View File

@ -1,11 +1,6 @@
.nitro-navigator {
width: 400px;
.content-area {
min-height: 400px;
height: 400px;
resize: vertical;
}
width: $navigator-width;
height: $navigator-height;
}
.nitro-navigator-doorbell {

View File

@ -3,8 +3,7 @@
width: 90px;
height: 130px;
background-repeat: no-repeat;
background-position-x: center;
background-position-y: -8px !important;
background-position: center -8px;
pointer-events: none;
image-rendering: pixelated;

View File

@ -14,6 +14,12 @@ export const AvatarImageView: FC<AvatarImageViewProps> = props =>
{
if(scale === .5) return '0-5';
if(scale === .75) return '0-75';
if(scale === 1.25) return '1-25';
if(scale === 1.50) return '1-50';
return scale.toString();
}, [ scale ]);