mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
🆙 Take #3 desktop view catalog is now 100%
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { GetRenderer, GetTicker, NitroTicker, RoomPreviewer, TextureUtils } from '@nitrots/nitro-renderer';
|
||||
import { GetRenderer, GetTicker, NitroLogger, NitroTicker, RoomPreviewer, TextureUtils } from '@nitrots/nitro-renderer';
|
||||
import { FC, MouseEvent, useEffect, useRef } from 'react';
|
||||
|
||||
export const LayoutRoomPreviewerView: FC<{
|
||||
@@ -8,6 +8,13 @@ export const LayoutRoomPreviewerView: FC<{
|
||||
{
|
||||
const { roomPreviewer = null, height = 0 } = props;
|
||||
const elementRef = useRef<HTMLDivElement>(null);
|
||||
// Latch that disables further renders once Pixi throws inside this
|
||||
// previewer. The crash (e.g. blackhole furni's filter chain that
|
||||
// accesses .alphaMode on a null texture) repeats every animation
|
||||
// frame as long as the ticker keeps firing, flooding the console
|
||||
// and locking the catalog. One catch and we stop trying for the
|
||||
// lifetime of this previewer instance.
|
||||
const renderFailedRef = useRef(false);
|
||||
|
||||
const onClick = (event: MouseEvent<HTMLDivElement>) =>
|
||||
{
|
||||
@@ -21,17 +28,22 @@ export const LayoutRoomPreviewerView: FC<{
|
||||
{
|
||||
if(!elementRef) return;
|
||||
|
||||
renderFailedRef.current = false;
|
||||
|
||||
const width = elementRef.current.parentElement.clientWidth;
|
||||
const texture = TextureUtils.createRenderTexture(width, height);
|
||||
|
||||
const paintToDOM = () =>
|
||||
{
|
||||
if(renderFailedRef.current) return;
|
||||
if(!roomPreviewer || !elementRef.current) return;
|
||||
|
||||
const renderingCanvas = roomPreviewer.getRenderingCanvas();
|
||||
|
||||
if(!renderingCanvas) return;
|
||||
|
||||
try
|
||||
{
|
||||
GetRenderer().render({
|
||||
target: texture,
|
||||
container: renderingCanvas.master,
|
||||
@@ -45,13 +57,29 @@ export const LayoutRoomPreviewerView: FC<{
|
||||
canvas.height = 0;
|
||||
|
||||
elementRef.current.style.backgroundImage = `url(${ base64 })`;
|
||||
}
|
||||
catch(error)
|
||||
{
|
||||
renderFailedRef.current = true;
|
||||
NitroLogger.error('LayoutRoomPreviewerView paint failed; disabling further renders for this preview', error);
|
||||
}
|
||||
};
|
||||
|
||||
const update = (ticker: NitroTicker) =>
|
||||
{
|
||||
if(renderFailedRef.current) return;
|
||||
if(!roomPreviewer || !elementRef.current) return;
|
||||
|
||||
try
|
||||
{
|
||||
roomPreviewer.updatePreviewRoomView();
|
||||
}
|
||||
catch(error)
|
||||
{
|
||||
renderFailedRef.current = true;
|
||||
NitroLogger.error('LayoutRoomPreviewerView update failed; disabling further renders for this preview', error);
|
||||
return;
|
||||
}
|
||||
|
||||
const renderingCanvas = roomPreviewer.getRenderingCanvas();
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ColorConverter } from '@nitrots/nitro-renderer';
|
||||
import { FC, useMemo, useState } from 'react';
|
||||
import { FaFillDrip } from 'react-icons/fa';
|
||||
import { IPurchasableOffer, SanitizeHtml } from '../../../../../api';
|
||||
import { AutoGrid, Button, Column, Grid, LayoutGridItem, Text } from '../../../../../common';
|
||||
import { FaExchangeAlt, FaFillDrip, FaSyncAlt } from 'react-icons/fa';
|
||||
import { IPurchasableOffer, ProductTypeEnum, SanitizeHtml } from '../../../../../api';
|
||||
import { AutoGrid, Button, Column, LayoutGridItem, Text } from '../../../../../common';
|
||||
import { useCatalogData, useCatalogUiState } from '../../../../../hooks';
|
||||
import { CatalogGridOfferView } from '../common/CatalogGridOfferView';
|
||||
import { CatalogAddOnBadgeWidgetView } from '../widgets/CatalogAddOnBadgeWidgetView';
|
||||
@@ -22,7 +22,7 @@ export const CatalogLayoutColorGroupingView: FC<CatalogLayoutColorGroupViewProps
|
||||
{
|
||||
const { page = null } = props;
|
||||
const [ colorableItems, setColorableItems ] = useState<Map<string, number[]>>(new Map<string, number[]>());
|
||||
const { currentOffer = null } = useCatalogData();
|
||||
const { currentOffer = null, roomPreviewer = null } = useCatalogData();
|
||||
const { setCurrentOffer = null } = useCatalogUiState();
|
||||
const [ colorsShowing, setColorsShowing ] = useState<boolean>(false);
|
||||
|
||||
@@ -132,26 +132,42 @@ export const CatalogLayoutColorGroupingView: FC<CatalogLayoutColorGroupViewProps
|
||||
}, [ page.offers ]);
|
||||
|
||||
return (
|
||||
<Grid>
|
||||
<Column overflow="hidden" size={ 7 }>
|
||||
<AutoGrid columnCount={ 5 }>
|
||||
<Column overflow="hidden">
|
||||
{ /* Top: two visible rows of furni tiles. Tile is 70px tall
|
||||
and the AutoGrid handles its own overflow if there are
|
||||
more than two rows worth of offers. */ }
|
||||
<div className="shrink-0" style={ { maxHeight: 154 } }>
|
||||
{ (!colorsShowing || !currentOffer || !colorableItems.has(currentOffer.product.furnitureData.className)) &&
|
||||
offers.map((offer, index) => <CatalogGridOfferView key={ index } itemActive={ (currentOffer && (currentOffer.product.furnitureData.hasIndexedColor ? currentOffer.product.furnitureData.className === offer.product.furnitureData.className : currentOffer.offerId === offer.offerId)) } offer={ offer } selectOffer={ selectOffer } />)
|
||||
}
|
||||
<AutoGrid columnCount={ 7 } columnMinHeight={ 70 } columnMinWidth={ 45 }>
|
||||
{ offers.map((offer, index) => <CatalogGridOfferView key={ index } itemActive={ (currentOffer && (currentOffer.product.furnitureData.hasIndexedColor ? currentOffer.product.furnitureData.className === offer.product.furnitureData.className : currentOffer.offerId === offer.offerId)) } offer={ offer } selectOffer={ selectOffer } />) }
|
||||
</AutoGrid> }
|
||||
{ (colorsShowing && currentOffer && colorableItems.has(currentOffer.product.furnitureData.className)) &&
|
||||
colorableItems.get(currentOffer.product.furnitureData.className).map((color, index) => <LayoutGridItem key={ index } itemHighlight className="clear-bg" itemActive={ (currentOffer.product.furnitureData.colorIndex === index) } itemColor={ ColorConverter.int2rgb(color) } onClick={ event => selectColor(index, currentOffer.product.furnitureData.className) } />)
|
||||
}
|
||||
</AutoGrid>
|
||||
</Column>
|
||||
<Column center={ !currentOffer } overflow="hidden" size={ 5 }>
|
||||
<div className="nitro-catalog-classic-color-swatches flex flex-wrap gap-1 p-2 overflow-auto">
|
||||
{ colorableItems.get(currentOffer.product.furnitureData.className).map((color, index) => <LayoutGridItem key={ index } itemHighlight className="clear-bg" itemActive={ (currentOffer.product.furnitureData.colorIndex === index) } itemColor={ ColorConverter.int2rgb(color) } onClick={ event => selectColor(index, currentOffer.product.furnitureData.className) } />) }
|
||||
</div> }
|
||||
</div>
|
||||
|
||||
{ /* Bottom: preview pane stacked under the grid. Mirrors the
|
||||
default-3x3 split (preview on the left, offer info on the
|
||||
right) so the rotate/state buttons and Buy/Gift actions
|
||||
sit where the user expects. */ }
|
||||
{ !currentOffer &&
|
||||
<>
|
||||
<Column center grow overflow="hidden">
|
||||
{ !!page.localization.getImage(1) && <img alt="" src={ page.localization.getImage(1) } /> }
|
||||
<Text center dangerouslySetInnerHTML={ { __html: SanitizeHtml(page.localization.getText(0)) } } />
|
||||
</> }
|
||||
</Column> }
|
||||
{ currentOffer &&
|
||||
<div className="nitro-catalog-classic-offer-panel flex flex-col items-center grow overflow-hidden gap-2">
|
||||
<div className="nitro-catalog-classic-offer-preview relative flex items-center justify-center overflow-hidden">
|
||||
{ (currentOffer.product.productType !== ProductTypeEnum.BADGE) &&
|
||||
<>
|
||||
<div className="relative overflow-hidden">
|
||||
<button className="nitro-catalog-classic-preview-btn nitro-catalog-classic-preview-rotate" onClick={ () => roomPreviewer?.changeRoomObjectDirection() }>
|
||||
<FaSyncAlt />
|
||||
</button>
|
||||
<button className="nitro-catalog-classic-preview-btn nitro-catalog-classic-preview-state" onClick={ () => roomPreviewer?.changeRoomObjectState() }>
|
||||
<FaExchangeAlt />
|
||||
</button>
|
||||
</> }
|
||||
<CatalogViewProductWidgetView />
|
||||
<CatalogAddOnBadgeWidgetView className="bg-muted rounded bottom-1 inset-e-1" position="absolute" />
|
||||
{ currentOffer.product.furnitureData.hasIndexedColor &&
|
||||
@@ -159,19 +175,16 @@ export const CatalogLayoutColorGroupingView: FC<CatalogLayoutColorGroupViewProps
|
||||
<FaFillDrip className="fa-icon" />
|
||||
</Button> }
|
||||
</div>
|
||||
<Column className="grow!" gap={ 1 }>
|
||||
<div className="w-full max-w-[360px] flex flex-col gap-2 px-1">
|
||||
<CatalogLimitedItemWidgetView />
|
||||
<Text truncate className="grow!">{ currentOffer.localizationName }</Text>
|
||||
<div className="flex justify-between">
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text truncate>{ currentOffer.localizationName }</Text>
|
||||
<div className="flex justify-between items-center">
|
||||
<CatalogSpinnerWidgetView />
|
||||
</div>
|
||||
<CatalogTotalPriceWidget alignItems="end" justifyContent="end" />
|
||||
</div>
|
||||
<CatalogPurchaseWidgetView />
|
||||
</div>
|
||||
</div> }
|
||||
</Column>
|
||||
</> }
|
||||
</Column>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -291,7 +291,7 @@ export const CatalogLayoutPetView: FC<CatalogLayoutProps> = props =>
|
||||
{ LocalizeText('catalog.pets.back.breeds') }
|
||||
</button> }
|
||||
</div>
|
||||
<div className="grid grid-cols-6 gap-1">
|
||||
<div className={ colorsShowing ? 'nitro-catalog-classic-color-swatches flex flex-wrap gap-1 p-2 overflow-auto' : 'grid grid-cols-6 gap-1' }>
|
||||
{ !colorsShowing && (sellablePalettes.length > 0) && sellablePalettes.map((palette, index) => (
|
||||
<LayoutGridItem
|
||||
key={ index }
|
||||
@@ -303,10 +303,12 @@ export const CatalogLayoutPetView: FC<CatalogLayoutProps> = props =>
|
||||
</LayoutGridItem>
|
||||
)) }
|
||||
{ colorsShowing && (sellableColors.length > 0) && sellableColors.map((colorSet, index) => (
|
||||
<div
|
||||
<LayoutGridItem
|
||||
key={ index }
|
||||
className={ `w-full aspect-square rounded border-2 cursor-pointer transition-all ${ selectedColorIndex === index ? 'border-primary scale-110 shadow-md' : 'border-card-grid-item-border hover:border-primary/50' }` }
|
||||
style={ { backgroundColor: `#${ ColorConverter.int2rgb(colorSet[0]) }` } }
|
||||
itemHighlight
|
||||
className="clear-bg"
|
||||
itemActive={ (selectedColorIndex === index) }
|
||||
itemColor={ ColorConverter.int2rgb(colorSet[0]) }
|
||||
onClick={ () => setSelectedColorIndex(index) }
|
||||
/>
|
||||
)) }
|
||||
|
||||
@@ -22,6 +22,8 @@ export const CatalogViewProductWidgetView: FC<{}> = props =>
|
||||
roomPreviewer.updateObjectRoom('default', 'default', 'default');
|
||||
roomPreviewer.updateRoomWallsAndFloorVisibility(true, true);
|
||||
|
||||
const populate = () =>
|
||||
{
|
||||
switch(product.productType)
|
||||
{
|
||||
case ProductTypeEnum.FLOOR: {
|
||||
@@ -101,6 +103,17 @@ export const CatalogViewProductWidgetView: FC<{}> = props =>
|
||||
roomPreviewer.addAvatarIntoRoom(GetSessionDataManager().figure, product.productClassId);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
populate();
|
||||
|
||||
// RoomPreviewer.addFurnitureIntoRoom / addAvatarIntoRoom flip
|
||||
// _automaticStateChange to true, which makes the ticker advance
|
||||
// the room object's state every AUTOMATIC_STATE_CHANGE_INTERVAL.
|
||||
// In the catalog we want the preview to sit still until the
|
||||
// user clicks the state button explicitly - turn it back off
|
||||
// after populate() runs.
|
||||
roomPreviewer.setAutomaticStateChange(false);
|
||||
}, [ currentOffer, previewStuffData, roomPreviewer ]);
|
||||
|
||||
if(!currentOffer) return null;
|
||||
@@ -119,5 +132,11 @@ export const CatalogViewProductWidgetView: FC<{}> = props =>
|
||||
);
|
||||
}
|
||||
|
||||
return <LayoutRoomPreviewerView height={ 240 } roomPreviewer={ roomPreviewer } />;
|
||||
// Re-mount the previewer whenever the offer changes so the render
|
||||
// latch / texture handle in LayoutRoomPreviewerView resets cleanly.
|
||||
// Without this a single broken offer (e.g. blackhole's Pixi filter
|
||||
// crash) latches the previewer permanently and every following
|
||||
// offer paints nothing - the singleton roomPreviewer + 240px height
|
||||
// keep the same component mounted otherwise.
|
||||
return <LayoutRoomPreviewerView key={ currentOffer?.offerId } height={ 240 } roomPreviewer={ roomPreviewer } />;
|
||||
};
|
||||
|
||||
@@ -12,14 +12,6 @@
|
||||
--catalog-swf-select-outer: #82d1ed;
|
||||
--catalog-swf-bc: #ff8d00;
|
||||
--catalog-swf-bc-outer: #ffb53c;
|
||||
--habbo-skin-ubuntu: url("../../assets/images/catalog/swf/skins/habbo_skin_ubuntu.png");
|
||||
--habbo-skin-blue: url("../../assets/images/catalog/swf/skins/habbo_skin_blue.png");
|
||||
--habbo-skin-illumina-light: url("../../assets/images/catalog/swf/skins/habbo_skin_illumina_light.png");
|
||||
--habbo-skin-illumina-dark: url("../../assets/images/catalog/swf/skins/habbo_skin_illumina_dark.png");
|
||||
--habbo-slice-frame: url("../../assets/images/catalog/swf/ubuntu_frame3_26x55.png");
|
||||
--habbo-slice-tab-default: url("../../assets/images/catalog/swf/ubuntu_tab3_default_22x32.png");
|
||||
--habbo-slice-tab-selected: url("../../assets/images/catalog/swf/ubuntu_tab3_selected_22x32.png");
|
||||
--habbo-slice-tab-hover: url("../../assets/images/catalog/swf/ubuntu_tab3_hover_22x32.png");
|
||||
/* Light gray secondary button - cropped from catalog_skin1.png
|
||||
at (10, 190, 25x22). Drives the gift button "Cadeau", the
|
||||
preview-room control button and the generic .nitro-catalog-swf-
|
||||
@@ -42,10 +34,6 @@
|
||||
--habbo-button-green-hover: url("../../assets/images/catalog/buttons/buy_hover.png");
|
||||
--habbo-button-green-pressed: url("../../assets/images/catalog/buttons/buy_pressed.png");
|
||||
--habbo-button-green-disabled: url("../../assets/images/catalog/buttons/buy_disabled.png");
|
||||
--habbo-grid-default: url("../../assets/images/catalog/swf/habbo_grid.png");
|
||||
--habbo-grid-hover: url("../../assets/images/catalog/swf/habbo_grid_hover.png");
|
||||
--habbo-grid-selected: url("../../assets/images/catalog/swf/habbo_grid_selected.png");
|
||||
--habbo-grid-selected-inactive: url("../../assets/images/catalog/swf/habbo_grid_selected_inactive.png");
|
||||
--habbo-close: url("../../assets/images/catalog/buttons/close.png");
|
||||
--habbo-close-hover: url("../../assets/images/catalog/buttons/close_hover.png");
|
||||
--habbo-close-pressed: url("../../assets/images/catalog/buttons/close_pressed.png");
|
||||
@@ -782,14 +770,24 @@
|
||||
|
||||
.nitro-catalog-classic-offer-preview {
|
||||
position: relative;
|
||||
width: 360px;
|
||||
min-width: 360px;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
/* The default-3x3 layout puts the preview next to .offer-info inside
|
||||
.offer-panel and needs the 360px column. Scope the pin to that
|
||||
context so other layouts (color-grouping, etc.) can put the same
|
||||
preview class inside a flex/grid column and let it track the
|
||||
container width. Without this scoping the absolute-positioned
|
||||
rotate/state buttons sit past the column's right edge and get
|
||||
clipped by overflow: hidden. */
|
||||
.nitro-catalog-classic-offer-panel > .nitro-catalog-classic-offer-preview {
|
||||
width: 360px;
|
||||
min-width: 360px;
|
||||
}
|
||||
|
||||
.nitro-catalog-classic-preview-title {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
@@ -892,12 +890,19 @@
|
||||
min-height: var(--nitro-grid-column-min-height, 70px) !important;
|
||||
border: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
background-color: transparent !important;
|
||||
background-image: none !important;
|
||||
box-shadow: none !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
/* Furni tiles drive their look from the icon image and need a clear
|
||||
background. Color-grouping swatches use itemHighlight (.has-highlight)
|
||||
to ask LayoutGridItem for a solid colour via inline backgroundColor -
|
||||
keep the transparent override off those so the swatch is visible. */
|
||||
.nitro-catalog-classic-window .layout-grid-item:not(.has-highlight) {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.nitro-catalog-classic-window .layout-grid-item:hover {
|
||||
background-image: none !important;
|
||||
box-shadow: inset 0 0 0 1px #a1a19b !important;
|
||||
@@ -911,6 +916,42 @@
|
||||
inset -2px -2px 0 #ecece4 !important;
|
||||
}
|
||||
|
||||
/* Habbo-classic colour swatches: small chip with a 1px dark border
|
||||
and a subtle inner highlight so light tones still read as buttons.
|
||||
Hover lifts the border; the selected swatch is "pressed" with a
|
||||
sunken inner shadow and a bright cyan ring matching the catalog
|
||||
selection accent. The cream inset from the generic .is-active rule
|
||||
above would wash out the swatch colour, so we replace it here. */
|
||||
.nitro-catalog-classic-window .layout-grid-item.has-highlight {
|
||||
width: 26px !important;
|
||||
height: 26px !important;
|
||||
min-width: 26px !important;
|
||||
min-height: 26px !important;
|
||||
margin: 1px !important;
|
||||
border: 1px solid #2a2a2a !important;
|
||||
border-radius: 2px !important;
|
||||
box-shadow:
|
||||
inset 1px 1px 0 rgba(255, 255, 255, 0.35),
|
||||
inset -1px -1px 0 rgba(0, 0, 0, 0.18) !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
.nitro-catalog-classic-window .layout-grid-item.has-highlight:hover {
|
||||
border-color: #000 !important;
|
||||
box-shadow:
|
||||
inset 1px 1px 0 rgba(255, 255, 255, 0.5),
|
||||
inset -1px -1px 0 rgba(0, 0, 0, 0.25),
|
||||
0 0 0 1px rgba(0, 0, 0, 0.45) !important;
|
||||
}
|
||||
|
||||
.nitro-catalog-classic-window .layout-grid-item.has-highlight.is-active {
|
||||
border-color: #000 !important;
|
||||
box-shadow:
|
||||
inset 0 0 0 2px #ffffff,
|
||||
inset 0 0 0 3px #000,
|
||||
0 0 0 1px #63c5e9 !important;
|
||||
}
|
||||
|
||||
.nitro-catalog-classic-grid-offer-icon {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
@@ -1432,6 +1473,44 @@
|
||||
right: 6px;
|
||||
}
|
||||
|
||||
/* Bulletproof override for the rotate/state buttons. The shared SWF
|
||||
button rule above lays a transparent body + border-image skin on
|
||||
top, which works only when the catalog/buttons/btn_secondary*.png
|
||||
sprites resolve - if they're missing the button renders 0x0
|
||||
invisible. Pin the box and paint a visible gradient + outline so
|
||||
the controls are always discoverable, and force z-index above the
|
||||
room-previewer DIV so they sit on top of the rendered scene. */
|
||||
.nitro-catalog-classic-window button.nitro-catalog-classic-preview-btn {
|
||||
width: 28px !important;
|
||||
height: 26px !important;
|
||||
min-width: 28px !important;
|
||||
min-height: 26px !important;
|
||||
padding: 0 !important;
|
||||
border: 1px solid #2a2a2a !important;
|
||||
border-image: none !important;
|
||||
border-image-source: none !important;
|
||||
border-radius: 3px !important;
|
||||
background: linear-gradient(180deg, #f6f6f0 0%, #d3d3c8 100%) !important;
|
||||
background-color: #ecece4 !important;
|
||||
background-image: linear-gradient(180deg, #f6f6f0 0%, #d3d3c8 100%) !important;
|
||||
box-shadow:
|
||||
inset 1px 1px 0 rgba(255, 255, 255, 0.7),
|
||||
0 1px 0 rgba(0, 0, 0, 0.35) !important;
|
||||
z-index: 10 !important;
|
||||
}
|
||||
|
||||
.nitro-catalog-classic-window button.nitro-catalog-classic-preview-btn:hover {
|
||||
background: linear-gradient(180deg, #ffffff 0%, #dedeD2 100%) !important;
|
||||
background-image: linear-gradient(180deg, #ffffff 0%, #dedeD2 100%) !important;
|
||||
border-color: #000 !important;
|
||||
}
|
||||
|
||||
.nitro-catalog-classic-window button.nitro-catalog-classic-preview-btn:active {
|
||||
background: linear-gradient(180deg, #d3d3c8 0%, #f6f6f0 100%) !important;
|
||||
background-image: linear-gradient(180deg, #d3d3c8 0%, #f6f6f0 100%) !important;
|
||||
box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.18) !important;
|
||||
}
|
||||
|
||||
.nitro-catalog-classic-window .nitro-catalog-classic-navigation-shell::-webkit-scrollbar,
|
||||
.nitro-catalog-classic-window .nitro-catalog-classic-navigation-list::-webkit-scrollbar,
|
||||
.nitro-catalog-classic-window .nitro-catalog-classic-grid-shell::-webkit-scrollbar,
|
||||
|
||||
@@ -1,70 +1,3 @@
|
||||
.nitro-swf-button {
|
||||
min-height: 22px !important;
|
||||
height: 22px;
|
||||
padding: 2px 10px !important;
|
||||
border: 3px solid transparent !important;
|
||||
border-radius: 0 !important;
|
||||
border-image-source: url("../../assets/images/catalog/swf/habbo_skin_button_default_9x22.png") !important;
|
||||
border-image-slice: 3 3 3 3 fill !important;
|
||||
border-image-width: 3px !important;
|
||||
border-image-repeat: stretch !important;
|
||||
background: transparent !important;
|
||||
background-color: transparent !important;
|
||||
background-image: none !important;
|
||||
box-shadow: none !important;
|
||||
color: #222 !important;
|
||||
font-size: 11px !important;
|
||||
font-weight: 700 !important;
|
||||
line-height: 16px !important;
|
||||
text-shadow: 0 1px 0 rgba(255,255,255,.75) !important;
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
.nitro-swf-button:hover {
|
||||
border-image-source: url("../../assets/images/catalog/swf/habbo_skin_button_hover_9x22.png") !important;
|
||||
background: transparent !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.nitro-swf-button:active,
|
||||
.nitro-swf-button.active {
|
||||
border-image-source: url("../../assets/images/catalog/swf/habbo_skin_button_pressed_9x22.png") !important;
|
||||
background: transparent !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.nitro-swf-button.pointer-events-none,
|
||||
.nitro-swf-button:disabled {
|
||||
border-image-source: url("../../assets/images/catalog/swf/habbo_skin_button_disabled_9x22.png") !important;
|
||||
color: #888 !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.nitro-swf-button-success {
|
||||
height: 24px;
|
||||
min-height: 24px !important;
|
||||
border: 6px solid transparent !important;
|
||||
border-image-source: url("../../assets/images/catalog/swf/habbo_skin_button_green_24x24.png") !important;
|
||||
border-image-slice: 6 6 6 6 fill !important;
|
||||
border-image-width: 6px !important;
|
||||
color: #fff !important;
|
||||
text-shadow: 0 1px 0 rgba(0,0,0,.55) !important;
|
||||
}
|
||||
|
||||
.nitro-swf-button-success:hover {
|
||||
border-image-source: url("../../assets/images/catalog/swf/habbo_skin_button_green_hover_24x24.png") !important;
|
||||
}
|
||||
|
||||
.nitro-swf-button-success:active,
|
||||
.nitro-swf-button-success.active {
|
||||
border-image-source: url("../../assets/images/catalog/swf/habbo_skin_button_green_pressed_24x24.png") !important;
|
||||
}
|
||||
|
||||
.nitro-swf-button-success.pointer-events-none,
|
||||
.nitro-swf-button-success:disabled {
|
||||
border-image-source: url("../../assets/images/catalog/swf/habbo_skin_button_green_disabled_24x24.png") !important;
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
min-height: 28px;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
.habbo-swf-window {
|
||||
--habbo-swf-ubuntu: url("../../assets/images/catalog/swf/habbo_skin_ubuntu.png");
|
||||
--habbo-swf-blue: url("../../assets/images/catalog/swf/skins/habbo_skin_blue.png");
|
||||
--habbo-swf-bg: #ecece4;
|
||||
--habbo-swf-panel: #f7f7f2;
|
||||
--habbo-swf-border: #9d9d96;
|
||||
|
||||
@@ -46,8 +46,6 @@ import './css/inventory/InventoryView.css';
|
||||
|
||||
import './css/layout/LayoutTrophy.css';
|
||||
|
||||
import './css/navigator/HabboNavigatorDesktop.css';
|
||||
|
||||
|
||||
import './css/nitrocard/NitroCardView.css';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user